@ably/ui 17.4.2 → 17.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +573 -0
- package/README.md +120 -68
- package/core/Accordion/types.js.map +1 -1
- package/core/Accordion/utils.js +1 -1
- package/core/Accordion/utils.js.map +1 -1
- package/core/Accordion.js +1 -1
- package/core/Accordion.js.map +1 -1
- package/core/Badge.js +1 -1
- package/core/Badge.js.map +1 -1
- package/core/Code/Code.test.js +2 -0
- package/core/Code/Code.test.js.map +1 -0
- package/core/Code.js +1 -1
- package/core/Code.js.map +1 -1
- package/core/CodeSnippet/ApiKeySelector.js +1 -1
- package/core/CodeSnippet/ApiKeySelector.js.map +1 -1
- package/core/CodeSnippet/CodeSnippet.test.js +2 -0
- package/core/CodeSnippet/CodeSnippet.test.js.map +1 -0
- package/core/CodeSnippet/CopyButton.js +1 -1
- package/core/CodeSnippet/CopyButton.js.map +1 -1
- package/core/CodeSnippet/LanguageSelector.js +1 -1
- package/core/CodeSnippet/LanguageSelector.js.map +1 -1
- package/core/CodeSnippet/PlainCodeView.js +1 -1
- package/core/CodeSnippet/PlainCodeView.js.map +1 -1
- package/core/CodeSnippet/TooltipButton.js +1 -1
- package/core/CodeSnippet/TooltipButton.js.map +1 -1
- package/core/CodeSnippet/languages.js +1 -1
- package/core/CodeSnippet/languages.js.map +1 -1
- package/core/CodeSnippet/languages.test.js +2 -0
- package/core/CodeSnippet/languages.test.js.map +1 -0
- package/core/CodeSnippet.js +1 -1
- package/core/CodeSnippet.js.map +1 -1
- package/core/ConnectStateWrapper.js.map +1 -1
- package/core/ContentTile.js +2 -0
- package/core/ContentTile.js.map +1 -0
- package/core/DropdownMenu.js +1 -1
- package/core/DropdownMenu.js.map +1 -1
- package/core/Expander.js +1 -1
- package/core/Expander.js.map +1 -1
- package/core/FeaturedLink.js +1 -1
- package/core/FeaturedLink.js.map +1 -1
- package/core/Flash.js +1 -1
- package/core/Flash.js.map +1 -1
- package/core/Flyout.js +1 -1
- package/core/Flyout.js.map +1 -1
- package/core/Footer/data.js +1 -1
- package/core/Footer/data.js.map +1 -1
- package/core/Footer.js +1 -1
- package/core/Footer.js.map +1 -1
- package/core/Header/HeaderLinks.js +1 -1
- package/core/Header/HeaderLinks.js.map +1 -1
- package/core/Header/types.js +2 -0
- package/core/Header/types.js.map +1 -0
- package/core/Header.js +1 -1
- package/core/Header.js.map +1 -1
- package/core/Icon/components/icon-display-cloud-servers-mono.js +2 -0
- package/core/Icon/components/icon-display-cloud-servers-mono.js.map +1 -0
- package/core/Icon/components/icon-display-data-integrity.js +2 -0
- package/core/Icon/components/icon-display-data-integrity.js.map +1 -0
- package/core/Icon/components/icon-display-database-connector.js +2 -0
- package/core/Icon/components/icon-display-database-connector.js.map +1 -0
- package/core/Icon/components/icon-display-ephemeral-messages-dark-col.js +2 -0
- package/core/Icon/components/icon-display-ephemeral-messages-dark-col.js.map +1 -0
- package/core/Icon/components/icon-display-ephemeral-messages.js +2 -0
- package/core/Icon/components/icon-display-ephemeral-messages.js.map +1 -0
- package/core/Icon/components/icon-display-live-updates.js +2 -0
- package/core/Icon/components/icon-display-live-updates.js.map +1 -0
- package/core/Icon/components/icon-display-message-annotations-dark-col.js +2 -0
- package/core/Icon/components/icon-display-message-annotations-dark-col.js.map +1 -0
- package/core/Icon/components/icon-display-message-annotations.js +2 -0
- package/core/Icon/components/icon-display-message-annotations.js.map +1 -0
- package/core/Icon/components/icon-display-multi-user-spaces.js +2 -0
- package/core/Icon/components/icon-display-multi-user-spaces.js.map +1 -0
- package/core/Icon/components/icon-display-sdks.js +2 -0
- package/core/Icon/components/icon-display-sdks.js.map +1 -0
- package/core/Icon/components/icon-display-something-else-mono.js +2 -0
- package/core/Icon/components/icon-display-something-else-mono.js.map +1 -0
- package/core/Icon/components/icon-display-something-else.js +2 -0
- package/core/Icon/components/icon-display-something-else.js.map +1 -0
- package/core/Icon/components/icon-display-ui-mono.js +2 -0
- package/core/Icon/components/icon-display-ui-mono.js.map +1 -0
- package/core/Icon/components/icon-display-ui.js +2 -0
- package/core/Icon/components/icon-display-ui.js.map +1 -0
- package/core/Icon/components/icon-gui-checklist-checked.js +1 -1
- package/core/Icon/components/icon-gui-checklist-checked.js.map +1 -1
- package/core/Icon/components/icon-gui-code-doc.js +1 -1
- package/core/Icon/components/icon-gui-code-doc.js.map +1 -1
- package/core/Icon/components/icon-gui-cursor.js +1 -1
- package/core/Icon/components/icon-gui-cursor.js.map +1 -1
- package/core/Icon/components/icon-gui-expand.js +1 -1
- package/core/Icon/components/icon-gui-expand.js.map +1 -1
- package/core/Icon/components/icon-gui-filter-flow-step-0.js +1 -1
- package/core/Icon/components/icon-gui-filter-flow-step-0.js.map +1 -1
- package/core/Icon/components/icon-gui-flower-growth.js +1 -1
- package/core/Icon/components/icon-gui-flower-growth.js.map +1 -1
- package/core/Icon/components/icon-gui-glasses.js +1 -1
- package/core/Icon/components/icon-gui-glasses.js.map +1 -1
- package/core/Icon/components/icon-gui-heartbeat-outline.js +2 -0
- package/core/Icon/components/icon-gui-heartbeat-outline.js.map +1 -0
- package/core/Icon/components/icon-gui-heartbeat-solid.js +2 -0
- package/core/Icon/components/icon-gui-heartbeat-solid.js.map +1 -0
- package/core/Icon/components/icon-gui-mouse.js +1 -1
- package/core/Icon/components/icon-gui-mouse.js.map +1 -1
- package/core/Icon/components/icon-gui-pitfall.js +1 -1
- package/core/Icon/components/icon-gui-pitfall.js.map +1 -1
- package/core/Icon/components/icon-gui-prod-ai-transport-outline.js +2 -0
- package/core/Icon/components/icon-gui-prod-ai-transport-outline.js.map +1 -0
- package/core/Icon/components/icon-gui-prod-ai-transport-solid.js +2 -0
- package/core/Icon/components/icon-gui-prod-ai-transport-solid.js.map +1 -0
- package/core/Icon/components/icon-gui-quote-marks-fill.js +1 -1
- package/core/Icon/components/icon-gui-quote-marks-fill.js.map +1 -1
- package/core/Icon/components/icon-product-ai-transport-mono.js +2 -0
- package/core/Icon/components/icon-product-ai-transport-mono.js.map +1 -0
- package/core/Icon/components/icon-product-ai-transport.js +2 -0
- package/core/Icon/components/icon-product-ai-transport.js.map +1 -0
- package/core/Icon/components/icon-product-chat-mono.js +1 -1
- package/core/Icon/components/icon-product-chat-mono.js.map +1 -1
- package/core/Icon/components/icon-product-liveobjects-mono.js +1 -1
- package/core/Icon/components/icon-product-liveobjects-mono.js.map +1 -1
- package/core/Icon/components/icon-product-livesync-mono.js +1 -1
- package/core/Icon/components/icon-product-livesync-mono.js.map +1 -1
- package/core/Icon/components/icon-product-pubsub-mono.js +1 -1
- package/core/Icon/components/icon-product-pubsub-mono.js.map +1 -1
- package/core/Icon/components/icon-product-spaces-mono.js +1 -1
- package/core/Icon/components/icon-product-spaces-mono.js.map +1 -1
- package/core/Icon/components/icon-tech-claude-mono.js +2 -0
- package/core/Icon/components/icon-tech-claude-mono.js.map +1 -0
- package/core/Icon/components/icon-tech-claude.js +2 -0
- package/core/Icon/components/icon-tech-claude.js.map +1 -0
- package/core/Icon/components/icon-tech-jetpack.js +2 -0
- package/core/Icon/components/icon-tech-jetpack.js.map +1 -0
- package/core/Icon/components/icon-tech-terraform-outline.js +2 -0
- package/core/Icon/components/icon-tech-terraform-outline.js.map +1 -0
- package/core/Icon/components/index.js +1 -1
- package/core/Icon/components/index.js.map +1 -1
- package/core/Icon/computed-icons/display-icons.js +1 -1
- package/core/Icon/computed-icons/display-icons.js.map +1 -1
- package/core/Icon/computed-icons/gui-icons.js +1 -1
- package/core/Icon/computed-icons/gui-icons.js.map +1 -1
- package/core/Icon/computed-icons/product-icons.js +1 -1
- package/core/Icon/computed-icons/product-icons.js.map +1 -1
- package/core/Icon/computed-icons/tech-icons.js +1 -1
- package/core/Icon/computed-icons/tech-icons.js.map +1 -1
- package/core/Icon.js +1 -1
- package/core/Icon.js.map +1 -1
- package/core/LinkButton.js +1 -1
- package/core/LinkButton.js.map +1 -1
- package/core/Logo.js +1 -1
- package/core/Logo.js.map +1 -1
- package/core/Meganav/MeganavBlog.js +2 -0
- package/core/Meganav/MeganavBlog.js.map +1 -0
- package/core/Meganav/MeganavCustomerStories.js +2 -0
- package/core/Meganav/MeganavCustomerStories.js.map +1 -0
- package/core/Meganav/MeganavMobile.js +1 -1
- package/core/Meganav/MeganavMobile.js.map +1 -1
- package/core/Meganav/MeganavPanel.js +1 -1
- package/core/Meganav/MeganavPanel.js.map +1 -1
- package/core/Meganav/MeganavPanelItemLinks.js +2 -0
- package/core/Meganav/MeganavPanelItemLinks.js.map +1 -0
- package/core/Meganav/MeganavTile.js +2 -0
- package/core/Meganav/MeganavTile.js.map +1 -0
- package/core/Meganav/PanelTitle.js +2 -0
- package/core/Meganav/PanelTitle.js.map +1 -0
- package/core/Meganav/data.js +1 -1
- package/core/Meganav/data.js.map +1 -1
- package/core/Meganav/images/cust-logo-doxy-dark.png +0 -0
- package/core/Meganav/images/cust-logo-doxy-light.png +0 -0
- package/core/Meganav/utils/getMenuItemsForHeader.js +2 -0
- package/core/Meganav/utils/getMenuItemsForHeader.js.map +1 -0
- package/core/Meganav.js +1 -1
- package/core/Meganav.js.map +1 -1
- package/core/Notice/component.css +9 -3
- package/core/Notice/component.js +1 -1
- package/core/Notice/component.js.map +1 -1
- package/core/Notice.js +1 -1
- package/core/Notice.js.map +1 -1
- package/core/Pricing/PricingCards.js +1 -1
- package/core/Pricing/PricingCards.js.map +1 -1
- package/core/Pricing/data.js +1 -1
- package/core/Pricing/data.js.map +1 -1
- package/core/Pricing/types.js.map +1 -1
- package/core/ProductTile/ProductDescription.js +1 -1
- package/core/ProductTile/ProductDescription.js.map +1 -1
- package/core/ProductTile/ProductIcon.js +1 -1
- package/core/ProductTile/ProductIcon.js.map +1 -1
- package/core/ProductTile/ProductLabel.js +1 -1
- package/core/ProductTile/ProductLabel.js.map +1 -1
- package/core/ProductTile/data.js +1 -1
- package/core/ProductTile/data.js.map +1 -1
- package/core/ProductTile.js +1 -1
- package/core/ProductTile.js.map +1 -1
- package/core/SegmentedControl.js +1 -1
- package/core/SegmentedControl.js.map +1 -1
- package/core/Slider/component.js +1 -1
- package/core/Slider/component.js.map +1 -1
- package/core/Slider.js +1 -1
- package/core/Slider.js.map +1 -1
- package/core/TabMenu.js +1 -1
- package/core/TabMenu.js.map +1 -1
- package/core/Table/data.js +1 -1
- package/core/Table/data.js.map +1 -1
- package/core/Toggle.js +1 -1
- package/core/Toggle.js.map +1 -1
- package/core/Tooltip.js +1 -1
- package/core/Tooltip.js.map +1 -1
- package/core/fonts/NEXT-Book-Light-Italic.eot +0 -0
- package/core/fonts/NEXT-Book-Light-Italic.otf +0 -0
- package/core/fonts/NEXT-Book-Light-Italic.woff +0 -0
- package/core/fonts/NEXT-Book-Light-Italic.woff2 +0 -0
- package/core/fonts/NEXT-Book-Light.eot +0 -0
- package/core/fonts/NEXT-Book-Light.otf +0 -0
- package/core/fonts/NEXT-Book-Light.woff +0 -0
- package/core/fonts/NEXT-Book-Light.woff2 +0 -0
- package/core/fonts/NEXT-Book-Medium-Italic.eot +0 -0
- package/core/fonts/NEXT-Book-Medium-Italic.otf +0 -0
- package/core/fonts/NEXT-Book-Medium-Italic.woff +0 -0
- package/core/fonts/NEXT-Book-Medium-Italic.woff2 +0 -0
- package/core/fonts/NEXT-Book-Medium.eot +0 -0
- package/core/fonts/NEXT-Book-Medium.otf +0 -0
- package/core/fonts/NEXT-Book-Medium.woff +0 -0
- package/core/fonts/NEXT-Book-Medium.woff2 +0 -0
- package/core/hooks/use-content-height.js +2 -0
- package/core/hooks/use-content-height.js.map +1 -0
- package/core/hooks/use-themed-scrollpoints.js +2 -0
- package/core/hooks/use-themed-scrollpoints.js.map +1 -0
- package/core/hooks/use-themed-scrollpoints.test.js +2 -0
- package/core/hooks/use-themed-scrollpoints.test.js.map +1 -0
- package/core/icons/display/icon-display-cloud-servers-mono.svg +3 -0
- package/core/icons/display/icon-display-data-integrity.svg +9 -0
- package/core/icons/display/icon-display-database-connector.svg +13 -0
- package/core/icons/display/icon-display-ephemeral-messages-dark-col.svg +6 -0
- package/core/icons/display/icon-display-ephemeral-messages.svg +6 -0
- package/core/icons/display/icon-display-live-updates.svg +8 -0
- package/core/icons/display/icon-display-message-annotations-dark-col.svg +11 -0
- package/core/icons/display/icon-display-message-annotations.svg +11 -0
- package/core/icons/display/icon-display-multi-user-spaces.svg +13 -0
- package/core/icons/display/icon-display-sdks.svg +11 -0
- package/core/icons/display/icon-display-something-else-mono.svg +4 -0
- package/core/icons/display/icon-display-something-else.svg +4 -0
- package/core/icons/display/icon-display-ui-mono.svg +22 -0
- package/core/icons/display/icon-display-ui.svg +22 -0
- package/core/icons/gui/icon-gui-checklist-checked.svg +1 -1
- package/core/icons/gui/icon-gui-code-doc.svg +1 -1
- package/core/icons/gui/icon-gui-cursor.svg +1 -1
- package/core/icons/gui/icon-gui-expand.svg +1 -1
- package/core/icons/gui/icon-gui-filter-flow-step-0.svg +3 -3
- package/core/icons/gui/icon-gui-flower-growth.svg +1 -1
- package/core/icons/gui/icon-gui-glasses.svg +1 -1
- package/core/icons/gui/icon-gui-heartbeat-outline.svg +4 -0
- package/core/icons/gui/icon-gui-heartbeat-solid.svg +4 -0
- package/core/icons/gui/icon-gui-mouse.svg +1 -1
- package/core/icons/gui/icon-gui-pitfall.svg +1 -1
- package/core/icons/gui/icon-gui-prod-ai-transport-outline.svg +5 -0
- package/core/icons/gui/icon-gui-prod-ai-transport-solid.svg +5 -0
- package/core/icons/gui/icon-gui-quote-marks-fill.svg +2 -2
- package/core/icons/product/icon-product-ai-transport-mono.svg +5 -0
- package/core/icons/product/icon-product-ai-transport.svg +12 -0
- package/core/icons/product/icon-product-chat-mono.svg +1 -1
- package/core/icons/product/icon-product-liveobjects-mono.svg +1 -4
- package/core/icons/product/icon-product-livesync-mono.svg +4 -4
- package/core/icons/product/icon-product-pubsub-mono.svg +1 -1
- package/core/icons/product/icon-product-spaces-mono.svg +1 -1
- package/core/icons/tech/icon-tech-claude-mono.svg +5 -0
- package/core/icons/tech/icon-tech-claude.svg +3 -0
- package/core/icons/tech/icon-tech-jetpack.svg +1 -0
- package/core/icons/tech/icon-tech-terraform-outline.svg +5 -0
- package/core/images/badges/g2-best-meets-requirements-spring-2025.svg +26 -0
- package/core/images/badges/g2-best-results-spring-2025.svg +26 -0
- package/core/images/badges/g2-best-support-spring-2025.svg +26 -0
- package/core/images/badges/g2-easiest-to-use-spring-2025.svg +26 -0
- package/core/images/badges/g2-users-most-likely-to-recommend-spring-2025.svg +26 -0
- package/core/images/cust-logo-mentimeter-mono-pos.svg +0 -0
- package/core/insights/command-queue.js +1 -1
- package/core/insights/command-queue.js.map +1 -1
- package/core/insights/datalayer.js +1 -1
- package/core/insights/datalayer.js.map +1 -1
- package/core/insights/index.js +1 -1
- package/core/insights/index.js.map +1 -1
- package/core/insights/index.test.js +1 -1
- package/core/insights/index.test.js.map +1 -1
- package/core/insights/mixpanel.js +1 -1
- package/core/insights/mixpanel.js.map +1 -1
- package/core/insights/mixpanel.test.js +2 -0
- package/core/insights/mixpanel.test.js.map +1 -0
- package/core/insights/posthog.js +1 -1
- package/core/insights/posthog.js.map +1 -1
- package/core/insights/posthog.test.js +2 -0
- package/core/insights/posthog.test.js.map +1 -0
- package/core/insights/service.js +1 -1
- package/core/insights/service.js.map +1 -1
- package/core/insights/types.js.map +1 -1
- package/core/react-renderer.js.map +1 -1
- package/core/sprites-display.svg +1 -1
- package/core/sprites-gui.svg +1 -1
- package/core/sprites-product.svg +1 -1
- package/core/sprites-tech.svg +1 -1
- package/core/styles/buttons.css +6 -6
- package/core/styles/colors/types.js +1 -1
- package/core/styles/colors/types.js.map +1 -1
- package/core/styles/forms.css +5 -5
- package/core/styles/legacy-buttons.css +8 -8
- package/core/styles/properties.css +4 -4
- package/core/styles/text.css +2 -2
- package/core/styles.components.css +4 -4
- package/core/utils/syntax-highlighter.css +31 -0
- package/core/utils/syntax-highlighter.js +1 -1
- package/core/utils/syntax-highlighter.js.map +1 -1
- package/core/utils/syntax-highlighter.test.js +2 -0
- package/core/utils/syntax-highlighter.test.js.map +1 -0
- package/index.d.ts +1201 -118
- package/package.json +66 -59
- package/tailwind.config.js +2 -2
- package/core/CookieMessage/component.css +0 -15
- package/core/CookieMessage.js +0 -2
- package/core/CookieMessage.js.map +0 -1
- package/core/Icon/components/icon-display-asset-tracking-col.js +0 -2
- package/core/Icon/components/icon-display-asset-tracking-col.js.map +0 -1
- package/core/Icon/components/icon-gui-prod-asset-tracking-outline.js +0 -2
- package/core/Icon/components/icon-gui-prod-asset-tracking-outline.js.map +0 -1
- package/core/Icon/components/icon-gui-prod-asset-tracking-solid.js +0 -2
- package/core/Icon/components/icon-gui-prod-asset-tracking-solid.js.map +0 -1
- package/core/Icon/components/icon-product-asset-tracking-mono.js +0 -2
- package/core/Icon/components/icon-product-asset-tracking-mono.js.map +0 -1
- package/core/Icon/components/icon-product-asset-tracking.js +0 -2
- package/core/Icon/components/icon-product-asset-tracking.js.map +0 -1
- package/core/Meganav/MeganavProductTile.js +0 -2
- package/core/Meganav/MeganavProductTile.js.map +0 -1
- package/core/Meganav/images/fan-engagement-nav-image.png +0 -0
- package/core/Meganav/images/founders-nav-image.png +0 -0
- package/core/icons/display/icon-display-asset-tracking-col.svg +0 -18
- package/core/icons/gui/icon-gui-prod-asset-tracking-outline.svg +0 -3
- package/core/icons/gui/icon-gui-prod-asset-tracking-solid.svg +0 -3
- package/core/icons/product/icon-product-asset-tracking-mono.svg +0 -3
- package/core/icons/product/icon-product-asset-tracking.svg +0 -12
- package/core/images/g2-best-meets-requirements-2025.svg +0 -10
- package/core/images/g2-best-support-2025.svg +0 -10
- package/core/images/g2-high-performer-2025.svg +0 -9
- package/core/images/g2-users-most-likely-to-recommend-2025.svg +0 -10
- package/core/utils/useCopyToClipboard.js +0 -2
- package/core/utils/useCopyToClipboard.js.map +0 -1
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
@layer components {
|
|
2
2
|
.ui-announcement {
|
|
3
|
-
@apply font-sans;
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
@apply font-sans transition-[max-height,transform,opacity] duration-300 ease-in-out;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.ui-announcement-visible {
|
|
7
|
+
@apply max-h-[37.5rem] translate-y-0 opacity-100 overflow-visible;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.ui-announcement-hidden {
|
|
11
|
+
@apply max-h-0 -translate-y-full opacity-0 overflow-hidden;
|
|
6
12
|
}
|
|
7
13
|
}
|
package/core/Notice/component.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import Cookie from"js-cookie";import
|
|
1
|
+
import Cookie from"js-cookie";import{throttle}from"es-toolkit/compat";import{queryId}from"../dom-query";import{FLASH_DATA_ID}from"../Flash";const COOKIE_EXPIRY=90;export const COLLAPSE_TRIGGER_DISTANCE=5;const SCROLL_LISTENER_THROTTLE=100;const RESIZE_LISTENER_THROTTLE=100;const isMdViewport=()=>!window.matchMedia(`(min-width: 65rem)`).matches;const adjustFlashMargin=open=>{const flash=queryId(FLASH_DATA_ID);if(flash){flash.style.marginTop=open?`4rem`:null}};const hideOnMobile=bannerContainer=>{if(isMdViewport()){bannerContainer.style.display="none"}else{bannerContainer.style.display=null}};const hideNotice=bannerContainer=>{bannerContainer.classList.remove("ui-announcement-visible");bannerContainer.classList.add("ui-announcement-hidden");adjustFlashMargin(false)};const showNotice=bannerContainer=>{bannerContainer.classList.remove("ui-announcement-hidden");bannerContainer.classList.add("ui-announcement-visible");adjustFlashMargin(true)};const setupRememberClosed=(cookieId,noticeId)=>{const cookie=Cookie.get(cookieId)||"";Cookie.set(cookieId,`${cookie.replace(`${noticeId},`,"")+noticeId},`,{expires:COOKIE_EXPIRY})};const hasBeenClosedBefore=(cookieId,noticeId)=>(Cookie.get(cookieId)||"").includes(noticeId);const setupNoticeCollapse=bannerContainer=>{const scrollTop=window.scrollY;if(scrollTop>COLLAPSE_TRIGGER_DISTANCE){hideNotice(bannerContainer)}const listener=throttle(()=>{const scrollTop=window.scrollY;if(scrollTop>COLLAPSE_TRIGGER_DISTANCE){hideNotice(bannerContainer)}else if(bannerContainer.classList.contains("ui-announcement-hidden")){showNotice(bannerContainer)}},SCROLL_LISTENER_THROTTLE);document.addEventListener("scroll",listener);return()=>document.removeEventListener("scroll",listener)};const setupCloseBtn=(bannerContainer,cookieId,noticeId,collapseUnmountListeners)=>{const closeBtn=bannerContainer.querySelector("button");if(!closeBtn)return()=>{};const listener=()=>{if(cookieId&¬iceId)setupRememberClosed(cookieId,noticeId);hideNotice(bannerContainer);collapseUnmountListeners()};closeBtn.addEventListener("click",listener);return()=>closeBtn.removeEventListener("click",listener)};const resizeHandler=bannerContainer=>{const handler=throttle(()=>{hideOnMobile(bannerContainer)},RESIZE_LISTENER_THROTTLE);window.addEventListener("resize",handler);return()=>window.removeEventListener("resize",handler)};const Notice=({bannerContainer,cookieId,noticeId,options})=>{if(typeof window==="undefined")return()=>{};if(!bannerContainer){console.warn("A Notice component was initited but no notice container was found.");return()=>{}}if(hasBeenClosedBefore(cookieId,noticeId))return()=>{};hideOnMobile(bannerContainer);showNotice(bannerContainer);const opts={collapse:true,...options};const collapseUnmountListeners=opts.collapse?setupNoticeCollapse(bannerContainer):()=>{};const closeBtnUnmountListeners=setupCloseBtn(bannerContainer,cookieId,noticeId,collapseUnmountListeners);const resizeUnmountListener=resizeHandler(bannerContainer);return()=>{[closeBtnUnmountListeners,collapseUnmountListeners,resizeUnmountListener].forEach(unmount=>unmount())}};export default Notice;
|
|
2
2
|
//# sourceMappingURL=component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Notice/component.js"],"sourcesContent":["import Cookie from \"js-cookie\";\nimport throttle from \"
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Notice/component.js"],"sourcesContent":["import Cookie from \"js-cookie\";\nimport { throttle } from \"es-toolkit/compat\";\n\nimport { queryId } from \"../dom-query\";\nimport { FLASH_DATA_ID } from \"../Flash\";\n\nconst COOKIE_EXPIRY = 90;\nexport const COLLAPSE_TRIGGER_DISTANCE = 5;\nconst SCROLL_LISTENER_THROTTLE = 100;\nconst RESIZE_LISTENER_THROTTLE = 100;\n\nconst isMdViewport = () => !window.matchMedia(`(min-width: 65rem)`).matches;\n\nconst adjustFlashMargin = (open) => {\n // HACK ALERT\n // Add margin to flashes when opening the notice.\n // Flashes are react components and this notice needs to work as a view-component and react component.\n // We could do this with redux but then we potentially update state on every scroll event, which\n // even with debounce will deplate our frame budget.\n\n const flash = queryId(FLASH_DATA_ID);\n\n if (flash) {\n flash.style.marginTop = open ? `4rem` : null;\n }\n};\n\nconst hideOnMobile = (bannerContainer) => {\n if (isMdViewport()) {\n bannerContainer.style.display = \"none\";\n } else {\n bannerContainer.style.display = null;\n }\n};\n\nconst hideNotice = (bannerContainer) => {\n bannerContainer.classList.remove(\"ui-announcement-visible\");\n bannerContainer.classList.add(\"ui-announcement-hidden\");\n\n adjustFlashMargin(false);\n};\n\nconst showNotice = (bannerContainer) => {\n bannerContainer.classList.remove(\"ui-announcement-hidden\");\n bannerContainer.classList.add(\"ui-announcement-visible\");\n\n adjustFlashMargin(true);\n};\n\nconst setupRememberClosed = (cookieId, noticeId) => {\n const cookie = Cookie.get(cookieId) || \"\";\n\n Cookie.set(cookieId, `${cookie.replace(`${noticeId},`, \"\") + noticeId},`, {\n expires: COOKIE_EXPIRY,\n });\n};\n\nconst hasBeenClosedBefore = (cookieId, noticeId) =>\n (Cookie.get(cookieId) || \"\").includes(noticeId);\n\nconst setupNoticeCollapse = (bannerContainer) => {\n const scrollTop = window.scrollY;\n\n if (scrollTop > COLLAPSE_TRIGGER_DISTANCE) {\n hideNotice(bannerContainer);\n }\n\n const listener = throttle(() => {\n const scrollTop = window.scrollY;\n\n if (scrollTop > COLLAPSE_TRIGGER_DISTANCE) {\n hideNotice(bannerContainer);\n } else if (bannerContainer.classList.contains(\"ui-announcement-hidden\")) {\n showNotice(bannerContainer);\n }\n }, SCROLL_LISTENER_THROTTLE);\n\n document.addEventListener(\"scroll\", listener);\n\n return () => document.removeEventListener(\"scroll\", listener);\n};\n\nconst setupCloseBtn = (\n bannerContainer,\n cookieId,\n noticeId,\n collapseUnmountListeners,\n) => {\n const closeBtn = bannerContainer.querySelector(\"button\");\n\n if (!closeBtn) return () => {};\n\n const listener = () => {\n if (cookieId && noticeId) setupRememberClosed(cookieId, noticeId);\n\n hideNotice(bannerContainer);\n collapseUnmountListeners();\n };\n\n closeBtn.addEventListener(\"click\", listener);\n\n return () => closeBtn.removeEventListener(\"click\", listener);\n};\n\nconst resizeHandler = (bannerContainer) => {\n const handler = throttle(() => {\n hideOnMobile(bannerContainer);\n }, RESIZE_LISTENER_THROTTLE);\n\n window.addEventListener(\"resize\", handler);\n\n return () => window.removeEventListener(\"resize\", handler);\n};\n\nconst Notice = ({ bannerContainer, cookieId, noticeId, options }) => {\n if (typeof window === \"undefined\") return () => {};\n\n if (!bannerContainer) {\n console.warn(\n \"A Notice component was initited but no notice container was found.\",\n );\n return () => {};\n }\n\n if (hasBeenClosedBefore(cookieId, noticeId)) return () => {};\n\n hideOnMobile(bannerContainer);\n showNotice(bannerContainer);\n\n const opts = { collapse: true, ...options };\n\n const collapseUnmountListeners = opts.collapse\n ? setupNoticeCollapse(bannerContainer)\n : () => {};\n\n const closeBtnUnmountListeners = setupCloseBtn(\n bannerContainer,\n cookieId,\n noticeId,\n collapseUnmountListeners,\n );\n\n const resizeUnmountListener = resizeHandler(bannerContainer);\n\n return () => {\n [\n closeBtnUnmountListeners,\n collapseUnmountListeners,\n resizeUnmountListener,\n ].forEach((unmount) => unmount());\n };\n};\n\nexport default Notice;\n"],"names":["Cookie","throttle","queryId","FLASH_DATA_ID","COOKIE_EXPIRY","COLLAPSE_TRIGGER_DISTANCE","SCROLL_LISTENER_THROTTLE","RESIZE_LISTENER_THROTTLE","isMdViewport","window","matchMedia","matches","adjustFlashMargin","open","flash","style","marginTop","hideOnMobile","bannerContainer","display","hideNotice","classList","remove","add","showNotice","setupRememberClosed","cookieId","noticeId","cookie","get","set","replace","expires","hasBeenClosedBefore","includes","setupNoticeCollapse","scrollTop","scrollY","listener","contains","document","addEventListener","removeEventListener","setupCloseBtn","collapseUnmountListeners","closeBtn","querySelector","resizeHandler","handler","Notice","options","console","warn","opts","collapse","closeBtnUnmountListeners","resizeUnmountListener","forEach","unmount"],"mappings":"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"}
|
package/core/Notice.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useEffect,useRef}from"react";import DOMPurify from"dompurify";import Icon from"./Icon";import cn from"./utils/cn.js";import NoticeScripts from"./Notice/component.js";import useRailsUjsLinks from"./hooks/use-rails-ujs-hooks";const defaultTextColor="text-neutral-1300 dark:text-neutral-000";const contentWrapperClasses="w-full pr-2 ui-text-p4 self-center";const
|
|
1
|
+
import React,{useEffect,useRef,useState}from"react";import DOMPurify from"dompurify";import Icon from"./Icon";import cn from"./utils/cn.js";import NoticeScripts from"./Notice/component.js";import useRailsUjsLinks from"./hooks/use-rails-ujs-hooks";const defaultTextColor="text-neutral-1300 dark:text-neutral-000";const contentWrapperClasses="w-full pr-2 ui-text-p4 self-center";const Notice=({buttonLink,buttonLabel,bodyText,title,config,closeBtn,bgColor="bg-orange-100 dark:bg-orange-1100",textColor=defaultTextColor,onClose})=>{const contentRef=useRef(null);const[isClosing,setIsClosing]=useState(false);useRailsUjsLinks(contentRef);useEffect(()=>{const cleanup=NoticeScripts({bannerContainer:document.querySelector('[data-id="ui-notice"]'),cookieId:config?.cookieId,noticeId:config?.noticeId,options:{collapse:config?.options?.collapse||false}});return cleanup},[config?.cookieId,config?.noticeId,config?.options?.collapse]);const safeContent=DOMPurify.sanitize(bodyText??"",{ALLOWED_TAGS:["a"],ALLOWED_ATTR:["href","data-method"],ALLOWED_URI_REGEXP:/^\/[^/]/});const isSafeButtonLink=typeof buttonLink==="string"&&(/^\/(?!\/)/.test(buttonLink)||/^https?:\/\//.test(buttonLink));return React.createElement("div",{className:cn("ui-announcement relative z-[60]",isClosing?"ui-announcement-hidden max-h-0 -translate-y-full opacity-0 overflow-hidden":"ui-announcement-visible",bgColor,textColor),"data-id":"ui-notice"},React.createElement("div",{className:"ui-grid-px py-4 max-w-screen-xl mx-auto flex items-start"},React.createElement("div",{className:cn(contentWrapperClasses,textColor)},React.createElement("strong",{className:"font-bold whitespace-nowrap pr-1"},title),React.createElement("span",{ref:contentRef,className:"pr-1",dangerouslySetInnerHTML:{__html:safeContent}}),buttonLabel&&(isSafeButtonLink?React.createElement("a",{href:buttonLink,className:"focus-base transition-colors cursor-pointer whitespace-nowrap text-gui-blue-default-light dark:text-gui-blue-default-dark"},buttonLabel):React.createElement("span",{className:"focus-base transition-colors cursor-pointer whitespace-nowrap text-gui-blue-default-light dark:text-gui-blue-default-dark"},buttonLabel))),closeBtn&&React.createElement("button",{type:"button",className:"ml-auto h-5 w-5 border-none bg-none self-baseline outline-none focus:outline-none focus:ring-0 focus:border-transparent",onClick:()=>{setIsClosing(true);setTimeout(()=>{document.dispatchEvent(new CustomEvent("notice-closed"));onClose?.()},300)}},React.createElement(Icon,{name:"icon-gui-x-mark-outline",size:"1.25rem",color:textColor}))))};export default Notice;
|
|
2
2
|
//# sourceMappingURL=Notice.js.map
|
package/core/Notice.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Notice.tsx"],"sourcesContent":["import React, {
|
|
1
|
+
{"version":3,"sources":["../../src/core/Notice.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport DOMPurify from \"dompurify\";\n\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn.js\";\nimport NoticeScripts from \"./Notice/component.js\";\nimport useRailsUjsLinks from \"./hooks/use-rails-ujs-hooks\";\n\n// TODO(jamiehenson):\n// This type is a bit messed up currently due to the NoticeScripts import being interpreted as NoticeProps.\n// Plan is to TS-ify the JS assets too, so this can be rectified then. The NoticeScripts-oriented props are\n// the ones after the line break.\nexport type NoticeProps = {\n buttonLink?: string;\n buttonLabel?: string;\n bodyText?: string;\n title?: string;\n closeBtn?: boolean;\n config?: {\n options: {\n collapse: boolean;\n };\n noticeId: string | number;\n cookieId: string;\n };\n bgColor?: string;\n textColor?: ColorClass | ColorThemeSet;\n onClose?: () => void;\n\n bannerContainer?: Element | null;\n cookieId?: string;\n noticeId?: string;\n options?: { collapse: boolean };\n};\n\nconst defaultTextColor = \"text-neutral-1300 dark:text-neutral-000\";\n\nconst contentWrapperClasses = \"w-full pr-2 ui-text-p4 self-center\";\n\nconst Notice = ({\n buttonLink,\n buttonLabel,\n bodyText,\n title,\n config,\n closeBtn,\n bgColor = \"bg-orange-100 dark:bg-orange-1100\",\n textColor = defaultTextColor,\n onClose,\n}: NoticeProps) => {\n const contentRef = useRef<HTMLSpanElement>(null);\n const [isClosing, setIsClosing] = useState(false);\n useRailsUjsLinks(contentRef);\n\n useEffect(() => {\n const cleanup = NoticeScripts({\n bannerContainer: document.querySelector('[data-id=\"ui-notice\"]'),\n cookieId: config?.cookieId,\n noticeId: config?.noticeId,\n options: {\n collapse: config?.options?.collapse || false,\n },\n });\n\n return cleanup;\n }, [config?.cookieId, config?.noticeId, config?.options?.collapse]);\n\n const safeContent = DOMPurify.sanitize(bodyText ?? \"\", {\n ALLOWED_TAGS: [\"a\"],\n ALLOWED_ATTR: [\"href\", \"data-method\"],\n ALLOWED_URI_REGEXP: /^\\/[^/]/,\n });\n\n const isSafeButtonLink =\n typeof buttonLink === \"string\" &&\n (/^\\/(?!\\/)/.test(buttonLink) || /^https?:\\/\\//.test(buttonLink));\n\n // have to add the style classes here as src/core/Notice/component.css is not being properly imported or distributed when ably-ui is used as a package.\n return (\n <div\n className={cn(\n \"ui-announcement relative z-[60]\",\n isClosing\n ? \"ui-announcement-hidden max-h-0 -translate-y-full opacity-0 overflow-hidden\"\n : \"ui-announcement-visible\",\n bgColor,\n textColor,\n )}\n data-id=\"ui-notice\"\n >\n <div className=\"ui-grid-px py-4 max-w-screen-xl mx-auto flex items-start\">\n <div className={cn(contentWrapperClasses, textColor)}>\n <strong className=\"font-bold whitespace-nowrap pr-1\">{title}</strong>\n <span\n ref={contentRef}\n className=\"pr-1\"\n dangerouslySetInnerHTML={{\n __html: safeContent,\n }}\n ></span>\n {buttonLabel &&\n (isSafeButtonLink ? (\n <a\n href={buttonLink}\n className=\"focus-base transition-colors cursor-pointer whitespace-nowrap text-gui-blue-default-light dark:text-gui-blue-default-dark\"\n >\n {buttonLabel}\n </a>\n ) : (\n <span className=\"focus-base transition-colors cursor-pointer whitespace-nowrap text-gui-blue-default-light dark:text-gui-blue-default-dark\">\n {buttonLabel}\n </span>\n ))}\n </div>\n\n {closeBtn && (\n <button\n type=\"button\"\n className=\"ml-auto h-5 w-5 border-none bg-none self-baseline outline-none focus:outline-none focus:ring-0 focus:border-transparent\"\n onClick={() => {\n setIsClosing(true);\n setTimeout(() => {\n document.dispatchEvent(new CustomEvent(\"notice-closed\"));\n onClose?.();\n }, 300);\n }}\n >\n <Icon\n name=\"icon-gui-x-mark-outline\"\n size=\"1.25rem\"\n color={textColor}\n />\n </button>\n )}\n </div>\n </div>\n );\n};\n\nexport default Notice;\n"],"names":["React","useEffect","useRef","useState","DOMPurify","Icon","cn","NoticeScripts","useRailsUjsLinks","defaultTextColor","contentWrapperClasses","Notice","buttonLink","buttonLabel","bodyText","title","config","closeBtn","bgColor","textColor","onClose","contentRef","isClosing","setIsClosing","cleanup","bannerContainer","document","querySelector","cookieId","noticeId","options","collapse","safeContent","sanitize","ALLOWED_TAGS","ALLOWED_ATTR","ALLOWED_URI_REGEXP","isSafeButtonLink","test","div","className","data-id","strong","span","ref","dangerouslySetInnerHTML","__html","a","href","button","type","onClick","setTimeout","dispatchEvent","CustomEvent","name","size","color"],"mappings":"AAAA,OAAOA,OAASC,SAAS,CAAEC,MAAM,CAAEC,QAAQ,KAAQ,OAAQ,AAC3D,QAAOC,cAAe,WAAY,AAGlC,QAAOC,SAAU,QAAS,AAC1B,QAAOC,OAAQ,eAAgB,AAC/B,QAAOC,kBAAmB,uBAAwB,AAClD,QAAOC,qBAAsB,6BAA8B,CA6B3D,MAAMC,iBAAmB,0CAEzB,MAAMC,sBAAwB,qCAE9B,MAAMC,OAAS,CAAC,CACdC,UAAU,CACVC,WAAW,CACXC,QAAQ,CACRC,KAAK,CACLC,MAAM,CACNC,QAAQ,CACRC,QAAU,mCAAmC,CAC7CC,UAAYV,gBAAgB,CAC5BW,OAAO,CACK,IACZ,MAAMC,WAAanB,OAAwB,MAC3C,KAAM,CAACoB,UAAWC,aAAa,CAAGpB,SAAS,OAC3CK,iBAAiBa,YAEjBpB,UAAU,KACR,MAAMuB,QAAUjB,cAAc,CAC5BkB,gBAAiBC,SAASC,aAAa,CAAC,yBACxCC,SAAUZ,QAAQY,SAClBC,SAAUb,QAAQa,SAClBC,QAAS,CACPC,SAAUf,QAAQc,SAASC,UAAY,KACzC,CACF,GAEA,OAAOP,OACT,EAAG,CAACR,QAAQY,SAAUZ,QAAQa,SAAUb,QAAQc,SAASC,SAAS,EAElE,MAAMC,YAAc5B,UAAU6B,QAAQ,CAACnB,UAAY,GAAI,CACrDoB,aAAc,CAAC,IAAI,CACnBC,aAAc,CAAC,OAAQ,cAAc,CACrCC,mBAAoB,SACtB,GAEA,MAAMC,iBACJ,OAAOzB,aAAe,UACrB,CAAA,YAAY0B,IAAI,CAAC1B,aAAe,eAAe0B,IAAI,CAAC1B,WAAU,EAGjE,OACE,oBAAC2B,OACCC,UAAWlC,GACT,kCACAgB,UACI,6EACA,0BACJJ,QACAC,WAEFsB,UAAQ,aAER,oBAACF,OAAIC,UAAU,4DACb,oBAACD,OAAIC,UAAWlC,GAAGI,sBAAuBS,YACxC,oBAACuB,UAAOF,UAAU,oCAAoCzB,OACtD,oBAAC4B,QACCC,IAAKvB,WACLmB,UAAU,OACVK,wBAAyB,CACvBC,OAAQd,WACV,IAEDnB,aACEwB,CAAAA,iBACC,oBAACU,KACCC,KAAMpC,WACN4B,UAAU,6HAET3B,aAGH,oBAAC8B,QAAKH,UAAU,6HACb3B,YAEL,GAGHI,UACC,oBAACgC,UACCC,KAAK,SACLV,UAAU,0HACVW,QAAS,KACP5B,aAAa,MACb6B,WAAW,KACT1B,SAAS2B,aAAa,CAAC,IAAIC,YAAY,kBACvClC,WACF,EAAG,IACL,GAEA,oBAACf,MACCkD,KAAK,0BACLC,KAAK,UACLC,MAAOtC,cAOrB,CAEA,gBAAeR,MAAO"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{Fragment,useEffect,useRef,useState}from"react";import
|
|
1
|
+
import React,{Fragment,useEffect,useRef,useState}from"react";import{throttle}from"es-toolkit/compat";import Icon from"../Icon";import LinkButton from"../LinkButton";import Tooltip from"../Tooltip";import cn from"../utils/cn";const PricingCards=({data,delimiter})=>{const descriptionsRef=useRef([]);const[descriptionHeight,setDescriptionHeight]=useState(0);useEffect(()=>{const determineMaxDescriptionHeight=throttle(()=>{if(descriptionsRef.current.length){setDescriptionHeight(Math.max(...descriptionsRef.current.map(description=>description?.getBoundingClientRect().height??0)))}},100);determineMaxDescriptionHeight();window.addEventListener("resize",determineMaxDescriptionHeight);return()=>{window.removeEventListener("resize",determineMaxDescriptionHeight);determineMaxDescriptionHeight.cancel()}},[]);const delimiterColumn=index=>delimiter&&index%2===1?React.createElement("div",{className:cn("flex items-center justify-center w-full @[920px]:w-5",{"m-2":delimiter!=="blank"})},delimiter!=="blank"?React.createElement(Icon,{name:delimiter,size:"20px",additionalCSS:"text-neutral-800 dark:text-neutral-500"}):null):null;const gridRules={nonDelimited:"grid @[552px]:grid-cols-2 @[1104px]:grid-cols-4",delimited:"flex flex-col items-center @[920px]:flex-row"};const borderClasses=color=>{const classes={neutral:{border:"border-neutral-600 dark:border-neutral-700",bg:"bg-neutral-600 dark:bg-neutral-700"},blue:{border:"border-blue-400 dark:border-blue-600",bg:"bg-blue-400 dark:bg-blue-600"},orange:{border:"border-orange-600 dark:border-orange-600",bg:"bg-orange-600 dark:bg-orange-600"}};if(color&&classes[color]){return classes[color]}};return React.createElement("div",{className:"@container flex justify-center","data-testid":delimiter?"delimited-pricing-card-group":"pricing-card-group"},React.createElement("div",{className:cn("gap-2",delimiter?gridRules.delimited:gridRules.nonDelimited)},data.map(({title,description,price,cta,sections,border,bottomCta},index)=>React.createElement(Fragment,{key:title.content},delimiterColumn(index),React.createElement("div",{className:cn("relative border flex-1 px-6 pt-6 pb-4 flex flex-col gap-6 rounded-2xl group min-w-[17rem] backdrop-blur bg-neutral-100 dark:bg-neutral-1200",borderClasses(border?.color)?.border??"border-neutral-200 dark:border-neutral-1100",border?.style,{"@[520px]:flex-row @[920px]:flex-col":delimiter}),"data-testid":delimiter?"delimited-pricing-card":"pricing-card"},border?React.createElement("div",{className:cn("flex items-center absolute z-10 -top-3 self-center font-semibold uppercase text-neutral-000 font-sans h-6 text-[11px] px-2.5 py-0.5 rounded-2xl select-none tracking-widest",borderClasses(border?.color)?.border,borderClasses(border?.color)?.bg)},border.text):null,React.createElement("div",{className:cn(`relative z-10 flex flex-col gap-4`,{"@[520px]:flex-1 @[920px]:flex-none":delimiter})},React.createElement("div",null,React.createElement("div",{className:"flex items-center mb-1"},React.createElement("p",{className:cn(title.className,title.color)},title.content),title.tooltip?React.createElement(Tooltip,{interactive:typeof title.tooltip!=="string",iconSize:"1.25rem"},title.tooltip):null),React.createElement("p",{className:cn("ui-text-h1 text-h1-xl h-5 block",description.className,description.color),style:{height:descriptionHeight}},React.createElement("span",{ref:el=>descriptionsRef.current[index]=el},description.content))),React.createElement("div",{className:cn("flex items-end gap-2",{"@[520px]:flex-col @[520px]:items-start @[920px]:flex-row @[920px]:items-end":delimiter})},React.createElement("p",{className:"ui-text-h1 text-h1-xl font-medium tracking-tight leading-none text-neutral-1300 dark:text-neutral-000"},price.amount),React.createElement("div",{className:"ui-text-p3 text-neutral-1300 dark:text-neutral-000"},price.content)),cta?React.createElement("div",{className:"group"},React.createElement(LinkButton,{className:cn("w-full",cta.className),variant:cta.isPriority?"priority":"primary",href:cta.url,onClick:cta.onClick,disabled:cta.disabled,rightIcon:"icon-gui-arrow-right-outline",iconColor:cta.iconColor},cta.text)):delimiter?null:React.createElement("div",{className:"flex items-center justify-center h-12 w-full"},React.createElement("hr",{className:"border-neutral-500 dark:border-neutral-800 w-16"}))),React.createElement("div",{className:"flex flex-col gap-4 relative z-10 flex-grow"},sections.map(({title,items,listItemColors})=>React.createElement("div",{key:title,className:"flex flex-col gap-3"},React.createElement("p",{className:"text-neutral-700 dark:text-neutral-600 font-mono uppercase text-overline2 font-medium tracking-[0.12em] h-4"},title),React.createElement("div",{className:cn({"flex flex-col":!delimiter})},items.map((item,index)=>Array.isArray(item)?React.createElement("div",{key:item[0],className:cn("flex justify-between gap-4 px-2 -mx-2",index===0?"py-2":"py-1",index>0&&index%2===0?"bg-blue-100 dark:bg-blue-900 rounded-md":"")},item.map((subItem,subIndex)=>React.createElement("span",{key:subItem,className:cn("ui-text-p3",index===0?"font-bold":"font-medium","text-neutral-1000 dark:text-neutral-300 leading-[1.4rem]",subIndex%2===1?"text-right":"")},subItem))):React.createElement("div",{key:item,className:"flex items-start gap-2"},listItemColors?React.createElement(Icon,{name:"icon-gui-check-circled-fill",color:listItemColors.background,secondaryColor:listItemColors.foreground,size:"16px",additionalCSS:"mt-1"}):null,React.createElement("div",{className:cn(`flex-1 font-medium text-neutral-1000 dark:text-neutral-300 ui-text-p3`)},item))))))),bottomCta&&React.createElement("div",null,React.createElement("div",{className:"border-t border-neutral-200 dark:border-neutral-1100 -mx-6"}),React.createElement("a",{href:bottomCta.url,className:cn("text-[13px] font-sans font-semibold group/bottom-cta cursor-pointer pt-4 flex items-center","text-neutral-700 dark:text-neutral-600 hover:text-neutral-1300 dark:hover:text-neutral-000 focus:outline-none focus-visible:outline-gui-focus")},bottomCta.text,React.createElement(Icon,{name:"icon-gui-arrow-down-outline",size:"12px",color:bottomCta.iconColor,additionalCSS:cn("align-middle ml-2 relative transition-[bottom] bottom-0 group-hover/bottom-cta:-bottom-0.5")})))),delimiterColumn(index)))))};export default PricingCards;
|
|
2
2
|
//# sourceMappingURL=PricingCards.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Pricing/PricingCards.tsx"],"sourcesContent":["import React, { Fragment, useEffect, useRef, useState } from \"react\";\nimport throttle from \"lodash.throttle\";\nimport type { PricingDataFeature } from \"./types\";\nimport Icon from \"../Icon\";\nimport FeaturedLink from \"../FeaturedLink\";\nimport LinkButton from \"../LinkButton\";\nimport { IconName } from \"../Icon/types\";\nimport Tooltip from \"../Tooltip\";\nimport cn from \"../utils/cn\";\n\nexport type PricingCardsProps = {\n data: PricingDataFeature[];\n delimiter?: IconName | \"blank\";\n};\n\nconst PricingCards = ({ data, delimiter }: PricingCardsProps) => {\n const descriptionsRef = useRef<(HTMLSpanElement | null)[]>([]);\n const [descriptionHeight, setDescriptionHeight] = useState<number>(0);\n\n const determineMaxDescriptionHeight = throttle(() => {\n if (descriptionsRef.current.length) {\n setDescriptionHeight(\n Math.max(\n ...descriptionsRef.current.map(\n (description) => description?.getBoundingClientRect().height ?? 0,\n ),\n ),\n );\n }\n }, 100);\n\n useEffect(() => {\n determineMaxDescriptionHeight();\n\n window.addEventListener(\"resize\", determineMaxDescriptionHeight);\n\n return () => {\n window.removeEventListener(\"resize\", determineMaxDescriptionHeight);\n determineMaxDescriptionHeight.cancel();\n };\n }, []);\n\n const delimiterColumn = (index: number) =>\n delimiter && index % 2 === 1 ? (\n <div\n className={cn(\"flex items-center justify-center w-full @[920px]:w-5\", {\n \"m-2\": delimiter !== \"blank\",\n })}\n >\n {delimiter !== \"blank\" ? (\n <Icon\n name={delimiter}\n size=\"20px\"\n additionalCSS={\"text-neutral-800 dark:text-neutral-500\"}\n />\n ) : null}\n </div>\n ) : null;\n\n const gridRules = {\n nonDelimited: \"grid @[552px]:grid-cols-2 @[1104px]:grid-cols-4\",\n delimited: \"flex flex-col items-center @[920px]:flex-row\",\n };\n\n const borderClasses = (color?: \"neutral\" | \"blue\" | \"orange\") => {\n const classes: Record<\n string,\n {\n border: string;\n bg: string;\n }\n > = {\n neutral: {\n border: \"border-neutral-600 dark:border-neutral-700\",\n bg: \"bg-neutral-600 dark:bg-neutral-700\",\n },\n blue: {\n border: \"border-blue-400 dark:border-blue-600\",\n bg: \"bg-blue-400 dark:bg-blue-600\",\n },\n orange: {\n border: \"border-orange-600 dark:border-orange-600\",\n bg: \"bg-orange-600 dark:bg-orange-600\",\n },\n };\n\n if (color && classes[color]) {\n return classes[color];\n }\n };\n\n return (\n <div\n className=\"@container flex justify-center\"\n data-testid={\n delimiter ? \"delimited-pricing-card-group\" : \"pricing-card-group\"\n }\n >\n <div\n className={cn(\n \"gap-2\",\n delimiter ? gridRules.delimited : gridRules.nonDelimited,\n )}\n >\n {data.map(\n ({ title, description, price, cta, sections, border }, index) => (\n <Fragment key={title.content}>\n {delimiterColumn(index)}\n <div\n className={cn(\n \"relative border flex-1 px-6 py-8 flex flex-col gap-6 rounded-2xl group min-w-[17rem] backdrop-blur\",\n borderClasses(border?.color)?.border ??\n \"border-neutral-200 dark:border-neutral-1100\",\n border?.style,\n { \"@[520px]:flex-row @[920px]:flex-col\": delimiter },\n )}\n data-testid={\n delimiter ? \"delimited-pricing-card\" : \"pricing-card\"\n }\n >\n {border ? (\n <div\n className={cn(\n \"flex items-center absolute z-10 -top-3 self-center font-semibold uppercase text-neutral-000 font-sans h-6 text-[11px] px-2.5 py-0.5 rounded-2xl select-none tracking-widest\",\n borderClasses(border?.color)?.border,\n borderClasses(border?.color)?.bg,\n )}\n >\n {border.text}\n </div>\n ) : null}\n <div\n className={cn(\n \"absolute z-0 top-0 left-0 w-full h-full rounded-2xl bg-neutral-000 dark:bg-neutral-1300 transition-[colors,opacity] opacity-25\",\n {\n \"group-hover:bg-neutral-100 dark:group-hover:bg-neutral-1200 group-hover:opacity-100\":\n !delimiter,\n },\n )}\n ></div>\n <div\n className={cn(`relative z-10 flex flex-col gap-6`, {\n \"@[520px]:flex-1 @[920px]:flex-none\": delimiter,\n })}\n >\n <div>\n <div className=\"flex items-center mb-3\">\n <p className={cn(title.className, title.color)}>\n {title.content}\n </p>\n {title.tooltip ? (\n <Tooltip\n interactive={typeof title.tooltip !== \"string\"}\n >\n {title.tooltip}\n </Tooltip>\n ) : null}\n </div>\n <p\n className={cn(\n \"ui-text-p1 min-h-5\",\n description.className,\n description.color,\n )}\n style={{ height: descriptionHeight }}\n >\n <span ref={(el) => (descriptionsRef.current[index] = el)}>\n {description.content}\n </span>\n </p>\n </div>\n <div\n className={cn(\"flex items-end gap-2\", {\n \"@[520px]:flex-col @[520px]:items-start @[920px]:flex-row @[920px]:items-end\":\n delimiter,\n })}\n >\n <p className=\"ui-text-title font-medium tracking-tight leading-none text-neutral-1300 dark:text-neutral-000\">\n {price.amount}\n </p>\n <div className=\"ui-text-p3 text-neutral-1300 dark:text-neutral-000\">\n {price.content}\n </div>\n </div>\n {cta ? (\n <div className=\"group\">\n <LinkButton\n className={cn(\"w-full\", cta.className)}\n variant={\n cta.url === \"/contact\" ? \"priority\" : \"primary\"\n }\n href={cta.url}\n onClick={cta.onClick}\n disabled={cta.disabled}\n rightIcon=\"icon-gui-arrow-long-right-outline\"\n iconColor={cta.iconColor}\n >\n {cta.text}\n </LinkButton>\n </div>\n ) : delimiter ? null : (\n <div className=\"flex items-center justify-center h-12 w-full\">\n <hr className=\"border-neutral-500 dark:border-neutral-800 w-16\" />\n </div>\n )}\n </div>\n <div className=\"flex-1 flex flex-col gap-6 relative z-10\">\n {sections.map(({ title, items, listItemColors, cta }) => (\n <div key={title} className=\"flex flex-col gap-3\">\n <p className=\"text-neutral-800 dark:text-neutral-500 font-mono uppercase text-overline2 tracking-[0.16em]\">\n {title}\n </p>\n <div\n className={cn({ \"flex flex-col gap-1\": !delimiter })}\n >\n {items.map((item, index) =>\n Array.isArray(item) ? (\n <div\n key={item[0]}\n className={cn(\n \"flex justify-between gap-4 px-2 -mx-2\",\n index === 0 ? \"py-2\" : \"py-1\",\n index > 0 && index % 2 === 0\n ? \"bg-blue-100 dark:bg-blue-900 rounded-md\"\n : \"\",\n )}\n >\n {item.map((subItem, subIndex) => (\n <span\n key={subItem}\n className={cn(\n \"ui-text-p3\",\n index === 0 ? \"font-bold\" : \"font-medium\",\n \"text-neutral-1000 dark:text-neutral-300\",\n subIndex % 2 === 1 ? \"text-right\" : \"\",\n )}\n >\n {subItem}\n </span>\n ))}\n </div>\n ) : (\n <div key={item} className=\"flex gap-2 items-start\">\n {listItemColors ? (\n <Icon\n name=\"icon-gui-check-circled-fill\"\n color={listItemColors.background}\n secondaryColor={listItemColors.foreground}\n size=\"16px\"\n additionalCSS=\"mt-0.5\"\n />\n ) : null}\n <div\n className={cn(\n `flex-1 font-medium text-neutral-1000 dark:text-neutral-300`,\n listItemColors ? \"ui-text-p3\" : \"ui-text-p2\",\n )}\n >\n {item}\n </div>\n </div>\n ),\n )}\n </div>\n {cta ? (\n <div className=\"relative -mx-6 flex items-center h-10 overflow-x-hidden\">\n <FeaturedLink\n url={cta.url}\n additionalCSS=\"absolute translate-x-6 sm:-translate-x-[7.5rem] sm:opacity-0 sm:group-hover:translate-x-6 duration-300 delay-0 sm:group-hover:delay-100 sm:group-hover:opacity-100 transition-[transform,opacity] font-medium ui-text-p3 dark:text-neutral-500 dark:hover:text-neutral-000 cursor-pointer\"\n onClick={cta.onClick}\n iconColor={listItemColors?.foreground}\n >\n {cta.text}\n </FeaturedLink>\n <div className=\"absolute hidden sm:block sm:translate-x-6 sm:opacity-100 sm:group-hover:translate-x-[7.5rem] sm:group-hover:opacity-0 duration-200 delay-100 sm:group-hover:delay-0 transition-[transform,opacity] leading-6 tracking-[0.15em] font-light text-p3 text-neutral-500 dark:text-neutral-800\">\n •••\n </div>\n </div>\n ) : null}\n </div>\n ))}\n </div>\n </div>\n {delimiterColumn(index)}\n </Fragment>\n ),\n )}\n </div>\n </div>\n );\n};\n\nexport default PricingCards;\n"],"names":["React","Fragment","useEffect","useRef","useState","throttle","Icon","FeaturedLink","LinkButton","Tooltip","cn","PricingCards","data","delimiter","descriptionsRef","descriptionHeight","setDescriptionHeight","determineMaxDescriptionHeight","current","length","Math","max","map","description","getBoundingClientRect","height","window","addEventListener","removeEventListener","cancel","delimiterColumn","index","div","className","name","size","additionalCSS","gridRules","nonDelimited","delimited","borderClasses","color","classes","neutral","border","bg","blue","orange","data-testid","title","price","cta","sections","key","content","style","text","p","tooltip","interactive","span","ref","el","amount","variant","url","href","onClick","disabled","rightIcon","iconColor","hr","items","listItemColors","item","Array","isArray","subItem","subIndex","background","secondaryColor","foreground"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Pricing/PricingCards.tsx"],"sourcesContent":["import React, { Fragment, useEffect, useRef, useState } from \"react\";\nimport { throttle } from \"es-toolkit/compat\";\nimport type { PricingDataFeature } from \"./types\";\nimport Icon from \"../Icon\";\nimport LinkButton from \"../LinkButton\";\nimport { IconName } from \"../Icon/types\";\nimport Tooltip from \"../Tooltip\";\nimport cn from \"../utils/cn\";\n\nexport type PricingCardsProps = {\n data: PricingDataFeature[];\n delimiter?: IconName | \"blank\";\n};\n\nconst PricingCards = ({ data, delimiter }: PricingCardsProps) => {\n const descriptionsRef = useRef<(HTMLSpanElement | null)[]>([]);\n const [descriptionHeight, setDescriptionHeight] = useState<number>(0);\n\n useEffect(() => {\n const determineMaxDescriptionHeight = throttle(() => {\n if (descriptionsRef.current.length) {\n setDescriptionHeight(\n Math.max(\n ...descriptionsRef.current.map(\n (description) => description?.getBoundingClientRect().height ?? 0,\n ),\n ),\n );\n }\n }, 100);\n\n determineMaxDescriptionHeight();\n\n window.addEventListener(\"resize\", determineMaxDescriptionHeight);\n\n return () => {\n window.removeEventListener(\"resize\", determineMaxDescriptionHeight);\n determineMaxDescriptionHeight.cancel();\n };\n }, []);\n\n const delimiterColumn = (index: number) =>\n delimiter && index % 2 === 1 ? (\n <div\n className={cn(\"flex items-center justify-center w-full @[920px]:w-5\", {\n \"m-2\": delimiter !== \"blank\",\n })}\n >\n {delimiter !== \"blank\" ? (\n <Icon\n name={delimiter}\n size=\"20px\"\n additionalCSS={\"text-neutral-800 dark:text-neutral-500\"}\n />\n ) : null}\n </div>\n ) : null;\n\n const gridRules = {\n nonDelimited: \"grid @[552px]:grid-cols-2 @[1104px]:grid-cols-4\",\n delimited: \"flex flex-col items-center @[920px]:flex-row\",\n };\n\n const borderClasses = (color?: \"neutral\" | \"blue\" | \"orange\") => {\n const classes: Record<\n string,\n {\n border: string;\n bg: string;\n }\n > = {\n neutral: {\n border: \"border-neutral-600 dark:border-neutral-700\",\n bg: \"bg-neutral-600 dark:bg-neutral-700\",\n },\n blue: {\n border: \"border-blue-400 dark:border-blue-600\",\n bg: \"bg-blue-400 dark:bg-blue-600\",\n },\n orange: {\n border: \"border-orange-600 dark:border-orange-600\",\n bg: \"bg-orange-600 dark:bg-orange-600\",\n },\n };\n\n if (color && classes[color]) {\n return classes[color];\n }\n };\n\n return (\n <div\n className=\"@container flex justify-center\"\n data-testid={\n delimiter ? \"delimited-pricing-card-group\" : \"pricing-card-group\"\n }\n >\n <div\n className={cn(\n \"gap-2\",\n delimiter ? gridRules.delimited : gridRules.nonDelimited,\n )}\n >\n {data.map(\n (\n { title, description, price, cta, sections, border, bottomCta },\n index,\n ) => (\n <Fragment key={title.content}>\n {delimiterColumn(index)}\n <div\n className={cn(\n \"relative border flex-1 px-6 pt-6 pb-4 flex flex-col gap-6 rounded-2xl group min-w-[17rem] backdrop-blur bg-neutral-100 dark:bg-neutral-1200\",\n borderClasses(border?.color)?.border ??\n \"border-neutral-200 dark:border-neutral-1100\",\n border?.style,\n { \"@[520px]:flex-row @[920px]:flex-col\": delimiter },\n )}\n data-testid={\n delimiter ? \"delimited-pricing-card\" : \"pricing-card\"\n }\n >\n {border ? (\n <div\n className={cn(\n \"flex items-center absolute z-10 -top-3 self-center font-semibold uppercase text-neutral-000 font-sans h-6 text-[11px] px-2.5 py-0.5 rounded-2xl select-none tracking-widest\",\n borderClasses(border?.color)?.border,\n borderClasses(border?.color)?.bg,\n )}\n >\n {border.text}\n </div>\n ) : null}\n <div\n className={cn(`relative z-10 flex flex-col gap-4`, {\n \"@[520px]:flex-1 @[920px]:flex-none\": delimiter,\n })}\n >\n <div>\n <div className=\"flex items-center mb-1\">\n <p className={cn(title.className, title.color)}>\n {title.content}\n </p>\n {title.tooltip ? (\n <Tooltip\n interactive={typeof title.tooltip !== \"string\"}\n iconSize=\"1.25rem\"\n >\n {title.tooltip}\n </Tooltip>\n ) : null}\n </div>\n <p\n className={cn(\n \"ui-text-h1 text-h1-xl h-5 block\",\n description.className,\n description.color,\n )}\n style={{ height: descriptionHeight }}\n >\n <span ref={(el) => (descriptionsRef.current[index] = el)}>\n {description.content}\n </span>\n </p>\n </div>\n <div\n className={cn(\"flex items-end gap-2\", {\n \"@[520px]:flex-col @[520px]:items-start @[920px]:flex-row @[920px]:items-end\":\n delimiter,\n })}\n >\n <p className=\"ui-text-h1 text-h1-xl font-medium tracking-tight leading-none text-neutral-1300 dark:text-neutral-000\">\n {price.amount}\n </p>\n <div className=\"ui-text-p3 text-neutral-1300 dark:text-neutral-000\">\n {price.content}\n </div>\n </div>\n {cta ? (\n <div className=\"group\">\n <LinkButton\n className={cn(\"w-full\", cta.className)}\n variant={cta.isPriority ? \"priority\" : \"primary\"}\n href={cta.url}\n onClick={cta.onClick}\n disabled={cta.disabled}\n rightIcon=\"icon-gui-arrow-right-outline\"\n iconColor={cta.iconColor}\n >\n {cta.text}\n </LinkButton>\n </div>\n ) : delimiter ? null : (\n <div className=\"flex items-center justify-center h-12 w-full\">\n <hr className=\"border-neutral-500 dark:border-neutral-800 w-16\" />\n </div>\n )}\n </div>\n <div className=\"flex flex-col gap-4 relative z-10 flex-grow\">\n {sections.map(({ title, items, listItemColors }) => (\n <div key={title} className=\"flex flex-col gap-3\">\n <p className=\"text-neutral-700 dark:text-neutral-600 font-mono uppercase text-overline2 font-medium tracking-[0.12em] h-4\">\n {title}\n </p>\n <div className={cn({ \"flex flex-col\": !delimiter })}>\n {items.map((item, index) =>\n Array.isArray(item) ? (\n <div\n key={item[0]}\n className={cn(\n \"flex justify-between gap-4 px-2 -mx-2\",\n index === 0 ? \"py-2\" : \"py-1\",\n index > 0 && index % 2 === 0\n ? \"bg-blue-100 dark:bg-blue-900 rounded-md\"\n : \"\",\n )}\n >\n {item.map((subItem, subIndex) => (\n <span\n key={subItem}\n className={cn(\n \"ui-text-p3\",\n index === 0 ? \"font-bold\" : \"font-medium\",\n \"text-neutral-1000 dark:text-neutral-300 leading-[1.4rem]\",\n subIndex % 2 === 1 ? \"text-right\" : \"\",\n )}\n >\n {subItem}\n </span>\n ))}\n </div>\n ) : (\n <div key={item} className=\"flex items-start gap-2\">\n {listItemColors ? (\n <Icon\n name=\"icon-gui-check-circled-fill\"\n color={listItemColors.background}\n secondaryColor={listItemColors.foreground}\n size=\"16px\"\n additionalCSS=\"mt-1\"\n />\n ) : null}\n <div\n className={cn(\n `flex-1 font-medium text-neutral-1000 dark:text-neutral-300 ui-text-p3`,\n )}\n >\n {item}\n </div>\n </div>\n ),\n )}\n </div>\n </div>\n ))}\n </div>\n\n {bottomCta && (\n <div>\n <div className=\"border-t border-neutral-200 dark:border-neutral-1100 -mx-6\"></div>\n <a\n href={bottomCta.url}\n className={cn(\n \"text-[13px] font-sans font-semibold group/bottom-cta cursor-pointer pt-4 flex items-center\",\n \"text-neutral-700 dark:text-neutral-600 hover:text-neutral-1300 dark:hover:text-neutral-000 focus:outline-none focus-visible:outline-gui-focus\",\n )}\n >\n {bottomCta.text}\n <Icon\n name=\"icon-gui-arrow-down-outline\"\n size=\"12px\"\n color={bottomCta.iconColor}\n additionalCSS={cn(\n \"align-middle ml-2 relative transition-[bottom] bottom-0 group-hover/bottom-cta:-bottom-0.5\",\n )}\n />\n </a>\n </div>\n )}\n </div>\n {delimiterColumn(index)}\n </Fragment>\n ),\n )}\n </div>\n </div>\n );\n};\n\nexport default PricingCards;\n"],"names":["React","Fragment","useEffect","useRef","useState","throttle","Icon","LinkButton","Tooltip","cn","PricingCards","data","delimiter","descriptionsRef","descriptionHeight","setDescriptionHeight","determineMaxDescriptionHeight","current","length","Math","max","map","description","getBoundingClientRect","height","window","addEventListener","removeEventListener","cancel","delimiterColumn","index","div","className","name","size","additionalCSS","gridRules","nonDelimited","delimited","borderClasses","color","classes","neutral","border","bg","blue","orange","data-testid","title","price","cta","sections","bottomCta","key","content","style","text","p","tooltip","interactive","iconSize","span","ref","el","amount","variant","isPriority","href","url","onClick","disabled","rightIcon","iconColor","hr","items","listItemColors","item","Array","isArray","subItem","subIndex","background","secondaryColor","foreground","a"],"mappings":"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"}
|
package/core/Pricing/data.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";export const planData=[{title:{content:"Free",className:"
|
|
1
|
+
import React from"react";import Tooltip from"../Tooltip";export const planData=[{title:{content:"Free",className:"ui-text-h4 tracking-[-0.002rem]",color:"text-neutral-1300 dark:text-neutral-000"},description:{content:"Build a proof of concept.",className:"ui-text-p3",color:"text-neutral-700 dark:text-neutral-600"},price:{amount:"$0"},cta:{text:"Start for free",url:"/sign-up",iconColor:"text-neutral-600 dark:text-neutral-700"},sections:[{title:"Capacity",items:["200 concurrent connections","500 messages / second","6M messages / month"]},{title:"Includes",items:["Build with any Ably product","Community & email support (best effort)","No commitment"],listItemColors:{foreground:"text-neutral-700 dark:text-neutral-600",background:"text-neutral-100 dark:text-neutral-1200"}}],bottomCta:{text:"See all features",url:"#pricing-table"}},{title:{content:"Standard",className:"ui-text-h4 tracking-[-0.002rem]",color:"text-neutral-1300 dark:text-neutral-000"},description:{content:"Roll-out into production.",className:"ui-text-p3",color:"text-neutral-700 dark:text-neutral-600"},price:{amount:"$29",content:React.createElement(React.Fragment,null,React.createElement("p",{className:"ui-text-p3 font-medium",style:{color:"currentColor"}},"/ month"),React.createElement("div",{className:"flex -mt-1"},React.createElement("p",{className:"ui-text-p3 font-bold text-gui-blue-default-dark leading-[1.4rem]"},"+ usage"),React.createElement(Tooltip,{interactive:true,iconSize:"1.25rem"},"Usage is billed on top of your plan. You'll be charged monthly based on how many messages, channel minutes, and connection minutes you use. See rates above.")))},cta:{text:"Get started",url:"/users/paid_sign_up?package=standard",iconColor:"text-neutral-600 dark:text-neutral-700"},sections:[{title:"Capacity",items:["10k concurrent channels","10k concurrent connections","2.5k messages / second"]},{title:"Includes",items:["Build with any Ably product","1 day email support SLA","Uptime SLO"],listItemColors:{foreground:"text-neutral-700 dark:text-neutral-600",background:"text-neutral-100 dark:text-neutral-1200"}}],bottomCta:{text:"See all features",url:"#pricing-table"}},{title:{content:"Pro",className:"ui-text-h4 tracking-[-0.002rem]",color:"text-neutral-1300 dark:text-neutral-000"},description:{content:"Scale business critical workloads.",className:"ui-text-p3",color:"text-neutral-700 dark:text-neutral-600"},price:{amount:"$399",content:React.createElement(React.Fragment,null,React.createElement("p",{className:"ui-text-p3 font-medium",style:{color:"currentColor"}},"/ month"),React.createElement("div",{className:"flex -mt-1"},React.createElement("p",{className:"ui-text-p3 font-bold text-gui-blue-default-dark leading-[1.4rem]"},"+ usage"),React.createElement(Tooltip,{interactive:true,iconSize:"1.25rem"},"Usage is billed on top of your plan. You'll be charged monthly based on how many messages, channel minutes, and connection minutes you use. See rates above.")))},cta:{text:"Get started",url:"/users/paid_sign_up?package=pro",iconColor:"text-neutral-600 dark:text-neutral-700"},sections:[{title:"Capacity",items:["50k concurrent channels","50k concurrent connections","10k messages / second"]},{title:"Includes",items:["Build with any Ably product","4 hour email support SLA","Datadog (lite)","Uptime SLO"],listItemColors:{foreground:"text-neutral-700 dark:text-neutral-600",background:"text-neutral-100 dark:text-neutral-1200"}}],bottomCta:{text:"See all features",url:"#pricing-table"}},{title:{content:"Enterprise",className:"ui-text-h4 tracking-[-0.002rem]",color:"text-orange-600"},description:{content:"Serious workloads without limits.",className:"ui-text-p3",color:"text-neutral-700 dark:text-neutral-600"},price:{amount:"Custom"},cta:{text:"Contact us",url:"/contact",isPriority:true},sections:[{title:"Capacity",items:["Unlimited concurrent channels","Unlimited connections","Unlimited messages / second"]},{title:"Includes",items:["Build with any Ably product","24/7 mission critical support","99.999% uptime SLAs","Committed use discounts","Datadog","CNAME, SSO, & more"],listItemColors:{foreground:"text-orange-700 dark:text-orange-500",background:"text-neutral-100 dark:text-neutral-1200"}}],bottomCta:{text:"See all features",url:"#pricing-table"}}];export const consumptionData=[{title:{content:"Messages",className:"ui-text-h3",color:"text-neutral-1300 dark:text-neutral-000"},description:{content:"Messages contain the data that a client is communicating, such as the contents of a chat message.",className:"ui-text-p3",color:"text-neutral-700 dark:text-neutral-600"},price:{amount:"$2.50",content:"/ million"},sections:[{title:"Volume discounts",items:[["Consumption","$ / million msgs"],["First 50 million msgs","$2.50"],["Next 450 million msgs","$2.25"],["Next 4.5 billion msgs","$1.95"],["Next 15 billion msgs","$1.65"],["Next 30 billion msgs","$1.40"],["Over 50 billion msgs","$1.25"]]}],subtext:"As low as $0.50/M with volume discount"},{title:{content:"Channels",className:"ui-text-h3",color:"text-neutral-1300 dark:text-neutral-000",tooltip:React.createElement("p",null,"We charge you for the amount of time a channel is active in our network by the minute. For example, if ten channels are in use for 45 minutes, you will be charged a total of 450 channel minutes.")},description:{content:"Channels are used to route messages from publishers to subscribers. Channels are billed by the minute when actively being used by a connected client.",className:"ui-text-p3",color:"text-neutral-700 dark:text-neutral-600"},price:{amount:"$1.00",content:"/ million mins"},sections:[{title:"Volume discounts",items:[["Consumption","$ / million mins"],["First 10 million mins","$1.00"],["Next 90 million mins","$0.95"],["Next 900 million mins","$0.85"],["Next 4 billion mins","$0.75"],["Next 10 billion mins","$0.65"],["Over 15 billion mins","$0.60"]]}],subtext:"As low as $0.20/M with volume discount"},{title:{content:"Connections",className:"ui-text-h3",color:"text-neutral-1300 dark:text-neutral-000",tooltip:React.createElement("p",null,"We charge you for the amount of time devices are connected to our network by the minute. For example, if ten devices are each connected for 45 minutes, you will be charged a total of 450 connection minutes.")},description:{content:"Clients establish and maintain a connection to the Ably service, typically over WebSockets.",className:"ui-text-p3",color:"text-neutral-700 dark:text-neutral-600"},price:{amount:"$1.00",content:"/ million mins"},sections:[{title:"Volume discounts",items:[["Consumption","$ / million mins"],["First 10 million mins","$1.00"],["Next 90 million mins","$0.95"],["Next 900 million mins","$0.85"],["Next 4 billion mins","$0.75"],["Next 10 billion mins","$0.65"],["Over 15 billion mins","$0.60"]]}],subtext:"As low as $0.20/M with volume discount"}];
|
|
2
2
|
//# sourceMappingURL=data.js.map
|
package/core/Pricing/data.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Pricing/data.tsx"],"sourcesContent":["import React from \"react\";\nimport { PricingDataFeature } from \"./types\";\n\nexport const planData: PricingDataFeature[] = [\n {\n title: {\n content: \"Free\",\n className: \"font-mono text-p3 uppercase font-bold tracking-[0.16em]\",\n color: \"text-neutral-600 dark:text-neutral-700\",\n },\n description: {\n content: \"Build a proof of concept.\",\n className: \"ui-text-p1\",\n color: \"text-neutral-800 dark:text-neutral-500\",\n },\n price: { amount: \"$0\" },\n cta: {\n text: \"Start for free\",\n url: \"/sign-up\",\n iconColor: \"text-neutral-600 dark:text-neutral-700\",\n },\n sections: [\n {\n title: \"Limits\",\n items: [\n \"200 concurrent channels\",\n \"200 concurrent connections\",\n \"500 messages / second\",\n \"6M messages / month\",\n ],\n },\n {\n title: \"Includes\",\n items: [\"Community & email support (best effort)\", \"No commitment\"],\n listItemColors: {\n foreground: \"text-neutral-700 dark:text-neutral-600\",\n background: \"text-neutral-300 dark:text-neutral-1000\",\n },\n cta: {\n text: \"See all features\",\n url: \"#pricing-table\",\n },\n },\n ],\n },\n {\n title: {\n content: \"Standard\",\n className: \"font-mono text-p3 uppercase font-bold tracking-[0.16em]\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n },\n description: {\n content: \"Roll-out into production.\",\n className: \"ui-text-p1\",\n color: \"text-neutral-800 dark:text-neutral-500\",\n },\n price: {\n amount: \"$29\",\n content: (\n <>\n <p\n className=\"ui-text-p3 font-medium\"\n style={{ color: \"currentColor\" }}\n >\n / month\n </p>\n <p className=\"ui-text-p2 font-bold text-gui-blue-default-dark -mt-1.5\">\n + consumption\n </p>\n </>\n ),\n },\n cta: {\n text: \"Get started\",\n url: \"/users/paid_sign_up?package=standard\",\n iconColor: \"text-gui-blue-default-dark dark:text-gui-blue-default-light\",\n },\n sections: [\n {\n title: \"Limits\",\n items: [\n \"10k concurrent channels\",\n \"10k concurrent connections\",\n \"2.5k messages / second\",\n ],\n },\n {\n title: \"Includes\",\n items: [\"1 day email support SLA\", \"Uptime SLO\"],\n listItemColors: {\n foreground: \"text-blue-600 dark:text-blue-400\",\n background: \"text-blue-200 dark:text-blue-800\",\n },\n cta: {\n text: \"See all features\",\n url: \"#pricing-table\",\n },\n },\n ],\n },\n {\n title: {\n content: \"Pro\",\n className: \"font-mono text-p3 uppercase font-bold tracking-[0.16em]\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n },\n description: {\n content: \"Scale with confidence.\",\n className: \"ui-text-p1\",\n color: \"text-neutral-800 dark:text-neutral-500\",\n },\n price: {\n amount: \"$399\",\n content: (\n <>\n <p\n className=\"ui-text-p3 font-medium\"\n style={{ color: \"currentColor\" }}\n >\n / month\n </p>\n <p className=\"ui-text-p2 font-bold text-gui-blue-default-dark -mt-1.5\">\n + consumption\n </p>\n </>\n ),\n },\n cta: {\n text: \"Get started\",\n url: \"/users/paid_sign_up?package=pro\",\n iconColor: \"text-gui-blue-default-dark dark:text-gui-blue-default-light\",\n },\n sections: [\n {\n title: \"Limits\",\n items: [\n \"50k concurrent channels\",\n \"50k concurrent connections\",\n \"10k messages / second\",\n ],\n },\n {\n title: \"Includes\",\n items: [\"2 hour support SLA\", \"Datadog (lite)\", \"Uptime SLO\"],\n listItemColors: {\n foreground: \"text-blue-600 dark:text-blue-400\",\n background: \"text-blue-200 dark:text-blue-800\",\n },\n cta: {\n text: \"See all features\",\n url: \"#pricing-table\",\n },\n },\n ],\n },\n\n {\n title: {\n content: \"Enterprise\",\n className: \"font-mono text-p3 uppercase font-bold tracking-[0.16em]\",\n color: \"text-orange-600\",\n },\n description: {\n content: \"Deliver without limits.\",\n className: \"ui-text-p1\",\n color: \"text-neutral-800 dark:text-neutral-500\",\n },\n price: { amount: \"Custom\" },\n cta: {\n text: \"Contact us\",\n url: \"/contact\",\n },\n sections: [\n {\n title: \"Unlimited\",\n items: [\n \"Concurrent channels\",\n \"Concurrent connections\",\n \"Messages / second\",\n ],\n },\n {\n title: \"Includes\",\n items: [\n \"24/7 mission critical support\",\n \"99.999% uptime SLAs\",\n \"Committed use discounts\",\n \"Datadog\",\n \"CNAME, SSO, & more\",\n ],\n listItemColors: {\n foreground: \"text-orange-600 dark:text-orange-600\",\n background: \"text-orange-200 dark:text-orange-1000\",\n },\n cta: {\n text: \"See all features\",\n url: \"#pricing-table\",\n },\n },\n ],\n },\n];\n\nexport const consumptionData: PricingDataFeature[] = [\n {\n title: {\n content: \"Messages\",\n className: \"ui-text-h3\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n },\n description: {\n content:\n \"Messages contain the data that a client is communicating, such as the contents of a chat message.\",\n className: \"ui-text-p3\",\n color: \"text-neutral-700 dark:text-neutral-600\",\n },\n price: { amount: \"$2.50\", content: \"/ million\" },\n sections: [\n {\n title: \"Volume discounts\",\n items: [\n [\"Consumption\", \"$ / million msgs\"],\n [\"First 50 million msgs\", \"$2.50\"],\n [\"Next 450 million msgs\", \"$2.25\"],\n [\"Next 4.5 billion msgs\", \"$1.95\"],\n [\"Next 15 billion msgs\", \"$1.65\"],\n [\"Next 30 billion msgs\", \"$1.40\"],\n [\"Over 50 billion msgs\", \"$1.25\"],\n ],\n },\n ],\n },\n {\n title: {\n content: \"Channels and Chat rooms\",\n className: \"ui-text-h3\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n tooltip: (\n <p>\n We charge you for the amount of time a channel is active in our\n network by the minute. For example, if ten channels are in use for 45\n minutes, you will be charged a total of 450 channel minutes.\n </p>\n ),\n },\n description: {\n content:\n \"Channels are used to route messages from publishers to subscribers. Channels are billed by the minute when actively being used by a connected client.\",\n className: \"ui-text-p3\",\n color: \"text-neutral-700 dark:text-neutral-600\",\n },\n price: { amount: \"$1.00\", content: \"/ million mins\" },\n sections: [\n {\n title: \"Volume discounts\",\n items: [\n [\"Consumption\", \"$ / million mins\"],\n [\"First 10 million mins\", \"$1.00\"],\n [\"Next 90 million mins\", \"$0.95\"],\n [\"Next 900 million mins\", \"$0.85\"],\n [\"Next 4 billion mins\", \"$0.75\"],\n [\"Next 10 billion mins\", \"$0.65\"],\n [\"Over 15 billion mins\", \"$0.60\"],\n ],\n },\n ],\n },\n {\n title: {\n content: \"Connections\",\n className: \"ui-text-h3\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n tooltip: (\n <p>\n We charge you for the amount of time devices are connected to our\n network by the minute. For example, if ten devices are each connected\n for 45 minutes, you will be charged a total of 450 connection minutes.\n </p>\n ),\n },\n description: {\n content:\n \"Clients establish and maintain a connection to the Ably service, typically over WebSockets.\",\n className: \"ui-text-p3\",\n color: \"text-neutral-700 dark:text-neutral-600\",\n },\n price: { amount: \"$1.00\", content: \"/ million mins\" },\n sections: [\n {\n title: \"Volume discounts\",\n items: [\n [\"Consumption\", \"$ / million mins\"],\n [\"First 10 million mins\", \"$1.00\"],\n [\"Next 90 million mins\", \"$0.95\"],\n [\"Next 900 million mins\", \"$0.85\"],\n [\"Next 4 billion mins\", \"$0.75\"],\n [\"Next 10 billion mins\", \"$0.65\"],\n [\"Over 15 billion mins\", \"$0.60\"],\n ],\n },\n ],\n },\n];\n"],"names":["React","planData","title","content","className","color","description","price","amount","cta","text","url","iconColor","sections","items","listItemColors","foreground","background","p","style","consumptionData","tooltip"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Pricing/data.tsx"],"sourcesContent":["import React from \"react\";\nimport { PricingDataFeature } from \"./types\";\nimport Tooltip from \"../Tooltip\";\n\nexport const planData: PricingDataFeature[] = [\n {\n title: {\n content: \"Free\",\n className: \"ui-text-h4 tracking-[-0.002rem]\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n },\n description: {\n content: \"Build a proof of concept.\",\n className: \"ui-text-p3\",\n color: \"text-neutral-700 dark:text-neutral-600\",\n },\n price: { amount: \"$0\" },\n cta: {\n text: \"Start for free\",\n url: \"/sign-up\",\n iconColor: \"text-neutral-600 dark:text-neutral-700\",\n },\n sections: [\n {\n title: \"Capacity\",\n items: [\n \"200 concurrent connections\",\n \"500 messages / second\",\n \"6M messages / month\",\n ],\n },\n {\n title: \"Includes\",\n items: [\n \"Build with any Ably product\",\n \"Community & email support (best effort)\",\n \"No commitment\",\n ],\n listItemColors: {\n foreground: \"text-neutral-700 dark:text-neutral-600\",\n background: \"text-neutral-100 dark:text-neutral-1200\",\n },\n },\n ],\n bottomCta: {\n text: \"See all features\",\n url: \"#pricing-table\",\n },\n },\n {\n title: {\n content: \"Standard\",\n className: \"ui-text-h4 tracking-[-0.002rem]\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n },\n description: {\n content: \"Roll-out into production.\",\n className: \"ui-text-p3\",\n color: \"text-neutral-700 dark:text-neutral-600\",\n },\n price: {\n amount: \"$29\",\n content: (\n <>\n <p\n className=\"ui-text-p3 font-medium\"\n style={{ color: \"currentColor\" }}\n >\n / month\n </p>\n <div className=\"flex -mt-1\">\n <p className=\"ui-text-p3 font-bold text-gui-blue-default-dark leading-[1.4rem]\">\n + usage\n </p>\n <Tooltip interactive={true} iconSize=\"1.25rem\">\n Usage is billed on top of your plan. You'll be charged\n monthly based on how many messages, channel minutes, and\n connection minutes you use. See rates above.\n </Tooltip>\n </div>\n </>\n ),\n },\n cta: {\n text: \"Get started\",\n url: \"/users/paid_sign_up?package=standard\",\n iconColor: \"text-neutral-600 dark:text-neutral-700\",\n },\n sections: [\n {\n title: \"Capacity\",\n items: [\n \"10k concurrent channels\",\n \"10k concurrent connections\",\n \"2.5k messages / second\",\n ],\n },\n {\n title: \"Includes\",\n items: [\n \"Build with any Ably product\",\n \"1 day email support SLA\",\n \"Uptime SLO\",\n ],\n listItemColors: {\n foreground: \"text-neutral-700 dark:text-neutral-600\",\n background: \"text-neutral-100 dark:text-neutral-1200\",\n },\n },\n ],\n bottomCta: {\n text: \"See all features\",\n url: \"#pricing-table\",\n },\n },\n {\n title: {\n content: \"Pro\",\n className: \"ui-text-h4 tracking-[-0.002rem]\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n },\n description: {\n content: \"Scale business critical workloads.\",\n className: \"ui-text-p3\",\n color: \"text-neutral-700 dark:text-neutral-600\",\n },\n price: {\n amount: \"$399\",\n content: (\n <>\n <p\n className=\"ui-text-p3 font-medium\"\n style={{ color: \"currentColor\" }}\n >\n / month\n </p>\n <div className=\"flex -mt-1\">\n <p className=\"ui-text-p3 font-bold text-gui-blue-default-dark leading-[1.4rem]\">\n + usage\n </p>\n <Tooltip interactive={true} iconSize=\"1.25rem\">\n Usage is billed on top of your plan. You'll be charged\n monthly based on how many messages, channel minutes, and\n connection minutes you use. See rates above.\n </Tooltip>\n </div>\n </>\n ),\n },\n cta: {\n text: \"Get started\",\n url: \"/users/paid_sign_up?package=pro\",\n iconColor: \"text-neutral-600 dark:text-neutral-700\",\n },\n sections: [\n {\n title: \"Capacity\",\n items: [\n \"50k concurrent channels\",\n \"50k concurrent connections\",\n \"10k messages / second\",\n ],\n },\n {\n title: \"Includes\",\n items: [\n \"Build with any Ably product\",\n \"4 hour email support SLA\",\n \"Datadog (lite)\",\n \"Uptime SLO\",\n ],\n listItemColors: {\n foreground: \"text-neutral-700 dark:text-neutral-600\",\n background: \"text-neutral-100 dark:text-neutral-1200\",\n },\n },\n ],\n bottomCta: {\n text: \"See all features\",\n url: \"#pricing-table\",\n },\n },\n\n {\n title: {\n content: \"Enterprise\",\n className: \"ui-text-h4 tracking-[-0.002rem]\",\n color: \"text-orange-600\",\n },\n description: {\n content: \"Serious workloads without limits.\",\n className: \"ui-text-p3\",\n color: \"text-neutral-700 dark:text-neutral-600\",\n },\n price: { amount: \"Custom\" },\n cta: {\n text: \"Contact us\",\n url: \"/contact\",\n isPriority: true,\n },\n sections: [\n {\n title: \"Capacity\",\n items: [\n \"Unlimited concurrent channels\",\n \"Unlimited connections\",\n \"Unlimited messages / second\",\n ],\n },\n {\n title: \"Includes\",\n items: [\n \"Build with any Ably product\",\n \"24/7 mission critical support\",\n \"99.999% uptime SLAs\",\n \"Committed use discounts\",\n \"Datadog\",\n \"CNAME, SSO, & more\",\n ],\n listItemColors: {\n foreground: \"text-orange-700 dark:text-orange-500\",\n background: \"text-neutral-100 dark:text-neutral-1200\",\n },\n },\n ],\n bottomCta: {\n text: \"See all features\",\n url: \"#pricing-table\",\n },\n },\n];\n\nexport const consumptionData: PricingDataFeature[] = [\n {\n title: {\n content: \"Messages\",\n className: \"ui-text-h3\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n },\n description: {\n content:\n \"Messages contain the data that a client is communicating, such as the contents of a chat message.\",\n className: \"ui-text-p3\",\n color: \"text-neutral-700 dark:text-neutral-600\",\n },\n price: { amount: \"$2.50\", content: \"/ million\" },\n sections: [\n {\n title: \"Volume discounts\",\n items: [\n [\"Consumption\", \"$ / million msgs\"],\n [\"First 50 million msgs\", \"$2.50\"],\n [\"Next 450 million msgs\", \"$2.25\"],\n [\"Next 4.5 billion msgs\", \"$1.95\"],\n [\"Next 15 billion msgs\", \"$1.65\"],\n [\"Next 30 billion msgs\", \"$1.40\"],\n [\"Over 50 billion msgs\", \"$1.25\"],\n ],\n },\n ],\n subtext: \"As low as $0.50/M with volume discount\",\n },\n {\n title: {\n content: \"Channels\",\n className: \"ui-text-h3\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n tooltip: (\n <p>\n We charge you for the amount of time a channel is active in our\n network by the minute. For example, if ten channels are in use for 45\n minutes, you will be charged a total of 450 channel minutes.\n </p>\n ),\n },\n description: {\n content:\n \"Channels are used to route messages from publishers to subscribers. Channels are billed by the minute when actively being used by a connected client.\",\n className: \"ui-text-p3\",\n color: \"text-neutral-700 dark:text-neutral-600\",\n },\n price: { amount: \"$1.00\", content: \"/ million mins\" },\n sections: [\n {\n title: \"Volume discounts\",\n items: [\n [\"Consumption\", \"$ / million mins\"],\n [\"First 10 million mins\", \"$1.00\"],\n [\"Next 90 million mins\", \"$0.95\"],\n [\"Next 900 million mins\", \"$0.85\"],\n [\"Next 4 billion mins\", \"$0.75\"],\n [\"Next 10 billion mins\", \"$0.65\"],\n [\"Over 15 billion mins\", \"$0.60\"],\n ],\n },\n ],\n subtext: \"As low as $0.20/M with volume discount\",\n },\n {\n title: {\n content: \"Connections\",\n className: \"ui-text-h3\",\n color: \"text-neutral-1300 dark:text-neutral-000\",\n tooltip: (\n <p>\n We charge you for the amount of time devices are connected to our\n network by the minute. For example, if ten devices are each connected\n for 45 minutes, you will be charged a total of 450 connection minutes.\n </p>\n ),\n },\n description: {\n content:\n \"Clients establish and maintain a connection to the Ably service, typically over WebSockets.\",\n className: \"ui-text-p3\",\n color: \"text-neutral-700 dark:text-neutral-600\",\n },\n price: { amount: \"$1.00\", content: \"/ million mins\" },\n sections: [\n {\n title: \"Volume discounts\",\n items: [\n [\"Consumption\", \"$ / million mins\"],\n [\"First 10 million mins\", \"$1.00\"],\n [\"Next 90 million mins\", \"$0.95\"],\n [\"Next 900 million mins\", \"$0.85\"],\n [\"Next 4 billion mins\", \"$0.75\"],\n [\"Next 10 billion mins\", \"$0.65\"],\n [\"Over 15 billion mins\", \"$0.60\"],\n ],\n },\n ],\n subtext: \"As low as $0.20/M with volume discount\",\n },\n];\n"],"names":["React","Tooltip","planData","title","content","className","color","description","price","amount","cta","text","url","iconColor","sections","items","listItemColors","foreground","background","bottomCta","p","style","div","interactive","iconSize","isPriority","consumptionData","subtext","tooltip"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAE1B,QAAOC,YAAa,YAAa,AAEjC,QAAO,MAAMC,SAAiC,CAC5C,CACEC,MAAO,CACLC,QAAS,OACTC,UAAW,kCACXC,MAAO,yCACT,EACAC,YAAa,CACXH,QAAS,4BACTC,UAAW,aACXC,MAAO,wCACT,EACAE,MAAO,CAAEC,OAAQ,IAAK,EACtBC,IAAK,CACHC,KAAM,iBACNC,IAAK,WACLC,UAAW,wCACb,EACAC,SAAU,CACR,CACEX,MAAO,WACPY,MAAO,CACL,6BACA,wBACA,sBACD,AACH,EACA,CACEZ,MAAO,WACPY,MAAO,CACL,8BACA,0CACA,gBACD,CACDC,eAAgB,CACdC,WAAY,yCACZC,WAAY,yCACd,CACF,EACD,CACDC,UAAW,CACTR,KAAM,mBACNC,IAAK,gBACP,CACF,EACA,CACET,MAAO,CACLC,QAAS,WACTC,UAAW,kCACXC,MAAO,yCACT,EACAC,YAAa,CACXH,QAAS,4BACTC,UAAW,aACXC,MAAO,wCACT,EACAE,MAAO,CACLC,OAAQ,MACRL,QACE,wCACE,oBAACgB,KACCf,UAAU,yBACVgB,MAAO,CAAEf,MAAO,cAAe,GAChC,WAGD,oBAACgB,OAAIjB,UAAU,cACb,oBAACe,KAAEf,UAAU,oEAAmE,WAGhF,oBAACJ,SAAQsB,YAAa,KAAMC,SAAS,WAAU,iKAQvD,EACAd,IAAK,CACHC,KAAM,cACNC,IAAK,uCACLC,UAAW,wCACb,EACAC,SAAU,CACR,CACEX,MAAO,WACPY,MAAO,CACL,0BACA,6BACA,yBACD,AACH,EACA,CACEZ,MAAO,WACPY,MAAO,CACL,8BACA,0BACA,aACD,CACDC,eAAgB,CACdC,WAAY,yCACZC,WAAY,yCACd,CACF,EACD,CACDC,UAAW,CACTR,KAAM,mBACNC,IAAK,gBACP,CACF,EACA,CACET,MAAO,CACLC,QAAS,MACTC,UAAW,kCACXC,MAAO,yCACT,EACAC,YAAa,CACXH,QAAS,qCACTC,UAAW,aACXC,MAAO,wCACT,EACAE,MAAO,CACLC,OAAQ,OACRL,QACE,wCACE,oBAACgB,KACCf,UAAU,yBACV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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Pricing/types.ts"],"sourcesContent":["import { ReactNode } from \"react\";\nimport { ColorClass, ColorThemeSet } from \"../styles/colors/types\";\n\ntype PricingDataHeader = {\n content: string;\n className?: string;\n color?: ColorClass | ColorThemeSet;\n tooltip?: string | ReactNode;\n};\n\ntype PricingDataFeatureCta = {\n text: string;\n url: string;\n className?: string;\n disabled?: boolean;\n onClick?: () => void;\n iconColor?: ColorClass | ColorThemeSet;\n};\n\nexport type PricingDataFeatureSection = {\n title: string;\n items: string[] | string[][];\n listItemColors?: { foreground: ColorThemeSet; background: ColorThemeSet };\n
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Pricing/types.ts"],"sourcesContent":["import { ReactNode } from \"react\";\nimport { ColorClass, ColorThemeSet } from \"../styles/colors/types\";\n\ntype PricingDataHeader = {\n content: string;\n className?: string;\n color?: ColorClass | ColorThemeSet;\n tooltip?: string | ReactNode;\n};\n\ntype PricingDataFeatureCta = {\n text: string;\n url: string;\n className?: string;\n disabled?: boolean;\n onClick?: () => void;\n iconColor?: ColorClass | ColorThemeSet;\n isPriority?: boolean;\n};\n\nexport type PricingDataFeatureSection = {\n title: string;\n items: string[] | string[][];\n listItemColors?: { foreground: ColorThemeSet; background: ColorThemeSet };\n};\n\nexport type PricingDataFeatureBorder = {\n text: string;\n style: \"border-solid\" | \"border-dashed\" | \"border-dotted\";\n color: \"neutral\" | \"blue\" | \"orange\";\n};\n\nexport type PricingDataFeature = {\n title: PricingDataHeader;\n description: PricingDataHeader;\n price: { amount: string; content?: ReactNode };\n cta?: PricingDataFeatureCta;\n sections: PricingDataFeatureSection[];\n border?: PricingDataFeatureBorder;\n subtext?: string;\n bottomCta?: PricingDataFeatureCta;\n};\n"],"names":[],"mappings":"AAgCA,QASE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import cn from"../utils/cn";const ProductDescription=({description,selected,unavailable,showDescription=true,className})=>{if(!description||!showDescription){return null}return React.createElement("span",{className:cn("block ui-text-p3 font-medium leading-snug",{"text-neutral-300 dark:text-neutral-1000":selected&&!unavailable},{"text-neutral-
|
|
1
|
+
import React from"react";import cn from"../utils/cn";const ProductDescription=({description,selected,unavailable,showDescription=true,className})=>{if(!description||!showDescription){return null}return React.createElement("span",{className:cn("block ui-text-p3 font-medium leading-snug",{"text-neutral-300 dark:text-neutral-1000":selected&&!unavailable},{"text-neutral-800 dark:text-neutral-500 group-hover/product-tile:text-neutral-1000 dark:group-hover/product-tile:text-neutral-300":!selected},className)},description)};export default ProductDescription;
|
|
2
2
|
//# sourceMappingURL=ProductDescription.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/ProductTile/ProductDescription.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"../utils/cn\";\n\ntype ProductDescriptionProps = {\n description: string;\n selected?: boolean;\n unavailable: boolean;\n showDescription?: boolean;\n className?: string;\n};\n\nconst ProductDescription = ({\n description,\n selected,\n unavailable,\n showDescription = true,\n className,\n}: ProductDescriptionProps) => {\n if (!description || !showDescription) {\n return null;\n }\n\n return (\n <span\n className={cn(\n \"block ui-text-p3 font-medium leading-snug\",\n {\n \"text-neutral-300 dark:text-neutral-1000\": selected && !unavailable,\n },\n {\n \"text-neutral-
|
|
1
|
+
{"version":3,"sources":["../../../src/core/ProductTile/ProductDescription.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"../utils/cn\";\n\ntype ProductDescriptionProps = {\n description: string;\n selected?: boolean;\n unavailable: boolean;\n showDescription?: boolean;\n className?: string;\n};\n\nconst ProductDescription = ({\n description,\n selected,\n unavailable,\n showDescription = true,\n className,\n}: ProductDescriptionProps) => {\n if (!description || !showDescription) {\n return null;\n }\n\n return (\n <span\n className={cn(\n \"block ui-text-p3 font-medium leading-snug\",\n {\n \"text-neutral-300 dark:text-neutral-1000\": selected && !unavailable,\n },\n {\n \"text-neutral-800 dark:text-neutral-500 group-hover/product-tile:text-neutral-1000 dark:group-hover/product-tile:text-neutral-300\":\n !selected,\n },\n className,\n )}\n >\n {description}\n </span>\n );\n};\n\nexport default ProductDescription;\n"],"names":["React","cn","ProductDescription","description","selected","unavailable","showDescription","className","span"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QAAOC,OAAQ,aAAc,CAU7B,MAAMC,mBAAqB,CAAC,CAC1BC,WAAW,CACXC,QAAQ,CACRC,WAAW,CACXC,gBAAkB,IAAI,CACtBC,SAAS,CACe,IACxB,GAAI,CAACJ,aAAe,CAACG,gBAAiB,CACpC,OAAO,IACT,CAEA,OACE,oBAACE,QACCD,UAAWN,GACT,4CACA,CACE,0CAA2CG,UAAY,CAACC,WAC1D,EACA,CACE,mIACE,CAACD,QACL,EACAG,YAGDJ,YAGP,CAEA,gBAAeD,kBAAmB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import Icon from"../Icon";import cn from"../utils/cn";const ProductIcon=({name,hoverName,selected,size,unavailable})=>{if(!name){return null}const
|
|
1
|
+
import React from"react";import Icon from"../Icon";import cn from"../utils/cn";const ProductIcon=({name,hoverName,selected,size,unavailable,className})=>{if(!name){return null}const iconSize=size/6*4;return React.createElement("span",{className:cn("flex items-center justify-center border border-neutral-300 dark:border-neutral-1000 rounded-xl","bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-000 dark:hover:bg-neutral-1300 active:bg-neutral-000 dark:active:bg-neutral-1300",className),style:{width:size,height:size}},hoverName?React.createElement(Icon,{name:hoverName,size:`${iconSize}px`,additionalCSS:cn({"hidden group-hover/product-tile:flex":!selected,flex:selected})}):null,React.createElement(Icon,{name:name,size:`${iconSize}px`,additionalCSS:cn({"text-neutral-000 dark:text-neutral-1300":selected&&!unavailable,"text-neutral-1300 dark:text-neutral-000":!selected&&!unavailable,"text-neutral-700 dark:text-neutral-600":selected&&unavailable,"text-neutral-600 dark:text-neutral-700":!selected&&unavailable,"flex group-hover/product-tile:hidden":hoverName&&!selected,hidden:hoverName&&selected})}))};export default ProductIcon;
|
|
2
2
|
//# sourceMappingURL=ProductIcon.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/ProductTile/ProductIcon.tsx"],"sourcesContent":["import React from \"react\";\nimport Icon from \"../Icon\";\nimport { IconName } from \"../Icon/types\";\nimport cn from \"../utils/cn\";\n\ntype ProductIconProps = {\n name?: IconName;\n hoverName?: IconName;\n selected?: boolean;\n size: number;\n unavailable: boolean;\n};\n\nconst ProductIcon = ({\n name,\n hoverName,\n selected,\n size,\n unavailable,\n}: ProductIconProps) => {\n if (!name) {\n return null;\n }\n\n //
|
|
1
|
+
{"version":3,"sources":["../../../src/core/ProductTile/ProductIcon.tsx"],"sourcesContent":["import React from \"react\";\nimport Icon from \"../Icon\";\nimport { IconName } from \"../Icon/types\";\nimport cn from \"../utils/cn\";\n\ntype ProductIconProps = {\n name?: IconName;\n hoverName?: IconName;\n selected?: boolean;\n size: number;\n unavailable: boolean;\n className?: string;\n};\n\nconst ProductIcon = ({\n name,\n hoverName,\n selected,\n size,\n unavailable,\n className,\n}: ProductIconProps) => {\n if (!name) {\n return null;\n }\n\n // Padding around the icon is 1/4 the icon's size, so the icon is 4 of 6 parts\n const iconSize = (size / 6) * 4;\n\n return (\n // Outer container, contains the gradient stroke (since we can't natively have CSS gradient strokes)\n\n <span\n className={cn(\n \"flex items-center justify-center border border-neutral-300 dark:border-neutral-1000 rounded-xl\",\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-000 dark:hover:bg-neutral-1300 active:bg-neutral-000 dark:active:bg-neutral-1300\",\n className,\n )}\n style={{ width: size, height: size }}\n >\n {/* The product icons themselves */}\n {hoverName ? (\n <Icon\n name={hoverName}\n size={`${iconSize}px`}\n additionalCSS={cn({\n \"hidden group-hover/product-tile:flex\": !selected,\n flex: selected,\n })}\n />\n ) : null}\n <Icon\n name={name}\n size={`${iconSize}px`}\n additionalCSS={cn({\n \"text-neutral-000 dark:text-neutral-1300\": selected && !unavailable,\n \"text-neutral-1300 dark:text-neutral-000\": !selected && !unavailable,\n \"text-neutral-700 dark:text-neutral-600\": selected && unavailable,\n \"text-neutral-600 dark:text-neutral-700\": !selected && unavailable,\n \"flex group-hover/product-tile:hidden\": hoverName && !selected,\n hidden: hoverName && selected,\n })}\n />\n </span>\n );\n};\n\nexport default ProductIcon;\n"],"names":["React","Icon","cn","ProductIcon","name","hoverName","selected","size","unavailable","className","iconSize","span","style","width","height","additionalCSS","flex","hidden"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QAAOC,SAAU,SAAU,AAE3B,QAAOC,OAAQ,aAAc,CAW7B,MAAMC,YAAc,CAAC,CACnBC,IAAI,CACJC,SAAS,CACTC,QAAQ,CACRC,IAAI,CACJC,WAAW,CACXC,SAAS,CACQ,IACjB,GAAI,CAACL,KAAM,CACT,OAAO,IACT,CAGA,MAAMM,SAAW,AAACH,KAAO,EAAK,EAE9B,OAGE,oBAACI,QACCF,UAAWP,GACT,iGACA,wIACAO,WAEFG,MAAO,CAAEC,MAAON,KAAMO,OAAQP,IAAK,GAGlCF,UACC,oBAACJ,MACCG,KAAMC,UACNE,KAAM,CAAC,EAAEG,SAAS,EAAE,CAAC,CACrBK,cAAeb,GAAG,CAChB,uCAAwC,CAACI,SACzCU,KAAMV,QACR,KAEA,KACJ,oBAACL,MACCG,KAAMA,KACNG,KAAM,CAAC,EAAEG,SAAS,EAAE,CAAC,CACrBK,cAAeb,GAAG,CAChB,0CAA2CI,UAAY,CAACE,YACxD,0CAA2C,CAACF,UAAY,CAACE,YACzD,yCAA0CF,UAAYE,YACtD,yCAA0C,CAACF,UAAYE,YACvD,uCAAwCH,WAAa,CAACC,SACtDW,OAAQZ,WAAaC,QACvB,KAIR,CAEA,gBAAeH,WAAY"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import cn from"../utils/cn";const LABEL_FONT_SIZE_RATIO=4;const DESCRIPTION_FONT_SIZE_RATIO=2.6;const ProductLabel=({label,unavailable,selected,numericalSize,showLabel,className})=>{if(!label||!showLabel){return null}const dynamicFontSize=numericalSize/LABEL_FONT_SIZE_RATIO;return React.createElement("span",{className:"flex flex-col justify-center"},unavailable?React.createElement("span",{className:"block"},React.createElement("span",{className:"table-cell font-sans bg-neutral-300 dark:bg-neutral-1000 rounded-full text-gui-
|
|
1
|
+
import React from"react";import cn from"../utils/cn";const LABEL_FONT_SIZE_RATIO=4;const DESCRIPTION_FONT_SIZE_RATIO=2.6;const ProductLabel=({label,unavailable,selected,numericalSize,showLabel,showAblyText=true,className})=>{if(!label||!showLabel){return null}const dynamicFontSize=numericalSize/LABEL_FONT_SIZE_RATIO;return React.createElement("span",{className:"flex flex-col justify-center"},unavailable?React.createElement("span",{className:"block"},React.createElement("span",{className:"table-cell font-sans bg-neutral-300 dark:bg-neutral-1000 rounded-full text-gui-disabled-light dark:text-gui-disabled-dark tracking-[0.04em] font-bold leading-snug",style:{fontSize:dynamicFontSize*.6,padding:`${dynamicFontSize*.25}px ${dynamicFontSize*.5}px`}},"COMING SOON")):showAblyText&&React.createElement("span",{className:cn("block font-bold uppercase ui-text-p2 leading-snug",{"text-neutral-500 dark:text-neutral-700":selected},{"text-neutral-700 dark:text-neutral-500":!selected}),style:{fontSize:dynamicFontSize,letterSpacing:"0.06em"}},"Ably"),React.createElement("span",{className:cn("block ui-text-p2 font-bold",{"text-neutral-000 dark:text-neutral-1300":selected===true&&!unavailable},{"text-neutral-1000 dark:text-neutral-300 group-hover/product-tile:text-neutral-1300 dark:group-hover/product-tile:text-neutral-000":selected===false&&!unavailable},{"text-neutral-1300 dark:text-neutral-000":selected===undefined&&!unavailable},{"text-neutral-700 dark:text-neutral-600":unavailable},{"mt-[-3px]":!unavailable},className),style:{fontSize:numericalSize/DESCRIPTION_FONT_SIZE_RATIO}},label))};export default ProductLabel;
|
|
2
2
|
//# sourceMappingURL=ProductLabel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/ProductTile/ProductLabel.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"../utils/cn\";\n\ntype ProductLabelProps = {\n label: string;\n unavailable: boolean;\n selected?: boolean;\n numericalSize: number;\n showLabel?: boolean;\n className?: string;\n};\n\nconst LABEL_FONT_SIZE_RATIO = 4;\nconst DESCRIPTION_FONT_SIZE_RATIO = 2.6;\n\nconst ProductLabel = ({\n label,\n unavailable,\n selected,\n numericalSize,\n showLabel,\n className,\n}: ProductLabelProps) => {\n if (!label || !showLabel) {\n return null;\n }\n\n const dynamicFontSize = numericalSize / LABEL_FONT_SIZE_RATIO;\n\n return (\n <span className=\"flex flex-col justify-center\">\n {unavailable ? (\n <span className=\"block\">\n <span\n className=\"table-cell font-sans bg-neutral-300 dark:bg-neutral-1000 rounded-full text-gui-
|
|
1
|
+
{"version":3,"sources":["../../../src/core/ProductTile/ProductLabel.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"../utils/cn\";\n\ntype ProductLabelProps = {\n label: string;\n unavailable: boolean;\n selected?: boolean;\n numericalSize: number;\n showLabel?: boolean;\n showAblyText?: boolean;\n className?: string;\n};\n\nconst LABEL_FONT_SIZE_RATIO = 4;\nconst DESCRIPTION_FONT_SIZE_RATIO = 2.6;\n\nconst ProductLabel = ({\n label,\n unavailable,\n selected,\n numericalSize,\n showLabel,\n showAblyText = true,\n className,\n}: ProductLabelProps) => {\n if (!label || !showLabel) {\n return null;\n }\n\n const dynamicFontSize = numericalSize / LABEL_FONT_SIZE_RATIO;\n\n return (\n <span className=\"flex flex-col justify-center\">\n {unavailable ? (\n <span className=\"block\">\n <span\n className=\"table-cell font-sans bg-neutral-300 dark:bg-neutral-1000 rounded-full text-gui-disabled-light dark:text-gui-disabled-dark tracking-[0.04em] font-bold leading-snug\"\n style={{\n fontSize: dynamicFontSize * 0.6,\n padding: `${dynamicFontSize * 0.25}px ${dynamicFontSize * 0.5}px`,\n }}\n >\n COMING SOON\n </span>\n </span>\n ) : (\n showAblyText && (\n <span\n className={cn(\n \"block font-bold uppercase ui-text-p2 leading-snug\",\n { \"text-neutral-500 dark:text-neutral-700\": selected },\n { \"text-neutral-700 dark:text-neutral-500\": !selected },\n )}\n style={{\n fontSize: dynamicFontSize,\n letterSpacing: \"0.06em\",\n }}\n >\n Ably\n </span>\n )\n )}\n <span\n className={cn(\n \"block ui-text-p2 font-bold\",\n {\n \"text-neutral-000 dark:text-neutral-1300\":\n selected === true && !unavailable,\n },\n {\n \"text-neutral-1000 dark:text-neutral-300 group-hover/product-tile:text-neutral-1300 dark:group-hover/product-tile:text-neutral-000\":\n selected === false && !unavailable,\n },\n {\n \"text-neutral-1300 dark:text-neutral-000\":\n selected === undefined && !unavailable,\n },\n {\n \"text-neutral-700 dark:text-neutral-600\": unavailable,\n },\n { \"mt-[-3px]\": !unavailable },\n className,\n )}\n style={{ fontSize: numericalSize / DESCRIPTION_FONT_SIZE_RATIO }}\n >\n {label}\n </span>\n </span>\n );\n};\n\nexport default ProductLabel;\n"],"names":["React","cn","LABEL_FONT_SIZE_RATIO","DESCRIPTION_FONT_SIZE_RATIO","ProductLabel","label","unavailable","selected","numericalSize","showLabel","showAblyText","className","dynamicFontSize","span","style","fontSize","padding","letterSpacing","undefined"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QAAOC,OAAQ,aAAc,CAY7B,MAAMC,sBAAwB,EAC9B,MAAMC,4BAA8B,IAEpC,MAAMC,aAAe,CAAC,CACpBC,KAAK,CACLC,WAAW,CACXC,QAAQ,CACRC,aAAa,CACbC,SAAS,CACTC,aAAe,IAAI,CACnBC,SAAS,CACS,IAClB,GAAI,CAACN,OAAS,CAACI,UAAW,CACxB,OAAO,IACT,CAEA,MAAMG,gBAAkBJ,cAAgBN,sBAExC,OACE,oBAACW,QAAKF,UAAU,gCACbL,YACC,oBAACO,QAAKF,UAAU,SACd,oBAACE,QACCF,UAAU,qKACVG,MAAO,CACLC,SAAUH,gBAAkB,GAC5BI,QAAS,CAAC,EAAEJ,gBAAkB,IAAK,GAAG,EAAEA,gBAAkB,GAAI,EAAE,CAAC,AACnE,GACD,gBAKHF,cACE,oBAACG,QACCF,UAAWV,GACT,oDACA,CAAE,yCAA0CM,QAAS,EACrD,CAAE,yCAA0C,CAACA,QAAS,GAExDO,MAAO,CACLC,SAAUH,gBACVK,cAAe,QACjB,GACD,QAKL,oBAACJ,QACCF,UAAWV,GACT,6BACA,CACE,0CACEM,WAAa,MAAQ,CAACD,WAC1B,EACA,CACE,oIACEC,WAAa,OAAS,CAACD,WAC3B,EACA,CACE,0CACEC,WAAaW,WAAa,CAACZ,WAC/B,EACA,CACE,yCAA0CA,WAC5C,EACA,CAAE,YAAa,CAACA,WAAY,EAC5BK,WAEFG,MAAO,CAAEC,SAAUP,cAAgBL,2BAA4B,GAE9DE,OAIT,CAEA,gBAAeD,YAAa"}
|
package/core/ProductTile/data.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const productNames=["pubsub","chat","
|
|
1
|
+
export const productNames=["pubsub","chat","aiTransport","liveObjects","spaces","liveSync"];export const products={pubsub:{label:"Pub/Sub",description:"Low-level APIs to build any realtime experience.",icon:"icon-product-pubsub-mono",hoverIcon:"icon-product-pubsub",link:"/docs/channels"},chat:{label:"Chat",description:"Rapidly build chat features and roll-out at scale.",icon:"icon-product-chat-mono",hoverIcon:"icon-product-chat",link:"/docs/chat"},aiTransport:{label:"AI Transport",description:"A drop-in infrastructure layer for a durable AI UX.",icon:"icon-product-ai-transport-mono",hoverIcon:"icon-product-ai-transport"},liveObjects:{label:"LiveObjects",description:"Sync application state across multiple devices.",icon:"icon-product-liveobjects-mono",hoverIcon:"icon-product-liveobjects",link:"/docs/liveobjects"},spaces:{label:"Spaces",description:"Create collaborative environments in a few lines of code.",icon:"icon-product-spaces-mono",hoverIcon:"icon-product-spaces",link:"/docs/spaces"},liveSync:{label:"LiveSync",description:"Sync database changes with frontend clients.",icon:"icon-product-livesync-mono",hoverIcon:"icon-product-livesync",link:"/docs/livesync"}};
|
|
2
2
|
//# sourceMappingURL=data.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/ProductTile/data.ts"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\nexport const productNames = [\n \"pubsub\",\n \"chat\",\n \"
|
|
1
|
+
{"version":3,"sources":["../../../src/core/ProductTile/data.ts"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\nexport const productNames = [\n \"pubsub\",\n \"chat\",\n \"aiTransport\",\n \"liveObjects\",\n \"spaces\",\n \"liveSync\",\n] as const;\n\nexport type ProductName = (typeof productNames)[number];\n\ntype Products = Record<\n ProductName,\n {\n label: string;\n description: string;\n link?: string;\n icon?: IconName;\n hoverIcon?: IconName;\n unavailable?: boolean;\n }\n>;\n\nexport const products: Products = {\n pubsub: {\n label: \"Pub/Sub\",\n description: \"Low-level APIs to build any realtime experience.\",\n icon: \"icon-product-pubsub-mono\",\n hoverIcon: \"icon-product-pubsub\",\n link: \"/docs/channels\",\n },\n chat: {\n label: \"Chat\",\n description: \"Rapidly build chat features and roll-out at scale.\",\n icon: \"icon-product-chat-mono\",\n hoverIcon: \"icon-product-chat\",\n link: \"/docs/chat\",\n },\n aiTransport: {\n label: \"AI Transport\",\n description: \"A drop-in infrastructure layer for a durable AI UX.\",\n icon: \"icon-product-ai-transport-mono\",\n hoverIcon: \"icon-product-ai-transport\",\n },\n liveObjects: {\n label: \"LiveObjects\",\n description: \"Sync application state across multiple devices.\",\n icon: \"icon-product-liveobjects-mono\",\n hoverIcon: \"icon-product-liveobjects\",\n link: \"/docs/liveobjects\",\n },\n spaces: {\n label: \"Spaces\",\n description: \"Create collaborative environments in a few lines of code.\",\n icon: \"icon-product-spaces-mono\",\n hoverIcon: \"icon-product-spaces\",\n link: \"/docs/spaces\",\n },\n liveSync: {\n label: \"LiveSync\",\n description: \"Sync database changes with frontend clients.\",\n icon: \"icon-product-livesync-mono\",\n hoverIcon: \"icon-product-livesync\",\n link: \"/docs/livesync\",\n },\n};\n"],"names":["productNames","products","pubsub","label","description","icon","hoverIcon","link","chat","aiTransport","liveObjects","spaces","liveSync"],"mappings":"AAEA,OAAO,MAAMA,aAAe,CAC1B,SACA,OACA,cACA,cACA,SACA,WACD,AAAU,AAgBX,QAAO,MAAMC,SAAqB,CAChCC,OAAQ,CACNC,MAAO,UACPC,YAAa,mDACbC,KAAM,2BACNC,UAAW,sBACXC,KAAM,gBACR,EACAC,KAAM,CACJL,MAAO,OACPC,YAAa,qDACbC,KAAM,yBACNC,UAAW,oBACXC,KAAM,YACR,EACAE,YAAa,CACXN,MAAO,eACPC,YAAa,sDACbC,KAAM,iCACNC,UAAW,2BACb,EACAI,YAAa,CACXP,MAAO,cACPC,YAAa,kDACbC,KAAM,gCACNC,UAAW,2BACXC,KAAM,mBACR,EACAI,OAAQ,CACNR,MAAO,SACPC,YAAa,4DACbC,KAAM,2BACNC,UAAW,sBACXC,KAAM,cACR,EACAK,SAAU,CACRT,MAAO,WACPC,YAAa,+CACbC,KAAM,6BACNC,UAAW,wBACXC,KAAM,gBACR,CACF,CAAE"}
|
package/core/ProductTile.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import cn from"./utils/cn";import LinkButton from"./LinkButton";import{products}from"./ProductTile/data";import ProductIcon from"./ProductTile/ProductIcon";import ProductLabel from"./ProductTile/ProductLabel";import ProductDescription from"./ProductTile/ProductDescription";const CONTAINER_GAP_RATIO=3;const ProductTile=({name,selected,currentPage,className,onClick,showDescription=true,showLabel=true,size="40px",animateIcons=false,descriptionClassName,labelClassName})=>{const{icon,hoverIcon,label,description,link,unavailable}=products[name]??{};const numericalSize=parseInt(size,10);const containerPresent=showDescription||showLabel;return React.createElement("div",{className:cn("transition-colors group/product-tile",{"flex flex-col p-3 rounded-lg gap-2":containerPresent},{"bg-neutral-1300 dark:bg-neutral-000":selected},{"bg-neutral-000 dark:bg-neutral-1300":!selected},{"hover:bg-neutral-100 dark:hover:bg-neutral-1200":selected===false&&!unavailable},{"cursor-pointer":selected!==undefined&&!unavailable},{"pointer-events-none":unavailable},{[`${className}`]:className}),"aria-hidden":unavailable,onClick:onClick},React.createElement("div",{className:cn("items-center",{flex:containerPresent},{"inline-flex":!containerPresent}),style:{gap:containerPresent?numericalSize/CONTAINER_GAP_RATIO:0}},React.createElement(ProductIcon,{size:numericalSize,name:icon,hoverName:animateIcons?hoverIcon:undefined,selected:selected,unavailable:!!unavailable}),React.createElement(ProductLabel,{label:label,selected:selected,unavailable:!!unavailable,numericalSize:numericalSize,showLabel:showLabel,className:labelClassName})),React.createElement(ProductDescription,{description:description,selected:selected,unavailable:!!unavailable,showDescription:showDescription,className:descriptionClassName}),selected&&link?React.createElement(LinkButton,{variant:"secondary",size:"xs",className:"mt-2 !text-neutral-000 dark:!text-neutral-1300",rightIcon:"icon-gui-arrow-right-micro",iconColor:"text-orange-600",href:link},currentPage?"View docs":"Explore"):null)};export default ProductTile;
|
|
1
|
+
import React from"react";import cn from"./utils/cn";import LinkButton from"./LinkButton";import{products}from"./ProductTile/data";import ProductIcon from"./ProductTile/ProductIcon";import ProductLabel from"./ProductTile/ProductLabel";import ProductDescription from"./ProductTile/ProductDescription";const CONTAINER_GAP_RATIO=3;const ProductTile=({name,selected,currentPage,className,onClick,showDescription=true,showLabel=true,size="40px",animateIcons=false,descriptionClassName,labelClassName,iconClassName})=>{const{icon,hoverIcon,label,description,link,unavailable}=products[name]??{};const numericalSize=parseInt(size,10);const containerPresent=showDescription||showLabel;return React.createElement("div",{className:cn("transition-colors group/product-tile",{"flex flex-col p-3 rounded-lg gap-2":containerPresent},{"bg-neutral-1300 dark:bg-neutral-000":selected},{"bg-neutral-000 dark:bg-neutral-1300":!selected},{"hover:bg-neutral-100 dark:hover:bg-neutral-1200":selected===false&&!unavailable},{"cursor-pointer":selected!==undefined&&!unavailable},{"pointer-events-none":unavailable},{[`${className}`]:className}),"aria-hidden":unavailable,onClick:onClick,onKeyDown:onClick?e=>{if(e.key==="Enter"||e.key===" "){e.preventDefault();onClick()}}:undefined,role:onClick?"button":undefined,tabIndex:onClick?0:undefined},React.createElement("div",{className:cn("items-center",{flex:containerPresent},{"inline-flex":!containerPresent}),style:{gap:containerPresent?numericalSize/CONTAINER_GAP_RATIO:0}},React.createElement(ProductIcon,{size:numericalSize,name:icon,hoverName:animateIcons?hoverIcon:undefined,selected:selected,unavailable:!!unavailable,className:iconClassName}),React.createElement(ProductLabel,{label:label,selected:selected,unavailable:!!unavailable,numericalSize:numericalSize,showLabel:showLabel,className:labelClassName})),React.createElement(ProductDescription,{description:description,selected:selected,unavailable:!!unavailable,showDescription:showDescription,className:descriptionClassName}),selected&&link?React.createElement(LinkButton,{variant:"secondary",size:"xs",className:"mt-2 !text-neutral-000 dark:!text-neutral-1300",rightIcon:"icon-gui-arrow-right-micro",iconColor:"text-orange-600",href:link},currentPage?"View docs":"Explore"):null)};export default ProductTile;
|
|
2
2
|
//# sourceMappingURL=ProductTile.js.map
|