18/implement standardized social share button#23
18/implement standardized social share button#23dark-Invincible wants to merge 2 commits intoStabilityNexus:mainfrom
Conversation
…am, and LinkedIn - Implemented ShareButton component with modal UI - Added social sharing utilities with intent URLs - Integrated share button in Details and Home pages - Added accessibility features (ARIA labels, keyboard navigation) - Included comprehensive type safety and error handling - Added URL encoding and sanitization - Responsive design with mobile optimization
WalkthroughA production-ready social sharing feature is introduced for Bene FundRaising EVM Frontend, adding support for Twitter/X, Telegram, and LinkedIn. The implementation includes a new Changes
Sequence DiagramsequenceDiagram
participant User
participant ShareButton
participant Modal
participant Platform as Share Platform<br/>(Twitter/TG/LinkedIn)
participant Clipboard
User->>ShareButton: Click share button
ShareButton->>Modal: Open modal with platform options
User->>Modal: Select platform or copy link
alt Share to Platform
Modal->>ShareButton: Generate share URL
ShareButton->>ShareButton: Validate & sanitize content
ShareButton->>Platform: Open popup with share intent
Platform->>User: Prompt to complete share
else Copy Link
Modal->>ShareButton: Copy URL to clipboard
ShareButton->>Clipboard: Use Clipboard API or fallback
Clipboard-->>ShareButton: Success indicator
ShareButton->>Modal: Show success feedback
end
Modal->>User: Close & fire callback
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
SHARE_FEATURE.md (1)
107-131: Specify language identifiers for fenced code blocks.Similar to SHARE_FEATURE_TESTING.md, the fenced code blocks need language specifiers for proper rendering.
🧹 Nitpick comments (3)
src/utils/socialShare.test.reference.ts (1)
1-89: Good test reference structure, but implement actual tests.This test reference file provides excellent coverage of edge cases and validation scenarios. However, as a
.test.reference.tsfile, these tests won't be executed by the test runner.Consider renaming this file to
socialShare.test.tsand setting up the testing infrastructure (Jest/Vitest) to run these tests. The test cases cover important scenarios including:
- URL validation and construction
- Hashtag inclusion
- Error handling for empty/invalid inputs
- Text truncation and sanitization
Would you like me to help generate a proper test setup?
src/ShareButton.tsx (2)
82-87: Consider removing fallback values that mask missing data.The
useMemoprovides fallback values ('Untitled Campaign', 'Check out this campaign!') for missing title/description, which could mask data issues and result in sharing generic content instead of failing early.Consider one of these approaches:
- Let validation fail early if title/description are missing (rely on validateShareContent in utilities)
- Disable the share button when required data is missing
- Document that fallbacks are intentional for partial data scenarios
Current implementation may lead to users sharing generic, unhelpful content if data is incomplete.
433-444: Consider extracting inline styles to CSS file or Tailwind config.The inline
<style>tag with @Keyframes animation works but is duplicated each time the component is mounted.Consider moving this to:
- A global CSS file
- Tailwind config (using custom animations)
- CSS modules
This would reduce duplication and improve maintainability, though the current approach is functional.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
IMPLEMENTATION_SUMMARY.md(1 hunks)SHARE_FEATURE.md(1 hunks)SHARE_FEATURE_TESTING.md(1 hunks)src/Details.tsx(2 hunks)src/Home.tsx(2 hunks)src/ShareButton.tsx(1 hunks)src/utils/socialShare.test.reference.ts(1 hunks)src/utils/socialShare.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/ShareButton.tsx (1)
src/utils/socialShare.ts (5)
ShareContent(7-16)generateTwitterShareUrl(75-92)generateTelegramShareUrl(100-115)generateLinkedInShareUrl(123-134)copyToClipboard(141-178)
src/utils/socialShare.test.reference.ts (1)
src/utils/socialShare.ts (5)
ShareContent(7-16)generateTwitterShareUrl(75-92)generateTelegramShareUrl(100-115)generateLinkedInShareUrl(123-134)copyToClipboard(141-178)
🪛 markdownlint-cli2 (0.18.1)
SHARE_FEATURE.md
107-107: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
119-119: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
124-124: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
129-129: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (19)
SHARE_FEATURE_TESTING.md (1)
1-297: LGTM! Comprehensive testing checklist.The testing documentation is thorough and covers all critical aspects including functional tests, accessibility, security, performance, and integration testing. This will be valuable for QA validation.
src/Home.tsx (2)
9-9: LGTM! ShareButton imported correctly.The import statement is clean and follows the project's import conventions.
91-107: LGTM! Well-structured integration with proper conditional rendering.The ShareButton integration is well-implemented with:
- Proper conditional rendering checks for required data
- Appropriate URL construction for campaign details
- Icon-only mode for compact display in cards
- Custom styling that matches the card design
src/Details.tsx (2)
14-14: LGTM! ShareButton imported correctly.
154-166: LGTM! Clean integration with proper conditional rendering.The ShareButton is well-integrated into the Details page with:
- Proper flex layout for title and share button
- Conditional rendering based on data availability
- Appropriate use of current page URL for sharing
src/ShareButton.tsx (6)
10-47: LGTM! Well-documented interface with comprehensive props.The ShareButtonProps interface is well-structured with:
- Clear JSDoc comments for each property
- Appropriate required vs optional properties
- Flexible customization options
- Type-safe callback signatures
66-79: LGTM! Proper URL validation with error handling.The URL validation effect correctly:
- Uses native URL constructor for validation
- Falls back to current page URL if not provided
- Handles errors gracefully with user feedback
- Invokes error callback for external tracking
106-114: Good popup blocking detection and error handling.The window.open error handling correctly:
- Detects when popup is blocked (returns null)
- Provides clear error message to user
- Maintains error state for display
153-170: LGTM! Proper cleanup and accessibility.The keyboard and scroll management effect correctly:
- Adds/removes event listeners
- Manages body scroll lock
- Returns cleanup function
- Handles ESC key for modal closure
180-206: LGTM! Accessible button with proper attributes.The share button includes:
- Proper aria-label for screen readers
- Disabled state handling
- Title attribute for tooltips
- Visual icon representation
210-259: LGTM! Accessible modal structure.The modal implementation includes:
- Click-outside-to-close with stopPropagation on modal content
- Close button with aria-label
- Error display with role="alert"
- Proper visual feedback
SHARE_FEATURE.md (1)
1-258: LGTM! Excellent feature documentation.The documentation is comprehensive and well-organized, covering:
- Clear usage examples
- Complete API reference
- Integration points
- Security considerations
- Accessibility features
- Troubleshooting guidance
This will be valuable for developers integrating and maintaining this feature.
src/utils/socialShare.ts (6)
48-54: LGTM! Text sanitization handles newlines appropriately.The sanitizeText function correctly:
- Trims whitespace
- Replaces newlines with spaces for URL compatibility
- Limits text length
- Re-trims after slicing
61-67: LGTM! Hashtag sanitization is appropriate.The function correctly:
- Filters empty hashtags
- Removes special characters (allowing only alphanumeric)
- Limits to 5 hashtags
- Removes whitespace
75-92: LGTM! Twitter URL generation follows platform guidelines.The implementation correctly:
- Validates content first
- Respects Twitter's ~280 character limit with truncation
- Includes organization branding
- Properly encodes parameters
100-115: LGTM! Telegram URL generation is correct.The implementation properly constructs Telegram share URLs with appropriate text formatting and parameter encoding.
123-134: LGTM! LinkedIn URL generation is correct.LinkedIn's share endpoint correctly receives only the URL parameter as per their API specification.
141-178: LGTM! Robust clipboard implementation with fallback.The copyToClipboard function includes:
- Early return for empty text
- Modern Clipboard API usage with secure context check
- Fallback using execCommand for older browsers
- Proper cleanup of DOM elements
- Comprehensive error handling
IMPLEMENTATION_SUMMARY.md (1)
1-335: LGTM! Comprehensive implementation summary.The implementation summary provides:
- Clear overview of deliverables
- Quality assurance checklist
- Integration details with code examples
- Deployment readiness assessment
- Known limitations and future enhancements
This documentation will be valuable for project stakeholders and reviewers to understand the scope and quality of the implementation.
| ### Visual Indicators | ||
| - [ ] All buttons have hover states | ||
| - [ ] All buttons have focus states | ||
| - [ ] Color contrast meets WCAG AA standards | ||
| - [ ] Icons are clear and recognizable | ||
| - [ ] Text is readable at all sizes | ||
|
|
||
| --- | ||
|
|
||
| ## ✅ Responsive Design Tests | ||
|
|
||
| ### Mobile (< 768px) | ||
| - [ ] Share button fits in layout | ||
| - [ ] Modal is full-width with proper padding | ||
| - [ ] All buttons are easily tappable (44x44 min) | ||
| - [ ] Text is readable without zooming | ||
| - [ ] Modal scrolls if content overflows | ||
| - [ ] Share windows open properly on mobile | ||
|
|
||
| ### Tablet (768px - 1024px) | ||
| - [ ] Share button displays correctly | ||
| - [ ] Modal is appropriately sized | ||
| - [ ] Layout doesn't break | ||
| - [ ] All features work as expected | ||
|
|
There was a problem hiding this comment.
Specify language identifiers for fenced code blocks.
The fenced code blocks at lines 107, 119, 124, and 129 are missing language specifiers, which impacts readability and syntax highlighting in documentation viewers.
Apply this diff to add language specifiers:
-```
+```text
src/
├── ShareButton.tsx # Main component
├── utils/-```
+```text
https://twitter.com/intent/tweet?text=[title + description + hashtags]&url=[campaign_url]-```
+```text
https://t.me/share/url?text=[title + description + url + hashtags]&url=[campaign_url]-```
+```text
https://www.linkedin.com/sharing/share-offsite/?url=[campaign_url]🤖 Prompt for AI Agents
In SHARE_FEATURE_TESTING.md around lines 107 to 131 the fenced code blocks lack
language identifiers; update each triple-backtick fence at those lines to
include "text" (e.g. ```text) so the four blocks render with correct plain-text
syntax highlighting: the src tree block and the three URL/example blocks should
all be changed to use ```text at their opening fences and keep the same content
and closing fences.
| const validateShareContent = (content: ShareContent): void => { | ||
| if (!content.title?.trim()) { | ||
| throw new Error('Share title is required'); | ||
| } | ||
| if (!content.description?.trim()) { | ||
| throw new Error('Share description is required'); | ||
| } | ||
| if (!content.url?.trim()) { | ||
| throw new Error('Share URL is required'); | ||
| } | ||
|
|
||
| // Validate URL format | ||
| try { | ||
| new URL(content.url); | ||
| } catch { | ||
| throw new Error('Invalid share URL format'); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Enhance URL validation to reject dangerous protocols.
The current URL validation only checks format using new URL(), but doesn't reject dangerous protocols like javascript:, data:, file:, or vbscript: which could lead to XSS vulnerabilities.
Apply this diff to add protocol validation:
// Validate URL format
try {
- new URL(content.url);
+ const parsedUrl = new URL(content.url);
+ const allowedProtocols = ['http:', 'https:'];
+ if (!allowedProtocols.includes(parsedUrl.protocol)) {
+ throw new Error('Invalid protocol');
+ }
} catch {
throw new Error('Invalid share URL format');
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const validateShareContent = (content: ShareContent): void => { | |
| if (!content.title?.trim()) { | |
| throw new Error('Share title is required'); | |
| } | |
| if (!content.description?.trim()) { | |
| throw new Error('Share description is required'); | |
| } | |
| if (!content.url?.trim()) { | |
| throw new Error('Share URL is required'); | |
| } | |
| // Validate URL format | |
| try { | |
| new URL(content.url); | |
| } catch { | |
| throw new Error('Invalid share URL format'); | |
| } | |
| }; | |
| const validateShareContent = (content: ShareContent): void => { | |
| if (!content.title?.trim()) { | |
| throw new Error('Share title is required'); | |
| } | |
| if (!content.description?.trim()) { | |
| throw new Error('Share description is required'); | |
| } | |
| if (!content.url?.trim()) { | |
| throw new Error('Share URL is required'); | |
| } | |
| // Validate URL format | |
| try { | |
| const parsedUrl = new URL(content.url); | |
| const allowedProtocols = ['http:', 'https:']; | |
| if (!allowedProtocols.includes(parsedUrl.protocol)) { | |
| throw new Error('Invalid protocol'); | |
| } | |
| } catch { | |
| throw new Error('Invalid share URL format'); | |
| } | |
| }; |
🤖 Prompt for AI Agents
In src/utils/socialShare.ts around lines 23 to 40, the URL format check using
new URL() must also reject dangerous protocols; after successfully constructing
the URL object, normalize its protocol (toLowerCase, trim) and throw an error if
the protocol is one of the dangerous schemes (e.g., javascript:, data:, file:,
vbscript:) or alternatively only allow http: and https: protocols; update the
validation to perform this protocol check and produce a clear error like
"Invalid or unsafe share URL protocol" when rejected.
#18 Resolved I have attached the Screen Shot
Summary by CodeRabbit
New Features
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.