feedback-vos 1.0.29 → 1.0.31

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.mjs CHANGED
@@ -1,15 +1,54 @@
1
- import { ChatTeardropDots, ArrowLeft, X, Paperclip, Trash, Camera, CircleNotch } from 'phosphor-react';
1
+ import { ChatTeardropDots, ArrowLeft, X, Paperclip, PencilSimple, Camera, CircleNotch, ArrowCounterClockwise, Trash, Check } from 'phosphor-react';
2
2
  import { Popover } from '@headlessui/react';
3
- import { useState, useEffect, useRef } from 'react';
4
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
+ import { useState, useEffect, useRef, useCallback } from 'react';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import html2canvas from 'html2canvas';
6
6
 
7
7
  // src/lib/svg-assets.ts
8
8
  var bugImageUrl = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzYiIHZpZXdCb3g9IjAgMCAzNiAzNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTcuNzUwMDcgNEM4Ljc1MDA3IDMgOC4wMDAwNyAwIDYuMzEyMDcgMEM0LjYyNDA3IDAgNC43NTAwNyAyIDUuNzUwMDcgMkM2Ljc1MDA3IDIgNi43NTAwNyA0IDYuNzUwMDcgNUM2Ljc1MDA3IDYgNy43NTAwNyA0IDcuNzUwMDcgNFpNMy41NjcwNyA1LjcyQzQuNTY3MDcgNC43MiAzLjgxNzA3IDEuNzIgMi4xMjkwNyAxLjcyQzAuNDQxMDY4IDEuNzIgMC41NjcwNjggMy43MiAxLjU2NzA3IDMuNzJDMi41NjcwNyAzLjcyIDIuNTY3MDcgNS43MiAyLjU2NzA3IDYuNzJDMi41NjcwNyA3LjcyIDMuNTY3MDcgNS43MiAzLjU2NzA3IDUuNzJaIiBmaWxsPSIjQUE4REQ4Ii8+CjxwYXRoIGQ9Ik0yOS45NDIgMzIuODU2QzMwLjEzMSAzMy42NjQgMzEuMTY5IDM1LjEzNiAzMS45NzQgMzQuOTQ3QzMyLjc4IDM0Ljc1NyAzMy4wNTEgMzIuOTc2IDMyLjg2MiAzMi4xN0MzMi42NzMgMzEuMzYyIDMxLjg2NCAzMC44NjMgMzEuMDU4IDMxLjA1M0MzMC4yNTMgMzEuMjQzIDI5Ljc1MiAzMi4wNSAyOS45NDIgMzIuODU2Wk0yNC41MDggMzMuNTA1QzI0LjUxMSAzNC4zMzUgMjUuMTg5IDM2LjAwMyAyNi4wMTcgMzZDMjYuODQ1IDM1Ljk5NiAyNy41MTEgMzQuMzIzIDI3LjUwOCAzMy40OTRDMjcuNTA1IDMyLjY2NSAyNi44MzEgMzEuOTk3IDI2LjAwMyAzMS45OTlDMjUuMTc1IDMyLjAwMyAyNC41MDUgMzIuNjc2IDI0LjUwOCAzMy41MDVaTTE5LjIzNyAzMS4wNTlDMTguOTExIDMxLjgyMyAxOC44NzIgMzMuNjIyIDE5LjYzMyAzMy45NDlDMjAuMzk2IDM0LjI3MyAyMS42NyAzMy4wMDIgMjEuOTk2IDMyLjIzOUMyMi4zMjEgMzEuNDc3IDIxLjk2OCAzMC41OTYgMjEuMjA3IDMwLjI2OUMyMC40NDUgMjkuOTQ0IDE5LjU2NCAzMC4yOTYgMTkuMjM3IDMxLjA1OVpNMTQuMjA2IDIwLjAxOUMxMy4zOTQgMjAuMTkxIDExLjg5OCAyMS4xOTIgMTIuMDY3IDIyLjAwMkMxMi4yNCAyMi44MTIgMTQuMDEyIDIzLjEyNiAxNC44MjQgMjIuOTU1QzE1LjYzNSAyMi43ODQgMTYuMTUzIDIxLjk4OCAxNS45ODQgMjEuMTc4QzE1LjgxMiAyMC4zNjggMTUuMDE5IDE5Ljg0OCAxNC4yMDYgMjAuMDE5Wk0xMi4xNjkgMTUuMDE5QzExLjM1NyAxNS4xOTEgOS44NjEwNCAxNi4xOTIgMTAuMDMgMTcuMDAyQzEwLjIwMyAxNy44MTIgMTEuOTc1IDE4LjEyNiAxMi43ODcgMTcuOTU1QzEzLjU5OCAxNy43ODQgMTQuMTE2IDE2Ljk4OCAxMy45NDcgMTYuMTc4QzEzLjc3NSAxNS4zNjggMTIuOTgxIDE0Ljg0OCAxMi4xNjkgMTUuMDE5WiIgZmlsbD0iIzc0NEVBQSIvPgo8cGF0aCBkPSJNMjcuNTc5MSAzNEMzMC40MSAzNCAzMi41MDUgMzMuMTIzIDMyLjg0NSAzMi45NzNDMzUuMTE2MSAzMS45NjMgMzYuMTM4MSAyOS4zMDQgMzUuMTI5MSAyNy4wMzRDMzQuMTMwMSAyNC43ODQgMzEuNTEzMSAyMy43NTkgMjkuMjU3MSAyNC43MkMyOS4xMjQxIDI0Ljc3IDI3LjQ2NDEgMjUuMzY5IDI1LjkxNDEgMjQuNjQ4QzI0LjA2MzEgMjMuNzg3IDIyLjkxOTEgMjEuMzM5IDIyLjI4NjEgMTkuNDM5QzIyLjE0MjEgMTkuMDA5IDIxLjkwMTEgMTguMTY1IDIxLjYgMTcuMTIzQzE5LjczNDEgMTAuNjUyIDE4Ljc2ODEgOC44Mzc5OSAxNy42MTcxIDcuMzAyOTlDMTMuOTA2IDIuMzUxOTkgOC4wMjUwNSAyLjAwNjk5IDUuMTM0MDUgMi41ODY5OUMyLjY5NzA1IDMuMDczOTkgMS4xMTYwNSA1LjQ0NDk5IDEuNjA0MDUgNy44ODE5OUMyLjA5MjA1IDEwLjMyIDQuNDY0MDUgMTEuOTAyIDYuOTAwMDUgMTEuNDEyQzcuMDYyMDUgMTEuMzg2IDkuMTA0MDUgMTEuMTA2IDEwLjMyNDEgMTIuNTgxQzEwLjk2NzEgMTMuODY4IDEyLjQwNDEgMTcuNzA5IDEyLjk1NDEgMTkuNjE1QzEzLjMwMDEgMjAuODE0IDEzLjU4MzEgMjEuNzg2IDEzLjc0ODEgMjIuMjgyQzE1LjUyMTEgMjcuNTk5IDE4LjQxNDEgMzEuMTc1IDIyLjM1MTEgMzIuOTExQzI0LjIwMzEgMzMuNzI5IDI2LjAwNTEgMzQgMjcuNTc5MSAzNFoiIGZpbGw9IiM5MjY2Q0MiLz4KPHBhdGggZD0iTTcuMDE3MDkgNkM3LjU2OTM3IDYgOC4wMTcwOSA1LjU1MjI4IDguMDE3MDkgNUM4LjAxNzA5IDQuNDQ3NzIgNy41NjkzNyA0IDcuMDE3MDkgNEM2LjQ2NDgxIDQgNi4wMTcwOSA0LjQ0NzcyIDYuMDE3MDkgNUM2LjAxNzA5IDUuNTUyMjggNi40NjQ4MSA2IDcuMDE3MDkgNloiIGZpbGw9IiMyMDIwMjQiLz4KPHBhdGggZD0iTTMxLjI1ODEgMzIuOTY0QzMxLjE2OTEgMzIuOTY0IDMxLjA3ODEgMzIuOTUyIDMwLjk4OTEgMzIuOTI4QzMwLjQ1NzEgMzIuNzggMzAuMTQ1MSAzMi4yMjkgMzAuMjkzMSAzMS42OTdDMzEuMDUwMSAyOC45NzUgMjkuNTIzMSAyNy4xNTUgMjkuNTA4MSAyNy4xMzdDMjkuMTQ5MSAyNi43MTggMjkuMTk2MSAyNi4wODYgMjkuNjE1MSAyNS43MjdDMzAuMDMzMSAyNS4zNjggMzAuNjY2MSAyNS40MTUgMzEuMDI1MSAyNS44MzRDMzEuMTE3MSAyNS45NDEgMzMuMjU5MSAyOC40OTQgMzIuMjIwMSAzMi4yMzFDMzIuMDk4MSAzMi42NzQgMzEuNjk1MSAzMi45NjQgMzEuMjU4MSAzMi45NjRaTTI0LjA1OTEgMzIuNDAxQzIzLjgxNDEgMzIuNDAxIDIzLjU2OTEgMzIuMzEyIDIzLjM3NTEgMzIuMTMxQzIyLjk3MjEgMzEuNzUzIDIyLjk1MTEgMzEuMTIgMjMuMzI4MSAzMC43MTdDMjQuODEzMSAyOS4xMyAyNC43ODExIDI2LjUyNCAyNC43ODAxIDI2LjQ5N0MyNC43NjQxIDI1Ljk0NSAyNS4xOTkxIDI1LjQ4NSAyNS43NTIxIDI1LjQ2OUMyNi4yOTQxIDI1LjQ2NCAyNi43NjUxIDI1Ljg4OCAyNi43ODAxIDI2LjQ0MUMyNi43ODQxIDI2LjU4IDI2Ljg1MzEgMjkuODc4IDI0Ljc4OTEgMzIuMDg1QzI0LjU5MjEgMzIuMjk1IDI0LjMyNTEgMzIuNDAxIDI0LjA1OTEgMzIuNDAxWk0xNS41MTcxIDIzLjcwNUMxNS4wMzcxIDIzLjcwNSAxNC42MTMxIDIzLjM1OCAxNC41MzIxIDIyLjg2OEMxNC40NDIxIDIyLjMyNCAxNC44MTAxIDIxLjgwOCAxNS4zNTUxIDIxLjcxOUMxOC40MjkxIDIxLjIwOSAyMC4xMjkxIDE5LjM0MiAyMC4xNDYxIDE5LjMyM0MyMC41MTExIDE4LjkxMyAyMS4xNDQxIDE4Ljg3NCAyMS41NTUxIDE5LjIzOUMyMS45NjcxIDE5LjYwNCAyMi4wMDgxIDIwLjIzMiAyMS42NDYxIDIwLjY0NUMyMS41NTkxIDIwLjc0NCAxOS40OTAxIDIzLjA2IDE1LjY4MjEgMjMuNjkxQzE1LjYyNjEgMjMuNzAxIDE1LjU3MTEgMjMuNzA1IDE1LjUxNzEgMjMuNzA1Wk0xOC40MzgxIDI4LjU2MkMxOC4wMTMxIDI4LjU2MiAxNy42MTkxIDI4LjI5IDE3LjQ4NDEgMjcuODY0QzE3LjMxODEgMjcuMzM4IDE3LjYxMDEgMjYuNzc1IDE4LjEzNjEgMjYuNjA5QzIwLjgyOTEgMjUuNzU2IDIyLjAxNjEgMjMuNzc5IDIyLjAyODEgMjMuNzU5QzIyLjMwODEgMjMuMjgyIDIyLjkyMDEgMjMuMTIyIDIzLjM5NjEgMjMuNDAyQzIzLjg3MzEgMjMuNjgxIDI0LjAzMjEgMjQuMjk1IDIzLjc1MzEgMjQuNzdDMjMuNjkwMSAyNC44NzggMjIuMTU4MSAyNy40MzMgMTguNzQwMSAyOC41MTRDMTguNjM5MSAyOC41NDcgMTguNTM3MSAyOC41NjIgMTguNDM4MSAyOC41NjJaTTEzLjgxOTEgMTcuODkyQzEzLjMyMzEgMTcuODkyIDEyLjg5MjEgMTcuNTIzIDEyLjgyODEgMTcuMDE3QzEyLjc1OTEgMTYuNDY5IDEzLjE0NzEgMTUuOTY5IDEzLjY5NTEgMTUuODk5QzE2LjM4NDEgMTUuNTU5IDE4LjM1MjEgMTMuOTI4IDE4LjM3MTEgMTMuOTExQzE4Ljc5MzEgMTMuNTU3IDE5LjQyNDEgMTMuNjA4IDE5Ljc3OTEgMTQuMDNDMjAuMTM1MSAxNC40NTEgMjAuMDg0MSAxNS4wOCAxOS42NjQxIDE1LjQzN0MxOS41NjcxIDE1LjUyIDE3LjI0NDEgMTcuNDY2IDEzLjk0NjEgMTcuODgzQzEzLjkwMzEgMTcuODg5IDEzLjg2MTEgMTcuODkyIDEzLjgxOTEgMTcuODkyWk0xMS45OTgxIDEzLjEyNUMxMS41NzMxIDEzLjEyNSAxMS4xNzkxIDEyLjg1MiAxMS4wNDQxIDEyLjQyNEMxMC44NzkxIDExLjg5NyAxMS4xNzExIDExLjMzNiAxMS42OTgxIDExLjE3QzE0LjgyODEgMTAuMTg3IDE1Ljk1MTEgOC40NzggMTUuOTk3MSA4LjQwNkMxNi4yOTIxIDcuOTQ0IDE2LjkwODEgNy44MDEgMTcuMzcyMSA4LjA5NEMxNy44MzcxIDguMzg2IDE3Ljk4MzEgOC45OTMgMTcuNjk2MSA5LjQ2QzE3LjYzNjEgOS41NTcgMTYuMTkwMSAxMS44NTYgMTIuMjk3MSAxMy4wNzlDMTIuMTk4MSAxMy4xMSAxMi4wOTcxIDEzLjEyNSAxMS45OTgxIDEzLjEyNVoiIGZpbGw9IiM3NDRFQUEiLz4KPC9zdmc+";
9
9
  var ideaImageUrl = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjMiIGhlaWdodD0iMzUiIHZpZXdCb3g9IjAgMCAyMyAzNSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTIyLjUgMTAuOTJDMjIuNSAxNy4zNTkgMTcuNSAxOC4zNTkgMTcuNSAyNC4zNkMxNy41IDI3LjQ1OCAxNC4zNzcgMjcuNzE5IDEyIDI3LjcxOUM5Ljk0NyAyNy43MTkgNS40MTQgMjYuOTQgNS40MTQgMjQuMzU4QzUuNDE0IDE4LjM2IDAuNSAxNy4zNiAwLjUgMTAuOTJDMC41IDQuODg5IDUuNzg1IDAgMTEuNTgzIDBDMTcuMzgzIDAgMjIuNSA0Ljg4OSAyMi41IDEwLjkyWiIgZmlsbD0iI0ZGREQ4MyIvPgo8cGF0aCBkPSJNMTUuNjY3IDMyLjM2QzE1LjY2NyAzMy4xODggMTMuNDMzIDM0Ljg2IDExLjUgMzQuODZDOS41NjcwMSAzNC44NiA3LjMzMzAxIDMzLjE4OCA3LjMzMzAxIDMyLjM2QzcuMzMzMDEgMzEuNTMyIDkuNTY2MDEgMzEuODYgMTEuNSAzMS44NkMxMy40MzMgMzEuODYgMTUuNjY3IDMxLjUzMiAxNS42NjcgMzIuMzZaIiBmaWxsPSIjQ0NENkREIi8+CjxwYXRoIGQ9Ik0xNi4yMDcgMTAuMTUzQzE1LjgxNiA5Ljc2MTk5IDE1LjE4NCA5Ljc2MTk5IDE0Ljc5MyAxMC4xNTNMMTEuNSAxMy40NDZMOC4yMDcwMSAxMC4xNTNDNy44MTYwMSA5Ljc2MTk5IDcuMTg0MDEgOS43NjE5OSA2Ljc5MzAxIDEwLjE1M0M2LjQwMjAxIDEwLjU0NCA2LjQwMjAxIDExLjE3NiA2Ljc5MzAxIDExLjU2N0wxMC41IDE1LjI3NFYyNS44NkMxMC41IDI2LjQxMyAxMC45NDggMjYuODYgMTEuNSAyNi44NkMxMi4wNTIgMjYuODYgMTIuNSAyNi40MTMgMTIuNSAyNS44NlYxNS4yNzRMMTYuMjA3IDExLjU2N0MxNi41OTggMTEuMTc2IDE2LjU5OCAxMC41NDQgMTYuMjA3IDEwLjE1M1oiIGZpbGw9IiNGRkNDNEQiLz4KPHBhdGggZD0iTTE3LjUgMzAuODZDMTcuNSAzMS45NjQgMTYuNjA0IDMyLjg2IDE1LjUgMzIuODZIOC41QzcuMzk2IDMyLjg2IDYuNSAzMS45NjQgNi41IDMwLjg2VjI0Ljg2SDE3LjVWMzAuODZaIiBmaWxsPSIjOTlBQUI1Ii8+CjxwYXRoIGQ9Ik01LjQ5OSAzMS44NkM1LjAxOSAzMS44NiA0LjU5NSAzMS41MTMgNC41MTQgMzEuMDI0QzQuNDIzIDMwLjQ4IDQuNzkxIDI5Ljk2NCA1LjMzNiAyOS44NzRMMTcuMzM2IDI3Ljg3NEMxNy44OCAyNy43NzYgMTguMzk2IDI4LjE1MSAxOC40ODYgMjguNjk2QzE4LjU3NyAyOS4yNCAxOC4yMDkgMjkuNzU2IDE3LjY2NCAyOS44NDZMOS42NjQgMzEuODQ2QzkuNjA5IDMxLjg1NiA5LjU1MyAzMS44NiA1LjQ5OSAzMS44NlpNNS40OTkgMjcuODZDNS4wMTkgMjcuODYgNC41OTUgMjcuNTEzIDQuNTE0IDI3LjAyNEM0LjQyMyAyNi40OCA0Ljc5MSAyNS45NjQgNS4zMzYgMjUuODc0TDE3LjMzNiAyMy44NzRDMTcuODggMjMuNzc3IDE4LjM5NiAyNC4xNTEgMTguNDg2IDI0LjY5NkMxOC41NzcgMjUuMjQgMTguMjA5IDI1Ljc1NiAxNy42NjQgMjUuODQ2TDkuNjY0IDI3Ljg0NkM5LjYwOSAyNy44NTYgOS41NTMgMjcuODYgNS40OTkgMjcuODZaIiBmaWxsPSIjQ0NENkREIi8+Cjwvc3ZnPg==";
10
10
  var thoughtImageUrl = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzYiIGhlaWdodD0iMzMiIHZpZXdCb3g9IjAgMCAzNiAzMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTM1LjE2NjYgMTAuODc1QzM1LjE2NjYgNy4wMDkgMzIuMDMyNiAzLjg3NSAyOC4xNjY2IDMuODc1QzI2Ljk5OTYgMy44NzUgMjUuOTAxNiA0LjE2NSAyNC45MzQ2IDQuNjY5QzIyLjg1MjYgMS44NDIgMTkuNTA5NiAwIDE1LjcyOTYgMEMxMC41OTc2IDAgNi4yNTQ2MyAzLjM4IDQuODA2NjMgOC4wMzZDMi4xNDg2MyA4LjY1MyAwLjE2NjYyNiAxMS4wMyAwLjE2NjYyNiAxMy44NzVDMC4xNjY2MjYgMTYuODU0IDIuMzQwNjMgMTkuMzIgNS4xODc2MyAxOS43ODhDNS40MDM2MyAyMy43MzcgOC42NjQ2MyAyNi44NzUgMTIuNjY2NiAyNi44NzVDMTQuODQyNiAyNi44NzUgMTYuNzk2NiAyNS45NDIgMTguMTY2NiAyNC40NjJDMTkuNTM2NiAyNS45NDIgMjEuNDg5NiAyNi44NzUgMjMuNjY2NiAyNi44NzVDMjcuODA5NiAyNi44NzUgMzEuMTY2NiAyMy41MTggMzEuMTY2NiAxOS4zNzVDMzEuMTY2NiAxOC42NjUgMzEuMDYxNiAxNy45ODEgMzAuODc3NiAxNy4zM0MzMy4zOTY2IDE2LjI3MSAzNS4xNjY2IDEzLjc4IDM1LjE2NjYgMTAuODc1WiIgZmlsbD0iIzg1QzhGOCIvPgo8cGF0aCBkPSJNNC4xNjY2MyAzMi44NzVDNS44MjM0OCAzMi44NzUgNy4xNjY2MyAzMS41MzE5IDcuMTY2NjMgMjkuODc1QzcuMTY2NjMgMjguMjE4MSA1LjgyMzQ4IDI2Ljg3NSA0LjE2NjYzIDI2Ljg3NUMuNTA5NzcgMjYuODc1IDEuMTY2NjMgMjguMjE4MSAxLjE2NjYzIDI5Ljg3NUMxLjE2NjYzIDMxLjUzMTkgMi41MDk3NyAzMi44NzUgNC4xNjY2MyAzMi44NzVaIiBmaWxsPSIjODVDOEY4Ii8+Cjwvc3ZnPg==";
11
- function CloseButton({ className = "", title = "Close feedback form" }) {
12
- return /* @__PURE__ */ jsx(Popover.Button, { className: `text-zinc-400 hover:text-zinc-100 ${className}`, title, children: /* @__PURE__ */ jsx(X, { weight: "bold", className: "w-4 h-4" }) });
11
+
12
+ // src/lib/theme.ts
13
+ function getThemeClasses(theme) {
14
+ return {
15
+ // Background colors - light mode is now softer (gray-50 instead of white)
16
+ bgPrimary: theme === "dark" ? "bg-zinc-900" : "bg-gray-50",
17
+ bgSecondary: theme === "dark" ? "bg-zinc-800" : "bg-gray-100",
18
+ bgTertiary: theme === "dark" ? "bg-zinc-700" : "bg-gray-200",
19
+ bgHover: theme === "dark" ? "hover:bg-zinc-600" : "hover:bg-gray-200",
20
+ bgHoverSecondary: theme === "dark" ? "hover:bg-zinc-700" : "hover:bg-gray-200",
21
+ // Text colors
22
+ textPrimary: theme === "dark" ? "text-zinc-100" : "text-gray-900",
23
+ textSecondary: theme === "dark" ? "text-zinc-300" : "text-gray-700",
24
+ textTertiary: theme === "dark" ? "text-zinc-400" : "text-gray-600",
25
+ textMuted: theme === "dark" ? "text-neutral-400" : "text-gray-500",
26
+ // Border colors
27
+ borderPrimary: theme === "dark" ? "border-zinc-700" : "border-gray-300",
28
+ borderSecondary: theme === "dark" ? "border-zinc-600" : "border-gray-300",
29
+ borderHover: theme === "dark" ? "hover:border-zinc-500" : "hover:border-gray-400",
30
+ // Canvas/Editor background
31
+ canvasBg: theme === "dark" ? "bg-zinc-900" : "bg-gray-200",
32
+ // Overlay
33
+ overlay: theme === "dark" ? "bg-black/80" : "bg-black/60",
34
+ // Focus ring offset
35
+ focusRingOffset: theme === "dark" ? "focus:ring-offset-zinc-900" : "focus:ring-offset-gray-50",
36
+ // Button variants
37
+ buttonSecondary: theme === "dark" ? "bg-zinc-800 hover:bg-zinc-700 text-zinc-100" : "bg-gray-200 hover:bg-gray-300 text-gray-900",
38
+ buttonTertiary: theme === "dark" ? "bg-zinc-700 hover:bg-zinc-600 text-zinc-100" : "bg-gray-300 hover:bg-gray-400 text-gray-900",
39
+ // Icon colors - make icons more visible (darker for better contrast)
40
+ iconColor: theme === "dark" ? "text-zinc-100" : "text-gray-900"
41
+ };
42
+ }
43
+ function getDefaultTheme() {
44
+ if (typeof process !== "undefined" && process.env.NEXT_PUBLIC_FEEDBACK_THEME === "light") {
45
+ return "light";
46
+ }
47
+ return "dark";
48
+ }
49
+ function CloseButton({ className = "", title = "Close feedback form", theme = "dark" }) {
50
+ const themeClasses = getThemeClasses(theme);
51
+ return /* @__PURE__ */ jsx(Popover.Button, { className: `${themeClasses.textTertiary} ${theme === "dark" ? "hover:text-zinc-100" : "hover:text-gray-900"} ${className}`, title, children: /* @__PURE__ */ jsx(X, { weight: "bold", className: "w-5 h-5" }) });
13
52
  }
14
53
 
15
54
  // src/lib/translations.ts
@@ -64,24 +103,25 @@ var translations = {
64
103
  function getTranslations(lang = "en") {
65
104
  return translations[lang];
66
105
  }
67
- function FeedbackTypeStep({ onFeedbackTypeChanged, language }) {
106
+ function FeedbackTypeStep({ onFeedbackTypeChanged, language, theme }) {
68
107
  const t = getTranslations(language);
69
108
  const feedbackTypes = getFeedbackTypes(language);
109
+ const themeClasses = getThemeClasses(theme);
70
110
  return /* @__PURE__ */ jsxs(Fragment, { children: [
71
111
  /* @__PURE__ */ jsxs("header", { className: "flex items-center justify-between w-full gap-2", children: [
72
- /* @__PURE__ */ jsx("span", { className: "text-xl leading-6", children: t.form.header }),
73
- /* @__PURE__ */ jsx(CloseButton, { title: t.form.closeButton })
112
+ /* @__PURE__ */ jsx("span", { className: `text-lg md:text-xl leading-6 ${themeClasses.textPrimary}`, children: t.form.header }),
113
+ /* @__PURE__ */ jsx(CloseButton, { title: t.form.closeButton, theme })
74
114
  ] }),
75
- /* @__PURE__ */ jsx("div", { className: "flex py-8 gap-2 w-full", children: Object.entries(feedbackTypes).map(([key, value]) => {
115
+ /* @__PURE__ */ jsx("div", { className: "flex py-6 md:py-8 gap-2 md:gap-2 w-full justify-center md:justify-start flex-wrap", children: Object.entries(feedbackTypes).map(([key, value]) => {
76
116
  return /* @__PURE__ */ jsxs(
77
117
  "button",
78
118
  {
79
- className: "bg-zinc-800 rounded py-5 w-24 flex1 flex flex-col items-center gap-2 border-2 border-transparent hover:border-brand-500 focus:border-brand-500 focus:outline-none",
119
+ className: `${themeClasses.bgSecondary} rounded py-4 md:py-5 flex-1 min-w-[80px] md:w-24 flex flex-col items-center gap-2 border-2 border-transparent hover:border-brand-500 focus:border-brand-500 focus:outline-none transition-colors`,
80
120
  type: "button",
81
121
  onClick: () => onFeedbackTypeChanged(key),
82
122
  children: [
83
- /* @__PURE__ */ jsx("img", { src: value.image.source, alt: value.image.alt }),
84
- /* @__PURE__ */ jsx("span", { children: value.title })
123
+ /* @__PURE__ */ jsx("img", { src: value.image.source, alt: value.image.alt, className: "w-5 h-5 md:w-6 md:h-6" }),
124
+ /* @__PURE__ */ jsx("span", { className: `text-xs md:text-sm text-center ${themeClasses.textPrimary}`, children: value.title })
85
125
  ]
86
126
  },
87
127
  key
@@ -92,41 +132,398 @@ function FeedbackTypeStep({ onFeedbackTypeChanged, language }) {
92
132
  function Loading() {
93
133
  return /* @__PURE__ */ jsx("div", { className: "w-4 h-4 flex items-center justify-center overflow-hidden ", children: /* @__PURE__ */ jsx(CircleNotch, { weight: "bold", className: "w-4 h-4 animate-spin" }) });
94
134
  }
135
+ function ScreenshotEditor({
136
+ screenshot,
137
+ onSave,
138
+ onCancel,
139
+ language,
140
+ theme = "dark"
141
+ }) {
142
+ const canvasRef = useRef(null);
143
+ const [isDrawing, setIsDrawing] = useState(false);
144
+ const [color, setColor] = useState("#ef4444");
145
+ const [brushSize, setBrushSize] = useState(3);
146
+ const [image, setImage] = useState(null);
147
+ const themeClasses = getThemeClasses(theme);
148
+ const t = {
149
+ en: {
150
+ save: "Save",
151
+ cancel: "Cancel",
152
+ clear: "Clear",
153
+ undo: "Undo"
154
+ },
155
+ nl: {
156
+ save: "Opslaan",
157
+ cancel: "Annuleren",
158
+ clear: "Wissen",
159
+ undo: "Ongedaan maken"
160
+ }
161
+ }[language];
162
+ const colors = [
163
+ "#ef4444",
164
+ // red-500
165
+ "#f59e0b",
166
+ // amber-500
167
+ "#eab308",
168
+ // yellow-500
169
+ "#22c55e",
170
+ // green-500
171
+ "#3b82f6",
172
+ // blue-500
173
+ "#8b5cf6",
174
+ // violet-500
175
+ "#ec4899",
176
+ // pink-500
177
+ "#ffffff",
178
+ // white
179
+ "#000000"
180
+ // black
181
+ ];
182
+ useEffect(() => {
183
+ const img = new Image();
184
+ img.onload = () => {
185
+ setImage(img);
186
+ if (canvasRef.current) {
187
+ const canvas = canvasRef.current;
188
+ canvas.width = img.width;
189
+ canvas.height = img.height;
190
+ const ctx = canvas.getContext("2d");
191
+ if (ctx) {
192
+ ctx.drawImage(img, 0, 0);
193
+ }
194
+ }
195
+ };
196
+ img.src = screenshot;
197
+ }, [screenshot]);
198
+ const getCoordinates = useCallback((e) => {
199
+ const canvas = canvasRef.current;
200
+ if (!canvas) return { x: 0, y: 0 };
201
+ const rect = canvas.getBoundingClientRect();
202
+ const scaleX = canvas.width / rect.width;
203
+ const scaleY = canvas.height / rect.height;
204
+ if ("touches" in e) {
205
+ const touch = e.touches[0] || e.changedTouches[0];
206
+ return {
207
+ x: (touch.clientX - rect.left) * scaleX,
208
+ y: (touch.clientY - rect.top) * scaleY
209
+ };
210
+ } else {
211
+ return {
212
+ x: (e.clientX - rect.left) * scaleX,
213
+ y: (e.clientY - rect.top) * scaleY
214
+ };
215
+ }
216
+ }, []);
217
+ const startDrawing = useCallback((e) => {
218
+ e.preventDefault();
219
+ const canvas = canvasRef.current;
220
+ if (!canvas) return;
221
+ const ctx = canvas.getContext("2d");
222
+ if (!ctx) return;
223
+ const { x, y } = getCoordinates(e);
224
+ setIsDrawing(true);
225
+ ctx.beginPath();
226
+ ctx.moveTo(x, y);
227
+ ctx.strokeStyle = color;
228
+ ctx.lineWidth = brushSize;
229
+ ctx.lineCap = "round";
230
+ ctx.lineJoin = "round";
231
+ }, [color, brushSize, getCoordinates]);
232
+ const draw = useCallback((e) => {
233
+ if (!isDrawing) return;
234
+ e.preventDefault();
235
+ const canvas = canvasRef.current;
236
+ if (!canvas) return;
237
+ const ctx = canvas.getContext("2d");
238
+ if (!ctx) return;
239
+ const { x, y } = getCoordinates(e);
240
+ ctx.lineTo(x, y);
241
+ ctx.stroke();
242
+ }, [isDrawing, getCoordinates]);
243
+ const stopDrawing = useCallback(() => {
244
+ setIsDrawing(false);
245
+ }, []);
246
+ const clearCanvas = () => {
247
+ const canvas = canvasRef.current;
248
+ if (!canvas || !image) return;
249
+ const ctx = canvas.getContext("2d");
250
+ if (!ctx) return;
251
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
252
+ ctx.drawImage(image, 0, 0);
253
+ };
254
+ const undo = () => {
255
+ const canvas = canvasRef.current;
256
+ if (!canvas || !image) return;
257
+ const ctx = canvas.getContext("2d");
258
+ if (!ctx) return;
259
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
260
+ ctx.drawImage(image, 0, 0);
261
+ };
262
+ const handleSave = () => {
263
+ const canvas = canvasRef.current;
264
+ if (!canvas) return;
265
+ const editedScreenshot = canvas.toDataURL("image/png");
266
+ onSave(editedScreenshot);
267
+ };
268
+ const maxWidth = 600;
269
+ const displayWidth = image ? Math.min(maxWidth, image.width) : maxWidth;
270
+ const displayHeight = image ? displayWidth / image.width * image.height : 400;
271
+ return /* @__PURE__ */ jsx("div", { className: `fixed inset-0 z-50 flex items-center justify-center ${themeClasses.overlay} p-2 md:p-4`, children: /* @__PURE__ */ jsxs("div", { className: `${themeClasses.bgSecondary} rounded-lg shadow-xl max-w-4xl w-full max-h-[95vh] md:max-h-[90vh] overflow-auto`, children: [
272
+ /* @__PURE__ */ jsxs("div", { className: `sticky top-0 ${themeClasses.bgSecondary} border-b ${themeClasses.borderPrimary} p-2 md:p-4 flex items-center justify-between z-10 gap-2`, children: [
273
+ /* @__PURE__ */ jsx("h3", { className: `text-base md:text-lg font-semibold ${themeClasses.textPrimary} truncate`, children: language === "nl" ? "Teken op screenshot" : "Draw on screenshot" }),
274
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1 md:gap-2 flex-shrink-0", children: [
275
+ /* @__PURE__ */ jsx(
276
+ "button",
277
+ {
278
+ type: "button",
279
+ onClick: undo,
280
+ className: `p-1.5 md:p-2 ${themeClasses.buttonTertiary} rounded-md ${themeClasses.textPrimary} transition-colors touch-manipulation`,
281
+ title: t.undo,
282
+ children: /* @__PURE__ */ jsx(ArrowCounterClockwise, { weight: "bold", className: "w-4 h-4 md:w-5 md:h-5" })
283
+ }
284
+ ),
285
+ /* @__PURE__ */ jsx(
286
+ "button",
287
+ {
288
+ type: "button",
289
+ onClick: clearCanvas,
290
+ className: `p-1.5 md:p-2 ${themeClasses.buttonTertiary} rounded-md ${themeClasses.textPrimary} transition-colors touch-manipulation`,
291
+ title: t.clear,
292
+ children: /* @__PURE__ */ jsx(Trash, { weight: "bold", className: "w-4 h-4 md:w-5 md:h-5" })
293
+ }
294
+ ),
295
+ /* @__PURE__ */ jsx(
296
+ "button",
297
+ {
298
+ type: "button",
299
+ onClick: onCancel,
300
+ className: `p-1.5 md:p-2 ${themeClasses.buttonTertiary} rounded-md ${themeClasses.textPrimary} transition-colors touch-manipulation`,
301
+ title: t.cancel,
302
+ children: /* @__PURE__ */ jsx(X, { weight: "bold", className: "w-4 h-4 md:w-5 md:h-5" })
303
+ }
304
+ ),
305
+ /* @__PURE__ */ jsx(
306
+ "button",
307
+ {
308
+ type: "button",
309
+ onClick: handleSave,
310
+ className: "p-1.5 md:p-2 bg-brand-500 hover:bg-brand-400 rounded-md text-white transition-colors touch-manipulation",
311
+ title: t.save,
312
+ children: /* @__PURE__ */ jsx(Check, { weight: "bold", className: "w-4 h-4 md:w-5 md:h-5" })
313
+ }
314
+ )
315
+ ] })
316
+ ] }),
317
+ /* @__PURE__ */ jsxs("div", { className: "p-3 md:p-4", children: [
318
+ /* @__PURE__ */ jsxs("div", { className: "mb-3 md:mb-4 flex flex-col md:flex-row items-start md:items-center gap-2 md:gap-4", children: [
319
+ /* @__PURE__ */ jsx("label", { className: `text-xs md:text-sm ${themeClasses.textSecondary} whitespace-nowrap`, children: language === "nl" ? "Kleur:" : "Color:" }),
320
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5 md:gap-2 flex-wrap", children: colors.map((c) => /* @__PURE__ */ jsx(
321
+ "button",
322
+ {
323
+ type: "button",
324
+ onClick: () => setColor(c),
325
+ className: `w-7 h-7 md:w-8 md:h-8 rounded-full border-2 transition-all touch-manipulation ${color === c ? `${theme === "dark" ? "border-zinc-100" : "border-gray-900"} scale-110` : `${themeClasses.borderSecondary} ${themeClasses.borderHover}`}`,
326
+ style: { backgroundColor: c },
327
+ title: c
328
+ },
329
+ c
330
+ )) })
331
+ ] }),
332
+ /* @__PURE__ */ jsxs("div", { className: "mb-3 md:mb-4 flex flex-col md:flex-row items-start md:items-center gap-2 md:gap-4", children: [
333
+ /* @__PURE__ */ jsx("label", { className: `text-xs md:text-sm ${themeClasses.textSecondary} whitespace-nowrap`, children: language === "nl" ? "Grootte:" : "Size:" }),
334
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-full md:w-auto", children: [
335
+ /* @__PURE__ */ jsx(
336
+ "input",
337
+ {
338
+ type: "range",
339
+ min: "1",
340
+ max: "10",
341
+ value: brushSize,
342
+ onChange: (e) => setBrushSize(Number(e.target.value)),
343
+ className: "flex-1 md:flex-none md:max-w-xs"
344
+ }
345
+ ),
346
+ /* @__PURE__ */ jsx("span", { className: `text-xs md:text-sm ${themeClasses.textTertiary} w-6 md:w-8 text-right`, children: brushSize })
347
+ ] })
348
+ ] }),
349
+ /* @__PURE__ */ jsx("div", { className: `flex justify-center ${themeClasses.canvasBg} rounded-lg p-2 md:p-4 overflow-auto`, children: /* @__PURE__ */ jsx(
350
+ "canvas",
351
+ {
352
+ ref: canvasRef,
353
+ onMouseDown: startDrawing,
354
+ onMouseMove: draw,
355
+ onMouseUp: stopDrawing,
356
+ onMouseLeave: stopDrawing,
357
+ onTouchStart: startDrawing,
358
+ onTouchMove: draw,
359
+ onTouchEnd: stopDrawing,
360
+ className: `cursor-crosshair border ${themeClasses.borderPrimary} rounded touch-none`,
361
+ style: {
362
+ width: `${displayWidth}px`,
363
+ height: `${displayHeight}px`,
364
+ maxWidth: "100%",
365
+ maxHeight: "calc(95vh - 200px)"
366
+ }
367
+ }
368
+ ) })
369
+ ] })
370
+ ] }) });
371
+ }
95
372
  function ScreenshotButton({
96
373
  screenshot,
97
- onScreenshotTook
374
+ onScreenshotTook,
375
+ language = "en",
376
+ theme = "dark"
98
377
  }) {
99
378
  const [isTakenScreenshot, setIsTakenScreenShot] = useState(false);
379
+ const [showEditor, setShowEditor] = useState(false);
380
+ const [tempScreenshot, setTempScreenshot] = useState(null);
381
+ const themeClasses = getThemeClasses(theme);
100
382
  async function handleTakeScreenshot() {
101
383
  setIsTakenScreenShot(true);
102
- const canvas = await html2canvas(document.querySelector("html"));
384
+ const canvas = await html2canvas(document.querySelector("html"), {
385
+ ignoreElements: (element) => {
386
+ return element.hasAttribute("data-feedback-widget") || element.closest("[data-feedback-widget]") !== null;
387
+ }
388
+ });
103
389
  const base64image = canvas.toDataURL("image/png");
104
390
  onScreenshotTook(base64image);
105
391
  setIsTakenScreenShot(false);
106
392
  }
393
+ function handleEditorSave(editedScreenshot) {
394
+ onScreenshotTook(editedScreenshot);
395
+ setShowEditor(false);
396
+ setTempScreenshot(null);
397
+ }
398
+ function handleEditorCancel() {
399
+ setShowEditor(false);
400
+ setTempScreenshot(null);
401
+ }
402
+ function handleEditScreenshot() {
403
+ if (screenshot) {
404
+ setTempScreenshot(screenshot);
405
+ setShowEditor(true);
406
+ }
407
+ }
408
+ if (showEditor && (tempScreenshot || screenshot)) {
409
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
410
+ /* @__PURE__ */ jsx(
411
+ ScreenshotEditor,
412
+ {
413
+ screenshot: tempScreenshot || screenshot,
414
+ onSave: handleEditorSave,
415
+ onCancel: handleEditorCancel,
416
+ language,
417
+ theme
418
+ }
419
+ ),
420
+ screenshot ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
421
+ /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
422
+ /* @__PURE__ */ jsx(
423
+ "div",
424
+ {
425
+ className: `p-1 w-10 h-10 rounded-md border ${themeClasses.borderSecondary} flex
426
+ justify-end items-end relative overflow-hidden`,
427
+ style: {
428
+ backgroundImage: `url(${screenshot})`,
429
+ backgroundPosition: "center",
430
+ backgroundSize: "cover"
431
+ },
432
+ children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors rounded-md" })
433
+ }
434
+ ),
435
+ /* @__PURE__ */ jsx(
436
+ "button",
437
+ {
438
+ type: "button",
439
+ onClick: (e) => {
440
+ e.stopPropagation();
441
+ onScreenshotTook(null);
442
+ },
443
+ className: "absolute -top-1 -right-1 w-4 h-4 bg-red-500 hover:bg-red-600 rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity z-10",
444
+ title: language === "nl" ? "Verwijderen" : "Delete",
445
+ children: /* @__PURE__ */ jsx(X, { weight: "bold", className: "w-3 h-3 text-white" })
446
+ }
447
+ )
448
+ ] }),
449
+ /* @__PURE__ */ jsx(
450
+ "button",
451
+ {
452
+ type: "button",
453
+ onClick: handleEditScreenshot,
454
+ className: `p-2 ${themeClasses.bgSecondary} rounded-md border-transparent ${themeClasses.bgHoverSecondary}
455
+ transition-colors focus:outline-none focus:ring-2
456
+ focus:ring-offset-2 ${themeClasses.focusRingOffset} focus:ring-brand-500`,
457
+ title: language === "nl" ? "Bewerk screenshot" : "Edit screenshot",
458
+ children: /* @__PURE__ */ jsx(PencilSimple, { weight: "bold", className: `w-5 h-5 ${themeClasses.textPrimary}` })
459
+ }
460
+ )
461
+ ] }) : /* @__PURE__ */ jsx(
462
+ "button",
463
+ {
464
+ type: "button",
465
+ className: `p-2 ${themeClasses.bgSecondary} rounded-md border-transparent ${themeClasses.bgHoverSecondary}
466
+ transition-colors focus:outline-none focus:ring-2
467
+ focus:ring-offset-2 ${themeClasses.focusRingOffset} focus:ring-brand-500`,
468
+ onClick: handleTakeScreenshot,
469
+ children: isTakenScreenshot ? /* @__PURE__ */ jsx(Loading, {}) : /* @__PURE__ */ jsx(Camera, { weight: "bold", className: `w-6 h-6 ${themeClasses.iconColor}` })
470
+ }
471
+ )
472
+ ] });
473
+ }
107
474
  if (screenshot) {
108
- return /* @__PURE__ */ jsx(
109
- "button",
110
- {
111
- type: "button",
112
- className: "p-1 w-10 h-10 rounded-md border-transparent flex \n justify-end items-end text-zinc-400 hover:text-zinc-100 transition-colors",
113
- onClick: () => onScreenshotTook(null),
114
- style: {
115
- backgroundImage: `url(${screenshot})`,
116
- backgroundPosition: "right bottom",
117
- backgroundSize: 180
118
- },
119
- children: /* @__PURE__ */ jsx(Trash, { weight: "fill" })
120
- }
121
- );
475
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
476
+ /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
477
+ /* @__PURE__ */ jsx(
478
+ "div",
479
+ {
480
+ className: `p-1 w-10 h-10 rounded-md border ${themeClasses.borderSecondary} flex
481
+ justify-end items-end relative overflow-hidden`,
482
+ style: {
483
+ backgroundImage: `url(${screenshot})`,
484
+ backgroundPosition: "center",
485
+ backgroundSize: "cover"
486
+ },
487
+ children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/10 transition-colors rounded-md" })
488
+ }
489
+ ),
490
+ /* @__PURE__ */ jsx(
491
+ "button",
492
+ {
493
+ type: "button",
494
+ onClick: (e) => {
495
+ e.stopPropagation();
496
+ onScreenshotTook(null);
497
+ },
498
+ className: "absolute -top-1 -right-1 w-4 h-4 bg-red-500 hover:bg-red-600 rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity z-10",
499
+ title: language === "nl" ? "Verwijderen" : "Delete",
500
+ children: /* @__PURE__ */ jsx(X, { weight: "bold", className: "w-3 h-3 text-white" })
501
+ }
502
+ )
503
+ ] }),
504
+ /* @__PURE__ */ jsx(
505
+ "button",
506
+ {
507
+ type: "button",
508
+ onClick: handleEditScreenshot,
509
+ className: `p-2 ${themeClasses.bgSecondary} rounded-md border-transparent ${themeClasses.bgHoverSecondary}
510
+ transition-colors focus:outline-none focus:ring-2
511
+ focus:ring-offset-2 ${themeClasses.focusRingOffset} focus:ring-brand-500`,
512
+ title: language === "nl" ? "Bewerk screenshot" : "Edit screenshot",
513
+ children: /* @__PURE__ */ jsx(PencilSimple, { weight: "bold", className: `w-5 h-5 ${themeClasses.textPrimary}` })
514
+ }
515
+ )
516
+ ] });
122
517
  }
123
518
  return /* @__PURE__ */ jsx(
124
519
  "button",
125
520
  {
126
521
  type: "button",
127
- className: "p-2 bg-zinc-800 rounded-md border-transparent hover:bg-zinc-700\n transitions-colors focus:outline-none focus:ring-2\n focus:ring-offset-2 focus:ring-offset-zinc-900 focus:ring-brand-500",
522
+ className: `p-2 ${themeClasses.bgSecondary} rounded-md border-transparent ${themeClasses.bgHoverSecondary}
523
+ transitions-colors focus:outline-none focus:ring-2
524
+ focus:ring-offset-2 ${themeClasses.focusRingOffset} focus:ring-brand-500`,
128
525
  onClick: handleTakeScreenshot,
129
- children: isTakenScreenshot ? /* @__PURE__ */ jsx(Loading, {}) : /* @__PURE__ */ jsx(Camera, { weight: "bold", className: "w-6 h-6" })
526
+ children: isTakenScreenshot ? /* @__PURE__ */ jsx(Loading, {}) : /* @__PURE__ */ jsx(Camera, { weight: "bold", className: `w-6 h-6 ${themeClasses.iconColor}` })
130
527
  }
131
528
  );
132
529
  }
@@ -138,10 +535,12 @@ function FileUploadButton({
138
535
  maxFileSize = DEFAULT_MAX_FILE_SIZE,
139
536
  maxTotalSize = DEFAULT_MAX_TOTAL_SIZE,
140
537
  acceptedTypes = "image/*,.pdf,.doc,.docx,.txt",
141
- language = "en"
538
+ language = "en",
539
+ theme = "dark"
142
540
  }) {
143
541
  const fileInputRef = useRef(null);
144
542
  const [error, setError] = useState(null);
543
+ const themeClasses = getThemeClasses(theme);
145
544
  const translations2 = {
146
545
  en: {
147
546
  upload: "Upload file",
@@ -227,10 +626,12 @@ function FileUploadButton({
227
626
  "button",
228
627
  {
229
628
  type: "button",
230
- className: "p-2 bg-zinc-800 rounded-md border-transparent hover:bg-zinc-700\n transitions-colors focus:outline-none focus:ring-2\n focus:ring-offset-2 focus:ring-offset-zinc-900 focus:ring-brand-500",
629
+ className: `p-2 ${themeClasses.bgSecondary} rounded-md border-transparent ${themeClasses.bgHoverSecondary}
630
+ transitions-colors focus:outline-none focus:ring-2
631
+ focus:ring-offset-2 ${themeClasses.focusRingOffset} focus:ring-brand-500`,
231
632
  onClick: handleButtonClick,
232
633
  title: t.upload,
233
- children: /* @__PURE__ */ jsx(Paperclip, { weight: "bold", className: "w-6 h-6" })
634
+ children: /* @__PURE__ */ jsx(Paperclip, { weight: "bold", className: `w-6 h-6 ${themeClasses.iconColor}` })
234
635
  }
235
636
  ),
236
637
  /* @__PURE__ */ jsx(
@@ -247,25 +648,25 @@ function FileUploadButton({
247
648
  files.map((uploadedFile) => /* @__PURE__ */ jsxs(
248
649
  "div",
249
650
  {
250
- className: "flex items-center gap-1 bg-zinc-800 rounded-md px-2 py-1 text-xs",
651
+ className: `flex items-center gap-1 ${themeClasses.bgSecondary} rounded-md px-2 py-1 text-xs`,
251
652
  children: [
252
653
  uploadedFile.preview ? /* @__PURE__ */ jsx(
253
654
  "img",
254
655
  {
255
656
  src: uploadedFile.preview,
256
657
  alt: uploadedFile.file.name,
257
- className: "w-6 h-6 object-cover rounded"
658
+ className: "w-5 h-5 md:w-6 md:h-6 object-cover rounded flex-shrink-0"
258
659
  }
259
- ) : /* @__PURE__ */ jsx(Paperclip, { className: "w-4 h-4" }),
260
- /* @__PURE__ */ jsx("span", { className: "text-zinc-300 max-w-[100px] truncate", title: uploadedFile.file.name, children: uploadedFile.file.name }),
660
+ ) : /* @__PURE__ */ jsx(Paperclip, { className: `w-3 h-3 md:w-4 md:h-4 flex-shrink-0 ${themeClasses.iconColor}` }),
661
+ /* @__PURE__ */ jsx("span", { className: `${themeClasses.textSecondary} max-w-[80px] md:max-w-[100px] truncate`, title: uploadedFile.file.name, children: uploadedFile.file.name }),
261
662
  /* @__PURE__ */ jsx(
262
663
  "button",
263
664
  {
264
665
  type: "button",
265
666
  onClick: () => handleRemoveFile(uploadedFile.id),
266
- className: "text-zinc-400 hover:text-zinc-100 transition-colors",
667
+ className: `${themeClasses.textTertiary} ${theme === "dark" ? "hover:text-zinc-100" : "hover:text-gray-900"} transition-colors flex-shrink-0 touch-manipulation`,
267
668
  title: t.remove,
268
- children: /* @__PURE__ */ jsx(X, { weight: "bold", className: "w-4 h-4" })
669
+ children: /* @__PURE__ */ jsx(X, { weight: "bold", className: "w-3 h-3 md:w-4 md:h-4" })
269
670
  }
270
671
  )
271
672
  ]
@@ -274,7 +675,7 @@ function FileUploadButton({
274
675
  ))
275
676
  ] }),
276
677
  error && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-400", children: error }),
277
- files.length > 0 && /* @__PURE__ */ jsxs("p", { className: "text-xs text-zinc-400", children: [
678
+ files.length > 0 && /* @__PURE__ */ jsxs("p", { className: `text-xs ${themeClasses.textTertiary}`, children: [
278
679
  files.length,
279
680
  " ",
280
681
  t.files,
@@ -799,10 +1200,12 @@ function FeedbackContentStep({
799
1200
  onFeedbackSent,
800
1201
  integration,
801
1202
  githubConfig,
802
- language
1203
+ language,
1204
+ theme
803
1205
  }) {
804
1206
  const t = getTranslations(language);
805
1207
  const feedbackTypes = getFeedbackTypes(language);
1208
+ const themeClasses = getThemeClasses(theme);
806
1209
  const [screenshot, setScreenshot] = useState(null);
807
1210
  const [uploadedFiles, setUploadedFiles] = useState([]);
808
1211
  const feedbackTypeData = feedbackTypes[feedbackType];
@@ -841,34 +1244,38 @@ function FeedbackContentStep({
841
1244
  }
842
1245
  }
843
1246
  return /* @__PURE__ */ jsxs(Fragment, { children: [
844
- /* @__PURE__ */ jsxs("header", { className: "relative w-full pr-8", children: [
1247
+ /* @__PURE__ */ jsxs("header", { className: "relative w-full", children: [
845
1248
  /* @__PURE__ */ jsx(
846
1249
  "button",
847
1250
  {
848
1251
  type: "button",
849
- className: "absolute top-5 left-5 text-zinc-400 hover:text-zinc-100 z-10",
1252
+ className: `absolute top-0 left-0 ${themeClasses.textTertiary} ${theme === "dark" ? "hover:text-zinc-100" : "hover:text-gray-900"} z-10 p-2 md:p-2.5`,
850
1253
  onClick: onFeedbackRestartRequest,
851
- children: /* @__PURE__ */ jsx(ArrowLeft, { weight: "bold", className: "w-4 h-4" })
1254
+ children: /* @__PURE__ */ jsx(ArrowLeft, { weight: "bold", className: "w-5 h-5 md:w-5 md:h-5" })
852
1255
  }
853
1256
  ),
854
- /* @__PURE__ */ jsxs("span", { className: "text-xl leading-6 flex items-center gap-2 mt-2 pl-10", children: [
1257
+ /* @__PURE__ */ jsxs("span", { className: `text-lg md:text-xl leading-6 flex items-center gap-2 pl-10 md:pl-12 pr-10 md:pr-12 ${themeClasses.textPrimary}`, children: [
855
1258
  /* @__PURE__ */ jsx(
856
1259
  "img",
857
1260
  {
858
1261
  src: feedbackTypeData.image.source,
859
1262
  alt: feedbackTypeData.image.alt,
860
- className: "w-6 h-6"
1263
+ className: "w-5 h-5 md:w-6 md:h-6"
861
1264
  }
862
1265
  ),
863
1266
  feedbackTypeData.title
864
1267
  ] }),
865
- /* @__PURE__ */ jsx(CloseButton, { className: "absolute top-5 right-5", title: t.form.closeButton })
1268
+ /* @__PURE__ */ jsx(CloseButton, { className: "absolute top-0 right-0 p-2 md:p-2.5", title: t.form.closeButton, theme })
866
1269
  ] }),
867
- /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmitFeedback, className: "my-4 w-full", children: [
1270
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmitFeedback, className: "my-3 md:my-4 w-full", children: [
868
1271
  /* @__PURE__ */ jsx(
869
1272
  "textarea",
870
1273
  {
871
- className: "min-w-[384px] w-full min-h-[112px] text-sm \n placeholder-zinc-400 text-zinc-100 border-zinc-600 bg-transparent rounded-md \n focus:border-brand-500 focus:ring-brand-500 focus:ring-1 resize-none focus:outline-none\n scrollbar-thumb-zinc-700 scrollbar-track-transparent scrollbar-thin",
1274
+ className: `w-full min-h-[100px] md:min-h-[112px] text-sm
1275
+ ${themeClasses.textPrimary} border-2 border-brand-500 bg-transparent rounded-md p-2 md:p-3
1276
+ ${theme === "dark" ? "placeholder:text-zinc-400" : "placeholder:text-gray-500"}
1277
+ focus:border-brand-500 focus:ring-brand-500 focus:ring-1 resize-none focus:outline-none
1278
+ ${theme === "dark" ? "scrollbar-thumb-zinc-700" : "scrollbar-thumb-gray-400"} scrollbar-track-transparent scrollbar-thin`,
872
1279
  placeholder: t.content.placeholder,
873
1280
  onChange: (e) => setComment(e.target.value)
874
1281
  }
@@ -878,15 +1285,18 @@ function FeedbackContentStep({
878
1285
  {
879
1286
  files: uploadedFiles,
880
1287
  onFilesChanged: setUploadedFiles,
881
- language
1288
+ language,
1289
+ theme
882
1290
  }
883
1291
  ) }),
884
- /* @__PURE__ */ jsxs("footer", { className: " flex gap-2 mt-2", children: [
1292
+ /* @__PURE__ */ jsxs("footer", { className: "flex gap-2 mt-3", children: [
885
1293
  /* @__PURE__ */ jsx(
886
1294
  ScreenshotButton,
887
1295
  {
888
1296
  screenshot,
889
- onScreenshotTook: setScreenshot
1297
+ onScreenshotTook: setScreenshot,
1298
+ language,
1299
+ theme
890
1300
  }
891
1301
  ),
892
1302
  /* @__PURE__ */ jsx(
@@ -894,7 +1304,11 @@ function FeedbackContentStep({
894
1304
  {
895
1305
  type: "submit",
896
1306
  disabled: comment.length === 0 || isSendingFeedback,
897
- className: "p-2 bg-brand-500 rounded-md border-transparent flex-1 justify-center\n items-center text-sm hover:bg-brand-300 focus:outline-none focus:ring-2\n focus:ring-offset-2 focus:ring-offset-zinc-900 focus:ring-brand-500\n transition-colors disabled:opacity-50 disabled:cursor-not-allowed\n disabled:hover:bg-brand-500",
1307
+ className: `p-2 bg-brand-500 rounded-md border-transparent flex-1 justify-center
1308
+ items-center text-sm hover:bg-brand-300 focus:outline-none focus:ring-2
1309
+ focus:ring-offset-2 ${themeClasses.focusRingOffset} focus:ring-brand-500
1310
+ transition-colors disabled:opacity-50 disabled:cursor-not-allowed
1311
+ disabled:hover:bg-brand-500 flex text-white`,
898
1312
  children: isSendingFeedback ? /* @__PURE__ */ jsx(Loading, {}) : t.content.sendButton
899
1313
  }
900
1314
  )
@@ -902,22 +1316,23 @@ function FeedbackContentStep({
902
1316
  ] })
903
1317
  ] });
904
1318
  }
905
- function FeedbackSuccessStep({ onFeedbackRestartRequest, language }) {
1319
+ function FeedbackSuccessStep({ onFeedbackRestartRequest, language, theme }) {
906
1320
  const t = getTranslations(language);
1321
+ const themeClasses = getThemeClasses(theme);
907
1322
  return /* @__PURE__ */ jsxs(Fragment, { children: [
908
- /* @__PURE__ */ jsx("header", { children: /* @__PURE__ */ jsx(CloseButton, { title: t.form.closeButton }) }),
909
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center py-10 w-[304px]", children: [
910
- /* @__PURE__ */ jsxs("svg", { width: "41", height: "40", viewBox: "0 0 41 40", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
1323
+ /* @__PURE__ */ jsx("header", { children: /* @__PURE__ */ jsx(CloseButton, { title: t.form.closeButton, theme }) }),
1324
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center py-8 md:py-10 w-full max-w-[304px] px-2", children: [
1325
+ /* @__PURE__ */ jsxs("svg", { width: "41", height: "40", viewBox: "0 0 41 40", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "w-10 h-10 md:w-[41px] md:h-[40px]", children: [
911
1326
  /* @__PURE__ */ jsx("path", { d: "M38.5 34C38.5 36.209 36.709 38 34.5 38H6.5C4.291 38 2.5 36.209 2.5 34V6C2.5 3.791 4.291 2 6.5 2H34.5C36.709 2 38.5 3.791 38.5 6V34Z", fill: "#77B255" }),
912
1327
  /* @__PURE__ */ jsx("path", { d: "M31.78 8.36202C30.624 7.61102 29.076 7.94002 28.322 9.09802L17.436 25.877L12.407 21.227C11.393 20.289 9.81103 20.352 8.87403 21.365C7.93703 22.379 7.99903 23.961 9.01303 24.898L16.222 31.564C16.702 32.009 17.312 32.229 17.918 32.229C18.591 32.229 19.452 31.947 20.017 31.09C20.349 30.584 32.517 11.82 32.517 11.82C33.268 10.661 32.938 9.11302 31.78 8.36202Z", fill: "white" })
913
1328
  ] }),
914
- /* @__PURE__ */ jsx("span", { className: "text-xl mt-2", children: t.success.message }),
1329
+ /* @__PURE__ */ jsx("span", { className: `text-lg md:text-xl mt-2 text-center ${themeClasses.textPrimary}`, children: t.success.message }),
915
1330
  /* @__PURE__ */ jsx(
916
1331
  "button",
917
1332
  {
918
1333
  type: "button",
919
1334
  onClick: onFeedbackRestartRequest,
920
- className: "py-2 px-6 mt-6 bg-zinc-800 rounded-md border-transparent text-sm leading-6 hover:bg-zinc-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-zinc-900 focus:ring-brand-500 transition-colors",
1335
+ className: `py-2 px-6 mt-6 ${themeClasses.buttonSecondary} rounded-md border-transparent text-sm leading-6 focus:outline-none focus:ring-2 focus:ring-offset-2 ${themeClasses.focusRingOffset} focus:ring-brand-500 transition-colors`,
921
1336
  children: t.success.sendAnother
922
1337
  }
923
1338
  )
@@ -950,15 +1365,16 @@ function getFeedbackTypes(language = "en") {
950
1365
  }
951
1366
  };
952
1367
  }
953
- function WidgetForm({ integration, githubConfig, language }) {
1368
+ function WidgetForm({ integration, githubConfig, language, theme }) {
954
1369
  const [feedbackType, setFeedbackType] = useState(null);
955
1370
  const [feedbackSent, setFeedbackSent] = useState(false);
1371
+ const themeClasses = getThemeClasses(theme);
956
1372
  function handleRestartFeedback() {
957
1373
  setFeedbackSent(false);
958
1374
  setFeedbackType(null);
959
1375
  }
960
- return /* @__PURE__ */ jsxs("div", { className: "bg-zinc-900 p-4 relative rounded-2xl mb-4 flex flex-col items-center shadow-lg w-[calc(100vw-2rem)] md:w-auto", children: [
961
- feedbackSent ? /* @__PURE__ */ jsx(FeedbackSuccessStep, { onFeedbackRestartRequest: handleRestartFeedback, language }) : /* @__PURE__ */ jsx(Fragment, { children: !feedbackType ? /* @__PURE__ */ jsx(FeedbackTypeStep, { onFeedbackTypeChanged: setFeedbackType, language }) : /* @__PURE__ */ jsx(
1376
+ return /* @__PURE__ */ jsxs("div", { className: `${themeClasses.bgPrimary} p-3 md:p-4 relative rounded-2xl mb-4 flex flex-col items-center shadow-lg w-[calc(100vw-2rem)] md:w-auto md:min-w-[384px] max-w-md`, children: [
1377
+ feedbackSent ? /* @__PURE__ */ jsx(FeedbackSuccessStep, { onFeedbackRestartRequest: handleRestartFeedback, language, theme }) : /* @__PURE__ */ jsx(Fragment, { children: !feedbackType ? /* @__PURE__ */ jsx(FeedbackTypeStep, { onFeedbackTypeChanged: setFeedbackType, language, theme }) : /* @__PURE__ */ jsx(
962
1378
  FeedbackContentStep,
963
1379
  {
964
1380
  feedbackType,
@@ -966,10 +1382,11 @@ function WidgetForm({ integration, githubConfig, language }) {
966
1382
  onFeedbackSent: () => setFeedbackSent(true),
967
1383
  integration,
968
1384
  githubConfig,
969
- language
1385
+ language,
1386
+ theme
970
1387
  }
971
1388
  ) }),
972
- /* @__PURE__ */ jsx("footer", { className: "text-xs text-neutral-400", children: /* @__PURE__ */ jsx(
1389
+ /* @__PURE__ */ jsx("footer", { className: `text-xs ${themeClasses.textMuted} mt-2`, children: /* @__PURE__ */ jsx(
973
1390
  "a",
974
1391
  {
975
1392
  className: "underline underline-offset-2",
@@ -987,13 +1404,25 @@ function getDefaultLanguage() {
987
1404
  }
988
1405
  return "en";
989
1406
  }
1407
+ function isWidgetEnabled() {
1408
+ if (typeof process !== "undefined" && process.env.NEXT_PUBLIC_FEEDBACK_ENABLED !== void 0) {
1409
+ const enabled = process.env.NEXT_PUBLIC_FEEDBACK_ENABLED.toLowerCase();
1410
+ return enabled !== "false" && enabled !== "0";
1411
+ }
1412
+ return true;
1413
+ }
990
1414
  function Widget({
991
1415
  integration,
992
1416
  githubConfig,
993
1417
  position = "bottom-right",
994
- language
1418
+ language,
1419
+ theme
995
1420
  }) {
1421
+ if (!isWidgetEnabled()) {
1422
+ return null;
1423
+ }
996
1424
  const finalLanguage = language || getDefaultLanguage();
1425
+ const finalTheme = theme || getDefaultTheme();
997
1426
  const t = getTranslations(finalLanguage);
998
1427
  const positionClasses = {
999
1428
  "bottom-right": "bottom-4 right-4 md:bottom-8 md:right-8",
@@ -1001,24 +1430,28 @@ function Widget({
1001
1430
  "top-right": "top-4 right-4 md:top-8 md:right-8",
1002
1431
  "top-left": "top-4 left-4 md:top-8 md:left-4"
1003
1432
  };
1004
- const alignmentClass = position.includes("left") ? "items-start" : "items-end";
1005
- return /* @__PURE__ */ jsxs(Popover, { className: `fixed ${positionClasses[position]} flex flex-col ${alignmentClass} z-50`, children: [
1006
- /* @__PURE__ */ jsx(Popover.Panel, { children: /* @__PURE__ */ jsx(
1433
+ const isTop = position.includes("top");
1434
+ const isLeft = position.includes("left");
1435
+ const panelPositionClass = isTop ? "absolute top-full mt-2" : "absolute bottom-full mb-2";
1436
+ const panelAlignmentClass = isLeft ? "left-0" : "right-0";
1437
+ return /* @__PURE__ */ jsx("div", { "data-feedback-widget": "true", className: `fixed ${positionClasses[position]} z-50`, children: /* @__PURE__ */ jsxs(Popover, { className: "relative", children: [
1438
+ /* @__PURE__ */ jsx(Popover.Panel, { className: `${panelPositionClass} ${panelAlignmentClass}`, children: /* @__PURE__ */ jsx(
1007
1439
  WidgetForm,
1008
1440
  {
1009
1441
  integration,
1010
1442
  githubConfig,
1011
- language: finalLanguage
1443
+ language: finalLanguage,
1444
+ theme: finalTheme
1012
1445
  }
1013
1446
  ) }),
1014
- /* @__PURE__ */ jsxs(Popover.Button, { className: "bg-brand-500 rounded-full px-3 h-12 text-white flex items-center group focus:outline-none", children: [
1015
- /* @__PURE__ */ jsx(ChatTeardropDots, { className: "w-6 h-6" }),
1016
- /* @__PURE__ */ jsxs("span", { className: "max-w-0 overflow-hidden group-hover:max-w-xs transition-all duration-500 ease-linear", children: [
1447
+ /* @__PURE__ */ jsxs(Popover.Button, { className: "bg-brand-500 rounded-full px-3 md:px-3 h-12 text-white flex items-center group focus:outline-none shadow-lg hover:shadow-xl transition-shadow", children: [
1448
+ /* @__PURE__ */ jsx(ChatTeardropDots, { className: "w-6 h-6 flex-shrink-0" }),
1449
+ /* @__PURE__ */ jsxs("span", { className: "max-w-0 overflow-hidden group-hover:max-w-xs md:group-hover:max-w-xs transition-all duration-500 ease-linear hidden md:block", children: [
1017
1450
  /* @__PURE__ */ jsx("span", { className: "pl-2" }),
1018
1451
  t.widget.button
1019
1452
  ] })
1020
1453
  ] })
1021
- ] });
1454
+ ] }) });
1022
1455
  }
1023
1456
 
1024
1457
  export { Widget };