@ably/ui 17.11.0-dev.4c4b6b55 → 17.11.0

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.
Files changed (73) hide show
  1. package/core/Flyout.js +1 -1
  2. package/core/Flyout.js.map +1 -1
  3. package/core/Header/HeaderLinks.js +1 -1
  4. package/core/Header/HeaderLinks.js.map +1 -1
  5. package/core/Header.js +1 -1
  6. package/core/Header.js.map +1 -1
  7. package/core/Icon/components/icon-gui-heartbeat-outline.js +2 -0
  8. package/core/Icon/components/icon-gui-heartbeat-outline.js.map +1 -0
  9. package/core/Icon/components/icon-gui-heartbeat-solid.js +2 -0
  10. package/core/Icon/components/icon-gui-heartbeat-solid.js.map +1 -0
  11. package/core/Icon/components/icon-product-chat-mono.js +1 -1
  12. package/core/Icon/components/icon-product-chat-mono.js.map +1 -1
  13. package/core/Icon/components/icon-product-liveobjects-mono.js +1 -1
  14. package/core/Icon/components/icon-product-liveobjects-mono.js.map +1 -1
  15. package/core/Icon/components/icon-product-livesync-mono.js +1 -1
  16. package/core/Icon/components/icon-product-livesync-mono.js.map +1 -1
  17. package/core/Icon/components/icon-product-pubsub-mono.js +1 -1
  18. package/core/Icon/components/icon-product-pubsub-mono.js.map +1 -1
  19. package/core/Icon/components/icon-product-spaces-mono.js +1 -1
  20. package/core/Icon/components/icon-product-spaces-mono.js.map +1 -1
  21. package/core/Icon/components/index.js +1 -1
  22. package/core/Icon/components/index.js.map +1 -1
  23. package/core/Icon/computed-icons/gui-icons.js +1 -1
  24. package/core/Icon/computed-icons/gui-icons.js.map +1 -1
  25. package/core/Meganav/MeganavBlog.js +2 -0
  26. package/core/Meganav/MeganavBlog.js.map +1 -0
  27. package/core/Meganav/MeganavCustomerStories.js +2 -0
  28. package/core/Meganav/MeganavCustomerStories.js.map +1 -0
  29. package/core/Meganav/MeganavMobile.js +1 -1
  30. package/core/Meganav/MeganavMobile.js.map +1 -1
  31. package/core/Meganav/MeganavPanel.js +1 -1
  32. package/core/Meganav/MeganavPanel.js.map +1 -1
  33. package/core/Meganav/MeganavPanelItemLinks.js +2 -0
  34. package/core/Meganav/MeganavPanelItemLinks.js.map +1 -0
  35. package/core/Meganav/MeganavTile.js +2 -0
  36. package/core/Meganav/MeganavTile.js.map +1 -0
  37. package/core/Meganav/PanelTitle.js +2 -0
  38. package/core/Meganav/PanelTitle.js.map +1 -0
  39. package/core/Meganav/data.js +1 -1
  40. package/core/Meganav/data.js.map +1 -1
  41. package/core/Meganav/images/cust-logo-doxy-dark.png +0 -0
  42. package/core/Meganav/images/cust-logo-doxy-light.png +0 -0
  43. package/core/Meganav/utils/getMenuItemsForHeader.js +2 -0
  44. package/core/Meganav/utils/getMenuItemsForHeader.js.map +1 -0
  45. package/core/Meganav.js +1 -1
  46. package/core/Meganav.js.map +1 -1
  47. package/core/ProductTile/ProductIcon.js +1 -1
  48. package/core/ProductTile/ProductIcon.js.map +1 -1
  49. package/core/ProductTile/ProductLabel.js +1 -1
  50. package/core/ProductTile/ProductLabel.js.map +1 -1
  51. package/core/ProductTile/data.js +1 -1
  52. package/core/ProductTile/data.js.map +1 -1
  53. package/core/icons/gui/icon-gui-heartbeat-outline.svg +4 -0
  54. package/core/icons/gui/icon-gui-heartbeat-solid.svg +4 -0
  55. package/core/icons/product/icon-product-chat-mono.svg +1 -1
  56. package/core/icons/product/icon-product-liveobjects-mono.svg +1 -4
  57. package/core/icons/product/icon-product-livesync-mono.svg +4 -4
  58. package/core/icons/product/icon-product-pubsub-mono.svg +1 -1
  59. package/core/icons/product/icon-product-spaces-mono.svg +1 -1
  60. package/core/sprites-gui.svg +1 -1
  61. package/core/sprites-product.svg +1 -1
  62. package/index.d.ts +143 -48
  63. package/package.json +5 -6
  64. package/core/Header/types.js +0 -2
  65. package/core/Header/types.js.map +0 -1
  66. package/core/Meganav/MeganavProductTile.js +0 -2
  67. package/core/Meganav/MeganavProductTile.js.map +0 -1
  68. package/core/Meganav/images/fan-engagement-nav-image.png +0 -0
  69. package/core/Meganav/images/founders-nav-image.png +0 -0
  70. package/core/hooks/use-themed-scrollpoints.js +0 -2
  71. package/core/hooks/use-themed-scrollpoints.js.map +0 -1
  72. package/core/hooks/use-themed-scrollpoints.test.js +0 -2
  73. package/core/hooks/use-themed-scrollpoints.test.js.map +0 -1
package/index.d.ts CHANGED
@@ -773,18 +773,12 @@ export const HeaderLinks: React.FC<Pick<HeaderProps, "sessionState" | "headerLin
773
773
  //# sourceMappingURL=HeaderLinks.d.ts.map
774
774
  }
775
775
 
776
- declare module '@ably/ui/core/Header/types' {
776
+ declare module '@ably/ui/core/Header' {
777
+ import React, { ReactNode } from "react";
777
778
  export type ThemedScrollpoint = {
778
779
  id: string;
779
780
  className: string;
780
781
  };
781
- //# sourceMappingURL=types.d.ts.map
782
- }
783
-
784
- declare module '@ably/ui/core/Header' {
785
- import React, { ReactNode } from "react";
786
- import { ThemedScrollpoint } from "@ably/ui/core/Header/types";
787
- export type { ThemedScrollpoint };
788
782
  /**
789
783
  * Represents the state of the user session in the header.
790
784
  */
@@ -2111,6 +2105,28 @@ export default ForwardRef;
2111
2105
  //# sourceMappingURL=icon-gui-glasses.d.ts.map
2112
2106
  }
2113
2107
 
2108
+ declare module '@ably/ui/core/Icon/components/icon-gui-heartbeat-outline' {
2109
+ import * as React from "react";
2110
+ interface SVGRProps {
2111
+ title?: string;
2112
+ titleId?: string;
2113
+ }
2114
+ const ForwardRef: React.ForwardRefExoticComponent<Omit<React.SVGProps<SVGSVGElement> & SVGRProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
2115
+ export default ForwardRef;
2116
+ //# sourceMappingURL=icon-gui-heartbeat-outline.d.ts.map
2117
+ }
2118
+
2119
+ declare module '@ably/ui/core/Icon/components/icon-gui-heartbeat-solid' {
2120
+ import * as React from "react";
2121
+ interface SVGRProps {
2122
+ title?: string;
2123
+ titleId?: string;
2124
+ }
2125
+ const ForwardRef: React.ForwardRefExoticComponent<Omit<React.SVGProps<SVGSVGElement> & SVGRProps, "ref"> & React.RefAttributes<SVGSVGElement>>;
2126
+ export default ForwardRef;
2127
+ //# sourceMappingURL=icon-gui-heartbeat-solid.d.ts.map
2128
+ }
2129
+
2114
2130
  declare module '@ably/ui/core/Icon/components/icon-gui-history' {
2115
2131
  import * as React from "react";
2116
2132
  interface SVGRProps {
@@ -5017,6 +5033,8 @@ import IconGuiFilterFlowStep3 from "@ably/ui/core/icon-gui-filter-flow-step-3";
5017
5033
  import IconGuiFlowerGrowth from "@ably/ui/core/icon-gui-flower-growth";
5018
5034
  import IconGuiFurtherReading from "@ably/ui/core/icon-gui-further-reading";
5019
5035
  import IconGuiGlasses from "@ably/ui/core/icon-gui-glasses";
5036
+ import IconGuiHeartbeatOutline from "@ably/ui/core/icon-gui-heartbeat-outline";
5037
+ import IconGuiHeartbeatSolid from "@ably/ui/core/icon-gui-heartbeat-solid";
5020
5038
  import IconGuiHistory from "@ably/ui/core/icon-gui-history";
5021
5039
  import IconGuiLiveChat from "@ably/ui/core/icon-gui-live-chat";
5022
5040
  import IconGuiMouse from "@ably/ui/core/icon-gui-mouse";
@@ -5041,7 +5059,7 @@ import IconGuiRefresh from "@ably/ui/core/icon-gui-refresh";
5041
5059
  import IconGuiResources from "@ably/ui/core/icon-gui-resources";
5042
5060
  import IconGuiSpinnerDark from "@ably/ui/core/icon-gui-spinner-dark";
5043
5061
  import IconGuiSpinnerLight from "@ably/ui/core/icon-gui-spinner-light";
5044
- export { IconGuiAblyBadge, IconGuiCheckCircledFill, IconGuiCheckLotusCircled, IconGuiChecklistChecked, IconGuiCodeDoc, IconGuiCursor, IconGuiExpand, IconGuiFilterFlowStep0, IconGuiFilterFlowStep1, IconGuiFilterFlowStep2, IconGuiFilterFlowStep3, IconGuiFlowerGrowth, IconGuiFurtherReading, IconGuiGlasses, IconGuiHistory, IconGuiLiveChat, IconGuiMouse, IconGuiPartial, IconGuiPitfall, IconGuiProdAiTransportOutline, IconGuiProdAiTransportSolid, IconGuiProdAssetTrackingOutline, IconGuiProdAssetTrackingSolid, IconGuiProdChatOutline, IconGuiProdChatSolid, IconGuiProdLiveobjectsOutline, IconGuiProdLiveobjectsSolid, IconGuiProdLivesyncOutline, IconGuiProdLivesyncSolid, IconGuiProdPubsubOutline, IconGuiProdPubsubSolid, IconGuiProdSpacesOutline, IconGuiProdSpacesSolid, IconGuiQuoteMarksFill, IconGuiRefresh, IconGuiResources, IconGuiSpinnerDark, IconGuiSpinnerLight, };
5062
+ export { IconGuiAblyBadge, IconGuiCheckCircledFill, IconGuiCheckLotusCircled, IconGuiChecklistChecked, IconGuiCodeDoc, IconGuiCursor, IconGuiExpand, IconGuiFilterFlowStep0, IconGuiFilterFlowStep1, IconGuiFilterFlowStep2, IconGuiFilterFlowStep3, IconGuiFlowerGrowth, IconGuiFurtherReading, IconGuiGlasses, IconGuiHeartbeatOutline, IconGuiHeartbeatSolid, IconGuiHistory, IconGuiLiveChat, IconGuiMouse, IconGuiPartial, IconGuiPitfall, IconGuiProdAiTransportOutline, IconGuiProdAiTransportSolid, IconGuiProdAssetTrackingOutline, IconGuiProdAssetTrackingSolid, IconGuiProdChatOutline, IconGuiProdChatSolid, IconGuiProdLiveobjectsOutline, IconGuiProdLiveobjectsSolid, IconGuiProdLivesyncOutline, IconGuiProdLivesyncSolid, IconGuiProdPubsubOutline, IconGuiProdPubsubSolid, IconGuiProdSpacesOutline, IconGuiProdSpacesSolid, IconGuiQuoteMarksFill, IconGuiRefresh, IconGuiResources, IconGuiSpinnerDark, IconGuiSpinnerLight, };
5045
5063
  import IconProductAiTransportMono from "@ably/ui/core/icon-product-ai-transport-mono";
5046
5064
  import IconProductAiTransport from "@ably/ui/core/icon-product-ai-transport";
5047
5065
  import IconProductAssetTrackingMono from "@ably/ui/core/icon-product-asset-tracking-mono";
@@ -5284,7 +5302,7 @@ export const displayIcons: readonly ["icon-display-48hrs", "icon-display-ably-ch
5284
5302
  }
5285
5303
 
5286
5304
  declare module '@ably/ui/core/Icon/computed-icons/gui-icons' {
5287
- export const guiIcons: readonly ["icon-gui-ably-badge", "icon-gui-check-circled-fill", "icon-gui-check-lotus-circled", "icon-gui-checklist-checked", "icon-gui-code-doc", "icon-gui-cursor", "icon-gui-expand", "icon-gui-filter-flow-step-0", "icon-gui-filter-flow-step-1", "icon-gui-filter-flow-step-2", "icon-gui-filter-flow-step-3", "icon-gui-flower-growth", "icon-gui-further-reading", "icon-gui-glasses", "icon-gui-history", "icon-gui-live-chat", "icon-gui-mouse", "icon-gui-partial", "icon-gui-pitfall", "icon-gui-prod-ai-transport-outline", "icon-gui-prod-ai-transport-solid", "icon-gui-prod-asset-tracking-outline", "icon-gui-prod-asset-tracking-solid", "icon-gui-prod-chat-outline", "icon-gui-prod-chat-solid", "icon-gui-prod-liveobjects-outline", "icon-gui-prod-liveobjects-solid", "icon-gui-prod-livesync-outline", "icon-gui-prod-livesync-solid", "icon-gui-prod-pubsub-outline", "icon-gui-prod-pubsub-solid", "icon-gui-prod-spaces-outline", "icon-gui-prod-spaces-solid", "icon-gui-quote-marks-fill", "icon-gui-refresh", "icon-gui-resources", "icon-gui-spinner-dark", "icon-gui-spinner-light"];
5305
+ export const guiIcons: readonly ["icon-gui-ably-badge", "icon-gui-check-circled-fill", "icon-gui-check-lotus-circled", "icon-gui-checklist-checked", "icon-gui-code-doc", "icon-gui-cursor", "icon-gui-expand", "icon-gui-filter-flow-step-0", "icon-gui-filter-flow-step-1", "icon-gui-filter-flow-step-2", "icon-gui-filter-flow-step-3", "icon-gui-flower-growth", "icon-gui-further-reading", "icon-gui-glasses", "icon-gui-heartbeat-outline", "icon-gui-heartbeat-solid", "icon-gui-history", "icon-gui-live-chat", "icon-gui-mouse", "icon-gui-partial", "icon-gui-pitfall", "icon-gui-prod-ai-transport-outline", "icon-gui-prod-ai-transport-solid", "icon-gui-prod-asset-tracking-outline", "icon-gui-prod-asset-tracking-solid", "icon-gui-prod-chat-outline", "icon-gui-prod-chat-solid", "icon-gui-prod-liveobjects-outline", "icon-gui-prod-liveobjects-solid", "icon-gui-prod-livesync-outline", "icon-gui-prod-livesync-solid", "icon-gui-prod-pubsub-outline", "icon-gui-prod-pubsub-solid", "icon-gui-prod-spaces-outline", "icon-gui-prod-spaces-solid", "icon-gui-quote-marks-fill", "icon-gui-refresh", "icon-gui-resources", "icon-gui-spinner-dark", "icon-gui-spinner-light"];
5288
5306
  //# sourceMappingURL=gui-icons.d.ts.map
5289
5307
  }
5290
5308
 
@@ -5305,7 +5323,7 @@ export const techIcons: readonly ["icon-tech-ably", "icon-tech-ably-api-streamer
5305
5323
 
5306
5324
  declare module '@ably/ui/core/Icon/types' {
5307
5325
  export const iconNames: {
5308
- gui: readonly ["icon-gui-ably-badge", "icon-gui-check-circled-fill", "icon-gui-check-lotus-circled", "icon-gui-checklist-checked", "icon-gui-code-doc", "icon-gui-cursor", "icon-gui-expand", "icon-gui-filter-flow-step-0", "icon-gui-filter-flow-step-1", "icon-gui-filter-flow-step-2", "icon-gui-filter-flow-step-3", "icon-gui-flower-growth", "icon-gui-further-reading", "icon-gui-glasses", "icon-gui-history", "icon-gui-live-chat", "icon-gui-mouse", "icon-gui-partial", "icon-gui-pitfall", "icon-gui-prod-ai-transport-outline", "icon-gui-prod-ai-transport-solid", "icon-gui-prod-asset-tracking-outline", "icon-gui-prod-asset-tracking-solid", "icon-gui-prod-chat-outline", "icon-gui-prod-chat-solid", "icon-gui-prod-liveobjects-outline", "icon-gui-prod-liveobjects-solid", "icon-gui-prod-livesync-outline", "icon-gui-prod-livesync-solid", "icon-gui-prod-pubsub-outline", "icon-gui-prod-pubsub-solid", "icon-gui-prod-spaces-outline", "icon-gui-prod-spaces-solid", "icon-gui-quote-marks-fill", "icon-gui-refresh", "icon-gui-resources", "icon-gui-spinner-dark", "icon-gui-spinner-light"];
5326
+ gui: readonly ["icon-gui-ably-badge", "icon-gui-check-circled-fill", "icon-gui-check-lotus-circled", "icon-gui-checklist-checked", "icon-gui-code-doc", "icon-gui-cursor", "icon-gui-expand", "icon-gui-filter-flow-step-0", "icon-gui-filter-flow-step-1", "icon-gui-filter-flow-step-2", "icon-gui-filter-flow-step-3", "icon-gui-flower-growth", "icon-gui-further-reading", "icon-gui-glasses", "icon-gui-heartbeat-outline", "icon-gui-heartbeat-solid", "icon-gui-history", "icon-gui-live-chat", "icon-gui-mouse", "icon-gui-partial", "icon-gui-pitfall", "icon-gui-prod-ai-transport-outline", "icon-gui-prod-ai-transport-solid", "icon-gui-prod-asset-tracking-outline", "icon-gui-prod-asset-tracking-solid", "icon-gui-prod-chat-outline", "icon-gui-prod-chat-solid", "icon-gui-prod-liveobjects-outline", "icon-gui-prod-liveobjects-solid", "icon-gui-prod-livesync-outline", "icon-gui-prod-livesync-solid", "icon-gui-prod-pubsub-outline", "icon-gui-prod-pubsub-solid", "icon-gui-prod-spaces-outline", "icon-gui-prod-spaces-solid", "icon-gui-quote-marks-fill", "icon-gui-refresh", "icon-gui-resources", "icon-gui-spinner-dark", "icon-gui-spinner-light"];
5309
5327
  display: readonly ["icon-display-48hrs", "icon-display-ably-channels", "icon-display-about-ably-col", "icon-display-api", "icon-display-api-keys", "icon-display-architectural-guidance", "icon-display-asset-tracking-col", "icon-display-authentication", "icon-display-avatar-stack", "icon-display-browser", "icon-display-calendar", "icon-display-call-mobile", "icon-display-careers-col", "icon-display-case-studies-col", "icon-display-chat-col", "icon-display-chat-mono", "icon-display-chat-stack", "icon-display-chat-stack-col", "icon-display-cloud-servers", "icon-display-compare-tech-col", "icon-display-connection-state-recovery", "icon-display-consumer-groups", "icon-display-custom", "icon-display-custom-cname", "icon-display-customers-col", "icon-display-data-broadcast-col", "icon-display-data-broadcast-mono", "icon-display-data-synchronization-col", "icon-display-dedicated-cluster", "icon-display-deltas", "icon-display-docs-col", "icon-display-documentation", "icon-display-dynamic-channel-groups", "icon-display-edge-network", "icon-display-elasticity", "icon-display-equalisers-mono", "icon-display-events-col", "icon-display-exactly-once-delivery", "icon-display-examples-col", "icon-display-fan-out", "icon-display-firehose", "icon-display-gdpr", "icon-display-general-comms", "icon-display-granular-permissions", "icon-display-hipaa", "icon-display-hipaa-mono", "icon-display-history", "icon-display-integrations", "icon-display-integrations-col", "icon-display-it-support-access", "icon-display-it-support-helpdesk", "icon-display-kafka-at-the-edge-col", "icon-display-laptop", "icon-display-last-seen", "icon-display-lightbulb-col", "icon-display-live-chat", "icon-display-live-updates-results-metrics-col", "icon-display-map-pin", "icon-display-message", "icon-display-message-batching", "icon-display-message-persistence", "icon-display-message-queues", "icon-display-multi-user-spaces-col", "icon-display-observe-analytics", "icon-display-padlock-closed", "icon-display-platform", "icon-display-play", "icon-display-premium-support", "icon-display-privacy-shield-framework", "icon-display-private-link", "icon-display-push-notifications", "icon-display-push-notifications-col", "icon-display-push-notifications-mono", "icon-display-quickstart-guides-col", "icon-display-reactions", "icon-display-read-receipts", "icon-display-resources-col", "icon-display-rewind", "icon-display-sdks-col", "icon-display-send-received-messages", "icon-display-servers", "icon-display-shopping-cart", "icon-display-sla", "icon-display-soc2-type2", "icon-display-soc2-type2-mono", "icon-display-something-else", "icon-display-something-else-mono", "icon-display-subscription-filters", "icon-display-support-chat-mono", "icon-display-system-metadata", "icon-display-tech-account-comms", "icon-display-tutorials-demos-col", "icon-display-ui", "icon-display-ui-mono", "icon-display-virtual-events", "icon-display-virtual-events-col"];
5310
5328
  social: readonly ["icon-social-discord", "icon-social-discord-mono", "icon-social-facebook", "icon-social-facebook-mono", "icon-social-github", "icon-social-github-mono", "icon-social-glassdoor", "icon-social-glassdoor-mono", "icon-social-google", "icon-social-google-mono", "icon-social-linkedin", "icon-social-linkedin-mono", "icon-social-slack", "icon-social-slack-mono", "icon-social-stackoverflow", "icon-social-stackoverflow-mono", "icon-social-twitter", "icon-social-twitter-mono", "icon-social-x", "icon-social-x-mono", "icon-social-youtube", "icon-social-youtube-mono"];
5311
5329
  tech: readonly ["icon-tech-ably", "icon-tech-ably-api-streamer", "icon-tech-ably-firehose", "icon-tech-ably-native", "icon-tech-activemq", "icon-tech-activitypub", "icon-tech-aerospike", "icon-tech-akka", "icon-tech-amazon-ec2", "icon-tech-amazon-event-bridge", "icon-tech-amqp091", "icon-tech-amqp10", "icon-tech-android-full", "icon-tech-android-head", "icon-tech-angular", "icon-tech-anycable", "icon-tech-apache-cassandra", "icon-tech-apache-cordova", "icon-tech-apache-kafka", "icon-tech-apache-spark", "icon-tech-apachepulsar", "icon-tech-apachestorm", "icon-tech-apns", "icon-tech-assemblyai", "icon-tech-atmosphere", "icon-tech-aws", "icon-tech-aws-app-sync", "icon-tech-aws-aurora", "icon-tech-aws-gateway-websockets", "icon-tech-aws-sns", "icon-tech-aws-sqs", "icon-tech-awsiot", "icon-tech-awskinesis", "icon-tech-awslambda", "icon-tech-awssqs", "icon-tech-azure-api", "icon-tech-azure-archive-api", "icon-tech-azure-bus", "icon-tech-azure-cosmos", "icon-tech-azure-event-hub", "icon-tech-azure-functions", "icon-tech-azure-search", "icon-tech-azure-static-web-app", "icon-tech-azure-static-web-apps", "icon-tech-azure-storage", "icon-tech-azure-web-pubsub", "icon-tech-azurefunctions", "icon-tech-azureservicebus", "icon-tech-azuresignalR", "icon-tech-bayeux", "icon-tech-c++", "icon-tech-centrifugo", "icon-tech-claude", "icon-tech-claude-mono", "icon-tech-client-side-frameworks", "icon-tech-clojure", "icon-tech-cloudflare-durable-objects", "icon-tech-cloudflareworkers", "icon-tech-cocoa", "icon-tech-confluent", "icon-tech-cord", "icon-tech-csharp", "icon-tech-curl", "icon-tech-customwebhooks", "icon-tech-datadog", "icon-tech-design-patterns", "icon-tech-devplatforms", "icon-tech-diffusion-data", "icon-tech-django", "icon-tech-engineio", "icon-tech-event-driven-servers", "icon-tech-fanout-io", "icon-tech-fast-api", "icon-tech-fauna", "icon-tech-featherjs", "icon-tech-firebase", "icon-tech-firebase-cloud-messaging", "icon-tech-flutter", "icon-tech-gcloudbigquery", "icon-tech-gclouddataflow", "icon-tech-gcloudfunctions", "icon-tech-gcloudpubsub", "icon-tech-go", "icon-tech-grpc", "icon-tech-hivemq", "icon-tech-http2", "icon-tech-http3", "icon-tech-httprest", "icon-tech-idempotency", "icon-tech-ifttt", "icon-tech-integrations", "icon-tech-ios", "icon-tech-ios-generic", "icon-tech-ipados", "icon-tech-ipfs", "icon-tech-ironmq", "icon-tech-java", "icon-tech-javascript", "icon-tech-jms", "icon-tech-json", "icon-tech-json-web-tokens", "icon-tech-kaazing", "icon-tech-kotlin", "icon-tech-ksql-db", "icon-tech-kubernetes", "icon-tech-laravel-broadcast", "icon-tech-laravel-echo", "icon-tech-lightstreamer", "icon-tech-liveblocks", "icon-tech-longpolling", "icon-tech-macos", "icon-tech-matrix", "icon-tech-meteor", "icon-tech-mongo-db", "icon-tech-mono", "icon-tech-mqtt", "icon-tech-mysql", "icon-tech-native-script", "icon-tech-net", "icon-tech-netlify", "icon-tech-nextjs", "icon-tech-nkn", "icon-tech-nodejs", "icon-tech-objectivec", "icon-tech-openai", "icon-tech-parse-server", "icon-tech-php", "icon-tech-planetscale", "icon-tech-postgres", "icon-tech-prisma", "icon-tech-programminglanguages", "icon-tech-protcol-adaptors", "icon-tech-protocols", "icon-tech-pub-sub", "icon-tech-pubnub", "icon-tech-push-technology", "icon-tech-pusher", "icon-tech-python", "icon-tech-quic", "icon-tech-rabbitMQ", "icon-tech-railsactioncable", "icon-tech-react", "icon-tech-react-app", "icon-tech-reactnative", "icon-tech-redis", "icon-tech-redpanda", "icon-tech-replicache", "icon-tech-rethinkdb", "icon-tech-rocketmq", "icon-tech-ruby", "icon-tech-scala", "icon-tech-scaledrone", "icon-tech-serversentevents", "icon-tech-serversideframeworks", "icon-tech-signalR", "icon-tech-snowflake", "icon-tech-socketio", "icon-tech-sockjs", "icon-tech-solace", "icon-tech-spring", "icon-tech-stomp", "icon-tech-streamdata-io", "icon-tech-streamr", "icon-tech-swift", "icon-tech-symfony", "icon-tech-symfony-mercure", "icon-tech-tcp-ip", "icon-tech-tenefit", "icon-tech-terraform", "icon-tech-terraform-outline", "icon-tech-tvos", "icon-tech-twilio", "icon-tech-typescript", "icon-tech-udp-protocol", "icon-tech-unity", "icon-tech-vercel", "icon-tech-vscode", "icon-tech-vuejs", "icon-tech-wamp", "icon-tech-watchos", "icon-tech-web", "icon-tech-web-push", "icon-tech-webhooks", "icon-tech-webrtc", "icon-tech-websockets", "icon-tech-websub", "icon-tech-xamarin", "icon-tech-xhr-streaming", "icon-tech-xmpp", "icon-tech-zapier", "icon-tech-zeromq"];
@@ -5390,6 +5408,44 @@ export default _default;
5390
5408
  //# sourceMappingURL=Logo.d.ts.map
5391
5409
  }
5392
5410
 
5411
+ declare module '@ably/ui/core/Meganav/MeganavBlog' {
5412
+ import { IconName } from ".@ably/ui/core/Icon/types";
5413
+ export type BlogPost = {
5414
+ title: string;
5415
+ link: string;
5416
+ categories: string[];
5417
+ pubDate: string;
5418
+ };
5419
+ export type MeganavBlogProps = {
5420
+ title: string;
5421
+ link: string;
5422
+ icon?: IconName;
5423
+ posts: BlogPost[];
5424
+ };
5425
+ const MeganavBlog: ({ title, link, icon, posts }: MeganavBlogProps) => import("react/jsx-runtime").JSX.Element;
5426
+ export default MeganavBlog;
5427
+ //# sourceMappingURL=MeganavBlog.d.ts.map
5428
+ }
5429
+
5430
+ declare module '@ably/ui/core/Meganav/MeganavCustomerStories' {
5431
+ import { IconName } from ".@ably/ui/core/Icon/types";
5432
+ export type CustomerStoryHighlight = {
5433
+ companyName: string;
5434
+ companyDesc: string;
5435
+ companyLink: string;
5436
+ companyLogo: string;
5437
+ companyLogoDark?: string;
5438
+ };
5439
+ const MeganavCustomerStories: ({ customerStoriesHighlight, title, link, icon, }: {
5440
+ customerStoriesHighlight: CustomerStoryHighlight;
5441
+ title: string;
5442
+ link: string;
5443
+ icon?: IconName;
5444
+ }) => import("react/jsx-runtime").JSX.Element;
5445
+ export default MeganavCustomerStories;
5446
+ //# sourceMappingURL=MeganavCustomerStories.d.ts.map
5447
+ }
5448
+
5393
5449
  declare module '@ably/ui/core/Meganav/MeganavMobile' {
5394
5450
  import { AccordionData } from ".@ably/ui/core/Accordion/types";
5395
5451
  export const MeganavMobile: ({ navItems }: {
@@ -5400,42 +5456,80 @@ export const MeganavMobile: ({ navItems }: {
5400
5456
 
5401
5457
  declare module '@ably/ui/core/Meganav/MeganavPanel' {
5402
5458
  import React from "react";
5403
- import { FlyoutPanelHighlight, FlyoutPanelList } from "@ably/ui/core/data";
5404
- export const MeganavPanel: ({ displayProductTile, panelLeft, panelLeftClassName, panelRightHeading, panelRightItems, panelRightBottom, }: {
5459
+ import { FlyoutPanelList } from "@ably/ui/core/data";
5460
+ import { MeganavPanelItemLink } from "@ably/ui/core/MeganavPanelItemLinks";
5461
+ type MeganavPanelProps = {
5405
5462
  displayProductTile?: boolean;
5406
- panelLeft?: FlyoutPanelHighlight;
5407
- panelLeftClassName?: string;
5408
- panelRightHeading?: string;
5409
- panelRightItems: FlyoutPanelList[];
5463
+ panelLeft?: React.ReactNode;
5464
+ panelMiddleItems?: React.ReactNode;
5465
+ panelRightItems?: MeganavPanelItemLink[];
5410
5466
  panelRightBottom?: React.ReactNode;
5467
+ panelRightBottomClassName?: string;
5468
+ };
5469
+ export const MeganavPanel: ({ displayProductTile, panelLeft, panelMiddleItems, panelRightItems, panelRightBottom, panelRightBottomClassName, }: MeganavPanelProps) => import("react/jsx-runtime").JSX.Element;
5470
+ export const MeganavPanelFullwidth: ({ panelItems, }: {
5471
+ panelItems: FlyoutPanelList[];
5411
5472
  }) => import("react/jsx-runtime").JSX.Element;
5473
+ export {};
5412
5474
  //# sourceMappingURL=MeganavPanel.d.ts.map
5413
5475
  }
5414
5476
 
5415
- declare module '@ably/ui/core/Meganav/MeganavProductTile' {
5416
- import { ProductTileProps } from ".@ably/ui/core/ProductTile";
5417
- const MeganavProductTile: ({ name, productLink, showDescription, showLabel, size, animateIcons, }: ProductTileProps & {
5418
- productLink?: string;
5477
+ declare module '@ably/ui/core/Meganav/MeganavPanelItemLinks' {
5478
+ import { IconName } from ".@ably/ui/core/Icon/types";
5479
+ import { FlyoutPanelList } from "@ably/ui/core/data";
5480
+ export type MeganavPanelItemLink = {
5481
+ label?: string;
5482
+ listItems: FlyoutPanelList[];
5483
+ icon?: IconName;
5484
+ link?: {
5485
+ label: string;
5486
+ link: string;
5487
+ };
5488
+ displayTitleInMobile?: boolean;
5489
+ };
5490
+ const MeganavPanelItemLinks: ({ label, listItems, link, displayTitleInMobile, }: MeganavPanelItemLink) => import("react/jsx-runtime").JSX.Element;
5491
+ export default MeganavPanelItemLinks;
5492
+ //# sourceMappingURL=MeganavPanelItemLinks.d.ts.map
5493
+ }
5494
+
5495
+ declare module '@ably/ui/core/Meganav/MeganavTile' {
5496
+ import { ProductName } from ".@ably/ui/core/ProductTile/data";
5497
+ import { IconName } from ".@ably/ui/core/Icon/types";
5498
+ export type MeganavTileProps = {
5499
+ link: string;
5500
+ productName?: ProductName;
5501
+ navLabel?: string;
5502
+ navIcon?: IconName;
5503
+ navDescription?: string;
5504
+ animateIcons?: boolean;
5505
+ showAblyText?: boolean;
5506
+ };
5507
+ const MeganavTile: ({ productName, navLabel, navIcon, navDescription, link, animateIcons, showAblyText, }: MeganavTileProps) => import("react/jsx-runtime").JSX.Element;
5508
+ export default MeganavTile;
5509
+ //# sourceMappingURL=MeganavTile.d.ts.map
5510
+ }
5511
+
5512
+ declare module '@ably/ui/core/Meganav/PanelTitle' {
5513
+ export const PanelTitle: ({ title, link, displayTitleInMobile, }: {
5514
+ title: string;
5515
+ link?: string;
5516
+ displayTitleInMobile?: boolean;
5419
5517
  }) => import("react/jsx-runtime").JSX.Element;
5420
- export default MeganavProductTile;
5421
- //# sourceMappingURL=MeganavProductTile.d.ts.map
5518
+ //# sourceMappingURL=PanelTitle.d.ts.map
5422
5519
  }
5423
5520
 
5424
5521
  declare module '@ably/ui/core/Meganav/data' {
5425
5522
  import React from "react";
5426
5523
  import { IconName } from ".@ably/ui/core/Icon/types";
5524
+ import { CustomerStoryHighlight } from "@ably/ui/core/MeganavCustomerStories";
5525
+ import { BlogPost } from "@ably/ui/core/MeganavBlog";
5427
5526
  export type FlyoutPanelList = {
5428
5527
  label: string;
5429
- icon: IconName;
5528
+ icon?: IconName;
5430
5529
  link: string;
5431
5530
  isMobile?: boolean;
5432
- };
5433
- export type FlyoutPanelHighlight = {
5434
- heading: string;
5435
- content: string;
5436
- labelLink: string;
5437
- url: string;
5438
- image: string;
5531
+ description?: string;
5532
+ badge?: string;
5439
5533
  };
5440
5534
  export type MenuItem = {
5441
5535
  name: string;
@@ -5444,6 +5538,11 @@ export type MenuItem = {
5444
5538
  content?: React.ReactNode;
5445
5539
  panelClassName?: string;
5446
5540
  };
5541
+ export const productsMenu: FlyoutPanelList[];
5542
+ export const compareMenu: FlyoutPanelList[];
5543
+ export const solutionsMenu: FlyoutPanelList[];
5544
+ export const customerStoriesHighlight: CustomerStoryHighlight;
5545
+ export const companyMenu: FlyoutPanelList[];
5447
5546
  export const ablyAwards: {
5448
5547
  image: string;
5449
5548
  desc: string;
@@ -5453,7 +5552,7 @@ export const menuItemLinks: {
5453
5552
  link: string;
5454
5553
  isHiddenMobile: boolean;
5455
5554
  }[];
5456
- export const menuItemsForHeader: MenuItem[];
5555
+ export const defaultBlogPosts: BlogPost[];
5457
5556
  export const productsForNav: {
5458
5557
  pubsub: {
5459
5558
  link: string;
@@ -5507,8 +5606,16 @@ export const productsForNav: {
5507
5606
  //# sourceMappingURL=data.d.ts.map
5508
5607
  }
5509
5608
 
5609
+ declare module '@ably/ui/core/Meganav/utils/getMenuItemsForHeader' {
5610
+ import { BlogPost } from ".@ably/ui/core/MeganavBlog";
5611
+ import { MenuItem } from ".@ably/ui/core/data";
5612
+ export const getMenuItemsForHeader: (blogPosts: BlogPost[]) => MenuItem[];
5613
+ //# sourceMappingURL=getMenuItemsForHeader.d.ts.map
5614
+ }
5615
+
5510
5616
  declare module '@ably/ui/core/Meganav' {
5511
5617
  import { HeaderSessionState, ThemedScrollpoint } from "@ably/ui/core/Header";
5618
+ import { BlogPost } from "@ably/ui/core/Meganav/MeganavBlog";
5512
5619
  export type MeganavNoticeBannerProps = {
5513
5620
  props: {
5514
5621
  title: string;
@@ -5527,12 +5634,13 @@ export type MeganavNoticeBannerProps = {
5527
5634
  };
5528
5635
  export type MeganavProps = {
5529
5636
  sessionState: HeaderSessionState;
5637
+ blogPosts: BlogPost[];
5530
5638
  notice?: MeganavNoticeBannerProps;
5531
5639
  theme?: string;
5532
5640
  themedScrollpoints?: ThemedScrollpoint[];
5533
5641
  onNoticeClose?: () => void;
5534
5642
  };
5535
- const Meganav: ({ sessionState, notice, theme, themedScrollpoints, onNoticeClose, }: MeganavProps) => import("react/jsx-runtime").JSX.Element;
5643
+ const Meganav: ({ sessionState, notice, theme, themedScrollpoints, onNoticeClose, blogPosts, }: MeganavProps) => import("react/jsx-runtime").JSX.Element;
5536
5644
  export default Meganav;
5537
5645
  //# sourceMappingURL=Meganav.d.ts.map
5538
5646
  }
@@ -5680,9 +5788,10 @@ type ProductLabelProps = {
5680
5788
  selected?: boolean;
5681
5789
  numericalSize: number;
5682
5790
  showLabel?: boolean;
5791
+ showAblyText?: boolean;
5683
5792
  className?: string;
5684
5793
  };
5685
- const ProductLabel: ({ label, unavailable, selected, numericalSize, showLabel, className, }: ProductLabelProps) => import("react/jsx-runtime").JSX.Element | null;
5794
+ const ProductLabel: ({ label, unavailable, selected, numericalSize, showLabel, showAblyText, className, }: ProductLabelProps) => import("react/jsx-runtime").JSX.Element | null;
5686
5795
  export default ProductLabel;
5687
5796
  //# sourceMappingURL=ProductLabel.d.ts.map
5688
5797
  }
@@ -6005,20 +6114,6 @@ export default useRailsUjsLinks;
6005
6114
  //# sourceMappingURL=use-rails-ujs-hooks.d.ts.map
6006
6115
  }
6007
6116
 
6008
- declare module '@ably/ui/core/hooks/use-themed-scrollpoints' {
6009
- import { ThemedScrollpoint } from ".@ably/ui/core/Header/types";
6010
- export function useThemedScrollpoints(scrollpoints: ThemedScrollpoint[]): string;
6011
- //# sourceMappingURL=use-themed-scrollpoints.d.ts.map
6012
- }
6013
-
6014
- declare module '@ably/ui/core/hooks/use-themed-scrollpoints.test' {
6015
- /**
6016
- * @vitest-environment jsdom
6017
- */
6018
- export {};
6019
- //# sourceMappingURL=use-themed-scrollpoints.test.d.ts.map
6020
- }
6021
-
6022
6117
  declare module '@ably/ui/core/insights/command-queue' {
6023
6118
  import { AnalyticsService, InsightsConfig, InsightsIdentity, TrackPageViewOptions } from "@ably/ui/core/types";
6024
6119
  export class InsightsCommandQueue implements AnalyticsService {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ably/ui",
3
- "version": "17.11.0-dev.4c4b6b55",
3
+ "version": "17.11.0",
4
4
  "description": "Home of the Ably design system library ([design.ably.com](https://design.ably.com)). It provides a showcase, development/test environment and a publishing pipeline for different distributables.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,14 +31,13 @@
31
31
  "@swc/cli": "^0.7.8",
32
32
  "@swc/core": "^1.13.5",
33
33
  "@tailwindcss/container-queries": "^0.1.1",
34
- "@testing-library/react": "^16.3.0",
35
34
  "@types/js-cookie": "^3.0.6",
36
35
  "@types/node": "^20",
37
36
  "@types/react": "^18.3.1",
38
37
  "@types/react-dom": "^18.3.0",
39
38
  "@types/svg-sprite": "^0.0.39",
40
- "@typescript-eslint/eslint-plugin": "^8.25.0",
41
- "@typescript-eslint/parser": "^8.25.0",
39
+ "@typescript-eslint/eslint-plugin": "^8.49.0",
40
+ "@typescript-eslint/parser": "^8.49.0",
42
41
  "@vitejs/plugin-react-swc": "^4.0.1",
43
42
  "@vitest/browser": "3.2.4",
44
43
  "@vitest/coverage-v8": "3.2.4",
@@ -52,12 +51,12 @@
52
51
  "eslint-plugin-storybook": "^10.0.0",
53
52
  "heroicons": "^2.2.0",
54
53
  "http-server": "14.1.1",
55
- "jsdom": "^27.0.0",
54
+ "jsdom": "^27.3.0",
56
55
  "mixpanel-browser": "^2.60.0",
57
56
  "msw": "2.12.0",
58
57
  "msw-storybook-addon": "^2.0.5",
59
58
  "playwright": "^1.49.1",
60
- "posthog-js": "^1.217.4",
59
+ "posthog-js": "^1.302.0",
61
60
  "prettier": "^3.2.5",
62
61
  "storybook": "^10.0.0",
63
62
  "svg-sprite": "^2.0.4",
@@ -1,2 +0,0 @@
1
- export{};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/core/Header/types.ts"],"sourcesContent":["export type ThemedScrollpoint = {\n id: string;\n className: string;\n};\n"],"names":[],"mappings":"AAAA,QAGE"}
@@ -1,2 +0,0 @@
1
- import React from"react";import cn from"../utils/cn";import{products}from"../ProductTile/data";import ProductIcon from"../ProductTile/ProductIcon";import ProductLabel from"../ProductTile/ProductLabel";import ProductDescription from"../ProductTile/ProductDescription";const CONTAINER_GAP_RATIO=3;const MeganavProductTile=({name,productLink,showDescription=true,showLabel=true,size="40px",animateIcons=false})=>{const{icon,hoverIcon,label,unavailable,description}=products[name]??{};const numericalSize=parseInt(size,10);return React.createElement("a",{href:productLink?productLink:"#",className:cn("transition-colors group/product-tile","flex flex-col p-3 rounded-lg gap-2","bg-neutral-000 dark:bg-neutral-1300",{"hover:bg-neutral-100 dark:hover:bg-neutral-1200":!unavailable},{"pointer-events-auto":!unavailable},{"pointer-events-none":unavailable}),"aria-hidden":unavailable},React.createElement("span",{className:cn("items-center flex"),style:{gap:numericalSize/CONTAINER_GAP_RATIO}},React.createElement(ProductIcon,{size:numericalSize,name:icon,hoverName:animateIcons?hoverIcon:undefined,unavailable:!!unavailable,selected:false}),React.createElement(ProductLabel,{label:label,unavailable:!!unavailable,numericalSize:numericalSize,showLabel:showLabel,selected:false})),React.createElement(ProductDescription,{description:description,unavailable:!!unavailable,showDescription:showDescription,selected:false}))};export default MeganavProductTile;
2
- //# sourceMappingURL=MeganavProductTile.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/core/Meganav/MeganavProductTile.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"../utils/cn\";\nimport { products } from \"../ProductTile/data\";\nimport ProductIcon from \"../ProductTile/ProductIcon\";\nimport ProductLabel from \"../ProductTile/ProductLabel\";\nimport ProductDescription from \"../ProductTile/ProductDescription\";\nimport { ProductTileProps } from \"../ProductTile\";\n\nconst CONTAINER_GAP_RATIO = 3;\n\nconst MeganavProductTile = ({\n name,\n productLink,\n showDescription = true,\n showLabel = true,\n size = \"40px\",\n animateIcons = false,\n}: ProductTileProps & { productLink?: string }) => {\n const { icon, hoverIcon, label, unavailable, description } =\n products[name] ?? {};\n const numericalSize = parseInt(size, 10);\n\n return (\n <a\n href={productLink ? productLink : \"#\"}\n className={cn(\n \"transition-colors group/product-tile\",\n \"flex flex-col p-3 rounded-lg gap-2\",\n \"bg-neutral-000 dark:bg-neutral-1300\",\n {\n \"hover:bg-neutral-100 dark:hover:bg-neutral-1200\": !unavailable,\n },\n { \"pointer-events-auto\": !unavailable },\n { \"pointer-events-none\": unavailable },\n )}\n aria-hidden={unavailable}\n >\n <span\n className={cn(\"items-center flex\")}\n style={{\n gap: numericalSize / CONTAINER_GAP_RATIO,\n }}\n >\n <ProductIcon\n size={numericalSize}\n name={icon}\n hoverName={animateIcons ? hoverIcon : undefined}\n unavailable={!!unavailable}\n selected={false}\n />\n <ProductLabel\n label={label}\n unavailable={!!unavailable}\n numericalSize={numericalSize}\n showLabel={showLabel}\n selected={false}\n />\n </span>\n <ProductDescription\n description={description}\n unavailable={!!unavailable}\n showDescription={showDescription}\n selected={false}\n />\n </a>\n );\n};\n\nexport default MeganavProductTile;\n"],"names":["React","cn","products","ProductIcon","ProductLabel","ProductDescription","CONTAINER_GAP_RATIO","MeganavProductTile","name","productLink","showDescription","showLabel","size","animateIcons","icon","hoverIcon","label","unavailable","description","numericalSize","parseInt","a","href","className","aria-hidden","span","style","gap","hoverName","undefined","selected"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QAAOC,OAAQ,aAAc,AAC7B,QAASC,QAAQ,KAAQ,qBAAsB,AAC/C,QAAOC,gBAAiB,4BAA6B,AACrD,QAAOC,iBAAkB,6BAA8B,AACvD,QAAOC,uBAAwB,mCAAoC,CAGnE,MAAMC,oBAAsB,EAE5B,MAAMC,mBAAqB,CAAC,CAC1BC,IAAI,CACJC,WAAW,CACXC,gBAAkB,IAAI,CACtBC,UAAY,IAAI,CAChBC,KAAO,MAAM,CACbC,aAAe,KAAK,CACwB,IAC5C,KAAM,CAAEC,IAAI,CAAEC,SAAS,CAAEC,KAAK,CAAEC,WAAW,CAAEC,WAAW,CAAE,CACxDhB,QAAQ,CAACM,KAAK,EAAI,CAAC,EACrB,MAAMW,cAAgBC,SAASR,KAAM,IAErC,OACE,oBAACS,KACCC,KAAMb,YAAcA,YAAc,IAClCc,UAAWtB,GACT,uCACA,qCACA,sCACA,CACE,kDAAmD,CAACgB,WACtD,EACA,CAAE,sBAAuB,CAACA,WAAY,EACtC,CAAE,sBAAuBA,WAAY,GAEvCO,cAAaP,aAEb,oBAACQ,QACCF,UAAWtB,GAAG,qBACdyB,MAAO,CACLC,IAAKR,cAAgBb,mBACvB,GAEA,oBAACH,aACCS,KAAMO,cACNX,KAAMM,KACNc,UAAWf,aAAeE,UAAYc,UACtCZ,YAAa,CAAC,CAACA,YACfa,SAAU,QAEZ,oBAAC1B,cACCY,MAAOA,MACPC,YAAa,CAAC,CAACA,YACfE,cAAeA,cACfR,UAAWA,UACXmB,SAAU,SAGd,oBAACzB,oBACCa,YAAaA,YACbD,YAAa,CAAC,CAACA,YACfP,gBAAiBA,gBACjBoB,SAAU,QAIlB,CAEA,gBAAevB,kBAAmB"}
@@ -1,2 +0,0 @@
1
- import{useState,useEffect,useRef}from"react";const HEADER_HEIGHT=64;export function useThemedScrollpoints(scrollpoints){const[activeClassName,setActiveClassName]=useState(scrollpoints.length>0?scrollpoints[0].className:"");const previousClassNameRef=useRef(activeClassName);const observerRef=useRef(null);useEffect(()=>{if(scrollpoints.length===0){return}observerRef.current=new IntersectionObserver(entries=>{requestAnimationFrame(()=>{for(const entry of entries){if(entry.isIntersecting){const scrollpoint=scrollpoints.find(sp=>sp.id===entry.target.id);if(scrollpoint&&scrollpoint.className!==previousClassNameRef.current){previousClassNameRef.current=scrollpoint.className;setActiveClassName(scrollpoint.className);return}}}})},{rootMargin:`-${HEADER_HEIGHT}px 0px 0px 0px`,threshold:0});scrollpoints.forEach(({id})=>{const element=document.getElementById(id);if(element){observerRef.current?.observe(element)}else{console.warn(`useThemedScrollpoints: Element with id "${id}" not found in DOM`)}});return()=>{observerRef.current?.disconnect();observerRef.current=null}},[scrollpoints]);return activeClassName}
2
- //# sourceMappingURL=use-themed-scrollpoints.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/core/hooks/use-themed-scrollpoints.ts"],"sourcesContent":["import { useState, useEffect, useRef } from \"react\";\nimport { ThemedScrollpoint } from \"../Header/types\";\n\nconst HEADER_HEIGHT = 64;\n\nexport function useThemedScrollpoints(\n scrollpoints: ThemedScrollpoint[]\n): string {\n const [activeClassName, setActiveClassName] = useState<string>(\n scrollpoints.length > 0 ? scrollpoints[0].className : \"\"\n );\n\n const previousClassNameRef = useRef<string>(activeClassName);\n const observerRef = useRef<IntersectionObserver | null>(null);\n\n useEffect(() => {\n if (scrollpoints.length === 0) {\n return;\n }\n\n observerRef.current = new IntersectionObserver(\n (entries) => {\n requestAnimationFrame(() => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n const scrollpoint = scrollpoints.find(\n (sp) => sp.id === entry.target.id\n );\n\n if (scrollpoint && scrollpoint.className !== previousClassNameRef.current) {\n previousClassNameRef.current = scrollpoint.className;\n setActiveClassName(scrollpoint.className);\n return;\n }\n }\n }\n });\n },\n {\n rootMargin: `-${HEADER_HEIGHT}px 0px 0px 0px`,\n threshold: 0,\n }\n );\n\n scrollpoints.forEach(({ id }) => {\n const element = document.getElementById(id);\n if (element) {\n observerRef.current?.observe(element);\n } else {\n console.warn(\n `useThemedScrollpoints: Element with id \"${id}\" not found in DOM`\n );\n }\n });\n\n return () => {\n observerRef.current?.disconnect();\n observerRef.current = null;\n };\n }, [scrollpoints]);\n\n return activeClassName;\n}\n"],"names":["useState","useEffect","useRef","HEADER_HEIGHT","useThemedScrollpoints","scrollpoints","activeClassName","setActiveClassName","length","className","previousClassNameRef","observerRef","current","IntersectionObserver","entries","requestAnimationFrame","entry","isIntersecting","scrollpoint","find","sp","id","target","rootMargin","threshold","forEach","element","document","getElementById","observe","console","warn","disconnect"],"mappings":"AAAA,OAASA,QAAQ,CAAEC,SAAS,CAAEC,MAAM,KAAQ,OAAQ,CAGpD,MAAMC,cAAgB,EAEtB,QAAO,SAASC,sBACdC,YAAiC,EAEjC,KAAM,CAACC,gBAAiBC,mBAAmB,CAAGP,SAC5CK,aAAaG,MAAM,CAAG,EAAIH,YAAY,CAAC,EAAE,CAACI,SAAS,CAAG,IAGxD,MAAMC,qBAAuBR,OAAeI,iBAC5C,MAAMK,YAAcT,OAAoC,MAExDD,UAAU,KACR,GAAII,aAAaG,MAAM,GAAK,EAAG,CAC7B,MACF,CAEAG,YAAYC,OAAO,CAAG,IAAIC,qBACxB,AAACC,UACCC,sBAAsB,KACpB,IAAK,MAAMC,SAASF,QAAS,CAC3B,GAAIE,MAAMC,cAAc,CAAE,CACxB,MAAMC,YAAcb,aAAac,IAAI,CACnC,AAACC,IAAOA,GAAGC,EAAE,GAAKL,MAAMM,MAAM,CAACD,EAAE,EAGnC,GAAIH,aAAeA,YAAYT,SAAS,GAAKC,qBAAqBE,OAAO,CAAE,CACzEF,qBAAqBE,OAAO,CAAGM,YAAYT,SAAS,CACpDF,mBAAmBW,YAAYT,SAAS,EACxC,MACF,CACF,CACF,CACF,EACF,EACA,CACEc,WAAY,CAAC,CAAC,EAAEpB,cAAc,cAAc,CAAC,CAC7CqB,UAAW,CACb,GAGFnB,aAAaoB,OAAO,CAAC,CAAC,CAAEJ,EAAE,CAAE,IAC1B,MAAMK,QAAUC,SAASC,cAAc,CAACP,IACxC,GAAIK,QAAS,CACXf,YAAYC,OAAO,EAAEiB,QAAQH,QAC/B,KAAO,CACLI,QAAQC,IAAI,CACV,CAAC,wCAAwC,EAAEV,GAAG,kBAAkB,CAAC,CAErE,CACF,GAEA,MAAO,KACLV,YAAYC,OAAO,EAAEoB,YACrBrB,CAAAA,YAAYC,OAAO,CAAG,IACxB,CACF,EAAG,CAACP,aAAa,EAEjB,OAAOC,eACT"}
@@ -1,2 +0,0 @@
1
- import{describe,it,expect,beforeEach,afterEach,vi}from"vitest";import{renderHook,waitFor}from"@testing-library/react";import{useThemedScrollpoints}from"./use-themed-scrollpoints";describe("useThemedScrollpoints",()=>{let observerCallback;let mockObserve;let mockUnobserve;let mockDisconnect;beforeEach(()=>{mockObserve=vi.fn();mockUnobserve=vi.fn();mockDisconnect=vi.fn();global.IntersectionObserver=vi.fn(callback=>{observerCallback=callback;return{observe:mockObserve,unobserve:mockUnobserve,disconnect:mockDisconnect}});global.requestAnimationFrame=vi.fn(cb=>{cb(0);return 0})});afterEach(()=>{vi.clearAllMocks();document.body.innerHTML=""});it("returns first scrollpoint className on mount",()=>{const scrollpoints=[{id:"zone1",className:"theme-light"},{id:"zone2",className:"theme-dark"}];const{result}=renderHook(()=>useThemedScrollpoints(scrollpoints));expect(result.current).toBe("theme-light")});it("returns empty string when no scrollpoints provided",()=>{const{result}=renderHook(()=>useThemedScrollpoints([]));expect(result.current).toBe("")});it("does not create IntersectionObserver when no scrollpoints provided",()=>{renderHook(()=>useThemedScrollpoints([]));expect(IntersectionObserver).not.toHaveBeenCalled()});it("creates IntersectionObserver with correct config",()=>{const scrollpoints=[{id:"zone1",className:"theme-light"}];const elem=document.createElement("div");elem.id="zone1";document.body.appendChild(elem);renderHook(()=>useThemedScrollpoints(scrollpoints));expect(IntersectionObserver).toHaveBeenCalledWith(expect.any(Function),expect.objectContaining({rootMargin:"-64px 0px 0px 0px",threshold:0}))});it("observes all scrollpoint elements that exist in DOM",()=>{const elem1=document.createElement("div");elem1.id="zone1";const elem2=document.createElement("div");elem2.id="zone2";document.body.appendChild(elem1);document.body.appendChild(elem2);const scrollpoints=[{id:"zone1",className:"theme-light"},{id:"zone2",className:"theme-dark"}];renderHook(()=>useThemedScrollpoints(scrollpoints));expect(mockObserve).toHaveBeenCalledTimes(2);expect(mockObserve).toHaveBeenCalledWith(elem1);expect(mockObserve).toHaveBeenCalledWith(elem2)});it("logs warning for missing DOM elements",()=>{const consoleWarn=vi.spyOn(console,"warn").mockImplementation(()=>{});const scrollpoints=[{id:"non-existent",className:"theme"}];renderHook(()=>useThemedScrollpoints(scrollpoints));expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('Element with id "non-existent" not found'));consoleWarn.mockRestore()});it("observes existing elements and warns about missing ones",()=>{const consoleWarn=vi.spyOn(console,"warn").mockImplementation(()=>{});const elem=document.createElement("div");elem.id="zone1";document.body.appendChild(elem);const scrollpoints=[{id:"zone1",className:"theme-light"},{id:"missing",className:"theme-dark"}];renderHook(()=>useThemedScrollpoints(scrollpoints));expect(mockObserve).toHaveBeenCalledTimes(1);expect(mockObserve).toHaveBeenCalledWith(elem);expect(consoleWarn).toHaveBeenCalledWith(expect.stringContaining('Element with id "missing" not found'));consoleWarn.mockRestore()});it("updates className when intersection occurs",async()=>{const elem1=document.createElement("div");elem1.id="zone1";const elem2=document.createElement("div");elem2.id="zone2";document.body.appendChild(elem1);document.body.appendChild(elem2);const scrollpoints=[{id:"zone1",className:"theme-light"},{id:"zone2",className:"theme-dark"}];const{result}=renderHook(()=>useThemedScrollpoints(scrollpoints));expect(result.current).toBe("theme-light");observerCallback([{target:elem2,isIntersecting:true}],{});await waitFor(()=>{expect(result.current).toBe("theme-dark")})});it("does not update className if same scrollpoint intersects again",async()=>{const elem=document.createElement("div");elem.id="zone1";document.body.appendChild(elem);const scrollpoints=[{id:"zone1",className:"theme-light"}];const{result}=renderHook(()=>useThemedScrollpoints(scrollpoints));expect(result.current).toBe("theme-light");const renderCount=result.current;observerCallback([{target:elem,isIntersecting:true}],{});expect(result.current).toBe(renderCount)});it("ignores non-intersecting entries",async()=>{const elem1=document.createElement("div");elem1.id="zone1";const elem2=document.createElement("div");elem2.id="zone2";document.body.appendChild(elem1);document.body.appendChild(elem2);const scrollpoints=[{id:"zone1",className:"theme-light"},{id:"zone2",className:"theme-dark"}];const{result}=renderHook(()=>useThemedScrollpoints(scrollpoints));expect(result.current).toBe("theme-light");observerCallback([{target:elem2,isIntersecting:false}],{});expect(result.current).toBe("theme-light")});it("uses first intersecting entry when multiple entries intersect",async()=>{const elem1=document.createElement("div");elem1.id="zone1";const elem2=document.createElement("div");elem2.id="zone2";const elem3=document.createElement("div");elem3.id="zone3";document.body.appendChild(elem1);document.body.appendChild(elem2);document.body.appendChild(elem3);const scrollpoints=[{id:"zone1",className:"theme-light"},{id:"zone2",className:"theme-dark"},{id:"zone3",className:"theme-blue"}];const{result}=renderHook(()=>useThemedScrollpoints(scrollpoints));observerCallback([{target:elem2,isIntersecting:true},{target:elem3,isIntersecting:true}],{});await waitFor(()=>{expect(result.current).toBe("theme-dark")})});it("disconnects observer on unmount",()=>{const elem=document.createElement("div");elem.id="zone1";document.body.appendChild(elem);const scrollpoints=[{id:"zone1",className:"theme-light"}];const{unmount}=renderHook(()=>useThemedScrollpoints(scrollpoints));unmount();expect(mockDisconnect).toHaveBeenCalled()});it("recreates observer when scrollpoints change",()=>{const elem1=document.createElement("div");elem1.id="zone1";const elem2=document.createElement("div");elem2.id="zone2";document.body.appendChild(elem1);document.body.appendChild(elem2);const{rerender}=renderHook(({scrollpoints})=>useThemedScrollpoints(scrollpoints),{initialProps:{scrollpoints:[{id:"zone1",className:"theme-light"}]}});expect(IntersectionObserver).toHaveBeenCalledTimes(1);expect(mockObserve).toHaveBeenCalledTimes(1);rerender({scrollpoints:[{id:"zone1",className:"theme-light"},{id:"zone2",className:"theme-dark"}]});expect(mockDisconnect).toHaveBeenCalledTimes(1);expect(IntersectionObserver).toHaveBeenCalledTimes(2);expect(mockObserve).toHaveBeenCalledTimes(3)});it("uses requestAnimationFrame for state updates",()=>{const elem=document.createElement("div");elem.id="zone1";document.body.appendChild(elem);const scrollpoints=[{id:"zone1",className:"theme-light"},{id:"zone2",className:"theme-dark"}];renderHook(()=>useThemedScrollpoints(scrollpoints));const rafSpy=vi.spyOn(global,"requestAnimationFrame");observerCallback([{target:elem,isIntersecting:true}],{});expect(rafSpy).toHaveBeenCalled();rafSpy.mockRestore()})});
2
- //# sourceMappingURL=use-themed-scrollpoints.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/core/hooks/use-themed-scrollpoints.test.ts"],"sourcesContent":["/**\n * @vitest-environment jsdom\n */\n\nimport { describe, it, expect, beforeEach, afterEach, vi } from \"vitest\";\nimport { renderHook, waitFor } from \"@testing-library/react\";\nimport { useThemedScrollpoints } from \"./use-themed-scrollpoints\";\n\ndescribe(\"useThemedScrollpoints\", () => {\n let observerCallback: IntersectionObserverCallback;\n let mockObserve: ReturnType<typeof vi.fn>;\n let mockUnobserve: ReturnType<typeof vi.fn>;\n let mockDisconnect: ReturnType<typeof vi.fn>;\n\n beforeEach(() => {\n // Mock IntersectionObserver\n mockObserve = vi.fn();\n mockUnobserve = vi.fn();\n mockDisconnect = vi.fn();\n\n global.IntersectionObserver = vi.fn((callback) => {\n observerCallback = callback;\n return {\n observe: mockObserve,\n unobserve: mockUnobserve,\n disconnect: mockDisconnect,\n };\n }) as any;\n\n // Mock requestAnimationFrame\n global.requestAnimationFrame = vi.fn((cb) => {\n cb(0);\n return 0;\n });\n });\n\n afterEach(() => {\n vi.clearAllMocks();\n document.body.innerHTML = \"\";\n });\n\n it(\"returns first scrollpoint className on mount\", () => {\n const scrollpoints = [\n { id: \"zone1\", className: \"theme-light\" },\n { id: \"zone2\", className: \"theme-dark\" },\n ];\n\n const { result } = renderHook(() => useThemedScrollpoints(scrollpoints));\n\n expect(result.current).toBe(\"theme-light\");\n });\n\n it(\"returns empty string when no scrollpoints provided\", () => {\n const { result } = renderHook(() => useThemedScrollpoints([]));\n expect(result.current).toBe(\"\");\n });\n\n it(\"does not create IntersectionObserver when no scrollpoints provided\", () => {\n renderHook(() => useThemedScrollpoints([]));\n\n expect(IntersectionObserver).not.toHaveBeenCalled();\n });\n\n it(\"creates IntersectionObserver with correct config\", () => {\n const scrollpoints = [{ id: \"zone1\", className: \"theme-light\" }];\n\n // Create DOM element\n const elem = document.createElement(\"div\");\n elem.id = \"zone1\";\n document.body.appendChild(elem);\n\n renderHook(() => useThemedScrollpoints(scrollpoints));\n\n expect(IntersectionObserver).toHaveBeenCalledWith(\n expect.any(Function),\n expect.objectContaining({\n rootMargin: \"-64px 0px 0px 0px\",\n threshold: 0,\n })\n );\n });\n\n it(\"observes all scrollpoint elements that exist in DOM\", () => {\n // Create DOM elements\n const elem1 = document.createElement(\"div\");\n elem1.id = \"zone1\";\n const elem2 = document.createElement(\"div\");\n elem2.id = \"zone2\";\n document.body.appendChild(elem1);\n document.body.appendChild(elem2);\n\n const scrollpoints = [\n { id: \"zone1\", className: \"theme-light\" },\n { id: \"zone2\", className: \"theme-dark\" },\n ];\n\n renderHook(() => useThemedScrollpoints(scrollpoints));\n\n expect(mockObserve).toHaveBeenCalledTimes(2);\n expect(mockObserve).toHaveBeenCalledWith(elem1);\n expect(mockObserve).toHaveBeenCalledWith(elem2);\n });\n\n it(\"logs warning for missing DOM elements\", () => {\n const consoleWarn = vi.spyOn(console, \"warn\").mockImplementation(() => {});\n\n const scrollpoints = [{ id: \"non-existent\", className: \"theme\" }];\n\n renderHook(() => useThemedScrollpoints(scrollpoints));\n\n expect(consoleWarn).toHaveBeenCalledWith(\n expect.stringContaining('Element with id \"non-existent\" not found')\n );\n\n consoleWarn.mockRestore();\n });\n\n it(\"observes existing elements and warns about missing ones\", () => {\n const consoleWarn = vi.spyOn(console, \"warn\").mockImplementation(() => {});\n\n // Create only one element\n const elem = document.createElement(\"div\");\n elem.id = \"zone1\";\n document.body.appendChild(elem);\n\n const scrollpoints = [\n { id: \"zone1\", className: \"theme-light\" },\n { id: \"missing\", className: \"theme-dark\" },\n ];\n\n renderHook(() => useThemedScrollpoints(scrollpoints));\n\n expect(mockObserve).toHaveBeenCalledTimes(1);\n expect(mockObserve).toHaveBeenCalledWith(elem);\n expect(consoleWarn).toHaveBeenCalledWith(\n expect.stringContaining('Element with id \"missing\" not found')\n );\n\n consoleWarn.mockRestore();\n });\n\n it(\"updates className when intersection occurs\", async () => {\n // Create DOM elements\n const elem1 = document.createElement(\"div\");\n elem1.id = \"zone1\";\n const elem2 = document.createElement(\"div\");\n elem2.id = \"zone2\";\n document.body.appendChild(elem1);\n document.body.appendChild(elem2);\n\n const scrollpoints = [\n { id: \"zone1\", className: \"theme-light\" },\n { id: \"zone2\", className: \"theme-dark\" },\n ];\n\n const { result } = renderHook(() => useThemedScrollpoints(scrollpoints));\n\n // Initial state\n expect(result.current).toBe(\"theme-light\");\n\n // Simulate intersection with zone2\n observerCallback(\n [\n {\n target: elem2,\n isIntersecting: true,\n } as unknown as IntersectionObserverEntry,\n ],\n {} as IntersectionObserver\n );\n\n await waitFor(() => {\n expect(result.current).toBe(\"theme-dark\");\n });\n });\n\n it(\"does not update className if same scrollpoint intersects again\", async () => {\n const elem = document.createElement(\"div\");\n elem.id = \"zone1\";\n document.body.appendChild(elem);\n\n const scrollpoints = [{ id: \"zone1\", className: \"theme-light\" }];\n\n const { result } = renderHook(() => useThemedScrollpoints(scrollpoints));\n\n expect(result.current).toBe(\"theme-light\");\n\n // Simulate intersection with same element\n const renderCount = result.current;\n observerCallback(\n [\n {\n target: elem,\n isIntersecting: true,\n } as unknown as IntersectionObserverEntry,\n ],\n {} as IntersectionObserver\n );\n\n // Should not trigger re-render (className unchanged)\n expect(result.current).toBe(renderCount);\n });\n\n it(\"ignores non-intersecting entries\", async () => {\n const elem1 = document.createElement(\"div\");\n elem1.id = \"zone1\";\n const elem2 = document.createElement(\"div\");\n elem2.id = \"zone2\";\n document.body.appendChild(elem1);\n document.body.appendChild(elem2);\n\n const scrollpoints = [\n { id: \"zone1\", className: \"theme-light\" },\n { id: \"zone2\", className: \"theme-dark\" },\n ];\n\n const { result } = renderHook(() => useThemedScrollpoints(scrollpoints));\n\n expect(result.current).toBe(\"theme-light\");\n\n // Simulate non-intersecting entry\n observerCallback(\n [\n {\n target: elem2,\n isIntersecting: false,\n } as unknown as IntersectionObserverEntry,\n ],\n {} as IntersectionObserver\n );\n\n // Should remain unchanged\n expect(result.current).toBe(\"theme-light\");\n });\n\n it(\"uses first intersecting entry when multiple entries intersect\", async () => {\n const elem1 = document.createElement(\"div\");\n elem1.id = \"zone1\";\n const elem2 = document.createElement(\"div\");\n elem2.id = \"zone2\";\n const elem3 = document.createElement(\"div\");\n elem3.id = \"zone3\";\n document.body.appendChild(elem1);\n document.body.appendChild(elem2);\n document.body.appendChild(elem3);\n\n const scrollpoints = [\n { id: \"zone1\", className: \"theme-light\" },\n { id: \"zone2\", className: \"theme-dark\" },\n { id: \"zone3\", className: \"theme-blue\" },\n ];\n\n const { result } = renderHook(() => useThemedScrollpoints(scrollpoints));\n\n // Simulate multiple intersections (zone2 and zone3 both intersecting)\n observerCallback(\n [\n {\n target: elem2,\n isIntersecting: true,\n } as unknown as IntersectionObserverEntry,\n {\n target: elem3,\n isIntersecting: true,\n } as unknown as IntersectionObserverEntry,\n ],\n {} as IntersectionObserver\n );\n\n await waitFor(() => {\n // Should use first intersecting entry (zone2)\n expect(result.current).toBe(\"theme-dark\");\n });\n });\n\n it(\"disconnects observer on unmount\", () => {\n const elem = document.createElement(\"div\");\n elem.id = \"zone1\";\n document.body.appendChild(elem);\n\n const scrollpoints = [{ id: \"zone1\", className: \"theme-light\" }];\n\n const { unmount } = renderHook(() => useThemedScrollpoints(scrollpoints));\n\n unmount();\n\n expect(mockDisconnect).toHaveBeenCalled();\n });\n\n it(\"recreates observer when scrollpoints change\", () => {\n const elem1 = document.createElement(\"div\");\n elem1.id = \"zone1\";\n const elem2 = document.createElement(\"div\");\n elem2.id = \"zone2\";\n document.body.appendChild(elem1);\n document.body.appendChild(elem2);\n\n const { rerender } = renderHook(\n ({ scrollpoints }) => useThemedScrollpoints(scrollpoints),\n {\n initialProps: {\n scrollpoints: [{ id: \"zone1\", className: \"theme-light\" }],\n },\n }\n );\n\n expect(IntersectionObserver).toHaveBeenCalledTimes(1);\n expect(mockObserve).toHaveBeenCalledTimes(1);\n\n // Change scrollpoints\n rerender({\n scrollpoints: [\n { id: \"zone1\", className: \"theme-light\" },\n { id: \"zone2\", className: \"theme-dark\" },\n ],\n });\n\n // Should disconnect old observer and create new one\n expect(mockDisconnect).toHaveBeenCalledTimes(1);\n expect(IntersectionObserver).toHaveBeenCalledTimes(2);\n expect(mockObserve).toHaveBeenCalledTimes(3); // 1 from first render + 2 from second\n });\n\n it(\"uses requestAnimationFrame for state updates\", () => {\n const elem = document.createElement(\"div\");\n elem.id = \"zone1\";\n document.body.appendChild(elem);\n\n const scrollpoints = [\n { id: \"zone1\", className: \"theme-light\" },\n { id: \"zone2\", className: \"theme-dark\" },\n ];\n\n renderHook(() => useThemedScrollpoints(scrollpoints));\n\n const rafSpy = vi.spyOn(global, \"requestAnimationFrame\");\n\n // Simulate intersection\n observerCallback(\n [\n {\n target: elem,\n isIntersecting: true,\n } as unknown as IntersectionObserverEntry,\n ],\n {} as IntersectionObserver\n );\n\n expect(rafSpy).toHaveBeenCalled();\n\n rafSpy.mockRestore();\n });\n});\n"],"names":["describe","it","expect","beforeEach","afterEach","vi","renderHook","waitFor","useThemedScrollpoints","observerCallback","mockObserve","mockUnobserve","mockDisconnect","fn","global","IntersectionObserver","callback","observe","unobserve","disconnect","requestAnimationFrame","cb","clearAllMocks","document","body","innerHTML","scrollpoints","id","className","result","current","toBe","not","toHaveBeenCalled","elem","createElement","appendChild","toHaveBeenCalledWith","any","Function","objectContaining","rootMargin","threshold","elem1","elem2","toHaveBeenCalledTimes","consoleWarn","spyOn","console","mockImplementation","stringContaining","mockRestore","target","isIntersecting","renderCount","elem3","unmount","rerender","initialProps","rafSpy"],"mappings":"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"}