Skip to content

Enhance SocialShareButton with customizable open/close callbacks and …#127

Open
sarthakdev14 wants to merge 2 commits intoAOSSIE-Org:mainfrom
sarthakdev14:main
Open

Enhance SocialShareButton with customizable open/close callbacks and …#127
sarthakdev14 wants to merge 2 commits intoAOSSIE-Org:mainfrom
sarthakdev14:main

Conversation

@sarthakdev14
Copy link

@sarthakdev14 sarthakdev14 commented Mar 23, 2026

🚀 PR: SocialShareButton – Usability, Accessibility & API Improvements

📌 Summary

This PR improves social-share-button.js by enhancing usability, accessibility, and API flexibility while maintaining backward compatibility.


✨ What’s Changed

  • Added shareText for better share content fallback
  • Added onOpen and onClose callbacks
  • Preserved existing onShare, onCopy, and analytics flow (social_share_* events, DOM events, plugin adapters)

♿ Accessibility Improvements

  • Buttons now use:
<button type="button">Share</button>
  • Modal now includes:
<div role="dialog" aria-modal="true" aria-hidden="true"></div>
  • Proper aria-hidden toggling on open/close
  • Improved keyboard accessibility

⚙️ Behavior Improvements

  • Share fallback:
shareText || title || "Check this out"
  • Callback triggers:
onOpen   openModal()
onClose  closeModal()
  • Safe error handling:
try {
  // handler logic
} catch (e) {
  _debugWarn(e);
}

📊 Status

  • ✅ No errors (get_errors clean)
  • ✅ Backward compatible
  • ✅ Ready for review

🧪 Next Steps

  • Add README documentation
  • Add tests for callbacks, ARIA states, and share behavior

💡 Impact

Improves developer experience, accessibility compliance, and overall reliability of the library.

Summary by CodeRabbit

  • New Features

    • Added onOpen/onClose callbacks to react to the share modal opening/closing
    • Added shareText and a default fallback share message for customizable share content
  • Bug Fixes / Accessibility

    • Improved modal accessibility (ARIA roles/labels and proper hidden state handling)
    • Explicit button types to prevent unintended form submissions and more robust share behavior

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 23, 2026

Walkthrough

Adds lifecycle callbacks (onOpen, onClose), configurable share text fields (shareText, defaultShareText), explicit type="button" attributes, and improved modal ARIA attributes; adjusts share URL/message construction and guards callback invocation with try/catch.

Changes

Cohort / File(s) Summary
Options & Message Construction
src/social-share-button.js
Adds new constructor options: onOpen, onClose, shareText, defaultShareText. Changes share message logic to prefer `shareText
Modal Lifecycle & Accessibility
src/social-share-button.js
Adds role="dialog", aria-modal="true", aria-hidden handling and aria-labelledby wiring; toggles aria-hidden in openModal()/closeModal(); invokes onOpen/onClose with try/catch forwarding errors to _debugWarn.
Button Markup
src/social-share-button.js
Sets type="button" on main share button and individual platform buttons to ensure proper button semantics.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

Typescript Lang

Suggested reviewers

  • kpj2006

Poem

🐇 I hop to the button, give a cheerful click,
The dialog wakes, polite and quick,
Callbacks peep out, then quietly close,
ShareText carried where the message goes,
A tiny rabbit cheers the accessible flow ✨

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Enhance SocialShareButton with customizable open/close callbacks and …' accurately summarizes the main changes: adding callbacks (onOpen/onClose) and other customization features to the SocialShareButton component.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/social-share-button.js (2)

106-114: ⚠️ Potential issue | 🟡 Minor

Add accessible name to dialog via aria-labelledby.

The dialog has role="dialog" and aria-modal="true", but lacks an accessible name. Screen readers need aria-labelledby referencing the heading to announce the dialog's purpose.

♿ Proposed fix
     const modal = document.createElement("div");
     modal.setAttribute("role", "dialog");
     modal.setAttribute("aria-modal", "true");
     modal.setAttribute("aria-hidden", "true");
+    modal.setAttribute("aria-labelledby", "social-share-modal-title");
     modal.className = `social-share-modal-overlay ${this.options.theme}`;
     modal.style.display = "none";
     modal.innerHTML = `
       <div class="social-share-modal-content ${this.options.modalPosition}">
         <div class="social-share-modal-header">
-          <h3>Share</h3>
+          <h3 id="social-share-modal-title">Share</h3>

Note: If multiple instances exist on the same page, you'll need unique IDs (e.g., append this.options.componentId or a counter).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/social-share-button.js` around lines 106 - 114, The dialog created in the
modal block lacks an accessible name; add an id to the heading inside the
template and set modal.setAttribute("aria-labelledby", headingId) so screen
readers announce the dialog; generate a unique headingId (e.g.,
`social-share-title-${this.options.componentId || uniqueCounter}`) and inject
that id into the <h3> element in the template string (and then call
modal.setAttribute("aria-labelledby", headingId)) in the same initialization
code that creates `modal` (referencing the modal variable and the template that
contains the <h3> "Share").

201-235: ⚠️ Potential issue | 🟡 Minor

Inconsistent shareText application across platforms.

The message variable (derived from shareText) is only used for WhatsApp, Facebook, and Twitter. Telegram, Reddit, Email, and Pinterest still reference title directly. This partial implementation may confuse API consumers expecting shareText to customize all platforms uniformly.

Consider applying message consistently, or document which platforms support shareText.

🔧 Suggested fix for consistency
     // Telegram: Casual with emoji
-    telegramMessage = `\u{1F517} ${title}${description ? "\n\n" + description : ""}${hashtagString ? "\n\n" + hashtagString : ""}\n\nLive + working\nClean stuff, take a look \u{1F447}`;
+    telegramMessage = `\u{1F517} ${message}${description ? "\n\n" + description : ""}${hashtagString ? "\n\n" + hashtagString : ""}\n\nLive + working\nClean stuff, take a look \u{1F447}`;

     // Reddit: Title + Description
-    redditTitle = `${title}${description ? " - " + description : ""}`;
+    redditTitle = `${message}${description ? " - " + description : ""}`;

     // Email: Friendly greeting
-    emailBody = `Hey \u{1F44B}\n\nSharing a clean project I came across:\n${title}${description ? "\n\n" + description : ""}\n\nLive, simple, and usable \u{2014} take a look \u{1F447}`;
+    emailBody = `Hey \u{1F44B}\n\nSharing a clean project I came across:\n${message}${description ? "\n\n" + description : ""}\n\nLive, simple, and usable \u{2014} take a look \u{1F447}`;

     // Pinterest: Title + Description
-    pinterestText = `${title || ""}${description ? " - " + description : ""}`;
+    pinterestText = `${message}${description ? " - " + description : ""}`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/social-share-button.js` around lines 201 - 235, The issue: shareText
(message) is only applied to WhatsApp/Facebook/Twitter while Telegram, Reddit,
Email and Pinterest still use title directly; update platform messages to use
the unified message variable (message) where appropriate. Locate
telegramMessage, redditTitle, emailBody, and pinterestText and replace their
direct uses of title with message (keeping the existing description and
hashtagString logic and emojis intact), and ensure message still falls back to
title or a default as defined by const message = shareText || title || "Check
this out".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/social-share-button.js`:
- Line 202: The hardcoded fallback "Check this out" should be made configurable
for i18n: add a new option/prop named defaultShareText and use it when computing
message (replace the expression that sets const message = shareText || title ||
"Check this out" with shareText || title || defaultShareText || "Check this
out"); update the component/function signature or options object to accept
defaultShareText (and provide a sensible default in defaults/propTypes or
equivalent) and update any docs/readme to mention developers can set
defaultShareText for localization.
- Around line 34-36: Add brief inline comments for the new public options in the
options object so callers understand their purpose: add one-line comments next
to onOpen, onClose, and shareText in the options initializer (e.g., where
onOpen: options.onOpen || null, onClose: options.onClose || null, shareText:
options.shareText || "") describing that onOpen/onClose are optional callback
hooks invoked when the share UI opens/closes and shareText is the default text
to prefill for sharing; keep comments minimal and factual to follow repository
guidelines.

---

Outside diff comments:
In `@src/social-share-button.js`:
- Around line 106-114: The dialog created in the modal block lacks an accessible
name; add an id to the heading inside the template and set
modal.setAttribute("aria-labelledby", headingId) so screen readers announce the
dialog; generate a unique headingId (e.g.,
`social-share-title-${this.options.componentId || uniqueCounter}`) and inject
that id into the <h3> element in the template string (and then call
modal.setAttribute("aria-labelledby", headingId)) in the same initialization
code that creates `modal` (referencing the modal variable and the template that
contains the <h3> "Share").
- Around line 201-235: The issue: shareText (message) is only applied to
WhatsApp/Facebook/Twitter while Telegram, Reddit, Email and Pinterest still use
title directly; update platform messages to use the unified message variable
(message) where appropriate. Locate telegramMessage, redditTitle, emailBody, and
pinterestText and replace their direct uses of title with message (keeping the
existing description and hashtagString logic and emojis intact), and ensure
message still falls back to title or a default as defined by const message =
shareText || title || "Check this out".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d7d6c56c-ecc3-4078-958c-a49e7dcccb10

📥 Commits

Reviewing files that changed from the base of the PR and between 18d0b97 and 6c0ea58.

📒 Files selected for processing (1)
  • src/social-share-button.js

@github-actions github-actions bot added size/M and removed size/S labels Mar 23, 2026
Copy link
Author

@sarthakdev14 sarthakdev14 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes made

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/social-share-button.js (1)

117-125: ⚠️ Potential issue | 🟡 Minor

Missing type="button" on modal buttons.

The close button (line 117) and copy button (line 125) are missing the explicit type="button" attribute, inconsistent with the main share button and platform buttons that were updated.

🔧 Proposed fix
-          <button class="social-share-modal-close" aria-label="Close">✕</button>
+          <button type="button" class="social-share-modal-close" aria-label="Close">✕</button>
-          <button class="social-share-copy-btn">Copy</button>
+          <button type="button" class="social-share-copy-btn">Copy</button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/social-share-button.js` around lines 117 - 125, The modal close and copy
buttons are missing explicit type attributes; update the button elements with
class names social-share-modal-close and social-share-copy-btn to include
type="button" so they don't act as default submit buttons (aligning with the
other buttons and platform buttons generated by getPlatformsHTML()); locate
these elements in src/social-share-button.js and add the attribute to each
button tag.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/social-share-button.js`:
- Around line 340-346: Add a short inline comment above the try/catch that
explains why we guard the user-provided callback: the block around
this.options.onOpen({ url: this.options.url, platform: null }) should note that
we call a third‑party/user callback so we catch exceptions to prevent them from
bubbling up and to log via this._debugWarn; mention that this is a defensive
safety check for faulty callbacks.
- Around line 107-116: The modal title ID is hardcoded as
"social-share-modal-title", causing duplicate IDs across multiple
SocialShareButton instances; modify createModal() to generate a unique id per
instance (e.g., using an instance-specific identifier like this.instanceId, a
counter, or timestamp), assign that unique id to the title element instead of
the hardcoded string, and update the modal's aria-labelledby attribute to
reference this generated id so the accessibility association remains correct for
each instance.

---

Outside diff comments:
In `@src/social-share-button.js`:
- Around line 117-125: The modal close and copy buttons are missing explicit
type attributes; update the button elements with class names
social-share-modal-close and social-share-copy-btn to include type="button" so
they don't act as default submit buttons (aligning with the other buttons and
platform buttons generated by getPlatformsHTML()); locate these elements in
src/social-share-button.js and add the attribute to each button tag.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 90314f37-d7e8-4993-9310-02dfb2e1b2f2

📥 Commits

Reviewing files that changed from the base of the PR and between 6c0ea58 and 7461f37.

📒 Files selected for processing (1)
  • src/social-share-button.js

Comment on lines +107 to +116
modal.setAttribute("role", "dialog");
modal.setAttribute("aria-modal", "true");
modal.setAttribute("aria-labelledby", "social-share-modal-title");
modal.setAttribute("aria-hidden", "true");
modal.className = `social-share-modal-overlay ${this.options.theme}`;
modal.style.display = "none";
modal.innerHTML = `
<div class="social-share-modal-content ${this.options.modalPosition}">
<div class="social-share-modal-header">
<h3>Share</h3>
<h3 id="social-share-modal-title">Share</h3>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Duplicate ID issue with multiple component instances.

The hardcoded id="social-share-modal-title" will cause duplicate IDs when multiple SocialShareButton instances exist on the same page. This breaks the aria-labelledby association and violates HTML validity.

Consider using a unique identifier per instance:

🛠️ Proposed fix
+ // Generate unique ID for this instance (used for ARIA associations)
+ this.instanceId = `ssb-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;

Then in createModal():

-    modal.setAttribute("aria-labelledby", "social-share-modal-title");
+    modal.setAttribute("aria-labelledby", `social-share-modal-title-${this.instanceId}`);
-          <h3 id="social-share-modal-title">Share</h3>
+          <h3 id="social-share-modal-title-${this.instanceId}">Share</h3>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/social-share-button.js` around lines 107 - 116, The modal title ID is
hardcoded as "social-share-modal-title", causing duplicate IDs across multiple
SocialShareButton instances; modify createModal() to generate a unique id per
instance (e.g., using an instance-specific identifier like this.instanceId, a
counter, or timestamp), assign that unique id to the title element instead of
the hardcoded string, and update the modal's aria-labelledby attribute to
reference this generated id so the accessibility association remains correct for
each instance.

Comment on lines +340 to +346
if (typeof this.options.onOpen === "function") {
try {
this.options.onOpen({ url: this.options.url, platform: null });
} catch (err) {
this._debugWarn("onOpen callback failed", err);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Add brief inline comment for the callback guard.

Per repository guidelines, non-obvious logic like try/catch guards should have brief comments. Consider:

+    // Invoke lifecycle callback safely; errors are non-fatal
     if (typeof this.options.onOpen === "function") {
       try {
         this.options.onOpen({ url: this.options.url, platform: null });
       } catch (err) {
         this._debugWarn("onOpen callback failed", err);
       }
     }

As per coding guidelines: "Add comments for edge cases and non-obvious logic (safety checks, race condition prevention, re-entrancy guards, cleanup callbacks, etc.)"

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/social-share-button.js` around lines 340 - 346, Add a short inline
comment above the try/catch that explains why we guard the user-provided
callback: the block around this.options.onOpen({ url: this.options.url,
platform: null }) should note that we call a third‑party/user callback so we
catch exceptions to prevent them from bubbling up and to log via
this._debugWarn; mention that this is a defensive safety check for faulty
callbacks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant