@ably/ui 17.9.0-dev.7b4c6aac → 17.9.1-dev.f8cf1684

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 (38) hide show
  1. package/core/Code.js +1 -1
  2. package/core/Code.js.map +1 -1
  3. package/core/CodeSnippet/ApiKeySelector.js +1 -1
  4. package/core/CodeSnippet/ApiKeySelector.js.map +1 -1
  5. package/core/CodeSnippet/CopyButton.js +1 -1
  6. package/core/CodeSnippet/CopyButton.js.map +1 -1
  7. package/core/CodeSnippet/LanguageSelector.js +1 -1
  8. package/core/CodeSnippet/LanguageSelector.js.map +1 -1
  9. package/core/CodeSnippet/PlainCodeView.js +1 -1
  10. package/core/CodeSnippet/PlainCodeView.js.map +1 -1
  11. package/core/CodeSnippet/TooltipButton.js +1 -1
  12. package/core/CodeSnippet/TooltipButton.js.map +1 -1
  13. package/core/CodeSnippet.js +1 -1
  14. package/core/CodeSnippet.js.map +1 -1
  15. package/core/CookieMessage.js +1 -1
  16. package/core/CookieMessage.js.map +1 -1
  17. package/core/DropdownMenu.js +1 -1
  18. package/core/DropdownMenu.js.map +1 -1
  19. package/core/Expander.js +1 -1
  20. package/core/Expander.js.map +1 -1
  21. package/core/Flash.js +1 -1
  22. package/core/Flash.js.map +1 -1
  23. package/core/Header/HeaderLinks.js +1 -1
  24. package/core/Header/HeaderLinks.js.map +1 -1
  25. package/core/Header.js +1 -1
  26. package/core/Header.js.map +1 -1
  27. package/core/Meganav.js +1 -1
  28. package/core/Meganav.js.map +1 -1
  29. package/core/Pricing/PricingCards.js +1 -1
  30. package/core/Pricing/PricingCards.js.map +1 -1
  31. package/core/Slider.js +1 -1
  32. package/core/Slider.js.map +1 -1
  33. package/core/TabMenu.js +1 -1
  34. package/core/TabMenu.js.map +1 -1
  35. package/index.d.ts +12 -39
  36. package/package.json +2 -3
  37. package/core/utils/useCopyToClipboard.js +0 -2
  38. package/core/utils/useCopyToClipboard.js.map +0 -1
package/core/Slider.js CHANGED
@@ -1,2 +1,2 @@
1
- import React,{useCallback,useEffect,useState}from"react";import useEmblaCarousel from"embla-carousel-react";import Autoplay from"embla-carousel-autoplay";import Icon from"./Icon";const SlideIndicator=({numSlides,activeIndex,interval,intervalIndicator,isInline})=>{return React.createElement("ul",{className:`flex gap-1 left-1/2 ${isInline?"bottom-0":"absolute bottom-0 transform -translate-x-1/2"}`},Array.from({length:numSlides},(_,i)=>intervalIndicator?React.createElement("li",{key:i,className:"relative w-10 h-1 mx-px rounded-full bg-neutral-500"},i===activeIndex&&React.createElement("span",{className:"absolute inset-0 rounded-full bg-active-orange",style:{animation:`fillAnimation ${interval}ms linear`}})):React.createElement("li",{key:i},React.createElement("span",{className:`ui-slider-marker ${i===activeIndex?"text-active-orange":"text-cool-black"}`,"data-id":"slider-marker"},"⬤"))))};const Slider=({children,options})=>{const[activeIndex,setActiveIndex]=useState(0);const interval=options?.interval??1e4;const isInline=options?.controlPosition==="inline";const[emblaRef,emblaApi]=useEmblaCarousel({loop:true,duration:30},[Autoplay({delay:interval,stopOnInteraction:false})]);const scrollPrev=useCallback(()=>{if(emblaApi)emblaApi.scrollPrev()},[emblaApi]);const scrollNext=useCallback(()=>{if(emblaApi)emblaApi.scrollNext()},[emblaApi]);const onSelect=useCallback(emblaApi=>{setActiveIndex(emblaApi.selectedScrollSnap())},[]);useEffect(()=>{if(!emblaApi)return;onSelect(emblaApi);emblaApi.on("select",onSelect).on("reInit",onSelect);return()=>{emblaApi.off("select",onSelect).off("reInit",onSelect)}},[emblaApi,onSelect]);return React.createElement("div",{className:"relative"},React.createElement("div",{className:"overflow-hidden w-full py-10",ref:emblaRef},React.createElement("div",{className:"flex"},children.map((child,index)=>React.createElement("div",{key:index,className:"w-full flex-shrink-0 flex justify-center sm:px-[3.75rem]"},child)))),React.createElement("div",{className:`flex items-center pointer-events-none ${isInline?"ui-standard-container justify-center gap-6 -mt-4":"sm:flex sm:absolute inset-0 justify-between"}`},React.createElement("button",{className:`${isInline?"w-8 h-8":"hidden sm:flex w-12 h-12"} pointer-events-auto rounded border border-mid-grey hover:border-active-orange flex justify-center items-center ui-icon-cta ui-icon-cta-left`,onClick:scrollPrev},React.createElement("div",{className:"ui-icon-cta-holder flex w-12"},React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-left-outline",size:"1.5rem"})),React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-left-outline",size:"1.5rem"})))),React.createElement(SlideIndicator,{numSlides:children.length,activeIndex:activeIndex,interval:interval,intervalIndicator:options?.intervalIndicator,isInline:isInline}),React.createElement("button",{className:`${isInline?"w-8 h-8":"hidden sm:flex w-12 h-12"} pointer-events-auto rounded border border-mid-grey hover:border-active-orange justify-center items-center ui-icon-cta ui-icon-cta-right`,onClick:scrollNext},React.createElement("div",{className:"ui-icon-cta-holder flex w-12 -ml-3.5"},React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:"1.5rem"})),React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:"1.5rem"}))))))};export default Slider;
1
+ import React,{useCallback,useEffect,useState}from"react";import useEmblaCarousel from"embla-carousel-react";import Autoplay from"embla-carousel-autoplay";import Icon from"./Icon";import cn from"./utils/cn";const SlideIndicator=({numSlides,activeIndex,interval,intervalIndicator,isInline})=>{return React.createElement("ul",{className:cn("flex gap-1 left-1/2",isInline?"bottom-0":"absolute bottom-0 transform -translate-x-1/2")},Array.from({length:numSlides},(_,i)=>intervalIndicator?React.createElement("li",{key:i,className:"relative w-10 h-1 mx-px rounded-full bg-neutral-500"},i===activeIndex&&React.createElement("span",{className:"absolute inset-0 rounded-full bg-active-orange",style:{animation:`fillAnimation ${interval}ms linear`}})):React.createElement("li",{key:i},React.createElement("span",{className:cn("ui-slider-marker",i===activeIndex?"text-active-orange":"text-cool-black"),"data-id":"slider-marker"},"⬤"))))};const Slider=({children,options})=>{const[activeIndex,setActiveIndex]=useState(0);const interval=options?.interval??1e4;const isInline=options?.controlPosition==="inline";const[emblaRef,emblaApi]=useEmblaCarousel({loop:true,duration:30},[Autoplay({delay:interval,stopOnInteraction:false})]);const scrollPrev=useCallback(()=>{if(emblaApi)emblaApi.scrollPrev()},[emblaApi]);const scrollNext=useCallback(()=>{if(emblaApi)emblaApi.scrollNext()},[emblaApi]);const onSelect=useCallback(emblaApi=>{setActiveIndex(emblaApi.selectedScrollSnap())},[]);useEffect(()=>{if(!emblaApi)return;onSelect(emblaApi);emblaApi.on("select",onSelect).on("reInit",onSelect);return()=>{emblaApi.off("select",onSelect).off("reInit",onSelect)}},[emblaApi,onSelect]);return React.createElement("div",{className:"relative"},React.createElement("div",{className:"overflow-hidden w-full py-10",ref:emblaRef},React.createElement("div",{className:"flex"},children.map((child,index)=>React.createElement("div",{key:index,className:"w-full flex-shrink-0 flex justify-center sm:px-[3.75rem]"},child)))),React.createElement("div",{className:cn("flex items-center pointer-events-none",isInline?"ui-standard-container justify-center gap-6 -mt-4":"sm:flex sm:absolute inset-0 justify-between")},React.createElement("button",{className:cn(isInline?"w-8 h-8":"hidden sm:flex w-12 h-12","pointer-events-auto rounded border border-mid-grey hover:border-active-orange flex justify-center items-center ui-icon-cta ui-icon-cta-left"),onClick:scrollPrev},React.createElement("div",{className:"ui-icon-cta-holder flex w-12"},React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-left-outline",size:"1.5rem"})),React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-left-outline",size:"1.5rem"})))),React.createElement(SlideIndicator,{numSlides:children.length,activeIndex:activeIndex,interval:interval,intervalIndicator:options?.intervalIndicator,isInline:isInline}),React.createElement("button",{className:cn(isInline?"w-8 h-8":"hidden sm:flex w-12 h-12","pointer-events-auto rounded border border-mid-grey hover:border-active-orange justify-center items-center ui-icon-cta ui-icon-cta-right"),onClick:scrollNext},React.createElement("div",{className:cn("ui-icon-cta-holder flex w-12",isInline?"-ml-3.5":"")},React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:"1.5rem"})),React.createElement("div",{className:"w-full h-full flex-shrink-0 flex items-center justify-center"},React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:"1.5rem"}))))))};export default Slider;
2
2
  //# sourceMappingURL=Slider.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/Slider.tsx"],"sourcesContent":["import React, { ReactNode, useCallback, useEffect, useState } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport Autoplay from \"embla-carousel-autoplay\";\nimport type { EmblaCarouselType } from \"embla-carousel\";\nimport Icon from \"./Icon\";\n\ninterface SliderProps {\n children: ReactNode[];\n options?: {\n interval?: number;\n controlPosition?: \"inline\" | \"floating\";\n intervalIndicator?: boolean;\n };\n}\n\ninterface SliderIndicatorProps {\n numSlides: number;\n activeIndex: number;\n interval: number;\n intervalIndicator?: boolean;\n isInline?: boolean;\n}\n\nconst SlideIndicator = ({\n numSlides,\n activeIndex,\n interval,\n intervalIndicator,\n isInline,\n}: SliderIndicatorProps) => {\n return (\n <ul\n className={`flex gap-1 left-1/2 ${\n isInline ? \"bottom-0\" : \"absolute bottom-0 transform -translate-x-1/2\"\n }`}\n >\n {Array.from({ length: numSlides }, (_, i) =>\n intervalIndicator ? (\n <li\n key={i}\n className=\"relative w-10 h-1 mx-px rounded-full bg-neutral-500\"\n >\n {i === activeIndex && (\n <span\n className=\"absolute inset-0 rounded-full bg-active-orange\"\n style={{\n animation: `fillAnimation ${interval}ms linear`,\n }}\n ></span>\n )}\n </li>\n ) : (\n <li key={i}>\n <span\n className={`ui-slider-marker ${\n i === activeIndex ? \"text-active-orange\" : \"text-cool-black\"\n }`}\n data-id=\"slider-marker\"\n >\n &#x2b24;\n </span>\n </li>\n ),\n )}\n </ul>\n );\n};\n\nconst Slider = ({ children, options }: SliderProps) => {\n const [activeIndex, setActiveIndex] = useState(0);\n const interval = options?.interval ?? 10000;\n const isInline = options?.controlPosition === \"inline\";\n\n const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true, duration: 30 }, [\n Autoplay({ delay: interval, stopOnInteraction: false }),\n ]);\n\n const scrollPrev = useCallback(() => {\n if (emblaApi) emblaApi.scrollPrev();\n }, [emblaApi]);\n\n const scrollNext = useCallback(() => {\n if (emblaApi) emblaApi.scrollNext();\n }, [emblaApi]);\n\n const onSelect = useCallback((emblaApi: EmblaCarouselType) => {\n setActiveIndex(emblaApi.selectedScrollSnap());\n }, []);\n\n useEffect(() => {\n if (!emblaApi) return;\n\n onSelect(emblaApi);\n emblaApi.on(\"select\", onSelect).on(\"reInit\", onSelect);\n\n return () => {\n emblaApi.off(\"select\", onSelect).off(\"reInit\", onSelect);\n };\n }, [emblaApi, onSelect]);\n\n return (\n <div className=\"relative\">\n <div className=\"overflow-hidden w-full py-10\" ref={emblaRef}>\n <div className=\"flex\">\n {children.map((child, index) => (\n <div\n key={index}\n className=\"w-full flex-shrink-0 flex justify-center sm:px-[3.75rem]\"\n >\n {child}\n </div>\n ))}\n </div>\n </div>\n\n <div\n className={`flex items-center pointer-events-none ${\n isInline\n ? \"ui-standard-container justify-center gap-6 -mt-4\"\n : \"sm:flex sm:absolute inset-0 justify-between\"\n }`}\n >\n <button\n className={`${\n isInline ? \"w-8 h-8\" : \"hidden sm:flex w-12 h-12\"\n } pointer-events-auto rounded border border-mid-grey hover:border-active-orange flex justify-center items-center ui-icon-cta ui-icon-cta-left`}\n onClick={scrollPrev}\n >\n <div className=\"ui-icon-cta-holder flex w-12\">\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-left-outline\" size=\"1.5rem\" />\n </div>\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-left-outline\" size=\"1.5rem\" />\n </div>\n </div>\n </button>\n\n <SlideIndicator\n numSlides={children.length}\n activeIndex={activeIndex}\n interval={interval}\n intervalIndicator={options?.intervalIndicator}\n isInline={isInline}\n />\n\n <button\n className={`${\n isInline ? \"w-8 h-8\" : \"hidden sm:flex w-12 h-12\"\n } pointer-events-auto rounded border border-mid-grey hover:border-active-orange justify-center items-center ui-icon-cta ui-icon-cta-right`}\n onClick={scrollNext}\n >\n <div className=\"ui-icon-cta-holder flex w-12 -ml-3.5\">\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-right-outline\" size=\"1.5rem\" />\n </div>\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-right-outline\" size=\"1.5rem\" />\n </div>\n </div>\n </button>\n </div>\n </div>\n );\n};\n\nexport default Slider;\n"],"names":["React","useCallback","useEffect","useState","useEmblaCarousel","Autoplay","Icon","SlideIndicator","numSlides","activeIndex","interval","intervalIndicator","isInline","ul","className","Array","from","length","_","i","li","key","span","style","animation","data-id","Slider","children","options","setActiveIndex","controlPosition","emblaRef","emblaApi","loop","duration","delay","stopOnInteraction","scrollPrev","scrollNext","onSelect","selectedScrollSnap","on","off","div","ref","map","child","index","button","onClick","name","size"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/Slider.tsx"],"sourcesContent":["import React, { ReactNode, useCallback, useEffect, useState } from \"react\";\nimport useEmblaCarousel from \"embla-carousel-react\";\nimport Autoplay from \"embla-carousel-autoplay\";\nimport type { EmblaCarouselType } from \"embla-carousel\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\n\ninterface SliderProps {\n children: ReactNode[];\n options?: {\n interval?: number;\n controlPosition?: \"inline\" | \"floating\";\n intervalIndicator?: boolean;\n };\n}\n\ninterface SliderIndicatorProps {\n numSlides: number;\n activeIndex: number;\n interval: number;\n intervalIndicator?: boolean;\n isInline?: boolean;\n}\n\nconst SlideIndicator = ({\n numSlides,\n activeIndex,\n interval,\n intervalIndicator,\n isInline,\n}: SliderIndicatorProps) => {\n return (\n <ul\n className={cn(\n \"flex gap-1 left-1/2\",\n isInline ? \"bottom-0\" : \"absolute bottom-0 transform -translate-x-1/2\",\n )}\n >\n {Array.from({ length: numSlides }, (_, i) =>\n intervalIndicator ? (\n <li\n key={i}\n className=\"relative w-10 h-1 mx-px rounded-full bg-neutral-500\"\n >\n {i === activeIndex && (\n <span\n className=\"absolute inset-0 rounded-full bg-active-orange\"\n style={{\n animation: `fillAnimation ${interval}ms linear`,\n }}\n ></span>\n )}\n </li>\n ) : (\n <li key={i}>\n <span\n className={cn(\n \"ui-slider-marker\",\n i === activeIndex ? \"text-active-orange\" : \"text-cool-black\",\n )}\n data-id=\"slider-marker\"\n >\n &#x2b24;\n </span>\n </li>\n ),\n )}\n </ul>\n );\n};\n\nconst Slider = ({ children, options }: SliderProps) => {\n const [activeIndex, setActiveIndex] = useState(0);\n const interval = options?.interval ?? 10000;\n const isInline = options?.controlPosition === \"inline\";\n\n const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true, duration: 30 }, [\n Autoplay({ delay: interval, stopOnInteraction: false }),\n ]);\n\n const scrollPrev = useCallback(() => {\n if (emblaApi) emblaApi.scrollPrev();\n }, [emblaApi]);\n\n const scrollNext = useCallback(() => {\n if (emblaApi) emblaApi.scrollNext();\n }, [emblaApi]);\n\n const onSelect = useCallback((emblaApi: EmblaCarouselType) => {\n setActiveIndex(emblaApi.selectedScrollSnap());\n }, []);\n\n useEffect(() => {\n if (!emblaApi) return;\n\n onSelect(emblaApi);\n emblaApi.on(\"select\", onSelect).on(\"reInit\", onSelect);\n\n return () => {\n emblaApi.off(\"select\", onSelect).off(\"reInit\", onSelect);\n };\n }, [emblaApi, onSelect]);\n\n return (\n <div className=\"relative\">\n <div className=\"overflow-hidden w-full py-10\" ref={emblaRef}>\n <div className=\"flex\">\n {children.map((child, index) => (\n <div\n key={index}\n className=\"w-full flex-shrink-0 flex justify-center sm:px-[3.75rem]\"\n >\n {child}\n </div>\n ))}\n </div>\n </div>\n\n <div\n className={cn(\n \"flex items-center pointer-events-none\",\n isInline\n ? \"ui-standard-container justify-center gap-6 -mt-4\"\n : \"sm:flex sm:absolute inset-0 justify-between\",\n )}\n >\n <button\n className={cn(\n isInline ? \"w-8 h-8\" : \"hidden sm:flex w-12 h-12\",\n \"pointer-events-auto rounded border border-mid-grey hover:border-active-orange flex justify-center items-center ui-icon-cta ui-icon-cta-left\",\n )}\n onClick={scrollPrev}\n >\n <div className=\"ui-icon-cta-holder flex w-12\">\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-left-outline\" size=\"1.5rem\" />\n </div>\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-left-outline\" size=\"1.5rem\" />\n </div>\n </div>\n </button>\n\n <SlideIndicator\n numSlides={children.length}\n activeIndex={activeIndex}\n interval={interval}\n intervalIndicator={options?.intervalIndicator}\n isInline={isInline}\n />\n\n <button\n className={cn(\n isInline ? \"w-8 h-8\" : \"hidden sm:flex w-12 h-12\",\n \"pointer-events-auto rounded border border-mid-grey hover:border-active-orange justify-center items-center ui-icon-cta ui-icon-cta-right\",\n )}\n onClick={scrollNext}\n >\n <div\n className={cn(\n \"ui-icon-cta-holder flex w-12\",\n isInline ? \"-ml-3.5\" : \"\",\n )}\n >\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-right-outline\" size=\"1.5rem\" />\n </div>\n <div className=\"w-full h-full flex-shrink-0 flex items-center justify-center\">\n <Icon name=\"icon-gui-arrow-long-right-outline\" size=\"1.5rem\" />\n </div>\n </div>\n </button>\n </div>\n </div>\n );\n};\n\nexport default Slider;\n"],"names":["React","useCallback","useEffect","useState","useEmblaCarousel","Autoplay","Icon","cn","SlideIndicator","numSlides","activeIndex","interval","intervalIndicator","isInline","ul","className","Array","from","length","_","i","li","key","span","style","animation","data-id","Slider","children","options","setActiveIndex","controlPosition","emblaRef","emblaApi","loop","duration","delay","stopOnInteraction","scrollPrev","scrollNext","onSelect","selectedScrollSnap","on","off","div","ref","map","child","index","button","onClick","name","size"],"mappings":"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"}
package/core/TabMenu.js CHANGED
@@ -1,2 +1,2 @@
1
- import React,{useEffect}from"react";import*as Tabs from"@radix-ui/react-tabs";import{throttle}from"es-toolkit/compat";import cn from"./utils/cn";const DEFAULT_TAILWIND_ANIMATION_DURATION=150;const TabMenu=({tabs=[],contents=[],tabOnClick,tabClassName,rootClassName,contentClassName,options})=>{const{defaultTabIndex=0,underline=true,animated:animatedOption=true,flexibleTabWidth=false,flexibleTabHeight=false}=options??{};const listRef=React.useRef(null);const[animated,setAnimated]=React.useState(false);const[highlight,setHighlight]=React.useState({offset:0,width:0});useEffect(()=>{if(animatedOption&&highlight.width>0){setTimeout(()=>{setAnimated(true)},DEFAULT_TAILWIND_ANIMATION_DURATION)}},[animatedOption,highlight.width]);useEffect(()=>{const handleResize=throttle(()=>{const activeTabElement=listRef.current?.querySelector(`[data-state="active"]`);if(activeTabElement){updateHighlightDimensions(activeTabElement)}},100);handleResize();window.addEventListener("resize",handleResize);return()=>{window.removeEventListener("resize",handleResize)}},[]);const updateHighlightDimensions=element=>{const{left:parentLeft}=listRef.current?.getBoundingClientRect()??{};const{left,width}=element.getBoundingClientRect()??{};setHighlight({offset:(left??0)-(parentLeft??0),width:width??0})};const handleTabClick=(event,index)=>{tabOnClick?.(index);updateHighlightDimensions(event.currentTarget)};const tabTriggerContent=tab=>{if(!tab){return null}if(React.isValidElement(tab)||typeof tab==="string"){return tab}if(typeof tab==="object"&&"label"in tab){return tab.label}return null};return React.createElement(Tabs.Root,{defaultValue:`tab-${defaultTabIndex}`,className:cn({"h-full":flexibleTabHeight},rootClassName)},React.createElement(Tabs.List,{ref:listRef,className:cn("relative",{"flex border-b border-neutral-300 dark:border-neutral-1000":underline},{"h-full":flexibleTabHeight})},tabs.map((tab,index)=>tab&&React.createElement(Tabs.Trigger,{key:`tab-${index}`,className:cn("lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-unavailable dark:disabled:text-gui-unavailable-dark disabled:cursor-not-allowed",{"flex-1":flexibleTabWidth},{"h-full":flexibleTabHeight},tabClassName),value:`tab-${index}`,onClick:event=>handleTabClick(event,index),disabled:typeof tab==="object"&&"disabled"in tab?tab.disabled:false},tabTriggerContent(tab))),React.createElement("div",{className:cn("absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6",{"transition-[transform,width]":animated}),style:{transform:`translateX(${highlight.offset}px)`,width:`${highlight.width}px`}})),contents.map((content,index)=>React.createElement(Tabs.Content,{key:`tab-${index}`,value:`tab-${index}`,className:contentClassName},content)))};export default TabMenu;
1
+ import React,{useEffect}from"react";import*as Tabs from"@radix-ui/react-tabs";import{throttle}from"es-toolkit/compat";import cn from"./utils/cn";const DEFAULT_TAILWIND_ANIMATION_DURATION=150;const TabMenu=({tabs=[],contents=[],tabOnClick,tabClassName,rootClassName,contentClassName,options})=>{const{defaultTabIndex=0,underline=true,animated:animatedOption=true,flexibleTabWidth=false,flexibleTabHeight=false}=options??{};const listRef=React.useRef(null);const[animated,setAnimated]=React.useState(false);const[highlight,setHighlight]=React.useState({offset:0,width:0});useEffect(()=>{if(animatedOption&&highlight.width>0){setTimeout(()=>{setAnimated(true)},DEFAULT_TAILWIND_ANIMATION_DURATION)}},[animatedOption,highlight.width]);const updateHighlightDimensions=element=>{const{left:parentLeft}=listRef.current?.getBoundingClientRect()??{};const{left,width}=element.getBoundingClientRect()??{};setHighlight({offset:(left??0)-(parentLeft??0),width:width??0})};useEffect(()=>{const handleResize=throttle(()=>{const activeTabElement=listRef.current?.querySelector(`[data-state="active"]`);if(activeTabElement){updateHighlightDimensions(activeTabElement)}},100);handleResize();window.addEventListener("resize",handleResize);return()=>{window.removeEventListener("resize",handleResize)}},[]);const handleTabClick=(event,index)=>{tabOnClick?.(index);updateHighlightDimensions(event.currentTarget)};const tabTriggerContent=tab=>{if(!tab){return null}if(React.isValidElement(tab)||typeof tab==="string"){return tab}if(typeof tab==="object"&&"label"in tab){return tab.label}return null};return React.createElement(Tabs.Root,{defaultValue:`tab-${defaultTabIndex}`,className:cn({"h-full":flexibleTabHeight},rootClassName)},React.createElement(Tabs.List,{ref:listRef,className:cn("relative",{"flex border-b border-neutral-300 dark:border-neutral-1000":underline},{"h-full":flexibleTabHeight})},tabs.map((tab,index)=>tab&&React.createElement(Tabs.Trigger,{key:`tab-${index}`,className:cn("lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-unavailable dark:disabled:text-gui-unavailable-dark disabled:cursor-not-allowed",{"flex-1":flexibleTabWidth},{"h-full":flexibleTabHeight},tabClassName),value:`tab-${index}`,onClick:event=>handleTabClick(event,index),disabled:typeof tab==="object"&&"disabled"in tab?tab.disabled:false},tabTriggerContent(tab))),React.createElement("div",{className:cn("absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6",{"transition-[transform,width]":animated}),style:{transform:`translateX(${highlight.offset}px)`,width:`${highlight.width}px`}})),contents.map((content,index)=>React.createElement(Tabs.Content,{key:`tab-${index}`,value:`tab-${index}`,className:contentClassName},content)))};export default TabMenu;
2
2
  //# sourceMappingURL=TabMenu.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/TabMenu.tsx"],"sourcesContent":["import React, { ReactNode, useEffect } from \"react\";\nimport * as Tabs from \"@radix-ui/react-tabs\";\nimport { throttle } from \"es-toolkit/compat\";\nimport cn from \"./utils/cn\";\n\ntype TabTriggerContent =\n | string\n | { label: string; disabled?: boolean }\n | ReactNode;\n\n/**\n * Props for the TabMenu component.\n */\n\nexport type TabMenuProps = {\n /**\n * An array of tabs, which can be either a string or an object with a label and an optional disabled state.\n */\n tabs: TabTriggerContent[];\n\n /**\n * An optional array of React nodes representing the content for each tab.\n */\n contents?: ReactNode[];\n\n /**\n * An optional callback function that is called when a tab is clicked, receiving the index of the clicked tab.\n */\n tabOnClick?: (index: number) => void;\n\n /**\n * An optional class name to apply to each tab.\n */\n tabClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Root element.\n */\n rootClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Content element.\n */\n contentClassName?: string;\n\n /**\n * Optional configuration options for the TabMenu.\n */\n options?: {\n /**\n * The index of the tab that should be selected by default.\n */\n defaultTabIndex?: number;\n\n /**\n * Whether to show an underline below the selected tab.\n */\n underline?: boolean;\n\n /**\n * Whether to animate the transition between tabs.\n */\n animated?: boolean;\n\n /**\n * Whether the tab width should be flexible.\n */\n flexibleTabWidth?: boolean;\n\n /**\n * Whether the tab height should be flexible.\n */\n flexibleTabHeight?: boolean;\n };\n};\n\nconst DEFAULT_TAILWIND_ANIMATION_DURATION = 150;\n\nconst TabMenu: React.FC<TabMenuProps> = ({\n tabs = [],\n contents = [],\n tabOnClick,\n tabClassName,\n rootClassName,\n contentClassName,\n options,\n}) => {\n const {\n defaultTabIndex = 0,\n underline = true,\n animated: animatedOption = true,\n flexibleTabWidth = false,\n flexibleTabHeight = false,\n } = options ?? {};\n\n const listRef = React.useRef<HTMLDivElement>(null);\n const [animated, setAnimated] = React.useState(false);\n const [highlight, setHighlight] = React.useState({ offset: 0, width: 0 });\n\n useEffect(() => {\n if (animatedOption && highlight.width > 0) {\n setTimeout(() => {\n setAnimated(true);\n }, DEFAULT_TAILWIND_ANIMATION_DURATION);\n }\n }, [animatedOption, highlight.width]);\n\n useEffect(() => {\n const handleResize = throttle(() => {\n const activeTabElement =\n listRef.current?.querySelector<HTMLButtonElement>(\n `[data-state=\"active\"]`,\n );\n\n if (activeTabElement) {\n updateHighlightDimensions(activeTabElement);\n }\n }, 100);\n\n handleResize();\n\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n const updateHighlightDimensions = (element: HTMLButtonElement) => {\n const { left: parentLeft } = listRef.current?.getBoundingClientRect() ?? {};\n const { left, width } = element.getBoundingClientRect() ?? {};\n\n setHighlight({\n offset: (left ?? 0) - (parentLeft ?? 0),\n width: width ?? 0,\n });\n };\n\n const handleTabClick = (\n event: React.MouseEvent<HTMLButtonElement>,\n index: number,\n ) => {\n tabOnClick?.(index);\n updateHighlightDimensions(event.currentTarget as HTMLButtonElement);\n };\n\n const tabTriggerContent = (tab: TabTriggerContent) => {\n if (!tab) {\n return null;\n }\n\n if (React.isValidElement(tab) || typeof tab === \"string\") {\n return tab;\n }\n\n if (typeof tab === \"object\" && \"label\" in tab) {\n return tab.label;\n }\n\n return null;\n };\n\n return (\n <Tabs.Root\n defaultValue={`tab-${defaultTabIndex}`}\n className={cn({ \"h-full\": flexibleTabHeight }, rootClassName)}\n >\n <Tabs.List\n ref={listRef}\n className={cn(\n \"relative\",\n {\n \"flex border-b border-neutral-300 dark:border-neutral-1000\":\n underline,\n },\n { \"h-full\": flexibleTabHeight },\n )}\n >\n {tabs.map(\n (tab, index) =>\n tab && (\n <Tabs.Trigger\n key={`tab-${index}`}\n className={cn(\n \"lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-unavailable dark:disabled:text-gui-unavailable-dark disabled:cursor-not-allowed\",\n { \"flex-1\": flexibleTabWidth },\n { \"h-full\": flexibleTabHeight },\n tabClassName,\n )}\n value={`tab-${index}`}\n onClick={(event) => handleTabClick(event, index)}\n disabled={\n typeof tab === \"object\" && \"disabled\" in tab\n ? tab.disabled\n : false\n }\n >\n {tabTriggerContent(tab)}\n </Tabs.Trigger>\n ),\n )}\n <div\n className={cn(\n \"absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6\",\n { \"transition-[transform,width]\": animated },\n )}\n style={{\n transform: `translateX(${highlight.offset}px)`,\n width: `${highlight.width}px`,\n }}\n ></div>\n </Tabs.List>\n {contents.map((content, index) => (\n <Tabs.Content\n key={`tab-${index}`}\n value={`tab-${index}`}\n className={contentClassName}\n >\n {content}\n </Tabs.Content>\n ))}\n </Tabs.Root>\n );\n};\n\nexport default TabMenu;\n"],"names":["React","useEffect","Tabs","throttle","cn","DEFAULT_TAILWIND_ANIMATION_DURATION","TabMenu","tabs","contents","tabOnClick","tabClassName","rootClassName","contentClassName","options","defaultTabIndex","underline","animated","animatedOption","flexibleTabWidth","flexibleTabHeight","listRef","useRef","setAnimated","useState","highlight","setHighlight","offset","width","setTimeout","handleResize","activeTabElement","current","querySelector","updateHighlightDimensions","window","addEventListener","removeEventListener","element","left","parentLeft","getBoundingClientRect","handleTabClick","event","index","currentTarget","tabTriggerContent","tab","isValidElement","label","Root","defaultValue","className","List","ref","map","Trigger","key","value","onClick","disabled","div","style","transform","content","Content"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/TabMenu.tsx"],"sourcesContent":["import React, { ReactNode, useEffect } from \"react\";\nimport * as Tabs from \"@radix-ui/react-tabs\";\nimport { throttle } from \"es-toolkit/compat\";\nimport cn from \"./utils/cn\";\n\ntype TabTriggerContent =\n | string\n | { label: string; disabled?: boolean }\n | ReactNode;\n\n/**\n * Props for the TabMenu component.\n */\n\nexport type TabMenuProps = {\n /**\n * An array of tabs, which can be either a string or an object with a label and an optional disabled state.\n */\n tabs: TabTriggerContent[];\n\n /**\n * An optional array of React nodes representing the content for each tab.\n */\n contents?: ReactNode[];\n\n /**\n * An optional callback function that is called when a tab is clicked, receiving the index of the clicked tab.\n */\n tabOnClick?: (index: number) => void;\n\n /**\n * An optional class name to apply to each tab.\n */\n tabClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Root element.\n */\n rootClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Content element.\n */\n contentClassName?: string;\n\n /**\n * Optional configuration options for the TabMenu.\n */\n options?: {\n /**\n * The index of the tab that should be selected by default.\n */\n defaultTabIndex?: number;\n\n /**\n * Whether to show an underline below the selected tab.\n */\n underline?: boolean;\n\n /**\n * Whether to animate the transition between tabs.\n */\n animated?: boolean;\n\n /**\n * Whether the tab width should be flexible.\n */\n flexibleTabWidth?: boolean;\n\n /**\n * Whether the tab height should be flexible.\n */\n flexibleTabHeight?: boolean;\n };\n};\n\nconst DEFAULT_TAILWIND_ANIMATION_DURATION = 150;\n\nconst TabMenu: React.FC<TabMenuProps> = ({\n tabs = [],\n contents = [],\n tabOnClick,\n tabClassName,\n rootClassName,\n contentClassName,\n options,\n}) => {\n const {\n defaultTabIndex = 0,\n underline = true,\n animated: animatedOption = true,\n flexibleTabWidth = false,\n flexibleTabHeight = false,\n } = options ?? {};\n\n const listRef = React.useRef<HTMLDivElement>(null);\n const [animated, setAnimated] = React.useState(false);\n const [highlight, setHighlight] = React.useState({ offset: 0, width: 0 });\n\n useEffect(() => {\n if (animatedOption && highlight.width > 0) {\n setTimeout(() => {\n setAnimated(true);\n }, DEFAULT_TAILWIND_ANIMATION_DURATION);\n }\n }, [animatedOption, highlight.width]);\n\n const updateHighlightDimensions = (element: HTMLButtonElement) => {\n const { left: parentLeft } = listRef.current?.getBoundingClientRect() ?? {};\n const { left, width } = element.getBoundingClientRect() ?? {};\n\n setHighlight({\n offset: (left ?? 0) - (parentLeft ?? 0),\n width: width ?? 0,\n });\n };\n\n useEffect(() => {\n const handleResize = throttle(() => {\n const activeTabElement =\n listRef.current?.querySelector<HTMLButtonElement>(\n `[data-state=\"active\"]`,\n );\n\n if (activeTabElement) {\n updateHighlightDimensions(activeTabElement);\n }\n }, 100);\n\n handleResize();\n\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n const handleTabClick = (\n event: React.MouseEvent<HTMLButtonElement>,\n index: number,\n ) => {\n tabOnClick?.(index);\n updateHighlightDimensions(event.currentTarget as HTMLButtonElement);\n };\n\n const tabTriggerContent = (tab: TabTriggerContent) => {\n if (!tab) {\n return null;\n }\n\n if (React.isValidElement(tab) || typeof tab === \"string\") {\n return tab;\n }\n\n if (typeof tab === \"object\" && \"label\" in tab) {\n return tab.label;\n }\n\n return null;\n };\n\n return (\n <Tabs.Root\n defaultValue={`tab-${defaultTabIndex}`}\n className={cn({ \"h-full\": flexibleTabHeight }, rootClassName)}\n >\n <Tabs.List\n ref={listRef}\n className={cn(\n \"relative\",\n {\n \"flex border-b border-neutral-300 dark:border-neutral-1000\":\n underline,\n },\n { \"h-full\": flexibleTabHeight },\n )}\n >\n {tabs.map(\n (tab, index) =>\n tab && (\n <Tabs.Trigger\n key={`tab-${index}`}\n className={cn(\n \"lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-unavailable dark:disabled:text-gui-unavailable-dark disabled:cursor-not-allowed\",\n { \"flex-1\": flexibleTabWidth },\n { \"h-full\": flexibleTabHeight },\n tabClassName,\n )}\n value={`tab-${index}`}\n onClick={(event) => handleTabClick(event, index)}\n disabled={\n typeof tab === \"object\" && \"disabled\" in tab\n ? tab.disabled\n : false\n }\n >\n {tabTriggerContent(tab)}\n </Tabs.Trigger>\n ),\n )}\n <div\n className={cn(\n \"absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6\",\n { \"transition-[transform,width]\": animated },\n )}\n style={{\n transform: `translateX(${highlight.offset}px)`,\n width: `${highlight.width}px`,\n }}\n ></div>\n </Tabs.List>\n {contents.map((content, index) => (\n <Tabs.Content\n key={`tab-${index}`}\n value={`tab-${index}`}\n className={contentClassName}\n >\n {content}\n </Tabs.Content>\n ))}\n </Tabs.Root>\n );\n};\n\nexport default TabMenu;\n"],"names":["React","useEffect","Tabs","throttle","cn","DEFAULT_TAILWIND_ANIMATION_DURATION","TabMenu","tabs","contents","tabOnClick","tabClassName","rootClassName","contentClassName","options","defaultTabIndex","underline","animated","animatedOption","flexibleTabWidth","flexibleTabHeight","listRef","useRef","setAnimated","useState","highlight","setHighlight","offset","width","setTimeout","updateHighlightDimensions","element","left","parentLeft","current","getBoundingClientRect","handleResize","activeTabElement","querySelector","window","addEventListener","removeEventListener","handleTabClick","event","index","currentTarget","tabTriggerContent","tab","isValidElement","label","Root","defaultValue","className","List","ref","map","Trigger","key","value","onClick","disabled","div","style","transform","content","Content"],"mappings":"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"}
package/index.d.ts CHANGED
@@ -321,37 +321,28 @@ type ApiKeySelectorProps = {
321
321
  selectedApiKey: string;
322
322
  onApiKeyChange: (apiKey: string) => void;
323
323
  };
324
- const ApiKeySelector: {
325
- ({ apiKeys, selectedApiKey, onApiKeyChange, }: ApiKeySelectorProps): import("react/jsx-runtime").JSX.Element;
326
- displayName: string;
327
- };
324
+ const ApiKeySelector: ({ apiKeys, selectedApiKey, onApiKeyChange, }: ApiKeySelectorProps) => import("react/jsx-runtime").JSX.Element;
328
325
  export default ApiKeySelector;
329
326
  //# sourceMappingURL=ApiKeySelector.d.ts.map
330
327
  }
331
328
 
332
329
  declare module '@ably/ui/core/CodeSnippet/CopyButton' {
333
- import React from "react";
334
330
  type CopyButtonProps = {
335
331
  onCopy: () => void;
336
- isCopied: boolean;
337
332
  tooltip?: string;
338
333
  };
339
- /**
340
- * A reusable copy button component with tooltip and copied indicator
341
- */
342
- const CopyButton: React.MemoExoticComponent<({ onCopy, isCopied, tooltip }: CopyButtonProps) => import("react/jsx-runtime").JSX.Element>;
334
+ const CopyButton: ({ onCopy, tooltip }: CopyButtonProps) => import("react/jsx-runtime").JSX.Element;
343
335
  export default CopyButton;
344
336
  //# sourceMappingURL=CopyButton.d.ts.map
345
337
  }
346
338
 
347
339
  declare module '@ably/ui/core/CodeSnippet/LanguageSelector' {
348
- import React from "react";
349
340
  type LanguageSelectorProps = {
350
341
  languages: string[];
351
342
  activeLanguage: string;
352
343
  onLanguageChange: (language: string) => void;
353
344
  };
354
- const LanguageSelector: React.MemoExoticComponent<({ languages, activeLanguage, onLanguageChange }: LanguageSelectorProps) => import("react/jsx-runtime").JSX.Element>;
345
+ const LanguageSelector: ({ languages, activeLanguage, onLanguageChange, }: LanguageSelectorProps) => import("react/jsx-runtime").JSX.Element;
355
346
  export default LanguageSelector;
356
347
  //# sourceMappingURL=LanguageSelector.d.ts.map
357
348
  }
@@ -365,29 +356,29 @@ type PlainCodeViewProps = {
365
356
  icon: IconName | null;
366
357
  className?: string;
367
358
  };
368
- const _default: React.NamedExoticComponent<PlainCodeViewProps>;
369
- export default _default;
359
+ const PlainCodeView: React.FC<PlainCodeViewProps>;
360
+ export default PlainCodeView;
370
361
  //# sourceMappingURL=PlainCodeView.d.ts.map
371
362
  }
372
363
 
373
364
  declare module '@ably/ui/core/CodeSnippet/TooltipButton' {
374
365
  import React from "react";
366
+ import { SegmentedControlSize } from ".@ably/ui/core/SegmentedControl";
375
367
  import { IconName } from ".@ably/ui/core/Icon/types";
368
+ import type { TooltipProps } from "@radix-ui/react-tooltip";
376
369
  type TooltipButtonProps = {
377
- tooltip: string;
370
+ tooltip: string | React.ReactNode;
378
371
  active?: boolean;
379
372
  onClick: () => void;
380
373
  icon?: IconName;
381
374
  className?: string;
382
375
  children?: React.ReactNode;
383
376
  variant?: "segmented" | "icon-button";
384
- size?: "sm" | "md";
377
+ size?: SegmentedControlSize;
385
378
  alwaysShowLabel?: boolean;
379
+ tooltipRootProps?: TooltipProps;
386
380
  };
387
- /**
388
- * A unified tooltip button component that can render either a segmented control or an icon button
389
- */
390
- const TooltipButton: React.MemoExoticComponent<({ tooltip, active, onClick, icon, className, children, variant, size, alwaysShowLabel, }: TooltipButtonProps) => import("react/jsx-runtime").JSX.Element>;
381
+ const TooltipButton: ({ tooltip, active, onClick, icon, className, children, variant, size, alwaysShowLabel, tooltipRootProps, }: TooltipButtonProps) => import("react/jsx-runtime").JSX.Element;
391
382
  export default TooltipButton;
392
383
  //# sourceMappingURL=TooltipButton.d.ts.map
393
384
  }
@@ -601,7 +592,7 @@ type LinkProps = {
601
592
  const DropdownMenu: {
602
593
  ({ children }: DropdownMenuProps): import("react/jsx-runtime").JSX.Element;
603
594
  Trigger: ({ children, triggerClassNames, description, }: TriggerProps) => import("react/jsx-runtime").JSX.Element;
604
- Content: ({ children, anchorPosition, contentClassNames, }: ContentProps) => import("react/jsx-runtime").JSX.Element;
595
+ Content: ({ children, anchorPosition, contentClassNames, }: ContentProps) => import("react/jsx-runtime").JSX.Element | null;
605
596
  Link: ({ url, title, subtitle, iconName, children }: LinkProps) => import("react/jsx-runtime").JSX.Element;
606
597
  };
607
598
  export default DropdownMenu;
@@ -6244,24 +6235,6 @@ export function registerDefaultLanguages(register: any): void;
6244
6235
  //# sourceMappingURL=syntax-highlighter.d.ts.map
6245
6236
  }
6246
6237
 
6247
- declare module '@ably/ui/core/utils/useCopyToClipboard' {
6248
- interface CopyToClipboardState {
6249
- isCopied: boolean;
6250
- error: Error | null;
6251
- }
6252
- interface CopyToClipboardReturn extends CopyToClipboardState {
6253
- copy: (text: string) => Promise<boolean>;
6254
- }
6255
- /**
6256
- * A hook that provides copy-to-clipboard functionality with state management
6257
- * @param copiedTimeout - How long to show the copied state in ms before resetting
6258
- * @returns Object with isCopied state, any error, and copy function
6259
- */
6260
- function useCopyToClipboard(copiedTimeout?: number): CopyToClipboardReturn;
6261
- export default useCopyToClipboard;
6262
- //# sourceMappingURL=useCopyToClipboard.d.ts.map
6263
- }
6264
-
6265
6238
  declare module '@ably/ui/reset/scripts' {
6266
6239
  export {};
6267
6240
  //# sourceMappingURL=scripts.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ably/ui",
3
- "version": "17.9.0-dev.7b4c6aac",
3
+ "version": "17.9.1-dev.f8cf1684",
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",
@@ -44,7 +44,7 @@
44
44
  "eslint-config-prettier": "^10.1.8",
45
45
  "eslint-plugin-jsx-a11y": "^6.10.2",
46
46
  "eslint-plugin-react": "^7.35.0",
47
- "eslint-plugin-react-hooks": "^6.1.0",
47
+ "eslint-plugin-react-hooks": "^7.0.0",
48
48
  "eslint-plugin-react-perf": "^3.3.3",
49
49
  "eslint-plugin-storybook": "^9.1.4",
50
50
  "heroicons": "^2.2.0",
@@ -68,7 +68,6 @@
68
68
  "@heroicons/react": "^2.2.0",
69
69
  "@radix-ui/react-accordion": "^1.2.1",
70
70
  "@radix-ui/react-collapsible": "^1.1.12",
71
- "@radix-ui/react-dropdown-menu": "^2.1.16",
72
71
  "@radix-ui/react-navigation-menu": "^1.2.4",
73
72
  "@radix-ui/react-select": "^2.2.2",
74
73
  "@radix-ui/react-switch": "^1.1.1",
@@ -1,2 +0,0 @@
1
- import{useState,useCallback}from"react";function useCopyToClipboard(copiedTimeout=2e3){const[state,setState]=useState({isCopied:false,error:null});const copy=useCallback(async text=>{try{await navigator.clipboard.writeText(text);setState({isCopied:true,error:null});setTimeout(()=>{setState(prev=>({...prev,isCopied:false}))},copiedTimeout);return true}catch(error){setState({isCopied:false,error:error instanceof Error?error:new Error(String(error))});return false}},[copiedTimeout]);return{...state,copy}}export default useCopyToClipboard;
2
- //# sourceMappingURL=useCopyToClipboard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/core/utils/useCopyToClipboard.ts"],"sourcesContent":["import { useState, useCallback } from \"react\";\n\ninterface CopyToClipboardState {\n isCopied: boolean;\n error: Error | null;\n}\n\ninterface CopyToClipboardReturn extends CopyToClipboardState {\n copy: (text: string) => Promise<boolean>;\n}\n\n/**\n * A hook that provides copy-to-clipboard functionality with state management\n * @param copiedTimeout - How long to show the copied state in ms before resetting\n * @returns Object with isCopied state, any error, and copy function\n */\nfunction useCopyToClipboard(copiedTimeout = 2000): CopyToClipboardReturn {\n const [state, setState] = useState<CopyToClipboardState>({\n isCopied: false,\n error: null,\n });\n\n const copy = useCallback(\n async (text: string): Promise<boolean> => {\n try {\n await navigator.clipboard.writeText(text);\n setState({ isCopied: true, error: null });\n\n // Reset the copied state after timeout\n setTimeout(() => {\n setState((prev) => ({ ...prev, isCopied: false }));\n }, copiedTimeout);\n\n return true;\n } catch (error) {\n setState({\n isCopied: false,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n return false;\n }\n },\n [copiedTimeout],\n );\n\n return { ...state, copy };\n}\n\nexport default useCopyToClipboard;\n"],"names":["useState","useCallback","useCopyToClipboard","copiedTimeout","state","setState","isCopied","error","copy","text","navigator","clipboard","writeText","setTimeout","prev","Error","String"],"mappings":"AAAA,OAASA,QAAQ,CAAEC,WAAW,KAAQ,OAAQ,CAgB9C,SAASC,mBAAmBC,cAAgB,GAAI,EAC9C,KAAM,CAACC,MAAOC,SAAS,CAAGL,SAA+B,CACvDM,SAAU,MACVC,MAAO,IACT,GAEA,MAAMC,KAAOP,YACX,MAAOQ,OACL,GAAI,CACF,MAAMC,UAAUC,SAAS,CAACC,SAAS,CAACH,MACpCJ,SAAS,CAAEC,SAAU,KAAMC,MAAO,IAAK,GAGvCM,WAAW,KACTR,SAAS,AAACS,MAAU,CAAA,CAAE,GAAGA,IAAI,CAAER,SAAU,KAAM,CAAA,EACjD,EAAGH,eAEH,OAAO,IACT,CAAE,MAAOI,MAAO,CACdF,SAAS,CACPC,SAAU,MACVC,MAAOA,iBAAiBQ,MAAQR,MAAQ,IAAIQ,MAAMC,OAAOT,OAC3D,GACA,OAAO,KACT,CACF,EACA,CAACJ,cAAc,EAGjB,MAAO,CAAE,GAAGC,KAAK,CAAEI,IAAK,CAC1B,CAEA,eAAeN,kBAAmB"}