feat(reui): update ReUI components and documentation to reflect 20 building blocks
Docker / build (push) Failing after 19s
Docker / build (push) Failing after 19s
- Expanded the ReUI skill description to include 20 free building blocks. - Updated references in various documentation files to reflect the new count of components. - Enhanced the data-grid documentation to specify the use of TanStack Table v9. - Added new component details, including the icon-tile, and clarified usage instructions across multiple files. This update improves clarity and ensures that all references are consistent with the latest component offerings.
This commit is contained in:
@@ -1,17 +1,17 @@
|
||||
---
|
||||
name: reui
|
||||
description: Use the ReUI registry from your AI agent - find, install, and correctly use ReUI components (the 17 free building blocks like data-grid, kanban, filters), their free examples, premium blocks, and Motion Icons. Applies in any project using ReUI, the @reui registry, REUI_LICENSE_KEY, or any shadcn project where the user asks for premium blocks, data grids, kanban boards, dashboards, or full pages. Pairs with the free ReUI MCP server for live, scored registry search and inline component APIs.
|
||||
description: Use the ReUI registry from your AI agent - find, install, and correctly use ReUI components (the 20 free building blocks like data-grid, kanban, filters), their free examples, premium blocks, and Motion Icons. Applies in any project using ReUI, the @reui registry, REUI_LICENSE_KEY, or any shadcn project where the user asks for premium blocks, data grids, kanban boards, dashboards, or full pages. Pairs with the free ReUI MCP server for live, scored registry search and inline component APIs.
|
||||
user-invocable: false
|
||||
allowed-tools: Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *)
|
||||
---
|
||||
|
||||
> **ReUI skill version `42d70dcc3d`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
|
||||
> **ReUI skill version `668fb463eb`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
|
||||
|
||||
# ReUI for Agents
|
||||
|
||||
ReUI is a shadcn-compatible registry. It ships four things you **reuse** - never redesign:
|
||||
|
||||
- **components** - the 17 ReUI building blocks with real APIs: `data-grid`, `kanban`, `filters`, `date-selector`, `tree`, `stepper`, ... (free)
|
||||
- **components** - the 20 ReUI building blocks with real APIs: `data-grid`, `kanban`, `filters`, `date-selector`, `tree`, `stepper`, ... (free)
|
||||
- **examples** - free `c-*` single-pattern use-cases of a component (`c-kanban-1`); install one and read it to see exact composition
|
||||
- **blocks** - premium full-page sections that compose components (`data-grid-2`, `pricing-page-1`); Pro or Ultimate license at install
|
||||
- **icons** - Motion Icons in 4 styles, static + hover-animated variants; Ultimate license at install
|
||||
@@ -58,7 +58,7 @@ Invocation differs slightly per agent (`/mcp__reui__build` in Claude Code/Cursor
|
||||
|
||||
- [rules/registry.md](./rules/registry.md) - the four types, the @reui registry, base/radix, free vs premium + license
|
||||
- [rules/workflow.md](./rules/workflow.md) - the find -> install -> read-API -> adapt loop (most important)
|
||||
- [rules/components.md](./rules/components.md) - the 17 components, the data-grid contract, base vs radix
|
||||
- [rules/components.md](./rules/components.md) - the 20 components, the data-grid contract, base vs radix
|
||||
- [rules/adapting.md](./rules/adapting.md) - reuse-first: preserve the design (no over-customizing), reuse examples + a block's own elements, real data, don't invent APIs
|
||||
- [rules/craft.md](./rules/craft.md) - make it exceptional: point of view, hierarchy, density, states, responsive, motion, the bar
|
||||
- [rules/quality.md](./rules/quality.md) - security, accessibility, and scroll gates (the done gate)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Registry setup (one-time, per project)
|
||||
|
||||
Free items (the 17 components and all `c-*` examples) need only the plain string registry in `components.json`:
|
||||
Free items (the 20 components and all `c-*` examples) need only the plain string registry in `components.json`:
|
||||
|
||||
```json
|
||||
{ "registries": { "@reui": "https://reui.io/r/{style}/{name}.json" } }
|
||||
@@ -54,7 +54,7 @@ bunx --bun shadcn@latest add @reui/<name> --yes # bun
|
||||
|
||||
## Free vs premium boundary
|
||||
|
||||
- Public, no key: `c-*` examples and the 17 components (`@reui/data-grid`, `@reui/badge`, ...) that those examples depend on.
|
||||
- Public, no key: `c-*` examples and the 20 components (`@reui/data-grid`, `@reui/badge`, ...) that those examples depend on.
|
||||
- Key required at install: blocks (`@reui/<category>-N`) need a Pro or Ultimate license; Motion Icons (`@reui/icons/...`) and templates need Ultimate.
|
||||
|
||||
If an install 401/403s, the license key is missing, invalid, or the plan does not cover that resource (blocks: Pro or higher; icons and templates: Ultimate). Point the user to https://reui.io/account (their key) or https://reui.io/pricing (upgrade).
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
# ReUI components
|
||||
|
||||
The 19 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
|
||||
The 20 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `icon-tile`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
|
||||
|
||||
**Rule one: never guess a component's API. Read it first.** Call **`get_component(name)`** for its inline `api` (props + usage, no web fetch), and **share the result's `docsUrl`** (the component's API documentation page) with the user whenever you work with that component's API, so they have the full reference (the `/llms.txt` index is a further fallback). Then call **`get_examples(name)`** to install a worked example and copy real composition. The contracts below are first-try orientation (required props, composition shape, the one gotcha); the inline `api` is the full reference. No single block fits? Compose: search the components you need, read each `get_component`, install a `get_examples` example per component, and adapt.
|
||||
|
||||
## data-grid (the flagship - read its API every time)
|
||||
|
||||
`data-grid` wraps TanStack Table v8. It is NOT a styled `<table>` and does NOT take `data`/`columns` props directly. The contract:
|
||||
`data-grid` wraps TanStack Table v9. It is NOT a styled `<table>` and does NOT take `data`/`columns` props directly. The contract:
|
||||
|
||||
- Build a TanStack table instance with `useReactTable(...)` (columns, data, the feature models you need: sorting, pagination, row selection).
|
||||
- Build a TanStack table instance with `useTable({ features: dataGridFeatures, ... })` (columns, data). `dataGridFeatures` is exported by the primitive and already bundles sorting, filtering, pagination, row selection, expanding, pinning, resizing and faceting, so there are no per-table row models to wire.
|
||||
- Pass that instance to `<DataGrid table={table} recordCount={total}>`.
|
||||
- Compose the body with `DataGridTable` inside `DataGrid`, and enable features through `tableLayout` (e.g. `{ headerSticky: true, columnsResizable: true }`), not ad-hoc classes.
|
||||
- Server-side data uses the documented fetch shape (`recordCount` is the total for pagination).
|
||||
|
||||
```tsx
|
||||
const table = useReactTable({
|
||||
const table = useTable({
|
||||
features: dataGridFeatures,
|
||||
data,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
// add sorting/pagination/selection models per the API
|
||||
})
|
||||
|
||||
<DataGrid table={table} recordCount={data.length}>
|
||||
@@ -28,9 +27,9 @@ const table = useReactTable({
|
||||
|
||||
Common mistakes:
|
||||
|
||||
- **Incorrect:** `<DataGrid data={rows} columns={cols} />` - these props do not exist. **Correct:** build a `useReactTable` instance and pass `table={table}` + `recordCount`.
|
||||
- **Incorrect:** `<DataGrid data={rows} columns={cols} />` - these props do not exist. **Correct:** build a `useTable({ features: dataGridFeatures, ... })` instance and pass `table={table}` + `recordCount`.
|
||||
- **Incorrect:** a raw `<table>` / hand-rolled pagination. **Correct:** use `data-grid`; read its API for sticky header, pagination, virtualization, row selection.
|
||||
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the documented `ColumnMeta` (e.g. `cellClassName`, `headerTitle`).
|
||||
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the primitive's `DataGridColumnMeta` (e.g. `cellClassName`, `headerTitle`), set through the bundle's `columnMeta` slot.
|
||||
|
||||
## event-calendar
|
||||
|
||||
@@ -312,6 +311,19 @@ const [value, setValue] = useState<DateSelectorValue | undefined>()
|
||||
|
||||
**Gotcha:** isometric layered artwork for empty states and illustrations; style the inner icon via its own `className`. Mark purely decorative stacks `aria-hidden="true"` and keep the real label in surrounding copy.
|
||||
|
||||
## icon-tile
|
||||
|
||||
**Required:** one child icon
|
||||
**Shape:**
|
||||
|
||||
```tsx
|
||||
<IconTile variant="elevated" size="lg">
|
||||
<PackageIcon />
|
||||
</IconTile>
|
||||
```
|
||||
|
||||
**Gotcha:** the square container an icon sits in, so every list row, feature card and empty state shares one affordance. `variant`: `outline` (default) | `elevated` (muted fill, raised ring) | `soft` (tinted nested, tone from currentColor) | `solid` (filled tone, contrasting glyph) | `frame` (double container). `soft` and `solid` retint from one text color class (they default to `text-primary`). `size`: `xs | sm | default | lg | xl` (24/32/40/48/64px tile, glyph scales 12/14/16/20/24px). `radius`: `default | full`. Do not set a `size-*` class on the child icon unless you mean to override the tile's glyph size; recolor with `className` on the tile, not the icon.
|
||||
|
||||
## alert
|
||||
|
||||
**Required:** `Alert` > `AlertTitle`
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
ReUI is a shadcn-compatible registry with four entity types. **Examples and blocks are built FROM components** - reuse them, don't rebuild.
|
||||
|
||||
- **component** - one of the 17 ReUI building blocks with a real API (`data-grid`, `kanban`, `filters`, `date-selector`, `tree`, ...). Install directly (`@reui/data-grid`) or let it come in as a dependency of an example/block. Free. Read its API with `get_component(name)`.
|
||||
- **component** - one of the 20 ReUI building blocks with a real API (`data-grid`, `kanban`, `filters`, `date-selector`, `tree`, ...). Install directly (`@reui/data-grid`) or let it come in as a dependency of an example/block. Free. Read its API with `get_component(name)`.
|
||||
- **example** - a free `c-*` single-pattern use-case of a component (`c-kanban-1`, `c-data-grid-3`). Install one and read it to copy real composition. Find a component's examples with `get_examples(name)`.
|
||||
- **block** - a premium, full-page section that composes several components (`data-grid-2`, `pricing-page-1`). Pro or Ultimate license at install. Adapts to your active theme via semantic tokens.
|
||||
- **icon** - Motion Icons in 4 styles (outline, solid, duotone, filled), static (`@reui/icons/default/<style>/<name>`) and hover-animated (`@reui/icons/animated/<style>/<name>`). Ultimate license at install. See [icons.md](./icons.md).
|
||||
@@ -27,7 +27,7 @@ Blocks adapt to your active theme through semantic tokens and CSS variables - ch
|
||||
|
||||
## Free vs premium
|
||||
|
||||
- **Free, no key:** the 17 components, all `c-*` examples, the ReUI MCP, and this skill.
|
||||
- **Free, no key:** the 20 components, all `c-*` examples, the ReUI MCP, and this skill.
|
||||
- **Premium, license required at install:** blocks (Pro or Ultimate), Motion Icons and templates (Ultimate). Set `REUI_LICENSE_KEY` (see [cli.md](./cli.md)).
|
||||
|
||||
## Component API index
|
||||
|
||||
@@ -8,7 +8,7 @@ The core ReUI loop. The MCP tells you what to install and gives you the API; the
|
||||
|
||||
For everything else, call `search` with the user's intent. Pass structured hints whenever you can infer them - you are an LLM, so do the parsing the server cannot:
|
||||
|
||||
- `type`: `"component"` (one of the 17 building blocks), `"example"` (a c-\* use-case), `"block"` (a full page/section), `"icon"`.
|
||||
- `type`: `"component"` (one of the 20 building blocks), `"example"` (a c-\* use-case), `"block"` (a full page/section), `"icon"`.
|
||||
- `component`: the ReUI component the request implies (`"data-grid"`, `"kanban"`, ...).
|
||||
- `category`, `features` (e.g. `["sortable","pagination"]`), `free`.
|
||||
|
||||
@@ -40,7 +40,7 @@ Before writing code against any component an item uses:
|
||||
|
||||
Installing files is not the end, and redesigning them defeats the point. First note the project's **base** so you write the right API - read `components.json` -> `style` and take the segment before the first `-` (`base-nova` -> Base UI, `radix-nova` -> Radix UI), see [components.md](./components.md). After `add`:
|
||||
|
||||
1. **Read the added files**; keep the composition intact. For a block, verify the components are wired correctly (for `data-grid`: a `useReactTable` instance passed as `table`, `recordCount` set - see [components.md](./components.md)).
|
||||
1. **Read the added files**; keep the composition intact. For a block, verify the components are wired correctly (for `data-grid`: a `useTable({ features: dataGridFeatures, ... })` instance passed as `table`, `recordCount` set - see [components.md](./components.md)).
|
||||
2. **Replace demo data with the user's real data** via typed structures (see [adapting.md](./adapting.md)).
|
||||
3. **Fix icon imports** to the project's icon library (see [icons.md](./icons.md)).
|
||||
4. **Align styling** to semantic tokens and the active theme - no raw colors (see [styling.md](./styling.md)).
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
---
|
||||
name: reui
|
||||
description: Use the ReUI registry from your AI agent - find, install, and correctly use ReUI components (the 17 free building blocks like data-grid, kanban, filters), their free examples, premium blocks, and Motion Icons. Applies in any project using ReUI, the @reui registry, REUI_LICENSE_KEY, or any shadcn project where the user asks for premium blocks, data grids, kanban boards, dashboards, or full pages. Pairs with the free ReUI MCP server for live, scored registry search and inline component APIs.
|
||||
description: Use the ReUI registry from your AI agent - find, install, and correctly use ReUI components (the 20 free building blocks like data-grid, kanban, filters), their free examples, premium blocks, and Motion Icons. Applies in any project using ReUI, the @reui registry, REUI_LICENSE_KEY, or any shadcn project where the user asks for premium blocks, data grids, kanban boards, dashboards, or full pages. Pairs with the free ReUI MCP server for live, scored registry search and inline component APIs.
|
||||
user-invocable: false
|
||||
allowed-tools: Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *)
|
||||
---
|
||||
|
||||
> **ReUI skill version `42d70dcc3d`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
|
||||
> **ReUI skill version `668fb463eb`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
|
||||
|
||||
# ReUI for Agents
|
||||
|
||||
ReUI is a shadcn-compatible registry. It ships four things you **reuse** - never redesign:
|
||||
|
||||
- **components** - the 17 ReUI building blocks with real APIs: `data-grid`, `kanban`, `filters`, `date-selector`, `tree`, `stepper`, ... (free)
|
||||
- **components** - the 20 ReUI building blocks with real APIs: `data-grid`, `kanban`, `filters`, `date-selector`, `tree`, `stepper`, ... (free)
|
||||
- **examples** - free `c-*` single-pattern use-cases of a component (`c-kanban-1`); install one and read it to see exact composition
|
||||
- **blocks** - premium full-page sections that compose components (`data-grid-2`, `pricing-page-1`); Pro or Ultimate license at install
|
||||
- **icons** - Motion Icons in 4 styles, static + hover-animated variants; Ultimate license at install
|
||||
@@ -58,7 +58,7 @@ Invocation differs slightly per agent (`/mcp__reui__build` in Claude Code/Cursor
|
||||
|
||||
- [rules/registry.md](./rules/registry.md) - the four types, the @reui registry, base/radix, free vs premium + license
|
||||
- [rules/workflow.md](./rules/workflow.md) - the find -> install -> read-API -> adapt loop (most important)
|
||||
- [rules/components.md](./rules/components.md) - the 17 components, the data-grid contract, base vs radix
|
||||
- [rules/components.md](./rules/components.md) - the 20 components, the data-grid contract, base vs radix
|
||||
- [rules/adapting.md](./rules/adapting.md) - reuse-first: preserve the design (no over-customizing), reuse examples + a block's own elements, real data, don't invent APIs
|
||||
- [rules/craft.md](./rules/craft.md) - make it exceptional: point of view, hierarchy, density, states, responsive, motion, the bar
|
||||
- [rules/quality.md](./rules/quality.md) - security, accessibility, and scroll gates (the done gate)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Registry setup (one-time, per project)
|
||||
|
||||
Free items (the 17 components and all `c-*` examples) need only the plain string registry in `components.json`:
|
||||
Free items (the 20 components and all `c-*` examples) need only the plain string registry in `components.json`:
|
||||
|
||||
```json
|
||||
{ "registries": { "@reui": "https://reui.io/r/{style}/{name}.json" } }
|
||||
@@ -54,7 +54,7 @@ bunx --bun shadcn@latest add @reui/<name> --yes # bun
|
||||
|
||||
## Free vs premium boundary
|
||||
|
||||
- Public, no key: `c-*` examples and the 17 components (`@reui/data-grid`, `@reui/badge`, ...) that those examples depend on.
|
||||
- Public, no key: `c-*` examples and the 20 components (`@reui/data-grid`, `@reui/badge`, ...) that those examples depend on.
|
||||
- Key required at install: blocks (`@reui/<category>-N`) need a Pro or Ultimate license; Motion Icons (`@reui/icons/...`) and templates need Ultimate.
|
||||
|
||||
If an install 401/403s, the license key is missing, invalid, or the plan does not cover that resource (blocks: Pro or higher; icons and templates: Ultimate). Point the user to https://reui.io/account (their key) or https://reui.io/pricing (upgrade).
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
# ReUI components
|
||||
|
||||
The 19 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
|
||||
The 20 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `icon-tile`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
|
||||
|
||||
**Rule one: never guess a component's API. Read it first.** Call **`get_component(name)`** for its inline `api` (props + usage, no web fetch), and **share the result's `docsUrl`** (the component's API documentation page) with the user whenever you work with that component's API, so they have the full reference (the `/llms.txt` index is a further fallback). Then call **`get_examples(name)`** to install a worked example and copy real composition. The contracts below are first-try orientation (required props, composition shape, the one gotcha); the inline `api` is the full reference. No single block fits? Compose: search the components you need, read each `get_component`, install a `get_examples` example per component, and adapt.
|
||||
|
||||
## data-grid (the flagship - read its API every time)
|
||||
|
||||
`data-grid` wraps TanStack Table v8. It is NOT a styled `<table>` and does NOT take `data`/`columns` props directly. The contract:
|
||||
`data-grid` wraps TanStack Table v9. It is NOT a styled `<table>` and does NOT take `data`/`columns` props directly. The contract:
|
||||
|
||||
- Build a TanStack table instance with `useReactTable(...)` (columns, data, the feature models you need: sorting, pagination, row selection).
|
||||
- Build a TanStack table instance with `useTable({ features: dataGridFeatures, ... })` (columns, data). `dataGridFeatures` is exported by the primitive and already bundles sorting, filtering, pagination, row selection, expanding, pinning, resizing and faceting, so there are no per-table row models to wire.
|
||||
- Pass that instance to `<DataGrid table={table} recordCount={total}>`.
|
||||
- Compose the body with `DataGridTable` inside `DataGrid`, and enable features through `tableLayout` (e.g. `{ headerSticky: true, columnsResizable: true }`), not ad-hoc classes.
|
||||
- Server-side data uses the documented fetch shape (`recordCount` is the total for pagination).
|
||||
|
||||
```tsx
|
||||
const table = useReactTable({
|
||||
const table = useTable({
|
||||
features: dataGridFeatures,
|
||||
data,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
// add sorting/pagination/selection models per the API
|
||||
})
|
||||
|
||||
<DataGrid table={table} recordCount={data.length}>
|
||||
@@ -28,9 +27,9 @@ const table = useReactTable({
|
||||
|
||||
Common mistakes:
|
||||
|
||||
- **Incorrect:** `<DataGrid data={rows} columns={cols} />` - these props do not exist. **Correct:** build a `useReactTable` instance and pass `table={table}` + `recordCount`.
|
||||
- **Incorrect:** `<DataGrid data={rows} columns={cols} />` - these props do not exist. **Correct:** build a `useTable({ features: dataGridFeatures, ... })` instance and pass `table={table}` + `recordCount`.
|
||||
- **Incorrect:** a raw `<table>` / hand-rolled pagination. **Correct:** use `data-grid`; read its API for sticky header, pagination, virtualization, row selection.
|
||||
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the documented `ColumnMeta` (e.g. `cellClassName`, `headerTitle`).
|
||||
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the primitive's `DataGridColumnMeta` (e.g. `cellClassName`, `headerTitle`), set through the bundle's `columnMeta` slot.
|
||||
|
||||
## event-calendar
|
||||
|
||||
@@ -312,6 +311,19 @@ const [value, setValue] = useState<DateSelectorValue | undefined>()
|
||||
|
||||
**Gotcha:** isometric layered artwork for empty states and illustrations; style the inner icon via its own `className`. Mark purely decorative stacks `aria-hidden="true"` and keep the real label in surrounding copy.
|
||||
|
||||
## icon-tile
|
||||
|
||||
**Required:** one child icon
|
||||
**Shape:**
|
||||
|
||||
```tsx
|
||||
<IconTile variant="elevated" size="lg">
|
||||
<PackageIcon />
|
||||
</IconTile>
|
||||
```
|
||||
|
||||
**Gotcha:** the square container an icon sits in, so every list row, feature card and empty state shares one affordance. `variant`: `outline` (default) | `elevated` (muted fill, raised ring) | `soft` (tinted nested, tone from currentColor) | `solid` (filled tone, contrasting glyph) | `frame` (double container). `soft` and `solid` retint from one text color class (they default to `text-primary`). `size`: `xs | sm | default | lg | xl` (24/32/40/48/64px tile, glyph scales 12/14/16/20/24px). `radius`: `default | full`. Do not set a `size-*` class on the child icon unless you mean to override the tile's glyph size; recolor with `className` on the tile, not the icon.
|
||||
|
||||
## alert
|
||||
|
||||
**Required:** `Alert` > `AlertTitle`
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
ReUI is a shadcn-compatible registry with four entity types. **Examples and blocks are built FROM components** - reuse them, don't rebuild.
|
||||
|
||||
- **component** - one of the 17 ReUI building blocks with a real API (`data-grid`, `kanban`, `filters`, `date-selector`, `tree`, ...). Install directly (`@reui/data-grid`) or let it come in as a dependency of an example/block. Free. Read its API with `get_component(name)`.
|
||||
- **component** - one of the 20 ReUI building blocks with a real API (`data-grid`, `kanban`, `filters`, `date-selector`, `tree`, ...). Install directly (`@reui/data-grid`) or let it come in as a dependency of an example/block. Free. Read its API with `get_component(name)`.
|
||||
- **example** - a free `c-*` single-pattern use-case of a component (`c-kanban-1`, `c-data-grid-3`). Install one and read it to copy real composition. Find a component's examples with `get_examples(name)`.
|
||||
- **block** - a premium, full-page section that composes several components (`data-grid-2`, `pricing-page-1`). Pro or Ultimate license at install. Adapts to your active theme via semantic tokens.
|
||||
- **icon** - Motion Icons in 4 styles (outline, solid, duotone, filled), static (`@reui/icons/default/<style>/<name>`) and hover-animated (`@reui/icons/animated/<style>/<name>`). Ultimate license at install. See [icons.md](./icons.md).
|
||||
@@ -27,7 +27,7 @@ Blocks adapt to your active theme through semantic tokens and CSS variables - ch
|
||||
|
||||
## Free vs premium
|
||||
|
||||
- **Free, no key:** the 17 components, all `c-*` examples, the ReUI MCP, and this skill.
|
||||
- **Free, no key:** the 20 components, all `c-*` examples, the ReUI MCP, and this skill.
|
||||
- **Premium, license required at install:** blocks (Pro or Ultimate), Motion Icons and templates (Ultimate). Set `REUI_LICENSE_KEY` (see [cli.md](./cli.md)).
|
||||
|
||||
## Component API index
|
||||
|
||||
@@ -8,7 +8,7 @@ The core ReUI loop. The MCP tells you what to install and gives you the API; the
|
||||
|
||||
For everything else, call `search` with the user's intent. Pass structured hints whenever you can infer them - you are an LLM, so do the parsing the server cannot:
|
||||
|
||||
- `type`: `"component"` (one of the 17 building blocks), `"example"` (a c-\* use-case), `"block"` (a full page/section), `"icon"`.
|
||||
- `type`: `"component"` (one of the 20 building blocks), `"example"` (a c-\* use-case), `"block"` (a full page/section), `"icon"`.
|
||||
- `component`: the ReUI component the request implies (`"data-grid"`, `"kanban"`, ...).
|
||||
- `category`, `features` (e.g. `["sortable","pagination"]`), `free`.
|
||||
|
||||
@@ -40,7 +40,7 @@ Before writing code against any component an item uses:
|
||||
|
||||
Installing files is not the end, and redesigning them defeats the point. First note the project's **base** so you write the right API - read `components.json` -> `style` and take the segment before the first `-` (`base-nova` -> Base UI, `radix-nova` -> Radix UI), see [components.md](./components.md). After `add`:
|
||||
|
||||
1. **Read the added files**; keep the composition intact. For a block, verify the components are wired correctly (for `data-grid`: a `useReactTable` instance passed as `table`, `recordCount` set - see [components.md](./components.md)).
|
||||
1. **Read the added files**; keep the composition intact. For a block, verify the components are wired correctly (for `data-grid`: a `useTable({ features: dataGridFeatures, ... })` instance passed as `table`, `recordCount` set - see [components.md](./components.md)).
|
||||
2. **Replace demo data with the user's real data** via typed structures (see [adapting.md](./adapting.md)).
|
||||
3. **Fix icon imports** to the project's icon library (see [icons.md](./icons.md)).
|
||||
4. **Align styling** to semantic tokens and the active theme - no raw colors (see [styling.md](./styling.md)).
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
name: MM ReUI Dashboard
|
||||
overview: Wave D — /dashboard и /traffic: **hybrid KpiStatGrid** (EvoBGP DNA) + OpsDashboard + QuickActionGrid + Frame charts.
|
||||
todos:
|
||||
- id: dashboard-ops
|
||||
content: "Dashboard: StatCard → hybrid KpiStatGrid + OpsDashboard"
|
||||
status: pending
|
||||
- id: traffic-frame
|
||||
content: "Traffic: hybrid KpiStatGrid + Frame charts"
|
||||
status: pending
|
||||
- id: qa-grid
|
||||
content: QuickActionGrid (sibling hybrid DNA)
|
||||
status: pending
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# Wave D — Dashboard & overview
|
||||
|
||||
Родитель: [MM ReUI Master](mm_reui_master_b80dbef6.plan.md). Зависимости: **A** (hybrid kit), **B** (эталон).
|
||||
|
||||
## Цель
|
||||
|
||||
Убрать hand-roll `StatCard` (Card). KPI = **hybrid как в старых apps**.
|
||||
|
||||
## KPI (MUST)
|
||||
|
||||
- `/dashboard` и `/traffic`: только `KpiStatGrid` hybrid ([stats-12](https://reui.io/preview/base/stats-12))
|
||||
- Удалить локальный `StatCard` / Card metric grids
|
||||
- NEVER: SectionCards, sparkline-inside-Card как KPI shell (sparkline может быть *внутри* hybrid tile через kit API, не отдельный Card KPI)
|
||||
- Quick Actions: только `QuickActionGrid` (sibling hybrid), не Button/Card grid
|
||||
|
||||
## Routes
|
||||
|
||||
| Route | ~LOC | Работа |
|
||||
|-------|------|--------|
|
||||
| `/dashboard` | ~926 | `StatCard` → **hybrid** `KpiStatGrid`; `OpsDashboard`; Frame probes |
|
||||
| `/traffic` | ~1020 | **hybrid** KPI; Frame charts; semantic tokens |
|
||||
|
||||
## ReUI refs (MCP `surface: frame`)
|
||||
|
||||
- [dashboard-1](https://reui.io/preview/base/dashboard-1)
|
||||
- KPI: **только** [stats-12](https://reui.io/preview/base/stats-12) · QA [card-12](https://reui.io/preview/base/card-12) DNA via kit
|
||||
- Charts: [chart-15](https://reui.io/preview/base/chart-15) adapt (не KPI substitute)
|
||||
- Shell: [app-shell-12](https://reui.io/preview/base/app-shell-12)
|
||||
|
||||
## Ключевые файлы
|
||||
|
||||
- [`app/(main)/dashboard/page.tsx`](c:/Users/shats/Dev/MikrotikManager-3/app/(main)/dashboard/page.tsx)
|
||||
- [`components/dashboard/latency-chart.tsx`](c:/Users/shats/Dev/MikrotikManager-3/components/dashboard/latency-chart.tsx), `bandwidth-chart.tsx`, `internet-path-map.tsx`
|
||||
- [`components/data-grids/dashboard-active-probes-data-grid.tsx`](c:/Users/shats/Dev/MikrotikManager-3/components/data-grids/dashboard-active-probes-data-grid.tsx)
|
||||
- [`app/(main)/traffic/page.tsx`](c:/Users/shats/Dev/MikrotikManager-3/app/(main)/traffic/page.tsx)
|
||||
|
||||
## Порядок секций
|
||||
|
||||
**Hybrid KPI** → QuickActionGrid → charts / path map → attention + probes.
|
||||
`showQuickActions` default true.
|
||||
|
||||
## Инварианты
|
||||
|
||||
- Не менять API fetch
|
||||
- Path map — Frame wrap, не rewrite
|
||||
- Не смешивать Card KPI с Frame
|
||||
|
||||
## DoD
|
||||
|
||||
- [ ] Нет `StatCard`/Card KPI на `/dashboard` и `/traffic`
|
||||
- [ ] Только hybrid `KpiStatGrid` (EvoBGP DNA)
|
||||
- [ ] Charts/path в Frame panels
|
||||
- [ ] lint/build OK
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
name: MM ReUI Foundation
|
||||
overview: "Wave A — foundation: ui-design-contract, kpi-hybrid rule, порт KpiStatGrid (EvoBGP hybrid DNA 1:1), Card→Frame shell, chrome (240px, NavUser)."
|
||||
todos:
|
||||
- id: docs-contract
|
||||
content: ui-design-contract + reui-mcp/kpi-hybrid rules + AGENTS
|
||||
status: pending
|
||||
- id: port-kit
|
||||
content: "Порт reui-kit: KpiStatGrid hybrid DNA 1:1 с EvoBGP"
|
||||
status: pending
|
||||
- id: frame-bridge
|
||||
content: DataPageCard → Frame surface bridge
|
||||
status: pending
|
||||
- id: chrome-240-navuser
|
||||
content: Sidebar 240px + NavUser segmented theme
|
||||
status: pending
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# Wave A — Foundation (MikrotikManager ReUI)
|
||||
|
||||
Родитель: [MM ReUI Master](mm_reui_master_b80dbef6.plan.md). Источники: [Explore MikrotikManager UI](a9e538ec-d664-4bf5-a712-4978beefe057), [ReUI SoT from siblings](97b837f2-382e-4bf9-b0fc-84678deb882c).
|
||||
|
||||
## Цель
|
||||
|
||||
Подготовить инфраструктуру ReUI PRO **без** массовой миграции страниц. После Wave A любой экран переводится на Frame + **hybrid KPI** (`KpiStatGrid`) по шаблону старых apps.
|
||||
|
||||
## KPI hybrid (закладывается здесь)
|
||||
|
||||
- Порт `KpiStatGrid` **байт-в-байт DNA** с EvoBGP (horizontal compact: icon `size-10.5` `bg-muted` + label/Badge + value ± variant)
|
||||
- Preview: [stats-12](https://reui.io/preview/base/stats-12) · rule `kpi-hybrid.mdc` в MM
|
||||
- **NEVER** в kit: SectionCards, vertical-only stats, Card KPI wrappers
|
||||
- Волны B–G только **потребляют** этот kit — не рисуют свои KPI
|
||||
|
||||
## Scope
|
||||
|
||||
### 1. Документы и rules
|
||||
|
||||
- Создать [`docs/ui-design-contract.md`](c:/Users/shats/Dev/MikrotikManager-3/docs/ui-design-contract.md) — адапт семейного контракта под пути MM (`components/reui`, `components/reui-kit`, `@/components/ui`, Next App Router); секция KPI = hybrid only
|
||||
- Cursor rules: `reui-mcp.mdc`, **`kpi-hybrid.mdc`** (копия семейного MUST/NEVER); обновить [`next-shadcn-production.mdc`](c:/Users/shats/Dev/MikrotikManager-3/.cursor/rules/next-shadcn-production.mdc)
|
||||
- Секция ReUI + KPI hybrid в [`AGENTS.md`](c:/Users/shats/Dev/MikrotikManager-3/AGENTS.md)
|
||||
|
||||
### 2. Kit port (SoT = EvoBGP)
|
||||
|
||||
Создать `components/reui-kit/`:
|
||||
|
||||
| Component | Источник |
|
||||
|-----------|----------|
|
||||
| **`KpiStatGrid`** | EvoBGP `kpi-stat-grid.tsx` — **hybrid DNA 1:1**, импорты → `@/components/ui/*` |
|
||||
| `QuickActionGrid` | EvoBGP sibling hybrid DNA (не Card grid) |
|
||||
| `ResourcePage` | Frame + tabs + Filters + DataGrid |
|
||||
| `OpsDashboard` | **hybrid** KPI strip + afterKpi + charts slot |
|
||||
| `DetailPanel` | Frame sections (+ Metrics → KpiStatGrid) |
|
||||
| `SettingsShell` | Next nested layout / local nav (не TanStack Outlet) |
|
||||
| `filter-utils` | apply/clear Filters |
|
||||
|
||||
`"use client"` на всех kit-компонентах с хуками (`rsc: true` в MM).
|
||||
|
||||
### 3. Surface bridge
|
||||
|
||||
- [`DataPageCard`](c:/Users/shats/Dev/MikrotikManager-3/components/data-page-card.tsx): заменить внутренний `Card` на ReUI `Frame`/`FramePanel` **или** ввести `DataPageFrame` + deprecate Card-shell (совместимый API `children`/`className`, чтобы Wave B+ меняли минимум)
|
||||
- Сохранить [`DataGridShell`](c:/Users/shats/Dev/MikrotikManager-3/components/data-grids/shared/data-grid-shell.tsx) как есть
|
||||
|
||||
### 4. Chrome
|
||||
|
||||
- [`components/ui/sidebar.tsx`](c:/Users/shats/Dev/MikrotikManager-3/components/ui/sidebar.tsx): `SIDEBAR_WIDTH` `16rem` → **`240px`**
|
||||
- [`app-sidebar.tsx`](c:/Users/shats/Dev/MikrotikManager-3/components/app-sidebar.tsx): подключить [`NavUser`](c:/Users/shats/Dev/MikrotikManager-3/components/nav-user.tsx) с segmented theme (убрать demo Sparkles/Billing); убрать дублирующий theme toggle из footer если переезжает в NavUser
|
||||
- Search: оставить ⌘K (не Search pill в header)
|
||||
- **AppsMenu / auth-portal / SystemMonitor — вне scope** (см. master)
|
||||
|
||||
### 5. MCP / CLI hygiene
|
||||
|
||||
- `user-reui` `get_project_context` + `surface: frame` на будущих задачах
|
||||
- При add PRO blocks: `npx shadcn@latest add @reui/<name> --dry-run` перед overwrite существующих `components/reui/*`
|
||||
- Preview refs: [app-shell-12](https://reui.io/preview/base/app-shell-12), **[stats-12](https://reui.io/preview/base/stats-12)** (hybrid KPI)
|
||||
|
||||
## Out of scope
|
||||
|
||||
Миграция `app/(main)/*/page.tsx` (кроме smoke-проверки, что Frame-bridge не ломает layout).
|
||||
|
||||
## DoD
|
||||
|
||||
- [ ] `docs/ui-design-contract.md` + `kpi-hybrid.mdc` на месте
|
||||
- [ ] `KpiStatGrid` markup совпадает с EvoBGP (diff только imports)
|
||||
- [ ] `components/reui-kit/*` собирается, импорты `@/components/ui`
|
||||
- [ ] List shell = Frame (не Card)
|
||||
- [ ] Sidebar 240px + NavUser theme
|
||||
- [ ] `npm run lint` / `npm run build` без регрессий от foundation
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
name: MM ReUI Lists Medium
|
||||
overview: "Wave C — medium CRUD: Frame + **hybrid KpiStatGrid** (EvoBGP DNA) на communities/wg/vxlan/containers/gre/backups/certificates."
|
||||
todos:
|
||||
- id: c1-small-crud
|
||||
content: "communities/wg/vxlan/containers: hybrid KPI + Frame"
|
||||
status: pending
|
||||
- id: c2-tunnels-certs
|
||||
content: "gre/backups/certificates: hybrid KPI + Frame"
|
||||
status: pending
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# Wave C — Medium CRUD lists
|
||||
|
||||
Родитель: [MM ReUI Master](mm_reui_master_b80dbef6.plan.md). Зависимость: **Wave B** (эталон hybrid KPI).
|
||||
|
||||
## Цель
|
||||
|
||||
Тиражировать `/servers`: Frame shell + **hybrid KPI** на medium CRUD.
|
||||
|
||||
## KPI (MUST)
|
||||
|
||||
- Любой metric strip на этих routes → только `KpiStatGrid` hybrid ([stats-12](https://reui.io/preview/base/stats-12))
|
||||
- Замена существующих `Card` KPI grids — без исключений
|
||||
- NEVER: StatCard, SectionCards, vertical-only, raw emerald
|
||||
|
||||
## Routes (priority)
|
||||
|
||||
| Route | ~LOC | Паттерн |
|
||||
|-------|------|---------|
|
||||
| `/communities` | ~268 | Card KPI → **hybrid** `KpiStatGrid`; Frame + CommunitiesDataGrid |
|
||||
| `/wireguard` | ~256 | То же + peers detail |
|
||||
| `/vxlan` | ~250 | То же |
|
||||
| `/containers` | ~435 | Card list → DataGrid/Frame tiles; KPI → **hybrid** |
|
||||
| `/gre` | ~778 | Dual grids + **hybrid** KPI strip |
|
||||
| `/backups` | ~752 | **hybrid** KPI + DataGrid + Stepper |
|
||||
| `/certificates` | ~779 | **hybrid** KPI + DataGrid + Stepper |
|
||||
|
||||
Split PR: C1 / C2 при необходимости.
|
||||
|
||||
## Refs
|
||||
|
||||
- KPI: **только** [stats-12](https://reui.io/preview/base/stats-12) via kit
|
||||
- Lists: [data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2)
|
||||
- Stepper — reuse
|
||||
|
||||
## DoD
|
||||
|
||||
- [ ] Нет Card как ops shell
|
||||
- [ ] Все KPI-полосы — hybrid `KpiStatGrid` (как EvoBGP)
|
||||
- [ ] Визуально = `/servers`
|
||||
- [ ] lint/build OK
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
name: MM ReUI Lists Simple
|
||||
overview: Wave B — /servers и simple lists на Frame + **hybrid KpiStatGrid** (EvoBGP DNA) + ResourcePage.
|
||||
todos:
|
||||
- id: servers-etalon
|
||||
content: "/servers: Frame + hybrid KpiStatGrid (не Card KPI)"
|
||||
status: pending
|
||||
- id: simple-lists
|
||||
content: domains / asns / ip-ranges / releases
|
||||
status: pending
|
||||
- id: loading-skeleton
|
||||
content: loading.tsx skeleton под hybrid KPI + Frame
|
||||
status: pending
|
||||
- id: rules-etalon
|
||||
content: Закрепить Frame+/servers hybrid KPI как эталон
|
||||
status: pending
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# Wave B — Etalon + simple lists
|
||||
|
||||
Родитель: [MM ReUI Master](mm_reui_master_b80dbef6.plan.md). Зависимость: **Wave A** (hybrid `KpiStatGrid` в kit).
|
||||
|
||||
## Цель
|
||||
|
||||
Сделать `/servers` эталоном ReUI PRO: Frame shell + **hybrid KPI** как в EvoBGP/vps/CFDM.
|
||||
|
||||
## KPI (MUST)
|
||||
|
||||
- Метрики на `/servers` (всего / онлайн / JH+Exit / Home) → **только** `KpiStatGrid` hybrid
|
||||
- Preview: [stats-12](https://reui.io/preview/base/stats-12)
|
||||
- Удалить `grid … Card` KPI strip; **запрещены** StatCard / SectionCards / vertical stats
|
||||
- Name-cells в grid: hybrid icon tile (`bg-muted` + semantic text)
|
||||
|
||||
## Routes
|
||||
|
||||
| Route | ~LOC | Работа |
|
||||
|-------|------|--------|
|
||||
| `/servers` | ~724 | **Эталон:** **hybrid** `KpiStatGrid`; Frame; toolbar+Filters+`ServersDataGrid`; Sheet+Stepper без редизайна |
|
||||
| `/domains` | ~98 | Frame + DataGrid (+ empty); KPI — только если появятся метрики → hybrid |
|
||||
| `/asns` | ~98 | То же |
|
||||
| `/ip-ranges` | ~99 | То же |
|
||||
| `/releases` | ~97 | Frame/settings-lite; без KPI, если нет метрик |
|
||||
|
||||
## ReUI refs
|
||||
|
||||
- List: [data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2) · [data-grid-filtering-1](https://reui.io/preview/base/data-grid-filtering-1)
|
||||
- KPI: **только** [stats-12](https://reui.io/preview/base/stats-12) hybrid via kit
|
||||
- Empty: [empty-state-12](https://reui.io/preview/base/empty-state-12)
|
||||
- Forms sheet: [form-7](https://reui.io/preview/base/form-7)
|
||||
|
||||
MCP: `search`/`get_block`/`validate_usage` с `surface: "frame"`.
|
||||
|
||||
## Ключевые файлы
|
||||
|
||||
- [`app/(main)/servers/page.tsx`](c:/Users/shats/Dev/MikrotikManager-3/app/(main)/servers/page.tsx)
|
||||
- [`components/data-grids/servers-data-grid.tsx`](c:/Users/shats/Dev/MikrotikManager-3/components/data-grids/servers-data-grid.tsx)
|
||||
- [`app/(main)/loading.tsx`](c:/Users/shats/Dev/MikrotikManager-3/app/(main)/loading.tsx) — skeleton под Frame + hybrid KPI
|
||||
- [`lib/data-filters/server-filter-fields.ts`](c:/Users/shats/Dev/MikrotikManager-3/lib/data-filters/server-filter-fields.ts)
|
||||
|
||||
## Правила
|
||||
|
||||
- Не менять API CRUD / poll / test connection
|
||||
- После миграции: `ma-ui-guardian` / `next-shadcn-production` — эталон = Frame + hybrid KPI `/servers`
|
||||
|
||||
## DoD
|
||||
|
||||
- [ ] `/servers`: нет Card KPI; только hybrid `KpiStatGrid`
|
||||
- [ ] domains/asns/ip-ranges на Frame+DataGrid
|
||||
- [ ] loading skeleton согласован с hybrid strip
|
||||
- [ ] UI Guardian сверка с новым эталоном
|
||||
- [ ] lint/build OK
|
||||
@@ -0,0 +1,167 @@
|
||||
---
|
||||
name: MM ReUI Master
|
||||
overview: Мастер-план поэтапного перевода MikrotikManager-3 на ReUI PRO (surface Frame + kit), без смены Next.js/API. DataGrid уже на ReUI — фокус на Frame, hybrid KPI, shell chrome и волнах экранов через отдельные подпланы.
|
||||
todos:
|
||||
- id: wave-a
|
||||
content: "Подплан A: Foundation (contract, kit, Frame shell, chrome)"
|
||||
status: pending
|
||||
- id: wave-b
|
||||
content: "Подплан B: /servers эталон + simple lists"
|
||||
status: pending
|
||||
- id: wave-c
|
||||
content: "Подплан C: medium CRUD lists"
|
||||
status: pending
|
||||
- id: wave-d
|
||||
content: "Подплан D: dashboard + traffic"
|
||||
status: pending
|
||||
- id: wave-e
|
||||
content: "Подплан E: network ops giants"
|
||||
status: pending
|
||||
- id: wave-f
|
||||
content: "Подплан F: settings / alerts / system"
|
||||
status: pending
|
||||
- id: wave-g
|
||||
content: "Подплан G: map / terminal / uptime / optimizer"
|
||||
status: pending
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# MikrotikManager → ReUI PRO (мастер-план)
|
||||
|
||||
## Вердикт
|
||||
|
||||
Проект **уже на полпути**: `base-nova`, `@reui` registry, `REUI_LICENSE_KEY`, MCP/`reui` skill, ~33 domain DataGrid на ReUI. Главный разрыв с ops-contract (EvoBGP/vps/CFDM): **shell списков = shadcn Card** ([`DataPageCard`](c:/Users/shats/Dev/MikrotikManager-3/components/data-page-card.tsx)), **Frame не используется**, **нет `reui-kit`**, KPI — hand-roll Card. Стек остаётся **Next.js 16 App Router** (не Vite monorepo).
|
||||
|
||||
## Зафиксированные решения
|
||||
|
||||
| Решение | Выбор |
|
||||
|---------|--------|
|
||||
| Surface lock | `frame` (не Card) |
|
||||
| Runtime | Next.js 16 + `@/components/ui` + `@/components/reui` |
|
||||
| Kit SoT | Порт DNA из EvoBGP (`KpiStatGrid`, `QuickActionGrid`, `ResourcePage`, `OpsDashboard`, `SettingsShell`, `DetailPanel`) → `components/reui-kit/` |
|
||||
| **KPI (все волны)** | **Только hybrid** как в EvoBGP / vps / CFDM / EvoFirewall / auth-portal: `reui-kit/KpiStatGrid` (DNA [stats-12](https://reui.io/preview/base/stats-12)). Markup 1:1 с EvoBGP — менять только import path |
|
||||
| API / UX behavior | Без изменений контрактов ([`docs/refactor-baseline.md`](c:/Users/shats/Dev/MikrotikManager-3/docs/refactor-baseline.md)) |
|
||||
| App Switcher / auth-portal | **Вне scope** этой миграции (MM standalone); chrome только выравниваем под contract |
|
||||
| Эталон | `/servers` остаётся эталоном — после Wave A+B **обновляется** под Frame + **hybrid KPI** |
|
||||
|
||||
## Целевая архитектура UI
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph chrome [App Shell]
|
||||
Sidebar[AppSidebar NavUser theme]
|
||||
Header[PageHeader sticky]
|
||||
end
|
||||
subgraph kit [components/reui-kit]
|
||||
ResourcePage
|
||||
KpiStatGrid
|
||||
QuickActionGrid
|
||||
OpsDashboard
|
||||
SettingsShell
|
||||
DetailPanel
|
||||
end
|
||||
subgraph reui [components/reui]
|
||||
Frame
|
||||
DataGrid
|
||||
Filters
|
||||
Badge
|
||||
Stepper
|
||||
end
|
||||
subgraph pages [app main routes]
|
||||
RoutePages[page.tsx domain wiring]
|
||||
end
|
||||
chrome --> pages
|
||||
pages --> kit
|
||||
kit --> reui
|
||||
pages --> DataGrids[components/data-grids]
|
||||
DataGrids --> DataGrid
|
||||
```
|
||||
|
||||
**Замена surface:** `DataPageCard` (Card) → Frame-обёртка (например `DataPageFrame` / `ResourcePage`), без смешивания Card+Frame на ops-экране.
|
||||
|
||||
## KPI hybrid — жёсткий контракт (все подпланы A–G)
|
||||
|
||||
Как в старых ops-apps. SoT markup: EvoBGP `apps/web/src/components/reui-kit/kpi-stat-grid.tsx`. Preview: [stats-12](https://reui.io/preview/base/stats-12). Rule: `kpi-hybrid.mdc`.
|
||||
|
||||
**MUST**
|
||||
|
||||
- Любая KPI-полоса / metric strip → только `components/reui-kit/KpiStatGrid` (через `OpsDashboard` / `DetailPanel.Metrics` при наличии)
|
||||
- Horizontal compact hybrid: icon left `Item` `size-10.5` `bg-muted` + `border-background` + shadow + `ItemMedia` + label/Badge + value ± `variant`
|
||||
- Row icon tiles в data-grid — та же DNA (semantic `text-*` на `bg-muted`)
|
||||
- Quick Actions — только `QuickActionGrid` (sibling hybrid DNA), не Card/Button grid
|
||||
|
||||
**NEVER (ни в одной волне)**
|
||||
|
||||
- `StatCard` / SectionCards / vertical-only KPI / hand-roll Frame/Card KPI grid
|
||||
- `stats-7` / `stats-1` / `card-35` как замена hybrid KPI
|
||||
- Solid brand fill вместо `bg-muted`; raw `bg-emerald-*` / `text-emerald-*`
|
||||
- Копипаст ReUI block KPI в route — только adapt через kit
|
||||
|
||||
Мягкие формулировки «KPI если есть» = **если метрики на экране есть — только hybrid `KpiStatGrid`**, иначе блок не рисуем.
|
||||
|
||||
## Canonical ReUI refs (MCP `surface: frame`)
|
||||
|
||||
| Зона | Block / DNA | Preview |
|
||||
|------|-------------|---------|
|
||||
| Shell | `app-shell-12` (+ monitor/cmdk DNA) | https://reui.io/preview/base/app-shell-12 |
|
||||
| KPI | **hybrid only** stats-12 (EvoBGP SoT) | https://reui.io/preview/base/stats-12 |
|
||||
| Lists | `data-grid-filtering-2` / `data-grid-filtering-1` | https://reui.io/preview/base/data-grid-filtering-2 |
|
||||
| Dashboard | `dashboard-1` | https://reui.io/preview/base/dashboard-1 |
|
||||
| Settings | `settings-16` + `settings-3` | https://reui.io/preview/base/settings-16 |
|
||||
| Empty | `empty-state-12` / shadcn Empty | https://reui.io/preview/base/empty-state-12 |
|
||||
| Forms Sheet | `form-7` DNA | https://reui.io/preview/base/form-7 |
|
||||
|
||||
Docs: https://reui.io/llms.txt · https://reui.io/docs/get-started · https://reui.io/docs/styling · https://reui.io/docs/mcp
|
||||
|
||||
## Workflow на каждую волну (обязательный)
|
||||
|
||||
1. MCP `user-reui`: `search` / `compose_page` / `get_block` / `get_component` с `surface: "frame"`
|
||||
2. CLI из корня MM: `npx shadcn@latest add @reui/<name> --yes` (или `--dry-run` перед overwrite)
|
||||
3. Adapt → `reui-kit` / route; **не** копипаст block в `page.tsx`
|
||||
4. `validate_usage` + `get_audit_checklist`
|
||||
5. Gate: `npm run lint` + визуальная сверка с `/servers` (после его миграции) + `npm run build` на milestone
|
||||
|
||||
## Волны = отдельные подпланы
|
||||
|
||||
Не выполнять всё одним PR. Каждый подплан — свой scope, DoD и PR(ы).
|
||||
|
||||
| ID | Подплан | Scope (кратко) |
|
||||
|----|---------|----------------|
|
||||
| **A** | [Foundation](mm_reui_foundation_8b1c5482.plan.md) | Contract, **kpi-hybrid**, порт hybrid `KpiStatGrid`, Frame shell, chrome |
|
||||
| **B** | [Etalon + simple lists](mm_reui_lists_simple_d9c1b930.plan.md) | `/servers` эталон Frame + **hybrid KPI** + simple lists |
|
||||
| **C** | [CRUD lists medium](mm_reui_lists_medium_1a708596.plan.md) | Medium CRUD: Frame + **hybrid KPI** |
|
||||
| **D** | [Dashboard & overview](mm_reui_dashboard_b54ab10d.plan.md) | `/dashboard` `/traffic`: StatCard → **hybrid** |
|
||||
| **E** | [Network ops](mm_reui_network_ops_e8a979a4.plan.md) | Network giants: Frame + **hybrid KPI** |
|
||||
| **F** | [System](mm_reui_system_9c5741cb.plan.md) | Settings/alerts/…: Frame + **hybrid** где есть метрики |
|
||||
| **G** | [Special surfaces](mm_reui_special_04f7eebc.plan.md) | Map/terminal/uptime/optimizer: Frame + **hybrid KPI** |
|
||||
|
||||
Порядок: **A → B → C → D**, затем **E∥F** (параллельно разными PR), затем **G**.
|
||||
|
||||
## Инварианты
|
||||
|
||||
- Не менять API shape / бизнес-логику backend
|
||||
- Не ломать ReUI DataGrid shell без нужды — переиспользовать [`DataGridShell`](c:/Users/shats/Dev/MikrotikManager-3/components/data-grids/shared/data-grid-shell.tsx)
|
||||
- **KPI: только hybrid `KpiStatGrid` (EvoBGP DNA)** — см. секцию выше; действует на волны B–G
|
||||
- Запрет: Card как ops list shell; hand-roll / Card / SectionCards KPI; `space-y-*`; raw `bg-emerald-*`
|
||||
- Giant pages (>1500 LOC): сначала вынос секций в компоненты, потом Frame — не «big bang rewrite»
|
||||
|
||||
## Документы / rules (часть Wave A)
|
||||
|
||||
- Добавить [`docs/ui-design-contract.md`](c:/Users/shats/Dev/MikrotikManager-3/docs/ui-design-contract.md) (адапт EvoBGP contract под MM paths)
|
||||
- Cursor rules: `reui-mcp.mdc`, `kpi-hybrid.mdc`, обновить `next-shadcn-production.mdc` (эталон после Wave B)
|
||||
- `AGENTS.md` — секция ReUI + команды CLI
|
||||
|
||||
## Риски
|
||||
|
||||
- **PRO license** нужна для premium blocks; free components уже стоят
|
||||
- Overwrite shadcn CLI на существующие `components/reui/*` — всегда `--dry-run` / diff
|
||||
- Giant pages (`alerts` ~3k, `uptime` ~2.7k) — отдельный подплан, иначе регрессии
|
||||
- Theme: сейчас toggle в sidebar footer кастомный → NavUser segmented (contract)
|
||||
|
||||
## Definition of Done (весь продукт)
|
||||
|
||||
- Все ops-экраны на Frame surface; Card только где нужен interactive container внутри, не как page shell
|
||||
- Все KPI-полосы — **hybrid** `KpiStatGrid` (идентично EvoBGP/vps/CFDM/FW); lists через Frame + DataGrid (+ Filters где есть)
|
||||
- `/servers` = актуальный эталон под ReUI PRO
|
||||
- Rules + `ui-design-contract.md` в репо
|
||||
- Lint/build зелёные на milestone после каждой волны
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
name: MM ReUI Network Ops
|
||||
overview: "Wave E — network ops: Frame + **hybrid KpiStatGrid** на filters/firewall/bgp/ospf/recursive (+ хвост C)."
|
||||
todos:
|
||||
- id: e1-bgp-rr
|
||||
content: "E1: recursive-routes + bgp Frame + hybrid KPI"
|
||||
status: pending
|
||||
- id: e2-filters
|
||||
content: "E2: filters extract + Frame + hybrid KPI if any"
|
||||
status: pending
|
||||
- id: e3-firewall
|
||||
content: "E3: firewall Frame + hybrid KPI if any"
|
||||
status: pending
|
||||
- id: e4-ospf
|
||||
content: "E4: ospf hybrid KPI + Frame (+ leftover C)"
|
||||
status: pending
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# Wave E — Network ops
|
||||
|
||||
Родитель: [MM ReUI Master](mm_reui_master_b80dbef6.plan.md). Зависимости: **A+B**; пересечение с **C** без дубля.
|
||||
|
||||
## Цель
|
||||
|
||||
Giant network pages → Frame + kit; метрики только **hybrid KPI**.
|
||||
|
||||
## KPI (MUST)
|
||||
|
||||
- Любые analytics/summary Cards (`/bgp`, `/ospf`, `/firewall`, …) → **hybrid** `KpiStatGrid`
|
||||
- Preview: [stats-12](https://reui.io/preview/base/stats-12)
|
||||
- Если метрик на экране нет — KPI-блок не рисуем; если есть — только hybrid
|
||||
- NEVER: Card KPI grid, SectionCards, stats-7 vertical
|
||||
|
||||
## Routes
|
||||
|
||||
| Route | ~LOC | Стратегия |
|
||||
|-------|------|-----------|
|
||||
| `/filters` | ~1790 | Frame layout; Sheets logic intact; KPI→hybrid если есть |
|
||||
| `/firewall` | ~1725 | Frame panels; rules DataGrid; summary → hybrid |
|
||||
| `/recursive-routes` | ~661 | Frame + DataGrid; KPI→hybrid если есть |
|
||||
| `/bgp` | ~720 | analytics Cards → **hybrid** `KpiStatGrid`; sessions grid |
|
||||
| `/ospf` | ~1270 | Frame tabs + grids; summary → **hybrid** |
|
||||
| `/gre` `/backups` `/certificates` | — | Только если не закрыты C (там тоже hybrid) |
|
||||
|
||||
## Подход
|
||||
|
||||
1. Extract секций
|
||||
2. Card shells → Frame
|
||||
3. KPI → **hybrid** `KpiStatGrid`
|
||||
4. `validate_usage`
|
||||
|
||||
## ReUI refs
|
||||
|
||||
- Lists: [data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2)
|
||||
- KPI: **только** [stats-12](https://reui.io/preview/base/stats-12)
|
||||
- Frame/DetailPanel docs
|
||||
|
||||
## PR split
|
||||
|
||||
E1 recursive+bgp · E2 filters · E3 firewall · E4 ospf (+ leftover)
|
||||
|
||||
## DoD
|
||||
|
||||
- [ ] Нет Card page shell
|
||||
- [ ] Все metric strips — hybrid `KpiStatGrid`
|
||||
- [ ] API/CRUD без регрессий
|
||||
- [ ] lint/build per PR
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
name: MM ReUI Special
|
||||
overview: "Wave G — special surfaces: Frame chrome; KPI на uptime/optimizer только **hybrid KpiStatGrid** (EvoBGP DNA)."
|
||||
todos:
|
||||
- id: g1-term-opt
|
||||
content: "G1: terminal Frame; optimizer Frame + hybrid KPI"
|
||||
status: pending
|
||||
- id: g2-uptime
|
||||
content: "G2: uptime extract + Frame + hybrid KpiStatGrid"
|
||||
status: pending
|
||||
- id: g3-map
|
||||
content: "G3: network-map Frame chrome (KPI hybrid if any)"
|
||||
status: pending
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# Wave G — Special surfaces
|
||||
|
||||
Родитель: [MM ReUI Master](mm_reui_master_b80dbef6.plan.md). Зависимости: **A+B**.
|
||||
|
||||
## Цель
|
||||
|
||||
Кастом map/CLI без форса DataGrid. Metric strips — **только hybrid KPI** как в старых apps.
|
||||
|
||||
## KPI (MUST)
|
||||
|
||||
- `/uptime`, `/route-optimizer` (и map, если есть summary): Card/Stat KPI → **hybrid** `KpiStatGrid`
|
||||
- Preview: [stats-12](https://reui.io/preview/base/stats-12)
|
||||
- `/terminal`: обычно без KPI-полосы
|
||||
- NEVER: StatCard, SectionCards, vertical-only
|
||||
|
||||
## Routes
|
||||
|
||||
| Route | ~LOC | Стратегия |
|
||||
|-------|------|-----------|
|
||||
| `/network-map` | ~2254 | Frame side panels; canvas без redesign; KPI→hybrid если есть |
|
||||
| `/terminal` | ~552 | Frame CLI; без KPI |
|
||||
| `/uptime` | ~2669 | Extract; **hybrid** `KpiStatGrid`; grids → Frame |
|
||||
| `/route-optimizer` | ~1034 | Frame tabs; Card KPI → **hybrid** |
|
||||
|
||||
## ReUI refs
|
||||
|
||||
- KPI: **только** [stats-12](https://reui.io/preview/base/stats-12)
|
||||
- [dashboard-1](https://reui.io/preview/base/dashboard-1) для uptime overview layout
|
||||
- Lists: [data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2)
|
||||
|
||||
## PR split
|
||||
|
||||
G1 terminal+optimizer · G2 uptime · G3 network-map
|
||||
|
||||
## Инварианты
|
||||
|
||||
- Не менять map/terminal protocols
|
||||
- Card только как interactive widget, не page shell / не KPI
|
||||
|
||||
## DoD
|
||||
|
||||
- [ ] Нет Card page shell
|
||||
- [ ] uptime/optimizer KPI = hybrid `KpiStatGrid`
|
||||
- [ ] Map/terminal smoke OK
|
||||
- [ ] Final lint/build + contract checklist
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
name: MM ReUI System
|
||||
overview: "Wave F — settings/alerts/data-collection/probes: Frame + SettingsShell; metric strips только **hybrid KpiStatGrid**."
|
||||
todos:
|
||||
- id: f-settings
|
||||
content: settings → SettingsShell + Frame (hybrid KPI if metrics)
|
||||
status: pending
|
||||
- id: f-alerts
|
||||
content: "alerts: extract + Frame; hybrid KPI if metrics"
|
||||
status: pending
|
||||
- id: f-collect-probes
|
||||
content: "data-collection/probes: Frame + hybrid KPI strips"
|
||||
status: pending
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# Wave F — System
|
||||
|
||||
Родитель: [MM ReUI Master](mm_reui_master_b80dbef6.plan.md). Зависимости: **A**; параллельно с **E**.
|
||||
|
||||
## Цель
|
||||
|
||||
System screens на Frame/SettingsShell; любые summary metrics → **hybrid KPI** как в старых apps.
|
||||
|
||||
## KPI (MUST)
|
||||
|
||||
- `/data-collection`, `/probes`, `/alerts` (если есть counters/summary) → только `KpiStatGrid` hybrid
|
||||
- Preview: [stats-12](https://reui.io/preview/base/stats-12)
|
||||
- Settings: обычно rows без KPI-полосы; если появятся — hybrid only
|
||||
- NEVER: Card KPI, SectionCards
|
||||
|
||||
## Routes
|
||||
|
||||
| Route | ~LOC | Паттерн |
|
||||
|-------|------|---------|
|
||||
| `/settings` | ~1586 | SettingsShell + Frame rows; DataGrids в Frame |
|
||||
| `/alerts` | ~2989 | Extract → Frame; summary → **hybrid** если есть |
|
||||
| `/data-collection` | ~1250 | Frame grids; summary Cards → **hybrid** `KpiStatGrid` |
|
||||
| `/probes` | ~1085 | Frame; schedule/speed grids; KPI → **hybrid** |
|
||||
|
||||
## Alerts strategy
|
||||
|
||||
F1 extract · F2 Frame + Badge/Alert · F3 DataGrid; KPI hybrid на F2 если есть метрики.
|
||||
|
||||
## ReUI refs
|
||||
|
||||
- Settings: [settings-16](https://reui.io/preview/base/settings-16) · [settings-3](https://reui.io/preview/base/settings-3)
|
||||
- KPI: **только** [stats-12](https://reui.io/preview/base/stats-12)
|
||||
- Alert: https://reui.io/docs/components/base/alert
|
||||
- Lists: [data-grid-filtering-2](https://reui.io/preview/base/data-grid-filtering-2)
|
||||
|
||||
## Ключевые файлы
|
||||
|
||||
- [`app/(main)/settings/page.tsx`](c:/Users/shats/Dev/MikrotikManager-3/app/(main)/settings/page.tsx)
|
||||
- [`app/(main)/alerts/page.tsx`](c:/Users/shats/Dev/MikrotikManager-3/app/(main)/alerts/page.tsx)
|
||||
- [`app/(main)/data-collection/page.tsx`](c:/Users/shats/Dev/MikrotikManager-3/app/(main)/data-collection/page.tsx)
|
||||
- [`app/(main)/probes/page.tsx`](c:/Users/shats/Dev/MikrotikManager-3/app/(main)/probes/page.tsx)
|
||||
|
||||
## DoD
|
||||
|
||||
- [ ] Settings на SettingsShell/Frame
|
||||
- [ ] Alerts extract + Frame; API engine без изменений
|
||||
- [ ] data-collection/probes: Frame + **hybrid** KPI где были Card metrics
|
||||
- [ ] lint/build per sub-PR
|
||||
@@ -11,10 +11,14 @@ alwaysApply: true
|
||||
|
||||
| Документ | URL |
|
||||
|----------|-----|
|
||||
| **Introduction** | https://reui.io/docs |
|
||||
| **llms.txt** | https://reui.io/llms.txt |
|
||||
| **Get Started** | https://reui.io/docs/get-started |
|
||||
| **Styling** | https://reui.io/docs/styling |
|
||||
| **Registry** | https://reui.io/docs/registry |
|
||||
| **MCP** | https://reui.io/docs/mcp |
|
||||
| **Agent Skills** | https://reui.io/docs/agent-skills |
|
||||
| **Cursor MCP** | https://reui.io/docs/cursor |
|
||||
| **Blocks** | https://reui.io/blocks |
|
||||
| **Settings blocks** | https://reui.io/blocks/application/settings |
|
||||
| **License** | https://reui.io/docs/license-setup |
|
||||
@@ -27,6 +31,10 @@ alwaysApply: true
|
||||
|
||||
**Обязательно** цитировать `previewUrl` + `docsUrl` для каждой UI-зоны.
|
||||
|
||||
**Registry (актуально):** 20 free components — `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `icon-tile`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree` ([docs](https://reui.io/docs), [MCP](https://reui.io/docs/mcp)). Skill: `.claude/skills/reui` (v `668fb463eb`); обновление: `curl.exe -fsSL https://mcp.reui.io/install | node -` из корня проекта.
|
||||
|
||||
**Важно:** skill описывает текущий registry (в т.ч. data-grid на TanStack Table v9). Установленный в проекте `@reui/data-grid` может оставаться на v8 до явного CLI upgrade — не ломать kit без миграции.
|
||||
|
||||
## Когда ReUI vs shadcn
|
||||
|
||||
| Задача | Registry | Импорт |
|
||||
@@ -39,7 +47,8 @@ alwaysApply: true
|
||||
| KPI | block [stats-12](https://reui.io/preview/base/stats-12) | `reui-kit/KpiStatGrid` — см. [`kpi-hybrid.mdc`](kpi-hybrid.mdc) |
|
||||
| Quick Actions | Frame tiles sibling KPI | `reui-kit/QuickActionGrid` |
|
||||
| Semantic badge / alert | `@reui` | `@/components/reui/badge`, `@/components/reui/alert` |
|
||||
| Number / date / autocomplete / color / kanban | `@reui` | `@/components/reui/*` |
|
||||
| Number / date / autocomplete / color / kanban / timeline / stepper / tree | `@reui` | `@/components/reui/*` |
|
||||
| Event Calendar / Gantt / Icon Tile (registry, 20 free) | `@reui` | CLI `@reui/<name>` → `@/components/reui/*` при установке |
|
||||
|
||||
**Сложные списки** — `ResourcePage` (с Filters) или `FrameDataGrid` (простой CRUD Frame+DataGrid); не raw `<table>`, не Card shell.
|
||||
**Quick Actions** — только `QuickActionGrid` (не Card / Button grid).
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
---
|
||||
name: reui
|
||||
description: Use the ReUI registry from your AI agent - find, install, and correctly use ReUI components (the 17 free building blocks like data-grid, kanban, filters), their free examples, premium blocks, and Motion Icons. Applies in any project using ReUI, the @reui registry, REUI_LICENSE_KEY, or any shadcn project where the user asks for premium blocks, data grids, kanban boards, dashboards, or full pages. Pairs with the free ReUI MCP server for live, scored registry search and inline component APIs.
|
||||
description: Use the ReUI registry from your AI agent - find, install, and correctly use ReUI components (the 20 free building blocks like data-grid, kanban, filters), their free examples, premium blocks, and Motion Icons. Applies in any project using ReUI, the @reui registry, REUI_LICENSE_KEY, or any shadcn project where the user asks for premium blocks, data grids, kanban boards, dashboards, or full pages. Pairs with the free ReUI MCP server for live, scored registry search and inline component APIs.
|
||||
user-invocable: false
|
||||
allowed-tools: Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *)
|
||||
---
|
||||
|
||||
> **ReUI skill version `42d70dcc3d`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
|
||||
> **ReUI skill version `668fb463eb`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
|
||||
|
||||
# ReUI for Agents
|
||||
|
||||
ReUI is a shadcn-compatible registry. It ships four things you **reuse** - never redesign:
|
||||
|
||||
- **components** - the 17 ReUI building blocks with real APIs: `data-grid`, `kanban`, `filters`, `date-selector`, `tree`, `stepper`, ... (free)
|
||||
- **components** - the 20 ReUI building blocks with real APIs: `data-grid`, `kanban`, `filters`, `date-selector`, `tree`, `stepper`, ... (free)
|
||||
- **examples** - free `c-*` single-pattern use-cases of a component (`c-kanban-1`); install one and read it to see exact composition
|
||||
- **blocks** - premium full-page sections that compose components (`data-grid-2`, `pricing-page-1`); Pro or Ultimate license at install
|
||||
- **icons** - Motion Icons in 4 styles, static + hover-animated variants; Ultimate license at install
|
||||
@@ -58,7 +58,7 @@ Invocation differs slightly per agent (`/mcp__reui__build` in Claude Code/Cursor
|
||||
|
||||
- [rules/registry.md](./rules/registry.md) - the four types, the @reui registry, base/radix, free vs premium + license
|
||||
- [rules/workflow.md](./rules/workflow.md) - the find -> install -> read-API -> adapt loop (most important)
|
||||
- [rules/components.md](./rules/components.md) - the 17 components, the data-grid contract, base vs radix
|
||||
- [rules/components.md](./rules/components.md) - the 20 components, the data-grid contract, base vs radix
|
||||
- [rules/adapting.md](./rules/adapting.md) - reuse-first: preserve the design (no over-customizing), reuse examples + a block's own elements, real data, don't invent APIs
|
||||
- [rules/craft.md](./rules/craft.md) - make it exceptional: point of view, hierarchy, density, states, responsive, motion, the bar
|
||||
- [rules/quality.md](./rules/quality.md) - security, accessibility, and scroll gates (the done gate)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Registry setup (one-time, per project)
|
||||
|
||||
Free items (the 17 components and all `c-*` examples) need only the plain string registry in `components.json`:
|
||||
Free items (the 20 components and all `c-*` examples) need only the plain string registry in `components.json`:
|
||||
|
||||
```json
|
||||
{ "registries": { "@reui": "https://reui.io/r/{style}/{name}.json" } }
|
||||
@@ -54,7 +54,7 @@ bunx --bun shadcn@latest add @reui/<name> --yes # bun
|
||||
|
||||
## Free vs premium boundary
|
||||
|
||||
- Public, no key: `c-*` examples and the 17 components (`@reui/data-grid`, `@reui/badge`, ...) that those examples depend on.
|
||||
- Public, no key: `c-*` examples and the 20 components (`@reui/data-grid`, `@reui/badge`, ...) that those examples depend on.
|
||||
- Key required at install: blocks (`@reui/<category>-N`) need a Pro or Ultimate license; Motion Icons (`@reui/icons/...`) and templates need Ultimate.
|
||||
|
||||
If an install 401/403s, the license key is missing, invalid, or the plan does not cover that resource (blocks: Pro or higher; icons and templates: Ultimate). Point the user to https://reui.io/account (their key) or https://reui.io/pricing (upgrade).
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
# ReUI components
|
||||
|
||||
The 19 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
|
||||
The 20 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `icon-tile`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
|
||||
|
||||
**Rule one: never guess a component's API. Read it first.** Call **`get_component(name)`** for its inline `api` (props + usage, no web fetch), and **share the result's `docsUrl`** (the component's API documentation page) with the user whenever you work with that component's API, so they have the full reference (the `/llms.txt` index is a further fallback). Then call **`get_examples(name)`** to install a worked example and copy real composition. The contracts below are first-try orientation (required props, composition shape, the one gotcha); the inline `api` is the full reference. No single block fits? Compose: search the components you need, read each `get_component`, install a `get_examples` example per component, and adapt.
|
||||
|
||||
## data-grid (the flagship - read its API every time)
|
||||
|
||||
`data-grid` wraps TanStack Table v8. It is NOT a styled `<table>` and does NOT take `data`/`columns` props directly. The contract:
|
||||
`data-grid` wraps TanStack Table v9. It is NOT a styled `<table>` and does NOT take `data`/`columns` props directly. The contract:
|
||||
|
||||
- Build a TanStack table instance with `useReactTable(...)` (columns, data, the feature models you need: sorting, pagination, row selection).
|
||||
- Build a TanStack table instance with `useTable({ features: dataGridFeatures, ... })` (columns, data). `dataGridFeatures` is exported by the primitive and already bundles sorting, filtering, pagination, row selection, expanding, pinning, resizing and faceting, so there are no per-table row models to wire.
|
||||
- Pass that instance to `<DataGrid table={table} recordCount={total}>`.
|
||||
- Compose the body with `DataGridTable` inside `DataGrid`, and enable features through `tableLayout` (e.g. `{ headerSticky: true, columnsResizable: true }`), not ad-hoc classes.
|
||||
- Server-side data uses the documented fetch shape (`recordCount` is the total for pagination).
|
||||
|
||||
```tsx
|
||||
const table = useReactTable({
|
||||
const table = useTable({
|
||||
features: dataGridFeatures,
|
||||
data,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
// add sorting/pagination/selection models per the API
|
||||
})
|
||||
|
||||
<DataGrid table={table} recordCount={data.length}>
|
||||
@@ -28,9 +27,9 @@ const table = useReactTable({
|
||||
|
||||
Common mistakes:
|
||||
|
||||
- **Incorrect:** `<DataGrid data={rows} columns={cols} />` - these props do not exist. **Correct:** build a `useReactTable` instance and pass `table={table}` + `recordCount`.
|
||||
- **Incorrect:** `<DataGrid data={rows} columns={cols} />` - these props do not exist. **Correct:** build a `useTable({ features: dataGridFeatures, ... })` instance and pass `table={table}` + `recordCount`.
|
||||
- **Incorrect:** a raw `<table>` / hand-rolled pagination. **Correct:** use `data-grid`; read its API for sticky header, pagination, virtualization, row selection.
|
||||
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the documented `ColumnMeta` (e.g. `cellClassName`, `headerTitle`).
|
||||
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the primitive's `DataGridColumnMeta` (e.g. `cellClassName`, `headerTitle`), set through the bundle's `columnMeta` slot.
|
||||
|
||||
## event-calendar
|
||||
|
||||
@@ -312,6 +311,19 @@ const [value, setValue] = useState<DateSelectorValue | undefined>()
|
||||
|
||||
**Gotcha:** isometric layered artwork for empty states and illustrations; style the inner icon via its own `className`. Mark purely decorative stacks `aria-hidden="true"` and keep the real label in surrounding copy.
|
||||
|
||||
## icon-tile
|
||||
|
||||
**Required:** one child icon
|
||||
**Shape:**
|
||||
|
||||
```tsx
|
||||
<IconTile variant="elevated" size="lg">
|
||||
<PackageIcon />
|
||||
</IconTile>
|
||||
```
|
||||
|
||||
**Gotcha:** the square container an icon sits in, so every list row, feature card and empty state shares one affordance. `variant`: `outline` (default) | `elevated` (muted fill, raised ring) | `soft` (tinted nested, tone from currentColor) | `solid` (filled tone, contrasting glyph) | `frame` (double container). `soft` and `solid` retint from one text color class (they default to `text-primary`). `size`: `xs | sm | default | lg | xl` (24/32/40/48/64px tile, glyph scales 12/14/16/20/24px). `radius`: `default | full`. Do not set a `size-*` class on the child icon unless you mean to override the tile's glyph size; recolor with `className` on the tile, not the icon.
|
||||
|
||||
## alert
|
||||
|
||||
**Required:** `Alert` > `AlertTitle`
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
ReUI is a shadcn-compatible registry with four entity types. **Examples and blocks are built FROM components** - reuse them, don't rebuild.
|
||||
|
||||
- **component** - one of the 17 ReUI building blocks with a real API (`data-grid`, `kanban`, `filters`, `date-selector`, `tree`, ...). Install directly (`@reui/data-grid`) or let it come in as a dependency of an example/block. Free. Read its API with `get_component(name)`.
|
||||
- **component** - one of the 20 ReUI building blocks with a real API (`data-grid`, `kanban`, `filters`, `date-selector`, `tree`, ...). Install directly (`@reui/data-grid`) or let it come in as a dependency of an example/block. Free. Read its API with `get_component(name)`.
|
||||
- **example** - a free `c-*` single-pattern use-case of a component (`c-kanban-1`, `c-data-grid-3`). Install one and read it to copy real composition. Find a component's examples with `get_examples(name)`.
|
||||
- **block** - a premium, full-page section that composes several components (`data-grid-2`, `pricing-page-1`). Pro or Ultimate license at install. Adapts to your active theme via semantic tokens.
|
||||
- **icon** - Motion Icons in 4 styles (outline, solid, duotone, filled), static (`@reui/icons/default/<style>/<name>`) and hover-animated (`@reui/icons/animated/<style>/<name>`). Ultimate license at install. See [icons.md](./icons.md).
|
||||
@@ -27,7 +27,7 @@ Blocks adapt to your active theme through semantic tokens and CSS variables - ch
|
||||
|
||||
## Free vs premium
|
||||
|
||||
- **Free, no key:** the 17 components, all `c-*` examples, the ReUI MCP, and this skill.
|
||||
- **Free, no key:** the 20 components, all `c-*` examples, the ReUI MCP, and this skill.
|
||||
- **Premium, license required at install:** blocks (Pro or Ultimate), Motion Icons and templates (Ultimate). Set `REUI_LICENSE_KEY` (see [cli.md](./cli.md)).
|
||||
|
||||
## Component API index
|
||||
|
||||
@@ -8,7 +8,7 @@ The core ReUI loop. The MCP tells you what to install and gives you the API; the
|
||||
|
||||
For everything else, call `search` with the user's intent. Pass structured hints whenever you can infer them - you are an LLM, so do the parsing the server cannot:
|
||||
|
||||
- `type`: `"component"` (one of the 17 building blocks), `"example"` (a c-\* use-case), `"block"` (a full page/section), `"icon"`.
|
||||
- `type`: `"component"` (one of the 20 building blocks), `"example"` (a c-\* use-case), `"block"` (a full page/section), `"icon"`.
|
||||
- `component`: the ReUI component the request implies (`"data-grid"`, `"kanban"`, ...).
|
||||
- `category`, `features` (e.g. `["sortable","pagination"]`), `free`.
|
||||
|
||||
@@ -40,7 +40,7 @@ Before writing code against any component an item uses:
|
||||
|
||||
Installing files is not the end, and redesigning them defeats the point. First note the project's **base** so you write the right API - read `components.json` -> `style` and take the segment before the first `-` (`base-nova` -> Base UI, `radix-nova` -> Radix UI), see [components.md](./components.md). After `add`:
|
||||
|
||||
1. **Read the added files**; keep the composition intact. For a block, verify the components are wired correctly (for `data-grid`: a `useReactTable` instance passed as `table`, `recordCount` set - see [components.md](./components.md)).
|
||||
1. **Read the added files**; keep the composition intact. For a block, verify the components are wired correctly (for `data-grid`: a `useTable({ features: dataGridFeatures, ... })` instance passed as `table`, `recordCount` set - see [components.md](./components.md)).
|
||||
2. **Replace demo data with the user's real data** via typed structures (see [adapting.md](./adapting.md)).
|
||||
3. **Fix icon imports** to the project's icon library (see [icons.md](./icons.md)).
|
||||
4. **Align styling** to semantic tokens and the active theme - no raw colors (see [styling.md](./styling.md)).
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
---
|
||||
name: reui
|
||||
description: Use the ReUI registry from your AI agent - find, install, and correctly use ReUI components (the 17 free building blocks like data-grid, kanban, filters), their free examples, premium blocks, and Motion Icons. Applies in any project using ReUI, the @reui registry, REUI_LICENSE_KEY, or any shadcn project where the user asks for premium blocks, data grids, kanban boards, dashboards, or full pages. Pairs with the free ReUI MCP server for live, scored registry search and inline component APIs.
|
||||
description: Use the ReUI registry from your AI agent - find, install, and correctly use ReUI components (the 20 free building blocks like data-grid, kanban, filters), their free examples, premium blocks, and Motion Icons. Applies in any project using ReUI, the @reui registry, REUI_LICENSE_KEY, or any shadcn project where the user asks for premium blocks, data grids, kanban boards, dashboards, or full pages. Pairs with the free ReUI MCP server for live, scored registry search and inline component APIs.
|
||||
user-invocable: false
|
||||
allowed-tools: Bash(npx shadcn@latest *), Bash(pnpm dlx shadcn@latest *), Bash(bunx --bun shadcn@latest *)
|
||||
---
|
||||
|
||||
> **ReUI skill version `42d70dcc3d`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
|
||||
> **ReUI skill version `668fb463eb`.** If the ReUI MCP's `get_agent_skill` reports a newer `version`, re-run the ReUI installer (see `get_agent_skill` -> `install.recommended`) to update this skill. Cloud/tools-only agents have no local file and always read the latest - they can ignore this.
|
||||
|
||||
# ReUI for Agents
|
||||
|
||||
ReUI is a shadcn-compatible registry. It ships four things you **reuse** - never redesign:
|
||||
|
||||
- **components** - the 17 ReUI building blocks with real APIs: `data-grid`, `kanban`, `filters`, `date-selector`, `tree`, `stepper`, ... (free)
|
||||
- **components** - the 20 ReUI building blocks with real APIs: `data-grid`, `kanban`, `filters`, `date-selector`, `tree`, `stepper`, ... (free)
|
||||
- **examples** - free `c-*` single-pattern use-cases of a component (`c-kanban-1`); install one and read it to see exact composition
|
||||
- **blocks** - premium full-page sections that compose components (`data-grid-2`, `pricing-page-1`); Pro or Ultimate license at install
|
||||
- **icons** - Motion Icons in 4 styles, static + hover-animated variants; Ultimate license at install
|
||||
@@ -58,7 +58,7 @@ Invocation differs slightly per agent (`/mcp__reui__build` in Claude Code/Cursor
|
||||
|
||||
- [rules/registry.md](./rules/registry.md) - the four types, the @reui registry, base/radix, free vs premium + license
|
||||
- [rules/workflow.md](./rules/workflow.md) - the find -> install -> read-API -> adapt loop (most important)
|
||||
- [rules/components.md](./rules/components.md) - the 17 components, the data-grid contract, base vs radix
|
||||
- [rules/components.md](./rules/components.md) - the 20 components, the data-grid contract, base vs radix
|
||||
- [rules/adapting.md](./rules/adapting.md) - reuse-first: preserve the design (no over-customizing), reuse examples + a block's own elements, real data, don't invent APIs
|
||||
- [rules/craft.md](./rules/craft.md) - make it exceptional: point of view, hierarchy, density, states, responsive, motion, the bar
|
||||
- [rules/quality.md](./rules/quality.md) - security, accessibility, and scroll gates (the done gate)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Registry setup (one-time, per project)
|
||||
|
||||
Free items (the 17 components and all `c-*` examples) need only the plain string registry in `components.json`:
|
||||
Free items (the 20 components and all `c-*` examples) need only the plain string registry in `components.json`:
|
||||
|
||||
```json
|
||||
{ "registries": { "@reui": "https://reui.io/r/{style}/{name}.json" } }
|
||||
@@ -54,7 +54,7 @@ bunx --bun shadcn@latest add @reui/<name> --yes # bun
|
||||
|
||||
## Free vs premium boundary
|
||||
|
||||
- Public, no key: `c-*` examples and the 17 components (`@reui/data-grid`, `@reui/badge`, ...) that those examples depend on.
|
||||
- Public, no key: `c-*` examples and the 20 components (`@reui/data-grid`, `@reui/badge`, ...) that those examples depend on.
|
||||
- Key required at install: blocks (`@reui/<category>-N`) need a Pro or Ultimate license; Motion Icons (`@reui/icons/...`) and templates need Ultimate.
|
||||
|
||||
If an install 401/403s, the license key is missing, invalid, or the plan does not cover that resource (blocks: Pro or higher; icons and templates: Ultimate). Point the user to https://reui.io/account (their key) or https://reui.io/pricing (upgrade).
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
# ReUI components
|
||||
|
||||
The 19 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
|
||||
The 20 ReUI building blocks: `alert`, `autocomplete`, `badge`, `data-grid`, `date-selector`, `event-calendar`, `filters`, `frame`, `gantt`, `icon-stack`, `icon-tile`, `kanban`, `number-field`, `phone-input`, `rating`, `scrollspy`, `sortable`, `stepper`, `timeline`, `tree`. Examples and blocks are composed from these.
|
||||
|
||||
**Rule one: never guess a component's API. Read it first.** Call **`get_component(name)`** for its inline `api` (props + usage, no web fetch), and **share the result's `docsUrl`** (the component's API documentation page) with the user whenever you work with that component's API, so they have the full reference (the `/llms.txt` index is a further fallback). Then call **`get_examples(name)`** to install a worked example and copy real composition. The contracts below are first-try orientation (required props, composition shape, the one gotcha); the inline `api` is the full reference. No single block fits? Compose: search the components you need, read each `get_component`, install a `get_examples` example per component, and adapt.
|
||||
|
||||
## data-grid (the flagship - read its API every time)
|
||||
|
||||
`data-grid` wraps TanStack Table v8. It is NOT a styled `<table>` and does NOT take `data`/`columns` props directly. The contract:
|
||||
`data-grid` wraps TanStack Table v9. It is NOT a styled `<table>` and does NOT take `data`/`columns` props directly. The contract:
|
||||
|
||||
- Build a TanStack table instance with `useReactTable(...)` (columns, data, the feature models you need: sorting, pagination, row selection).
|
||||
- Build a TanStack table instance with `useTable({ features: dataGridFeatures, ... })` (columns, data). `dataGridFeatures` is exported by the primitive and already bundles sorting, filtering, pagination, row selection, expanding, pinning, resizing and faceting, so there are no per-table row models to wire.
|
||||
- Pass that instance to `<DataGrid table={table} recordCount={total}>`.
|
||||
- Compose the body with `DataGridTable` inside `DataGrid`, and enable features through `tableLayout` (e.g. `{ headerSticky: true, columnsResizable: true }`), not ad-hoc classes.
|
||||
- Server-side data uses the documented fetch shape (`recordCount` is the total for pagination).
|
||||
|
||||
```tsx
|
||||
const table = useReactTable({
|
||||
const table = useTable({
|
||||
features: dataGridFeatures,
|
||||
data,
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
// add sorting/pagination/selection models per the API
|
||||
})
|
||||
|
||||
<DataGrid table={table} recordCount={data.length}>
|
||||
@@ -28,9 +27,9 @@ const table = useReactTable({
|
||||
|
||||
Common mistakes:
|
||||
|
||||
- **Incorrect:** `<DataGrid data={rows} columns={cols} />` - these props do not exist. **Correct:** build a `useReactTable` instance and pass `table={table}` + `recordCount`.
|
||||
- **Incorrect:** `<DataGrid data={rows} columns={cols} />` - these props do not exist. **Correct:** build a `useTable({ features: dataGridFeatures, ... })` instance and pass `table={table}` + `recordCount`.
|
||||
- **Incorrect:** a raw `<table>` / hand-rolled pagination. **Correct:** use `data-grid`; read its API for sticky header, pagination, virtualization, row selection.
|
||||
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the documented `ColumnMeta` (e.g. `cellClassName`, `headerTitle`).
|
||||
- **Incorrect:** styling rows/cells with arbitrary classes. **Correct:** drive layout via `tableLayout` and the primitive's `DataGridColumnMeta` (e.g. `cellClassName`, `headerTitle`), set through the bundle's `columnMeta` slot.
|
||||
|
||||
## event-calendar
|
||||
|
||||
@@ -312,6 +311,19 @@ const [value, setValue] = useState<DateSelectorValue | undefined>()
|
||||
|
||||
**Gotcha:** isometric layered artwork for empty states and illustrations; style the inner icon via its own `className`. Mark purely decorative stacks `aria-hidden="true"` and keep the real label in surrounding copy.
|
||||
|
||||
## icon-tile
|
||||
|
||||
**Required:** one child icon
|
||||
**Shape:**
|
||||
|
||||
```tsx
|
||||
<IconTile variant="elevated" size="lg">
|
||||
<PackageIcon />
|
||||
</IconTile>
|
||||
```
|
||||
|
||||
**Gotcha:** the square container an icon sits in, so every list row, feature card and empty state shares one affordance. `variant`: `outline` (default) | `elevated` (muted fill, raised ring) | `soft` (tinted nested, tone from currentColor) | `solid` (filled tone, contrasting glyph) | `frame` (double container). `soft` and `solid` retint from one text color class (they default to `text-primary`). `size`: `xs | sm | default | lg | xl` (24/32/40/48/64px tile, glyph scales 12/14/16/20/24px). `radius`: `default | full`. Do not set a `size-*` class on the child icon unless you mean to override the tile's glyph size; recolor with `className` on the tile, not the icon.
|
||||
|
||||
## alert
|
||||
|
||||
**Required:** `Alert` > `AlertTitle`
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
ReUI is a shadcn-compatible registry with four entity types. **Examples and blocks are built FROM components** - reuse them, don't rebuild.
|
||||
|
||||
- **component** - one of the 17 ReUI building blocks with a real API (`data-grid`, `kanban`, `filters`, `date-selector`, `tree`, ...). Install directly (`@reui/data-grid`) or let it come in as a dependency of an example/block. Free. Read its API with `get_component(name)`.
|
||||
- **component** - one of the 20 ReUI building blocks with a real API (`data-grid`, `kanban`, `filters`, `date-selector`, `tree`, ...). Install directly (`@reui/data-grid`) or let it come in as a dependency of an example/block. Free. Read its API with `get_component(name)`.
|
||||
- **example** - a free `c-*` single-pattern use-case of a component (`c-kanban-1`, `c-data-grid-3`). Install one and read it to copy real composition. Find a component's examples with `get_examples(name)`.
|
||||
- **block** - a premium, full-page section that composes several components (`data-grid-2`, `pricing-page-1`). Pro or Ultimate license at install. Adapts to your active theme via semantic tokens.
|
||||
- **icon** - Motion Icons in 4 styles (outline, solid, duotone, filled), static (`@reui/icons/default/<style>/<name>`) and hover-animated (`@reui/icons/animated/<style>/<name>`). Ultimate license at install. See [icons.md](./icons.md).
|
||||
@@ -27,7 +27,7 @@ Blocks adapt to your active theme through semantic tokens and CSS variables - ch
|
||||
|
||||
## Free vs premium
|
||||
|
||||
- **Free, no key:** the 17 components, all `c-*` examples, the ReUI MCP, and this skill.
|
||||
- **Free, no key:** the 20 components, all `c-*` examples, the ReUI MCP, and this skill.
|
||||
- **Premium, license required at install:** blocks (Pro or Ultimate), Motion Icons and templates (Ultimate). Set `REUI_LICENSE_KEY` (see [cli.md](./cli.md)).
|
||||
|
||||
## Component API index
|
||||
|
||||
@@ -8,7 +8,7 @@ The core ReUI loop. The MCP tells you what to install and gives you the API; the
|
||||
|
||||
For everything else, call `search` with the user's intent. Pass structured hints whenever you can infer them - you are an LLM, so do the parsing the server cannot:
|
||||
|
||||
- `type`: `"component"` (one of the 17 building blocks), `"example"` (a c-\* use-case), `"block"` (a full page/section), `"icon"`.
|
||||
- `type`: `"component"` (one of the 20 building blocks), `"example"` (a c-\* use-case), `"block"` (a full page/section), `"icon"`.
|
||||
- `component`: the ReUI component the request implies (`"data-grid"`, `"kanban"`, ...).
|
||||
- `category`, `features` (e.g. `["sortable","pagination"]`), `free`.
|
||||
|
||||
@@ -40,7 +40,7 @@ Before writing code against any component an item uses:
|
||||
|
||||
Installing files is not the end, and redesigning them defeats the point. First note the project's **base** so you write the right API - read `components.json` -> `style` and take the segment before the first `-` (`base-nova` -> Base UI, `radix-nova` -> Radix UI), see [components.md](./components.md). After `add`:
|
||||
|
||||
1. **Read the added files**; keep the composition intact. For a block, verify the components are wired correctly (for `data-grid`: a `useReactTable` instance passed as `table`, `recordCount` set - see [components.md](./components.md)).
|
||||
1. **Read the added files**; keep the composition intact. For a block, verify the components are wired correctly (for `data-grid`: a `useTable({ features: dataGridFeatures, ... })` instance passed as `table`, `recordCount` set - see [components.md](./components.md)).
|
||||
2. **Replace demo data with the user's real data** via typed structures (see [adapting.md](./adapting.md)).
|
||||
3. **Fix icon imports** to the project's icon library (see [icons.md](./icons.md)).
|
||||
4. **Align styling** to semantic tokens and the active theme - no raw colors (see [styling.md](./styling.md)).
|
||||
|
||||
@@ -84,7 +84,7 @@ vps-tracker/
|
||||
## Уведомления
|
||||
|
||||
- **Движок:** `apps/api/src/services/notifications/` — rules, dedup, engine, channels
|
||||
- **Планировщик:** `apps/api/src/services/scheduler.ts` — sync отдельно; notify/uptime не зависят от `syncEnabled`
|
||||
- **Планировщик:** `apps/api/src/services/scheduler.ts` — sync отдельно; notify/uptime не зависят от `syncEnabled`; **CFDM pull** (домены → `vps_domains`) каждые **15 мин**, если включена интеграция + URL + токен (и при старте API)
|
||||
- **События:** `payment_expiry`, `sync_digest`, `low_balance`, `new_tariffs`, `vps_down`, `vps_up`
|
||||
- **Каналы:** Telegram (`telegram.ts`) и webhook (`webhook.ts`); webhook работает без Telegram
|
||||
- **Журнал:** таблица `notification_log`, API `GET /api/notifications/log`
|
||||
@@ -105,7 +105,8 @@ pnpm --filter web test # Vitest frontend
|
||||
|
||||
- Registry: `@reui` в [`apps/web/components.json`](apps/web/components.json)
|
||||
- **Design contract:** [`docs/ui-design-contract.md`](docs/ui-design-contract.md) — surface `frame`, kit `reui-kit/`
|
||||
- AI-карта: [llms.txt](https://reui.io/llms.txt)
|
||||
- Docs: [Introduction](https://reui.io/docs) · [llms.txt](https://reui.io/llms.txt) · [Get Started](https://reui.io/docs/get-started) · [MCP](https://reui.io/docs/mcp) · [Agent Skills](https://reui.io/docs/agent-skills) · [Cursor](https://reui.io/docs/cursor)
|
||||
- Skill (локально): `.claude/skills/reui` / `.cursor/skills/reui` — версия `668fb463eb` (20 free components). Обновление: `curl.exe -fsSL https://mcp.reui.io/install | node -`
|
||||
- Установка: `cd apps/web && pnpm dlx shadcn@latest add @reui/<name>`
|
||||
- Правила: [`reui-mcp.mdc`](.cursor/rules/reui-mcp.mdc), [`shadcn-mcp.mdc`](.cursor/rules/shadcn-mcp.mdc)
|
||||
- Зависимости ReUI в `apps/web`: `@tanstack/react-table`, `@tanstack/react-virtual`, `@dnd-kit/*`, `date-fns`, `react-day-picker`
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { closeDb } from '@cfdm/db'
|
||||
import { settingsRepository } from '@cfdm/db/repositories/settings'
|
||||
import { resetTestDb } from '@cfdm/db/test-setup'
|
||||
|
||||
vi.mock('./cfdm-sync.js', () => ({
|
||||
requestCfdmFullSync: vi.fn(),
|
||||
}))
|
||||
|
||||
import { requestCfdmFullSync } from './cfdm-sync.js'
|
||||
import { runScheduledCfdmSync } from './scheduler.js'
|
||||
|
||||
const pullMock = vi.mocked(requestCfdmFullSync)
|
||||
|
||||
describe('runScheduledCfdmSync', () => {
|
||||
beforeEach(async () => {
|
||||
await resetTestDb()
|
||||
pullMock.mockReset()
|
||||
pullMock.mockResolvedValue({ ok: true, count: 3 })
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await closeDb()
|
||||
})
|
||||
|
||||
it('pulls CFDM when integration is enabled with url and token', async () => {
|
||||
settingsRepository.upsertForSpace('space-main', {
|
||||
integrationEnabled: true,
|
||||
integrationToken: 'tok-sched-cfdm',
|
||||
cfdmApiUrl: 'http://cfdm.test',
|
||||
})
|
||||
|
||||
await runScheduledCfdmSync()
|
||||
|
||||
expect(pullMock).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('skips when integration is disabled', async () => {
|
||||
settingsRepository.upsertForSpace('space-main', {
|
||||
integrationEnabled: false,
|
||||
integrationToken: 'tok-sched-cfdm',
|
||||
cfdmApiUrl: 'http://cfdm.test',
|
||||
})
|
||||
|
||||
await runScheduledCfdmSync()
|
||||
|
||||
expect(pullMock).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@@ -6,6 +6,7 @@ import { resolveSyncAccount, getProviderAdapter, type SyncReadyAccount } from '.
|
||||
import { runAccountSync } from './providers/sync-job.js'
|
||||
import { runVpsUptimeChecks } from './uptime-check.js'
|
||||
import { notifyCfdmVpsEvent } from './cfdm-notify.js'
|
||||
import { requestCfdmFullSync } from './cfdm-sync.js'
|
||||
import { publishMany, publishNotification } from './notifications/engine.js'
|
||||
import {
|
||||
buildLowBalanceNotification,
|
||||
@@ -15,10 +16,15 @@ import {
|
||||
buildVpsHealthNotification,
|
||||
} from './notifications/rules.js'
|
||||
|
||||
/** Pull bindings from CFDM → vps_domains (domains on VPS). */
|
||||
export const CFDM_SYNC_INTERVAL_MINUTES = 15
|
||||
|
||||
let syncIntervalId: ReturnType<typeof setInterval> | null = null
|
||||
let syncTariffsIntervalId: ReturnType<typeof setInterval> | null = null
|
||||
let notifyIntervalId: ReturnType<typeof setInterval> | null = null
|
||||
let uptimeIntervalId: ReturnType<typeof setInterval> | null = null
|
||||
let cfdmSyncIntervalId: ReturnType<typeof setInterval> | null = null
|
||||
let cfdmSyncInFlight = false
|
||||
|
||||
type AccountRow = typeof schema.providerAccounts.$inferSelect
|
||||
type SettingsRow = typeof schema.settings.$inferSelect
|
||||
@@ -201,6 +207,48 @@ export async function runScheduledUptimeChecks(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
function spaceHasCfdmPullConfig(settings: SettingsRow): boolean {
|
||||
return (
|
||||
Boolean(settings.integrationEnabled) &&
|
||||
Boolean(settings.integrationToken?.trim()) &&
|
||||
Boolean(settings.cfdmApiUrl?.trim())
|
||||
)
|
||||
}
|
||||
|
||||
/** Pull full CFDM bindings into local vps_domains for each configured space. */
|
||||
export async function runScheduledCfdmSync(): Promise<void> {
|
||||
if (cfdmSyncInFlight) return
|
||||
cfdmSyncInFlight = true
|
||||
try {
|
||||
for (const settings of allSettings()) {
|
||||
if (!spaceHasCfdmPullConfig(settings)) continue
|
||||
const spaceId = settings.spaceId || MAIN_SPACE_ID
|
||||
try {
|
||||
await runWithSpaceAsync(spaceId, async () => {
|
||||
const result = await requestCfdmFullSync()
|
||||
if (!result.ok) {
|
||||
console.warn(
|
||||
`CFDM scheduled sync [${spaceId}]:`,
|
||||
result.error ?? 'unknown error',
|
||||
)
|
||||
return
|
||||
}
|
||||
console.log(
|
||||
`CFDM scheduled sync [${spaceId}]: ${result.count ?? 0} bindings`,
|
||||
)
|
||||
})
|
||||
} catch (err) {
|
||||
console.warn(
|
||||
`CFDM scheduled sync error [${spaceId}]:`,
|
||||
err instanceof Error ? err.message : err,
|
||||
)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
cfdmSyncInFlight = false
|
||||
}
|
||||
}
|
||||
|
||||
function pickSchedulerIntervals(rows: SettingsRow[]): {
|
||||
notifyInterval: number
|
||||
uptimeInterval: number
|
||||
@@ -240,6 +288,8 @@ export function startScheduler(): void {
|
||||
notifyIntervalId = null
|
||||
if (uptimeIntervalId) clearInterval(uptimeIntervalId)
|
||||
uptimeIntervalId = null
|
||||
if (cfdmSyncIntervalId) clearInterval(cfdmSyncIntervalId)
|
||||
cfdmSyncIntervalId = null
|
||||
|
||||
try {
|
||||
const rows = allSettings()
|
||||
@@ -247,6 +297,7 @@ export function startScheduler(): void {
|
||||
|
||||
const { notifyInterval, uptimeInterval, syncInterval, tariffsInterval } =
|
||||
pickSchedulerIntervals(rows)
|
||||
const cfdmConfigured = rows.some(spaceHasCfdmPullConfig)
|
||||
|
||||
notifyIntervalId = setInterval(() => void runNotificationTick(), notifyInterval * 60 * 1000)
|
||||
uptimeIntervalId = setInterval(
|
||||
@@ -274,6 +325,13 @@ export function startScheduler(): void {
|
||||
parts.unshift(`tariffs every ${tariffsInterval} min`)
|
||||
}
|
||||
|
||||
if (cfdmConfigured) {
|
||||
const cfdmMs = CFDM_SYNC_INTERVAL_MINUTES * 60 * 1000
|
||||
cfdmSyncIntervalId = setInterval(() => void runScheduledCfdmSync(), cfdmMs)
|
||||
void runScheduledCfdmSync()
|
||||
parts.unshift(`cfdm every ${CFDM_SYNC_INTERVAL_MINUTES} min`)
|
||||
}
|
||||
|
||||
console.log(`Scheduler: ${parts.join(', ')}`)
|
||||
} catch {
|
||||
// ignore
|
||||
@@ -289,6 +347,8 @@ export function stopScheduler(): void {
|
||||
notifyIntervalId = null
|
||||
if (uptimeIntervalId) clearInterval(uptimeIntervalId)
|
||||
uptimeIntervalId = null
|
||||
if (cfdmSyncIntervalId) clearInterval(cfdmSyncIntervalId)
|
||||
cfdmSyncIntervalId = null
|
||||
}
|
||||
|
||||
export function restartScheduler(): void {
|
||||
|
||||
@@ -107,7 +107,7 @@ export function CfdmIntegrationForm({
|
||||
<FieldGroup className="gap-0">
|
||||
<SettingRow
|
||||
title="Принимать синхронизацию"
|
||||
description="Разрешить CFDM пушить домены и сервисы (авто-sync)"
|
||||
description="Вкл.: push от CFDM + авто-pull доменов каждые 15 мин (нужны URL и токен)"
|
||||
>
|
||||
<Controller
|
||||
control={form.control}
|
||||
@@ -183,8 +183,8 @@ export function CfdmIntegrationForm({
|
||||
title="Синхронизация"
|
||||
description={
|
||||
settings?.integrationLastSyncAt
|
||||
? `Последний sync: ${new Date(settings.integrationLastSyncAt).toLocaleString('ru-RU')}`
|
||||
: 'Используются только сохранённые URL и токен'
|
||||
? `Последний sync: ${new Date(settings.integrationLastSyncAt).toLocaleString('ru-RU')} · авто каждые 15 мин`
|
||||
: 'Авто каждые 15 мин при включённой интеграции; кнопка — ручной pull'
|
||||
}
|
||||
last
|
||||
>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Surface: **ReUI Frame**. Kit: `apps/web/src/components/reui-kit/`.
|
||||
Иерархия: **ReUI PRO > shadcn primitives**.
|
||||
|
||||
Карта: [llms.txt](https://reui.io/llms.txt) · [Styling](https://reui.io/docs/styling) · [License](https://reui.io/docs/license-setup) · [Blocks](https://reui.io/blocks) · [MCP](https://reui.io/docs/mcp)
|
||||
Карта: [docs](https://reui.io/docs) · [llms.txt](https://reui.io/llms.txt) · [Get Started](https://reui.io/docs/get-started) · [Styling](https://reui.io/docs/styling) · [Registry](https://reui.io/docs/registry) · [License](https://reui.io/docs/license-setup) · [Blocks](https://reui.io/blocks) · [MCP](https://reui.io/docs/mcp) · [Agent Skills](https://reui.io/docs/agent-skills)
|
||||
|
||||
## Surface
|
||||
|
||||
|
||||
Reference in New Issue
Block a user