uidex 0.0.1 → 0.1.0

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 (39) hide show
  1. package/README.md +103 -152
  2. package/claude/audit-command.md +16 -0
  3. package/claude/rules.md +88 -0
  4. package/dist/core/index.cjs +3217 -0
  5. package/dist/core/index.cjs.map +1 -0
  6. package/dist/core/index.d.cts +331 -0
  7. package/dist/core/index.d.ts +331 -0
  8. package/dist/core/index.global.js +3199 -0
  9. package/dist/core/index.global.js.map +1 -0
  10. package/dist/core/index.js +3174 -0
  11. package/dist/core/index.js.map +1 -0
  12. package/dist/core/style.css +964 -0
  13. package/dist/index.cjs +3288 -0
  14. package/dist/index.cjs.map +1 -0
  15. package/dist/index.d.cts +74 -0
  16. package/dist/index.d.ts +74 -0
  17. package/dist/index.js +3251 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/playwright/index.cjs +72 -0
  20. package/dist/playwright/index.cjs.map +1 -0
  21. package/dist/playwright/index.d.cts +62 -0
  22. package/dist/playwright/index.d.ts +62 -0
  23. package/dist/playwright/index.js +39 -0
  24. package/dist/playwright/index.js.map +1 -0
  25. package/dist/playwright/reporter.cjs +88 -0
  26. package/dist/playwright/reporter.cjs.map +1 -0
  27. package/dist/playwright/reporter.d.cts +24 -0
  28. package/dist/playwright/reporter.d.ts +24 -0
  29. package/dist/playwright/reporter.js +57 -0
  30. package/dist/playwright/reporter.js.map +1 -0
  31. package/dist/react/index.cjs +3288 -0
  32. package/dist/react/index.cjs.map +1 -0
  33. package/dist/react/index.d.cts +74 -0
  34. package/dist/react/index.d.ts +74 -0
  35. package/dist/react/index.js +3251 -0
  36. package/dist/react/index.js.map +1 -0
  37. package/dist/scripts/cli.cjs +1167 -0
  38. package/package.json +106 -7
  39. package/uidex.schema.json +93 -0
package/README.md CHANGED
@@ -13,6 +13,24 @@ npm install uidex
13
13
  - React 18 or higher
14
14
  - React DOM 18 or higher
15
15
 
16
+ ## Quick Start
17
+
18
+ ```tsx
19
+ // 1. Add data-uidex attributes to elements you want to track
20
+ <button data-uidex="submit-btn">Submit</button>
21
+
22
+ // 2. Run the scanner to generate the registry
23
+ npx uidex-scan
24
+
25
+ // 3. Import the generated file (auto-registers components)
26
+ import './uidex.gen';
27
+
28
+ // 4. Add UidexDevtools anywhere in your app
29
+ import { UidexDevtools } from 'uidex';
30
+
31
+ <UidexDevtools />
32
+ ```
33
+
16
34
  ## Configuration
17
35
 
18
36
  Create a `.uidex.json` file in your project root to customize default settings:
@@ -34,51 +52,30 @@ Create a `.uidex.json` file in your project root to customize default settings:
34
52
  "error": "#ef4444",
35
53
  "info": "#6366f1"
36
54
  },
37
- "disabled": false
38
- }
39
- ```
40
-
41
- ### Using the Config Provider
42
-
43
- Wrap your app with `AnnotateProvider` to apply configuration:
44
-
45
- ```tsx
46
- import { AnnotateProvider } from 'uidex';
47
- import config from './.uidex.json';
48
-
49
- function App() {
50
- return (
51
- <AnnotateProvider config={config}>
52
- {/* Your app */}
53
- </AnnotateProvider>
54
- );
55
+ "scanner": {
56
+ "rootDir": "src",
57
+ "include": ["**/*.tsx", "**/*.jsx"],
58
+ "exclude": ["**/*.test.*", "**/*.spec.*"],
59
+ "outputPath": "src/uidex.gen.ts"
60
+ }
55
61
  }
56
62
  ```
57
63
 
58
- ### Named Colors
59
-
60
- Use named colors from your config:
61
-
62
- ```tsx
63
- <Annotate label="Error" color="error">
64
- <button>Delete</button>
65
- </Annotate>
66
- ```
67
-
68
- ## Usage
64
+ ## Components
69
65
 
70
- ### Annotate Component
66
+ ### UidexDevtools
71
67
 
72
- Wrap any component with `Annotate` to add hover-based highlighting:
68
+ The main devtools component that displays a floating button with a list of all registered components:
73
69
 
74
70
  ```tsx
75
- import { Annotate } from 'uidex';
71
+ import { UidexDevtools } from 'uidex';
76
72
 
77
73
  function App() {
78
74
  return (
79
- <Annotate label="Submit Button" color="#10b981">
80
- <button>Submit</button>
81
- </Annotate>
75
+ <>
76
+ {/* Your app content */}
77
+ <UidexDevtools />
78
+ </>
82
79
  );
83
80
  }
84
81
  ```
@@ -87,102 +84,59 @@ function App() {
87
84
 
88
85
  | Prop | Type | Default | Description |
89
86
  |------|------|---------|-------------|
90
- | `children` | `ReactNode` | required | The content to wrap |
91
- | `label` | `string` | - | Label text shown on hover |
92
- | `color` | `string` | `#3b82f6` | Highlight color (hex or named color) |
93
- | `borderStyle` | `'solid' \| 'dashed' \| 'dotted'` | `'solid'` | Border style |
94
- | `borderWidth` | `number` | `2` | Border width in pixels |
95
- | `showLabel` | `boolean` | `true` | Whether to show the label |
96
- | `labelPosition` | `'top-left' \| 'top-right' \| 'bottom-left' \| 'bottom-right'` | `'top-left'` | Label position |
97
- | `disabled` | `boolean` | `false` | Disable highlighting |
98
- | `className` | `string` | - | Additional CSS class |
99
- | `style` | `CSSProperties` | - | Additional inline styles |
100
- | `onHover` | `(isHovered: boolean) => void` | - | Callback on hover state change |
87
+ | `components` | `UidexMap` | - | Optional components map (uses registry if not provided) |
88
+ | `config` | `UidexConfig` | - | Optional configuration for styling |
89
+ | `buttonPosition` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | `'bottom-right'` | Position of the floating button |
90
+ | `trigger` | `ReactNode` | - | Custom trigger element |
91
+ | `disabled` | `boolean` | `false` | Disable the devtools |
92
+ | `onSelect` | `(id: string) => void` | - | Callback when a component is selected |
101
93
 
102
- ### HighlightOverlay Component
94
+ ### UidexOverlay
103
95
 
104
- For more control, use `HighlightOverlay` with a ref to any element:
96
+ For manual control over overlays:
105
97
 
106
98
  ```tsx
107
- import { useRef } from 'react';
108
- import { HighlightOverlay } from 'uidex';
99
+ import { useState } from 'react';
100
+ import { UidexOverlay } from 'uidex';
109
101
 
110
102
  function App() {
111
- const buttonRef = useRef<HTMLButtonElement>(null);
103
+ const [target, setTarget] = useState<HTMLElement | null>(null);
112
104
 
113
105
  return (
114
106
  <>
115
- <button ref={buttonRef}>Click me</button>
116
- <HighlightOverlay
117
- targetRef={buttonRef}
118
- label="Action Button"
119
- color="#f59e0b"
120
- visible={true}
107
+ <button
108
+ ref={(el) => setTarget(el)}
109
+ onMouseEnter={(e) => setTarget(e.currentTarget)}
110
+ onMouseLeave={() => setTarget(null)}
111
+ >
112
+ Hover me
113
+ </button>
114
+ <UidexOverlay
115
+ target={target}
116
+ label="Button"
117
+ color="#3b82f6"
121
118
  />
122
119
  </>
123
120
  );
124
121
  }
125
122
  ```
126
123
 
127
- ### Hooks
128
-
129
- #### useHighlight
130
-
131
- Simple state management for highlight visibility:
132
-
133
- ```tsx
134
- import { useHighlight } from 'uidex';
135
-
136
- function App() {
137
- const { isHighlighted, highlight, unhighlight, toggle } = useHighlight();
138
-
139
- return (
140
- <div>
141
- <button onClick={toggle}>Toggle Highlight</button>
142
- {isHighlighted && <div>Highlighted!</div>}
143
- </div>
144
- );
145
- }
146
- ```
147
-
148
- #### useAnnotation
149
-
150
- Combines a ref with highlight state:
151
-
152
- ```tsx
153
- import { useAnnotation, HighlightOverlay } from 'uidex';
154
-
155
- function App() {
156
- const { ref, isHighlighted, toggle } = useAnnotation();
157
-
158
- return (
159
- <>
160
- <div ref={ref}>Target element</div>
161
- <button onClick={toggle}>Toggle</button>
162
- <HighlightOverlay targetRef={ref} visible={isHighlighted} label="Target" />
163
- </>
164
- );
165
- }
166
- ```
167
-
168
- #### useAnnotateConfig
169
-
170
- Access the current configuration:
171
-
172
- ```tsx
173
- import { useAnnotateConfig } from 'uidex';
174
-
175
- function MyComponent() {
176
- const config = useAnnotateConfig();
124
+ #### Props
177
125
 
178
- console.log(config.defaults?.color); // Current default color
179
- console.log(config.colors?.primary); // Named color value
180
- }
181
- ```
126
+ | Prop | Type | Default | Description |
127
+ |------|------|---------|-------------|
128
+ | `target` | `HTMLElement \| null` | required | The element to highlight |
129
+ | `label` | `string` | - | Label text shown on the overlay |
130
+ | `color` | `string` | `#3b82f6` | Highlight color (hex or named color) |
131
+ | `borderStyle` | `'solid' \| 'dashed' \| 'dotted'` | `'solid'` | Border style |
132
+ | `borderWidth` | `number` | `2` | Border width in pixels |
133
+ | `showLabel` | `boolean` | `true` | Whether to show the label |
134
+ | `labelPosition` | `'top-left' \| 'top-right' \| 'bottom-left' \| 'bottom-right'` | `'top-left'` | Label position |
135
+ | `colors` | `Record<string, string>` | - | Named colors map |
182
136
 
183
137
  ## Build-Time Scanner
184
138
 
185
- The `uidex-scan` CLI tool scans your source files for `data-uidex` attributes and generates a TypeScript registry file. This enables type-safe access to all annotations in your codebase.
139
+ The `uidex-scan` CLI tool scans your source files for `data-uidex` attributes and generates a TypeScript registry file.
186
140
 
187
141
  ### Setup
188
142
 
@@ -194,17 +148,15 @@ Add scanner configuration to your `.uidex.json`:
194
148
  "scanner": {
195
149
  "include": ["**/*.tsx"],
196
150
  "exclude": ["**/*.test.*", "**/*.spec.*", "**/generated/**"],
197
- "outputPath": "src/generated/annotations.ts",
151
+ "outputPath": "src/uidex.gen.ts",
198
152
  "rootDir": "src"
199
153
  }
200
154
  }
201
155
  ```
202
156
 
203
- Note: The `include` and `exclude` patterns are relative to `rootDir`. If `rootDir` is `src`, use patterns like `**/*.tsx` (not `src/**/*.tsx`).
204
-
205
157
  ### Monorepo Support
206
158
 
207
- For monorepos with multiple packages, use the `sources` array to scan multiple directories:
159
+ For monorepos with multiple packages, use the `sources` array:
208
160
 
209
161
  ```json
210
162
  {
@@ -219,34 +171,19 @@ For monorepos with multiple packages, use the `sources` array to scan multiple d
219
171
  "rootDir": "../packages/ui/src",
220
172
  "include": ["**/*.tsx"],
221
173
  "prefix": "@myorg/ui"
222
- },
223
- {
224
- "rootDir": "../packages/components/src",
225
- "include": ["**/*.tsx"],
226
- "exclude": ["**/internal/**"],
227
- "prefix": "@myorg/components"
228
174
  }
229
175
  ],
230
- "exclude": ["**/*.test.*", "**/*.spec.*", "**/generated/**"],
231
- "outputPath": "src/generated/annotations.ts"
176
+ "exclude": ["**/*.test.*", "**/*.spec.*"],
177
+ "outputPath": "src/uidex.gen.ts"
232
178
  }
233
179
  }
234
180
  ```
235
181
 
236
- Each source can have:
237
- - `rootDir` - Directory to scan (can be relative path like `../packages/ui`)
238
- - `include` - Glob patterns for files to include
239
- - `exclude` - Additional exclude patterns for this source only
240
- - `prefix` - Optional prefix for file paths in output (e.g., `@myorg/ui/Button.tsx`)
241
-
242
- The `exclude` at the top level applies globally to all sources.
243
-
244
182
  ### Usage
245
183
 
246
184
  Run the scanner as part of your build process:
247
185
 
248
186
  ```json
249
- // package.json
250
187
  {
251
188
  "scripts": {
252
189
  "prebuild": "npx uidex-scan",
@@ -261,7 +198,7 @@ Or run it directly:
261
198
  npx uidex-scan
262
199
  ```
263
200
 
264
- ### Adding Annotations
201
+ ### Adding Components
265
202
 
266
203
  Add `data-uidex` attributes to your JSX elements:
267
204
 
@@ -273,55 +210,69 @@ Add `data-uidex` attributes to your JSX elements:
273
210
  <button data-uidex="cta-button">Click Me</button>
274
211
  ```
275
212
 
213
+ ### JSDoc Documentation
214
+
215
+ Add documentation to components using JSDoc comments:
216
+
217
+ ```tsx
218
+ /** @uidex cta-button - Primary call-to-action button */
219
+ <button data-uidex="cta-button">Click Me</button>
220
+ ```
221
+
276
222
  ### Generated Output
277
223
 
278
- The scanner generates a TypeScript file with all discovered annotations:
224
+ The scanner generates a TypeScript file with all discovered components:
279
225
 
280
226
  ```typescript
281
227
  // Auto-generated by uidex scanner
282
228
  // Do not edit this file manually
283
229
 
284
- export const annotations = {
230
+ import { registerComponents } from 'uidex';
231
+
232
+ export const components = {
285
233
  "cta-button": [{ filePath: "src/pages/Home.tsx", line: 12 }],
286
234
  "main-nav": [{ filePath: "src/components/Header.tsx", line: 5 }]
287
- } as const;
235
+ };
236
+
237
+ export const componentIds = ["cta-button", "main-nav"] as const;
288
238
 
289
- export const annotationIds = ["cta-button", "main-nav"] as const;
239
+ export type ComponentId = typeof componentIds[number];
290
240
 
291
- export type AnnotationId = typeof annotationIds[number];
241
+ // Auto-register components
242
+ registerComponents(components);
292
243
  ```
293
244
 
294
245
  ### Using Generated Types
295
246
 
296
- Import the generated types for type-safe annotation access:
247
+ Import the generated types for type-safe component access:
297
248
 
298
249
  ```tsx
299
- import { annotations, AnnotationId } from './generated/annotations';
250
+ import { components, ComponentId } from './uidex.gen';
300
251
 
301
- function highlightElement(id: AnnotationId) {
302
- const locations = annotations[id];
252
+ function highlightElement(id: ComponentId) {
253
+ const locations = components[id];
303
254
  console.log(`Found at: ${locations[0].filePath}:${locations[0].line}`);
304
255
  }
305
256
 
306
- // Type error: "invalid-id" is not a valid AnnotationId
257
+ // Type error: "invalid-id" is not a valid ComponentId
307
258
  highlightElement("invalid-id");
308
259
  ```
309
260
 
310
261
  ## TypeScript
311
262
 
312
- This package is written in TypeScript and includes full type definitions. All types are exported:
263
+ This package is written in TypeScript and includes full type definitions:
313
264
 
314
265
  ```tsx
315
266
  import type {
316
- AnnotateProps,
317
- AnnotateProviderProps,
267
+ UidexConfig,
268
+ UidexDefaults,
269
+ UidexDevtoolsProps,
270
+ UidexOverlayProps,
271
+ UidexLocation,
272
+ UidexMap,
318
273
  BorderStyle,
319
- HighlightOverlayProps,
320
274
  LabelPosition,
321
- ReactAnnotateConfig,
322
- ReactAnnotateDefaults,
323
- UseAnnotationOptions,
324
- UseHighlightOptions,
275
+ ButtonPosition,
325
276
  } from 'uidex';
326
277
  ```
327
278
 
@@ -0,0 +1,16 @@
1
+ Run `npx uidex scan --check` and fix all reported issues:
2
+
3
+ 1. **Uncovered components** (components missing UIDEX_PAGE.md coverage):
4
+ - Create a `UIDEX_PAGE.md` in the nearest feature directory
5
+ - Include a heading, brief description, and acceptance criteria
6
+
7
+ 2. **Orphaned UIDEX_PAGE.md files** (docs with no components underneath):
8
+ - If the components were removed, delete the UIDEX_PAGE.md
9
+ - If components are missing `data-uidex` attributes, add them
10
+
11
+ 3. **Review interactive elements** without `data-uidex` attributes:
12
+ - Scan modified files for buttons, inputs, links, and other interactive elements
13
+ - Add `data-uidex="kebab-id"` attributes where missing
14
+ - Add `/** @uidex id - description */` JSDoc above each annotated element
15
+
16
+ After fixing all issues, run `npx uidex scan` to regenerate the component registry.
@@ -0,0 +1,88 @@
1
+ # uidex conventions
2
+
3
+ This project uses [uidex](https://github.com/soel/uidex) for UI element tracking and documentation.
4
+
5
+ ## data-uidex attributes
6
+
7
+ - Every user-facing interactive element MUST have a `data-uidex="kebab-id"` attribute.
8
+ - IDs should be descriptive and kebab-cased: `data-uidex="submit-btn"`, `data-uidex="user-avatar"`.
9
+ - When creating new components with interactive elements, always add `data-uidex` attributes.
10
+ - When modifying components, preserve existing `data-uidex` attributes. If you rename or remove an element, update or remove its attribute accordingly.
11
+
12
+ ## @uidex JSDoc comments
13
+
14
+ Add a JSDoc comment above annotated elements describing their purpose:
15
+
16
+ ```tsx
17
+ /** @uidex submit-btn - Primary action button for form submission */
18
+ <button data-uidex="submit-btn">Submit</button>
19
+ ```
20
+
21
+ Multi-line format for longer descriptions:
22
+
23
+ ```tsx
24
+ /**
25
+ * @uidex user-profile-card
26
+ * Displays user avatar, name, and role.
27
+ * Shown in the sidebar and team directory.
28
+ */
29
+ <div data-uidex="user-profile-card">...</div>
30
+ ```
31
+
32
+ ## UIDEX_PAGE.md files
33
+
34
+ Page docs describe a route/view. Components in the directory are automatically associated.
35
+
36
+ - Each page directory should have a `UIDEX_PAGE.md` with acceptance criteria.
37
+ - When adding components to a directory that lacks a `UIDEX_PAGE.md`, create one.
38
+ - When removing all components from a directory, remove its `UIDEX_PAGE.md`.
39
+
40
+ ```markdown
41
+ # Page Name
42
+
43
+ Brief description of the page.
44
+
45
+ ## Acceptance
46
+ - User can do X
47
+ - Y is displayed when Z
48
+ ```
49
+
50
+ ## UIDEX_FEATURE.md files
51
+
52
+ Feature docs describe a cross-cutting feature. Components are explicitly listed via frontmatter.
53
+
54
+ - Use `UIDEX_FEATURE.md` for features that span multiple pages (e.g., auth, billing).
55
+ - List associated component IDs in the `components:` frontmatter.
56
+
57
+ ```markdown
58
+ ---
59
+ components:
60
+ - login-form
61
+ - signup-btn
62
+ ---
63
+ # Feature Name
64
+
65
+ Brief description of the feature.
66
+
67
+ ## Acceptance
68
+ - User can do X
69
+ - Y is displayed when Z
70
+ ```
71
+
72
+ ## Component registry
73
+
74
+ For a project-wide view of all components, pages, and features, read the generated registry file (default: `src/uidex.gen.ts`). This file is kept up to date by the scanner.
75
+
76
+ ## Scanner
77
+
78
+ After adding, removing, or renaming `data-uidex` attributes, run:
79
+
80
+ ```bash
81
+ npx uidex scan
82
+ ```
83
+
84
+ To validate that all components have UIDEX_PAGE.md coverage:
85
+
86
+ ```bash
87
+ npx uidex scan --check
88
+ ```