@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/README.md
CHANGED
|
@@ -2,20 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
`ably-ui` is the of home of the Ably design system library ([https://ably-ui.herokuapp.com/](https://ably-ui.herokuapp.com/)). It provides a showcase, development/test environment and a publishing pipeline for different distributables.
|
|
4
4
|
|
|
5
|
-
## Getting started
|
|
6
|
-
|
|
7
|
-
`ably-ui` is a library built in mind with supporting a variety of websites/apps based on core web technologies. That's why where possible we build based on those but publish in a way that is easy to consume for frameworks we use across our properties.
|
|
8
|
-
|
|
9
|
-
As an example, the `Logo` component has two templates, for a [React](https://reactjs.org/) component and [view-component](https://viewcomponent.org/) but uses the same CSS classes and same JavaScript hooks (`data-id`).
|
|
10
|
-
|
|
11
|
-
In some cases, this is impractical. Some components will be more specialized and take advantage of a given framework, and we will have no need to make it available in multiple frameworks (for example, something that is only used within signed in, SPA like areas).
|
|
12
|
-
|
|
13
|
-
### Guiding principles
|
|
14
|
-
|
|
15
|
-
1. Provide easy access to common patterns and assets, from brand colours to navigation.
|
|
16
|
-
2. Use the web platform as much as possible without relying on frameworks.
|
|
17
|
-
3. Be flexible in how the library can be integrated.
|
|
18
|
-
|
|
19
5
|
### Library structure
|
|
20
6
|
|
|
21
7
|
The library is built out of modules, assets, and JavaScript components. A module is a container for all of those.
|
|
@@ -24,8 +10,6 @@ For example, the `core` module provides the most general elements one can build
|
|
|
24
10
|
|
|
25
11
|
Components do not require assets directly — instead, it's up to the consumer to load the assets and pass them to the components. This ensures flexibility in terms of URLs.
|
|
26
12
|
|
|
27
|
-
Each module, apart from components, exposes a `scripts.js` and `styles.css`. `scripts.js` contains helper functions. `styles.css` contains CSS that does not belong to any module in particular.
|
|
28
|
-
|
|
29
13
|
### Installation
|
|
30
14
|
|
|
31
15
|
### NPM
|
|
@@ -33,11 +17,7 @@ Each module, apart from components, exposes a `scripts.js` and `styles.css`. `sc
|
|
|
33
17
|
This type of installation gives you access to module/components assets as well as React components.
|
|
34
18
|
|
|
35
19
|
```bash
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# or
|
|
39
|
-
|
|
40
|
-
yarn add @ably/ui # Preferred
|
|
20
|
+
pnpm add @ably/ui # Preferred
|
|
41
21
|
```
|
|
42
22
|
|
|
43
23
|
To attach the imported JavaScript from the `Core` module to the `window` object:
|
|
@@ -122,31 +102,18 @@ import Meganav from "@ably/ui/core/Meganav";
|
|
|
122
102
|
|
|
123
103
|
### Icons
|
|
124
104
|
|
|
125
|
-
|
|
105
|
+
Icons are available in two formats to support different application types:
|
|
126
106
|
|
|
127
|
-
|
|
107
|
+
1. **React Component Imports** (recommended for React apps)
|
|
108
|
+
2. **SVG Spritesheets** (fallback for non-React apps)
|
|
128
109
|
|
|
129
|
-
|
|
110
|
+
We provide access to both custom local assets hosted in the repo and the third-party [Heroicons](https://heroicons.com/) library.
|
|
130
111
|
|
|
131
|
-
|
|
132
|
-
2. Generate React components that can be imported dynamically
|
|
112
|
+
#### For React Applications (Recommended)
|
|
133
113
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
#### Heroicons Integration
|
|
114
|
+
**Using the Icon React Component**
|
|
137
115
|
|
|
138
|
-
The
|
|
139
|
-
|
|
140
|
-
- `icon-gui-{heroicon-name}-{variant}`
|
|
141
|
-
|
|
142
|
-
Where `variant` can be:
|
|
143
|
-
|
|
144
|
-
- `outline` → 24px outline icons
|
|
145
|
-
- `solid` → 24px solid icons
|
|
146
|
-
- `mini` → 20px solid icons
|
|
147
|
-
- `micro` → 16px solid icons
|
|
148
|
-
|
|
149
|
-
#### Usage with the Icon React Component
|
|
116
|
+
The `Icon` component is the preferred method for React applications, providing automatic fallback and consistent sizing:
|
|
150
117
|
|
|
151
118
|
```tsx
|
|
152
119
|
// Local custom icon
|
|
@@ -159,7 +126,17 @@ Where `variant` can be:
|
|
|
159
126
|
<Icon name="icon-gui-chevron-down" variant="solid" size="1.5rem" />
|
|
160
127
|
```
|
|
161
128
|
|
|
162
|
-
|
|
129
|
+
**How the React Component Works**
|
|
130
|
+
|
|
131
|
+
1. **First**: Attempts to load a local React component generated from your custom SVGs
|
|
132
|
+
2. **Fallback**: If no local component exists, dynamically imports the corresponding heroicon
|
|
133
|
+
3. **Graceful degradation**: If neither exists, returns null (no icon displayed)
|
|
134
|
+
|
|
135
|
+
#### For Non-React Applications
|
|
136
|
+
|
|
137
|
+
**Using SVG Spritesheets**
|
|
138
|
+
|
|
139
|
+
For applications that don't use React, icons are available as SVG sprites that can be referenced directly:
|
|
163
140
|
|
|
164
141
|
```html
|
|
165
142
|
<!-- The width and height are required for correct sizing. The actual color class might depend on the svg and whether it uses strokes, fills etc. Note as well xlink:href, which is xlinkHref in react. -->
|
|
@@ -168,7 +145,7 @@ Where `variant` can be:
|
|
|
168
145
|
</svg>
|
|
169
146
|
```
|
|
170
147
|
|
|
171
|
-
|
|
148
|
+
Even in React applications, you can use the sprite method for advanced use cases like hover states with the [group](https://tailwindcss.com/docs/hover-focus-and-other-states#group-hover) class:
|
|
172
149
|
|
|
173
150
|
```tsx
|
|
174
151
|
<a
|
|
@@ -182,11 +159,29 @@ Usage without a component, in React, with hover states. Note the [group](https:/
|
|
|
182
159
|
</a>
|
|
183
160
|
```
|
|
184
161
|
|
|
185
|
-
|
|
162
|
+
The sprites file can be loaded with the `loadSprites` helper available in the `core` module or included in the page directly.
|
|
186
163
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
164
|
+
#### Icon Sources
|
|
165
|
+
|
|
166
|
+
**Local Custom Icons**
|
|
167
|
+
|
|
168
|
+
Putting SVG files inside a `src/core/icons` folder will:
|
|
169
|
+
|
|
170
|
+
1. Generate React components that can be imported dynamically
|
|
171
|
+
2. Add them to a per-group sprites file (e.g., `core/sprites-gui.svg`) for non-React usage
|
|
172
|
+
|
|
173
|
+
**Heroicons Integration**
|
|
174
|
+
|
|
175
|
+
The system automatically falls back to [Heroicons](https://heroicons.com/) when a local icon isn't found, using this naming convention:
|
|
176
|
+
|
|
177
|
+
- `icon-gui-{heroicon-name}-{variant}`
|
|
178
|
+
|
|
179
|
+
Where `variant` can be:
|
|
180
|
+
|
|
181
|
+
- `outline` → 24px outline icons
|
|
182
|
+
- `solid` → 24px solid icons
|
|
183
|
+
- `mini` → 20px solid icons
|
|
184
|
+
- `micro` → 16px solid icons
|
|
190
185
|
|
|
191
186
|
This hybrid approach allows you to use custom brand icons while having access to the entire heroicons library as a fallback.
|
|
192
187
|
|
|
@@ -211,11 +206,29 @@ An important part of ably-ui is ensuring the produced UI is accessible to as wid
|
|
|
211
206
|
|
|
212
207
|
To visualise the assets in `ably-ui`, there is a Storybook instance, which serves as both a showcase and a development environment.
|
|
213
208
|
|
|
214
|
-
|
|
209
|
+
### Quick Start
|
|
210
|
+
|
|
211
|
+
The easiest way to get started is to use the development script:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
./bin/dev
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
This script will:
|
|
215
218
|
|
|
216
|
-
|
|
219
|
+
- Check that all required tools (Node.js, pnpm) are installed at the correct versions via asdf
|
|
220
|
+
- Install all project dependencies
|
|
221
|
+
- Start Storybook automatically
|
|
217
222
|
|
|
218
|
-
|
|
223
|
+
### Manual Setup
|
|
224
|
+
|
|
225
|
+
If you prefer to run commands manually:
|
|
226
|
+
|
|
227
|
+
Firstly, ensure you have all of the required project dependencies by running `pnpm install` in the project root.
|
|
228
|
+
|
|
229
|
+
Then, to run Storybook, run `pnpm storybook` in the project root - it should open automatically in your browser.
|
|
230
|
+
|
|
231
|
+
To build Storybook as if it was a statically built site (i.e. what it looks like when deployed), run `pnpm build-storybook` from the project root, go to the generated directory with `cd preview`, and then run `npx http-server` (accepting the prompt to install that package if you haven't done already). The built site will be available at the listed local URL.
|
|
219
232
|
|
|
220
233
|
### SWC compile flags
|
|
221
234
|
|
|
@@ -236,7 +249,7 @@ if (__DEBUG_MODE__) {
|
|
|
236
249
|
The flag can be added to the list in `swc.config.ts`, and enabled with an environment variable:
|
|
237
250
|
|
|
238
251
|
```
|
|
239
|
-
$ DEBUG_MODE=true
|
|
252
|
+
$ DEBUG_MODE=true pnpm build
|
|
240
253
|
```
|
|
241
254
|
|
|
242
255
|
### Publishing pre-release packages for review apps
|
|
@@ -256,22 +269,25 @@ After the above, you should have:
|
|
|
256
269
|
To deploy a review app with your in-progress code, you can use the `pre-release` script:
|
|
257
270
|
|
|
258
271
|
```bash
|
|
259
|
-
# in
|
|
260
|
-
scripts/pre-release.sh
|
|
272
|
+
# in packages/ui directory
|
|
273
|
+
./scripts/pre-release.sh
|
|
261
274
|
```
|
|
262
275
|
|
|
263
|
-
This script
|
|
276
|
+
This script automates the following steps:
|
|
264
277
|
|
|
265
278
|
1. Pre-Release:
|
|
266
279
|
|
|
267
|
-
-
|
|
268
|
-
-
|
|
280
|
+
- Updates local dependencies for ably-ui and runs a production build
|
|
281
|
+
- Releases an NPM package with the version built from your current SemVer but adding a pre-release tag based on a short SHA of your HEAD commit
|
|
282
|
+
- Waits for the package to be available on the NPM registry (handles propagation delay)
|
|
283
|
+
- Automatically updates both `apps/website` and `apps/voltaire` with the new dev version
|
|
269
284
|
|
|
270
285
|
2. Update Pre-Release Version:
|
|
271
286
|
|
|
272
|
-
-
|
|
287
|
+
- Commits all changes (UI package.json, app package.json files, and lockfiles) in a single atomic commit
|
|
288
|
+
- Pushes the commit and tag to origin
|
|
273
289
|
|
|
274
|
-
This will trigger a build of the review app.
|
|
290
|
+
This will trigger a build of the review app with the pre-release version installed in both consuming apps.
|
|
275
291
|
|
|
276
292
|
### Components
|
|
277
293
|
|
|
@@ -282,8 +298,8 @@ All components live in `src` and follow a directory and filename convention:
|
|
|
282
298
|
- module directory (TitleCase)
|
|
283
299
|
- module asset files: `scripts.js` for JavaScript and `styles.css` for CSS
|
|
284
300
|
- component directory (TitleCase)
|
|
285
|
-
- `component.js` - supporting
|
|
286
|
-
- `component.css` - additional CSS
|
|
301
|
+
- `component.js` - supporting JS script (legacy)
|
|
302
|
+
- `component.css` - additional CSS (legacy)
|
|
287
303
|
- `[ComponentName].stories.tsx` - if React, a Storybook presentation file
|
|
288
304
|
- if React, `[ComponentName].tsx` at a sibling level to the component directory
|
|
289
305
|
|
|
@@ -326,13 +342,13 @@ We use [Semantic Versioning 2.0.0](https://semver.org/) to version different lib
|
|
|
326
342
|
|
|
327
343
|
Packages are published to the [GitHub private registry](https://github.com/features/packages).
|
|
328
344
|
|
|
329
|
-
Publishing is done by tagging a release in GitHub. This triggers a GitHub action that pushes to the
|
|
345
|
+
Publishing is done by tagging a release in GitHub. This triggers a GitHub action that pushes to the NPM registry as well as deploying Storybook to the [ably/ably-ui](https://github.com/ably/ably-ui) repository, with the version taken from the tag of the GitHub release.
|
|
330
346
|
|
|
331
|
-
|
|
347
|
+
After publishing, you can manually trigger the `update-ably-ui` workflow to create a single draft PR that updates both [Voltaire](http://github.com/ably/voltaire) and [Website](http://github.com/ably/website) with the new ably-ui version.
|
|
332
348
|
|
|
333
349
|
**To trigger a release:**
|
|
334
350
|
|
|
335
|
-
- Make sure you have run pre-release script `./pre-release.sh` (This updates the npm package version for ably-ui in `package.json`).
|
|
351
|
+
- Make sure you have run the pre-release script `./scripts/pre-release.sh` (This updates the npm package version for ably-ui in `package.json` and updates both consuming apps).
|
|
336
352
|
- Merge your PR into `main` after it has been approved.
|
|
337
353
|
- On the Github [Ably-UI](http://github.com/ably/ably-ui) repo, [create a new release](https://github.com/ably/ably-ui/releases/new) tag.
|
|
338
354
|
- Create a new tag with the new version number for the release.
|
|
@@ -341,14 +357,50 @@ This will trigger GitHub actions in supported apps (currently [Voltaire](http://
|
|
|
341
357
|
- Click on the Autogenerate release notes button.
|
|
342
358
|
- Publish Release.
|
|
343
359
|
- Check the Github `Actions` tab in the repo to make sure the release is green.
|
|
344
|
-
- Upon successful release, a compiled version of the Storybook site will be deployed to
|
|
360
|
+
- Upon successful release, a compiled version of the Storybook site will be deployed to the [ably/ably-ui](https://github.com/ably/ably-ui) repository's gh-pages branch.
|
|
361
|
+
- Manually trigger the `update-ably-ui` workflow from the Actions tab to create a draft PR updating both apps.
|
|
362
|
+
|
|
363
|
+
This will publish the package to NPM and deploy a new Storybook site to [https://ably.github.io/ably-ui/](https://ably.github.io/ably-ui/). To update the consuming apps, manually trigger the workflow, which will create a single draft PR for both Voltaire and Website that requires review before merging.
|
|
364
|
+
|
|
365
|
+
### Tagging Convention (Monorepo)
|
|
366
|
+
|
|
367
|
+
In the monorepo, ably-ui uses **component-prefixed tags** to enable independent releases:
|
|
368
|
+
|
|
369
|
+
**Release tags:** `ui-<version>` (e.g., `ui-17.13.2`)
|
|
370
|
+
- Used for production NPM releases
|
|
371
|
+
- Created via GitHub Releases
|
|
372
|
+
- Do NOT include `v` prefix
|
|
373
|
+
|
|
374
|
+
**Pre-release tags:** `ui-v<version>-dev.<sha>` (e.g., `ui-v17.13.2-dev.a1b2c3d`)
|
|
375
|
+
- Created automatically by `./scripts/pre-release.sh`
|
|
376
|
+
- Published to NPM with `dev` tag
|
|
377
|
+
- Includes `v` prefix and commit SHA
|
|
345
378
|
|
|
346
|
-
|
|
379
|
+
See the [root docs/TAGGING.md](../../docs/TAGGING.md) for complete details on the monorepo tagging convention.
|
|
380
|
+
|
|
381
|
+
### Review Apps
|
|
382
|
+
|
|
383
|
+
Review apps allow you to create temporary deployments of Storybook for sharing UI changes with stakeholders without requiring local development setup.
|
|
384
|
+
|
|
385
|
+
To create a review app:
|
|
386
|
+
|
|
387
|
+
1. Create a pull request with your changes
|
|
388
|
+
2. Add the `review-app` label to your PR
|
|
389
|
+
3. A Heroku review app will be automatically created and deployed
|
|
390
|
+
4. The deployment will appear in the deployments section of your PR (basic auth is enabled - ask fellow contributors for credentials if needed)
|
|
391
|
+
|
|
392
|
+
Review apps are automatically cleaned up when the PR is closed or the label is removed. Only repository contributors can create review apps.
|
|
347
393
|
|
|
348
394
|
### Running tests
|
|
349
395
|
|
|
350
|
-
`ably-ui` uses Storybook
|
|
396
|
+
`ably-ui` uses [vitest](https://vitest.dev/) with the [Storybook addon for vitest](https://storybook.js.org/docs/writing-tests/integrations/vitest-addon) to automatically turn all stories into executable tests. This means that we don't have to explicitly write tests for stories, though we have the ability to write [play functions](https://storybook.js.org/docs/writing-stories/play-function), which allow us to test more detailed interactions.
|
|
351
397
|
|
|
352
|
-
|
|
398
|
+
The tests run in a browser environment using Playwright, providing comprehensive visual regression testing and interaction testing capabilities.
|
|
399
|
+
|
|
400
|
+
You can run the tests locally using:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
pnpm test
|
|
404
|
+
```
|
|
353
405
|
|
|
354
|
-
|
|
406
|
+
This will run all story tests using vitest in a headless browser environment.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Accordion/types.ts"],"sourcesContent":["import { ReactNode } from \"react\";\nimport { IconName, IconSize } from \"../Icon/types\";\nimport { ColorThemeSet } from \"../styles/colors/types\";\n\n/**\n * Represents the data structure for an Accordion component.\n */\nexport type AccordionData = {\n /**\n * The name of the accordion item.\n */\n name: string;\n\n /**\n * The optional icon name to be displayed alongside the accordion item.\n */\n icon?: IconName | AccordionIcon;\n\n /**\n * The content to be displayed when the accordion item is expanded.\n */\n content: ReactNode;\n\n /**\n * Optional click handler function that is called when the accordion item is clicked.\n * @param index - The index of the clicked accordion item.\n */\n onClick?: (index: number) => void;\n\n /**\n * Indicates whether the accordion item is interactive.\n * When false, the item cannot be expanded or collapsed by user interaction.\n * @default true\n */\n interactive?: boolean;\n};\n\nexport type AccordionIcon = {\n name: IconName;\n css?: string;\n};\n\nexport type AccordionIcons = {\n closed: AccordionIcon;\n open: AccordionIcon;\n};\n\nexport const accordionThemes = [\"default\", \"transparent\", \"static\"] as const;\n\nexport type AccordionTheme = (typeof accordionThemes)[number];\n\n/**\n * Represents the theme colors for an accordion component.\n */\nexport type AccordionThemeColors = {\n /**\n * Background color class for the accordion.\n */\n bg: ColorThemeSet;\n\n /**\n * Background color when the accordion item is hovered.\n */\n hoverBg: ColorThemeSet;\n\n /**\n * Text color class for the accordion.\n */\n text: ColorThemeSet;\n\n /**\n * Color class for the toggle icon of the accordion.\n */\n toggleIconColor: ColorThemeSet;\n\n /**\n * Optional background color class for selectable accordion items.\n */\n selectableBg?: ColorThemeSet;\n\n /**\n * Optional text color class for selectable accordion items.\n */\n selectableText?: ColorThemeSet;\n\n /**\n * Optional border color for the accordion.\n */\n border?: string;\n};\n\n/**\n * Options for configuring the Accordion component.\n */\nexport type AccordionOptions = {\n /**\n * If true, only one accordion item can be open at a time.\n * @default false\n */\n autoClose?: boolean;\n\n /**\n * If true, accordion items can be selected.\n * @default false\n */\n selectable?: boolean;\n\n /**\n * If true, the accordion header will stick to the top when scrolling.\n * @default false\n */\n sticky?: boolean;\n\n /**\n * An array of indexes indicating which accordion items should be open by default.\n * @default []\n */\n defaultOpenIndexes?: number[];\n\n /**\n * If true, all accordion items will be fully open.\n * @default false\n */\n fullyOpen?: boolean;\n\n /**\n * Custom CSS class to apply to the accordion header.\n * @default \"\"\n */\n headerCSS?: string;\n\n /**\n * If true, borders between accordion items will be hidden.\n * @default false\n */\n hideBorders?: boolean;\n\n /**\n * Size of the row icon.\n * @default \"32px\"\n */\n rowIconSize?: IconSize;\n\n /**\n * Size of the accordion icon.\n * @default \"16px\"\n */\n iconSize?: IconSize;\n\n /**\n * Custom CSS classes to apply to the selected accordion header.\n * @default \"\"\n */\n selectedHeaderCSS?: string;\n\n /**\n * Custom CSS classes to apply to the accordion content.\n * @default \"\"\n */\n contentCSS?: string;\n};\n"],"names":["accordionThemes"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Accordion/types.ts"],"sourcesContent":["import { ReactNode } from \"react\";\nimport { IconName, IconSize } from \"../Icon/types\";\nimport { ColorThemeSet } from \"../styles/colors/types\";\n\n/**\n * Represents the data structure for an Accordion component.\n */\nexport type AccordionData = {\n /**\n * The name of the accordion item.\n */\n name: string;\n\n /**\n * Custom heading content. If provided, this will be used instead of `name`.\n * Can be a ReactNode or a function that receives the index and isOpen state\n * and returns ReactNode.\n */\n heading?: ReactNode | ((index: number, isOpen: boolean) => ReactNode);\n\n /**\n * The optional icon name to be displayed alongside the accordion item.\n */\n icon?: IconName | AccordionIcon;\n\n /**\n * The content to be displayed when the accordion item is expanded.\n */\n content: ReactNode;\n\n /**\n * Optional click handler function that is called when the accordion item is clicked.\n * @param index - The index of the clicked accordion item.\n */\n onClick?: (index: number) => void;\n\n /**\n * Indicates whether the accordion item is interactive.\n * When false, the item cannot be expanded or collapsed by user interaction.\n * @default true\n */\n interactive?: boolean;\n};\n\nexport type AccordionIcon = {\n name: IconName;\n css?: string;\n};\n\nexport type AccordionIcons = {\n closed: AccordionIcon;\n open: AccordionIcon;\n};\n\nexport const accordionThemes = [\"default\", \"transparent\", \"static\"] as const;\n\nexport type AccordionTheme = (typeof accordionThemes)[number];\n\n/**\n * Represents the theme colors for an accordion component.\n */\nexport type AccordionThemeColors = {\n /**\n * Background color class for the accordion.\n */\n bg: ColorThemeSet;\n\n /**\n * Background color when the accordion item is hovered.\n */\n hoverBg: ColorThemeSet;\n\n /**\n * Text color class for the accordion.\n */\n text: ColorThemeSet;\n\n /**\n * Color class for the toggle icon of the accordion.\n */\n toggleIconColor: ColorThemeSet;\n\n /**\n * Optional background color class for selectable accordion items.\n */\n selectableBg?: ColorThemeSet;\n\n /**\n * Optional text color class for selectable accordion items.\n */\n selectableText?: ColorThemeSet;\n\n /**\n * Optional border color for the accordion.\n */\n border?: string;\n};\n\n/**\n * Options for configuring the Accordion component.\n */\nexport type AccordionOptions = {\n /**\n * If true, only one accordion item can be open at a time.\n * @default false\n */\n autoClose?: boolean;\n\n /**\n * If true, accordion items can be selected.\n * @default false\n */\n selectable?: boolean;\n\n /**\n * If true, the accordion header will stick to the top when scrolling.\n * @default false\n */\n sticky?: boolean;\n\n /**\n * An array of indexes indicating which accordion items should be open by default.\n * @default []\n */\n defaultOpenIndexes?: number[];\n\n /**\n * If true, all accordion items will be fully open.\n * @default false\n */\n fullyOpen?: boolean;\n\n /**\n * Custom CSS class to apply to the accordion header.\n * @default \"\"\n */\n headerCSS?: string;\n\n /**\n * If true, borders between accordion items will be hidden.\n * @default false\n */\n hideBorders?: boolean;\n\n /**\n * Size of the row icon.\n * @default \"32px\"\n */\n rowIconSize?: IconSize;\n\n /**\n * Size of the accordion icon.\n * @default \"16px\"\n */\n iconSize?: IconSize;\n\n /**\n * Custom CSS classes to apply to the selected accordion header.\n * @default \"\"\n */\n selectedHeaderCSS?: string;\n\n /**\n * Custom CSS classes to apply to the accordion content.\n * @default \"\"\n */\n contentCSS?: string;\n\n /**\n * Custom CSS classes to apply to the accordion item wrapper when it is open/active.\n * @default \"\"\n */\n selectedItemCSS?: string;\n};\n"],"names":["accordionThemes"],"mappings":"AAsDA,OAAO,MAAMA,gBAAkB,CAAC,UAAW,cAAe,SAAS,AAAU"}
|
package/core/Accordion/utils.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const themeClasses={default:{bg:"bg-neutral-200 dark:bg-neutral-1100",hoverBg:"hover:bg-neutral-300 dark:hover:bg-neutral-1100",text:"text-neutral-1300 dark:text-white",toggleIconColor:"text-neutral-1000 dark:text-orange-600",selectableBg:"bg-neutral-1200 dark:bg-neutral-300",selectableText:"text-neutral-000 dark:text-neutral-1300"},transparent:{bg:"bg-transparent dark:bg-transparent",hoverBg:"hover:bg-transparent dark:hover:bg-transparent",text:"text-neutral-1000 dark:text-neutral-000",toggleIconColor:"text-
|
|
1
|
+
export const themeClasses={default:{bg:"bg-neutral-200 dark:bg-neutral-1100",hoverBg:"hover:bg-neutral-300 dark:hover:bg-neutral-1100",text:"text-neutral-1300 dark:text-white",toggleIconColor:"text-neutral-1000 dark:text-orange-600",selectableBg:"bg-neutral-1200 dark:bg-neutral-300",selectableText:"text-neutral-000 dark:text-neutral-1300"},transparent:{bg:"bg-transparent dark:bg-transparent",hoverBg:"hover:bg-transparent dark:hover:bg-transparent",text:"text-neutral-1000 dark:text-neutral-000",toggleIconColor:"text-neutral-700 dark:text-neutral-600",border:"border-neutral-500 border-b last:border-none dark:border-neutral-1000"},static:{bg:"bg-neutral-200 dark:bg-neutral-1200",hoverBg:"hover:bg-neutral-200 dark:hover:bg-neutral-1200",text:"text-neutral-1300 dark:text-white",toggleIconColor:"text-neutral-200 dark:text-neutral-1200",selectableBg:"bg-neutral-1200 dark:bg-neutral-1200",selectableText:"text-white dark:text-neutral-1300"}};export const isNonTransparentTheme=theme=>theme!=="transparent";export const isStaticTheme=theme=>theme==="static";
|
|
2
2
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Accordion/utils.ts"],"sourcesContent":["import { AccordionTheme, AccordionThemeColors } from \"./types\";\n\nexport const themeClasses: Record<AccordionTheme, AccordionThemeColors> = {\n default: {\n bg: \"bg-neutral-200 dark:bg-neutral-1100\",\n hoverBg: \"hover:bg-neutral-300 dark:hover:bg-neutral-1100\",\n text: \"text-neutral-1300 dark:text-white\",\n toggleIconColor: \"text-neutral-1000 dark:text-orange-600\",\n selectableBg: \"bg-neutral-1200 dark:bg-neutral-300\",\n selectableText: \"text-neutral-000 dark:text-neutral-1300\",\n },\n transparent: {\n bg: \"bg-transparent dark:bg-transparent\",\n hoverBg: \"hover:bg-transparent dark:hover:bg-transparent\",\n text: \"text-neutral-1000 dark:text-neutral-000\",\n toggleIconColor: \"text-
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Accordion/utils.ts"],"sourcesContent":["import { AccordionTheme, AccordionThemeColors } from \"./types\";\n\nexport const themeClasses: Record<AccordionTheme, AccordionThemeColors> = {\n default: {\n bg: \"bg-neutral-200 dark:bg-neutral-1100\",\n hoverBg: \"hover:bg-neutral-300 dark:hover:bg-neutral-1100\",\n text: \"text-neutral-1300 dark:text-white\",\n toggleIconColor: \"text-neutral-1000 dark:text-orange-600\",\n selectableBg: \"bg-neutral-1200 dark:bg-neutral-300\",\n selectableText: \"text-neutral-000 dark:text-neutral-1300\",\n },\n transparent: {\n bg: \"bg-transparent dark:bg-transparent\",\n hoverBg: \"hover:bg-transparent dark:hover:bg-transparent\",\n text: \"text-neutral-1000 dark:text-neutral-000\",\n toggleIconColor: \"text-neutral-700 dark:text-neutral-600\",\n border:\n \"border-neutral-500 border-b last:border-none dark:border-neutral-1000\",\n },\n static: {\n bg: \"bg-neutral-200 dark:bg-neutral-1200\",\n hoverBg: \"hover:bg-neutral-200 dark:hover:bg-neutral-1200\",\n text: \"text-neutral-1300 dark:text-white\",\n toggleIconColor: \"text-neutral-200 dark:text-neutral-1200\",\n selectableBg: \"bg-neutral-1200 dark:bg-neutral-1200\",\n selectableText: \"text-white dark:text-neutral-1300\",\n },\n};\n\nexport const isNonTransparentTheme = (theme: AccordionTheme) =>\n theme !== \"transparent\";\n\nexport const isStaticTheme = (theme: AccordionTheme) => theme === \"static\";\n"],"names":["themeClasses","default","bg","hoverBg","text","toggleIconColor","selectableBg","selectableText","transparent","border","static","isNonTransparentTheme","theme","isStaticTheme"],"mappings":"AAEA,OAAO,MAAMA,aAA6D,CACxEC,QAAS,CACPC,GAAI,sCACJC,QAAS,kDACTC,KAAM,oCACNC,gBAAiB,yCACjBC,aAAc,sCACdC,eAAgB,yCAClB,EACAC,YAAa,CACXN,GAAI,qCACJC,QAAS,iDACTC,KAAM,0CACNC,gBAAiB,yCACjBI,OACE,uEACJ,EACAC,OAAQ,CACNR,GAAI,sCACJC,QAAS,kDACTC,KAAM,oCACNC,gBAAiB,0CACjBC,aAAc,uCACdC,eAAgB,mCAClB,CACF,CAAE,AAEF,QAAO,MAAMI,sBAAwB,AAACC,OACpCA,QAAU,aAAc,AAE1B,QAAO,MAAMC,cAAgB,AAACD,OAA0BA,QAAU,QAAS"}
|
package/core/Accordion.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useMemo,useState,forwardRef,useEffect}from"react";import{AccordionContent,AccordionItem,AccordionTrigger,Accordion as RadixAccordion}from"@radix-ui/react-accordion";import Icon from"./Icon";import{themeClasses,isNonTransparentTheme,isStaticTheme}from"./Accordion/utils";import cn from"./utils/cn";const AccordionRow=({name,children,rowIcon,options,toggleIcons,theme,index,onClick,openRowValues,rowInteractive=true})=>{const{selectable,sticky}=options||{};const rowKey=`accordion-item-${index}`;const isOpen=openRowValues.includes(rowKey);const{text,bg,hoverBg,selectableBg,selectableText,border,toggleIconColor}=themeClasses[theme];const textClass=selectable&&isOpen&&selectableText||text;return React.createElement(AccordionItem,{value:rowKey,className:cn({[`${border}`]:border&&!options?.hideBorders})},React.createElement(AccordionTrigger,{onClick:onClick,className:cn({"flex w-full group/accordion-trigger py-4 ui-text-p1 font-bold text-left items-center gap-3 transition-colors focus:outline-none":true,"px-4 mb-4 rounded-lg":isNonTransparentTheme(theme),"px-0 rounded-none":!isNonTransparentTheme(theme),"pointer-events-none focus-visible:outline-none":isStaticTheme(theme),"focus-base":!isStaticTheme(theme),"sticky top-0":sticky,[`${bg} ${hoverBg} ${text}`]:!(selectable&&isOpen),[`${selectableBg} ${selectableText}`]:selectable&&isOpen,[options?.headerCSS??""]:options?.headerCSS,[options?.selectedHeaderCSS??""]:options?.selectedHeaderCSS&&isOpen})},rowIcon?React.createElement(Icon,{name:typeof rowIcon==="object"?rowIcon.name:rowIcon,color:textClass,additionalCSS:typeof rowIcon==="object"&&rowIcon.css?rowIcon.css:"",size:options?.rowIconSize??"32px"}):null,
|
|
1
|
+
import React,{useMemo,useState,forwardRef,useEffect}from"react";import{AccordionContent,AccordionItem,AccordionTrigger,Accordion as RadixAccordion}from"@radix-ui/react-accordion";import Icon from"./Icon";import{themeClasses,isNonTransparentTheme,isStaticTheme}from"./Accordion/utils";import cn from"./utils/cn";const AccordionRow=({name,heading,children,rowIcon,options,toggleIcons,theme,index,onClick,openRowValues,rowInteractive=true})=>{const{selectable,sticky}=options||{};const rowKey=`accordion-item-${index}`;const isOpen=openRowValues.includes(rowKey);const{text,bg,hoverBg,selectableBg,selectableText,border,toggleIconColor}=themeClasses[theme];const textClass=selectable&&isOpen&&selectableText||text;const renderHeading=()=>{if(heading){if(typeof heading==="function"){return heading(index,isOpen)}return heading}return React.createElement("span",null,name)};return React.createElement(AccordionItem,{value:rowKey,className:cn({[`${border}`]:border&&!options?.hideBorders,[`${options?.selectedItemCSS}`]:options?.selectedItemCSS&&isOpen})},React.createElement(AccordionTrigger,{onClick:onClick,className:cn({"flex w-full group/accordion-trigger py-4 ui-text-p1 font-bold text-left items-center gap-3 transition-colors focus:outline-none":true,"px-4 mb-4 rounded-lg":isNonTransparentTheme(theme),"px-0 rounded-none":!isNonTransparentTheme(theme),"pointer-events-none focus-visible:outline-none":isStaticTheme(theme),"focus-base":!isStaticTheme(theme),"sticky top-0":sticky,[`${bg} ${hoverBg} ${text}`]:!(selectable&&isOpen),[`${selectableBg} ${selectableText}`]:selectable&&isOpen,[options?.headerCSS??""]:options?.headerCSS,[options?.selectedHeaderCSS??""]:options?.selectedHeaderCSS&&isOpen})},rowIcon?React.createElement(Icon,{name:typeof rowIcon==="object"?rowIcon.name:rowIcon,color:textClass,additionalCSS:typeof rowIcon==="object"&&rowIcon.css?rowIcon.css:"",size:options?.rowIconSize??"32px"}):null,renderHeading(),!selectable&&!isStaticTheme(theme)&&rowInteractive?React.createElement("span",{className:"flex-1 justify-end flex items-center"},React.createElement(Icon,{name:isOpen?toggleIcons.open.name:toggleIcons.closed.name,color:toggleIconColor,additionalCSS:isOpen?typeof toggleIcons.open==="object"&&toggleIcons.open.css||"":typeof toggleIcons.closed==="object"&&toggleIcons.closed.css||"",size:options?.iconSize??"16px"})):null),rowInteractive&&React.createElement(AccordionContent,{className:cn({"ui-text-p2 overflow-hidden transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down":true,[options?.contentCSS??""]:options?.contentCSS})},React.createElement("div",{className:"pb-4"},children)))};const Accordion=forwardRef(({data,theme="transparent",icons={closed:{name:"icon-gui-plus-outline"},open:{name:"icon-gui-minus-outline"}},options,...props},ref)=>{const openIndexes=useMemo(()=>{const indexValues=data.map((_,i)=>`accordion-item-${i}`);return options?.fullyOpen?indexValues:indexValues.filter((_,index)=>options?.defaultOpenIndexes?.includes(index))},[data,options?.fullyOpen,options?.defaultOpenIndexes]);const[openRowValues,setOpenRowValues]=useState(openIndexes);useEffect(()=>{setOpenRowValues(openIndexes)},[openIndexes]);const innerAccordion=data.map((item,index)=>React.createElement(AccordionRow,{key:item.name,name:item.name,heading:item.heading,rowIcon:item.icon,toggleIcons:icons,theme:theme,options:options,index:index,onClick:()=>{item.onClick?.(index)},openRowValues:openRowValues,rowInteractive:item.interactive},item.content));return React.createElement("div",{ref:ref,...props},options?.autoClose?React.createElement(RadixAccordion,{type:"single",collapsible:true,value:openRowValues[0],onValueChange:values=>setOpenRowValues([values])},innerAccordion):React.createElement(RadixAccordion,{type:"multiple",value:openRowValues,onValueChange:values=>setOpenRowValues(values)},innerAccordion))});Accordion.displayName="Accordion";export default Accordion;
|
|
2
2
|
//# sourceMappingURL=Accordion.js.map
|
package/core/Accordion.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Accordion.tsx"],"sourcesContent":["import React, {\n ReactNode,\n useMemo,\n useState,\n forwardRef,\n useEffect,\n} from \"react\";\nimport {\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n Accordion as RadixAccordion,\n} from \"@radix-ui/react-accordion\";\n\nimport Icon from \"./Icon\";\nimport type { IconName } from \"./Icon/types\";\nimport type {\n AccordionData,\n AccordionIcon,\n AccordionIcons,\n AccordionOptions,\n AccordionTheme,\n} from \"./Accordion/types\";\nimport {\n themeClasses,\n isNonTransparentTheme,\n isStaticTheme,\n} from \"./Accordion/utils\";\nimport cn from \"./utils/cn\";\n\ntype AccordionRowProps = {\n children: ReactNode;\n name: string;\n rowIcon?: IconName | AccordionIcon;\n theme: AccordionTheme;\n toggleIcons: AccordionIcons;\n options?: AccordionOptions;\n index: number;\n onClick: () => void;\n openRowValues: string[];\n rowInteractive?: boolean;\n};\n\nexport type AccordionProps = {\n /**\n * The data for the accordion items.\n */\n data: AccordionData[];\n\n /**\n * Icons for the accordion toggle.\n */\n icons?: AccordionIcons;\n\n /**\n * Theme for the accordion.\n */\n theme?: AccordionTheme;\n\n /**\n * Options for the accordion behavior.\n */\n options?: AccordionOptions;\n} & React.HTMLAttributes<HTMLDivElement>;\n\nconst AccordionRow = ({\n name,\n children,\n rowIcon,\n options,\n toggleIcons,\n theme,\n index,\n onClick,\n openRowValues,\n rowInteractive = true,\n}: AccordionRowProps) => {\n const { selectable, sticky } = options || {};\n const rowKey = `accordion-item-${index}`;\n const isOpen = openRowValues.includes(rowKey);\n\n const {\n text,\n bg,\n hoverBg,\n selectableBg,\n selectableText,\n border,\n toggleIconColor,\n } = themeClasses[theme];\n\n const textClass = (selectable && isOpen && selectableText) || text;\n\n return (\n <AccordionItem\n value={rowKey}\n className={cn({\n [`${border}`]: border && !options?.hideBorders,\n })}\n >\n <AccordionTrigger\n onClick={onClick}\n className={cn({\n \"flex w-full group/accordion-trigger py-4 ui-text-p1 font-bold text-left items-center gap-3 transition-colors focus:outline-none\":\n true,\n \"px-4 mb-4 rounded-lg\": isNonTransparentTheme(theme),\n \"px-0 rounded-none\": !isNonTransparentTheme(theme),\n \"pointer-events-none focus-visible:outline-none\":\n isStaticTheme(theme),\n \"focus-base\": !isStaticTheme(theme),\n \"sticky top-0\": sticky,\n [`${bg} ${hoverBg} ${text}`]: !(selectable && isOpen),\n [`${selectableBg} ${selectableText}`]: selectable && isOpen,\n [options?.headerCSS ?? \"\"]: options?.headerCSS,\n [options?.selectedHeaderCSS ?? \"\"]:\n options?.selectedHeaderCSS && isOpen,\n })}\n >\n {rowIcon ? (\n <Icon\n name={typeof rowIcon === \"object\" ? rowIcon.name : rowIcon}\n color={textClass}\n additionalCSS={\n typeof rowIcon === \"object\" && rowIcon.css ? rowIcon.css : \"\"\n }\n size={options?.rowIconSize ?? \"32px\"}\n />\n ) : null}\n <span>{name}</span>\n {!selectable && !isStaticTheme(theme) && rowInteractive ? (\n <span className=\"flex-1 justify-end flex items-center\">\n <Icon\n name={isOpen ? toggleIcons.open.name : toggleIcons.closed.name}\n color={toggleIconColor}\n size={options?.iconSize ?? \"16px\"}\n />\n </span>\n ) : null}\n </AccordionTrigger>\n {rowInteractive && (\n <AccordionContent\n className={cn({\n \"ui-text-p2 overflow-hidden transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\":\n true,\n [options?.contentCSS ?? \"\"]: options?.contentCSS,\n })}\n >\n <div className=\"pb-4\">{children}</div>\n </AccordionContent>\n )}\n </AccordionItem>\n );\n};\n\nconst Accordion = forwardRef<HTMLDivElement, AccordionProps>(\n (\n {\n data,\n theme = \"transparent\",\n icons = {\n closed: { name: \"icon-gui-plus-outline\" },\n open: { name: \"icon-gui-minus-outline\" },\n },\n options,\n ...props\n },\n ref,\n ) => {\n const openIndexes = useMemo(() => {\n const indexValues = data.map((_, i) => `accordion-item-${i}`);\n return options?.fullyOpen\n ? indexValues\n : indexValues.filter((_, index) =>\n options?.defaultOpenIndexes?.includes(index),\n );\n }, [options?.defaultOpenIndexes, options?.fullyOpen, data.length]);\n\n const [openRowValues, setOpenRowValues] = useState<string[]>(openIndexes);\n\n useEffect(() => {\n setOpenRowValues(openIndexes);\n }, [openIndexes]);\n\n const innerAccordion = data.map((item, index) => (\n <AccordionRow\n key={item.name}\n name={item.name}\n rowIcon={item.icon}\n toggleIcons={icons}\n theme={theme}\n options={options}\n index={index}\n onClick={() => {\n item.onClick?.(index);\n }}\n openRowValues={openRowValues}\n rowInteractive={item.interactive}\n >\n {item.content}\n </AccordionRow>\n ));\n\n return (\n <div ref={ref} {...props}>\n {options?.autoClose ? (\n <RadixAccordion\n type=\"single\"\n collapsible\n value={openRowValues[0]}\n onValueChange={(values) => setOpenRowValues([values])}\n >\n {innerAccordion}\n </RadixAccordion>\n ) : (\n <RadixAccordion\n type=\"multiple\"\n value={openRowValues}\n onValueChange={(values) => setOpenRowValues(values)}\n >\n {innerAccordion}\n </RadixAccordion>\n )}\n </div>\n );\n },\n);\n\nAccordion.displayName = \"Accordion\";\n\nexport default Accordion;\n"],"names":["React","useMemo","useState","forwardRef","useEffect","AccordionContent","AccordionItem","AccordionTrigger","Accordion","RadixAccordion","Icon","themeClasses","isNonTransparentTheme","isStaticTheme","cn","AccordionRow","name","children","rowIcon","options","toggleIcons","theme","index","onClick","openRowValues","rowInteractive","selectable","sticky","rowKey","isOpen","includes","text","bg","hoverBg","selectableBg","selectableText","border","toggleIconColor","textClass","value","className","hideBorders","headerCSS","selectedHeaderCSS","color","additionalCSS","css","size","rowIconSize","span","open","closed","iconSize","contentCSS","div","data","icons","props","ref","openIndexes","indexValues","map","_","i","fullyOpen","filter","defaultOpenIndexes","length","setOpenRowValues","innerAccordion","item","key","icon","interactive","content","autoClose","type","collapsible","onValueChange","values","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/Accordion.tsx"],"sourcesContent":["import React, {\n ReactNode,\n useMemo,\n useState,\n forwardRef,\n useEffect,\n} from \"react\";\nimport {\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n Accordion as RadixAccordion,\n} from \"@radix-ui/react-accordion\";\n\nimport Icon from \"./Icon\";\nimport type { IconName } from \"./Icon/types\";\nimport type {\n AccordionData,\n AccordionIcon,\n AccordionIcons,\n AccordionOptions,\n AccordionTheme,\n} from \"./Accordion/types\";\nimport {\n themeClasses,\n isNonTransparentTheme,\n isStaticTheme,\n} from \"./Accordion/utils\";\nimport cn from \"./utils/cn\";\n\ntype AccordionRowProps = {\n children: ReactNode;\n name: string;\n heading?: ReactNode | ((index: number, isOpen: boolean) => ReactNode);\n rowIcon?: IconName | AccordionIcon;\n theme: AccordionTheme;\n toggleIcons: AccordionIcons;\n options?: AccordionOptions;\n index: number;\n onClick: () => void;\n openRowValues: string[];\n rowInteractive?: boolean;\n};\n\nexport type AccordionProps = {\n /**\n * The data for the accordion items.\n */\n data: AccordionData[];\n\n /**\n * Icons for the accordion toggle.\n */\n icons?: AccordionIcons;\n\n /**\n * Theme for the accordion.\n */\n theme?: AccordionTheme;\n\n /**\n * Options for the accordion behavior.\n */\n options?: AccordionOptions;\n} & React.HTMLAttributes<HTMLDivElement>;\n\nconst AccordionRow = ({\n name,\n heading,\n children,\n rowIcon,\n options,\n toggleIcons,\n theme,\n index,\n onClick,\n openRowValues,\n rowInteractive = true,\n}: AccordionRowProps) => {\n const { selectable, sticky } = options || {};\n const rowKey = `accordion-item-${index}`;\n const isOpen = openRowValues.includes(rowKey);\n\n const {\n text,\n bg,\n hoverBg,\n selectableBg,\n selectableText,\n border,\n toggleIconColor,\n } = themeClasses[theme];\n\n const textClass = (selectable && isOpen && selectableText) || text;\n\n // Render custom heading or fallback to name\n const renderHeading = () => {\n if (heading) {\n if (typeof heading === \"function\") {\n return heading(index, isOpen);\n }\n return heading;\n }\n return <span>{name}</span>;\n };\n\n return (\n <AccordionItem\n value={rowKey}\n className={cn({\n [`${border}`]: border && !options?.hideBorders,\n [`${options?.selectedItemCSS}`]: options?.selectedItemCSS && isOpen,\n })}\n >\n <AccordionTrigger\n onClick={onClick}\n className={cn({\n \"flex w-full group/accordion-trigger py-4 ui-text-p1 font-bold text-left items-center gap-3 transition-colors focus:outline-none\": true,\n \"px-4 mb-4 rounded-lg\": isNonTransparentTheme(theme),\n \"px-0 rounded-none\": !isNonTransparentTheme(theme),\n \"pointer-events-none focus-visible:outline-none\":\n isStaticTheme(theme),\n \"focus-base\": !isStaticTheme(theme),\n \"sticky top-0\": sticky,\n [`${bg} ${hoverBg} ${text}`]: !(selectable && isOpen),\n [`${selectableBg} ${selectableText}`]: selectable && isOpen,\n [options?.headerCSS ?? \"\"]: options?.headerCSS,\n [options?.selectedHeaderCSS ?? \"\"]:\n options?.selectedHeaderCSS && isOpen,\n })}\n >\n {rowIcon ? (\n <Icon\n name={typeof rowIcon === \"object\" ? rowIcon.name : rowIcon}\n color={textClass}\n additionalCSS={\n typeof rowIcon === \"object\" && rowIcon.css ? rowIcon.css : \"\"\n }\n size={options?.rowIconSize ?? \"32px\"}\n />\n ) : null}\n {renderHeading()}\n {!selectable && !isStaticTheme(theme) && rowInteractive ? (\n <span className=\"flex-1 justify-end flex items-center\">\n <Icon\n name={isOpen ? toggleIcons.open.name : toggleIcons.closed.name}\n color={toggleIconColor}\n additionalCSS={\n isOpen\n ? (typeof toggleIcons.open === \"object\" &&\n toggleIcons.open.css) ||\n \"\"\n : (typeof toggleIcons.closed === \"object\" &&\n toggleIcons.closed.css) ||\n \"\"\n }\n size={options?.iconSize ?? \"16px\"}\n />\n </span>\n ) : null}\n </AccordionTrigger>\n {rowInteractive && (\n <AccordionContent\n className={cn({\n \"ui-text-p2 overflow-hidden transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\": true,\n [options?.contentCSS ?? \"\"]: options?.contentCSS,\n })}\n >\n <div className=\"pb-4\">{children}</div>\n </AccordionContent>\n )}\n </AccordionItem>\n );\n};\n\nconst Accordion = forwardRef<HTMLDivElement, AccordionProps>(\n (\n {\n data,\n theme = \"transparent\",\n icons = {\n closed: { name: \"icon-gui-plus-outline\" },\n open: { name: \"icon-gui-minus-outline\" },\n },\n options,\n ...props\n },\n ref,\n ) => {\n const openIndexes = useMemo(() => {\n const indexValues = data.map((_, i) => `accordion-item-${i}`);\n return options?.fullyOpen\n ? indexValues\n : indexValues.filter((_, index) =>\n options?.defaultOpenIndexes?.includes(index),\n );\n }, [data, options?.fullyOpen, options?.defaultOpenIndexes]);\n\n const [openRowValues, setOpenRowValues] = useState<string[]>(openIndexes);\n\n useEffect(() => {\n setOpenRowValues(openIndexes);\n }, [openIndexes]);\n\n const innerAccordion = data.map((item, index) => (\n <AccordionRow\n key={item.name}\n name={item.name}\n heading={item.heading}\n rowIcon={item.icon}\n toggleIcons={icons}\n theme={theme}\n options={options}\n index={index}\n onClick={() => {\n item.onClick?.(index);\n }}\n openRowValues={openRowValues}\n rowInteractive={item.interactive}\n >\n {item.content}\n </AccordionRow>\n ));\n\n return (\n <div ref={ref} {...props}>\n {options?.autoClose ? (\n <RadixAccordion\n type=\"single\"\n collapsible\n value={openRowValues[0]}\n onValueChange={(values) => setOpenRowValues([values])}\n >\n {innerAccordion}\n </RadixAccordion>\n ) : (\n <RadixAccordion\n type=\"multiple\"\n value={openRowValues}\n onValueChange={(values) => setOpenRowValues(values)}\n >\n {innerAccordion}\n </RadixAccordion>\n )}\n </div>\n );\n },\n);\n\nAccordion.displayName = \"Accordion\";\n\nexport default Accordion;\n"],"names":["React","useMemo","useState","forwardRef","useEffect","AccordionContent","AccordionItem","AccordionTrigger","Accordion","RadixAccordion","Icon","themeClasses","isNonTransparentTheme","isStaticTheme","cn","AccordionRow","name","heading","children","rowIcon","options","toggleIcons","theme","index","onClick","openRowValues","rowInteractive","selectable","sticky","rowKey","isOpen","includes","text","bg","hoverBg","selectableBg","selectableText","border","toggleIconColor","textClass","renderHeading","span","value","className","hideBorders","selectedItemCSS","headerCSS","selectedHeaderCSS","color","additionalCSS","css","size","rowIconSize","open","closed","iconSize","contentCSS","div","data","icons","props","ref","openIndexes","indexValues","map","_","i","fullyOpen","filter","defaultOpenIndexes","setOpenRowValues","innerAccordion","item","key","icon","interactive","content","autoClose","type","collapsible","onValueChange","values","displayName"],"mappings":"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"}
|
package/core/Badge.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useMemo}from"react";import Icon from"./Icon";import cn from"./utils/cn";const Badge=({size="md",color="neutral",iconBefore,iconAfter,className,children,disabled=false,focusable=false,hoverable=false,iconSize
|
|
1
|
+
import React,{useMemo}from"react";import Icon from"./Icon";import cn from"./utils/cn";const defaultIconSizeByBadgeSize={lg:"16px",md:"15px",sm:"14px",xs:"13px"};const Badge=({size="md",color="neutral",iconBefore,iconAfter,className,childClassName,children,disabled=false,focusable=false,hoverable=false,iconSize,ariaLabel})=>{const sizeClass=useMemo(()=>{switch(size){case"xs":return"px-2 py-0 text-[10px] leading-tight";case"sm":return"px-2 py-0.5 text-[10px] leading-tight";case"md":return"px-2.5 py-0.5 text-[11px] leading-normal";case"lg":return"px-3 py-[0.1875rem] text-[12px] leading-normal"}},[size]);const childClass=useMemo(()=>{switch(size){case"xs":case"sm":return"leading-[18px]";case"md":case"lg":return"leading-[20px]"}},[size]);const colorClass=useMemo(()=>{switch(color){case"neutral":return"text-neutral-900 dark:text-neutral-400";case"violet":return"text-violet-400";case"orange":return"text-orange-600";case"yellow":return"text-yellow-600";case"green":return"text-green-600";case"blue":return"text-blue-600";case"pink":return"text-pink-600";case"red":return"text-orange-700"}},[color]);const computedIconSize=iconSize??defaultIconSizeByBadgeSize[size];return React.createElement("div",{className:cn("inline-flex bg-neutral-100 dark:bg-neutral-1200 rounded-2xl gap-1 items-center focus-base transition-colors select-none font-semibold",sizeClass,colorClass,{"focus-base":focusable},{"hover:bg-neutral-300 hover:dark:bg-neutral-1000 active:bg-neutral-300 dark:active:bg-neutral-1000":hoverable},{"cursor-not-allowed disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark":disabled},className),tabIndex:focusable?0:undefined,role:focusable?"button":undefined,"aria-label":focusable||hoverable?ariaLabel:undefined},iconBefore?React.createElement(Icon,{name:iconBefore,size:computedIconSize,color:colorClass}):null,React.createElement("span",{className:cn("whitespace-nowrap tracking-[0.04em]",childClass,childClassName)},children),iconAfter?React.createElement(Icon,{name:iconAfter,size:computedIconSize,color:colorClass}):null)};export default Badge;
|
|
2
2
|
//# sourceMappingURL=Badge.js.map
|
package/core/Badge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Badge.tsx"],"sourcesContent":["import React, { PropsWithChildren, useMemo } from \"react\";\nimport { IconName, IconSize } from \"./Icon/types\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\nimport { ColorClassColorGroups } from \"./styles/colors/types\";\n\n/**\n * Props for the Badge component.\n */\
|
|
1
|
+
{"version":3,"sources":["../../src/core/Badge.tsx"],"sourcesContent":["import React, { PropsWithChildren, useMemo } from \"react\";\nimport { IconName, IconSize } from \"./Icon/types\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\nimport { ColorClassColorGroups } from \"./styles/colors/types\";\n\n/**\n * Props for the Badge component.\n */\nexport interface BadgeProps {\n /**\n * The size of the badge. Can be one of \"xs\", \"sm\", \"md\", or \"lg\".\n */\n size?: \"xs\" | \"sm\" | \"md\" | \"lg\";\n\n /**\n * The color of the badge. Can be a value from ColorClassColorGroups or \"red\".\n */\n color?: ColorClassColorGroups | \"red\";\n\n /**\n * The name of the icon to be displayed before the children in the badge.\n */\n iconBefore?: IconName;\n\n /**\n * The name of the icon to be displayed after the children in the badge.\n */\n iconAfter?: IconName;\n\n /**\n * Additional CSS class names to apply to the badge.\n */\n className?: string;\n\n /**\n * Whether the badge is disabled. Defaults to false.\n */\n disabled?: boolean;\n\n /**\n * Whether the badge is focusable. Defaults to false.\n */\n focusable?: boolean;\n\n /**\n * Whether the badge is hoverable. Defaults to false.\n */\n hoverable?: boolean;\n\n /**\n * The size of the icons in the badge. If not provided, it will be derived from the badge size.\n */\n iconSize?: IconSize;\n\n /**\n * Accessible label for the badge when interactive\n */\n ariaLabel?: string;\n\n /**\n * Additional CSS class names to apply to the children of the badge.\n */\n childClassName?: string;\n}\n\nconst defaultIconSizeByBadgeSize: Record<\n NonNullable<BadgeProps[\"size\"]>,\n IconSize\n> = {\n lg: \"16px\",\n md: \"15px\",\n sm: \"14px\",\n xs: \"13px\",\n};\n\nconst Badge: React.FC<PropsWithChildren<BadgeProps>> = ({\n size = \"md\",\n color = \"neutral\",\n iconBefore,\n iconAfter,\n className,\n childClassName,\n children,\n disabled = false,\n focusable = false,\n hoverable = false,\n iconSize,\n ariaLabel,\n}) => {\n const sizeClass = useMemo(() => {\n switch (size) {\n case \"xs\":\n return \"px-2 py-0 text-[10px] leading-tight\";\n case \"sm\":\n return \"px-2 py-0.5 text-[10px] leading-tight\";\n case \"md\":\n return \"px-2.5 py-0.5 text-[11px] leading-normal\";\n case \"lg\":\n return \"px-3 py-[0.1875rem] text-[12px] leading-normal\";\n }\n }, [size]);\n\n const childClass = useMemo(() => {\n switch (size) {\n case \"xs\":\n case \"sm\":\n return \"leading-[18px]\";\n case \"md\":\n case \"lg\":\n return \"leading-[20px]\";\n }\n }, [size]);\n\n const colorClass = useMemo(() => {\n switch (color) {\n case \"neutral\":\n return \"text-neutral-900 dark:text-neutral-400\";\n case \"violet\":\n return \"text-violet-400\";\n case \"orange\":\n return \"text-orange-600\";\n case \"yellow\":\n return \"text-yellow-600\";\n case \"green\":\n return \"text-green-600\";\n case \"blue\":\n return \"text-blue-600\";\n case \"pink\":\n return \"text-pink-600\";\n case \"red\":\n return \"text-orange-700\";\n }\n }, [color]);\n\n const computedIconSize = iconSize ?? defaultIconSizeByBadgeSize[size];\n\n return (\n <div\n className={cn(\n \"inline-flex bg-neutral-100 dark:bg-neutral-1200 rounded-2xl gap-1 items-center focus-base transition-colors select-none font-semibold\",\n sizeClass,\n colorClass,\n { \"focus-base\": focusable },\n {\n \"hover:bg-neutral-300 hover:dark:bg-neutral-1000 active:bg-neutral-300 dark:active:bg-neutral-1000\":\n hoverable,\n },\n {\n \"cursor-not-allowed disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark\":\n disabled,\n },\n className,\n )}\n tabIndex={focusable ? 0 : undefined}\n role={focusable ? \"button\" : undefined}\n aria-label={focusable || hoverable ? ariaLabel : undefined}\n >\n {iconBefore ? (\n <Icon name={iconBefore} size={computedIconSize} color={colorClass} />\n ) : null}\n\n <span\n className={cn(\n \"whitespace-nowrap tracking-[0.04em]\",\n childClass,\n childClassName,\n )}\n >\n {children}\n </span>\n\n {iconAfter ? (\n <Icon name={iconAfter} size={computedIconSize} color={colorClass} />\n ) : null}\n </div>\n );\n};\n\nexport default Badge;\n"],"names":["React","useMemo","Icon","cn","defaultIconSizeByBadgeSize","lg","md","sm","xs","Badge","size","color","iconBefore","iconAfter","className","childClassName","children","disabled","focusable","hoverable","iconSize","ariaLabel","sizeClass","childClass","colorClass","computedIconSize","div","tabIndex","undefined","role","aria-label","name","span"],"mappings":"AAAA,OAAOA,OAA4BC,OAAO,KAAQ,OAAQ,AAE1D,QAAOC,SAAU,QAAS,AAC1B,QAAOC,OAAQ,YAAa,CA+D5B,MAAMC,2BAGF,CACFC,GAAI,OACJC,GAAI,OACJC,GAAI,OACJC,GAAI,MACN,EAEA,MAAMC,MAAiD,CAAC,CACtDC,KAAO,IAAI,CACXC,MAAQ,SAAS,CACjBC,UAAU,CACVC,SAAS,CACTC,SAAS,CACTC,cAAc,CACdC,QAAQ,CACRC,SAAW,KAAK,CAChBC,UAAY,KAAK,CACjBC,UAAY,KAAK,CACjBC,QAAQ,CACRC,SAAS,CACV,IACC,MAAMC,UAAYrB,QAAQ,KACxB,OAAQS,MACN,IAAK,KACH,MAAO,qCACT,KAAK,KACH,MAAO,uCACT,KAAK,KACH,MAAO,0CACT,KAAK,KACH,MAAO,gDACX,CACF,EAAG,CAACA,KAAK,EAET,MAAMa,WAAatB,QAAQ,KACzB,OAAQS,MACN,IAAK,KACL,IAAK,KACH,MAAO,gBACT,KAAK,KACL,IAAK,KACH,MAAO,gBACX,CACF,EAAG,CAACA,KAAK,EAET,MAAMc,WAAavB,QAAQ,KACzB,OAAQU,OACN,IAAK,UACH,MAAO,wCACT,KAAK,SACH,MAAO,iBACT,KAAK,SACH,MAAO,iBACT,KAAK,SACH,MAAO,iBACT,KAAK,QACH,MAAO,gBACT,KAAK,OACH,MAAO,eACT,KAAK,OACH,MAAO,eACT,KAAK,MACH,MAAO,iBACX,CACF,EAAG,CAACA,MAAM,EAEV,MAAMc,iBAAmBL,UAAYhB,0BAA0B,CAACM,KAAK,CAErE,OACE,oBAACgB,OACCZ,UAAWX,GACT,wIACAmB,UACAE,WACA,CAAE,aAAcN,SAAU,EAC1B,CACE,oGACEC,SACJ,EACA,CACE,2FACEF,QACJ,EACAH,WAEFa,SAAUT,UAAY,EAAIU,UAC1BC,KAAMX,UAAY,SAAWU,UAC7BE,aAAYZ,WAAaC,UAAYE,UAAYO,WAEhDhB,WACC,oBAACV,MAAK6B,KAAMnB,WAAYF,KAAMe,iBAAkBd,MAAOa,aACrD,KAEJ,oBAACQ,QACClB,UAAWX,GACT,sCACAoB,WACAR,iBAGDC,UAGFH,UACC,oBAACX,MAAK6B,KAAMlB,UAAWH,KAAMe,iBAAkBd,MAAOa,aACpD,KAGV,CAEA,gBAAef,KAAM"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import React from"react";import{describe,expect,it}from"vitest";import{render}from"@testing-library/react";import Code from"../Code";describe("Code",()=>{it("renders a single <code> element when no highlights are present",()=>{const{container}=render(React.createElement(Code,{language:"javascript",snippet:'var x = "hello";'}));const codeElements=container.querySelectorAll("pre > code");expect(codeElements.length).toBe(1)});it("wraps highlighted lines in a single <code> element",()=>{const{container}=render(React.createElement(Code,{language:"javascript",snippet:'var x = "hello";\nvar y = "world";',lineHighlights:{1:"addition"}}));const pre=container.querySelector("pre");const codeElements=pre?.querySelectorAll("code");expect(codeElements?.length).toBe(1);const lineSpans=codeElements?.[0].querySelectorAll(":scope > span");expect(lineSpans?.length).toBe(2)});it("applies highlight classes to the correct lines",()=>{const{container}=render(React.createElement(Code,{language:"javascript",snippet:"line1\nline2\nline3",lineHighlights:{1:"addition",3:"removal"}}));const lineWrappers=container.querySelectorAll("pre > code > span");expect(lineWrappers.length).toBe(3);expect(lineWrappers[0].classList.contains("code-line-addition")).toBe(true);expect(lineWrappers[1].classList.contains("code-line-addition")).toBe(false);expect(lineWrappers[2].classList.contains("code-line-removal")).toBe(true)})});
|
|
2
|
+
//# sourceMappingURL=Code.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Code/Code.test.tsx"],"sourcesContent":["/**\n * @vitest-environment jsdom\n */\n\nimport React from \"react\";\nimport { describe, expect, it } from \"vitest\";\nimport { render } from \"@testing-library/react\";\n\nimport Code from \"../Code\";\n\ndescribe(\"Code\", () => {\n it(\"renders a single <code> element when no highlights are present\", () => {\n const { container } = render(\n <Code language=\"javascript\" snippet={'var x = \"hello\";'} />,\n );\n const codeElements = container.querySelectorAll(\"pre > code\");\n expect(codeElements.length).toBe(1);\n });\n\n it(\"wraps highlighted lines in a single <code> element\", () => {\n const { container } = render(\n <Code\n language=\"javascript\"\n snippet={'var x = \"hello\";\\nvar y = \"world\";'}\n lineHighlights={{ 1: \"addition\" }}\n />,\n );\n\n const pre = container.querySelector(\"pre\");\n const codeElements = pre?.querySelectorAll(\"code\");\n expect(codeElements?.length).toBe(1);\n\n // Line content spans should be inside the <code>\n const lineSpans = codeElements?.[0].querySelectorAll(\":scope > span\");\n expect(lineSpans?.length).toBe(2);\n });\n\n it(\"applies highlight classes to the correct lines\", () => {\n const { container } = render(\n <Code\n language=\"javascript\"\n snippet={\"line1\\nline2\\nline3\"}\n lineHighlights={{ 1: \"addition\", 3: \"removal\" }}\n />,\n );\n\n const lineWrappers = container.querySelectorAll(\"pre > code > span\");\n expect(lineWrappers.length).toBe(3);\n expect(lineWrappers[0].classList.contains(\"code-line-addition\")).toBe(true);\n expect(lineWrappers[1].classList.contains(\"code-line-addition\")).toBe(\n false,\n );\n expect(lineWrappers[2].classList.contains(\"code-line-removal\")).toBe(true);\n });\n});\n"],"names":["React","describe","expect","it","render","Code","container","language","snippet","codeElements","querySelectorAll","length","toBe","lineHighlights","pre","querySelector","lineSpans","lineWrappers","classList","contains"],"mappings":"AAIA,OAAOA,UAAW,OAAQ,AAC1B,QAASC,QAAQ,CAAEC,MAAM,CAAEC,EAAE,KAAQ,QAAS,AAC9C,QAASC,MAAM,KAAQ,wBAAyB,AAEhD,QAAOC,SAAU,SAAU,CAE3BJ,SAAS,OAAQ,KACfE,GAAG,iEAAkE,KACnE,KAAM,CAAEG,SAAS,CAAE,CAAGF,OACpB,oBAACC,MAAKE,SAAS,aAAaC,QAAS,sBAEvC,MAAMC,aAAeH,UAAUI,gBAAgB,CAAC,cAChDR,OAAOO,aAAaE,MAAM,EAAEC,IAAI,CAAC,EACnC,GAEAT,GAAG,qDAAsD,KACvD,KAAM,CAAEG,SAAS,CAAE,CAAGF,OACpB,oBAACC,MACCE,SAAS,aACTC,QAAS,qCACTK,eAAgB,CAAE,EAAG,UAAW,KAIpC,MAAMC,IAAMR,UAAUS,aAAa,CAAC,OACpC,MAAMN,aAAeK,KAAKJ,iBAAiB,QAC3CR,OAAOO,cAAcE,QAAQC,IAAI,CAAC,GAGlC,MAAMI,UAAYP,cAAc,CAAC,EAAE,CAACC,iBAAiB,iBACrDR,OAAOc,WAAWL,QAAQC,IAAI,CAAC,EACjC,GAEAT,GAAG,iDAAkD,KACnD,KAAM,CAAEG,SAAS,CAAE,CAAGF,OACpB,oBAACC,MACCE,SAAS,aACTC,QAAS,sBACTK,eAAgB,CAAE,EAAG,WAAY,EAAG,SAAU,KAIlD,MAAMI,aAAeX,UAAUI,gBAAgB,CAAC,qBAChDR,OAAOe,aAAaN,MAAM,EAAEC,IAAI,CAAC,GACjCV,OAAOe,YAAY,CAAC,EAAE,CAACC,SAAS,CAACC,QAAQ,CAAC,uBAAuBP,IAAI,CAAC,MACtEV,OAAOe,YAAY,CAAC,EAAE,CAACC,SAAS,CAACC,QAAQ,CAAC,uBAAuBP,IAAI,CACnE,OAEFV,OAAOe,YAAY,CAAC,EAAE,CAACC,SAAS,CAACC,QAAQ,CAAC,sBAAsBP,IAAI,CAAC,KACvE,EACF"}
|
package/core/Code.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import{highlightSnippet,registerDefaultLanguages}from"./utils/syntax-highlighter";import languagesRegistry from"./utils/syntax-highlighter-registry";import cn from"./utils/cn";registerDefaultLanguages(languagesRegistry);const Code=({language,snippet,textSize="ui-text-code",padding="p-8",additionalCSS="",showLines,lineCSS})=>{const trimmedSnippet=snippet.trimEnd();const HTMLraw=highlightSnippet(language,trimmedSnippet)??"";const className=`language-${language} ${textSize}`;const lines=trimmedSnippet.split(/\r\n|\r|\n/);const lineCount=lines.length;return React.createElement("div",{className:cn("hljs overflow-y-auto flex",padding,additionalCSS),"data-id":"code"},showLines?React.createElement("div",{className:"text-
|
|
1
|
+
import React from"react";import{highlightSnippet,LINE_HIGHLIGHT_CLASSES,registerDefaultLanguages,splitHtmlLines}from"./utils/syntax-highlighter";import languagesRegistry from"./utils/syntax-highlighter-registry";import cn from"./utils/cn";registerDefaultLanguages(languagesRegistry);const Code=({language,snippet,textSize="ui-text-code",padding="p-8",additionalCSS="",showLines,lineCSS,wrap=false,lineHighlights})=>{const trimmedSnippet=snippet.trimEnd();const HTMLraw=highlightSnippet(language,trimmedSnippet)??"";const className=`language-${language} ${textSize}`;const lines=trimmedSnippet.split(/\r\n|\r|\n/);const lineCount=lines.length;const hasHighlights=lineHighlights&&Object.keys(lineHighlights).length>0;if(hasHighlights){const htmlLines=splitHtmlLines(HTMLraw);return React.createElement("div",{className:cn("hljs overflow-y-auto",padding,additionalCSS),"data-id":"code"},React.createElement("pre",{lang:language,className:cn("h-full flex-1 text-p4 leading-normal",wrap?"whitespace-pre-wrap break-words":"overflow-x-auto")},React.createElement("code",{className:className},htmlLines.map((lineHtml,i)=>{const lineNum=i+1;const highlightType=lineHighlights[lineNum];const highlightClass=highlightType?LINE_HIGHLIGHT_CLASSES[highlightType]:undefined;return React.createElement("span",{key:i,className:cn("flex min-w-full pl-2",highlightClass)},showLines&&React.createElement("span",{className:cn("mr-4 font-mono text-right text-neutral-800 select-none shrink-0 inline-block leading-normal",lineCSS),style:{minWidth:`${String(lineCount).length}ch`}},lineNum),React.createElement("span",{className:"flex-1 !leading-normal",dangerouslySetInnerHTML:{__html:lineHtml||" "}}))}))))}return React.createElement("div",{className:cn("hljs overflow-y-auto flex",padding,additionalCSS),"data-id":"code"},showLines?React.createElement("div",{className:"text-p4 leading-normal pt-px"},[...Array(lineCount)].map((_,i)=>React.createElement("p",{className:cn("mr-4 font-mono text-right text-neutral-800",lineCSS),key:i},i+1))):null,React.createElement("pre",{lang:language,className:cn("h-full flex-1 text-p4 leading-normal",wrap?"whitespace-pre-wrap break-words":"overflow-x-auto")},React.createElement("code",{className:className,dangerouslySetInnerHTML:{__html:HTMLraw}})))};export default Code;
|
|
2
2
|
//# sourceMappingURL=Code.js.map
|
package/core/Code.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Code.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n highlightSnippet,\n registerDefaultLanguages,\n} from \"./utils/syntax-highlighter\";\nimport languagesRegistry from \"./utils/syntax-highlighter-registry\";\nimport cn from \"./utils/cn\";\n\nregisterDefaultLanguages(languagesRegistry);\n\ntype CodeProps = {\n language: string;\n snippet: string;\n textSize?: string;\n padding?: string;\n additionalCSS?: string;\n showLines?: boolean;\n lineCSS?: string;\n};\n\nconst Code = ({\n language,\n snippet,\n textSize = \"ui-text-code\",\n padding = \"p-8\",\n additionalCSS = \"\",\n showLines,\n lineCSS,\n}: CodeProps) => {\n // Trim the snippet and remove trailing empty lines\n const trimmedSnippet = snippet.trimEnd();\n const HTMLraw = highlightSnippet(language, trimmedSnippet) ?? \"\";\n const className = `language-${language} ${textSize}`;\n\n // Calculate line count after removing trailing empty lines\n const lines = trimmedSnippet.split(/\\r\\n|\\r|\\n/);\n const lineCount = lines.length;\n\n return (\n <div\n className={cn(\"hljs overflow-y-auto flex\", padding, additionalCSS)}\n data-id=\"code\"\n >\n {showLines ? (\n <div className=\"text-
|
|
1
|
+
{"version":3,"sources":["../../src/core/Code.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n highlightSnippet,\n LINE_HIGHLIGHT_CLASSES,\n registerDefaultLanguages,\n splitHtmlLines,\n} from \"./utils/syntax-highlighter\";\nimport languagesRegistry from \"./utils/syntax-highlighter-registry\";\nimport cn from \"./utils/cn\";\n\nregisterDefaultLanguages(languagesRegistry);\n\nexport type LineHighlightType = \"addition\" | \"removal\" | \"highlight\";\n\ntype CodeProps = {\n language: string;\n snippet: string;\n textSize?: string;\n padding?: string;\n additionalCSS?: string;\n showLines?: boolean;\n lineCSS?: string;\n wrap?: boolean;\n lineHighlights?: Record<number, LineHighlightType>;\n};\n\nconst Code = ({\n language,\n snippet,\n textSize = \"ui-text-code\",\n padding = \"p-8\",\n additionalCSS = \"\",\n showLines,\n lineCSS,\n wrap = false,\n lineHighlights,\n}: CodeProps) => {\n // Trim the snippet and remove trailing empty lines\n const trimmedSnippet = snippet.trimEnd();\n const HTMLraw = highlightSnippet(language, trimmedSnippet) ?? \"\";\n const className = `language-${language} ${textSize}`;\n\n // Calculate line count after removing trailing empty lines\n const lines = trimmedSnippet.split(/\\r\\n|\\r|\\n/);\n const lineCount = lines.length;\n\n const hasHighlights =\n lineHighlights && Object.keys(lineHighlights).length > 0;\n\n // Per-line rendering when highlights are present\n if (hasHighlights) {\n const htmlLines = splitHtmlLines(HTMLraw);\n\n return (\n <div\n className={cn(\"hljs overflow-y-auto\", padding, additionalCSS)}\n data-id=\"code\"\n >\n <pre\n lang={language}\n className={cn(\n \"h-full flex-1 text-p4 leading-normal\",\n wrap ? \"whitespace-pre-wrap break-words\" : \"overflow-x-auto\",\n )}\n >\n <code className={className}>\n {htmlLines.map((lineHtml, i) => {\n const lineNum = i + 1;\n const highlightType = lineHighlights[lineNum];\n const highlightClass = highlightType\n ? LINE_HIGHLIGHT_CLASSES[highlightType]\n : undefined;\n\n return (\n <span\n key={i}\n className={cn(\"flex min-w-full pl-2\", highlightClass)}\n >\n {showLines && (\n <span\n className={cn(\n \"mr-4 font-mono text-right text-neutral-800 select-none shrink-0 inline-block leading-normal\",\n lineCSS,\n )}\n style={{ minWidth: `${String(lineCount).length}ch` }}\n >\n {lineNum}\n </span>\n )}\n <span\n className=\"flex-1 !leading-normal\"\n dangerouslySetInnerHTML={{\n __html: lineHtml || \" \",\n }}\n />\n </span>\n );\n })}\n </code>\n </pre>\n </div>\n );\n }\n\n // Default: single-block rendering (no highlights)\n return (\n <div\n className={cn(\"hljs overflow-y-auto flex\", padding, additionalCSS)}\n data-id=\"code\"\n >\n {showLines ? (\n <div className=\"text-p4 leading-normal pt-px\">\n {[...Array(lineCount)].map((_, i) => (\n <p\n className={cn(\n \"mr-4 font-mono text-right text-neutral-800\",\n lineCSS,\n )}\n key={i}\n >\n {i + 1}\n </p>\n ))}\n </div>\n ) : null}\n <pre\n lang={language}\n className={cn(\n \"h-full flex-1 text-p4 leading-normal\",\n wrap ? \"whitespace-pre-wrap break-words\" : \"overflow-x-auto\",\n )}\n >\n <code\n className={className}\n dangerouslySetInnerHTML={{ __html: HTMLraw }}\n />\n </pre>\n </div>\n );\n};\n\nexport default Code;\n"],"names":["React","highlightSnippet","LINE_HIGHLIGHT_CLASSES","registerDefaultLanguages","splitHtmlLines","languagesRegistry","cn","Code","language","snippet","textSize","padding","additionalCSS","showLines","lineCSS","wrap","lineHighlights","trimmedSnippet","trimEnd","HTMLraw","className","lines","split","lineCount","length","hasHighlights","Object","keys","htmlLines","div","data-id","pre","lang","code","map","lineHtml","i","lineNum","highlightType","highlightClass","undefined","span","key","style","minWidth","String","dangerouslySetInnerHTML","__html","Array","_","p"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QACEC,gBAAgB,CAChBC,sBAAsB,CACtBC,wBAAwB,CACxBC,cAAc,KACT,4BAA6B,AACpC,QAAOC,sBAAuB,qCAAsC,AACpE,QAAOC,OAAQ,YAAa,CAE5BH,yBAAyBE,mBAgBzB,MAAME,KAAO,CAAC,CACZC,QAAQ,CACRC,OAAO,CACPC,SAAW,cAAc,CACzBC,QAAU,KAAK,CACfC,cAAgB,EAAE,CAClBC,SAAS,CACTC,OAAO,CACPC,KAAO,KAAK,CACZC,cAAc,CACJ,IAEV,MAAMC,eAAiBR,QAAQS,OAAO,GACtC,MAAMC,QAAUlB,iBAAiBO,SAAUS,iBAAmB,GAC9D,MAAMG,UAAY,CAAC,SAAS,EAAEZ,SAAS,CAAC,EAAEE,SAAS,CAAC,CAGpD,MAAMW,MAAQJ,eAAeK,KAAK,CAAC,cACnC,MAAMC,UAAYF,MAAMG,MAAM,CAE9B,MAAMC,cACJT,gBAAkBU,OAAOC,IAAI,CAACX,gBAAgBQ,MAAM,CAAG,EAGzD,GAAIC,cAAe,CACjB,MAAMG,UAAYxB,eAAee,SAEjC,OACE,oBAACU,OACCT,UAAWd,GAAG,uBAAwBK,QAASC,eAC/CkB,UAAQ,QAER,oBAACC,OACCC,KAAMxB,SACNY,UAAWd,GACT,uCACAS,KAAO,kCAAoC,oBAG7C,oBAACkB,QAAKb,UAAWA,WACdQ,UAAUM,GAAG,CAAC,CAACC,SAAUC,KACxB,MAAMC,QAAUD,EAAI,EACpB,MAAME,cAAgBtB,cAAc,CAACqB,QAAQ,CAC7C,MAAME,eAAiBD,cACnBpC,sBAAsB,CAACoC,cAAc,CACrCE,UAEJ,OACE,oBAACC,QACCC,IAAKN,EACLhB,UAAWd,GAAG,uBAAwBiC,iBAErC1B,WACC,oBAAC4B,QACCrB,UAAWd,GACT,8FACAQ,SAEF6B,MAAO,CAAEC,SAAU,CAAC,EAAEC,OAAOtB,WAAWC,MAAM,CAAC,EAAE,CAAC,AAAC,GAElDa,SAGL,oBAACI,QACCrB,UAAU,yBACV0B,wBAAyB,CACvBC,OAAQZ,UAAY,QACtB,IAIR,KAKV,CAGA,OACE,oBAACN,OACCT,UAAWd,GAAG,4BAA6BK,QAASC,eACpDkB,UAAQ,QAEPjB,UACC,oBAACgB,OAAIT,UAAU,gCACZ,IAAI4B,MAAMzB,WAAW,CAACW,GAAG,CAAC,CAACe,EAAGb,IAC7B,oBAACc,KACC9B,UAAWd,GACT,6CACAQ,SAEF4B,IAAKN,GAEJA,EAAI,KAIT,KACJ,oBAACL,OACCC,KAAMxB,SACNY,UAAWd,GACT,uCACAS,KAAO,kCAAoC,oBAG7C,oBAACkB,QACCb,UAAWA,UACX0B,wBAAyB,CAAEC,OAAQ5B,OAAQ,KAKrD,CAEA,gBAAeZ,IAAK"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useMemo}from"react";import*as Select from"@radix-ui/react-select";import Badge from"../Badge";import Icon from"../Icon";import Tooltip from"../Tooltip";const ApiKeySelector=({apiKeys,selectedApiKey,onApiKeyChange})=>{const isDemoMode=useMemo(()=>apiKeys?.length===1&&apiKeys[0].app==="demo",[apiKeys]);const renderDemoMode=useMemo(()=>React.createElement("div",{className:"flex items-center gap-2"},React.createElement(Badge,{className:"ml-1 bg-neutral-200 dark:bg-neutral-1100"},"DEMO ONLY"),React.createElement(Tooltip,{className:"ml-0",triggerElement:React.createElement(Icon,{name:"icon-gui-information-circle-outline",size:"
|
|
1
|
+
import React,{useMemo}from"react";import*as Select from"@radix-ui/react-select";import Badge from"../Badge";import Icon from"../Icon";import Tooltip from"../Tooltip";const ApiKeySelector=({apiKeys,selectedApiKey,onApiKeyChange})=>{const isDemoMode=useMemo(()=>apiKeys?.length===1&&apiKeys[0].app==="demo",[apiKeys]);const renderDemoMode=useMemo(()=>React.createElement("div",{className:"flex items-center gap-2"},React.createElement(Badge,{className:"ml-1 bg-neutral-200 dark:bg-neutral-1100"},"DEMO ONLY"),React.createElement(Tooltip,{className:"ml-0",triggerProps:{className:"h-5"},contentProps:{className:"bg-neutral-1100 dark:bg-neutral-200 text-neutral-300 dark:text-neutral-1000"},triggerElement:React.createElement("div",{className:"group/code-snippet-tooltip-icon-hover flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-information-circle-outline",size:"20px",color:"text-neutral-700 dark:text-neutral-600",additionalCSS:"group-hover/code-snippet-tooltip-icon-hover:hidden"}),React.createElement(Icon,{name:"icon-gui-information-circle-solid",size:"20px",color:"text-neutral-1300 dark:text-neutral-000",additionalCSS:"group-hover/code-snippet-tooltip-icon-hover:flex hidden"}))},"This code example uses a temporary key that is rate limited and expires in 4 hrs. Sign in to Ably to use your API keys instead.")),[]);const renderApiKeyDropdown=useMemo(()=>{if(isDemoMode){return renderDemoMode}if(!apiKeys?.length){return null}return React.createElement(Select.Root,{value:selectedApiKey,onValueChange:onApiKeyChange},React.createElement(Select.Trigger,{className:"font-sans inline-flex items-center justify-between rounded px-3 py-2 ml-1 text-14 text-neutral-1300 dark:text-neutral-000 bg-neutral-200 dark:bg-neutral-1100 hover:bg-neutral-300 dark:hover:bg-neutral-1000 gap-2 focus-base border border-neutral-300 dark:border-neutral-1000 transition-colors","aria-label":"API Key"},React.createElement(Select.Value,null),React.createElement(Select.Icon,{className:"size-4"},React.createElement(Icon,{name:"icon-gui-chevron-down-micro",size:"16px"}))),React.createElement(Select.Portal,null,React.createElement(Select.Content,{className:"overflow-hidden rounded-lg bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 shadow-md z-50"},React.createElement(Select.ScrollUpButton,{className:"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base"},React.createElement(Icon,{name:"icon-gui-chevron-down-outline",size:"16px",additionalCSS:"rotate-180"})),React.createElement(Select.Viewport,{className:"rounded-lg font-sans"},apiKeys.map(apiKeyItem=>React.createElement(Select.Group,{key:apiKeyItem.app},apiKeys.length>1&&React.createElement(Select.Label,{className:"text-neutral-700 rounded-none dark:text-neutral-600 p-1 bg-neutral-200 dark:bg-neutral-1100"},apiKeyItem.app),apiKeyItem.keys.map(({name,key})=>React.createElement(Select.Item,{key:`${apiKeyItem.app}-${name}-${key}`,value:key,className:"relative flex items-center justify-between m-2 p-2 rounded-lg text-14 text-neutral-1300 dark:text-neutral-000 select-none hover:bg-neutral-100 dark:hover:bg-neutral-1200 data-[highlighted]:outline-none data-[highlighted]:bg-neutral-100 dark:data-[highlighted]:bg-neutral-1200 focus-base min-w-64"},React.createElement(Select.ItemText,null,key.length>10?`${key.substring(0,10)}...`:key,React.createElement("span",{className:"font-light"},name&&` - ${name}`)),React.createElement(Select.ItemIndicator,{className:"size-4"},React.createElement(Icon,{name:"icon-gui-check-micro",size:"16px"}))))))),React.createElement(Select.ScrollDownButton,{className:"flex items-center justify-center h-6 bg-neutral-000 dark:bg-neutral-1300 text-neutral-1300 dark:text-neutral-000 cursor-default focus-base"},React.createElement(Icon,{name:"icon-gui-chevron-down-outline",size:"16px"})))))},[apiKeys,isDemoMode,selectedApiKey,onApiKeyChange,renderDemoMode]);return React.createElement("div",{className:"flex items-center border-t border-neutral-300 dark:border-neutral-1000 px-3 py-3"},React.createElement("span",{className:"ui-text-label4 text-neutral-700 dark:text-neutral-600 mr-1"},"API key:"),renderApiKeyDropdown)};export default ApiKeySelector;
|
|
2
2
|
//# sourceMappingURL=ApiKeySelector.js.map
|