@ewjdev/anyclick-react 1.1.1 → 1.3.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.
- package/README.md +31 -3
- package/dist/index.d.mts +491 -40
- package/dist/index.d.ts +491 -40
- package/dist/index.js +5211 -112
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5193 -111
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,175 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
3
|
-
export {
|
|
4
|
-
import * as
|
|
5
|
-
import { ReactNode, CSSProperties } from 'react';
|
|
2
|
+
import { AnyclickAdapter, AnyclickTriggerEvent, AnyclickType, AnyclickPayload, ScreenshotConfig, ScreenshotData, AnyclickMenuEvent } from '@ewjdev/anyclick-core';
|
|
3
|
+
export { ALL_CURATED_PROPERTIES, AccessibilityInfo, AnyclickAdapter, AnyclickPayload, AnyclickType, BoxModelInfo, CURATED_STYLE_PROPERTIES, ComputedStylesInfo, DEFAULT_SCREENSHOT_CONFIG, DEFAULT_SENSITIVE_SELECTORS, ElementContext, ElementInspectInfo, PageContext, ScreenshotCapture, ScreenshotCaptureMode, ScreenshotConfig, ScreenshotData, captureAllScreenshots, captureScreenshot, estimateTotalSize, formatBoxModel, formatBytes, formatStylesAsCSS, getAccessibilityInfo, getAttributes, getBoxModelInfo, getComputedStyles, getElementInspectInfo, isScreenshotSupported } from '@ewjdev/anyclick-core';
|
|
4
|
+
import * as React$1 from 'react';
|
|
5
|
+
import React__default, { ReactNode, CSSProperties } from 'react';
|
|
6
6
|
import * as zustand from 'zustand';
|
|
7
|
+
import * as zustand_middleware from 'zustand/middleware';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* IDE protocol handler integration for opening files directly in IDEs.
|
|
11
|
+
* Supports VS Code, Cursor, WebStorm, and other IDEs that support URL protocols.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Supported IDE protocol types
|
|
15
|
+
*/
|
|
16
|
+
type IDEProtocol = "vscode" | "cursor" | "webstorm" | "intellij" | "phpstorm" | "sublime" | "atom" | "custom";
|
|
17
|
+
/**
|
|
18
|
+
* Configuration for IDE integration
|
|
19
|
+
*/
|
|
20
|
+
interface IDEConfig {
|
|
21
|
+
/** The IDE protocol to use */
|
|
22
|
+
protocol: IDEProtocol;
|
|
23
|
+
/** Custom protocol string (only used when protocol is 'custom') */
|
|
24
|
+
customProtocol?: string;
|
|
25
|
+
/** Base path to prepend to file paths (for mapping web paths to file system) */
|
|
26
|
+
basePath?: string;
|
|
27
|
+
/** Path transformations to apply (regex find/replace) */
|
|
28
|
+
pathTransforms?: Array<{
|
|
29
|
+
find: string | RegExp;
|
|
30
|
+
replace: string;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Source location information
|
|
35
|
+
*/
|
|
36
|
+
interface SourceLocation {
|
|
37
|
+
/** File path */
|
|
38
|
+
file: string;
|
|
39
|
+
/** Line number (1-indexed) */
|
|
40
|
+
line: number;
|
|
41
|
+
/** Column number (1-indexed, optional) */
|
|
42
|
+
column?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build the URL for opening a file in an IDE
|
|
46
|
+
*/
|
|
47
|
+
declare function buildIDEUrl(location: SourceLocation, config?: Partial<IDEConfig>): string;
|
|
48
|
+
/**
|
|
49
|
+
* Open a file in the IDE using the protocol handler
|
|
50
|
+
*/
|
|
51
|
+
declare function openInIDE(location: SourceLocation, config?: Partial<IDEConfig>): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Check if the current environment likely supports IDE protocol handlers
|
|
54
|
+
* Note: This is a heuristic and may not be 100% accurate
|
|
55
|
+
*/
|
|
56
|
+
declare function isIDEProtocolSupported(): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Detect the most likely IDE based on environment
|
|
59
|
+
* This is a heuristic based on common development setups
|
|
60
|
+
*/
|
|
61
|
+
declare function detectPreferredIDE(): IDEProtocol;
|
|
62
|
+
/**
|
|
63
|
+
* Try to extract source location from element data attributes
|
|
64
|
+
*/
|
|
65
|
+
declare function getSourceLocationFromElement(element: Element): SourceLocation | null;
|
|
66
|
+
/**
|
|
67
|
+
* Walk up the DOM tree to find source location from any ancestor
|
|
68
|
+
*/
|
|
69
|
+
declare function findSourceLocationInAncestors(element: Element, maxDepth?: number): SourceLocation | null;
|
|
70
|
+
/**
|
|
71
|
+
* Create a configured IDE opener function
|
|
72
|
+
*/
|
|
73
|
+
declare function createIDEOpener(config?: Partial<IDEConfig>): (location: SourceLocation) => boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Format a source location as a readable string
|
|
76
|
+
*/
|
|
77
|
+
declare function formatSourceLocation(location: SourceLocation): string;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Position where the dialog is pinned
|
|
81
|
+
*/
|
|
82
|
+
type PinnedPosition = "left" | "right" | "top" | "bottom" | "floating";
|
|
83
|
+
/**
|
|
84
|
+
* Compact mode configuration type
|
|
85
|
+
* Adjust these values to control compact styling
|
|
86
|
+
*/
|
|
87
|
+
interface CompactModeConfig {
|
|
88
|
+
/** Base scaling factor (0.75 = 75% of normal size) */
|
|
89
|
+
scale: number;
|
|
90
|
+
/** Font sizes in pixels */
|
|
91
|
+
fonts: {
|
|
92
|
+
base: number;
|
|
93
|
+
title: number;
|
|
94
|
+
tag: number;
|
|
95
|
+
selector: number;
|
|
96
|
+
section: number;
|
|
97
|
+
badge: number;
|
|
98
|
+
property: number;
|
|
99
|
+
styleRow: number;
|
|
100
|
+
button: number;
|
|
101
|
+
};
|
|
102
|
+
/** Spacing (padding/margins) as CSS values */
|
|
103
|
+
spacing: {
|
|
104
|
+
headerPadding: string;
|
|
105
|
+
identityPadding: string;
|
|
106
|
+
sectionHeaderPadding: string;
|
|
107
|
+
sectionContentPadding: string;
|
|
108
|
+
footerPadding: string;
|
|
109
|
+
selectorCodePadding: string;
|
|
110
|
+
buttonPadding: string;
|
|
111
|
+
buttonPrimaryPadding: string;
|
|
112
|
+
buttonDangerPadding: string;
|
|
113
|
+
badgePadding: string;
|
|
114
|
+
propertyRowPadding: string;
|
|
115
|
+
styleRowPadding: string;
|
|
116
|
+
};
|
|
117
|
+
/** Gap values as CSS values */
|
|
118
|
+
gaps: {
|
|
119
|
+
headerTitle: string;
|
|
120
|
+
pinButtons: string;
|
|
121
|
+
propertyRow: string;
|
|
122
|
+
propertyValue: string;
|
|
123
|
+
button: string;
|
|
124
|
+
footer: string;
|
|
125
|
+
};
|
|
126
|
+
/** Size values in pixels */
|
|
127
|
+
sizes: {
|
|
128
|
+
dialogWidth: number;
|
|
129
|
+
closeButton: number;
|
|
130
|
+
copyButtonSmall: number;
|
|
131
|
+
styleValueMaxWidth: number;
|
|
132
|
+
categoryMarginBottom: number;
|
|
133
|
+
styleCategoryHeaderMarginBottom: number;
|
|
134
|
+
};
|
|
135
|
+
/** Letter spacing values */
|
|
136
|
+
letterSpacing: {
|
|
137
|
+
sectionTitle: string;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Default compact mode configuration
|
|
142
|
+
* Use this as a base to create custom configurations
|
|
143
|
+
*/
|
|
144
|
+
declare const DEFAULT_COMPACT_CONFIG: CompactModeConfig;
|
|
145
|
+
/**
|
|
146
|
+
* Props for the InspectDialog component
|
|
147
|
+
*/
|
|
148
|
+
interface InspectDialogProps {
|
|
149
|
+
/** Whether the dialog is visible */
|
|
150
|
+
visible: boolean;
|
|
151
|
+
/** The element being inspected */
|
|
152
|
+
targetElement: Element | null;
|
|
153
|
+
/** Callback when dialog is closed */
|
|
154
|
+
onClose: () => void;
|
|
155
|
+
/** Callback when selecting a different element (e.g., from modified elements list) */
|
|
156
|
+
onSelectElement?: (element: Element) => void;
|
|
157
|
+
/** IDE configuration for "Open in IDE" feature */
|
|
158
|
+
ideConfig?: Partial<IDEConfig>;
|
|
159
|
+
/** Custom styles for the dialog */
|
|
160
|
+
style?: React__default.CSSProperties;
|
|
161
|
+
/** Custom class name */
|
|
162
|
+
className?: string;
|
|
163
|
+
/** Custom highlight colors */
|
|
164
|
+
highlightColors?: HighlightColors;
|
|
165
|
+
/** Whether to show box model overlay (padding/margin visualization) */
|
|
166
|
+
showBoxModelOverlay?: boolean;
|
|
167
|
+
/** Initial pinned position. Defaults to "floating" (centered) */
|
|
168
|
+
initialPinnedPosition?: PinnedPosition;
|
|
169
|
+
/** Custom compact mode configuration. Partially override DEFAULT_COMPACT_CONFIG */
|
|
170
|
+
compactConfig?: Partial<CompactModeConfig>;
|
|
171
|
+
}
|
|
172
|
+
declare function InspectDialog({ visible, targetElement, onClose, onSelectElement, ideConfig, style, className, highlightColors, showBoxModelOverlay, initialPinnedPosition, compactConfig, }: InspectDialogProps): react_jsx_runtime.JSX.Element | null;
|
|
7
173
|
|
|
8
174
|
/**
|
|
9
175
|
* Theme configuration for AnyclickProvider
|
|
@@ -20,6 +186,22 @@ interface AnyclickTheme {
|
|
|
20
186
|
screenshotConfig?: ScreenshotConfig;
|
|
21
187
|
/** Whether anyclick functionality is disabled in this theme */
|
|
22
188
|
disabled?: boolean;
|
|
189
|
+
/**
|
|
190
|
+
* Enable fun mode (go-kart cursor) within this scoped provider.
|
|
191
|
+
* When true/configured, a FunModeBridge can hand off the track to the pointer.
|
|
192
|
+
*/
|
|
193
|
+
funMode?: boolean | FunModeThemeConfig;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Optional fun mode configuration (forwarded to pointer fun mode)
|
|
197
|
+
*/
|
|
198
|
+
interface FunModeThemeConfig {
|
|
199
|
+
/** Whether fun mode is enabled (default: true) */
|
|
200
|
+
enabled?: boolean;
|
|
201
|
+
/** Optional max speed override for this provider */
|
|
202
|
+
maxSpeed?: number;
|
|
203
|
+
/** Optional acceleration override */
|
|
204
|
+
acceleration?: number;
|
|
23
205
|
}
|
|
24
206
|
/**
|
|
25
207
|
* Menu positioning modes
|
|
@@ -55,26 +237,52 @@ interface HighlightConfig {
|
|
|
55
237
|
minChildrenForContainer?: number;
|
|
56
238
|
}
|
|
57
239
|
/**
|
|
58
|
-
* Menu item displayed in the
|
|
240
|
+
* Menu item displayed in the Anyclick context menu
|
|
59
241
|
*/
|
|
60
|
-
interface
|
|
242
|
+
interface ContextMenuItem {
|
|
61
243
|
/** Feedback type for this option (use unique identifier for parent items with children) */
|
|
62
|
-
type:
|
|
244
|
+
type: AnyclickType;
|
|
63
245
|
/** Display label */
|
|
64
246
|
label: string;
|
|
65
247
|
/** Optional icon */
|
|
66
248
|
icon?: ReactNode;
|
|
67
249
|
/** Whether to show a comment input for this type */
|
|
68
250
|
showComment?: boolean;
|
|
251
|
+
/** Optional status to signal availability (e.g., coming soon) */
|
|
252
|
+
status?: FeedbackMenuStatus;
|
|
253
|
+
/** Optional badge to render next to the label */
|
|
254
|
+
badge?: FeedbackMenuBadge;
|
|
69
255
|
/** Optional role(s) required to see this menu item */
|
|
70
256
|
requiredRoles?: string[];
|
|
71
257
|
/** Child menu items (creates a submenu) */
|
|
72
|
-
children?:
|
|
258
|
+
children?: ContextMenuItem[];
|
|
259
|
+
/**
|
|
260
|
+
* Optional click handler for custom behavior.
|
|
261
|
+
* Return `false` (or a Promise resolving to false) to skip the default submission flow.
|
|
262
|
+
*/
|
|
263
|
+
onClick?: (context: {
|
|
264
|
+
targetElement: Element | null;
|
|
265
|
+
containerElement: Element | null;
|
|
266
|
+
closeMenu: () => void;
|
|
267
|
+
}) => void | boolean | Promise<void | boolean>;
|
|
73
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Visual badge for menu items
|
|
271
|
+
*/
|
|
272
|
+
interface FeedbackMenuBadge {
|
|
273
|
+
/** Text shown inside the badge */
|
|
274
|
+
label: string;
|
|
275
|
+
/** Optional tone to drive styling */
|
|
276
|
+
tone?: "neutral" | "info" | "warning" | "success";
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Status of a menu item used for presets (e.g., coming soon)
|
|
280
|
+
*/
|
|
281
|
+
type FeedbackMenuStatus = "available" | "comingSoon";
|
|
74
282
|
/**
|
|
75
283
|
* User context for role-based menu filtering
|
|
76
284
|
*/
|
|
77
|
-
interface
|
|
285
|
+
interface AnyclickUserContext {
|
|
78
286
|
/** User's role(s) */
|
|
79
287
|
roles?: string[];
|
|
80
288
|
/** User ID */
|
|
@@ -85,23 +293,25 @@ interface FeedbackUserContext {
|
|
|
85
293
|
/**
|
|
86
294
|
* Filter menu items based on user context
|
|
87
295
|
*/
|
|
88
|
-
declare function filterMenuItemsByRole(items:
|
|
296
|
+
declare function filterMenuItemsByRole(items: ContextMenuItem[], userContext?: AnyclickUserContext): ContextMenuItem[];
|
|
89
297
|
/**
|
|
90
298
|
* Props for the AnyclickProvider component
|
|
91
299
|
*/
|
|
92
300
|
interface AnyclickProviderProps {
|
|
93
|
-
/**
|
|
94
|
-
|
|
301
|
+
/** Header content */
|
|
302
|
+
header?: ReactNode | null;
|
|
303
|
+
/** The adapter to use for submitting anyclick */
|
|
304
|
+
adapter: AnyclickAdapter;
|
|
95
305
|
/** Child components */
|
|
96
306
|
children: ReactNode;
|
|
97
307
|
/**
|
|
98
|
-
* Filter function to determine if
|
|
99
|
-
* Return true to allow
|
|
308
|
+
* Filter function to determine if anyclick should be captured for a target element
|
|
309
|
+
* Return true to allow anyclick, false to ignore
|
|
100
310
|
* Accepts both MouseEvent (right-click) and TouchEvent (press-and-hold)
|
|
101
311
|
*/
|
|
102
|
-
targetFilter?: (event:
|
|
312
|
+
targetFilter?: (event: AnyclickTriggerEvent, target: Element) => boolean;
|
|
103
313
|
/** Custom menu items (defaults to Issue, Feature, Like) */
|
|
104
|
-
menuItems?:
|
|
314
|
+
menuItems?: ContextMenuItem[];
|
|
105
315
|
/** Maximum length for innerText capture */
|
|
106
316
|
maxInnerTextLength?: number;
|
|
107
317
|
/** Maximum length for outerHTML capture */
|
|
@@ -115,9 +325,9 @@ interface AnyclickProviderProps {
|
|
|
115
325
|
/** Additional metadata to include with every submission */
|
|
116
326
|
metadata?: Record<string, unknown>;
|
|
117
327
|
/** Callback after successful submission */
|
|
118
|
-
onSubmitSuccess?: (payload:
|
|
328
|
+
onSubmitSuccess?: (payload: AnyclickPayload) => void;
|
|
119
329
|
/** Callback after failed submission */
|
|
120
|
-
onSubmitError?: (error: Error, payload:
|
|
330
|
+
onSubmitError?: (error: Error, payload: AnyclickPayload) => void;
|
|
121
331
|
/** Custom styles for the context menu */
|
|
122
332
|
menuStyle?: CSSProperties;
|
|
123
333
|
/** Custom class name for the context menu */
|
|
@@ -147,26 +357,22 @@ interface AnyclickProviderProps {
|
|
|
147
357
|
/** Menu positioning mode (default: 'inView') */
|
|
148
358
|
menuPositionMode?: MenuPositionMode;
|
|
149
359
|
}
|
|
150
|
-
/**
|
|
151
|
-
* @deprecated Use AnyclickProviderProps instead
|
|
152
|
-
*/
|
|
153
|
-
type FeedbackProviderProps = AnyclickProviderProps;
|
|
154
360
|
/**
|
|
155
361
|
* Context value exposed by AnyclickProvider
|
|
156
362
|
*/
|
|
157
363
|
interface AnyclickContextValue {
|
|
158
|
-
/** Whether
|
|
364
|
+
/** Whether anyclick is currently enabled */
|
|
159
365
|
isEnabled: boolean;
|
|
160
366
|
/** Whether a submission is in progress */
|
|
161
367
|
isSubmitting: boolean;
|
|
162
|
-
/** Submit
|
|
163
|
-
|
|
164
|
-
/** Open the
|
|
368
|
+
/** Submit anyclick for a specific element */
|
|
369
|
+
submitAnyclick: (element: Element, type: AnyclickType, comment?: string) => Promise<void>;
|
|
370
|
+
/** Open the anyclick menu programmatically */
|
|
165
371
|
openMenu: (element: Element, position: {
|
|
166
372
|
x: number;
|
|
167
373
|
y: number;
|
|
168
374
|
}) => void;
|
|
169
|
-
/** Close the
|
|
375
|
+
/** Close the anyclick menu */
|
|
170
376
|
closeMenu: () => void;
|
|
171
377
|
/** The current merged theme (inherited from ancestors) */
|
|
172
378
|
theme: AnyclickTheme;
|
|
@@ -175,10 +381,6 @@ interface AnyclickContextValue {
|
|
|
175
381
|
/** The provider's unique ID */
|
|
176
382
|
providerId: string;
|
|
177
383
|
}
|
|
178
|
-
/**
|
|
179
|
-
* @deprecated Use AnyclickContextValue instead
|
|
180
|
-
*/
|
|
181
|
-
type FeedbackContextValue = AnyclickContextValue;
|
|
182
384
|
/**
|
|
183
385
|
* Props for the context menu component
|
|
184
386
|
*/
|
|
@@ -190,14 +392,14 @@ interface ContextMenuProps {
|
|
|
190
392
|
x: number;
|
|
191
393
|
y: number;
|
|
192
394
|
};
|
|
193
|
-
/** Target element for
|
|
395
|
+
/** Target element for anyclick */
|
|
194
396
|
targetElement: Element | null;
|
|
195
397
|
/** Container element found by highlight logic */
|
|
196
398
|
containerElement: Element | null;
|
|
197
399
|
/** Menu items to display */
|
|
198
|
-
items:
|
|
400
|
+
items: ContextMenuItem[];
|
|
199
401
|
/** Callback when an item is selected */
|
|
200
|
-
onSelect: (type:
|
|
402
|
+
onSelect: (type: AnyclickType, comment?: string, screenshots?: ScreenshotData) => void;
|
|
201
403
|
/** Callback when menu is closed */
|
|
202
404
|
onClose: () => void;
|
|
203
405
|
/** Whether submission is in progress */
|
|
@@ -212,6 +414,10 @@ interface ContextMenuProps {
|
|
|
212
414
|
screenshotConfig?: ScreenshotConfig;
|
|
213
415
|
/** Menu positioning mode (default: 'inView') */
|
|
214
416
|
positionMode?: MenuPositionMode;
|
|
417
|
+
/** Header content */
|
|
418
|
+
header?: ReactNode;
|
|
419
|
+
/** Footer content */
|
|
420
|
+
footer?: ReactNode;
|
|
215
421
|
}
|
|
216
422
|
/**
|
|
217
423
|
* Props for the screenshot preview component
|
|
@@ -235,16 +441,23 @@ interface ScreenshotPreviewProps {
|
|
|
235
441
|
* AnyclickProvider component - wraps your app to enable feedback capture
|
|
236
442
|
* Supports scoped providers and nested theming
|
|
237
443
|
*/
|
|
238
|
-
declare function AnyclickProvider({ adapter, children, targetFilter, menuItems, maxInnerTextLength, maxOuterHTMLLength, maxAncestors, cooldownMs, stripAttributes, metadata, onSubmitSuccess, onSubmitError, menuStyle, menuClassName, disabled, highlightConfig, screenshotConfig, scoped, theme, touchHoldDurationMs, touchMoveThreshold, }: AnyclickProviderProps): react_jsx_runtime.JSX.Element;
|
|
444
|
+
declare function AnyclickProvider({ adapter, children, targetFilter, menuItems, maxInnerTextLength, maxOuterHTMLLength, maxAncestors, cooldownMs, stripAttributes, metadata, onSubmitSuccess, onSubmitError, menuStyle, menuClassName, disabled, highlightConfig, header, screenshotConfig, scoped, theme, touchHoldDurationMs, touchMoveThreshold, }: AnyclickProviderProps): react_jsx_runtime.JSX.Element;
|
|
239
445
|
/**
|
|
240
446
|
* @deprecated Use AnyclickProvider instead
|
|
241
447
|
*/
|
|
242
448
|
declare const FeedbackProvider: typeof AnyclickProvider;
|
|
243
449
|
|
|
450
|
+
/**
|
|
451
|
+
* FunModeBridge watches Anyclick scoped providers and toggles the pointer
|
|
452
|
+
* into fun mode (go-kart) when the cursor is within a provider with funMode enabled.
|
|
453
|
+
* Requires a PointerProvider higher in the tree.
|
|
454
|
+
*/
|
|
455
|
+
declare function FunModeBridge(): null;
|
|
456
|
+
|
|
244
457
|
/**
|
|
245
458
|
* Context menu component for selecting feedback type
|
|
246
459
|
*/
|
|
247
|
-
declare function ContextMenu({ visible, position, targetElement, containerElement, items, onSelect, onClose, isSubmitting, style, className, highlightConfig, screenshotConfig, positionMode, }: ContextMenuProps): react_jsx_runtime.JSX.Element | null;
|
|
460
|
+
declare function ContextMenu({ visible, position, targetElement, containerElement, items, onSelect, onClose, isSubmitting, style, className, highlightConfig, screenshotConfig, positionMode, header, footer, }: ContextMenuProps): react_jsx_runtime.JSX.Element | null;
|
|
248
461
|
|
|
249
462
|
/**
|
|
250
463
|
* Screenshot preview component - shows captured screenshots before sending
|
|
@@ -254,11 +467,11 @@ declare function ScreenshotPreview({ screenshots, isLoading, onConfirm, onCancel
|
|
|
254
467
|
/**
|
|
255
468
|
* React context for anyclick functionality
|
|
256
469
|
*/
|
|
257
|
-
declare const AnyclickContext:
|
|
470
|
+
declare const AnyclickContext: React$1.Context<AnyclickContextValue | null>;
|
|
258
471
|
/**
|
|
259
472
|
* @deprecated Use AnyclickContext instead
|
|
260
473
|
*/
|
|
261
|
-
declare const FeedbackContext:
|
|
474
|
+
declare const FeedbackContext: React$1.Context<AnyclickContextValue | null>;
|
|
262
475
|
/**
|
|
263
476
|
* Hook to access anyclick context
|
|
264
477
|
* @throws Error if used outside of AnyclickProvider
|
|
@@ -288,7 +501,7 @@ interface ProviderInstance {
|
|
|
288
501
|
/** Depth in the provider hierarchy (0 = root) */
|
|
289
502
|
depth: number;
|
|
290
503
|
/** Handler to call when an event occurs in this provider's scope */
|
|
291
|
-
onContextMenu?: (event:
|
|
504
|
+
onContextMenu?: (event: AnyclickMenuEvent, element: Element) => boolean | void;
|
|
292
505
|
}
|
|
293
506
|
/**
|
|
294
507
|
* Provider registry store state
|
|
@@ -347,6 +560,36 @@ declare const useProviderStore: zustand.UseBoundStore<zustand.StoreApi<ProviderS
|
|
|
347
560
|
*/
|
|
348
561
|
declare function dispatchContextMenuEvent(event: MouseEvent, element: Element): void;
|
|
349
562
|
|
|
563
|
+
type PresetRole = "qa" | "pm" | "designer" | "developer" | "chrome";
|
|
564
|
+
interface PresetConfig {
|
|
565
|
+
role: PresetRole;
|
|
566
|
+
label: string;
|
|
567
|
+
description: string;
|
|
568
|
+
menuItems: ContextMenuItem[];
|
|
569
|
+
screenshotConfig?: Partial<ScreenshotConfig>;
|
|
570
|
+
metadata?: Record<string, unknown>;
|
|
571
|
+
theme?: AnyclickTheme;
|
|
572
|
+
highlightConfig?: HighlightConfig;
|
|
573
|
+
}
|
|
574
|
+
interface CreatePresetMenuOptions {
|
|
575
|
+
/** Whether to include coming-soon items (defaults to true) */
|
|
576
|
+
includeComingSoon?: boolean;
|
|
577
|
+
/**
|
|
578
|
+
* Optional overrides for menu items, screenshot config, metadata, or theme.
|
|
579
|
+
* Useful when you want to tweak a preset without rebuilding it manually.
|
|
580
|
+
*/
|
|
581
|
+
overrides?: Partial<Omit<PresetConfig, "role" | "label" | "description">>;
|
|
582
|
+
}
|
|
583
|
+
declare const presetDefaults: Record<PresetRole, PresetConfig>;
|
|
584
|
+
/**
|
|
585
|
+
* Create a preset menu for a given role. Coming-soon items remain visible but disabled.
|
|
586
|
+
*/
|
|
587
|
+
declare function createPresetMenu(role: PresetRole, options?: CreatePresetMenuOptions): PresetConfig;
|
|
588
|
+
/**
|
|
589
|
+
* List all available presets with their defaults.
|
|
590
|
+
*/
|
|
591
|
+
declare function listPresets(): PresetConfig[];
|
|
592
|
+
|
|
350
593
|
/**
|
|
351
594
|
* CSS custom properties for menu theming.
|
|
352
595
|
* These can be overridden via the `style` prop on AnyclickProvider.
|
|
@@ -418,4 +661,212 @@ declare function applyHighlights(targetElement: Element, config?: HighlightConfi
|
|
|
418
661
|
container: Element | null;
|
|
419
662
|
};
|
|
420
663
|
|
|
421
|
-
|
|
664
|
+
/**
|
|
665
|
+
* Custom event name for triggering the inspect dialog
|
|
666
|
+
*/
|
|
667
|
+
declare const INSPECT_DIALOG_EVENT = "anyclick:inspect";
|
|
668
|
+
/**
|
|
669
|
+
* Custom event detail for the inspect dialog
|
|
670
|
+
*/
|
|
671
|
+
interface InspectDialogEventDetail {
|
|
672
|
+
targetElement: Element;
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Dispatch an event to open the inspect dialog for an element
|
|
676
|
+
*/
|
|
677
|
+
declare function openInspectDialog(targetElement: Element): void;
|
|
678
|
+
/**
|
|
679
|
+
* Props for InspectDialogManager
|
|
680
|
+
*/
|
|
681
|
+
interface InspectDialogManagerProps {
|
|
682
|
+
/** IDE configuration for "Open in IDE" feature */
|
|
683
|
+
ideConfig?: Partial<IDEConfig>;
|
|
684
|
+
/** Custom styles for the dialog */
|
|
685
|
+
dialogStyle?: React__default.CSSProperties;
|
|
686
|
+
/** Custom class name for the dialog */
|
|
687
|
+
dialogClassName?: string;
|
|
688
|
+
/** Custom highlight colors for the element highlight */
|
|
689
|
+
highlightColors?: HighlightColors;
|
|
690
|
+
/** Whether to show box model overlay (padding/margin visualization). Defaults to true. */
|
|
691
|
+
showBoxModelOverlay?: boolean;
|
|
692
|
+
/** Initial pinned position for the dialog. Defaults to "floating" (centered) */
|
|
693
|
+
initialPinnedPosition?: PinnedPosition;
|
|
694
|
+
/** Custom compact mode configuration. Partially override DEFAULT_COMPACT_CONFIG */
|
|
695
|
+
compactConfig?: Partial<CompactModeConfig>;
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* InspectDialogManager - A component that listens for inspect events and renders the dialog
|
|
699
|
+
*
|
|
700
|
+
* Place this component once in your app (e.g., alongside AnyclickProvider) to enable
|
|
701
|
+
* the inspect dialog functionality from the chrome preset.
|
|
702
|
+
*
|
|
703
|
+
* @example
|
|
704
|
+
* ```tsx
|
|
705
|
+
* <AnyclickProvider adapter={adapter}>
|
|
706
|
+
* <InspectDialogManager ideConfig={{ protocol: "cursor", basePath: "/Users/me/project" }} />
|
|
707
|
+
* {children}
|
|
708
|
+
* </AnyclickProvider>
|
|
709
|
+
* ```
|
|
710
|
+
*/
|
|
711
|
+
declare function InspectDialogManager({ ideConfig, dialogStyle, dialogClassName, highlightColors, showBoxModelOverlay, initialPinnedPosition, compactConfig, }: InspectDialogManagerProps): react_jsx_runtime.JSX.Element;
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Represents a modification made to an element
|
|
715
|
+
*/
|
|
716
|
+
interface ElementModification {
|
|
717
|
+
/** Unique identifier for the element (generated selector or path) */
|
|
718
|
+
elementId: string;
|
|
719
|
+
/** CSS selector to find the element */
|
|
720
|
+
selector: string;
|
|
721
|
+
/** Human-readable description of the element */
|
|
722
|
+
description: string;
|
|
723
|
+
/** Timestamp of the last modification */
|
|
724
|
+
lastModified: number;
|
|
725
|
+
/** Original inline styles before modification */
|
|
726
|
+
originalStyles: Record<string, string>;
|
|
727
|
+
/** Current modified inline styles */
|
|
728
|
+
modifiedStyles: Record<string, string>;
|
|
729
|
+
/** Original attributes before modification */
|
|
730
|
+
originalAttributes: Record<string, string>;
|
|
731
|
+
/** Current modified attributes */
|
|
732
|
+
modifiedAttributes: Record<string, string>;
|
|
733
|
+
/** Whether the element was deleted */
|
|
734
|
+
isDeleted?: boolean;
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Represents a deleted (hidden) element that can be restored
|
|
738
|
+
* Elements are hidden with display:none rather than removed from DOM
|
|
739
|
+
* for easier persistence and recovery
|
|
740
|
+
*/
|
|
741
|
+
interface DeletedElement {
|
|
742
|
+
/** Unique identifier for the element */
|
|
743
|
+
elementId: string;
|
|
744
|
+
/** CSS selector to find the element */
|
|
745
|
+
selector: string;
|
|
746
|
+
/** Human-readable description */
|
|
747
|
+
description: string;
|
|
748
|
+
/** Original display value before hiding */
|
|
749
|
+
originalDisplay: string;
|
|
750
|
+
/** Timestamp of deletion */
|
|
751
|
+
deletedAt: number;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Generate a unique ID for an element based on its position in the DOM
|
|
755
|
+
* Uses only simple, reliable selectors to avoid issues with special characters
|
|
756
|
+
*/
|
|
757
|
+
declare function generateElementId(element: Element): string;
|
|
758
|
+
/**
|
|
759
|
+
* Get a human-readable description of an element
|
|
760
|
+
*/
|
|
761
|
+
declare function getElementDescription(element: Element): string;
|
|
762
|
+
/**
|
|
763
|
+
* Persisted state shape (what gets saved to localStorage)
|
|
764
|
+
*/
|
|
765
|
+
interface PersistedState {
|
|
766
|
+
pinnedPosition: PinnedPosition;
|
|
767
|
+
modifiedElements: Record<string, ElementModification>;
|
|
768
|
+
deletedElements: Record<string, DeletedElement>;
|
|
769
|
+
}
|
|
770
|
+
interface InspectStore extends PersistedState {
|
|
771
|
+
/** Persisted pinned position */
|
|
772
|
+
setPinnedPosition: (position: PinnedPosition) => void;
|
|
773
|
+
/** Whether the store has been hydrated from storage */
|
|
774
|
+
_hasHydrated: boolean;
|
|
775
|
+
setHasHydrated: (state: boolean) => void;
|
|
776
|
+
/** Whether modifications were auto-applied on page load */
|
|
777
|
+
hasAutoAppliedModifications: boolean;
|
|
778
|
+
setHasAutoAppliedModifications: (value: boolean) => void;
|
|
779
|
+
/** Track a modification to an element */
|
|
780
|
+
trackModification: (element: Element, type: "style" | "attribute", key: string, oldValue: string | null, newValue: string | null) => void;
|
|
781
|
+
/** Track an element deletion */
|
|
782
|
+
trackDeletion: (element: Element) => void;
|
|
783
|
+
/** Get modification record for an element */
|
|
784
|
+
getModification: (element: Element) => ElementModification | null;
|
|
785
|
+
/** Reset all modifications for a specific element */
|
|
786
|
+
resetElement: (elementId: string) => void;
|
|
787
|
+
/** Reset all modifications for all elements (including restoring deleted elements) */
|
|
788
|
+
resetAllElements: () => void;
|
|
789
|
+
/** Get all modified elements that still exist in the DOM */
|
|
790
|
+
getModifiedElementsInDOM: () => Array<{
|
|
791
|
+
modification: ElementModification;
|
|
792
|
+
element: Element | null;
|
|
793
|
+
}>;
|
|
794
|
+
/** Get count of deleted elements */
|
|
795
|
+
getDeletedCount: () => number;
|
|
796
|
+
/** Apply persisted modifications to the DOM */
|
|
797
|
+
applyPersistedModifications: () => number;
|
|
798
|
+
/** Clear persisted state (for testing) */
|
|
799
|
+
clearPersistedState: () => void;
|
|
800
|
+
}
|
|
801
|
+
declare const useInspectStore: zustand.UseBoundStore<Omit<zustand.StoreApi<InspectStore>, "setState" | "persist"> & {
|
|
802
|
+
setState(partial: InspectStore | Partial<InspectStore> | ((state: InspectStore) => InspectStore | Partial<InspectStore>), replace?: false | undefined): unknown;
|
|
803
|
+
setState(state: InspectStore | ((state: InspectStore) => InspectStore), replace: true): unknown;
|
|
804
|
+
persist: {
|
|
805
|
+
setOptions: (options: Partial<zustand_middleware.PersistOptions<InspectStore, unknown, unknown>>) => void;
|
|
806
|
+
clearStorage: () => void;
|
|
807
|
+
rehydrate: () => Promise<void> | void;
|
|
808
|
+
hasHydrated: () => boolean;
|
|
809
|
+
onHydrate: (fn: (state: InspectStore) => void) => () => void;
|
|
810
|
+
onFinishHydration: (fn: (state: InspectStore) => void) => () => void;
|
|
811
|
+
getOptions: () => Partial<zustand_middleware.PersistOptions<InspectStore, unknown, unknown>>;
|
|
812
|
+
};
|
|
813
|
+
}>;
|
|
814
|
+
/**
|
|
815
|
+
* Custom hook to check if the store has been hydrated
|
|
816
|
+
* Use this to prevent hydration mismatches in SSR
|
|
817
|
+
*/
|
|
818
|
+
declare function useHasHydrated(): boolean;
|
|
819
|
+
/**
|
|
820
|
+
* Wait for hydration to complete before accessing persisted data
|
|
821
|
+
* Useful for ensuring data is available before rendering
|
|
822
|
+
*/
|
|
823
|
+
declare function waitForHydration(): Promise<void>;
|
|
824
|
+
|
|
825
|
+
interface AnyclickLogoProps {
|
|
826
|
+
/** Size of the logo in pixels. Defaults to 64 */
|
|
827
|
+
size?: number;
|
|
828
|
+
/** Border width in pixels. Defaults to 2 (same as default cursor stroke) */
|
|
829
|
+
borderWidth?: number;
|
|
830
|
+
/** Primary color for the circle border and cursor. Defaults to #3b82f6 (blue-500) */
|
|
831
|
+
primaryColor?: string;
|
|
832
|
+
/** Background color of the circle. Defaults to rgba(59, 130, 246, 0.1) */
|
|
833
|
+
backgroundColor?: string;
|
|
834
|
+
/** Custom class name */
|
|
835
|
+
className?: string;
|
|
836
|
+
/** Custom styles */
|
|
837
|
+
style?: React__default.CSSProperties;
|
|
838
|
+
/** Click handler */
|
|
839
|
+
onClick?: () => void;
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Anyclick Logo - A circle with a cursor pointer in the center
|
|
843
|
+
* The cursor is styled similarly to the default system cursor
|
|
844
|
+
*/
|
|
845
|
+
declare function AnyclickLogo({ size, borderWidth, primaryColor, backgroundColor, className, style, onClick, }: AnyclickLogoProps): react_jsx_runtime.JSX.Element;
|
|
846
|
+
|
|
847
|
+
interface ModificationIndicatorProps {
|
|
848
|
+
/** Position of the indicator. Defaults to "bottom-right" */
|
|
849
|
+
position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
|
|
850
|
+
/** Size of the logo in pixels. Defaults to 48 */
|
|
851
|
+
size?: number;
|
|
852
|
+
/** Whether to auto-apply persisted modifications on mount. Defaults to true */
|
|
853
|
+
autoApply?: boolean;
|
|
854
|
+
/** Offset from edge in pixels. Defaults to 16 */
|
|
855
|
+
offset?: number;
|
|
856
|
+
/** Primary color for the logo */
|
|
857
|
+
primaryColor?: string;
|
|
858
|
+
/** Background color for the logo */
|
|
859
|
+
backgroundColor?: string;
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* ModificationIndicator - Shows the Anyclick logo when modifications are active
|
|
863
|
+
*
|
|
864
|
+
* This component:
|
|
865
|
+
* 1. Waits for Zustand hydration before applying modifications
|
|
866
|
+
* 2. Auto-applies persisted modifications on mount (if autoApply is true)
|
|
867
|
+
* 3. Shows the Anyclick logo in the corner when modifications are active
|
|
868
|
+
* 4. Clicking the logo opens a quick menu to view/reset modifications
|
|
869
|
+
*/
|
|
870
|
+
declare function ModificationIndicator({ position, size, autoApply, offset, primaryColor, backgroundColor, }: ModificationIndicatorProps): react_jsx_runtime.JSX.Element | null;
|
|
871
|
+
|
|
872
|
+
export { AnyclickContext, type AnyclickContextValue, AnyclickLogo, type AnyclickLogoProps, AnyclickProvider, type AnyclickProviderProps, type AnyclickTheme, type AnyclickUserContext, type CompactModeConfig, ContextMenu, type ContextMenuItem, type ContextMenuProps, type CreatePresetMenuOptions, DEFAULT_COMPACT_CONFIG, type DeletedElement, type ElementModification, FeedbackContext, type FeedbackMenuBadge, type FeedbackMenuStatus, FeedbackProvider, FunModeBridge, type FunModeThemeConfig, type HighlightColors, type HighlightConfig, type IDEConfig, type IDEProtocol, INSPECT_DIALOG_EVENT, InspectDialog, type InspectDialogEventDetail, InspectDialogManager, type InspectDialogManagerProps, type InspectDialogProps, type MenuPositionMode, ModificationIndicator, type ModificationIndicatorProps, type PinnedPosition, type PresetConfig, type PresetRole, type ProviderInstance, ScreenshotPreview, type ScreenshotPreviewProps, type SourceLocation, applyHighlights, buildIDEUrl, clearHighlights, createIDEOpener, createPresetMenu, darkMenuStyles, defaultContainerSelectors, defaultHighlightColors, detectPreferredIDE, dispatchContextMenuEvent, filterMenuItemsByRole, findContainerParent, findSourceLocationInAncestors, formatSourceLocation, generateElementId, generateProviderId, getElementDescription, getSourceLocationFromElement, highlightContainer, highlightTarget, isIDEProtocolSupported, listPresets, menuCSSVariables, menuStyles, openInIDE, openInspectDialog, presetDefaults, useAnyclick, useFeedback, useHasHydrated, useInspectStore, useProviderStore, waitForHydration };
|