@ewjdev/anyclick-react 1.2.0 → 1.4.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 CHANGED
@@ -53,12 +53,12 @@ That's it! Users can now right-click any element to submit feedback.
53
53
 
54
54
  | Prop | Type | Description |
55
55
  | ----------------- | -------------------------- | ---------------------------------------------- |
56
- | `adapter` | `FeedbackAdapter` | Required. The adapter for submitting feedback |
57
- | `menuItems` | `FeedbackMenuItem[]` | Custom menu items |
56
+ | `adapter` | `AnyclickAdapter` | Required. The adapter for submitting anyclick |
57
+ | `menuItems` | `ContextMenuItem[]` | Custom menu items |
58
58
  | `metadata` | `Record<string, unknown>` | Additional data included with every submission |
59
59
  | `theme` | `AnyclickTheme \| null` | Theme configuration (inherits from parent) |
60
60
  | `scoped` | `boolean` | Limit capture to this provider's children only |
61
- | `disabled` | `boolean` | Disable feedback capture |
61
+ | `disabled` | `boolean` | Disable anyclick capture |
62
62
  | `onSubmitSuccess` | `(payload) => void` | Success callback |
63
63
  | `onSubmitError` | `(error, payload) => void` | Error callback |
64
64
 
@@ -188,6 +188,34 @@ const userContext = { roles: ["user", "developer"] };
188
188
  const menuItems = filterMenuItemsByRole(allMenuItems, userContext);
189
189
  ```
190
190
 
191
+ ## Role-Based Presets
192
+
193
+ Skip hand-authoring menus by pulling in a preset for common roles. Coming-soon actions stay visible with a badge but are disabled by default.
194
+
195
+ ```tsx
196
+ import { AnyclickProvider, createPresetMenu } from "@ewjdev/anyclick-react";
197
+
198
+ const qaPreset = createPresetMenu("qa");
199
+ // Or: listPresets() to show available roles, createPresetMenu("developer", { includeComingSoon: false })
200
+
201
+ <AnyclickProvider
202
+ adapter={adapter}
203
+ menuItems={qaPreset.menuItems}
204
+ screenshotConfig={qaPreset.screenshotConfig}
205
+ metadata={qaPreset.metadata}
206
+ theme={qaPreset.theme}
207
+ >
208
+ {children}
209
+ </AnyclickProvider>;
210
+ ```
211
+
212
+ Preset defaults (examples):
213
+
214
+ - QA: bug / repro / UX papercut + “Performance trace” (coming soon)
215
+ - PM: feature idea / UX papercut + “Impact sizing” (coming soon)
216
+ - Designer: visual bug / accessibility + “Motion glitch” (coming soon)
217
+ - Developer: bug / refactor + diagnostics submenu (console/network traces marked coming soon)
218
+
191
219
  ## Highlight Configuration
192
220
 
193
221
  ```tsx
package/dist/index.d.mts CHANGED
@@ -1,9 +1,175 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { AnyclickAdapter, AnyclickTriggerEvent, AnyclickType, AnyclickPayload, ScreenshotConfig, ScreenshotData, AnyclickMenuEvent } from '@ewjdev/anyclick-core';
3
- export { AnyclickAdapter, AnyclickPayload, AnyclickType, DEFAULT_SCREENSHOT_CONFIG, DEFAULT_SENSITIVE_SELECTORS, ElementContext, PageContext, ScreenshotCapture, ScreenshotCaptureMode, ScreenshotConfig, ScreenshotData, captureAllScreenshots, captureScreenshot, estimateTotalSize, formatBytes, isScreenshotSupported } from '@ewjdev/anyclick-core';
4
- import * as react from 'react';
5
- import { ReactNode, CSSProperties } from 'react';
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
@@ -73,7 +239,7 @@ interface HighlightConfig {
73
239
  /**
74
240
  * Menu item displayed in the Anyclick context menu
75
241
  */
76
- interface AnyclickMenuItem {
242
+ interface ContextMenuItem {
77
243
  /** Feedback type for this option (use unique identifier for parent items with children) */
78
244
  type: AnyclickType;
79
245
  /** Display label */
@@ -82,10 +248,14 @@ interface AnyclickMenuItem {
82
248
  icon?: ReactNode;
83
249
  /** Whether to show a comment input for this type */
84
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;
85
255
  /** Optional role(s) required to see this menu item */
86
256
  requiredRoles?: string[];
87
257
  /** Child menu items (creates a submenu) */
88
- children?: AnyclickMenuItem[];
258
+ children?: ContextMenuItem[];
89
259
  /**
90
260
  * Optional click handler for custom behavior.
91
261
  * Return `false` (or a Promise resolving to false) to skip the default submission flow.
@@ -96,6 +266,19 @@ interface AnyclickMenuItem {
96
266
  closeMenu: () => void;
97
267
  }) => void | boolean | Promise<void | boolean>;
98
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";
99
282
  /**
100
283
  * User context for role-based menu filtering
101
284
  */
@@ -110,7 +293,7 @@ interface AnyclickUserContext {
110
293
  /**
111
294
  * Filter menu items based on user context
112
295
  */
113
- declare function filterMenuItemsByRole(items: AnyclickMenuItem[], userContext?: AnyclickUserContext): AnyclickMenuItem[];
296
+ declare function filterMenuItemsByRole(items: ContextMenuItem[], userContext?: AnyclickUserContext): ContextMenuItem[];
114
297
  /**
115
298
  * Props for the AnyclickProvider component
116
299
  */
@@ -128,7 +311,7 @@ interface AnyclickProviderProps {
128
311
  */
129
312
  targetFilter?: (event: AnyclickTriggerEvent, target: Element) => boolean;
130
313
  /** Custom menu items (defaults to Issue, Feature, Like) */
131
- menuItems?: AnyclickMenuItem[];
314
+ menuItems?: ContextMenuItem[];
132
315
  /** Maximum length for innerText capture */
133
316
  maxInnerTextLength?: number;
134
317
  /** Maximum length for outerHTML capture */
@@ -214,7 +397,7 @@ interface ContextMenuProps {
214
397
  /** Container element found by highlight logic */
215
398
  containerElement: Element | null;
216
399
  /** Menu items to display */
217
- items: AnyclickMenuItem[];
400
+ items: ContextMenuItem[];
218
401
  /** Callback when an item is selected */
219
402
  onSelect: (type: AnyclickType, comment?: string, screenshots?: ScreenshotData) => void;
220
403
  /** Callback when menu is closed */
@@ -284,11 +467,11 @@ declare function ScreenshotPreview({ screenshots, isLoading, onConfirm, onCancel
284
467
  /**
285
468
  * React context for anyclick functionality
286
469
  */
287
- declare const AnyclickContext: react.Context<AnyclickContextValue | null>;
470
+ declare const AnyclickContext: React$1.Context<AnyclickContextValue | null>;
288
471
  /**
289
472
  * @deprecated Use AnyclickContext instead
290
473
  */
291
- declare const FeedbackContext: react.Context<AnyclickContextValue | null>;
474
+ declare const FeedbackContext: React$1.Context<AnyclickContextValue | null>;
292
475
  /**
293
476
  * Hook to access anyclick context
294
477
  * @throws Error if used outside of AnyclickProvider
@@ -377,6 +560,36 @@ declare const useProviderStore: zustand.UseBoundStore<zustand.StoreApi<ProviderS
377
560
  */
378
561
  declare function dispatchContextMenuEvent(event: MouseEvent, element: Element): void;
379
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
+
380
593
  /**
381
594
  * CSS custom properties for menu theming.
382
595
  * These can be overridden via the `style` prop on AnyclickProvider.
@@ -448,4 +661,212 @@ declare function applyHighlights(targetElement: Element, config?: HighlightConfi
448
661
  container: Element | null;
449
662
  };
450
663
 
451
- export { AnyclickContext, type AnyclickContextValue, type AnyclickMenuItem, AnyclickProvider, type AnyclickProviderProps, type AnyclickTheme, type AnyclickUserContext, ContextMenu, type ContextMenuProps, FeedbackContext, FeedbackProvider, FunModeBridge, type FunModeThemeConfig, type HighlightColors, type HighlightConfig, type MenuPositionMode, type ProviderInstance, ScreenshotPreview, type ScreenshotPreviewProps, applyHighlights, clearHighlights, darkMenuStyles, defaultContainerSelectors, defaultHighlightColors, dispatchContextMenuEvent, filterMenuItemsByRole, findContainerParent, generateProviderId, highlightContainer, highlightTarget, menuCSSVariables, menuStyles, useAnyclick, useFeedback, useProviderStore };
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 };