annotate-kit 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.
@@ -0,0 +1,211 @@
1
+ /* annotate-kit — self-contained stylesheet.
2
+ The overlay keeps HRMS's Tailwind class names; this file compiles JUST the utilities it uses,
3
+ with the design tokens given concrete values. Tailwind's global reset (preflight) is deliberately
4
+ NOT imported — instead a tiny reset scoped to [data-annot-ui] runs, so dropping this CSS into ANY
5
+ app (Tailwind or not, tokens or not) styles the widget correctly and touches nothing else. */
6
+
7
+ @layer theme, base, components, utilities;
8
+ @import "tailwindcss/theme.css" layer(theme);
9
+ @import "tailwindcss/utilities.css" layer(utilities);
10
+
11
+ /* Only scan the widget's own source for class names. */
12
+ @source "../Annotate.tsx";
13
+ @source "../constants.ts";
14
+
15
+ /* ── Design tokens (values lifted verbatim from the HRMS "Trust Enterprise Light" system) ── */
16
+ @theme {
17
+ --color-canvas: #f6f8fb;
18
+ --color-surface: #ffffff;
19
+ --color-elevated: #ffffff;
20
+ --color-sunken: #f1f5f9;
21
+ --color-sidebar: #fbfcfe;
22
+ --color-table-head: #f3f6fa;
23
+ --color-row-alt: #fafbfd;
24
+
25
+ --color-fg: #0f172a;
26
+ --color-fg-secondary: #334155;
27
+ --color-fg-muted: #64748b;
28
+ --color-fg-disabled: #94a3b8;
29
+ --color-ink-hover: #334155;
30
+
31
+ --color-line: #e9eef5;
32
+ --color-line-strong: #d8e0ea;
33
+ --color-line-brand: #e0e3ff;
34
+
35
+ --color-brand: #6366f1;
36
+ --color-brand-strong: #4f46e5;
37
+ --color-brand-deep: #4338ca;
38
+ --color-brand-2: #8b5cf6;
39
+ --color-brand-tint: #eef0ff;
40
+ --color-brand-hairline: #e0e3ff;
41
+
42
+ --color-accent: #f59e0b;
43
+ --color-accent-text: #b45309;
44
+ --color-accent-tint: #fffbeb;
45
+ --color-accent-hairline: #fde68a;
46
+
47
+ --color-success: #059669;
48
+ --color-success-text: #047857;
49
+ --color-success-tint: #ecfdf5;
50
+ --color-success-hairline: #a7f3d0;
51
+ --color-warning: #f59e0b;
52
+ --color-warning-text: #b45309;
53
+ --color-warning-tint: #fffbeb;
54
+ --color-warning-hairline: #fde68a;
55
+ --color-danger: #dc2626;
56
+ --color-danger-text: #b91c1c;
57
+ --color-danger-tint: #fef2f2;
58
+ --color-danger-hairline: #fecaca;
59
+ --color-info: #2563eb;
60
+ --color-info-text: #1d4ed8;
61
+ --color-info-tint: #eff6ff;
62
+ --color-info-hairline: #bfdbfe;
63
+ --color-neutral-tint: #f1f5f9;
64
+
65
+ --radius-input: 0.625rem;
66
+ --radius-control: 0.625rem;
67
+ --radius-card: 0.875rem;
68
+ --radius-modal: 1.25rem;
69
+
70
+ --shadow-e1: 0 1px 2px rgba(16, 24, 40, 0.05);
71
+ --shadow-e2: 0 1px 3px rgba(16, 24, 40, 0.08), 0 1px 2px rgba(16, 24, 40, 0.06);
72
+ --shadow-e3: 0 8px 24px -6px rgba(16, 24, 40, 0.12);
73
+ --shadow-e4: 0 20px 48px -16px rgba(16, 24, 40, 0.28);
74
+ --shadow-brand: 0 10px 28px -10px rgba(99, 102, 241, 0.45);
75
+ }
76
+
77
+ /* ── Scoped reset — replaces preflight, ONLY inside the overlay ──────────────────────────────
78
+ Re-pinning the token vars here means the widget looks identical even if the host app happens to
79
+ define its own --color-surface / --color-fg-* etc. at :root. */
80
+ [data-annot-ui] {
81
+ box-sizing: border-box;
82
+ font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
83
+ line-height: 1.4;
84
+ -webkit-font-smoothing: antialiased;
85
+ color: var(--color-fg-secondary); /* base text colour — inputs inherit this, so typed text stays readable in every theme */
86
+
87
+ --color-canvas: #f6f8fb;
88
+ --color-surface: #ffffff;
89
+ --color-sunken: #f1f5f9;
90
+ --color-row-alt: #fafbfd;
91
+ --color-fg: #0f172a;
92
+ --color-fg-secondary: #334155;
93
+ --color-fg-muted: #64748b;
94
+ --color-fg-disabled: #94a3b8;
95
+ --color-ink-hover: #334155;
96
+ --color-line: #e9eef5;
97
+ --color-line-strong: #d8e0ea;
98
+ --color-brand: #6366f1;
99
+ --color-brand-strong: #4f46e5;
100
+ --color-brand-tint: #eef0ff;
101
+ --color-brand-hairline: #e0e3ff;
102
+ --color-success: #059669;
103
+ --color-success-text: #047857;
104
+ --color-success-tint: #ecfdf5;
105
+ --color-success-hairline: #a7f3d0;
106
+ --color-warning: #f59e0b;
107
+ --color-warning-text: #b45309;
108
+ --color-warning-tint: #fffbeb;
109
+ --color-warning-hairline: #fde68a;
110
+ --color-danger: #dc2626;
111
+ --color-danger-text: #b91c1c;
112
+ --color-danger-tint: #fef2f2;
113
+ --color-danger-hairline: #fecaca;
114
+ }
115
+
116
+ /* ── Dark theme — overrides the token vars when data-annot-theme="dark" (or "auto" + OS is dark).
117
+ --color-fg stays dark ON PURPOSE: it backs the inverted chrome (dock header, tooltips, scrims),
118
+ which keep white text in both themes. Text tokens (fg-secondary/muted) flip to light. ────────── */
119
+ [data-annot-ui][data-annot-theme="dark"],
120
+ [data-annot-theme="dark"] [data-annot-ui] {
121
+ --color-canvas: #0b1120;
122
+ --color-surface: #1e293b;
123
+ --color-sunken: #0f172a;
124
+ --color-row-alt: #263449;
125
+ --color-fg-secondary: #e2e8f0;
126
+ --color-fg-muted: #94a3b8;
127
+ --color-fg-disabled: #64748b;
128
+ --color-line: #334155;
129
+ --color-line-strong: #475569;
130
+ --color-brand-strong: #a5b4fc;
131
+ --color-brand-tint: #312e81;
132
+ --color-brand-hairline: #4338ca;
133
+ --color-success-text: #6ee7b7;
134
+ --color-success-tint: #064e3b;
135
+ --color-success-hairline: #065f46;
136
+ --color-warning-text: #fcd34d;
137
+ --color-warning-tint: #422006;
138
+ --color-warning-hairline: #78350f;
139
+ --color-danger-text: #fca5a5;
140
+ --color-danger-tint: #450a0a;
141
+ --color-danger-hairline: #7f1d1d;
142
+ }
143
+ @media (prefers-color-scheme: dark) {
144
+ [data-annot-ui][data-annot-theme="auto"],
145
+ [data-annot-theme="auto"] [data-annot-ui] {
146
+ --color-canvas: #0b1120;
147
+ --color-surface: #1e293b;
148
+ --color-sunken: #0f172a;
149
+ --color-row-alt: #263449;
150
+ --color-fg-secondary: #e2e8f0;
151
+ --color-fg-muted: #94a3b8;
152
+ --color-fg-disabled: #64748b;
153
+ --color-line: #334155;
154
+ --color-line-strong: #475569;
155
+ --color-brand-strong: #a5b4fc;
156
+ --color-brand-tint: #312e81;
157
+ --color-brand-hairline: #4338ca;
158
+ --color-success-text: #6ee7b7;
159
+ --color-success-tint: #064e3b;
160
+ --color-success-hairline: #065f46;
161
+ --color-warning-text: #fcd34d;
162
+ --color-warning-tint: #422006;
163
+ --color-warning-hairline: #78350f;
164
+ --color-danger-text: #fca5a5;
165
+ --color-danger-tint: #450a0a;
166
+ --color-danger-hairline: #7f1d1d;
167
+ }
168
+ }
169
+ [data-annot-ui] *,
170
+ [data-annot-ui] *::before,
171
+ [data-annot-ui] *::after {
172
+ box-sizing: border-box;
173
+ }
174
+ [data-annot-ui] button {
175
+ margin: 0;
176
+ padding: 0;
177
+ border: 0;
178
+ background: none;
179
+ font: inherit;
180
+ color: inherit;
181
+ line-height: inherit;
182
+ cursor: pointer;
183
+ }
184
+ [data-annot-ui] button:disabled {
185
+ cursor: default;
186
+ }
187
+ [data-annot-ui] input,
188
+ [data-annot-ui] textarea,
189
+ [data-annot-ui] select {
190
+ font: inherit;
191
+ color: inherit;
192
+ margin: 0;
193
+ }
194
+ [data-annot-ui] textarea {
195
+ line-height: 1.4;
196
+ }
197
+ [data-annot-ui] p,
198
+ [data-annot-ui] pre {
199
+ margin: 0;
200
+ }
201
+ [data-annot-ui] svg {
202
+ display: inline-block;
203
+ vertical-align: middle;
204
+ flex-shrink: 0;
205
+ }
206
+ [data-annot-ui] a {
207
+ color: inherit;
208
+ }
209
+ [data-annot-ui] kbd {
210
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
211
+ }
package/src/types.ts ADDED
@@ -0,0 +1,71 @@
1
+ // Data shapes for a single annotation. Kept identical to the HRMS "Live Annotate" model so rows
2
+ // migrate 1:1, but with zero backend/framework coupling — this file is pure types.
3
+
4
+ export type AnnType = 'change' | 'add' | 'remove' | 'bug' | 'style' | 'question'
5
+ export type AnnPriority = 'low' | 'med' | 'high'
6
+ export type AnnStatus = 'open' | 'in_progress' | 'done' | 'dismissed'
7
+ export type AnnKind = 'pin' | 'shape'
8
+ export type AnnShape = 'rect' | 'arrow' | 'circle' | 'freehand'
9
+ export type AnnVisibility = 'public' | 'private'
10
+
11
+ export type AnnReply = { note: string; author?: string; at?: string }
12
+ export type AnnPoint = { x: number; y: number }
13
+ export type AnnMeta = { browser?: string; os?: string; device?: string; viewport?: string; screen?: string; dpr?: number; url?: string; ua?: string }
14
+ export type AnnLog = { level: string; text: string; at?: string }
15
+ export type AnnNetLog = { method: string; url: string; status?: number; ms?: number; ok?: boolean; at?: string }
16
+
17
+ export type Annotation = {
18
+ id: number
19
+ page_route: string
20
+ page_title: string
21
+ target_selector: string
22
+ target_text: string
23
+ pos_x: number
24
+ pos_y: number
25
+ viewport_w: number
26
+ viewport_h: number
27
+ note: string
28
+ type: AnnType
29
+ priority: AnnPriority
30
+ status: AnnStatus
31
+ screenshot_path?: string | null
32
+ screenshot_url?: string | null
33
+ replies?: AnnReply[]
34
+ created_by?: string
35
+ created_at?: string
36
+ updated_at?: string
37
+ // shapes + visibility + author snapshot + captured element styles
38
+ kind?: AnnKind
39
+ shape_type?: AnnShape | null
40
+ x2?: number | null
41
+ y2?: number | null
42
+ points?: AnnPoint[] | null
43
+ color?: string | null
44
+ visibility?: AnnVisibility
45
+ created_by_role?: string | null
46
+ created_by_name?: string | null
47
+ styles?: Record<string, string> | null
48
+ el_context?: string[] | null
49
+ // auto technical context + captured console/JS errors (reproducible bug reports)
50
+ meta?: AnnMeta | null
51
+ console_logs?: AnnLog[] | null
52
+ network_logs?: AnnNetLog[] | null
53
+ dom_snapshot?: string | null
54
+ }
55
+
56
+ // What the overlay hands the adapter to persist a new mark (server assigns id/timestamps/author).
57
+ export type NewAnnotation = Omit<Annotation, 'id' | 'status' | 'created_at' | 'updated_at' | 'screenshot_url' | 'created_by' | 'created_by_role' | 'created_by_name'> & {
58
+ screenshot_path?: string | null
59
+ }
60
+
61
+ // A partial edit (status / note / type / priority) applied by id.
62
+ export type AnnotationPatch = { id: number } & Partial<Pick<Annotation, 'note' | 'status' | 'type' | 'priority'>>
63
+
64
+ // The current viewer + their permission envelope, resolved by the adapter.
65
+ export type AnnotateAccess = {
66
+ enabled: boolean // global toggle: is the tool shown to all users, or ADMIN-only?
67
+ isAdmin: boolean // can flip the global toggle + clear-resolved
68
+ canUse: boolean // may see/use the tool at all (enabled || isAdmin)
69
+ seeAll: boolean // sees everyone's marks + can edit them (else own + public only)
70
+ me?: { email?: string; name?: string; role?: string }
71
+ }