blocfeed 0.4.0 → 0.5.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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0 — 2026-02-20
4
+
5
+ ### New features
6
+
7
+ - **Custom trigger label** — `config.ui.triggerLabel` sets the text shown on the trigger button (default: `"Feedback"`). Applies to all trigger styles.
8
+ - **Keyboard shortcut** — `config.ui.shortcut` (e.g., `"mod+shift+f"`) toggles the widget open/closed. Supports `ctrl`, `meta`/`cmd`, `shift`, `alt`/`option` modifiers; `mod` maps to Ctrl on Windows/Linux and Cmd on Mac.
9
+ - **Beacon trigger style** — new `"beacon"` trigger with a lighthouse-style sweeping beam and glowing dot that expands to a pill on hover.
10
+ - **Typewriter trigger style** — new `"typewriter"` trigger with text that types out character by character with a blinking cursor, fully visible on hover.
11
+ - **Offline queue badge** — when submissions are queued for retry, a red badge with the count appears on the trigger button across all styles.
12
+ - **Success checkmark** — after a successful submission, the trigger briefly shows a checkmark icon for 1.5 seconds before returning to normal.
13
+ - **Panel / toast / hint animations** — the feedback panel slides in from below, the success toast slides up, and the hint bar slides down using CSS keyframe animations.
14
+
15
+ ### Improvements
16
+
17
+ - **`prefers-reduced-motion` support** — all framer-motion animations and CSS keyframe animations are disabled when the user prefers reduced motion. Animated triggers use instant transitions; panel/toast/hint entrance animations are suppressed.
18
+ - **`TriggerStyle` type** updated to include `"beacon"` and `"typewriter"`.
19
+
20
+ ---
21
+
3
22
  ## 0.4.0 — 2026-02-20
4
23
 
5
24
  ### New features
package/README.md CHANGED
@@ -105,7 +105,9 @@ All configuration is passed via the `config` prop on `<BlocFeedWidget>` or `<Blo
105
105
  // Widget position, theme & trigger style
106
106
  ui: {
107
107
  position: "bottom-right", // "bottom-left" | "top-right" | "top-left"
108
- triggerStyle: "dot", // "classic" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop"
108
+ triggerStyle: "dot", // "classic" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop" | "beacon" | "typewriter"
109
+ triggerLabel: "Feedback", // custom label text
110
+ shortcut: "mod+shift+f", // keyboard shortcut to toggle widget
109
111
  zIndex: 99999,
110
112
  theme: {
111
113
  accentColor: "#12D393",
@@ -201,8 +203,32 @@ config={{
201
203
  | `"pulse-ring"` | Sonar-style pulsing rings around a dot, expands on hover | Yes |
202
204
  | `"minimal"` | Text-only "Feedback" with animated underline on hover | Yes |
203
205
  | `"icon-pop"` | Wobbling icon that pops and reveals text on hover | Yes |
206
+ | `"beacon"` | Lighthouse-style sweeping beam with glowing dot, expands on hover | Yes |
207
+ | `"typewriter"` | Text types out character by character with blinking cursor | Yes |
204
208
 
205
- All animated styles include smooth enter/exit transitions powered by framer-motion's spring physics.
209
+ All animated styles include smooth enter/exit transitions. Animations automatically simplify when `prefers-reduced-motion: reduce` is active.
210
+
211
+ ### Custom trigger label
212
+
213
+ ```tsx
214
+ config={{
215
+ ui: { triggerLabel: "Report Bug" }
216
+ }}
217
+ ```
218
+
219
+ The label defaults to `"Feedback"` and is used across all trigger styles.
220
+
221
+ ### Keyboard shortcut
222
+
223
+ Open/close the widget with a keyboard shortcut:
224
+
225
+ ```tsx
226
+ config={{
227
+ ui: { shortcut: "mod+shift+f" }
228
+ }}
229
+ ```
230
+
231
+ Use `mod` for platform-aware behavior (Ctrl on Windows/Linux, Cmd on Mac). Supports `ctrl`, `meta`/`cmd`, `shift`, `alt`/`option` modifiers.
206
232
 
207
233
  ### Installing framer-motion
208
234
 
@@ -346,9 +372,11 @@ The widget supports full keyboard navigation:
346
372
  - **Shift+Tab** cycles backward
347
373
  - **Escape** cancels picking or closes the panel
348
374
  - **Ctrl/Cmd+Enter** submits feedback from the textarea
375
+ - **Custom shortcut** — configurable via `config.ui.shortcut` (e.g., `"mod+shift+f"`)
349
376
  - Focus is trapped within the panel when open
350
377
  - All interactive elements have `aria-label` attributes
351
378
  - Status messages use `aria-live="polite"` for screen reader announcements
379
+ - Animations respect `prefers-reduced-motion: reduce` — all motion is disabled when the user prefers reduced motion
352
380
 
353
381
  ## Client-Side Rate Limiting
354
382
 
@@ -24,7 +24,7 @@ interface TransportConfig {
24
24
  backoffMs?: number;
25
25
  }
26
26
  type WidgetPosition = "bottom-right" | "bottom-left" | "top-right" | "top-left";
27
- type TriggerStyle = "classic" | "dot" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop";
27
+ type TriggerStyle = "classic" | "dot" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop" | "beacon" | "typewriter";
28
28
  interface ThemeConfig {
29
29
  accentColor?: string;
30
30
  panelBackground?: string;
@@ -155,6 +155,10 @@ interface BlocFeedConfig {
155
155
  theme?: ThemeConfig;
156
156
  /** Trigger button animation style. Default: "classic" */
157
157
  triggerStyle?: TriggerStyle;
158
+ /** Custom label text for the trigger button. Default: "Feedback" */
159
+ triggerLabel?: string;
160
+ /** Keyboard shortcut to toggle the widget. e.g. "ctrl+shift+f" */
161
+ shortcut?: string;
158
162
  };
159
163
  }
160
164
  interface ScreenshotIntent {
@@ -24,7 +24,7 @@ interface TransportConfig {
24
24
  backoffMs?: number;
25
25
  }
26
26
  type WidgetPosition = "bottom-right" | "bottom-left" | "top-right" | "top-left";
27
- type TriggerStyle = "classic" | "dot" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop";
27
+ type TriggerStyle = "classic" | "dot" | "bubble" | "edge-tab" | "pulse-ring" | "minimal" | "icon-pop" | "beacon" | "typewriter";
28
28
  interface ThemeConfig {
29
29
  accentColor?: string;
30
30
  panelBackground?: string;
@@ -155,6 +155,10 @@ interface BlocFeedConfig {
155
155
  theme?: ThemeConfig;
156
156
  /** Trigger button animation style. Default: "classic" */
157
157
  triggerStyle?: TriggerStyle;
158
+ /** Custom label text for the trigger button. Default: "Feedback" */
159
+ triggerLabel?: string;
160
+ /** Keyboard shortcut to toggle the widget. e.g. "ctrl+shift+f" */
161
+ shortcut?: string;
158
162
  };
159
163
  }
160
164
  interface ScreenshotIntent {
package/dist/engine.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { j as ScreenshotAdapter, C as CaptureConfig, f as CaptureResult, h as MetadataConfig, i as MetadataContext, d as BlocFeedUser, g as FeedbackPayload } from './controller-D7kOehzb.cjs';
2
- export { B as BlocFeedConfig, b as BlocFeedController, c as BlocFeedError, a as BlocFeedState, E as ElementDescriptor, F as FeedbackApiResponse, H as HoverListener, I as ImageAsset, R as Rect, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, r as StateListener, S as SubmitResult, T as ThemeConfig, o as TransportConfig, q as TriggerStyle, W as WidgetPosition, s as createBlocFeedController } from './controller-D7kOehzb.cjs';
1
+ import { j as ScreenshotAdapter, C as CaptureConfig, f as CaptureResult, h as MetadataConfig, i as MetadataContext, d as BlocFeedUser, g as FeedbackPayload } from './controller-did-WBAQ.cjs';
2
+ export { B as BlocFeedConfig, b as BlocFeedController, c as BlocFeedError, a as BlocFeedState, E as ElementDescriptor, F as FeedbackApiResponse, H as HoverListener, I as ImageAsset, R as Rect, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, r as StateListener, S as SubmitResult, T as ThemeConfig, o as TransportConfig, q as TriggerStyle, W as WidgetPosition, s as createBlocFeedController } from './controller-did-WBAQ.cjs';
3
3
 
4
4
  declare function createHtmlToImageAdapter(): ScreenshotAdapter;
5
5
 
package/dist/engine.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { j as ScreenshotAdapter, C as CaptureConfig, f as CaptureResult, h as MetadataConfig, i as MetadataContext, d as BlocFeedUser, g as FeedbackPayload } from './controller-D7kOehzb.js';
2
- export { B as BlocFeedConfig, b as BlocFeedController, c as BlocFeedError, a as BlocFeedState, E as ElementDescriptor, F as FeedbackApiResponse, H as HoverListener, I as ImageAsset, R as Rect, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, r as StateListener, S as SubmitResult, T as ThemeConfig, o as TransportConfig, q as TriggerStyle, W as WidgetPosition, s as createBlocFeedController } from './controller-D7kOehzb.js';
1
+ import { j as ScreenshotAdapter, C as CaptureConfig, f as CaptureResult, h as MetadataConfig, i as MetadataContext, d as BlocFeedUser, g as FeedbackPayload } from './controller-did-WBAQ.js';
2
+ export { B as BlocFeedConfig, b as BlocFeedController, c as BlocFeedError, a as BlocFeedState, E as ElementDescriptor, F as FeedbackApiResponse, H as HoverListener, I as ImageAsset, R as Rect, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, r as StateListener, S as SubmitResult, T as ThemeConfig, o as TransportConfig, q as TriggerStyle, W as WidgetPosition, s as createBlocFeedController } from './controller-did-WBAQ.js';
3
3
 
4
4
  declare function createHtmlToImageAdapter(): ScreenshotAdapter;
5
5
 
package/dist/main.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- 'use strict';var chunkJLPJP7DD_cjs=require('./chunk-JLPJP7DD.cjs'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),reactDom=require('react-dom'),framerMotion=require('framer-motion');var k=react.createContext(null);function M(t){let e=react.useMemo(()=>chunkJLPJP7DD_cjs.j({...t.config??{},blocfeed_id:t.blocfeed_id}),[]),[i,r]=react.useState(()=>e.getState());return react.useEffect(()=>e.subscribe(r),[e]),react.useEffect(()=>e.setConfig({...t.config??{},blocfeed_id:t.blocfeed_id}),[e,t.config,t.blocfeed_id]),react.useEffect(()=>()=>e.destroy(),[e]),jsxRuntime.jsx(k.Provider,{value:{controller:e,state:i},children:t.children})}var Y="blocfeed-styles-v1",Se=`
2
+ 'use strict';var chunkJLPJP7DD_cjs=require('./chunk-JLPJP7DD.cjs'),react=require('react'),jsxRuntime=require('react/jsx-runtime'),reactDom=require('react-dom'),framerMotion=require('framer-motion');var $=react.createContext(null);function J(t){let e=react.useMemo(()=>chunkJLPJP7DD_cjs.j({...t.config??{},blocfeed_id:t.blocfeed_id}),[]),[n,i]=react.useState(()=>e.getState());return react.useEffect(()=>e.subscribe(i),[e]),react.useEffect(()=>e.setConfig({...t.config??{},blocfeed_id:t.blocfeed_id}),[e,t.config,t.blocfeed_id]),react.useEffect(()=>()=>e.destroy(),[e]),jsxRuntime.jsx($.Provider,{value:{controller:e,state:n},children:t.children})}var ce="blocfeed-styles-v1",tt=`
3
3
  :where([data-blocfeed-ui-root]),
4
4
  :where([data-blocfeed-ui-root]) * {
5
5
  box-sizing: border-box;
@@ -386,5 +386,94 @@
386
386
  white-space: nowrap;
387
387
  border: 0;
388
388
  }
389
- `;function J(){if(!chunkJLPJP7DD_cjs.a()||document.getElementById(Y))return;let t=document.createElement("style");t.id=Y,t.textContent=Se,document.head.appendChild(t);}function A(){let t=react.useContext(k);if(!t)throw new Error("useBlocFeed must be used within a <BlocFeedProvider />");return {state:t.state,controller:t.controller,start:t.controller.start,stop:t.controller.stop,clearSelection:t.controller.clearSelection,submit:t.controller.submit}}function c(t){switch(t){case "bottom-left":return "bf-trigger bf-trigger-bl";case "top-right":return "bf-trigger bf-trigger-tr";case "top-left":return "bf-trigger bf-trigger-tl";default:return "bf-trigger"}}function Q({position:t,onClick:e,isVisible:i}){return i?jsxRuntime.jsxs("button",{className:c(t),type:"button",onClick:e,"aria-label":"Give feedback",children:[jsxRuntime.jsx("span",{className:"bf-dot","aria-hidden":"true"}),"Feedback"]}):null}function ee({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0},animate:{scale:1,opacity:1,padding:r?"10px 16px":"10px 10px"},exit:{scale:0,opacity:0},transition:{type:"spring",stiffness:500,damping:28},whileTap:{scale:.92},style:{overflow:"hidden"},children:[jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",animate:{scale:r?1:[1,1.2,1],boxShadow:r?"0 0 0 4px rgba(99, 102, 241, 0.18)":["0 0 0 4px rgba(99, 102, 241, 0.18)","0 0 0 8px rgba(99, 102, 241, 0.28)","0 0 0 4px rgba(99, 102, 241, 0.18)"]},transition:r?{type:"spring",stiffness:400,damping:20}:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsxRuntime.jsx(framerMotion.AnimatePresence,{children:r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,width:0,x:-8},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-8},transition:{type:"spring",stiffness:400,damping:25},style:{whiteSpace:"nowrap",overflow:"hidden"},children:"Feedback"})}),jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",inset:0,borderRadius:"inherit",border:"2px solid var(--bf-accent)",pointerEvents:"none"},initial:false,animate:{scale:1,opacity:0},whileTap:{scale:2.5,opacity:[.6,0]},transition:{duration:.4}})]})})}function te({size:t=14}){return jsxRuntime.jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function oe({size:t=16}){return jsxRuntime.jsxs("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsxRuntime.jsx("path",{d:"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),jsxRuntime.jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function ie({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.div,{style:{position:"fixed",zIndex:"var(--bf-z)"},className:c(t),initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{y:12,opacity:0,scale:.8},transition:{type:"spring",stiffness:400,damping:25},onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),children:[jsxRuntime.jsx(framerMotion.AnimatePresence,{children:r&&jsxRuntime.jsx(framerMotion.motion.div,{initial:{opacity:0,y:6,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:6,scale:.95},transition:{type:"spring",stiffness:500,damping:30},style:{position:"absolute",bottom:"calc(100% + 8px)",left:"50%",transform:"translateX(-50%)",padding:"6px 12px",borderRadius:"8px",background:"var(--bf-panel-bg)",border:"1px solid var(--bf-border)",boxShadow:"var(--bf-shadow)",whiteSpace:"nowrap",fontSize:"12px",color:"var(--bf-panel-fg)",pointerEvents:"none"},children:"Got feedback?"})}),jsxRuntime.jsx(framerMotion.motion.button,{type:"button",onClick:e,"aria-label":"Give feedback",style:{display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",borderRadius:"50%",border:"1px solid var(--bf-border)",background:"var(--bf-panel-bg)",color:"var(--bf-panel-fg)",boxShadow:"var(--bf-shadow)",cursor:"pointer",padding:0},animate:{y:[0,-3,0]},transition:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:jsxRuntime.jsx(te,{size:16})})]})})}function ne(t){return t==="bottom-left"||t==="top-left"}function We(t){return `bf-trigger-edge ${ne(t)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function se({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false),l=ne(t);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:We(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{opacity:0,width:0},animate:{opacity:1,width:r?140:22,height:r?40:90},exit:{width:0,opacity:0},transition:{type:"spring",stiffness:350,damping:30},whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:[jsxRuntime.jsxs(framerMotion.motion.span,{animate:{rotate:r?0:l?-90:90,opacity:r?1:.6},transition:{type:"spring",stiffness:300,damping:25},style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:{type:"spring",stiffness:500,damping:20},style:{width:"6px",height:"6px",borderRadius:"50%",background:"var(--bf-accent)",flexShrink:0}}),"Feedback"]}),jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",animate:{opacity:r?1:0},style:{position:"absolute",top:0,bottom:0,[l?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}})]})})}function de({delay:t,hovered:e}){return jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"12px",height:"12px",borderRadius:"50%",border:"2px solid var(--bf-accent)",pointerEvents:"none",left:"50%",top:"50%",x:"-50%",y:"-50%"},animate:e?{scale:1.3,opacity:.6}:{scale:[1,2.5],opacity:[.5,0]},transition:e?{type:"spring",stiffness:300,damping:20}:{duration:2,repeat:1/0,delay:t,ease:"easeOut"}})}function pe({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0},animate:{scale:1,opacity:1,padding:r?"10px 16px":"10px 10px"},exit:{scale:0,opacity:0},transition:{type:"spring",stiffness:400,damping:25},whileTap:{scale:.92},style:{position:"relative",overflow:"visible"},children:[jsxRuntime.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:[jsxRuntime.jsx(de,{delay:0,hovered:r}),jsxRuntime.jsx(de,{delay:.7,hovered:r})]}),jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1},animate:{scale:r?1.1:1},transition:{type:"spring",stiffness:400,damping:20}}),jsxRuntime.jsx(framerMotion.AnimatePresence,{children:r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,width:0,x:-12},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-12},transition:{type:"spring",stiffness:400,damping:25},style:{whiteSpace:"nowrap",overflow:"hidden",position:"relative",zIndex:1},children:"Feedback"})})]})})}function Ge(t){switch(t){case "bottom-left":return "bf-trigger-minimal bf-trigger-bl";case "top-right":return "bf-trigger-minimal bf-trigger-tr";case "top-left":return "bf-trigger-minimal bf-trigger-tl";default:return "bf-trigger-minimal"}}function be({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:Ge(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{opacity:0,y:5},animate:{opacity:r?1:.65,y:0},exit:{opacity:0,y:5},transition:{type:"spring",stiffness:400,damping:30},whileTap:{scale:.95},children:[jsxRuntime.jsx("span",{children:"Feedback"}),jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",bottom:4,left:4,right:4,height:"2px",background:"var(--bf-accent)",borderRadius:"1px",transformOrigin:"left"},initial:false,animate:{scaleX:r?1:0},transition:{type:"spring",stiffness:400,damping:25}})]})})}function ge({position:t,onClick:e,isVisible:i}){let[r,o]=react.useState(false);return jsxRuntime.jsx(framerMotion.AnimatePresence,{children:i&&jsxRuntime.jsxs(framerMotion.motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0,rotate:-45},animate:{scale:1,opacity:1,rotate:0,padding:r?"10px 16px":"10px 10px"},exit:{rotate:180,scale:0,opacity:0},transition:{type:"spring",stiffness:400,damping:22},whileTap:{scale:.9,rotate:360},style:{overflow:"hidden"},children:[jsxRuntime.jsx(framerMotion.motion.span,{style:{display:"inline-flex",flexShrink:0},animate:r?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:r?{type:"spring",stiffness:500,damping:12}:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsxRuntime.jsx(oe,{size:16})}),jsxRuntime.jsx(framerMotion.AnimatePresence,{children:r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,width:0,x:-16},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-16},transition:{type:"spring",stiffness:350,damping:25,delay:.03},style:{whiteSpace:"nowrap",overflow:"hidden"},children:"Feedback"})})]})})}function me(t){switch(t){case "dot":return ee;case "bubble":return ie;case "edge-tab":return se;case "pulse-ring":return pe;case "minimal":return be;case "icon-pop":return ge;default:return Q}}function xe(t,e,i){return Math.max(e,Math.min(i,t))}function qe(t,e,i="bottom-right"){let o=window.innerWidth,l=window.innerHeight,n;n=xe(t.x,12,Math.max(12,o-e-12));let p=t.y+t.height+12,S=Math.max(12,t.y-240);return {top:p+240<=l?p:S,left:n}}function Ye(t){let{rect:e}=t,i={left:`${e.x}px`,top:`${e.y}px`,width:`${Math.max(0,e.width)}px`,height:`${Math.max(0,e.height)}px`};return jsxRuntime.jsx("div",{className:"bf-highlight",style:i,"aria-hidden":"true"})}function Je(t){let e=react.useRef(null);return react.useEffect(()=>{if(!t||!e.current)return;e.current.querySelector(".bf-textarea")?.focus();let r=o=>{if(o.key!=="Tab"||!e.current)return;let l=e.current.querySelectorAll('button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])');if(l.length===0)return;let n=l[0],p=l[l.length-1];o.shiftKey&&document.activeElement===n?(o.preventDefault(),p.focus()):!o.shiftKey&&document.activeElement===p&&(o.preventDefault(),n.focus());};return document.addEventListener("keydown",r,{capture:true}),()=>document.removeEventListener("keydown",r,{capture:true})},[t]),e}function Qe(t){let{state:e,controller:i,start:r,stop:o,clearSelection:l,submit:n}=A(),p=t.config.ui?.position,[S,_]=react.useState(null),[g,D]=react.useState(""),[B,O]=react.useState(t.config.capture?.element??true),[E,G]=react.useState(t.config.capture?.fullPage??false),[ye,K]=react.useState(null),V=e.phase==="review"||e.phase==="capturing"||e.phase==="submitting"||e.phase==="error"||e.phase==="success",ve=Je(V);react.useEffect(()=>i.subscribeHover(_),[i]),react.useEffect(()=>{let s=i.__unsafeGetSelectedElement();if(!s||e.phase==="idle"||e.phase==="picking"){K(null);return}let $=()=>{K(chunkJLPJP7DD_cjs.b(s.getBoundingClientRect()));};$();let w=()=>$();return window.addEventListener("scroll",w,{capture:true,passive:true}),window.addEventListener("resize",w,{passive:true}),()=>{window.removeEventListener("scroll",w,{capture:true}),window.removeEventListener("resize",w);}},[i,e.phase,e.selection?.selector]),react.useEffect(()=>{e.phase==="review"&&(D(""),O(t.config.capture?.element??true),G(t.config.capture?.fullPage??false));},[e.phase,e.selection?.selector,t.config.capture?.element,t.config.capture?.fullPage]),react.useEffect(()=>{if(e.phase!=="success")return;let s=window.setTimeout(()=>o(),1200);return ()=>window.clearTimeout(s)},[e.phase,o]);let f=e.phase==="capturing"||e.phase==="submitting",b=e.phase==="picking"?S?.rect??null:ye??e.selection?.rect??null,N=react.useMemo(()=>b?qe(b,360,p):null,[b?.x,b?.y,b?.width,b?.height,p]),X=e.lastError?.message,z=react.useCallback(()=>{n(g,{capture:{element:B,fullPage:E}});},[n,g,B,E]),we=react.useCallback(s=>{(s.metaKey||s.ctrlKey)&&s.key==="Enter"&&g.trim().length>0&&!f&&(s.preventDefault(),z());},[z,g,f]),ke=me(t.config.ui?.triggerStyle);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ke,{position:p,onClick:()=>r(),isVisible:e.phase==="idle"}),e.phase!=="idle"&&jsxRuntime.jsxs("div",{className:"bf-overlay",role:"presentation",children:[e.phase!=="picking"&&jsxRuntime.jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>o()}),b&&jsxRuntime.jsx(Ye,{rect:b}),e.phase==="picking"&&jsxRuntime.jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsxRuntime.jsxs("p",{id:"bf-hint-text",children:["Click an element to attach your feedback. Press ",jsxRuntime.jsx("strong",{children:"Esc"})," to cancel."]}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),"aria-label":"Cancel element selection",children:"Cancel"})]}),V&&N&&jsxRuntime.jsxs("div",{ref:ve,className:"bf-panel",style:{left:N.left,top:N.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxRuntime.jsxs("div",{className:"bf-panelHeader",children:[jsxRuntime.jsx("div",{className:"bf-title",id:"bf-panel-title",children:"Feedback"}),jsxRuntime.jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>l(),disabled:f,"aria-label":"Re-pick element",children:"Re-pick"}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:f,"aria-label":"Close feedback form",children:"Close"})]})]}),jsxRuntime.jsxs("div",{className:"bf-panelBody",children:[jsxRuntime.jsx("textarea",{className:"bf-textarea",placeholder:"What's happening? What did you expect?",value:g,onChange:s=>D(s.target.value),onKeyDown:we,disabled:f,"aria-label":"Feedback message"}),jsxRuntime.jsxs("div",{className:"bf-row",role:"group","aria-label":"Screenshot options",children:[jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:B,onChange:s=>O(s.target.checked),disabled:f}),"Screenshot element"]}),jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:E,onChange:s=>G(s.target.checked),disabled:f}),"Full page"]})]}),e.phase==="capturing"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Capturing screenshots\u2026"]}),e.phase==="submitting"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Submitting\u2026"]}),e.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:"Sent. Thank you!"}),e.phase==="error"&&X&&jsxRuntime.jsx("div",{className:"bf-error",role:"alert",children:X}),jsxRuntime.jsxs("div",{className:"bf-actions",children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:f,"aria-label":"Cancel feedback",children:"Cancel"}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:z,disabled:f||g.trim().length===0,"aria-label":"Send feedback",children:"Send"})]})]})]})]}),e.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:"Feedback sent"})]})}function Ze(t){let e={...t.config??{},blocfeed_id:t.blocfeed_id},[i,r]=react.useState(null);return react.useEffect(()=>{J();let o=document.createElement("div");o.setAttribute("data-blocfeed-ui-root","true"),o.setAttribute("data-blocfeed-ui","true");let l=e.ui?.zIndex;typeof l=="number"&&o.style.setProperty("--bf-z",String(l));let n=e.ui?.theme;return n&&(n.accentColor&&o.style.setProperty("--bf-accent",n.accentColor),n.panelBackground&&o.style.setProperty("--bf-panel-bg",n.panelBackground),n.panelForeground&&o.style.setProperty("--bf-panel-fg",n.panelForeground),n.fontFamily&&o.style.setProperty("--bf-font",n.fontFamily)),document.body.appendChild(o),r(o),()=>{o.remove(),r(null);}},[e.ui?.zIndex,e.ui?.theme?.accentColor,e.ui?.theme?.panelBackground,e.ui?.theme?.panelForeground,e.ui?.theme?.fontFamily]),i?reactDom.createPortal(jsxRuntime.jsx(M,{blocfeed_id:e.blocfeed_id,...t.config?{config:t.config}:{},children:jsxRuntime.jsx(Qe,{config:e})}),i):null}
390
- exports.BlocFeedProvider=M;exports.BlocFeedWidget=Ze;exports.useBlocFeed=A;
389
+
390
+ /* ------------------------------------------------------------------ */
391
+ /* Queue badge */
392
+ /* ------------------------------------------------------------------ */
393
+
394
+ :where([data-blocfeed-ui-root]) .bf-badge {
395
+ display: inline-flex;
396
+ align-items: center;
397
+ justify-content: center;
398
+ min-width: 16px;
399
+ height: 16px;
400
+ padding: 0 4px;
401
+ border-radius: 999px;
402
+ background: var(--bf-danger);
403
+ color: white;
404
+ font-size: 10px;
405
+ font-weight: 600;
406
+ line-height: 1;
407
+ flex-shrink: 0;
408
+ }
409
+
410
+ :where([data-blocfeed-ui-root]) .bf-badge-float {
411
+ position: absolute;
412
+ top: -4px;
413
+ right: -4px;
414
+ }
415
+
416
+ /* ------------------------------------------------------------------ */
417
+ /* Typewriter cursor */
418
+ /* ------------------------------------------------------------------ */
419
+
420
+ :where([data-blocfeed-ui-root]) .bf-cursor {
421
+ display: inline-block;
422
+ width: 1px;
423
+ height: 1em;
424
+ background: var(--bf-panel-fg);
425
+ margin-left: 1px;
426
+ vertical-align: text-bottom;
427
+ animation: bf-blink 1s steps(2) infinite;
428
+ }
429
+
430
+ @keyframes bf-blink {
431
+ 0% { opacity: 1; }
432
+ 50% { opacity: 0; }
433
+ }
434
+
435
+ /* ------------------------------------------------------------------ */
436
+ /* Panel / toast / hint entrance animations */
437
+ /* ------------------------------------------------------------------ */
438
+
439
+ :where([data-blocfeed-ui-root]) .bf-panel {
440
+ animation: bf-panel-in 0.2s ease-out;
441
+ }
442
+
443
+ @keyframes bf-panel-in {
444
+ from { opacity: 0; transform: translateY(8px); }
445
+ to { opacity: 1; transform: translateY(0); }
446
+ }
447
+
448
+ :where([data-blocfeed-ui-root]) .bf-toast {
449
+ animation: bf-toast-in 0.25s ease-out;
450
+ }
451
+
452
+ @keyframes bf-toast-in {
453
+ from { opacity: 0; transform: translateX(-50%) translateY(12px); }
454
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
455
+ }
456
+
457
+ :where([data-blocfeed-ui-root]) .bf-hint {
458
+ animation: bf-hint-in 0.2s ease-out;
459
+ }
460
+
461
+ @keyframes bf-hint-in {
462
+ from { opacity: 0; transform: translateX(-50%) translateY(-10px); }
463
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
464
+ }
465
+
466
+ /* ------------------------------------------------------------------ */
467
+ /* Reduced motion */
468
+ /* ------------------------------------------------------------------ */
469
+
470
+ @media (prefers-reduced-motion: reduce) {
471
+ :where([data-blocfeed-ui-root]) .bf-panel,
472
+ :where([data-blocfeed-ui-root]) .bf-toast,
473
+ :where([data-blocfeed-ui-root]) .bf-hint,
474
+ :where([data-blocfeed-ui-root]) .bf-cursor {
475
+ animation: none;
476
+ }
477
+ }
478
+ `;function de(){if(!chunkJLPJP7DD_cjs.a()||document.getElementById(ce))return;let t=document.createElement("style");t.id=ce,t.textContent=tt,document.head.appendChild(t);}function Z(){let t=react.useContext($);if(!t)throw new Error("useBlocFeed must be used within a <BlocFeedProvider />");return {state:t.state,controller:t.controller,start:t.controller.start,stop:t.controller.stop,clearSelection:t.controller.clearSelection,submit:t.controller.submit}}function m(t){switch(t){case "bottom-left":return "bf-trigger bf-trigger-bl";case "top-right":return "bf-trigger bf-trigger-tr";case "top-left":return "bf-trigger bf-trigger-tl";default:return "bf-trigger"}}function f({size:t=14}){return jsxRuntime.jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function pe({size:t=14}){return jsxRuntime.jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsxRuntime.jsx("path",{d:"M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function fe({size:t=16}){return jsxRuntime.jsxs("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsxRuntime.jsx("path",{d:"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),jsxRuntime.jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function be({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){return n?jsxRuntime.jsxs("button",{className:m(t),type:"button",onClick:e,"aria-label":i,children:[c?jsxRuntime.jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{className:"bf-dot","aria-hidden":"true"}),i]}),o>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]}):null}function b(){let[t,e]=react.useState(()=>typeof window>"u"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches);return react.useEffect(()=>{let n=window.matchMedia("(prefers-reduced-motion: reduce)"),i=o=>e(o.matches);return n.addEventListener("change",i),()=>n.removeEventListener("change",i)},[]),t}var lt={duration:.18,ease:"easeOut"},ct={duration:0};function ge({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=react.useState(false),a=b(),s=a?ct:lt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",animate:a?{}:{scale:r?1:[1,1.2,1],boxShadow:r?"0 0 0 4px rgba(99, 102, 241, 0.18)":["0 0 0 4px rgba(99, 102, 241, 0.18)","0 0 0 8px rgba(99, 102, 241, 0.28)","0 0 0 4px rgba(99, 102, 241, 0.18)"]},transition:r||a?s:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:a?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-6},transition:s,style:{whiteSpace:"nowrap"},children:i},"label")}),o>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"dot")})}var ut={duration:.18,ease:"easeOut"},xe={duration:0};function ve({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=react.useState(false),a=b(),s=a?xe:ut;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsxs(framerMotion.motion.div,{className:m(t),initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{y:8,opacity:0},transition:s,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),style:{background:"transparent",border:"none",boxShadow:"none",padding:0},children:[jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:r&&jsxRuntime.jsx(framerMotion.motion.div,{initial:{opacity:0,y:a?0:4},animate:{opacity:1,y:0},exit:{opacity:0,y:a?0:4},transition:s,style:{position:"absolute",bottom:"calc(100% + 8px)",left:"50%",transform:"translateX(-50%)",padding:"6px 12px",borderRadius:"8px",background:"var(--bf-panel-bg)",border:"1px solid var(--bf-border)",boxShadow:"var(--bf-shadow)",whiteSpace:"nowrap",fontSize:"12px",color:"var(--bf-panel-fg)",pointerEvents:"none"},children:i},"tooltip")}),jsxRuntime.jsxs(framerMotion.motion.button,{type:"button",onClick:e,"aria-label":i,style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",borderRadius:"50%",border:"1px solid var(--bf-border)",background:"var(--bf-panel-bg)",color:"var(--bf-panel-fg)",boxShadow:"var(--bf-shadow)",cursor:"pointer",padding:0},animate:a?{}:{y:[0,-3,0]},transition:a?xe:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:[c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:16})},"success"):jsxRuntime.jsx(pe,{size:16}),o>0&&jsxRuntime.jsx("span",{className:"bf-badge bf-badge-float","aria-label":`${o} queued`,children:o})]})]},"bubble")})}var gt={duration:.2,ease:"easeOut"},ht={duration:0};function ke(t){return t==="bottom-left"||t==="top-left"}function xt(t){return `bf-trigger-edge ${ke(t)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function Te({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=react.useState(false),a=ke(t),s=b(),u=s?ht:gt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:xt(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{opacity:0,width:0},animate:{opacity:1,width:r?140:22,height:r?40:90},exit:{width:0,opacity:0},transition:u,whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:u,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(framerMotion.motion.span,{animate:{rotate:s||r?0:a?-90:90,opacity:r?1:.6},transition:u,style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:{duration:.12},style:{width:"6px",height:"6px",borderRadius:"50%",background:"var(--bf-accent)",flexShrink:0}}),i]}),jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",animate:{opacity:r?1:0},transition:{duration:.12},style:{position:"absolute",top:0,bottom:0,[a?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}}),o>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"edge-tab")})}var wt={duration:.18,ease:"easeOut"},kt={duration:0};function Pe({delay:t,hovered:e,reduced:n}){return n?null:jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"10px",height:"10px",borderRadius:"50%",border:"2px solid var(--bf-accent)",pointerEvents:"none"},animate:e?{scale:1,opacity:0}:{scale:[1,1.8],opacity:[.5,0]},transition:e?{duration:.15}:{duration:2,repeat:1/0,delay:t,ease:"easeOut"}})}function Se({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=react.useState(false),a=b(),s=a?kt:wt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("span",{style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsxRuntime.jsx(Pe,{delay:0,hovered:r,reduced:a}),jsxRuntime.jsx(Pe,{delay:.7,hovered:r,reduced:a}),jsxRuntime.jsx(framerMotion.motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1}})]}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:a?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-6},transition:s,style:{whiteSpace:"nowrap"},children:i},"label")}),o>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"pulse-ring")})}var Et={duration:.18,ease:"easeOut"},St={duration:0};function Nt(t){switch(t){case "bottom-left":return "bf-trigger-minimal bf-trigger-bl";case "top-right":return "bf-trigger-minimal bf-trigger-tr";case "top-left":return "bf-trigger-minimal bf-trigger-tl";default:return "bf-trigger-minimal"}}function Be({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=react.useState(false),a=b(),s=a?St:Et;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsxs(framerMotion.motion.button,{className:Nt(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{opacity:0,y:a?0:5},animate:{opacity:r?1:.65,y:0},exit:{opacity:0,y:a?0:5},transition:s,whileTap:{scale:.95},children:[c?jsxRuntime.jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{children:i}),o>0&&jsxRuntime.jsx("span",{className:"bf-badge",style:{marginLeft:"4px"},"aria-label":`${o} queued`,children:o})]}),!a&&jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",bottom:4,left:4,right:4,height:"2px",background:"var(--bf-accent)",borderRadius:"1px",transformOrigin:"left"},initial:false,animate:{scaleX:r?1:0},transition:s})]},"minimal")})}var Mt={duration:.18,ease:"easeOut"},Rt={duration:0};function Re({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=react.useState(false),a=b(),s=a?Rt:Mt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.9},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(framerMotion.motion.span,{style:{display:"inline-flex",flexShrink:0},animate:a?{}:r?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:r||a?s:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsxRuntime.jsx(fe,{size:16})}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:a?0:-8},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-8},transition:s,style:{whiteSpace:"nowrap"},children:i},"label")}),o>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"icon-pop")})}var Lt={duration:.18,ease:"easeOut"},Wt={duration:0};function Ae({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=react.useState(false),a=b(),s=a?Wt:Lt;return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("span",{style:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{width:"10px",height:"10px",borderRadius:"50%",background:"var(--bf-accent)",position:"relative",zIndex:1},animate:a?{}:{opacity:r?1:[.5,1,.5],boxShadow:r?"0 0 8px 2px var(--bf-accent)":["0 0 4px 1px var(--bf-accent)","0 0 12px 4px var(--bf-accent)","0 0 4px 1px var(--bf-accent)"]},transition:r||a?s:{duration:2,repeat:1/0,ease:"easeInOut"}}),!r&&!a&&jsxRuntime.jsx(framerMotion.motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"18px",height:"2px",background:"linear-gradient(90deg, var(--bf-accent), transparent)",transformOrigin:"left center",left:"5px",top:"4px"},animate:{rotate:[0,360]},transition:{duration:4,repeat:1/0,ease:"linear"}})]}),jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:r&&jsxRuntime.jsx(framerMotion.motion.span,{initial:{opacity:0,x:a?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-6},transition:s,style:{whiteSpace:"nowrap"},children:i},"label")}),o>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"beacon")})}var Dt={duration:.18,ease:"easeOut"},$t={duration:0};function Oe({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=react.useState(false),[a,s]=react.useState(0),u=b(),W=u?$t:Dt,h=react.useRef(null);react.useEffect(()=>{if(h.current&&(clearInterval(h.current),h.current=null),!n||r||u){s(r||u?i.length:0);return}let P=8,D=i.length*2+P*2,v=0;return h.current=setInterval(()=>{v=(v+1)%D,v<=i.length?s(v):v<=i.length+P?s(i.length):v<=i.length*2+P?s(i.length*2+P-v):s(0);},100),()=>{h.current&&(clearInterval(h.current),h.current=null);}},[n,r,u,i]);let K=i.slice(0,a);return jsxRuntime.jsx(framerMotion.AnimatePresence,{mode:"wait",children:n&&jsxRuntime.jsx(framerMotion.motion.button,{className:m(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{opacity:0,y:u?0:5},animate:{opacity:1,y:0},exit:{opacity:0,y:u?0:5},transition:W,whileTap:{scale:.95},style:{minWidth:"44px"},children:c?jsxRuntime.jsx(framerMotion.motion.span,{initial:{scale:0},animate:{scale:1},transition:W,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsxRuntime.jsx(f,{size:14})},"success"):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{className:"bf-dot","aria-hidden":"true"}),jsxRuntime.jsxs("span",{style:{whiteSpace:"nowrap",minWidth:"1ch"},children:[K,jsxRuntime.jsx("span",{className:"bf-cursor","aria-hidden":"true"})]}),o>0&&jsxRuntime.jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"typewriter")})}function He(t){switch(t){case "dot":return ge;case "bubble":return ve;case "edge-tab":return Te;case "pulse-ring":return Se;case "minimal":return Be;case "icon-pop":return Re;case "beacon":return Ae;case "typewriter":return Oe;default:return be}}function De(t,e,n){return Math.max(e,Math.min(n,t))}function Qt(t,e,n="bottom-right"){let o=window.innerWidth,c=window.innerHeight,r;r=De(t.x,12,Math.max(12,o-e-12));let l=t.y+t.height+12,a=Math.max(12,t.y-240);return {top:l+240<=c?l:a,left:r}}function Ut(t){let{rect:e}=t,n={left:`${e.x}px`,top:`${e.y}px`,width:`${Math.max(0,e.width)}px`,height:`${Math.max(0,e.height)}px`};return jsxRuntime.jsx("div",{className:"bf-highlight",style:n,"aria-hidden":"true"})}function Vt(t){let e=react.useRef(null);return react.useEffect(()=>{if(!t||!e.current)return;e.current.querySelector(".bf-textarea")?.focus();let i=o=>{if(o.key!=="Tab"||!e.current)return;let c=e.current.querySelectorAll('button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])');if(c.length===0)return;let r=c[0],l=c[c.length-1];o.shiftKey&&document.activeElement===r?(o.preventDefault(),l.focus()):!o.shiftKey&&document.activeElement===l&&(o.preventDefault(),r.focus());};return document.addEventListener("keydown",i,{capture:true}),()=>document.removeEventListener("keydown",i,{capture:true})},[t]),e}function Gt(t){let{state:e,controller:n,start:i,stop:o,clearSelection:c,submit:r}=Z(),l=t.config.ui?.position,[a,s]=react.useState(null),[u,W]=react.useState(""),[h,K]=react.useState(t.config.capture?.element??true),[P,D]=react.useState(t.config.capture?.fullPage??false),[v,q]=react.useState(null),ee=e.phase==="review"||e.phase==="capturing"||e.phase==="submitting"||e.phase==="error"||e.phase==="success",Xe=Vt(ee),[Ye,je]=react.useState(0);react.useEffect(()=>{e.phase==="idle"&&je(chunkJLPJP7DD_cjs.i());},[e.phase]);let[Qe,te]=react.useState(false),oe=react.useRef(e.phase);react.useEffect(()=>{if(oe.current==="success"&&e.phase==="idle"){te(true);let p=window.setTimeout(()=>te(false),1500);return ()=>window.clearTimeout(p)}oe.current=e.phase;},[e.phase]),react.useEffect(()=>{let p=t.config.ui?.shortcut;if(!p)return;let z=p.toLowerCase().split("+").map(y=>y.trim()),I=z[z.length-1]||"",F=new Set(z.slice(0,-1)),ie=y=>{let Ge=/Mac|iPod|iPhone|iPad/.test(navigator.platform);if(F.has("mod")){if(Ge?!y.metaKey:!y.ctrlKey)return}else if(F.has("ctrl")&&!y.ctrlKey||(F.has("meta")||F.has("cmd"))&&!y.metaKey)return;F.has("shift")&&!y.shiftKey||(F.has("alt")||F.has("option"))&&!y.altKey||y.key.toLowerCase()===I&&(y.preventDefault(),e.phase==="idle"?i():o());};return document.addEventListener("keydown",ie),()=>document.removeEventListener("keydown",ie)},[t.config.ui?.shortcut,e.phase,i,o]),react.useEffect(()=>n.subscribeHover(s),[n]),react.useEffect(()=>{let p=n.__unsafeGetSelectedElement();if(!p||e.phase==="idle"||e.phase==="picking"){q(null);return}let z=()=>{q(chunkJLPJP7DD_cjs.b(p.getBoundingClientRect()));};z();let I=()=>z();return window.addEventListener("scroll",I,{capture:true,passive:true}),window.addEventListener("resize",I,{passive:true}),()=>{window.removeEventListener("scroll",I,{capture:true}),window.removeEventListener("resize",I);}},[n,e.phase,e.selection?.selector]),react.useEffect(()=>{e.phase==="review"&&(W(""),K(t.config.capture?.element??true),D(t.config.capture?.fullPage??false));},[e.phase,e.selection?.selector,t.config.capture?.element,t.config.capture?.fullPage]),react.useEffect(()=>{if(e.phase!=="success")return;let p=window.setTimeout(()=>o(),1200);return ()=>window.clearTimeout(p)},[e.phase,o]);let w=e.phase==="capturing"||e.phase==="submitting",E=e.phase==="picking"?a?.rect??null:v??e.selection?.rect??null,U=react.useMemo(()=>E?Qt(E,360,l):null,[E?.x,E?.y,E?.width,E?.height,l]),re=e.lastError?.message,V=react.useCallback(()=>{r(u,{capture:{element:h,fullPage:P}});},[r,u,h,P]),Ue=react.useCallback(p=>{(p.metaKey||p.ctrlKey)&&p.key==="Enter"&&u.trim().length>0&&!w&&(p.preventDefault(),V());},[V,u,w]),Ve=He(t.config.ui?.triggerStyle);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(Ve,{position:l,onClick:()=>i(),isVisible:e.phase==="idle",label:t.config.ui?.triggerLabel??"Feedback",queueCount:Ye,showSuccess:Qe}),e.phase!=="idle"&&jsxRuntime.jsxs("div",{className:"bf-overlay",role:"presentation",children:[e.phase!=="picking"&&jsxRuntime.jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>o()}),E&&jsxRuntime.jsx(Ut,{rect:E}),e.phase==="picking"&&jsxRuntime.jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsxRuntime.jsxs("p",{id:"bf-hint-text",children:["Click an element to attach your feedback. Press ",jsxRuntime.jsx("strong",{children:"Esc"})," to cancel."]}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),"aria-label":"Cancel element selection",children:"Cancel"})]}),ee&&U&&jsxRuntime.jsxs("div",{ref:Xe,className:"bf-panel",style:{left:U.left,top:U.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxRuntime.jsxs("div",{className:"bf-panelHeader",children:[jsxRuntime.jsx("div",{className:"bf-title",id:"bf-panel-title",children:"Feedback"}),jsxRuntime.jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>c(),disabled:w,"aria-label":"Re-pick element",children:"Re-pick"}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:w,"aria-label":"Close feedback form",children:"Close"})]})]}),jsxRuntime.jsxs("div",{className:"bf-panelBody",children:[jsxRuntime.jsx("textarea",{className:"bf-textarea",placeholder:"What's happening? What did you expect?",value:u,onChange:p=>W(p.target.value),onKeyDown:Ue,disabled:w,"aria-label":"Feedback message"}),jsxRuntime.jsxs("div",{className:"bf-row",role:"group","aria-label":"Screenshot options",children:[jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:h,onChange:p=>K(p.target.checked),disabled:w}),"Screenshot element"]}),jsxRuntime.jsxs("label",{children:[jsxRuntime.jsx("input",{type:"checkbox",checked:P,onChange:p=>D(p.target.checked),disabled:w}),"Full page"]})]}),e.phase==="capturing"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Capturing screenshots\u2026"]}),e.phase==="submitting"&&jsxRuntime.jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsxRuntime.jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Submitting\u2026"]}),e.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:"Sent. Thank you!"}),e.phase==="error"&&re&&jsxRuntime.jsx("div",{className:"bf-error",role:"alert",children:re}),jsxRuntime.jsxs("div",{className:"bf-actions",children:[jsxRuntime.jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:w,"aria-label":"Cancel feedback",children:"Cancel"}),jsxRuntime.jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:V,disabled:w||u.trim().length===0,"aria-label":"Send feedback",children:"Send"})]})]})]})]}),e.phase==="success"&&jsxRuntime.jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:"Feedback sent"})]})}function Jt(t){let e={...t.config??{},blocfeed_id:t.blocfeed_id},[n,i]=react.useState(null);return react.useEffect(()=>{de();let o=document.createElement("div");o.setAttribute("data-blocfeed-ui-root","true"),o.setAttribute("data-blocfeed-ui","true");let c=e.ui?.zIndex;typeof c=="number"&&o.style.setProperty("--bf-z",String(c));let r=e.ui?.theme;return r&&(r.accentColor&&o.style.setProperty("--bf-accent",r.accentColor),r.panelBackground&&o.style.setProperty("--bf-panel-bg",r.panelBackground),r.panelForeground&&o.style.setProperty("--bf-panel-fg",r.panelForeground),r.fontFamily&&o.style.setProperty("--bf-font",r.fontFamily)),document.body.appendChild(o),i(o),()=>{o.remove(),i(null);}},[e.ui?.zIndex,e.ui?.theme?.accentColor,e.ui?.theme?.panelBackground,e.ui?.theme?.panelForeground,e.ui?.theme?.fontFamily]),n?reactDom.createPortal(jsxRuntime.jsx(J,{blocfeed_id:e.blocfeed_id,...t.config?{config:t.config}:{},children:jsxRuntime.jsx(Gt,{config:e})}),n):null}
479
+ exports.BlocFeedProvider=J;exports.BlocFeedWidget=Jt;exports.useBlocFeed=Z;
package/dist/main.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BlocFeedConfig, a as BlocFeedState, b as BlocFeedController, C as CaptureConfig, S as SubmitResult } from './controller-D7kOehzb.cjs';
2
- export { c as BlocFeedError, d as BlocFeedUser, e as CaptureDiagnostics, f as CaptureResult, E as ElementDescriptor, F as FeedbackApiResponse, g as FeedbackPayload, I as ImageAsset, M as MaybePromise, h as MetadataConfig, i as MetadataContext, P as PickerConfig, R as Rect, j as ScreenshotAdapter, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, T as ThemeConfig, o as TransportConfig, p as TransportResult, q as TriggerStyle, W as WidgetPosition } from './controller-D7kOehzb.cjs';
1
+ import { B as BlocFeedConfig, a as BlocFeedState, b as BlocFeedController, C as CaptureConfig, S as SubmitResult } from './controller-did-WBAQ.cjs';
2
+ export { c as BlocFeedError, d as BlocFeedUser, e as CaptureDiagnostics, f as CaptureResult, E as ElementDescriptor, F as FeedbackApiResponse, g as FeedbackPayload, I as ImageAsset, M as MaybePromise, h as MetadataConfig, i as MetadataContext, P as PickerConfig, R as Rect, j as ScreenshotAdapter, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, T as ThemeConfig, o as TransportConfig, p as TransportResult, q as TriggerStyle, W as WidgetPosition } from './controller-did-WBAQ.cjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
package/dist/main.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as BlocFeedConfig, a as BlocFeedState, b as BlocFeedController, C as CaptureConfig, S as SubmitResult } from './controller-D7kOehzb.js';
2
- export { c as BlocFeedError, d as BlocFeedUser, e as CaptureDiagnostics, f as CaptureResult, E as ElementDescriptor, F as FeedbackApiResponse, g as FeedbackPayload, I as ImageAsset, M as MaybePromise, h as MetadataConfig, i as MetadataContext, P as PickerConfig, R as Rect, j as ScreenshotAdapter, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, T as ThemeConfig, o as TransportConfig, p as TransportResult, q as TriggerStyle, W as WidgetPosition } from './controller-D7kOehzb.js';
1
+ import { B as BlocFeedConfig, a as BlocFeedState, b as BlocFeedController, C as CaptureConfig, S as SubmitResult } from './controller-did-WBAQ.js';
2
+ export { c as BlocFeedError, d as BlocFeedUser, e as CaptureDiagnostics, f as CaptureResult, E as ElementDescriptor, F as FeedbackApiResponse, g as FeedbackPayload, I as ImageAsset, M as MaybePromise, h as MetadataConfig, i as MetadataContext, P as PickerConfig, R as Rect, j as ScreenshotAdapter, k as ScreenshotAdapterOptions, l as ScreenshotIntent, m as ScreenshotMime, n as SessionPhase, T as ThemeConfig, o as TransportConfig, p as TransportResult, q as TriggerStyle, W as WidgetPosition } from './controller-did-WBAQ.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import {j,a,b}from'./chunk-FMFONS5S.js';import {createContext,useMemo,useState,useEffect,useContext,useCallback,useRef}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {createPortal}from'react-dom';import {AnimatePresence,motion}from'framer-motion';var k=createContext(null);function M(t){let e=useMemo(()=>j({...t.config??{},blocfeed_id:t.blocfeed_id}),[]),[i,r]=useState(()=>e.getState());return useEffect(()=>e.subscribe(r),[e]),useEffect(()=>e.setConfig({...t.config??{},blocfeed_id:t.blocfeed_id}),[e,t.config,t.blocfeed_id]),useEffect(()=>()=>e.destroy(),[e]),jsx(k.Provider,{value:{controller:e,state:i},children:t.children})}var Y="blocfeed-styles-v1",Se=`
2
+ import {j,a,i,b as b$1}from'./chunk-FMFONS5S.js';import {createContext,useMemo,useState,useEffect,useContext,useRef,useCallback}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {createPortal}from'react-dom';import {AnimatePresence,motion}from'framer-motion';var $=createContext(null);function J(t){let e=useMemo(()=>j({...t.config??{},blocfeed_id:t.blocfeed_id}),[]),[n,i]=useState(()=>e.getState());return useEffect(()=>e.subscribe(i),[e]),useEffect(()=>e.setConfig({...t.config??{},blocfeed_id:t.blocfeed_id}),[e,t.config,t.blocfeed_id]),useEffect(()=>()=>e.destroy(),[e]),jsx($.Provider,{value:{controller:e,state:n},children:t.children})}var ce="blocfeed-styles-v1",tt=`
3
3
  :where([data-blocfeed-ui-root]),
4
4
  :where([data-blocfeed-ui-root]) * {
5
5
  box-sizing: border-box;
@@ -386,5 +386,94 @@ import {j,a,b}from'./chunk-FMFONS5S.js';import {createContext,useMemo,useState,u
386
386
  white-space: nowrap;
387
387
  border: 0;
388
388
  }
389
- `;function J(){if(!a()||document.getElementById(Y))return;let t=document.createElement("style");t.id=Y,t.textContent=Se,document.head.appendChild(t);}function A(){let t=useContext(k);if(!t)throw new Error("useBlocFeed must be used within a <BlocFeedProvider />");return {state:t.state,controller:t.controller,start:t.controller.start,stop:t.controller.stop,clearSelection:t.controller.clearSelection,submit:t.controller.submit}}function c(t){switch(t){case "bottom-left":return "bf-trigger bf-trigger-bl";case "top-right":return "bf-trigger bf-trigger-tr";case "top-left":return "bf-trigger bf-trigger-tl";default:return "bf-trigger"}}function Q({position:t,onClick:e,isVisible:i}){return i?jsxs("button",{className:c(t),type:"button",onClick:e,"aria-label":"Give feedback",children:[jsx("span",{className:"bf-dot","aria-hidden":"true"}),"Feedback"]}):null}function ee({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false);return jsx(AnimatePresence,{children:i&&jsxs(motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0},animate:{scale:1,opacity:1,padding:r?"10px 16px":"10px 10px"},exit:{scale:0,opacity:0},transition:{type:"spring",stiffness:500,damping:28},whileTap:{scale:.92},style:{overflow:"hidden"},children:[jsx(motion.span,{className:"bf-dot","aria-hidden":"true",animate:{scale:r?1:[1,1.2,1],boxShadow:r?"0 0 0 4px rgba(99, 102, 241, 0.18)":["0 0 0 4px rgba(99, 102, 241, 0.18)","0 0 0 8px rgba(99, 102, 241, 0.28)","0 0 0 4px rgba(99, 102, 241, 0.18)"]},transition:r?{type:"spring",stiffness:400,damping:20}:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsx(AnimatePresence,{children:r&&jsx(motion.span,{initial:{opacity:0,width:0,x:-8},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-8},transition:{type:"spring",stiffness:400,damping:25},style:{whiteSpace:"nowrap",overflow:"hidden"},children:"Feedback"})}),jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",inset:0,borderRadius:"inherit",border:"2px solid var(--bf-accent)",pointerEvents:"none"},initial:false,animate:{scale:1,opacity:0},whileTap:{scale:2.5,opacity:[.6,0]},transition:{duration:.4}})]})})}function te({size:t=14}){return jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function oe({size:t=16}){return jsxs("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsx("path",{d:"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function ie({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false);return jsx(AnimatePresence,{children:i&&jsxs(motion.div,{style:{position:"fixed",zIndex:"var(--bf-z)"},className:c(t),initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{y:12,opacity:0,scale:.8},transition:{type:"spring",stiffness:400,damping:25},onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),children:[jsx(AnimatePresence,{children:r&&jsx(motion.div,{initial:{opacity:0,y:6,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:6,scale:.95},transition:{type:"spring",stiffness:500,damping:30},style:{position:"absolute",bottom:"calc(100% + 8px)",left:"50%",transform:"translateX(-50%)",padding:"6px 12px",borderRadius:"8px",background:"var(--bf-panel-bg)",border:"1px solid var(--bf-border)",boxShadow:"var(--bf-shadow)",whiteSpace:"nowrap",fontSize:"12px",color:"var(--bf-panel-fg)",pointerEvents:"none"},children:"Got feedback?"})}),jsx(motion.button,{type:"button",onClick:e,"aria-label":"Give feedback",style:{display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",borderRadius:"50%",border:"1px solid var(--bf-border)",background:"var(--bf-panel-bg)",color:"var(--bf-panel-fg)",boxShadow:"var(--bf-shadow)",cursor:"pointer",padding:0},animate:{y:[0,-3,0]},transition:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:jsx(te,{size:16})})]})})}function ne(t){return t==="bottom-left"||t==="top-left"}function We(t){return `bf-trigger-edge ${ne(t)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function se({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false),l=ne(t);return jsx(AnimatePresence,{children:i&&jsxs(motion.button,{className:We(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{opacity:0,width:0},animate:{opacity:1,width:r?140:22,height:r?40:90},exit:{width:0,opacity:0},transition:{type:"spring",stiffness:350,damping:30},whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:[jsxs(motion.span,{animate:{rotate:r?0:l?-90:90,opacity:r?1:.6},transition:{type:"spring",stiffness:300,damping:25},style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[r&&jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:{type:"spring",stiffness:500,damping:20},style:{width:"6px",height:"6px",borderRadius:"50%",background:"var(--bf-accent)",flexShrink:0}}),"Feedback"]}),jsx(motion.span,{"aria-hidden":"true",animate:{opacity:r?1:0},style:{position:"absolute",top:0,bottom:0,[l?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}})]})})}function de({delay:t,hovered:e}){return jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"12px",height:"12px",borderRadius:"50%",border:"2px solid var(--bf-accent)",pointerEvents:"none",left:"50%",top:"50%",x:"-50%",y:"-50%"},animate:e?{scale:1.3,opacity:.6}:{scale:[1,2.5],opacity:[.5,0]},transition:e?{type:"spring",stiffness:300,damping:20}:{duration:2,repeat:1/0,delay:t,ease:"easeOut"}})}function pe({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false);return jsx(AnimatePresence,{children:i&&jsxs(motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0},animate:{scale:1,opacity:1,padding:r?"10px 16px":"10px 10px"},exit:{scale:0,opacity:0},transition:{type:"spring",stiffness:400,damping:25},whileTap:{scale:.92},style:{position:"relative",overflow:"visible"},children:[jsxs("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:[jsx(de,{delay:0,hovered:r}),jsx(de,{delay:.7,hovered:r})]}),jsx(motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1},animate:{scale:r?1.1:1},transition:{type:"spring",stiffness:400,damping:20}}),jsx(AnimatePresence,{children:r&&jsx(motion.span,{initial:{opacity:0,width:0,x:-12},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-12},transition:{type:"spring",stiffness:400,damping:25},style:{whiteSpace:"nowrap",overflow:"hidden",position:"relative",zIndex:1},children:"Feedback"})})]})})}function Ge(t){switch(t){case "bottom-left":return "bf-trigger-minimal bf-trigger-bl";case "top-right":return "bf-trigger-minimal bf-trigger-tr";case "top-left":return "bf-trigger-minimal bf-trigger-tl";default:return "bf-trigger-minimal"}}function be({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false);return jsx(AnimatePresence,{children:i&&jsxs(motion.button,{className:Ge(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{opacity:0,y:5},animate:{opacity:r?1:.65,y:0},exit:{opacity:0,y:5},transition:{type:"spring",stiffness:400,damping:30},whileTap:{scale:.95},children:[jsx("span",{children:"Feedback"}),jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",bottom:4,left:4,right:4,height:"2px",background:"var(--bf-accent)",borderRadius:"1px",transformOrigin:"left"},initial:false,animate:{scaleX:r?1:0},transition:{type:"spring",stiffness:400,damping:25}})]})})}function ge({position:t,onClick:e,isVisible:i}){let[r,o]=useState(false);return jsx(AnimatePresence,{children:i&&jsxs(motion.button,{className:c(t),type:"button",onClick:e,onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),"aria-label":"Give feedback",initial:{scale:0,opacity:0,rotate:-45},animate:{scale:1,opacity:1,rotate:0,padding:r?"10px 16px":"10px 10px"},exit:{rotate:180,scale:0,opacity:0},transition:{type:"spring",stiffness:400,damping:22},whileTap:{scale:.9,rotate:360},style:{overflow:"hidden"},children:[jsx(motion.span,{style:{display:"inline-flex",flexShrink:0},animate:r?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:r?{type:"spring",stiffness:500,damping:12}:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsx(oe,{size:16})}),jsx(AnimatePresence,{children:r&&jsx(motion.span,{initial:{opacity:0,width:0,x:-16},animate:{opacity:1,width:"auto",x:0},exit:{opacity:0,width:0,x:-16},transition:{type:"spring",stiffness:350,damping:25,delay:.03},style:{whiteSpace:"nowrap",overflow:"hidden"},children:"Feedback"})})]})})}function me(t){switch(t){case "dot":return ee;case "bubble":return ie;case "edge-tab":return se;case "pulse-ring":return pe;case "minimal":return be;case "icon-pop":return ge;default:return Q}}function xe(t,e,i){return Math.max(e,Math.min(i,t))}function qe(t,e,i="bottom-right"){let o=window.innerWidth,l=window.innerHeight,n;n=xe(t.x,12,Math.max(12,o-e-12));let p=t.y+t.height+12,S=Math.max(12,t.y-240);return {top:p+240<=l?p:S,left:n}}function Ye(t){let{rect:e}=t,i={left:`${e.x}px`,top:`${e.y}px`,width:`${Math.max(0,e.width)}px`,height:`${Math.max(0,e.height)}px`};return jsx("div",{className:"bf-highlight",style:i,"aria-hidden":"true"})}function Je(t){let e=useRef(null);return useEffect(()=>{if(!t||!e.current)return;e.current.querySelector(".bf-textarea")?.focus();let r=o=>{if(o.key!=="Tab"||!e.current)return;let l=e.current.querySelectorAll('button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])');if(l.length===0)return;let n=l[0],p=l[l.length-1];o.shiftKey&&document.activeElement===n?(o.preventDefault(),p.focus()):!o.shiftKey&&document.activeElement===p&&(o.preventDefault(),n.focus());};return document.addEventListener("keydown",r,{capture:true}),()=>document.removeEventListener("keydown",r,{capture:true})},[t]),e}function Qe(t){let{state:e,controller:i,start:r,stop:o,clearSelection:l,submit:n}=A(),p=t.config.ui?.position,[S,_]=useState(null),[g,D]=useState(""),[B,O]=useState(t.config.capture?.element??true),[E,G]=useState(t.config.capture?.fullPage??false),[ye,K]=useState(null),V=e.phase==="review"||e.phase==="capturing"||e.phase==="submitting"||e.phase==="error"||e.phase==="success",ve=Je(V);useEffect(()=>i.subscribeHover(_),[i]),useEffect(()=>{let s=i.__unsafeGetSelectedElement();if(!s||e.phase==="idle"||e.phase==="picking"){K(null);return}let $=()=>{K(b(s.getBoundingClientRect()));};$();let w=()=>$();return window.addEventListener("scroll",w,{capture:true,passive:true}),window.addEventListener("resize",w,{passive:true}),()=>{window.removeEventListener("scroll",w,{capture:true}),window.removeEventListener("resize",w);}},[i,e.phase,e.selection?.selector]),useEffect(()=>{e.phase==="review"&&(D(""),O(t.config.capture?.element??true),G(t.config.capture?.fullPage??false));},[e.phase,e.selection?.selector,t.config.capture?.element,t.config.capture?.fullPage]),useEffect(()=>{if(e.phase!=="success")return;let s=window.setTimeout(()=>o(),1200);return ()=>window.clearTimeout(s)},[e.phase,o]);let f=e.phase==="capturing"||e.phase==="submitting",b$1=e.phase==="picking"?S?.rect??null:ye??e.selection?.rect??null,N=useMemo(()=>b$1?qe(b$1,360,p):null,[b$1?.x,b$1?.y,b$1?.width,b$1?.height,p]),X=e.lastError?.message,z=useCallback(()=>{n(g,{capture:{element:B,fullPage:E}});},[n,g,B,E]),we=useCallback(s=>{(s.metaKey||s.ctrlKey)&&s.key==="Enter"&&g.trim().length>0&&!f&&(s.preventDefault(),z());},[z,g,f]),ke=me(t.config.ui?.triggerStyle);return jsxs(Fragment,{children:[jsx(ke,{position:p,onClick:()=>r(),isVisible:e.phase==="idle"}),e.phase!=="idle"&&jsxs("div",{className:"bf-overlay",role:"presentation",children:[e.phase!=="picking"&&jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>o()}),b$1&&jsx(Ye,{rect:b$1}),e.phase==="picking"&&jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsxs("p",{id:"bf-hint-text",children:["Click an element to attach your feedback. Press ",jsx("strong",{children:"Esc"})," to cancel."]}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),"aria-label":"Cancel element selection",children:"Cancel"})]}),V&&N&&jsxs("div",{ref:ve,className:"bf-panel",style:{left:N.left,top:N.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxs("div",{className:"bf-panelHeader",children:[jsx("div",{className:"bf-title",id:"bf-panel-title",children:"Feedback"}),jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>l(),disabled:f,"aria-label":"Re-pick element",children:"Re-pick"}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:f,"aria-label":"Close feedback form",children:"Close"})]})]}),jsxs("div",{className:"bf-panelBody",children:[jsx("textarea",{className:"bf-textarea",placeholder:"What's happening? What did you expect?",value:g,onChange:s=>D(s.target.value),onKeyDown:we,disabled:f,"aria-label":"Feedback message"}),jsxs("div",{className:"bf-row",role:"group","aria-label":"Screenshot options",children:[jsxs("label",{children:[jsx("input",{type:"checkbox",checked:B,onChange:s=>O(s.target.checked),disabled:f}),"Screenshot element"]}),jsxs("label",{children:[jsx("input",{type:"checkbox",checked:E,onChange:s=>G(s.target.checked),disabled:f}),"Full page"]})]}),e.phase==="capturing"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Capturing screenshots\u2026"]}),e.phase==="submitting"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Submitting\u2026"]}),e.phase==="success"&&jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:"Sent. Thank you!"}),e.phase==="error"&&X&&jsx("div",{className:"bf-error",role:"alert",children:X}),jsxs("div",{className:"bf-actions",children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:f,"aria-label":"Cancel feedback",children:"Cancel"}),jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:z,disabled:f||g.trim().length===0,"aria-label":"Send feedback",children:"Send"})]})]})]})]}),e.phase==="success"&&jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:"Feedback sent"})]})}function Ze(t){let e={...t.config??{},blocfeed_id:t.blocfeed_id},[i,r]=useState(null);return useEffect(()=>{J();let o=document.createElement("div");o.setAttribute("data-blocfeed-ui-root","true"),o.setAttribute("data-blocfeed-ui","true");let l=e.ui?.zIndex;typeof l=="number"&&o.style.setProperty("--bf-z",String(l));let n=e.ui?.theme;return n&&(n.accentColor&&o.style.setProperty("--bf-accent",n.accentColor),n.panelBackground&&o.style.setProperty("--bf-panel-bg",n.panelBackground),n.panelForeground&&o.style.setProperty("--bf-panel-fg",n.panelForeground),n.fontFamily&&o.style.setProperty("--bf-font",n.fontFamily)),document.body.appendChild(o),r(o),()=>{o.remove(),r(null);}},[e.ui?.zIndex,e.ui?.theme?.accentColor,e.ui?.theme?.panelBackground,e.ui?.theme?.panelForeground,e.ui?.theme?.fontFamily]),i?createPortal(jsx(M,{blocfeed_id:e.blocfeed_id,...t.config?{config:t.config}:{},children:jsx(Qe,{config:e})}),i):null}
390
- export{M as BlocFeedProvider,Ze as BlocFeedWidget,A as useBlocFeed};
389
+
390
+ /* ------------------------------------------------------------------ */
391
+ /* Queue badge */
392
+ /* ------------------------------------------------------------------ */
393
+
394
+ :where([data-blocfeed-ui-root]) .bf-badge {
395
+ display: inline-flex;
396
+ align-items: center;
397
+ justify-content: center;
398
+ min-width: 16px;
399
+ height: 16px;
400
+ padding: 0 4px;
401
+ border-radius: 999px;
402
+ background: var(--bf-danger);
403
+ color: white;
404
+ font-size: 10px;
405
+ font-weight: 600;
406
+ line-height: 1;
407
+ flex-shrink: 0;
408
+ }
409
+
410
+ :where([data-blocfeed-ui-root]) .bf-badge-float {
411
+ position: absolute;
412
+ top: -4px;
413
+ right: -4px;
414
+ }
415
+
416
+ /* ------------------------------------------------------------------ */
417
+ /* Typewriter cursor */
418
+ /* ------------------------------------------------------------------ */
419
+
420
+ :where([data-blocfeed-ui-root]) .bf-cursor {
421
+ display: inline-block;
422
+ width: 1px;
423
+ height: 1em;
424
+ background: var(--bf-panel-fg);
425
+ margin-left: 1px;
426
+ vertical-align: text-bottom;
427
+ animation: bf-blink 1s steps(2) infinite;
428
+ }
429
+
430
+ @keyframes bf-blink {
431
+ 0% { opacity: 1; }
432
+ 50% { opacity: 0; }
433
+ }
434
+
435
+ /* ------------------------------------------------------------------ */
436
+ /* Panel / toast / hint entrance animations */
437
+ /* ------------------------------------------------------------------ */
438
+
439
+ :where([data-blocfeed-ui-root]) .bf-panel {
440
+ animation: bf-panel-in 0.2s ease-out;
441
+ }
442
+
443
+ @keyframes bf-panel-in {
444
+ from { opacity: 0; transform: translateY(8px); }
445
+ to { opacity: 1; transform: translateY(0); }
446
+ }
447
+
448
+ :where([data-blocfeed-ui-root]) .bf-toast {
449
+ animation: bf-toast-in 0.25s ease-out;
450
+ }
451
+
452
+ @keyframes bf-toast-in {
453
+ from { opacity: 0; transform: translateX(-50%) translateY(12px); }
454
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
455
+ }
456
+
457
+ :where([data-blocfeed-ui-root]) .bf-hint {
458
+ animation: bf-hint-in 0.2s ease-out;
459
+ }
460
+
461
+ @keyframes bf-hint-in {
462
+ from { opacity: 0; transform: translateX(-50%) translateY(-10px); }
463
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
464
+ }
465
+
466
+ /* ------------------------------------------------------------------ */
467
+ /* Reduced motion */
468
+ /* ------------------------------------------------------------------ */
469
+
470
+ @media (prefers-reduced-motion: reduce) {
471
+ :where([data-blocfeed-ui-root]) .bf-panel,
472
+ :where([data-blocfeed-ui-root]) .bf-toast,
473
+ :where([data-blocfeed-ui-root]) .bf-hint,
474
+ :where([data-blocfeed-ui-root]) .bf-cursor {
475
+ animation: none;
476
+ }
477
+ }
478
+ `;function de(){if(!a()||document.getElementById(ce))return;let t=document.createElement("style");t.id=ce,t.textContent=tt,document.head.appendChild(t);}function Z(){let t=useContext($);if(!t)throw new Error("useBlocFeed must be used within a <BlocFeedProvider />");return {state:t.state,controller:t.controller,start:t.controller.start,stop:t.controller.stop,clearSelection:t.controller.clearSelection,submit:t.controller.submit}}function m(t){switch(t){case "bottom-left":return "bf-trigger bf-trigger-bl";case "top-right":return "bf-trigger bf-trigger-tr";case "top-left":return "bf-trigger bf-trigger-tl";default:return "bf-trigger"}}function f({size:t=14}){return jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function pe({size:t=14}){return jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:jsx("path",{d:"M21 11.5a8.38 8.38 0 01-.9 3.8 8.5 8.5 0 01-7.6 4.7 8.38 8.38 0 01-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 01-.9-3.8 8.5 8.5 0 014.7-7.6 8.38 8.38 0 013.8-.9h.5a8.48 8.48 0 018 8v.5z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function fe({size:t=16}){return jsxs("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[jsx("path",{d:"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),jsx("path",{d:"M22 6l-10 7L2 6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}function be({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){return n?jsxs("button",{className:m(t),type:"button",onClick:e,"aria-label":i,children:[c?jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})}):jsxs(Fragment,{children:[jsx("span",{className:"bf-dot","aria-hidden":"true"}),i]}),o>0&&jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]}):null}function b(){let[t,e]=useState(()=>typeof window>"u"?false:window.matchMedia("(prefers-reduced-motion: reduce)").matches);return useEffect(()=>{let n=window.matchMedia("(prefers-reduced-motion: reduce)"),i=o=>e(o.matches);return n.addEventListener("change",i),()=>n.removeEventListener("change",i)},[]),t}var lt={duration:.18,ease:"easeOut"},ct={duration:0};function ge({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=useState(false),a=b(),s=a?ct:lt;return jsx(AnimatePresence,{mode:"wait",children:n&&jsx(motion.button,{className:m(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsx(motion.span,{className:"bf-dot","aria-hidden":"true",animate:a?{}:{scale:r?1:[1,1.2,1],boxShadow:r?"0 0 0 4px rgba(99, 102, 241, 0.18)":["0 0 0 4px rgba(99, 102, 241, 0.18)","0 0 0 8px rgba(99, 102, 241, 0.28)","0 0 0 4px rgba(99, 102, 241, 0.18)"]},transition:r||a?s:{duration:2,repeat:1/0,ease:"easeInOut"}}),jsx(AnimatePresence,{mode:"wait",children:r&&jsx(motion.span,{initial:{opacity:0,x:a?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-6},transition:s,style:{whiteSpace:"nowrap"},children:i},"label")}),o>0&&jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"dot")})}var ut={duration:.18,ease:"easeOut"},xe={duration:0};function ve({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=useState(false),a=b(),s=a?xe:ut;return jsx(AnimatePresence,{mode:"wait",children:n&&jsxs(motion.div,{className:m(t),initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{y:8,opacity:0},transition:s,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),style:{background:"transparent",border:"none",boxShadow:"none",padding:0},children:[jsx(AnimatePresence,{mode:"wait",children:r&&jsx(motion.div,{initial:{opacity:0,y:a?0:4},animate:{opacity:1,y:0},exit:{opacity:0,y:a?0:4},transition:s,style:{position:"absolute",bottom:"calc(100% + 8px)",left:"50%",transform:"translateX(-50%)",padding:"6px 12px",borderRadius:"8px",background:"var(--bf-panel-bg)",border:"1px solid var(--bf-border)",boxShadow:"var(--bf-shadow)",whiteSpace:"nowrap",fontSize:"12px",color:"var(--bf-panel-fg)",pointerEvents:"none"},children:i},"tooltip")}),jsxs(motion.button,{type:"button",onClick:e,"aria-label":i,style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",borderRadius:"50%",border:"1px solid var(--bf-border)",background:"var(--bf-panel-bg)",color:"var(--bf-panel-fg)",boxShadow:"var(--bf-shadow)",cursor:"pointer",padding:0},animate:a?{}:{y:[0,-3,0]},transition:a?xe:{y:{duration:3,repeat:1/0,ease:"easeInOut"}},whileHover:{scale:1.1,borderColor:"var(--bf-accent)"},whileTap:{scale:.9},children:[c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:16})},"success"):jsx(pe,{size:16}),o>0&&jsx("span",{className:"bf-badge bf-badge-float","aria-label":`${o} queued`,children:o})]})]},"bubble")})}var gt={duration:.2,ease:"easeOut"},ht={duration:0};function ke(t){return t==="bottom-left"||t==="top-left"}function xt(t){return `bf-trigger-edge ${ke(t)?"bf-trigger-edge-left":"bf-trigger-edge-right"}`}function Te({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=useState(false),a=ke(t),s=b(),u=s?ht:gt;return jsx(AnimatePresence,{mode:"wait",children:n&&jsx(motion.button,{className:xt(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{opacity:0,width:0},animate:{opacity:1,width:r?140:22,height:r?40:90},exit:{width:0,opacity:0},transition:u,whileTap:{scale:.97},style:{top:"50%",translateY:"-50%"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:u,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsxs(motion.span,{animate:{rotate:s||r?0:a?-90:90,opacity:r?1:.6},transition:u,style:{display:"flex",alignItems:"center",gap:"8px",whiteSpace:"nowrap",fontSize:"12px",letterSpacing:"0.5px",textTransform:"uppercase"},children:[r&&jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:{duration:.12},style:{width:"6px",height:"6px",borderRadius:"50%",background:"var(--bf-accent)",flexShrink:0}}),i]}),jsx(motion.span,{"aria-hidden":"true",animate:{opacity:r?1:0},transition:{duration:.12},style:{position:"absolute",top:0,bottom:0,[a?"left":"right"]:0,width:"2px",background:"var(--bf-accent)"}}),o>0&&jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"edge-tab")})}var wt={duration:.18,ease:"easeOut"},kt={duration:0};function Pe({delay:t,hovered:e,reduced:n}){return n?null:jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"10px",height:"10px",borderRadius:"50%",border:"2px solid var(--bf-accent)",pointerEvents:"none"},animate:e?{scale:1,opacity:0}:{scale:[1,1.8],opacity:[.5,0]},transition:e?{duration:.15}:{duration:2,repeat:1/0,delay:t,ease:"easeOut"}})}function Se({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=useState(false),a=b(),s=a?kt:wt;return jsx(AnimatePresence,{mode:"wait",children:n&&jsx(motion.button,{className:m(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsxs("span",{style:{position:"relative",display:"flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsx(Pe,{delay:0,hovered:r,reduced:a}),jsx(Pe,{delay:.7,hovered:r,reduced:a}),jsx(motion.span,{className:"bf-dot","aria-hidden":"true",style:{position:"relative",zIndex:1}})]}),jsx(AnimatePresence,{mode:"wait",children:r&&jsx(motion.span,{initial:{opacity:0,x:a?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-6},transition:s,style:{whiteSpace:"nowrap"},children:i},"label")}),o>0&&jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"pulse-ring")})}var Et={duration:.18,ease:"easeOut"},St={duration:0};function Nt(t){switch(t){case "bottom-left":return "bf-trigger-minimal bf-trigger-bl";case "top-right":return "bf-trigger-minimal bf-trigger-tr";case "top-left":return "bf-trigger-minimal bf-trigger-tl";default:return "bf-trigger-minimal"}}function Be({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=useState(false),a=b(),s=a?St:Et;return jsx(AnimatePresence,{mode:"wait",children:n&&jsxs(motion.button,{className:Nt(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{opacity:0,y:a?0:5},animate:{opacity:r?1:.65,y:0},exit:{opacity:0,y:a?0:5},transition:s,whileTap:{scale:.95},children:[c?jsx("span",{style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})}):jsxs(Fragment,{children:[jsx("span",{children:i}),o>0&&jsx("span",{className:"bf-badge",style:{marginLeft:"4px"},"aria-label":`${o} queued`,children:o})]}),!a&&jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",bottom:4,left:4,right:4,height:"2px",background:"var(--bf-accent)",borderRadius:"1px",transformOrigin:"left"},initial:false,animate:{scaleX:r?1:0},transition:s})]},"minimal")})}var Mt={duration:.18,ease:"easeOut"},Rt={duration:0};function Re({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=useState(false),a=b(),s=a?Rt:Mt;return jsx(AnimatePresence,{mode:"wait",children:n&&jsx(motion.button,{className:m(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.9},style:{overflow:"hidden"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsx(motion.span,{style:{display:"inline-flex",flexShrink:0},animate:a?{}:r?{scale:1.2,rotate:0}:{rotate:[-5,5,-5]},transition:r||a?s:{duration:3,repeat:1/0,ease:"easeInOut"},children:jsx(fe,{size:16})}),jsx(AnimatePresence,{mode:"wait",children:r&&jsx(motion.span,{initial:{opacity:0,x:a?0:-8},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-8},transition:s,style:{whiteSpace:"nowrap"},children:i},"label")}),o>0&&jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"icon-pop")})}var Lt={duration:.18,ease:"easeOut"},Wt={duration:0};function Ae({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=useState(false),a=b(),s=a?Wt:Lt;return jsx(AnimatePresence,{mode:"wait",children:n&&jsx(motion.button,{className:m(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{scale:0,opacity:0},animate:{scale:1,opacity:1},exit:{scale:0,opacity:0},transition:s,whileTap:{scale:.92},style:{overflow:"hidden"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:s,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsxs("span",{style:{position:"relative",display:"inline-flex",alignItems:"center",justifyContent:"center",width:"10px",height:"10px",flexShrink:0},children:[jsx(motion.span,{"aria-hidden":"true",style:{width:"10px",height:"10px",borderRadius:"50%",background:"var(--bf-accent)",position:"relative",zIndex:1},animate:a?{}:{opacity:r?1:[.5,1,.5],boxShadow:r?"0 0 8px 2px var(--bf-accent)":["0 0 4px 1px var(--bf-accent)","0 0 12px 4px var(--bf-accent)","0 0 4px 1px var(--bf-accent)"]},transition:r||a?s:{duration:2,repeat:1/0,ease:"easeInOut"}}),!r&&!a&&jsx(motion.span,{"aria-hidden":"true",style:{position:"absolute",width:"18px",height:"2px",background:"linear-gradient(90deg, var(--bf-accent), transparent)",transformOrigin:"left center",left:"5px",top:"4px"},animate:{rotate:[0,360]},transition:{duration:4,repeat:1/0,ease:"linear"}})]}),jsx(AnimatePresence,{mode:"wait",children:r&&jsx(motion.span,{initial:{opacity:0,x:a?0:-6},animate:{opacity:1,x:0},exit:{opacity:0,x:a?0:-6},transition:s,style:{whiteSpace:"nowrap"},children:i},"label")}),o>0&&jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"beacon")})}var Dt={duration:.18,ease:"easeOut"},$t={duration:0};function Oe({position:t,onClick:e,isVisible:n,label:i,queueCount:o,showSuccess:c}){let[r,l]=useState(false),[a,s]=useState(0),u=b(),W=u?$t:Dt,h=useRef(null);useEffect(()=>{if(h.current&&(clearInterval(h.current),h.current=null),!n||r||u){s(r||u?i.length:0);return}let P=8,D=i.length*2+P*2,v=0;return h.current=setInterval(()=>{v=(v+1)%D,v<=i.length?s(v):v<=i.length+P?s(i.length):v<=i.length*2+P?s(i.length*2+P-v):s(0);},100),()=>{h.current&&(clearInterval(h.current),h.current=null);}},[n,r,u,i]);let K=i.slice(0,a);return jsx(AnimatePresence,{mode:"wait",children:n&&jsx(motion.button,{className:m(t),type:"button",onClick:e,onMouseEnter:()=>l(true),onMouseLeave:()=>l(false),"aria-label":i,initial:{opacity:0,y:u?0:5},animate:{opacity:1,y:0},exit:{opacity:0,y:u?0:5},transition:W,whileTap:{scale:.95},style:{minWidth:"44px"},children:c?jsx(motion.span,{initial:{scale:0},animate:{scale:1},transition:W,style:{display:"inline-flex",color:"var(--bf-accent)"},children:jsx(f,{size:14})},"success"):jsxs(Fragment,{children:[jsx("span",{className:"bf-dot","aria-hidden":"true"}),jsxs("span",{style:{whiteSpace:"nowrap",minWidth:"1ch"},children:[K,jsx("span",{className:"bf-cursor","aria-hidden":"true"})]}),o>0&&jsx("span",{className:"bf-badge","aria-label":`${o} queued`,children:o})]})},"typewriter")})}function He(t){switch(t){case "dot":return ge;case "bubble":return ve;case "edge-tab":return Te;case "pulse-ring":return Se;case "minimal":return Be;case "icon-pop":return Re;case "beacon":return Ae;case "typewriter":return Oe;default:return be}}function De(t,e,n){return Math.max(e,Math.min(n,t))}function Qt(t,e,n="bottom-right"){let o=window.innerWidth,c=window.innerHeight,r;r=De(t.x,12,Math.max(12,o-e-12));let l=t.y+t.height+12,a=Math.max(12,t.y-240);return {top:l+240<=c?l:a,left:r}}function Ut(t){let{rect:e}=t,n={left:`${e.x}px`,top:`${e.y}px`,width:`${Math.max(0,e.width)}px`,height:`${Math.max(0,e.height)}px`};return jsx("div",{className:"bf-highlight",style:n,"aria-hidden":"true"})}function Vt(t){let e=useRef(null);return useEffect(()=>{if(!t||!e.current)return;e.current.querySelector(".bf-textarea")?.focus();let i=o=>{if(o.key!=="Tab"||!e.current)return;let c=e.current.querySelectorAll('button:not([disabled]), textarea:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])');if(c.length===0)return;let r=c[0],l=c[c.length-1];o.shiftKey&&document.activeElement===r?(o.preventDefault(),l.focus()):!o.shiftKey&&document.activeElement===l&&(o.preventDefault(),r.focus());};return document.addEventListener("keydown",i,{capture:true}),()=>document.removeEventListener("keydown",i,{capture:true})},[t]),e}function Gt(t){let{state:e,controller:n,start:i$1,stop:o,clearSelection:c,submit:r}=Z(),l=t.config.ui?.position,[a,s]=useState(null),[u,W]=useState(""),[h,K]=useState(t.config.capture?.element??true),[P,D]=useState(t.config.capture?.fullPage??false),[v,q]=useState(null),ee=e.phase==="review"||e.phase==="capturing"||e.phase==="submitting"||e.phase==="error"||e.phase==="success",Xe=Vt(ee),[Ye,je]=useState(0);useEffect(()=>{e.phase==="idle"&&je(i());},[e.phase]);let[Qe,te]=useState(false),oe=useRef(e.phase);useEffect(()=>{if(oe.current==="success"&&e.phase==="idle"){te(true);let p=window.setTimeout(()=>te(false),1500);return ()=>window.clearTimeout(p)}oe.current=e.phase;},[e.phase]),useEffect(()=>{let p=t.config.ui?.shortcut;if(!p)return;let z=p.toLowerCase().split("+").map(y=>y.trim()),I=z[z.length-1]||"",F=new Set(z.slice(0,-1)),ie=y=>{let Ge=/Mac|iPod|iPhone|iPad/.test(navigator.platform);if(F.has("mod")){if(Ge?!y.metaKey:!y.ctrlKey)return}else if(F.has("ctrl")&&!y.ctrlKey||(F.has("meta")||F.has("cmd"))&&!y.metaKey)return;F.has("shift")&&!y.shiftKey||(F.has("alt")||F.has("option"))&&!y.altKey||y.key.toLowerCase()===I&&(y.preventDefault(),e.phase==="idle"?i$1():o());};return document.addEventListener("keydown",ie),()=>document.removeEventListener("keydown",ie)},[t.config.ui?.shortcut,e.phase,i$1,o]),useEffect(()=>n.subscribeHover(s),[n]),useEffect(()=>{let p=n.__unsafeGetSelectedElement();if(!p||e.phase==="idle"||e.phase==="picking"){q(null);return}let z=()=>{q(b$1(p.getBoundingClientRect()));};z();let I=()=>z();return window.addEventListener("scroll",I,{capture:true,passive:true}),window.addEventListener("resize",I,{passive:true}),()=>{window.removeEventListener("scroll",I,{capture:true}),window.removeEventListener("resize",I);}},[n,e.phase,e.selection?.selector]),useEffect(()=>{e.phase==="review"&&(W(""),K(t.config.capture?.element??true),D(t.config.capture?.fullPage??false));},[e.phase,e.selection?.selector,t.config.capture?.element,t.config.capture?.fullPage]),useEffect(()=>{if(e.phase!=="success")return;let p=window.setTimeout(()=>o(),1200);return ()=>window.clearTimeout(p)},[e.phase,o]);let w=e.phase==="capturing"||e.phase==="submitting",E=e.phase==="picking"?a?.rect??null:v??e.selection?.rect??null,U=useMemo(()=>E?Qt(E,360,l):null,[E?.x,E?.y,E?.width,E?.height,l]),re=e.lastError?.message,V=useCallback(()=>{r(u,{capture:{element:h,fullPage:P}});},[r,u,h,P]),Ue=useCallback(p=>{(p.metaKey||p.ctrlKey)&&p.key==="Enter"&&u.trim().length>0&&!w&&(p.preventDefault(),V());},[V,u,w]),Ve=He(t.config.ui?.triggerStyle);return jsxs(Fragment,{children:[jsx(Ve,{position:l,onClick:()=>i$1(),isVisible:e.phase==="idle",label:t.config.ui?.triggerLabel??"Feedback",queueCount:Ye,showSuccess:Qe}),e.phase!=="idle"&&jsxs("div",{className:"bf-overlay",role:"presentation",children:[e.phase!=="picking"&&jsx("div",{className:"bf-blocker",role:"presentation",onClick:()=>o()}),E&&jsx(Ut,{rect:E}),e.phase==="picking"&&jsxs("div",{className:"bf-hint",role:"status","aria-live":"polite",children:[jsxs("p",{id:"bf-hint-text",children:["Click an element to attach your feedback. Press ",jsx("strong",{children:"Esc"})," to cancel."]}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),"aria-label":"Cancel element selection",children:"Cancel"})]}),ee&&U&&jsxs("div",{ref:Xe,className:"bf-panel",style:{left:U.left,top:U.top},role:"dialog","aria-modal":"true","aria-label":"Feedback form",children:[jsxs("div",{className:"bf-panelHeader",children:[jsx("div",{className:"bf-title",id:"bf-panel-title",children:"Feedback"}),jsxs("div",{className:"bf-row",style:{justifyContent:"flex-end"},children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>c(),disabled:w,"aria-label":"Re-pick element",children:"Re-pick"}),jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:w,"aria-label":"Close feedback form",children:"Close"})]})]}),jsxs("div",{className:"bf-panelBody",children:[jsx("textarea",{className:"bf-textarea",placeholder:"What's happening? What did you expect?",value:u,onChange:p=>W(p.target.value),onKeyDown:Ue,disabled:w,"aria-label":"Feedback message"}),jsxs("div",{className:"bf-row",role:"group","aria-label":"Screenshot options",children:[jsxs("label",{children:[jsx("input",{type:"checkbox",checked:h,onChange:p=>K(p.target.checked),disabled:w}),"Screenshot element"]}),jsxs("label",{children:[jsx("input",{type:"checkbox",checked:P,onChange:p=>D(p.target.checked),disabled:w}),"Full page"]})]}),e.phase==="capturing"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Capturing screenshots\u2026"]}),e.phase==="submitting"&&jsxs("div",{className:"bf-status",role:"status","aria-live":"polite",children:[jsx("span",{className:"bf-spinner","aria-hidden":"true"}),"Submitting\u2026"]}),e.phase==="success"&&jsx("div",{className:"bf-status",role:"status","aria-live":"polite",children:"Sent. Thank you!"}),e.phase==="error"&&re&&jsx("div",{className:"bf-error",role:"alert",children:re}),jsxs("div",{className:"bf-actions",children:[jsx("button",{type:"button",className:"bf-btn",onClick:()=>o(),disabled:w,"aria-label":"Cancel feedback",children:"Cancel"}),jsx("button",{type:"button",className:"bf-btn bf-btnPrimary",onClick:V,disabled:w||u.trim().length===0,"aria-label":"Send feedback",children:"Send"})]})]})]})]}),e.phase==="success"&&jsx("div",{className:"bf-toast",role:"status","aria-live":"polite",children:"Feedback sent"})]})}function Jt(t){let e={...t.config??{},blocfeed_id:t.blocfeed_id},[n,i]=useState(null);return useEffect(()=>{de();let o=document.createElement("div");o.setAttribute("data-blocfeed-ui-root","true"),o.setAttribute("data-blocfeed-ui","true");let c=e.ui?.zIndex;typeof c=="number"&&o.style.setProperty("--bf-z",String(c));let r=e.ui?.theme;return r&&(r.accentColor&&o.style.setProperty("--bf-accent",r.accentColor),r.panelBackground&&o.style.setProperty("--bf-panel-bg",r.panelBackground),r.panelForeground&&o.style.setProperty("--bf-panel-fg",r.panelForeground),r.fontFamily&&o.style.setProperty("--bf-font",r.fontFamily)),document.body.appendChild(o),i(o),()=>{o.remove(),i(null);}},[e.ui?.zIndex,e.ui?.theme?.accentColor,e.ui?.theme?.panelBackground,e.ui?.theme?.panelForeground,e.ui?.theme?.fontFamily]),n?createPortal(jsx(J,{blocfeed_id:e.blocfeed_id,...t.config?{config:t.config}:{},children:jsx(Gt,{config:e})}),n):null}
479
+ export{J as BlocFeedProvider,Jt as BlocFeedWidget,Z as useBlocFeed};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blocfeed",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Drop-in feedback + screenshot widget for React.",
5
5
  "license": "MIT",
6
6
  "type": "module",