skema-core 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,356 @@
1
+ import React from 'react';
2
+
3
+ /**
4
+ * Represents a single DOM element in a selection
5
+ */
6
+ interface DOMElement {
7
+ selector: string;
8
+ tagName: string;
9
+ elementPath: string;
10
+ text: string;
11
+ boundingBox: BoundingBox;
12
+ cssClasses?: string;
13
+ attributes?: Record<string, string>;
14
+ }
15
+ /**
16
+ * Represents a DOM element selection (can contain one or more elements)
17
+ */
18
+ interface DOMSelection {
19
+ id: string;
20
+ selector: string;
21
+ tagName: string;
22
+ elementPath: string;
23
+ text: string;
24
+ boundingBox: BoundingBox;
25
+ timestamp: number;
26
+ pathname: string;
27
+ cssClasses?: string;
28
+ attributes?: Record<string, string>;
29
+ /** User annotation comment */
30
+ comment?: string;
31
+ /** Whether this is a multi-element selection */
32
+ isMultiSelect?: boolean;
33
+ /** Individual elements when this is a grouped selection */
34
+ elements?: DOMElement[];
35
+ }
36
+ /**
37
+ * Pending annotation state for the popup
38
+ */
39
+ interface PendingAnnotation {
40
+ /** Screen X position (percentage of viewport width) */
41
+ x: number;
42
+ /** Screen Y position (pixels from top of document) */
43
+ y: number;
44
+ /** Y position relative to viewport (for popup positioning) */
45
+ clientY: number;
46
+ /** Element identifier string */
47
+ element: string;
48
+ /** CSS selector path */
49
+ elementPath: string;
50
+ /** Selected text content if any */
51
+ selectedText?: string;
52
+ /** Bounding box of selected element(s) */
53
+ boundingBox?: BoundingBox;
54
+ /** Whether this is a multi-element selection */
55
+ isMultiSelect?: boolean;
56
+ /** The DOM selection(s) being annotated */
57
+ selections?: DOMSelection[];
58
+ /** Type of annotation */
59
+ annotationType: 'dom_selection' | 'drawing';
60
+ /** Drawing shape IDs if annotating drawings */
61
+ shapeIds?: string[];
62
+ }
63
+ /**
64
+ * Bounding box for element positioning
65
+ */
66
+ interface BoundingBox {
67
+ x: number;
68
+ y: number;
69
+ width: number;
70
+ height: number;
71
+ }
72
+ /**
73
+ * Viewport information for coordinate calculations
74
+ */
75
+ interface ViewportInfo {
76
+ width: number;
77
+ height: number;
78
+ scrollX: number;
79
+ scrollY: number;
80
+ }
81
+ /**
82
+ * Computed styles for an element
83
+ */
84
+ interface ElementStyles {
85
+ fontFamily?: string;
86
+ fontSize?: string;
87
+ fontWeight?: string;
88
+ lineHeight?: string;
89
+ letterSpacing?: string;
90
+ textAlign?: string;
91
+ color?: string;
92
+ padding?: string;
93
+ margin?: string;
94
+ gap?: string;
95
+ display?: string;
96
+ flexDirection?: string;
97
+ alignItems?: string;
98
+ justifyContent?: string;
99
+ backgroundColor?: string;
100
+ borderRadius?: string;
101
+ border?: string;
102
+ boxShadow?: string;
103
+ width?: string;
104
+ height?: string;
105
+ maxWidth?: string;
106
+ }
107
+ /**
108
+ * Nearby element with style context for AI
109
+ */
110
+ interface NearbyElement {
111
+ selector: string;
112
+ tagName: string;
113
+ text?: string;
114
+ className?: string;
115
+ styles?: ElementStyles;
116
+ tailwindClasses?: string[];
117
+ }
118
+ /**
119
+ * Project-level style context
120
+ */
121
+ interface ProjectStyleContext {
122
+ cssFramework?: 'tailwind' | 'bootstrap' | 'material-ui' | 'chakra' | 'vanilla' | 'css-modules' | 'styled-components' | 'unknown';
123
+ cssVariables?: Record<string, string>;
124
+ colorPalette?: string[];
125
+ baseFontFamily?: string;
126
+ baseFontSize?: string;
127
+ }
128
+ /**
129
+ * Drawing annotation from tldraw
130
+ */
131
+ interface DrawingAnnotation {
132
+ id: string;
133
+ type: 'drawing';
134
+ tool: string;
135
+ shapes: unknown[];
136
+ boundingBox: BoundingBox;
137
+ relatedTo?: string;
138
+ timestamp: number;
139
+ /** User annotation comment describing what to build */
140
+ comment?: string;
141
+ /** SVG representation of the drawing for AI processing */
142
+ drawingSvg?: string;
143
+ /** Base64 PNG image of the drawing for vision AI */
144
+ drawingImage?: string;
145
+ /** Extracted text content from text shapes in the drawing */
146
+ extractedText?: string;
147
+ /** Grid configuration used for positioning reference */
148
+ gridConfig?: {
149
+ color: string;
150
+ size: number;
151
+ labels: boolean;
152
+ };
153
+ /** Viewport info for relative sizing context */
154
+ viewport?: ViewportInfo;
155
+ /** Project-level style context */
156
+ projectStyles?: ProjectStyleContext;
157
+ /** Nearby DOM elements that the drawing may relate to */
158
+ nearbyElements?: NearbyElement[];
159
+ }
160
+ /**
161
+ * Gesture action annotation
162
+ */
163
+ interface GestureAnnotation {
164
+ id: string;
165
+ type: 'gesture';
166
+ gesture: 'scribble_delete' | 'circle' | 'rectangle' | 'arrow';
167
+ target?: string;
168
+ boundingBox: BoundingBox;
169
+ timestamp: number;
170
+ }
171
+ /**
172
+ * Union type for all annotation types
173
+ */
174
+ type Annotation = {
175
+ type: 'dom_selection';
176
+ } & DOMSelection | DrawingAnnotation | GestureAnnotation;
177
+ /**
178
+ * Complete export format for annotations
179
+ */
180
+ interface AnnotationExport {
181
+ version: string;
182
+ timestamp: string;
183
+ viewport: ViewportInfo;
184
+ pathname: string;
185
+ annotations: Annotation[];
186
+ }
187
+ /**
188
+ * Skema component props
189
+ */
190
+ interface SkemaProps {
191
+ /** Whether Skema overlay is enabled */
192
+ enabled?: boolean;
193
+ /** Callback when annotations change */
194
+ onAnnotationsChange?: (annotations: Annotation[]) => void;
195
+ /** Callback when a single annotation is submitted - for real-time integrations like Gemini */
196
+ onAnnotationSubmit?: (annotation: Annotation, comment: string) => void;
197
+ /** Callback when an annotation is deleted - for reverting changes */
198
+ onAnnotationDelete?: (annotationId: string) => void;
199
+ /** Keyboard shortcut to toggle Skema (default: Cmd/Ctrl + Shift + E) */
200
+ toggleShortcut?: string;
201
+ /** Initial annotations to load */
202
+ initialAnnotations?: Annotation[];
203
+ /** Z-index for the overlay (default: 99999) */
204
+ zIndex?: number;
205
+ }
206
+ /**
207
+ * Skema mode - determines what tools are available
208
+ */
209
+ type SkemaMode = 'select' | 'draw';
210
+
211
+ /**
212
+ * Main Skema component - renders tldraw as a transparent overlay
213
+ */
214
+ declare const Skema: React.FC<SkemaProps>;
215
+
216
+ interface AnnotationPopupProps {
217
+ /** Element name/description to display in header */
218
+ element: string;
219
+ /** Optional selected/highlighted text */
220
+ selectedText?: string;
221
+ /** Placeholder text for the textarea */
222
+ placeholder?: string;
223
+ /** Initial value for textarea (for edit mode) */
224
+ initialValue?: string;
225
+ /** Label for submit button (default: "Add") */
226
+ submitLabel?: string;
227
+ /** Called when annotation is submitted with text */
228
+ onSubmit: (text: string) => void;
229
+ /** Called when popup is cancelled/dismissed */
230
+ onCancel: () => void;
231
+ /** Position styles (left, top) */
232
+ style?: React.CSSProperties;
233
+ /** Custom accent color (hex) */
234
+ accentColor?: string;
235
+ /** External exit state (parent controls exit animation) */
236
+ isExiting?: boolean;
237
+ /** Whether this is a multi-select annotation */
238
+ isMultiSelect?: boolean;
239
+ }
240
+ interface AnnotationPopupHandle {
241
+ /** Shake the popup (e.g., when user clicks outside) */
242
+ shake: () => void;
243
+ }
244
+ declare const AnnotationPopup: React.ForwardRefExoticComponent<AnnotationPopupProps & React.RefAttributes<AnnotationPopupHandle>>;
245
+
246
+ /**
247
+ * Generates a unique CSS selector for an element
248
+ */
249
+ declare function generateSelector(element: HTMLElement): string;
250
+ /**
251
+ * Gets a readable path for an element (e.g., "article > section > p")
252
+ */
253
+ declare function getElementPath(target: HTMLElement, maxDepth?: number): string;
254
+ /**
255
+ * Identifies an element and returns a human-readable name
256
+ */
257
+ declare function identifyElement(target: HTMLElement): string;
258
+ /**
259
+ * Gets bounding box for an element in document coordinates (includes scroll offset)
260
+ */
261
+ declare function getBoundingBox(element: HTMLElement): BoundingBox;
262
+ /**
263
+ * Gets CSS class names from an element (cleaned of module hashes)
264
+ */
265
+ declare function getElementClasses(target: HTMLElement): string;
266
+ /**
267
+ * Creates a DOMSelection from an element
268
+ */
269
+ declare function createDOMSelection(element: HTMLElement): DOMSelection;
270
+ /**
271
+ * Checks if an element should be ignored for DOM picking
272
+ */
273
+ declare function shouldIgnoreElement(element: HTMLElement): boolean;
274
+
275
+ /**
276
+ * Gets current viewport information
277
+ */
278
+ declare function getViewportInfo(): ViewportInfo;
279
+ /**
280
+ * Converts viewport-relative coordinates to document coordinates
281
+ */
282
+ declare function viewportToDocument(x: number, y: number, viewport?: ViewportInfo): {
283
+ x: number;
284
+ y: number;
285
+ };
286
+ /**
287
+ * Converts document coordinates to viewport-relative coordinates
288
+ */
289
+ declare function documentToViewport(x: number, y: number, viewport?: ViewportInfo): {
290
+ x: number;
291
+ y: number;
292
+ };
293
+ /**
294
+ * Converts a bounding box from viewport to document coordinates
295
+ */
296
+ declare function bboxViewportToDocument(bbox: BoundingBox, viewport?: ViewportInfo): BoundingBox;
297
+ /**
298
+ * Converts a bounding box from document to viewport coordinates
299
+ */
300
+ declare function bboxDocumentToViewport(bbox: BoundingBox, viewport?: ViewportInfo): BoundingBox;
301
+ /**
302
+ * Checks if two bounding boxes intersect
303
+ */
304
+ declare function bboxIntersects(a: BoundingBox, b: BoundingBox): boolean;
305
+ /**
306
+ * Checks if point is inside bounding box
307
+ */
308
+ declare function pointInBbox(x: number, y: number, bbox: BoundingBox): boolean;
309
+ /**
310
+ * Gets the center point of a bounding box
311
+ */
312
+ declare function bboxCenter(bbox: BoundingBox): {
313
+ x: number;
314
+ y: number;
315
+ };
316
+ /**
317
+ * Expands a bounding box by a padding amount
318
+ */
319
+ declare function expandBbox(bbox: BoundingBox, padding: number): BoundingBox;
320
+ /**
321
+ * Creates a bounding box from two points
322
+ */
323
+ declare function bboxFromPoints(x1: number, y1: number, x2: number, y2: number): BoundingBox;
324
+
325
+ /**
326
+ * Convert a Blob to a base64 string
327
+ */
328
+ declare function blobToBase64(blob: Blob): Promise<string>;
329
+ /**
330
+ * Add a labeled grid overlay to an SVG string
331
+ * Grid uses A/B/C column labels and 0/1/2 row numbers for positioning reference
332
+ * @param svgString - The SVG markup to add grid to
333
+ * @param opts - Grid options (color, cell size, whether to show labels)
334
+ * @returns SVG string with grid overlay added
335
+ */
336
+ declare function addGridToSvg(svgString: string, opts?: {
337
+ color?: string;
338
+ size?: number;
339
+ labels?: boolean;
340
+ }): string;
341
+ /**
342
+ * Get the grid cell reference (e.g., "B2") for a given position
343
+ * @param x - X coordinate in pixels
344
+ * @param y - Y coordinate in pixels
345
+ * @param gridSize - Size of each grid cell (default 100px)
346
+ * @returns Grid cell reference string (e.g., "B2")
347
+ */
348
+ declare function getGridCellReference(x: number, y: number, gridSize?: number): string;
349
+ /**
350
+ * Extract text content from tldraw shapes
351
+ * @param shapes - Array of tldraw shapes
352
+ * @returns Combined text content from text and note shapes
353
+ */
354
+ declare function extractTextFromShapes(shapes: unknown[]): string;
355
+
356
+ export { type Annotation, type AnnotationExport, AnnotationPopup, type AnnotationPopupHandle, type AnnotationPopupProps, type BoundingBox, type DOMElement, type DOMSelection, type DrawingAnnotation, type ElementStyles, type GestureAnnotation, type NearbyElement, type PendingAnnotation, type ProjectStyleContext, Skema, type SkemaMode, type SkemaProps, type ViewportInfo, addGridToSvg, bboxCenter, bboxDocumentToViewport, bboxFromPoints, bboxIntersects, bboxViewportToDocument, blobToBase64, createDOMSelection, Skema as default, documentToViewport, expandBbox, extractTextFromShapes, generateSelector, getBoundingBox, getElementClasses, getElementPath, getGridCellReference, getViewportInfo, identifyElement, pointInBbox, shouldIgnoreElement, viewportToDocument };