autumn-js
Version:
Autumn JS Library
707 lines (701 loc) • 26 kB
JavaScript
"use client";
import {
getAttachContent
} from "./chunk-O6TAJHK3.mjs";
import {
getPricingTableContent
} from "./chunk-URQMBRFZ.mjs";
import {
Input
} from "./chunk-GUM4HIGI.mjs";
import {
Popover,
PopoverContent,
PopoverTrigger
} from "./chunk-UM3ZQPMU.mjs";
import {
Switch
} from "./chunk-6EZVNJHQ.mjs";
import {
loadingStyles,
spinnerStyles
} from "./chunk-WVKYZYFT.mjs";
import {
Button
} from "./chunk-EV5RNY5U.mjs";
import {
Dialog,
DialogContent,
DialogFooter,
DialogTitle
} from "./chunk-JPLUWGH4.mjs";
import {
Accordion,
AccordionContent,
AccordionItem
} from "./chunk-JGRLRPKG.mjs";
import {
ArrowRight,
ChevronDown,
LoaderCircle
} from "./chunk-QJPZFEVW.mjs";
import {
usePricingTable
} from "./chunk-OTYSAMRH.mjs";
import {
cn
} from "./chunk-4J6OC4ZQ.mjs";
import {
useCustomer
} from "./chunk-4CHWEUKX.mjs";
// src/libraries/react/components/pricing-table/pricing-table-synced.tsx
import React2 from "react";
// src/libraries/react/components/attach-dialog/attach-dialog-synced.tsx
import * as AccordionPrimitive from "@radix-ui/react-accordion";
import { useEffect, useState } from "react";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var formatCurrency = ({
amount,
currency
}) => {
return new Intl.NumberFormat("en-US", {
style: "currency",
currency
}).format(amount);
};
function AttachDialog(params) {
const { attach } = useCustomer();
const [checkoutResult, setCheckoutResult] = useState(params?.checkoutResult);
useEffect(() => {
if (params.checkoutResult) {
setCheckoutResult(params.checkoutResult);
}
}, [params.checkoutResult]);
const [loading, setLoading] = useState(false);
if (!checkoutResult) {
return /* @__PURE__ */ jsx(Fragment, {});
}
const { open, setOpen } = params;
const { title, message } = getAttachContent(checkoutResult);
const isFree = checkoutResult?.product.properties?.is_free;
const isPaid = isFree === false;
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(DialogContent, { className: "au-p-0 au-pt-4 au-gap-0 au-text-foreground au-overflow-hidden au-text-sm", children: [
/* @__PURE__ */ jsx(DialogTitle, { className: "au-px-6 au-mb-1", children: title }),
/* @__PURE__ */ jsx("div", { className: "au-px-6 au-mt-1 au-mb-4 au-text-muted-foreground", children: message }),
isPaid && checkoutResult && /* @__PURE__ */ jsx(
PriceInformation,
{
checkoutResult,
setCheckoutResult
}
),
/* @__PURE__ */ jsx(DialogFooter, { className: "au-flex au-flex-col sm:au-flex-row au-justify-between au-gap-x-4 au-py-2 au-pl-6 au-pr-3 au-bg-secondary au-border-t au-shadow-inner", children: /* @__PURE__ */ jsx(
Button,
{
size: "sm",
onClick: async () => {
setLoading(true);
const options = checkoutResult.options.map((option) => {
return {
featureId: option.feature_id,
quantity: option.quantity
};
});
await attach({
productId: checkoutResult.product.id,
options
});
setOpen(false);
setLoading(false);
},
disabled: loading,
className: "au-min-w-16 au-flex au-items-center au-gap-2",
children: loading ? /* @__PURE__ */ jsx(LoaderCircle, { className: "au-w-4 au-h-4 au-animate-spin" }) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("span", { className: "au-whitespace-nowrap au-flex au-gap-1", children: "Confirm" }) })
}
) })
] }) });
}
function PriceInformation({
checkoutResult,
setCheckoutResult
}) {
return /* @__PURE__ */ jsxs("div", { className: "au-px-6 au-mb-4 au-flex au-flex-col au-gap-4", children: [
/* @__PURE__ */ jsx(
ProductItems,
{
checkoutResult,
setCheckoutResult
}
),
/* @__PURE__ */ jsxs("div", { className: "au-flex au-flex-col au-gap-2", children: [
checkoutResult?.has_prorations && checkoutResult.lines.length > 0 && /* @__PURE__ */ jsx(CheckoutLines, { checkoutResult }),
/* @__PURE__ */ jsx(DueAmounts, { checkoutResult })
] })
] });
}
function DueAmounts({ checkoutResult }) {
const { next_cycle, product } = checkoutResult;
const nextCycleAtStr = next_cycle ? new Date(next_cycle.starts_at).toLocaleDateString() : void 0;
const hasUsagePrice = product.items.some(
(item) => item.usage_model === "pay_per_use"
);
const showNextCycle = next_cycle && next_cycle.total !== checkoutResult.total;
return /* @__PURE__ */ jsxs("div", { className: "au-flex au-flex-col au-gap-1", children: [
/* @__PURE__ */ jsxs("div", { className: "au-flex au-justify-between", children: [
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("p", { className: "au-font-medium au-text-md", children: "Total due today" }) }),
/* @__PURE__ */ jsx("p", { className: "au-font-medium au-text-md", children: formatCurrency({
amount: checkoutResult?.total,
currency: checkoutResult?.currency
}) })
] }),
showNextCycle && /* @__PURE__ */ jsxs("div", { className: "au-flex au-justify-between au-text-muted-foreground", children: [
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("p", { className: "au-text-md", children: [
"Due next cycle (",
nextCycleAtStr,
")"
] }) }),
/* @__PURE__ */ jsxs("p", { className: "au-text-md", children: [
formatCurrency({
amount: next_cycle.total,
currency: checkoutResult?.currency
}),
hasUsagePrice && /* @__PURE__ */ jsx("span", { children: " + usage prices" })
] })
] })
] });
}
function ProductItems({
checkoutResult,
setCheckoutResult
}) {
const isUpdateQuantity = checkoutResult?.product.scenario === "active" && checkoutResult.product.properties.updateable;
return /* @__PURE__ */ jsxs("div", { className: "au-flex au-flex-col au-gap-2", children: [
/* @__PURE__ */ jsx("p", { className: "au-text-sm au-font-medium", children: "Price" }),
checkoutResult?.product.items.filter((item) => item.type !== "feature").map((item, index) => {
if (item.usage_model == "prepaid") {
return /* @__PURE__ */ jsx(
PrepaidItem,
{
item,
checkoutResult,
setCheckoutResult
},
index
);
}
if (isUpdateQuantity) {
return null;
}
return /* @__PURE__ */ jsxs("div", { className: "au-flex au-justify-between", children: [
/* @__PURE__ */ jsx("p", { className: "au-text-muted-foreground", children: item.feature ? item.feature.name : "Subscription" }),
/* @__PURE__ */ jsxs("p", { children: [
item.display?.primary_text,
" ",
item.display?.secondary_text
] })
] }, index);
})
] });
}
function CheckoutLines({ checkoutResult }) {
return /* @__PURE__ */ jsx(Accordion, { type: "single", collapsible: true, children: /* @__PURE__ */ jsxs(AccordionItem, { value: "total", className: "au-border-b-0", children: [
/* @__PURE__ */ jsx(CustomAccordionTrigger, { className: "au-justify-between au-w-full au-my-0 au-py-0 au-border-none", children: /* @__PURE__ */ jsxs("div", { className: "au-cursor-pointer au-flex au-items-center au-gap-1 au-w-full au-justify-end", children: [
/* @__PURE__ */ jsx("p", { className: "au-font-light au-text-muted-foreground", children: "View details" }),
/* @__PURE__ */ jsx(
ChevronDown,
{
className: "au-text-muted-foreground au-mt-0.5 au-rotate-90 au-transition-transform au-duration-200 au-ease-in-out",
size: 14
}
)
] }) }),
/* @__PURE__ */ jsx(AccordionContent, { className: "au-mt-2 au-mb-0 au-pb-2 au-flex au-flex-col au-gap-2", children: checkoutResult?.lines.filter((line) => line.amount != 0).map((line, index) => {
return /* @__PURE__ */ jsxs("div", { className: "au-flex au-justify-between", children: [
/* @__PURE__ */ jsx("p", { className: "au-text-muted-foreground", children: line.description }),
/* @__PURE__ */ jsx("p", { className: "au-text-muted-foreground", children: new Intl.NumberFormat("en-US", {
style: "currency",
currency: checkoutResult?.currency
}).format(line.amount) })
] }, index);
}) })
] }) });
}
function CustomAccordionTrigger({
className,
children,
...props
}) {
return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "au-flex", children: /* @__PURE__ */ jsx(
AccordionPrimitive.Trigger,
{
"data-slot": "accordion-trigger",
className: cn(
"focus-visible:au-border-ring focus-visible:au-ring-ring/50 au-flex au-flex-1 au-items-start au-justify-between au-gap-4 au-rounded-md au-py-4 au-text-left au-text-sm au-font-medium au-transition-all au-outline-none focus-visible:au-ring-[3px] disabled:au-pointer-events-none disabled:au-opacity-50 [&[data-state=open]_svg]:au-rotate-0",
className
),
...props,
children
}
) });
}
var PrepaidItem = ({
item,
checkoutResult,
setCheckoutResult
}) => {
const { quantity = 0, billing_units: billingUnits = 1 } = item;
const [quantityInput, setQuantityInput] = useState(
(quantity / billingUnits).toString()
);
const { checkout } = useCustomer();
const [loading, setLoading] = useState(false);
const [open, setOpen] = useState(false);
const scenario = checkoutResult.product.scenario;
const handleSave = async () => {
setLoading(true);
try {
const newOptions = checkoutResult.options.filter((option) => option.feature_id !== item.feature_id).map((option) => {
return {
featureId: option.feature_id,
quantity: option.quantity
};
});
newOptions.push({
featureId: item.feature_id,
quantity: Number(quantityInput) * billingUnits
});
const { data, error } = await checkout({
productId: checkoutResult.product.id,
options: newOptions
});
if (error) {
console.error(error);
return;
}
setCheckoutResult(data);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
setOpen(false);
}
};
const disableSelection = scenario === "renew";
return /* @__PURE__ */ jsxs("div", { className: "au-flex au-justify-between", children: [
/* @__PURE__ */ jsxs("div", { className: "au-flex au-gap-2", children: [
/* @__PURE__ */ jsx("p", { className: "au-text-muted-foreground", children: item.feature?.name }),
/* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
/* @__PURE__ */ jsxs(
PopoverTrigger,
{
className: cn(
"au-text-muted-foreground au-text-xs au-px-1 au-py-0.5 au-rounded-md au-flex au-items-center au-gap-1 au-bg-accent/80",
disableSelection !== true && "hover:au-bg-accent hover:au-text-foreground"
),
disabled: disableSelection,
children: [
"Qty: ",
quantity,
/* @__PURE__ */ jsx(ChevronDown, { size: 12 })
]
}
),
/* @__PURE__ */ jsxs(
PopoverContent,
{
align: "start",
className: "au-w-80 au-text-sm au-p-4 au-pt-3 au-flex au-flex-col au-gap-4",
children: [
/* @__PURE__ */ jsxs("div", { className: "au-flex au-flex-col au-gap-1", children: [
/* @__PURE__ */ jsx("p", { className: "au-text-sm au-font-medium", children: item.feature?.name }),
/* @__PURE__ */ jsxs("p", { className: "au-text-muted-foreground", children: [
item.display?.primary_text,
" ",
item.display?.secondary_text
] })
] }),
/* @__PURE__ */ jsxs("div", { className: "au-flex au-justify-between au-items-end", children: [
/* @__PURE__ */ jsxs("div", { className: "au-flex au-gap-2 au-items-center", children: [
/* @__PURE__ */ jsx(
Input,
{
className: "au-h-7 au-w-16 focus:!au-ring-2",
value: quantityInput,
onChange: (e) => setQuantityInput(e.target.value)
}
),
/* @__PURE__ */ jsxs("p", { className: "au-text-muted-foreground", children: [
billingUnits > 1 && `x ${billingUnits} `,
item.feature?.name
] })
] }),
/* @__PURE__ */ jsx(
Button,
{
onClick: handleSave,
className: "au-w-14 !au-h-7 au-text-sm au-items-center au-bg-white au-text-foreground au-shadow-sm au-border au-border-zinc-200 hover:au-bg-zinc-100",
disabled: loading,
children: loading ? /* @__PURE__ */ jsx(LoaderCircle, { className: "au-text-muted-foreground au-animate-spin !au-w-4 !au-h-4" }) : "Save"
}
)
] })
]
}
)
] })
] }),
/* @__PURE__ */ jsxs("p", { children: [
item.display?.primary_text,
" ",
item.display?.secondary_text
] })
] });
};
var PriceItem = ({
children,
className,
...props
}) => {
return /* @__PURE__ */ jsx(
"div",
{
className: cn(
"au-flex au-flex-col au-pb-4 sm:au-pb-0 au-gap-1 sm:au-flex-row au-justify-between sm:au-h-7 sm:au-gap-2 sm:au-items-center",
className
),
...props,
children
}
);
};
var PricingDialogButton = ({
children,
size,
onClick,
disabled,
className
}) => {
return /* @__PURE__ */ jsxs(
Button,
{
onClick,
disabled,
size,
className: cn(className, "au-shadow-sm au-shadow-stone-400"),
children: [
children,
/* @__PURE__ */ jsx(ArrowRight, { className: "!au-h-3" })
]
}
);
};
// src/libraries/react/components/pricing-table/pricing-table-synced.tsx
import { createContext, useContext, useState as useState2 } from "react";
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
function PricingTable({
productDetails
}) {
const { checkout } = useCustomer();
const [isAnnual, setIsAnnual] = useState2(false);
const { products, isLoading, error } = usePricingTable({ productDetails });
if (isLoading) {
return /* @__PURE__ */ jsx2("div", { style: loadingStyles, children: /* @__PURE__ */ jsx2(LoaderCircle, { style: spinnerStyles }) });
}
if (error) {
return /* @__PURE__ */ jsx2("div", { children: " Something went wrong..." });
}
const intervals = Array.from(
new Set(
products?.map((p) => p.properties?.interval_group).filter((i) => !!i)
)
);
const multiInterval = intervals.length > 1;
const intervalFilter = (product) => {
if (!product.properties?.interval_group) {
return true;
}
if (multiInterval) {
if (isAnnual) {
return product.properties?.interval_group === "year";
} else {
return product.properties?.interval_group === "month";
}
}
return true;
};
return /* @__PURE__ */ jsx2("div", { className: cn("au-root"), children: products && /* @__PURE__ */ jsx2(
PricingTableContainer,
{
products,
isAnnualToggle: isAnnual,
setIsAnnualToggle: setIsAnnual,
multiInterval,
children: products.filter(intervalFilter).map((product, index) => /* @__PURE__ */ jsx2(
PricingCard,
{
productId: product.id,
buttonProps: {
disabled: product.scenario === "active" && !product.properties.updateable || product.scenario === "scheduled",
onClick: async () => {
if (product.id) {
await checkout({
productId: product.id,
dialog: AttachDialog
});
} else if (product.display?.button_url) {
window.open(product.display?.button_url, "_blank");
}
}
}
},
index
))
}
) });
}
var PricingTableContext = createContext({
isAnnualToggle: false,
setIsAnnualToggle: () => {
},
products: [],
showFeatures: true
});
var usePricingTableContext = (componentName) => {
const context = useContext(PricingTableContext);
if (context === void 0) {
throw new Error(`${componentName} must be used within <PricingTable />`);
}
return context;
};
var PricingTableContainer = ({
children,
products,
showFeatures = true,
className,
isAnnualToggle,
setIsAnnualToggle,
multiInterval
}) => {
if (!products) {
throw new Error("products is required in <PricingTable />");
}
if (products.length === 0) {
return /* @__PURE__ */ jsx2(Fragment2, {});
}
const hasRecommended = products?.some((p) => p.display?.recommend_text);
return /* @__PURE__ */ jsx2(
PricingTableContext.Provider,
{
value: { isAnnualToggle, setIsAnnualToggle, products, showFeatures },
children: /* @__PURE__ */ jsxs2(
"div",
{
className: cn(
"au-flex au-items-center au-flex-col",
hasRecommended && "!au-py-10"
),
children: [
multiInterval && /* @__PURE__ */ jsx2(
"div",
{
className: cn(
products.some((p) => p.display?.recommend_text) && "au-mb-8"
),
children: /* @__PURE__ */ jsx2(
AnnualSwitch,
{
isAnnualToggle,
setIsAnnualToggle
}
)
}
),
/* @__PURE__ */ jsx2(
"div",
{
className: cn(
"au-grid au-grid-cols-1 sm:au-grid-cols-2 lg:au-grid-cols-[repeat(auto-fit,minmax(200px,1fr))] au-w-full au-gap-2",
className
),
children
}
)
]
}
)
}
);
};
var PricingCard = ({
productId,
className,
buttonProps
}) => {
const { products, showFeatures } = usePricingTableContext("PricingCard");
const product = products.find((p) => p.id === productId);
if (!product) {
throw new Error(`Product with id ${productId} not found`);
}
const { name, display: productDisplay, items } = product;
const { buttonText } = getPricingTableContent(product);
const isRecommended = productDisplay?.recommend_text ? true : false;
const mainPriceDisplay = product.properties?.is_free ? {
primary_text: "Free"
} : product.items[0].display;
const featureItems = product.properties?.is_free ? product.items : product.items.slice(1);
return /* @__PURE__ */ jsxs2(
"div",
{
className: cn(
" au-w-full au-h-full au-py-6 au-text-foreground au-border au-rounded-lg au-shadow-sm au-max-w-xl",
isRecommended && "lg:au--translate-y-6 lg:au-shadow-lg dark:au-shadow-zinc-800/80 lg:au-h-[calc(100%+48px)] au-bg-secondary/40",
className
),
children: [
productDisplay?.recommend_text && /* @__PURE__ */ jsx2(RecommendedBadge, { recommended: productDisplay?.recommend_text }),
/* @__PURE__ */ jsxs2(
"div",
{
className: cn(
"au-flex au-flex-col au-h-full au-flex-grow",
isRecommended && "lg:au-translate-y-6"
),
children: [
/* @__PURE__ */ jsxs2("div", { className: "au-h-full", children: [
/* @__PURE__ */ jsxs2("div", { className: "au-flex au-flex-col", children: [
/* @__PURE__ */ jsxs2("div", { className: "au-pb-4", children: [
/* @__PURE__ */ jsx2("h2", { className: "au-text-2xl au-font-semibold au-px-6 au-truncate", children: productDisplay?.name || name }),
productDisplay?.description && /* @__PURE__ */ jsx2("div", { className: "au-text-sm au-text-muted-foreground au-px-6 au-h-8", children: /* @__PURE__ */ jsx2("p", { className: "au-line-clamp-2", children: productDisplay?.description }) })
] }),
/* @__PURE__ */ jsx2("div", { className: "au-mb-2", children: /* @__PURE__ */ jsx2("h3", { className: "au-font-semibold au-h-16 au-flex au-px-6 au-items-center au-border-y au-mb-4 au-bg-secondary/40", children: /* @__PURE__ */ jsxs2("div", { className: "au-line-clamp-2", children: [
mainPriceDisplay?.primary_text,
" ",
mainPriceDisplay?.secondary_text && /* @__PURE__ */ jsx2("span", { className: "au-font-normal au-text-muted-foreground au-mt-1", children: mainPriceDisplay?.secondary_text })
] }) }) })
] }),
showFeatures && featureItems.length > 0 && /* @__PURE__ */ jsx2("div", { className: "au-flex-grow au-px-6 au-mb-6", children: /* @__PURE__ */ jsx2(
PricingFeatureList,
{
items: featureItems,
showIcon: true,
everythingFrom: product.display?.everything_from
}
) })
] }),
/* @__PURE__ */ jsx2(
"div",
{
className: cn(" au-px-6 ", isRecommended && "lg:au--translate-y-12"),
children: /* @__PURE__ */ jsx2(
PricingCardButton,
{
recommended: productDisplay?.recommend_text ? true : false,
...buttonProps,
children: productDisplay?.button_text || buttonText
}
)
}
)
]
}
)
]
}
);
};
var PricingFeatureList = ({
items,
showIcon = true,
everythingFrom,
className
}) => {
return /* @__PURE__ */ jsxs2("div", { className: cn("au-flex-grow", className), children: [
everythingFrom && /* @__PURE__ */ jsxs2("p", { className: "au-text-sm au-mb-4", children: [
"Everything from ",
everythingFrom,
", plus:"
] }),
/* @__PURE__ */ jsx2("div", { className: "au-space-y-3", children: items.map((item, index) => /* @__PURE__ */ jsx2(
"div",
{
className: "au-flex au-items-start au-gap-2 au-text-sm",
children: /* @__PURE__ */ jsxs2("div", { className: "au-flex au-flex-col", children: [
/* @__PURE__ */ jsx2("span", { children: item.display?.primary_text }),
item.display?.secondary_text && /* @__PURE__ */ jsx2("span", { className: "au-text-sm au-text-muted-foreground", children: item.display?.secondary_text })
] })
},
index
)) })
] });
};
var PricingCardButton = React2.forwardRef(({ recommended, children, className, onClick, ...props }, ref) => {
const [loading, setLoading] = useState2(false);
const handleClick = async (e) => {
setLoading(true);
try {
await onClick?.(e);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};
return /* @__PURE__ */ jsx2(
Button,
{
className: cn(
"au-w-full au-py-3 au-px-4 au-group au-overflow-hidden au-relative au-transition-all au-duration-300 hover:au-brightness-90 au-border au-rounded-lg",
className
),
...props,
variant: recommended ? "default" : "secondary",
ref,
disabled: loading || props.disabled,
onClick: handleClick,
children: loading ? /* @__PURE__ */ jsx2(LoaderCircle, { className: "au-h-4 au-w-4 au-animate-spin" }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
/* @__PURE__ */ jsxs2("div", { className: "au-flex au-items-center au-justify-between au-w-full au-transition-transform au-duration-300 group-hover:au-translate-y-[-130%]", children: [
/* @__PURE__ */ jsx2("span", { children }),
/* @__PURE__ */ jsx2("span", { className: "au-text-sm", children: "\u2192" })
] }),
/* @__PURE__ */ jsxs2("div", { className: "au-flex au-items-center au-justify-between au-w-full au-absolute au-px-4 au-translate-y-[130%] au-transition-transform au-duration-300 group-hover:au-translate-y-0 au-mt-2 group-hover:au-mt-0", children: [
/* @__PURE__ */ jsx2("span", { children }),
/* @__PURE__ */ jsx2("span", { className: "au-text-sm", children: "\u2192" })
] })
] })
}
);
});
PricingCardButton.displayName = "PricingCardButton";
var AnnualSwitch = ({
isAnnualToggle,
setIsAnnualToggle
}) => {
return /* @__PURE__ */ jsxs2("div", { className: "au-flex au-items-center au-space-x-2 au-mb-4", children: [
/* @__PURE__ */ jsx2("span", { className: "au-text-sm au-text-muted-foreground", children: "Monthly" }),
/* @__PURE__ */ jsx2(
Switch,
{
id: "annual-billing",
checked: isAnnualToggle,
onCheckedChange: setIsAnnualToggle
}
),
/* @__PURE__ */ jsx2("span", { className: "au-text-sm au-text-muted-foreground", children: "Annual" })
] });
};
var RecommendedBadge = ({ recommended }) => {
return /* @__PURE__ */ jsx2("div", { className: "au-bg-secondary au-absolute au-border au-text-muted-foreground au-text-sm au-font-medium lg:au-rounded-full au-px-3 lg:au-py-0.5 lg:au-top-4 lg:au-right-4 au-top-[-1px] au-right-[-1px] au-rounded-bl-lg", children: recommended });
};
export {
PricingTable,
usePricingTableContext,
PricingTableContainer,
PricingCard,
PricingFeatureList,
PricingCardButton,
AnnualSwitch,
RecommendedBadge,
AttachDialog,
PriceItem,
PricingDialogButton
};