web-remarq 0.1.0 → 0.1.1
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.
- package/README.md +142 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# web-remarq
|
|
2
|
+
|
|
3
|
+
Visual annotation tool for design review workflows. Framework-agnostic, zero dependencies.
|
|
4
|
+
|
|
5
|
+
Designer annotates UI elements on staging/dev, exports a report. Developer imports the report and sees markers on the exact elements.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install web-remarq
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { WebRemarq } from 'web-remarq'
|
|
17
|
+
|
|
18
|
+
WebRemarq.init({ theme: 'light' })
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Script tag
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<script src="https://unpkg.com/web-remarq/dist/web-remarq.global.global.js"></script>
|
|
25
|
+
<script>WebRemarq.init({ theme: 'dark' })</script>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## API
|
|
29
|
+
|
|
30
|
+
### `WebRemarq.init(options?)`
|
|
31
|
+
|
|
32
|
+
Initialize the tool. Idempotent — safe to call multiple times.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
WebRemarq.init({
|
|
36
|
+
theme: 'light', // 'light' | 'dark'
|
|
37
|
+
classFilter: (name) => boolean, // custom class filter for fingerprinting
|
|
38
|
+
dataAttribute: 'data-annotate', // which data-attr to use as stable anchor
|
|
39
|
+
})
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### `WebRemarq.destroy()`
|
|
43
|
+
|
|
44
|
+
Remove all DOM nodes, event listeners, and observers. Full cleanup.
|
|
45
|
+
|
|
46
|
+
### `WebRemarq.setTheme(theme)`
|
|
47
|
+
|
|
48
|
+
Switch between `'light'` and `'dark'` themes.
|
|
49
|
+
|
|
50
|
+
### `WebRemarq.export(format)`
|
|
51
|
+
|
|
52
|
+
- `'md'` — copies markdown report to clipboard
|
|
53
|
+
- `'json'` — downloads `.json` file with full annotation data
|
|
54
|
+
|
|
55
|
+
### `WebRemarq.import(file)`
|
|
56
|
+
|
|
57
|
+
Import annotations from a JSON file. Returns `Promise<{ total, matched, detached }>`.
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
const input = document.querySelector('input[type="file"]')
|
|
61
|
+
const result = await WebRemarq.import(input.files[0])
|
|
62
|
+
// { total: 12, matched: 10, detached: 2 }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### `WebRemarq.getAnnotations(route?)`
|
|
66
|
+
|
|
67
|
+
Get all annotations, or filter by route.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
WebRemarq.getAnnotations() // all
|
|
71
|
+
WebRemarq.getAnnotations('/casino') // by route
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### `WebRemarq.clearAll()`
|
|
75
|
+
|
|
76
|
+
Remove all annotations.
|
|
77
|
+
|
|
78
|
+
## Core-only usage
|
|
79
|
+
|
|
80
|
+
For programmatic access without UI:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { createFingerprint, matchElement, AnnotationStorage } from 'web-remarq/core'
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## How It Works
|
|
87
|
+
|
|
88
|
+
### Fingerprinting
|
|
89
|
+
|
|
90
|
+
When a user clicks an element, a multi-signal fingerprint is captured:
|
|
91
|
+
|
|
92
|
+
- **Stable anchors** — `data-annotate`, `data-testid`, `id`
|
|
93
|
+
- **Semantics** — tag name, text content, ARIA role/label
|
|
94
|
+
- **Structure** — stable CSS classes (hashes stripped), DOM path, sibling index
|
|
95
|
+
- **Parent context** — nearest ancestor's `data-annotate` value
|
|
96
|
+
|
|
97
|
+
### Matching
|
|
98
|
+
|
|
99
|
+
When loading annotations, elements are found via a fallback chain:
|
|
100
|
+
|
|
101
|
+
1. Exact match by `data-annotate` or `data-testid`
|
|
102
|
+
2. Exact match by `id`
|
|
103
|
+
3. Fuzzy match using weighted scoring (text similarity, ARIA, classes, DOM path)
|
|
104
|
+
4. Unmatched annotations go to a "detached" panel
|
|
105
|
+
|
|
106
|
+
### Hash Detection
|
|
107
|
+
|
|
108
|
+
Automatically strips hashed classes from CSS Modules, styled-components, Emotion, and pure hash patterns.
|
|
109
|
+
|
|
110
|
+
### SPA Support
|
|
111
|
+
|
|
112
|
+
Listens for `popstate`, `hashchange`, and intercepts `history.pushState`/`replaceState`. Annotations are scoped per route (`pathname + hash`).
|
|
113
|
+
|
|
114
|
+
## Stable Selectors
|
|
115
|
+
|
|
116
|
+
Works without any markup changes, but for guaranteed stable matching add `data-annotate` to key components:
|
|
117
|
+
|
|
118
|
+
```html
|
|
119
|
+
<CasinoTabs data-annotate="casino-tabs" />
|
|
120
|
+
<SearchBar data-annotate="search-bar" />
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## UI Components
|
|
124
|
+
|
|
125
|
+
- **Toolbar** — fixed bottom-right panel with inspect, export, import, clear, theme, minimize
|
|
126
|
+
- **Inspect mode** — hover to highlight, click to annotate
|
|
127
|
+
- **Markers** — numbered circles (orange = pending, green = resolved)
|
|
128
|
+
- **Popup** — comment input for new annotations, detail view with Resolve/Delete for existing
|
|
129
|
+
- **Detached panel** — shows annotations whose elements can't be found
|
|
130
|
+
|
|
131
|
+
## Build Outputs
|
|
132
|
+
|
|
133
|
+
| Format | File | Use |
|
|
134
|
+
|--------|------|-----|
|
|
135
|
+
| ESM | `dist/index.js` | Bundlers |
|
|
136
|
+
| CJS | `dist/index.cjs` | `require()` |
|
|
137
|
+
| IIFE | `dist/web-remarq.global.global.js` | `<script>` tag |
|
|
138
|
+
| Types | `dist/index.d.ts` | TypeScript |
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
MIT
|