@useclickly/react 1.0.4 → 1.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.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -2
  3. package/dist/index.cjs +5237 -1455
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +31 -7
  6. package/dist/index.d.ts +93 -12
  7. package/dist/index.js +5181 -1390
  8. package/dist/index.js.map +1 -1
  9. package/package.json +13 -12
  10. package/dist/Clickly.d.ts +0 -25
  11. package/dist/Clickly.d.ts.map +0 -1
  12. package/dist/hooks/useDraggable.d.ts +0 -28
  13. package/dist/hooks/useDraggable.d.ts.map +0 -1
  14. package/dist/hooks/usePersistedState.d.ts +0 -6
  15. package/dist/hooks/usePersistedState.d.ts.map +0 -1
  16. package/dist/index.d.ts.map +0 -1
  17. package/dist/internal/AnnotationList.d.ts +0 -11
  18. package/dist/internal/AnnotationList.d.ts.map +0 -1
  19. package/dist/internal/AnnotationPins.d.ts +0 -2
  20. package/dist/internal/AnnotationPins.d.ts.map +0 -1
  21. package/dist/internal/AnnotationPopup.d.ts +0 -5
  22. package/dist/internal/AnnotationPopup.d.ts.map +0 -1
  23. package/dist/internal/ClicklyRoot.d.ts +0 -15
  24. package/dist/internal/ClicklyRoot.d.ts.map +0 -1
  25. package/dist/internal/CollapsedFAB.d.ts +0 -10
  26. package/dist/internal/CollapsedFAB.d.ts.map +0 -1
  27. package/dist/internal/SettingsPopover.d.ts +0 -11
  28. package/dist/internal/SettingsPopover.d.ts.map +0 -1
  29. package/dist/internal/Toolbar.d.ts +0 -8
  30. package/dist/internal/Toolbar.d.ts.map +0 -1
  31. package/dist/internal/globalStyles.d.ts +0 -13
  32. package/dist/internal/globalStyles.d.ts.map +0 -1
  33. package/dist/internal/icons.d.ts +0 -14
  34. package/dist/internal/icons.d.ts.map +0 -1
  35. package/dist/internal/styles.d.ts +0 -7
  36. package/dist/internal/styles.d.ts.map +0 -1
  37. package/dist/output/markdown.d.ts +0 -5
  38. package/dist/output/markdown.d.ts.map +0 -1
  39. package/dist/output/markdown.test.d.ts +0 -2
  40. package/dist/output/markdown.test.d.ts.map +0 -1
  41. package/dist/state/annotations.d.ts +0 -21
  42. package/dist/state/annotations.d.ts.map +0 -1
  43. package/dist/state/annotations.test.d.ts +0 -2
  44. package/dist/state/annotations.test.d.ts.map +0 -1
  45. package/dist/state/settings.d.ts +0 -14
  46. package/dist/state/settings.d.ts.map +0 -1
  47. package/dist/state/settings.test.d.ts +0 -2
  48. package/dist/state/settings.test.d.ts.map +0 -1
  49. package/dist/state/useEngineState.d.ts +0 -7
  50. package/dist/state/useEngineState.d.ts.map +0 -1
  51. package/dist/test/setup.d.ts +0 -7
  52. package/dist/test/setup.d.ts.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1,4 +1,3 @@
1
- import * as react from 'react';
2
1
  import * as zustand from 'zustand';
3
2
  import { Annotation } from '@useclickly/core';
4
3
  export { Annotation, AnnotationKind, AnnotationStatus, ScreenshotData } from '@useclickly/core';
@@ -25,8 +24,17 @@ interface ClicklyProps {
25
24
  *
26
25
  * Renders a small floating button (FAB) in the bottom-right corner.
27
26
  * Click it (or press `⌘/Ctrl+Shift+F`) to open the full toolbar.
27
+ *
28
+ * Implementation note: we create a *separate* React root inside the shadow
29
+ * (via `createRoot(portal)`) rather than using `createPortal` from this
30
+ * component. Reason: React's event delegation listens at the React root
31
+ * container. With createPortal from the parent app tree, clicks bubbling
32
+ * out of the shadow are retargeted to `<clickly-root>`, which has no React
33
+ * fiber attached, so onClick handlers on toolbar buttons never fire. A
34
+ * dedicated root inside the shadow keeps the entire dispatch path inside
35
+ * the shadow boundary, which is what React's synthetic events need.
28
36
  */
29
- declare function Clickly({ className }?: ClicklyProps): react.ReactPortal | null;
37
+ declare function Clickly({ className }?: ClicklyProps): null;
30
38
 
31
39
  interface AnnotationsStore {
32
40
  byId: Record<string, Annotation>;
@@ -37,6 +45,9 @@ interface AnnotationsStore {
37
45
  clear: () => void;
38
46
  /** Imperative read. Hooks should use `useAnnotationsList()` instead. */
39
47
  list: () => Annotation[];
48
+ /** Bulk-merge strokes loaded from IndexedDB on mount. Does NOT trigger
49
+ * a save back — these annotations already exist on disk. */
50
+ hydrateStrokes: (strokesById: Record<string, NonNullable<Annotation["strokes"]>>) => void;
40
51
  }
41
52
  declare const useAnnotations: zustand.UseBoundStore<zustand.StoreApi<AnnotationsStore>>;
42
53
  /**
@@ -49,11 +60,29 @@ declare const useAnnotations: zustand.UseBoundStore<zustand.StoreApi<Annotations
49
60
  declare function useAnnotationsList(): Annotation[];
50
61
 
51
62
  type OutputDetail = "compact" | "standard" | "detailed" | "forensic";
63
+ /**
64
+ * Theme: `"system"` follows the OS preference via `prefers-color-scheme`;
65
+ * `"light"` and `"dark"` lock the choice. ClicklyRoot resolves "system"
66
+ * to a concrete value at render time and sets `data-clickly-theme` on
67
+ * the shadow-root wrapper so the CSS in styles.ts can target it.
68
+ */
69
+ type Theme = "system" | "light" | "dark";
52
70
  interface Settings {
53
71
  outputDetail: OutputDetail;
54
72
  copyOnAdd: boolean;
55
73
  showReactComponents: boolean;
56
74
  markerColor: string;
75
+ theme: Theme;
76
+ /** MCP sync — push new annotations to a running mcp-server's HTTP bridge. */
77
+ mcpEnabled: boolean;
78
+ /** HTTP-bridge URL the React side connects to (default localhost:4747). */
79
+ mcpEndpoint: string;
80
+ /**
81
+ * Session ID returned by POST /sessions. Persisted so a reload re-attaches
82
+ * to the same session and the agent keeps seeing one continuous stream
83
+ * of annotations from this page.
84
+ */
85
+ mcpSessionId: string | null;
57
86
  }
58
87
  interface SettingsStore extends Settings {
59
88
  set: (patch: Partial<Settings>) => void;
@@ -62,11 +91,6 @@ interface SettingsStore extends Settings {
62
91
  declare const DEFAULTS: Settings;
63
92
  declare const useSettings: zustand.UseBoundStore<zustand.StoreApi<SettingsStore>>;
64
93
 
65
- /**
66
- * Phase 5 placeholder formatter — Phase 9 adds the React + Source lines
67
- * when those fields are populated. Phase 8 replaces the whole thing with
68
- * a full AFS-compliant implementation.
69
- */
70
94
  declare function annotationsToMarkdown(annotations: Annotation[], detail?: OutputDetail): string;
71
95
 
72
96
  export { type AnnotationsStore, Clickly, type ClicklyProps, DEFAULTS as DEFAULT_SETTINGS, type OutputDetail, type Settings, type SettingsStore, annotationsToMarkdown, useAnnotations, useAnnotationsList, useSettings };
package/dist/index.d.ts CHANGED
@@ -1,15 +1,96 @@
1
+ import * as zustand from 'zustand';
2
+ import { Annotation } from '@useclickly/core';
3
+ export { Annotation, AnnotationKind, AnnotationStatus, ScreenshotData } from '@useclickly/core';
4
+
5
+ interface ClicklyProps {
6
+ /** Custom class on the host element (for z-index / positioning overrides). */
7
+ className?: string;
8
+ /** Optional MCP server endpoint, e.g. "http://localhost:4747". */
9
+ endpoint?: string;
10
+ /** Join an existing MCP session by ID. */
11
+ sessionId?: string;
12
+ onAnnotationAdd?: (id: string) => void;
13
+ onAnnotationDelete?: (id: string) => void;
14
+ onAnnotationsClear?: () => void;
15
+ onCopy?: (markdown: string) => void;
16
+ onSessionCreated?: (sessionId: string) => void;
17
+ }
1
18
  /**
2
- * @useclickly/react public surface
19
+ * Mount once near the root of your React app. Dev-only by convention:
3
20
  *
4
- * The single export is `<Clickly />`. Stores and types are also
5
- * re-exported for advanced integrations.
21
+ * ```tsx
22
+ * {process.env.NODE_ENV === "development" && <Clickly />}
23
+ * ```
24
+ *
25
+ * Renders a small floating button (FAB) in the bottom-right corner.
26
+ * Click it (or press `⌘/Ctrl+Shift+F`) to open the full toolbar.
27
+ *
28
+ * Implementation note: we create a *separate* React root inside the shadow
29
+ * (via `createRoot(portal)`) rather than using `createPortal` from this
30
+ * component. Reason: React's event delegation listens at the React root
31
+ * container. With createPortal from the parent app tree, clicks bubbling
32
+ * out of the shadow are retargeted to `<clickly-root>`, which has no React
33
+ * fiber attached, so onClick handlers on toolbar buttons never fire. A
34
+ * dedicated root inside the shadow keeps the entire dispatch path inside
35
+ * the shadow boundary, which is what React's synthetic events need.
36
+ */
37
+ declare function Clickly({ className }?: ClicklyProps): null;
38
+
39
+ interface AnnotationsStore {
40
+ byId: Record<string, Annotation>;
41
+ order: string[];
42
+ add: (a: Annotation) => void;
43
+ remove: (id: string) => void;
44
+ update: (id: string, patch: Partial<Annotation>) => void;
45
+ clear: () => void;
46
+ /** Imperative read. Hooks should use `useAnnotationsList()` instead. */
47
+ list: () => Annotation[];
48
+ /** Bulk-merge strokes loaded from IndexedDB on mount. Does NOT trigger
49
+ * a save back — these annotations already exist on disk. */
50
+ hydrateStrokes: (strokesById: Record<string, NonNullable<Annotation["strokes"]>>) => void;
51
+ }
52
+ declare const useAnnotations: zustand.UseBoundStore<zustand.StoreApi<AnnotationsStore>>;
53
+ /**
54
+ * Subscribe to the annotation list with shallow equality — re-renders
55
+ * only when items add/remove/reorder/update. Always use this from
56
+ * component code; never call `useAnnotations(s => s.list())`, which
57
+ * returns a new array reference on every store change and infinite-loops
58
+ * `useSyncExternalStore`.
59
+ */
60
+ declare function useAnnotationsList(): Annotation[];
61
+
62
+ type OutputDetail = "compact" | "standard" | "detailed" | "forensic";
63
+ /**
64
+ * Theme: `"system"` follows the OS preference via `prefers-color-scheme`;
65
+ * `"light"` and `"dark"` lock the choice. ClicklyRoot resolves "system"
66
+ * to a concrete value at render time and sets `data-clickly-theme` on
67
+ * the shadow-root wrapper so the CSS in styles.ts can target it.
6
68
  */
7
- export { Clickly } from "./Clickly";
8
- export type { ClicklyProps } from "./Clickly";
9
- export { useAnnotations, useAnnotationsList } from "./state/annotations";
10
- export { useSettings, DEFAULTS as DEFAULT_SETTINGS } from "./state/settings";
11
- export type { AnnotationsStore } from "./state/annotations";
12
- export type { Settings, SettingsStore, OutputDetail } from "./state/settings";
13
- export { annotationsToMarkdown } from "./output/markdown";
14
- export type { Annotation, AnnotationStatus, AnnotationKind, ScreenshotData, } from "@useclickly/core";
15
- //# sourceMappingURL=index.d.ts.map
69
+ type Theme = "system" | "light" | "dark";
70
+ interface Settings {
71
+ outputDetail: OutputDetail;
72
+ copyOnAdd: boolean;
73
+ showReactComponents: boolean;
74
+ markerColor: string;
75
+ theme: Theme;
76
+ /** MCP sync push new annotations to a running mcp-server's HTTP bridge. */
77
+ mcpEnabled: boolean;
78
+ /** HTTP-bridge URL the React side connects to (default localhost:4747). */
79
+ mcpEndpoint: string;
80
+ /**
81
+ * Session ID returned by POST /sessions. Persisted so a reload re-attaches
82
+ * to the same session and the agent keeps seeing one continuous stream
83
+ * of annotations from this page.
84
+ */
85
+ mcpSessionId: string | null;
86
+ }
87
+ interface SettingsStore extends Settings {
88
+ set: (patch: Partial<Settings>) => void;
89
+ reset: () => void;
90
+ }
91
+ declare const DEFAULTS: Settings;
92
+ declare const useSettings: zustand.UseBoundStore<zustand.StoreApi<SettingsStore>>;
93
+
94
+ declare function annotationsToMarkdown(annotations: Annotation[], detail?: OutputDetail): string;
95
+
96
+ export { type AnnotationsStore, Clickly, type ClicklyProps, DEFAULTS as DEFAULT_SETTINGS, type OutputDetail, type Settings, type SettingsStore, annotationsToMarkdown, useAnnotations, useAnnotationsList, useSettings };