GetProModal
A GetProModal is built with design system components and guidelines to promote premium features and encourage users to upgrade. It provides contextual information about Pro features along with clear actions to Upgrade or Cancel, ensuring a consistent, accessible, and seamless upgrade experience across products.
Quick Start
- Installation
npm install @adaptavant/get-pro-modal- Import
import { GetProModal } from '@adaptavant/get-pro-modal';
Key Properties
The GetProModal component provides several key properties for promoting premium upgrades:
- Intentional user interaction – The modal cannot be closed using Esc or overlay clicks. This behavior is fixed and cannot be overridden.
- Mobile-friendly by default – On mobile screens, the modal opens as a sheet component for a better user experience. This behavior is built-in and cannot be disabled.
- Configurable size – The default modal width is 480px, but developers can override this using custom props.
- Flexible content structure – Supports adding more features to the list and including additional contextual content beneath the feature listing.
Default
The GetProModal can be opened by clicking the GetPro button or any link configured to trigger it. In this example, clicking the GetPro button opens the GetProModal, showing the feature list and upgrade options.
const [openModal, setOpenModal] = React.useState(false);
const closeModal = () => {
setOpenModal(false);
};
const onUpgrade = () => {
closeModal();
};
return (
<React.Fragment>
<GetPro
size="standard"
isExpanded
isRounded
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
setOpenModal(true);
}
}}
onClick={() => {
setOpenModal(true);
}}
/>
<GetProModal
className="get-pro-modal"
open={openModal}
onClose={closeModal}
closeButtonProps={{
label: "Close share modal",
onClick: closeModal,
}}
coverImage={
<Image
src="https://assets.setmore.com/billing/images/settings-sms-reminders.png"
alt="SMS Reminders"
/>
}
title="SMS Reminders"
itemList={[
{
title: "Reduce missed appointments",
description:
"Send automated SMS reminders so clients never forget their bookings.",
},
{
title: "Personalize your messages",
description:
"Include names, dates, and times for a professional, personal touch.",
},
{
title: "Control delivery timing",
description:
"Schedule reminders in advance to give customers enough time to confirm or reschedule.",
},
]}
upgradeButtonProps={{
label: "Upgrade Now",
onClick: onUpgrade,
}}
closeButtonProps={{
label: "Close modal",
onClick: closeModal,
}}
cancelButtonProps={{
label: "Cancel",
onClick: closeModal,
}}
/>
</React.Fragment>
);
With Long Item List
The GetProModal supports longer feature lists through the itemList prop.
const [openModal, setOpenModal] = React.useState(false);
const closeModal = () => {
setOpenModal(false);
};
const onUpgrade = () => {
closeModal();
};
return (
<React.Fragment>
<GetPro
size="standard"
isExpanded
isRounded
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
setOpenModal(true);
}
}}
onClick={() => {
setOpenModal(true);
}}
/>
<GetProModal
className="get-pro-modal"
open={openModal}
onClose={closeModal}
closeButtonProps={{
label: "Close share modal",
onClick: closeModal,
}}
coverImage={
<Image
src="https://assets.setmore.com/billing/images/settings-sms-reminders.png"
alt="SMS Reminders"
/>
}
title="SMS Reminders"
// adding the itemList here
itemList={[
{
title: "Reduce missed appointments",
description:
"Send automated SMS reminders so clients never forget their bookings.",
},
{
title: "Personalize your messages",
description:
"Include names, dates, and times for a professional, personal touch.",
},
{
title: "Control delivery timing",
description:
"Schedule reminders in advance to give customers enough time to confirm or reschedule.",
},
{
title: "Personalize your messages",
description:
"Include names, dates, and times for a professional, personal touch.",
},
{
title: "Control delivery timing",
description:
"Schedule reminders in advance to give customers enough time to confirm or reschedule.",
},
{
title: "Control delivery timing",
description:
"Schedule reminders in advance to give customers enough time to confirm or reschedule.",
},
]}
upgradeButtonProps={{
label: "Upgrade Now",
onClick: onUpgrade,
}}
closeButtonProps={{
label: "Close modal",
onClick: closeModal,
}}
cancelButtonProps={{
label: "Cancel",
onClick: closeModal,
}}
/>
</React.Fragment>
);
With Additional Content
It also supports adding custom content below the item list using the additionalContent prop. You can pass any React component, such as notes or extra information, to give more context about the feature. Like shown in the example
const [openModal, setOpenModal] = React.useState(false);
const closeModal = () => {
setOpenModal(false);
};
const onUpgrade = () => {
closeModal();
};
return (
<React.Fragment>
<GetPro
size="standard"
isExpanded
isRounded
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
setOpenModal(true);
}
}}
onClick={() => {
setOpenModal(true);
}}
/>
<GetProModal
className="get-pro-modal"
open={openModal}
onClose={closeModal}
closeButtonProps={{
label: "Close share modal",
onClick: closeModal,
}}
coverImage={
<Image
src="https://assets.setmore.com/billing/images/settings-sms-reminders.png"
alt="SMS Reminders"
/>
}
title="SMS Reminders"
itemList={[
{
title: "Reduce missed appointments",
description:
"Send automated SMS reminders so clients never forget their bookings.",
},
{
title: "Personalize your messages",
description:
"Include names, dates, and times for a professional, personal touch.",
},
{
title: "Control delivery timing",
description:
"Schedule reminders in advance to give customers enough time to confirm or reschedule.",
},
]}
upgradeButtonProps={{
label: "Upgrade Now",
onClick: onUpgrade,
}}
closeButtonProps={{
label: "Close modal",
onClick: closeModal,
}}
cancelButtonProps={{
label: "Cancel",
onClick: closeModal,
}}
// adding additional content below the feature list
additionalContent={
<Box
className="flex items-start bg-canvas-secondary gap-2 px-3 py-2 rounded-8px"
data-eds-component="true"
>
<InformationIcon size="20" />
<Box className="flex flex-col">
<Text className="text-body-12 text-primary font-stronger">
SMS reminders require a separate purchase.
</Text>
<Text
className="flex-col min-w-0 text-body-12 text-secondary"
data-eds-component="true"
>
SMS cost varies by country per our{" "}
<TextLink className="text-body-12 text-secondary" href="#">
SMS reminder policy
</TextLink>
</Text>
</Box>
</Box>
}
/>
</React.Fragment>
);
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.
GetProModal parts
const [openModal, setOpenModal] = React.useState(false);
const closeModal = () => {
setOpenModal(false);
};
const onUpgrade = () => {
closeModal();
};
return (
<React.Fragment>
<Text className="text-body-16">
Want to unlock more features?{' '}
<TextLink
variant="accentPrimary"
href="#"
onClick={(e) => {
e.preventDefault();
setOpenModal(true);
}}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
setOpenModal(true);
}
}}
>
Get Pro now
</TextLink>
</Text>
{/* GetProModal with better color visibility */}
<GetProModal
open={openModal}
onClose={closeModal}
title="SMS Reminders"
classNames={{
// Style the modal wrapper (overlay)
modalWrapper: "bg-black/70",
// Style the modal header with green theme
modalHeader: "bg-[#198057] p-4",
// Style the title with white text (visible on green background)
title: "text-white font-stronger",
// Style the content area
modalContent: "bg-white",
// Style the icon wrapper
iconWrapper: "",
// Style feature titles with dark text (visible on white background)
itemListTitle: "text-gray-900 font-stronger",
// Style feature descriptions
itemListDescription: "text-gray-700",
// Style the upgrade button with green background and white text
upgradeButton: "bg-[#198057] hover:bg-[#156b4a] text-white font-semibold",
// Style the cancel button with gray background and dark text
cancelButton: "bg-gray-200 hover:bg-gray-300 text-gray-800",
// Style the modal footer
modalFooter: "bg-gray-50 p-4",
}}
coverImage={
<Image
src="https://assets.setmore.com/billing/images/settings-sms-reminders.png"
alt="SMS Reminders"
/>
}
itemList={[
{
title: "Reduce missed appointments",
description: "Send automated SMS reminders so clients never forget their bookings.",
},
{
title: "Personalize your messages",
description: "Include names, dates, and times for a professional touch.",
},
{
title: "Control delivery timing",
description: "Schedule reminders in advance to give customers time to confirm.",
},
]}
upgradeButtonProps={{
label: "Upgrade Now",
onClick: onUpgrade,
}}
cancelButtonProps={{
label: "Maybe Later",
onClick: closeModal,
}}
closeButtonProps={{
label: "Close modal",
onClick: closeModal,
}}
// Custom props passed through
data-testid="sms-reminder-modal"
/>
</React.Fragment>
);
| Stylable Parts | Description |
|---|---|
| root | The container that wraps the entire GetProModal component. |
| title | The title displayed in the header of the GetProModal |
| modalHeader | The container for the header area, including the title and close button. |
| modalWrapper | The container that wraps the whole modal element, acts as the overlay as well. |
| modalContent | The container for the modal body content, including cover image, item list, and additional content. |
| contentWrapper | The wrapper for the list of Pro plan features (itemList). |
| itemListTrack | The container for each feature row in the list, including the icon, title, and description. It controls the layout and spacing for the item. |
| iconWrapper | The container for the brand icon displayed at the start of each item in the list. |
| itemListTitle | The feature's title text inside the list. |
| itemListDescription | The feature's description inside the list. |
| additionalContent | The container for optional extra content (e.g., SMS reminder info block). Appears below the feature list. |
| modalFooter | The container for the footer area, where the Cancel and Upgrade buttons are displayed. |
| cancelButton | The cancel button inside the modal footer. This button is not visible on mobile screens. |
| upgradeButton | The upgrade button inside the footer (primary CTA). |