react-visual-feedback 1.4.0 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +306 -12
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -139,6 +139,24 @@ function App() {
|
|
|
139
139
|
| `isActive` | `boolean` | - | Controlled active state |
|
|
140
140
|
| `onActiveChange` | `(active) => void` | - | Callback for controlled mode |
|
|
141
141
|
|
|
142
|
+
### FeedbackDashboard Props
|
|
143
|
+
|
|
144
|
+
| Prop | Type | Default | Description |
|
|
145
|
+
|------|------|---------|-------------|
|
|
146
|
+
| `isOpen` | `boolean` | required | Control dashboard visibility |
|
|
147
|
+
| `onClose` | `() => void` | required | Callback when dashboard closes |
|
|
148
|
+
| `data` | `Array` | - | Feedback data (uses localStorage if undefined) |
|
|
149
|
+
| `isDeveloper` | `boolean` | `false` | Enable developer mode with delete |
|
|
150
|
+
| `isUser` | `boolean` | `true` | Enable user mode |
|
|
151
|
+
| `onStatusChange` | `({id, status, comment}) => void` | - | Callback when status changes |
|
|
152
|
+
| `mode` | `'light' \| 'dark'` | `'light'` | Theme mode |
|
|
153
|
+
| `isLoading` | `boolean` | `false` | Show loading state |
|
|
154
|
+
| `onRefresh` | `() => void` | - | Callback for refresh button |
|
|
155
|
+
| `title` | `string` | `'Feedback'` | Dashboard title |
|
|
156
|
+
| `statuses` | `object` | `DEFAULT_STATUSES` | Custom status configurations |
|
|
157
|
+
| `showAllStatuses` | `boolean` | `true` | Show all statuses in filter |
|
|
158
|
+
| `error` | `string` | `null` | Error message to display |
|
|
159
|
+
|
|
142
160
|
### useFeedback Hook
|
|
143
161
|
|
|
144
162
|
```jsx
|
|
@@ -553,22 +571,223 @@ app.patch('/api/feedback/:id/status', async (req, res) => {
|
|
|
553
571
|
|
|
554
572
|
| Shortcut | Action |
|
|
555
573
|
|----------|--------|
|
|
556
|
-
| `Alt+Q` | Activate feedback mode |
|
|
574
|
+
| `Alt+Q` | Activate feedback mode (element selection) |
|
|
575
|
+
| `Alt+W` | Start screen recording |
|
|
557
576
|
| `Alt+Shift+Q` | Open dashboard |
|
|
558
577
|
| `Esc` | Cancel/close |
|
|
559
578
|
|
|
560
|
-
## Status
|
|
579
|
+
## Status System
|
|
580
|
+
|
|
581
|
+
### Default Statuses
|
|
582
|
+
|
|
583
|
+
| Key | Label | Color | Icon |
|
|
584
|
+
|-----|-------|-------|------|
|
|
585
|
+
| `new` | New | Purple (#8b5cf6) | Inbox |
|
|
586
|
+
| `open` | Open | Amber (#f59e0b) | AlertCircle |
|
|
587
|
+
| `inProgress` | In Progress | Blue (#3b82f6) | Play |
|
|
588
|
+
| `underReview` | Under Review | Cyan (#06b6d4) | Eye |
|
|
589
|
+
| `onHold` | On Hold | Gray (#6b7280) | PauseCircle |
|
|
590
|
+
| `resolved` | Resolved | Green (#10b981) | CheckCircle |
|
|
591
|
+
| `closed` | Closed | Slate (#64748b) | Archive |
|
|
592
|
+
| `wontFix` | Won't Fix | Red (#ef4444) | Ban |
|
|
593
|
+
|
|
594
|
+
### Custom Statuses
|
|
595
|
+
|
|
596
|
+
You control which statuses are available. Pass your own `statuses` object to `FeedbackDashboard`. The widget will only show the statuses you provide:
|
|
597
|
+
|
|
598
|
+
```jsx
|
|
599
|
+
import { FeedbackDashboard } from 'react-visual-feedback';
|
|
600
|
+
|
|
601
|
+
// Define ONLY the statuses you want to show
|
|
602
|
+
const myStatuses = {
|
|
603
|
+
pending: {
|
|
604
|
+
key: 'pending',
|
|
605
|
+
label: 'Pending Review',
|
|
606
|
+
color: '#f59e0b',
|
|
607
|
+
bgColor: '#fef3c7',
|
|
608
|
+
textColor: '#92400e',
|
|
609
|
+
icon: 'AlertCircle'
|
|
610
|
+
},
|
|
611
|
+
approved: {
|
|
612
|
+
key: 'approved',
|
|
613
|
+
label: 'Approved',
|
|
614
|
+
color: '#10b981',
|
|
615
|
+
bgColor: '#d1fae5',
|
|
616
|
+
textColor: '#065f46',
|
|
617
|
+
icon: 'CheckCircle'
|
|
618
|
+
},
|
|
619
|
+
rejected: {
|
|
620
|
+
key: 'rejected',
|
|
621
|
+
label: 'Rejected',
|
|
622
|
+
color: '#ef4444',
|
|
623
|
+
bgColor: '#fee2e2',
|
|
624
|
+
textColor: '#991b1b',
|
|
625
|
+
icon: 'Ban'
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
<FeedbackDashboard
|
|
630
|
+
isOpen={true}
|
|
631
|
+
statuses={myStatuses} // Only these 3 statuses will be shown
|
|
632
|
+
// ... other props
|
|
633
|
+
/>
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
#### Extending Default Statuses
|
|
637
|
+
|
|
638
|
+
If you want to keep the defaults and add more:
|
|
639
|
+
|
|
640
|
+
```jsx
|
|
641
|
+
import { DEFAULT_STATUSES } from 'react-visual-feedback';
|
|
642
|
+
|
|
643
|
+
const extendedStatuses = {
|
|
644
|
+
...DEFAULT_STATUSES,
|
|
645
|
+
// Add new status
|
|
646
|
+
testing: {
|
|
647
|
+
key: 'testing',
|
|
648
|
+
label: 'In Testing',
|
|
649
|
+
color: '#8b5cf6',
|
|
650
|
+
bgColor: '#ede9fe',
|
|
651
|
+
textColor: '#6d28d9',
|
|
652
|
+
icon: 'Bug'
|
|
653
|
+
},
|
|
654
|
+
// Override existing
|
|
655
|
+
resolved: {
|
|
656
|
+
...DEFAULT_STATUSES.resolved,
|
|
657
|
+
label: 'Fixed & Deployed'
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
### Status Object Structure
|
|
663
|
+
|
|
664
|
+
```typescript
|
|
665
|
+
interface StatusConfig {
|
|
666
|
+
key: string; // Unique identifier
|
|
667
|
+
label: string; // Display name in UI
|
|
668
|
+
color: string; // Border and icon color (hex)
|
|
669
|
+
bgColor: string; // Background color (hex)
|
|
670
|
+
textColor: string; // Text color (hex)
|
|
671
|
+
icon: string; // Icon name from available icons
|
|
672
|
+
}
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
### Available Icons
|
|
676
|
+
|
|
677
|
+
The following icons from Lucide React are available for custom statuses:
|
|
678
|
+
|
|
679
|
+
| Icon Name | Description |
|
|
680
|
+
|-----------|-------------|
|
|
681
|
+
| `Inbox` | New items |
|
|
682
|
+
| `AlertCircle` | Warnings/alerts |
|
|
683
|
+
| `Play` | In progress |
|
|
684
|
+
| `Eye` | Under review |
|
|
685
|
+
| `PauseCircle` | Paused/on hold |
|
|
686
|
+
| `CheckCircle` | Completed/resolved |
|
|
687
|
+
| `Archive` | Archived/closed |
|
|
688
|
+
| `Ban` | Rejected/won't fix |
|
|
689
|
+
| `XCircle` | Cancelled |
|
|
690
|
+
| `HelpCircle` | Questions |
|
|
691
|
+
| `Lightbulb` | Ideas/features |
|
|
692
|
+
| `Bug` | Bug reports |
|
|
693
|
+
| `Zap` | Quick actions |
|
|
694
|
+
| `MessageSquare` | Comments |
|
|
695
|
+
|
|
696
|
+
### Status Utility Functions
|
|
697
|
+
|
|
698
|
+
```jsx
|
|
699
|
+
import {
|
|
700
|
+
getStatusData, // Get status config with safe defaults
|
|
701
|
+
getIconComponent, // Get icon component from name
|
|
702
|
+
normalizeStatusKey, // Normalize status key to available options
|
|
703
|
+
StatusBadge, // Status badge component
|
|
704
|
+
StatusDropdown // Status dropdown component
|
|
705
|
+
} from 'react-visual-feedback';
|
|
706
|
+
|
|
707
|
+
// Get status data with fallbacks for missing properties
|
|
708
|
+
const statusData = getStatusData('inProgress', customStatuses);
|
|
709
|
+
// Returns: { key, label, color, bgColor, textColor, icon }
|
|
710
|
+
|
|
711
|
+
// Get icon component from string name
|
|
712
|
+
const Icon = getIconComponent('CheckCircle');
|
|
713
|
+
// Returns: Lucide React component
|
|
714
|
+
|
|
715
|
+
// Normalize various status formats to valid keys
|
|
716
|
+
const key = normalizeStatusKey('in_progress', customStatuses);
|
|
717
|
+
// Returns: 'inProgress'
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
### Status Key Normalization
|
|
561
721
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
|
565
|
-
|
|
566
|
-
|
|
|
567
|
-
|
|
|
568
|
-
|
|
|
569
|
-
|
|
|
570
|
-
|
|
|
571
|
-
|
|
|
722
|
+
The widget automatically normalizes various status key formats:
|
|
723
|
+
|
|
724
|
+
| Input | Normalized To |
|
|
725
|
+
|-------|---------------|
|
|
726
|
+
| `reported`, `submitted`, `pending` | `new` |
|
|
727
|
+
| `doing`, `in_progress` | `inProgress` |
|
|
728
|
+
| `review`, `under_review` | `underReview` |
|
|
729
|
+
| `hold`, `on_hold`, `paused` | `onHold` |
|
|
730
|
+
| `done`, `fixed`, `completed` | `resolved` |
|
|
731
|
+
| `archived` | `closed` |
|
|
732
|
+
| `rejected`, `wont_fix`, `cancelled` | `wontFix` |
|
|
733
|
+
|
|
734
|
+
## Next.js Usage
|
|
735
|
+
|
|
736
|
+
This package uses browser-only APIs and requires client-side rendering. Use dynamic import with `ssr: false`:
|
|
737
|
+
|
|
738
|
+
```tsx
|
|
739
|
+
// providers/FeedbackProviderClient.tsx
|
|
740
|
+
'use client';
|
|
741
|
+
|
|
742
|
+
import dynamic from 'next/dynamic';
|
|
743
|
+
|
|
744
|
+
const FeedbackProvider = dynamic(
|
|
745
|
+
() => import('react-visual-feedback').then((mod) => mod.FeedbackProvider),
|
|
746
|
+
{ ssr: false }
|
|
747
|
+
);
|
|
748
|
+
|
|
749
|
+
export default function FeedbackProviderClient({
|
|
750
|
+
children,
|
|
751
|
+
...props
|
|
752
|
+
}: {
|
|
753
|
+
children: React.ReactNode;
|
|
754
|
+
[key: string]: any;
|
|
755
|
+
}) {
|
|
756
|
+
return (
|
|
757
|
+
<FeedbackProvider {...props}>
|
|
758
|
+
{children}
|
|
759
|
+
</FeedbackProvider>
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
Then use in your layout:
|
|
765
|
+
|
|
766
|
+
```tsx
|
|
767
|
+
// app/layout.tsx
|
|
768
|
+
import FeedbackProviderClient from './providers/FeedbackProviderClient';
|
|
769
|
+
|
|
770
|
+
export default function RootLayout({ children }) {
|
|
771
|
+
return (
|
|
772
|
+
<html>
|
|
773
|
+
<body>
|
|
774
|
+
<FeedbackProviderClient
|
|
775
|
+
onSubmit={async (data) => {
|
|
776
|
+
await fetch('/api/feedback', {
|
|
777
|
+
method: 'POST',
|
|
778
|
+
body: JSON.stringify(data)
|
|
779
|
+
});
|
|
780
|
+
}}
|
|
781
|
+
dashboard={true}
|
|
782
|
+
mode="light"
|
|
783
|
+
>
|
|
784
|
+
{children}
|
|
785
|
+
</FeedbackProviderClient>
|
|
786
|
+
</body>
|
|
787
|
+
</html>
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
```
|
|
572
791
|
|
|
573
792
|
## Browser Support
|
|
574
793
|
|
|
@@ -577,6 +796,81 @@ app.patch('/api/feedback/:id/status', async (req, res) => {
|
|
|
577
796
|
- Safari
|
|
578
797
|
- Opera
|
|
579
798
|
|
|
799
|
+
## All Exports
|
|
800
|
+
|
|
801
|
+
```jsx
|
|
802
|
+
import {
|
|
803
|
+
// Core components
|
|
804
|
+
FeedbackProvider,
|
|
805
|
+
FeedbackModal,
|
|
806
|
+
FeedbackDashboard,
|
|
807
|
+
FeedbackTrigger,
|
|
808
|
+
CanvasOverlay,
|
|
809
|
+
|
|
810
|
+
// Hooks
|
|
811
|
+
useFeedback,
|
|
812
|
+
|
|
813
|
+
// Status components
|
|
814
|
+
StatusBadge,
|
|
815
|
+
StatusDropdown,
|
|
816
|
+
|
|
817
|
+
// Status utilities
|
|
818
|
+
getStatusData,
|
|
819
|
+
getIconComponent,
|
|
820
|
+
normalizeStatusKey,
|
|
821
|
+
DEFAULT_STATUSES,
|
|
822
|
+
|
|
823
|
+
// Storage utilities
|
|
824
|
+
saveFeedbackToLocalStorage,
|
|
825
|
+
|
|
826
|
+
// Theme utilities
|
|
827
|
+
getTheme,
|
|
828
|
+
lightTheme,
|
|
829
|
+
darkTheme,
|
|
830
|
+
|
|
831
|
+
// General utilities
|
|
832
|
+
getElementInfo,
|
|
833
|
+
captureElementScreenshot,
|
|
834
|
+
getReactComponentInfo,
|
|
835
|
+
formatPath
|
|
836
|
+
} from 'react-visual-feedback';
|
|
837
|
+
```
|
|
838
|
+
|
|
839
|
+
## Changelog
|
|
840
|
+
|
|
841
|
+
### v1.4.2
|
|
842
|
+
- **Fixed**: Modal state not resetting after submission (was showing "Sending..." on reopen)
|
|
843
|
+
- **Added**: `Alt+W` keyboard shortcut for video recording
|
|
844
|
+
- **Improved**: Custom status documentation - clarified that users control which statuses appear
|
|
845
|
+
- **Fixed**: Prevented double submission by checking `isSubmitting` state
|
|
846
|
+
|
|
847
|
+
### v1.4.1
|
|
848
|
+
- **Fixed**: `Cannot read properties of undefined (reading 'icon')` error when status data is malformed
|
|
849
|
+
- **Added**: `getStatusData()` utility function for safe status access with defaults
|
|
850
|
+
- **Improved**: Defensive null checks in StatusBadge, StatusDropdown, and FeedbackDashboard
|
|
851
|
+
- **Added**: Export of status utility functions for custom implementations
|
|
852
|
+
|
|
853
|
+
### v1.4.0
|
|
854
|
+
- **Added**: Screen recording with session replay
|
|
855
|
+
- **Added**: Console and network log capture during recording
|
|
856
|
+
- **Added**: Session replay component with expandable logs panel
|
|
857
|
+
- **Improved**: Dashboard UI with video playback support
|
|
858
|
+
|
|
859
|
+
### v1.3.0
|
|
860
|
+
- **Added**: Canvas drawing and annotation support
|
|
861
|
+
- **Added**: Download all feedback as ZIP
|
|
862
|
+
|
|
863
|
+
### v1.2.0
|
|
864
|
+
- **Added**: Custom status configurations
|
|
865
|
+
- **Added**: Status normalization for various formats
|
|
866
|
+
|
|
867
|
+
### v1.1.0
|
|
868
|
+
- **Added**: Dark mode support
|
|
869
|
+
- **Added**: Developer/User mode views
|
|
870
|
+
|
|
871
|
+
### v1.0.0
|
|
872
|
+
- Initial release with element selection and screenshot capture
|
|
873
|
+
|
|
580
874
|
## License
|
|
581
875
|
|
|
582
876
|
MIT
|