uilint-react 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +210 -0
  2. package/package.json +14 -3
package/README.md ADDED
@@ -0,0 +1,210 @@
1
+ # uilint-react
2
+
3
+ React component for AI-powered UI consistency checking in running applications.
4
+
5
+ ## Overview
6
+
7
+ `uilint-react` provides React components and utilities for analyzing UI consistency at runtime and in tests. It includes a visual overlay for development and a JSDOM adapter for testing.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install uilint-react uilint-core
13
+ ```
14
+
15
+ ## Usage in a Running App
16
+
17
+ Wrap your app with the `<UILint>` component to get a visual overlay:
18
+
19
+ ### Next.js Setup
20
+
21
+ ```tsx
22
+ // app/layout.tsx
23
+ import { UILint } from "uilint-react";
24
+
25
+ export default function RootLayout({ children }) {
26
+ return (
27
+ <html>
28
+ <body>
29
+ <UILint
30
+ enabled={process.env.NODE_ENV !== "production"}
31
+ position="bottom-left"
32
+ autoScan={false}
33
+ >
34
+ {children}
35
+ </UILint>
36
+ </body>
37
+ </html>
38
+ );
39
+ }
40
+ ```
41
+
42
+ ### Props
43
+
44
+ | Prop | Type | Default | Description |
45
+ | ------------- | -------------------------------------------------------------- | ----------------------- | ------------------------------- |
46
+ | `enabled` | `boolean` | `true` | Enable/disable UILint |
47
+ | `position` | `'bottom-left' \| 'bottom-right' \| 'top-left' \| 'top-right'` | `'bottom-left'` | Overlay position |
48
+ | `autoScan` | `boolean` | `false` | Automatically scan on page load |
49
+ | `apiEndpoint` | `string` | `'/api/uilint/analyze'` | Custom API endpoint |
50
+
51
+ ### API Routes
52
+
53
+ You'll need to add API routes for the React component:
54
+
55
+ ```ts
56
+ // app/api/uilint/analyze/route.ts
57
+ import { NextRequest, NextResponse } from "next/server";
58
+ import { OllamaClient } from "uilint-core";
59
+
60
+ export async function POST(request: NextRequest) {
61
+ const { styleSummary, styleGuide, generateGuide, model } =
62
+ await request.json();
63
+ const client = new OllamaClient({ model: model || "qwen2.5-coder:7b" });
64
+
65
+ if (generateGuide) {
66
+ const styleGuideContent = await client.generateStyleGuide(styleSummary);
67
+ return NextResponse.json({ styleGuide: styleGuideContent });
68
+ } else {
69
+ const result = await client.analyzeStyles(styleSummary, styleGuide);
70
+ return NextResponse.json({ issues: result.issues });
71
+ }
72
+ }
73
+ ```
74
+
75
+ ```ts
76
+ // app/api/uilint/styleguide/route.ts
77
+ import { NextRequest, NextResponse } from "next/server";
78
+ import {
79
+ readStyleGuideFromProject,
80
+ writeStyleGuide,
81
+ styleGuideExists,
82
+ getDefaultStyleGuidePath,
83
+ } from "uilint-core/node";
84
+
85
+ export async function GET() {
86
+ const projectPath = process.cwd();
87
+ if (!styleGuideExists(projectPath)) {
88
+ return NextResponse.json({ exists: false, content: null });
89
+ }
90
+ const content = await readStyleGuideFromProject(projectPath);
91
+ return NextResponse.json({ exists: true, content });
92
+ }
93
+
94
+ export async function POST(request: NextRequest) {
95
+ const { content } = await request.json();
96
+ const projectPath = process.cwd();
97
+ const stylePath = getDefaultStyleGuidePath(projectPath);
98
+ await writeStyleGuide(stylePath, content);
99
+ return NextResponse.json({ success: true });
100
+ }
101
+ ```
102
+
103
+ ## Usage in Tests
104
+
105
+ UILint can run in Vitest/Jest tests with JSDOM:
106
+
107
+ ### Basic Test
108
+
109
+ ```tsx
110
+ import { render, screen } from "@testing-library/react";
111
+ import { UILint } from "uilint-react";
112
+ import { MyComponent } from "./MyComponent";
113
+
114
+ test("MyComponent has consistent styles", async () => {
115
+ render(
116
+ <UILint enabled={true}>
117
+ <MyComponent />
118
+ </UILint>
119
+ );
120
+
121
+ expect(screen.getByRole("button")).toBeInTheDocument();
122
+
123
+ // UILint automatically outputs warnings to console:
124
+ // ⚠️ [UILint] Button uses #3B82F6 but style guide specifies #2563EB
125
+ });
126
+ ```
127
+
128
+ ### Direct JSDOM Adapter
129
+
130
+ For more control, use the `JSDOMAdapter`:
131
+
132
+ ```tsx
133
+ import { JSDOMAdapter, runUILintInTest } from "uilint-react";
134
+ import { render } from "@testing-library/react";
135
+
136
+ test("detect style inconsistencies", async () => {
137
+ render(<MyComponent />);
138
+
139
+ // Run UILint and get issues
140
+ const issues = await runUILintInTest(document.body);
141
+
142
+ // Assert on specific issues
143
+ expect(issues).toHaveLength(0); // Fail if any issues found
144
+ });
145
+
146
+ test("custom adapter usage", async () => {
147
+ render(<MyComponent />);
148
+
149
+ const adapter = new JSDOMAdapter(".uilint/styleguide.md");
150
+ await adapter.loadStyleGuide();
151
+
152
+ const result = await adapter.analyze(document.body);
153
+ adapter.outputWarnings(result.issues);
154
+
155
+ expect(result.issues.filter((i) => i.type === "color")).toHaveLength(0);
156
+ });
157
+ ```
158
+
159
+ ## API
160
+
161
+ ### UILint Component
162
+
163
+ ```tsx
164
+ interface UILintProps {
165
+ enabled?: boolean;
166
+ position?: "bottom-left" | "bottom-right" | "top-left" | "top-right";
167
+ autoScan?: boolean;
168
+ apiEndpoint?: string;
169
+ children: React.ReactNode;
170
+ }
171
+
172
+ function UILint(props: UILintProps): JSX.Element;
173
+ ```
174
+
175
+ ### JSDOM Adapter
176
+
177
+ ```typescript
178
+ class JSDOMAdapter {
179
+ constructor(styleGuidePath?: string);
180
+
181
+ loadStyleGuide(): Promise<void>;
182
+ analyze(element: Element): Promise<{ issues: Issue[] }>;
183
+ outputWarnings(issues: Issue[]): void;
184
+ }
185
+
186
+ function runUILintInTest(element: Element): Promise<Issue[]>;
187
+ ```
188
+
189
+ ## Prerequisites
190
+
191
+ For LLM-powered features, you need [Ollama](https://ollama.ai) installed locally:
192
+
193
+ ```bash
194
+ # Install Ollama, then pull the default model
195
+ ollama pull qwen2.5-coder:7b
196
+ ```
197
+
198
+ ## Related Packages
199
+
200
+ - [`uilint-core`](https://www.npmjs.com/package/uilint-core) - Core library
201
+ - [`uilint-cli`](https://www.npmjs.com/package/uilint-cli) - Command-line interface
202
+ - [`uilint-mcp`](https://www.npmjs.com/package/uilint-mcp) - MCP server
203
+
204
+ ## Documentation
205
+
206
+ For full documentation, visit the [UILint GitHub repository](https://github.com/peter-suggate/uilint).
207
+
208
+ ## License
209
+
210
+ MIT
package/package.json CHANGED
@@ -1,7 +1,17 @@
1
1
  {
2
2
  "name": "uilint-react",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "React component for AI-powered UI consistency checking",
5
+ "author": "Peter Suggate",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/peter-suggate/uilint.git",
9
+ "directory": "packages/uilint-react"
10
+ },
11
+ "homepage": "https://github.com/peter-suggate/uilint#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/peter-suggate/uilint/issues"
14
+ },
5
15
  "type": "module",
6
16
  "main": "./dist/index.js",
7
17
  "module": "./dist/index.js",
@@ -17,13 +27,14 @@
17
27
  }
18
28
  },
19
29
  "files": [
20
- "dist"
30
+ "dist",
31
+ "README.md"
21
32
  ],
22
33
  "engines": {
23
34
  "node": ">=20.0.0"
24
35
  },
25
36
  "dependencies": {
26
- "uilint-core": "^0.1.5"
37
+ "uilint-core": "^0.1.7"
27
38
  },
28
39
  "peerDependencies": {
29
40
  "react": "^19.0.0",