@ably/ui 16.2.0-dev.fccd868b → 16.2.1-dev.4113a861
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/Accordion.js +1 -1
- package/core/Accordion.js.map +1 -1
- package/core/CodeSnippet/ShellCommandView.js +1 -1
- package/core/CodeSnippet/ShellCommandView.js.map +1 -1
- package/core/CodeSnippet/languages.js +1 -1
- package/core/CodeSnippet/languages.js.map +1 -1
- package/core/CodeSnippet.js +1 -1
- package/core/CodeSnippet.js.map +1 -1
- package/core/Header.js +1 -1
- package/core/Header.js.map +1 -1
- package/core/Icon/computed-icons.js +1 -1
- package/core/Icon/computed-icons.js.map +1 -1
- package/core/ProductTile/ProductDescription.js +1 -1
- package/core/ProductTile/ProductDescription.js.map +1 -1
- package/core/ProductTile/ProductLabel.js +1 -1
- package/core/ProductTile/ProductLabel.js.map +1 -1
- package/core/ProductTile/data.js +1 -1
- package/core/ProductTile/data.js.map +1 -1
- package/core/ProductTile.js +1 -1
- package/core/ProductTile.js.map +1 -1
- package/core/icons/tech/icon-tech-json.svg +15 -0
- package/core/remote-session-data.js.map +1 -1
- package/core/sprites.svg +1 -1
- package/index.d.ts +25 -6
- package/package.json +2 -2
- package/core/.DS_Store +0 -0
- package/core/Accordion/.DS_Store +0 -0
- package/core/Code/.DS_Store +0 -0
- package/core/ContactFooter/.DS_Store +0 -0
- package/core/CookieMessage/.DS_Store +0 -0
- package/core/CustomerLogos/.DS_Store +0 -0
- package/core/DropdownMenu/.DS_Store +0 -0
- package/core/FeaturedLink/.DS_Store +0 -0
- package/core/Flash/.DS_Store +0 -0
- package/core/Footer/.DS_Store +0 -0
- package/core/Icon/.DS_Store +0 -0
- package/core/Loader/.DS_Store +0 -0
- package/core/Logo/.DS_Store +0 -0
- package/core/Meganav/.DS_Store +0 -0
- package/core/Notice/.DS_Store +0 -0
- package/core/Slider/.DS_Store +0 -0
- package/core/Table/.DS_Store +0 -0
- package/core/Tooltip/.DS_Store +0 -0
- package/core/icons/.DS_Store +0 -0
- package/core/icons/gui/.DS_Store +0 -0
- package/core/images/.DS_Store +0 -0
- package/core/images/logo/.DS_Store +0 -0
package/core/Accordion.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useMemo,useState,forwardRef}from"react";import{AccordionContent,AccordionItem,AccordionTrigger,Accordion as RadixAccordion}from"@radix-ui/react-accordion";import Icon from"./Icon";import{themeClasses,isNonTransparentTheme,isStaticTheme}from"./Accordion/utils";import cn from"./utils/cn";const AccordionRow=({name,children,rowIcon,options,toggleIcons,theme,index,onClick,openRowValues,rowInteractive=true})=>{const{selectable,sticky}=options||{};const rowKey=`accordion-item-${index}`;const isOpen=openRowValues.includes(rowKey);const{text,bg,hoverBg,selectableBg,selectableText,border,toggleIconColor}=themeClasses[theme];const textClass=selectable&&isOpen&&selectableText||text;return React.createElement(AccordionItem,{value:rowKey,className:cn({[`${border}`]:border&&!options?.hideBorders})},React.createElement(AccordionTrigger,{onClick:onClick,className:cn({"flex w-full group/accordion-trigger py-16 ui-text-p1 font-bold text-left items-center gap-12 transition-colors focus:outline-none":true,"px-16 mb-16 rounded-lg":isNonTransparentTheme(theme),"px-0 rounded-none":!isNonTransparentTheme(theme),"pointer-events-none focus-visible:outline-none":isStaticTheme(theme),"focus-base":!isStaticTheme(theme),"sticky top-0":sticky,[`${bg} ${hoverBg} ${text}`]:!(selectable&&isOpen),[`${selectableBg} ${selectableText}`]:selectable&&isOpen,[options?.headerCSS??""]:options?.headerCSS,[options?.selectedHeaderCSS??""]:options?.selectedHeaderCSS&&isOpen})},rowIcon?React.createElement(Icon,{name:rowIcon,color:textClass,size:options?.rowIconSize??"32px"}):null,React.createElement("span",null,name),!selectable&&!isStaticTheme(theme)&&rowInteractive?React.createElement("span",{className:"flex-1 justify-end flex items-center"},React.createElement(Icon,{name:isOpen?toggleIcons.open.name:toggleIcons.closed.name,color:toggleIconColor,size:options?.iconSize??"16px"})):null),rowInteractive&&React.createElement(AccordionContent,{className:cn({"ui-text-p2 overflow-hidden transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down":true,[options?.contentCSS??""]:options?.contentCSS})},React.createElement("div",{className:"pb-16"},children)))};const Accordion=forwardRef(({data,theme="transparent",icons={closed:{name:"icon-gui-plus-outline"},open:{name:"icon-gui-minus-outline"}},options,...props},ref)=>{const openIndexes=useMemo(()=>{const indexValues=data.map((_,i)=>`accordion-item-${i}`);return options?.fullyOpen?indexValues:indexValues.filter((_,index)=>options?.defaultOpenIndexes?.includes(index))},[options?.defaultOpenIndexes,options?.fullyOpen,data.length]);const[openRowValues,setOpenRowValues]=useState(openIndexes);const innerAccordion=data.map((item,index)=>React.createElement(AccordionRow,{key:item.name,name:item.name,rowIcon:item.icon,toggleIcons:icons,theme:theme,options:options,index:index,onClick:()=>{item.onClick?.(index)},openRowValues:openRowValues,rowInteractive:item.interactive},item.content));return React.createElement("div",{ref:ref,...props},options?.autoClose?React.createElement(RadixAccordion,{type:"single",collapsible:true,
|
|
1
|
+
import React,{useMemo,useState,forwardRef,useEffect}from"react";import{AccordionContent,AccordionItem,AccordionTrigger,Accordion as RadixAccordion}from"@radix-ui/react-accordion";import Icon from"./Icon";import{themeClasses,isNonTransparentTheme,isStaticTheme}from"./Accordion/utils";import cn from"./utils/cn";const AccordionRow=({name,children,rowIcon,options,toggleIcons,theme,index,onClick,openRowValues,rowInteractive=true})=>{const{selectable,sticky}=options||{};const rowKey=`accordion-item-${index}`;const isOpen=openRowValues.includes(rowKey);const{text,bg,hoverBg,selectableBg,selectableText,border,toggleIconColor}=themeClasses[theme];const textClass=selectable&&isOpen&&selectableText||text;return React.createElement(AccordionItem,{value:rowKey,className:cn({[`${border}`]:border&&!options?.hideBorders})},React.createElement(AccordionTrigger,{onClick:onClick,className:cn({"flex w-full group/accordion-trigger py-16 ui-text-p1 font-bold text-left items-center gap-12 transition-colors focus:outline-none":true,"px-16 mb-16 rounded-lg":isNonTransparentTheme(theme),"px-0 rounded-none":!isNonTransparentTheme(theme),"pointer-events-none focus-visible:outline-none":isStaticTheme(theme),"focus-base":!isStaticTheme(theme),"sticky top-0":sticky,[`${bg} ${hoverBg} ${text}`]:!(selectable&&isOpen),[`${selectableBg} ${selectableText}`]:selectable&&isOpen,[options?.headerCSS??""]:options?.headerCSS,[options?.selectedHeaderCSS??""]:options?.selectedHeaderCSS&&isOpen})},rowIcon?React.createElement(Icon,{name:rowIcon,color:textClass,size:options?.rowIconSize??"32px"}):null,React.createElement("span",null,name),!selectable&&!isStaticTheme(theme)&&rowInteractive?React.createElement("span",{className:"flex-1 justify-end flex items-center"},React.createElement(Icon,{name:isOpen?toggleIcons.open.name:toggleIcons.closed.name,color:toggleIconColor,size:options?.iconSize??"16px"})):null),rowInteractive&&React.createElement(AccordionContent,{className:cn({"ui-text-p2 overflow-hidden transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down":true,[options?.contentCSS??""]:options?.contentCSS})},React.createElement("div",{className:"pb-16"},children)))};const Accordion=forwardRef(({data,theme="transparent",icons={closed:{name:"icon-gui-plus-outline"},open:{name:"icon-gui-minus-outline"}},options,...props},ref)=>{const openIndexes=useMemo(()=>{const indexValues=data.map((_,i)=>`accordion-item-${i}`);return options?.fullyOpen?indexValues:indexValues.filter((_,index)=>options?.defaultOpenIndexes?.includes(index))},[options?.defaultOpenIndexes,options?.fullyOpen,data.length]);const[openRowValues,setOpenRowValues]=useState(openIndexes);useEffect(()=>{setOpenRowValues(openIndexes)},[openIndexes]);const innerAccordion=data.map((item,index)=>React.createElement(AccordionRow,{key:item.name,name:item.name,rowIcon:item.icon,toggleIcons:icons,theme:theme,options:options,index:index,onClick:()=>{item.onClick?.(index)},openRowValues:openRowValues,rowInteractive:item.interactive},item.content));return React.createElement("div",{ref:ref,...props},options?.autoClose?React.createElement(RadixAccordion,{type:"single",collapsible:true,value:openRowValues[0],onValueChange:values=>setOpenRowValues([values])},innerAccordion):React.createElement(RadixAccordion,{type:"multiple",value:openRowValues,onValueChange:values=>setOpenRowValues(values)},innerAccordion))});Accordion.displayName="Accordion";export default Accordion;
|
|
2
2
|
//# sourceMappingURL=Accordion.js.map
|
package/core/Accordion.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Accordion.tsx"],"sourcesContent":["import React, {
|
|
1
|
+
{"version":3,"sources":["../../src/core/Accordion.tsx"],"sourcesContent":["import React, {\n ReactNode,\n useMemo,\n useState,\n forwardRef,\n useEffect,\n} from \"react\";\nimport {\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n Accordion as RadixAccordion,\n} from \"@radix-ui/react-accordion\";\n\nimport Icon from \"./Icon\";\nimport type { IconName } from \"./Icon/types\";\nimport type {\n AccordionData,\n AccordionIcons,\n AccordionOptions,\n AccordionTheme,\n} from \"./Accordion/types\";\nimport {\n themeClasses,\n isNonTransparentTheme,\n isStaticTheme,\n} from \"./Accordion/utils\";\nimport cn from \"./utils/cn\";\n\ntype AccordionRowProps = {\n children: ReactNode;\n name: string;\n rowIcon?: IconName;\n theme: AccordionTheme;\n toggleIcons: AccordionIcons;\n options?: AccordionOptions;\n index: number;\n onClick: () => void;\n openRowValues: string[];\n rowInteractive?: boolean;\n};\n\nexport type AccordionProps = {\n /**\n * The data for the accordion items.\n */\n data: AccordionData[];\n\n /**\n * Icons for the accordion toggle.\n */\n icons?: AccordionIcons;\n\n /**\n * Theme for the accordion.\n */\n theme?: AccordionTheme;\n\n /**\n * Options for the accordion behavior.\n */\n options?: AccordionOptions;\n} & React.HTMLAttributes<HTMLDivElement>;\n\nconst AccordionRow = ({\n name,\n children,\n rowIcon,\n options,\n toggleIcons,\n theme,\n index,\n onClick,\n openRowValues,\n rowInteractive = true,\n}: AccordionRowProps) => {\n const { selectable, sticky } = options || {};\n const rowKey = `accordion-item-${index}`;\n const isOpen = openRowValues.includes(rowKey);\n\n const {\n text,\n bg,\n hoverBg,\n selectableBg,\n selectableText,\n border,\n toggleIconColor,\n } = themeClasses[theme];\n\n const textClass = (selectable && isOpen && selectableText) || text;\n\n return (\n <AccordionItem\n value={rowKey}\n className={cn({\n [`${border}`]: border && !options?.hideBorders,\n })}\n >\n <AccordionTrigger\n onClick={onClick}\n className={cn({\n \"flex w-full group/accordion-trigger py-16 ui-text-p1 font-bold text-left items-center gap-12 transition-colors focus:outline-none\":\n true,\n \"px-16 mb-16 rounded-lg\": isNonTransparentTheme(theme),\n \"px-0 rounded-none\": !isNonTransparentTheme(theme),\n \"pointer-events-none focus-visible:outline-none\":\n isStaticTheme(theme),\n \"focus-base\": !isStaticTheme(theme),\n \"sticky top-0\": sticky,\n [`${bg} ${hoverBg} ${text}`]: !(selectable && isOpen),\n [`${selectableBg} ${selectableText}`]: selectable && isOpen,\n [options?.headerCSS ?? \"\"]: options?.headerCSS,\n [options?.selectedHeaderCSS ?? \"\"]:\n options?.selectedHeaderCSS && isOpen,\n })}\n >\n {rowIcon ? (\n <Icon\n name={rowIcon}\n color={textClass}\n size={options?.rowIconSize ?? \"32px\"}\n />\n ) : null}\n <span>{name}</span>\n {!selectable && !isStaticTheme(theme) && rowInteractive ? (\n <span className=\"flex-1 justify-end flex items-center\">\n <Icon\n name={isOpen ? toggleIcons.open.name : toggleIcons.closed.name}\n color={toggleIconColor}\n size={options?.iconSize ?? \"16px\"}\n />\n </span>\n ) : null}\n </AccordionTrigger>\n {rowInteractive && (\n <AccordionContent\n className={cn({\n \"ui-text-p2 overflow-hidden transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\":\n true,\n [options?.contentCSS ?? \"\"]: options?.contentCSS,\n })}\n >\n <div className=\"pb-16\">{children}</div>\n </AccordionContent>\n )}\n </AccordionItem>\n );\n};\n\nconst Accordion = forwardRef<HTMLDivElement, AccordionProps>(\n (\n {\n data,\n theme = \"transparent\",\n icons = {\n closed: { name: \"icon-gui-plus-outline\" },\n open: { name: \"icon-gui-minus-outline\" },\n },\n options,\n ...props\n },\n ref,\n ) => {\n const openIndexes = useMemo(() => {\n const indexValues = data.map((_, i) => `accordion-item-${i}`);\n return options?.fullyOpen\n ? indexValues\n : indexValues.filter((_, index) =>\n options?.defaultOpenIndexes?.includes(index),\n );\n }, [options?.defaultOpenIndexes, options?.fullyOpen, data.length]);\n\n const [openRowValues, setOpenRowValues] = useState<string[]>(openIndexes);\n\n useEffect(() => {\n setOpenRowValues(openIndexes);\n }, [openIndexes]);\n\n const innerAccordion = data.map((item, index) => (\n <AccordionRow\n key={item.name}\n name={item.name}\n rowIcon={item.icon}\n toggleIcons={icons}\n theme={theme}\n options={options}\n index={index}\n onClick={() => {\n item.onClick?.(index);\n }}\n openRowValues={openRowValues}\n rowInteractive={item.interactive}\n >\n {item.content}\n </AccordionRow>\n ));\n\n return (\n <div ref={ref} {...props}>\n {options?.autoClose ? (\n <RadixAccordion\n type=\"single\"\n collapsible\n value={openRowValues[0]}\n onValueChange={(values) => setOpenRowValues([values])}\n >\n {innerAccordion}\n </RadixAccordion>\n ) : (\n <RadixAccordion\n type=\"multiple\"\n value={openRowValues}\n onValueChange={(values) => setOpenRowValues(values)}\n >\n {innerAccordion}\n </RadixAccordion>\n )}\n </div>\n );\n },\n);\n\nAccordion.displayName = \"Accordion\";\n\nexport default Accordion;\n"],"names":["React","useMemo","useState","forwardRef","useEffect","AccordionContent","AccordionItem","AccordionTrigger","Accordion","RadixAccordion","Icon","themeClasses","isNonTransparentTheme","isStaticTheme","cn","AccordionRow","name","children","rowIcon","options","toggleIcons","theme","index","onClick","openRowValues","rowInteractive","selectable","sticky","rowKey","isOpen","includes","text","bg","hoverBg","selectableBg","selectableText","border","toggleIconColor","textClass","value","className","hideBorders","headerCSS","selectedHeaderCSS","color","size","rowIconSize","span","open","closed","iconSize","contentCSS","div","data","icons","props","ref","openIndexes","indexValues","map","_","i","fullyOpen","filter","defaultOpenIndexes","length","setOpenRowValues","innerAccordion","item","key","icon","interactive","content","autoClose","type","collapsible","onValueChange","values","displayName"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useRef,useCallback}from"react";import Icon from"../Icon";import Code from"../Code";import cn from"../utils/cn";import useCopyToClipboard from"../utils/useCopyToClipboard";import CopyButton from"./CopyButton";const ShellCommandView=({content,className})=>{const{isCopied,copy}=useCopyToClipboard();const codeRef=useRef(null);const[isHovering,setIsHovering]=React.useState(false);const handleCopy=useCallback(()=>{if(!codeRef.current)return;copy(content)},[copy,content]);return React.createElement("div",{className:cn("rounded-lg overflow-hidden bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 relative",className),onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>setIsHovering(false),onFocus:()=>setIsHovering(true),onBlur:()=>setIsHovering(false),tabIndex:0,ref:codeRef},React.createElement("div",{className:"absolute top-8 left-8 z-10"},React.createElement("div",{className:"w-36 h-36 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100"},React.createElement(Icon,{name:"icon-gui-command-line-outline",size:"20px",color:"text-neutral-1300 dark:text-neutral-000"}))),React.createElement("div",{className:"pl-56"},React.createElement(Code,{language:"shell",snippet:content,additionalCSS:"bg-neutral-000 text-neutral-1300 dark:bg-neutral-1300 dark:text-neutral-200 pl-[56px] py-12",showLines:false})),isHovering&&React.createElement(CopyButton,{onCopy:handleCopy,isCopied:isCopied}))};export default ShellCommandView;
|
|
1
|
+
import React,{useRef,useCallback}from"react";import Icon from"../Icon";import Code from"../Code";import cn from"../utils/cn";import useCopyToClipboard from"../utils/useCopyToClipboard";import CopyButton from"./CopyButton";const ShellCommandView=({content,className})=>{const{isCopied,copy}=useCopyToClipboard();const codeRef=useRef(null);const[isHovering,setIsHovering]=React.useState(false);const handleCopy=useCallback(()=>{if(!codeRef.current)return;copy(content)},[copy,content]);return React.createElement("div",{className:cn("rounded-lg overflow-hidden bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 relative min-h-[54px]",className),onMouseEnter:()=>setIsHovering(true),onMouseLeave:()=>setIsHovering(false),onFocus:()=>setIsHovering(true),onBlur:()=>setIsHovering(false),tabIndex:0,ref:codeRef},React.createElement("div",{className:"absolute top-8 left-8 z-10"},React.createElement("div",{className:"w-36 h-36 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100"},React.createElement(Icon,{name:"icon-gui-command-line-outline",size:"20px",color:"text-neutral-1300 dark:text-neutral-000"}))),React.createElement("div",{className:"pl-56"},React.createElement(Code,{language:"shell",snippet:content,additionalCSS:"bg-neutral-000 text-neutral-1300 dark:bg-neutral-1300 dark:text-neutral-200 pl-[56px] py-12",showLines:false})),isHovering&&React.createElement(CopyButton,{onCopy:handleCopy,isCopied:isCopied}))};export default ShellCommandView;
|
|
2
2
|
//# sourceMappingURL=ShellCommandView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/CodeSnippet/ShellCommandView.tsx"],"sourcesContent":["import React, { useRef, useCallback } from \"react\";\nimport Icon from \"../Icon\";\nimport Code from \"../Code\";\nimport cn from \"../utils/cn\";\nimport useCopyToClipboard from \"../utils/useCopyToClipboard\";\nimport CopyButton from \"./CopyButton\";\n\ninterface ShellCommandViewProps {\n content: string;\n className?: string;\n}\n\n/**\n * A specialized component for displaying shell commands with copy functionality\n */\nconst ShellCommandView: React.FC<ShellCommandViewProps> = ({\n content,\n className,\n}) => {\n const { isCopied, copy } = useCopyToClipboard();\n const codeRef = useRef<HTMLDivElement>(null);\n const [isHovering, setIsHovering] = React.useState(false);\n\n const handleCopy = useCallback(() => {\n if (!codeRef.current) return;\n copy(content);\n }, [copy, content]);\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 relative\",\n className,\n )}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n onFocus={() => setIsHovering(true)}\n onBlur={() => setIsHovering(false)}\n tabIndex={0}\n ref={codeRef}\n >\n {/* Shell Icon */}\n <div className=\"absolute top-8 left-8 z-10\">\n <div className=\"w-36 h-36 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100\">\n <Icon\n name=\"icon-gui-command-line-outline\"\n size=\"20px\"\n color=\"text-neutral-1300 dark:text-neutral-000\"\n />\n </div>\n </div>\n\n {/* Code Content */}\n <div className=\"pl-56\">\n <Code\n language=\"shell\"\n snippet={content}\n additionalCSS=\"bg-neutral-000 text-neutral-1300 dark:bg-neutral-1300 dark:text-neutral-200 pl-[56px] py-12\"\n showLines={false}\n />\n </div>\n\n {/* Copy Button - only shown on hover */}\n {isHovering && <CopyButton onCopy={handleCopy} isCopied={isCopied} />}\n </div>\n );\n};\n\nexport default ShellCommandView;\n"],"names":["React","useRef","useCallback","Icon","Code","cn","useCopyToClipboard","CopyButton","ShellCommandView","content","className","isCopied","copy","codeRef","isHovering","setIsHovering","useState","handleCopy","current","div","onMouseEnter","onMouseLeave","onFocus","onBlur","tabIndex","ref","name","size","color","language","snippet","additionalCSS","showLines","onCopy"],"mappings":"AAAA,OAAOA,OAASC,MAAM,CAAEC,WAAW,KAAQ,OAAQ,AACnD,QAAOC,SAAU,SAAU,AAC3B,QAAOC,SAAU,SAAU,AAC3B,QAAOC,OAAQ,aAAc,AAC7B,QAAOC,uBAAwB,6BAA8B,AAC7D,QAAOC,eAAgB,cAAe,CAUtC,MAAMC,iBAAoD,CAAC,CACzDC,OAAO,CACPC,SAAS,CACV,IACC,KAAM,CAAEC,QAAQ,CAAEC,IAAI,CAAE,CAAGN,qBAC3B,MAAMO,QAAUZ,OAAuB,MACvC,KAAM,CAACa,WAAYC,cAAc,CAAGf,MAAMgB,QAAQ,CAAC,OAEnD,MAAMC,WAAaf,YAAY,KAC7B,GAAI,CAACW,QAAQK,OAAO,CAAE,OACtBN,KAAKH,QACP,EAAG,CAACG,KAAMH,QAAQ,EAElB,OACE,oBAACU,OACCT,UAAWL,GACT,
|
|
1
|
+
{"version":3,"sources":["../../../src/core/CodeSnippet/ShellCommandView.tsx"],"sourcesContent":["import React, { useRef, useCallback } from \"react\";\nimport Icon from \"../Icon\";\nimport Code from \"../Code\";\nimport cn from \"../utils/cn\";\nimport useCopyToClipboard from \"../utils/useCopyToClipboard\";\nimport CopyButton from \"./CopyButton\";\n\ninterface ShellCommandViewProps {\n content: string;\n className?: string;\n}\n\n/**\n * A specialized component for displaying shell commands with copy functionality\n */\nconst ShellCommandView: React.FC<ShellCommandViewProps> = ({\n content,\n className,\n}) => {\n const { isCopied, copy } = useCopyToClipboard();\n const codeRef = useRef<HTMLDivElement>(null);\n const [isHovering, setIsHovering] = React.useState(false);\n\n const handleCopy = useCallback(() => {\n if (!codeRef.current) return;\n copy(content);\n }, [copy, content]);\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-000 dark:bg-neutral-1300 border border-neutral-300 dark:border-neutral-1000 relative min-h-[54px]\",\n className,\n )}\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n onFocus={() => setIsHovering(true)}\n onBlur={() => setIsHovering(false)}\n tabIndex={0}\n ref={codeRef}\n >\n {/* Shell Icon */}\n <div className=\"absolute top-8 left-8 z-10\">\n <div className=\"w-36 h-36 rounded-lg flex items-center justify-center bg-neutral-200 dark:bg-neutral-1100\">\n <Icon\n name=\"icon-gui-command-line-outline\"\n size=\"20px\"\n color=\"text-neutral-1300 dark:text-neutral-000\"\n />\n </div>\n </div>\n\n {/* Code Content */}\n <div className=\"pl-56\">\n <Code\n language=\"shell\"\n snippet={content}\n additionalCSS=\"bg-neutral-000 text-neutral-1300 dark:bg-neutral-1300 dark:text-neutral-200 pl-[56px] py-12\"\n showLines={false}\n />\n </div>\n\n {/* Copy Button - only shown on hover */}\n {isHovering && <CopyButton onCopy={handleCopy} isCopied={isCopied} />}\n </div>\n );\n};\n\nexport default ShellCommandView;\n"],"names":["React","useRef","useCallback","Icon","Code","cn","useCopyToClipboard","CopyButton","ShellCommandView","content","className","isCopied","copy","codeRef","isHovering","setIsHovering","useState","handleCopy","current","div","onMouseEnter","onMouseLeave","onFocus","onBlur","tabIndex","ref","name","size","color","language","snippet","additionalCSS","showLines","onCopy"],"mappings":"AAAA,OAAOA,OAASC,MAAM,CAAEC,WAAW,KAAQ,OAAQ,AACnD,QAAOC,SAAU,SAAU,AAC3B,QAAOC,SAAU,SAAU,AAC3B,QAAOC,OAAQ,aAAc,AAC7B,QAAOC,uBAAwB,6BAA8B,AAC7D,QAAOC,eAAgB,cAAe,CAUtC,MAAMC,iBAAoD,CAAC,CACzDC,OAAO,CACPC,SAAS,CACV,IACC,KAAM,CAAEC,QAAQ,CAAEC,IAAI,CAAE,CAAGN,qBAC3B,MAAMO,QAAUZ,OAAuB,MACvC,KAAM,CAACa,WAAYC,cAAc,CAAGf,MAAMgB,QAAQ,CAAC,OAEnD,MAAMC,WAAaf,YAAY,KAC7B,GAAI,CAACW,QAAQK,OAAO,CAAE,OACtBN,KAAKH,QACP,EAAG,CAACG,KAAMH,QAAQ,EAElB,OACE,oBAACU,OACCT,UAAWL,GACT,0IACAK,WAEFU,aAAc,IAAML,cAAc,MAClCM,aAAc,IAAMN,cAAc,OAClCO,QAAS,IAAMP,cAAc,MAC7BQ,OAAQ,IAAMR,cAAc,OAC5BS,SAAU,EACVC,IAAKZ,SAGL,oBAACM,OAAIT,UAAU,8BACb,oBAACS,OAAIT,UAAU,6FACb,oBAACP,MACCuB,KAAK,gCACLC,KAAK,OACLC,MAAM,8CAMZ,oBAACT,OAAIT,UAAU,SACb,oBAACN,MACCyB,SAAS,QACTC,QAASrB,QACTsB,cAAc,8FACdC,UAAW,SAKdlB,YAAc,oBAACP,YAAW0B,OAAQhB,WAAYN,SAAUA,WAG/D,CAEA,gBAAeH,gBAAiB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const languages={javascript:{label:"JavaScript",icon:"icon-tech-javascript",syntaxHighlighterKey:"javascript"},typescript:{label:"TypeScript",icon:"icon-tech-typescript",syntaxHighlighterKey:"typescript"},
|
|
1
|
+
const languages={javascript:{label:"JavaScript",icon:"icon-tech-javascript",syntaxHighlighterKey:"javascript"},typescript:{label:"TypeScript",icon:"icon-tech-typescript",syntaxHighlighterKey:"typescript"},java:{label:"Java",icon:"icon-tech-java",syntaxHighlighterKey:"java"},kotlin:{label:"Kotlin",icon:"icon-tech-kotlin",syntaxHighlighterKey:"kotlin"},python:{label:"Python",icon:"icon-tech-python",syntaxHighlighterKey:"python"},csharp:{label:"C#",icon:"icon-tech-csharp",syntaxHighlighterKey:"csharp"},go:{label:"Go",icon:"icon-tech-go",syntaxHighlighterKey:"go"},ruby:{label:"Ruby",icon:"icon-tech-ruby",syntaxHighlighterKey:"ruby"},php:{label:"PHP",icon:"icon-tech-php",syntaxHighlighterKey:"php"},nodejs:{label:"Node.js",icon:"icon-tech-nodejs",syntaxHighlighterKey:"javascript"},react:{label:"React",icon:"icon-tech-react",syntaxHighlighterKey:"javascript"},html:{label:"HTML",icon:"icon-tech-web",syntaxHighlighterKey:"xml"},shell:{label:"Shell",icon:"icon-tech-web",syntaxHighlighterKey:"bash"},json:{label:"JSON",icon:"icon-tech-json",syntaxHighlighterKey:"json"},xml:{label:"XML",icon:"icon-tech-web",syntaxHighlighterKey:"xml"},sql:{label:"SQL",icon:"icon-tech-postgres",syntaxHighlighterKey:"sql"},swift:{label:"Swift",icon:"icon-tech-swift",syntaxHighlighterKey:"swift"},cpp:{label:"C++",icon:"icon-tech-web",syntaxHighlighterKey:"cpp"},dart:{label:"Dart",icon:"icon-tech-web",syntaxHighlighterKey:"dart"},objc:{label:"Objective-C",icon:"icon-tech-objectivec",syntaxHighlighterKey:"objc"},android:{label:"Android",icon:"icon-tech-android-head",syntaxHighlighterKey:"java"},flutter:{label:"Flutter",icon:"icon-tech-flutter",syntaxHighlighterKey:"dart"}};export const getLanguageInfo=langKey=>{const key=langKey.toLowerCase();if(languages[key]){return languages[key]}return{label:langKey,icon:"icon-tech-web",syntaxHighlighterKey:langKey}};export default languages;
|
|
2
2
|
//# sourceMappingURL=languages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/CodeSnippet/languages.tsx"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\nexport interface LanguageInfo {\n label: string;\n icon: IconName;\n syntaxHighlighterKey?: string;\n}\n\nexport type LanguageMap = Record<string, LanguageInfo>;\n\nconst languages: LanguageMap = {\n javascript: {\n label: \"JavaScript\",\n icon: \"icon-tech-javascript\",\n syntaxHighlighterKey: \"javascript\",\n },\n typescript: {\n label: \"TypeScript\",\n icon: \"icon-tech-typescript\",\n syntaxHighlighterKey: \"typescript\",\n },\n
|
|
1
|
+
{"version":3,"sources":["../../../src/core/CodeSnippet/languages.tsx"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\nexport interface LanguageInfo {\n label: string;\n icon: IconName;\n syntaxHighlighterKey?: string;\n}\n\nexport type LanguageMap = Record<string, LanguageInfo>;\n\nconst languages: LanguageMap = {\n javascript: {\n label: \"JavaScript\",\n icon: \"icon-tech-javascript\",\n syntaxHighlighterKey: \"javascript\",\n },\n typescript: {\n label: \"TypeScript\",\n icon: \"icon-tech-typescript\",\n syntaxHighlighterKey: \"typescript\",\n },\n java: {\n label: \"Java\",\n icon: \"icon-tech-java\",\n syntaxHighlighterKey: \"java\",\n },\n kotlin: {\n label: \"Kotlin\",\n icon: \"icon-tech-kotlin\",\n syntaxHighlighterKey: \"kotlin\",\n },\n python: {\n label: \"Python\",\n icon: \"icon-tech-python\",\n syntaxHighlighterKey: \"python\",\n },\n csharp: {\n label: \"C#\",\n icon: \"icon-tech-csharp\",\n syntaxHighlighterKey: \"csharp\",\n },\n go: {\n label: \"Go\",\n icon: \"icon-tech-go\",\n syntaxHighlighterKey: \"go\",\n },\n ruby: {\n label: \"Ruby\",\n icon: \"icon-tech-ruby\",\n syntaxHighlighterKey: \"ruby\",\n },\n php: {\n label: \"PHP\",\n icon: \"icon-tech-php\",\n syntaxHighlighterKey: \"php\",\n },\n nodejs: {\n label: \"Node.js\",\n icon: \"icon-tech-nodejs\",\n syntaxHighlighterKey: \"javascript\",\n },\n react: {\n label: \"React\",\n icon: \"icon-tech-react\",\n syntaxHighlighterKey: \"javascript\",\n },\n html: {\n label: \"HTML\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"xml\",\n },\n shell: {\n label: \"Shell\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"bash\",\n },\n json: {\n label: \"JSON\",\n icon: \"icon-tech-json\",\n syntaxHighlighterKey: \"json\",\n },\n xml: {\n label: \"XML\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"xml\",\n },\n sql: {\n label: \"SQL\",\n icon: \"icon-tech-postgres\",\n syntaxHighlighterKey: \"sql\",\n },\n swift: {\n label: \"Swift\",\n icon: \"icon-tech-swift\",\n syntaxHighlighterKey: \"swift\",\n },\n // New entries from languageInfo.ts\n cpp: {\n label: \"C++\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"cpp\",\n },\n dart: {\n label: \"Dart\",\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: \"dart\",\n },\n objc: {\n label: \"Objective-C\",\n icon: \"icon-tech-objectivec\",\n syntaxHighlighterKey: \"objc\",\n },\n android: {\n label: \"Android\",\n icon: \"icon-tech-android-head\",\n syntaxHighlighterKey: \"java\",\n },\n flutter: {\n label: \"Flutter\",\n icon: \"icon-tech-flutter\",\n syntaxHighlighterKey: \"dart\",\n },\n};\n\n// Fallback function to handle languages not in the map\nexport const getLanguageInfo = (langKey: string): LanguageInfo => {\n const key = langKey.toLowerCase();\n\n if (languages[key]) {\n return languages[key];\n }\n\n // Fallback for unknown languages\n return {\n label: langKey,\n icon: \"icon-tech-web\",\n syntaxHighlighterKey: langKey,\n };\n};\n\nexport default languages;\n"],"names":["languages","javascript","label","icon","syntaxHighlighterKey","typescript","java","kotlin","python","csharp","go","ruby","php","nodejs","react","html","shell","json","xml","sql","swift","cpp","dart","objc","android","flutter","getLanguageInfo","langKey","key","toLowerCase"],"mappings":"AAUA,MAAMA,UAAyB,CAC7BC,WAAY,CACVC,MAAO,aACPC,KAAM,uBACNC,qBAAsB,YACxB,EACAC,WAAY,CACVH,MAAO,aACPC,KAAM,uBACNC,qBAAsB,YACxB,EACAE,KAAM,CACJJ,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAG,OAAQ,CACNL,MAAO,SACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAI,OAAQ,CACNN,MAAO,SACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAK,OAAQ,CACNP,MAAO,KACPC,KAAM,mBACNC,qBAAsB,QACxB,EACAM,GAAI,CACFR,MAAO,KACPC,KAAM,eACNC,qBAAsB,IACxB,EACAO,KAAM,CACJT,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAQ,IAAK,CACHV,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAS,OAAQ,CACNX,MAAO,UACPC,KAAM,mBACNC,qBAAsB,YACxB,EACAU,MAAO,CACLZ,MAAO,QACPC,KAAM,kBACNC,qBAAsB,YACxB,EACAW,KAAM,CACJb,MAAO,OACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAY,MAAO,CACLd,MAAO,QACPC,KAAM,gBACNC,qBAAsB,MACxB,EACAa,KAAM,CACJf,MAAO,OACPC,KAAM,iBACNC,qBAAsB,MACxB,EACAc,IAAK,CACHhB,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAe,IAAK,CACHjB,MAAO,MACPC,KAAM,qBACNC,qBAAsB,KACxB,EACAgB,MAAO,CACLlB,MAAO,QACPC,KAAM,kBACNC,qBAAsB,OACxB,EAEAiB,IAAK,CACHnB,MAAO,MACPC,KAAM,gBACNC,qBAAsB,KACxB,EACAkB,KAAM,CACJpB,MAAO,OACPC,KAAM,gBACNC,qBAAsB,MACxB,EACAmB,KAAM,CACJrB,MAAO,cACPC,KAAM,uBACNC,qBAAsB,MACxB,EACAoB,QAAS,CACPtB,MAAO,UACPC,KAAM,yBACNC,qBAAsB,MACxB,EACAqB,QAAS,CACPvB,MAAO,UACPC,KAAM,oBACNC,qBAAsB,MACxB,CACF,CAGA,QAAO,MAAMsB,gBAAkB,AAACC,UAC9B,MAAMC,IAAMD,QAAQE,WAAW,GAE/B,GAAI7B,SAAS,CAAC4B,IAAI,CAAE,CAClB,OAAO5B,SAAS,CAAC4B,IAAI,AACvB,CAGA,MAAO,CACL1B,MAAOyB,QACPxB,KAAM,gBACNC,qBAAsBuB,OACxB,CACF,CAAE,AAEF,gBAAe3B,SAAU"}
|
package/core/CodeSnippet.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useState,useEffect,Children,isValidElement,useRef,useCallback,useMemo}from"react";import Code from"./Code";import cn from"./utils/cn";import{getLanguageInfo}from"./CodeSnippet/languages";import Icon from"./Icon";import LanguageSelector from"./CodeSnippet/LanguageSelector";import ApiKeySelector from"./CodeSnippet/ApiKeySelector";import useCopyToClipboard from"./utils/useCopyToClipboard";import ShellCommandView from"./CodeSnippet/ShellCommandView";import CopyButton from"./CodeSnippet/CopyButton";import TooltipButton from"./CodeSnippet/TooltipButton";const CodeSnippet=({fixed=false,headerRow=false,title="Code",children,className,lang,onChange,apiKeys})=>{const{childrenArray,languages,sdkTypes,originalLangMap,isSingleShellCommand}=useMemo(()=>{const childrenArray=Children.toArray(children);const languages=[];const sdkTypes=new Set;const originalLangMap=new Map;const isSingleShellCommand=childrenArray.length===1&&isValidElement(childrenArray[0])&&isValidElement(childrenArray[0].props.children)&&childrenArray[0].props.children.props.className?.includes("language-shell");childrenArray.forEach(child=>{if(!isValidElement(child))return;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;if(!codeElement||!codeElement.props.className)return;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return;let langName=langClass.substring(9);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,isSingleShellCommand}},[children]);const showSDKSelector=sdkTypes.size>0;const hasOnlyJsonSnippet=useMemo(()=>{return languages.length===1&&languages[0]==="json"},[languages]);const[state,setState]=useState(()=>({activeSDKType:sdkTypes.size>0?sdkTypes.has("realtime")?"realtime":"rest":null,activeLanguage:null,selectedApiKey:apiKeys&&apiKeys.length>0?apiKeys[0]:"",ui:{isHovering:false}}));const{isCopied,copy}=useCopyToClipboard();const filteredLanguages=useMemo(()=>{if(!state.activeSDKType||!showSDKSelector){return languages}return languages.filter(lang=>lang.startsWith(`${state.activeSDKType}_`))},[state.activeSDKType,showSDKSelector,languages]);const initialActiveLanguage=useMemo(()=>{if(!lang){return filteredLanguages.length>0?filteredLanguages[0]:null}if(state.activeSDKType){const prefixedLang=`${state.activeSDKType}_${lang}`;if(languages.includes(prefixedLang)){return prefixedLang}}if(languages.includes(lang)){return lang}if(getLanguageInfo(lang).label!==lang){return lang}return filteredLanguages.length>0?filteredLanguages[0]:null},[lang,state.activeSDKType,languages,filteredLanguages]);useEffect(()=>{setState(prevState=>({...prevState,activeLanguage:initialActiveLanguage}))},[initialActiveLanguage]);const codeRef=useRef(null);const processedChildren=useMemo(()=>{if(!state.activeLanguage)return[];const targetLanguage=hasOnlyJsonSnippet?"json":state.activeLanguage;return childrenArray.filter(child=>{if(!isValidElement(child))return false;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;if(!codeElement||!codeElement.props.className)return false;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return false;const langName=langClass.substring(9);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 classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return child;const langName=langClass.substring(9);const cleanLang=hasOnlyJsonSnippet?"json":originalLangMap.get(langName)||langName;const langInfo=getLanguageInfo(cleanLang);if(typeof codeContent==="string"||typeof codeContent==="number"||typeof codeContent==="boolean"){return React.createElement(Code,{key:langName,language:langInfo.syntaxHighlighterKey||cleanLang,snippet:String(codeContent),additionalCSS:"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-24 py-16",showLines:true})}return child})},[state.activeLanguage,childrenArray,originalLangMap,hasOnlyJsonSnippet]);const hasSnippetForActiveLanguage=useMemo(()=>{if(!state.activeLanguage)return false;if(hasOnlyJsonSnippet)return true;return childrenArray.some(child=>{if(!isValidElement(child))return false;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;if(!codeElement||!codeElement.props.className)return false;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return false;const langName=langClass.substring(9);return langName===state.activeLanguage})},[state.activeLanguage,childrenArray,hasOnlyJsonSnippet]);const getCodeText=useCallback(()=>{if(!state.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===state.activeLanguage){return codeElement.textContent||""}}return null},[state.activeLanguage,hasSnippetForActiveLanguage,hasOnlyJsonSnippet]);useEffect(()=>{if(apiKeys&&apiKeys.length>0&&!apiKeys.includes(state.selectedApiKey)){setState(prev=>({...prev,selectedApiKey:apiKeys[0]}))}},[apiKeys,state.selectedApiKey]);const handleSDKTypeChange=useCallback(type=>{const nextLang=languages.find(l=>l.startsWith(`${type}_`))??null;setState(prev=>({...prev,activeSDKType:type,activeLanguage:nextLang}))},[languages]);const handleLanguageChange=useCallback(language=>{setState(prev=>({...prev,activeLanguage:language}));if(onChange){const cleanLang=originalLangMap.get(language)||language;onChange(cleanLang)}},[onChange,originalLangMap]);const handleMouseEnter=useCallback(()=>{setState(prev=>({...prev,ui:{...prev.ui,isHovering:true}}))},[]);const handleMouseLeave=useCallback(()=>{setState(prev=>({...prev,ui:{...prev.ui,isHovering:false}}))},[]);const handleApiKeyChange=useCallback(apiKey=>{setState(prev=>({...prev,selectedApiKey:apiKey}))},[]);const getDisplayLanguageInfo=useCallback(lang=>{if(!lang)return null;const cleanLang=originalLangMap.get(lang)||lang;return getLanguageInfo(cleanLang)},[originalLangMap]);const activeLanguageInfo=useMemo(()=>getDisplayLanguageInfo(state.activeLanguage),[getDisplayLanguageInfo,state.activeLanguage]);const getLanguageDisplayName=useCallback(lang=>{const cleanLang=originalLangMap.get(lang)||lang;return getLanguageInfo(cleanLang).label},[originalLangMap]);const getLanguageIcon=useCallback(lang=>{const cleanLang=originalLangMap.get(lang)||lang;return getLanguageInfo(cleanLang).icon},[originalLangMap]);const NoSnippetMessage=useMemo(()=>{if(!activeLanguageInfo)return()=>null;return()=>React.createElement("div",{className:"px-64 py-24 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-12 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."))},[activeLanguageInfo]);const showLanguageSelector=!fixed&&filteredLanguages.length>0;const showFullSelector=filteredLanguages.length>1;const renderContent=()=>{if(!state.activeLanguage){return null}if(hasSnippetForActiveLanguage){return processedChildren}if(activeLanguageInfo){return React.createElement(NoSnippetMessage,null)}return null};if(isSingleShellCommand){const shellChild=childrenArray[0];if(isValidElement(shellChild)&&isValidElement(shellChild.props.children)){const codeElement=shellChild.props.children;const codeContent=codeElement.props.children;return React.createElement(ShellCommandView,{content:String(codeContent),className:className})}}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-[54px]",className)},headerRow&&React.createElement("div",{className:"h-[38px] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-4 px-12 rounded-t-lg"},React.createElement("div",{className:"flex space-x-6"},React.createElement("div",{className:"w-[12px] h-[12px] rounded-full bg-orange-500"}),React.createElement("div",{className:"w-[12px] h-[12px] rounded-full bg-yellow-500"}),React.createElement("div",{className:"w-[12px] h-[12px] 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-[48px]"})),showSDKSelector&&React.createElement("div",{className:cn("p-8 border-b border-neutral-200 dark:border-neutral-1100 h-[56px]",headerRow?"":"rounded-t-lg")},React.createElement("div",{className:"flex gap-12 justify-start"},sdkTypes.has("realtime")&&React.createElement(TooltipButton,{tooltip:"Realtime SDK",active:state.activeSDKType==="realtime",onClick:()=>handleSDKTypeChange("realtime"),variant:"segmented",size:"sm",alwaysShowLabel:true},"Realtime"),sdkTypes.has("rest")&&React.createElement(TooltipButton,{tooltip:"REST SDK",active:state.activeSDKType==="rest",onClick:()=>handleSDKTypeChange("rest"),variant:"segmented",size:"sm",alwaysShowLabel:true},"REST"))),showLanguageSelector&&(showFullSelector?React.createElement(LanguageSelector,{languages:filteredLanguages,activeLanguage:state.activeLanguage,onLanguageChange:handleLanguageChange,getLanguageDisplayName:getLanguageDisplayName,getLanguageIcon:getLanguageIcon,activeLanguageInfo:activeLanguageInfo}):React.createElement("div",{className:cn("border-b border-neutral-200 dark:border-neutral-1100 h-[34px] flex items-center px-12",headerRow?"":"rounded-t-lg")},filteredLanguages.length>0&&React.createElement(React.Fragment,null,React.createElement(Icon,{name:getLanguageIcon(filteredLanguages[0]),size:"16px",additionalCSS:"mr-8"}),React.createElement("span",{className:"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500"},getLanguageDisplayName(filteredLanguages[0]))))),React.createElement("div",{ref:codeRef,className:"relative",onMouseEnter:handleMouseEnter,onMouseLeave:handleMouseLeave,onFocus:handleMouseEnter,onBlur:handleMouseLeave,tabIndex:0},renderContent(),state.ui.isHovering&&state.activeLanguage&&hasSnippetForActiveLanguage&&React.createElement(CopyButton,{onCopy:()=>{const text=getCodeText();if(text)copy(text)},isCopied:isCopied})),apiKeys&&React.createElement(ApiKeySelector,{apiKeys:apiKeys,selectedApiKey:state.selectedApiKey,onApiKeyChange:handleApiKeyChange}))};export default CodeSnippet;
|
|
1
|
+
import React,{useState,useEffect,Children,isValidElement,useRef,useCallback,useMemo}from"react";import Code from"./Code";import cn from"./utils/cn";import{getLanguageInfo}from"./CodeSnippet/languages";import Icon from"./Icon";import LanguageSelector from"./CodeSnippet/LanguageSelector";import ApiKeySelector from"./CodeSnippet/ApiKeySelector";import useCopyToClipboard from"./utils/useCopyToClipboard";import ShellCommandView from"./CodeSnippet/ShellCommandView";import CopyButton from"./CodeSnippet/CopyButton";import TooltipButton from"./CodeSnippet/TooltipButton";const CodeSnippet=({fixed=false,headerRow=false,title="Code",children,className,lang,onChange,apiKeys,sdk})=>{const{childrenArray,languages,sdkTypes,originalLangMap,isSingleShellCommand}=useMemo(()=>{const childrenArray=Children.toArray(children);const languages=[];const sdkTypes=new Set;const originalLangMap=new Map;const isSingleShellCommand=childrenArray.length===1&&isValidElement(childrenArray[0])&&isValidElement(childrenArray[0].props.children)&&childrenArray[0].props.children.props.className?.includes("language-shell");childrenArray.forEach(child=>{if(!isValidElement(child))return;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;if(!codeElement||!codeElement.props.className)return;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return;const langName=langClass.substring(9);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,isSingleShellCommand}},[children]);const showSDKSelector=sdkTypes.size>0;const hasOnlyJsonSnippet=useMemo(()=>{return languages.length===1&&languages[0]==="json"},[languages]);const initialSDKType=useMemo(()=>{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},[sdk,sdkTypes]);const[state,setState]=useState(()=>({activeSDKType:initialSDKType,activeLanguage:null,selectedApiKey:apiKeys&&apiKeys.length>0?apiKeys[0]:"",ui:{isHovering:false}}));const{isCopied,copy}=useCopyToClipboard();const filteredLanguages=useMemo(()=>{if(!state.activeSDKType||!showSDKSelector){return languages}return languages.filter(lang=>lang.startsWith(`${state.activeSDKType}_`))},[state.activeSDKType,showSDKSelector,languages]);const initialActiveLanguage=useMemo(()=>{if(!lang){return filteredLanguages.length>0?filteredLanguages[0]:null}if(state.activeSDKType){const prefixedLang=`${state.activeSDKType}_${lang}`;if(languages.includes(prefixedLang)){return prefixedLang}}if(languages.includes(lang)){return lang}if(getLanguageInfo(lang).label!==lang){return lang}return filteredLanguages.length>0?filteredLanguages[0]:null},[lang,state.activeSDKType,languages,filteredLanguages]);useEffect(()=>{setState(prevState=>({...prevState,activeLanguage:initialActiveLanguage}))},[initialActiveLanguage]);const codeRef=useRef(null);const processedChildren=useMemo(()=>{if(!state.activeLanguage)return[];const targetLanguage=hasOnlyJsonSnippet?"json":state.activeLanguage;return childrenArray.filter(child=>{if(!isValidElement(child))return false;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;if(!codeElement||!codeElement.props.className)return false;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return false;const langName=langClass.substring(9);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 classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return child;const langName=langClass.substring(9);const cleanLang=hasOnlyJsonSnippet?"json":originalLangMap.get(langName)||langName;const langInfo=getLanguageInfo(cleanLang);if(typeof codeContent==="string"||typeof codeContent==="number"||typeof codeContent==="boolean"){return React.createElement(Code,{key:langName,language:langInfo.syntaxHighlighterKey||cleanLang,snippet:String(codeContent),additionalCSS:"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-24 py-16",showLines:true})}return child})},[state.activeLanguage,childrenArray,originalLangMap,hasOnlyJsonSnippet]);const hasSnippetForActiveLanguage=useMemo(()=>{if(!state.activeLanguage)return false;if(hasOnlyJsonSnippet)return true;return childrenArray.some(child=>{if(!isValidElement(child))return false;const preElement=child;const codeElement=isValidElement(preElement.props.children)?preElement.props.children:null;if(!codeElement||!codeElement.props.className)return false;const classNames=codeElement.props.className.split(" ");const langClass=classNames.find(cls=>cls.startsWith("language-"));if(!langClass)return false;const langName=langClass.substring(9);return langName===state.activeLanguage})},[state.activeLanguage,childrenArray,hasOnlyJsonSnippet]);const getCodeText=useCallback(()=>{if(!state.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===state.activeLanguage){return codeElement.textContent||""}}return null},[state.activeLanguage,hasSnippetForActiveLanguage,hasOnlyJsonSnippet]);useEffect(()=>{if(apiKeys&&apiKeys.length>0&&!apiKeys.includes(state.selectedApiKey)){setState(prev=>({...prev,selectedApiKey:apiKeys[0]}))}},[apiKeys,state.selectedApiKey]);const handleSDKTypeChange=useCallback(type=>{const nextLang=languages.find(l=>l.startsWith(`${type}_`))??null;setState(prev=>({...prev,activeSDKType:type,activeLanguage:nextLang}))},[languages]);const handleLanguageChange=useCallback(language=>{setState(prev=>({...prev,activeLanguage:language}));if(onChange){const cleanLang=originalLangMap.get(language)||language;onChange(cleanLang,state.activeSDKType)}},[onChange,originalLangMap,state.activeSDKType]);const handleMouseEnter=useCallback(()=>{setState(prev=>({...prev,ui:{...prev.ui,isHovering:true}}))},[]);const handleMouseLeave=useCallback(()=>{setState(prev=>({...prev,ui:{...prev.ui,isHovering:false}}))},[]);const handleApiKeyChange=useCallback(apiKey=>{setState(prev=>({...prev,selectedApiKey:apiKey}))},[]);const getDisplayLanguageInfo=useCallback(lang=>{if(!lang)return null;const cleanLang=originalLangMap.get(lang)||lang;return getLanguageInfo(cleanLang)},[originalLangMap]);const activeLanguageInfo=useMemo(()=>getDisplayLanguageInfo(state.activeLanguage),[getDisplayLanguageInfo,state.activeLanguage]);const getLanguageDisplayName=useCallback(lang=>{const cleanLang=originalLangMap.get(lang)||lang;return getLanguageInfo(cleanLang).label},[originalLangMap]);const getLanguageIcon=useCallback(lang=>{const cleanLang=originalLangMap.get(lang)||lang;return getLanguageInfo(cleanLang).icon},[originalLangMap]);const NoSnippetMessage=useMemo(()=>{if(!activeLanguageInfo)return()=>null;return()=>React.createElement("div",{className:"px-64 py-24 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-12 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."))},[activeLanguageInfo]);const showLanguageSelector=!fixed&&filteredLanguages.length>0;const showFullSelector=filteredLanguages.length>1;const renderContent=()=>{if(!state.activeLanguage){return null}if(hasSnippetForActiveLanguage){return processedChildren}if(activeLanguageInfo){return React.createElement(NoSnippetMessage,null)}return null};if(isSingleShellCommand){const shellChild=childrenArray[0];if(isValidElement(shellChild)&&isValidElement(shellChild.props.children)){const codeElement=shellChild.props.children;const codeContent=codeElement.props.children;return React.createElement(ShellCommandView,{content:String(codeContent),className:className})}}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-[54px]",className)},headerRow&&React.createElement("div",{className:"h-[38px] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-4 px-12 rounded-t-lg"},React.createElement("div",{className:"flex space-x-6"},React.createElement("div",{className:"w-[12px] h-[12px] rounded-full bg-orange-500"}),React.createElement("div",{className:"w-[12px] h-[12px] rounded-full bg-yellow-500"}),React.createElement("div",{className:"w-[12px] h-[12px] 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-[48px]"})),showSDKSelector&&React.createElement("div",{className:cn("p-8 border-b border-neutral-200 dark:border-neutral-1100 h-[56px]",headerRow?"":"rounded-t-lg")},React.createElement("div",{className:"flex gap-12 justify-start"},sdkTypes.has("realtime")&&React.createElement(TooltipButton,{tooltip:"Realtime SDK",active:state.activeSDKType==="realtime",onClick:()=>handleSDKTypeChange("realtime"),variant:"segmented",size:"sm",alwaysShowLabel:true},"Realtime"),sdkTypes.has("rest")&&React.createElement(TooltipButton,{tooltip:"REST SDK",active:state.activeSDKType==="rest",onClick:()=>handleSDKTypeChange("rest"),variant:"segmented",size:"sm",alwaysShowLabel:true},"REST"))),showLanguageSelector&&(showFullSelector?React.createElement(LanguageSelector,{languages:filteredLanguages,activeLanguage:state.activeLanguage,onLanguageChange:handleLanguageChange,getLanguageDisplayName:getLanguageDisplayName,getLanguageIcon:getLanguageIcon,activeLanguageInfo:activeLanguageInfo}):React.createElement("div",{className:cn("border-b border-neutral-200 dark:border-neutral-1100 h-[34px] flex items-center px-12",headerRow?"":"rounded-t-lg")},filteredLanguages.length>0&&React.createElement(React.Fragment,null,React.createElement(Icon,{name:getLanguageIcon(filteredLanguages[0]),size:"16px",additionalCSS:"mr-8"}),React.createElement("span",{className:"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500"},getLanguageDisplayName(filteredLanguages[0]))))),React.createElement("div",{ref:codeRef,className:"relative",onMouseEnter:handleMouseEnter,onMouseLeave:handleMouseLeave,onFocus:handleMouseEnter,onBlur:handleMouseLeave,tabIndex:0},renderContent(),state.ui.isHovering&&state.activeLanguage&&hasSnippetForActiveLanguage&&React.createElement(CopyButton,{onCopy:()=>{const text=getCodeText();if(text)copy(text)},isCopied:isCopied})),apiKeys&&React.createElement(ApiKeySelector,{apiKeys:apiKeys,selectedApiKey:state.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 useEffect,\n Children,\n isValidElement,\n useRef,\n useCallback,\n useMemo,\n} from \"react\";\nimport Code from \"./Code\";\nimport cn from \"./utils/cn\";\nimport { getLanguageInfo } from \"./CodeSnippet/languages\";\nimport Icon from \"./Icon\";\nimport LanguageSelector from \"./CodeSnippet/LanguageSelector\";\nimport ApiKeySelector from \"./CodeSnippet/ApiKeySelector\";\nimport { IconName } from \"./Icon/types\";\nimport useCopyToClipboard from \"./utils/useCopyToClipboard\";\nimport ShellCommandView from \"./CodeSnippet/ShellCommandView\";\nimport CopyButton from \"./CodeSnippet/CopyButton\";\nimport TooltipButton from \"./CodeSnippet/TooltipButton\";\n\n// Define SDK type\ntype SDKType = \"realtime\" | \"rest\" | null;\n\n// Interface for component state management\ninterface CodeSnippetState {\n activeSDKType: SDKType;\n activeLanguage: string | null;\n selectedApiKey: string;\n ui: {\n isHovering: boolean;\n };\n}\n\nexport interface CodeSnippetProps {\n /**\n * If true, hides the language selector row completely\n */\n fixed?: boolean;\n /**\n * If true, renders a macOS-style window header with buttons and title\n */\n headerRow?: boolean;\n /**\n * Title to display in the header row (when headerRow is true)\n */\n title?: string;\n /**\n * Children elements with lang attribute\n */\n children: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Default language to display. If not found in available languages, first available is used.\n * If found in languages but no matching snippet exists, a message is displayed.\n */\n lang?: string;\n /**\n * Callback fired when the active language changes\n */\n onChange?: (language: string) => void;\n /**\n * List of API keys to display in a dropdown\n */\n apiKeys?: string[];\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}) => {\n // Extract languages and SDK types from children\n const {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSingleShellCommand,\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 // Check if we have a single shell command\n const isSingleShellCommand =\n childrenArray.length === 1 &&\n isValidElement(childrenArray[0]) &&\n isValidElement(childrenArray[0].props.children) &&\n childrenArray[0].props.children.props.className?.includes(\n \"language-shell\",\n );\n\n // Extract all available languages from children and identify SDK types\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 if (!codeElement || !codeElement.props.className) return;\n\n // Extract language from className (format: \"language-javascript\", \"language-typescript\", etc.)\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return;\n\n // Extract the language name from the class (remove \"language-\" prefix)\n let langName = langClass.substring(9);\n\n // Look for SDK prefixes in the language name itself (e.g., \"language-realtime_javascript\")\n if (langName.startsWith(\"realtime_\")) {\n const baseLanguage = langName.substring(9);\n sdkTypes.add(\"realtime\");\n // Store original language value for later use\n originalLangMap.set(langName, baseLanguage);\n } else if (langName.startsWith(\"rest_\")) {\n const baseLanguage = langName.substring(5);\n sdkTypes.add(\"rest\");\n // Store original language value for later use\n originalLangMap.set(langName, baseLanguage);\n } else {\n // Regular language without SDK prefix\n originalLangMap.set(langName, langName);\n }\n\n // Add to languages list if not already included\n if (!languages.includes(langName)) {\n languages.push(langName);\n }\n });\n\n return {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSingleShellCommand,\n };\n }, [children]);\n\n // Check if we need to show SDK type selector\n const showSDKSelector = sdkTypes.size > 0;\n\n // Check if there is only a JSON snippet\n const hasOnlyJsonSnippet = useMemo(() => {\n return languages.length === 1 && languages[0] === \"json\";\n }, [languages]);\n\n // Consolidated state management\n const [state, setState] = useState<CodeSnippetState>(() => ({\n activeSDKType:\n sdkTypes.size > 0\n ? sdkTypes.has(\"realtime\")\n ? \"realtime\"\n : \"rest\"\n : null,\n activeLanguage: null, // Will be set after filteredLanguages are calculated\n selectedApiKey: apiKeys && apiKeys.length > 0 ? apiKeys[0] : \"\",\n ui: {\n isHovering: false,\n },\n }));\n\n // Use the copyToClipboard hook\n const { isCopied, copy } = useCopyToClipboard();\n\n // Get languages filtered by active SDK type - optimized with primitive dependencies\n const filteredLanguages = useMemo(() => {\n if (!state.activeSDKType || !showSDKSelector) {\n return languages;\n }\n return languages.filter((lang) =>\n lang.startsWith(`${state.activeSDKType}_`),\n );\n }, [state.activeSDKType, showSDKSelector, languages]);\n\n // Determine the initial active language - simplified dependencies\n const initialActiveLanguage = useMemo((): string | null => {\n // If no lang prop specified, default to first available filtered language\n if (!lang) {\n return filteredLanguages.length > 0 ? filteredLanguages[0] : null;\n }\n\n // Try to find the language with SDK type prefix if applicable\n if (state.activeSDKType) {\n const prefixedLang = `${state.activeSDKType}_${lang}`;\n if (languages.includes(prefixedLang)) {\n return prefixedLang;\n }\n }\n\n // Try to find the language directly\n if (languages.includes(lang)) {\n return lang;\n }\n\n // Check if it's a known language but not available in snippets\n if (getLanguageInfo(lang).label !== lang) {\n return lang;\n }\n\n // Fallback to first available language\n return filteredLanguages.length > 0 ? filteredLanguages[0] : null;\n }, [lang, state.activeSDKType, languages, filteredLanguages]);\n\n // Initialize activeLanguage after filteredLanguages are calculated\n useEffect(() => {\n setState((prevState) => ({\n ...prevState,\n activeLanguage: initialActiveLanguage,\n }));\n }, [initialActiveLanguage]);\n\n const codeRef = useRef<HTMLDivElement>(null);\n\n // Filter and process children for the active language - optimized with specific dependencies\n const processedChildren = useMemo(() => {\n if (!state.activeLanguage) return [];\n\n // Special case for JSON-only snippets\n const targetLanguage = hasOnlyJsonSnippet ? \"json\" : state.activeLanguage;\n\n return childrenArray\n .filter((child) => {\n if (!isValidElement(child)) return false;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n\n if (!codeElement || !codeElement.props.className) return false;\n\n // Extract language from className\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return false;\n\n // Extract the language name from the class (remove \"language-\" prefix)\n const langName = langClass.substring(9);\n\n // In JSON-only mode, only show JSON\n // Otherwise, match exactly with active language\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\n if (!codeElement) return child;\n\n const codeContent = codeElement.props.children;\n\n // Extract language from className\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return child;\n\n // Extract the language name from the class (remove \"language-\" prefix)\n const langName = langClass.substring(9);\n\n const cleanLang = hasOnlyJsonSnippet\n ? \"json\"\n : originalLangMap.get(langName) || langName;\n const langInfo = getLanguageInfo(cleanLang);\n\n // If child content is a string or can be converted to a string\n if (\n typeof codeContent === \"string\" ||\n typeof codeContent === \"number\" ||\n typeof codeContent === \"boolean\"\n ) {\n return (\n <Code\n key={langName}\n language={langInfo.syntaxHighlighterKey || cleanLang}\n snippet={String(codeContent)}\n additionalCSS=\"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-24 py-16\"\n showLines\n />\n );\n }\n\n // Otherwise, return the original content\n return child;\n });\n }, [\n state.activeLanguage,\n childrenArray,\n originalLangMap,\n hasOnlyJsonSnippet,\n ]);\n\n // Check if there's a snippet available for the active language\n const hasSnippetForActiveLanguage = useMemo(() => {\n if (!state.activeLanguage) return false;\n\n // If we have only JSON snippet, consider it available for any language\n if (hasOnlyJsonSnippet) return true;\n\n return childrenArray.some((child) => {\n if (!isValidElement(child)) return false;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n\n if (!codeElement || !codeElement.props.className) return false;\n\n // Extract language from className\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return false;\n\n // Extract the language name from the class (remove \"language-\" prefix)\n const langName = langClass.substring(9);\n\n // Match exactly with active language\n return langName === state.activeLanguage;\n });\n }, [state.activeLanguage, childrenArray, hasOnlyJsonSnippet]);\n\n // Function to get the current code text content\n const getCodeText = useCallback((): string | null => {\n if (\n !state.activeLanguage ||\n !hasSnippetForActiveLanguage ||\n !codeRef.current\n )\n return null;\n\n // Get the text content from the matching code element\n const allPreElements = codeRef.current.querySelectorAll(\"pre\");\n\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 // Extract the language name from the class (remove \"language-\" prefix)\n const langName = langClass.substring(9);\n\n // In JSON-only mode, look for JSON, otherwise match active language\n if (\n (hasOnlyJsonSnippet && langName === \"json\") ||\n (!hasOnlyJsonSnippet && langName === state.activeLanguage)\n ) {\n return codeElement.textContent || \"\";\n }\n }\n\n return null;\n }, [state.activeLanguage, hasSnippetForActiveLanguage, hasOnlyJsonSnippet]);\n\n // Update selected API key if apiKeys changes\n useEffect(() => {\n if (\n apiKeys &&\n apiKeys.length > 0 &&\n !apiKeys.includes(state.selectedApiKey)\n ) {\n setState((prev) => ({\n ...prev,\n selectedApiKey: apiKeys[0],\n }));\n }\n }, [apiKeys, state.selectedApiKey]);\n\n // Event handlers - memoized with empty dependencies as they only use setState\n const handleSDKTypeChange = useCallback(\n (type: SDKType) => {\n // pick the first language that matches the new SDK prefix\n const nextLang = languages.find((l) => l.startsWith(`${type}_`)) ?? null;\n\n setState((prev) => ({\n ...prev,\n activeSDKType: type,\n activeLanguage: nextLang,\n }));\n\n // Don't call onChange when only the SDK type changes\n // The initialActiveLanguage useEffect will handle calling onChange\n // if needed when the active language changes as a result\n },\n [languages],\n );\n\n const handleLanguageChange = useCallback(\n (language: string) => {\n setState((prev) => ({\n ...prev,\n activeLanguage: language,\n }));\n\n // Always call onChange for explicit user changes\n // But pass the clean language name without SDK prefix\n if (onChange) {\n const cleanLang = originalLangMap.get(language) || language;\n onChange(cleanLang);\n }\n },\n [onChange, originalLangMap],\n );\n\n const handleMouseEnter = useCallback(() => {\n setState((prev) => ({\n ...prev,\n ui: { ...prev.ui, isHovering: true },\n }));\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n setState((prev) => ({\n ...prev,\n ui: { ...prev.ui, isHovering: false },\n }));\n }, []);\n\n const handleApiKeyChange = useCallback((apiKey: string) => {\n setState((prev) => ({\n ...prev,\n selectedApiKey: apiKey,\n }));\n }, []);\n\n // Get language info for the active language - optimized to only depend on map and activeLanguage\n const getDisplayLanguageInfo = useCallback(\n (lang: string | null) => {\n if (!lang) return null;\n const cleanLang = originalLangMap.get(lang) || lang;\n return getLanguageInfo(cleanLang);\n },\n [originalLangMap],\n );\n\n const activeLanguageInfo = useMemo(\n () => getDisplayLanguageInfo(state.activeLanguage),\n [getDisplayLanguageInfo, state.activeLanguage],\n );\n\n // Memoize language related function to avoid recreation on every render\n const getLanguageDisplayName = useCallback(\n (lang: string) => {\n const cleanLang = originalLangMap.get(lang) || lang;\n return getLanguageInfo(cleanLang).label;\n },\n [originalLangMap],\n );\n\n // Memoize icon function to avoid recreation on every render\n const getLanguageIcon = useCallback(\n (lang: string): IconName => {\n const cleanLang = originalLangMap.get(lang) || lang;\n return getLanguageInfo(cleanLang).icon;\n },\n [originalLangMap],\n );\n\n // Optimize no-snippet message by memoizing it\n const NoSnippetMessage = useMemo(() => {\n if (!activeLanguageInfo) return () => null;\n\n return () => (\n <div className=\"px-64 py-24 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-12 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 }, [activeLanguageInfo]);\n\n // Determine if we should show the language selector\n const showLanguageSelector = !fixed && filteredLanguages.length > 0;\n\n // Determine if we should show the full selector or simplified view\n const showFullSelector = filteredLanguages.length > 1;\n\n // Simplified content render logic\n const renderContent = () => {\n // No active language case\n if (!state.activeLanguage) {\n return null;\n }\n\n // Has snippet for active language (including JSON-only case)\n if (hasSnippetForActiveLanguage) {\n return processedChildren;\n }\n\n // No snippet but language info available\n if (activeLanguageInfo) {\n return <NoSnippetMessage />;\n }\n\n return null;\n };\n\n // Render special case for shell commands\n if (isSingleShellCommand) {\n const shellChild = childrenArray[0];\n if (\n isValidElement(shellChild) &&\n isValidElement(shellChild.props.children)\n ) {\n const codeElement = shellChild.props.children;\n const codeContent = codeElement.props.children;\n return (\n <ShellCommandView content={String(codeContent)} className={className} />\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-[54px]\",\n className,\n )}\n >\n {headerRow && (\n <div className=\"h-[38px] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-4 px-12 rounded-t-lg\">\n {/* macOS window buttons */}\n <div className=\"flex space-x-6\">\n <div className=\"w-[12px] h-[12px] rounded-full bg-orange-500\"></div>\n <div className=\"w-[12px] h-[12px] rounded-full bg-yellow-500\"></div>\n <div className=\"w-[12px] h-[12px] rounded-full bg-green-500\"></div>\n </div>\n\n {/* Title */}\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-[48px]\"></div>\n </div>\n )}\n\n {/* SDK Type Selector Row */}\n {showSDKSelector && (\n <div\n className={cn(\n \"p-8 border-b border-neutral-200 dark:border-neutral-1100 h-[56px]\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n <div className=\"flex gap-12 justify-start\">\n {sdkTypes.has(\"realtime\") && (\n <TooltipButton\n tooltip=\"Realtime SDK\"\n active={state.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={state.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 {/* Language Selector Row */}\n {showLanguageSelector &&\n (showFullSelector ? (\n <LanguageSelector\n languages={filteredLanguages}\n activeLanguage={state.activeLanguage}\n onLanguageChange={handleLanguageChange}\n getLanguageDisplayName={getLanguageDisplayName}\n getLanguageIcon={getLanguageIcon}\n activeLanguageInfo={activeLanguageInfo}\n />\n ) : (\n <div\n className={cn(\n \"border-b border-neutral-200 dark:border-neutral-1100 h-[34px] flex items-center px-12\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n {filteredLanguages.length > 0 && (\n <>\n <Icon\n name={getLanguageIcon(filteredLanguages[0])}\n size=\"16px\"\n additionalCSS=\"mr-8\"\n />\n <span className=\"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500\">\n {getLanguageDisplayName(filteredLanguages[0])}\n </span>\n </>\n )}\n </div>\n ))}\n\n <div\n ref={codeRef}\n className=\"relative\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleMouseEnter}\n onBlur={handleMouseLeave}\n tabIndex={0}\n >\n {renderContent()}\n\n {/* Copy button - simplified conditional */}\n {state.ui.isHovering &&\n state.activeLanguage &&\n hasSnippetForActiveLanguage && (\n <CopyButton\n onCopy={() => {\n const text = getCodeText();\n if (text) copy(text);\n }}\n isCopied={isCopied}\n />\n )}\n </div>\n\n {/* API Key Selector */}\n {apiKeys && (\n <ApiKeySelector\n apiKeys={apiKeys}\n selectedApiKey={state.selectedApiKey}\n onApiKeyChange={handleApiKeyChange}\n />\n )}\n </div>\n );\n};\n\nexport default CodeSnippet;\n"],"names":["React","useState","useEffect","Children","isValidElement","useRef","useCallback","useMemo","Code","cn","getLanguageInfo","Icon","LanguageSelector","ApiKeySelector","useCopyToClipboard","ShellCommandView","CopyButton","TooltipButton","CodeSnippet","fixed","headerRow","title","children","className","lang","onChange","apiKeys","childrenArray","languages","sdkTypes","originalLangMap","isSingleShellCommand","toArray","Set","Map","length","props","includes","forEach","child","preElement","codeElement","classNames","split","langClass","find","cls","startsWith","langName","substring","baseLanguage","add","set","push","showSDKSelector","size","hasOnlyJsonSnippet","state","setState","activeSDKType","has","activeLanguage","selectedApiKey","ui","isHovering","isCopied","copy","filteredLanguages","filter","initialActiveLanguage","prefixedLang","label","prevState","codeRef","processedChildren","targetLanguage","map","codeContent","cleanLang","get","langInfo","key","language","syntaxHighlighterKey","snippet","String","additionalCSS","showLines","hasSnippetForActiveLanguage","some","getCodeText","current","allPreElements","querySelectorAll","Array","from","querySelector","textContent","prev","handleSDKTypeChange","type","nextLang","l","handleLanguageChange","handleMouseEnter","handleMouseLeave","handleApiKeyChange","apiKey","getDisplayLanguageInfo","activeLanguageInfo","getLanguageDisplayName","getLanguageIcon","icon","NoSnippetMessage","div","name","color","p","showLanguageSelector","showFullSelector","renderContent","shellChild","content","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 useEffect,\n Children,\n isValidElement,\n useRef,\n useCallback,\n useMemo,\n} from \"react\";\nimport Code from \"./Code\";\nimport cn from \"./utils/cn\";\nimport { getLanguageInfo } from \"./CodeSnippet/languages\";\nimport Icon from \"./Icon\";\nimport LanguageSelector from \"./CodeSnippet/LanguageSelector\";\nimport ApiKeySelector from \"./CodeSnippet/ApiKeySelector\";\nimport { IconName } from \"./Icon/types\";\nimport useCopyToClipboard from \"./utils/useCopyToClipboard\";\nimport ShellCommandView from \"./CodeSnippet/ShellCommandView\";\nimport CopyButton from \"./CodeSnippet/CopyButton\";\nimport TooltipButton from \"./CodeSnippet/TooltipButton\";\n\n// Define SDK type\ntype SDKType = \"realtime\" | \"rest\" | null;\n\n// Interface for component state management\ninterface CodeSnippetState {\n activeSDKType: SDKType;\n activeLanguage: string | null;\n selectedApiKey: string;\n ui: {\n isHovering: boolean;\n };\n}\n\nexport interface CodeSnippetProps {\n /**\n * If true, hides the language selector row completely\n */\n fixed?: boolean;\n /**\n * If true, renders a macOS-style window header with buttons and title\n */\n headerRow?: boolean;\n /**\n * Title to display in the header row (when headerRow is true)\n */\n title?: string;\n /**\n * Children elements with lang attribute\n */\n children: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Default language to display. If not found in available languages, first available is used.\n * If found in languages but no matching snippet exists, a message is displayed.\n */\n lang?: string;\n /**\n * Callback fired when the active language changes\n */\n onChange?: (language: string, sdk?: SDKType) => void;\n /**\n * List of API keys to display in a dropdown\n */\n apiKeys?: string[];\n /**\n * Default SDK type to use for the code snippet\n */\n sdk?: SDKType;\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}) => {\n // Extract languages and SDK types from children\n const {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSingleShellCommand,\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 // Check if we have a single shell command\n const isSingleShellCommand =\n childrenArray.length === 1 &&\n isValidElement(childrenArray[0]) &&\n isValidElement(childrenArray[0].props.children) &&\n childrenArray[0].props.children.props.className?.includes(\n \"language-shell\",\n );\n\n // Extract all available languages from children and identify SDK types\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 if (!codeElement || !codeElement.props.className) return;\n\n // Extract language from className (format: \"language-javascript\", \"language-typescript\", etc.)\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return;\n\n // Extract the language name from the class (remove \"language-\" prefix)\n const langName = langClass.substring(9);\n\n // Look for SDK prefixes in the language name itself (e.g., \"language-realtime_javascript\")\n if (langName.startsWith(\"realtime_\")) {\n const baseLanguage = langName.substring(9);\n sdkTypes.add(\"realtime\");\n // Store original language value for later use\n originalLangMap.set(langName, baseLanguage);\n } else if (langName.startsWith(\"rest_\")) {\n const baseLanguage = langName.substring(5);\n sdkTypes.add(\"rest\");\n // Store original language value for later use\n originalLangMap.set(langName, baseLanguage);\n } else {\n // Regular language without SDK prefix\n originalLangMap.set(langName, langName);\n }\n\n // Add to languages list if not already included\n if (!languages.includes(langName)) {\n languages.push(langName);\n }\n });\n\n return {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSingleShellCommand,\n };\n }, [children]);\n\n // Check if we need to show SDK type selector\n const showSDKSelector = sdkTypes.size > 0;\n\n // Check if there is only a JSON snippet\n const hasOnlyJsonSnippet = useMemo(() => {\n return languages.length === 1 && languages[0] === \"json\";\n }, [languages]);\n\n const initialSDKType = useMemo(() => {\n if (sdkTypes.size === 0) {\n return null;\n }\n\n if (sdk && sdkTypes.has(sdk)) return sdk;\n\n if (sdkTypes.has(\"realtime\")) return \"realtime\";\n\n if (sdkTypes.has(\"rest\")) return \"rest\";\n\n return null;\n }, [sdk, sdkTypes]);\n\n // Consolidated state management\n const [state, setState] = useState<CodeSnippetState>(() => ({\n activeSDKType: initialSDKType,\n activeLanguage: null, // Will be set after filteredLanguages are calculated\n selectedApiKey: apiKeys && apiKeys.length > 0 ? apiKeys[0] : \"\",\n ui: {\n isHovering: false,\n },\n }));\n\n // Use the copyToClipboard hook\n const { isCopied, copy } = useCopyToClipboard();\n\n // Get languages filtered by active SDK type - optimized with primitive dependencies\n const filteredLanguages = useMemo(() => {\n if (!state.activeSDKType || !showSDKSelector) {\n return languages;\n }\n return languages.filter((lang) =>\n lang.startsWith(`${state.activeSDKType}_`),\n );\n }, [state.activeSDKType, showSDKSelector, languages]);\n\n // Determine the initial active language - simplified dependencies\n const initialActiveLanguage = useMemo((): string | null => {\n // If no lang prop specified, default to first available filtered language\n if (!lang) {\n return filteredLanguages.length > 0 ? filteredLanguages[0] : null;\n }\n\n // Try to find the language with SDK type prefix if applicable\n if (state.activeSDKType) {\n const prefixedLang = `${state.activeSDKType}_${lang}`;\n if (languages.includes(prefixedLang)) {\n return prefixedLang;\n }\n }\n\n // Try to find the language directly\n if (languages.includes(lang)) {\n return lang;\n }\n\n // Check if it's a known language but not available in snippets\n if (getLanguageInfo(lang).label !== lang) {\n return lang;\n }\n\n // Fallback to first available language\n return filteredLanguages.length > 0 ? filteredLanguages[0] : null;\n }, [lang, state.activeSDKType, languages, filteredLanguages]);\n\n // Initialize activeLanguage after filteredLanguages are calculated\n useEffect(() => {\n setState((prevState) => ({\n ...prevState,\n activeLanguage: initialActiveLanguage,\n }));\n }, [initialActiveLanguage]);\n\n const codeRef = useRef<HTMLDivElement>(null);\n\n // Filter and process children for the active language - optimized with specific dependencies\n const processedChildren = useMemo(() => {\n if (!state.activeLanguage) return [];\n\n // Special case for JSON-only snippets\n const targetLanguage = hasOnlyJsonSnippet ? \"json\" : state.activeLanguage;\n\n return childrenArray\n .filter((child) => {\n if (!isValidElement(child)) return false;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n\n if (!codeElement || !codeElement.props.className) return false;\n\n // Extract language from className\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return false;\n\n // Extract the language name from the class (remove \"language-\" prefix)\n const langName = langClass.substring(9);\n\n // In JSON-only mode, only show JSON\n // Otherwise, match exactly with active language\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\n if (!codeElement) return child;\n\n const codeContent = codeElement.props.children;\n\n // Extract language from className\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return child;\n\n // Extract the language name from the class (remove \"language-\" prefix)\n const langName = langClass.substring(9);\n\n const cleanLang = hasOnlyJsonSnippet\n ? \"json\"\n : originalLangMap.get(langName) || langName;\n const langInfo = getLanguageInfo(cleanLang);\n\n // If child content is a string or can be converted to a string\n if (\n typeof codeContent === \"string\" ||\n typeof codeContent === \"number\" ||\n typeof codeContent === \"boolean\"\n ) {\n return (\n <Code\n key={langName}\n language={langInfo.syntaxHighlighterKey || cleanLang}\n snippet={String(codeContent)}\n additionalCSS=\"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-24 py-16\"\n showLines\n />\n );\n }\n\n // Otherwise, return the original content\n return child;\n });\n }, [\n state.activeLanguage,\n childrenArray,\n originalLangMap,\n hasOnlyJsonSnippet,\n ]);\n\n // Check if there's a snippet available for the active language\n const hasSnippetForActiveLanguage = useMemo(() => {\n if (!state.activeLanguage) return false;\n\n // If we have only JSON snippet, consider it available for any language\n if (hasOnlyJsonSnippet) return true;\n\n return childrenArray.some((child) => {\n if (!isValidElement(child)) return false;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n\n if (!codeElement || !codeElement.props.className) return false;\n\n // Extract language from className\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return false;\n\n // Extract the language name from the class (remove \"language-\" prefix)\n const langName = langClass.substring(9);\n\n // Match exactly with active language\n return langName === state.activeLanguage;\n });\n }, [state.activeLanguage, childrenArray, hasOnlyJsonSnippet]);\n\n // Function to get the current code text content\n const getCodeText = useCallback((): string | null => {\n if (\n !state.activeLanguage ||\n !hasSnippetForActiveLanguage ||\n !codeRef.current\n )\n return null;\n\n // Get the text content from the matching code element\n const allPreElements = codeRef.current.querySelectorAll(\"pre\");\n\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 // Extract the language name from the class (remove \"language-\" prefix)\n const langName = langClass.substring(9);\n\n // In JSON-only mode, look for JSON, otherwise match active language\n if (\n (hasOnlyJsonSnippet && langName === \"json\") ||\n (!hasOnlyJsonSnippet && langName === state.activeLanguage)\n ) {\n return codeElement.textContent || \"\";\n }\n }\n\n return null;\n }, [state.activeLanguage, hasSnippetForActiveLanguage, hasOnlyJsonSnippet]);\n\n // Update selected API key if apiKeys changes\n useEffect(() => {\n if (\n apiKeys &&\n apiKeys.length > 0 &&\n !apiKeys.includes(state.selectedApiKey)\n ) {\n setState((prev) => ({\n ...prev,\n selectedApiKey: apiKeys[0],\n }));\n }\n }, [apiKeys, state.selectedApiKey]);\n\n // Event handlers - memoized with empty dependencies as they only use setState\n const handleSDKTypeChange = useCallback(\n (type: SDKType) => {\n // pick the first language that matches the new SDK prefix\n const nextLang = languages.find((l) => l.startsWith(`${type}_`)) ?? null;\n\n setState((prev) => ({\n ...prev,\n activeSDKType: type,\n activeLanguage: nextLang,\n }));\n\n // Don't call onChange when only the SDK type changes\n // The initialActiveLanguage useEffect will handle calling onChange\n // if needed when the active language changes as a result\n },\n [languages],\n );\n\n const handleLanguageChange = useCallback(\n (language: string) => {\n setState((prev) => ({\n ...prev,\n activeLanguage: language,\n }));\n\n // Always call onChange for explicit user changes\n // But pass the clean language name without SDK prefix\n if (onChange) {\n const cleanLang = originalLangMap.get(language) || language;\n onChange(cleanLang, state.activeSDKType);\n }\n },\n [onChange, originalLangMap, state.activeSDKType],\n );\n\n const handleMouseEnter = useCallback(() => {\n setState((prev) => ({\n ...prev,\n ui: { ...prev.ui, isHovering: true },\n }));\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n setState((prev) => ({\n ...prev,\n ui: { ...prev.ui, isHovering: false },\n }));\n }, []);\n\n const handleApiKeyChange = useCallback((apiKey: string) => {\n setState((prev) => ({\n ...prev,\n selectedApiKey: apiKey,\n }));\n }, []);\n\n // Get language info for the active language - optimized to only depend on map and activeLanguage\n const getDisplayLanguageInfo = useCallback(\n (lang: string | null) => {\n if (!lang) return null;\n const cleanLang = originalLangMap.get(lang) || lang;\n return getLanguageInfo(cleanLang);\n },\n [originalLangMap],\n );\n\n const activeLanguageInfo = useMemo(\n () => getDisplayLanguageInfo(state.activeLanguage),\n [getDisplayLanguageInfo, state.activeLanguage],\n );\n\n // Memoize language related function to avoid recreation on every render\n const getLanguageDisplayName = useCallback(\n (lang: string) => {\n const cleanLang = originalLangMap.get(lang) || lang;\n return getLanguageInfo(cleanLang).label;\n },\n [originalLangMap],\n );\n\n // Memoize icon function to avoid recreation on every render\n const getLanguageIcon = useCallback(\n (lang: string): IconName => {\n const cleanLang = originalLangMap.get(lang) || lang;\n return getLanguageInfo(cleanLang).icon;\n },\n [originalLangMap],\n );\n\n // Optimize no-snippet message by memoizing it\n const NoSnippetMessage = useMemo(() => {\n if (!activeLanguageInfo) return () => null;\n\n return () => (\n <div className=\"px-64 py-24 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-12 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 }, [activeLanguageInfo]);\n\n // Determine if we should show the language selector\n const showLanguageSelector = !fixed && filteredLanguages.length > 0;\n\n // Determine if we should show the full selector or simplified view\n const showFullSelector = filteredLanguages.length > 1;\n\n // Simplified content render logic\n const renderContent = () => {\n // No active language case\n if (!state.activeLanguage) {\n return null;\n }\n\n // Has snippet for active language (including JSON-only case)\n if (hasSnippetForActiveLanguage) {\n return processedChildren;\n }\n\n // No snippet but language info available\n if (activeLanguageInfo) {\n return <NoSnippetMessage />;\n }\n\n return null;\n };\n\n // Render special case for shell commands\n if (isSingleShellCommand) {\n const shellChild = childrenArray[0];\n if (\n isValidElement(shellChild) &&\n isValidElement(shellChild.props.children)\n ) {\n const codeElement = shellChild.props.children;\n const codeContent = codeElement.props.children;\n return (\n <ShellCommandView content={String(codeContent)} className={className} />\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-[54px]\",\n className,\n )}\n >\n {headerRow && (\n <div className=\"h-[38px] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-4 px-12 rounded-t-lg\">\n {/* macOS window buttons */}\n <div className=\"flex space-x-6\">\n <div className=\"w-[12px] h-[12px] rounded-full bg-orange-500\"></div>\n <div className=\"w-[12px] h-[12px] rounded-full bg-yellow-500\"></div>\n <div className=\"w-[12px] h-[12px] rounded-full bg-green-500\"></div>\n </div>\n\n {/* Title */}\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-[48px]\"></div>\n </div>\n )}\n\n {/* SDK Type Selector Row */}\n {showSDKSelector && (\n <div\n className={cn(\n \"p-8 border-b border-neutral-200 dark:border-neutral-1100 h-[56px]\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n <div className=\"flex gap-12 justify-start\">\n {sdkTypes.has(\"realtime\") && (\n <TooltipButton\n tooltip=\"Realtime SDK\"\n active={state.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={state.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 {/* Language Selector Row */}\n {showLanguageSelector &&\n (showFullSelector ? (\n <LanguageSelector\n languages={filteredLanguages}\n activeLanguage={state.activeLanguage}\n onLanguageChange={handleLanguageChange}\n getLanguageDisplayName={getLanguageDisplayName}\n getLanguageIcon={getLanguageIcon}\n activeLanguageInfo={activeLanguageInfo}\n />\n ) : (\n <div\n className={cn(\n \"border-b border-neutral-200 dark:border-neutral-1100 h-[34px] flex items-center px-12\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n {filteredLanguages.length > 0 && (\n <>\n <Icon\n name={getLanguageIcon(filteredLanguages[0])}\n size=\"16px\"\n additionalCSS=\"mr-8\"\n />\n <span className=\"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500\">\n {getLanguageDisplayName(filteredLanguages[0])}\n </span>\n </>\n )}\n </div>\n ))}\n\n <div\n ref={codeRef}\n className=\"relative\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleMouseEnter}\n onBlur={handleMouseLeave}\n tabIndex={0}\n >\n {renderContent()}\n\n {/* Copy button - simplified conditional */}\n {state.ui.isHovering &&\n state.activeLanguage &&\n hasSnippetForActiveLanguage && (\n <CopyButton\n onCopy={() => {\n const text = getCodeText();\n if (text) copy(text);\n }}\n isCopied={isCopied}\n />\n )}\n </div>\n\n {/* API Key Selector */}\n {apiKeys && (\n <ApiKeySelector\n apiKeys={apiKeys}\n selectedApiKey={state.selectedApiKey}\n onApiKeyChange={handleApiKeyChange}\n />\n )}\n </div>\n );\n};\n\nexport default CodeSnippet;\n"],"names":["React","useState","useEffect","Children","isValidElement","useRef","useCallback","useMemo","Code","cn","getLanguageInfo","Icon","LanguageSelector","ApiKeySelector","useCopyToClipboard","ShellCommandView","CopyButton","TooltipButton","CodeSnippet","fixed","headerRow","title","children","className","lang","onChange","apiKeys","sdk","childrenArray","languages","sdkTypes","originalLangMap","isSingleShellCommand","toArray","Set","Map","length","props","includes","forEach","child","preElement","codeElement","classNames","split","langClass","find","cls","startsWith","langName","substring","baseLanguage","add","set","push","showSDKSelector","size","hasOnlyJsonSnippet","initialSDKType","has","state","setState","activeSDKType","activeLanguage","selectedApiKey","ui","isHovering","isCopied","copy","filteredLanguages","filter","initialActiveLanguage","prefixedLang","label","prevState","codeRef","processedChildren","targetLanguage","map","codeContent","cleanLang","get","langInfo","key","language","syntaxHighlighterKey","snippet","String","additionalCSS","showLines","hasSnippetForActiveLanguage","some","getCodeText","current","allPreElements","querySelectorAll","Array","from","querySelector","textContent","prev","handleSDKTypeChange","type","nextLang","l","handleLanguageChange","handleMouseEnter","handleMouseLeave","handleApiKeyChange","apiKey","getDisplayLanguageInfo","activeLanguageInfo","getLanguageDisplayName","getLanguageIcon","icon","NoSnippetMessage","div","name","color","p","showLanguageSelector","showFullSelector","renderContent","shellChild","content","tooltip","active","onClick","variant","alwaysShowLabel","onLanguageChange","span","ref","onMouseEnter","onMouseLeave","onFocus","onBlur","tabIndex","onCopy","text","onApiKeyChange"],"mappings":"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"}
|
package/core/Header.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useState,useEffect,useRef,useMemo}from"react";import Icon from"./Icon";import cn from"./utils/cn";import Logo from"./Logo";import{componentMaxHeight,HEADER_BOTTOM_MARGIN,HEADER_HEIGHT}from"./utils/heights";import{HeaderLinks}from"./Header/HeaderLinks";import throttle from"lodash.throttle";import{COLLAPSE_TRIGGER_DISTANCE}from"./Notice/component";const FLEXIBLE_DESKTOP_CLASSES="hidden md:flex flex-1 items-center h-full";const MAX_MOBILE_MENU_WIDTH="560px";const Header=({className,isNoticeVisible=false,searchBar,searchButton,logoHref,headerLinks,headerLinksClassName,nav,mobileNav,sessionState,themedScrollpoints=[],searchButtonVisibility="all",location})=>{const[showMenu,setShowMenu]=useState(false);const[fadingOut,setFadingOut]=useState(false);const[bannerVisible,setBannerVisible]=useState(isNoticeVisible);const menuRef=useRef(null);const[scrollpointClasses,setScrollpointClasses]=useState(themedScrollpoints.length>0?themedScrollpoints[0].className:"");const closeMenu=()=>{setFadingOut(true);setTimeout(()=>{setShowMenu(false);setFadingOut(false)},150)};useEffect(()=>{const handleScroll=()=>{setBannerVisible(window.scrollY<=COLLAPSE_TRIGGER_DISTANCE&&isNoticeVisible);for(const scrollpoint of themedScrollpoints){const element=document.getElementById(scrollpoint.id);if(element){const rect=element.getBoundingClientRect();if(rect.top<=HEADER_HEIGHT&&rect.bottom>=HEADER_HEIGHT){setScrollpointClasses(scrollpoint.className);return}}}};const throttledHandleScroll=throttle(handleScroll,150);handleScroll();window.addEventListener("scroll",throttledHandleScroll);return()=>window.removeEventListener("scroll",throttledHandleScroll)},[themedScrollpoints]);useEffect(()=>{const handleResize=()=>{if(window.innerWidth>=1040){setShowMenu(false)}};window.addEventListener("resize",handleResize);return()=>window.removeEventListener("resize",handleResize)},[]);useEffect(()=>{if(showMenu){document.body.classList.add("overflow-hidden")}else{document.body.classList.remove("overflow-hidden")}return()=>{document.body.classList.remove("overflow-hidden")}},[showMenu]);useEffect(()=>{if(location&&showMenu){closeMenu()}},[location]);const wrappedSearchButton=useMemo(()=>searchButton?React.createElement("div",{className:"text-neutral-1300 dark:text-neutral-000 flex items-center"},searchButton):null,[searchButton]);return React.createElement(React.Fragment,null,React.createElement("header",{role:"banner",className:cn("fixed left-0 top-0 w-full z-50 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 dark:border-neutral-1000 transition-colors px-24 md:px-64",scrollpointClasses,{"md:top-auto":bannerVisible}),style:{height:HEADER_HEIGHT}},React.createElement("div",{className:cn("flex items-center h-full",className)},React.createElement("nav",{className:"flex flex-1 h-full items-center"},["light","dark"].map(theme=>React.createElement(Logo,{key:theme,href:logoHref,theme:theme,additionalLinkAttrs:{className:cn("h-full focus-base rounded mr-32 w-[96px]",{"flex dark:hidden":theme==="light","hidden dark:flex":theme==="dark"})}})),React.createElement("div",{className:FLEXIBLE_DESKTOP_CLASSES},nav)),React.createElement("div",{className:"flex md:hidden flex-1 items-center justify-end gap-24 h-full"},searchButtonVisibility!=="desktop"?wrappedSearchButton:null,React.createElement("button",{className:"cursor-pointer focus-base rounded flex items-center p-0",onClick:()=>setShowMenu(!showMenu),"aria-expanded":showMenu,"aria-controls":"mobile-menu","aria-label":"Toggle menu"},React.createElement(Icon,{name:showMenu?"icon-gui-x-mark-outline":"icon-gui-bars-3-outline",additionalCSS:"text-neutral-1300 dark:text-neutral-000",size:"1.5rem"}))),searchBar?React.createElement("div",{className:cn(FLEXIBLE_DESKTOP_CLASSES,"justify-center")},searchBar):null,React.createElement(HeaderLinks,{className:cn(FLEXIBLE_DESKTOP_CLASSES,headerLinksClassName),headerLinks:headerLinks,sessionState:sessionState,searchButton:wrappedSearchButton,searchButtonVisibility:searchButtonVisibility}))),showMenu?React.createElement(React.Fragment,null,React.createElement("div",{className:cn("fixed inset-0 bg-neutral-1300 dark:bg-neutral-1300 z-40",{"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]":!fadingOut,"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]":fadingOut}),onClick:closeMenu,onKeyDown:e=>e.key==="Escape"&&closeMenu(),role:"presentation"}),React.createElement("div",{id:"mobile-menu",className:"md:hidden fixed flex flex-col top-[76px] overflow-y-hidden mx-12 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-50",style:{maxWidth:MAX_MOBILE_MENU_WIDTH,maxHeight:componentMaxHeight(HEADER_HEIGHT,HEADER_BOTTOM_MARGIN)},ref:menuRef,role:"navigation"},mobileNav,React.createElement(HeaderLinks,{headerLinks:headerLinks,sessionState:sessionState}))):null)};export default Header;
|
|
1
|
+
import React,{useState,useEffect,useRef,useMemo}from"react";import Icon from"./Icon";import cn from"./utils/cn";import Logo from"./Logo";import{componentMaxHeight,HEADER_BOTTOM_MARGIN,HEADER_HEIGHT}from"./utils/heights";import{HeaderLinks}from"./Header/HeaderLinks";import throttle from"lodash.throttle";import{COLLAPSE_TRIGGER_DISTANCE}from"./Notice/component";const FLEXIBLE_DESKTOP_CLASSES="hidden md:flex flex-1 items-center h-full";const MAX_MOBILE_MENU_WIDTH="560px";const Header=({className,isNoticeVisible=false,searchBar,searchButton,logoHref,headerLinks,headerLinksClassName,headerCenterClassName,nav,mobileNav,sessionState,themedScrollpoints=[],searchButtonVisibility="all",location})=>{const[showMenu,setShowMenu]=useState(false);const[fadingOut,setFadingOut]=useState(false);const[bannerVisible,setBannerVisible]=useState(isNoticeVisible);const menuRef=useRef(null);const[scrollpointClasses,setScrollpointClasses]=useState(themedScrollpoints.length>0?themedScrollpoints[0].className:"");const closeMenu=()=>{setFadingOut(true);setTimeout(()=>{setShowMenu(false);setFadingOut(false)},150)};useEffect(()=>{const handleScroll=()=>{setBannerVisible(window.scrollY<=COLLAPSE_TRIGGER_DISTANCE&&isNoticeVisible);for(const scrollpoint of themedScrollpoints){const element=document.getElementById(scrollpoint.id);if(element){const rect=element.getBoundingClientRect();if(rect.top<=HEADER_HEIGHT&&rect.bottom>=HEADER_HEIGHT){setScrollpointClasses(scrollpoint.className);return}}}};const throttledHandleScroll=throttle(handleScroll,150);handleScroll();window.addEventListener("scroll",throttledHandleScroll);return()=>window.removeEventListener("scroll",throttledHandleScroll)},[themedScrollpoints]);useEffect(()=>{const handleResize=()=>{if(window.innerWidth>=1040){setShowMenu(false)}};window.addEventListener("resize",handleResize);return()=>window.removeEventListener("resize",handleResize)},[]);useEffect(()=>{if(showMenu){document.body.classList.add("overflow-hidden")}else{document.body.classList.remove("overflow-hidden")}return()=>{document.body.classList.remove("overflow-hidden")}},[showMenu]);useEffect(()=>{if(location&&showMenu){closeMenu()}},[location]);const wrappedSearchButton=useMemo(()=>searchButton?React.createElement("div",{className:"text-neutral-1300 dark:text-neutral-000 flex items-center"},searchButton):null,[searchButton]);return React.createElement(React.Fragment,null,React.createElement("header",{role:"banner",className:cn("fixed left-0 top-0 w-full z-50 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 dark:border-neutral-1000 transition-colors px-24 md:px-64",scrollpointClasses,{"md:top-auto":bannerVisible}),style:{height:HEADER_HEIGHT}},React.createElement("div",{className:cn("flex items-center h-full",className)},React.createElement("nav",{className:"flex flex-1 h-full items-center"},["light","dark"].map(theme=>React.createElement(Logo,{key:theme,href:logoHref,theme:theme,additionalLinkAttrs:{className:cn("h-full focus-base rounded mr-32 w-[96px]",{"flex dark:hidden":theme==="light","hidden dark:flex":theme==="dark"})}})),React.createElement("div",{className:FLEXIBLE_DESKTOP_CLASSES},nav)),React.createElement("div",{className:"flex md:hidden flex-1 items-center justify-end gap-24 h-full"},searchButtonVisibility!=="desktop"?wrappedSearchButton:null,React.createElement("button",{className:"cursor-pointer focus-base rounded flex items-center p-0",onClick:()=>setShowMenu(!showMenu),"aria-expanded":showMenu,"aria-controls":"mobile-menu","aria-label":"Toggle menu"},React.createElement(Icon,{name:showMenu?"icon-gui-x-mark-outline":"icon-gui-bars-3-outline",additionalCSS:"text-neutral-1300 dark:text-neutral-000",size:"1.5rem"}))),searchBar?React.createElement("div",{className:cn(FLEXIBLE_DESKTOP_CLASSES,"justify-center",headerCenterClassName)},searchBar):null,React.createElement(HeaderLinks,{className:cn(FLEXIBLE_DESKTOP_CLASSES,headerLinksClassName),headerLinks:headerLinks,sessionState:sessionState,searchButton:wrappedSearchButton,searchButtonVisibility:searchButtonVisibility}))),showMenu?React.createElement(React.Fragment,null,React.createElement("div",{className:cn("fixed inset-0 bg-neutral-1300 dark:bg-neutral-1300 z-40",{"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]":!fadingOut,"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]":fadingOut}),onClick:closeMenu,onKeyDown:e=>e.key==="Escape"&&closeMenu(),role:"presentation"}),React.createElement("div",{id:"mobile-menu",className:"md:hidden fixed flex flex-col top-[76px] overflow-y-hidden mx-12 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-50",style:{maxWidth:MAX_MOBILE_MENU_WIDTH,maxHeight:componentMaxHeight(HEADER_HEIGHT,HEADER_BOTTOM_MARGIN)},ref:menuRef,role:"navigation"},mobileNav,React.createElement(HeaderLinks,{headerLinks:headerLinks,sessionState:sessionState}))):null)};export default Header;
|
|
2
2
|
//# sourceMappingURL=Header.js.map
|
package/core/Header.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Header.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, ReactNode, useMemo } from \"react\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\nimport Logo from \"./Logo\";\nimport {\n componentMaxHeight,\n HEADER_BOTTOM_MARGIN,\n HEADER_HEIGHT,\n} from \"./utils/heights\";\nimport { HeaderLinks } from \"./Header/HeaderLinks\";\nimport throttle from \"lodash.throttle\";\nimport { Theme } from \"./styles/colors/types\";\nimport { COLLAPSE_TRIGGER_DISTANCE } from \"./Notice/component\";\n\nexport type ThemedScrollpoint = {\n id: string;\n className: string;\n};\n\n/**\n * Represents the state of the user session in the header.\n */\nexport type HeaderSessionState = {\n /**\n * Indicates if the user is signed in.\n */\n signedIn: boolean;\n\n /**\n * Information required to log out the user.\n */\n logOut: {\n /**\n * Token used for logging out.\n */\n token: string;\n\n /**\n * URL to log out the user.\n */\n href: string;\n };\n\n /**\n * Name of the user's account.\n */\n accountName: string;\n};\n\n/**\n * Props for the Header component.\n */\nexport type HeaderProps = {\n /**\n * Optional classnames to add to the header\n */\n className?: string;\n /**\n * Indicates if the notice banner is visible.\n */\n isNoticeVisible?: boolean;\n /**\n * Optional search bar element.\n */\n searchBar?: ReactNode;\n\n /**\n * Optional search button element.\n */\n searchButton?: ReactNode;\n\n /**\n * URL for the logo link.\n */\n logoHref?: string;\n\n /**\n * Array of header links.\n */\n headerLinks?: {\n /**\n * URL for the link.\n */\n href: string;\n\n /**\n * Label for the link.\n */\n label: string;\n\n /**\n * Indicates if the link should open in a new tab.\n */\n external?: boolean;\n }[];\n\n /**\n * Optional classname for styling the header links container.\n */\n headerLinksClassName?: string;\n\n /**\n * Optional desktop navigation element.\n */\n nav?: ReactNode;\n\n /**\n * Optional mobile navigation element.\n */\n mobileNav?: ReactNode;\n\n /**\n * State of the user session.\n */\n sessionState?: HeaderSessionState;\n\n /**\n * Array of themed scrollpoints. The header will change its appearance based on the scrollpoint in view.\n */\n themedScrollpoints?: ThemedScrollpoint[];\n\n /**\n * Visibility setting for the search button.\n * - \"all\": Visible on all devices.\n * - \"desktop\": Visible only on desktop devices.\n * - \"mobile\": Visible only on mobile devices.\n */\n searchButtonVisibility?: \"all\" | \"desktop\" | \"mobile\";\n\n /**\n * Optional location object to detect location changes.\n */\n location?: Location;\n};\n\nconst FLEXIBLE_DESKTOP_CLASSES = \"hidden md:flex flex-1 items-center h-full\";\n\n/**\n * Maximum width before the menu expanded into full width\n */\nconst MAX_MOBILE_MENU_WIDTH = \"560px\";\n\nconst Header: React.FC<HeaderProps> = ({\n className,\n isNoticeVisible = false,\n searchBar,\n searchButton,\n logoHref,\n headerLinks,\n headerLinksClassName,\n nav,\n mobileNav,\n sessionState,\n themedScrollpoints = [],\n searchButtonVisibility = \"all\",\n location,\n}) => {\n const [showMenu, setShowMenu] = useState(false);\n const [fadingOut, setFadingOut] = useState(false);\n const [bannerVisible, setBannerVisible] = useState(isNoticeVisible);\n const menuRef = useRef<HTMLDivElement>(null);\n const [scrollpointClasses, setScrollpointClasses] = useState<string>(\n themedScrollpoints.length > 0 ? themedScrollpoints[0].className : \"\",\n );\n\n const closeMenu = () => {\n setFadingOut(true);\n\n setTimeout(() => {\n setShowMenu(false);\n setFadingOut(false);\n }, 150);\n };\n\n useEffect(() => {\n const handleScroll = () => {\n setBannerVisible(\n window.scrollY <= COLLAPSE_TRIGGER_DISTANCE && isNoticeVisible,\n );\n for (const scrollpoint of themedScrollpoints) {\n const element = document.getElementById(scrollpoint.id);\n if (element) {\n const rect = element.getBoundingClientRect();\n if (rect.top <= HEADER_HEIGHT && rect.bottom >= HEADER_HEIGHT) {\n setScrollpointClasses(scrollpoint.className);\n return;\n }\n }\n }\n };\n\n const throttledHandleScroll = throttle(handleScroll, 150);\n\n handleScroll();\n\n window.addEventListener(\"scroll\", throttledHandleScroll);\n return () => window.removeEventListener(\"scroll\", throttledHandleScroll);\n }, [themedScrollpoints]);\n\n useEffect(() => {\n const handleResize = () => {\n if (window.innerWidth >= 1040) {\n setShowMenu(false);\n }\n };\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (showMenu) {\n document.body.classList.add(\"overflow-hidden\");\n } else {\n document.body.classList.remove(\"overflow-hidden\");\n }\n\n // Cleanup on unmount\n return () => {\n document.body.classList.remove(\"overflow-hidden\");\n };\n }, [showMenu]);\n\n // Close menu when location changes\n useEffect(() => {\n if (location && showMenu) {\n closeMenu();\n }\n }, [location]);\n\n const wrappedSearchButton = useMemo(\n () =>\n searchButton ? (\n <div className=\"text-neutral-1300 dark:text-neutral-000 flex items-center\">\n {searchButton}\n </div>\n ) : null,\n [searchButton],\n );\n\n return (\n <>\n <header\n role=\"banner\"\n className={cn(\n \"fixed left-0 top-0 w-full z-50 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 dark:border-neutral-1000 transition-colors px-24 md:px-64\",\n scrollpointClasses,\n {\n \"md:top-auto\": bannerVisible,\n },\n )}\n style={{ height: HEADER_HEIGHT }}\n >\n <div className={cn(\"flex items-center h-full\", className)}>\n <nav className=\"flex flex-1 h-full items-center\">\n {([\"light\", \"dark\"] as Theme[]).map((theme) => (\n <Logo\n key={theme}\n href={logoHref}\n theme={theme}\n additionalLinkAttrs={{\n className: cn(\"h-full focus-base rounded mr-32 w-[96px]\", {\n \"flex dark:hidden\": theme === \"light\",\n \"hidden dark:flex\": theme === \"dark\",\n }),\n }}\n />\n ))}\n <div className={FLEXIBLE_DESKTOP_CLASSES}>{nav}</div>\n </nav>\n <div className=\"flex md:hidden flex-1 items-center justify-end gap-24 h-full\">\n {searchButtonVisibility !== \"desktop\" ? wrappedSearchButton : null}\n <button\n className=\"cursor-pointer focus-base rounded flex items-center p-0\"\n onClick={() => setShowMenu(!showMenu)}\n aria-expanded={showMenu}\n aria-controls=\"mobile-menu\"\n aria-label=\"Toggle menu\"\n >\n <Icon\n name={\n showMenu\n ? \"icon-gui-x-mark-outline\"\n : \"icon-gui-bars-3-outline\"\n }\n additionalCSS=\"text-neutral-1300 dark:text-neutral-000\"\n size=\"1.5rem\"\n />\n </button>\n </div>\n {searchBar ? (\n <div className={cn(FLEXIBLE_DESKTOP_CLASSES, \"justify-center\")}>\n {searchBar}\n </div>\n ) : null}\n <HeaderLinks\n className={cn(FLEXIBLE_DESKTOP_CLASSES, headerLinksClassName)}\n headerLinks={headerLinks}\n sessionState={sessionState}\n searchButton={wrappedSearchButton}\n searchButtonVisibility={searchButtonVisibility}\n />\n </div>\n </header>\n {showMenu ? (\n <>\n <div\n className={cn(\n \"fixed inset-0 bg-neutral-1300 dark:bg-neutral-1300 z-40\",\n {\n \"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]\":\n !fadingOut,\n \"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]\":\n fadingOut,\n },\n )}\n onClick={closeMenu}\n onKeyDown={(e) => e.key === \"Escape\" && closeMenu()}\n role=\"presentation\"\n />\n <div\n id=\"mobile-menu\"\n className=\"md:hidden fixed flex flex-col top-[76px] overflow-y-hidden mx-12 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-50\"\n style={{\n maxWidth: MAX_MOBILE_MENU_WIDTH,\n maxHeight: componentMaxHeight(\n HEADER_HEIGHT,\n HEADER_BOTTOM_MARGIN,\n ),\n }}\n ref={menuRef}\n role=\"navigation\"\n >\n {mobileNav}\n <HeaderLinks\n headerLinks={headerLinks}\n sessionState={sessionState}\n />\n </div>\n </>\n ) : null}\n </>\n );\n};\n\nexport default Header;\n"],"names":["React","useState","useEffect","useRef","useMemo","Icon","cn","Logo","componentMaxHeight","HEADER_BOTTOM_MARGIN","HEADER_HEIGHT","HeaderLinks","throttle","COLLAPSE_TRIGGER_DISTANCE","FLEXIBLE_DESKTOP_CLASSES","MAX_MOBILE_MENU_WIDTH","Header","className","isNoticeVisible","searchBar","searchButton","logoHref","headerLinks","headerLinksClassName","nav","mobileNav","sessionState","themedScrollpoints","searchButtonVisibility","location","showMenu","setShowMenu","fadingOut","setFadingOut","bannerVisible","setBannerVisible","menuRef","scrollpointClasses","setScrollpointClasses","length","closeMenu","setTimeout","handleScroll","window","scrollY","scrollpoint","element","document","getElementById","id","rect","getBoundingClientRect","top","bottom","throttledHandleScroll","addEventListener","removeEventListener","handleResize","innerWidth","body","classList","add","remove","wrappedSearchButton","div","header","role","style","height","map","theme","key","href","additionalLinkAttrs","button","onClick","aria-expanded","aria-controls","aria-label","name","additionalCSS","size","onKeyDown","e","maxWidth","maxHeight","ref"],"mappings":"AAAA,OAAOA,OAASC,QAAQ,CAAEC,SAAS,CAAEC,MAAM,CAAaC,OAAO,KAAQ,OAAQ,AAC/E,QAAOC,SAAU,QAAS,AAC1B,QAAOC,OAAQ,YAAa,AAC5B,QAAOC,SAAU,QAAS,AAC1B,QACEC,kBAAkB,CAClBC,oBAAoB,CACpBC,aAAa,KACR,iBAAkB,AACzB,QAASC,WAAW,KAAQ,sBAAuB,AACnD,QAAOC,aAAc,iBAAkB,AAEvC,QAASC,yBAAyB,KAAQ,oBAAqB,CA2H/D,MAAMC,yBAA2B,4CAKjC,MAAMC,sBAAwB,QAE9B,MAAMC,OAAgC,CAAC,CACrCC,SAAS,CACTC,gBAAkB,KAAK,CACvBC,SAAS,CACTC,YAAY,CACZC,QAAQ,CACRC,WAAW,CACXC,oBAAoB,CACpBC,GAAG,CACHC,SAAS,CACTC,YAAY,CACZC,mBAAqB,EAAE,CACvBC,uBAAyB,KAAK,CAC9BC,QAAQ,CACT,IACC,KAAM,CAACC,SAAUC,YAAY,CAAG9B,SAAS,OACzC,KAAM,CAAC+B,UAAWC,aAAa,CAAGhC,SAAS,OAC3C,KAAM,CAACiC,cAAeC,iBAAiB,CAAGlC,SAASiB,iBACnD,MAAMkB,QAAUjC,OAAuB,MACvC,KAAM,CAACkC,mBAAoBC,sBAAsB,CAAGrC,SAClD0B,mBAAmBY,MAAM,CAAG,EAAIZ,kBAAkB,CAAC,EAAE,CAACV,SAAS,CAAG,IAGpE,MAAMuB,UAAY,KAChBP,aAAa,MAEbQ,WAAW,KACTV,YAAY,OACZE,aAAa,MACf,EAAG,IACL,EAEA/B,UAAU,KACR,MAAMwC,aAAe,KACnBP,iBACEQ,OAAOC,OAAO,EAAI/B,2BAA6BK,iBAEjD,IAAK,MAAM2B,eAAelB,mBAAoB,CAC5C,MAAMmB,QAAUC,SAASC,cAAc,CAACH,YAAYI,EAAE,EACtD,GAAIH,QAAS,CACX,MAAMI,KAAOJ,QAAQK,qBAAqB,GAC1C,GAAID,KAAKE,GAAG,EAAI1C,eAAiBwC,KAAKG,MAAM,EAAI3C,cAAe,CAC7D4B,sBAAsBO,YAAY5B,SAAS,EAC3C,MACF,CACF,CACF,CACF,EAEA,MAAMqC,sBAAwB1C,SAAS8B,aAAc,KAErDA,eAEAC,OAAOY,gBAAgB,CAAC,SAAUD,uBAClC,MAAO,IAAMX,OAAOa,mBAAmB,CAAC,SAAUF,sBACpD,EAAG,CAAC3B,mBAAmB,EAEvBzB,UAAU,KACR,MAAMuD,aAAe,KACnB,GAAId,OAAOe,UAAU,EAAI,KAAM,CAC7B3B,YAAY,MACd,CACF,EACAY,OAAOY,gBAAgB,CAAC,SAAUE,cAClC,MAAO,IAAMd,OAAOa,mBAAmB,CAAC,SAAUC,aACpD,EAAG,EAAE,EAELvD,UAAU,KACR,GAAI4B,SAAU,CACZiB,SAASY,IAAI,CAACC,SAAS,CAACC,GAAG,CAAC,kBAC9B,KAAO,CACLd,SAASY,IAAI,CAACC,SAAS,CAACE,MAAM,CAAC,kBACjC,CAGA,MAAO,KACLf,SAASY,IAAI,CAACC,SAAS,CAACE,MAAM,CAAC,kBACjC,CACF,EAAG,CAAChC,SAAS,EAGb5B,UAAU,KACR,GAAI2B,UAAYC,SAAU,CACxBU,WACF,CACF,EAAG,CAACX,SAAS,EAEb,MAAMkC,oBAAsB3D,QAC1B,IACEgB,aACE,oBAAC4C,OAAI/C,UAAU,6DACZG,cAED,KACN,CAACA,aAAa,EAGhB,OACE,wCACE,oBAAC6C,UACCC,KAAK,SACLjD,UAAWX,GACT,2JACA+B,mBACA,CACE,cAAeH,aACjB,GAEFiC,MAAO,CAAEC,OAAQ1D,aAAc,GAE/B,oBAACsD,OAAI/C,UAAWX,GAAG,2BAA4BW,YAC7C,oBAACO,OAAIP,UAAU,mCACZ,AAAC,CAAC,QAAS,OAAO,CAAaoD,GAAG,CAAC,AAACC,OACnC,oBAAC/D,MACCgE,IAAKD,MACLE,KAAMnD,SACNiD,MAAOA,MACPG,oBAAqB,CACnBxD,UAAWX,GAAG,2CAA4C,CACxD,mBAAoBgE,QAAU,QAC9B,mBAAoBA,QAAU,MAChC,EACF,KAGJ,oBAACN,OAAI/C,UAAWH,0BAA2BU,MAE7C,oBAACwC,OAAI/C,UAAU,gEACZW,yBAA2B,UAAYmC,oBAAsB,KAC9D,oBAACW,UACCzD,UAAU,0DACV0D,QAAS,IAAM5C,YAAY,CAACD,UAC5B8C,gBAAe9C,SACf+C,gBAAc,cACdC,aAAW,eAEX,oBAACzE,MACC0E,KACEjD,SACI,0BACA,0BAENkD,cAAc,0CACdC,KAAK,aAIV9D,UACC,oBAAC6C,OAAI/C,UAAWX,GAAGQ,yBAA0B,mBAC1CK,WAED,KACJ,oBAACR,aACCM,UAAWX,GAAGQ,yBAA0BS,sBACxCD,YAAaA,YACbI,aAAcA,aACdN,aAAc2C,oBACdnC,uBAAwBA,2BAI7BE,SACC,wCACE,oBAACkC,OACC/C,UAAWX,GACT,0DACA,CACE,2DACE,CAAC0B,UACH,4DACEA,SACJ,GAEF2C,QAASnC,UACT0C,UAAW,AAACC,GAAMA,EAAEZ,GAAG,GAAK,UAAY/B,YACxC0B,KAAK,iBAEP,oBAACF,OACCf,GAAG,cACHhC,UAAU,wKACVkD,MAAO,CACLiB,SAAUrE,sBACVsE,UAAW7E,mBACTE,cACAD,qBAEJ,EACA6E,IAAKlD,QACL8B,KAAK,cAEJzC,UACD,oBAACd,aACCW,YAAaA,YACbI,aAAcA,iBAIlB,KAGV,CAEA,gBAAeV,MAAO"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/Header.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, ReactNode, useMemo } from \"react\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\nimport Logo from \"./Logo\";\nimport {\n componentMaxHeight,\n HEADER_BOTTOM_MARGIN,\n HEADER_HEIGHT,\n} from \"./utils/heights\";\nimport { HeaderLinks } from \"./Header/HeaderLinks\";\nimport throttle from \"lodash.throttle\";\nimport { Theme } from \"./styles/colors/types\";\nimport { COLLAPSE_TRIGGER_DISTANCE } from \"./Notice/component\";\n\nexport type ThemedScrollpoint = {\n id: string;\n className: string;\n};\n\n/**\n * Represents the state of the user session in the header.\n */\nexport type HeaderSessionState = {\n /**\n * Indicates if the user is signed in.\n */\n signedIn: boolean;\n\n /**\n * Information required to log out the user.\n */\n logOut: {\n /**\n * Token used for logging out.\n */\n token: string;\n\n /**\n * URL to log out the user.\n */\n href: string;\n };\n\n /**\n * Name of the user's account.\n */\n accountName: string;\n};\n\n/**\n * Props for the Header component.\n */\nexport type HeaderProps = {\n /**\n * Optional classnames to add to the header\n */\n className?: string;\n /**\n * Indicates if the notice banner is visible.\n */\n isNoticeVisible?: boolean;\n /**\n * Optional search bar element.\n */\n searchBar?: ReactNode;\n\n /**\n * Optional search button element.\n */\n searchButton?: ReactNode;\n\n /**\n * URL for the logo link.\n */\n logoHref?: string;\n\n /**\n * Array of header links.\n */\n headerLinks?: {\n /**\n * URL for the link.\n */\n href: string;\n\n /**\n * Label for the link.\n */\n label: string;\n\n /**\n * Indicates if the link should open in a new tab.\n */\n external?: boolean;\n }[];\n\n /**\n * Optional classname for styling the header links container.\n */\n headerLinksClassName?: string;\n\n /**\n * Optional classname for styling the header center container.\n */\n headerCenterClassName?: string;\n\n /**\n * Optional desktop navigation element.\n */\n nav?: ReactNode;\n\n /**\n * Optional mobile navigation element.\n */\n mobileNav?: ReactNode;\n\n /**\n * State of the user session.\n */\n sessionState?: HeaderSessionState;\n\n /**\n * Array of themed scrollpoints. The header will change its appearance based on the scrollpoint in view.\n */\n themedScrollpoints?: ThemedScrollpoint[];\n\n /**\n * Visibility setting for the search button.\n * - \"all\": Visible on all devices.\n * - \"desktop\": Visible only on desktop devices.\n * - \"mobile\": Visible only on mobile devices.\n */\n searchButtonVisibility?: \"all\" | \"desktop\" | \"mobile\";\n\n /**\n * Optional location object to detect location changes.\n */\n location?: Location;\n};\n\nconst FLEXIBLE_DESKTOP_CLASSES = \"hidden md:flex flex-1 items-center h-full\";\n\n/**\n * Maximum width before the menu expanded into full width\n */\nconst MAX_MOBILE_MENU_WIDTH = \"560px\";\n\nconst Header: React.FC<HeaderProps> = ({\n className,\n isNoticeVisible = false,\n searchBar,\n searchButton,\n logoHref,\n headerLinks,\n headerLinksClassName,\n headerCenterClassName,\n nav,\n mobileNav,\n sessionState,\n themedScrollpoints = [],\n searchButtonVisibility = \"all\",\n location,\n}) => {\n const [showMenu, setShowMenu] = useState(false);\n const [fadingOut, setFadingOut] = useState(false);\n const [bannerVisible, setBannerVisible] = useState(isNoticeVisible);\n const menuRef = useRef<HTMLDivElement>(null);\n const [scrollpointClasses, setScrollpointClasses] = useState<string>(\n themedScrollpoints.length > 0 ? themedScrollpoints[0].className : \"\",\n );\n\n const closeMenu = () => {\n setFadingOut(true);\n\n setTimeout(() => {\n setShowMenu(false);\n setFadingOut(false);\n }, 150);\n };\n\n useEffect(() => {\n const handleScroll = () => {\n setBannerVisible(\n window.scrollY <= COLLAPSE_TRIGGER_DISTANCE && isNoticeVisible,\n );\n for (const scrollpoint of themedScrollpoints) {\n const element = document.getElementById(scrollpoint.id);\n if (element) {\n const rect = element.getBoundingClientRect();\n if (rect.top <= HEADER_HEIGHT && rect.bottom >= HEADER_HEIGHT) {\n setScrollpointClasses(scrollpoint.className);\n return;\n }\n }\n }\n };\n\n const throttledHandleScroll = throttle(handleScroll, 150);\n\n handleScroll();\n\n window.addEventListener(\"scroll\", throttledHandleScroll);\n return () => window.removeEventListener(\"scroll\", throttledHandleScroll);\n }, [themedScrollpoints]);\n\n useEffect(() => {\n const handleResize = () => {\n if (window.innerWidth >= 1040) {\n setShowMenu(false);\n }\n };\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (showMenu) {\n document.body.classList.add(\"overflow-hidden\");\n } else {\n document.body.classList.remove(\"overflow-hidden\");\n }\n\n // Cleanup on unmount\n return () => {\n document.body.classList.remove(\"overflow-hidden\");\n };\n }, [showMenu]);\n\n // Close menu when location changes\n useEffect(() => {\n if (location && showMenu) {\n closeMenu();\n }\n }, [location]);\n\n const wrappedSearchButton = useMemo(\n () =>\n searchButton ? (\n <div className=\"text-neutral-1300 dark:text-neutral-000 flex items-center\">\n {searchButton}\n </div>\n ) : null,\n [searchButton],\n );\n\n return (\n <>\n <header\n role=\"banner\"\n className={cn(\n \"fixed left-0 top-0 w-full z-50 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 dark:border-neutral-1000 transition-colors px-24 md:px-64\",\n scrollpointClasses,\n {\n \"md:top-auto\": bannerVisible,\n },\n )}\n style={{ height: HEADER_HEIGHT }}\n >\n <div className={cn(\"flex items-center h-full\", className)}>\n <nav className=\"flex flex-1 h-full items-center\">\n {([\"light\", \"dark\"] as Theme[]).map((theme) => (\n <Logo\n key={theme}\n href={logoHref}\n theme={theme}\n additionalLinkAttrs={{\n className: cn(\"h-full focus-base rounded mr-32 w-[96px]\", {\n \"flex dark:hidden\": theme === \"light\",\n \"hidden dark:flex\": theme === \"dark\",\n }),\n }}\n />\n ))}\n <div className={FLEXIBLE_DESKTOP_CLASSES}>{nav}</div>\n </nav>\n <div className=\"flex md:hidden flex-1 items-center justify-end gap-24 h-full\">\n {searchButtonVisibility !== \"desktop\" ? wrappedSearchButton : null}\n <button\n className=\"cursor-pointer focus-base rounded flex items-center p-0\"\n onClick={() => setShowMenu(!showMenu)}\n aria-expanded={showMenu}\n aria-controls=\"mobile-menu\"\n aria-label=\"Toggle menu\"\n >\n <Icon\n name={\n showMenu\n ? \"icon-gui-x-mark-outline\"\n : \"icon-gui-bars-3-outline\"\n }\n additionalCSS=\"text-neutral-1300 dark:text-neutral-000\"\n size=\"1.5rem\"\n />\n </button>\n </div>\n {searchBar ? (\n <div\n className={cn(\n FLEXIBLE_DESKTOP_CLASSES,\n \"justify-center\",\n headerCenterClassName,\n )}\n >\n {searchBar}\n </div>\n ) : null}\n <HeaderLinks\n className={cn(FLEXIBLE_DESKTOP_CLASSES, headerLinksClassName)}\n headerLinks={headerLinks}\n sessionState={sessionState}\n searchButton={wrappedSearchButton}\n searchButtonVisibility={searchButtonVisibility}\n />\n </div>\n </header>\n {showMenu ? (\n <>\n <div\n className={cn(\n \"fixed inset-0 bg-neutral-1300 dark:bg-neutral-1300 z-40\",\n {\n \"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]\":\n !fadingOut,\n \"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]\":\n fadingOut,\n },\n )}\n onClick={closeMenu}\n onKeyDown={(e) => e.key === \"Escape\" && closeMenu()}\n role=\"presentation\"\n />\n <div\n id=\"mobile-menu\"\n className=\"md:hidden fixed flex flex-col top-[76px] overflow-y-hidden mx-12 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-50\"\n style={{\n maxWidth: MAX_MOBILE_MENU_WIDTH,\n maxHeight: componentMaxHeight(\n HEADER_HEIGHT,\n HEADER_BOTTOM_MARGIN,\n ),\n }}\n ref={menuRef}\n role=\"navigation\"\n >\n {mobileNav}\n <HeaderLinks\n headerLinks={headerLinks}\n sessionState={sessionState}\n />\n </div>\n </>\n ) : null}\n </>\n );\n};\n\nexport default Header;\n"],"names":["React","useState","useEffect","useRef","useMemo","Icon","cn","Logo","componentMaxHeight","HEADER_BOTTOM_MARGIN","HEADER_HEIGHT","HeaderLinks","throttle","COLLAPSE_TRIGGER_DISTANCE","FLEXIBLE_DESKTOP_CLASSES","MAX_MOBILE_MENU_WIDTH","Header","className","isNoticeVisible","searchBar","searchButton","logoHref","headerLinks","headerLinksClassName","headerCenterClassName","nav","mobileNav","sessionState","themedScrollpoints","searchButtonVisibility","location","showMenu","setShowMenu","fadingOut","setFadingOut","bannerVisible","setBannerVisible","menuRef","scrollpointClasses","setScrollpointClasses","length","closeMenu","setTimeout","handleScroll","window","scrollY","scrollpoint","element","document","getElementById","id","rect","getBoundingClientRect","top","bottom","throttledHandleScroll","addEventListener","removeEventListener","handleResize","innerWidth","body","classList","add","remove","wrappedSearchButton","div","header","role","style","height","map","theme","key","href","additionalLinkAttrs","button","onClick","aria-expanded","aria-controls","aria-label","name","additionalCSS","size","onKeyDown","e","maxWidth","maxHeight","ref"],"mappings":"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"}
|