@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
package/core/ProductTile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/ProductTile.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"./utils/cn\";\nimport { IconSize } from \"./Icon/types\";\nimport LinkButton from \"./LinkButton\";\nimport { ProductName, products } from \"./ProductTile/data\";\nimport ProductIcon from \"./ProductTile/ProductIcon\";\nimport ProductLabel from \"./ProductTile/ProductLabel\";\nimport ProductDescription from \"./ProductTile/ProductDescription\";\n\n/**\n * Props for the ProductTile component.\n */\nexport type ProductTileProps = {\n /**\n * The name of the product.\n */\n name: ProductName;\n\n /**\n * Indicates if the product tile is selected. If `undefined`, the product tile is not selectable.\n * @default false\n */\n selected?: boolean;\n\n /**\n * Indicates if the product tile is on the \"current\" page. Changes CTA copy.\n * @default false\n */\n currentPage?: boolean;\n\n /**\n * Additional CSS class names to apply to the product tile outer container.\n */\n className?: string;\n\n /**\n * Additional CSS class names to apply to the product description container.\n */\n descriptionClassName?: string;\n\n /**\n * Additional CSS class names to apply to the product name / label container.\n */\n labelClassName?: string;\n\n /**\n * Callback function to handle click events on the product tile.\n */\n onClick?: () => void;\n\n /**\n * Indicates if the product description should be shown.\n * @default true\n */\n showDescription?: boolean;\n\n /**\n * Indicates if the product label should be shown.\n * @default true\n */\n showLabel?: boolean;\n\n /**\n * The size of the product icon.\n * @default \"40px\"\n */\n size?: IconSize;\n\n /**\n * Indicates if the product icons should be animated.\n * @default false\n */\n animateIcons?: boolean;\n};\n\nconst CONTAINER_GAP_RATIO = 3;\n\nconst ProductTile = ({\n name,\n selected,\n currentPage,\n className,\n onClick,\n showDescription = true,\n showLabel = true,\n size = \"40px\",\n animateIcons = false,\n descriptionClassName,\n labelClassName,\n}: ProductTileProps) => {\n const { icon, hoverIcon, label, description, link, unavailable } =\n products[name] ?? {};\n const numericalSize = parseInt(size, 10);\n const containerPresent = showDescription || showLabel;\n\n return (\n <div\n className={cn(\n \"transition-colors group/product-tile\",\n { \"flex flex-col p-3 rounded-lg gap-2\": containerPresent },\n { \"bg-neutral-1300 dark:bg-neutral-000\": selected },\n {\n \"bg-neutral-000 dark:bg-neutral-1300\": !selected,\n },\n {\n \"hover:bg-neutral-100 dark:hover:bg-neutral-1200\":\n selected === false && !unavailable,\n },\n { \"cursor-pointer\": selected !== undefined && !unavailable },\n { \"pointer-events-none\": unavailable },\n { [`${className}`]: className },\n )}\n aria-hidden={unavailable}\n onClick={onClick}\n >\n <div\n className={cn(\n \"items-center\",\n { flex: containerPresent },\n { \"inline-flex\": !containerPresent },\n )}\n style={{\n gap: containerPresent ? numericalSize / CONTAINER_GAP_RATIO : 0,\n }}\n >\n <ProductIcon\n size={numericalSize}\n name={icon}\n hoverName={animateIcons ? hoverIcon : undefined}\n selected={selected}\n unavailable={!!unavailable}\n />\n <ProductLabel\n label={label}\n selected={selected}\n unavailable={!!unavailable}\n numericalSize={numericalSize}\n showLabel={showLabel}\n className={labelClassName}\n />\n </div>\n <ProductDescription\n description={description}\n selected={selected}\n unavailable={!!unavailable}\n showDescription={showDescription}\n className={descriptionClassName}\n />\n {selected && link ? (\n <LinkButton\n variant=\"secondary\"\n size=\"xs\"\n className=\"mt-2 !text-neutral-000 dark:!text-neutral-1300\"\n rightIcon=\"icon-gui-arrow-right-micro\"\n iconColor=\"text-orange-600\"\n href={link}\n >\n {currentPage ? \"View docs\" : \"Explore\"}\n </LinkButton>\n ) : null}\n </div>\n );\n};\n\nexport default ProductTile;\n"],"names":["React","cn","LinkButton","products","ProductIcon","ProductLabel","ProductDescription","CONTAINER_GAP_RATIO","ProductTile","name","selected","currentPage","className","onClick","showDescription","showLabel","size","animateIcons","descriptionClassName","labelClassName","icon","hoverIcon","label","description","link","unavailable","numericalSize","parseInt","containerPresent","div","undefined","aria-hidden","flex","style","gap","hoverName","variant","rightIcon","iconColor","href"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QAAOC,OAAQ,YAAa,AAE5B,QAAOC,eAAgB,cAAe,AACtC,QAAsBC,QAAQ,KAAQ,oBAAqB,AAC3D,QAAOC,gBAAiB,2BAA4B,AACpD,QAAOC,iBAAkB,4BAA6B,AACtD,QAAOC,uBAAwB,kCAAmC,
|
|
1
|
+
{"version":3,"sources":["../../src/core/ProductTile.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"./utils/cn\";\nimport { IconSize } from \"./Icon/types\";\nimport LinkButton from \"./LinkButton\";\nimport { ProductName, products } from \"./ProductTile/data\";\nimport ProductIcon from \"./ProductTile/ProductIcon\";\nimport ProductLabel from \"./ProductTile/ProductLabel\";\nimport ProductDescription from \"./ProductTile/ProductDescription\";\n\n/**\n * Props for the ProductTile component.\n */\nexport type ProductTileProps = {\n /**\n * The name of the product.\n */\n name: ProductName;\n\n /**\n * Indicates if the product tile is selected. If `undefined`, the product tile is not selectable.\n * @default false\n */\n selected?: boolean;\n\n /**\n * Indicates if the product tile is on the \"current\" page. Changes CTA copy.\n * @default false\n */\n currentPage?: boolean;\n\n /**\n * Additional CSS class names to apply to the product tile outer container.\n */\n className?: string;\n\n /**\n * Additional CSS class names to apply to the product description container.\n */\n descriptionClassName?: string;\n\n /**\n * Additional CSS class names to apply to the product name / label container.\n */\n labelClassName?: string;\n\n /**\n * Additional CSS class names to apply to the product icon.\n */\n iconClassName?: string;\n\n /**\n * Callback function to handle click events on the product tile.\n */\n\n onClick?: () => void;\n\n /**\n * Indicates if the product description should be shown.\n * @default true\n */\n showDescription?: boolean;\n\n /**\n * Indicates if the product label should be shown.\n * @default true\n */\n showLabel?: boolean;\n\n /**\n * The size of the product icon.\n * @default \"40px\"\n */\n size?: IconSize;\n\n /**\n * Indicates if the product icons should be animated.\n * @default false\n */\n animateIcons?: boolean;\n};\n\nconst CONTAINER_GAP_RATIO = 3;\n\nconst ProductTile = ({\n name,\n selected,\n currentPage,\n className,\n onClick,\n showDescription = true,\n showLabel = true,\n size = \"40px\",\n animateIcons = false,\n descriptionClassName,\n labelClassName,\n iconClassName,\n}: ProductTileProps) => {\n const { icon, hoverIcon, label, description, link, unavailable } =\n products[name] ?? {};\n const numericalSize = parseInt(size, 10);\n const containerPresent = showDescription || showLabel;\n\n return (\n <div\n className={cn(\n \"transition-colors group/product-tile\",\n { \"flex flex-col p-3 rounded-lg gap-2\": containerPresent },\n { \"bg-neutral-1300 dark:bg-neutral-000\": selected },\n {\n \"bg-neutral-000 dark:bg-neutral-1300\": !selected,\n },\n {\n \"hover:bg-neutral-100 dark:hover:bg-neutral-1200\":\n selected === false && !unavailable,\n },\n { \"cursor-pointer\": selected !== undefined && !unavailable },\n { \"pointer-events-none\": unavailable },\n { [`${className}`]: className },\n )}\n aria-hidden={unavailable}\n onClick={onClick}\n onKeyDown={\n onClick\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n }\n : undefined\n }\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n >\n <div\n className={cn(\n \"items-center\",\n { flex: containerPresent },\n { \"inline-flex\": !containerPresent },\n )}\n style={{\n gap: containerPresent ? numericalSize / CONTAINER_GAP_RATIO : 0,\n }}\n >\n <ProductIcon\n size={numericalSize}\n name={icon}\n hoverName={animateIcons ? hoverIcon : undefined}\n selected={selected}\n unavailable={!!unavailable}\n className={iconClassName}\n />\n <ProductLabel\n label={label}\n selected={selected}\n unavailable={!!unavailable}\n numericalSize={numericalSize}\n showLabel={showLabel}\n className={labelClassName}\n />\n </div>\n <ProductDescription\n description={description}\n selected={selected}\n unavailable={!!unavailable}\n showDescription={showDescription}\n className={descriptionClassName}\n />\n {selected && link ? (\n <LinkButton\n variant=\"secondary\"\n size=\"xs\"\n className=\"mt-2 !text-neutral-000 dark:!text-neutral-1300\"\n rightIcon=\"icon-gui-arrow-right-micro\"\n iconColor=\"text-orange-600\"\n href={link}\n >\n {currentPage ? \"View docs\" : \"Explore\"}\n </LinkButton>\n ) : null}\n </div>\n );\n};\n\nexport default ProductTile;\n"],"names":["React","cn","LinkButton","products","ProductIcon","ProductLabel","ProductDescription","CONTAINER_GAP_RATIO","ProductTile","name","selected","currentPage","className","onClick","showDescription","showLabel","size","animateIcons","descriptionClassName","labelClassName","iconClassName","icon","hoverIcon","label","description","link","unavailable","numericalSize","parseInt","containerPresent","div","undefined","aria-hidden","onKeyDown","e","key","preventDefault","role","tabIndex","flex","style","gap","hoverName","variant","rightIcon","iconColor","href"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QAAOC,OAAQ,YAAa,AAE5B,QAAOC,eAAgB,cAAe,AACtC,QAAsBC,QAAQ,KAAQ,oBAAqB,AAC3D,QAAOC,gBAAiB,2BAA4B,AACpD,QAAOC,iBAAkB,4BAA6B,AACtD,QAAOC,uBAAwB,kCAAmC,CA0ElE,MAAMC,oBAAsB,EAE5B,MAAMC,YAAc,CAAC,CACnBC,IAAI,CACJC,QAAQ,CACRC,WAAW,CACXC,SAAS,CACTC,OAAO,CACPC,gBAAkB,IAAI,CACtBC,UAAY,IAAI,CAChBC,KAAO,MAAM,CACbC,aAAe,KAAK,CACpBC,oBAAoB,CACpBC,cAAc,CACdC,aAAa,CACI,IACjB,KAAM,CAAEC,IAAI,CAAEC,SAAS,CAAEC,KAAK,CAAEC,WAAW,CAAEC,IAAI,CAAEC,WAAW,CAAE,CAC9DvB,QAAQ,CAACM,KAAK,EAAI,CAAC,EACrB,MAAMkB,cAAgBC,SAASZ,KAAM,IACrC,MAAMa,iBAAmBf,iBAAmBC,UAE5C,OACE,oBAACe,OACClB,UAAWX,GACT,uCACA,CAAE,qCAAsC4B,gBAAiB,EACzD,CAAE,sCAAuCnB,QAAS,EAClD,CACE,sCAAuC,CAACA,QAC1C,EACA,CACE,kDACEA,WAAa,OAAS,CAACgB,WAC3B,EACA,CAAE,iBAAkBhB,WAAaqB,WAAa,CAACL,WAAY,EAC3D,CAAE,sBAAuBA,WAAY,EACrC,CAAE,CAAC,CAAC,EAAEd,UAAU,CAAC,CAAC,CAAEA,SAAU,GAEhCoB,cAAaN,YACbb,QAASA,QACToB,UACEpB,QACI,AAACqB,IACC,GAAIA,EAAEC,GAAG,GAAK,SAAWD,EAAEC,GAAG,GAAK,IAAK,CACtCD,EAAEE,cAAc,GAChBvB,SACF,CACF,EACAkB,UAENM,KAAMxB,QAAU,SAAWkB,UAC3BO,SAAUzB,QAAU,EAAIkB,WAExB,oBAACD,OACClB,UAAWX,GACT,eACA,CAAEsC,KAAMV,gBAAiB,EACzB,CAAE,cAAe,CAACA,gBAAiB,GAErCW,MAAO,CACLC,IAAKZ,iBAAmBF,cAAgBpB,oBAAsB,CAChE,GAEA,oBAACH,aACCY,KAAMW,cACNlB,KAAMY,KACNqB,UAAWzB,aAAeK,UAAYS,UACtCrB,SAAUA,SACVgB,YAAa,CAAC,CAACA,YACfd,UAAWQ,gBAEb,oBAACf,cACCkB,MAAOA,MACPb,SAAUA,SACVgB,YAAa,CAAC,CAACA,YACfC,cAAeA,cACfZ,UAAWA,UACXH,UAAWO,kBAGf,oBAACb,oBACCkB,YAAaA,YACbd,SAAUA,SACVgB,YAAa,CAAC,CAACA,YACfZ,gBAAiBA,gBACjBF,UAAWM,uBAEZR,UAAYe,KACX,oBAACvB,YACCyC,QAAQ,YACR3B,KAAK,KACLJ,UAAU,iDACVgC,UAAU,6BACVC,UAAU,kBACVC,KAAMrB,MAELd,YAAc,YAAc,WAE7B,KAGV,CAEA,gBAAeH,WAAY"}
|
package/core/SegmentedControl.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import cn from"./utils/cn";import Icon from"./Icon";const SegmentedControl=({className,rounded=false,leftIcon,rightIcon,active=false,variant="default",size="md",children,onClick,disabled})=>{const colorStyles={default:{active:"bg-neutral-200 dark:bg-neutral-1100",inactive:"bg-neutral-000 dark:bg-neutral-1300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-100 dark:active:bg-neutral-1200"},subtle:{active:"bg-neutral-000 dark:bg-neutral-1000",inactive:"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100"},strong:{active:"bg-neutral-1000 dark:bg-neutral-300",inactive:"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100"}};const contentColorStyles={default:{active:"text-neutral-1300 dark:text-neutral-000",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"},subtle:{active:"text-neutral-1300 dark:text-neutral-000",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"},strong:{active:"text-neutral-000 dark:text-neutral-1300",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"}};const sizeStyles={md:cn("h-12 p-3 gap-2.5",rounded&&"px-[1.125rem]"),sm:cn("h-10 p-[0.5625rem] gap-[0.5625rem]",rounded&&"px-3.5"),xs:cn("h-9 p-2 gap-2",rounded&&"px-3")};const textStyles={md:"ui-text-label2",sm:"ui-text-label3",xs:"ui-text-label4"};const iconSizes={md:"23px",sm:"22px",xs:"20px"};const activeKey=active?"active":"inactive";return React.createElement("div",{onClick:!disabled?onClick:undefined,onKeyDown:e=>{if((e.key==="Enter"||e.key===" ")&&!disabled&&onClick){e.preventDefault();onClick()}},className:cn("focus-base flex items-center justify-center cursor-pointer select-none transition-colors",colorStyles[variant][activeKey],contentColorStyles[variant][activeKey],sizeStyles[size],textStyles[size],disabled&&"cursor-not-allowed hover:bg-inherit dark:hover:bg-inherit active:bg-inherit dark:active:bg-inherit",rounded?"rounded-full":"rounded-lg",className),tabIndex:disabled?-1:0,role:"button","aria-pressed":active,"aria-disabled":disabled},leftIcon&&React.createElement(Icon,{name:leftIcon,size:iconSizes[size],"aria-hidden":"true"}),children&&React.createElement("span",{className:cn("font-semibold transition-colors",contentColorStyles[variant][activeKey],disabled&&"text-gui-
|
|
1
|
+
import React from"react";import cn from"./utils/cn";import Icon from"./Icon";const SegmentedControl=({className,rounded=false,leftIcon,rightIcon,active=false,variant="default",size="md",children,onClick,disabled})=>{const colorStyles={default:{active:"bg-neutral-200 dark:bg-neutral-1100",inactive:"bg-neutral-000 dark:bg-neutral-1300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-100 dark:active:bg-neutral-1200"},subtle:{active:"bg-neutral-000 dark:bg-neutral-1000",inactive:"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100"},strong:{active:"bg-neutral-1000 dark:bg-neutral-300",inactive:"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100"}};const contentColorStyles={default:{active:"text-neutral-1300 dark:text-neutral-000",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"},subtle:{active:"text-neutral-1300 dark:text-neutral-000",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"},strong:{active:"text-neutral-000 dark:text-neutral-1300",inactive:"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000"}};const sizeStyles={md:cn("h-12 p-3 gap-2.5",rounded&&"px-[1.125rem]"),sm:cn("h-10 p-[0.5625rem] gap-[0.5625rem]",rounded&&"px-3.5"),xs:cn("h-9 p-2 gap-2",rounded&&"px-3")};const textStyles={md:"ui-text-label2",sm:"ui-text-label3",xs:"ui-text-label4"};const iconSizes={md:"23px",sm:"22px",xs:"20px"};const activeKey=active?"active":"inactive";return React.createElement("div",{onClick:!disabled?onClick:undefined,onKeyDown:e=>{if((e.key==="Enter"||e.key===" ")&&!disabled&&onClick){e.preventDefault();onClick()}},className:cn("focus-base flex items-center justify-center cursor-pointer select-none transition-colors",colorStyles[variant][activeKey],contentColorStyles[variant][activeKey],sizeStyles[size],textStyles[size],disabled&&"cursor-not-allowed hover:bg-inherit dark:hover:bg-inherit active:bg-inherit dark:active:bg-inherit",rounded?"rounded-full":"rounded-lg",className),tabIndex:disabled?-1:0,role:"button","aria-pressed":active,"aria-disabled":disabled},leftIcon&&React.createElement(Icon,{name:leftIcon,size:iconSizes[size],"aria-hidden":"true",color:contentColorStyles[variant][activeKey]}),children&&React.createElement("span",{className:cn("font-semibold transition-colors",contentColorStyles[variant][activeKey],disabled&&"text-gui-disabled-light dark:text-gui-disabled-dark hover:text-gui-disabled-light dark:hover:text-gui-disabled-dark")},children),rightIcon&&React.createElement(Icon,{name:rightIcon,size:iconSizes[size],"aria-hidden":"true",color:contentColorStyles[variant][activeKey]}))};export default SegmentedControl;
|
|
2
2
|
//# sourceMappingURL=SegmentedControl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/SegmentedControl.tsx"],"sourcesContent":["import React, { PropsWithChildren } from \"react\";\nimport cn from \"./utils/cn\";\nimport Icon from \"./Icon\";\nimport type { IconName, IconSize } from \"./Icon/types\";\n\nexport type SegmentedControlSize = \"md\" | \"sm\" | \"xs\";\n\nexport type SegmentedControlProps = {\n className?: string;\n rounded?: boolean;\n leftIcon?: IconName;\n rightIcon?: IconName;\n active?: boolean;\n variant?: \"default\" | \"subtle\" | \"strong\";\n size?: SegmentedControlSize;\n onClick?: () => void;\n disabled?: boolean;\n};\n\nconst SegmentedControl: React.FC<PropsWithChildren<SegmentedControlProps>> = ({\n className,\n rounded = false,\n leftIcon,\n rightIcon,\n active = false,\n variant = \"default\",\n size = \"md\",\n children,\n onClick,\n disabled,\n}) => {\n const colorStyles = {\n default: {\n active: \"bg-neutral-200 dark:bg-neutral-1100\",\n inactive:\n \"bg-neutral-000 dark:bg-neutral-1300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-100 dark:active:bg-neutral-1200\",\n },\n subtle: {\n active: \"bg-neutral-000 dark:bg-neutral-1000\",\n inactive:\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100\",\n },\n strong: {\n active: \"bg-neutral-1000 dark:bg-neutral-300\",\n inactive:\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100\",\n },\n };\n\n const contentColorStyles = {\n default: {\n active: \"text-neutral-1300 dark:text-neutral-000\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n subtle: {\n active: \"text-neutral-1300 dark:text-neutral-000\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n strong: {\n active: \"text-neutral-000 dark:text-neutral-1300\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n };\n\n const sizeStyles = {\n md: cn(\"h-12 p-3 gap-2.5\", rounded && \"px-[1.125rem]\"),\n sm: cn(\"h-10 p-[0.5625rem] gap-[0.5625rem]\", rounded && \"px-3.5\"),\n xs: cn(\"h-9 p-2 gap-2\", rounded && \"px-3\"),\n };\n\n const textStyles = {\n md: \"ui-text-label2\",\n sm: \"ui-text-label3\",\n xs: \"ui-text-label4\",\n };\n\n const iconSizes: Record<SegmentedControlSize, IconSize> = {\n md: \"23px\",\n sm: \"22px\",\n xs: \"20px\",\n };\n\n const activeKey = active ? \"active\" : \"inactive\";\n\n return (\n <div\n onClick={!disabled ? onClick : undefined}\n onKeyDown={(e) => {\n if ((e.key === \"Enter\" || e.key === \" \") && !disabled && onClick) {\n e.preventDefault();\n onClick();\n }\n }}\n className={cn(\n \"focus-base flex items-center justify-center cursor-pointer select-none transition-colors\",\n colorStyles[variant][activeKey],\n contentColorStyles[variant][activeKey],\n sizeStyles[size],\n textStyles[size],\n disabled &&\n \"cursor-not-allowed hover:bg-inherit dark:hover:bg-inherit active:bg-inherit dark:active:bg-inherit\",\n rounded ? \"rounded-full\" : \"rounded-lg\",\n className,\n )}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-pressed={active}\n aria-disabled={disabled}\n >\n {leftIcon && (\n <Icon
|
|
1
|
+
{"version":3,"sources":["../../src/core/SegmentedControl.tsx"],"sourcesContent":["import React, { PropsWithChildren } from \"react\";\nimport cn from \"./utils/cn\";\nimport Icon from \"./Icon\";\nimport type { IconName, IconSize } from \"./Icon/types\";\nimport { ColorClass } from \"./styles/colors/types\";\n\nexport type SegmentedControlSize = \"md\" | \"sm\" | \"xs\";\n\nexport type SegmentedControlProps = {\n className?: string;\n rounded?: boolean;\n leftIcon?: IconName;\n rightIcon?: IconName;\n active?: boolean;\n variant?: \"default\" | \"subtle\" | \"strong\";\n size?: SegmentedControlSize;\n onClick?: () => void;\n disabled?: boolean;\n};\n\nconst SegmentedControl: React.FC<PropsWithChildren<SegmentedControlProps>> = ({\n className,\n rounded = false,\n leftIcon,\n rightIcon,\n active = false,\n variant = \"default\",\n size = \"md\",\n children,\n onClick,\n disabled,\n}) => {\n const colorStyles = {\n default: {\n active: \"bg-neutral-200 dark:bg-neutral-1100\",\n inactive:\n \"bg-neutral-000 dark:bg-neutral-1300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-100 dark:active:bg-neutral-1200\",\n },\n subtle: {\n active: \"bg-neutral-000 dark:bg-neutral-1000\",\n inactive:\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100\",\n },\n strong: {\n active: \"bg-neutral-1000 dark:bg-neutral-300\",\n inactive:\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-200 dark:active:bg-neutral-1100\",\n },\n };\n\n const contentColorStyles = {\n default: {\n active: \"text-neutral-1300 dark:text-neutral-000\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n subtle: {\n active: \"text-neutral-1300 dark:text-neutral-000\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n strong: {\n active: \"text-neutral-000 dark:text-neutral-1300\",\n inactive:\n \"text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000\",\n },\n };\n\n const sizeStyles = {\n md: cn(\"h-12 p-3 gap-2.5\", rounded && \"px-[1.125rem]\"),\n sm: cn(\"h-10 p-[0.5625rem] gap-[0.5625rem]\", rounded && \"px-3.5\"),\n xs: cn(\"h-9 p-2 gap-2\", rounded && \"px-3\"),\n };\n\n const textStyles = {\n md: \"ui-text-label2\",\n sm: \"ui-text-label3\",\n xs: \"ui-text-label4\",\n };\n\n const iconSizes: Record<SegmentedControlSize, IconSize> = {\n md: \"23px\",\n sm: \"22px\",\n xs: \"20px\",\n };\n\n const activeKey = active ? \"active\" : \"inactive\";\n\n return (\n <div\n onClick={!disabled ? onClick : undefined}\n onKeyDown={(e) => {\n if ((e.key === \"Enter\" || e.key === \" \") && !disabled && onClick) {\n e.preventDefault();\n onClick();\n }\n }}\n className={cn(\n \"focus-base flex items-center justify-center cursor-pointer select-none transition-colors\",\n colorStyles[variant][activeKey],\n contentColorStyles[variant][activeKey],\n sizeStyles[size],\n textStyles[size],\n disabled &&\n \"cursor-not-allowed hover:bg-inherit dark:hover:bg-inherit active:bg-inherit dark:active:bg-inherit\",\n rounded ? \"rounded-full\" : \"rounded-lg\",\n className,\n )}\n tabIndex={disabled ? -1 : 0}\n role=\"button\"\n aria-pressed={active}\n aria-disabled={disabled}\n >\n {leftIcon && (\n <Icon\n name={leftIcon}\n size={iconSizes[size]}\n aria-hidden=\"true\"\n color={contentColorStyles[variant][activeKey] as ColorClass}\n />\n )}\n {children && (\n <span\n className={cn(\n \"font-semibold transition-colors\",\n contentColorStyles[variant][activeKey],\n disabled &&\n \"text-gui-disabled-light dark:text-gui-disabled-dark hover:text-gui-disabled-light dark:hover:text-gui-disabled-dark\",\n )}\n >\n {children}\n </span>\n )}\n {rightIcon && (\n <Icon\n name={rightIcon}\n size={iconSizes[size]}\n aria-hidden=\"true\"\n color={contentColorStyles[variant][activeKey] as ColorClass}\n />\n )}\n </div>\n );\n};\n\nexport default SegmentedControl;\n"],"names":["React","cn","Icon","SegmentedControl","className","rounded","leftIcon","rightIcon","active","variant","size","children","onClick","disabled","colorStyles","default","inactive","subtle","strong","contentColorStyles","sizeStyles","md","sm","xs","textStyles","iconSizes","activeKey","div","undefined","onKeyDown","e","key","preventDefault","tabIndex","role","aria-pressed","aria-disabled","name","aria-hidden","color","span"],"mappings":"AAAA,OAAOA,UAAkC,OAAQ,AACjD,QAAOC,OAAQ,YAAa,AAC5B,QAAOC,SAAU,QAAS,CAkB1B,MAAMC,iBAAuE,CAAC,CAC5EC,SAAS,CACTC,QAAU,KAAK,CACfC,QAAQ,CACRC,SAAS,CACTC,OAAS,KAAK,CACdC,QAAU,SAAS,CACnBC,KAAO,IAAI,CACXC,QAAQ,CACRC,OAAO,CACPC,QAAQ,CACT,IACC,MAAMC,YAAc,CAClBC,QAAS,CACPP,OAAQ,sCACRQ,SACE,uIACJ,EACAC,OAAQ,CACNT,OAAQ,sCACRQ,SACE,uIACJ,EACAE,OAAQ,CACNV,OAAQ,sCACRQ,SACE,uIACJ,CACF,EAEA,MAAMG,mBAAqB,CACzBJ,QAAS,CACPP,OAAQ,0CACRQ,SACE,6FACJ,EACAC,OAAQ,CACNT,OAAQ,0CACRQ,SACE,6FACJ,EACAE,OAAQ,CACNV,OAAQ,0CACRQ,SACE,6FACJ,CACF,EAEA,MAAMI,WAAa,CACjBC,GAAIpB,GAAG,mBAAoBI,SAAW,iBACtCiB,GAAIrB,GAAG,qCAAsCI,SAAW,UACxDkB,GAAItB,GAAG,gBAAiBI,SAAW,OACrC,EAEA,MAAMmB,WAAa,CACjBH,GAAI,iBACJC,GAAI,iBACJC,GAAI,gBACN,EAEA,MAAME,UAAoD,CACxDJ,GAAI,OACJC,GAAI,OACJC,GAAI,MACN,EAEA,MAAMG,UAAYlB,OAAS,SAAW,WAEtC,OACE,oBAACmB,OACCf,QAAS,CAACC,SAAWD,QAAUgB,UAC/BC,UAAW,AAACC,IACV,GAAI,AAACA,CAAAA,EAAEC,GAAG,GAAK,SAAWD,EAAEC,GAAG,GAAK,GAAE,GAAM,CAAClB,UAAYD,QAAS,CAChEkB,EAAEE,cAAc,GAChBpB,SACF,CACF,EACAR,UAAWH,GACT,2FACAa,WAAW,CAACL,QAAQ,CAACiB,UAAU,CAC/BP,kBAAkB,CAACV,QAAQ,CAACiB,UAAU,CACtCN,UAAU,CAACV,KAAK,CAChBc,UAAU,CAACd,KAAK,CAChBG,UACE,qGACFR,QAAU,eAAiB,aAC3BD,WAEF6B,SAAUpB,SAAW,CAAC,EAAI,EAC1BqB,KAAK,SACLC,eAAc3B,OACd4B,gBAAevB,UAEdP,UACC,oBAACJ,MACCmC,KAAM/B,SACNI,KAAMe,SAAS,CAACf,KAAK,CACrB4B,cAAY,OACZC,MAAOpB,kBAAkB,CAACV,QAAQ,CAACiB,UAAU,GAGhDf,UACC,oBAAC6B,QACCpC,UAAWH,GACT,kCACAkB,kBAAkB,CAACV,QAAQ,CAACiB,UAAU,CACtCb,UACE,wHAGHF,UAGJJ,WACC,oBAACL,MACCmC,KAAM9B,UACNG,KAAMe,SAAS,CAACf,KAAK,CACrB4B,cAAY,OACZC,MAAOpB,kBAAkB,CAACV,QAAQ,CAACiB,UAAU,GAKvD,CAEA,gBAAevB,gBAAiB"}
|
package/core/Slider/component.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import{throttle}from"es-toolkit/compat";import{queryId,queryIdAll}from"../dom-query";const mdBreakpoint=()=>window.matchMedia("(min-width: 48rem)").matches;const DRAG_BUFFER=20;const init=slidesContainer=>{const transformContainer=queryId("slider-strip",slidesContainer);const slides=Array.from(queryIdAll("slider-slide",slidesContainer));const slideLeftChevron=queryId("slider-previous",slidesContainer);const slideRightChevron=queryId("slider-next",slidesContainer);const slideMarkers=Array.from(queryIdAll("slider-marker",slidesContainer));const sliderControls=queryId("slider-controls",slidesContainer);sliderControls.classList.replace("hidden","flex");const slidesLength=slides.length;const slidesWidth=slidesContainer.getBoundingClientRect().width;const{width:slideWidth,left:slideLeftDistance}=slides[0].getBoundingClientRect();const{left:slideLeftDistanceSecond}=slides[1].getBoundingClientRect();const slideGap=slideLeftDistanceSecond-slideLeftDistance-slideWidth;const adjustment=(slidesWidth-slideWidth)/2;let currentIndex=0;let touchStartX=0;const calculateTransform=index=>index*-slideWidth+adjustment+index*-slideGap;const updateSlide=index=>transformContainer.style.transform=`translateX(${calculateTransform(index)}px)`;const updateMarkers=index=>{slideMarkers.forEach(marker=>marker.classList.remove("text-active-orange"));slideMarkers[index].classList.remove("text-cool-black");slideMarkers[index].classList.add("text-active-orange")};const slideLeft=()=>{currentIndex=currentIndex-1<=0?0:currentIndex-1;updateSlide(currentIndex);updateMarkers(currentIndex)};const slideRight=()=>{currentIndex=currentIndex+1>=slidesLength?currentIndex:currentIndex+1;updateSlide(currentIndex);updateMarkers(currentIndex)};updateSlide(0);updateMarkers(0);slideLeftChevron.addEventListener("click",slideLeft);transformContainer.addEventListener("touchstart",e=>{touchStartX=e.touches[0]?.clientX});transformContainer.addEventListener("touchend",e=>{const distance=e.changedTouches[0]?.clientX-touchStartX;if(Math.abs(distance)<DRAG_BUFFER)return;const direction=distance>0?slideLeft:slideRight;direction()});slideRightChevron.addEventListener("click",slideRight);return()=>{transformContainer.style.transform=null;sliderControls.classList.replace("flex","hidden")}};const Slider=({container,mqEnableThreshold})=>{if(!container)return;const breakpointCheck=mqEnableThreshold||(()=>!mdBreakpoint());let unmount=()=>{};if(breakpointCheck())unmount=init(container);window.addEventListener("resize",throttle(()=>{if(breakpointCheck()){unmount=init(container)}else{unmount()}},100))};export default Slider;
|
|
2
2
|
//# sourceMappingURL=component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Slider/component.js"],"sourcesContent":["import throttle from \"
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Slider/component.js"],"sourcesContent":["import { throttle } from \"es-toolkit/compat\";\n\nimport { queryId, queryIdAll } from \"../dom-query\";\n\nconst mdBreakpoint = () => window.matchMedia(\"(min-width: 48rem)\").matches;\nconst DRAG_BUFFER = 20;\n\nconst init = (slidesContainer) => {\n const transformContainer = queryId(\"slider-strip\", slidesContainer);\n const slides = Array.from(queryIdAll(\"slider-slide\", slidesContainer));\n const slideLeftChevron = queryId(\"slider-previous\", slidesContainer);\n const slideRightChevron = queryId(\"slider-next\", slidesContainer);\n const slideMarkers = Array.from(queryIdAll(\"slider-marker\", slidesContainer));\n const sliderControls = queryId(\"slider-controls\", slidesContainer);\n\n sliderControls.classList.replace(\"hidden\", \"flex\");\n const slidesLength = slides.length;\n\n const slidesWidth = slidesContainer.getBoundingClientRect().width;\n const { width: slideWidth, left: slideLeftDistance } =\n slides[0].getBoundingClientRect();\n const { left: slideLeftDistanceSecond } = slides[1].getBoundingClientRect();\n const slideGap = slideLeftDistanceSecond - slideLeftDistance - slideWidth;\n const adjustment = (slidesWidth - slideWidth) / 2;\n\n let currentIndex = 0;\n let touchStartX = 0;\n\n const calculateTransform = (index) =>\n index * -slideWidth + adjustment + index * -slideGap;\n\n const updateSlide = (index) =>\n (transformContainer.style.transform = `translateX(${calculateTransform(\n index,\n )}px)`);\n\n const updateMarkers = (index) => {\n slideMarkers.forEach((marker) =>\n marker.classList.remove(\"text-active-orange\"),\n );\n slideMarkers[index].classList.remove(\"text-cool-black\");\n slideMarkers[index].classList.add(\"text-active-orange\");\n };\n\n const slideLeft = () => {\n currentIndex = currentIndex - 1 <= 0 ? 0 : currentIndex - 1;\n updateSlide(currentIndex);\n updateMarkers(currentIndex);\n };\n\n const slideRight = () => {\n currentIndex =\n currentIndex + 1 >= slidesLength ? currentIndex : currentIndex + 1;\n updateSlide(currentIndex);\n updateMarkers(currentIndex);\n };\n\n updateSlide(0);\n updateMarkers(0);\n\n slideLeftChevron.addEventListener(\"click\", slideLeft);\n\n transformContainer.addEventListener(\"touchstart\", (e) => {\n touchStartX = e.touches[0]?.clientX;\n });\n\n transformContainer.addEventListener(\"touchend\", (e) => {\n const distance = e.changedTouches[0]?.clientX - touchStartX;\n\n // Prevent sliding on clicks\n if (Math.abs(distance) < DRAG_BUFFER) return;\n\n const direction = distance > 0 ? slideLeft : slideRight;\n direction();\n });\n\n slideRightChevron.addEventListener(\"click\", slideRight);\n\n return () => {\n transformContainer.style.transform = null;\n sliderControls.classList.replace(\"flex\", \"hidden\");\n };\n};\n\nconst Slider = ({ container, mqEnableThreshold }) => {\n if (!container) return;\n\n const breakpointCheck = mqEnableThreshold || (() => !mdBreakpoint());\n\n let unmount = () => {};\n if (breakpointCheck()) unmount = init(container);\n\n window.addEventListener(\n \"resize\",\n throttle(() => {\n if (breakpointCheck()) {\n unmount = init(container);\n } else {\n unmount();\n }\n }, 100),\n );\n};\n\nexport default Slider;\n"],"names":["throttle","queryId","queryIdAll","mdBreakpoint","window","matchMedia","matches","DRAG_BUFFER","init","slidesContainer","transformContainer","slides","Array","from","slideLeftChevron","slideRightChevron","slideMarkers","sliderControls","classList","replace","slidesLength","length","slidesWidth","getBoundingClientRect","width","slideWidth","left","slideLeftDistance","slideLeftDistanceSecond","slideGap","adjustment","currentIndex","touchStartX","calculateTransform","index","updateSlide","style","transform","updateMarkers","forEach","marker","remove","add","slideLeft","slideRight","addEventListener","e","touches","clientX","distance","changedTouches","Math","abs","direction","Slider","container","mqEnableThreshold","breakpointCheck","unmount"],"mappings":"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"}
|
package/core/Slider.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{
|
|
1
|
+
import React,{useCallback,useEffect,useState}from"react";import useEmblaCarousel from"embla-carousel-react";import Autoplay from"embla-carousel-autoplay";import Icon from"./Icon";import cn from"./utils/cn";const SlideIndicator=({numSlides,activeIndex,interval,intervalIndicator,isInline})=>{return React.createElement("ul",{className:cn("flex gap-1 left-1/2",isInline?"bottom-0":"absolute bottom-0 transform -translate-x-1/2")},Array.from({length:numSlides},(_,i)=>intervalIndicator?React.createElement("li",{key:i,className:"relative w-10 h-1 mx-px rounded-full bg-neutral-500"},i===activeIndex&&React.createElement("span",{className:"absolute inset-0 rounded-full bg-active-orange",style:{animation:`fillAnimation ${interval}ms linear`}})):React.createElement("li",{key:i},React.createElement("span",{className:cn("ui-slider-marker",i===activeIndex?"text-active-orange":"text-cool-black"),"data-id":"slider-marker"},"⬤"))))};const Slider=({children,options})=>{const[activeIndex,setActiveIndex]=useState(0);const interval=options?.interval??1e4;const isInline=options?.controlPosition==="inline";const[emblaRef,emblaApi]=useEmblaCarousel({loop:true,duration:30},[Autoplay({delay:interval,stopOnInteraction:false})]);const scrollPrev=useCallback(()=>{if(emblaApi)emblaApi.scrollPrev()},[emblaApi]);const scrollNext=useCallback(()=>{if(emblaApi)emblaApi.scrollNext()},[emblaApi]);const onSelect=useCallback(emblaApi=>{setActiveIndex(emblaApi.selectedScrollSnap())},[]);useEffect(()=>{if(!emblaApi)return;onSelect(emblaApi);emblaApi.on("select",onSelect).on("reInit",onSelect);return()=>{emblaApi.off("select",onSelect).off("reInit",onSelect)}},[emblaApi,onSelect]);return React.createElement("div",{className:"relative"},React.createElement("div",{className:"overflow-hidden w-full py-10",ref:emblaRef},React.createElement("div",{className:"flex"},children.map((child,index)=>React.createElement("div",{key:index,className:"w-full flex-shrink-0 flex justify-center sm:px-[3.75rem]"},child)))),React.createElement("div",{className:cn("flex items-center pointer-events-none",isInline?"ui-standard-container justify-center gap-6 -mt-4":"sm:flex sm:absolute inset-0 justify-between")},React.createElement("button",{className:cn(isInline?"w-8 h-8":"hidden sm:flex w-12 h-12","pointer-events-auto rounded border border-mid-grey hover:border-active-orange flex justify-center items-center ui-icon-cta ui-icon-cta-left"),onClick:scrollPrev},React.createElement("div",{className:"ui-icon-cta-holder flex w-12"},React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-left-outline",size:"1.5rem"})),React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-left-outline",size:"1.5rem"})))),React.createElement(SlideIndicator,{numSlides:children.length,activeIndex:activeIndex,interval:interval,intervalIndicator:options?.intervalIndicator,isInline:isInline}),React.createElement("button",{className:cn(isInline?"w-8 h-8":"hidden sm:flex w-12 h-12","pointer-events-auto rounded border border-mid-grey hover:border-active-orange justify-center items-center ui-icon-cta ui-icon-cta-right"),onClick:scrollNext},React.createElement("div",{className:cn("ui-icon-cta-holder flex w-12",isInline?"-ml-3.5":"")},React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:"1.5rem"})),React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:"1.5rem"}))))))};export default Slider;
|
|
2
2
|
//# sourceMappingURL=Slider.js.map
|
package/core/Slider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Slider.tsx"],"sourcesContent":["import React, {\n useState,\n useEffect,\n useRef,\n ReactNode,\n TouchEvent,\n} from \"react\";\nimport Icon from \"./Icon\";\n\ninterface SliderProps {\n children: ReactNode[];\n options?: {\n interval?: number;\n controlPosition?: \"inline\" | \"floating\";\n intervalIndicator?: boolean;\n };\n}\n\ninterface SliderIndicatorProps {\n numSlides: number;\n activeIndex: number;\n interval: number;\n intervalIndicator?: boolean;\n isInline?: boolean;\n}\n\nconst SLIDE_TRANSITION_LENGTH = 300;\n\nconst SlideIndicator = ({\n numSlides,\n activeIndex,\n interval,\n intervalIndicator,\n isInline,\n}: SliderIndicatorProps) => {\n return (\n <ul\n className={`flex gap-1 left-1/2 ${\n isInline ? \"bottom-0\" : \"absolute bottom-0 transform -translate-x-1/2\"\n }`}\n >\n {Array.from({ length: numSlides }, (_, i) =>\n intervalIndicator ? (\n <li\n key={i}\n className=\"relative w-10 h-1 mx-px rounded-full bg-neutral-500\"\n >\n {i === activeIndex && (\n <span\n className=\"absolute inset-0 rounded-full bg-active-orange\"\n style={{\n animation: `fillAnimation ${interval}ms linear`,\n }}\n ></span>\n )}\n </li>\n ) : (\n <li key={i}>\n <span\n className={`ui-slider-marker ${\n i === activeIndex ? \"text-active-orange\" : \"text-cool-black\"\n }`}\n data-id=\"slider-marker\"\n >\n ⬤\n </span>\n </li>\n ),\n )}\n </ul>\n );\n};\n\nconst setupSlides = (children: ReactNode[], activeIndex: number) => [\n children[activeIndex === 0 ? children.length - 1 : activeIndex - 1],\n children[activeIndex],\n children[activeIndex === children.length - 1 ? 0 : activeIndex + 1],\n];\n\nconst Slider = ({ children, options }: SliderProps) => {\n const [activeIndex, setActiveIndex] = useState(0);\n const [touchStartX, setTouchStartX] = useState(0);\n const [touchEndX, setTouchEndX] = useState(0);\n const [slides, setSlides] = useState<ReactNode[]>(\n setupSlides(children, activeIndex),\n );\n const [translationCoefficient, setTranslationCoefficient] = useState(0);\n const timerRef = useRef<NodeJS.Timeout | null>(null);\n const [slideLock, setSlideLock] = useState(false);\n\n const isInline = options?.controlPosition === \"inline\";\n\n const next = () => {\n if (!slideLock) {\n setActiveIndex((prevIndex) => (prevIndex + 1) % children.length);\n setTranslationCoefficient(1);\n resetInterval();\n setSlideLock(true);\n }\n };\n\n const prev = () => {\n if (!slideLock) {\n setActiveIndex((prevIndex) =>\n prevIndex > 0 ? prevIndex - 1 : children.length - 1,\n );\n setTranslationCoefficient(-1);\n resetInterval();\n setSlideLock(true);\n }\n };\n\n const resetInterval = () => {\n if (timerRef.current) clearInterval(timerRef.current);\n timerRef.current = setInterval(next, options?.interval ?? 10000);\n };\n\n const handleTouchStart = (e: TouchEvent) => {\n setTouchStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: TouchEvent) => {\n setTouchEndX(e.touches[0].clientX);\n };\n\n const handleTouchEnd = () => {\n if (touchStartX - touchEndX > 50) {\n next();\n }\n if (touchStartX - touchEndX < -50) {\n prev();\n }\n };\n\n useEffect(() => {\n resetInterval();\n return () => {\n if (timerRef.current) clearInterval(timerRef.current);\n };\n }, [children.length, options?.interval]);\n\n useEffect(() => {\n setTimeout(() => {\n setSlides(setupSlides(children, activeIndex));\n setTranslationCoefficient(0);\n setSlideLock(false);\n }, SLIDE_TRANSITION_LENGTH);\n }, [activeIndex]);\n\n return (\n <div\n className=\"relative\"\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n <div className=\"overflow-y-visible overflow-x-clip w-full py-10\">\n <div\n className={`flex items-center ${\n translationCoefficient !== 0\n ? `transition-transform ease-in-out duration-${SLIDE_TRANSITION_LENGTH}`\n : \"\"\n } `}\n style={{\n transform: `translateX(-${(translationCoefficient + 1) * 100}%)`,\n }}\n >\n {slides.map((child, index) => (\n <div\n key={index}\n className=\"w-full flex-shrink-0 flex justify-center sm:px-[3.75rem]\"\n >\n {child}\n </div>\n ))}\n </div>\n </div>\n\n <div\n className={`flex items-center pointer-events-none ${\n isInline\n ? \"ui-standard-container justify-center gap-6 -mt-4\"\n : \"sm:flex sm:absolute inset-0 justify-between\"\n }`}\n >\n <button\n className={`${\n isInline ? \"w-8 h-8\" : \"hidden sm:flex w-12 h-12\"\n } pointer-events-auto rounded border border-mid-grey hover:border-active-orange flex justify-center items-center ui-icon-cta ui-icon-cta-left`}\n onClick={prev}\n >\n <div className=\"ui-icon-cta-holder flex w-12\">\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-left-outline\" size=\"1.5rem\" />\n </div>\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-left-outline\" size=\"1.5rem\" />\n </div>\n </div>\n </button>\n\n <SlideIndicator\n numSlides={children.length}\n activeIndex={activeIndex}\n interval={options?.interval ?? 10000}\n intervalIndicator={options?.intervalIndicator}\n isInline={isInline}\n />\n\n <button\n className={`${\n isInline ? \"w-8 h-8\" : \"hidden sm:flex w-12 h-12\"\n } pointer-events-auto rounded border border-mid-grey hover:border-active-orange justify-center items-center ui-icon-cta ui-icon-cta-right`}\n onClick={next}\n >\n <div className=\"ui-icon-cta-holder flex w-12\">\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-right-outline\" size=\"1.5rem\" />\n </div>\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-right-outline\" size=\"1.5rem\" />\n </div>\n </div>\n </button>\n </div>\n </div>\n );\n};\n\nexport default Slider;\n"],"names":["React","useState","useEffect","useRef","Icon","SLIDE_TRANSITION_LENGTH","SlideIndicator","numSlides","activeIndex","interval","intervalIndicator","isInline","ul","className","Array","from","length","_","i","li","key","span","style","animation","data-id","setupSlides","children","Slider","options","setActiveIndex","touchStartX","setTouchStartX","touchEndX","setTouchEndX","slides","setSlides","translationCoefficient","setTranslationCoefficient","timerRef","slideLock","setSlideLock","controlPosition","next","prevIndex","resetInterval","prev","current","clearInterval","setInterval","handleTouchStart","e","touches","clientX","handleTouchMove","handleTouchEnd","setTimeout","div","onTouchStart","onTouchMove","onTouchEnd","transform","map","child","index","button","onClick","name","size"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/Slider.tsx"],"sourcesContent":["import React, { ReactNode, useCallback, useEffect, useState } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport Autoplay from \"embla-carousel-autoplay\";\nimport type { EmblaCarouselType } from \"embla-carousel\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\n\ninterface SliderProps {\n children: ReactNode[];\n options?: {\n interval?: number;\n controlPosition?: \"inline\" | \"floating\";\n intervalIndicator?: boolean;\n };\n}\n\ninterface SliderIndicatorProps {\n numSlides: number;\n activeIndex: number;\n interval: number;\n intervalIndicator?: boolean;\n isInline?: boolean;\n}\n\nconst SlideIndicator = ({\n numSlides,\n activeIndex,\n interval,\n intervalIndicator,\n isInline,\n}: SliderIndicatorProps) => {\n return (\n <ul\n className={cn(\n \"flex gap-1 left-1/2\",\n isInline ? \"bottom-0\" : \"absolute bottom-0 transform -translate-x-1/2\",\n )}\n >\n {Array.from({ length: numSlides }, (_, i) =>\n intervalIndicator ? (\n <li\n key={i}\n className=\"relative w-10 h-1 mx-px rounded-full bg-neutral-500\"\n >\n {i === activeIndex && (\n <span\n className=\"absolute inset-0 rounded-full bg-active-orange\"\n style={{\n animation: `fillAnimation ${interval}ms linear`,\n }}\n ></span>\n )}\n </li>\n ) : (\n <li key={i}>\n <span\n className={cn(\n \"ui-slider-marker\",\n i === activeIndex ? \"text-active-orange\" : \"text-cool-black\",\n )}\n data-id=\"slider-marker\"\n >\n ⬤\n </span>\n </li>\n ),\n )}\n </ul>\n );\n};\n\nconst Slider = ({ children, options }: SliderProps) => {\n const [activeIndex, setActiveIndex] = useState(0);\n const interval = options?.interval ?? 10000;\n const isInline = options?.controlPosition === \"inline\";\n\n const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true, duration: 30 }, [\n Autoplay({ delay: interval, stopOnInteraction: false }),\n ]);\n\n const scrollPrev = useCallback(() => {\n if (emblaApi) emblaApi.scrollPrev();\n }, [emblaApi]);\n\n const scrollNext = useCallback(() => {\n if (emblaApi) emblaApi.scrollNext();\n }, [emblaApi]);\n\n const onSelect = useCallback((emblaApi: EmblaCarouselType) => {\n setActiveIndex(emblaApi.selectedScrollSnap());\n }, []);\n\n useEffect(() => {\n if (!emblaApi) return;\n\n onSelect(emblaApi);\n emblaApi.on(\"select\", onSelect).on(\"reInit\", onSelect);\n\n return () => {\n emblaApi.off(\"select\", onSelect).off(\"reInit\", onSelect);\n };\n }, [emblaApi, onSelect]);\n\n return (\n <div className=\"relative\">\n <div className=\"overflow-hidden w-full py-10\" ref={emblaRef}>\n <div className=\"flex\">\n {children.map((child, index) => (\n <div\n key={index}\n className=\"w-full flex-shrink-0 flex justify-center sm:px-[3.75rem]\"\n >\n {child}\n </div>\n ))}\n </div>\n </div>\n\n <div\n className={cn(\n \"flex items-center pointer-events-none\",\n isInline\n ? \"ui-standard-container justify-center gap-6 -mt-4\"\n : \"sm:flex sm:absolute inset-0 justify-between\",\n )}\n >\n <button\n className={cn(\n isInline ? \"w-8 h-8\" : \"hidden sm:flex w-12 h-12\",\n \"pointer-events-auto rounded border border-mid-grey hover:border-active-orange flex justify-center items-center ui-icon-cta ui-icon-cta-left\",\n )}\n onClick={scrollPrev}\n >\n <div className=\"ui-icon-cta-holder flex w-12\">\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-left-outline\" size=\"1.5rem\" />\n </div>\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-left-outline\" size=\"1.5rem\" />\n </div>\n </div>\n </button>\n\n <SlideIndicator\n numSlides={children.length}\n activeIndex={activeIndex}\n interval={interval}\n intervalIndicator={options?.intervalIndicator}\n isInline={isInline}\n />\n\n <button\n className={cn(\n isInline ? \"w-8 h-8\" : \"hidden sm:flex w-12 h-12\",\n \"pointer-events-auto rounded border border-mid-grey hover:border-active-orange justify-center items-center ui-icon-cta ui-icon-cta-right\",\n )}\n onClick={scrollNext}\n >\n <div\n className={cn(\n \"ui-icon-cta-holder flex w-12\",\n isInline ? \"-ml-3.5\" : \"\",\n )}\n >\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-right-outline\" size=\"1.5rem\" />\n </div>\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-right-outline\" size=\"1.5rem\" />\n </div>\n </div>\n </button>\n </div>\n </div>\n );\n};\n\nexport default Slider;\n"],"names":["React","useCallback","useEffect","useState","useEmblaCarousel","Autoplay","Icon","cn","SlideIndicator","numSlides","activeIndex","interval","intervalIndicator","isInline","ul","className","Array","from","length","_","i","li","key","span","style","animation","data-id","Slider","children","options","setActiveIndex","controlPosition","emblaRef","emblaApi","loop","duration","delay","stopOnInteraction","scrollPrev","scrollNext","onSelect","selectedScrollSnap","on","off","div","ref","map","child","index","button","onClick","name","size"],"mappings":"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"}
|
package/core/TabMenu.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useEffect}from"react";import*as Tabs from"@radix-ui/react-tabs";import
|
|
1
|
+
import React,{useEffect}from"react";import*as Tabs from"@radix-ui/react-tabs";import{throttle}from"es-toolkit/compat";import cn from"./utils/cn";const DEFAULT_TAILWIND_ANIMATION_DURATION=150;const TabMenu=({tabs=[],contents=[],tabOnClick,tabClassName,rootClassName,contentClassName,options})=>{const{defaultTabIndex=0,underline=true,animated:animatedOption=true,flexibleTabWidth=false,flexibleTabHeight=false}=options??{};const listRef=React.useRef(null);const[animated,setAnimated]=React.useState(false);const[highlight,setHighlight]=React.useState({offset:0,width:0});useEffect(()=>{if(animatedOption&&highlight.width>0){setTimeout(()=>{setAnimated(true)},DEFAULT_TAILWIND_ANIMATION_DURATION)}},[animatedOption,highlight.width]);const updateHighlightDimensions=element=>{const{left:parentLeft}=listRef.current?.getBoundingClientRect()??{};const{left,width}=element.getBoundingClientRect()??{};setHighlight({offset:(left??0)-(parentLeft??0),width:width??0})};useEffect(()=>{const handleResize=throttle(()=>{const activeTabElement=listRef.current?.querySelector(`[data-state="active"]`);if(activeTabElement){updateHighlightDimensions(activeTabElement)}},100);handleResize();window.addEventListener("resize",handleResize);return()=>{window.removeEventListener("resize",handleResize)}},[]);const handleTabClick=(event,index)=>{tabOnClick?.(index);updateHighlightDimensions(event.currentTarget)};const tabTriggerContent=tab=>{if(!tab){return null}if(React.isValidElement(tab)||typeof tab==="string"){return tab}if(typeof tab==="object"&&"label"in tab){return tab.label}return null};return React.createElement(Tabs.Root,{defaultValue:`tab-${defaultTabIndex}`,className:cn({"h-full":flexibleTabHeight},rootClassName)},React.createElement(Tabs.List,{ref:listRef,className:cn("relative",{"flex border-b border-neutral-300 dark:border-neutral-1000":underline},{"h-full":flexibleTabHeight})},tabs.map((tab,index)=>tab&&React.createElement(Tabs.Trigger,{key:`tab-${index}`,className:cn("lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark disabled:cursor-not-allowed",{"flex-1":flexibleTabWidth},{"h-full":flexibleTabHeight},tabClassName),value:`tab-${index}`,onClick:event=>handleTabClick(event,index),disabled:typeof tab==="object"&&"disabled"in tab?tab.disabled:false},tabTriggerContent(tab))),React.createElement("div",{className:cn("absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6",{"transition-[transform,width]":animated}),style:{transform:`translateX(${highlight.offset}px)`,width:`${highlight.width}px`}})),contents.map((content,index)=>React.createElement(Tabs.Content,{key:`tab-${index}`,value:`tab-${index}`,className:contentClassName},content)))};export default TabMenu;
|
|
2
2
|
//# sourceMappingURL=TabMenu.js.map
|
package/core/TabMenu.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/TabMenu.tsx"],"sourcesContent":["import React, { ReactNode, useEffect } from \"react\";\nimport * as Tabs from \"@radix-ui/react-tabs\";\nimport throttle from \"
|
|
1
|
+
{"version":3,"sources":["../../src/core/TabMenu.tsx"],"sourcesContent":["import React, { ReactNode, useEffect } from \"react\";\nimport * as Tabs from \"@radix-ui/react-tabs\";\nimport { throttle } from \"es-toolkit/compat\";\nimport cn from \"./utils/cn\";\n\ntype TabTriggerContent =\n | string\n | { label: string; disabled?: boolean }\n | ReactNode;\n\n/**\n * Props for the TabMenu component.\n */\n\nexport type TabMenuProps = {\n /**\n * An array of tabs, which can be either a string or an object with a label and an optional disabled state.\n */\n tabs: TabTriggerContent[];\n\n /**\n * An optional array of React nodes representing the content for each tab.\n */\n contents?: ReactNode[];\n\n /**\n * An optional callback function that is called when a tab is clicked, receiving the index of the clicked tab.\n */\n tabOnClick?: (index: number) => void;\n\n /**\n * An optional class name to apply to each tab.\n */\n tabClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Root element.\n */\n rootClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Content element.\n */\n contentClassName?: string;\n\n /**\n * Optional configuration options for the TabMenu.\n */\n options?: {\n /**\n * The index of the tab that should be selected by default.\n */\n defaultTabIndex?: number;\n\n /**\n * Whether to show an underline below the selected tab.\n */\n underline?: boolean;\n\n /**\n * Whether to animate the transition between tabs.\n */\n animated?: boolean;\n\n /**\n * Whether the tab width should be flexible.\n */\n flexibleTabWidth?: boolean;\n\n /**\n * Whether the tab height should be flexible.\n */\n flexibleTabHeight?: boolean;\n };\n};\n\nconst DEFAULT_TAILWIND_ANIMATION_DURATION = 150;\n\nconst TabMenu: React.FC<TabMenuProps> = ({\n tabs = [],\n contents = [],\n tabOnClick,\n tabClassName,\n rootClassName,\n contentClassName,\n options,\n}) => {\n const {\n defaultTabIndex = 0,\n underline = true,\n animated: animatedOption = true,\n flexibleTabWidth = false,\n flexibleTabHeight = false,\n } = options ?? {};\n\n const listRef = React.useRef<HTMLDivElement>(null);\n const [animated, setAnimated] = React.useState(false);\n const [highlight, setHighlight] = React.useState({ offset: 0, width: 0 });\n\n useEffect(() => {\n if (animatedOption && highlight.width > 0) {\n setTimeout(() => {\n setAnimated(true);\n }, DEFAULT_TAILWIND_ANIMATION_DURATION);\n }\n }, [animatedOption, highlight.width]);\n\n const updateHighlightDimensions = (element: HTMLButtonElement) => {\n const { left: parentLeft } = listRef.current?.getBoundingClientRect() ?? {};\n const { left, width } = element.getBoundingClientRect() ?? {};\n\n setHighlight({\n offset: (left ?? 0) - (parentLeft ?? 0),\n width: width ?? 0,\n });\n };\n\n useEffect(() => {\n const handleResize = throttle(() => {\n const activeTabElement =\n listRef.current?.querySelector<HTMLButtonElement>(\n `[data-state=\"active\"]`,\n );\n\n if (activeTabElement) {\n updateHighlightDimensions(activeTabElement);\n }\n }, 100);\n\n handleResize();\n\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n const handleTabClick = (\n event: React.MouseEvent<HTMLButtonElement>,\n index: number,\n ) => {\n tabOnClick?.(index);\n updateHighlightDimensions(event.currentTarget as HTMLButtonElement);\n };\n\n const tabTriggerContent = (tab: TabTriggerContent) => {\n if (!tab) {\n return null;\n }\n\n if (React.isValidElement(tab) || typeof tab === \"string\") {\n return tab;\n }\n\n if (typeof tab === \"object\" && \"label\" in tab) {\n return tab.label;\n }\n\n return null;\n };\n\n return (\n <Tabs.Root\n defaultValue={`tab-${defaultTabIndex}`}\n className={cn({ \"h-full\": flexibleTabHeight }, rootClassName)}\n >\n <Tabs.List\n ref={listRef}\n className={cn(\n \"relative\",\n {\n \"flex border-b border-neutral-300 dark:border-neutral-1000\":\n underline,\n },\n { \"h-full\": flexibleTabHeight },\n )}\n >\n {tabs.map(\n (tab, index) =>\n tab && (\n <Tabs.Trigger\n key={`tab-${index}`}\n className={cn(\n \"lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark disabled:cursor-not-allowed\",\n { \"flex-1\": flexibleTabWidth },\n { \"h-full\": flexibleTabHeight },\n tabClassName,\n )}\n value={`tab-${index}`}\n onClick={(event) => handleTabClick(event, index)}\n disabled={\n typeof tab === \"object\" && \"disabled\" in tab\n ? tab.disabled\n : false\n }\n >\n {tabTriggerContent(tab)}\n </Tabs.Trigger>\n ),\n )}\n <div\n className={cn(\n \"absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6\",\n { \"transition-[transform,width]\": animated },\n )}\n style={{\n transform: `translateX(${highlight.offset}px)`,\n width: `${highlight.width}px`,\n }}\n ></div>\n </Tabs.List>\n {contents.map((content, index) => (\n <Tabs.Content\n key={`tab-${index}`}\n value={`tab-${index}`}\n className={contentClassName}\n >\n {content}\n </Tabs.Content>\n ))}\n </Tabs.Root>\n );\n};\n\nexport default TabMenu;\n"],"names":["React","useEffect","Tabs","throttle","cn","DEFAULT_TAILWIND_ANIMATION_DURATION","TabMenu","tabs","contents","tabOnClick","tabClassName","rootClassName","contentClassName","options","defaultTabIndex","underline","animated","animatedOption","flexibleTabWidth","flexibleTabHeight","listRef","useRef","setAnimated","useState","highlight","setHighlight","offset","width","setTimeout","updateHighlightDimensions","element","left","parentLeft","current","getBoundingClientRect","handleResize","activeTabElement","querySelector","window","addEventListener","removeEventListener","handleTabClick","event","index","currentTarget","tabTriggerContent","tab","isValidElement","label","Root","defaultValue","className","List","ref","map","Trigger","key","value","onClick","disabled","div","style","transform","content","Content"],"mappings":"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"}
|
package/core/Table/data.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{Fragment}from"react";import Tooltip from"../Tooltip";import Table from"../Table";import Icon from"../Icon";const Supported=()=>React.createElement(Icon,{name:"icon-gui-check-circle-solid",size:"1.5rem",color:"text-gui-success",additionalCSS:"flex-grow-0 flex-shrink-0","data-testid":"supported-icon"});const Unsupported=()=>React.createElement(Icon,{name:"icon-gui-x-circle-solid",size:"1.5rem",color:"text-gui-error",additionalCSS:"flex-grow-0 flex-shrink-0","data-testid":"unsupported-icon"});const testRow=index=>({label:`Label ${index+1}`,cells:[{label:"text",content:"Cell content",column:"Free"},{label:"yes",content:React.createElement("div",{className:"flex items-center sm:flex-col sm:items-start"},React.createElement("span",{className:"sm:order-1 px-1.5 sm:py-1.5 sm:px-0"},"Supported"),React.createElement("span",{className:"sm:order-0"},React.createElement(Supported,null))),column:"PAYG"},{label:"no",content:React.createElement("div",{className:"flex items-center sm:flex-col sm:items-start"},React.createElement("span",{className:"sm:order-1 px-1.5 sm:py-1.5 sm:px-0"},"Unsupported"),React.createElement("span",{className:"sm:order-0"},React.createElement(Unsupported,null))),column:"Custom"}]});const sections=["Features","Support","Technical Support"].map(label=>({label,rows:[...Array(5)].map((_,i)=>testRow(i))}));export const PricingPageTable=()=>{return React.createElement("div",{className:"ui-standard-container"},React.createElement("h2",{className:"ui-text-h2 text-center m-8"},"Pricing Page Table"),React.createElement("p",{className:"text-center m-8"},"Example content"),React.createElement(Table.Root,null,React.createElement(Table.Header,null,React.createElement(Table.Row,null,React.createElement(Table.Cell,null,React.createElement("span",{className:"ui-text-h3 hidden sm:block"},"Free")),React.createElement(Table.Cell,null,React.createElement("span",{className:"ui-text-h3 hidden sm:block"},"PAYG")),React.createElement(Table.Cell,null,React.createElement("span",{className:"ui-text-h3 hidden sm:block"},"Custom")))),React.createElement(Table.Body,null,sections.map(section=>React.createElement(Fragment,{key:section.label},React.createElement(Table.RowHeader,null,React.createElement(Table.Cell,{colSpan:4},section.label)),section.rows.map(row=>React.createElement(Table.Row,{key:row.label},React.createElement(Table.LabelCell,{key:row.label,className:"border-t border-light-grey"},React.createElement("a",{className:"ui-link"
|
|
1
|
+
import React,{Fragment}from"react";import Tooltip from"../Tooltip";import Table from"../Table";import Icon from"../Icon";const Supported=()=>React.createElement(Icon,{name:"icon-gui-check-circle-solid",size:"1.5rem",color:"text-gui-success",additionalCSS:"flex-grow-0 flex-shrink-0","data-testid":"supported-icon"});const Unsupported=()=>React.createElement(Icon,{name:"icon-gui-x-circle-solid",size:"1.5rem",color:"text-gui-error",additionalCSS:"flex-grow-0 flex-shrink-0","data-testid":"unsupported-icon"});const testRow=index=>({label:`Label ${index+1}`,cells:[{label:"text",content:"Cell content",column:"Free"},{label:"yes",content:React.createElement("div",{className:"flex items-center sm:flex-col sm:items-start"},React.createElement("span",{className:"sm:order-1 px-1.5 sm:py-1.5 sm:px-0"},"Supported"),React.createElement("span",{className:"sm:order-0"},React.createElement(Supported,null))),column:"PAYG"},{label:"no",content:React.createElement("div",{className:"flex items-center sm:flex-col sm:items-start"},React.createElement("span",{className:"sm:order-1 px-1.5 sm:py-1.5 sm:px-0"},"Unsupported"),React.createElement("span",{className:"sm:order-0"},React.createElement(Unsupported,null))),column:"Custom"}]});const sections=["Features","Support","Technical Support"].map(label=>({label,rows:[...Array(5)].map((_,i)=>testRow(i))}));export const PricingPageTable=()=>{return React.createElement("div",{className:"ui-standard-container"},React.createElement("h2",{className:"ui-text-h2 text-center m-8"},"Pricing Page Table"),React.createElement("p",{className:"text-center m-8"},"Example content"),React.createElement(Table.Root,null,React.createElement(Table.Header,null,React.createElement(Table.Row,null,React.createElement(Table.Cell,null,React.createElement("span",{className:"ui-text-h3 hidden sm:block"},"Free")),React.createElement(Table.Cell,null,React.createElement("span",{className:"ui-text-h3 hidden sm:block"},"PAYG")),React.createElement(Table.Cell,null,React.createElement("span",{className:"ui-text-h3 hidden sm:block"},"Custom")))),React.createElement(Table.Body,null,sections.map(section=>React.createElement(Fragment,{key:section.label},React.createElement(Table.RowHeader,null,React.createElement(Table.Cell,{colSpan:4},section.label)),section.rows.map(row=>React.createElement(Table.Row,{key:row.label},React.createElement(Table.LabelCell,{key:row.label,className:"border-t border-light-grey"},React.createElement("a",{href:"/",className:"ui-link"},row.label),React.createElement(Tooltip,null,"Example tooltip")),row.cells.map(cell=>React.createElement(Table.Cell,{key:cell.label,className:"last:mb-4 sm:mb-0"},React.createElement("div",{className:"flex-1 sm:hidden !text-dark-grey ui-text-overline2"},cell.column),cell.content)))))),React.createElement(Table.Row,null,React.createElement(Table.Cell,null),React.createElement(Table.CtaCell,null,React.createElement("a",{href:"/",className:"ui-btn-secondary"},"Get started")),React.createElement(Table.CtaCell,null,React.createElement("a",{href:"/",className:"ui-btn-secondary"},"Get started")),React.createElement(Table.CtaCell,null,React.createElement("a",{href:"/",className:"ui-btn"},"Contact sales"))))))};
|
|
2
2
|
//# sourceMappingURL=data.js.map
|
package/core/Table/data.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Table/data.tsx"],"sourcesContent":["import React, { Fragment } from \"react\";\n\nimport Tooltip from \"../Tooltip\";\nimport Table from \"../Table\";\nimport Icon from \"../Icon\";\n\nconst Supported = () => (\n <Icon\n name=\"icon-gui-check-circle-solid\"\n size=\"1.5rem\"\n color=\"text-gui-success\"\n additionalCSS=\"flex-grow-0 flex-shrink-0\"\n data-testid=\"supported-icon\"\n />\n);\n\nconst Unsupported = () => (\n <Icon\n name=\"icon-gui-x-circle-solid\"\n size=\"1.5rem\"\n color=\"text-gui-error\"\n additionalCSS=\"flex-grow-0 flex-shrink-0\"\n data-testid=\"unsupported-icon\"\n />\n);\n\nconst testRow = (index: number) => ({\n label: `Label ${index + 1}`,\n cells: [\n { label: \"text\", content: \"Cell content\", column: \"Free\" },\n {\n label: \"yes\",\n content: (\n <div className=\"flex items-center sm:flex-col sm:items-start\">\n <span className=\"sm:order-1 px-1.5 sm:py-1.5 sm:px-0\">Supported</span>\n <span className=\"sm:order-0\">\n <Supported />\n </span>\n </div>\n ),\n column: \"PAYG\",\n },\n {\n label: \"no\",\n content: (\n <div className=\"flex items-center sm:flex-col sm:items-start\">\n <span className=\"sm:order-1 px-1.5 sm:py-1.5 sm:px-0\">\n Unsupported\n </span>\n <span className=\"sm:order-0\">\n <Unsupported />\n </span>\n </div>\n ),\n column: \"Custom\",\n },\n ],\n});\n\nconst sections = [\"Features\", \"Support\", \"Technical Support\"].map((label) => ({\n label,\n rows: [...Array(5)].map((_, i) => testRow(i)),\n}));\n\nexport const PricingPageTable = () => {\n return (\n <div className=\"ui-standard-container\">\n <h2 className=\"ui-text-h2 text-center m-8\">Pricing Page Table</h2>\n <p className=\"text-center m-8\">Example content</p>\n <Table.Root>\n <Table.Header>\n <Table.Row>\n <Table.Cell>\n <span className=\"ui-text-h3 hidden sm:block\">Free</span>\n </Table.Cell>\n <Table.Cell>\n <span className=\"ui-text-h3 hidden sm:block\">PAYG</span>\n </Table.Cell>\n <Table.Cell>\n <span className=\"ui-text-h3 hidden sm:block\">Custom</span>\n </Table.Cell>\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {sections.map((section) => (\n <Fragment key={section.label}>\n <Table.RowHeader>\n <Table.Cell colSpan={4}>{section.label}</Table.Cell>\n </Table.RowHeader>\n {section.rows.map((row) => (\n <Table.Row key={row.label}>\n <Table.LabelCell\n key={row.label}\n className=\"border-t border-light-grey\"\n >\n <a className=\"ui-link\"
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Table/data.tsx"],"sourcesContent":["import React, { Fragment } from \"react\";\n\nimport Tooltip from \"../Tooltip\";\nimport Table from \"../Table\";\nimport Icon from \"../Icon\";\n\nconst Supported = () => (\n <Icon\n name=\"icon-gui-check-circle-solid\"\n size=\"1.5rem\"\n color=\"text-gui-success\"\n additionalCSS=\"flex-grow-0 flex-shrink-0\"\n data-testid=\"supported-icon\"\n />\n);\n\nconst Unsupported = () => (\n <Icon\n name=\"icon-gui-x-circle-solid\"\n size=\"1.5rem\"\n color=\"text-gui-error\"\n additionalCSS=\"flex-grow-0 flex-shrink-0\"\n data-testid=\"unsupported-icon\"\n />\n);\n\nconst testRow = (index: number) => ({\n label: `Label ${index + 1}`,\n cells: [\n { label: \"text\", content: \"Cell content\", column: \"Free\" },\n {\n label: \"yes\",\n content: (\n <div className=\"flex items-center sm:flex-col sm:items-start\">\n <span className=\"sm:order-1 px-1.5 sm:py-1.5 sm:px-0\">Supported</span>\n <span className=\"sm:order-0\">\n <Supported />\n </span>\n </div>\n ),\n column: \"PAYG\",\n },\n {\n label: \"no\",\n content: (\n <div className=\"flex items-center sm:flex-col sm:items-start\">\n <span className=\"sm:order-1 px-1.5 sm:py-1.5 sm:px-0\">\n Unsupported\n </span>\n <span className=\"sm:order-0\">\n <Unsupported />\n </span>\n </div>\n ),\n column: \"Custom\",\n },\n ],\n});\n\nconst sections = [\"Features\", \"Support\", \"Technical Support\"].map((label) => ({\n label,\n rows: [...Array(5)].map((_, i) => testRow(i)),\n}));\n\nexport const PricingPageTable = () => {\n return (\n <div className=\"ui-standard-container\">\n <h2 className=\"ui-text-h2 text-center m-8\">Pricing Page Table</h2>\n <p className=\"text-center m-8\">Example content</p>\n <Table.Root>\n <Table.Header>\n <Table.Row>\n <Table.Cell>\n <span className=\"ui-text-h3 hidden sm:block\">Free</span>\n </Table.Cell>\n <Table.Cell>\n <span className=\"ui-text-h3 hidden sm:block\">PAYG</span>\n </Table.Cell>\n <Table.Cell>\n <span className=\"ui-text-h3 hidden sm:block\">Custom</span>\n </Table.Cell>\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {sections.map((section) => (\n <Fragment key={section.label}>\n <Table.RowHeader>\n <Table.Cell colSpan={4}>{section.label}</Table.Cell>\n </Table.RowHeader>\n {section.rows.map((row) => (\n <Table.Row key={row.label}>\n <Table.LabelCell\n key={row.label}\n className=\"border-t border-light-grey\"\n >\n <a href=\"/\" className=\"ui-link\">\n {row.label}\n </a>\n <Tooltip>Example tooltip</Tooltip>\n </Table.LabelCell>\n {row.cells.map((cell) => (\n <Table.Cell key={cell.label} className=\"last:mb-4 sm:mb-0\">\n <div className=\"flex-1 sm:hidden !text-dark-grey ui-text-overline2\">\n {cell.column}\n </div>\n {cell.content}\n </Table.Cell>\n ))}\n </Table.Row>\n ))}\n </Fragment>\n ))}\n <Table.Row>\n <Table.Cell></Table.Cell>\n <Table.CtaCell>\n <a href=\"/\" className=\"ui-btn-secondary\">\n Get started\n </a>\n </Table.CtaCell>\n <Table.CtaCell>\n <a href=\"/\" className=\"ui-btn-secondary\">\n Get started\n </a>\n </Table.CtaCell>\n <Table.CtaCell>\n <a href=\"/\" className=\"ui-btn\">\n Contact sales\n </a>\n </Table.CtaCell>\n </Table.Row>\n </Table.Body>\n </Table.Root>\n </div>\n );\n};\n"],"names":["React","Fragment","Tooltip","Table","Icon","Supported","name","size","color","additionalCSS","data-testid","Unsupported","testRow","index","label","cells","content","column","div","className","span","sections","map","rows","Array","_","i","PricingPageTable","h2","p","Root","Header","Row","Cell","Body","section","key","RowHeader","colSpan","row","LabelCell","a","href","cell","CtaCell"],"mappings":"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"}
|
package/core/Toggle.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import*as Switch from"@radix-ui/react-switch";import React from"react";import cn from"./utils/cn";const Toggle=({id,size="lg",label,className,...props})=>{const rootSize=size==="sm"?"w-[2.625rem] h-6":"w-14 h-8";const thumbSize=size==="sm"?"w-[1.3125rem] h-[1.3125rem] translate-x-px data-[state=checked]:translate-x-5":"h-7 w-7 translate-x-0.5 data-[state=checked]:translate-x-[1.625rem]";return React.createElement("div",{className:"flex items-center"},React.createElement(Switch.Root,{className:cn("p-0 bg-neutral-600 rounded-full relative inline-block transition-colors data-[disabled]:bg-gui-
|
|
1
|
+
import*as Switch from"@radix-ui/react-switch";import React from"react";import cn from"./utils/cn";const Toggle=({id,size="lg",label,className,...props})=>{const rootSize=size==="sm"?"w-[2.625rem] h-6":"w-14 h-8";const thumbSize=size==="sm"?"w-[1.3125rem] h-[1.3125rem] translate-x-px data-[state=checked]:translate-x-5":"h-7 w-7 translate-x-0.5 data-[state=checked]:translate-x-[1.625rem]";return React.createElement("div",{className:"flex items-center"},React.createElement(Switch.Root,{className:cn("p-0 bg-neutral-600 rounded-full relative inline-block transition-colors data-[disabled]:bg-gui-disabled-light dark:data-[disabled]:bg-gui-disabled-dark data-[disabled]:cursor-not-allowed data-[state=checked]:bg-orange-600 focus-base",className,rootSize),id:id,...props},React.createElement(Switch.Thumb,{className:cn(`block bg-white data-[disabled]:bg-neutral-500 dark:data-[disabled]:bg-neutral-800 rounded-full drop-shadow-toggle transition-transform`,thumbSize)})),label?React.createElement("label",{className:"ml-4",htmlFor:id},label):null)};export default Toggle;
|
|
2
2
|
//# sourceMappingURL=Toggle.js.map
|
package/core/Toggle.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Toggle.tsx"],"sourcesContent":["import * as Switch from \"@radix-ui/react-switch\";\nimport React from \"react\";\nimport cn from \"./utils/cn\";\n\ntype ToggleProps = {\n id: string;\n size?: \"sm\" | \"lg\";\n label?: string;\n className?: string;\n onCheckedChange?: (checked: boolean) => void;\n} & React.ButtonHTMLAttributes<HTMLButtonElement>;\n\nconst Toggle: React.FC<ToggleProps> = ({\n id,\n size = \"lg\",\n label,\n className,\n ...props\n}) => {\n const rootSize = size === \"sm\" ? \"w-[2.625rem] h-6\" : \"w-14 h-8\";\n const thumbSize =\n size === \"sm\"\n ? \"w-[1.3125rem] h-[1.3125rem] translate-x-px data-[state=checked]:translate-x-5\"\n : \"h-7 w-7 translate-x-0.5 data-[state=checked]:translate-x-[1.625rem]\";\n\n return (\n <div className=\"flex items-center\">\n <Switch.Root\n className={cn(\n \"p-0 bg-neutral-600 rounded-full relative inline-block transition-colors data-[disabled]:bg-gui-
|
|
1
|
+
{"version":3,"sources":["../../src/core/Toggle.tsx"],"sourcesContent":["import * as Switch from \"@radix-ui/react-switch\";\nimport React from \"react\";\nimport cn from \"./utils/cn\";\n\ntype ToggleProps = {\n id: string;\n size?: \"sm\" | \"lg\";\n label?: string;\n className?: string;\n onCheckedChange?: (checked: boolean) => void;\n} & React.ButtonHTMLAttributes<HTMLButtonElement>;\n\nconst Toggle: React.FC<ToggleProps> = ({\n id,\n size = \"lg\",\n label,\n className,\n ...props\n}) => {\n const rootSize = size === \"sm\" ? \"w-[2.625rem] h-6\" : \"w-14 h-8\";\n const thumbSize =\n size === \"sm\"\n ? \"w-[1.3125rem] h-[1.3125rem] translate-x-px data-[state=checked]:translate-x-5\"\n : \"h-7 w-7 translate-x-0.5 data-[state=checked]:translate-x-[1.625rem]\";\n\n return (\n <div className=\"flex items-center\">\n <Switch.Root\n className={cn(\n \"p-0 bg-neutral-600 rounded-full relative inline-block transition-colors data-[disabled]:bg-gui-disabled-light dark:data-[disabled]:bg-gui-disabled-dark data-[disabled]:cursor-not-allowed data-[state=checked]:bg-orange-600 focus-base\",\n className,\n rootSize,\n )}\n id={id}\n {...props}\n >\n <Switch.Thumb\n className={cn(\n `block bg-white data-[disabled]:bg-neutral-500 dark:data-[disabled]:bg-neutral-800 rounded-full drop-shadow-toggle transition-transform`,\n thumbSize,\n )}\n />\n </Switch.Root>\n {label ? (\n <label className=\"ml-4\" htmlFor={id}>\n {label}\n </label>\n ) : null}\n </div>\n );\n};\n\nexport default Toggle;\n"],"names":["Switch","React","cn","Toggle","id","size","label","className","props","rootSize","thumbSize","div","Root","Thumb","htmlFor"],"mappings":"AAAA,UAAYA,WAAY,wBAAyB,AACjD,QAAOC,UAAW,OAAQ,AAC1B,QAAOC,OAAQ,YAAa,CAU5B,MAAMC,OAAgC,CAAC,CACrCC,EAAE,CACFC,KAAO,IAAI,CACXC,KAAK,CACLC,SAAS,CACT,GAAGC,MACJ,IACC,MAAMC,SAAWJ,OAAS,KAAO,mBAAqB,WACtD,MAAMK,UACJL,OAAS,KACL,gFACA,sEAEN,OACE,oBAACM,OAAIJ,UAAU,qBACb,oBAACP,OAAOY,IAAI,EACVL,UAAWL,GACT,2OACAK,UACAE,UAEFL,GAAIA,GACH,GAAGI,KAAK,EAET,oBAACR,OAAOa,KAAK,EACXN,UAAWL,GACT,CAAC,sIAAsI,CAAC,CACxIQ,cAILJ,MACC,oBAACA,SAAMC,UAAU,OAAOO,QAASV,IAC9BE,OAED,KAGV,CAEA,gBAAeH,MAAO"}
|
package/core/Tooltip.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from"react";import*as RadixTooltip from"@radix-ui/react-tooltip";import Icon from"./Icon";import cn from"./utils/cn";const Tooltip=({children,triggerElement,triggerProps,contentProps,rootProps,interactive=false,iconSize="1rem",...rest})=>{return React.createElement("div",{...rest,className:cn("inline-flex ml-2",rest?.className)},React.createElement(RadixTooltip.Provider,{delayDuration:0},React.createElement(RadixTooltip.Root,{...!interactive?{disableHoverableContent:true}:{},...rootProps},React.createElement(RadixTooltip.Trigger,{asChild:true},React.createElement("button",{type:"button",...triggerProps,className:cn("p-0 relative focus:outline-none h-[1rem]",triggerProps?.className)},triggerElement??React.createElement(Icon,{name:"icon-gui-information-circle-outline",color:"text-neutral-700 dark:text-neutral-600 hover:text-neutral-1000 dark:hover:text-neutral-300",size:iconSize}))),React.createElement(RadixTooltip.Portal,null,React.createElement(RadixTooltip.Content,{sideOffset:8,...contentProps,className:cn("bg-neutral-300 dark:bg-neutral-1000 text-neutral-1100 dark:text-neutral-200 ui-text-p3 font-medium p-4",{"pointer-events-auto":interactive},"rounded-lg shadow-[4px_4px_15px_rgba(0,0,0,0.2)] z-[1000]","data-[state=closed]:animate-[tooltipExit_0.25s_ease-in-out]","data-[state=delayed-open]:animate-[tooltipEntry_0.25s_ease-in-out]",contentProps?.className)},React.createElement("div",{className:"max-w-60 w-auto"},children))))))};export default Tooltip;
|
|
2
2
|
//# sourceMappingURL=Tooltip.js.map
|
package/core/Tooltip.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Tooltip.tsx"],"sourcesContent":["import React, {\n ButtonHTMLAttributes,\n HTMLAttributes,\n PropsWithChildren,\n ReactNode,\n useRef,\n useState,\n MouseEvent,\n RefObject,\n useEffect,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\n\ntype TooltipProps = {\n triggerElement?: ReactNode;\n triggerProps?: ButtonHTMLAttributes<HTMLButtonElement>;\n tooltipProps?: HTMLAttributes<HTMLDivElement>;\n interactive?: boolean;\n} & HTMLAttributes<HTMLDivElement>;\n\nconst Tooltip = ({\n children,\n triggerElement,\n triggerProps,\n tooltipProps,\n interactive = false,\n ...rest\n}: PropsWithChildren<TooltipProps>) => {\n const [open, setOpen] = useState(false);\n const [fadeOut, setFadeOut] = useState(false);\n const [position, setPosition] = useState({ x: 0, y: 0, orientation: \"top\" });\n const offset = 8;\n const reference = useRef<HTMLButtonElement>(null);\n const floating = useRef<HTMLDivElement>(null);\n const fadeOutTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n useEffect(() => {\n if (open) {\n const floatingRect = floating.current?.getBoundingClientRect();\n const referenceRect = reference.current?.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n let orientation = \"top\";\n\n if (floatingRect && referenceRect) {\n let x =\n referenceRect.left +\n referenceRect.width / 2 -\n floatingRect.width / 2 +\n window.scrollX;\n let y =\n referenceRect.top - floatingRect.height - offset + window.scrollY;\n\n // Adjust if tooltip goes off the right edge\n if (x + floatingRect.width > viewportWidth + window.scrollX) {\n x = viewportWidth + window.scrollX - floatingRect.width - offset;\n orientation = \"left\";\n }\n\n // Adjust if tooltip goes off the left edge\n if (x < window.scrollX) {\n x = window.scrollX + offset;\n orientation = \"right\";\n }\n\n // Adjust if tooltip goes off the top edge\n if (y < window.scrollY) {\n y = referenceRect.bottom + offset + window.scrollY;\n orientation = \"bottom\";\n }\n\n // Adjust if tooltip goes off the bottom edge\n if (y + floatingRect.height > viewportHeight + window.scrollY) {\n y = referenceRect.top - floatingRect.height - offset + window.scrollY;\n }\n\n setPosition({ x, y, orientation });\n }\n } else {\n setPosition({ x: 0, y: 0, orientation: \"top\" });\n }\n\n return () => {\n if (fadeOutTimeoutRef.current !== null) {\n clearTimeout(fadeOutTimeoutRef.current);\n }\n };\n }, [open]);\n\n const initiateFadeOut = () => {\n setFadeOut(true);\n fadeOutTimeoutRef.current = setTimeout(() => {\n setOpen(false);\n setFadeOut(false);\n }, 250);\n };\n\n const cursorTowardsTooltip = (\n event: MouseEvent,\n ref: RefObject<HTMLButtonElement>,\n ) => {\n if (!ref.current) {\n return false;\n }\n\n const { clientX, clientY } = event;\n const { x, y, width, height } = ref.current.getBoundingClientRect();\n const { orientation } = position;\n\n switch (orientation) {\n case \"top\":\n return clientX >= x && clientX <= x + width && clientY < y;\n case \"left\":\n return clientY >= y && clientY <= y + height && clientX < x;\n case \"right\":\n return clientY >= y && clientY <= y + height && clientX > x + width;\n case \"bottom\":\n return clientX >= x && clientX <= x + width && clientY > y + height;\n default:\n return false;\n }\n };\n\n const fadeOutIfNotWithinTrigger = (event: MouseEvent) => {\n if (!reference.current) return;\n\n const { clientX, clientY } = event;\n const { x, y, width, height } = reference.current.getBoundingClientRect();\n const withinBounds =\n clientX >= x &&\n clientX <= x + width &&\n clientY >= y &&\n clientY <= y + height;\n\n if (!withinBounds) {\n initiateFadeOut();\n }\n };\n\n return (\n <div {...rest} className={cn(\"inline-flex ml-2\", rest?.className)}>\n <button\n onMouseEnter={() => setOpen(true)}\n onMouseLeave={(event) => {\n if (!interactive || !cursorTowardsTooltip(event, reference)) {\n initiateFadeOut();\n }\n }}\n type=\"button\"\n ref={reference}\n aria-describedby=\"tooltip\"\n {...triggerProps}\n className={`p-0 relative focus:outline-none h-[1rem] ${\n triggerProps?.className ?? \"\"\n }`}\n >\n {triggerElement ?? (\n <Icon\n name=\"icon-gui-information-circle-micro\"\n color=\"text-neutral-800 dark:text-neutral-500\"\n size=\"1rem\"\n />\n )}\n </button>\n\n {open\n ? createPortal(\n <div\n role=\"tooltip\"\n ref={floating}\n onMouseLeave={(event) =>\n setTimeout(() => fadeOutIfNotWithinTrigger(event), 250)\n }\n style={{\n top: position.y,\n left: position.x,\n zIndex: 1000,\n boxShadow: \"4px 4px 15px rgba(0, 0, 0, 0.2)\",\n }}\n {...tooltipProps}\n className={cn(\n \"bg-neutral-1000 dark:bg-neutral-300 text-neutral-200 dark:text-neutral-1000 ui-text-p3 font-medium p-4\",\n { \"pointer-events-none\": !interactive },\n \"rounded-lg absolute\",\n tooltipProps?.className,\n { \"animate-[tooltipExit_0.25s_ease-in-out]\": fadeOut },\n { \"animate-[tooltipEntry_0.25s_ease-in-out]\": !fadeOut },\n )}\n >\n <div className=\"max-w-60 w-auto\">{children}</div>\n </div>,\n document.body,\n )\n : null}\n </div>\n );\n};\n\nexport default Tooltip;\n"],"names":["React","useRef","useState","useEffect","createPortal","Icon","cn","Tooltip","children","triggerElement","triggerProps","tooltipProps","interactive","rest","open","setOpen","fadeOut","setFadeOut","position","setPosition","x","y","orientation","offset","reference","floating","fadeOutTimeoutRef","floatingRect","current","getBoundingClientRect","referenceRect","viewportWidth","window","innerWidth","viewportHeight","innerHeight","left","width","scrollX","top","height","scrollY","bottom","clearTimeout","initiateFadeOut","setTimeout","cursorTowardsTooltip","event","ref","clientX","clientY","fadeOutIfNotWithinTrigger","withinBounds","div","className","button","onMouseEnter","onMouseLeave","type","aria-describedby","name","color","size","role","style","zIndex","boxShadow","document","body"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/Tooltip.tsx"],"sourcesContent":["import React, {\n ButtonHTMLAttributes,\n HTMLAttributes,\n PropsWithChildren,\n ReactNode,\n} from \"react\";\nimport * as RadixTooltip from \"@radix-ui/react-tooltip\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\nimport { IconSize } from \"./Icon/types\";\n\ntype TooltipProps = {\n triggerElement?: ReactNode;\n triggerProps?: ButtonHTMLAttributes<HTMLButtonElement>;\n contentProps?: RadixTooltip.TooltipContentProps &\n HTMLAttributes<HTMLDivElement>;\n rootProps?: RadixTooltip.TooltipProps;\n interactive?: boolean;\n iconSize?: IconSize;\n} & HTMLAttributes<HTMLDivElement>;\n\nconst Tooltip = ({\n children,\n triggerElement,\n triggerProps,\n contentProps,\n rootProps,\n interactive = false,\n iconSize = \"1rem\",\n ...rest\n}: PropsWithChildren<TooltipProps>) => {\n return (\n <div {...rest} className={cn(\"inline-flex ml-2\", rest?.className)}>\n <RadixTooltip.Provider delayDuration={0}>\n <RadixTooltip.Root\n {...(!interactive ? { disableHoverableContent: true } : {})}\n {...rootProps}\n >\n <RadixTooltip.Trigger asChild>\n <button\n type=\"button\"\n {...triggerProps}\n className={cn(\n \"p-0 relative focus:outline-none h-[1rem]\",\n triggerProps?.className,\n )}\n >\n {triggerElement ?? (\n <Icon\n name=\"icon-gui-information-circle-outline\"\n color=\"text-neutral-700 dark:text-neutral-600 hover:text-neutral-1000 dark:hover:text-neutral-300\"\n size={iconSize}\n />\n )}\n </button>\n </RadixTooltip.Trigger>\n <RadixTooltip.Portal>\n <RadixTooltip.Content\n sideOffset={8}\n {...contentProps}\n className={cn(\n \"bg-neutral-300 dark:bg-neutral-1000 text-neutral-1100 dark:text-neutral-200 ui-text-p3 font-medium p-4\",\n { \"pointer-events-auto\": interactive },\n \"rounded-lg shadow-[4px_4px_15px_rgba(0,0,0,0.2)] z-[1000]\",\n \"data-[state=closed]:animate-[tooltipExit_0.25s_ease-in-out]\",\n \"data-[state=delayed-open]:animate-[tooltipEntry_0.25s_ease-in-out]\",\n contentProps?.className,\n )}\n >\n <div className=\"max-w-60 w-auto\">{children}</div>\n </RadixTooltip.Content>\n </RadixTooltip.Portal>\n </RadixTooltip.Root>\n </RadixTooltip.Provider>\n </div>\n );\n};\n\nexport default Tooltip;\n"],"names":["React","RadixTooltip","Icon","cn","Tooltip","children","triggerElement","triggerProps","contentProps","rootProps","interactive","iconSize","rest","div","className","Provider","delayDuration","Root","disableHoverableContent","Trigger","asChild","button","type","name","color","size","Portal","Content","sideOffset"],"mappings":"AAAA,OAAOA,UAKA,OAAQ,AACf,WAAYC,iBAAkB,yBAA0B,AACxD,QAAOC,SAAU,QAAS,AAC1B,QAAOC,OAAQ,YAAa,CAa5B,MAAMC,QAAU,CAAC,CACfC,QAAQ,CACRC,cAAc,CACdC,YAAY,CACZC,YAAY,CACZC,SAAS,CACTC,YAAc,KAAK,CACnBC,SAAW,MAAM,CACjB,GAAGC,KAC6B,IAChC,OACE,oBAACC,OAAK,GAAGD,IAAI,CAAEE,UAAWX,GAAG,mBAAoBS,MAAME,YACrD,oBAACb,aAAac,QAAQ,EAACC,cAAe,GACpC,oBAACf,aAAagB,IAAI,EACf,GAAI,CAACP,YAAc,CAAEQ,wBAAyB,IAAK,EAAI,CAAC,CAAC,CACzD,GAAGT,SAAS,EAEb,oBAACR,aAAakB,OAAO,EAACC,QAAAA,MACpB,oBAACC,UACCC,KAAK,SACJ,GAAGf,YAAY,CAChBO,UAAWX,GACT,2CACAI,cAAcO,YAGfR,gBACC,oBAACJ,MACCqB,KAAK,sCACLC,MAAM,6FACNC,KAAMd,aAKd,oBAACV,aAAayB,MAAM,MAClB,oBAACzB,aAAa0B,OAAO,EACnBC,WAAY,EACX,GAAGpB,YAAY,CAChBM,UAAWX,GACT,yGACA,CAAE,sBAAuBO,WAAY,EACrC,4DACA,8DACA,qEACAF,cAAcM,YAGhB,oBAACD,OAAIC,UAAU,mBAAmBT,cAOhD,CAEA,gBAAeD,OAAQ"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{useState,useEffect,useRef}from"react";export function useContentHeight(ref,initialHeight=0){const[contentHeight,setContentHeight]=useState(initialHeight);const observerRef=useRef(null);const rafIdRef=useRef(null);useEffect(()=>{const element=ref.current;if(!element){return}let isMounted=true;observerRef.current=new ResizeObserver(entries=>{if(rafIdRef.current!==null){cancelAnimationFrame(rafIdRef.current)}rafIdRef.current=requestAnimationFrame(()=>{rafIdRef.current=null;if(!isMounted)return;const entry=entries[0];if(entry&&entry.contentRect){const newHeight=Math.round(entry.contentRect.height);setContentHeight(newHeight)}})});observerRef.current.observe(element);return()=>{isMounted=false;if(rafIdRef.current!==null){cancelAnimationFrame(rafIdRef.current);rafIdRef.current=null}observerRef.current?.disconnect();observerRef.current=null}},[ref]);return contentHeight}
|
|
2
|
+
//# sourceMappingURL=use-content-height.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/hooks/use-content-height.ts"],"sourcesContent":["import { useState, useEffect, useRef, RefObject } from \"react\";\n\n/**\n * Custom hook that tracks the content height of an element using ResizeObserver.\n * This eliminates forced reflows by using the browser's native resize observation API\n * instead of synchronous clientHeight/getBoundingClientRect queries.\n *\n * @param ref - React ref to the element to observe\n * @param initialHeight - Initial height value (default: 0)\n * @returns Current content height in pixels\n */\nexport function useContentHeight(\n ref: RefObject<HTMLElement>,\n initialHeight = 0,\n): number {\n const [contentHeight, setContentHeight] = useState<number>(initialHeight);\n const observerRef = useRef<ResizeObserver | null>(null);\n const rafIdRef = useRef<number | null>(null);\n\n useEffect(() => {\n const element = ref.current;\n\n if (!element) {\n return;\n }\n\n let isMounted = true;\n\n observerRef.current = new ResizeObserver((entries) => {\n // Cancel any pending RAF to avoid stale updates\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n // Guard against updates after unmount\n if (!isMounted) return;\n\n const entry = entries[0];\n if (entry && entry.contentRect) {\n const newHeight = Math.round(entry.contentRect.height);\n setContentHeight(newHeight);\n }\n });\n });\n\n observerRef.current.observe(element);\n\n return () => {\n isMounted = false;\n // Cancel pending RAF to prevent setState after unmount\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n observerRef.current?.disconnect();\n observerRef.current = null;\n };\n }, [ref]);\n\n return contentHeight;\n}\n"],"names":["useState","useEffect","useRef","useContentHeight","ref","initialHeight","contentHeight","setContentHeight","observerRef","rafIdRef","element","current","isMounted","ResizeObserver","entries","cancelAnimationFrame","requestAnimationFrame","entry","contentRect","newHeight","Math","round","height","observe","disconnect"],"mappings":"AAAA,OAASA,QAAQ,CAAEC,SAAS,CAAEC,MAAM,KAAmB,OAAQ,AAW/D,QAAO,SAASC,iBACdC,GAA2B,CAC3BC,cAAgB,CAAC,EAEjB,KAAM,CAACC,cAAeC,iBAAiB,CAAGP,SAAiBK,eAC3D,MAAMG,YAAcN,OAA8B,MAClD,MAAMO,SAAWP,OAAsB,MAEvCD,UAAU,KACR,MAAMS,QAAUN,IAAIO,OAAO,CAE3B,GAAI,CAACD,QAAS,CACZ,MACF,CAEA,IAAIE,UAAY,IAEhBJ,CAAAA,YAAYG,OAAO,CAAG,IAAIE,eAAe,AAACC,UAExC,GAAIL,SAASE,OAAO,GAAK,KAAM,CAC7BI,qBAAqBN,SAASE,OAAO,CACvC,CAEAF,SAASE,OAAO,CAAGK,sBAAsB,KACvCP,SAASE,OAAO,CAAG,KAEnB,GAAI,CAACC,UAAW,OAEhB,MAAMK,MAAQH,OAAO,CAAC,EAAE,CACxB,GAAIG,OAASA,MAAMC,WAAW,CAAE,CAC9B,MAAMC,UAAYC,KAAKC,KAAK,CAACJ,MAAMC,WAAW,CAACI,MAAM,EACrDf,iBAAiBY,UACnB,CACF,EACF,GAEAX,YAAYG,OAAO,CAACY,OAAO,CAACb,SAE5B,MAAO,KACLE,UAAY,MAEZ,GAAIH,SAASE,OAAO,GAAK,KAAM,CAC7BI,qBAAqBN,SAASE,OAAO,CACrCF,CAAAA,SAASE,OAAO,CAAG,IACrB,CACAH,YAAYG,OAAO,EAAEa,YACrBhB,CAAAA,YAAYG,OAAO,CAAG,IACxB,CACF,EAAG,CAACP,IAAI,EAER,OAAOE,aACT"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{useState,useEffect,useRef}from"react";const HEADER_HEIGHT=64;export function useThemedScrollpoints(scrollpoints){const[activeClassName,setActiveClassName]=useState("");const previousClassNameRef=useRef("");const observerRef=useRef(null);const initialCheckDoneRef=useRef(false);const rafIdRef=useRef(null);const intersectingElementsRef=useRef(new Map);useEffect(()=>{if(scrollpoints.length===0){setActiveClassName("");previousClassNameRef.current="";return}let isMounted=true;const intersectingElements=intersectingElementsRef.current;const updateBestMatch=(useEntryRects=false)=>{let bestMatch=null;for(const[id,entry]of intersectingElements){const scrollpointIndex=scrollpoints.findIndex(sp=>sp.id===id);if(scrollpointIndex===-1)continue;const scrollpoint=scrollpoints[scrollpointIndex];const rect=useEntryRects?entry.boundingClientRect??entry.target.getBoundingClientRect():entry.target.getBoundingClientRect();if(rect.top>HEADER_HEIGHT)continue;const distance=Math.abs(rect.top-HEADER_HEIGHT);if(!bestMatch||distance<bestMatch.distance||distance===bestMatch.distance&&scrollpointIndex<bestMatch.index){bestMatch={scrollpoint,distance,index:scrollpointIndex}}}if(bestMatch&&bestMatch.scrollpoint.className!==previousClassNameRef.current){previousClassNameRef.current=bestMatch.scrollpoint.className;setActiveClassName(bestMatch.scrollpoint.className)}};observerRef.current=new IntersectionObserver(entries=>{for(const entry of entries){const id=entry.target.id;if(entry.isIntersecting){intersectingElements.set(id,entry)}else{intersectingElements.delete(id)}}if(rafIdRef.current!==null){cancelAnimationFrame(rafIdRef.current)}rafIdRef.current=requestAnimationFrame(()=>{rafIdRef.current=null;if(!isMounted)return;updateBestMatch(true)})},{rootMargin:`-${HEADER_HEIGHT}px 0px 0px 0px`,threshold:0});const handleScroll=()=>{if(rafIdRef.current!==null){cancelAnimationFrame(rafIdRef.current)}rafIdRef.current=requestAnimationFrame(()=>{rafIdRef.current=null;if(!isMounted)return;updateBestMatch(false)})};window.addEventListener("scroll",handleScroll,{passive:true});scrollpoints.forEach(({id})=>{const element=document.getElementById(id);if(element){observerRef.current?.observe(element)}else{console.warn(`useThemedScrollpoints: Element with id "${id}" not found in DOM`)}});const timeoutId=setTimeout(()=>{if(initialCheckDoneRef.current){return}initialCheckDoneRef.current=true;for(const scrollpoint of scrollpoints){const element=document.getElementById(scrollpoint.id);if(element){intersectingElements.set(scrollpoint.id,{target:element})}}updateBestMatch(false)},0);return()=>{isMounted=false;clearTimeout(timeoutId);window.removeEventListener("scroll",handleScroll);if(rafIdRef.current!==null){cancelAnimationFrame(rafIdRef.current);rafIdRef.current=null}observerRef.current?.disconnect();observerRef.current=null;initialCheckDoneRef.current=false;intersectingElements.clear()}},[scrollpoints]);return activeClassName}
|
|
2
|
+
//# sourceMappingURL=use-themed-scrollpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/hooks/use-themed-scrollpoints.ts"],"sourcesContent":["import { useState, useEffect, useRef } from \"react\";\nimport { ThemedScrollpoint } from \"../Header/types\";\n\nconst HEADER_HEIGHT = 64;\n\nexport function useThemedScrollpoints(\n scrollpoints: ThemedScrollpoint[],\n): string {\n const [activeClassName, setActiveClassName] = useState<string>(\"\");\n\n const previousClassNameRef = useRef<string>(\"\");\n const observerRef = useRef<IntersectionObserver | null>(null);\n const initialCheckDoneRef = useRef<boolean>(false);\n const rafIdRef = useRef<number | null>(null);\n const intersectingElementsRef = useRef<\n Map<string, IntersectionObserverEntry>\n >(new Map());\n\n useEffect(() => {\n if (scrollpoints.length === 0) {\n // Clear active className when scrollpoints becomes empty\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setActiveClassName(\"\");\n previousClassNameRef.current = \"\";\n return;\n }\n\n let isMounted = true;\n const intersectingElements = intersectingElementsRef.current;\n\n // Function to find and update the best matching scrollpoint\n const updateBestMatch = (useEntryRects = false) => {\n // Find the best match from ALL currently intersecting elements\n // Strategy: Pick the element whose top edge is closest to the header position\n // Use scrollpoints array order as tiebreaker when distances are equal\n let bestMatch: {\n scrollpoint: ThemedScrollpoint;\n distance: number;\n index: number;\n } | null = null;\n\n for (const [id, entry] of intersectingElements) {\n const scrollpointIndex = scrollpoints.findIndex((sp) => sp.id === id);\n if (scrollpointIndex === -1) continue;\n\n const scrollpoint = scrollpoints[scrollpointIndex];\n\n // For observer callbacks, use entry.boundingClientRect (for test compatibility)\n // For scroll handler, get fresh position data\n const rect = useEntryRects\n ? (entry.boundingClientRect ?? entry.target.getBoundingClientRect())\n : entry.target.getBoundingClientRect();\n\n // Only consider elements at or past the header line\n // This prevents selecting elements that are marked as \"intersecting\" by rootMargin\n // but haven't actually reached the header position yet\n if (rect.top > HEADER_HEIGHT) continue;\n\n // Calculate distance from element's top edge to header position\n const distance = Math.abs(rect.top - HEADER_HEIGHT);\n\n // Pick element with smallest distance; if equal, pick earlier in scrollpoints array\n if (\n !bestMatch ||\n distance < bestMatch.distance ||\n (distance === bestMatch.distance &&\n scrollpointIndex < bestMatch.index)\n ) {\n bestMatch = { scrollpoint, distance, index: scrollpointIndex };\n }\n }\n\n if (\n bestMatch &&\n bestMatch.scrollpoint.className !== previousClassNameRef.current\n ) {\n previousClassNameRef.current = bestMatch.scrollpoint.className;\n setActiveClassName(bestMatch.scrollpoint.className);\n }\n };\n\n observerRef.current = new IntersectionObserver(\n (entries) => {\n // Update the map of currently intersecting elements\n for (const entry of entries) {\n const id = (entry.target as HTMLElement).id;\n if (entry.isIntersecting) {\n intersectingElements.set(id, entry);\n } else {\n intersectingElements.delete(id);\n }\n }\n\n // Schedule best match calculation using entry rects\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n if (!isMounted) return;\n updateBestMatch(true); // Use entry.boundingClientRect\n });\n },\n {\n rootMargin: `-${HEADER_HEIGHT}px 0px 0px 0px`,\n threshold: 0,\n },\n );\n\n // Lightweight scroll handler to re-evaluate on scroll (gets fresh position data)\n const handleScroll = () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n\n rafIdRef.current = requestAnimationFrame(() => {\n rafIdRef.current = null;\n if (!isMounted) return;\n updateBestMatch(false); // Get fresh position data\n });\n };\n\n window.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n scrollpoints.forEach(({ id }) => {\n const element = document.getElementById(id);\n if (element) {\n observerRef.current?.observe(element);\n } else {\n console.warn(\n `useThemedScrollpoints: Element with id \"${id}\" not found in DOM`,\n );\n }\n });\n\n // Manually check initial intersection state since IntersectionObserver\n // callbacks only fire on changes, not on initial observation\n // Use a small timeout to ensure DOM is fully laid out\n const timeoutId = setTimeout(() => {\n if (initialCheckDoneRef.current) {\n return;\n }\n initialCheckDoneRef.current = true;\n\n // Manually populate the intersection map for initial check\n // (observer callbacks haven't fired yet)\n for (const scrollpoint of scrollpoints) {\n const element = document.getElementById(scrollpoint.id);\n if (element) {\n // Create a minimal entry with just the target\n intersectingElements.set(scrollpoint.id, {\n target: element,\n } as unknown as IntersectionObserverEntry);\n }\n }\n\n // Run initial best match calculation (gets fresh position data)\n updateBestMatch(false);\n }, 0);\n\n return () => {\n isMounted = false;\n clearTimeout(timeoutId);\n window.removeEventListener(\"scroll\", handleScroll);\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n observerRef.current?.disconnect();\n observerRef.current = null;\n initialCheckDoneRef.current = false;\n intersectingElements.clear();\n };\n }, [scrollpoints]);\n\n return activeClassName;\n}\n"],"names":["useState","useEffect","useRef","HEADER_HEIGHT","useThemedScrollpoints","scrollpoints","activeClassName","setActiveClassName","previousClassNameRef","observerRef","initialCheckDoneRef","rafIdRef","intersectingElementsRef","Map","length","current","isMounted","intersectingElements","updateBestMatch","useEntryRects","bestMatch","id","entry","scrollpointIndex","findIndex","sp","scrollpoint","rect","boundingClientRect","target","getBoundingClientRect","top","distance","Math","abs","index","className","IntersectionObserver","entries","isIntersecting","set","delete","cancelAnimationFrame","requestAnimationFrame","rootMargin","threshold","handleScroll","window","addEventListener","passive","forEach","element","document","getElementById","observe","console","warn","timeoutId","setTimeout","clearTimeout","removeEventListener","disconnect","clear"],"mappings":"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"}
|