@feedvalue/vue 0.1.8 → 0.1.10

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/dist/index.cjs CHANGED
@@ -165,7 +165,8 @@ function useReaction(widgetId) {
165
165
  });
166
166
  const reactionConfig = vue.computed(() => {
167
167
  if (!instance.value || !isReady.value) return null;
168
- return instance.value._widgetConfig?.config ?? null;
168
+ const widgetConfig = instance.value.getWidgetConfig();
169
+ return widgetConfig?.config ?? null;
169
170
  });
170
171
  const showLabels = vue.computed(() => {
171
172
  return reactionConfig.value?.showLabels ?? true;
@@ -192,7 +193,7 @@ function useReaction(widgetId) {
192
193
  if (!instance.value || !isReady.value) {
193
194
  return defaultStyling;
194
195
  }
195
- const widgetConfig = instance.value._widgetConfig;
196
+ const widgetConfig = instance.value.getWidgetConfig();
196
197
  if (!widgetConfig?.styling) {
197
198
  return defaultStyling;
198
199
  }
@@ -271,7 +272,10 @@ var borderWidthMap = {
271
272
  "1": "1px",
272
273
  "2": "2px",
273
274
  "3": "3px",
274
- "4": "4px"
275
+ "4": "4px",
276
+ thin: "1px",
277
+ medium: "2px",
278
+ thick: "3px"
275
279
  };
276
280
  var sizeStyles = {
277
281
  sm: {
@@ -334,7 +338,8 @@ var styles = {
334
338
  border: "1px solid #d1d5db",
335
339
  borderRadius: "0.375rem",
336
340
  backgroundColor: "#ffffff",
337
- boxSizing: "border-box"
341
+ boxSizing: "border-box",
342
+ resize: "none"
338
343
  },
339
344
  actions: {
340
345
  display: "flex",
@@ -409,11 +414,33 @@ var ReactionButtons = vue.defineComponent({
409
414
  buttonClass: {
410
415
  type: String,
411
416
  default: ""
417
+ },
418
+ /** Custom class for the follow-up form */
419
+ formClass: {
420
+ type: String,
421
+ default: ""
422
+ },
423
+ /** Custom class for the thank you message */
424
+ thankYouClass: {
425
+ type: String,
426
+ default: ""
427
+ },
428
+ /** Hide after submission (default: false) */
429
+ hideAfterSubmit: {
430
+ type: Boolean,
431
+ default: false
432
+ },
433
+ /** Whether to show follow-up inline or not at all */
434
+ followUpMode: {
435
+ type: String,
436
+ default: "inline"
412
437
  }
413
438
  },
414
439
  emits: {
415
440
  /** Emitted when a reaction is submitted */
416
- react: (value, _followUp) => typeof value === "string"
441
+ react: (value, _followUp) => typeof value === "string",
442
+ /** Emitted when an error occurs */
443
+ error: (_error) => true
417
444
  },
418
445
  setup(props, { emit }) {
419
446
  const {
@@ -429,25 +456,30 @@ var ReactionButtons = vue.defineComponent({
429
456
  showLabels,
430
457
  buttonSize,
431
458
  shouldShowFollowUp,
432
- styling
459
+ styling,
460
+ isReactionWidget
433
461
  } = useReaction(props.widgetId);
434
462
  const followUpText = vue.ref("");
463
+ const hoveredButton = vue.ref(null);
435
464
  const getFollowUpOption = vue.computed(() => {
436
465
  if (!showFollowUp.value || !options.value) return null;
437
466
  return options.value.find((opt) => opt.value === showFollowUp.value) ?? null;
438
467
  });
439
468
  const handleOptionClick = (option) => {
440
- if (shouldShowFollowUp(option.value)) {
469
+ if (props.followUpMode === "inline" && shouldShowFollowUp(option.value)) {
441
470
  setShowFollowUp(option.value);
442
471
  } else {
443
472
  submitReaction(option.value);
444
473
  }
445
474
  };
446
475
  const submitReaction = async (value, followUp) => {
476
+ const trimmedFollowUp = followUp?.trim() || void 0;
447
477
  try {
448
- await react(value, followUp);
449
- emit("react", value, followUp);
450
- } catch {
478
+ await react(value, trimmedFollowUp);
479
+ emit("react", value, trimmedFollowUp);
480
+ } catch (err) {
481
+ const reactionError = err instanceof Error ? err : new Error(String(err));
482
+ emit("error", reactionError);
451
483
  }
452
484
  };
453
485
  const handleFollowUpSubmit = (e) => {
@@ -462,7 +494,10 @@ var ReactionButtons = vue.defineComponent({
462
494
  followUpText.value = "";
463
495
  };
464
496
  return () => {
465
- if (!isReady.value || !options.value) {
497
+ if (!isReady.value || !isReactionWidget.value || !options.value) {
498
+ return null;
499
+ }
500
+ if (submitted.value && props.hideAfterSubmit) {
466
501
  return null;
467
502
  }
468
503
  if (submitted.value) {
@@ -470,8 +505,8 @@ var ReactionButtons = vue.defineComponent({
470
505
  return vue.h(
471
506
  "div",
472
507
  {
473
- class: props.containerClass,
474
- style: {
508
+ class: props.thankYouClass || props.containerClass,
509
+ style: props.thankYouClass ? void 0 : {
475
510
  ...styles.thankYou,
476
511
  color: currentStyling2.primaryColor ?? "#059669"
477
512
  }
@@ -495,8 +530,9 @@ var ReactionButtons = vue.defineComponent({
495
530
  const currentStyling = styling.value;
496
531
  const borderRadius = borderRadiusMap[currentStyling.borderRadius ?? "full"] ?? "9999px";
497
532
  const borderWidth = borderWidthMap[currentStyling.borderWidth ?? "1"] ?? "1px";
498
- const buttonElements = options.value.map((option) => {
533
+ const buttonElements = !showFollowUp.value ? options.value.map((option) => {
499
534
  const isActive = showFollowUp.value === option.value;
535
+ const isHovered = hoveredButton.value === option.value;
500
536
  const children = [
501
537
  vue.h("span", { style: { ...styles.icon, ...currentSizeStyles.icon }, "aria-hidden": "true" }, option.icon)
502
538
  ];
@@ -513,11 +549,12 @@ var ReactionButtons = vue.defineComponent({
513
549
  ...styles.button,
514
550
  ...currentSizeStyles.button,
515
551
  backgroundColor: currentStyling.backgroundColor ?? "#ffffff",
516
- borderColor: isActive ? currentStyling.primaryColor ?? "#6366f1" : currentStyling.borderColor ?? "#e5e7eb",
552
+ borderColor: isActive || isHovered ? currentStyling.primaryColor ?? "#6366f1" : currentStyling.borderColor ?? "#e5e7eb",
517
553
  borderWidth,
518
554
  borderRadius,
555
+ borderStyle: "solid",
519
556
  color: currentStyling.buttonTextColor ?? "#4b5563",
520
- ...isActive ? {
557
+ ...isActive || isHovered ? {
521
558
  backgroundColor: `${currentStyling.primaryColor ?? "#6366f1"}10`
522
559
  } : {},
523
560
  ...isSubmitting.value ? styles.buttonDisabled : {}
@@ -525,28 +562,35 @@ var ReactionButtons = vue.defineComponent({
525
562
  disabled: isSubmitting.value,
526
563
  "aria-pressed": isActive,
527
564
  "aria-label": option.label,
528
- onClick: () => handleOptionClick(option)
565
+ onClick: () => handleOptionClick(option),
566
+ onMouseenter: () => {
567
+ hoveredButton.value = option.value;
568
+ },
569
+ onMouseleave: () => {
570
+ hoveredButton.value = null;
571
+ }
529
572
  },
530
573
  children
531
574
  );
532
- });
575
+ }) : [];
533
576
  let followUpForm = null;
534
577
  const followUpOption = getFollowUpOption.value;
535
578
  if (showFollowUp.value && followUpOption) {
536
579
  followUpForm = vue.h(
537
580
  "form",
538
581
  {
539
- style: styles.followUp,
582
+ class: props.formClass,
583
+ style: props.formClass ? void 0 : styles.followUp,
540
584
  onSubmit: handleFollowUpSubmit
541
585
  },
542
586
  [
543
- vue.h("input", {
544
- type: "text",
587
+ vue.h("textarea", {
545
588
  style: styles.input,
546
589
  value: followUpText.value,
547
- placeholder: followUpOption.followUpPlaceholder || "Tell us more...",
590
+ placeholder: followUpOption.followUpPlaceholder || "Tell us more (optional)",
548
591
  disabled: isSubmitting.value,
549
592
  maxlength: 500,
593
+ rows: 3,
550
594
  onInput: (e) => {
551
595
  followUpText.value = e.target.value;
552
596
  }
@@ -603,10 +647,11 @@ var ReactionButtons = vue.defineComponent({
603
647
  "aria-label": "Reaction buttons"
604
648
  },
605
649
  [
606
- vue.h("div", { style: styles.buttonGroup, role: "radiogroup" }, buttonElements),
650
+ // Only render button group if there are buttons to show
651
+ buttonElements.length > 0 ? vue.h("div", { style: styles.buttonGroup, role: "radiogroup" }, buttonElements) : null,
607
652
  followUpForm,
608
653
  errorElement
609
- ]
654
+ ].filter(Boolean)
610
655
  );
611
656
  };
612
657
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugin.ts","../src/composables.ts","../src/use-reaction.ts","../src/ReactionButtons.ts"],"names":["FeedValue","inject","shallowRef","ref","onMounted","onUnmounted","readonly","computed","NEGATIVE_OPTIONS_MAP","defineComponent","currentStyling","h"],"mappings":";;;;;;AAkCO,IAAM,aAAA,0BAAwD,WAAW;AAKzE,IAAM,qBAAA,0BAAqE,mBAAmB;AAsB9F,SAAS,gBAAgB,OAAA,EAAiC;AAC/D,EAAA,IAAI,QAAA,GAAqC,IAAA;AAEzC,EAAA,OAAO;AAAA,IACL,QAAQ,GAAA,EAAU;AAEhB,MAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,QAAA,QAAA,GAAWA,eAAU,IAAA,CAAK;AAAA,UACxB,UAAU,OAAA,CAAQ,QAAA;AAAA,UAClB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,UAAU,OAAA,CAAQ;AAAA,SACnB,CAAA;AAGD,QAAA,GAAA,CAAI,OAAA,CAAQ,eAAe,QAAQ,CAAA;AAGnC,QAAA,GAAA,CAAI,MAAA,CAAO,iBAAiB,UAAA,GAAa,QAAA;AAAA,MAC3C;AAGA,MAAA,GAAA,CAAI,OAAA,CAAQ,uBAAuB,OAAO,CAAA;AAAA,IAC5C;AAAA,GACF;AACF;ACEO,SAAS,YAAA,CACd,UACA,MAAA,EACoB;AAEpB,EAAA,MAAM,gBAAA,GAAmBC,UAAA,CAAO,aAAA,EAAe,IAAI,CAAA;AACnD,EAAA,MAAM,eAAA,GAAkBA,UAAA,CAAO,qBAAA,EAAuB,IAAI,CAAA;AAG1D,EAAA,MAAM,QAAA,GAAWC,eAAqC,IAAI,CAAA;AAC1D,EAAA,MAAM,OAAA,GAAUC,QAAI,KAAK,CAAA;AACzB,EAAA,MAAM,MAAA,GAASA,QAAI,KAAK,CAAA;AACxB,EAAA,MAAM,SAAA,GAAYA,QAAI,KAAK,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQA,QAAkB,IAAI,CAAA;AACpC,EAAA,MAAM,YAAA,GAAeA,QAAI,KAAK,CAAA;AAC9B,EAAA,MAAM,UAAA,GAAaA,QAAI,KAAK,CAAA;AAG5B,EAAA,IAAI,YAAA,GAAe,KAAA;AACnB,EAAA,IAAI,WAAA,GAAmC,IAAA;AAKvC,EAAA,MAAM,YAAY,MAAM;AACtB,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,EAAO,WAAA,EAAY;AAC1C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,OAAA;AACtB,MAAA,MAAA,CAAO,QAAQ,KAAA,CAAM,MAAA;AACrB,MAAA,SAAA,CAAU,QAAQ,KAAA,CAAM,SAAA;AACxB,MAAA,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA;AACpB,MAAA,YAAA,CAAa,QAAQ,KAAA,CAAM,YAAA;AAAA,IAC7B;AAAA,EACF,CAAA;AAEA,EAAAC,aAAA,CAAU,MAAM;AAEd,IAAA,IAAI,gBAAA,IAAoB,CAAC,QAAA,EAAU;AACjC,MAAA,QAAA,CAAS,KAAA,GAAQ,gBAAA;AACjB,MAAA,UAAA,CAAW,KAAA,GAAQ,iBAAiB,UAAA,EAAW;AAAA,IACjD,CAAA,MAAO;AAEL,MAAA,MAAM,iBAAA,GAAoB,YAAY,eAAA,EAAiB,QAAA;AAEvD,MAAA,IAAI,CAAC,iBAAA,EAAmB;AACtB,QAAA,OAAA,CAAQ,KAAA;AAAA,UACN;AAAA,SAEF;AACA,QAAA;AAAA,MACF;AAEA,MAAA,QAAA,CAAS,KAAA,GAAQJ,eAAU,IAAA,CAAK;AAAA,QAC9B,QAAA,EAAU,iBAAA;AAAA,QACV,YAAY,eAAA,EAAiB,UAAA;AAAA,QAC7B,MAAA,EAAQ,UAAU,eAAA,EAAiB,MAAA;AAAA,QACnC,UAAU,eAAA,EAAiB;AAAA,OAC5B,CAAA;AACD,MAAA,YAAA,GAAe,IAAA;AAAA,IACjB;AAGA,IAAA,IAAI,SAAS,KAAA,EAAO;AAClB,MAAA,WAAA,GAAc,QAAA,CAAS,KAAA,CAAM,SAAA,CAAU,SAAS,CAAA;AAChD,MAAA,UAAA,CAAW,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,UAAA,EAAW;AAC7C,MAAA,SAAA,EAAU;AAAA,IACZ;AAAA,EACF,CAAC,CAAA;AAED,EAAAK,eAAA,CAAY,MAAM;AAChB,IAAA,WAAA,IAAc;AACd,IAAA,IAAI,YAAA,IAAgB,SAAS,KAAA,EAAO;AAClC,MAAA,QAAA,CAAS,MAAM,OAAA,EAAQ;AAAA,IACzB;AACA,IAAA,QAAA,CAAS,KAAA,GAAQ,IAAA;AAAA,EACnB,CAAC,CAAA;AAGD,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,KAAA,EAAO,IAAA,EAAK;AACxC,EAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,KAAA,EAAO,KAAA,EAAM;AAC1C,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,KAAA,EAAO,MAAA,EAAO;AAC5C,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,KAAA,EAAO,IAAA,EAAK;AACxC,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,KAAA,EAAO,IAAA,EAAK;AACxC,EAAA,MAAM,MAAA,GAAS,CAAC,QAAA,KACd,QAAA,CAAS,KAAA,EAAO,MAAA,CAAO,QAAQ,CAAA,IAAK,OAAA,CAAQ,MAAA,CAAO,IAAI,KAAA,CAAM,iBAAiB,CAAC,CAAA;AACjF,EAAA,MAAM,QAAA,GAAW,CAAC,MAAA,EAAgB,MAAA,KAChC,SAAS,KAAA,EAAO,QAAA,CAAS,QAAQ,MAAM,CAAA;AACzC,EAAA,MAAM,UAAU,CAAC,IAAA,KAAiC,QAAA,CAAS,KAAA,EAAO,QAAQ,IAAI,CAAA;AAC9E,EAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,KAAA,EAAO,KAAA,EAAM;AAE1C,EAAA,OAAO;AAAA,IACL,QAAA,EAAUC,aAAS,QAAQ,CAAA;AAAA,IAC3B,OAAA,EAASA,aAAS,OAAO,CAAA;AAAA,IACzB,MAAA,EAAQA,aAAS,MAAM,CAAA;AAAA,IACvB,SAAA,EAAWA,aAAS,SAAS,CAAA;AAAA,IAC7B,KAAA,EAAOA,aAAS,KAAK,CAAA;AAAA,IACrB,YAAA,EAAcA,aAAS,YAAY,CAAA;AAAA,IACnC,UAAA,EAAYA,aAAS,UAAU,CAAA;AAAA,IAC/B,IAAA;AAAA,IACA,KAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF;AACF;ACzEO,SAAS,YAAY,QAAA,EAAsC;AAEhE,EAAA,MAAM,gBAAA,GAAmBL,UAAAA,CAAO,aAAA,EAAe,IAAI,CAAA;AACnD,EAAA,MAAM,eAAA,GAAkBA,UAAAA,CAAO,qBAAA,EAAuB,IAAI,CAAA;AAG1D,EAAA,MAAM,QAAA,GAAWE,QAA8B,IAAI,CAAA;AACnD,EAAA,MAAM,OAAA,GAAUA,QAAI,KAAK,CAAA;AAGzB,EAAA,MAAM,YAAA,GAAeA,QAAmB,IAAI,CAAA;AAC5C,EAAA,MAAM,SAAA,GAAYA,QAAmB,IAAI,CAAA;AACzC,EAAA,MAAM,YAAA,GAAeA,QAAI,KAAK,CAAA;AAC9B,EAAA,MAAM,KAAA,GAAQA,QAAkB,IAAI,CAAA;AAGpC,EAAA,IAAI,YAAA,GAAe,KAAA;AACnB,EAAA,IAAI,WAAA,GAAmC,IAAA;AAKvC,EAAA,MAAM,YAAY,MAAM;AACtB,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,EAAO,WAAA,EAAY;AAC1C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,OAAA;AAAA,IACxB;AAAA,EACF,CAAA;AAEA,EAAAC,cAAU,MAAM;AAEd,IAAA,IAAI,gBAAA,IAAoB,CAAC,QAAA,EAAU;AACjC,MAAA,QAAA,CAAS,KAAA,GAAQ,gBAAA;AAAA,IACnB,CAAA,MAAO;AAEL,MAAA,MAAM,iBAAA,GAAoB,YAAY,eAAA,EAAiB,QAAA;AAEvD,MAAA,IAAI,CAAC,iBAAA,EAAmB;AACtB,QAAA,OAAA,CAAQ,KAAA;AAAA,UACN;AAAA,SAEF;AACA,QAAA;AAAA,MACF;AAEA,MAAA,QAAA,CAAS,KAAA,GAAQJ,eAAU,IAAA,CAAK;AAAA,QAC9B,QAAA,EAAU,iBAAA;AAAA,QACV,YAAY,eAAA,EAAiB,UAAA;AAAA,QAC7B,QAAQ,eAAA,EAAiB,MAAA;AAAA,QACzB,QAAA,EAAU;AAAA;AAAA,OACX,CAAA;AACD,MAAA,YAAA,GAAe,IAAA;AAAA,IACjB;AAGA,IAAA,IAAI,SAAS,KAAA,EAAO;AAClB,MAAA,WAAA,GAAc,QAAA,CAAS,KAAA,CAAM,SAAA,CAAU,SAAS,CAAA;AAChD,MAAA,SAAA,EAAU;AAAA,IACZ;AAAA,EACF,CAAC,CAAA;AAED,EAAAK,gBAAY,MAAM;AAChB,IAAA,WAAA,IAAc;AACd,IAAA,IAAI,YAAA,IAAgB,SAAS,KAAA,EAAO;AAClC,MAAA,QAAA,CAAS,MAAM,OAAA,EAAQ;AAAA,IACzB;AACA,IAAA,QAAA,CAAS,KAAA,GAAQ,IAAA;AAAA,EACnB,CAAC,CAAA;AAGD,EAAA,MAAM,OAAA,GAAUE,aAAkC,MAAM;AACtD,IAAA,IAAI,CAAC,QAAA,CAAS,KAAA,IAAS,CAAC,OAAA,CAAQ,OAAO,OAAO,IAAA;AAC9C,IAAA,OAAO,QAAA,CAAS,MAAM,kBAAA,EAAmB;AAAA,EAC3C,CAAC,CAAA;AAGD,EAAA,MAAM,gBAAA,GAAmBA,aAAS,MAAM;AACtC,IAAA,OAAO,QAAA,CAAS,KAAA,EAAO,UAAA,EAAW,IAAK,KAAA;AAAA,EACzC,CAAC,CAAA;AAGD,EAAA,MAAM,cAAA,GAAiBA,aAAS,MAAM;AACpC,IAAA,IAAI,CAAC,QAAA,CAAS,KAAA,IAAS,CAAC,OAAA,CAAQ,OAAO,OAAO,IAAA;AAG9C,IAAA,OAAQ,QAAA,CAAS,KAAA,CAAc,aAAA,EAAe,MAAA,IAAU,IAAA;AAAA,EAC1D,CAAC,CAAA;AAED,EAAA,MAAM,UAAA,GAAaA,aAAS,MAAM;AAChC,IAAA,OAAO,cAAA,CAAe,OAAO,UAAA,IAAc,IAAA;AAAA,EAC7C,CAAC,CAAA;AAED,EAAA,MAAM,UAAA,GAAaA,aAAqB,MAAM;AAC5C,IAAA,OAAO,cAAA,CAAe,OAAO,UAAA,IAAc,IAAA;AAAA,EAC7C,CAAC,CAAA;AAED,EAAA,MAAM,eAAA,GAAkBA,aAA0B,MAAM;AACtD,IAAA,OAAO,cAAA,CAAe,OAAO,eAAA,IAAmB,UAAA;AAAA,EAClD,CAAC,CAAA;AAED,EAAA,MAAM,QAAA,GAAWA,aAAuC,MAAM;AAC5D,IAAA,OAAO,eAAe,KAAA,EAAO,QAAA;AAAA,EAC/B,CAAC,CAAA;AAGD,EAAA,MAAM,OAAA,GAAUA,aAA0B,MAAM;AAC9C,IAAA,MAAM,cAAA,GAAkC;AAAA,MACtC,YAAA,EAAc,SAAA;AAAA,MACd,eAAA,EAAiB,SAAA;AAAA,MACjB,SAAA,EAAW,SAAA;AAAA,MACX,eAAA,EAAiB,SAAA;AAAA,MACjB,WAAA,EAAa,SAAA;AAAA,MACb,WAAA,EAAa,GAAA;AAAA,MACb,YAAA,EAAc;AAAA,KAChB;AAEA,IAAA,IAAI,CAAC,QAAA,CAAS,KAAA,IAAS,CAAC,QAAQ,KAAA,EAAO;AACrC,MAAA,OAAO,cAAA;AAAA,IACT;AAIA,IAAA,MAAM,YAAA,GAAgB,SAAS,KAAA,CAAc,aAAA;AAC7C,IAAA,IAAI,CAAC,cAAc,OAAA,EAAS;AAC1B,MAAA,OAAO,cAAA;AAAA,IACT;AAIA,IAAA,MAAM,gBAAgB,YAAA,CAAa,OAAA;AACnC,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,aAAA,CAAc,YAAA,IAAgB,cAAA,CAAe,YAAA;AAAA,MAC3D,eAAA,EAAiB,aAAA,CAAc,eAAA,IAAmB,cAAA,CAAe,eAAA;AAAA,MACjE,SAAA,EAAW,aAAA,CAAc,SAAA,IAAa,cAAA,CAAe,SAAA;AAAA,MACrD,eAAA,EAAiB,aAAA,CAAc,eAAA,IAAmB,cAAA,CAAe,eAAA;AAAA,MACjE,WAAA,EAAa,aAAA,CAAc,WAAA,IAAe,cAAA,CAAe,WAAA;AAAA,MACzD,WAAA,EAAa,aAAA,CAAc,WAAA,IAAe,cAAA,CAAe,WAAA;AAAA,MACzD,YAAA,EAAc,aAAA,CAAc,YAAA,IAAgB,cAAA,CAAe;AAAA,KAC7D;AAAA,EACF,CAAC,CAAA;AAKD,EAAA,MAAM,kBAAA,GAAqB,CAAC,WAAA,KAAiC;AAC3D,IAAA,IAAI,eAAA,CAAgB,KAAA,KAAU,MAAA,EAAQ,OAAO,KAAA;AAC7C,IAAA,IAAI,eAAA,CAAgB,KAAA,KAAU,KAAA,EAAO,OAAO,IAAA;AAE5C,IAAA,IAAI,QAAA,CAAS,KAAA,IAASC,yBAAA,CAAqB,QAAA,CAAS,KAAK,CAAA,EAAG;AAC1D,MAAA,OAAOA,yBAAA,CAAqB,QAAA,CAAS,KAAK,CAAA,CAAE,SAAS,WAAW,CAAA;AAAA,IAClE;AAEA,IAAA,MAAM,MAAA,GAAS,QAAQ,KAAA,EAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,WAAW,CAAA;AACjE,IAAA,OAAO,QAAQ,YAAA,IAAgB,KAAA;AAAA,EACjC,CAAA;AAKA,EAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,EAAe,QAAA,KAAqC;AACvE,IAAA,IAAI,CAAC,SAAS,KAAA,EAAO;AACnB,MAAA,MAAM,IAAI,MAAM,2BAA2B,CAAA;AAAA,IAC7C;AAEA,IAAA,YAAA,CAAa,KAAA,GAAQ,IAAA;AACrB,IAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AAEd,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,CAAS,MAAM,KAAA,CAAM,KAAA,EAAO,WAAW,EAAE,QAAA,KAAa,KAAA,CAAS,CAAA;AACrE,MAAA,SAAA,CAAU,KAAA,GAAQ,KAAA;AAClB,MAAA,YAAA,CAAa,KAAA,GAAQ,IAAA;AAAA,IACvB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,aAAA,GAAgB,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AACxE,MAAA,KAAA,CAAM,KAAA,GAAQ,aAAA;AACd,MAAA,MAAM,aAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAA,GAAQ,KAAA;AAAA,IACvB;AAAA,EACF,CAAA;AAKA,EAAA,MAAM,eAAA,GAAkB,CAAC,KAAA,KAA+B;AACtD,IAAA,YAAA,CAAa,KAAA,GAAQ,KAAA;AAAA,EACvB,CAAA;AAKA,EAAA,MAAM,iBAAiB,MAAY;AACjC,IAAA,SAAA,CAAU,KAAA,GAAQ,IAAA;AAClB,IAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AAAA,EAChB,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,YAAA,EAAcF,aAAS,YAAY,CAAA;AAAA,IACnC,SAAA,EAAWA,aAAS,SAAS,CAAA;AAAA,IAC7B,KAAA,EAAOA,aAAS,KAAK,CAAA;AAAA,IACrB,YAAA,EAAcA,aAAS,YAAY,CAAA;AAAA,IACnC,KAAA;AAAA,IACA,eAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,OAAA,EAASA,aAAS,OAAO,CAAA;AAAA,IACzB,UAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACF;AACF;AC/TA,IAAM,eAAA,GAAwD;AAAA,EAC5D,IAAA,EAAM,QAAA;AAAA,EACN,EAAA,EAAI,MAAA;AAAA,EACJ,EAAA,EAAI,KAAA;AAAA,EACJ,EAAA,EAAI,KAAA;AAAA,EACJ,IAAA,EAAM;AACR,CAAA;AAKA,IAAM,cAAA,GAAsD;AAAA,EAC1D,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK;AACP,CAAA;AAKA,IAAM,UAAA,GAAkI;AAAA,EACtI,EAAA,EAAI;AAAA,IACF,QAAQ,EAAE,OAAA,EAAS,oBAAoB,QAAA,EAAU,SAAA,EAAW,KAAK,UAAA,EAAW;AAAA,IAC5E,IAAA,EAAM,EAAE,QAAA,EAAU,MAAA,EAAO;AAAA,IACzB,KAAA,EAAO,EAAE,QAAA,EAAU,SAAA;AAAU,GAC/B;AAAA,EACA,EAAA,EAAI;AAAA,IACF,QAAQ,EAAE,OAAA,EAAS,eAAe,QAAA,EAAU,UAAA,EAAY,KAAK,QAAA,EAAS;AAAA,IACtE,IAAA,EAAM,EAAE,QAAA,EAAU,UAAA,EAAW;AAAA,IAC7B,KAAA,EAAO,EAAE,QAAA,EAAU,UAAA;AAAW,GAChC;AAAA,EACA,EAAA,EAAI;AAAA,IACF,QAAQ,EAAE,OAAA,EAAS,mBAAmB,QAAA,EAAU,MAAA,EAAQ,KAAK,UAAA,EAAW;AAAA,IACxE,IAAA,EAAM,EAAE,QAAA,EAAU,QAAA,EAAS;AAAA,IAC3B,KAAA,EAAO,EAAE,QAAA,EAAU,MAAA;AAAO;AAE9B,CAAA;AAKA,IAAM,MAAA,GAAS;AAAA,EACb,SAAA,EAAW;AAAA,IACT,OAAA,EAAS,MAAA;AAAA,IACT,aAAA,EAAe,QAAA;AAAA,IACf,GAAA,EAAK,SAAA;AAAA,IACL,UAAA,EAAY;AAAA,GACd;AAAA,EACA,WAAA,EAAa;AAAA,IACX,OAAA,EAAS,MAAA;AAAA,IACT,QAAA,EAAU,MAAA;AAAA,IACV,GAAA,EAAK;AAAA,GACP;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,OAAA,EAAS,aAAA;AAAA,IACT,UAAA,EAAY,QAAA;AAAA,IACZ,UAAA,EAAY,KAAA;AAAA,IACZ,KAAA,EAAO,SAAA;AAAA,IACP,eAAA,EAAiB,SAAA;AAAA,IACjB,MAAA,EAAQ,mBAAA;AAAA,IACR,YAAA,EAAc,QAAA;AAAA,IACd,MAAA,EAAQ,SAAA;AAAA,IACR,UAAA,EAAY;AAAA,GACd;AAAA,EAMA,cAAA,EAAgB;AAAA,IACd,OAAA,EAAS,GAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,MAAM,EAAC;AAAA,EACP,QAAA,EAAU;AAAA,IACR,OAAA,EAAS,MAAA;AAAA,IACT,aAAA,EAAe,QAAA;AAAA,IACf,GAAA,EAAK,QAAA;AAAA,IACL,OAAA,EAAS,SAAA;AAAA,IACT,eAAA,EAAiB,SAAA;AAAA,IACjB,MAAA,EAAQ,mBAAA;AAAA,IACR,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,KAAA,EAAO;AAAA,IACL,KAAA,EAAO,MAAA;AAAA,IACP,OAAA,EAAS,gBAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,mBAAA;AAAA,IACR,YAAA,EAAc,UAAA;AAAA,IACd,eAAA,EAAiB,SAAA;AAAA,IACjB,SAAA,EAAW;AAAA,GACb;AAAA,EACA,OAAA,EAAS;AAAA,IACP,OAAA,EAAS,MAAA;AAAA,IACT,GAAA,EAAK,QAAA;AAAA,IACL,cAAA,EAAgB;AAAA,GAClB;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,OAAA,EAAS,kBAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,UAAA,EAAY,KAAA;AAAA,IACZ,KAAA,EAAO,SAAA;AAAA,IACP,eAAA,EAAiB,SAAA;AAAA,IACjB,MAAA,EAAQ,MAAA;AAAA,IACR,YAAA,EAAc,UAAA;AAAA,IACd,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,OAAA,EAAS,kBAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,KAAA,EAAO,SAAA;AAAA,IACP,UAAA,EAAY,MAAA;AAAA,IACZ,MAAA,EAAQ,MAAA;AAAA,IACR,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,QAAA,EAAU;AAAA,IACR,OAAA,EAAS,MAAA;AAAA,IACT,UAAA,EAAY,QAAA;AAAA,IACZ,GAAA,EAAK,QAAA;AAAA,IACL,OAAA,EAAS,cAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,KAAA,EAAO,SAAA;AAAA,IACP,eAAA,EAAiB,SAAA;AAAA,IACjB,MAAA,EAAQ,mBAAA;AAAA,IACR,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,WAAA,EAAa;AAAA,IACX,OAAA,EAAS,gBAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,KAAA,EAAO,SAAA;AAAA,IACP,UAAA,EAAY,MAAA;AAAA,IACZ,MAAA,EAAQ,MAAA;AAAA,IACR,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,KAAA,EAAO;AAAA,IACL,OAAA,EAAS,gBAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,KAAA,EAAO,SAAA;AAAA,IACP,eAAA,EAAiB,SAAA;AAAA,IACjB,MAAA,EAAQ,mBAAA;AAAA,IACR,YAAA,EAAc;AAAA;AAElB,CAAA;AAsBO,IAAM,kBAAkBG,mBAAA,CAAgB;AAAA,EAC7C,IAAA,EAAM,iBAAA;AAAA,EAEN,KAAA,EAAO;AAAA;AAAA,IAEL,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACX;AAAA;AAAA,IAEA,eAAA,EAAiB;AAAA,MACf,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACX;AAAA;AAAA,IAEA,cAAA,EAAgB;AAAA,MACd,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACX;AAAA;AAAA,IAEA,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA;AACX,GACF;AAAA,EAEA,KAAA,EAAO;AAAA;AAAA,IAEL,KAAA,EAAO,CAAC,KAAA,EAAe,SAAA,KAAuB,OAAO,KAAA,KAAU;AAAA,GACjE;AAAA,EAEA,KAAA,CAAM,KAAA,EAAO,EAAE,IAAA,EAAK,EAAG;AACrB,IAAA,MAAM;AAAA,MACJ,OAAA;AAAA,MACA,KAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA;AAAA,MACA,KAAA;AAAA,MACA,YAAA;AAAA,MACA,eAAA;AAAA,MACA,cAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA;AAAA,MACA,UAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA,KACF,GAAI,WAAA,CAAY,KAAA,CAAM,QAAQ,CAAA;AAG9B,IAAA,MAAM,YAAA,GAAeN,QAAI,EAAE,CAAA;AAG3B,IAAA,MAAM,iBAAA,GAAoBI,aAAgC,MAAM;AAC9D,MAAA,IAAI,CAAC,YAAA,CAAa,KAAA,IAAS,CAAC,OAAA,CAAQ,OAAO,OAAO,IAAA;AAClD,MAAA,OAAO,OAAA,CAAQ,MAAM,IAAA,CAAK,CAAC,QAAQ,GAAA,CAAI,KAAA,KAAU,YAAA,CAAa,KAAK,CAAA,IAAK,IAAA;AAAA,IAC1E,CAAC,CAAA;AAKD,IAAA,MAAM,iBAAA,GAAoB,CAAC,MAAA,KAA2B;AACpD,MAAA,IAAI,kBAAA,CAAmB,MAAA,CAAO,KAAK,CAAA,EAAG;AACpC,QAAA,eAAA,CAAgB,OAAO,KAAK,CAAA;AAAA,MAC9B,CAAA,MAAO;AACL,QAAA,cAAA,CAAe,OAAO,KAAK,CAAA;AAAA,MAC7B;AAAA,IACF,CAAA;AAKA,IAAA,MAAM,cAAA,GAAiB,OAAO,KAAA,EAAe,QAAA,KAAsB;AACjE,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,CAAM,OAAO,QAAQ,CAAA;AAC3B,QAAA,IAAA,CAAK,OAAA,EAAS,OAAO,QAAQ,CAAA;AAAA,MAC/B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAA;AAKA,IAAA,MAAM,oBAAA,GAAuB,CAAC,CAAA,KAAa;AACzC,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,IAAI,aAAa,KAAA,EAAO;AACtB,QAAA,cAAA,CAAe,YAAA,CAAa,KAAA,EAAO,YAAA,CAAa,KAAA,IAAS,MAAS,CAAA;AAClE,QAAA,YAAA,CAAa,KAAA,GAAQ,EAAA;AAAA,MACvB;AAAA,IACF,CAAA;AAKA,IAAA,MAAM,iBAAiB,MAAM;AAC3B,MAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,MAAA,YAAA,CAAa,KAAA,GAAQ,EAAA;AAAA,IACvB,CAAA;AAEA,IAAA,OAAO,MAAM;AAEX,MAAA,IAAI,CAAC,OAAA,CAAQ,KAAA,IAAS,CAAC,QAAQ,KAAA,EAAO;AACpC,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,IAAI,UAAU,KAAA,EAAO;AACnB,QAAA,MAAMG,kBAAiB,OAAA,CAAQ,KAAA;AAC/B,QAAA,OAAOC,KAAA;AAAA,UACL,KAAA;AAAA,UACA;AAAA,YACE,OAAO,KAAA,CAAM,cAAA;AAAA,YACb,KAAA,EAAO;AAAA,cACL,GAAG,MAAA,CAAO,QAAA;AAAA,cACV,KAAA,EAAOD,gBAAe,YAAA,IAAgB;AAAA;AACxC,WACF;AAAA,UACA;AAAA,YACEC,KAAA,CAAE,MAAA,EAAQ,KAAA,CAAM,eAAA,IAAmB,2BAA2B,CAAA;AAAA,YAC9DA,KAAA;AAAA,cACE,QAAA;AAAA,cACA;AAAA,gBACE,IAAA,EAAM,QAAA;AAAA,gBACN,OAAO,MAAA,CAAO,WAAA;AAAA,gBACd,OAAA,EAAS,cAAA;AAAA,gBACT,YAAA,EAAc;AAAA,eAChB;AAAA,cACA;AAAA;AACF;AACF,SACF;AAAA,MACF;AAGA,MAAA,MAAM,iBAAA,GAAoB,UAAA,CAAW,UAAA,CAAW,KAAK,KAAK,UAAA,CAAW,EAAA;AACrE,MAAA,MAAM,iBAAiB,OAAA,CAAQ,KAAA;AAC/B,MAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,cAAA,CAAe,YAAA,IAAgB,MAAM,CAAA,IAAK,QAAA;AAC/E,MAAA,MAAM,WAAA,GAAc,cAAA,CAAe,cAAA,CAAe,WAAA,IAAe,GAAG,CAAA,IAAK,KAAA;AAEzE,MAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,KAAW;AACnD,QAAA,MAAM,QAAA,GAAW,YAAA,CAAa,KAAA,KAAU,MAAA,CAAO,KAAA;AAC/C,QAAA,MAAM,QAAA,GAAW;AAAA,UACfA,MAAE,MAAA,EAAQ,EAAE,KAAA,EAAO,EAAE,GAAG,MAAA,CAAO,IAAA,EAAM,GAAG,iBAAA,CAAkB,MAAK,EAAG,aAAA,EAAe,MAAA,EAAO,EAAG,OAAO,IAAI;AAAA,SACxG;AACA,QAAA,IAAI,WAAW,KAAA,EAAO;AACpB,UAAA,QAAA,CAAS,KAAKA,KAAA,CAAE,MAAA,EAAQ,EAAE,KAAA,EAAO,EAAE,GAAG,iBAAA,CAAkB,KAAA,EAAO,KAAA,EAAO,eAAe,eAAA,IAAmB,SAAA,IAAY,EAAG,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,QACtI;AAEA,QAAA,OAAOA,KAAA;AAAA,UACL,QAAA;AAAA,UACA;AAAA,YACE,KAAK,MAAA,CAAO,KAAA;AAAA,YACZ,IAAA,EAAM,QAAA;AAAA,YACN,OAAO,KAAA,CAAM,WAAA;AAAA,YACb,KAAA,EAAO;AAAA,cACL,GAAG,MAAA,CAAO,MAAA;AAAA,cACV,GAAG,iBAAA,CAAkB,MAAA;AAAA,cACrB,eAAA,EAAiB,eAAe,eAAA,IAAmB,SAAA;AAAA,cACnD,aAAa,QAAA,GAAY,cAAA,CAAe,YAAA,IAAgB,SAAA,GAAc,eAAe,WAAA,IAAe,SAAA;AAAA,cACpG,WAAA;AAAA,cACA,YAAA;AAAA,cACA,KAAA,EAAO,eAAe,eAAA,IAAmB,SAAA;AAAA,cACzC,GAAI,QAAA,GAAW;AAAA,gBACb,eAAA,EAAiB,CAAA,EAAG,cAAA,CAAe,YAAA,IAAgB,SAAS,CAAA,EAAA;AAAA,kBAC1D,EAAC;AAAA,cACL,GAAI,YAAA,CAAa,KAAA,GAAQ,MAAA,CAAO,iBAAiB;AAAC,aACpD;AAAA,YACA,UAAU,YAAA,CAAa,KAAA;AAAA,YACvB,cAAA,EAAgB,QAAA;AAAA,YAChB,cAAc,MAAA,CAAO,KAAA;AAAA,YACrB,OAAA,EAAS,MAAM,iBAAA,CAAkB,MAAM;AAAA,WACzC;AAAA,UACA;AAAA,SACF;AAAA,MACF,CAAC,CAAA;AAGD,MAAA,IAAI,YAAA,GAAe,IAAA;AACnB,MAAA,MAAM,iBAAiB,iBAAA,CAAkB,KAAA;AACzC,MAAA,IAAI,YAAA,CAAa,SAAS,cAAA,EAAgB;AACxC,QAAA,YAAA,GAAeA,KAAA;AAAA,UACb,MAAA;AAAA,UACA;AAAA,YACE,OAAO,MAAA,CAAO,QAAA;AAAA,YACd,QAAA,EAAU;AAAA,WACZ;AAAA,UACA;AAAA,YACEA,MAAE,OAAA,EAAS;AAAA,cACT,IAAA,EAAM,MAAA;AAAA,cACN,OAAO,MAAA,CAAO,KAAA;AAAA,cACd,OAAO,YAAA,CAAa,KAAA;AAAA,cACpB,WAAA,EAAa,eAAe,mBAAA,IAAuB,iBAAA;AAAA,cACnD,UAAU,YAAA,CAAa,KAAA;AAAA,cACvB,SAAA,EAAW,GAAA;AAAA,cACX,OAAA,EAAS,CAAC,CAAA,KAAa;AACrB,gBAAA,YAAA,CAAa,KAAA,GAAS,EAAE,MAAA,CAA4B,KAAA;AAAA,cACtD;AAAA,aACD,CAAA;AAAA,YACDA,KAAA,CAAE,KAAA,EAAO,EAAE,KAAA,EAAO,EAAE,GAAG,MAAA,CAAO,OAAA,EAAS,cAAA,EAAgB,QAAA,EAAS,EAAE,EAAG;AAAA,cACnEA,KAAA;AAAA,gBACE,QAAA;AAAA,gBACA;AAAA,kBACE,IAAA,EAAM,QAAA;AAAA,kBACN,KAAA,EAAO;AAAA,oBACL,GAAG,MAAA,CAAO,YAAA;AAAA,oBACV,eAAA,EAAiB,eAAe,YAAA,IAAgB,SAAA;AAAA,oBAChD,YAAA;AAAA,oBACA,GAAI,YAAA,CAAa,KAAA,GAAQ,MAAA,CAAO,iBAAiB;AAAC,mBACpD;AAAA,kBACA,UAAU,YAAA,CAAa;AAAA,iBACzB;AAAA,gBACA,YAAA,CAAa,QAAQ,YAAA,GAAe;AAAA,eACtC;AAAA,cACAA,KAAA;AAAA,gBACE,QAAA;AAAA,gBACA;AAAA,kBACE,IAAA,EAAM,QAAA;AAAA,kBACN,KAAA,EAAO;AAAA,oBACL,GAAG,MAAA,CAAO,YAAA;AAAA,oBACV,eAAA,EAAiB,eAAe,eAAA,IAAmB,SAAA;AAAA,oBACnD,KAAA,EAAO,eAAe,eAAA,IAAmB,SAAA;AAAA,oBACzC,YAAA;AAAA,oBACA,QAAQ,CAAA,EAAG,WAAW,CAAA,OAAA,EAAU,cAAA,CAAe,eAAe,SAAS,CAAA;AAAA,mBACzE;AAAA,kBACA,UAAU,YAAA,CAAa,KAAA;AAAA,kBACvB,OAAA,EAAS;AAAA,iBACX;AAAA,gBACA;AAAA;AACF,aACD;AAAA;AACH,SACF;AAAA,MACF;AAGA,MAAA,IAAI,YAAA,GAAe,IAAA;AACnB,MAAA,IAAI,MAAM,KAAA,EAAO;AACf,QAAA,YAAA,GAAeA,KAAA;AAAA,UACb,KAAA;AAAA,UACA,EAAE,KAAA,EAAO,MAAA,CAAO,KAAA,EAAO,MAAM,OAAA,EAAQ;AAAA,UACrC,MAAM,KAAA,CAAM;AAAA,SACd;AAAA,MACF;AAGA,MAAA,OAAOA,KAAA;AAAA,QACL,KAAA;AAAA,QACA;AAAA,UACE,OAAO,KAAA,CAAM,cAAA;AAAA,UACb,OAAO,MAAA,CAAO,SAAA;AAAA,UACd,IAAA,EAAM,OAAA;AAAA,UACN,YAAA,EAAc;AAAA,SAChB;AAAA,QACA;AAAA,UACEA,KAAA,CAAE,OAAO,EAAE,KAAA,EAAO,OAAO,WAAA,EAAa,IAAA,EAAM,YAAA,EAAa,EAAG,cAAc,CAAA;AAAA,UAC1E,YAAA;AAAA,UACA;AAAA;AACF,OACF;AAAA,IACF,CAAA;AAAA,EACF;AACF,CAAC","file":"index.cjs","sourcesContent":["/**\n * @feedvalue/vue - Plugin\n *\n * Vue plugin for FeedValue. Provides app-level configuration\n * and automatic initialization.\n */\n\nimport type { App, InjectionKey } from 'vue';\nimport { FeedValue, type FeedValueConfig, type FeedValueInstance } from '@feedvalue/core';\n\n/**\n * Plugin options\n */\nexport interface FeedValuePluginOptions {\n /** Widget ID from FeedValue dashboard */\n widgetId: string;\n /** API base URL (for self-hosted) */\n apiBaseUrl?: string;\n /** Configuration overrides */\n config?: Partial<FeedValueConfig>;\n /**\n * Headless mode - disables all DOM rendering.\n * Use this when you want full control over the UI.\n * The SDK will still fetch config and provide all API methods\n * but won't render any trigger button or modal.\n *\n * @default false\n */\n headless?: boolean;\n}\n\n/**\n * Injection key for FeedValue instance\n */\nexport const FEEDVALUE_KEY: InjectionKey<FeedValueInstance> = Symbol('feedvalue');\n\n/**\n * Injection key for widget ID (used by useFeedValue when no instance is injected)\n */\nexport const FEEDVALUE_OPTIONS_KEY: InjectionKey<FeedValuePluginOptions> = Symbol('feedvalue-options');\n\n/**\n * Create FeedValue Vue plugin\n *\n * @example\n * ```ts\n * // main.ts\n * import { createApp } from 'vue';\n * import { createFeedValue } from '@feedvalue/vue';\n * import App from './App.vue';\n *\n * const app = createApp(App);\n *\n * app.use(createFeedValue({\n * widgetId: 'your-widget-id',\n * config: { theme: 'dark' }\n * }));\n *\n * app.mount('#app');\n * ```\n */\nexport function createFeedValue(options: FeedValuePluginOptions) {\n let instance: FeedValueInstance | null = null;\n\n return {\n install(app: App) {\n // Only initialize on client side\n if (typeof window !== 'undefined') {\n instance = FeedValue.init({\n widgetId: options.widgetId,\n apiBaseUrl: options.apiBaseUrl,\n config: options.config,\n headless: options.headless,\n });\n\n // Provide instance to all components\n app.provide(FEEDVALUE_KEY, instance);\n\n // Also provide to global properties for Options API access\n app.config.globalProperties.$feedvalue = instance;\n }\n\n // Always provide options (for SSR where we don't initialize)\n app.provide(FEEDVALUE_OPTIONS_KEY, options);\n },\n };\n}\n\n/**\n * Type augmentation for global properties\n */\ndeclare module 'vue' {\n interface ComponentCustomProperties {\n $feedvalue: FeedValueInstance | undefined;\n }\n}\n","/**\n * @feedvalue/vue - Composables\n *\n * Vue composables for FeedValue. Provides reactive state and methods.\n */\n\nimport {\n ref,\n shallowRef,\n readonly,\n onMounted,\n onUnmounted,\n inject,\n type Ref,\n type ShallowRef,\n} from 'vue';\nimport {\n FeedValue,\n type FeedValueConfig,\n type FeedValueInstance,\n type FeedbackData,\n type UserTraits,\n} from '@feedvalue/core';\nimport { FEEDVALUE_KEY, FEEDVALUE_OPTIONS_KEY } from './plugin';\n\n/**\n * Return type for useFeedValue composable\n */\nexport interface UseFeedValueReturn {\n /** FeedValue instance (for advanced usage) */\n instance: Readonly<ShallowRef<FeedValueInstance | null>>;\n /** Widget is ready */\n isReady: Readonly<Ref<boolean>>;\n /** Modal is open */\n isOpen: Readonly<Ref<boolean>>;\n /** Widget is visible */\n isVisible: Readonly<Ref<boolean>>;\n /** Current error */\n error: Readonly<Ref<Error | null>>;\n /** Submission in progress */\n isSubmitting: Readonly<Ref<boolean>>;\n /** Running in headless mode (no default UI rendered) */\n isHeadless: Readonly<Ref<boolean>>;\n /** Open the feedback modal */\n open: () => void;\n /** Close the feedback modal */\n close: () => void;\n /** Toggle the feedback modal */\n toggle: () => void;\n /** Show the trigger button */\n show: () => void;\n /** Hide the trigger button */\n hide: () => void;\n /** Submit feedback programmatically */\n submit: (feedback: Partial<FeedbackData>) => Promise<void>;\n /** Identify user */\n identify: (userId: string, traits?: UserTraits) => void;\n /** Set user data */\n setData: (data: Record<string, string>) => void;\n /** Reset user data */\n reset: () => void;\n}\n\n/**\n * FeedValue composable\n *\n * Can be used with or without plugin. If plugin is installed, uses the\n * provided instance. Otherwise, creates a new instance.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useFeedValue } from '@feedvalue/vue';\n *\n * // With plugin installed\n * const { open, isReady } = useFeedValue();\n *\n * // Or standalone with widgetId\n * const { open, isReady } = useFeedValue('your-widget-id');\n * </script>\n *\n * <template>\n * <button @click=\"open\" :disabled=\"!isReady\">\n * Give Feedback\n * </button>\n * </template>\n * ```\n */\nexport function useFeedValue(\n widgetId?: string,\n config?: Partial<FeedValueConfig>\n): UseFeedValueReturn {\n // Try to inject instance from plugin\n const injectedInstance = inject(FEEDVALUE_KEY, null);\n const injectedOptions = inject(FEEDVALUE_OPTIONS_KEY, null);\n\n // Refs for reactive state\n const instance = shallowRef<FeedValueInstance | null>(null);\n const isReady = ref(false);\n const isOpen = ref(false);\n const isVisible = ref(false);\n const error = ref<Error | null>(null);\n const isSubmitting = ref(false);\n const isHeadless = ref(false);\n\n // Track if we own the instance (need to destroy on unmount)\n let ownsInstance = false;\n let unsubscribe: (() => void) | null = null;\n\n /**\n * Sync reactive state from instance\n */\n const syncState = () => {\n const state = instance.value?.getSnapshot();\n if (state) {\n isReady.value = state.isReady;\n isOpen.value = state.isOpen;\n isVisible.value = state.isVisible;\n error.value = state.error;\n isSubmitting.value = state.isSubmitting;\n }\n };\n\n onMounted(() => {\n // Use injected instance if available and no widgetId override\n if (injectedInstance && !widgetId) {\n instance.value = injectedInstance;\n isHeadless.value = injectedInstance.isHeadless();\n } else {\n // Create new instance\n const effectiveWidgetId = widgetId ?? injectedOptions?.widgetId;\n\n if (!effectiveWidgetId) {\n console.error(\n '[FeedValue] No widgetId provided. Either install the plugin with createFeedValue() ' +\n 'or pass widgetId to useFeedValue().'\n );\n return;\n }\n\n instance.value = FeedValue.init({\n widgetId: effectiveWidgetId,\n apiBaseUrl: injectedOptions?.apiBaseUrl,\n config: config ?? injectedOptions?.config,\n headless: injectedOptions?.headless,\n });\n ownsInstance = true;\n }\n\n // Subscribe to state changes\n if (instance.value) {\n unsubscribe = instance.value.subscribe(syncState);\n isHeadless.value = instance.value.isHeadless();\n syncState(); // Initial sync\n }\n });\n\n onUnmounted(() => {\n unsubscribe?.();\n if (ownsInstance && instance.value) {\n instance.value.destroy();\n }\n instance.value = null;\n });\n\n // Methods that delegate to instance\n const open = () => instance.value?.open();\n const close = () => instance.value?.close();\n const toggle = () => instance.value?.toggle();\n const show = () => instance.value?.show();\n const hide = () => instance.value?.hide();\n const submit = (feedback: Partial<FeedbackData>) =>\n instance.value?.submit(feedback) ?? Promise.reject(new Error('Not initialized'));\n const identify = (userId: string, traits?: UserTraits) =>\n instance.value?.identify(userId, traits);\n const setData = (data: Record<string, string>) => instance.value?.setData(data);\n const reset = () => instance.value?.reset();\n\n return {\n instance: readonly(instance),\n isReady: readonly(isReady),\n isOpen: readonly(isOpen),\n isVisible: readonly(isVisible),\n error: readonly(error),\n isSubmitting: readonly(isSubmitting),\n isHeadless: readonly(isHeadless),\n open,\n close,\n toggle,\n show,\n hide,\n submit,\n identify,\n setData,\n reset,\n };\n}\n","/**\n * @feedvalue/vue - useReaction Composable\n *\n * Composable for reaction widgets in Vue applications.\n * Provides a simple API for submitting reactions.\n */\n\nimport {\n ref,\n computed,\n readonly,\n onMounted,\n onUnmounted,\n inject,\n type Ref,\n type ComputedRef,\n} from 'vue';\nimport {\n FeedValue,\n NEGATIVE_OPTIONS_MAP,\n type ReactionOption,\n type FeedValueInstance,\n type ButtonSize,\n type FollowUpTrigger,\n type ReactionTemplate,\n type ReactionStyling,\n} from '@feedvalue/core';\nimport { FEEDVALUE_KEY, FEEDVALUE_OPTIONS_KEY } from './plugin';\n\n/**\n * Return type for useReaction composable\n */\nexport interface UseReactionReturn {\n /** Available reaction options */\n options: ComputedRef<ReactionOption[] | null>;\n /** Currently submitting */\n isSubmitting: Readonly<Ref<boolean>>;\n /** Successfully submitted value (null if not yet submitted) */\n submitted: Readonly<Ref<string | null>>;\n /** Error if submission failed */\n error: Readonly<Ref<Error | null>>;\n /** Option value requiring follow-up input (null if none) */\n showFollowUp: Readonly<Ref<string | null>>;\n /** Submit a reaction */\n react: (value: string, followUp?: string) => Promise<void>;\n /** Set which option is showing follow-up input */\n setShowFollowUp: (value: string | null) => void;\n /** Clear the submitted state to allow re-submission */\n clearSubmitted: () => void;\n /** Check if widget is a reaction type */\n isReactionWidget: ComputedRef<boolean>;\n /** Widget configuration is ready */\n isReady: Readonly<Ref<boolean>>;\n /** Whether to show text labels next to icons */\n showLabels: ComputedRef<boolean>;\n /** Button size */\n buttonSize: ComputedRef<ButtonSize>;\n /** When to show follow-up input */\n followUpTrigger: ComputedRef<FollowUpTrigger>;\n /** Check if an option should show follow-up based on followUpTrigger */\n shouldShowFollowUp: (optionValue: string) => boolean;\n /** Widget styling configuration */\n styling: ComputedRef<ReactionStyling>;\n}\n\n/**\n * Composable for reaction widgets\n *\n * Provides reaction options, submission handling, and follow-up state management.\n * Can be used with or without the FeedValue plugin.\n *\n * @param widgetId - Optional widget ID override (uses plugin widget if not provided)\n *\n * @example\n * ```vue\n * <script setup>\n * import { useReaction } from '@feedvalue/vue';\n *\n * const {\n * options,\n * react,\n * isSubmitting,\n * submitted,\n * error,\n * showFollowUp,\n * setShowFollowUp,\n * isReady,\n * } = useReaction();\n *\n * const handleClick = (option) => {\n * if (option.showFollowUp) {\n * setShowFollowUp(option.value);\n * } else {\n * react(option.value);\n * }\n * };\n * </script>\n *\n * <template>\n * <div v-if=\"isReady && options\">\n * <div v-if=\"submitted\">Thanks for your feedback!</div>\n *\n * <template v-else>\n * <button\n * v-for=\"option in options\"\n * :key=\"option.value\"\n * @click=\"handleClick(option)\"\n * :disabled=\"isSubmitting\"\n * >\n * {{ option.icon }} {{ option.label }}\n * </button>\n *\n * <form v-if=\"showFollowUp\" @submit.prevent=\"react(showFollowUp, followUpText)\">\n * <input v-model=\"followUpText\" placeholder=\"Tell us more...\" />\n * <button type=\"submit\">Send</button>\n * </form>\n *\n * <div v-if=\"error\">Error: {{ error.message }}</div>\n * </template>\n * </div>\n * </template>\n * ```\n */\nexport function useReaction(widgetId?: string): UseReactionReturn {\n // Try to inject instance from plugin\n const injectedInstance = inject(FEEDVALUE_KEY, null);\n const injectedOptions = inject(FEEDVALUE_OPTIONS_KEY, null);\n\n // Local instance ref (may be created if no plugin or widgetId override)\n const instance = ref<FeedValueInstance | null>(null);\n const isReady = ref(false);\n\n // Local state for reaction UI\n const showFollowUp = ref<string | null>(null);\n const submitted = ref<string | null>(null);\n const isSubmitting = ref(false);\n const error = ref<Error | null>(null);\n\n // Track if we own the instance (need to destroy on unmount)\n let ownsInstance = false;\n let unsubscribe: (() => void) | null = null;\n\n /**\n * Sync ready state from instance\n */\n const syncState = () => {\n const state = instance.value?.getSnapshot();\n if (state) {\n isReady.value = state.isReady;\n }\n };\n\n onMounted(() => {\n // Use injected instance if available and no widgetId override\n if (injectedInstance && !widgetId) {\n instance.value = injectedInstance;\n } else {\n // Create new instance\n const effectiveWidgetId = widgetId ?? injectedOptions?.widgetId;\n\n if (!effectiveWidgetId) {\n console.error(\n '[FeedValue] No widgetId provided. Either install the plugin with createFeedValue() ' +\n 'or pass widgetId to useReaction().'\n );\n return;\n }\n\n instance.value = FeedValue.init({\n widgetId: effectiveWidgetId,\n apiBaseUrl: injectedOptions?.apiBaseUrl,\n config: injectedOptions?.config,\n headless: true, // Reaction widgets are always headless\n });\n ownsInstance = true;\n }\n\n // Subscribe to state changes\n if (instance.value) {\n unsubscribe = instance.value.subscribe(syncState);\n syncState(); // Initial sync\n }\n });\n\n onUnmounted(() => {\n unsubscribe?.();\n if (ownsInstance && instance.value) {\n instance.value.destroy();\n }\n instance.value = null;\n });\n\n // Computed: reaction options from instance\n const options = computed<ReactionOption[] | null>(() => {\n if (!instance.value || !isReady.value) return null;\n return instance.value.getReactionOptions();\n });\n\n // Computed: check if this is a reaction widget\n const isReactionWidget = computed(() => {\n return instance.value?.isReaction() ?? false;\n });\n\n // Computed: get config values with defaults\n const reactionConfig = computed(() => {\n if (!instance.value || !isReady.value) return null;\n // Access the widget config which includes reaction config\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (instance.value as any)._widgetConfig?.config ?? null;\n });\n\n const showLabels = computed(() => {\n return reactionConfig.value?.showLabels ?? true;\n });\n\n const buttonSize = computed<ButtonSize>(() => {\n return reactionConfig.value?.buttonSize ?? 'md';\n });\n\n const followUpTrigger = computed<FollowUpTrigger>(() => {\n return reactionConfig.value?.followUpTrigger ?? 'negative';\n });\n\n const template = computed<ReactionTemplate | undefined>(() => {\n return reactionConfig.value?.template;\n });\n\n // Computed: widget styling configuration\n const styling = computed<ReactionStyling>(() => {\n const defaultStyling: ReactionStyling = {\n primaryColor: '#6366f1',\n backgroundColor: '#ffffff',\n textColor: '#111827',\n buttonTextColor: '#4b5563',\n borderColor: '#e5e7eb',\n borderWidth: '1',\n borderRadius: 'full',\n };\n\n if (!instance.value || !isReady.value) {\n return defaultStyling;\n }\n\n // Access the widget config styling\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const widgetConfig = (instance.value as any)._widgetConfig;\n if (!widgetConfig?.styling) {\n return defaultStyling;\n }\n\n // Cast styling to access extended properties that may be present from API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const widgetStyling = widgetConfig.styling as any;\n return {\n primaryColor: widgetStyling.primaryColor ?? defaultStyling.primaryColor,\n backgroundColor: widgetStyling.backgroundColor ?? defaultStyling.backgroundColor,\n textColor: widgetStyling.textColor ?? defaultStyling.textColor,\n buttonTextColor: widgetStyling.buttonTextColor ?? defaultStyling.buttonTextColor,\n borderColor: widgetStyling.borderColor ?? defaultStyling.borderColor,\n borderWidth: widgetStyling.borderWidth ?? defaultStyling.borderWidth,\n borderRadius: widgetStyling.borderRadius ?? defaultStyling.borderRadius,\n };\n });\n\n /**\n * Check if an option should show follow-up based on followUpTrigger\n */\n const shouldShowFollowUp = (optionValue: string): boolean => {\n if (followUpTrigger.value === 'none') return false;\n if (followUpTrigger.value === 'all') return true;\n // followUpTrigger === 'negative'\n if (template.value && NEGATIVE_OPTIONS_MAP[template.value]) {\n return NEGATIVE_OPTIONS_MAP[template.value].includes(optionValue);\n }\n // For custom options, use the option's own showFollowUp setting\n const option = options.value?.find((o) => o.value === optionValue);\n return option?.showFollowUp ?? false;\n };\n\n /**\n * Submit a reaction\n */\n const react = async (value: string, followUp?: string): Promise<void> => {\n if (!instance.value) {\n throw new Error('FeedValue not initialized');\n }\n\n isSubmitting.value = true;\n error.value = null;\n\n try {\n await instance.value.react(value, followUp ? { followUp } : undefined);\n submitted.value = value;\n showFollowUp.value = null;\n } catch (err) {\n const reactionError = err instanceof Error ? err : new Error(String(err));\n error.value = reactionError;\n throw reactionError;\n } finally {\n isSubmitting.value = false;\n }\n };\n\n /**\n * Set which option is showing follow-up input\n */\n const setShowFollowUp = (value: string | null): void => {\n showFollowUp.value = value;\n };\n\n /**\n * Clear submitted state to allow re-submission\n */\n const clearSubmitted = (): void => {\n submitted.value = null;\n error.value = null;\n };\n\n return {\n options,\n isSubmitting: readonly(isSubmitting),\n submitted: readonly(submitted),\n error: readonly(error),\n showFollowUp: readonly(showFollowUp),\n react,\n setShowFollowUp,\n clearSubmitted,\n isReactionWidget,\n isReady: readonly(isReady),\n showLabels,\n buttonSize,\n followUpTrigger,\n shouldShowFollowUp,\n styling,\n };\n}\n","/**\n * @feedvalue/vue - ReactionButtons Component\n *\n * Pre-built reaction buttons component for Vue applications.\n * Renders reaction options with optional follow-up input.\n */\n\nimport { defineComponent, ref, computed, h, type PropType } from 'vue';\nimport { useReaction } from './use-reaction';\nimport type { ReactionOption } from '@feedvalue/core';\n\nimport type { ButtonSize, ReactionBorderRadius, ReactionBorderWidth } from '@feedvalue/core';\n\n/**\n * Border radius mapping from preset to CSS value\n */\nconst borderRadiusMap: Record<ReactionBorderRadius, string> = {\n full: '9999px',\n lg: '12px',\n md: '8px',\n sm: '4px',\n none: '0px',\n};\n\n/**\n * Border width mapping from preset to CSS value\n */\nconst borderWidthMap: Record<ReactionBorderWidth, string> = {\n '0': '0px',\n '1': '1px',\n '2': '2px',\n '3': '3px',\n '4': '4px',\n};\n\n/**\n * Button size style variants\n */\nconst sizeStyles: Record<ButtonSize, { button: Record<string, string>; icon: Record<string, string>; label: Record<string, string> }> = {\n sm: {\n button: { padding: '0.375rem 0.75rem', fontSize: '0.75rem', gap: '0.375rem' },\n icon: { fontSize: '1rem' },\n label: { fontSize: '0.75rem' },\n },\n md: {\n button: { padding: '0.5rem 1rem', fontSize: '0.875rem', gap: '0.5rem' },\n icon: { fontSize: '1.125rem' },\n label: { fontSize: '0.875rem' },\n },\n lg: {\n button: { padding: '0.75rem 1.25rem', fontSize: '1rem', gap: '0.625rem' },\n icon: { fontSize: '1.5rem' },\n label: { fontSize: '1rem' },\n },\n};\n\n/**\n * Default CSS styles for the component\n */\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '0.75rem',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n },\n buttonGroup: {\n display: 'flex',\n flexWrap: 'wrap' as const,\n gap: '0.5rem',\n },\n button: {\n display: 'inline-flex',\n alignItems: 'center',\n fontWeight: '500',\n color: '#374151',\n backgroundColor: '#ffffff',\n border: '1px solid #d1d5db',\n borderRadius: '9999px',\n cursor: 'pointer',\n transition: 'background-color 0.15s, border-color 0.15s, transform 0.1s',\n },\n buttonActive: {\n backgroundColor: '#eef2ff',\n borderColor: '#6366f1',\n color: '#4f46e5',\n },\n buttonDisabled: {\n opacity: 0.7,\n cursor: 'not-allowed',\n },\n icon: {},\n followUp: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '0.5rem',\n padding: '0.75rem',\n backgroundColor: '#f9fafb',\n border: '1px solid #e5e7eb',\n borderRadius: '0.5rem',\n },\n input: {\n width: '100%',\n padding: '0.5rem 0.75rem',\n fontSize: '0.875rem',\n border: '1px solid #d1d5db',\n borderRadius: '0.375rem',\n backgroundColor: '#ffffff',\n boxSizing: 'border-box' as const,\n },\n actions: {\n display: 'flex',\n gap: '0.5rem',\n justifyContent: 'flex-end',\n },\n submitButton: {\n padding: '0.375rem 0.75rem',\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#ffffff',\n backgroundColor: '#6366f1',\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n },\n cancelButton: {\n padding: '0.375rem 0.75rem',\n fontSize: '0.875rem',\n color: '#6b7280',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n },\n thankYou: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.75rem 1rem',\n fontSize: '0.875rem',\n color: '#059669',\n backgroundColor: '#ecfdf5',\n border: '1px solid #a7f3d0',\n borderRadius: '0.5rem',\n },\n resetButton: {\n padding: '0.25rem 0.5rem',\n fontSize: '0.875rem',\n color: '#6b7280',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n },\n error: {\n padding: '0.5rem 0.75rem',\n fontSize: '0.875rem',\n color: '#dc2626',\n backgroundColor: '#fef2f2',\n border: '1px solid #fecaca',\n borderRadius: '0.375rem',\n },\n};\n\n/**\n * ReactionButtons Component\n *\n * Pre-built reaction buttons with follow-up input support.\n *\n * @example\n * ```vue\n * <template>\n * <ReactionButtons widget-id=\"xxx\" @react=\"onReact\" />\n * </template>\n *\n * <script setup>\n * import { ReactionButtons } from '@feedvalue/vue';\n *\n * const onReact = (value, followUp) => {\n * console.log('Reacted:', value, followUp);\n * };\n * </script>\n * ```\n */\nexport const ReactionButtons = defineComponent({\n name: 'ReactionButtons',\n\n props: {\n /** Widget ID (optional if using FeedValue plugin) */\n widgetId: {\n type: String as PropType<string | undefined>,\n default: undefined,\n },\n /** Custom thank you message (overrides widget config) */\n thankYouMessage: {\n type: String as PropType<string | undefined>,\n default: undefined,\n },\n /** Custom class for the container */\n containerClass: {\n type: String,\n default: '',\n },\n /** Custom class for buttons */\n buttonClass: {\n type: String,\n default: '',\n },\n },\n\n emits: {\n /** Emitted when a reaction is submitted */\n react: (value: string, _followUp?: string) => typeof value === 'string',\n },\n\n setup(props, { emit }) {\n const {\n options,\n react,\n isSubmitting,\n submitted,\n error,\n showFollowUp,\n setShowFollowUp,\n clearSubmitted,\n isReady,\n showLabels,\n buttonSize,\n shouldShowFollowUp,\n styling,\n } = useReaction(props.widgetId);\n\n // Local state for follow-up input\n const followUpText = ref('');\n\n // Get follow-up option\n const getFollowUpOption = computed<ReactionOption | null>(() => {\n if (!showFollowUp.value || !options.value) return null;\n return options.value.find((opt) => opt.value === showFollowUp.value) ?? null;\n });\n\n /**\n * Handle option click\n */\n const handleOptionClick = (option: ReactionOption) => {\n if (shouldShowFollowUp(option.value)) {\n setShowFollowUp(option.value);\n } else {\n submitReaction(option.value);\n }\n };\n\n /**\n * Submit reaction\n */\n const submitReaction = async (value: string, followUp?: string) => {\n try {\n await react(value, followUp);\n emit('react', value, followUp);\n } catch {\n // Error is already set in state\n }\n };\n\n /**\n * Handle follow-up form submit\n */\n const handleFollowUpSubmit = (e: Event) => {\n e.preventDefault();\n if (showFollowUp.value) {\n submitReaction(showFollowUp.value, followUpText.value || undefined);\n followUpText.value = '';\n }\n };\n\n /**\n * Cancel follow-up\n */\n const cancelFollowUp = () => {\n setShowFollowUp(null);\n followUpText.value = '';\n };\n\n return () => {\n // Don't render if not ready or no options\n if (!isReady.value || !options.value) {\n return null;\n }\n\n // Render thank you message after submission\n if (submitted.value) {\n const currentStyling = styling.value;\n return h(\n 'div',\n {\n class: props.containerClass,\n style: {\n ...styles.thankYou,\n color: currentStyling.primaryColor ?? '#059669',\n },\n },\n [\n h('span', props.thankYouMessage || 'Thanks for your feedback!'),\n h(\n 'button',\n {\n type: 'button',\n style: styles.resetButton,\n onClick: clearSubmitted,\n 'aria-label': 'Submit another reaction',\n },\n '↺'\n ),\n ]\n );\n }\n\n // Build reaction buttons using styling from widget config\n const currentSizeStyles = sizeStyles[buttonSize.value] || sizeStyles.md;\n const currentStyling = styling.value;\n const borderRadius = borderRadiusMap[currentStyling.borderRadius ?? 'full'] ?? '9999px';\n const borderWidth = borderWidthMap[currentStyling.borderWidth ?? '1'] ?? '1px';\n\n const buttonElements = options.value.map((option) => {\n const isActive = showFollowUp.value === option.value;\n const children = [\n h('span', { style: { ...styles.icon, ...currentSizeStyles.icon }, 'aria-hidden': 'true' }, option.icon),\n ];\n if (showLabels.value) {\n children.push(h('span', { style: { ...currentSizeStyles.label, color: currentStyling.buttonTextColor ?? '#4b5563' } }, option.label));\n }\n\n return h(\n 'button',\n {\n key: option.value,\n type: 'button',\n class: props.buttonClass,\n style: {\n ...styles.button,\n ...currentSizeStyles.button,\n backgroundColor: currentStyling.backgroundColor ?? '#ffffff',\n borderColor: isActive ? (currentStyling.primaryColor ?? '#6366f1') : (currentStyling.borderColor ?? '#e5e7eb'),\n borderWidth: borderWidth,\n borderRadius: borderRadius,\n color: currentStyling.buttonTextColor ?? '#4b5563',\n ...(isActive ? {\n backgroundColor: `${currentStyling.primaryColor ?? '#6366f1'}10`,\n } : {}),\n ...(isSubmitting.value ? styles.buttonDisabled : {}),\n },\n disabled: isSubmitting.value,\n 'aria-pressed': isActive,\n 'aria-label': option.label,\n onClick: () => handleOptionClick(option),\n },\n children\n );\n });\n\n // Build follow-up form if needed\n let followUpForm = null;\n const followUpOption = getFollowUpOption.value;\n if (showFollowUp.value && followUpOption) {\n followUpForm = h(\n 'form',\n {\n style: styles.followUp,\n onSubmit: handleFollowUpSubmit,\n },\n [\n h('input', {\n type: 'text',\n style: styles.input,\n value: followUpText.value,\n placeholder: followUpOption.followUpPlaceholder || 'Tell us more...',\n disabled: isSubmitting.value,\n maxlength: 500,\n onInput: (e: Event) => {\n followUpText.value = (e.target as HTMLInputElement).value;\n },\n }),\n h('div', { style: { ...styles.actions, justifyContent: 'center' } }, [\n h(\n 'button',\n {\n type: 'submit',\n style: {\n ...styles.submitButton,\n backgroundColor: currentStyling.primaryColor ?? '#6366f1',\n borderRadius: borderRadius,\n ...(isSubmitting.value ? styles.buttonDisabled : {}),\n },\n disabled: isSubmitting.value,\n },\n isSubmitting.value ? 'Sending...' : 'Send'\n ),\n h(\n 'button',\n {\n type: 'button',\n style: {\n ...styles.cancelButton,\n backgroundColor: currentStyling.backgroundColor ?? '#ffffff',\n color: currentStyling.buttonTextColor ?? '#6b7280',\n borderRadius: borderRadius,\n border: `${borderWidth} solid ${currentStyling.borderColor ?? '#e5e7eb'}`,\n },\n disabled: isSubmitting.value,\n onClick: cancelFollowUp,\n },\n 'Cancel'\n ),\n ]),\n ]\n );\n }\n\n // Build error message\n let errorElement = null;\n if (error.value) {\n errorElement = h(\n 'div',\n { style: styles.error, role: 'alert' },\n error.value.message\n );\n }\n\n // Return full component\n return h(\n 'div',\n {\n class: props.containerClass,\n style: styles.container,\n role: 'group',\n 'aria-label': 'Reaction buttons',\n },\n [\n h('div', { style: styles.buttonGroup, role: 'radiogroup' }, buttonElements),\n followUpForm,\n errorElement,\n ]\n );\n };\n },\n});\n\nexport default ReactionButtons;\n"]}
1
+ {"version":3,"sources":["../src/plugin.ts","../src/composables.ts","../src/use-reaction.ts","../src/ReactionButtons.ts"],"names":["FeedValue","inject","shallowRef","ref","onMounted","onUnmounted","readonly","computed","NEGATIVE_OPTIONS_MAP","defineComponent","currentStyling","h"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @feedvalue/vue - Plugin\n *\n * Vue plugin for FeedValue. Provides app-level configuration\n * and automatic initialization.\n */\n\nimport type { App, InjectionKey } from 'vue';\nimport { FeedValue, type FeedValueConfig, type FeedValueInstance } from '@feedvalue/core';\n\n/**\n * Plugin options\n */\nexport interface FeedValuePluginOptions {\n /** Widget ID from FeedValue dashboard */\n widgetId: string;\n /** API base URL (for self-hosted) */\n apiBaseUrl?: string;\n /** Configuration overrides */\n config?: Partial<FeedValueConfig>;\n /**\n * Headless mode - disables all DOM rendering.\n * Use this when you want full control over the UI.\n * The SDK will still fetch config and provide all API methods\n * but won't render any trigger button or modal.\n *\n * @default false\n */\n headless?: boolean;\n}\n\n/**\n * Injection key for FeedValue instance\n */\nexport const FEEDVALUE_KEY: InjectionKey<FeedValueInstance> = Symbol('feedvalue');\n\n/**\n * Injection key for widget ID (used by useFeedValue when no instance is injected)\n */\nexport const FEEDVALUE_OPTIONS_KEY: InjectionKey<FeedValuePluginOptions> = Symbol('feedvalue-options');\n\n/**\n * Create FeedValue Vue plugin\n *\n * @example\n * ```ts\n * // main.ts\n * import { createApp } from 'vue';\n * import { createFeedValue } from '@feedvalue/vue';\n * import App from './App.vue';\n *\n * const app = createApp(App);\n *\n * app.use(createFeedValue({\n * widgetId: 'your-widget-id',\n * config: { theme: 'dark' }\n * }));\n *\n * app.mount('#app');\n * ```\n */\nexport function createFeedValue(options: FeedValuePluginOptions) {\n let instance: FeedValueInstance | null = null;\n\n return {\n install(app: App) {\n // Only initialize on client side\n if (typeof window !== 'undefined') {\n instance = FeedValue.init({\n widgetId: options.widgetId,\n apiBaseUrl: options.apiBaseUrl,\n config: options.config,\n headless: options.headless,\n });\n\n // Provide instance to all components\n app.provide(FEEDVALUE_KEY, instance);\n\n // Also provide to global properties for Options API access\n app.config.globalProperties.$feedvalue = instance;\n }\n\n // Always provide options (for SSR where we don't initialize)\n app.provide(FEEDVALUE_OPTIONS_KEY, options);\n },\n };\n}\n\n/**\n * Type augmentation for global properties\n */\ndeclare module 'vue' {\n interface ComponentCustomProperties {\n $feedvalue: FeedValueInstance | undefined;\n }\n}\n","/**\n * @feedvalue/vue - Composables\n *\n * Vue composables for FeedValue. Provides reactive state and methods.\n */\n\nimport {\n ref,\n shallowRef,\n readonly,\n onMounted,\n onUnmounted,\n inject,\n type Ref,\n type ShallowRef,\n} from 'vue';\nimport {\n FeedValue,\n type FeedValueConfig,\n type FeedValueInstance,\n type FeedbackData,\n type UserTraits,\n} from '@feedvalue/core';\nimport { FEEDVALUE_KEY, FEEDVALUE_OPTIONS_KEY } from './plugin';\n\n/**\n * Return type for useFeedValue composable\n */\nexport interface UseFeedValueReturn {\n /** FeedValue instance (for advanced usage) */\n instance: Readonly<ShallowRef<FeedValueInstance | null>>;\n /** Widget is ready */\n isReady: Readonly<Ref<boolean>>;\n /** Modal is open */\n isOpen: Readonly<Ref<boolean>>;\n /** Widget is visible */\n isVisible: Readonly<Ref<boolean>>;\n /** Current error */\n error: Readonly<Ref<Error | null>>;\n /** Submission in progress */\n isSubmitting: Readonly<Ref<boolean>>;\n /** Running in headless mode (no default UI rendered) */\n isHeadless: Readonly<Ref<boolean>>;\n /** Open the feedback modal */\n open: () => void;\n /** Close the feedback modal */\n close: () => void;\n /** Toggle the feedback modal */\n toggle: () => void;\n /** Show the trigger button */\n show: () => void;\n /** Hide the trigger button */\n hide: () => void;\n /** Submit feedback programmatically */\n submit: (feedback: Partial<FeedbackData>) => Promise<void>;\n /** Identify user */\n identify: (userId: string, traits?: UserTraits) => void;\n /** Set user data */\n setData: (data: Record<string, string>) => void;\n /** Reset user data */\n reset: () => void;\n}\n\n/**\n * FeedValue composable\n *\n * Can be used with or without plugin. If plugin is installed, uses the\n * provided instance. Otherwise, creates a new instance.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useFeedValue } from '@feedvalue/vue';\n *\n * // With plugin installed\n * const { open, isReady } = useFeedValue();\n *\n * // Or standalone with widgetId\n * const { open, isReady } = useFeedValue('your-widget-id');\n * </script>\n *\n * <template>\n * <button @click=\"open\" :disabled=\"!isReady\">\n * Give Feedback\n * </button>\n * </template>\n * ```\n */\nexport function useFeedValue(\n widgetId?: string,\n config?: Partial<FeedValueConfig>\n): UseFeedValueReturn {\n // Try to inject instance from plugin\n const injectedInstance = inject(FEEDVALUE_KEY, null);\n const injectedOptions = inject(FEEDVALUE_OPTIONS_KEY, null);\n\n // Refs for reactive state\n const instance = shallowRef<FeedValueInstance | null>(null);\n const isReady = ref(false);\n const isOpen = ref(false);\n const isVisible = ref(false);\n const error = ref<Error | null>(null);\n const isSubmitting = ref(false);\n const isHeadless = ref(false);\n\n // Track if we own the instance (need to destroy on unmount)\n let ownsInstance = false;\n let unsubscribe: (() => void) | null = null;\n\n /**\n * Sync reactive state from instance\n */\n const syncState = () => {\n const state = instance.value?.getSnapshot();\n if (state) {\n isReady.value = state.isReady;\n isOpen.value = state.isOpen;\n isVisible.value = state.isVisible;\n error.value = state.error;\n isSubmitting.value = state.isSubmitting;\n }\n };\n\n onMounted(() => {\n // Use injected instance if available and no widgetId override\n if (injectedInstance && !widgetId) {\n instance.value = injectedInstance;\n isHeadless.value = injectedInstance.isHeadless();\n } else {\n // Create new instance\n const effectiveWidgetId = widgetId ?? injectedOptions?.widgetId;\n\n if (!effectiveWidgetId) {\n console.error(\n '[FeedValue] No widgetId provided. Either install the plugin with createFeedValue() ' +\n 'or pass widgetId to useFeedValue().'\n );\n return;\n }\n\n instance.value = FeedValue.init({\n widgetId: effectiveWidgetId,\n apiBaseUrl: injectedOptions?.apiBaseUrl,\n config: config ?? injectedOptions?.config,\n headless: injectedOptions?.headless,\n });\n ownsInstance = true;\n }\n\n // Subscribe to state changes\n if (instance.value) {\n unsubscribe = instance.value.subscribe(syncState);\n isHeadless.value = instance.value.isHeadless();\n syncState(); // Initial sync\n }\n });\n\n onUnmounted(() => {\n unsubscribe?.();\n if (ownsInstance && instance.value) {\n instance.value.destroy();\n }\n instance.value = null;\n });\n\n // Methods that delegate to instance\n const open = () => instance.value?.open();\n const close = () => instance.value?.close();\n const toggle = () => instance.value?.toggle();\n const show = () => instance.value?.show();\n const hide = () => instance.value?.hide();\n const submit = (feedback: Partial<FeedbackData>) =>\n instance.value?.submit(feedback) ?? Promise.reject(new Error('Not initialized'));\n const identify = (userId: string, traits?: UserTraits) =>\n instance.value?.identify(userId, traits);\n const setData = (data: Record<string, string>) => instance.value?.setData(data);\n const reset = () => instance.value?.reset();\n\n return {\n instance: readonly(instance),\n isReady: readonly(isReady),\n isOpen: readonly(isOpen),\n isVisible: readonly(isVisible),\n error: readonly(error),\n isSubmitting: readonly(isSubmitting),\n isHeadless: readonly(isHeadless),\n open,\n close,\n toggle,\n show,\n hide,\n submit,\n identify,\n setData,\n reset,\n };\n}\n","/**\n * @feedvalue/vue - useReaction Composable\n *\n * Composable for reaction widgets in Vue applications.\n * Provides a simple API for submitting reactions.\n */\n\nimport {\n ref,\n computed,\n readonly,\n onMounted,\n onUnmounted,\n inject,\n type Ref,\n type ComputedRef,\n} from 'vue';\nimport {\n FeedValue,\n NEGATIVE_OPTIONS_MAP,\n type ReactionOption,\n type FeedValueInstance,\n type ButtonSize,\n type FollowUpTrigger,\n type ReactionTemplate,\n type ReactionStyling,\n} from '@feedvalue/core';\nimport { FEEDVALUE_KEY, FEEDVALUE_OPTIONS_KEY } from './plugin';\n\n/**\n * Return type for useReaction composable\n */\nexport interface UseReactionReturn {\n /** Available reaction options */\n options: ComputedRef<ReactionOption[] | null>;\n /** Currently submitting */\n isSubmitting: Readonly<Ref<boolean>>;\n /** Successfully submitted value (null if not yet submitted) */\n submitted: Readonly<Ref<string | null>>;\n /** Error if submission failed */\n error: Readonly<Ref<Error | null>>;\n /** Option value requiring follow-up input (null if none) */\n showFollowUp: Readonly<Ref<string | null>>;\n /** Submit a reaction */\n react: (value: string, followUp?: string) => Promise<void>;\n /** Set which option is showing follow-up input */\n setShowFollowUp: (value: string | null) => void;\n /** Clear the submitted state to allow re-submission */\n clearSubmitted: () => void;\n /** Check if widget is a reaction type */\n isReactionWidget: ComputedRef<boolean>;\n /** Widget configuration is ready */\n isReady: Readonly<Ref<boolean>>;\n /** Whether to show text labels next to icons */\n showLabels: ComputedRef<boolean>;\n /** Button size */\n buttonSize: ComputedRef<ButtonSize>;\n /** When to show follow-up input */\n followUpTrigger: ComputedRef<FollowUpTrigger>;\n /** Check if an option should show follow-up based on followUpTrigger */\n shouldShowFollowUp: (optionValue: string) => boolean;\n /** Widget styling configuration */\n styling: ComputedRef<ReactionStyling>;\n}\n\n/**\n * Composable for reaction widgets\n *\n * Provides reaction options, submission handling, and follow-up state management.\n * Can be used with or without the FeedValue plugin.\n *\n * @param widgetId - Optional widget ID override (uses plugin widget if not provided)\n *\n * @example\n * ```vue\n * <script setup>\n * import { useReaction } from '@feedvalue/vue';\n *\n * const {\n * options,\n * react,\n * isSubmitting,\n * submitted,\n * error,\n * showFollowUp,\n * setShowFollowUp,\n * isReady,\n * } = useReaction();\n *\n * const handleClick = (option) => {\n * if (option.showFollowUp) {\n * setShowFollowUp(option.value);\n * } else {\n * react(option.value);\n * }\n * };\n * </script>\n *\n * <template>\n * <div v-if=\"isReady && options\">\n * <div v-if=\"submitted\">Thanks for your feedback!</div>\n *\n * <template v-else>\n * <button\n * v-for=\"option in options\"\n * :key=\"option.value\"\n * @click=\"handleClick(option)\"\n * :disabled=\"isSubmitting\"\n * >\n * {{ option.icon }} {{ option.label }}\n * </button>\n *\n * <form v-if=\"showFollowUp\" @submit.prevent=\"react(showFollowUp, followUpText)\">\n * <input v-model=\"followUpText\" placeholder=\"Tell us more...\" />\n * <button type=\"submit\">Send</button>\n * </form>\n *\n * <div v-if=\"error\">Error: {{ error.message }}</div>\n * </template>\n * </div>\n * </template>\n * ```\n */\nexport function useReaction(widgetId?: string): UseReactionReturn {\n // Try to inject instance from plugin\n const injectedInstance = inject(FEEDVALUE_KEY, null);\n const injectedOptions = inject(FEEDVALUE_OPTIONS_KEY, null);\n\n // Local instance ref (may be created if no plugin or widgetId override)\n const instance = ref<FeedValueInstance | null>(null);\n const isReady = ref(false);\n\n // Local state for reaction UI\n const showFollowUp = ref<string | null>(null);\n const submitted = ref<string | null>(null);\n const isSubmitting = ref(false);\n const error = ref<Error | null>(null);\n\n // Track if we own the instance (need to destroy on unmount)\n let ownsInstance = false;\n let unsubscribe: (() => void) | null = null;\n\n /**\n * Sync ready state from instance\n */\n const syncState = () => {\n const state = instance.value?.getSnapshot();\n if (state) {\n isReady.value = state.isReady;\n }\n };\n\n onMounted(() => {\n // Use injected instance if available and no widgetId override\n if (injectedInstance && !widgetId) {\n instance.value = injectedInstance;\n } else {\n // Create new instance\n const effectiveWidgetId = widgetId ?? injectedOptions?.widgetId;\n\n if (!effectiveWidgetId) {\n console.error(\n '[FeedValue] No widgetId provided. Either install the plugin with createFeedValue() ' +\n 'or pass widgetId to useReaction().'\n );\n return;\n }\n\n instance.value = FeedValue.init({\n widgetId: effectiveWidgetId,\n apiBaseUrl: injectedOptions?.apiBaseUrl,\n config: injectedOptions?.config,\n headless: true, // Reaction widgets are always headless\n });\n ownsInstance = true;\n }\n\n // Subscribe to state changes\n if (instance.value) {\n unsubscribe = instance.value.subscribe(syncState);\n syncState(); // Initial sync\n }\n });\n\n onUnmounted(() => {\n unsubscribe?.();\n if (ownsInstance && instance.value) {\n instance.value.destroy();\n }\n instance.value = null;\n });\n\n // Computed: reaction options from instance\n const options = computed<ReactionOption[] | null>(() => {\n if (!instance.value || !isReady.value) return null;\n return instance.value.getReactionOptions();\n });\n\n // Computed: check if this is a reaction widget\n const isReactionWidget = computed(() => {\n return instance.value?.isReaction() ?? false;\n });\n\n // Computed: get config values with defaults\n const reactionConfig = computed(() => {\n if (!instance.value || !isReady.value) return null;\n // Access the widget config which includes reaction config\n const widgetConfig = instance.value.getWidgetConfig();\n return widgetConfig?.config ?? null;\n });\n\n const showLabels = computed(() => {\n return reactionConfig.value?.showLabels ?? true;\n });\n\n const buttonSize = computed<ButtonSize>(() => {\n return reactionConfig.value?.buttonSize ?? 'md';\n });\n\n const followUpTrigger = computed<FollowUpTrigger>(() => {\n return reactionConfig.value?.followUpTrigger ?? 'negative';\n });\n\n const template = computed<ReactionTemplate | undefined>(() => {\n return reactionConfig.value?.template;\n });\n\n // Computed: widget styling configuration\n const styling = computed<ReactionStyling>(() => {\n const defaultStyling: ReactionStyling = {\n primaryColor: '#6366f1',\n backgroundColor: '#ffffff',\n textColor: '#111827',\n buttonTextColor: '#4b5563',\n borderColor: '#e5e7eb',\n borderWidth: '1',\n borderRadius: 'full',\n };\n\n if (!instance.value || !isReady.value) {\n return defaultStyling;\n }\n\n // Access the widget config styling using public method\n const widgetConfig = instance.value.getWidgetConfig();\n if (!widgetConfig?.styling) {\n return defaultStyling;\n }\n\n // Cast styling to access extended properties that may be present from API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const widgetStyling = widgetConfig.styling as any;\n return {\n primaryColor: widgetStyling.primaryColor ?? defaultStyling.primaryColor,\n backgroundColor: widgetStyling.backgroundColor ?? defaultStyling.backgroundColor,\n textColor: widgetStyling.textColor ?? defaultStyling.textColor,\n buttonTextColor: widgetStyling.buttonTextColor ?? defaultStyling.buttonTextColor,\n borderColor: widgetStyling.borderColor ?? defaultStyling.borderColor,\n borderWidth: widgetStyling.borderWidth ?? defaultStyling.borderWidth,\n borderRadius: widgetStyling.borderRadius ?? defaultStyling.borderRadius,\n };\n });\n\n /**\n * Check if an option should show follow-up based on followUpTrigger\n */\n const shouldShowFollowUp = (optionValue: string): boolean => {\n if (followUpTrigger.value === 'none') return false;\n if (followUpTrigger.value === 'all') return true;\n // followUpTrigger === 'negative'\n if (template.value && NEGATIVE_OPTIONS_MAP[template.value]) {\n return NEGATIVE_OPTIONS_MAP[template.value].includes(optionValue);\n }\n // For custom options, use the option's own showFollowUp setting\n const option = options.value?.find((o) => o.value === optionValue);\n return option?.showFollowUp ?? false;\n };\n\n /**\n * Submit a reaction\n */\n const react = async (value: string, followUp?: string): Promise<void> => {\n if (!instance.value) {\n throw new Error('FeedValue not initialized');\n }\n\n isSubmitting.value = true;\n error.value = null;\n\n try {\n await instance.value.react(value, followUp ? { followUp } : undefined);\n submitted.value = value;\n showFollowUp.value = null;\n } catch (err) {\n const reactionError = err instanceof Error ? err : new Error(String(err));\n error.value = reactionError;\n throw reactionError;\n } finally {\n isSubmitting.value = false;\n }\n };\n\n /**\n * Set which option is showing follow-up input\n */\n const setShowFollowUp = (value: string | null): void => {\n showFollowUp.value = value;\n };\n\n /**\n * Clear submitted state to allow re-submission\n */\n const clearSubmitted = (): void => {\n submitted.value = null;\n error.value = null;\n };\n\n return {\n options,\n isSubmitting: readonly(isSubmitting),\n submitted: readonly(submitted),\n error: readonly(error),\n showFollowUp: readonly(showFollowUp),\n react,\n setShowFollowUp,\n clearSubmitted,\n isReactionWidget,\n isReady: readonly(isReady),\n showLabels,\n buttonSize,\n followUpTrigger,\n shouldShowFollowUp,\n styling,\n };\n}\n","/**\n * @feedvalue/vue - ReactionButtons Component\n *\n * Pre-built reaction buttons component for Vue applications.\n * Renders reaction options with optional follow-up input.\n */\n\nimport { defineComponent, ref, computed, h, type PropType } from 'vue';\nimport { useReaction } from './use-reaction';\nimport type { ReactionOption } from '@feedvalue/core';\n\nimport type { ButtonSize, ReactionBorderRadius } from '@feedvalue/core';\n\n/**\n * Border radius mapping from preset to CSS value\n */\nconst borderRadiusMap: Record<ReactionBorderRadius, string> = {\n full: '9999px',\n lg: '12px',\n md: '8px',\n sm: '4px',\n none: '0px',\n};\n\n/**\n * Border width mapping from preset to CSS value\n */\nconst borderWidthMap: Record<string, string> = {\n '0': '0px',\n '1': '1px',\n '2': '2px',\n '3': '3px',\n '4': '4px',\n thin: '1px',\n medium: '2px',\n thick: '3px',\n};\n\n/**\n * Button size style variants\n */\nconst sizeStyles: Record<ButtonSize, { button: Record<string, string>; icon: Record<string, string>; label: Record<string, string> }> = {\n sm: {\n button: { padding: '0.375rem 0.75rem', fontSize: '0.75rem', gap: '0.375rem' },\n icon: { fontSize: '1rem' },\n label: { fontSize: '0.75rem' },\n },\n md: {\n button: { padding: '0.5rem 1rem', fontSize: '0.875rem', gap: '0.5rem' },\n icon: { fontSize: '1.125rem' },\n label: { fontSize: '0.875rem' },\n },\n lg: {\n button: { padding: '0.75rem 1.25rem', fontSize: '1rem', gap: '0.625rem' },\n icon: { fontSize: '1.5rem' },\n label: { fontSize: '1rem' },\n },\n};\n\n/**\n * Default CSS styles for the component\n */\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '0.75rem',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n },\n buttonGroup: {\n display: 'flex',\n flexWrap: 'wrap' as const,\n gap: '0.5rem',\n },\n button: {\n display: 'inline-flex',\n alignItems: 'center',\n fontWeight: '500',\n color: '#374151',\n backgroundColor: '#ffffff',\n border: '1px solid #d1d5db',\n borderRadius: '9999px',\n cursor: 'pointer',\n transition: 'background-color 0.15s, border-color 0.15s, transform 0.1s',\n },\n buttonActive: {\n backgroundColor: '#eef2ff',\n borderColor: '#6366f1',\n color: '#4f46e5',\n },\n buttonDisabled: {\n opacity: 0.7,\n cursor: 'not-allowed',\n },\n icon: {},\n followUp: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '0.5rem',\n padding: '0.75rem',\n backgroundColor: '#f9fafb',\n border: '1px solid #e5e7eb',\n borderRadius: '0.5rem',\n },\n input: {\n width: '100%',\n padding: '0.5rem 0.75rem',\n fontSize: '0.875rem',\n border: '1px solid #d1d5db',\n borderRadius: '0.375rem',\n backgroundColor: '#ffffff',\n boxSizing: 'border-box' as const,\n resize: 'none' as const,\n },\n actions: {\n display: 'flex',\n gap: '0.5rem',\n justifyContent: 'flex-end',\n },\n submitButton: {\n padding: '0.375rem 0.75rem',\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#ffffff',\n backgroundColor: '#6366f1',\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n },\n cancelButton: {\n padding: '0.375rem 0.75rem',\n fontSize: '0.875rem',\n color: '#6b7280',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n },\n thankYou: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.75rem 1rem',\n fontSize: '0.875rem',\n color: '#059669',\n backgroundColor: '#ecfdf5',\n border: '1px solid #a7f3d0',\n borderRadius: '0.5rem',\n },\n resetButton: {\n padding: '0.25rem 0.5rem',\n fontSize: '0.875rem',\n color: '#6b7280',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n },\n error: {\n padding: '0.5rem 0.75rem',\n fontSize: '0.875rem',\n color: '#dc2626',\n backgroundColor: '#fef2f2',\n border: '1px solid #fecaca',\n borderRadius: '0.375rem',\n },\n};\n\n/**\n * ReactionButtons Component\n *\n * Pre-built reaction buttons with follow-up input support.\n *\n * @example\n * ```vue\n * <template>\n * <ReactionButtons widget-id=\"xxx\" @react=\"onReact\" />\n * </template>\n *\n * <script setup>\n * import { ReactionButtons } from '@feedvalue/vue';\n *\n * const onReact = (value, followUp) => {\n * console.log('Reacted:', value, followUp);\n * };\n * </script>\n * ```\n */\nexport const ReactionButtons = defineComponent({\n name: 'ReactionButtons',\n\n props: {\n /** Widget ID (optional if using FeedValue plugin) */\n widgetId: {\n type: String as PropType<string | undefined>,\n default: undefined,\n },\n /** Custom thank you message (overrides widget config) */\n thankYouMessage: {\n type: String as PropType<string | undefined>,\n default: undefined,\n },\n /** Custom class for the container */\n containerClass: {\n type: String,\n default: '',\n },\n /** Custom class for buttons */\n buttonClass: {\n type: String,\n default: '',\n },\n /** Custom class for the follow-up form */\n formClass: {\n type: String,\n default: '',\n },\n /** Custom class for the thank you message */\n thankYouClass: {\n type: String,\n default: '',\n },\n /** Hide after submission (default: false) */\n hideAfterSubmit: {\n type: Boolean,\n default: false,\n },\n /** Whether to show follow-up inline or not at all */\n followUpMode: {\n type: String as PropType<'inline' | 'none'>,\n default: 'inline',\n },\n },\n\n emits: {\n /** Emitted when a reaction is submitted */\n react: (value: string, _followUp?: string) => typeof value === 'string',\n /** Emitted when an error occurs */\n error: (_error: Error) => true,\n },\n\n setup(props, { emit }) {\n const {\n options,\n react,\n isSubmitting,\n submitted,\n error,\n showFollowUp,\n setShowFollowUp,\n clearSubmitted,\n isReady,\n showLabels,\n buttonSize,\n shouldShowFollowUp,\n styling,\n isReactionWidget,\n } = useReaction(props.widgetId);\n\n // Local state for follow-up input\n const followUpText = ref('');\n // Hover state for buttons\n const hoveredButton = ref<string | null>(null);\n\n // Get follow-up option\n const getFollowUpOption = computed<ReactionOption | null>(() => {\n if (!showFollowUp.value || !options.value) return null;\n return options.value.find((opt) => opt.value === showFollowUp.value) ?? null;\n });\n\n /**\n * Handle option click\n */\n const handleOptionClick = (option: ReactionOption) => {\n if (props.followUpMode === 'inline' && shouldShowFollowUp(option.value)) {\n setShowFollowUp(option.value);\n } else {\n submitReaction(option.value);\n }\n };\n\n /**\n * Submit reaction\n */\n const submitReaction = async (value: string, followUp?: string) => {\n const trimmedFollowUp = followUp?.trim() || undefined;\n try {\n await react(value, trimmedFollowUp);\n emit('react', value, trimmedFollowUp);\n } catch (err) {\n const reactionError = err instanceof Error ? err : new Error(String(err));\n emit('error', reactionError);\n }\n };\n\n /**\n * Handle follow-up form submit\n */\n const handleFollowUpSubmit = (e: Event) => {\n e.preventDefault();\n if (showFollowUp.value) {\n submitReaction(showFollowUp.value, followUpText.value || undefined);\n followUpText.value = '';\n }\n };\n\n /**\n * Cancel follow-up\n */\n const cancelFollowUp = () => {\n setShowFollowUp(null);\n followUpText.value = '';\n };\n\n return () => {\n // Don't render if not ready, not a reaction widget, or no options\n if (!isReady.value || !isReactionWidget.value || !options.value) {\n return null;\n }\n\n // Hide after submission if prop is set\n if (submitted.value && props.hideAfterSubmit) {\n return null;\n }\n\n // Render thank you message after submission\n if (submitted.value) {\n const currentStyling = styling.value;\n return h(\n 'div',\n {\n class: props.thankYouClass || props.containerClass,\n style: props.thankYouClass ? undefined : {\n ...styles.thankYou,\n color: currentStyling.primaryColor ?? '#059669',\n },\n },\n [\n h('span', props.thankYouMessage || 'Thanks for your feedback!'),\n h(\n 'button',\n {\n type: 'button',\n style: styles.resetButton,\n onClick: clearSubmitted,\n 'aria-label': 'Submit another reaction',\n },\n '↺'\n ),\n ]\n );\n }\n\n // Build reaction buttons using styling from widget config\n const currentSizeStyles = sizeStyles[buttonSize.value] || sizeStyles.md;\n const currentStyling = styling.value;\n const borderRadius = borderRadiusMap[currentStyling.borderRadius ?? 'full'] ?? '9999px';\n const borderWidth = borderWidthMap[currentStyling.borderWidth ?? '1'] ?? '1px';\n\n // Only show buttons when follow-up is not displayed\n const buttonElements = !showFollowUp.value ? options.value.map((option) => {\n const isActive = showFollowUp.value === option.value;\n const isHovered = hoveredButton.value === option.value;\n const children = [\n h('span', { style: { ...styles.icon, ...currentSizeStyles.icon }, 'aria-hidden': 'true' }, option.icon),\n ];\n if (showLabels.value) {\n children.push(h('span', { style: { ...currentSizeStyles.label, color: currentStyling.buttonTextColor ?? '#4b5563' } }, option.label));\n }\n\n return h(\n 'button',\n {\n key: option.value,\n type: 'button',\n class: props.buttonClass,\n style: {\n ...styles.button,\n ...currentSizeStyles.button,\n backgroundColor: currentStyling.backgroundColor ?? '#ffffff',\n borderColor: isActive || isHovered ? (currentStyling.primaryColor ?? '#6366f1') : (currentStyling.borderColor ?? '#e5e7eb'),\n borderWidth: borderWidth,\n borderRadius: borderRadius,\n borderStyle: 'solid',\n color: currentStyling.buttonTextColor ?? '#4b5563',\n ...(isActive || isHovered ? {\n backgroundColor: `${currentStyling.primaryColor ?? '#6366f1'}10`,\n } : {}),\n ...(isSubmitting.value ? styles.buttonDisabled : {}),\n },\n disabled: isSubmitting.value,\n 'aria-pressed': isActive,\n 'aria-label': option.label,\n onClick: () => handleOptionClick(option),\n onMouseenter: () => { hoveredButton.value = option.value; },\n onMouseleave: () => { hoveredButton.value = null; },\n },\n children\n );\n }) : [];\n\n // Build follow-up form if needed\n let followUpForm = null;\n const followUpOption = getFollowUpOption.value;\n if (showFollowUp.value && followUpOption) {\n followUpForm = h(\n 'form',\n {\n class: props.formClass,\n style: props.formClass ? undefined : styles.followUp,\n onSubmit: handleFollowUpSubmit,\n },\n [\n h('textarea', {\n style: styles.input,\n value: followUpText.value,\n placeholder: followUpOption.followUpPlaceholder || 'Tell us more (optional)',\n disabled: isSubmitting.value,\n maxlength: 500,\n rows: 3,\n onInput: (e: Event) => {\n followUpText.value = (e.target as HTMLTextAreaElement).value;\n },\n }),\n h('div', { style: { ...styles.actions, justifyContent: 'center' } }, [\n h(\n 'button',\n {\n type: 'submit',\n style: {\n ...styles.submitButton,\n backgroundColor: currentStyling.primaryColor ?? '#6366f1',\n borderRadius: borderRadius,\n ...(isSubmitting.value ? styles.buttonDisabled : {}),\n },\n disabled: isSubmitting.value,\n },\n isSubmitting.value ? 'Sending...' : 'Send'\n ),\n h(\n 'button',\n {\n type: 'button',\n style: {\n ...styles.cancelButton,\n backgroundColor: currentStyling.backgroundColor ?? '#ffffff',\n color: currentStyling.buttonTextColor ?? '#6b7280',\n borderRadius: borderRadius,\n border: `${borderWidth} solid ${currentStyling.borderColor ?? '#e5e7eb'}`,\n },\n disabled: isSubmitting.value,\n onClick: cancelFollowUp,\n },\n 'Cancel'\n ),\n ]),\n ]\n );\n }\n\n // Build error message\n let errorElement = null;\n if (error.value) {\n errorElement = h(\n 'div',\n { style: styles.error, role: 'alert' },\n error.value.message\n );\n }\n\n // Return full component\n return h(\n 'div',\n {\n class: props.containerClass,\n style: styles.container,\n role: 'group',\n 'aria-label': 'Reaction buttons',\n },\n [\n // Only render button group if there are buttons to show\n buttonElements.length > 0\n ? h('div', { style: styles.buttonGroup, role: 'radiogroup' }, buttonElements)\n : null,\n followUpForm,\n errorElement,\n ].filter(Boolean)\n );\n };\n },\n});\n\nexport default ReactionButtons;\n"]}
package/dist/index.d.cts CHANGED
@@ -283,11 +283,33 @@ declare const ReactionButtons: vue.DefineComponent<vue.ExtractPropTypes<{
283
283
  type: StringConstructor;
284
284
  default: string;
285
285
  };
286
+ /** Custom class for the follow-up form */
287
+ formClass: {
288
+ type: StringConstructor;
289
+ default: string;
290
+ };
291
+ /** Custom class for the thank you message */
292
+ thankYouClass: {
293
+ type: StringConstructor;
294
+ default: string;
295
+ };
296
+ /** Hide after submission (default: false) */
297
+ hideAfterSubmit: {
298
+ type: BooleanConstructor;
299
+ default: boolean;
300
+ };
301
+ /** Whether to show follow-up inline or not at all */
302
+ followUpMode: {
303
+ type: PropType<"inline" | "none">;
304
+ default: string;
305
+ };
286
306
  }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
287
307
  [key: string]: any;
288
308
  }> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
289
309
  /** Emitted when a reaction is submitted */
290
310
  react: (value: string, _followUp?: string) => boolean;
311
+ /** Emitted when an error occurs */
312
+ error: (_error: Error) => true;
291
313
  }, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
292
314
  /** Widget ID (optional if using FeedValue plugin) */
293
315
  widgetId: {
@@ -309,13 +331,38 @@ declare const ReactionButtons: vue.DefineComponent<vue.ExtractPropTypes<{
309
331
  type: StringConstructor;
310
332
  default: string;
311
333
  };
334
+ /** Custom class for the follow-up form */
335
+ formClass: {
336
+ type: StringConstructor;
337
+ default: string;
338
+ };
339
+ /** Custom class for the thank you message */
340
+ thankYouClass: {
341
+ type: StringConstructor;
342
+ default: string;
343
+ };
344
+ /** Hide after submission (default: false) */
345
+ hideAfterSubmit: {
346
+ type: BooleanConstructor;
347
+ default: boolean;
348
+ };
349
+ /** Whether to show follow-up inline or not at all */
350
+ followUpMode: {
351
+ type: PropType<"inline" | "none">;
352
+ default: string;
353
+ };
312
354
  }>> & Readonly<{
355
+ onError?: (_error: Error) => any;
313
356
  onReact?: (value: string, _followUp?: string | undefined) => any;
314
357
  }>, {
315
- widgetId: string | undefined;
316
358
  thankYouMessage: string | undefined;
359
+ widgetId: string | undefined;
317
360
  containerClass: string;
318
361
  buttonClass: string;
362
+ formClass: string;
363
+ thankYouClass: string;
364
+ hideAfterSubmit: boolean;
365
+ followUpMode: "none" | "inline";
319
366
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
320
367
 
321
368
  export { FEEDVALUE_KEY, FEEDVALUE_OPTIONS_KEY, type FeedValuePluginOptions, ReactionButtons, type UseFeedValueReturn, type UseReactionReturn, createFeedValue, useFeedValue, useReaction };
package/dist/index.d.ts CHANGED
@@ -283,11 +283,33 @@ declare const ReactionButtons: vue.DefineComponent<vue.ExtractPropTypes<{
283
283
  type: StringConstructor;
284
284
  default: string;
285
285
  };
286
+ /** Custom class for the follow-up form */
287
+ formClass: {
288
+ type: StringConstructor;
289
+ default: string;
290
+ };
291
+ /** Custom class for the thank you message */
292
+ thankYouClass: {
293
+ type: StringConstructor;
294
+ default: string;
295
+ };
296
+ /** Hide after submission (default: false) */
297
+ hideAfterSubmit: {
298
+ type: BooleanConstructor;
299
+ default: boolean;
300
+ };
301
+ /** Whether to show follow-up inline or not at all */
302
+ followUpMode: {
303
+ type: PropType<"inline" | "none">;
304
+ default: string;
305
+ };
286
306
  }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
287
307
  [key: string]: any;
288
308
  }> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
289
309
  /** Emitted when a reaction is submitted */
290
310
  react: (value: string, _followUp?: string) => boolean;
311
+ /** Emitted when an error occurs */
312
+ error: (_error: Error) => true;
291
313
  }, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
292
314
  /** Widget ID (optional if using FeedValue plugin) */
293
315
  widgetId: {
@@ -309,13 +331,38 @@ declare const ReactionButtons: vue.DefineComponent<vue.ExtractPropTypes<{
309
331
  type: StringConstructor;
310
332
  default: string;
311
333
  };
334
+ /** Custom class for the follow-up form */
335
+ formClass: {
336
+ type: StringConstructor;
337
+ default: string;
338
+ };
339
+ /** Custom class for the thank you message */
340
+ thankYouClass: {
341
+ type: StringConstructor;
342
+ default: string;
343
+ };
344
+ /** Hide after submission (default: false) */
345
+ hideAfterSubmit: {
346
+ type: BooleanConstructor;
347
+ default: boolean;
348
+ };
349
+ /** Whether to show follow-up inline or not at all */
350
+ followUpMode: {
351
+ type: PropType<"inline" | "none">;
352
+ default: string;
353
+ };
312
354
  }>> & Readonly<{
355
+ onError?: (_error: Error) => any;
313
356
  onReact?: (value: string, _followUp?: string | undefined) => any;
314
357
  }>, {
315
- widgetId: string | undefined;
316
358
  thankYouMessage: string | undefined;
359
+ widgetId: string | undefined;
317
360
  containerClass: string;
318
361
  buttonClass: string;
362
+ formClass: string;
363
+ thankYouClass: string;
364
+ hideAfterSubmit: boolean;
365
+ followUpMode: "none" | "inline";
319
366
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
320
367
 
321
368
  export { FEEDVALUE_KEY, FEEDVALUE_OPTIONS_KEY, type FeedValuePluginOptions, ReactionButtons, type UseFeedValueReturn, type UseReactionReturn, createFeedValue, useFeedValue, useReaction };
package/dist/index.js CHANGED
@@ -163,7 +163,8 @@ function useReaction(widgetId) {
163
163
  });
164
164
  const reactionConfig = computed(() => {
165
165
  if (!instance.value || !isReady.value) return null;
166
- return instance.value._widgetConfig?.config ?? null;
166
+ const widgetConfig = instance.value.getWidgetConfig();
167
+ return widgetConfig?.config ?? null;
167
168
  });
168
169
  const showLabels = computed(() => {
169
170
  return reactionConfig.value?.showLabels ?? true;
@@ -190,7 +191,7 @@ function useReaction(widgetId) {
190
191
  if (!instance.value || !isReady.value) {
191
192
  return defaultStyling;
192
193
  }
193
- const widgetConfig = instance.value._widgetConfig;
194
+ const widgetConfig = instance.value.getWidgetConfig();
194
195
  if (!widgetConfig?.styling) {
195
196
  return defaultStyling;
196
197
  }
@@ -269,7 +270,10 @@ var borderWidthMap = {
269
270
  "1": "1px",
270
271
  "2": "2px",
271
272
  "3": "3px",
272
- "4": "4px"
273
+ "4": "4px",
274
+ thin: "1px",
275
+ medium: "2px",
276
+ thick: "3px"
273
277
  };
274
278
  var sizeStyles = {
275
279
  sm: {
@@ -332,7 +336,8 @@ var styles = {
332
336
  border: "1px solid #d1d5db",
333
337
  borderRadius: "0.375rem",
334
338
  backgroundColor: "#ffffff",
335
- boxSizing: "border-box"
339
+ boxSizing: "border-box",
340
+ resize: "none"
336
341
  },
337
342
  actions: {
338
343
  display: "flex",
@@ -407,11 +412,33 @@ var ReactionButtons = defineComponent({
407
412
  buttonClass: {
408
413
  type: String,
409
414
  default: ""
415
+ },
416
+ /** Custom class for the follow-up form */
417
+ formClass: {
418
+ type: String,
419
+ default: ""
420
+ },
421
+ /** Custom class for the thank you message */
422
+ thankYouClass: {
423
+ type: String,
424
+ default: ""
425
+ },
426
+ /** Hide after submission (default: false) */
427
+ hideAfterSubmit: {
428
+ type: Boolean,
429
+ default: false
430
+ },
431
+ /** Whether to show follow-up inline or not at all */
432
+ followUpMode: {
433
+ type: String,
434
+ default: "inline"
410
435
  }
411
436
  },
412
437
  emits: {
413
438
  /** Emitted when a reaction is submitted */
414
- react: (value, _followUp) => typeof value === "string"
439
+ react: (value, _followUp) => typeof value === "string",
440
+ /** Emitted when an error occurs */
441
+ error: (_error) => true
415
442
  },
416
443
  setup(props, { emit }) {
417
444
  const {
@@ -427,25 +454,30 @@ var ReactionButtons = defineComponent({
427
454
  showLabels,
428
455
  buttonSize,
429
456
  shouldShowFollowUp,
430
- styling
457
+ styling,
458
+ isReactionWidget
431
459
  } = useReaction(props.widgetId);
432
460
  const followUpText = ref("");
461
+ const hoveredButton = ref(null);
433
462
  const getFollowUpOption = computed(() => {
434
463
  if (!showFollowUp.value || !options.value) return null;
435
464
  return options.value.find((opt) => opt.value === showFollowUp.value) ?? null;
436
465
  });
437
466
  const handleOptionClick = (option) => {
438
- if (shouldShowFollowUp(option.value)) {
467
+ if (props.followUpMode === "inline" && shouldShowFollowUp(option.value)) {
439
468
  setShowFollowUp(option.value);
440
469
  } else {
441
470
  submitReaction(option.value);
442
471
  }
443
472
  };
444
473
  const submitReaction = async (value, followUp) => {
474
+ const trimmedFollowUp = followUp?.trim() || void 0;
445
475
  try {
446
- await react(value, followUp);
447
- emit("react", value, followUp);
448
- } catch {
476
+ await react(value, trimmedFollowUp);
477
+ emit("react", value, trimmedFollowUp);
478
+ } catch (err) {
479
+ const reactionError = err instanceof Error ? err : new Error(String(err));
480
+ emit("error", reactionError);
449
481
  }
450
482
  };
451
483
  const handleFollowUpSubmit = (e) => {
@@ -460,7 +492,10 @@ var ReactionButtons = defineComponent({
460
492
  followUpText.value = "";
461
493
  };
462
494
  return () => {
463
- if (!isReady.value || !options.value) {
495
+ if (!isReady.value || !isReactionWidget.value || !options.value) {
496
+ return null;
497
+ }
498
+ if (submitted.value && props.hideAfterSubmit) {
464
499
  return null;
465
500
  }
466
501
  if (submitted.value) {
@@ -468,8 +503,8 @@ var ReactionButtons = defineComponent({
468
503
  return h(
469
504
  "div",
470
505
  {
471
- class: props.containerClass,
472
- style: {
506
+ class: props.thankYouClass || props.containerClass,
507
+ style: props.thankYouClass ? void 0 : {
473
508
  ...styles.thankYou,
474
509
  color: currentStyling2.primaryColor ?? "#059669"
475
510
  }
@@ -493,8 +528,9 @@ var ReactionButtons = defineComponent({
493
528
  const currentStyling = styling.value;
494
529
  const borderRadius = borderRadiusMap[currentStyling.borderRadius ?? "full"] ?? "9999px";
495
530
  const borderWidth = borderWidthMap[currentStyling.borderWidth ?? "1"] ?? "1px";
496
- const buttonElements = options.value.map((option) => {
531
+ const buttonElements = !showFollowUp.value ? options.value.map((option) => {
497
532
  const isActive = showFollowUp.value === option.value;
533
+ const isHovered = hoveredButton.value === option.value;
498
534
  const children = [
499
535
  h("span", { style: { ...styles.icon, ...currentSizeStyles.icon }, "aria-hidden": "true" }, option.icon)
500
536
  ];
@@ -511,11 +547,12 @@ var ReactionButtons = defineComponent({
511
547
  ...styles.button,
512
548
  ...currentSizeStyles.button,
513
549
  backgroundColor: currentStyling.backgroundColor ?? "#ffffff",
514
- borderColor: isActive ? currentStyling.primaryColor ?? "#6366f1" : currentStyling.borderColor ?? "#e5e7eb",
550
+ borderColor: isActive || isHovered ? currentStyling.primaryColor ?? "#6366f1" : currentStyling.borderColor ?? "#e5e7eb",
515
551
  borderWidth,
516
552
  borderRadius,
553
+ borderStyle: "solid",
517
554
  color: currentStyling.buttonTextColor ?? "#4b5563",
518
- ...isActive ? {
555
+ ...isActive || isHovered ? {
519
556
  backgroundColor: `${currentStyling.primaryColor ?? "#6366f1"}10`
520
557
  } : {},
521
558
  ...isSubmitting.value ? styles.buttonDisabled : {}
@@ -523,28 +560,35 @@ var ReactionButtons = defineComponent({
523
560
  disabled: isSubmitting.value,
524
561
  "aria-pressed": isActive,
525
562
  "aria-label": option.label,
526
- onClick: () => handleOptionClick(option)
563
+ onClick: () => handleOptionClick(option),
564
+ onMouseenter: () => {
565
+ hoveredButton.value = option.value;
566
+ },
567
+ onMouseleave: () => {
568
+ hoveredButton.value = null;
569
+ }
527
570
  },
528
571
  children
529
572
  );
530
- });
573
+ }) : [];
531
574
  let followUpForm = null;
532
575
  const followUpOption = getFollowUpOption.value;
533
576
  if (showFollowUp.value && followUpOption) {
534
577
  followUpForm = h(
535
578
  "form",
536
579
  {
537
- style: styles.followUp,
580
+ class: props.formClass,
581
+ style: props.formClass ? void 0 : styles.followUp,
538
582
  onSubmit: handleFollowUpSubmit
539
583
  },
540
584
  [
541
- h("input", {
542
- type: "text",
585
+ h("textarea", {
543
586
  style: styles.input,
544
587
  value: followUpText.value,
545
- placeholder: followUpOption.followUpPlaceholder || "Tell us more...",
588
+ placeholder: followUpOption.followUpPlaceholder || "Tell us more (optional)",
546
589
  disabled: isSubmitting.value,
547
590
  maxlength: 500,
591
+ rows: 3,
548
592
  onInput: (e) => {
549
593
  followUpText.value = e.target.value;
550
594
  }
@@ -601,10 +645,11 @@ var ReactionButtons = defineComponent({
601
645
  "aria-label": "Reaction buttons"
602
646
  },
603
647
  [
604
- h("div", { style: styles.buttonGroup, role: "radiogroup" }, buttonElements),
648
+ // Only render button group if there are buttons to show
649
+ buttonElements.length > 0 ? h("div", { style: styles.buttonGroup, role: "radiogroup" }, buttonElements) : null,
605
650
  followUpForm,
606
651
  errorElement
607
- ]
652
+ ].filter(Boolean)
608
653
  );
609
654
  };
610
655
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugin.ts","../src/composables.ts","../src/use-reaction.ts","../src/ReactionButtons.ts"],"names":["FeedValue","inject","ref","onMounted","onUnmounted","readonly","computed","currentStyling"],"mappings":";;;;AAkCO,IAAM,aAAA,0BAAwD,WAAW;AAKzE,IAAM,qBAAA,0BAAqE,mBAAmB;AAsB9F,SAAS,gBAAgB,OAAA,EAAiC;AAC/D,EAAA,IAAI,QAAA,GAAqC,IAAA;AAEzC,EAAA,OAAO;AAAA,IACL,QAAQ,GAAA,EAAU;AAEhB,MAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,QAAA,QAAA,GAAW,UAAU,IAAA,CAAK;AAAA,UACxB,UAAU,OAAA,CAAQ,QAAA;AAAA,UAClB,YAAY,OAAA,CAAQ,UAAA;AAAA,UACpB,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,UAAU,OAAA,CAAQ;AAAA,SACnB,CAAA;AAGD,QAAA,GAAA,CAAI,OAAA,CAAQ,eAAe,QAAQ,CAAA;AAGnC,QAAA,GAAA,CAAI,MAAA,CAAO,iBAAiB,UAAA,GAAa,QAAA;AAAA,MAC3C;AAGA,MAAA,GAAA,CAAI,OAAA,CAAQ,uBAAuB,OAAO,CAAA;AAAA,IAC5C;AAAA,GACF;AACF;ACEO,SAAS,YAAA,CACd,UACA,MAAA,EACoB;AAEpB,EAAA,MAAM,gBAAA,GAAmB,MAAA,CAAO,aAAA,EAAe,IAAI,CAAA;AACnD,EAAA,MAAM,eAAA,GAAkB,MAAA,CAAO,qBAAA,EAAuB,IAAI,CAAA;AAG1D,EAAA,MAAM,QAAA,GAAW,WAAqC,IAAI,CAAA;AAC1D,EAAA,MAAM,OAAA,GAAU,IAAI,KAAK,CAAA;AACzB,EAAA,MAAM,MAAA,GAAS,IAAI,KAAK,CAAA;AACxB,EAAA,MAAM,SAAA,GAAY,IAAI,KAAK,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,IAAkB,IAAI,CAAA;AACpC,EAAA,MAAM,YAAA,GAAe,IAAI,KAAK,CAAA;AAC9B,EAAA,MAAM,UAAA,GAAa,IAAI,KAAK,CAAA;AAG5B,EAAA,IAAI,YAAA,GAAe,KAAA;AACnB,EAAA,IAAI,WAAA,GAAmC,IAAA;AAKvC,EAAA,MAAM,YAAY,MAAM;AACtB,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,EAAO,WAAA,EAAY;AAC1C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,OAAA;AACtB,MAAA,MAAA,CAAO,QAAQ,KAAA,CAAM,MAAA;AACrB,MAAA,SAAA,CAAU,QAAQ,KAAA,CAAM,SAAA;AACxB,MAAA,KAAA,CAAM,QAAQ,KAAA,CAAM,KAAA;AACpB,MAAA,YAAA,CAAa,QAAQ,KAAA,CAAM,YAAA;AAAA,IAC7B;AAAA,EACF,CAAA;AAEA,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,IAAI,gBAAA,IAAoB,CAAC,QAAA,EAAU;AACjC,MAAA,QAAA,CAAS,KAAA,GAAQ,gBAAA;AACjB,MAAA,UAAA,CAAW,KAAA,GAAQ,iBAAiB,UAAA,EAAW;AAAA,IACjD,CAAA,MAAO;AAEL,MAAA,MAAM,iBAAA,GAAoB,YAAY,eAAA,EAAiB,QAAA;AAEvD,MAAA,IAAI,CAAC,iBAAA,EAAmB;AACtB,QAAA,OAAA,CAAQ,KAAA;AAAA,UACN;AAAA,SAEF;AACA,QAAA;AAAA,MACF;AAEA,MAAA,QAAA,CAAS,KAAA,GAAQA,UAAU,IAAA,CAAK;AAAA,QAC9B,QAAA,EAAU,iBAAA;AAAA,QACV,YAAY,eAAA,EAAiB,UAAA;AAAA,QAC7B,MAAA,EAAQ,UAAU,eAAA,EAAiB,MAAA;AAAA,QACnC,UAAU,eAAA,EAAiB;AAAA,OAC5B,CAAA;AACD,MAAA,YAAA,GAAe,IAAA;AAAA,IACjB;AAGA,IAAA,IAAI,SAAS,KAAA,EAAO;AAClB,MAAA,WAAA,GAAc,QAAA,CAAS,KAAA,CAAM,SAAA,CAAU,SAAS,CAAA;AAChD,MAAA,UAAA,CAAW,KAAA,GAAQ,QAAA,CAAS,KAAA,CAAM,UAAA,EAAW;AAC7C,MAAA,SAAA,EAAU;AAAA,IACZ;AAAA,EACF,CAAC,CAAA;AAED,EAAA,WAAA,CAAY,MAAM;AAChB,IAAA,WAAA,IAAc;AACd,IAAA,IAAI,YAAA,IAAgB,SAAS,KAAA,EAAO;AAClC,MAAA,QAAA,CAAS,MAAM,OAAA,EAAQ;AAAA,IACzB;AACA,IAAA,QAAA,CAAS,KAAA,GAAQ,IAAA;AAAA,EACnB,CAAC,CAAA;AAGD,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,KAAA,EAAO,IAAA,EAAK;AACxC,EAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,KAAA,EAAO,KAAA,EAAM;AAC1C,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,KAAA,EAAO,MAAA,EAAO;AAC5C,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,KAAA,EAAO,IAAA,EAAK;AACxC,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,KAAA,EAAO,IAAA,EAAK;AACxC,EAAA,MAAM,MAAA,GAAS,CAAC,QAAA,KACd,QAAA,CAAS,KAAA,EAAO,MAAA,CAAO,QAAQ,CAAA,IAAK,OAAA,CAAQ,MAAA,CAAO,IAAI,KAAA,CAAM,iBAAiB,CAAC,CAAA;AACjF,EAAA,MAAM,QAAA,GAAW,CAAC,MAAA,EAAgB,MAAA,KAChC,SAAS,KAAA,EAAO,QAAA,CAAS,QAAQ,MAAM,CAAA;AACzC,EAAA,MAAM,UAAU,CAAC,IAAA,KAAiC,QAAA,CAAS,KAAA,EAAO,QAAQ,IAAI,CAAA;AAC9E,EAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,KAAA,EAAO,KAAA,EAAM;AAE1C,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,SAAS,QAAQ,CAAA;AAAA,IAC3B,OAAA,EAAS,SAAS,OAAO,CAAA;AAAA,IACzB,MAAA,EAAQ,SAAS,MAAM,CAAA;AAAA,IACvB,SAAA,EAAW,SAAS,SAAS,CAAA;AAAA,IAC7B,KAAA,EAAO,SAAS,KAAK,CAAA;AAAA,IACrB,YAAA,EAAc,SAAS,YAAY,CAAA;AAAA,IACnC,UAAA,EAAY,SAAS,UAAU,CAAA;AAAA,IAC/B,IAAA;AAAA,IACA,KAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF;AACF;ACzEO,SAAS,YAAY,QAAA,EAAsC;AAEhE,EAAA,MAAM,gBAAA,GAAmBC,MAAAA,CAAO,aAAA,EAAe,IAAI,CAAA;AACnD,EAAA,MAAM,eAAA,GAAkBA,MAAAA,CAAO,qBAAA,EAAuB,IAAI,CAAA;AAG1D,EAAA,MAAM,QAAA,GAAWC,IAA8B,IAAI,CAAA;AACnD,EAAA,MAAM,OAAA,GAAUA,IAAI,KAAK,CAAA;AAGzB,EAAA,MAAM,YAAA,GAAeA,IAAmB,IAAI,CAAA;AAC5C,EAAA,MAAM,SAAA,GAAYA,IAAmB,IAAI,CAAA;AACzC,EAAA,MAAM,YAAA,GAAeA,IAAI,KAAK,CAAA;AAC9B,EAAA,MAAM,KAAA,GAAQA,IAAkB,IAAI,CAAA;AAGpC,EAAA,IAAI,YAAA,GAAe,KAAA;AACnB,EAAA,IAAI,WAAA,GAAmC,IAAA;AAKvC,EAAA,MAAM,YAAY,MAAM;AACtB,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,EAAO,WAAA,EAAY;AAC1C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,OAAA,CAAQ,QAAQ,KAAA,CAAM,OAAA;AAAA,IACxB;AAAA,EACF,CAAA;AAEA,EAAAC,UAAU,MAAM;AAEd,IAAA,IAAI,gBAAA,IAAoB,CAAC,QAAA,EAAU;AACjC,MAAA,QAAA,CAAS,KAAA,GAAQ,gBAAA;AAAA,IACnB,CAAA,MAAO;AAEL,MAAA,MAAM,iBAAA,GAAoB,YAAY,eAAA,EAAiB,QAAA;AAEvD,MAAA,IAAI,CAAC,iBAAA,EAAmB;AACtB,QAAA,OAAA,CAAQ,KAAA;AAAA,UACN;AAAA,SAEF;AACA,QAAA;AAAA,MACF;AAEA,MAAA,QAAA,CAAS,KAAA,GAAQH,UAAU,IAAA,CAAK;AAAA,QAC9B,QAAA,EAAU,iBAAA;AAAA,QACV,YAAY,eAAA,EAAiB,UAAA;AAAA,QAC7B,QAAQ,eAAA,EAAiB,MAAA;AAAA,QACzB,QAAA,EAAU;AAAA;AAAA,OACX,CAAA;AACD,MAAA,YAAA,GAAe,IAAA;AAAA,IACjB;AAGA,IAAA,IAAI,SAAS,KAAA,EAAO;AAClB,MAAA,WAAA,GAAc,QAAA,CAAS,KAAA,CAAM,SAAA,CAAU,SAAS,CAAA;AAChD,MAAA,SAAA,EAAU;AAAA,IACZ;AAAA,EACF,CAAC,CAAA;AAED,EAAAI,YAAY,MAAM;AAChB,IAAA,WAAA,IAAc;AACd,IAAA,IAAI,YAAA,IAAgB,SAAS,KAAA,EAAO;AAClC,MAAA,QAAA,CAAS,MAAM,OAAA,EAAQ;AAAA,IACzB;AACA,IAAA,QAAA,CAAS,KAAA,GAAQ,IAAA;AAAA,EACnB,CAAC,CAAA;AAGD,EAAA,MAAM,OAAA,GAAU,SAAkC,MAAM;AACtD,IAAA,IAAI,CAAC,QAAA,CAAS,KAAA,IAAS,CAAC,OAAA,CAAQ,OAAO,OAAO,IAAA;AAC9C,IAAA,OAAO,QAAA,CAAS,MAAM,kBAAA,EAAmB;AAAA,EAC3C,CAAC,CAAA;AAGD,EAAA,MAAM,gBAAA,GAAmB,SAAS,MAAM;AACtC,IAAA,OAAO,QAAA,CAAS,KAAA,EAAO,UAAA,EAAW,IAAK,KAAA;AAAA,EACzC,CAAC,CAAA;AAGD,EAAA,MAAM,cAAA,GAAiB,SAAS,MAAM;AACpC,IAAA,IAAI,CAAC,QAAA,CAAS,KAAA,IAAS,CAAC,OAAA,CAAQ,OAAO,OAAO,IAAA;AAG9C,IAAA,OAAQ,QAAA,CAAS,KAAA,CAAc,aAAA,EAAe,MAAA,IAAU,IAAA;AAAA,EAC1D,CAAC,CAAA;AAED,EAAA,MAAM,UAAA,GAAa,SAAS,MAAM;AAChC,IAAA,OAAO,cAAA,CAAe,OAAO,UAAA,IAAc,IAAA;AAAA,EAC7C,CAAC,CAAA;AAED,EAAA,MAAM,UAAA,GAAa,SAAqB,MAAM;AAC5C,IAAA,OAAO,cAAA,CAAe,OAAO,UAAA,IAAc,IAAA;AAAA,EAC7C,CAAC,CAAA;AAED,EAAA,MAAM,eAAA,GAAkB,SAA0B,MAAM;AACtD,IAAA,OAAO,cAAA,CAAe,OAAO,eAAA,IAAmB,UAAA;AAAA,EAClD,CAAC,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,SAAuC,MAAM;AAC5D,IAAA,OAAO,eAAe,KAAA,EAAO,QAAA;AAAA,EAC/B,CAAC,CAAA;AAGD,EAAA,MAAM,OAAA,GAAU,SAA0B,MAAM;AAC9C,IAAA,MAAM,cAAA,GAAkC;AAAA,MACtC,YAAA,EAAc,SAAA;AAAA,MACd,eAAA,EAAiB,SAAA;AAAA,MACjB,SAAA,EAAW,SAAA;AAAA,MACX,eAAA,EAAiB,SAAA;AAAA,MACjB,WAAA,EAAa,SAAA;AAAA,MACb,WAAA,EAAa,GAAA;AAAA,MACb,YAAA,EAAc;AAAA,KAChB;AAEA,IAAA,IAAI,CAAC,QAAA,CAAS,KAAA,IAAS,CAAC,QAAQ,KAAA,EAAO;AACrC,MAAA,OAAO,cAAA;AAAA,IACT;AAIA,IAAA,MAAM,YAAA,GAAgB,SAAS,KAAA,CAAc,aAAA;AAC7C,IAAA,IAAI,CAAC,cAAc,OAAA,EAAS;AAC1B,MAAA,OAAO,cAAA;AAAA,IACT;AAIA,IAAA,MAAM,gBAAgB,YAAA,CAAa,OAAA;AACnC,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,aAAA,CAAc,YAAA,IAAgB,cAAA,CAAe,YAAA;AAAA,MAC3D,eAAA,EAAiB,aAAA,CAAc,eAAA,IAAmB,cAAA,CAAe,eAAA;AAAA,MACjE,SAAA,EAAW,aAAA,CAAc,SAAA,IAAa,cAAA,CAAe,SAAA;AAAA,MACrD,eAAA,EAAiB,aAAA,CAAc,eAAA,IAAmB,cAAA,CAAe,eAAA;AAAA,MACjE,WAAA,EAAa,aAAA,CAAc,WAAA,IAAe,cAAA,CAAe,WAAA;AAAA,MACzD,WAAA,EAAa,aAAA,CAAc,WAAA,IAAe,cAAA,CAAe,WAAA;AAAA,MACzD,YAAA,EAAc,aAAA,CAAc,YAAA,IAAgB,cAAA,CAAe;AAAA,KAC7D;AAAA,EACF,CAAC,CAAA;AAKD,EAAA,MAAM,kBAAA,GAAqB,CAAC,WAAA,KAAiC;AAC3D,IAAA,IAAI,eAAA,CAAgB,KAAA,KAAU,MAAA,EAAQ,OAAO,KAAA;AAC7C,IAAA,IAAI,eAAA,CAAgB,KAAA,KAAU,KAAA,EAAO,OAAO,IAAA;AAE5C,IAAA,IAAI,QAAA,CAAS,KAAA,IAAS,oBAAA,CAAqB,QAAA,CAAS,KAAK,CAAA,EAAG;AAC1D,MAAA,OAAO,oBAAA,CAAqB,QAAA,CAAS,KAAK,CAAA,CAAE,SAAS,WAAW,CAAA;AAAA,IAClE;AAEA,IAAA,MAAM,MAAA,GAAS,QAAQ,KAAA,EAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,WAAW,CAAA;AACjE,IAAA,OAAO,QAAQ,YAAA,IAAgB,KAAA;AAAA,EACjC,CAAA;AAKA,EAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,EAAe,QAAA,KAAqC;AACvE,IAAA,IAAI,CAAC,SAAS,KAAA,EAAO;AACnB,MAAA,MAAM,IAAI,MAAM,2BAA2B,CAAA;AAAA,IAC7C;AAEA,IAAA,YAAA,CAAa,KAAA,GAAQ,IAAA;AACrB,IAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AAEd,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,CAAS,MAAM,KAAA,CAAM,KAAA,EAAO,WAAW,EAAE,QAAA,KAAa,KAAA,CAAS,CAAA;AACrE,MAAA,SAAA,CAAU,KAAA,GAAQ,KAAA;AAClB,MAAA,YAAA,CAAa,KAAA,GAAQ,IAAA;AAAA,IACvB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,aAAA,GAAgB,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AACxE,MAAA,KAAA,CAAM,KAAA,GAAQ,aAAA;AACd,MAAA,MAAM,aAAA;AAAA,IACR,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAA,GAAQ,KAAA;AAAA,IACvB;AAAA,EACF,CAAA;AAKA,EAAA,MAAM,eAAA,GAAkB,CAAC,KAAA,KAA+B;AACtD,IAAA,YAAA,CAAa,KAAA,GAAQ,KAAA;AAAA,EACvB,CAAA;AAKA,EAAA,MAAM,iBAAiB,MAAY;AACjC,IAAA,SAAA,CAAU,KAAA,GAAQ,IAAA;AAClB,IAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AAAA,EAChB,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,YAAA,EAAcC,SAAS,YAAY,CAAA;AAAA,IACnC,SAAA,EAAWA,SAAS,SAAS,CAAA;AAAA,IAC7B,KAAA,EAAOA,SAAS,KAAK,CAAA;AAAA,IACrB,YAAA,EAAcA,SAAS,YAAY,CAAA;AAAA,IACnC,KAAA;AAAA,IACA,eAAA;AAAA,IACA,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,OAAA,EAASA,SAAS,OAAO,CAAA;AAAA,IACzB,UAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACF;AACF;AC/TA,IAAM,eAAA,GAAwD;AAAA,EAC5D,IAAA,EAAM,QAAA;AAAA,EACN,EAAA,EAAI,MAAA;AAAA,EACJ,EAAA,EAAI,KAAA;AAAA,EACJ,EAAA,EAAI,KAAA;AAAA,EACJ,IAAA,EAAM;AACR,CAAA;AAKA,IAAM,cAAA,GAAsD;AAAA,EAC1D,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK;AACP,CAAA;AAKA,IAAM,UAAA,GAAkI;AAAA,EACtI,EAAA,EAAI;AAAA,IACF,QAAQ,EAAE,OAAA,EAAS,oBAAoB,QAAA,EAAU,SAAA,EAAW,KAAK,UAAA,EAAW;AAAA,IAC5E,IAAA,EAAM,EAAE,QAAA,EAAU,MAAA,EAAO;AAAA,IACzB,KAAA,EAAO,EAAE,QAAA,EAAU,SAAA;AAAU,GAC/B;AAAA,EACA,EAAA,EAAI;AAAA,IACF,QAAQ,EAAE,OAAA,EAAS,eAAe,QAAA,EAAU,UAAA,EAAY,KAAK,QAAA,EAAS;AAAA,IACtE,IAAA,EAAM,EAAE,QAAA,EAAU,UAAA,EAAW;AAAA,IAC7B,KAAA,EAAO,EAAE,QAAA,EAAU,UAAA;AAAW,GAChC;AAAA,EACA,EAAA,EAAI;AAAA,IACF,QAAQ,EAAE,OAAA,EAAS,mBAAmB,QAAA,EAAU,MAAA,EAAQ,KAAK,UAAA,EAAW;AAAA,IACxE,IAAA,EAAM,EAAE,QAAA,EAAU,QAAA,EAAS;AAAA,IAC3B,KAAA,EAAO,EAAE,QAAA,EAAU,MAAA;AAAO;AAE9B,CAAA;AAKA,IAAM,MAAA,GAAS;AAAA,EACb,SAAA,EAAW;AAAA,IACT,OAAA,EAAS,MAAA;AAAA,IACT,aAAA,EAAe,QAAA;AAAA,IACf,GAAA,EAAK,SAAA;AAAA,IACL,UAAA,EAAY;AAAA,GACd;AAAA,EACA,WAAA,EAAa;AAAA,IACX,OAAA,EAAS,MAAA;AAAA,IACT,QAAA,EAAU,MAAA;AAAA,IACV,GAAA,EAAK;AAAA,GACP;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,OAAA,EAAS,aAAA;AAAA,IACT,UAAA,EAAY,QAAA;AAAA,IACZ,UAAA,EAAY,KAAA;AAAA,IACZ,KAAA,EAAO,SAAA;AAAA,IACP,eAAA,EAAiB,SAAA;AAAA,IACjB,MAAA,EAAQ,mBAAA;AAAA,IACR,YAAA,EAAc,QAAA;AAAA,IACd,MAAA,EAAQ,SAAA;AAAA,IACR,UAAA,EAAY;AAAA,GACd;AAAA,EAMA,cAAA,EAAgB;AAAA,IACd,OAAA,EAAS,GAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,MAAM,EAAC;AAAA,EACP,QAAA,EAAU;AAAA,IACR,OAAA,EAAS,MAAA;AAAA,IACT,aAAA,EAAe,QAAA;AAAA,IACf,GAAA,EAAK,QAAA;AAAA,IACL,OAAA,EAAS,SAAA;AAAA,IACT,eAAA,EAAiB,SAAA;AAAA,IACjB,MAAA,EAAQ,mBAAA;AAAA,IACR,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,KAAA,EAAO;AAAA,IACL,KAAA,EAAO,MAAA;AAAA,IACP,OAAA,EAAS,gBAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,mBAAA;AAAA,IACR,YAAA,EAAc,UAAA;AAAA,IACd,eAAA,EAAiB,SAAA;AAAA,IACjB,SAAA,EAAW;AAAA,GACb;AAAA,EACA,OAAA,EAAS;AAAA,IACP,OAAA,EAAS,MAAA;AAAA,IACT,GAAA,EAAK,QAAA;AAAA,IACL,cAAA,EAAgB;AAAA,GAClB;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,OAAA,EAAS,kBAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,UAAA,EAAY,KAAA;AAAA,IACZ,KAAA,EAAO,SAAA;AAAA,IACP,eAAA,EAAiB,SAAA;AAAA,IACjB,MAAA,EAAQ,MAAA;AAAA,IACR,YAAA,EAAc,UAAA;AAAA,IACd,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,OAAA,EAAS,kBAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,KAAA,EAAO,SAAA;AAAA,IACP,UAAA,EAAY,MAAA;AAAA,IACZ,MAAA,EAAQ,MAAA;AAAA,IACR,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,QAAA,EAAU;AAAA,IACR,OAAA,EAAS,MAAA;AAAA,IACT,UAAA,EAAY,QAAA;AAAA,IACZ,GAAA,EAAK,QAAA;AAAA,IACL,OAAA,EAAS,cAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,KAAA,EAAO,SAAA;AAAA,IACP,eAAA,EAAiB,SAAA;AAAA,IACjB,MAAA,EAAQ,mBAAA;AAAA,IACR,YAAA,EAAc;AAAA,GAChB;AAAA,EACA,WAAA,EAAa;AAAA,IACX,OAAA,EAAS,gBAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,KAAA,EAAO,SAAA;AAAA,IACP,UAAA,EAAY,MAAA;AAAA,IACZ,MAAA,EAAQ,MAAA;AAAA,IACR,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,KAAA,EAAO;AAAA,IACL,OAAA,EAAS,gBAAA;AAAA,IACT,QAAA,EAAU,UAAA;AAAA,IACV,KAAA,EAAO,SAAA;AAAA,IACP,eAAA,EAAiB,SAAA;AAAA,IACjB,MAAA,EAAQ,mBAAA;AAAA,IACR,YAAA,EAAc;AAAA;AAElB,CAAA;AAsBO,IAAM,kBAAkB,eAAA,CAAgB;AAAA,EAC7C,IAAA,EAAM,iBAAA;AAAA,EAEN,KAAA,EAAO;AAAA;AAAA,IAEL,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACX;AAAA;AAAA,IAEA,eAAA,EAAiB;AAAA,MACf,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACX;AAAA;AAAA,IAEA,cAAA,EAAgB;AAAA,MACd,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA,KACX;AAAA;AAAA,IAEA,WAAA,EAAa;AAAA,MACX,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS;AAAA;AACX,GACF;AAAA,EAEA,KAAA,EAAO;AAAA;AAAA,IAEL,KAAA,EAAO,CAAC,KAAA,EAAe,SAAA,KAAuB,OAAO,KAAA,KAAU;AAAA,GACjE;AAAA,EAEA,KAAA,CAAM,KAAA,EAAO,EAAE,IAAA,EAAK,EAAG;AACrB,IAAA,MAAM;AAAA,MACJ,OAAA;AAAA,MACA,KAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA;AAAA,MACA,KAAA;AAAA,MACA,YAAA;AAAA,MACA,eAAA;AAAA,MACA,cAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAA;AAAA,MACA,UAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA,KACF,GAAI,WAAA,CAAY,KAAA,CAAM,QAAQ,CAAA;AAG9B,IAAA,MAAM,YAAA,GAAeH,IAAI,EAAE,CAAA;AAG3B,IAAA,MAAM,iBAAA,GAAoBI,SAAgC,MAAM;AAC9D,MAAA,IAAI,CAAC,YAAA,CAAa,KAAA,IAAS,CAAC,OAAA,CAAQ,OAAO,OAAO,IAAA;AAClD,MAAA,OAAO,OAAA,CAAQ,MAAM,IAAA,CAAK,CAAC,QAAQ,GAAA,CAAI,KAAA,KAAU,YAAA,CAAa,KAAK,CAAA,IAAK,IAAA;AAAA,IAC1E,CAAC,CAAA;AAKD,IAAA,MAAM,iBAAA,GAAoB,CAAC,MAAA,KAA2B;AACpD,MAAA,IAAI,kBAAA,CAAmB,MAAA,CAAO,KAAK,CAAA,EAAG;AACpC,QAAA,eAAA,CAAgB,OAAO,KAAK,CAAA;AAAA,MAC9B,CAAA,MAAO;AACL,QAAA,cAAA,CAAe,OAAO,KAAK,CAAA;AAAA,MAC7B;AAAA,IACF,CAAA;AAKA,IAAA,MAAM,cAAA,GAAiB,OAAO,KAAA,EAAe,QAAA,KAAsB;AACjE,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,CAAM,OAAO,QAAQ,CAAA;AAC3B,QAAA,IAAA,CAAK,OAAA,EAAS,OAAO,QAAQ,CAAA;AAAA,MAC/B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAA;AAKA,IAAA,MAAM,oBAAA,GAAuB,CAAC,CAAA,KAAa;AACzC,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,IAAI,aAAa,KAAA,EAAO;AACtB,QAAA,cAAA,CAAe,YAAA,CAAa,KAAA,EAAO,YAAA,CAAa,KAAA,IAAS,MAAS,CAAA;AAClE,QAAA,YAAA,CAAa,KAAA,GAAQ,EAAA;AAAA,MACvB;AAAA,IACF,CAAA;AAKA,IAAA,MAAM,iBAAiB,MAAM;AAC3B,MAAA,eAAA,CAAgB,IAAI,CAAA;AACpB,MAAA,YAAA,CAAa,KAAA,GAAQ,EAAA;AAAA,IACvB,CAAA;AAEA,IAAA,OAAO,MAAM;AAEX,MAAA,IAAI,CAAC,OAAA,CAAQ,KAAA,IAAS,CAAC,QAAQ,KAAA,EAAO;AACpC,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,IAAI,UAAU,KAAA,EAAO;AACnB,QAAA,MAAMC,kBAAiB,OAAA,CAAQ,KAAA;AAC/B,QAAA,OAAO,CAAA;AAAA,UACL,KAAA;AAAA,UACA;AAAA,YACE,OAAO,KAAA,CAAM,cAAA;AAAA,YACb,KAAA,EAAO;AAAA,cACL,GAAG,MAAA,CAAO,QAAA;AAAA,cACV,KAAA,EAAOA,gBAAe,YAAA,IAAgB;AAAA;AACxC,WACF;AAAA,UACA;AAAA,YACE,CAAA,CAAE,MAAA,EAAQ,KAAA,CAAM,eAAA,IAAmB,2BAA2B,CAAA;AAAA,YAC9D,CAAA;AAAA,cACE,QAAA;AAAA,cACA;AAAA,gBACE,IAAA,EAAM,QAAA;AAAA,gBACN,OAAO,MAAA,CAAO,WAAA;AAAA,gBACd,OAAA,EAAS,cAAA;AAAA,gBACT,YAAA,EAAc;AAAA,eAChB;AAAA,cACA;AAAA;AACF;AACF,SACF;AAAA,MACF;AAGA,MAAA,MAAM,iBAAA,GAAoB,UAAA,CAAW,UAAA,CAAW,KAAK,KAAK,UAAA,CAAW,EAAA;AACrE,MAAA,MAAM,iBAAiB,OAAA,CAAQ,KAAA;AAC/B,MAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,cAAA,CAAe,YAAA,IAAgB,MAAM,CAAA,IAAK,QAAA;AAC/E,MAAA,MAAM,WAAA,GAAc,cAAA,CAAe,cAAA,CAAe,WAAA,IAAe,GAAG,CAAA,IAAK,KAAA;AAEzE,MAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,KAAW;AACnD,QAAA,MAAM,QAAA,GAAW,YAAA,CAAa,KAAA,KAAU,MAAA,CAAO,KAAA;AAC/C,QAAA,MAAM,QAAA,GAAW;AAAA,UACf,EAAE,MAAA,EAAQ,EAAE,KAAA,EAAO,EAAE,GAAG,MAAA,CAAO,IAAA,EAAM,GAAG,iBAAA,CAAkB,MAAK,EAAG,aAAA,EAAe,MAAA,EAAO,EAAG,OAAO,IAAI;AAAA,SACxG;AACA,QAAA,IAAI,WAAW,KAAA,EAAO;AACpB,UAAA,QAAA,CAAS,KAAK,CAAA,CAAE,MAAA,EAAQ,EAAE,KAAA,EAAO,EAAE,GAAG,iBAAA,CAAkB,KAAA,EAAO,KAAA,EAAO,eAAe,eAAA,IAAmB,SAAA,IAAY,EAAG,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,QACtI;AAEA,QAAA,OAAO,CAAA;AAAA,UACL,QAAA;AAAA,UACA;AAAA,YACE,KAAK,MAAA,CAAO,KAAA;AAAA,YACZ,IAAA,EAAM,QAAA;AAAA,YACN,OAAO,KAAA,CAAM,WAAA;AAAA,YACb,KAAA,EAAO;AAAA,cACL,GAAG,MAAA,CAAO,MAAA;AAAA,cACV,GAAG,iBAAA,CAAkB,MAAA;AAAA,cACrB,eAAA,EAAiB,eAAe,eAAA,IAAmB,SAAA;AAAA,cACnD,aAAa,QAAA,GAAY,cAAA,CAAe,YAAA,IAAgB,SAAA,GAAc,eAAe,WAAA,IAAe,SAAA;AAAA,cACpG,WAAA;AAAA,cACA,YAAA;AAAA,cACA,KAAA,EAAO,eAAe,eAAA,IAAmB,SAAA;AAAA,cACzC,GAAI,QAAA,GAAW;AAAA,gBACb,eAAA,EAAiB,CAAA,EAAG,cAAA,CAAe,YAAA,IAAgB,SAAS,CAAA,EAAA;AAAA,kBAC1D,EAAC;AAAA,cACL,GAAI,YAAA,CAAa,KAAA,GAAQ,MAAA,CAAO,iBAAiB;AAAC,aACpD;AAAA,YACA,UAAU,YAAA,CAAa,KAAA;AAAA,YACvB,cAAA,EAAgB,QAAA;AAAA,YAChB,cAAc,MAAA,CAAO,KAAA;AAAA,YACrB,OAAA,EAAS,MAAM,iBAAA,CAAkB,MAAM;AAAA,WACzC;AAAA,UACA;AAAA,SACF;AAAA,MACF,CAAC,CAAA;AAGD,MAAA,IAAI,YAAA,GAAe,IAAA;AACnB,MAAA,MAAM,iBAAiB,iBAAA,CAAkB,KAAA;AACzC,MAAA,IAAI,YAAA,CAAa,SAAS,cAAA,EAAgB;AACxC,QAAA,YAAA,GAAe,CAAA;AAAA,UACb,MAAA;AAAA,UACA;AAAA,YACE,OAAO,MAAA,CAAO,QAAA;AAAA,YACd,QAAA,EAAU;AAAA,WACZ;AAAA,UACA;AAAA,YACE,EAAE,OAAA,EAAS;AAAA,cACT,IAAA,EAAM,MAAA;AAAA,cACN,OAAO,MAAA,CAAO,KAAA;AAAA,cACd,OAAO,YAAA,CAAa,KAAA;AAAA,cACpB,WAAA,EAAa,eAAe,mBAAA,IAAuB,iBAAA;AAAA,cACnD,UAAU,YAAA,CAAa,KAAA;AAAA,cACvB,SAAA,EAAW,GAAA;AAAA,cACX,OAAA,EAAS,CAAC,CAAA,KAAa;AACrB,gBAAA,YAAA,CAAa,KAAA,GAAS,EAAE,MAAA,CAA4B,KAAA;AAAA,cACtD;AAAA,aACD,CAAA;AAAA,YACD,CAAA,CAAE,KAAA,EAAO,EAAE,KAAA,EAAO,EAAE,GAAG,MAAA,CAAO,OAAA,EAAS,cAAA,EAAgB,QAAA,EAAS,EAAE,EAAG;AAAA,cACnE,CAAA;AAAA,gBACE,QAAA;AAAA,gBACA;AAAA,kBACE,IAAA,EAAM,QAAA;AAAA,kBACN,KAAA,EAAO;AAAA,oBACL,GAAG,MAAA,CAAO,YAAA;AAAA,oBACV,eAAA,EAAiB,eAAe,YAAA,IAAgB,SAAA;AAAA,oBAChD,YAAA;AAAA,oBACA,GAAI,YAAA,CAAa,KAAA,GAAQ,MAAA,CAAO,iBAAiB;AAAC,mBACpD;AAAA,kBACA,UAAU,YAAA,CAAa;AAAA,iBACzB;AAAA,gBACA,YAAA,CAAa,QAAQ,YAAA,GAAe;AAAA,eACtC;AAAA,cACA,CAAA;AAAA,gBACE,QAAA;AAAA,gBACA;AAAA,kBACE,IAAA,EAAM,QAAA;AAAA,kBACN,KAAA,EAAO;AAAA,oBACL,GAAG,MAAA,CAAO,YAAA;AAAA,oBACV,eAAA,EAAiB,eAAe,eAAA,IAAmB,SAAA;AAAA,oBACnD,KAAA,EAAO,eAAe,eAAA,IAAmB,SAAA;AAAA,oBACzC,YAAA;AAAA,oBACA,QAAQ,CAAA,EAAG,WAAW,CAAA,OAAA,EAAU,cAAA,CAAe,eAAe,SAAS,CAAA;AAAA,mBACzE;AAAA,kBACA,UAAU,YAAA,CAAa,KAAA;AAAA,kBACvB,OAAA,EAAS;AAAA,iBACX;AAAA,gBACA;AAAA;AACF,aACD;AAAA;AACH,SACF;AAAA,MACF;AAGA,MAAA,IAAI,YAAA,GAAe,IAAA;AACnB,MAAA,IAAI,MAAM,KAAA,EAAO;AACf,QAAA,YAAA,GAAe,CAAA;AAAA,UACb,KAAA;AAAA,UACA,EAAE,KAAA,EAAO,MAAA,CAAO,KAAA,EAAO,MAAM,OAAA,EAAQ;AAAA,UACrC,MAAM,KAAA,CAAM;AAAA,SACd;AAAA,MACF;AAGA,MAAA,OAAO,CAAA;AAAA,QACL,KAAA;AAAA,QACA;AAAA,UACE,OAAO,KAAA,CAAM,cAAA;AAAA,UACb,OAAO,MAAA,CAAO,SAAA;AAAA,UACd,IAAA,EAAM,OAAA;AAAA,UACN,YAAA,EAAc;AAAA,SAChB;AAAA,QACA;AAAA,UACE,CAAA,CAAE,OAAO,EAAE,KAAA,EAAO,OAAO,WAAA,EAAa,IAAA,EAAM,YAAA,EAAa,EAAG,cAAc,CAAA;AAAA,UAC1E,YAAA;AAAA,UACA;AAAA;AACF,OACF;AAAA,IACF,CAAA;AAAA,EACF;AACF,CAAC","file":"index.js","sourcesContent":["/**\n * @feedvalue/vue - Plugin\n *\n * Vue plugin for FeedValue. Provides app-level configuration\n * and automatic initialization.\n */\n\nimport type { App, InjectionKey } from 'vue';\nimport { FeedValue, type FeedValueConfig, type FeedValueInstance } from '@feedvalue/core';\n\n/**\n * Plugin options\n */\nexport interface FeedValuePluginOptions {\n /** Widget ID from FeedValue dashboard */\n widgetId: string;\n /** API base URL (for self-hosted) */\n apiBaseUrl?: string;\n /** Configuration overrides */\n config?: Partial<FeedValueConfig>;\n /**\n * Headless mode - disables all DOM rendering.\n * Use this when you want full control over the UI.\n * The SDK will still fetch config and provide all API methods\n * but won't render any trigger button or modal.\n *\n * @default false\n */\n headless?: boolean;\n}\n\n/**\n * Injection key for FeedValue instance\n */\nexport const FEEDVALUE_KEY: InjectionKey<FeedValueInstance> = Symbol('feedvalue');\n\n/**\n * Injection key for widget ID (used by useFeedValue when no instance is injected)\n */\nexport const FEEDVALUE_OPTIONS_KEY: InjectionKey<FeedValuePluginOptions> = Symbol('feedvalue-options');\n\n/**\n * Create FeedValue Vue plugin\n *\n * @example\n * ```ts\n * // main.ts\n * import { createApp } from 'vue';\n * import { createFeedValue } from '@feedvalue/vue';\n * import App from './App.vue';\n *\n * const app = createApp(App);\n *\n * app.use(createFeedValue({\n * widgetId: 'your-widget-id',\n * config: { theme: 'dark' }\n * }));\n *\n * app.mount('#app');\n * ```\n */\nexport function createFeedValue(options: FeedValuePluginOptions) {\n let instance: FeedValueInstance | null = null;\n\n return {\n install(app: App) {\n // Only initialize on client side\n if (typeof window !== 'undefined') {\n instance = FeedValue.init({\n widgetId: options.widgetId,\n apiBaseUrl: options.apiBaseUrl,\n config: options.config,\n headless: options.headless,\n });\n\n // Provide instance to all components\n app.provide(FEEDVALUE_KEY, instance);\n\n // Also provide to global properties for Options API access\n app.config.globalProperties.$feedvalue = instance;\n }\n\n // Always provide options (for SSR where we don't initialize)\n app.provide(FEEDVALUE_OPTIONS_KEY, options);\n },\n };\n}\n\n/**\n * Type augmentation for global properties\n */\ndeclare module 'vue' {\n interface ComponentCustomProperties {\n $feedvalue: FeedValueInstance | undefined;\n }\n}\n","/**\n * @feedvalue/vue - Composables\n *\n * Vue composables for FeedValue. Provides reactive state and methods.\n */\n\nimport {\n ref,\n shallowRef,\n readonly,\n onMounted,\n onUnmounted,\n inject,\n type Ref,\n type ShallowRef,\n} from 'vue';\nimport {\n FeedValue,\n type FeedValueConfig,\n type FeedValueInstance,\n type FeedbackData,\n type UserTraits,\n} from '@feedvalue/core';\nimport { FEEDVALUE_KEY, FEEDVALUE_OPTIONS_KEY } from './plugin';\n\n/**\n * Return type for useFeedValue composable\n */\nexport interface UseFeedValueReturn {\n /** FeedValue instance (for advanced usage) */\n instance: Readonly<ShallowRef<FeedValueInstance | null>>;\n /** Widget is ready */\n isReady: Readonly<Ref<boolean>>;\n /** Modal is open */\n isOpen: Readonly<Ref<boolean>>;\n /** Widget is visible */\n isVisible: Readonly<Ref<boolean>>;\n /** Current error */\n error: Readonly<Ref<Error | null>>;\n /** Submission in progress */\n isSubmitting: Readonly<Ref<boolean>>;\n /** Running in headless mode (no default UI rendered) */\n isHeadless: Readonly<Ref<boolean>>;\n /** Open the feedback modal */\n open: () => void;\n /** Close the feedback modal */\n close: () => void;\n /** Toggle the feedback modal */\n toggle: () => void;\n /** Show the trigger button */\n show: () => void;\n /** Hide the trigger button */\n hide: () => void;\n /** Submit feedback programmatically */\n submit: (feedback: Partial<FeedbackData>) => Promise<void>;\n /** Identify user */\n identify: (userId: string, traits?: UserTraits) => void;\n /** Set user data */\n setData: (data: Record<string, string>) => void;\n /** Reset user data */\n reset: () => void;\n}\n\n/**\n * FeedValue composable\n *\n * Can be used with or without plugin. If plugin is installed, uses the\n * provided instance. Otherwise, creates a new instance.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useFeedValue } from '@feedvalue/vue';\n *\n * // With plugin installed\n * const { open, isReady } = useFeedValue();\n *\n * // Or standalone with widgetId\n * const { open, isReady } = useFeedValue('your-widget-id');\n * </script>\n *\n * <template>\n * <button @click=\"open\" :disabled=\"!isReady\">\n * Give Feedback\n * </button>\n * </template>\n * ```\n */\nexport function useFeedValue(\n widgetId?: string,\n config?: Partial<FeedValueConfig>\n): UseFeedValueReturn {\n // Try to inject instance from plugin\n const injectedInstance = inject(FEEDVALUE_KEY, null);\n const injectedOptions = inject(FEEDVALUE_OPTIONS_KEY, null);\n\n // Refs for reactive state\n const instance = shallowRef<FeedValueInstance | null>(null);\n const isReady = ref(false);\n const isOpen = ref(false);\n const isVisible = ref(false);\n const error = ref<Error | null>(null);\n const isSubmitting = ref(false);\n const isHeadless = ref(false);\n\n // Track if we own the instance (need to destroy on unmount)\n let ownsInstance = false;\n let unsubscribe: (() => void) | null = null;\n\n /**\n * Sync reactive state from instance\n */\n const syncState = () => {\n const state = instance.value?.getSnapshot();\n if (state) {\n isReady.value = state.isReady;\n isOpen.value = state.isOpen;\n isVisible.value = state.isVisible;\n error.value = state.error;\n isSubmitting.value = state.isSubmitting;\n }\n };\n\n onMounted(() => {\n // Use injected instance if available and no widgetId override\n if (injectedInstance && !widgetId) {\n instance.value = injectedInstance;\n isHeadless.value = injectedInstance.isHeadless();\n } else {\n // Create new instance\n const effectiveWidgetId = widgetId ?? injectedOptions?.widgetId;\n\n if (!effectiveWidgetId) {\n console.error(\n '[FeedValue] No widgetId provided. Either install the plugin with createFeedValue() ' +\n 'or pass widgetId to useFeedValue().'\n );\n return;\n }\n\n instance.value = FeedValue.init({\n widgetId: effectiveWidgetId,\n apiBaseUrl: injectedOptions?.apiBaseUrl,\n config: config ?? injectedOptions?.config,\n headless: injectedOptions?.headless,\n });\n ownsInstance = true;\n }\n\n // Subscribe to state changes\n if (instance.value) {\n unsubscribe = instance.value.subscribe(syncState);\n isHeadless.value = instance.value.isHeadless();\n syncState(); // Initial sync\n }\n });\n\n onUnmounted(() => {\n unsubscribe?.();\n if (ownsInstance && instance.value) {\n instance.value.destroy();\n }\n instance.value = null;\n });\n\n // Methods that delegate to instance\n const open = () => instance.value?.open();\n const close = () => instance.value?.close();\n const toggle = () => instance.value?.toggle();\n const show = () => instance.value?.show();\n const hide = () => instance.value?.hide();\n const submit = (feedback: Partial<FeedbackData>) =>\n instance.value?.submit(feedback) ?? Promise.reject(new Error('Not initialized'));\n const identify = (userId: string, traits?: UserTraits) =>\n instance.value?.identify(userId, traits);\n const setData = (data: Record<string, string>) => instance.value?.setData(data);\n const reset = () => instance.value?.reset();\n\n return {\n instance: readonly(instance),\n isReady: readonly(isReady),\n isOpen: readonly(isOpen),\n isVisible: readonly(isVisible),\n error: readonly(error),\n isSubmitting: readonly(isSubmitting),\n isHeadless: readonly(isHeadless),\n open,\n close,\n toggle,\n show,\n hide,\n submit,\n identify,\n setData,\n reset,\n };\n}\n","/**\n * @feedvalue/vue - useReaction Composable\n *\n * Composable for reaction widgets in Vue applications.\n * Provides a simple API for submitting reactions.\n */\n\nimport {\n ref,\n computed,\n readonly,\n onMounted,\n onUnmounted,\n inject,\n type Ref,\n type ComputedRef,\n} from 'vue';\nimport {\n FeedValue,\n NEGATIVE_OPTIONS_MAP,\n type ReactionOption,\n type FeedValueInstance,\n type ButtonSize,\n type FollowUpTrigger,\n type ReactionTemplate,\n type ReactionStyling,\n} from '@feedvalue/core';\nimport { FEEDVALUE_KEY, FEEDVALUE_OPTIONS_KEY } from './plugin';\n\n/**\n * Return type for useReaction composable\n */\nexport interface UseReactionReturn {\n /** Available reaction options */\n options: ComputedRef<ReactionOption[] | null>;\n /** Currently submitting */\n isSubmitting: Readonly<Ref<boolean>>;\n /** Successfully submitted value (null if not yet submitted) */\n submitted: Readonly<Ref<string | null>>;\n /** Error if submission failed */\n error: Readonly<Ref<Error | null>>;\n /** Option value requiring follow-up input (null if none) */\n showFollowUp: Readonly<Ref<string | null>>;\n /** Submit a reaction */\n react: (value: string, followUp?: string) => Promise<void>;\n /** Set which option is showing follow-up input */\n setShowFollowUp: (value: string | null) => void;\n /** Clear the submitted state to allow re-submission */\n clearSubmitted: () => void;\n /** Check if widget is a reaction type */\n isReactionWidget: ComputedRef<boolean>;\n /** Widget configuration is ready */\n isReady: Readonly<Ref<boolean>>;\n /** Whether to show text labels next to icons */\n showLabels: ComputedRef<boolean>;\n /** Button size */\n buttonSize: ComputedRef<ButtonSize>;\n /** When to show follow-up input */\n followUpTrigger: ComputedRef<FollowUpTrigger>;\n /** Check if an option should show follow-up based on followUpTrigger */\n shouldShowFollowUp: (optionValue: string) => boolean;\n /** Widget styling configuration */\n styling: ComputedRef<ReactionStyling>;\n}\n\n/**\n * Composable for reaction widgets\n *\n * Provides reaction options, submission handling, and follow-up state management.\n * Can be used with or without the FeedValue plugin.\n *\n * @param widgetId - Optional widget ID override (uses plugin widget if not provided)\n *\n * @example\n * ```vue\n * <script setup>\n * import { useReaction } from '@feedvalue/vue';\n *\n * const {\n * options,\n * react,\n * isSubmitting,\n * submitted,\n * error,\n * showFollowUp,\n * setShowFollowUp,\n * isReady,\n * } = useReaction();\n *\n * const handleClick = (option) => {\n * if (option.showFollowUp) {\n * setShowFollowUp(option.value);\n * } else {\n * react(option.value);\n * }\n * };\n * </script>\n *\n * <template>\n * <div v-if=\"isReady && options\">\n * <div v-if=\"submitted\">Thanks for your feedback!</div>\n *\n * <template v-else>\n * <button\n * v-for=\"option in options\"\n * :key=\"option.value\"\n * @click=\"handleClick(option)\"\n * :disabled=\"isSubmitting\"\n * >\n * {{ option.icon }} {{ option.label }}\n * </button>\n *\n * <form v-if=\"showFollowUp\" @submit.prevent=\"react(showFollowUp, followUpText)\">\n * <input v-model=\"followUpText\" placeholder=\"Tell us more...\" />\n * <button type=\"submit\">Send</button>\n * </form>\n *\n * <div v-if=\"error\">Error: {{ error.message }}</div>\n * </template>\n * </div>\n * </template>\n * ```\n */\nexport function useReaction(widgetId?: string): UseReactionReturn {\n // Try to inject instance from plugin\n const injectedInstance = inject(FEEDVALUE_KEY, null);\n const injectedOptions = inject(FEEDVALUE_OPTIONS_KEY, null);\n\n // Local instance ref (may be created if no plugin or widgetId override)\n const instance = ref<FeedValueInstance | null>(null);\n const isReady = ref(false);\n\n // Local state for reaction UI\n const showFollowUp = ref<string | null>(null);\n const submitted = ref<string | null>(null);\n const isSubmitting = ref(false);\n const error = ref<Error | null>(null);\n\n // Track if we own the instance (need to destroy on unmount)\n let ownsInstance = false;\n let unsubscribe: (() => void) | null = null;\n\n /**\n * Sync ready state from instance\n */\n const syncState = () => {\n const state = instance.value?.getSnapshot();\n if (state) {\n isReady.value = state.isReady;\n }\n };\n\n onMounted(() => {\n // Use injected instance if available and no widgetId override\n if (injectedInstance && !widgetId) {\n instance.value = injectedInstance;\n } else {\n // Create new instance\n const effectiveWidgetId = widgetId ?? injectedOptions?.widgetId;\n\n if (!effectiveWidgetId) {\n console.error(\n '[FeedValue] No widgetId provided. Either install the plugin with createFeedValue() ' +\n 'or pass widgetId to useReaction().'\n );\n return;\n }\n\n instance.value = FeedValue.init({\n widgetId: effectiveWidgetId,\n apiBaseUrl: injectedOptions?.apiBaseUrl,\n config: injectedOptions?.config,\n headless: true, // Reaction widgets are always headless\n });\n ownsInstance = true;\n }\n\n // Subscribe to state changes\n if (instance.value) {\n unsubscribe = instance.value.subscribe(syncState);\n syncState(); // Initial sync\n }\n });\n\n onUnmounted(() => {\n unsubscribe?.();\n if (ownsInstance && instance.value) {\n instance.value.destroy();\n }\n instance.value = null;\n });\n\n // Computed: reaction options from instance\n const options = computed<ReactionOption[] | null>(() => {\n if (!instance.value || !isReady.value) return null;\n return instance.value.getReactionOptions();\n });\n\n // Computed: check if this is a reaction widget\n const isReactionWidget = computed(() => {\n return instance.value?.isReaction() ?? false;\n });\n\n // Computed: get config values with defaults\n const reactionConfig = computed(() => {\n if (!instance.value || !isReady.value) return null;\n // Access the widget config which includes reaction config\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (instance.value as any)._widgetConfig?.config ?? null;\n });\n\n const showLabels = computed(() => {\n return reactionConfig.value?.showLabels ?? true;\n });\n\n const buttonSize = computed<ButtonSize>(() => {\n return reactionConfig.value?.buttonSize ?? 'md';\n });\n\n const followUpTrigger = computed<FollowUpTrigger>(() => {\n return reactionConfig.value?.followUpTrigger ?? 'negative';\n });\n\n const template = computed<ReactionTemplate | undefined>(() => {\n return reactionConfig.value?.template;\n });\n\n // Computed: widget styling configuration\n const styling = computed<ReactionStyling>(() => {\n const defaultStyling: ReactionStyling = {\n primaryColor: '#6366f1',\n backgroundColor: '#ffffff',\n textColor: '#111827',\n buttonTextColor: '#4b5563',\n borderColor: '#e5e7eb',\n borderWidth: '1',\n borderRadius: 'full',\n };\n\n if (!instance.value || !isReady.value) {\n return defaultStyling;\n }\n\n // Access the widget config styling\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const widgetConfig = (instance.value as any)._widgetConfig;\n if (!widgetConfig?.styling) {\n return defaultStyling;\n }\n\n // Cast styling to access extended properties that may be present from API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const widgetStyling = widgetConfig.styling as any;\n return {\n primaryColor: widgetStyling.primaryColor ?? defaultStyling.primaryColor,\n backgroundColor: widgetStyling.backgroundColor ?? defaultStyling.backgroundColor,\n textColor: widgetStyling.textColor ?? defaultStyling.textColor,\n buttonTextColor: widgetStyling.buttonTextColor ?? defaultStyling.buttonTextColor,\n borderColor: widgetStyling.borderColor ?? defaultStyling.borderColor,\n borderWidth: widgetStyling.borderWidth ?? defaultStyling.borderWidth,\n borderRadius: widgetStyling.borderRadius ?? defaultStyling.borderRadius,\n };\n });\n\n /**\n * Check if an option should show follow-up based on followUpTrigger\n */\n const shouldShowFollowUp = (optionValue: string): boolean => {\n if (followUpTrigger.value === 'none') return false;\n if (followUpTrigger.value === 'all') return true;\n // followUpTrigger === 'negative'\n if (template.value && NEGATIVE_OPTIONS_MAP[template.value]) {\n return NEGATIVE_OPTIONS_MAP[template.value].includes(optionValue);\n }\n // For custom options, use the option's own showFollowUp setting\n const option = options.value?.find((o) => o.value === optionValue);\n return option?.showFollowUp ?? false;\n };\n\n /**\n * Submit a reaction\n */\n const react = async (value: string, followUp?: string): Promise<void> => {\n if (!instance.value) {\n throw new Error('FeedValue not initialized');\n }\n\n isSubmitting.value = true;\n error.value = null;\n\n try {\n await instance.value.react(value, followUp ? { followUp } : undefined);\n submitted.value = value;\n showFollowUp.value = null;\n } catch (err) {\n const reactionError = err instanceof Error ? err : new Error(String(err));\n error.value = reactionError;\n throw reactionError;\n } finally {\n isSubmitting.value = false;\n }\n };\n\n /**\n * Set which option is showing follow-up input\n */\n const setShowFollowUp = (value: string | null): void => {\n showFollowUp.value = value;\n };\n\n /**\n * Clear submitted state to allow re-submission\n */\n const clearSubmitted = (): void => {\n submitted.value = null;\n error.value = null;\n };\n\n return {\n options,\n isSubmitting: readonly(isSubmitting),\n submitted: readonly(submitted),\n error: readonly(error),\n showFollowUp: readonly(showFollowUp),\n react,\n setShowFollowUp,\n clearSubmitted,\n isReactionWidget,\n isReady: readonly(isReady),\n showLabels,\n buttonSize,\n followUpTrigger,\n shouldShowFollowUp,\n styling,\n };\n}\n","/**\n * @feedvalue/vue - ReactionButtons Component\n *\n * Pre-built reaction buttons component for Vue applications.\n * Renders reaction options with optional follow-up input.\n */\n\nimport { defineComponent, ref, computed, h, type PropType } from 'vue';\nimport { useReaction } from './use-reaction';\nimport type { ReactionOption } from '@feedvalue/core';\n\nimport type { ButtonSize, ReactionBorderRadius, ReactionBorderWidth } from '@feedvalue/core';\n\n/**\n * Border radius mapping from preset to CSS value\n */\nconst borderRadiusMap: Record<ReactionBorderRadius, string> = {\n full: '9999px',\n lg: '12px',\n md: '8px',\n sm: '4px',\n none: '0px',\n};\n\n/**\n * Border width mapping from preset to CSS value\n */\nconst borderWidthMap: Record<ReactionBorderWidth, string> = {\n '0': '0px',\n '1': '1px',\n '2': '2px',\n '3': '3px',\n '4': '4px',\n};\n\n/**\n * Button size style variants\n */\nconst sizeStyles: Record<ButtonSize, { button: Record<string, string>; icon: Record<string, string>; label: Record<string, string> }> = {\n sm: {\n button: { padding: '0.375rem 0.75rem', fontSize: '0.75rem', gap: '0.375rem' },\n icon: { fontSize: '1rem' },\n label: { fontSize: '0.75rem' },\n },\n md: {\n button: { padding: '0.5rem 1rem', fontSize: '0.875rem', gap: '0.5rem' },\n icon: { fontSize: '1.125rem' },\n label: { fontSize: '0.875rem' },\n },\n lg: {\n button: { padding: '0.75rem 1.25rem', fontSize: '1rem', gap: '0.625rem' },\n icon: { fontSize: '1.5rem' },\n label: { fontSize: '1rem' },\n },\n};\n\n/**\n * Default CSS styles for the component\n */\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '0.75rem',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n },\n buttonGroup: {\n display: 'flex',\n flexWrap: 'wrap' as const,\n gap: '0.5rem',\n },\n button: {\n display: 'inline-flex',\n alignItems: 'center',\n fontWeight: '500',\n color: '#374151',\n backgroundColor: '#ffffff',\n border: '1px solid #d1d5db',\n borderRadius: '9999px',\n cursor: 'pointer',\n transition: 'background-color 0.15s, border-color 0.15s, transform 0.1s',\n },\n buttonActive: {\n backgroundColor: '#eef2ff',\n borderColor: '#6366f1',\n color: '#4f46e5',\n },\n buttonDisabled: {\n opacity: 0.7,\n cursor: 'not-allowed',\n },\n icon: {},\n followUp: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '0.5rem',\n padding: '0.75rem',\n backgroundColor: '#f9fafb',\n border: '1px solid #e5e7eb',\n borderRadius: '0.5rem',\n },\n input: {\n width: '100%',\n padding: '0.5rem 0.75rem',\n fontSize: '0.875rem',\n border: '1px solid #d1d5db',\n borderRadius: '0.375rem',\n backgroundColor: '#ffffff',\n boxSizing: 'border-box' as const,\n },\n actions: {\n display: 'flex',\n gap: '0.5rem',\n justifyContent: 'flex-end',\n },\n submitButton: {\n padding: '0.375rem 0.75rem',\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#ffffff',\n backgroundColor: '#6366f1',\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n },\n cancelButton: {\n padding: '0.375rem 0.75rem',\n fontSize: '0.875rem',\n color: '#6b7280',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n },\n thankYou: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.75rem 1rem',\n fontSize: '0.875rem',\n color: '#059669',\n backgroundColor: '#ecfdf5',\n border: '1px solid #a7f3d0',\n borderRadius: '0.5rem',\n },\n resetButton: {\n padding: '0.25rem 0.5rem',\n fontSize: '0.875rem',\n color: '#6b7280',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n },\n error: {\n padding: '0.5rem 0.75rem',\n fontSize: '0.875rem',\n color: '#dc2626',\n backgroundColor: '#fef2f2',\n border: '1px solid #fecaca',\n borderRadius: '0.375rem',\n },\n};\n\n/**\n * ReactionButtons Component\n *\n * Pre-built reaction buttons with follow-up input support.\n *\n * @example\n * ```vue\n * <template>\n * <ReactionButtons widget-id=\"xxx\" @react=\"onReact\" />\n * </template>\n *\n * <script setup>\n * import { ReactionButtons } from '@feedvalue/vue';\n *\n * const onReact = (value, followUp) => {\n * console.log('Reacted:', value, followUp);\n * };\n * </script>\n * ```\n */\nexport const ReactionButtons = defineComponent({\n name: 'ReactionButtons',\n\n props: {\n /** Widget ID (optional if using FeedValue plugin) */\n widgetId: {\n type: String as PropType<string | undefined>,\n default: undefined,\n },\n /** Custom thank you message (overrides widget config) */\n thankYouMessage: {\n type: String as PropType<string | undefined>,\n default: undefined,\n },\n /** Custom class for the container */\n containerClass: {\n type: String,\n default: '',\n },\n /** Custom class for buttons */\n buttonClass: {\n type: String,\n default: '',\n },\n },\n\n emits: {\n /** Emitted when a reaction is submitted */\n react: (value: string, _followUp?: string) => typeof value === 'string',\n },\n\n setup(props, { emit }) {\n const {\n options,\n react,\n isSubmitting,\n submitted,\n error,\n showFollowUp,\n setShowFollowUp,\n clearSubmitted,\n isReady,\n showLabels,\n buttonSize,\n shouldShowFollowUp,\n styling,\n } = useReaction(props.widgetId);\n\n // Local state for follow-up input\n const followUpText = ref('');\n\n // Get follow-up option\n const getFollowUpOption = computed<ReactionOption | null>(() => {\n if (!showFollowUp.value || !options.value) return null;\n return options.value.find((opt) => opt.value === showFollowUp.value) ?? null;\n });\n\n /**\n * Handle option click\n */\n const handleOptionClick = (option: ReactionOption) => {\n if (shouldShowFollowUp(option.value)) {\n setShowFollowUp(option.value);\n } else {\n submitReaction(option.value);\n }\n };\n\n /**\n * Submit reaction\n */\n const submitReaction = async (value: string, followUp?: string) => {\n try {\n await react(value, followUp);\n emit('react', value, followUp);\n } catch {\n // Error is already set in state\n }\n };\n\n /**\n * Handle follow-up form submit\n */\n const handleFollowUpSubmit = (e: Event) => {\n e.preventDefault();\n if (showFollowUp.value) {\n submitReaction(showFollowUp.value, followUpText.value || undefined);\n followUpText.value = '';\n }\n };\n\n /**\n * Cancel follow-up\n */\n const cancelFollowUp = () => {\n setShowFollowUp(null);\n followUpText.value = '';\n };\n\n return () => {\n // Don't render if not ready or no options\n if (!isReady.value || !options.value) {\n return null;\n }\n\n // Render thank you message after submission\n if (submitted.value) {\n const currentStyling = styling.value;\n return h(\n 'div',\n {\n class: props.containerClass,\n style: {\n ...styles.thankYou,\n color: currentStyling.primaryColor ?? '#059669',\n },\n },\n [\n h('span', props.thankYouMessage || 'Thanks for your feedback!'),\n h(\n 'button',\n {\n type: 'button',\n style: styles.resetButton,\n onClick: clearSubmitted,\n 'aria-label': 'Submit another reaction',\n },\n '↺'\n ),\n ]\n );\n }\n\n // Build reaction buttons using styling from widget config\n const currentSizeStyles = sizeStyles[buttonSize.value] || sizeStyles.md;\n const currentStyling = styling.value;\n const borderRadius = borderRadiusMap[currentStyling.borderRadius ?? 'full'] ?? '9999px';\n const borderWidth = borderWidthMap[currentStyling.borderWidth ?? '1'] ?? '1px';\n\n const buttonElements = options.value.map((option) => {\n const isActive = showFollowUp.value === option.value;\n const children = [\n h('span', { style: { ...styles.icon, ...currentSizeStyles.icon }, 'aria-hidden': 'true' }, option.icon),\n ];\n if (showLabels.value) {\n children.push(h('span', { style: { ...currentSizeStyles.label, color: currentStyling.buttonTextColor ?? '#4b5563' } }, option.label));\n }\n\n return h(\n 'button',\n {\n key: option.value,\n type: 'button',\n class: props.buttonClass,\n style: {\n ...styles.button,\n ...currentSizeStyles.button,\n backgroundColor: currentStyling.backgroundColor ?? '#ffffff',\n borderColor: isActive ? (currentStyling.primaryColor ?? '#6366f1') : (currentStyling.borderColor ?? '#e5e7eb'),\n borderWidth: borderWidth,\n borderRadius: borderRadius,\n color: currentStyling.buttonTextColor ?? '#4b5563',\n ...(isActive ? {\n backgroundColor: `${currentStyling.primaryColor ?? '#6366f1'}10`,\n } : {}),\n ...(isSubmitting.value ? styles.buttonDisabled : {}),\n },\n disabled: isSubmitting.value,\n 'aria-pressed': isActive,\n 'aria-label': option.label,\n onClick: () => handleOptionClick(option),\n },\n children\n );\n });\n\n // Build follow-up form if needed\n let followUpForm = null;\n const followUpOption = getFollowUpOption.value;\n if (showFollowUp.value && followUpOption) {\n followUpForm = h(\n 'form',\n {\n style: styles.followUp,\n onSubmit: handleFollowUpSubmit,\n },\n [\n h('input', {\n type: 'text',\n style: styles.input,\n value: followUpText.value,\n placeholder: followUpOption.followUpPlaceholder || 'Tell us more...',\n disabled: isSubmitting.value,\n maxlength: 500,\n onInput: (e: Event) => {\n followUpText.value = (e.target as HTMLInputElement).value;\n },\n }),\n h('div', { style: { ...styles.actions, justifyContent: 'center' } }, [\n h(\n 'button',\n {\n type: 'submit',\n style: {\n ...styles.submitButton,\n backgroundColor: currentStyling.primaryColor ?? '#6366f1',\n borderRadius: borderRadius,\n ...(isSubmitting.value ? styles.buttonDisabled : {}),\n },\n disabled: isSubmitting.value,\n },\n isSubmitting.value ? 'Sending...' : 'Send'\n ),\n h(\n 'button',\n {\n type: 'button',\n style: {\n ...styles.cancelButton,\n backgroundColor: currentStyling.backgroundColor ?? '#ffffff',\n color: currentStyling.buttonTextColor ?? '#6b7280',\n borderRadius: borderRadius,\n border: `${borderWidth} solid ${currentStyling.borderColor ?? '#e5e7eb'}`,\n },\n disabled: isSubmitting.value,\n onClick: cancelFollowUp,\n },\n 'Cancel'\n ),\n ]),\n ]\n );\n }\n\n // Build error message\n let errorElement = null;\n if (error.value) {\n errorElement = h(\n 'div',\n { style: styles.error, role: 'alert' },\n error.value.message\n );\n }\n\n // Return full component\n return h(\n 'div',\n {\n class: props.containerClass,\n style: styles.container,\n role: 'group',\n 'aria-label': 'Reaction buttons',\n },\n [\n h('div', { style: styles.buttonGroup, role: 'radiogroup' }, buttonElements),\n followUpForm,\n errorElement,\n ]\n );\n };\n },\n});\n\nexport default ReactionButtons;\n"]}
1
+ {"version":3,"sources":["../src/plugin.ts","../src/composables.ts","../src/use-reaction.ts","../src/ReactionButtons.ts"],"names":["FeedValue","inject","ref","onMounted","onUnmounted","readonly","computed","currentStyling"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @feedvalue/vue - Plugin\n *\n * Vue plugin for FeedValue. Provides app-level configuration\n * and automatic initialization.\n */\n\nimport type { App, InjectionKey } from 'vue';\nimport { FeedValue, type FeedValueConfig, type FeedValueInstance } from '@feedvalue/core';\n\n/**\n * Plugin options\n */\nexport interface FeedValuePluginOptions {\n /** Widget ID from FeedValue dashboard */\n widgetId: string;\n /** API base URL (for self-hosted) */\n apiBaseUrl?: string;\n /** Configuration overrides */\n config?: Partial<FeedValueConfig>;\n /**\n * Headless mode - disables all DOM rendering.\n * Use this when you want full control over the UI.\n * The SDK will still fetch config and provide all API methods\n * but won't render any trigger button or modal.\n *\n * @default false\n */\n headless?: boolean;\n}\n\n/**\n * Injection key for FeedValue instance\n */\nexport const FEEDVALUE_KEY: InjectionKey<FeedValueInstance> = Symbol('feedvalue');\n\n/**\n * Injection key for widget ID (used by useFeedValue when no instance is injected)\n */\nexport const FEEDVALUE_OPTIONS_KEY: InjectionKey<FeedValuePluginOptions> = Symbol('feedvalue-options');\n\n/**\n * Create FeedValue Vue plugin\n *\n * @example\n * ```ts\n * // main.ts\n * import { createApp } from 'vue';\n * import { createFeedValue } from '@feedvalue/vue';\n * import App from './App.vue';\n *\n * const app = createApp(App);\n *\n * app.use(createFeedValue({\n * widgetId: 'your-widget-id',\n * config: { theme: 'dark' }\n * }));\n *\n * app.mount('#app');\n * ```\n */\nexport function createFeedValue(options: FeedValuePluginOptions) {\n let instance: FeedValueInstance | null = null;\n\n return {\n install(app: App) {\n // Only initialize on client side\n if (typeof window !== 'undefined') {\n instance = FeedValue.init({\n widgetId: options.widgetId,\n apiBaseUrl: options.apiBaseUrl,\n config: options.config,\n headless: options.headless,\n });\n\n // Provide instance to all components\n app.provide(FEEDVALUE_KEY, instance);\n\n // Also provide to global properties for Options API access\n app.config.globalProperties.$feedvalue = instance;\n }\n\n // Always provide options (for SSR where we don't initialize)\n app.provide(FEEDVALUE_OPTIONS_KEY, options);\n },\n };\n}\n\n/**\n * Type augmentation for global properties\n */\ndeclare module 'vue' {\n interface ComponentCustomProperties {\n $feedvalue: FeedValueInstance | undefined;\n }\n}\n","/**\n * @feedvalue/vue - Composables\n *\n * Vue composables for FeedValue. Provides reactive state and methods.\n */\n\nimport {\n ref,\n shallowRef,\n readonly,\n onMounted,\n onUnmounted,\n inject,\n type Ref,\n type ShallowRef,\n} from 'vue';\nimport {\n FeedValue,\n type FeedValueConfig,\n type FeedValueInstance,\n type FeedbackData,\n type UserTraits,\n} from '@feedvalue/core';\nimport { FEEDVALUE_KEY, FEEDVALUE_OPTIONS_KEY } from './plugin';\n\n/**\n * Return type for useFeedValue composable\n */\nexport interface UseFeedValueReturn {\n /** FeedValue instance (for advanced usage) */\n instance: Readonly<ShallowRef<FeedValueInstance | null>>;\n /** Widget is ready */\n isReady: Readonly<Ref<boolean>>;\n /** Modal is open */\n isOpen: Readonly<Ref<boolean>>;\n /** Widget is visible */\n isVisible: Readonly<Ref<boolean>>;\n /** Current error */\n error: Readonly<Ref<Error | null>>;\n /** Submission in progress */\n isSubmitting: Readonly<Ref<boolean>>;\n /** Running in headless mode (no default UI rendered) */\n isHeadless: Readonly<Ref<boolean>>;\n /** Open the feedback modal */\n open: () => void;\n /** Close the feedback modal */\n close: () => void;\n /** Toggle the feedback modal */\n toggle: () => void;\n /** Show the trigger button */\n show: () => void;\n /** Hide the trigger button */\n hide: () => void;\n /** Submit feedback programmatically */\n submit: (feedback: Partial<FeedbackData>) => Promise<void>;\n /** Identify user */\n identify: (userId: string, traits?: UserTraits) => void;\n /** Set user data */\n setData: (data: Record<string, string>) => void;\n /** Reset user data */\n reset: () => void;\n}\n\n/**\n * FeedValue composable\n *\n * Can be used with or without plugin. If plugin is installed, uses the\n * provided instance. Otherwise, creates a new instance.\n *\n * @example\n * ```vue\n * <script setup>\n * import { useFeedValue } from '@feedvalue/vue';\n *\n * // With plugin installed\n * const { open, isReady } = useFeedValue();\n *\n * // Or standalone with widgetId\n * const { open, isReady } = useFeedValue('your-widget-id');\n * </script>\n *\n * <template>\n * <button @click=\"open\" :disabled=\"!isReady\">\n * Give Feedback\n * </button>\n * </template>\n * ```\n */\nexport function useFeedValue(\n widgetId?: string,\n config?: Partial<FeedValueConfig>\n): UseFeedValueReturn {\n // Try to inject instance from plugin\n const injectedInstance = inject(FEEDVALUE_KEY, null);\n const injectedOptions = inject(FEEDVALUE_OPTIONS_KEY, null);\n\n // Refs for reactive state\n const instance = shallowRef<FeedValueInstance | null>(null);\n const isReady = ref(false);\n const isOpen = ref(false);\n const isVisible = ref(false);\n const error = ref<Error | null>(null);\n const isSubmitting = ref(false);\n const isHeadless = ref(false);\n\n // Track if we own the instance (need to destroy on unmount)\n let ownsInstance = false;\n let unsubscribe: (() => void) | null = null;\n\n /**\n * Sync reactive state from instance\n */\n const syncState = () => {\n const state = instance.value?.getSnapshot();\n if (state) {\n isReady.value = state.isReady;\n isOpen.value = state.isOpen;\n isVisible.value = state.isVisible;\n error.value = state.error;\n isSubmitting.value = state.isSubmitting;\n }\n };\n\n onMounted(() => {\n // Use injected instance if available and no widgetId override\n if (injectedInstance && !widgetId) {\n instance.value = injectedInstance;\n isHeadless.value = injectedInstance.isHeadless();\n } else {\n // Create new instance\n const effectiveWidgetId = widgetId ?? injectedOptions?.widgetId;\n\n if (!effectiveWidgetId) {\n console.error(\n '[FeedValue] No widgetId provided. Either install the plugin with createFeedValue() ' +\n 'or pass widgetId to useFeedValue().'\n );\n return;\n }\n\n instance.value = FeedValue.init({\n widgetId: effectiveWidgetId,\n apiBaseUrl: injectedOptions?.apiBaseUrl,\n config: config ?? injectedOptions?.config,\n headless: injectedOptions?.headless,\n });\n ownsInstance = true;\n }\n\n // Subscribe to state changes\n if (instance.value) {\n unsubscribe = instance.value.subscribe(syncState);\n isHeadless.value = instance.value.isHeadless();\n syncState(); // Initial sync\n }\n });\n\n onUnmounted(() => {\n unsubscribe?.();\n if (ownsInstance && instance.value) {\n instance.value.destroy();\n }\n instance.value = null;\n });\n\n // Methods that delegate to instance\n const open = () => instance.value?.open();\n const close = () => instance.value?.close();\n const toggle = () => instance.value?.toggle();\n const show = () => instance.value?.show();\n const hide = () => instance.value?.hide();\n const submit = (feedback: Partial<FeedbackData>) =>\n instance.value?.submit(feedback) ?? Promise.reject(new Error('Not initialized'));\n const identify = (userId: string, traits?: UserTraits) =>\n instance.value?.identify(userId, traits);\n const setData = (data: Record<string, string>) => instance.value?.setData(data);\n const reset = () => instance.value?.reset();\n\n return {\n instance: readonly(instance),\n isReady: readonly(isReady),\n isOpen: readonly(isOpen),\n isVisible: readonly(isVisible),\n error: readonly(error),\n isSubmitting: readonly(isSubmitting),\n isHeadless: readonly(isHeadless),\n open,\n close,\n toggle,\n show,\n hide,\n submit,\n identify,\n setData,\n reset,\n };\n}\n","/**\n * @feedvalue/vue - useReaction Composable\n *\n * Composable for reaction widgets in Vue applications.\n * Provides a simple API for submitting reactions.\n */\n\nimport {\n ref,\n computed,\n readonly,\n onMounted,\n onUnmounted,\n inject,\n type Ref,\n type ComputedRef,\n} from 'vue';\nimport {\n FeedValue,\n NEGATIVE_OPTIONS_MAP,\n type ReactionOption,\n type FeedValueInstance,\n type ButtonSize,\n type FollowUpTrigger,\n type ReactionTemplate,\n type ReactionStyling,\n} from '@feedvalue/core';\nimport { FEEDVALUE_KEY, FEEDVALUE_OPTIONS_KEY } from './plugin';\n\n/**\n * Return type for useReaction composable\n */\nexport interface UseReactionReturn {\n /** Available reaction options */\n options: ComputedRef<ReactionOption[] | null>;\n /** Currently submitting */\n isSubmitting: Readonly<Ref<boolean>>;\n /** Successfully submitted value (null if not yet submitted) */\n submitted: Readonly<Ref<string | null>>;\n /** Error if submission failed */\n error: Readonly<Ref<Error | null>>;\n /** Option value requiring follow-up input (null if none) */\n showFollowUp: Readonly<Ref<string | null>>;\n /** Submit a reaction */\n react: (value: string, followUp?: string) => Promise<void>;\n /** Set which option is showing follow-up input */\n setShowFollowUp: (value: string | null) => void;\n /** Clear the submitted state to allow re-submission */\n clearSubmitted: () => void;\n /** Check if widget is a reaction type */\n isReactionWidget: ComputedRef<boolean>;\n /** Widget configuration is ready */\n isReady: Readonly<Ref<boolean>>;\n /** Whether to show text labels next to icons */\n showLabels: ComputedRef<boolean>;\n /** Button size */\n buttonSize: ComputedRef<ButtonSize>;\n /** When to show follow-up input */\n followUpTrigger: ComputedRef<FollowUpTrigger>;\n /** Check if an option should show follow-up based on followUpTrigger */\n shouldShowFollowUp: (optionValue: string) => boolean;\n /** Widget styling configuration */\n styling: ComputedRef<ReactionStyling>;\n}\n\n/**\n * Composable for reaction widgets\n *\n * Provides reaction options, submission handling, and follow-up state management.\n * Can be used with or without the FeedValue plugin.\n *\n * @param widgetId - Optional widget ID override (uses plugin widget if not provided)\n *\n * @example\n * ```vue\n * <script setup>\n * import { useReaction } from '@feedvalue/vue';\n *\n * const {\n * options,\n * react,\n * isSubmitting,\n * submitted,\n * error,\n * showFollowUp,\n * setShowFollowUp,\n * isReady,\n * } = useReaction();\n *\n * const handleClick = (option) => {\n * if (option.showFollowUp) {\n * setShowFollowUp(option.value);\n * } else {\n * react(option.value);\n * }\n * };\n * </script>\n *\n * <template>\n * <div v-if=\"isReady && options\">\n * <div v-if=\"submitted\">Thanks for your feedback!</div>\n *\n * <template v-else>\n * <button\n * v-for=\"option in options\"\n * :key=\"option.value\"\n * @click=\"handleClick(option)\"\n * :disabled=\"isSubmitting\"\n * >\n * {{ option.icon }} {{ option.label }}\n * </button>\n *\n * <form v-if=\"showFollowUp\" @submit.prevent=\"react(showFollowUp, followUpText)\">\n * <input v-model=\"followUpText\" placeholder=\"Tell us more...\" />\n * <button type=\"submit\">Send</button>\n * </form>\n *\n * <div v-if=\"error\">Error: {{ error.message }}</div>\n * </template>\n * </div>\n * </template>\n * ```\n */\nexport function useReaction(widgetId?: string): UseReactionReturn {\n // Try to inject instance from plugin\n const injectedInstance = inject(FEEDVALUE_KEY, null);\n const injectedOptions = inject(FEEDVALUE_OPTIONS_KEY, null);\n\n // Local instance ref (may be created if no plugin or widgetId override)\n const instance = ref<FeedValueInstance | null>(null);\n const isReady = ref(false);\n\n // Local state for reaction UI\n const showFollowUp = ref<string | null>(null);\n const submitted = ref<string | null>(null);\n const isSubmitting = ref(false);\n const error = ref<Error | null>(null);\n\n // Track if we own the instance (need to destroy on unmount)\n let ownsInstance = false;\n let unsubscribe: (() => void) | null = null;\n\n /**\n * Sync ready state from instance\n */\n const syncState = () => {\n const state = instance.value?.getSnapshot();\n if (state) {\n isReady.value = state.isReady;\n }\n };\n\n onMounted(() => {\n // Use injected instance if available and no widgetId override\n if (injectedInstance && !widgetId) {\n instance.value = injectedInstance;\n } else {\n // Create new instance\n const effectiveWidgetId = widgetId ?? injectedOptions?.widgetId;\n\n if (!effectiveWidgetId) {\n console.error(\n '[FeedValue] No widgetId provided. Either install the plugin with createFeedValue() ' +\n 'or pass widgetId to useReaction().'\n );\n return;\n }\n\n instance.value = FeedValue.init({\n widgetId: effectiveWidgetId,\n apiBaseUrl: injectedOptions?.apiBaseUrl,\n config: injectedOptions?.config,\n headless: true, // Reaction widgets are always headless\n });\n ownsInstance = true;\n }\n\n // Subscribe to state changes\n if (instance.value) {\n unsubscribe = instance.value.subscribe(syncState);\n syncState(); // Initial sync\n }\n });\n\n onUnmounted(() => {\n unsubscribe?.();\n if (ownsInstance && instance.value) {\n instance.value.destroy();\n }\n instance.value = null;\n });\n\n // Computed: reaction options from instance\n const options = computed<ReactionOption[] | null>(() => {\n if (!instance.value || !isReady.value) return null;\n return instance.value.getReactionOptions();\n });\n\n // Computed: check if this is a reaction widget\n const isReactionWidget = computed(() => {\n return instance.value?.isReaction() ?? false;\n });\n\n // Computed: get config values with defaults\n const reactionConfig = computed(() => {\n if (!instance.value || !isReady.value) return null;\n // Access the widget config which includes reaction config\n const widgetConfig = instance.value.getWidgetConfig();\n return widgetConfig?.config ?? null;\n });\n\n const showLabels = computed(() => {\n return reactionConfig.value?.showLabels ?? true;\n });\n\n const buttonSize = computed<ButtonSize>(() => {\n return reactionConfig.value?.buttonSize ?? 'md';\n });\n\n const followUpTrigger = computed<FollowUpTrigger>(() => {\n return reactionConfig.value?.followUpTrigger ?? 'negative';\n });\n\n const template = computed<ReactionTemplate | undefined>(() => {\n return reactionConfig.value?.template;\n });\n\n // Computed: widget styling configuration\n const styling = computed<ReactionStyling>(() => {\n const defaultStyling: ReactionStyling = {\n primaryColor: '#6366f1',\n backgroundColor: '#ffffff',\n textColor: '#111827',\n buttonTextColor: '#4b5563',\n borderColor: '#e5e7eb',\n borderWidth: '1',\n borderRadius: 'full',\n };\n\n if (!instance.value || !isReady.value) {\n return defaultStyling;\n }\n\n // Access the widget config styling using public method\n const widgetConfig = instance.value.getWidgetConfig();\n if (!widgetConfig?.styling) {\n return defaultStyling;\n }\n\n // Cast styling to access extended properties that may be present from API\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const widgetStyling = widgetConfig.styling as any;\n return {\n primaryColor: widgetStyling.primaryColor ?? defaultStyling.primaryColor,\n backgroundColor: widgetStyling.backgroundColor ?? defaultStyling.backgroundColor,\n textColor: widgetStyling.textColor ?? defaultStyling.textColor,\n buttonTextColor: widgetStyling.buttonTextColor ?? defaultStyling.buttonTextColor,\n borderColor: widgetStyling.borderColor ?? defaultStyling.borderColor,\n borderWidth: widgetStyling.borderWidth ?? defaultStyling.borderWidth,\n borderRadius: widgetStyling.borderRadius ?? defaultStyling.borderRadius,\n };\n });\n\n /**\n * Check if an option should show follow-up based on followUpTrigger\n */\n const shouldShowFollowUp = (optionValue: string): boolean => {\n if (followUpTrigger.value === 'none') return false;\n if (followUpTrigger.value === 'all') return true;\n // followUpTrigger === 'negative'\n if (template.value && NEGATIVE_OPTIONS_MAP[template.value]) {\n return NEGATIVE_OPTIONS_MAP[template.value].includes(optionValue);\n }\n // For custom options, use the option's own showFollowUp setting\n const option = options.value?.find((o) => o.value === optionValue);\n return option?.showFollowUp ?? false;\n };\n\n /**\n * Submit a reaction\n */\n const react = async (value: string, followUp?: string): Promise<void> => {\n if (!instance.value) {\n throw new Error('FeedValue not initialized');\n }\n\n isSubmitting.value = true;\n error.value = null;\n\n try {\n await instance.value.react(value, followUp ? { followUp } : undefined);\n submitted.value = value;\n showFollowUp.value = null;\n } catch (err) {\n const reactionError = err instanceof Error ? err : new Error(String(err));\n error.value = reactionError;\n throw reactionError;\n } finally {\n isSubmitting.value = false;\n }\n };\n\n /**\n * Set which option is showing follow-up input\n */\n const setShowFollowUp = (value: string | null): void => {\n showFollowUp.value = value;\n };\n\n /**\n * Clear submitted state to allow re-submission\n */\n const clearSubmitted = (): void => {\n submitted.value = null;\n error.value = null;\n };\n\n return {\n options,\n isSubmitting: readonly(isSubmitting),\n submitted: readonly(submitted),\n error: readonly(error),\n showFollowUp: readonly(showFollowUp),\n react,\n setShowFollowUp,\n clearSubmitted,\n isReactionWidget,\n isReady: readonly(isReady),\n showLabels,\n buttonSize,\n followUpTrigger,\n shouldShowFollowUp,\n styling,\n };\n}\n","/**\n * @feedvalue/vue - ReactionButtons Component\n *\n * Pre-built reaction buttons component for Vue applications.\n * Renders reaction options with optional follow-up input.\n */\n\nimport { defineComponent, ref, computed, h, type PropType } from 'vue';\nimport { useReaction } from './use-reaction';\nimport type { ReactionOption } from '@feedvalue/core';\n\nimport type { ButtonSize, ReactionBorderRadius } from '@feedvalue/core';\n\n/**\n * Border radius mapping from preset to CSS value\n */\nconst borderRadiusMap: Record<ReactionBorderRadius, string> = {\n full: '9999px',\n lg: '12px',\n md: '8px',\n sm: '4px',\n none: '0px',\n};\n\n/**\n * Border width mapping from preset to CSS value\n */\nconst borderWidthMap: Record<string, string> = {\n '0': '0px',\n '1': '1px',\n '2': '2px',\n '3': '3px',\n '4': '4px',\n thin: '1px',\n medium: '2px',\n thick: '3px',\n};\n\n/**\n * Button size style variants\n */\nconst sizeStyles: Record<ButtonSize, { button: Record<string, string>; icon: Record<string, string>; label: Record<string, string> }> = {\n sm: {\n button: { padding: '0.375rem 0.75rem', fontSize: '0.75rem', gap: '0.375rem' },\n icon: { fontSize: '1rem' },\n label: { fontSize: '0.75rem' },\n },\n md: {\n button: { padding: '0.5rem 1rem', fontSize: '0.875rem', gap: '0.5rem' },\n icon: { fontSize: '1.125rem' },\n label: { fontSize: '0.875rem' },\n },\n lg: {\n button: { padding: '0.75rem 1.25rem', fontSize: '1rem', gap: '0.625rem' },\n icon: { fontSize: '1.5rem' },\n label: { fontSize: '1rem' },\n },\n};\n\n/**\n * Default CSS styles for the component\n */\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '0.75rem',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n },\n buttonGroup: {\n display: 'flex',\n flexWrap: 'wrap' as const,\n gap: '0.5rem',\n },\n button: {\n display: 'inline-flex',\n alignItems: 'center',\n fontWeight: '500',\n color: '#374151',\n backgroundColor: '#ffffff',\n border: '1px solid #d1d5db',\n borderRadius: '9999px',\n cursor: 'pointer',\n transition: 'background-color 0.15s, border-color 0.15s, transform 0.1s',\n },\n buttonActive: {\n backgroundColor: '#eef2ff',\n borderColor: '#6366f1',\n color: '#4f46e5',\n },\n buttonDisabled: {\n opacity: 0.7,\n cursor: 'not-allowed',\n },\n icon: {},\n followUp: {\n display: 'flex',\n flexDirection: 'column' as const,\n gap: '0.5rem',\n padding: '0.75rem',\n backgroundColor: '#f9fafb',\n border: '1px solid #e5e7eb',\n borderRadius: '0.5rem',\n },\n input: {\n width: '100%',\n padding: '0.5rem 0.75rem',\n fontSize: '0.875rem',\n border: '1px solid #d1d5db',\n borderRadius: '0.375rem',\n backgroundColor: '#ffffff',\n boxSizing: 'border-box' as const,\n resize: 'none' as const,\n },\n actions: {\n display: 'flex',\n gap: '0.5rem',\n justifyContent: 'flex-end',\n },\n submitButton: {\n padding: '0.375rem 0.75rem',\n fontSize: '0.875rem',\n fontWeight: '500',\n color: '#ffffff',\n backgroundColor: '#6366f1',\n border: 'none',\n borderRadius: '0.375rem',\n cursor: 'pointer',\n },\n cancelButton: {\n padding: '0.375rem 0.75rem',\n fontSize: '0.875rem',\n color: '#6b7280',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n },\n thankYou: {\n display: 'flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.75rem 1rem',\n fontSize: '0.875rem',\n color: '#059669',\n backgroundColor: '#ecfdf5',\n border: '1px solid #a7f3d0',\n borderRadius: '0.5rem',\n },\n resetButton: {\n padding: '0.25rem 0.5rem',\n fontSize: '0.875rem',\n color: '#6b7280',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n },\n error: {\n padding: '0.5rem 0.75rem',\n fontSize: '0.875rem',\n color: '#dc2626',\n backgroundColor: '#fef2f2',\n border: '1px solid #fecaca',\n borderRadius: '0.375rem',\n },\n};\n\n/**\n * ReactionButtons Component\n *\n * Pre-built reaction buttons with follow-up input support.\n *\n * @example\n * ```vue\n * <template>\n * <ReactionButtons widget-id=\"xxx\" @react=\"onReact\" />\n * </template>\n *\n * <script setup>\n * import { ReactionButtons } from '@feedvalue/vue';\n *\n * const onReact = (value, followUp) => {\n * console.log('Reacted:', value, followUp);\n * };\n * </script>\n * ```\n */\nexport const ReactionButtons = defineComponent({\n name: 'ReactionButtons',\n\n props: {\n /** Widget ID (optional if using FeedValue plugin) */\n widgetId: {\n type: String as PropType<string | undefined>,\n default: undefined,\n },\n /** Custom thank you message (overrides widget config) */\n thankYouMessage: {\n type: String as PropType<string | undefined>,\n default: undefined,\n },\n /** Custom class for the container */\n containerClass: {\n type: String,\n default: '',\n },\n /** Custom class for buttons */\n buttonClass: {\n type: String,\n default: '',\n },\n /** Custom class for the follow-up form */\n formClass: {\n type: String,\n default: '',\n },\n /** Custom class for the thank you message */\n thankYouClass: {\n type: String,\n default: '',\n },\n /** Hide after submission (default: false) */\n hideAfterSubmit: {\n type: Boolean,\n default: false,\n },\n /** Whether to show follow-up inline or not at all */\n followUpMode: {\n type: String as PropType<'inline' | 'none'>,\n default: 'inline',\n },\n },\n\n emits: {\n /** Emitted when a reaction is submitted */\n react: (value: string, _followUp?: string) => typeof value === 'string',\n /** Emitted when an error occurs */\n error: (_error: Error) => true,\n },\n\n setup(props, { emit }) {\n const {\n options,\n react,\n isSubmitting,\n submitted,\n error,\n showFollowUp,\n setShowFollowUp,\n clearSubmitted,\n isReady,\n showLabels,\n buttonSize,\n shouldShowFollowUp,\n styling,\n isReactionWidget,\n } = useReaction(props.widgetId);\n\n // Local state for follow-up input\n const followUpText = ref('');\n // Hover state for buttons\n const hoveredButton = ref<string | null>(null);\n\n // Get follow-up option\n const getFollowUpOption = computed<ReactionOption | null>(() => {\n if (!showFollowUp.value || !options.value) return null;\n return options.value.find((opt) => opt.value === showFollowUp.value) ?? null;\n });\n\n /**\n * Handle option click\n */\n const handleOptionClick = (option: ReactionOption) => {\n if (props.followUpMode === 'inline' && shouldShowFollowUp(option.value)) {\n setShowFollowUp(option.value);\n } else {\n submitReaction(option.value);\n }\n };\n\n /**\n * Submit reaction\n */\n const submitReaction = async (value: string, followUp?: string) => {\n const trimmedFollowUp = followUp?.trim() || undefined;\n try {\n await react(value, trimmedFollowUp);\n emit('react', value, trimmedFollowUp);\n } catch (err) {\n const reactionError = err instanceof Error ? err : new Error(String(err));\n emit('error', reactionError);\n }\n };\n\n /**\n * Handle follow-up form submit\n */\n const handleFollowUpSubmit = (e: Event) => {\n e.preventDefault();\n if (showFollowUp.value) {\n submitReaction(showFollowUp.value, followUpText.value || undefined);\n followUpText.value = '';\n }\n };\n\n /**\n * Cancel follow-up\n */\n const cancelFollowUp = () => {\n setShowFollowUp(null);\n followUpText.value = '';\n };\n\n return () => {\n // Don't render if not ready, not a reaction widget, or no options\n if (!isReady.value || !isReactionWidget.value || !options.value) {\n return null;\n }\n\n // Hide after submission if prop is set\n if (submitted.value && props.hideAfterSubmit) {\n return null;\n }\n\n // Render thank you message after submission\n if (submitted.value) {\n const currentStyling = styling.value;\n return h(\n 'div',\n {\n class: props.thankYouClass || props.containerClass,\n style: props.thankYouClass ? undefined : {\n ...styles.thankYou,\n color: currentStyling.primaryColor ?? '#059669',\n },\n },\n [\n h('span', props.thankYouMessage || 'Thanks for your feedback!'),\n h(\n 'button',\n {\n type: 'button',\n style: styles.resetButton,\n onClick: clearSubmitted,\n 'aria-label': 'Submit another reaction',\n },\n '↺'\n ),\n ]\n );\n }\n\n // Build reaction buttons using styling from widget config\n const currentSizeStyles = sizeStyles[buttonSize.value] || sizeStyles.md;\n const currentStyling = styling.value;\n const borderRadius = borderRadiusMap[currentStyling.borderRadius ?? 'full'] ?? '9999px';\n const borderWidth = borderWidthMap[currentStyling.borderWidth ?? '1'] ?? '1px';\n\n // Only show buttons when follow-up is not displayed\n const buttonElements = !showFollowUp.value ? options.value.map((option) => {\n const isActive = showFollowUp.value === option.value;\n const isHovered = hoveredButton.value === option.value;\n const children = [\n h('span', { style: { ...styles.icon, ...currentSizeStyles.icon }, 'aria-hidden': 'true' }, option.icon),\n ];\n if (showLabels.value) {\n children.push(h('span', { style: { ...currentSizeStyles.label, color: currentStyling.buttonTextColor ?? '#4b5563' } }, option.label));\n }\n\n return h(\n 'button',\n {\n key: option.value,\n type: 'button',\n class: props.buttonClass,\n style: {\n ...styles.button,\n ...currentSizeStyles.button,\n backgroundColor: currentStyling.backgroundColor ?? '#ffffff',\n borderColor: isActive || isHovered ? (currentStyling.primaryColor ?? '#6366f1') : (currentStyling.borderColor ?? '#e5e7eb'),\n borderWidth: borderWidth,\n borderRadius: borderRadius,\n borderStyle: 'solid',\n color: currentStyling.buttonTextColor ?? '#4b5563',\n ...(isActive || isHovered ? {\n backgroundColor: `${currentStyling.primaryColor ?? '#6366f1'}10`,\n } : {}),\n ...(isSubmitting.value ? styles.buttonDisabled : {}),\n },\n disabled: isSubmitting.value,\n 'aria-pressed': isActive,\n 'aria-label': option.label,\n onClick: () => handleOptionClick(option),\n onMouseenter: () => { hoveredButton.value = option.value; },\n onMouseleave: () => { hoveredButton.value = null; },\n },\n children\n );\n }) : [];\n\n // Build follow-up form if needed\n let followUpForm = null;\n const followUpOption = getFollowUpOption.value;\n if (showFollowUp.value && followUpOption) {\n followUpForm = h(\n 'form',\n {\n class: props.formClass,\n style: props.formClass ? undefined : styles.followUp,\n onSubmit: handleFollowUpSubmit,\n },\n [\n h('textarea', {\n style: styles.input,\n value: followUpText.value,\n placeholder: followUpOption.followUpPlaceholder || 'Tell us more (optional)',\n disabled: isSubmitting.value,\n maxlength: 500,\n rows: 3,\n onInput: (e: Event) => {\n followUpText.value = (e.target as HTMLTextAreaElement).value;\n },\n }),\n h('div', { style: { ...styles.actions, justifyContent: 'center' } }, [\n h(\n 'button',\n {\n type: 'submit',\n style: {\n ...styles.submitButton,\n backgroundColor: currentStyling.primaryColor ?? '#6366f1',\n borderRadius: borderRadius,\n ...(isSubmitting.value ? styles.buttonDisabled : {}),\n },\n disabled: isSubmitting.value,\n },\n isSubmitting.value ? 'Sending...' : 'Send'\n ),\n h(\n 'button',\n {\n type: 'button',\n style: {\n ...styles.cancelButton,\n backgroundColor: currentStyling.backgroundColor ?? '#ffffff',\n color: currentStyling.buttonTextColor ?? '#6b7280',\n borderRadius: borderRadius,\n border: `${borderWidth} solid ${currentStyling.borderColor ?? '#e5e7eb'}`,\n },\n disabled: isSubmitting.value,\n onClick: cancelFollowUp,\n },\n 'Cancel'\n ),\n ]),\n ]\n );\n }\n\n // Build error message\n let errorElement = null;\n if (error.value) {\n errorElement = h(\n 'div',\n { style: styles.error, role: 'alert' },\n error.value.message\n );\n }\n\n // Return full component\n return h(\n 'div',\n {\n class: props.containerClass,\n style: styles.container,\n role: 'group',\n 'aria-label': 'Reaction buttons',\n },\n [\n // Only render button group if there are buttons to show\n buttonElements.length > 0\n ? h('div', { style: styles.buttonGroup, role: 'radiogroup' }, buttonElements)\n : null,\n followUpForm,\n errorElement,\n ].filter(Boolean)\n );\n };\n },\n});\n\nexport default ReactionButtons;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feedvalue/vue",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "FeedValue Vue 3 SDK - Plugin and Composables for Vue 3+",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -27,7 +27,7 @@
27
27
  "vue": ">=3.3.0"
28
28
  },
29
29
  "dependencies": {
30
- "@feedvalue/core": "^0.1.11"
30
+ "@feedvalue/core": "^0.1.14"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@vitejs/plugin-vue": "^6.0.3",