ShareModal
A ShareModal is build with a design system components and guidelines that enables users to share a link or content effortlessly. It provides options to share via social media, copy the link, or send via email, ensuring a seamless and accessible sharing experience.
Quick Start
- Installation
npm install @adaptavant/share-modal- Import
import { ShareModal } from '@adaptavant/share-modal';
Default
The Share Modal takes a link, title, description (primary and secondary), and optionLabels for built‑in actions like Copy Link, Email, Facebook, Messenger, and WhatsApp. It also connects onClose and closeButtonProps with an explicit label to improve screen‑reader clarity.
The ShareModal is responsive: from tablet breakpoint it converts to a bottom sheet, displaying the link as a QR code with Copy and native Share button.
Note:
headingImagePropshas been deprecate as of1.1.0, please useavatarProps
const [openModal, setOpenModal] = React.useState(false);
const closeModal = () => {
setOpenModal(false);
};
return (
<React.Fragment>
<Button
iconStart={ShareIcon}
label="Share"
onClick={() => {
setOpenModal(true);
}}
size="standard"
variant="neutralSecondary"
>
Share
</Button>
<ShareModal
className="share-modal"
closeButtonProps={{
label: "Close share modal",
onClick: closeModal,
}}
link="https://earth.anywhere.co/widgets"
onClose={closeModal}
open={openModal}
translations={{
description: {
primary: "Earth Design System",
secondary:
"That’s here. An evolving digital ecosystem that we strive to care.",
},
optionLabels: {
copyLabel: "Copy Link",
emailLabel: "Email",
facebookLabel: "Facebook",
messengerLabel: "Messenger",
whatsappLabel: "Whatsapp",
},
title: "Share this page",
}}
/>
</React.Fragment>
);
Translations
Use the translations prop to localize the modal’s title and descriptions, and optionLabels to translate built‑in action buttons (Copy Link, Email, Facebook, Messenger, WhatsApp).
Note:
translations.contenthas been deprecate as of1.1.0, please usetranslations.description.primary
const [openModal, setOpenModal] = React.useState(false);
const closeModal = () => {
setOpenModal(false);
};
return (
<React.Fragment>
<Button
iconStart={ShareIcon}
label="Compartir"
onClick={() => {
setOpenModal(true);
}}
size="standard"
variant="neutralSecondary"
>
Compartir
</Button>
<ShareModal
className="share-modal"
closeButtonProps={{
label: "Cerrar modal de compartir",
onClick: closeModal,
}}
link="https://earth.anywhere.co/widgets"
onClose={closeModal}
open={openModal}
translations={{
description: {
primary: "Sistema de Diseño Earth",
secondary:
"Aquí está. Un ecosistema digital en evolución que nos esforzamos por cuidar.",
},
optionLabels: {
copyLabel: "Copiar enlace",
emailLabel: "Correo",
facebookLabel: "Facebook",
messengerLabel: "Messenger",
whatsappLabel: "WhatsApp",
},
title: "Compartir esta página",
}}
/>
</React.Fragment>
);
With Custom Options
Use the shareOptions prop to include your own sharing buttons. Each option takes an icon, label, and onClick action—for example, opening a Twitter or LinkedIn share.
const [openModal, setOpenModal] = React.useState(false);
const closeModal = () => {
setOpenModal(false);
};
return (
<React.Fragment>
<Button
iconStart={ShareIcon}
label="Share"
onClick={() => {
setOpenModal(true);
}}
size="standard"
variant="neutralSecondary"
>
Share
</Button>
<ShareModal
className="share-modal"
closeButtonProps={{
label: "Modal Close Button",
onClick: closeModal,
}}
link="https://go.setmore.com"
onClose={closeModal}
open={openModal}
shareOptions={[
{
icon: TwitterIcon,
id: "share-via-twitter",
label: "Twitter",
onClick: () => {
window.open(
"https://twitter.com/intent/tweet?url=somelink",
"_blank"
);
},
},
{
icon: LinkedinIcon,
id: "share-via-linkedin",
label: "Linkedin",
onClick: () => {
window.open(
"https://www.linkedin.com/sharing/share-offsite/?url=somelink",
"_blank"
);
},
},
]}
translations={{
description: { primary: "Share this page with" },
optionLabels: {
copyLabel: "Copy Link",
emailLabel: "Email",
},
title: "Share this page",
}}
/>
</React.Fragment>
);
API Reference
ShareModal
| Props | Type | Description | Default |
|---|---|---|---|
translations | object | Translations object for the ShareModal. title key is required. description and optionLabels are optional. If optionLabels are undefined then shareOption should be provided. | _ |
translations.title | string | title key is required prop | _ |
translations.description | object | description key is optional prop | _ |
translations.content | string |
| _ |
translations.description.primary | string | Primary text inside the share modal. | _ |
translations.description.secondary | string | Secondary text inside the share modal. | _ |
translations.optionLabels | copyLabel | emailLabel | facebookLabel | messengerLabel | whatsappLabel | All keys in optionLabels are optional, a default option will be rendered only if a corresponding key is provided. | _ |
onClose | function | Callback triggered on closing the share modal and will activate upon pressing "Esc" or clicking on the overlay. | _ |
onEscPress? | (event: KeyboardEvent) => void | Callback fired when "Esc" key is pressed along with onClose. | _ |
onOverlayClick? | function | Callback fired when the overlay is clicked along with onClose | _ |
closeOnEsc? | boolean | If set to false, the share modal will not close when the Esc key is pressed, and the Esc keydown event along with the onClose callback won't be attached. Similarly, onEscPress will have no effect. | true |
open | boolean | When set to true, the dialog will be mounted to DOM. | _ |
size? | number | The size of the Modal 'Dialog' box in pixels. | 640 |
togglePoint? | number | The screen width at which the modal should switch to a mobile-friendly layout. Deprecated with backwards compatibility ⚠️ (The logic will be handled internally in future) | 768 |
mobileFriendly? | boolean | Indicates if the share modal should be render Sheet in responsive view. | true |
closeOnOverlayClick? | boolean | If set to false, the share modal will not close when the overlay is clicked, and the onClose callback won’t be attached. Similarly, onOverlayClick will have no effect. | true |
avatarProps? | object | To render image before the heading, contains label and src | _ |
avatarProps.label | string | Aria label content for the image added before the heading. | _ |
avatarProps.src | string | Url content for the image added before the heading. | _ |
|
|
To render image before the heading, contains | _ |
|
|
Aria label content for the image added before the heading. | _ |
|
|
Url content for the image added before the heading. | _ |
link | string | Link to be shared | _ |
shareOptions? | Array of Objects | To have custom share options, If no share options are passed, the default share options will be displayed | _ |
closeButtonProps? | object | To render and customise share modal close button contains label and onClick | _ |
closeButtonProps.label | string | Aria label content for the close Icon button. | _ |
closeButtonProps.onClick | function | Callback function to be invoked when the close button is clicked. | _ |
Style API
Our design system components include style props that allow you to easily customize different parts of each component to match your design needs.
Please refer to the Style API documentation for more insights.
ShareModal parts
const [openModal, setOpenModal] = React.useState(false);
const closeModal = () => {
setOpenModal(false);
};
return (
<React.Fragment>
<Button
iconStart={ShareIcon}
label="Share"
onClick={() => {
setOpenModal(true);
}}
size="standard"
variant="neutralSecondary"
>
Share
</Button>
<ShareModal
className="border-4"
classNames={{
title: "text-positive-secondary",
modalHeader: "mx-2 rounded-md p-2 bg-positive-secondary",
modalContent: "p-3 bg-caution-secondary",
modalHeaderContent: "text-critical-secondary border-4 bg-critical-secondary-hover",
modalWrapper: "z-10 bg-opacity-90",
}}
closeButtonProps={{
label: "Close share modal",
onClick: closeModal,
}}
link="https://go.setmore.com"
onClose={closeModal}
open={openModal}
translations={{
description: { primary: 'Share this page with' },
optionLabels: {
copyLabel: "Copy Link",
emailLabel: "Email",
facebookLabel: "Facebook",
messengerLabel: "Messenger",
whatsappLabel: "Whatsapp",
},
title: "Share this page",
}}
/>
</React.Fragment>
);
| Stylable Parts | Description |
|---|---|
| root | The container that wraps the share modal. |
| title | The title displayed in the header of the share modal. |
| modalHeader | The container that holds and organizes the heading components. |
| modalHeaderContent | The container that holds the heading text and icon. |
| modalWrapper | The container that wraps the whole modal element, acts as the overlay as well. |
| modalContent | The container that holds the main content within the modal body. |
NOTE: The
contentstyle part has been removed. UseprimaryDescriptionandsecondaryDescriptionstyle parts instead for styling description text.
ShareModalChildren parts
const [openModal, setOpenModal] = React.useState(false);
const closeModal = () => {
setOpenModal(false);
};
return (
<React.Fragment>
<Button
iconStart={ShareIcon}
label="Share"
onClick={() => {
setOpenModal(true);
}}
size="standard"
variant="neutralSecondary"
>
Share
</Button>
<ShareModal
className="border-4"
classNames={{
optionStack: 'bg-critical',
optionButton: 'bg-positive',
track: 'bg-caution',
primaryDescription: 'text-link',
secondaryDescription: 'text-body-16'
}}
closeButtonProps={{
label: "Close share modal",
onClick: closeModal,
}}
link="https://anywhereworks.com"
onClose={closeModal}
open={openModal}
translations={{
description: { primary: 'Anywhereworks', secondary: 'Help the world work Anywhere' },
optionLabels: {
copyLabel: "Copy Link",
emailLabel: "Email",
facebookLabel: "Facebook",
messengerLabel: "Messenger",
whatsappLabel: "Whatsapp",
},
title: "Share this page",
}}
/>
</React.Fragment>
);
| Stylable Parts | Description |
|---|---|
| optionStack | The container that wraps the option buttons. |
| optionButton | The style for option button. |
| track | The container that holds and avatar the description. |
| primaryDescription | The style for primary text. |
| secondaryDrescription | The style for secondary text. |
ShareSheetChildren parts
Note: The bottom sheet renders only on mobile. The
qrCodeandsheetWrapperstyle parts apply only while the sheet is visible.
const [openModal, setOpenModal] = React.useState(false);
const closeModal = () => {
setOpenModal(false);
};
return (
<React.Fragment>
<Button
iconStart={ShareIcon}
label="Share"
onClick={() => {
setOpenModal(true);
}}
size="standard"
variant="neutralSecondary"
>
Share
</Button>
<ShareModal
className="border-4"
classNames={{
optionStack: 'bg-critical',
optionButton: 'bg-positive',
sheetWrapper: 'bg-caution',
qrCode: 'fill-positive',
}}
closeButtonProps={{
label: "Close share modal",
onClick: closeModal,
}}
link="https://anywhereworks.com"
onClose={closeModal}
open={openModal}
translations={{
description: { primary: 'Anywhereworks', secondary: 'Help the world work Anywhere' },
optionLabels: {
copyLabel: "Copy Link",
emailLabel: "Email",
facebookLabel: "Facebook",
messengerLabel: "Messenger",
whatsappLabel: "Whatsapp",
},
title: "Share this page",
}}
/>
</React.Fragment>
);
| Stylable Parts | Description |
|---|---|
| optionStack | The container that wraps the option buttons. |
| optionButton | The style for option button. |
| sheetWrapper | The container that qrcode and buttons. |
| qrCode | The style for qrcode. |