@ably/ui 17.4.0-dev.8a486360 → 17.4.0-dev.ab50c043
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core/CodeSnippet.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useState,Children,isValidElement,useRef,useCallback,useMemo,useEffect}from"react";import Code from"./Code";import cn from"./utils/cn";import Icon from"./Icon";import{getLanguageInfo,stripSdkType}from"./CodeSnippet/languages";import LanguageSelector from"./CodeSnippet/LanguageSelector";import ApiKeySelector from"./CodeSnippet/ApiKeySelector";import useCopyToClipboard from"./utils/useCopyToClipboard";import PlainCodeView from"./CodeSnippet/PlainCodeView";import CopyButton from"./CodeSnippet/CopyButton";import TooltipButton from"./CodeSnippet/TooltipButton";const substituteApiKey=(content,apiKey)=>{return content.replace(/\{\{API_KEY\}\}/g,apiKey)};const CodeSnippet=({fixed=false,headerRow=false,title="Code",children,className,lang,onChange,apiKeys,sdk,showCodeLines=true,languageOrdering})=>{const codeRef=useRef(null);const{isCopied,copy}=useCopyToClipboard();const extractLanguageFromCode=useCallback(codeElement=>{if(!codeElement||!codeElement.props.className)return null;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return null;return langClass.substring(9)},[]);console.log("ably-ui keys",apiKeys);const{childrenArray,languages,sdkTypes,originalLangMap,isSinglePlainCommand}=useMemo(()=>{const childrenArray=Children.toArray(children);const languages=[];const sdkTypes=new Set;const originalLangMap=new Map;const isSinglePlainCommand=childrenArray.length===1&&["language-shell","language-text"].some(lang=>isValidElement(childrenArray[0])&&isValidElement(childrenArray[0].props.children)&&childrenArray[0].props.children.props.className?.includes(lang));childrenArray.forEach(child=>{if(!isValidElement(child))return;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;const langName=extractLanguageFromCode(codeElement);if(!langName)return;if(langName.startsWith("realtime_")){const baseLanguage=langName.substring(9);sdkTypes.add("realtime");originalLangMap.set(langName,baseLanguage)}else if(langName.startsWith("rest_")){const baseLanguage=langName.substring(5);sdkTypes.add("rest");originalLangMap.set(langName,baseLanguage)}else{originalLangMap.set(langName,langName)}if(!languages.includes(langName)){languages.push(langName)}});return{childrenArray,languages,sdkTypes,originalLangMap,isSinglePlainCommand}},[children,extractLanguageFromCode]);const[activeSDKType,setActiveSDKType]=useState(()=>{if(sdkTypes.size===0)return null;if(sdk&&sdkTypes.has(sdk))return sdk;if(sdkTypes.has("realtime"))return"realtime";if(sdkTypes.has("rest"))return"rest";return null});const showSDKSelector=sdkTypes.size>0;const filteredLanguages=useMemo(()=>{const filtered=!activeSDKType||!showSDKSelector?[...languages]:languages.filter(lang=>lang.startsWith(`${activeSDKType}_`));if(languageOrdering&&languageOrdering.length>0){filtered.sort((a,b)=>{const aBase=originalLangMap.get(a)||a;const bBase=originalLangMap.get(b)||b;const aIndex=languageOrdering.indexOf(aBase);const bIndex=languageOrdering.indexOf(bBase);if(aIndex!==-1&&bIndex!==-1)return aIndex-bIndex;if(aIndex!==-1)return-1;if(bIndex!==-1)return 1;return 0})}return filtered},[activeSDKType,showSDKSelector,languages,languageOrdering,originalLangMap]);const activeLanguage=useMemo(()=>{if(sdk&&sdkTypes.has(sdk)){return languages.find(l=>l===`${sdk}_${lang}`)??lang}if(lang)return lang;if(filteredLanguages.length>0)return filteredLanguages[0];return lang},[lang,sdk,sdkTypes,filteredLanguages]);const[selectedApiKey,setSelectedApiKey]=useState(()=>apiKeys?.[0]?.keys?.[0]?.key??"");useEffect(()=>{if(!selectedApiKey&&apiKeys&&apiKeys.length>0){setSelectedApiKey(apiKeys[0].keys?.[0]?.key)}},[apiKeys]);const[isHovering,setIsHovering]=useState(false);const hasOnlyJsonSnippet=useMemo(()=>languages.length===1&&languages[0]==="json",[languages]);const processedChildren=useMemo(()=>{if(!activeLanguage)return[];const targetLanguage=hasOnlyJsonSnippet?"json":activeLanguage;return childrenArray.filter(child=>{if(!isValidElement(child))return false;const codeElement=isValidElement(child.props.children)?child.props.children:null;const langName=extractLanguageFromCode(codeElement);return langName===targetLanguage}).map(child=>{if(!isValidElement(child))return child;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;if(!codeElement)return child;const codeContent=codeElement.props.children;const langName=extractLanguageFromCode(codeElement);if(!langName)return child;const cleanLang=hasOnlyJsonSnippet?"json":langName;const langInfo=getLanguageInfo(cleanLang);if(typeof codeContent==="string"||typeof codeContent==="number"||typeof codeContent==="boolean"){let processedContent=String(codeContent);if(apiKeys&&apiKeys.length>0&&selectedApiKey){processedContent=substituteApiKey(processedContent,selectedApiKey)}return React.createElement(Code,{key:langName,language:langInfo.syntaxHighlighterKey||cleanLang,snippet:processedContent,additionalCSS:"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-6 py-4",showLines:showCodeLines})}return child})},[activeLanguage,childrenArray,extractLanguageFromCode,hasOnlyJsonSnippet,showCodeLines,apiKeys,selectedApiKey]);const hasSnippetForActiveLanguage=useMemo(()=>{if(!activeLanguage)return false;if(hasOnlyJsonSnippet)return true;return childrenArray.some(child=>{if(!isValidElement(child))return false;const codeElement=isValidElement(child.props.children)?child.props.children:null;const langName=extractLanguageFromCode(codeElement);return langName===activeLanguage})},[activeLanguage,childrenArray,extractLanguageFromCode,hasOnlyJsonSnippet]);const getCodeText=useCallback(()=>{if(!activeLanguage||!hasSnippetForActiveLanguage||!codeRef.current)return null;const allPreElements=codeRef.current.querySelectorAll("pre");for(const preElement of Array.from(allPreElements)){const codeElement=preElement.querySelector("code");if(!codeElement||!codeElement.className)continue;const classNames=codeElement.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)continue;const langName=langClass.substring(9);if(hasOnlyJsonSnippet&&langName==="json"||!hasOnlyJsonSnippet&&langName===activeLanguage){return codeElement.textContent||""}}return null},[activeLanguage,hasSnippetForActiveLanguage,hasOnlyJsonSnippet]);const handleSDKTypeChange=useCallback(type=>{const nextLang=stripSdkType(languages.find(l=>l.startsWith(`${type}_`))??lang);setActiveSDKType(type);if(onChange&&nextLang){onChange(nextLang,type)}},[languages]);const handleLanguageChange=useCallback(language=>{if(onChange){onChange(stripSdkType(language),activeSDKType)}},[onChange,activeSDKType]);const handleApiKeyChange=useCallback(apiKey=>{setSelectedApiKey(apiKey)},[]);const NoSnippetMessage=useMemo(()=>{if(!activeLanguage)return()=>null;const activeLanguageInfo=getLanguageInfo(activeLanguage);return()=>React.createElement("div",{className:"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center"},React.createElement(Icon,{name:"icon-gui-exclamation-triangle-outline",color:"text-yellow-600 dark:text-yellow-400",size:"24px"}),React.createElement("p",{className:"ui-text-p3 text-neutral-700 dark:text-neutral-600"},"You're currently viewing the ",activeLanguageInfo.label," docs. There either isn't a ",activeLanguageInfo.label," code sample for this example, or this feature isn't supported in"," ",activeLanguageInfo.label,". Switch language to view this example in a different language, or check which SDKs support this feature."))},[activeLanguage]);const showLanguageSelector=!fixed&&filteredLanguages.length>0;const showFullSelector=filteredLanguages.length>1;const renderContent=useMemo(()=>{if(!activeLanguage)return null;if(hasSnippetForActiveLanguage){return processedChildren}if(activeLanguage){return React.createElement(NoSnippetMessage,null)}return null},[activeLanguage,hasSnippetForActiveLanguage,processedChildren,NoSnippetMessage]);if(isSinglePlainCommand){const plainChild=childrenArray[0];if(isValidElement(plainChild)&&isValidElement(plainChild.props.children)){const codeElement=plainChild.props.children;const codeContent=codeElement.props.children;const language=extractLanguageFromCode(codeElement);if(!language||!codeContent)return null;let processedContent=String(codeContent);if(apiKeys&&apiKeys.length>0&&selectedApiKey){processedContent=substituteApiKey(processedContent,selectedApiKey)}return React.createElement(PlainCodeView,{content:processedContent,className:className,language:language,icon:language==="shell"?"icon-gui-command-line-outline":null})}}return React.createElement("div",{className:cn("rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]",className)},headerRow&&React.createElement("div",{className:"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg"},React.createElement("div",{className:"flex space-x-1.5"},React.createElement("div",{className:"w-3 h-3 rounded-full bg-orange-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-green-500"})),React.createElement("div",{className:"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000"},title),React.createElement("div",{className:"w-12"})),showSDKSelector&&React.createElement("div",{className:cn("p-2 border-b border-neutral-200 dark:border-neutral-1100 h-14",headerRow?"":"rounded-t-lg")},React.createElement("div",{className:"flex gap-3 justify-start"},sdkTypes.has("realtime")&&React.createElement(TooltipButton,{tooltip:"Realtime SDK",active:activeSDKType==="realtime",onClick:()=>handleSDKTypeChange("realtime"),variant:"segmented",size:"sm",alwaysShowLabel:true},"Realtime"),sdkTypes.has("rest")&&React.createElement(TooltipButton,{tooltip:"REST SDK",active:activeSDKType==="rest",onClick:()=>handleSDKTypeChange("rest"),variant:"segmented",size:"sm",alwaysShowLabel:true},"REST"))),showLanguageSelector&&(showFullSelector?React.createElement(LanguageSelector,{languages:filteredLanguages,activeLanguage:activeLanguage,onLanguageChange:handleLanguageChange}):React.createElement("div",{className:cn("border-b border-neutral-200 dark:border-neutral-1100 h-[2.125rem] inline-flex items-center px-3",{"rounded-t-lg":!headerRow},{"cursor-pointer":filteredLanguages.length>0}),...filteredLanguages.length>0&&{onClick:()=>handleLanguageChange(filteredLanguages[0])}},filteredLanguages.length>0&&React.createElement(React.Fragment,null,React.createElement(Icon,{name:getLanguageInfo(filteredLanguages[0]).icon,size:"16px",additionalCSS:"mr-2"}),React.createElement("span",{className:"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none"},getLanguageInfo(filteredLanguages[0]).label)))),React.createElement("div",{ref:codeRef,className:"relative",onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>setIsHovering(false),onFocus:()=>setIsHovering(true),onBlur:()=>setIsHovering(false),tabIndex:0},renderContent,isHovering&&activeLanguage&&hasSnippetForActiveLanguage&&React.createElement(CopyButton,{onCopy:()=>{const text=getCodeText();if(text)copy(text)},isCopied:isCopied})),apiKeys&&apiKeys.length>0&&React.createElement(ApiKeySelector,{apiKeys:apiKeys,selectedApiKey:selectedApiKey,onApiKeyChange:handleApiKeyChange}))};export default CodeSnippet;
|
|
1
|
+
import React,{useState,Children,isValidElement,useRef,useCallback,useMemo,useEffect}from"react";import Code from"./Code";import cn from"./utils/cn";import Icon from"./Icon";import{getLanguageInfo,stripSdkType}from"./CodeSnippet/languages";import LanguageSelector from"./CodeSnippet/LanguageSelector";import ApiKeySelector from"./CodeSnippet/ApiKeySelector";import useCopyToClipboard from"./utils/useCopyToClipboard";import PlainCodeView from"./CodeSnippet/PlainCodeView";import CopyButton from"./CodeSnippet/CopyButton";import TooltipButton from"./CodeSnippet/TooltipButton";const substituteApiKey=(content,apiKey)=>{return content.replace(/\{\{API_KEY\}\}/g,`${apiKey.split(":")[0]}:*****`)};const CodeSnippet=({fixed=false,headerRow=false,title="Code",children,className,lang,onChange,apiKeys,sdk,showCodeLines=true,languageOrdering})=>{const codeRef=useRef(null);const{isCopied,copy}=useCopyToClipboard();const extractLanguageFromCode=useCallback(codeElement=>{if(!codeElement||!codeElement.props.className)return null;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return null;return langClass.substring(9)},[]);const{childrenArray,languages,sdkTypes,originalLangMap,isSinglePlainCommand}=useMemo(()=>{const childrenArray=Children.toArray(children);const languages=[];const sdkTypes=new Set;const originalLangMap=new Map;const isSinglePlainCommand=childrenArray.length===1&&["language-shell","language-text"].some(lang=>isValidElement(childrenArray[0])&&isValidElement(childrenArray[0].props.children)&&childrenArray[0].props.children.props.className?.includes(lang));childrenArray.forEach(child=>{if(!isValidElement(child))return;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;const langName=extractLanguageFromCode(codeElement);if(!langName)return;if(langName.startsWith("realtime_")){const baseLanguage=langName.substring(9);sdkTypes.add("realtime");originalLangMap.set(langName,baseLanguage)}else if(langName.startsWith("rest_")){const baseLanguage=langName.substring(5);sdkTypes.add("rest");originalLangMap.set(langName,baseLanguage)}else{originalLangMap.set(langName,langName)}if(!languages.includes(langName)){languages.push(langName)}});return{childrenArray,languages,sdkTypes,originalLangMap,isSinglePlainCommand}},[children,extractLanguageFromCode]);const[activeSDKType,setActiveSDKType]=useState(()=>{if(sdkTypes.size===0)return null;if(sdk&&sdkTypes.has(sdk))return sdk;if(sdkTypes.has("realtime"))return"realtime";if(sdkTypes.has("rest"))return"rest";return null});const showSDKSelector=sdkTypes.size>0;const filteredLanguages=useMemo(()=>{const filtered=!activeSDKType||!showSDKSelector?[...languages]:languages.filter(lang=>lang.startsWith(`${activeSDKType}_`));if(languageOrdering&&languageOrdering.length>0){filtered.sort((a,b)=>{const aBase=originalLangMap.get(a)||a;const bBase=originalLangMap.get(b)||b;const aIndex=languageOrdering.indexOf(aBase);const bIndex=languageOrdering.indexOf(bBase);if(aIndex!==-1&&bIndex!==-1)return aIndex-bIndex;if(aIndex!==-1)return-1;if(bIndex!==-1)return 1;return 0})}return filtered},[activeSDKType,showSDKSelector,languages,languageOrdering,originalLangMap]);const activeLanguage=useMemo(()=>{if(sdk&&sdkTypes.has(sdk)){return languages.find(l=>l===`${sdk}_${lang}`)??lang}if(lang)return lang;if(filteredLanguages.length>0)return filteredLanguages[0];return lang},[lang,sdk,sdkTypes,filteredLanguages]);const[selectedApiKey,setSelectedApiKey]=useState(()=>apiKeys?.[0]?.keys?.[0]?.key??"");useEffect(()=>{if(!selectedApiKey&&apiKeys&&apiKeys.length>0){setSelectedApiKey(apiKeys[0].keys?.[0]?.key)}},[apiKeys]);const requiresApiKeySubstitution=useMemo(()=>{const containsPlaceholder=childrenArray.some(child=>{if(!isValidElement(child))return false;const codeElement=isValidElement(child.props.children)?child.props.children:null;const codeContent=codeElement.props.children;return codeContent.includes("{{API_KEY}}")});return containsPlaceholder&&!!apiKeys&&apiKeys.length>0&&!!selectedApiKey},[childrenArray,apiKeys,selectedApiKey]);const[isHovering,setIsHovering]=useState(false);const hasOnlyJsonSnippet=useMemo(()=>languages.length===1&&languages[0]==="json",[languages]);const processedChildren=useMemo(()=>{if(!activeLanguage)return[];const targetLanguage=hasOnlyJsonSnippet?"json":activeLanguage;return childrenArray.filter(child=>{if(!isValidElement(child))return false;const codeElement=isValidElement(child.props.children)?child.props.children:null;const langName=extractLanguageFromCode(codeElement);return langName===targetLanguage}).map(child=>{if(!isValidElement(child))return child;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;if(!codeElement)return child;const codeContent=codeElement.props.children;const langName=extractLanguageFromCode(codeElement);if(!langName)return child;const cleanLang=hasOnlyJsonSnippet?"json":langName;const langInfo=getLanguageInfo(cleanLang);if(typeof codeContent==="string"||typeof codeContent==="number"||typeof codeContent==="boolean"){let processedContent=String(codeContent);if(requiresApiKeySubstitution){processedContent=substituteApiKey(processedContent,selectedApiKey)}return React.createElement(Code,{key:langName,language:langInfo.syntaxHighlighterKey||cleanLang,snippet:processedContent,additionalCSS:"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-6 py-4",showLines:showCodeLines})}return child})},[activeLanguage,childrenArray,extractLanguageFromCode,hasOnlyJsonSnippet,showCodeLines,apiKeys,selectedApiKey]);const hasSnippetForActiveLanguage=useMemo(()=>{if(!activeLanguage)return false;if(hasOnlyJsonSnippet)return true;return childrenArray.some(child=>{if(!isValidElement(child))return false;const codeElement=isValidElement(child.props.children)?child.props.children:null;const langName=extractLanguageFromCode(codeElement);return langName===activeLanguage})},[activeLanguage,childrenArray,extractLanguageFromCode,hasOnlyJsonSnippet]);const getCodeText=useCallback(()=>{if(!activeLanguage||!hasSnippetForActiveLanguage||!codeRef.current)return null;const allPreElements=codeRef.current.querySelectorAll("pre");for(const preElement of Array.from(allPreElements)){const codeElement=preElement.querySelector("code");if(!codeElement||!codeElement.className)continue;const classNames=codeElement.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)continue;const langName=langClass.substring(9);if(hasOnlyJsonSnippet&&langName==="json"||!hasOnlyJsonSnippet&&langName===activeLanguage){return codeElement.textContent||""}}return null},[activeLanguage,hasSnippetForActiveLanguage,hasOnlyJsonSnippet]);const handleSDKTypeChange=useCallback(type=>{const nextLang=stripSdkType(languages.find(l=>l.startsWith(`${type}_`))??lang);setActiveSDKType(type);if(onChange&&nextLang){onChange(nextLang,type)}},[languages]);const handleLanguageChange=useCallback(language=>{if(onChange){onChange(stripSdkType(language),activeSDKType)}},[onChange,activeSDKType]);const handleApiKeyChange=useCallback(apiKey=>{setSelectedApiKey(apiKey)},[]);const NoSnippetMessage=useMemo(()=>{if(!activeLanguage)return()=>null;const activeLanguageInfo=getLanguageInfo(activeLanguage);return()=>React.createElement("div",{className:"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center"},React.createElement(Icon,{name:"icon-gui-exclamation-triangle-outline",color:"text-yellow-600 dark:text-yellow-400",size:"24px"}),React.createElement("p",{className:"ui-text-p3 text-neutral-700 dark:text-neutral-600"},"You're currently viewing the ",activeLanguageInfo.label," docs. There either isn't a ",activeLanguageInfo.label," code sample for this example, or this feature isn't supported in"," ",activeLanguageInfo.label,". Switch language to view this example in a different language, or check which SDKs support this feature."))},[activeLanguage]);const showLanguageSelector=!fixed&&filteredLanguages.length>0;const showFullSelector=filteredLanguages.length>1;const renderContent=useMemo(()=>{if(!activeLanguage)return null;if(hasSnippetForActiveLanguage){return processedChildren}if(activeLanguage){return React.createElement(NoSnippetMessage,null)}return null},[activeLanguage,hasSnippetForActiveLanguage,processedChildren,NoSnippetMessage]);if(isSinglePlainCommand){const plainChild=childrenArray[0];if(isValidElement(plainChild)&&isValidElement(plainChild.props.children)){const codeElement=plainChild.props.children;const codeContent=codeElement.props.children;const language=extractLanguageFromCode(codeElement);if(!language||!codeContent)return null;let processedContent=String(codeContent);if(requiresApiKeySubstitution){processedContent=substituteApiKey(processedContent,selectedApiKey)}return React.createElement(PlainCodeView,{content:processedContent,className:className,language:language,icon:language==="shell"?"icon-gui-command-line-outline":null})}}return React.createElement("div",{className:cn("rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]",className)},headerRow&&React.createElement("div",{className:"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg"},React.createElement("div",{className:"flex space-x-1.5"},React.createElement("div",{className:"w-3 h-3 rounded-full bg-orange-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-yellow-500"}),React.createElement("div",{className:"w-3 h-3 rounded-full bg-green-500"})),React.createElement("div",{className:"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000"},title),React.createElement("div",{className:"w-12"})),showSDKSelector&&React.createElement("div",{className:cn("p-2 border-b border-neutral-200 dark:border-neutral-1100 h-14",headerRow?"":"rounded-t-lg")},React.createElement("div",{className:"flex gap-3 justify-start"},sdkTypes.has("realtime")&&React.createElement(TooltipButton,{tooltip:"Realtime SDK",active:activeSDKType==="realtime",onClick:()=>handleSDKTypeChange("realtime"),variant:"segmented",size:"sm",alwaysShowLabel:true},"Realtime"),sdkTypes.has("rest")&&React.createElement(TooltipButton,{tooltip:"REST SDK",active:activeSDKType==="rest",onClick:()=>handleSDKTypeChange("rest"),variant:"segmented",size:"sm",alwaysShowLabel:true},"REST"))),showLanguageSelector&&(showFullSelector?React.createElement(LanguageSelector,{languages:filteredLanguages,activeLanguage:activeLanguage,onLanguageChange:handleLanguageChange}):React.createElement("div",{className:cn("border-b border-neutral-200 dark:border-neutral-1100 h-[2.125rem] inline-flex items-center px-3",{"rounded-t-lg":!headerRow},{"cursor-pointer":filteredLanguages.length>0}),...filteredLanguages.length>0&&{onClick:()=>handleLanguageChange(filteredLanguages[0])}},filteredLanguages.length>0&&React.createElement(React.Fragment,null,React.createElement(Icon,{name:getLanguageInfo(filteredLanguages[0]).icon,size:"16px",additionalCSS:"mr-2"}),React.createElement("span",{className:"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none"},getLanguageInfo(filteredLanguages[0]).label)))),React.createElement("div",{ref:codeRef,className:"relative",onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>setIsHovering(false),onFocus:()=>setIsHovering(true),onBlur:()=>setIsHovering(false),tabIndex:0},renderContent,isHovering&&activeLanguage&&hasSnippetForActiveLanguage&&React.createElement(CopyButton,{onCopy:()=>{const text=getCodeText();if(text)copy(text)},isCopied:isCopied})),requiresApiKeySubstitution&&React.createElement(ApiKeySelector,{apiKeys:apiKeys,selectedApiKey:selectedApiKey,onApiKeyChange:handleApiKeyChange}))};export default CodeSnippet;
|
|
2
2
|
//# sourceMappingURL=CodeSnippet.js.map
|
package/core/CodeSnippet.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/CodeSnippet.tsx"],"sourcesContent":["import React, {\n useState,\n Children,\n isValidElement,\n useRef,\n useCallback,\n useMemo,\n useEffect,\n} from \"react\";\nimport Code from \"./Code\";\nimport cn from \"./utils/cn\";\nimport Icon from \"./Icon\";\nimport { getLanguageInfo, stripSdkType } from \"./CodeSnippet/languages\";\nimport LanguageSelector from \"./CodeSnippet/LanguageSelector\";\nimport ApiKeySelector from \"./CodeSnippet/ApiKeySelector\";\nimport useCopyToClipboard from \"./utils/useCopyToClipboard\";\nimport PlainCodeView from \"./CodeSnippet/PlainCodeView\";\nimport CopyButton from \"./CodeSnippet/CopyButton\";\nimport TooltipButton from \"./CodeSnippet/TooltipButton\";\nimport { type CodeSnippetProps, type SDKType } from \"./CodeSnippet/types\";\n\n// Substitution function for API key placeholders\nconst substituteApiKey = (content: string, apiKey: string): string => {\n return content.replace(/\\{\\{API_KEY\\}\\}/g, apiKey);\n};\n\n/**\n * CodeSnippet component that displays code with language switching capability\n */\nconst CodeSnippet: React.FC<CodeSnippetProps> = ({\n fixed = false,\n headerRow = false,\n title = \"Code\",\n children,\n className,\n lang,\n onChange,\n apiKeys,\n sdk,\n showCodeLines = true,\n languageOrdering,\n}) => {\n const codeRef = useRef<HTMLDivElement>(null);\n const { isCopied, copy } = useCopyToClipboard();\n\n const extractLanguageFromCode = useCallback(\n (codeElement: React.ReactElement | null): string | null => {\n if (!codeElement || !codeElement.props.className) return null;\n\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return null;\n\n return langClass.substring(9); // Remove \"language-\" prefix\n },\n [],\n );\n\n console.log(\"ably-ui keys\", apiKeys);\n\n const {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSinglePlainCommand,\n } = useMemo(() => {\n const childrenArray = Children.toArray(children);\n const languages: string[] = [];\n const sdkTypes = new Set<SDKType>();\n const originalLangMap = new Map<string, string>();\n\n const isSinglePlainCommand =\n childrenArray.length === 1 &&\n [\"language-shell\", \"language-text\"].some(\n (lang) =>\n isValidElement(childrenArray[0]) &&\n isValidElement(childrenArray[0].props.children) &&\n childrenArray[0].props.children.props.className?.includes(lang),\n );\n\n childrenArray.forEach((child) => {\n if (!isValidElement(child)) return;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n\n const langName = extractLanguageFromCode(codeElement);\n if (!langName) return;\n\n if (langName.startsWith(\"realtime_\")) {\n const baseLanguage = langName.substring(9);\n sdkTypes.add(\"realtime\");\n originalLangMap.set(langName, baseLanguage);\n } else if (langName.startsWith(\"rest_\")) {\n const baseLanguage = langName.substring(5);\n sdkTypes.add(\"rest\");\n originalLangMap.set(langName, baseLanguage);\n } else {\n originalLangMap.set(langName, langName);\n }\n\n if (!languages.includes(langName)) {\n languages.push(langName);\n }\n });\n\n return {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSinglePlainCommand,\n };\n }, [children, extractLanguageFromCode]);\n\n const [activeSDKType, setActiveSDKType] = useState<SDKType>(() => {\n if (sdkTypes.size === 0) return null;\n if (sdk && sdkTypes.has(sdk)) return sdk;\n if (sdkTypes.has(\"realtime\")) return \"realtime\";\n if (sdkTypes.has(\"rest\")) return \"rest\";\n return null;\n });\n\n const showSDKSelector = sdkTypes.size > 0;\n\n const filteredLanguages = useMemo(() => {\n const filtered =\n !activeSDKType || !showSDKSelector\n ? [...languages]\n : languages.filter((lang) => lang.startsWith(`${activeSDKType}_`));\n\n // Apply custom ordering if provided\n if (languageOrdering && languageOrdering.length > 0) {\n filtered.sort((a, b) => {\n const aBase = originalLangMap.get(a) || a;\n const bBase = originalLangMap.get(b) || b;\n\n const aIndex = languageOrdering.indexOf(aBase);\n const bIndex = languageOrdering.indexOf(bBase);\n\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return 0;\n });\n }\n\n return filtered;\n }, [\n activeSDKType,\n showSDKSelector,\n languages,\n languageOrdering,\n originalLangMap,\n ]);\n\n const activeLanguage = useMemo(() => {\n if (sdk && sdkTypes.has(sdk)) {\n return languages.find((l) => l === `${sdk}_${lang}`) ?? lang;\n }\n\n if (lang) return lang;\n\n if (filteredLanguages.length > 0) return filteredLanguages[0];\n\n return lang;\n }, [lang, sdk, sdkTypes, filteredLanguages]);\n\n const [selectedApiKey, setSelectedApiKey] = useState<string>(\n () => apiKeys?.[0]?.keys?.[0]?.key ?? \"\",\n );\n\n useEffect(() => {\n if (!selectedApiKey && apiKeys && apiKeys.length > 0) {\n setSelectedApiKey(apiKeys[0].keys?.[0]?.key);\n }\n }, [apiKeys]);\n\n const [isHovering, setIsHovering] = useState(false);\n\n const hasOnlyJsonSnippet = useMemo(\n () => languages.length === 1 && languages[0] === \"json\",\n [languages],\n );\n\n const processedChildren = useMemo(() => {\n if (!activeLanguage) return [];\n\n const targetLanguage = hasOnlyJsonSnippet ? \"json\" : activeLanguage;\n\n return childrenArray\n .filter((child) => {\n if (!isValidElement(child)) return false;\n const codeElement = isValidElement(child.props.children)\n ? child.props.children\n : null;\n const langName = extractLanguageFromCode(codeElement);\n return langName === targetLanguage;\n })\n .map((child) => {\n if (!isValidElement(child)) return child;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n if (!codeElement) return child;\n\n const codeContent = codeElement.props.children;\n const langName = extractLanguageFromCode(codeElement);\n if (!langName) return child;\n\n const cleanLang = hasOnlyJsonSnippet ? \"json\" : langName;\n const langInfo = getLanguageInfo(cleanLang);\n\n if (\n typeof codeContent === \"string\" ||\n typeof codeContent === \"number\" ||\n typeof codeContent === \"boolean\"\n ) {\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(codeContent);\n if (apiKeys && apiKeys.length > 0 && selectedApiKey) {\n processedContent = substituteApiKey(\n processedContent,\n selectedApiKey,\n );\n }\n\n return (\n <Code\n key={langName}\n language={langInfo.syntaxHighlighterKey || cleanLang}\n snippet={processedContent}\n additionalCSS=\"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-6 py-4\"\n showLines={showCodeLines}\n />\n );\n }\n\n return child;\n });\n }, [\n activeLanguage,\n childrenArray,\n extractLanguageFromCode,\n hasOnlyJsonSnippet,\n showCodeLines,\n apiKeys,\n selectedApiKey,\n ]);\n\n const hasSnippetForActiveLanguage = useMemo(() => {\n if (!activeLanguage) return false;\n if (hasOnlyJsonSnippet) return true;\n\n return childrenArray.some((child) => {\n if (!isValidElement(child)) return false;\n const codeElement = isValidElement(child.props.children)\n ? child.props.children\n : null;\n const langName = extractLanguageFromCode(codeElement);\n return langName === activeLanguage;\n });\n }, [\n activeLanguage,\n childrenArray,\n extractLanguageFromCode,\n hasOnlyJsonSnippet,\n ]);\n\n const getCodeText = useCallback((): string | null => {\n if (!activeLanguage || !hasSnippetForActiveLanguage || !codeRef.current)\n return null;\n\n const allPreElements = codeRef.current.querySelectorAll(\"pre\");\n for (const preElement of Array.from(allPreElements)) {\n const codeElement = preElement.querySelector(\"code\");\n if (!codeElement || !codeElement.className) continue;\n\n const classNames = codeElement.className.split(\" \");\n const langClass = classNames.find((cls) => cls.startsWith(\"language-\"));\n if (!langClass) continue;\n\n const langName = langClass.substring(9);\n if (\n (hasOnlyJsonSnippet && langName === \"json\") ||\n (!hasOnlyJsonSnippet && langName === activeLanguage)\n ) {\n return codeElement.textContent || \"\";\n }\n }\n\n return null;\n }, [activeLanguage, hasSnippetForActiveLanguage, hasOnlyJsonSnippet]);\n\n const handleSDKTypeChange = useCallback(\n (type: SDKType) => {\n // pick first language matching the new SDK prefix\n const nextLang = stripSdkType(\n languages.find((l) => l.startsWith(`${type}_`)) ?? lang,\n );\n setActiveSDKType(type);\n\n // Call onChange with clean language name\n if (onChange && nextLang) {\n onChange(nextLang, type);\n }\n },\n [languages],\n );\n\n const handleLanguageChange = useCallback(\n (language: string) => {\n if (onChange) {\n onChange(stripSdkType(language), activeSDKType);\n }\n },\n [onChange, activeSDKType],\n );\n\n const handleApiKeyChange = useCallback((apiKey: string) => {\n setSelectedApiKey(apiKey);\n }, []);\n\n const NoSnippetMessage = useMemo(() => {\n if (!activeLanguage) return () => null;\n\n const activeLanguageInfo = getLanguageInfo(activeLanguage);\n\n return () => (\n <div className=\"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center\">\n <Icon\n name=\"icon-gui-exclamation-triangle-outline\"\n color=\"text-yellow-600 dark:text-yellow-400\"\n size=\"24px\"\n />\n <p className=\"ui-text-p3 text-neutral-700 dark:text-neutral-600\">\n You're currently viewing the {activeLanguageInfo.label} docs.\n There either isn't a {activeLanguageInfo.label} code sample for\n this example, or this feature isn't supported in{\" \"}\n {activeLanguageInfo.label}. Switch language to view this example in a\n different language, or check which SDKs support this feature.\n </p>\n </div>\n );\n }, [activeLanguage]);\n\n const showLanguageSelector = !fixed && filteredLanguages.length > 0;\n const showFullSelector = filteredLanguages.length > 1;\n\n const renderContent = useMemo(() => {\n if (!activeLanguage) return null;\n\n if (hasSnippetForActiveLanguage) {\n return processedChildren;\n }\n\n if (activeLanguage) {\n return <NoSnippetMessage />;\n }\n\n return null;\n }, [\n activeLanguage,\n hasSnippetForActiveLanguage,\n processedChildren,\n NoSnippetMessage,\n ]);\n\n // Render special case for plain commands (shell or text)\n if (isSinglePlainCommand) {\n const plainChild = childrenArray[0];\n if (\n isValidElement(plainChild) &&\n isValidElement(plainChild.props.children)\n ) {\n const codeElement = plainChild.props.children;\n const codeContent = codeElement.props.children;\n const language = extractLanguageFromCode(codeElement);\n\n if (!language || !codeContent) return null;\n\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(codeContent);\n if (apiKeys && apiKeys.length > 0 && selectedApiKey) {\n processedContent = substituteApiKey(processedContent, selectedApiKey);\n }\n\n return (\n <PlainCodeView\n content={processedContent}\n className={className}\n language={language}\n icon={language === \"shell\" ? \"icon-gui-command-line-outline\" : null}\n />\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]\",\n className,\n )}\n >\n {headerRow && (\n <div className=\"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg\">\n <div className=\"flex space-x-1.5\">\n <div className=\"w-3 h-3 rounded-full bg-orange-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-yellow-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-green-500\"></div>\n </div>\n\n <div className=\"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000\">\n {title}\n </div>\n\n {/* Empty div for balance */}\n <div className=\"w-12\"></div>\n </div>\n )}\n {showSDKSelector && (\n <div\n className={cn(\n \"p-2 border-b border-neutral-200 dark:border-neutral-1100 h-14\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n <div className=\"flex gap-3 justify-start\">\n {sdkTypes.has(\"realtime\") && (\n <TooltipButton\n tooltip=\"Realtime SDK\"\n active={activeSDKType === \"realtime\"}\n onClick={() => handleSDKTypeChange(\"realtime\")}\n variant=\"segmented\"\n size=\"sm\"\n alwaysShowLabel={true}\n >\n Realtime\n </TooltipButton>\n )}\n\n {sdkTypes.has(\"rest\") && (\n <TooltipButton\n tooltip=\"REST SDK\"\n active={activeSDKType === \"rest\"}\n onClick={() => handleSDKTypeChange(\"rest\")}\n variant=\"segmented\"\n size=\"sm\"\n alwaysShowLabel={true}\n >\n REST\n </TooltipButton>\n )}\n </div>\n </div>\n )}\n\n {showLanguageSelector &&\n (showFullSelector ? (\n <LanguageSelector\n languages={filteredLanguages}\n activeLanguage={activeLanguage}\n onLanguageChange={handleLanguageChange}\n />\n ) : (\n <div\n className={cn(\n \"border-b border-neutral-200 dark:border-neutral-1100 h-[2.125rem] inline-flex items-center px-3\",\n { \"rounded-t-lg\": !headerRow },\n { \"cursor-pointer\": filteredLanguages.length > 0 },\n )}\n {...(filteredLanguages.length > 0 && {\n onClick: () => handleLanguageChange(filteredLanguages[0]),\n })}\n >\n {filteredLanguages.length > 0 && (\n <>\n <Icon\n name={getLanguageInfo(filteredLanguages[0]).icon}\n size=\"16px\"\n additionalCSS=\"mr-2\"\n />\n <span className=\"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none\">\n {getLanguageInfo(filteredLanguages[0]).label}\n </span>\n </>\n )}\n </div>\n ))}\n <div\n ref={codeRef}\n className=\"relative\"\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n onFocus={() => setIsHovering(true)}\n onBlur={() => setIsHovering(false)}\n tabIndex={0}\n >\n {renderContent}\n {isHovering && activeLanguage && hasSnippetForActiveLanguage && (\n <CopyButton\n onCopy={() => {\n const text = getCodeText();\n if (text) copy(text);\n }}\n isCopied={isCopied}\n />\n )}\n </div>\n {apiKeys && apiKeys.length > 0 && (\n <ApiKeySelector\n apiKeys={apiKeys}\n selectedApiKey={selectedApiKey}\n onApiKeyChange={handleApiKeyChange}\n />\n )}\n </div>\n );\n};\n\nexport default CodeSnippet;\n"],"names":["React","useState","Children","isValidElement","useRef","useCallback","useMemo","useEffect","Code","cn","Icon","getLanguageInfo","stripSdkType","LanguageSelector","ApiKeySelector","useCopyToClipboard","PlainCodeView","CopyButton","TooltipButton","substituteApiKey","content","apiKey","replace","CodeSnippet","fixed","headerRow","title","children","className","lang","onChange","apiKeys","sdk","showCodeLines","languageOrdering","codeRef","isCopied","copy","extractLanguageFromCode","codeElement","props","classNames","split","langClass","find","cls","startsWith","substring","console","log","childrenArray","languages","sdkTypes","originalLangMap","isSinglePlainCommand","toArray","Set","Map","length","some","includes","forEach","child","preElement","langName","baseLanguage","add","set","push","activeSDKType","setActiveSDKType","size","has","showSDKSelector","filteredLanguages","filtered","filter","sort","a","b","aBase","get","bBase","aIndex","indexOf","bIndex","activeLanguage","l","selectedApiKey","setSelectedApiKey","keys","key","isHovering","setIsHovering","hasOnlyJsonSnippet","processedChildren","targetLanguage","map","codeContent","cleanLang","langInfo","processedContent","String","language","syntaxHighlighterKey","snippet","additionalCSS","showLines","hasSnippetForActiveLanguage","getCodeText","current","allPreElements","querySelectorAll","Array","from","querySelector","textContent","handleSDKTypeChange","type","nextLang","handleLanguageChange","handleApiKeyChange","NoSnippetMessage","activeLanguageInfo","div","name","color","p","label","showLanguageSelector","showFullSelector","renderContent","plainChild","icon","tooltip","active","onClick","variant","alwaysShowLabel","onLanguageChange","span","ref","onMouseEnter","onMouseLeave","onFocus","onBlur","tabIndex","onCopy","text","onApiKeyChange"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/CodeSnippet.tsx"],"sourcesContent":["import React, {\n useState,\n Children,\n isValidElement,\n useRef,\n useCallback,\n useMemo,\n useEffect,\n} from \"react\";\nimport Code from \"./Code\";\nimport cn from \"./utils/cn\";\nimport Icon from \"./Icon\";\nimport { getLanguageInfo, stripSdkType } from \"./CodeSnippet/languages\";\nimport LanguageSelector from \"./CodeSnippet/LanguageSelector\";\nimport ApiKeySelector from \"./CodeSnippet/ApiKeySelector\";\nimport useCopyToClipboard from \"./utils/useCopyToClipboard\";\nimport PlainCodeView from \"./CodeSnippet/PlainCodeView\";\nimport CopyButton from \"./CodeSnippet/CopyButton\";\nimport TooltipButton from \"./CodeSnippet/TooltipButton\";\nimport { type CodeSnippetProps, type SDKType } from \"./CodeSnippet/types\";\n\n// Substitution function for API key placeholders\nconst substituteApiKey = (content: string, apiKey: string): string => {\n return content.replace(/\\{\\{API_KEY\\}\\}/g, `${apiKey.split(\":\")[0]}:*****`);\n};\n\n/**\n * CodeSnippet component that displays code with language switching capability\n */\nconst CodeSnippet: React.FC<CodeSnippetProps> = ({\n fixed = false,\n headerRow = false,\n title = \"Code\",\n children,\n className,\n lang,\n onChange,\n apiKeys,\n sdk,\n showCodeLines = true,\n languageOrdering,\n}) => {\n const codeRef = useRef<HTMLDivElement>(null);\n const { isCopied, copy } = useCopyToClipboard();\n\n const extractLanguageFromCode = useCallback(\n (codeElement: React.ReactElement | null): string | null => {\n if (!codeElement || !codeElement.props.className) return null;\n\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return null;\n\n return langClass.substring(9); // Remove \"language-\" prefix\n },\n [],\n );\n\n const {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSinglePlainCommand,\n } = useMemo(() => {\n const childrenArray = Children.toArray(children);\n const languages: string[] = [];\n const sdkTypes = new Set<SDKType>();\n const originalLangMap = new Map<string, string>();\n\n const isSinglePlainCommand =\n childrenArray.length === 1 &&\n [\"language-shell\", \"language-text\"].some(\n (lang) =>\n isValidElement(childrenArray[0]) &&\n isValidElement(childrenArray[0].props.children) &&\n childrenArray[0].props.children.props.className?.includes(lang),\n );\n\n childrenArray.forEach((child) => {\n if (!isValidElement(child)) return;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n\n const langName = extractLanguageFromCode(codeElement);\n if (!langName) return;\n\n if (langName.startsWith(\"realtime_\")) {\n const baseLanguage = langName.substring(9);\n sdkTypes.add(\"realtime\");\n originalLangMap.set(langName, baseLanguage);\n } else if (langName.startsWith(\"rest_\")) {\n const baseLanguage = langName.substring(5);\n sdkTypes.add(\"rest\");\n originalLangMap.set(langName, baseLanguage);\n } else {\n originalLangMap.set(langName, langName);\n }\n\n if (!languages.includes(langName)) {\n languages.push(langName);\n }\n });\n\n return {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSinglePlainCommand,\n };\n }, [children, extractLanguageFromCode]);\n\n const [activeSDKType, setActiveSDKType] = useState<SDKType>(() => {\n if (sdkTypes.size === 0) return null;\n if (sdk && sdkTypes.has(sdk)) return sdk;\n if (sdkTypes.has(\"realtime\")) return \"realtime\";\n if (sdkTypes.has(\"rest\")) return \"rest\";\n return null;\n });\n\n const showSDKSelector = sdkTypes.size > 0;\n\n const filteredLanguages = useMemo(() => {\n const filtered =\n !activeSDKType || !showSDKSelector\n ? [...languages]\n : languages.filter((lang) => lang.startsWith(`${activeSDKType}_`));\n\n // Apply custom ordering if provided\n if (languageOrdering && languageOrdering.length > 0) {\n filtered.sort((a, b) => {\n const aBase = originalLangMap.get(a) || a;\n const bBase = originalLangMap.get(b) || b;\n\n const aIndex = languageOrdering.indexOf(aBase);\n const bIndex = languageOrdering.indexOf(bBase);\n\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return 0;\n });\n }\n\n return filtered;\n }, [\n activeSDKType,\n showSDKSelector,\n languages,\n languageOrdering,\n originalLangMap,\n ]);\n\n const activeLanguage = useMemo(() => {\n if (sdk && sdkTypes.has(sdk)) {\n return languages.find((l) => l === `${sdk}_${lang}`) ?? lang;\n }\n\n if (lang) return lang;\n\n if (filteredLanguages.length > 0) return filteredLanguages[0];\n\n return lang;\n }, [lang, sdk, sdkTypes, filteredLanguages]);\n\n const [selectedApiKey, setSelectedApiKey] = useState<string>(\n () => apiKeys?.[0]?.keys?.[0]?.key ?? \"\",\n );\n\n useEffect(() => {\n if (!selectedApiKey && apiKeys && apiKeys.length > 0) {\n setSelectedApiKey(apiKeys[0].keys?.[0]?.key);\n }\n }, [apiKeys]);\n\n const requiresApiKeySubstitution = useMemo(() => {\n const containsPlaceholder = childrenArray.some((child) => {\n if (!isValidElement(child)) return false;\n const codeElement = isValidElement(child.props.children)\n ? child.props.children\n : null;\n const codeContent = codeElement.props.children;\n return codeContent.includes(\"{{API_KEY}}\");\n });\n\n return (\n containsPlaceholder && !!apiKeys && apiKeys.length > 0 && !!selectedApiKey\n );\n }, [childrenArray, apiKeys, selectedApiKey]);\n\n const [isHovering, setIsHovering] = useState(false);\n\n const hasOnlyJsonSnippet = useMemo(\n () => languages.length === 1 && languages[0] === \"json\",\n [languages],\n );\n\n const processedChildren = useMemo(() => {\n if (!activeLanguage) return [];\n\n const targetLanguage = hasOnlyJsonSnippet ? \"json\" : activeLanguage;\n\n return childrenArray\n .filter((child) => {\n if (!isValidElement(child)) return false;\n const codeElement = isValidElement(child.props.children)\n ? child.props.children\n : null;\n const langName = extractLanguageFromCode(codeElement);\n return langName === targetLanguage;\n })\n .map((child) => {\n if (!isValidElement(child)) return child;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n if (!codeElement) return child;\n\n const codeContent = codeElement.props.children;\n const langName = extractLanguageFromCode(codeElement);\n if (!langName) return child;\n\n const cleanLang = hasOnlyJsonSnippet ? \"json\" : langName;\n const langInfo = getLanguageInfo(cleanLang);\n\n if (\n typeof codeContent === \"string\" ||\n typeof codeContent === \"number\" ||\n typeof codeContent === \"boolean\"\n ) {\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(codeContent);\n if (requiresApiKeySubstitution) {\n processedContent = substituteApiKey(\n processedContent,\n selectedApiKey,\n );\n }\n\n return (\n <Code\n key={langName}\n language={langInfo.syntaxHighlighterKey || cleanLang}\n snippet={processedContent}\n additionalCSS=\"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-6 py-4\"\n showLines={showCodeLines}\n />\n );\n }\n\n return child;\n });\n }, [\n activeLanguage,\n childrenArray,\n extractLanguageFromCode,\n hasOnlyJsonSnippet,\n showCodeLines,\n apiKeys,\n selectedApiKey,\n ]);\n\n const hasSnippetForActiveLanguage = useMemo(() => {\n if (!activeLanguage) return false;\n if (hasOnlyJsonSnippet) return true;\n\n return childrenArray.some((child) => {\n if (!isValidElement(child)) return false;\n const codeElement = isValidElement(child.props.children)\n ? child.props.children\n : null;\n const langName = extractLanguageFromCode(codeElement);\n return langName === activeLanguage;\n });\n }, [\n activeLanguage,\n childrenArray,\n extractLanguageFromCode,\n hasOnlyJsonSnippet,\n ]);\n\n const getCodeText = useCallback((): string | null => {\n if (!activeLanguage || !hasSnippetForActiveLanguage || !codeRef.current)\n return null;\n\n const allPreElements = codeRef.current.querySelectorAll(\"pre\");\n for (const preElement of Array.from(allPreElements)) {\n const codeElement = preElement.querySelector(\"code\");\n if (!codeElement || !codeElement.className) continue;\n\n const classNames = codeElement.className.split(\" \");\n const langClass = classNames.find((cls) => cls.startsWith(\"language-\"));\n if (!langClass) continue;\n\n const langName = langClass.substring(9);\n if (\n (hasOnlyJsonSnippet && langName === \"json\") ||\n (!hasOnlyJsonSnippet && langName === activeLanguage)\n ) {\n return codeElement.textContent || \"\";\n }\n }\n\n return null;\n }, [activeLanguage, hasSnippetForActiveLanguage, hasOnlyJsonSnippet]);\n\n const handleSDKTypeChange = useCallback(\n (type: SDKType) => {\n // pick first language matching the new SDK prefix\n const nextLang = stripSdkType(\n languages.find((l) => l.startsWith(`${type}_`)) ?? lang,\n );\n setActiveSDKType(type);\n\n // Call onChange with clean language name\n if (onChange && nextLang) {\n onChange(nextLang, type);\n }\n },\n [languages],\n );\n\n const handleLanguageChange = useCallback(\n (language: string) => {\n if (onChange) {\n onChange(stripSdkType(language), activeSDKType);\n }\n },\n [onChange, activeSDKType],\n );\n\n const handleApiKeyChange = useCallback((apiKey: string) => {\n setSelectedApiKey(apiKey);\n }, []);\n\n const NoSnippetMessage = useMemo(() => {\n if (!activeLanguage) return () => null;\n\n const activeLanguageInfo = getLanguageInfo(activeLanguage);\n\n return () => (\n <div className=\"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center\">\n <Icon\n name=\"icon-gui-exclamation-triangle-outline\"\n color=\"text-yellow-600 dark:text-yellow-400\"\n size=\"24px\"\n />\n <p className=\"ui-text-p3 text-neutral-700 dark:text-neutral-600\">\n You're currently viewing the {activeLanguageInfo.label} docs.\n There either isn't a {activeLanguageInfo.label} code sample for\n this example, or this feature isn't supported in{\" \"}\n {activeLanguageInfo.label}. Switch language to view this example in a\n different language, or check which SDKs support this feature.\n </p>\n </div>\n );\n }, [activeLanguage]);\n\n const showLanguageSelector = !fixed && filteredLanguages.length > 0;\n const showFullSelector = filteredLanguages.length > 1;\n\n const renderContent = useMemo(() => {\n if (!activeLanguage) return null;\n\n if (hasSnippetForActiveLanguage) {\n return processedChildren;\n }\n\n if (activeLanguage) {\n return <NoSnippetMessage />;\n }\n\n return null;\n }, [\n activeLanguage,\n hasSnippetForActiveLanguage,\n processedChildren,\n NoSnippetMessage,\n ]);\n\n // Render special case for plain commands (shell or text)\n if (isSinglePlainCommand) {\n const plainChild = childrenArray[0];\n if (\n isValidElement(plainChild) &&\n isValidElement(plainChild.props.children)\n ) {\n const codeElement = plainChild.props.children;\n const codeContent = codeElement.props.children;\n const language = extractLanguageFromCode(codeElement);\n\n if (!language || !codeContent) return null;\n\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(codeContent);\n if (requiresApiKeySubstitution) {\n processedContent = substituteApiKey(processedContent, selectedApiKey);\n }\n\n return (\n <PlainCodeView\n content={processedContent}\n className={className}\n language={language}\n icon={language === \"shell\" ? \"icon-gui-command-line-outline\" : null}\n />\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]\",\n className,\n )}\n >\n {headerRow && (\n <div className=\"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg\">\n <div className=\"flex space-x-1.5\">\n <div className=\"w-3 h-3 rounded-full bg-orange-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-yellow-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-green-500\"></div>\n </div>\n\n <div className=\"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000\">\n {title}\n </div>\n\n {/* Empty div for balance */}\n <div className=\"w-12\"></div>\n </div>\n )}\n {showSDKSelector && (\n <div\n className={cn(\n \"p-2 border-b border-neutral-200 dark:border-neutral-1100 h-14\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n <div className=\"flex gap-3 justify-start\">\n {sdkTypes.has(\"realtime\") && (\n <TooltipButton\n tooltip=\"Realtime SDK\"\n active={activeSDKType === \"realtime\"}\n onClick={() => handleSDKTypeChange(\"realtime\")}\n variant=\"segmented\"\n size=\"sm\"\n alwaysShowLabel={true}\n >\n Realtime\n </TooltipButton>\n )}\n\n {sdkTypes.has(\"rest\") && (\n <TooltipButton\n tooltip=\"REST SDK\"\n active={activeSDKType === \"rest\"}\n onClick={() => handleSDKTypeChange(\"rest\")}\n variant=\"segmented\"\n size=\"sm\"\n alwaysShowLabel={true}\n >\n REST\n </TooltipButton>\n )}\n </div>\n </div>\n )}\n\n {showLanguageSelector &&\n (showFullSelector ? (\n <LanguageSelector\n languages={filteredLanguages}\n activeLanguage={activeLanguage}\n onLanguageChange={handleLanguageChange}\n />\n ) : (\n <div\n className={cn(\n \"border-b border-neutral-200 dark:border-neutral-1100 h-[2.125rem] inline-flex items-center px-3\",\n { \"rounded-t-lg\": !headerRow },\n { \"cursor-pointer\": filteredLanguages.length > 0 },\n )}\n {...(filteredLanguages.length > 0 && {\n onClick: () => handleLanguageChange(filteredLanguages[0]),\n })}\n >\n {filteredLanguages.length > 0 && (\n <>\n <Icon\n name={getLanguageInfo(filteredLanguages[0]).icon}\n size=\"16px\"\n additionalCSS=\"mr-2\"\n />\n <span className=\"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none\">\n {getLanguageInfo(filteredLanguages[0]).label}\n </span>\n </>\n )}\n </div>\n ))}\n <div\n ref={codeRef}\n className=\"relative\"\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n onFocus={() => setIsHovering(true)}\n onBlur={() => setIsHovering(false)}\n tabIndex={0}\n >\n {renderContent}\n {isHovering && activeLanguage && hasSnippetForActiveLanguage && (\n <CopyButton\n onCopy={() => {\n const text = getCodeText();\n if (text) copy(text);\n }}\n isCopied={isCopied}\n />\n )}\n </div>\n {requiresApiKeySubstitution && (\n <ApiKeySelector\n apiKeys={apiKeys}\n selectedApiKey={selectedApiKey}\n onApiKeyChange={handleApiKeyChange}\n />\n )}\n </div>\n );\n};\n\nexport default CodeSnippet;\n"],"names":["React","useState","Children","isValidElement","useRef","useCallback","useMemo","useEffect","Code","cn","Icon","getLanguageInfo","stripSdkType","LanguageSelector","ApiKeySelector","useCopyToClipboard","PlainCodeView","CopyButton","TooltipButton","substituteApiKey","content","apiKey","replace","split","CodeSnippet","fixed","headerRow","title","children","className","lang","onChange","apiKeys","sdk","showCodeLines","languageOrdering","codeRef","isCopied","copy","extractLanguageFromCode","codeElement","props","classNames","langClass","find","cls","startsWith","substring","childrenArray","languages","sdkTypes","originalLangMap","isSinglePlainCommand","toArray","Set","Map","length","some","includes","forEach","child","preElement","langName","baseLanguage","add","set","push","activeSDKType","setActiveSDKType","size","has","showSDKSelector","filteredLanguages","filtered","filter","sort","a","b","aBase","get","bBase","aIndex","indexOf","bIndex","activeLanguage","l","selectedApiKey","setSelectedApiKey","keys","key","requiresApiKeySubstitution","containsPlaceholder","codeContent","isHovering","setIsHovering","hasOnlyJsonSnippet","processedChildren","targetLanguage","map","cleanLang","langInfo","processedContent","String","language","syntaxHighlighterKey","snippet","additionalCSS","showLines","hasSnippetForActiveLanguage","getCodeText","current","allPreElements","querySelectorAll","Array","from","querySelector","textContent","handleSDKTypeChange","type","nextLang","handleLanguageChange","handleApiKeyChange","NoSnippetMessage","activeLanguageInfo","div","name","color","p","label","showLanguageSelector","showFullSelector","renderContent","plainChild","icon","tooltip","active","onClick","variant","alwaysShowLabel","onLanguageChange","span","ref","onMouseEnter","onMouseLeave","onFocus","onBlur","tabIndex","onCopy","text","onApiKeyChange"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/remote-session-data.js"],"sourcesContent":["/* global __ENABLE_FETCH_WITH_CREDENTIALS__ */\n\n// Fetches current users session data\n// Assumes an authenticated session, so will only work when used on ably.com/ably.io\n\nimport { isJsonResponse } from \"./remote-data-util\";\n\nconst NOT_FOUND_ERROR_CODE = \"not-found\";\n\nconst fetchSessionData = async (store, sessionUrl) => {\n const sessionLoaded = (payload = {}) =>\n store.dispatch({ type: \"session/loaded\", payload });\n\n try {\n if (!sessionUrl) {\n console.log(\n `Skipping fetching session, invalid sessionUrl: \"${sessionUrl}\"`,\n );\n sessionLoaded();\n return;\n }\n\n const options = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n if (__ENABLE_FETCH_WITH_CREDENTIALS__) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(sessionUrl, options);\n const jsonResponse = isJsonResponse(res.headers.get(\"content-type\"));\n\n if (!jsonResponse) {\n throw new Error(\"Session endpoint is not serving json\");\n }\n\n const payload = await res.json();\n\n if (payload.error === NOT_FOUND_ERROR_CODE) {\n sessionLoaded();\n } else {\n sessionLoaded(payload);\n }\n } catch (e) {\n sessionLoaded();\n console.warn(\"Could not fetch session data due to error:\", e);\n }\n};\n\nconst initialState = { data: null };\n\nconst REDUCER_KEY = \"session\";\n\nconst reducerSessionData = {\n [REDUCER_KEY]: (state = initialState, action) => {\n switch (action.type) {\n case \"session/loaded\":\n return { ...state, data: action.payload };\n default:\n return state;\n }\n },\n};\n\nconst selectSessionData = (store) => store.getState()[REDUCER_KEY]?.data;\n\nexport { fetchSessionData, reducerSessionData, selectSessionData };\n"],"names":["isJsonResponse","NOT_FOUND_ERROR_CODE","fetchSessionData","store","sessionUrl","sessionLoaded","payload","dispatch","type","console","log","options","headers","accept","cache","credentials","res","fetch","jsonResponse","get","Error","json","error","e","warn","initialState","data","REDUCER_KEY","reducerSessionData","state","action","selectSessionData","getState"],"mappings":"AAKA,OAASA,cAAc,KAAQ,oBAAqB,CAEpD,MAAMC,qBAAuB,YAE7B,MAAMC,iBAAmB,MAAOC,MAAOC,cACrC,MAAMC,cAAgB,CAACC,QAAU,CAAC,CAAC,GACjCH,MAAMI,QAAQ,CAAC,CAAEC,KAAM,iBAAkBF,OAAQ,GAEnD,GAAI,CACF,GAAI,CAACF,WAAY,CACfK,QAAQC,GAAG,CACT,CAAC,gDAAgD,EAAEN,WAAW,CAAC,CAAC,EAElEC,gBACA,MACF,CAEA,MAAMM,QAAU,CACdC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAEA,
|
|
1
|
+
{"version":3,"sources":["../../src/core/remote-session-data.js"],"sourcesContent":["/* global __ENABLE_FETCH_WITH_CREDENTIALS__ */\n\n// Fetches current users session data\n// Assumes an authenticated session, so will only work when used on ably.com/ably.io\n\nimport { isJsonResponse } from \"./remote-data-util\";\n\nconst NOT_FOUND_ERROR_CODE = \"not-found\";\n\nconst fetchSessionData = async (store, sessionUrl) => {\n const sessionLoaded = (payload = {}) =>\n store.dispatch({ type: \"session/loaded\", payload });\n\n try {\n if (!sessionUrl) {\n console.log(\n `Skipping fetching session, invalid sessionUrl: \"${sessionUrl}\"`,\n );\n sessionLoaded();\n return;\n }\n\n const options = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n if (__ENABLE_FETCH_WITH_CREDENTIALS__) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(sessionUrl, options);\n const jsonResponse = isJsonResponse(res.headers.get(\"content-type\"));\n\n if (!jsonResponse) {\n throw new Error(\"Session endpoint is not serving json\");\n }\n\n const payload = await res.json();\n\n if (payload.error === NOT_FOUND_ERROR_CODE) {\n sessionLoaded();\n } else {\n sessionLoaded(payload);\n }\n } catch (e) {\n sessionLoaded();\n console.warn(\"Could not fetch session data due to error:\", e);\n }\n};\n\nconst initialState = { data: null };\n\nconst REDUCER_KEY = \"session\";\n\nconst reducerSessionData = {\n [REDUCER_KEY]: (state = initialState, action) => {\n switch (action.type) {\n case \"session/loaded\":\n return { ...state, data: action.payload };\n default:\n return state;\n }\n },\n};\n\nconst selectSessionData = (store) => store.getState()[REDUCER_KEY]?.data;\n\nexport { fetchSessionData, reducerSessionData, selectSessionData };\n"],"names":["isJsonResponse","NOT_FOUND_ERROR_CODE","fetchSessionData","store","sessionUrl","sessionLoaded","payload","dispatch","type","console","log","options","headers","accept","cache","credentials","res","fetch","jsonResponse","get","Error","json","error","e","warn","initialState","data","REDUCER_KEY","reducerSessionData","state","action","selectSessionData","getState"],"mappings":"AAKA,OAASA,cAAc,KAAQ,oBAAqB,CAEpD,MAAMC,qBAAuB,YAE7B,MAAMC,iBAAmB,MAAOC,MAAOC,cACrC,MAAMC,cAAgB,CAACC,QAAU,CAAC,CAAC,GACjCH,MAAMI,QAAQ,CAAC,CAAEC,KAAM,iBAAkBF,OAAQ,GAEnD,GAAI,CACF,GAAI,CAACF,WAAY,CACfK,QAAQC,GAAG,CACT,CAAC,gDAAgD,EAAEN,WAAW,CAAC,CAAC,EAElEC,gBACA,MACF,CAEA,MAAMM,QAAU,CACdC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAEA,GA0BgB,MA1BuB,CACrCH,QAAQI,WAAW,CAAG,SACxB,CAEA,MAAMC,IAAM,MAAMC,MAAMb,WAAYO,SACpC,MAAMO,aAAelB,eAAegB,IAAIJ,OAAO,CAACO,GAAG,CAAC,iBAEpD,GAAI,CAACD,aAAc,CACjB,MAAM,IAAIE,MAAM,uCAClB,CAEA,MAAMd,QAAU,MAAMU,IAAIK,IAAI,GAE9B,GAAIf,QAAQgB,KAAK,GAAKrB,qBAAsB,CAC1CI,eACF,KAAO,CACLA,cAAcC,QAChB,CACF,CAAE,MAAOiB,EAAG,CACVlB,gBACAI,QAAQe,IAAI,CAAC,6CAA8CD,EAC7D,CACF,EAEA,MAAME,aAAe,CAAEC,KAAM,IAAK,EAElC,MAAMC,YAAc,UAEpB,MAAMC,mBAAqB,CACzB,CAACD,YAAY,CAAE,CAACE,MAAQJ,YAAY,CAAEK,UACpC,OAAQA,OAAOtB,IAAI,EACjB,IAAK,iBACH,MAAO,CAAE,GAAGqB,KAAK,CAAEH,KAAMI,OAAOxB,OAAO,AAAC,CAC1C,SACE,OAAOuB,KACX,CACF,CACF,EAEA,MAAME,kBAAoB,AAAC5B,OAAUA,MAAM6B,QAAQ,EAAE,CAACL,YAAY,EAAED,IAEpE,QAASxB,gBAAgB,CAAE0B,kBAAkB,CAAEG,iBAAiB,CAAG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ably/ui",
|
|
3
|
-
"version": "17.4.0-dev.
|
|
3
|
+
"version": "17.4.0-dev.ab50c043",
|
|
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",
|