@ably/ui 18.3.1 → 18.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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 type { LineHighlightType } from \"./Code\";\nimport cn from \"./utils/cn\";\nimport { parseLineHighlights } from \"./utils/syntax-highlighter\";\nimport Icon from \"./Icon\";\nimport {\n getLanguageInfo,\n stripSdkType,\n SDK_PREFIXES,\n SDKType,\n} from \"./CodeSnippet/languages\";\nimport LanguageSelector from \"./CodeSnippet/LanguageSelector\";\nimport ApiKeySelector from \"./CodeSnippet/ApiKeySelector\";\nimport PlainCodeView from \"./CodeSnippet/PlainCodeView\";\nimport CopyButton from \"./CodeSnippet/CopyButton\";\nimport SegmentedControl from \"./SegmentedControl\";\n\n// Re-export SDKType for consumers\nexport type { SDKType };\n\n// Define API key types\nexport type ApiKeysItem = {\n app: string;\n keys: { name: string; key: string }[];\n};\n\nexport type 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 | null;\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?: ApiKeysItem[];\n /**\n * Default SDK type to use for the code snippet\n */\n sdk?: SDKType;\n /**\n * Whether to show line numbers in code snippets\n */\n showCodeLines?: boolean;\n /**\n * Defines the order in which languages should be displayed.\n * Languages not in this array will be shown after those that are included.\n */\n languageOrdering?: string[];\n /**\n * Whether to wrap code content instead of scrolling\n */\n wrapCode?: boolean;\n};\n\n// Substitution function for API key placeholders\nconst substituteApiKey = (\n content: string,\n apiKey: string,\n mask = true,\n): string => {\n return content.replace(\n /\\{\\{API_KEY\\}\\}/g,\n mask ? `${apiKey.split(\":\")[0]}:*****` : apiKey,\n );\n};\n\n/**\n * CodeSnippet component that displays code with language switching capability\n */\nconst CodeSnippet: React.FC<CodeSnippetProps> = ({\n fixed = false,\n headerRow = false,\n title = \"Code\",\n children,\n className,\n lang,\n onChange,\n apiKeys,\n sdk,\n showCodeLines = true,\n languageOrdering,\n wrapCode = false,\n}) => {\n const codeRef = useRef<HTMLDivElement>(null);\n\n const [selectedApiKey, setSelectedApiKey] = useState<string>(\n () => apiKeys?.[0]?.keys?.[0]?.key ?? \"\",\n );\n const [prevApiKeys, setPrevApiKeys] = useState(apiKeys);\n if (prevApiKeys !== apiKeys) {\n setPrevApiKeys(apiKeys);\n if (!selectedApiKey && apiKeys && apiKeys.length > 0) {\n setSelectedApiKey(apiKeys[0].keys?.[0]?.key ?? \"\");\n }\n }\n\n useEffect(() => {\n const element = codeRef.current;\n if (!element) return;\n\n // Detects the key masking via substituteApiKey (i.e. \"abcde:*****\") and replaces it with the actual API key\n const unmaskRenderedApiKey = (content: string, apiKey: string): string => {\n return content.replace(/(['\"]?)([^:'\"]+):\\*{5}\\1/g, `$1${apiKey}$1`);\n };\n\n const handleCopy = (event: ClipboardEvent) => {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return;\n\n const selectedText = selection.toString();\n if (!selectedText) return;\n\n // Check if the selection is within our element\n const range = selection.getRangeAt(0);\n if (!element.contains(range.commonAncestorContainer)) return;\n\n const modifiedText = unmaskRenderedApiKey(selectedText, selectedApiKey);\n\n event.clipboardData?.setData(\"text/plain\", modifiedText);\n event.preventDefault();\n };\n\n document.addEventListener(\"copy\", handleCopy);\n\n return () => {\n document.removeEventListener(\"copy\", handleCopy);\n };\n }, [selectedApiKey]);\n\n const extractLanguageFromCode = useCallback(\n (codeElement: React.ReactElement | null): string | null => {\n if (!codeElement || !codeElement.props.className) return null;\n\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return null;\n\n return langClass.substring(9); // Remove \"language-\" prefix\n },\n [],\n );\n\n // Helper to find the code element within pre's children (handles both single element and array)\n const findCodeElement = useCallback(\n (preChildren: React.ReactNode): React.ReactElement | null => {\n if (isValidElement(preChildren)) {\n return preChildren;\n }\n if (Array.isArray(preChildren)) {\n const codeEl = preChildren.find((c) => isValidElement(c));\n return codeEl && isValidElement(codeEl) ? codeEl : null;\n }\n return null;\n },\n [],\n );\n\n const { codeData, languages, sdkTypes, isSinglePlainCommand } =\n useMemo(() => {\n const childrenArray = Children.toArray(children);\n const languages: string[] = [];\n const sdkTypes = new Set<SDKType>();\n const codeData: {\n language: string;\n content: string;\n lineHighlights: Record<number, LineHighlightType>;\n }[] = [];\n\n const isSinglePlainCommand =\n childrenArray.length === 1 &&\n [\"language-shell\", \"language-text\"].some((lang) => {\n if (!isValidElement(childrenArray[0])) return false;\n const codeEl = findCodeElement(childrenArray[0].props.children);\n return codeEl?.props.className?.includes(lang);\n });\n\n childrenArray.forEach((child) => {\n if (!isValidElement(child)) return;\n\n const preElement = child;\n const codeElement = findCodeElement(preElement.props.children);\n\n if (!codeElement) return;\n\n const rawLanguage = extractLanguageFromCode(codeElement);\n\n if (!rawLanguage) return;\n\n const meta: string | undefined = codeElement.props?.[\"data-meta\"];\n const { lang: codeLanguage, highlights: lineHighlights } =\n parseLineHighlights(rawLanguage, meta);\n\n for (const prefix of SDK_PREFIXES) {\n if (codeLanguage.startsWith(`${prefix}_`)) {\n sdkTypes.add(prefix);\n break;\n }\n }\n\n if (!languages.includes(codeLanguage)) {\n languages.push(codeLanguage);\n }\n\n const codeContent = codeElement.props.children;\n codeData.push({\n language: codeLanguage,\n content: codeContent,\n lineHighlights,\n });\n });\n\n return {\n codeData,\n languages,\n sdkTypes,\n isSinglePlainCommand,\n };\n }, [children, extractLanguageFromCode, findCodeElement]);\n\n // Resolve which SDK type to filter by. If the snippet only contains one SDK type\n // and it doesn't match the current selector, fall back to the only available type.\n // Returns undefined when no SDK prop is provided (e.g. plain code blocks without SDK prefixes).\n const resolvedSdk: SDKType | undefined = useMemo(() => {\n if (sdkTypes.size === 1 && sdk && !sdkTypes.has(sdk)) {\n return Array.from(sdkTypes)[0];\n }\n return sdk;\n }, [sdk, sdkTypes]);\n\n // Only show SDK selector for realtime/rest types, not for client/agent (which are controlled by page-level selector)\n const showSDKSelector = sdkTypes.has(\"realtime\") || sdkTypes.has(\"rest\");\n\n const filteredLanguages = useMemo(() => {\n const filtered =\n !resolvedSdk || !showSDKSelector\n ? [...languages]\n : languages.filter((lang) => lang.startsWith(`${resolvedSdk}_`));\n\n // Apply custom ordering if provided\n if (languageOrdering && languageOrdering.length > 0) {\n filtered.sort((a, b) => {\n const aBase = stripSdkType(a);\n const bBase = stripSdkType(b);\n\n const aIndex = languageOrdering.indexOf(aBase);\n const bIndex = languageOrdering.indexOf(bBase);\n\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return 0;\n });\n }\n\n return filtered;\n }, [resolvedSdk, showSDKSelector, languages, languageOrdering]);\n\n const activeLanguage = useMemo(() => {\n // For client/agent SDK types (controlled by page-level selector), construct the full language\n if (resolvedSdk === \"client\" || resolvedSdk === \"agent\") {\n const fullLang = `${resolvedSdk}_${lang}`;\n // Verify this language exists in available languages\n if (languages.includes(fullLang)) {\n return fullLang;\n }\n // Fall back to first language with this prefix\n const prefixMatch = languages.find((l) =>\n l.startsWith(`${resolvedSdk}_`),\n );\n if (prefixMatch) return prefixMatch;\n }\n\n // For realtime/rest SDK types\n if (resolvedSdk && sdkTypes.has(resolvedSdk)) {\n return `${resolvedSdk}_${lang}`;\n }\n\n if (lang) return lang;\n\n if (filteredLanguages.length > 0) return filteredLanguages[0];\n\n return languages[0];\n }, [resolvedSdk, sdkTypes, lang, filteredLanguages, languages]);\n\n const requiresApiKeySubstitution = useMemo(() => {\n const containsPlaceholder = codeData.some((code) =>\n code?.content.includes(\"{{API_KEY}}\"),\n );\n\n return (\n containsPlaceholder && !!apiKeys && apiKeys.length > 0 && !!selectedApiKey\n );\n }, [codeData, apiKeys, selectedApiKey]);\n\n const [isHovering, setIsHovering] = useState(false);\n\n const hasOnlyJsonSnippet = useMemo(\n () => languages.length === 1 && languages[0] === \"json\",\n [languages],\n );\n\n const processedChildren = useMemo(() => {\n if (!activeLanguage) return [];\n\n const targetLanguage = hasOnlyJsonSnippet ? \"json\" : activeLanguage;\n\n return codeData\n .filter((code) => {\n return code?.language === targetLanguage;\n })\n .map((code) => {\n if (!code) return null;\n\n const cleanLang = hasOnlyJsonSnippet ? \"json\" : code.language;\n const langInfo = getLanguageInfo(cleanLang ?? \"\");\n\n if (\n typeof code.content === \"string\" ||\n typeof code.content === \"number\" ||\n typeof code.content === \"boolean\"\n ) {\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(code.content);\n if (requiresApiKeySubstitution) {\n processedContent = substituteApiKey(\n processedContent,\n selectedApiKey,\n );\n }\n\n if (!langInfo.syntaxHighlighterKey || !cleanLang) return null;\n\n return (\n <Code\n key={code.language}\n language={langInfo.syntaxHighlighterKey || cleanLang}\n snippet={processedContent}\n additionalCSS=\"!bg-neutral-000 text-neutral-1300 dark:!bg-neutral-1300 dark:text-neutral-200 px-6 py-4\"\n showLines={showCodeLines}\n wrap={wrapCode}\n lineHighlights={\n Object.keys(code.lineHighlights).length > 0\n ? code.lineHighlights\n : undefined\n }\n />\n );\n }\n\n return null;\n });\n }, [\n activeLanguage,\n hasOnlyJsonSnippet,\n codeData,\n requiresApiKeySubstitution,\n showCodeLines,\n wrapCode,\n selectedApiKey,\n ]);\n\n const hasSnippetForActiveLanguage = useMemo(() => {\n if (!activeLanguage) return false;\n if (hasOnlyJsonSnippet) return true;\n\n return codeData.some((code) => {\n return code?.language === activeLanguage;\n });\n }, [activeLanguage, hasOnlyJsonSnippet, codeData]);\n\n const handleSDKTypeChange = useCallback(\n (type: SDKType) => {\n const nextLang = stripSdkType(\n languages.find(\n (l) => l === `${type}_${stripSdkType(activeLanguage)}`,\n ) ??\n languages.find((l) => l.startsWith(`${type}_`)) ??\n activeLanguage,\n );\n\n if (onChange && nextLang) {\n onChange(stripSdkType(activeLanguage), type);\n }\n },\n [activeLanguage, languages, onChange],\n );\n\n const handleLanguageChange = useCallback(\n (language: string) => {\n if (onChange) {\n onChange(stripSdkType(language), resolvedSdk);\n }\n },\n [onChange, resolvedSdk],\n );\n\n const noSnippetMessage = useMemo(() => {\n if (!activeLanguage) return null;\n\n const activeLanguageInfo = getLanguageInfo(activeLanguage);\n\n return (\n <div className=\"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center\">\n <Icon\n name=\"icon-gui-exclamation-triangle-outline\"\n color=\"text-yellow-600 dark:text-yellow-400\"\n size=\"24px\"\n />\n <p className=\"ui-text-p3 text-neutral-700 dark:text-neutral-600\">\n You&apos;re currently viewing the {activeLanguageInfo.label} docs.\n There either isn&apos;t a {activeLanguageInfo.label} code sample for\n this example, or this feature isn&apos;t supported in{\" \"}\n {activeLanguageInfo.label}. Switch language to view this example in a\n different language, or check which SDKs support this feature.\n </p>\n </div>\n );\n }, [activeLanguage]);\n\n const showLanguageSelector = !fixed && filteredLanguages.length > 0;\n const showFullSelector = filteredLanguages.length > 1;\n // Show a read-only language label when fixed (controlled by external selector)\n const showFixedLanguageLabel = fixed && activeLanguage;\n\n const renderLanguageLabel = (langKey: string, onClick?: () => void) => (\n <div\n className={cn(\n \"border-b border-neutral-300 dark:border-neutral-1000 h-[2.125rem] inline-flex items-center px-3 w-full\",\n { \"rounded-t-lg\": !headerRow },\n )}\n >\n <div\n className={cn(\"inline-flex items-center\", onClick && \"cursor-pointer\")}\n {...(onClick && { onClick })}\n >\n <Icon\n name={getLanguageInfo(langKey).icon}\n size=\"16px\"\n additionalCSS=\"mr-2\"\n />\n <span className=\"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none\">\n {getLanguageInfo(langKey).label}\n </span>\n </div>\n </div>\n );\n\n const renderContent = useMemo(() => {\n if (!activeLanguage) return null;\n\n if (hasSnippetForActiveLanguage) {\n return processedChildren;\n }\n\n return noSnippetMessage;\n }, [\n activeLanguage,\n hasSnippetForActiveLanguage,\n processedChildren,\n noSnippetMessage,\n ]);\n\n // Render special case for plain commands (shell or text)\n if (isSinglePlainCommand) {\n const plainChild = codeData[0];\n if (plainChild) {\n const codeContent = plainChild.content;\n const language = plainChild.language;\n\n if (!language || !codeContent) return null;\n\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(codeContent);\n if (requiresApiKeySubstitution) {\n processedContent = substituteApiKey(processedContent, selectedApiKey);\n }\n\n return (\n <PlainCodeView\n content={processedContent}\n className={className}\n language={language}\n icon={language === \"shell\" ? \"icon-gui-command-line-outline\" : null}\n />\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]\",\n className,\n )}\n >\n {headerRow && (\n <div className=\"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg\">\n <div className=\"flex space-x-1.5\">\n <div className=\"w-3 h-3 rounded-full bg-orange-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-yellow-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-green-500\"></div>\n </div>\n\n <div className=\"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000\">\n {title}\n </div>\n\n <div className=\"w-12\"></div>\n </div>\n )}\n\n {showSDKSelector && (\n <div\n className={cn(\n \"p-2 border-b border-neutral-300 dark:border-neutral-1000\",\n sdkTypes.size === 1 && \"p-1\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n <div className=\"flex gap-1 justify-start\">\n {[\"realtime\", \"rest\"].map(\n (type) =>\n sdkTypes.has(type as SDKType) && (\n <SegmentedControl\n key={type}\n onClick={() => handleSDKTypeChange(type as SDKType)}\n size=\"xs\"\n active={resolvedSdk === type}\n className={cn(\n \"text-[11px] font-semibold px-2 py-1 h-auto\",\n sdkTypes.size === 1 &&\n \"pointer-events-none bg-neutral-100 dark:bg-neutral-1200 !text-neutral-800 !dark:text-neutral-500\",\n sdkTypes.size > 1 &&\n resolvedSdk !== type &&\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-400 dark:active:bg-neutral-900\",\n sdkTypes.size > 1 &&\n resolvedSdk === type &&\n \"bg-neutral-000 dark:bg-neutral-1100\",\n )}\n >\n {type === \"realtime\" ? \"Realtime\" : \"REST\"}\n </SegmentedControl>\n ),\n )}\n </div>\n </div>\n )}\n\n {showFixedLanguageLabel && renderLanguageLabel(activeLanguage)}\n\n {showLanguageSelector &&\n (showFullSelector ? (\n <LanguageSelector\n languages={filteredLanguages}\n activeLanguage={activeLanguage}\n onLanguageChange={handleLanguageChange}\n />\n ) : (\n renderLanguageLabel(filteredLanguages[0], () =>\n handleLanguageChange(filteredLanguages[0]),\n )\n ))}\n <div\n ref={codeRef}\n className=\"relative\"\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n onFocus={() => setIsHovering(true)}\n onBlur={() => setIsHovering(false)}\n >\n {renderContent}\n {isHovering && activeLanguage && hasSnippetForActiveLanguage && (\n <CopyButton\n onCopy={() => {\n const text = codeData.find(\n (code) => code.language === activeLanguage,\n )?.content;\n if (text)\n navigator.clipboard.writeText(\n substituteApiKey(text, selectedApiKey, false),\n );\n }}\n />\n )}\n </div>\n {requiresApiKeySubstitution && (\n <ApiKeySelector\n apiKeys={apiKeys}\n selectedApiKey={selectedApiKey}\n onApiKeyChange={setSelectedApiKey}\n />\n )}\n </div>\n );\n};\n\nexport default CodeSnippet;\n"],"names":["React","useState","useEffect","Children","isValidElement","useRef","useCallback","useMemo","Code","cn","parseLineHighlights","Icon","getLanguageInfo","stripSdkType","SDK_PREFIXES","LanguageSelector","ApiKeySelector","PlainCodeView","CopyButton","SegmentedControl","substituteApiKey","content","apiKey","mask","replace","split","CodeSnippet","fixed","headerRow","title","children","className","lang","onChange","apiKeys","sdk","showCodeLines","languageOrdering","wrapCode","codeRef","selectedApiKey","setSelectedApiKey","keys","key","prevApiKeys","setPrevApiKeys","length","element","current","unmaskRenderedApiKey","handleCopy","event","selection","window","getSelection","rangeCount","selectedText","toString","range","getRangeAt","contains","commonAncestorContainer","modifiedText","clipboardData","setData","preventDefault","document","addEventListener","removeEventListener","extractLanguageFromCode","codeElement","props","classNames","langClass","find","cls","startsWith","substring","findCodeElement","preChildren","Array","isArray","codeEl","c","codeData","languages","sdkTypes","isSinglePlainCommand","childrenArray","toArray","Set","some","includes","forEach","child","preElement","rawLanguage","meta","codeLanguage","highlights","lineHighlights","prefix","add","push","codeContent","language","resolvedSdk","size","has","from","showSDKSelector","filteredLanguages","filtered","filter","sort","a","b","aBase","bBase","aIndex","indexOf","bIndex","activeLanguage","fullLang","prefixMatch","l","requiresApiKeySubstitution","containsPlaceholder","code","isHovering","setIsHovering","hasOnlyJsonSnippet","processedChildren","targetLanguage","map","cleanLang","langInfo","processedContent","String","syntaxHighlighterKey","snippet","additionalCSS","showLines","wrap","Object","undefined","hasSnippetForActiveLanguage","handleSDKTypeChange","type","nextLang","handleLanguageChange","noSnippetMessage","activeLanguageInfo","div","name","color","p","label","showLanguageSelector","showFullSelector","showFixedLanguageLabel","renderLanguageLabel","langKey","onClick","icon","span","renderContent","plainChild","active","onLanguageChange","ref","onMouseEnter","onMouseLeave","onFocus","onBlur","onCopy","text","navigator","clipboard","writeText","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 type { LineHighlightType } from \"./Code\";\nimport cn from \"./utils/cn\";\nimport { parseLineHighlights } from \"./utils/syntax-highlighter\";\nimport Icon from \"./Icon\";\nimport {\n getLanguageInfo,\n stripSdkType,\n SDK_PREFIXES,\n SDKType,\n} from \"./CodeSnippet/languages\";\nimport LanguageSelector from \"./CodeSnippet/LanguageSelector\";\nimport ApiKeySelector from \"./CodeSnippet/ApiKeySelector\";\nimport PlainCodeView from \"./CodeSnippet/PlainCodeView\";\nimport CopyButton from \"./CodeSnippet/CopyButton\";\nimport copyToClipboard from \"./CodeSnippet/copyToClipboard\";\nimport SegmentedControl from \"./SegmentedControl\";\n\n// Re-export SDKType for consumers\nexport type { SDKType };\n\n// Define API key types\nexport type ApiKeysItem = {\n app: string;\n keys: { name: string; key: string }[];\n};\n\nexport type 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 | null;\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?: ApiKeysItem[];\n /**\n * Default SDK type to use for the code snippet\n */\n sdk?: SDKType;\n /**\n * Whether to show line numbers in code snippets\n */\n showCodeLines?: boolean;\n /**\n * Defines the order in which languages should be displayed.\n * Languages not in this array will be shown after those that are included.\n */\n languageOrdering?: string[];\n /**\n * Whether to wrap code content instead of scrolling\n */\n wrapCode?: boolean;\n /**\n * Fired when the user takes the snippet with a copy control, receiving the\n * exact text written to the clipboard. Selecting part of the code and\n * pressing cmd-C does not fire it — a partial selection isn't the user\n * taking the snippet, and callers use this to record that they did. A copy\n * that fails to reach the clipboard does not fire it either.\n *\n * The text may contain a live, unmasked API key — `apiKeys` placeholders are\n * substituted for real before the copy. Do not log it or transmit it to\n * third-party services.\n */\n onCopy?: (text: string) => void;\n};\n\n// Substitution function for API key placeholders\nconst substituteApiKey = (\n content: string,\n apiKey: string,\n mask = true,\n): string => {\n return content.replace(\n /\\{\\{API_KEY\\}\\}/g,\n mask ? `${apiKey.split(\":\")[0]}:*****` : apiKey,\n );\n};\n\n/**\n * CodeSnippet component that displays code with language switching capability\n */\nconst CodeSnippet: React.FC<CodeSnippetProps> = ({\n fixed = false,\n headerRow = false,\n title = \"Code\",\n children,\n className,\n lang,\n onChange,\n apiKeys,\n sdk,\n showCodeLines = true,\n languageOrdering,\n wrapCode = false,\n onCopy,\n}) => {\n const codeRef = useRef<HTMLDivElement>(null);\n\n const [selectedApiKey, setSelectedApiKey] = useState<string>(\n () => apiKeys?.[0]?.keys?.[0]?.key ?? \"\",\n );\n const [prevApiKeys, setPrevApiKeys] = useState(apiKeys);\n if (prevApiKeys !== apiKeys) {\n setPrevApiKeys(apiKeys);\n if (!selectedApiKey && apiKeys && apiKeys.length > 0) {\n setSelectedApiKey(apiKeys[0].keys?.[0]?.key ?? \"\");\n }\n }\n\n useEffect(() => {\n const element = codeRef.current;\n if (!element) return;\n\n // Detects the key masking via substituteApiKey (i.e. \"abcde:*****\") and replaces it with the actual API key\n const unmaskRenderedApiKey = (content: string, apiKey: string): string => {\n return content.replace(/(['\"]?)([^:'\"]+):\\*{5}\\1/g, `$1${apiKey}$1`);\n };\n\n const handleCopy = (event: ClipboardEvent) => {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0) return;\n\n const selectedText = selection.toString();\n if (!selectedText) return;\n\n // Check if the selection is within our element\n const range = selection.getRangeAt(0);\n if (!element.contains(range.commonAncestorContainer)) return;\n\n const modifiedText = unmaskRenderedApiKey(selectedText, selectedApiKey);\n\n event.clipboardData?.setData(\"text/plain\", modifiedText);\n event.preventDefault();\n };\n\n document.addEventListener(\"copy\", handleCopy);\n\n return () => {\n document.removeEventListener(\"copy\", handleCopy);\n };\n }, [selectedApiKey]);\n\n const extractLanguageFromCode = useCallback(\n (codeElement: React.ReactElement | null): string | null => {\n if (!codeElement || !codeElement.props.className) return null;\n\n const classNames = codeElement.props.className.split(\" \");\n const langClass = classNames.find((cls: string) =>\n cls.startsWith(\"language-\"),\n );\n if (!langClass) return null;\n\n return langClass.substring(9); // Remove \"language-\" prefix\n },\n [],\n );\n\n // Helper to find the code element within pre's children (handles both single element and array)\n const findCodeElement = useCallback(\n (preChildren: React.ReactNode): React.ReactElement | null => {\n if (isValidElement(preChildren)) {\n return preChildren;\n }\n if (Array.isArray(preChildren)) {\n const codeEl = preChildren.find((c) => isValidElement(c));\n return codeEl && isValidElement(codeEl) ? codeEl : null;\n }\n return null;\n },\n [],\n );\n\n const { codeData, languages, sdkTypes, isSinglePlainCommand } =\n useMemo(() => {\n const childrenArray = Children.toArray(children);\n const languages: string[] = [];\n const sdkTypes = new Set<SDKType>();\n const codeData: {\n language: string;\n content: string;\n lineHighlights: Record<number, LineHighlightType>;\n }[] = [];\n\n const isSinglePlainCommand =\n childrenArray.length === 1 &&\n [\"language-shell\", \"language-text\"].some((lang) => {\n if (!isValidElement(childrenArray[0])) return false;\n const codeEl = findCodeElement(childrenArray[0].props.children);\n return codeEl?.props.className?.includes(lang);\n });\n\n childrenArray.forEach((child) => {\n if (!isValidElement(child)) return;\n\n const preElement = child;\n const codeElement = findCodeElement(preElement.props.children);\n\n if (!codeElement) return;\n\n const rawLanguage = extractLanguageFromCode(codeElement);\n\n if (!rawLanguage) return;\n\n const meta: string | undefined = codeElement.props?.[\"data-meta\"];\n const { lang: codeLanguage, highlights: lineHighlights } =\n parseLineHighlights(rawLanguage, meta);\n\n for (const prefix of SDK_PREFIXES) {\n if (codeLanguage.startsWith(`${prefix}_`)) {\n sdkTypes.add(prefix);\n break;\n }\n }\n\n if (!languages.includes(codeLanguage)) {\n languages.push(codeLanguage);\n }\n\n const codeContent = codeElement.props.children;\n codeData.push({\n language: codeLanguage,\n content: codeContent,\n lineHighlights,\n });\n });\n\n return {\n codeData,\n languages,\n sdkTypes,\n isSinglePlainCommand,\n };\n }, [children, extractLanguageFromCode, findCodeElement]);\n\n // Resolve which SDK type to filter by. If the snippet only contains one SDK type\n // and it doesn't match the current selector, fall back to the only available type.\n // Returns undefined when no SDK prop is provided (e.g. plain code blocks without SDK prefixes).\n const resolvedSdk: SDKType | undefined = useMemo(() => {\n if (sdkTypes.size === 1 && sdk && !sdkTypes.has(sdk)) {\n return Array.from(sdkTypes)[0];\n }\n return sdk;\n }, [sdk, sdkTypes]);\n\n // Only show SDK selector for realtime/rest types, not for client/agent (which are controlled by page-level selector)\n const showSDKSelector = sdkTypes.has(\"realtime\") || sdkTypes.has(\"rest\");\n\n const filteredLanguages = useMemo(() => {\n const filtered =\n !resolvedSdk || !showSDKSelector\n ? [...languages]\n : languages.filter((lang) => lang.startsWith(`${resolvedSdk}_`));\n\n // Apply custom ordering if provided\n if (languageOrdering && languageOrdering.length > 0) {\n filtered.sort((a, b) => {\n const aBase = stripSdkType(a);\n const bBase = stripSdkType(b);\n\n const aIndex = languageOrdering.indexOf(aBase);\n const bIndex = languageOrdering.indexOf(bBase);\n\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return 0;\n });\n }\n\n return filtered;\n }, [resolvedSdk, showSDKSelector, languages, languageOrdering]);\n\n const activeLanguage = useMemo(() => {\n // For client/agent SDK types (controlled by page-level selector), construct the full language\n if (resolvedSdk === \"client\" || resolvedSdk === \"agent\") {\n const fullLang = `${resolvedSdk}_${lang}`;\n // Verify this language exists in available languages\n if (languages.includes(fullLang)) {\n return fullLang;\n }\n // Fall back to first language with this prefix\n const prefixMatch = languages.find((l) =>\n l.startsWith(`${resolvedSdk}_`),\n );\n if (prefixMatch) return prefixMatch;\n }\n\n // For realtime/rest SDK types\n if (resolvedSdk && sdkTypes.has(resolvedSdk)) {\n return `${resolvedSdk}_${lang}`;\n }\n\n if (lang) return lang;\n\n if (filteredLanguages.length > 0) return filteredLanguages[0];\n\n return languages[0];\n }, [resolvedSdk, sdkTypes, lang, filteredLanguages, languages]);\n\n const requiresApiKeySubstitution = useMemo(() => {\n const containsPlaceholder = codeData.some((code) =>\n code?.content.includes(\"{{API_KEY}}\"),\n );\n\n return (\n containsPlaceholder && !!apiKeys && apiKeys.length > 0 && !!selectedApiKey\n );\n }, [codeData, apiKeys, selectedApiKey]);\n\n const [isHovering, setIsHovering] = useState(false);\n\n const hasOnlyJsonSnippet = useMemo(\n () => languages.length === 1 && languages[0] === \"json\",\n [languages],\n );\n\n const processedChildren = useMemo(() => {\n if (!activeLanguage) return [];\n\n const targetLanguage = hasOnlyJsonSnippet ? \"json\" : activeLanguage;\n\n return codeData\n .filter((code) => {\n return code?.language === targetLanguage;\n })\n .map((code) => {\n if (!code) return null;\n\n const cleanLang = hasOnlyJsonSnippet ? \"json\" : code.language;\n const langInfo = getLanguageInfo(cleanLang ?? \"\");\n\n if (\n typeof code.content === \"string\" ||\n typeof code.content === \"number\" ||\n typeof code.content === \"boolean\"\n ) {\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(code.content);\n if (requiresApiKeySubstitution) {\n processedContent = substituteApiKey(\n processedContent,\n selectedApiKey,\n );\n }\n\n if (!langInfo.syntaxHighlighterKey || !cleanLang) return null;\n\n return (\n <Code\n key={code.language}\n language={langInfo.syntaxHighlighterKey || cleanLang}\n snippet={processedContent}\n additionalCSS=\"!bg-neutral-000 text-neutral-1300 dark:!bg-neutral-1300 dark:text-neutral-200 px-6 py-4\"\n showLines={showCodeLines}\n wrap={wrapCode}\n lineHighlights={\n Object.keys(code.lineHighlights).length > 0\n ? code.lineHighlights\n : undefined\n }\n />\n );\n }\n\n return null;\n });\n }, [\n activeLanguage,\n hasOnlyJsonSnippet,\n codeData,\n requiresApiKeySubstitution,\n showCodeLines,\n wrapCode,\n selectedApiKey,\n ]);\n\n const hasSnippetForActiveLanguage = useMemo(() => {\n if (!activeLanguage) return false;\n if (hasOnlyJsonSnippet) return true;\n\n return codeData.some((code) => {\n return code?.language === activeLanguage;\n });\n }, [activeLanguage, hasOnlyJsonSnippet, codeData]);\n\n const handleSDKTypeChange = useCallback(\n (type: SDKType) => {\n const nextLang = stripSdkType(\n languages.find(\n (l) => l === `${type}_${stripSdkType(activeLanguage)}`,\n ) ??\n languages.find((l) => l.startsWith(`${type}_`)) ??\n activeLanguage,\n );\n\n if (onChange && nextLang) {\n onChange(stripSdkType(activeLanguage), type);\n }\n },\n [activeLanguage, languages, onChange],\n );\n\n const handleLanguageChange = useCallback(\n (language: string) => {\n if (onChange) {\n onChange(stripSdkType(language), resolvedSdk);\n }\n },\n [onChange, resolvedSdk],\n );\n\n const noSnippetMessage = useMemo(() => {\n if (!activeLanguage) return null;\n\n const activeLanguageInfo = getLanguageInfo(activeLanguage);\n\n return (\n <div className=\"px-16 py-6 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-3 items-center\">\n <Icon\n name=\"icon-gui-exclamation-triangle-outline\"\n color=\"text-yellow-600 dark:text-yellow-400\"\n size=\"24px\"\n />\n <p className=\"ui-text-p3 text-neutral-700 dark:text-neutral-600\">\n You&apos;re currently viewing the {activeLanguageInfo.label} docs.\n There either isn&apos;t a {activeLanguageInfo.label} code sample for\n this example, or this feature isn&apos;t supported in{\" \"}\n {activeLanguageInfo.label}. Switch language to view this example in a\n different language, or check which SDKs support this feature.\n </p>\n </div>\n );\n }, [activeLanguage]);\n\n const showLanguageSelector = !fixed && filteredLanguages.length > 0;\n const showFullSelector = filteredLanguages.length > 1;\n // Show a read-only language label when fixed (controlled by external selector)\n const showFixedLanguageLabel = fixed && activeLanguage;\n\n const renderLanguageLabel = (langKey: string, onClick?: () => void) => (\n <div\n className={cn(\n \"border-b border-neutral-300 dark:border-neutral-1000 h-[2.125rem] inline-flex items-center px-3 w-full\",\n { \"rounded-t-lg\": !headerRow },\n )}\n >\n <div\n className={cn(\"inline-flex items-center\", onClick && \"cursor-pointer\")}\n {...(onClick && { onClick })}\n >\n <Icon\n name={getLanguageInfo(langKey).icon}\n size=\"16px\"\n additionalCSS=\"mr-2\"\n />\n <span className=\"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none\">\n {getLanguageInfo(langKey).label}\n </span>\n </div>\n </div>\n );\n\n const renderContent = useMemo(() => {\n if (!activeLanguage) return null;\n\n if (hasSnippetForActiveLanguage) {\n return processedChildren;\n }\n\n return noSnippetMessage;\n }, [\n activeLanguage,\n hasSnippetForActiveLanguage,\n processedChildren,\n noSnippetMessage,\n ]);\n\n // Render special case for plain commands (shell or text)\n if (isSinglePlainCommand) {\n const plainChild = codeData[0];\n if (plainChild) {\n const codeContent = plainChild.content;\n const language = plainChild.language;\n\n if (!language || !codeContent) return null;\n\n // Apply API key substitution if apiKeys are provided\n let processedContent = String(codeContent);\n if (requiresApiKeySubstitution) {\n processedContent = substituteApiKey(processedContent, selectedApiKey);\n }\n\n return (\n <PlainCodeView\n content={processedContent}\n className={className}\n language={language}\n icon={language === \"shell\" ? \"icon-gui-command-line-outline\" : null}\n onCopy={onCopy}\n />\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[3.375rem]\",\n className,\n )}\n >\n {headerRow && (\n <div className=\"h-[2.375rem] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-1 px-3 rounded-t-lg\">\n <div className=\"flex space-x-1.5\">\n <div className=\"w-3 h-3 rounded-full bg-orange-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-yellow-500\"></div>\n <div className=\"w-3 h-3 rounded-full bg-green-500\"></div>\n </div>\n\n <div className=\"flex-1 text-center ui-text-p3 font-semibold text-neutral-1300 dark:text-neutral-000\">\n {title}\n </div>\n\n <div className=\"w-12\"></div>\n </div>\n )}\n\n {showSDKSelector && (\n <div\n className={cn(\n \"p-2 border-b border-neutral-300 dark:border-neutral-1000\",\n sdkTypes.size === 1 && \"p-1\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n <div className=\"flex gap-1 justify-start\">\n {[\"realtime\", \"rest\"].map(\n (type) =>\n sdkTypes.has(type as SDKType) && (\n <SegmentedControl\n key={type}\n onClick={() => handleSDKTypeChange(type as SDKType)}\n size=\"xs\"\n active={resolvedSdk === type}\n className={cn(\n \"text-[11px] font-semibold px-2 py-1 h-auto\",\n sdkTypes.size === 1 &&\n \"pointer-events-none bg-neutral-100 dark:bg-neutral-1200 !text-neutral-800 !dark:text-neutral-500\",\n sdkTypes.size > 1 &&\n resolvedSdk !== type &&\n \"bg-neutral-100 dark:bg-neutral-1200 hover:bg-neutral-200 dark:hover:bg-neutral-1100 active:bg-neutral-400 dark:active:bg-neutral-900\",\n sdkTypes.size > 1 &&\n resolvedSdk === type &&\n \"bg-neutral-000 dark:bg-neutral-1100\",\n )}\n >\n {type === \"realtime\" ? \"Realtime\" : \"REST\"}\n </SegmentedControl>\n ),\n )}\n </div>\n </div>\n )}\n\n {showFixedLanguageLabel && renderLanguageLabel(activeLanguage)}\n\n {showLanguageSelector &&\n (showFullSelector ? (\n <LanguageSelector\n languages={filteredLanguages}\n activeLanguage={activeLanguage}\n onLanguageChange={handleLanguageChange}\n />\n ) : (\n renderLanguageLabel(filteredLanguages[0], () =>\n handleLanguageChange(filteredLanguages[0]),\n )\n ))}\n <div\n ref={codeRef}\n className=\"relative\"\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => setIsHovering(false)}\n onFocus={() => setIsHovering(true)}\n onBlur={() => setIsHovering(false)}\n >\n {renderContent}\n {isHovering && activeLanguage && hasSnippetForActiveLanguage && (\n <CopyButton\n onCopy={() => {\n const text = codeData.find(\n (code) => code.language === activeLanguage,\n )?.content;\n if (!text) return;\n copyToClipboard(\n substituteApiKey(text, selectedApiKey, false),\n onCopy,\n );\n }}\n />\n )}\n </div>\n {requiresApiKeySubstitution && (\n <ApiKeySelector\n apiKeys={apiKeys}\n selectedApiKey={selectedApiKey}\n onApiKeyChange={setSelectedApiKey}\n />\n )}\n </div>\n );\n};\n\nexport default CodeSnippet;\n"],"names":["React","useState","useEffect","Children","isValidElement","useRef","useCallback","useMemo","Code","cn","parseLineHighlights","Icon","getLanguageInfo","stripSdkType","SDK_PREFIXES","LanguageSelector","ApiKeySelector","PlainCodeView","CopyButton","copyToClipboard","SegmentedControl","substituteApiKey","content","apiKey","mask","replace","split","CodeSnippet","fixed","headerRow","title","children","className","lang","onChange","apiKeys","sdk","showCodeLines","languageOrdering","wrapCode","onCopy","codeRef","selectedApiKey","setSelectedApiKey","keys","key","prevApiKeys","setPrevApiKeys","length","element","current","unmaskRenderedApiKey","handleCopy","event","selection","window","getSelection","rangeCount","selectedText","toString","range","getRangeAt","contains","commonAncestorContainer","modifiedText","clipboardData","setData","preventDefault","document","addEventListener","removeEventListener","extractLanguageFromCode","codeElement","props","classNames","langClass","find","cls","startsWith","substring","findCodeElement","preChildren","Array","isArray","codeEl","c","codeData","languages","sdkTypes","isSinglePlainCommand","childrenArray","toArray","Set","some","includes","forEach","child","preElement","rawLanguage","meta","codeLanguage","highlights","lineHighlights","prefix","add","push","codeContent","language","resolvedSdk","size","has","from","showSDKSelector","filteredLanguages","filtered","filter","sort","a","b","aBase","bBase","aIndex","indexOf","bIndex","activeLanguage","fullLang","prefixMatch","l","requiresApiKeySubstitution","containsPlaceholder","code","isHovering","setIsHovering","hasOnlyJsonSnippet","processedChildren","targetLanguage","map","cleanLang","langInfo","processedContent","String","syntaxHighlighterKey","snippet","additionalCSS","showLines","wrap","Object","undefined","hasSnippetForActiveLanguage","handleSDKTypeChange","type","nextLang","handleLanguageChange","noSnippetMessage","activeLanguageInfo","div","name","color","p","label","showLanguageSelector","showFullSelector","showFixedLanguageLabel","renderLanguageLabel","langKey","onClick","icon","span","renderContent","plainChild","active","onLanguageChange","ref","onMouseEnter","onMouseLeave","onFocus","onBlur","text","onApiKeyChange"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import React,{createContext,useContext,useState,useEffect,useRef}from"react";import Icon from"./Icon";import cn from"./utils/cn";const DropdownMenuContext=createContext({isOpen:false,setOpen:()=>{}});const DropdownMenu=({children})=>{const[isOpen,setOpen]=useState(false);const ref=useRef(null);useEffect(()=>{const clickHandler=e=>{if(ref.current?.contains(e.target))return;setOpen(false)};document.addEventListener("click",clickHandler);return()=>document.removeEventListener("click",clickHandler)},[]);return React.createElement(DropdownMenuContext.Provider,{value:{isOpen,setOpen}},React.createElement("div",{id:"dropdown-menu",className:"relative",ref:ref},children))};const Trigger=({children,triggerClassNames="",description})=>{const{isOpen,setOpen}=useContext(DropdownMenuContext);return React.createElement("button",{id:"menu-trigger","aria-label":description,onClick:()=>setOpen(!isOpen),className:cn("flex items-center ui-text-label3 font-bold text-neutral-1000 dark:text-neutral-300 focus:outline-none",triggerClassNames)},children,React.createElement(Icon,{name:isOpen?"icon-gui-chevron-up-mini":"icon-gui-chevron-down-mini",size:"1.25rem",additionalCSS:"text-neutral-1300 dark:text-neutral-000"}))};const Content=({children,anchorPosition="right",contentClassNames})=>{const{isOpen}=useContext(DropdownMenuContext);if(!isOpen){return null}return React.createElement("div",{id:"menu-content",role:"menu",className:cn("flex flex-col absolute z-10 border border-neutral-400 dark:border-neutral-900 bg-neutral-000 dark:bg-neutral-1300 rounded-lg ui-shadow-md-soft",anchorPosition==="right"?"right-0":"left-0",contentClassNames)},children)};const Link=({url,title,subtitle,iconName,children})=>{return React.createElement("a",{href:url,className:"menu-link group block p-2 rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 hover:dark:text-neutral-000"},React.createElement("p",{className:"mb-1"},title,iconName?React.createElement(Icon,{name:iconName,size:"1rem",additionalCSS:"align-middle ml-2 relative -top-px -left-1 text-neutral-1300 dark:text-neutral-000"}):null),subtitle?React.createElement("p",{className:"ui-text-p3 mb-4"},subtitle):null,children)};DropdownMenu.Trigger=Trigger;DropdownMenu.Content=Content;DropdownMenu.Link=Link;export default DropdownMenu;
1
+ import React,{createContext,useContext,useState,useEffect,useRef}from"react";import Icon from"./Icon";import cn from"./utils/cn";const DropdownMenuContext=createContext({isOpen:false,setOpen:()=>{}});const DropdownMenu=({children})=>{const[isOpen,setOpen]=useState(false);const ref=useRef(null);useEffect(()=>{const clickHandler=e=>{if(ref.current?.contains(e.target))return;setOpen(false)};document.addEventListener("click",clickHandler);return()=>document.removeEventListener("click",clickHandler)},[]);return React.createElement(DropdownMenuContext.Provider,{value:{isOpen,setOpen}},React.createElement("div",{id:"dropdown-menu",className:"relative",ref:ref},children))};const Trigger=({children,triggerClassNames="",description})=>{const{isOpen,setOpen}=useContext(DropdownMenuContext);return React.createElement("button",{id:"menu-trigger","aria-label":description,onClick:()=>setOpen(!isOpen),className:cn("flex items-center ui-text-label3 font-semibold text-neutral-1000 dark:text-neutral-300 focus:outline-none",triggerClassNames)},children,React.createElement(Icon,{name:isOpen?"icon-gui-chevron-up-mini":"icon-gui-chevron-down-mini",size:"1.25rem",additionalCSS:"text-neutral-1300 dark:text-neutral-000"}))};const Content=({children,anchorPosition="right",contentClassNames})=>{const{isOpen}=useContext(DropdownMenuContext);if(!isOpen){return null}return React.createElement("div",{id:"menu-content",role:"menu",className:cn("flex flex-col absolute z-10 border border-neutral-400 dark:border-neutral-900 bg-neutral-000 dark:bg-neutral-1300 rounded-lg ui-shadow-md-soft",anchorPosition==="right"?"right-0":"left-0",contentClassNames)},children)};const Link=({url,title,subtitle,iconName,children})=>{return React.createElement("a",{href:url,className:"menu-link group block p-2 rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 hover:dark:text-neutral-000"},React.createElement("p",{className:"mb-1"},title,iconName?React.createElement(Icon,{name:iconName,size:"1rem",additionalCSS:"align-middle ml-2 relative -top-px -left-1 text-neutral-1300 dark:text-neutral-000"}):null),subtitle?React.createElement("p",{className:"ui-text-p3 mb-4"},subtitle):null,children)};DropdownMenu.Trigger=Trigger;DropdownMenu.Content=Content;DropdownMenu.Link=Link;export default DropdownMenu;
2
2
  //# sourceMappingURL=DropdownMenu.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/DropdownMenu.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useState,\n useEffect,\n useRef,\n ReactNode,\n Dispatch,\n} from \"react\";\nimport Icon from \"./Icon\";\nimport { IconName } from \"./Icon/types\";\nimport cn from \"./utils/cn\";\n\nconst DropdownMenuContext = createContext<{\n isOpen: boolean;\n setOpen: Dispatch<React.SetStateAction<boolean>>;\n}>({\n isOpen: false,\n setOpen: () => {},\n});\n\ntype DropdownMenuProps = {\n /**\n * The content to be displayed within the dropdown menu.\n */\n children: ReactNode;\n};\n\ntype TriggerProps = {\n /**\n * The content to be displayed within the trigger element.\n */\n children: ReactNode;\n /**\n * Additional class names to apply to the trigger element.\n */\n triggerClassNames?: string;\n /**\n * A description for the trigger element, used for accessibility purposes.\n */\n description?: string;\n};\n\ntype ContentProps = {\n /**\n * The content to be displayed within the dropdown menu.\n */\n children: ReactNode;\n /**\n * The position of the dropdown menu relative to the trigger element.\n * Defaults to \"right\".\n */\n anchorPosition?: string;\n /**\n * Additional class names to apply to the content container.\n */\n contentClassNames?: string;\n};\n\ntype LinkProps = {\n url: string;\n title: string;\n subtitle?: string;\n iconName?: IconName;\n children?: ReactNode;\n};\n\nconst DropdownMenu = ({ children }: DropdownMenuProps) => {\n const [isOpen, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const clickHandler = (e: MouseEvent) => {\n if (ref.current?.contains(e.target as Node)) return;\n setOpen(false);\n };\n document.addEventListener(\"click\", clickHandler);\n return () => document.removeEventListener(\"click\", clickHandler);\n }, []);\n\n return (\n <DropdownMenuContext.Provider value={{ isOpen, setOpen }}>\n <div id=\"dropdown-menu\" className=\"relative\" ref={ref}>\n {children}\n </div>\n </DropdownMenuContext.Provider>\n );\n};\n\nconst Trigger = ({\n children,\n triggerClassNames = \"\",\n description,\n}: TriggerProps) => {\n const { isOpen, setOpen } = useContext(DropdownMenuContext);\n\n return (\n <button\n id=\"menu-trigger\"\n aria-label={description}\n onClick={() => setOpen(!isOpen)}\n className={cn(\n \"flex items-center ui-text-label3 font-bold text-neutral-1000 dark:text-neutral-300 focus:outline-none\",\n triggerClassNames,\n )}\n >\n {children}\n <Icon\n name={\n isOpen ? \"icon-gui-chevron-up-mini\" : \"icon-gui-chevron-down-mini\"\n }\n size=\"1.25rem\"\n additionalCSS=\"text-neutral-1300 dark:text-neutral-000\"\n />\n </button>\n );\n};\n\nconst Content = ({\n children,\n anchorPosition = \"right\",\n contentClassNames,\n}: ContentProps) => {\n const { isOpen } = useContext(DropdownMenuContext);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <div\n id=\"menu-content\"\n role=\"menu\"\n className={cn(\n \"flex flex-col absolute z-10 border border-neutral-400 dark:border-neutral-900 bg-neutral-000 dark:bg-neutral-1300 rounded-lg ui-shadow-md-soft\",\n anchorPosition === \"right\" ? \"right-0\" : \"left-0\",\n contentClassNames,\n )}\n >\n {children}\n </div>\n );\n};\n\nconst Link = ({ url, title, subtitle, iconName, children }: LinkProps) => {\n return (\n <a\n href={url}\n className=\"menu-link group block p-2 rounded-lg\n hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 hover:dark:text-neutral-000\"\n >\n <p className=\"mb-1\">\n {title}\n {iconName ? (\n <Icon\n name={iconName}\n size=\"1rem\"\n additionalCSS=\"align-middle ml-2 relative -top-px -left-1 text-neutral-1300 dark:text-neutral-000\"\n />\n ) : null}\n </p>\n {subtitle ? <p className=\"ui-text-p3 mb-4\">{subtitle}</p> : null}\n {children}\n </a>\n );\n};\n\nDropdownMenu.Trigger = Trigger;\nDropdownMenu.Content = Content;\nDropdownMenu.Link = Link;\n\nexport default DropdownMenu;\n"],"names":["React","createContext","useContext","useState","useEffect","useRef","Icon","cn","DropdownMenuContext","isOpen","setOpen","DropdownMenu","children","ref","clickHandler","e","current","contains","target","document","addEventListener","removeEventListener","Provider","value","div","id","className","Trigger","triggerClassNames","description","button","aria-label","onClick","name","size","additionalCSS","Content","anchorPosition","contentClassNames","role","Link","url","title","subtitle","iconName","a","href","p"],"mappings":"AAAA,OAAOA,OACLC,aAAa,CACbC,UAAU,CACVC,QAAQ,CACRC,SAAS,CACTC,MAAM,KAGD,OAAQ,AACf,QAAOC,SAAU,QAAS,AAE1B,QAAOC,OAAQ,YAAa,CAE5B,MAAMC,oBAAsBP,cAGzB,CACDQ,OAAQ,MACRC,QAAS,KAAO,CAClB,GAgDA,MAAMC,aAAe,CAAC,CAAEC,QAAQ,CAAqB,IACnD,KAAM,CAACH,OAAQC,QAAQ,CAAGP,SAAS,OACnC,MAAMU,IAAMR,OAAuB,MAEnCD,UAAU,KACR,MAAMU,aAAe,AAACC,IACpB,GAAIF,IAAIG,OAAO,EAAEC,SAASF,EAAEG,MAAM,EAAW,OAC7CR,QAAQ,MACV,EACAS,SAASC,gBAAgB,CAAC,QAASN,cACnC,MAAO,IAAMK,SAASE,mBAAmB,CAAC,QAASP,aACrD,EAAG,EAAE,EAEL,OACE,oBAACN,oBAAoBc,QAAQ,EAACC,MAAO,CAAEd,OAAQC,OAAQ,GACrD,oBAACc,OAAIC,GAAG,gBAAgBC,UAAU,WAAWb,IAAKA,KAC/CD,UAIT,EAEA,MAAMe,QAAU,CAAC,CACff,QAAQ,CACRgB,kBAAoB,EAAE,CACtBC,WAAW,CACE,IACb,KAAM,CAAEpB,MAAM,CAAEC,OAAO,CAAE,CAAGR,WAAWM,qBAEvC,OACE,oBAACsB,UACCL,GAAG,eACHM,aAAYF,YACZG,QAAS,IAAMtB,QAAQ,CAACD,QACxBiB,UAAWnB,GACT,wGACAqB,oBAGDhB,SACD,oBAACN,MACC2B,KACExB,OAAS,2BAA6B,6BAExCyB,KAAK,UACLC,cAAc,4CAItB,EAEA,MAAMC,QAAU,CAAC,CACfxB,QAAQ,CACRyB,eAAiB,OAAO,CACxBC,iBAAiB,CACJ,IACb,KAAM,CAAE7B,MAAM,CAAE,CAAGP,WAAWM,qBAE9B,GAAI,CAACC,OAAQ,CACX,OAAO,IACT,CAEA,OACE,oBAACe,OACCC,GAAG,eACHc,KAAK,OACLb,UAAWnB,GACT,iJACA8B,iBAAmB,QAAU,UAAY,SACzCC,oBAGD1B,SAGP,EAEA,MAAM4B,KAAO,CAAC,CAAEC,GAAG,CAAEC,KAAK,CAAEC,QAAQ,CAAEC,QAAQ,CAAEhC,QAAQ,CAAa,IACnE,OACE,oBAACiC,KACCC,KAAML,IACNf,UAAU,sOAGV,oBAACqB,KAAErB,UAAU,QACVgB,MACAE,SACC,oBAACtC,MACC2B,KAAMW,SACNV,KAAK,OACLC,cAAc,uFAEd,MAELQ,SAAW,oBAACI,KAAErB,UAAU,mBAAmBiB,UAAgB,KAC3D/B,SAGP,CAEAD,CAAAA,aAAagB,OAAO,CAAGA,OACvBhB,CAAAA,aAAayB,OAAO,CAAGA,OACvBzB,CAAAA,aAAa6B,IAAI,CAAGA,IAEpB,gBAAe7B,YAAa"}
1
+ {"version":3,"sources":["../../src/core/DropdownMenu.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useState,\n useEffect,\n useRef,\n ReactNode,\n Dispatch,\n} from \"react\";\nimport Icon from \"./Icon\";\nimport { IconName } from \"./Icon/types\";\nimport cn from \"./utils/cn\";\n\nconst DropdownMenuContext = createContext<{\n isOpen: boolean;\n setOpen: Dispatch<React.SetStateAction<boolean>>;\n}>({\n isOpen: false,\n setOpen: () => {},\n});\n\ntype DropdownMenuProps = {\n /**\n * The content to be displayed within the dropdown menu.\n */\n children: ReactNode;\n};\n\ntype TriggerProps = {\n /**\n * The content to be displayed within the trigger element.\n */\n children: ReactNode;\n /**\n * Additional class names to apply to the trigger element.\n */\n triggerClassNames?: string;\n /**\n * A description for the trigger element, used for accessibility purposes.\n */\n description?: string;\n};\n\ntype ContentProps = {\n /**\n * The content to be displayed within the dropdown menu.\n */\n children: ReactNode;\n /**\n * The position of the dropdown menu relative to the trigger element.\n * Defaults to \"right\".\n */\n anchorPosition?: string;\n /**\n * Additional class names to apply to the content container.\n */\n contentClassNames?: string;\n};\n\ntype LinkProps = {\n url: string;\n title: string;\n subtitle?: string;\n iconName?: IconName;\n children?: ReactNode;\n};\n\nconst DropdownMenu = ({ children }: DropdownMenuProps) => {\n const [isOpen, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const clickHandler = (e: MouseEvent) => {\n if (ref.current?.contains(e.target as Node)) return;\n setOpen(false);\n };\n document.addEventListener(\"click\", clickHandler);\n return () => document.removeEventListener(\"click\", clickHandler);\n }, []);\n\n return (\n <DropdownMenuContext.Provider value={{ isOpen, setOpen }}>\n <div id=\"dropdown-menu\" className=\"relative\" ref={ref}>\n {children}\n </div>\n </DropdownMenuContext.Provider>\n );\n};\n\nconst Trigger = ({\n children,\n triggerClassNames = \"\",\n description,\n}: TriggerProps) => {\n const { isOpen, setOpen } = useContext(DropdownMenuContext);\n\n return (\n <button\n id=\"menu-trigger\"\n aria-label={description}\n onClick={() => setOpen(!isOpen)}\n className={cn(\n \"flex items-center ui-text-label3 font-semibold text-neutral-1000 dark:text-neutral-300 focus:outline-none\",\n triggerClassNames,\n )}\n >\n {children}\n <Icon\n name={\n isOpen ? \"icon-gui-chevron-up-mini\" : \"icon-gui-chevron-down-mini\"\n }\n size=\"1.25rem\"\n additionalCSS=\"text-neutral-1300 dark:text-neutral-000\"\n />\n </button>\n );\n};\n\nconst Content = ({\n children,\n anchorPosition = \"right\",\n contentClassNames,\n}: ContentProps) => {\n const { isOpen } = useContext(DropdownMenuContext);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <div\n id=\"menu-content\"\n role=\"menu\"\n className={cn(\n \"flex flex-col absolute z-10 border border-neutral-400 dark:border-neutral-900 bg-neutral-000 dark:bg-neutral-1300 rounded-lg ui-shadow-md-soft\",\n anchorPosition === \"right\" ? \"right-0\" : \"left-0\",\n contentClassNames,\n )}\n >\n {children}\n </div>\n );\n};\n\nconst Link = ({ url, title, subtitle, iconName, children }: LinkProps) => {\n return (\n <a\n href={url}\n className=\"menu-link group block p-2 rounded-lg\n hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 hover:dark:text-neutral-000\"\n >\n <p className=\"mb-1\">\n {title}\n {iconName ? (\n <Icon\n name={iconName}\n size=\"1rem\"\n additionalCSS=\"align-middle ml-2 relative -top-px -left-1 text-neutral-1300 dark:text-neutral-000\"\n />\n ) : null}\n </p>\n {subtitle ? <p className=\"ui-text-p3 mb-4\">{subtitle}</p> : null}\n {children}\n </a>\n );\n};\n\nDropdownMenu.Trigger = Trigger;\nDropdownMenu.Content = Content;\nDropdownMenu.Link = Link;\n\nexport default DropdownMenu;\n"],"names":["React","createContext","useContext","useState","useEffect","useRef","Icon","cn","DropdownMenuContext","isOpen","setOpen","DropdownMenu","children","ref","clickHandler","e","current","contains","target","document","addEventListener","removeEventListener","Provider","value","div","id","className","Trigger","triggerClassNames","description","button","aria-label","onClick","name","size","additionalCSS","Content","anchorPosition","contentClassNames","role","Link","url","title","subtitle","iconName","a","href","p"],"mappings":"AAAA,OAAOA,OACLC,aAAa,CACbC,UAAU,CACVC,QAAQ,CACRC,SAAS,CACTC,MAAM,KAGD,OAAQ,AACf,QAAOC,SAAU,QAAS,AAE1B,QAAOC,OAAQ,YAAa,CAE5B,MAAMC,oBAAsBP,cAGzB,CACDQ,OAAQ,MACRC,QAAS,KAAO,CAClB,GAgDA,MAAMC,aAAe,CAAC,CAAEC,QAAQ,CAAqB,IACnD,KAAM,CAACH,OAAQC,QAAQ,CAAGP,SAAS,OACnC,MAAMU,IAAMR,OAAuB,MAEnCD,UAAU,KACR,MAAMU,aAAe,AAACC,IACpB,GAAIF,IAAIG,OAAO,EAAEC,SAASF,EAAEG,MAAM,EAAW,OAC7CR,QAAQ,MACV,EACAS,SAASC,gBAAgB,CAAC,QAASN,cACnC,MAAO,IAAMK,SAASE,mBAAmB,CAAC,QAASP,aACrD,EAAG,EAAE,EAEL,OACE,oBAACN,oBAAoBc,QAAQ,EAACC,MAAO,CAAEd,OAAQC,OAAQ,GACrD,oBAACc,OAAIC,GAAG,gBAAgBC,UAAU,WAAWb,IAAKA,KAC/CD,UAIT,EAEA,MAAMe,QAAU,CAAC,CACff,QAAQ,CACRgB,kBAAoB,EAAE,CACtBC,WAAW,CACE,IACb,KAAM,CAAEpB,MAAM,CAAEC,OAAO,CAAE,CAAGR,WAAWM,qBAEvC,OACE,oBAACsB,UACCL,GAAG,eACHM,aAAYF,YACZG,QAAS,IAAMtB,QAAQ,CAACD,QACxBiB,UAAWnB,GACT,4GACAqB,oBAGDhB,SACD,oBAACN,MACC2B,KACExB,OAAS,2BAA6B,6BAExCyB,KAAK,UACLC,cAAc,4CAItB,EAEA,MAAMC,QAAU,CAAC,CACfxB,QAAQ,CACRyB,eAAiB,OAAO,CACxBC,iBAAiB,CACJ,IACb,KAAM,CAAE7B,MAAM,CAAE,CAAGP,WAAWM,qBAE9B,GAAI,CAACC,OAAQ,CACX,OAAO,IACT,CAEA,OACE,oBAACe,OACCC,GAAG,eACHc,KAAK,OACLb,UAAWnB,GACT,iJACA8B,iBAAmB,QAAU,UAAY,SACzCC,oBAGD1B,SAGP,EAEA,MAAM4B,KAAO,CAAC,CAAEC,GAAG,CAAEC,KAAK,CAAEC,QAAQ,CAAEC,QAAQ,CAAEhC,QAAQ,CAAa,IACnE,OACE,oBAACiC,KACCC,KAAML,IACNf,UAAU,sOAGV,oBAACqB,KAAErB,UAAU,QACVgB,MACAE,SACC,oBAACtC,MACC2B,KAAMW,SACNV,KAAK,OACLC,cAAc,uFAEd,MAELQ,SAAW,oBAACI,KAAErB,UAAU,mBAAmBiB,UAAgB,KAC3D/B,SAGP,CAEAD,CAAAA,aAAagB,OAAO,CAAGA,OACvBhB,CAAAA,aAAayB,OAAO,CAAGA,OACvBzB,CAAAA,aAAa6B,IAAI,CAAGA,IAEpB,gBAAe7B,YAAa"}
@@ -1,2 +1,2 @@
1
- import React from"react";import Icon from"./Icon";import cn from"./utils/cn";const buildTargetAndRel=(url,newWindow)=>{const props={};if(newWindow){props.target="_blank";if(url.startsWith("/")&&!url.startsWith("//")){props.rel="noopener"}else{props.rel="noopenner noreferrer"}}return props};const FeaturedLink=({url,textSize="text-p2",iconColor,flush=false,reverse=false,additionalCSS="",newWindow=false,onClick=undefined,children,disabled=false,iconClassName=""})=>{const targetAndRel=buildTargetAndRel(url,newWindow);return React.createElement("a",{...onClick?{}:{href:url},className:cn("font-sans font-bold block group/featured-link",{"text-gui-disabled-light dark:text-gui-disabled-dark pointer-events-none":disabled},{"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus":!disabled},{"py-2":!flush},`ui-${textSize}`,additionalCSS),style:{"--featured-link-icon-size":`var(${textSize.replace("text","--fs")})`},...targetAndRel,onClick:onClick,onKeyDown:onClick?e=>{if(e.key==="Enter"||e.key===" "){e.preventDefault();onClick()}}:undefined,role:onClick&&!url?"button":undefined},reverse?React.createElement(React.Fragment,null,React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:`calc(var(--featured-link-icon-size) * 1.25)`,color:iconColor,additionalCSS:cn("align-middle mr-2 relative -top-px -right-1 transition-[right] transform rotate-180",{"group-hover/featured-link:right-0":!disabled},iconClassName)}),children):React.createElement(React.Fragment,null,children,React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:`calc(var(--featured-link-icon-size) * 1.25)`,color:iconColor,additionalCSS:cn("align-middle ml-2 relative -top-px -left-1 transition-[left]",{"group-hover/featured-link:left-0":!disabled},iconClassName)})))};export default FeaturedLink;
1
+ import React from"react";import Icon from"./Icon";import cn from"./utils/cn";const buildTargetAndRel=(url,newWindow)=>{const props={};if(newWindow){props.target="_blank";if(url.startsWith("/")&&!url.startsWith("//")){props.rel="noopener"}else{props.rel="noopenner noreferrer"}}return props};const FeaturedLink=({url,textSize="text-p2",iconColor,flush=false,reverse=false,additionalCSS="",newWindow=false,onClick=undefined,children,disabled=false,iconClassName=""})=>{const targetAndRel=buildTargetAndRel(url,newWindow);return React.createElement("a",{...onClick?{}:{href:url},className:cn("font-sans font-semibold block group/featured-link",{"text-gui-disabled-light dark:text-gui-disabled-dark pointer-events-none":disabled},{"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus":!disabled},{"py-2":!flush},`ui-${textSize}`,additionalCSS),style:{"--featured-link-icon-size":`var(${textSize.replace("text","--fs")})`},...targetAndRel,onClick:onClick,onKeyDown:onClick?e=>{if(e.key==="Enter"||e.key===" "){e.preventDefault();onClick()}}:undefined,role:onClick&&!url?"button":undefined},reverse?React.createElement(React.Fragment,null,React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:`calc(var(--featured-link-icon-size) * 1.25)`,color:iconColor,additionalCSS:cn("align-middle mr-2 relative -top-px -right-1 transition-[right] transform rotate-180",{"group-hover/featured-link:right-0":!disabled},iconClassName)}),children):React.createElement(React.Fragment,null,children,React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:`calc(var(--featured-link-icon-size) * 1.25)`,color:iconColor,additionalCSS:cn("align-middle ml-2 relative -top-px -left-1 transition-[left]",{"group-hover/featured-link:left-0":!disabled},iconClassName)})))};export default FeaturedLink;
2
2
  //# sourceMappingURL=FeaturedLink.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/FeaturedLink.tsx"],"sourcesContent":["import React, { CSSProperties, ReactNode } from \"react\";\n\nimport Icon from \"./Icon\";\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport cn from \"./utils/cn\";\n\ntype FeaturedLinkProps = {\n url: string;\n children: ReactNode;\n textSize?: string;\n iconColor?: ColorClass | ColorThemeSet;\n flush?: boolean;\n reverse?: boolean;\n additionalCSS?: string;\n newWindow?: boolean;\n onClick?: () => void;\n disabled?: boolean;\n /**\n * Optional class name for the icon.\n */\n iconClassName?: string;\n};\n\ntype TargetProps = { target?: string; rel?: string };\n\n// When generating links with target=_blank, we only add `noreferrer` to\n// links that don't start with `/`, so we can continue tracking referrers\n// across our own domains\nconst buildTargetAndRel = (url: string, newWindow: boolean) => {\n const props: TargetProps = {};\n\n if (newWindow) {\n props.target = \"_blank\";\n\n if (url.startsWith(\"/\") && !url.startsWith(\"//\")) {\n props.rel = \"noopener\";\n } else {\n props.rel = \"noopenner noreferrer\";\n }\n }\n\n return props;\n};\n\nconst FeaturedLink = ({\n url,\n textSize = \"text-p2\",\n iconColor,\n flush = false,\n reverse = false,\n additionalCSS = \"\",\n newWindow = false,\n onClick = undefined,\n children,\n disabled = false,\n iconClassName = \"\",\n}: FeaturedLinkProps) => {\n const targetAndRel = buildTargetAndRel(url, newWindow);\n\n return (\n <a\n {...(onClick ? {} : { href: url })}\n className={cn(\n \"font-sans font-bold block group/featured-link\",\n {\n \"text-gui-disabled-light dark:text-gui-disabled-dark pointer-events-none\":\n disabled,\n },\n {\n \"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus\":\n !disabled,\n },\n { \"py-2\": !flush },\n `ui-${textSize}`,\n additionalCSS,\n )}\n style={\n {\n \"--featured-link-icon-size\": `var(${textSize.replace(\n \"text\",\n \"--fs\",\n )})`,\n } as CSSProperties\n }\n {...targetAndRel}\n onClick={onClick}\n onKeyDown={\n onClick\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n }\n : undefined\n }\n role={onClick && !url ? \"button\" : undefined}\n >\n {reverse ? (\n <>\n <Icon\n name=\"icon-gui-arrow-long-right-outline\"\n size={`calc(var(--featured-link-icon-size) * 1.25)`}\n color={iconColor}\n additionalCSS={cn(\n \"align-middle mr-2 relative -top-px -right-1 transition-[right] transform rotate-180\",\n { \"group-hover/featured-link:right-0\": !disabled },\n iconClassName,\n )}\n />\n {children}\n </>\n ) : (\n <>\n {children}\n <Icon\n name=\"icon-gui-arrow-long-right-outline\"\n size={`calc(var(--featured-link-icon-size) * 1.25)`}\n color={iconColor}\n additionalCSS={cn(\n \"align-middle ml-2 relative -top-px -left-1 transition-[left]\",\n {\n \"group-hover/featured-link:left-0\": !disabled,\n },\n iconClassName,\n )}\n />\n </>\n )}\n </a>\n );\n};\n\nexport default FeaturedLink;\n"],"names":["React","Icon","cn","buildTargetAndRel","url","newWindow","props","target","startsWith","rel","FeaturedLink","textSize","iconColor","flush","reverse","additionalCSS","onClick","undefined","children","disabled","iconClassName","targetAndRel","a","href","className","style","replace","onKeyDown","e","key","preventDefault","role","name","size","color"],"mappings":"AAAA,OAAOA,UAAyC,OAAQ,AAExD,QAAOC,SAAU,QAAS,AAE1B,QAAOC,OAAQ,YAAa,CAwB5B,MAAMC,kBAAoB,CAACC,IAAaC,aACtC,MAAMC,MAAqB,CAAC,EAE5B,GAAID,UAAW,CACbC,MAAMC,MAAM,CAAG,SAEf,GAAIH,IAAII,UAAU,CAAC,MAAQ,CAACJ,IAAII,UAAU,CAAC,MAAO,CAChDF,MAAMG,GAAG,CAAG,UACd,KAAO,CACLH,MAAMG,GAAG,CAAG,sBACd,CACF,CAEA,OAAOH,KACT,EAEA,MAAMI,aAAe,CAAC,CACpBN,GAAG,CACHO,SAAW,SAAS,CACpBC,SAAS,CACTC,MAAQ,KAAK,CACbC,QAAU,KAAK,CACfC,cAAgB,EAAE,CAClBV,UAAY,KAAK,CACjBW,QAAUC,SAAS,CACnBC,QAAQ,CACRC,SAAW,KAAK,CAChBC,cAAgB,EAAE,CACA,IAClB,MAAMC,aAAelB,kBAAkBC,IAAKC,WAE5C,OACE,oBAACiB,KACE,GAAIN,QAAU,CAAC,EAAI,CAAEO,KAAMnB,GAAI,CAAC,CACjCoB,UAAWtB,GACT,gDACA,CACE,0EACEiB,QACJ,EACA,CACE,gHACE,CAACA,QACL,EACA,CAAE,OAAQ,CAACN,KAAM,EACjB,CAAC,GAAG,EAAEF,SAAS,CAAC,CAChBI,eAEFU,MACE,CACE,4BAA6B,CAAC,IAAI,EAAEd,SAASe,OAAO,CAClD,OACA,QACA,CAAC,CAAC,AACN,EAED,GAAGL,YAAY,CAChBL,QAASA,QACTW,UACEX,QACI,AAACY,IACC,GAAIA,EAAEC,GAAG,GAAK,SAAWD,EAAEC,GAAG,GAAK,IAAK,CACtCD,EAAEE,cAAc,GAChBd,SACF,CACF,EACAC,UAENc,KAAMf,SAAW,CAACZ,IAAM,SAAWa,WAElCH,QACC,wCACE,oBAACb,MACC+B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOtB,UACPG,cAAeb,GACb,sFACA,CAAE,oCAAqC,CAACiB,QAAS,EACjDC,iBAGHF,UAGH,wCACGA,SACD,oBAACjB,MACC+B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOtB,UACPG,cAAeb,GACb,+DACA,CACE,mCAAoC,CAACiB,QACvC,EACAC,kBAOd,CAEA,gBAAeV,YAAa"}
1
+ {"version":3,"sources":["../../src/core/FeaturedLink.tsx"],"sourcesContent":["import React, { CSSProperties, ReactNode } from \"react\";\n\nimport Icon from \"./Icon\";\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport cn from \"./utils/cn\";\n\ntype FeaturedLinkProps = {\n url: string;\n children: ReactNode;\n textSize?: string;\n iconColor?: ColorClass | ColorThemeSet;\n flush?: boolean;\n reverse?: boolean;\n additionalCSS?: string;\n newWindow?: boolean;\n onClick?: () => void;\n disabled?: boolean;\n /**\n * Optional class name for the icon.\n */\n iconClassName?: string;\n};\n\ntype TargetProps = { target?: string; rel?: string };\n\n// When generating links with target=_blank, we only add `noreferrer` to\n// links that don't start with `/`, so we can continue tracking referrers\n// across our own domains\nconst buildTargetAndRel = (url: string, newWindow: boolean) => {\n const props: TargetProps = {};\n\n if (newWindow) {\n props.target = \"_blank\";\n\n if (url.startsWith(\"/\") && !url.startsWith(\"//\")) {\n props.rel = \"noopener\";\n } else {\n props.rel = \"noopenner noreferrer\";\n }\n }\n\n return props;\n};\n\nconst FeaturedLink = ({\n url,\n textSize = \"text-p2\",\n iconColor,\n flush = false,\n reverse = false,\n additionalCSS = \"\",\n newWindow = false,\n onClick = undefined,\n children,\n disabled = false,\n iconClassName = \"\",\n}: FeaturedLinkProps) => {\n const targetAndRel = buildTargetAndRel(url, newWindow);\n\n return (\n <a\n {...(onClick ? {} : { href: url })}\n className={cn(\n \"font-sans font-semibold block group/featured-link\",\n {\n \"text-gui-disabled-light dark:text-gui-disabled-dark pointer-events-none\":\n disabled,\n },\n {\n \"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus\":\n !disabled,\n },\n { \"py-2\": !flush },\n `ui-${textSize}`,\n additionalCSS,\n )}\n style={\n {\n \"--featured-link-icon-size\": `var(${textSize.replace(\n \"text\",\n \"--fs\",\n )})`,\n } as CSSProperties\n }\n {...targetAndRel}\n onClick={onClick}\n onKeyDown={\n onClick\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onClick();\n }\n }\n : undefined\n }\n role={onClick && !url ? \"button\" : undefined}\n >\n {reverse ? (\n <>\n <Icon\n name=\"icon-gui-arrow-long-right-outline\"\n size={`calc(var(--featured-link-icon-size) * 1.25)`}\n color={iconColor}\n additionalCSS={cn(\n \"align-middle mr-2 relative -top-px -right-1 transition-[right] transform rotate-180\",\n { \"group-hover/featured-link:right-0\": !disabled },\n iconClassName,\n )}\n />\n {children}\n </>\n ) : (\n <>\n {children}\n <Icon\n name=\"icon-gui-arrow-long-right-outline\"\n size={`calc(var(--featured-link-icon-size) * 1.25)`}\n color={iconColor}\n additionalCSS={cn(\n \"align-middle ml-2 relative -top-px -left-1 transition-[left]\",\n {\n \"group-hover/featured-link:left-0\": !disabled,\n },\n iconClassName,\n )}\n />\n </>\n )}\n </a>\n );\n};\n\nexport default FeaturedLink;\n"],"names":["React","Icon","cn","buildTargetAndRel","url","newWindow","props","target","startsWith","rel","FeaturedLink","textSize","iconColor","flush","reverse","additionalCSS","onClick","undefined","children","disabled","iconClassName","targetAndRel","a","href","className","style","replace","onKeyDown","e","key","preventDefault","role","name","size","color"],"mappings":"AAAA,OAAOA,UAAyC,OAAQ,AAExD,QAAOC,SAAU,QAAS,AAE1B,QAAOC,OAAQ,YAAa,CAwB5B,MAAMC,kBAAoB,CAACC,IAAaC,aACtC,MAAMC,MAAqB,CAAC,EAE5B,GAAID,UAAW,CACbC,MAAMC,MAAM,CAAG,SAEf,GAAIH,IAAII,UAAU,CAAC,MAAQ,CAACJ,IAAII,UAAU,CAAC,MAAO,CAChDF,MAAMG,GAAG,CAAG,UACd,KAAO,CACLH,MAAMG,GAAG,CAAG,sBACd,CACF,CAEA,OAAOH,KACT,EAEA,MAAMI,aAAe,CAAC,CACpBN,GAAG,CACHO,SAAW,SAAS,CACpBC,SAAS,CACTC,MAAQ,KAAK,CACbC,QAAU,KAAK,CACfC,cAAgB,EAAE,CAClBV,UAAY,KAAK,CACjBW,QAAUC,SAAS,CACnBC,QAAQ,CACRC,SAAW,KAAK,CAChBC,cAAgB,EAAE,CACA,IAClB,MAAMC,aAAelB,kBAAkBC,IAAKC,WAE5C,OACE,oBAACiB,KACE,GAAIN,QAAU,CAAC,EAAI,CAAEO,KAAMnB,GAAI,CAAC,CACjCoB,UAAWtB,GACT,oDACA,CACE,0EACEiB,QACJ,EACA,CACE,gHACE,CAACA,QACL,EACA,CAAE,OAAQ,CAACN,KAAM,EACjB,CAAC,GAAG,EAAEF,SAAS,CAAC,CAChBI,eAEFU,MACE,CACE,4BAA6B,CAAC,IAAI,EAAEd,SAASe,OAAO,CAClD,OACA,QACA,CAAC,CAAC,AACN,EAED,GAAGL,YAAY,CAChBL,QAASA,QACTW,UACEX,QACI,AAACY,IACC,GAAIA,EAAEC,GAAG,GAAK,SAAWD,EAAEC,GAAG,GAAK,IAAK,CACtCD,EAAEE,cAAc,GAChBd,SACF,CACF,EACAC,UAENc,KAAMf,SAAW,CAACZ,IAAM,SAAWa,WAElCH,QACC,wCACE,oBAACb,MACC+B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOtB,UACPG,cAAeb,GACb,sFACA,CAAE,oCAAqC,CAACiB,QAAS,EACjDC,iBAGHF,UAGH,wCACGA,SACD,oBAACjB,MACC+B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOtB,UACPG,cAAeb,GACb,+DACA,CACE,mCAAoC,CAACiB,QACvC,EACAC,kBAOd,CAEA,gBAAeV,YAAa"}
package/core/Flyout.js CHANGED
@@ -1,2 +1,2 @@
1
- import React,{useState}from"react";import{NavigationMenu,NavigationMenuItem,NavigationMenuList,NavigationMenuTrigger,NavigationMenuContent,NavigationMenuViewport,NavigationMenuLink}from"@radix-ui/react-navigation-menu";import cn from"./utils/cn";import{componentMaxHeight,HEADER_HEIGHT}from"./utils/heights";const DEFAULT_MENU_LINK_STYLING="ui-text-label3 font-bold text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 px-3 py-2 flex items-center justify-between";const DEFAULT_VIEWPORT_STYLING="relative overflow-hidden w-full h-[var(--radix-navigation-menu-viewport-height)] origin-[top_center] transition-[width,_height] duration-300 data-[state=closed]:animate-scale-out data-[state=open]:animate-scale-in sm:w-[var(--radix-navigation-menu-viewport-width)]";const PANEL_ANIMATION="data-[motion=from-end]:animate-enter-from-right data-[motion=from-start]:animate-enter-from-left data-[motion=to-end]:animate-exit-to-right data-[motion=to-start]:animate-exit-to-left";const FlyOverlay=({className,fadingOut})=>React.createElement("div",{className:cn("absolute left-0 right-0 h-screen w-full opacity-0",{"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]":!fadingOut,"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]":fadingOut},className),style:{height:componentMaxHeight(HEADER_HEIGHT),top:HEADER_HEIGHT}});const Flyout=({menuItems,className,flyOutClassName,menuLinkClassName,viewPortClassName})=>{const[isOpen,setIsOpen]=useState(false);const[fadingOut,setFadingOut]=useState(false);const closeMenu=()=>{setFadingOut(true);setTimeout(()=>{setIsOpen(false);setFadingOut(false)},150)};return React.createElement(React.Fragment,null,React.createElement(NavigationMenu,{className:cn(className,"flex w-full"),onValueChange:val=>val?setIsOpen(true):closeMenu(),delayDuration:0},React.createElement(NavigationMenuList,{className:"flex list-none center"},menuItems.map(({name,content,link,panelClassName})=>content?React.createElement(NavigationMenuItem,{key:name},React.createElement(NavigationMenuTrigger,{onPointerDown:event=>{if(event.pointerType==="mouse"){event.preventDefault()}},className:cn("group outline-none focus:outline-none select-none cursor-pointer relative","rounded-md hover:bg-neutral-100 dark:hover:bg-neutral-1200","[&[data-state=open]]:bg-neutral-100 dark:[&[data-state=open]]:bg-neutral-1200","[&[data-state=open]]:text-neutral-1300 dark:[&[data-state=open]]:text-neutral-000",DEFAULT_MENU_LINK_STYLING,menuLinkClassName)},name),React.createElement(NavigationMenuContent,{className:cn("absolute right-0 top-0 z-10",PANEL_ANIMATION,panelClassName)},content)):React.createElement(NavigationMenuLink,{key:name,href:link,className:cn(DEFAULT_MENU_LINK_STYLING,menuLinkClassName)},name))),React.createElement("div",{className:cn("absolute top-full",flyOutClassName)},React.createElement(NavigationMenuViewport,{className:cn(DEFAULT_VIEWPORT_STYLING,viewPortClassName)}))),isOpen?React.createElement(FlyOverlay,{className:"bg-neutral-1300 opacity-10 z-20 h-screen mix-blend-multiply",fadingOut:fadingOut}):null)};export default Flyout;
1
+ import React,{useState}from"react";import{NavigationMenu,NavigationMenuItem,NavigationMenuList,NavigationMenuTrigger,NavigationMenuContent,NavigationMenuViewport,NavigationMenuLink}from"@radix-ui/react-navigation-menu";import cn from"./utils/cn";import{componentMaxHeight,HEADER_HEIGHT}from"./utils/heights";const DEFAULT_MENU_LINK_STYLING="ui-text-label3 font-semibold text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 px-3 py-2 flex items-center justify-between";const DEFAULT_VIEWPORT_STYLING="relative overflow-hidden w-full h-[var(--radix-navigation-menu-viewport-height)] origin-[top_center] transition-[width,_height] duration-300 data-[state=closed]:animate-scale-out data-[state=open]:animate-scale-in sm:w-[var(--radix-navigation-menu-viewport-width)]";const PANEL_ANIMATION="data-[motion=from-end]:animate-enter-from-right data-[motion=from-start]:animate-enter-from-left data-[motion=to-end]:animate-exit-to-right data-[motion=to-start]:animate-exit-to-left";const FlyOverlay=({className,fadingOut})=>React.createElement("div",{className:cn("absolute left-0 right-0 h-screen w-full opacity-0",{"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]":!fadingOut,"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]":fadingOut},className),style:{height:componentMaxHeight(HEADER_HEIGHT),top:HEADER_HEIGHT}});const Flyout=({menuItems,className,flyOutClassName,menuLinkClassName,viewPortClassName})=>{const[isOpen,setIsOpen]=useState(false);const[fadingOut,setFadingOut]=useState(false);const closeMenu=()=>{setFadingOut(true);setTimeout(()=>{setIsOpen(false);setFadingOut(false)},150)};return React.createElement(React.Fragment,null,React.createElement(NavigationMenu,{className:cn(className,"flex w-full"),onValueChange:val=>val?setIsOpen(true):closeMenu(),delayDuration:50,skipDelayDuration:0},React.createElement(NavigationMenuList,{className:"flex list-none center"},menuItems.map(({name,content,link,panelClassName})=>content?React.createElement(NavigationMenuItem,{key:name},React.createElement(NavigationMenuTrigger,{onPointerDown:event=>{if(event.pointerType==="mouse"){event.preventDefault()}},className:cn("group outline-none focus:outline-none select-none cursor-pointer relative","rounded-md hover:bg-neutral-100 dark:hover:bg-neutral-1200","[&[data-state=open]]:bg-neutral-100 dark:[&[data-state=open]]:bg-neutral-1200","[&[data-state=open]]:text-neutral-1300 dark:[&[data-state=open]]:text-neutral-000",DEFAULT_MENU_LINK_STYLING,menuLinkClassName)},name),React.createElement(NavigationMenuContent,{className:cn("absolute right-0 top-0 z-10",PANEL_ANIMATION,panelClassName)},content)):React.createElement(NavigationMenuLink,{key:name,href:link,className:cn(DEFAULT_MENU_LINK_STYLING,menuLinkClassName)},name))),React.createElement("div",{className:cn("absolute top-full",flyOutClassName)},React.createElement(NavigationMenuViewport,{className:cn(DEFAULT_VIEWPORT_STYLING,viewPortClassName)}))),isOpen?React.createElement(FlyOverlay,{className:"bg-neutral-1300 opacity-10 z-20 h-screen mix-blend-multiply",fadingOut:fadingOut}):null)};export default Flyout;
2
2
  //# sourceMappingURL=Flyout.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/Flyout.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport {\n NavigationMenu,\n NavigationMenuItem,\n NavigationMenuList,\n NavigationMenuTrigger,\n NavigationMenuContent,\n NavigationMenuViewport,\n NavigationMenuLink,\n} from \"@radix-ui/react-navigation-menu\";\nimport cn from \"./utils/cn\";\nimport { componentMaxHeight, HEADER_HEIGHT } from \"./utils/heights\";\n\n/**\n * Props for the Flyout component.\n */\ntype FlyoutProps = {\n /**\n * Array of menu items to be displayed in the flyout.\n */\n menuItems: {\n /**\n * Name for the menu item.\n */\n name: string;\n /**\n * Optional content to be displayed in the flyout panel.\n */\n content?: React.ReactNode;\n /**\n * Optional link for the menu item.\n */\n link?: string;\n /**\n * Optional styling for the flyout panel.\n */\n panelClassName?: string;\n }[];\n /**\n * Optional class name for the flyout container.\n */\n className?: string;\n /**\n * Optional class name for the flyout element.\n */\n flyOutClassName?: string;\n /**\n * Optional class name for the menu link.\n */\n menuLinkClassName?: string;\n /**\n * Optional class name for the viewport.\n */\n viewPortClassName?: string;\n};\n\nconst DEFAULT_MENU_LINK_STYLING =\n \"ui-text-label3 font-bold text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 px-3 py-2 flex items-center justify-between\";\nconst DEFAULT_VIEWPORT_STYLING =\n \"relative overflow-hidden w-full h-[var(--radix-navigation-menu-viewport-height)] origin-[top_center] transition-[width,_height] duration-300 data-[state=closed]:animate-scale-out data-[state=open]:animate-scale-in sm:w-[var(--radix-navigation-menu-viewport-width)]\";\nconst PANEL_ANIMATION =\n \"data-[motion=from-end]:animate-enter-from-right data-[motion=from-start]:animate-enter-from-left data-[motion=to-end]:animate-exit-to-right data-[motion=to-start]:animate-exit-to-left\";\n\nconst FlyOverlay = ({\n className,\n fadingOut,\n}: {\n className: string;\n fadingOut: boolean;\n}) => (\n <div\n className={cn(\n \"absolute left-0 right-0 h-screen w-full opacity-0\",\n {\n \"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]\": !fadingOut,\n \"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]\": fadingOut,\n },\n className,\n )}\n style={{ height: componentMaxHeight(HEADER_HEIGHT), top: HEADER_HEIGHT }}\n ></div>\n);\n\nconst Flyout = ({\n menuItems,\n className,\n flyOutClassName,\n menuLinkClassName,\n viewPortClassName,\n}: FlyoutProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [fadingOut, setFadingOut] = useState(false);\n\n const closeMenu = () => {\n setFadingOut(true);\n\n setTimeout(() => {\n setIsOpen(false);\n setFadingOut(false);\n }, 150);\n };\n\n return (\n <>\n <NavigationMenu\n className={cn(className, \"flex w-full\")}\n onValueChange={(val) => (val ? setIsOpen(true) : closeMenu())}\n delayDuration={0}\n >\n <NavigationMenuList className=\"flex list-none center\">\n {menuItems.map(({ name, content, link, panelClassName }) =>\n content ? (\n <NavigationMenuItem key={name}>\n <NavigationMenuTrigger\n onPointerDown={(event) => {\n if (event.pointerType === \"mouse\") {\n event.preventDefault();\n }\n }}\n className={cn(\n \"group outline-none focus:outline-none select-none cursor-pointer relative\",\n \"rounded-md hover:bg-neutral-100 dark:hover:bg-neutral-1200\",\n \"[&[data-state=open]]:bg-neutral-100 dark:[&[data-state=open]]:bg-neutral-1200\",\n \"[&[data-state=open]]:text-neutral-1300 dark:[&[data-state=open]]:text-neutral-000\",\n DEFAULT_MENU_LINK_STYLING,\n menuLinkClassName,\n )}\n >\n {name}\n </NavigationMenuTrigger>\n <NavigationMenuContent\n className={cn(\n \"absolute right-0 top-0 z-10\",\n PANEL_ANIMATION,\n panelClassName,\n )}\n >\n {content}\n </NavigationMenuContent>\n </NavigationMenuItem>\n ) : (\n <NavigationMenuLink\n key={name}\n href={link}\n className={cn(DEFAULT_MENU_LINK_STYLING, menuLinkClassName)}\n >\n {name}\n </NavigationMenuLink>\n ),\n )}\n </NavigationMenuList>\n\n <div className={cn(\"absolute top-full\", flyOutClassName)}>\n <NavigationMenuViewport\n className={cn(DEFAULT_VIEWPORT_STYLING, viewPortClassName)}\n />\n </div>\n </NavigationMenu>\n {isOpen ? (\n <FlyOverlay\n className=\"bg-neutral-1300 opacity-10 z-20 h-screen mix-blend-multiply\"\n fadingOut={fadingOut}\n />\n ) : null}\n </>\n );\n};\n\nexport default Flyout;\n"],"names":["React","useState","NavigationMenu","NavigationMenuItem","NavigationMenuList","NavigationMenuTrigger","NavigationMenuContent","NavigationMenuViewport","NavigationMenuLink","cn","componentMaxHeight","HEADER_HEIGHT","DEFAULT_MENU_LINK_STYLING","DEFAULT_VIEWPORT_STYLING","PANEL_ANIMATION","FlyOverlay","className","fadingOut","div","style","height","top","Flyout","menuItems","flyOutClassName","menuLinkClassName","viewPortClassName","isOpen","setIsOpen","setFadingOut","closeMenu","setTimeout","onValueChange","val","delayDuration","map","name","content","link","panelClassName","key","onPointerDown","event","pointerType","preventDefault","href"],"mappings":"AAAA,OAAOA,OAASC,QAAQ,KAAQ,OAAQ,AACxC,QACEC,cAAc,CACdC,kBAAkB,CAClBC,kBAAkB,CAClBC,qBAAqB,CACrBC,qBAAqB,CACrBC,sBAAsB,CACtBC,kBAAkB,KACb,iCAAkC,AACzC,QAAOC,OAAQ,YAAa,AAC5B,QAASC,kBAAkB,CAAEC,aAAa,KAAQ,iBAAkB,CA6CpE,MAAMC,0BACJ,mKACF,MAAMC,yBACJ,2QACF,MAAMC,gBACJ,0LAEF,MAAMC,WAAa,CAAC,CAClBC,SAAS,CACTC,SAAS,CAIV,GACC,oBAACC,OACCF,UAAWP,GACT,oDACA,CACE,2DAA4D,CAACQ,UAC7D,4DAA6DA,SAC/D,EACAD,WAEFG,MAAO,CAAEC,OAAQV,mBAAmBC,eAAgBU,IAAKV,aAAc,IAI3E,MAAMW,OAAS,CAAC,CACdC,SAAS,CACTP,SAAS,CACTQ,eAAe,CACfC,iBAAiB,CACjBC,iBAAiB,CACL,IACZ,KAAM,CAACC,OAAQC,UAAU,CAAG3B,SAAS,OACrC,KAAM,CAACgB,UAAWY,aAAa,CAAG5B,SAAS,OAE3C,MAAM6B,UAAY,KAChBD,aAAa,MAEbE,WAAW,KACTH,UAAU,OACVC,aAAa,MACf,EAAG,IACL,EAEA,OACE,wCACE,oBAAC3B,gBACCc,UAAWP,GAAGO,UAAW,eACzBgB,cAAe,AAACC,KAASA,IAAML,UAAU,MAAQE,YACjDI,cAAe,GAEf,oBAAC9B,oBAAmBY,UAAU,yBAC3BO,UAAUY,GAAG,CAAC,CAAC,CAAEC,IAAI,CAAEC,OAAO,CAAEC,IAAI,CAAEC,cAAc,CAAE,GACrDF,QACE,oBAAClC,oBAAmBqC,IAAKJ,MACvB,oBAAC/B,uBACCoC,cAAe,AAACC,QACd,GAAIA,MAAMC,WAAW,GAAK,QAAS,CACjCD,MAAME,cAAc,EACtB,CACF,EACA5B,UAAWP,GACT,4EACA,6DACA,gFACA,oFACAG,0BACAa,oBAGDW,MAEH,oBAAC9B,uBACCU,UAAWP,GACT,8BACAK,gBACAyB,iBAGDF,UAIL,oBAAC7B,oBACCgC,IAAKJ,KACLS,KAAMP,KACNtB,UAAWP,GAAGG,0BAA2Ba,oBAExCW,QAMT,oBAAClB,OAAIF,UAAWP,GAAG,oBAAqBe,kBACtC,oBAACjB,wBACCS,UAAWP,GAAGI,yBAA0Ba,uBAI7CC,OACC,oBAACZ,YACCC,UAAU,8DACVC,UAAWA,YAEX,KAGV,CAEA,gBAAeK,MAAO"}
1
+ {"version":3,"sources":["../../src/core/Flyout.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport {\n NavigationMenu,\n NavigationMenuItem,\n NavigationMenuList,\n NavigationMenuTrigger,\n NavigationMenuContent,\n NavigationMenuViewport,\n NavigationMenuLink,\n} from \"@radix-ui/react-navigation-menu\";\nimport cn from \"./utils/cn\";\nimport { componentMaxHeight, HEADER_HEIGHT } from \"./utils/heights\";\n\n/**\n * Props for the Flyout component.\n */\ntype FlyoutProps = {\n /**\n * Array of menu items to be displayed in the flyout.\n */\n menuItems: {\n /**\n * Name for the menu item.\n */\n name: string;\n /**\n * Optional content to be displayed in the flyout panel.\n */\n content?: React.ReactNode;\n /**\n * Optional link for the menu item.\n */\n link?: string;\n /**\n * Optional styling for the flyout panel.\n */\n panelClassName?: string;\n }[];\n /**\n * Optional class name for the flyout container.\n */\n className?: string;\n /**\n * Optional class name for the flyout element.\n */\n flyOutClassName?: string;\n /**\n * Optional class name for the menu link.\n */\n menuLinkClassName?: string;\n /**\n * Optional class name for the viewport.\n */\n viewPortClassName?: string;\n};\n\nconst DEFAULT_MENU_LINK_STYLING =\n \"ui-text-label3 font-semibold text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 px-3 py-2 flex items-center justify-between\";\nconst DEFAULT_VIEWPORT_STYLING =\n \"relative overflow-hidden w-full h-[var(--radix-navigation-menu-viewport-height)] origin-[top_center] transition-[width,_height] duration-300 data-[state=closed]:animate-scale-out data-[state=open]:animate-scale-in sm:w-[var(--radix-navigation-menu-viewport-width)]\";\nconst PANEL_ANIMATION =\n \"data-[motion=from-end]:animate-enter-from-right data-[motion=from-start]:animate-enter-from-left data-[motion=to-end]:animate-exit-to-right data-[motion=to-start]:animate-exit-to-left\";\n\nconst FlyOverlay = ({\n className,\n fadingOut,\n}: {\n className: string;\n fadingOut: boolean;\n}) => (\n <div\n className={cn(\n \"absolute left-0 right-0 h-screen w-full opacity-0\",\n {\n \"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]\": !fadingOut,\n \"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]\": fadingOut,\n },\n className,\n )}\n style={{ height: componentMaxHeight(HEADER_HEIGHT), top: HEADER_HEIGHT }}\n ></div>\n);\n\nconst Flyout = ({\n menuItems,\n className,\n flyOutClassName,\n menuLinkClassName,\n viewPortClassName,\n}: FlyoutProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [fadingOut, setFadingOut] = useState(false);\n\n const closeMenu = () => {\n setFadingOut(true);\n\n setTimeout(() => {\n setIsOpen(false);\n setFadingOut(false);\n }, 150);\n };\n\n return (\n <>\n <NavigationMenu\n className={cn(className, \"flex w-full\")}\n onValueChange={(val) => (val ? setIsOpen(true) : closeMenu())}\n delayDuration={50}\n skipDelayDuration={0}\n >\n <NavigationMenuList className=\"flex list-none center\">\n {menuItems.map(({ name, content, link, panelClassName }) =>\n content ? (\n <NavigationMenuItem key={name}>\n <NavigationMenuTrigger\n onPointerDown={(event) => {\n if (event.pointerType === \"mouse\") {\n event.preventDefault();\n }\n }}\n className={cn(\n \"group outline-none focus:outline-none select-none cursor-pointer relative\",\n \"rounded-md hover:bg-neutral-100 dark:hover:bg-neutral-1200\",\n \"[&[data-state=open]]:bg-neutral-100 dark:[&[data-state=open]]:bg-neutral-1200\",\n \"[&[data-state=open]]:text-neutral-1300 dark:[&[data-state=open]]:text-neutral-000\",\n DEFAULT_MENU_LINK_STYLING,\n menuLinkClassName,\n )}\n >\n {name}\n </NavigationMenuTrigger>\n <NavigationMenuContent\n className={cn(\n \"absolute right-0 top-0 z-10\",\n PANEL_ANIMATION,\n panelClassName,\n )}\n >\n {content}\n </NavigationMenuContent>\n </NavigationMenuItem>\n ) : (\n <NavigationMenuLink\n key={name}\n href={link}\n className={cn(DEFAULT_MENU_LINK_STYLING, menuLinkClassName)}\n >\n {name}\n </NavigationMenuLink>\n ),\n )}\n </NavigationMenuList>\n\n <div className={cn(\"absolute top-full\", flyOutClassName)}>\n <NavigationMenuViewport\n className={cn(DEFAULT_VIEWPORT_STYLING, viewPortClassName)}\n />\n </div>\n </NavigationMenu>\n {isOpen ? (\n <FlyOverlay\n className=\"bg-neutral-1300 opacity-10 z-20 h-screen mix-blend-multiply\"\n fadingOut={fadingOut}\n />\n ) : null}\n </>\n );\n};\n\nexport default Flyout;\n"],"names":["React","useState","NavigationMenu","NavigationMenuItem","NavigationMenuList","NavigationMenuTrigger","NavigationMenuContent","NavigationMenuViewport","NavigationMenuLink","cn","componentMaxHeight","HEADER_HEIGHT","DEFAULT_MENU_LINK_STYLING","DEFAULT_VIEWPORT_STYLING","PANEL_ANIMATION","FlyOverlay","className","fadingOut","div","style","height","top","Flyout","menuItems","flyOutClassName","menuLinkClassName","viewPortClassName","isOpen","setIsOpen","setFadingOut","closeMenu","setTimeout","onValueChange","val","delayDuration","skipDelayDuration","map","name","content","link","panelClassName","key","onPointerDown","event","pointerType","preventDefault","href"],"mappings":"AAAA,OAAOA,OAASC,QAAQ,KAAQ,OAAQ,AACxC,QACEC,cAAc,CACdC,kBAAkB,CAClBC,kBAAkB,CAClBC,qBAAqB,CACrBC,qBAAqB,CACrBC,sBAAsB,CACtBC,kBAAkB,KACb,iCAAkC,AACzC,QAAOC,OAAQ,YAAa,AAC5B,QAASC,kBAAkB,CAAEC,aAAa,KAAQ,iBAAkB,CA6CpE,MAAMC,0BACJ,uKACF,MAAMC,yBACJ,2QACF,MAAMC,gBACJ,0LAEF,MAAMC,WAAa,CAAC,CAClBC,SAAS,CACTC,SAAS,CAIV,GACC,oBAACC,OACCF,UAAWP,GACT,oDACA,CACE,2DAA4D,CAACQ,UAC7D,4DAA6DA,SAC/D,EACAD,WAEFG,MAAO,CAAEC,OAAQV,mBAAmBC,eAAgBU,IAAKV,aAAc,IAI3E,MAAMW,OAAS,CAAC,CACdC,SAAS,CACTP,SAAS,CACTQ,eAAe,CACfC,iBAAiB,CACjBC,iBAAiB,CACL,IACZ,KAAM,CAACC,OAAQC,UAAU,CAAG3B,SAAS,OACrC,KAAM,CAACgB,UAAWY,aAAa,CAAG5B,SAAS,OAE3C,MAAM6B,UAAY,KAChBD,aAAa,MAEbE,WAAW,KACTH,UAAU,OACVC,aAAa,MACf,EAAG,IACL,EAEA,OACE,wCACE,oBAAC3B,gBACCc,UAAWP,GAAGO,UAAW,eACzBgB,cAAe,AAACC,KAASA,IAAML,UAAU,MAAQE,YACjDI,cAAe,GACfC,kBAAmB,GAEnB,oBAAC/B,oBAAmBY,UAAU,yBAC3BO,UAAUa,GAAG,CAAC,CAAC,CAAEC,IAAI,CAAEC,OAAO,CAAEC,IAAI,CAAEC,cAAc,CAAE,GACrDF,QACE,oBAACnC,oBAAmBsC,IAAKJ,MACvB,oBAAChC,uBACCqC,cAAe,AAACC,QACd,GAAIA,MAAMC,WAAW,GAAK,QAAS,CACjCD,MAAME,cAAc,EACtB,CACF,EACA7B,UAAWP,GACT,4EACA,6DACA,gFACA,oFACAG,0BACAa,oBAGDY,MAEH,oBAAC/B,uBACCU,UAAWP,GACT,8BACAK,gBACA0B,iBAGDF,UAIL,oBAAC9B,oBACCiC,IAAKJ,KACLS,KAAMP,KACNvB,UAAWP,GAAGG,0BAA2Ba,oBAExCY,QAMT,oBAACnB,OAAIF,UAAWP,GAAG,oBAAqBe,kBACtC,oBAACjB,wBACCS,UAAWP,GAAGI,yBAA0Ba,uBAI7CC,OACC,oBAACZ,YACCC,UAAU,8DACVC,UAAWA,YAEX,KAGV,CAEA,gBAAeK,MAAO"}
@@ -1,2 +1,2 @@
1
- import React,{useRef}from"react";import Icon from"../Icon";import LinkButton from"../LinkButton";import cn from"../utils/cn";import DropdownMenu from"../DropdownMenu";const testSessionState={signedIn:false,logOut:{token:"0000",href:"accounts/sign_out"},accountName:"Ably"};const DashboardLink=({className})=>React.createElement("a",{href:"/dashboard",className:className},"Dashboard");export const HeaderLinks=({sessionState=testSessionState,headerLinks,searchButtonVisibility,searchButton,className})=>{const{signedIn,logOut}=sessionState;const formRef=useRef(null);const headerLinkClasses="font-sans !text-label2 md:!text-label3 font-bold py-4 text-neutral-1300 dark:text-neutral-000 md:text-neutral-1000 dark:md:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-1300 dark:active:text-neutral-000 transition-colors";const dropdownMenuLinkClasses="block p-2 ui-text-label3 font-semibold text-neutral-1000 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 rounded-lg";const onClickLogout=e=>{e.preventDefault();formRef.current?.submit()};const LogoutForm=React.createElement("form",{ref:formRef,method:"post",action:logOut.href,className:"hidden"},React.createElement("input",{name:"_method",value:"delete",type:"hidden"}),React.createElement("input",{name:"authenticity_token",value:logOut.token,type:"hidden"}));return React.createElement("nav",{className:cn("flex md:flex-1 md:items-center md:justify-end flex-col md:flex-row border-t-[1px] border-neutral-300 md:border-t-0 md:gap-4 pt-3 pb-4 md:py-0",className)},signedIn&&React.createElement(React.Fragment,null,LogoutForm,React.createElement("div",{className:"block md:hidden"},React.createElement("div",{className:"flex flex-col border-b-[1px] border-neutral-300 px-4 pb-3 mb-3"},React.createElement("span",{className:"py-3 ui-text-sub-header text-[18px] text-neutral-700 dark:text-neutral-600 font-bold"},sessionState.accountName),React.createElement(DashboardLink,{className:headerLinkClasses})))),headerLinks?.map(({href,label,external})=>React.createElement("a",{key:href,className:cn(headerLinkClasses,"flex items-center gap-1.5 px-4 md:px-0 leading-none"),href:href,target:external?"_blank":undefined,rel:external?"noreferrer noopener":undefined},label,external&&React.createElement(Icon,{name:"icon-gui-arrow-top-right-on-square-mini",size:"20px"}))),searchButtonVisibility!=="mobile"?searchButton:null,signedIn?React.createElement(React.Fragment,null,React.createElement("div",{className:"hidden md:block relative"},React.createElement(DropdownMenu,null,React.createElement(DropdownMenu.Trigger,{description:`Account menu for ${sessionState.accountName}`},React.createElement("span",{className:"block text-ellipsis overflow-hidden whitespace-nowrap w-full max-w-[9.375rem] leading-normal"},sessionState.accountName)),React.createElement(DropdownMenu.Content,{anchorPosition:"right",contentClassNames:"w-60 mt-3"},React.createElement("div",{className:"p-2"},React.createElement(DashboardLink,{className:dropdownMenuLinkClasses}),React.createElement("button",{onClick:onClickLogout,className:dropdownMenuLinkClasses},"Logout"))))),React.createElement("div",{className:"block md:hidden px-4 pt-4 pb-0"},React.createElement(LinkButton,{onClick:onClickLogout,variant:"secondary",className:"w-full md:ui-button-secondary-xs","aria-label":"Logout",rightIcon:"icon-gui-arrow-right-end-on-rectangle-outline"},"Logout"))):React.createElement("div",{className:"flex gap-3 pt-3 md:py-0 px-4 md:px-0"},React.createElement(LinkButton,{href:"/login",variant:"secondary",className:"flex-1 md:flex-none md:ui-button-secondary-xs hover:text-neutral-1300 dark:hover:text-neutral-000"},"Login"),React.createElement(LinkButton,{href:"/sign-up",variant:"primary",className:"flex-1 md:flex-none md:ui-button-primary-xs hover:text-neutral-000 dark:hover:text-neutral-1300"},"Start free")))};
1
+ import React,{useRef}from"react";import Icon from"../Icon";import LinkButton from"../LinkButton";import cn from"../utils/cn";import DropdownMenu from"../DropdownMenu";const testSessionState={signedIn:false,logOut:{token:"0000",href:"accounts/sign_out"},accountName:"Ably"};const DashboardLink=({className})=>React.createElement("a",{href:"/dashboard",className:className},"Dashboard");export const HeaderLinks=({sessionState=testSessionState,headerLinks,searchButtonVisibility,searchButton,className})=>{const{signedIn,logOut}=sessionState;const formRef=useRef(null);const headerLinkClasses="font-sans !text-label2 md:!text-label3 font-semibold py-4 text-neutral-1300 dark:text-neutral-000 md:text-neutral-1000 dark:md:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-1300 dark:active:text-neutral-000 transition-colors";const dropdownMenuLinkClasses="block p-2 ui-text-label3 font-semibold text-neutral-1000 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 rounded-lg";const onClickLogout=e=>{e.preventDefault();formRef.current?.submit()};const LogoutForm=React.createElement("form",{ref:formRef,method:"post",action:logOut.href,className:"hidden"},React.createElement("input",{name:"_method",value:"delete",type:"hidden"}),React.createElement("input",{name:"authenticity_token",value:logOut.token,type:"hidden"}));return React.createElement("nav",{className:cn("flex md:flex-1 md:items-center md:justify-end flex-col md:flex-row border-t-[1px] border-neutral-300 md:border-t-0 md:gap-4 pt-3 pb-4 md:py-0",className)},signedIn&&React.createElement(React.Fragment,null,LogoutForm,React.createElement("div",{className:"block md:hidden"},React.createElement("div",{className:"flex flex-col border-b-[1px] border-neutral-300 px-4 pb-3 mb-3"},React.createElement("span",{className:"py-3 ui-text-sub-header text-[18px] text-neutral-700 dark:text-neutral-600 font-bold"},sessionState.accountName),React.createElement(DashboardLink,{className:headerLinkClasses})))),headerLinks?.map(({href,label,external})=>React.createElement("a",{key:href,className:cn(headerLinkClasses,"flex items-center gap-1.5 px-4 md:px-0 leading-none"),href:href,target:external?"_blank":undefined,rel:external?"noreferrer noopener":undefined},label,external&&React.createElement(Icon,{name:"icon-gui-arrow-top-right-on-square-mini",size:"20px"}))),searchButtonVisibility!=="mobile"?searchButton:null,signedIn?React.createElement(React.Fragment,null,React.createElement("div",{className:"hidden md:block relative"},React.createElement(DropdownMenu,null,React.createElement(DropdownMenu.Trigger,{description:`Account menu for ${sessionState.accountName}`},React.createElement("span",{className:"block text-ellipsis overflow-hidden whitespace-nowrap w-full max-w-[9.375rem] leading-normal"},sessionState.accountName)),React.createElement(DropdownMenu.Content,{anchorPosition:"right",contentClassNames:"w-60 mt-3"},React.createElement("div",{className:"p-2"},React.createElement(DashboardLink,{className:dropdownMenuLinkClasses}),React.createElement("button",{onClick:onClickLogout,className:dropdownMenuLinkClasses},"Logout"))))),React.createElement("div",{className:"block md:hidden px-4 pt-4 pb-0"},React.createElement(LinkButton,{onClick:onClickLogout,variant:"secondary",className:"w-full md:ui-button-secondary-xs","aria-label":"Logout",rightIcon:"icon-gui-arrow-right-end-on-rectangle-outline"},"Logout"))):React.createElement("div",{className:"flex gap-3 pt-3 md:py-0 px-4 md:px-0"},React.createElement(LinkButton,{href:"/login",variant:"secondary",className:"flex-1 md:flex-none md:ui-button-secondary-xs hover:text-neutral-1300 dark:hover:text-neutral-000"},"Login"),React.createElement(LinkButton,{href:"/sign-up",variant:"primary",className:"flex-1 md:flex-none md:ui-button-primary-xs hover:text-neutral-000 dark:hover:text-neutral-1300"},"Start free")))};
2
2
  //# sourceMappingURL=HeaderLinks.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/Header/HeaderLinks.tsx"],"sourcesContent":["import React, { MouseEvent, useRef } from \"react\";\nimport { HeaderProps } from \"../Header\";\nimport Icon from \"../Icon\";\nimport LinkButton from \"../LinkButton\";\nimport cn from \"../utils/cn\";\nimport DropdownMenu from \"../DropdownMenu\";\n\nconst testSessionState = {\n signedIn: false,\n logOut: {\n token: \"0000\",\n href: \"accounts/sign_out\",\n },\n accountName: \"Ably\",\n};\n\nconst DashboardLink = ({ className }: { className: string }) => (\n <a href=\"/dashboard\" className={className}>\n Dashboard\n </a>\n);\n\nexport const HeaderLinks: React.FC<\n Pick<\n HeaderProps,\n | \"sessionState\"\n | \"headerLinks\"\n | \"searchButtonVisibility\"\n | \"searchButton\"\n | \"className\"\n >\n> = ({\n sessionState = testSessionState,\n headerLinks,\n searchButtonVisibility,\n searchButton,\n className,\n}) => {\n const { signedIn, logOut } = sessionState;\n const formRef = useRef<HTMLFormElement>(null);\n\n const headerLinkClasses =\n \"font-sans !text-label2 md:!text-label3 font-bold py-4 text-neutral-1300 dark:text-neutral-000 md:text-neutral-1000 dark:md:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-1300 dark:active:text-neutral-000 transition-colors\";\n\n const dropdownMenuLinkClasses =\n \"block p-2 ui-text-label3 font-semibold text-neutral-1000 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 rounded-lg\";\n\n const onClickLogout = (e: MouseEvent) => {\n e.preventDefault();\n formRef.current?.submit();\n };\n\n const LogoutForm = (\n <form ref={formRef} method=\"post\" action={logOut.href} className=\"hidden\">\n <input name=\"_method\" value=\"delete\" type=\"hidden\" />\n <input name=\"authenticity_token\" value={logOut.token} type=\"hidden\" />\n </form>\n );\n\n return (\n <nav\n className={cn(\n \"flex md:flex-1 md:items-center md:justify-end flex-col md:flex-row border-t-[1px] border-neutral-300 md:border-t-0 md:gap-4 pt-3 pb-4 md:py-0\",\n className,\n )}\n >\n {signedIn && (\n <>\n {LogoutForm}\n <div className=\"block md:hidden\">\n <div className=\"flex flex-col border-b-[1px] border-neutral-300 px-4 pb-3 mb-3\">\n <span className=\"py-3 ui-text-sub-header text-[18px] text-neutral-700 dark:text-neutral-600 font-bold\">\n {sessionState.accountName}\n </span>\n <DashboardLink className={headerLinkClasses} />\n </div>\n </div>\n </>\n )}\n\n {headerLinks?.map(({ href, label, external }) => (\n <a\n key={href}\n className={cn(\n headerLinkClasses,\n \"flex items-center gap-1.5 px-4 md:px-0 leading-none\",\n )}\n href={href}\n target={external ? \"_blank\" : undefined}\n rel={external ? \"noreferrer noopener\" : undefined}\n >\n {label}\n {external && (\n <Icon name=\"icon-gui-arrow-top-right-on-square-mini\" size=\"20px\" />\n )}\n </a>\n ))}\n\n {searchButtonVisibility !== \"mobile\" ? searchButton : null}\n {signedIn ? (\n <>\n <div className=\"hidden md:block relative\">\n <DropdownMenu>\n <DropdownMenu.Trigger\n description={`Account menu for ${sessionState.accountName}`}\n >\n <span className=\"block text-ellipsis overflow-hidden whitespace-nowrap w-full max-w-[9.375rem] leading-normal\">\n {sessionState.accountName}\n </span>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content\n anchorPosition=\"right\"\n contentClassNames=\"w-60 mt-3\"\n >\n <div className=\"p-2\">\n <DashboardLink className={dropdownMenuLinkClasses} />\n <button\n onClick={onClickLogout}\n className={dropdownMenuLinkClasses}\n >\n Logout\n </button>\n </div>\n </DropdownMenu.Content>\n </DropdownMenu>\n </div>\n <div className=\"block md:hidden px-4 pt-4 pb-0\">\n <LinkButton\n onClick={onClickLogout}\n variant=\"secondary\"\n className=\"w-full md:ui-button-secondary-xs\"\n aria-label=\"Logout\"\n rightIcon=\"icon-gui-arrow-right-end-on-rectangle-outline\"\n >\n Logout\n </LinkButton>\n </div>\n </>\n ) : (\n <div className=\"flex gap-3 pt-3 md:py-0 px-4 md:px-0\">\n <LinkButton\n href=\"/login\"\n variant=\"secondary\"\n className=\"flex-1 md:flex-none md:ui-button-secondary-xs hover:text-neutral-1300 dark:hover:text-neutral-000\"\n >\n Login\n </LinkButton>\n <LinkButton\n href=\"/sign-up\"\n variant=\"primary\"\n className=\"flex-1 md:flex-none md:ui-button-primary-xs hover:text-neutral-000 dark:hover:text-neutral-1300\"\n >\n Start free\n </LinkButton>\n </div>\n )}\n </nav>\n );\n};\n"],"names":["React","useRef","Icon","LinkButton","cn","DropdownMenu","testSessionState","signedIn","logOut","token","href","accountName","DashboardLink","className","a","HeaderLinks","sessionState","headerLinks","searchButtonVisibility","searchButton","formRef","headerLinkClasses","dropdownMenuLinkClasses","onClickLogout","e","preventDefault","current","submit","LogoutForm","form","ref","method","action","input","name","value","type","nav","div","span","map","label","external","key","target","undefined","rel","size","Trigger","description","Content","anchorPosition","contentClassNames","button","onClick","variant","aria-label","rightIcon"],"mappings":"AAAA,OAAOA,OAAqBC,MAAM,KAAQ,OAAQ,AAElD,QAAOC,SAAU,SAAU,AAC3B,QAAOC,eAAgB,eAAgB,AACvC,QAAOC,OAAQ,aAAc,AAC7B,QAAOC,iBAAkB,iBAAkB,CAE3C,MAAMC,iBAAmB,CACvBC,SAAU,MACVC,OAAQ,CACNC,MAAO,OACPC,KAAM,mBACR,EACAC,YAAa,MACf,EAEA,MAAMC,cAAgB,CAAC,CAAEC,SAAS,CAAyB,GACzD,oBAACC,KAAEJ,KAAK,aAAaG,UAAWA,WAAW,YAK7C,QAAO,MAAME,YAST,CAAC,CACHC,aAAeV,gBAAgB,CAC/BW,WAAW,CACXC,sBAAsB,CACtBC,YAAY,CACZN,SAAS,CACV,IACC,KAAM,CAAEN,QAAQ,CAAEC,MAAM,CAAE,CAAGQ,aAC7B,MAAMI,QAAUnB,OAAwB,MAExC,MAAMoB,kBACJ,0QAEF,MAAMC,wBACJ,8LAEF,MAAMC,cAAgB,AAACC,IACrBA,EAAEC,cAAc,EAChBL,CAAAA,QAAQM,OAAO,EAAEC,QACnB,EAEA,MAAMC,WACJ,oBAACC,QAAKC,IAAKV,QAASW,OAAO,OAAOC,OAAQxB,OAAOE,IAAI,CAAEG,UAAU,UAC/D,oBAACoB,SAAMC,KAAK,UAAUC,MAAM,SAASC,KAAK,WAC1C,oBAACH,SAAMC,KAAK,qBAAqBC,MAAO3B,OAAOC,KAAK,CAAE2B,KAAK,YAI/D,OACE,oBAACC,OACCxB,UAAWT,GACT,gJACAS,YAGDN,UACC,wCACGqB,WACD,oBAACU,OAAIzB,UAAU,mBACb,oBAACyB,OAAIzB,UAAU,kEACb,oBAAC0B,QAAK1B,UAAU,wFACbG,aAAaL,WAAW,EAE3B,oBAACC,eAAcC,UAAWQ,uBAMjCJ,aAAauB,IAAI,CAAC,CAAE9B,IAAI,CAAE+B,KAAK,CAAEC,QAAQ,CAAE,GAC1C,oBAAC5B,KACC6B,IAAKjC,KACLG,UAAWT,GACTiB,kBACA,uDAEFX,KAAMA,KACNkC,OAAQF,SAAW,SAAWG,UAC9BC,IAAKJ,SAAW,sBAAwBG,WAEvCJ,MACAC,UACC,oBAACxC,MAAKgC,KAAK,0CAA0Ca,KAAK,WAK/D7B,yBAA2B,SAAWC,aAAe,KACrDZ,SACC,wCACE,oBAAC+B,OAAIzB,UAAU,4BACb,oBAACR,kBACC,oBAACA,aAAa2C,OAAO,EACnBC,YAAa,CAAC,iBAAiB,EAAEjC,aAAaL,WAAW,CAAC,CAAC,EAE3D,oBAAC4B,QAAK1B,UAAU,gGACbG,aAAaL,WAAW,GAG7B,oBAACN,aAAa6C,OAAO,EACnBC,eAAe,QACfC,kBAAkB,aAElB,oBAACd,OAAIzB,UAAU,OACb,oBAACD,eAAcC,UAAWS,0BAC1B,oBAAC+B,UACCC,QAAS/B,cACTV,UAAWS,yBACZ,cAOT,oBAACgB,OAAIzB,UAAU,kCACb,oBAACV,YACCmD,QAAS/B,cACTgC,QAAQ,YACR1C,UAAU,mCACV2C,aAAW,SACXC,UAAU,iDACX,YAML,oBAACnB,OAAIzB,UAAU,wCACb,oBAACV,YACCO,KAAK,SACL6C,QAAQ,YACR1C,UAAU,qGACX,SAGD,oBAACV,YACCO,KAAK,WACL6C,QAAQ,UACR1C,UAAU,mGACX,eAOX,CAAE"}
1
+ {"version":3,"sources":["../../../src/core/Header/HeaderLinks.tsx"],"sourcesContent":["import React, { MouseEvent, useRef } from \"react\";\nimport { HeaderProps } from \"../Header\";\nimport Icon from \"../Icon\";\nimport LinkButton from \"../LinkButton\";\nimport cn from \"../utils/cn\";\nimport DropdownMenu from \"../DropdownMenu\";\n\nconst testSessionState = {\n signedIn: false,\n logOut: {\n token: \"0000\",\n href: \"accounts/sign_out\",\n },\n accountName: \"Ably\",\n};\n\nconst DashboardLink = ({ className }: { className: string }) => (\n <a href=\"/dashboard\" className={className}>\n Dashboard\n </a>\n);\n\nexport const HeaderLinks: React.FC<\n Pick<\n HeaderProps,\n | \"sessionState\"\n | \"headerLinks\"\n | \"searchButtonVisibility\"\n | \"searchButton\"\n | \"className\"\n >\n> = ({\n sessionState = testSessionState,\n headerLinks,\n searchButtonVisibility,\n searchButton,\n className,\n}) => {\n const { signedIn, logOut } = sessionState;\n const formRef = useRef<HTMLFormElement>(null);\n\n const headerLinkClasses =\n \"font-sans !text-label2 md:!text-label3 font-semibold py-4 text-neutral-1300 dark:text-neutral-000 md:text-neutral-1000 dark:md:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-1300 dark:active:text-neutral-000 transition-colors\";\n\n const dropdownMenuLinkClasses =\n \"block p-2 ui-text-label3 font-semibold text-neutral-1000 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 rounded-lg\";\n\n const onClickLogout = (e: MouseEvent) => {\n e.preventDefault();\n formRef.current?.submit();\n };\n\n const LogoutForm = (\n <form ref={formRef} method=\"post\" action={logOut.href} className=\"hidden\">\n <input name=\"_method\" value=\"delete\" type=\"hidden\" />\n <input name=\"authenticity_token\" value={logOut.token} type=\"hidden\" />\n </form>\n );\n\n return (\n <nav\n className={cn(\n \"flex md:flex-1 md:items-center md:justify-end flex-col md:flex-row border-t-[1px] border-neutral-300 md:border-t-0 md:gap-4 pt-3 pb-4 md:py-0\",\n className,\n )}\n >\n {signedIn && (\n <>\n {LogoutForm}\n <div className=\"block md:hidden\">\n <div className=\"flex flex-col border-b-[1px] border-neutral-300 px-4 pb-3 mb-3\">\n <span className=\"py-3 ui-text-sub-header text-[18px] text-neutral-700 dark:text-neutral-600 font-bold\">\n {sessionState.accountName}\n </span>\n <DashboardLink className={headerLinkClasses} />\n </div>\n </div>\n </>\n )}\n\n {headerLinks?.map(({ href, label, external }) => (\n <a\n key={href}\n className={cn(\n headerLinkClasses,\n \"flex items-center gap-1.5 px-4 md:px-0 leading-none\",\n )}\n href={href}\n target={external ? \"_blank\" : undefined}\n rel={external ? \"noreferrer noopener\" : undefined}\n >\n {label}\n {external && (\n <Icon name=\"icon-gui-arrow-top-right-on-square-mini\" size=\"20px\" />\n )}\n </a>\n ))}\n\n {searchButtonVisibility !== \"mobile\" ? searchButton : null}\n {signedIn ? (\n <>\n <div className=\"hidden md:block relative\">\n <DropdownMenu>\n <DropdownMenu.Trigger\n description={`Account menu for ${sessionState.accountName}`}\n >\n <span className=\"block text-ellipsis overflow-hidden whitespace-nowrap w-full max-w-[9.375rem] leading-normal\">\n {sessionState.accountName}\n </span>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content\n anchorPosition=\"right\"\n contentClassNames=\"w-60 mt-3\"\n >\n <div className=\"p-2\">\n <DashboardLink className={dropdownMenuLinkClasses} />\n <button\n onClick={onClickLogout}\n className={dropdownMenuLinkClasses}\n >\n Logout\n </button>\n </div>\n </DropdownMenu.Content>\n </DropdownMenu>\n </div>\n <div className=\"block md:hidden px-4 pt-4 pb-0\">\n <LinkButton\n onClick={onClickLogout}\n variant=\"secondary\"\n className=\"w-full md:ui-button-secondary-xs\"\n aria-label=\"Logout\"\n rightIcon=\"icon-gui-arrow-right-end-on-rectangle-outline\"\n >\n Logout\n </LinkButton>\n </div>\n </>\n ) : (\n <div className=\"flex gap-3 pt-3 md:py-0 px-4 md:px-0\">\n <LinkButton\n href=\"/login\"\n variant=\"secondary\"\n className=\"flex-1 md:flex-none md:ui-button-secondary-xs hover:text-neutral-1300 dark:hover:text-neutral-000\"\n >\n Login\n </LinkButton>\n <LinkButton\n href=\"/sign-up\"\n variant=\"primary\"\n className=\"flex-1 md:flex-none md:ui-button-primary-xs hover:text-neutral-000 dark:hover:text-neutral-1300\"\n >\n Start free\n </LinkButton>\n </div>\n )}\n </nav>\n );\n};\n"],"names":["React","useRef","Icon","LinkButton","cn","DropdownMenu","testSessionState","signedIn","logOut","token","href","accountName","DashboardLink","className","a","HeaderLinks","sessionState","headerLinks","searchButtonVisibility","searchButton","formRef","headerLinkClasses","dropdownMenuLinkClasses","onClickLogout","e","preventDefault","current","submit","LogoutForm","form","ref","method","action","input","name","value","type","nav","div","span","map","label","external","key","target","undefined","rel","size","Trigger","description","Content","anchorPosition","contentClassNames","button","onClick","variant","aria-label","rightIcon"],"mappings":"AAAA,OAAOA,OAAqBC,MAAM,KAAQ,OAAQ,AAElD,QAAOC,SAAU,SAAU,AAC3B,QAAOC,eAAgB,eAAgB,AACvC,QAAOC,OAAQ,aAAc,AAC7B,QAAOC,iBAAkB,iBAAkB,CAE3C,MAAMC,iBAAmB,CACvBC,SAAU,MACVC,OAAQ,CACNC,MAAO,OACPC,KAAM,mBACR,EACAC,YAAa,MACf,EAEA,MAAMC,cAAgB,CAAC,CAAEC,SAAS,CAAyB,GACzD,oBAACC,KAAEJ,KAAK,aAAaG,UAAWA,WAAW,YAK7C,QAAO,MAAME,YAST,CAAC,CACHC,aAAeV,gBAAgB,CAC/BW,WAAW,CACXC,sBAAsB,CACtBC,YAAY,CACZN,SAAS,CACV,IACC,KAAM,CAAEN,QAAQ,CAAEC,MAAM,CAAE,CAAGQ,aAC7B,MAAMI,QAAUnB,OAAwB,MAExC,MAAMoB,kBACJ,8QAEF,MAAMC,wBACJ,8LAEF,MAAMC,cAAgB,AAACC,IACrBA,EAAEC,cAAc,EAChBL,CAAAA,QAAQM,OAAO,EAAEC,QACnB,EAEA,MAAMC,WACJ,oBAACC,QAAKC,IAAKV,QAASW,OAAO,OAAOC,OAAQxB,OAAOE,IAAI,CAAEG,UAAU,UAC/D,oBAACoB,SAAMC,KAAK,UAAUC,MAAM,SAASC,KAAK,WAC1C,oBAACH,SAAMC,KAAK,qBAAqBC,MAAO3B,OAAOC,KAAK,CAAE2B,KAAK,YAI/D,OACE,oBAACC,OACCxB,UAAWT,GACT,gJACAS,YAGDN,UACC,wCACGqB,WACD,oBAACU,OAAIzB,UAAU,mBACb,oBAACyB,OAAIzB,UAAU,kEACb,oBAAC0B,QAAK1B,UAAU,wFACbG,aAAaL,WAAW,EAE3B,oBAACC,eAAcC,UAAWQ,uBAMjCJ,aAAauB,IAAI,CAAC,CAAE9B,IAAI,CAAE+B,KAAK,CAAEC,QAAQ,CAAE,GAC1C,oBAAC5B,KACC6B,IAAKjC,KACLG,UAAWT,GACTiB,kBACA,uDAEFX,KAAMA,KACNkC,OAAQF,SAAW,SAAWG,UAC9BC,IAAKJ,SAAW,sBAAwBG,WAEvCJ,MACAC,UACC,oBAACxC,MAAKgC,KAAK,0CAA0Ca,KAAK,WAK/D7B,yBAA2B,SAAWC,aAAe,KACrDZ,SACC,wCACE,oBAAC+B,OAAIzB,UAAU,4BACb,oBAACR,kBACC,oBAACA,aAAa2C,OAAO,EACnBC,YAAa,CAAC,iBAAiB,EAAEjC,aAAaL,WAAW,CAAC,CAAC,EAE3D,oBAAC4B,QAAK1B,UAAU,gGACbG,aAAaL,WAAW,GAG7B,oBAACN,aAAa6C,OAAO,EACnBC,eAAe,QACfC,kBAAkB,aAElB,oBAACd,OAAIzB,UAAU,OACb,oBAACD,eAAcC,UAAWS,0BAC1B,oBAAC+B,UACCC,QAAS/B,cACTV,UAAWS,yBACZ,cAOT,oBAACgB,OAAIzB,UAAU,kCACb,oBAACV,YACCmD,QAAS/B,cACTgC,QAAQ,YACR1C,UAAU,mCACV2C,aAAW,SACXC,UAAU,iDACX,YAML,oBAACnB,OAAIzB,UAAU,wCACb,oBAACV,YACCO,KAAK,SACL6C,QAAQ,YACR1C,UAAU,qGACX,SAGD,oBAACV,YACCO,KAAK,WACL6C,QAAQ,UACR1C,UAAU,mGACX,eAOX,CAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/Icon/types.ts"],"sourcesContent":["import { displayIcons } from \"./computed-icons/display-icons\";\nimport { guiIcons } from \"./computed-icons/gui-icons\";\nimport { socialIcons } from \"./computed-icons/social-icons\";\nimport { techIcons } from \"./computed-icons/tech-icons\";\nimport { productIcons } from \"./computed-icons/product-icons\";\n\nexport const iconNames = {\n gui: guiIcons,\n display: displayIcons,\n social: socialIcons,\n tech: techIcons,\n product: productIcons,\n};\n\n// Type for heroicons following the pattern: icon-gui-{name}-{variant}\ntype HeroiconVariant = \"outline\" | \"solid\" | \"mini\" | \"micro\";\ntype HeroiconName = `icon-gui-${string}-${HeroiconVariant}`;\n\nexport type IconName =\n | (typeof iconNames.gui)[number]\n | (typeof iconNames.display)[number]\n | (typeof iconNames.social)[number]\n | (typeof iconNames.tech)[number]\n | (typeof iconNames.product)[number]\n | HeroiconName;\n\nexport type IconSize =\n | `${number}px`\n | `${number}em`\n | `${number}rem`\n | `calc(${string})`;\n"],"names":["displayIcons","guiIcons","socialIcons","techIcons","productIcons","iconNames","gui","display","social","tech","product"],"mappings":"AAAA,OAASA,YAAY,KAAQ,gCAAiC,AAC9D,QAASC,QAAQ,KAAQ,4BAA6B,AACtD,QAASC,WAAW,KAAQ,+BAAgC,AAC5D,QAASC,SAAS,KAAQ,6BAA8B,AACxD,QAASC,YAAY,KAAQ,gCAAiC,AAE9D,QAAO,MAAMC,UAAY,CACvBC,IAAKL,SACLM,QAASP,aACTQ,OAAQN,YACRO,KAAMN,UACNO,QAASN,YACX,CAAE"}
1
+ {"version":3,"sources":["../../../src/core/Icon/types.ts"],"sourcesContent":["import { displayIcons } from \"./computed-icons/display-icons\";\nimport { guiIcons } from \"./computed-icons/gui-icons\";\nimport { socialIcons } from \"./computed-icons/social-icons\";\nimport { techIcons } from \"./computed-icons/tech-icons\";\nimport { productIcons } from \"./computed-icons/product-icons\";\n\nexport const iconNames = {\n gui: guiIcons,\n display: displayIcons,\n social: socialIcons,\n tech: techIcons,\n product: productIcons,\n};\n\n// Type for heroicons following the pattern: icon-gui-{name}-{variant}\ntype HeroiconVariant = \"outline\" | \"solid\" | \"mini\" | \"micro\";\ntype HeroiconName = `icon-gui-${string}-${HeroiconVariant}`;\n\nexport type IconName =\n | (typeof iconNames.gui)[number]\n | (typeof iconNames.display)[number]\n | (typeof iconNames.social)[number]\n | (typeof iconNames.tech)[number]\n | (typeof iconNames.product)[number]\n | HeroiconName;\n\nexport type IconSize =\n `${number}px` | `${number}em` | `${number}rem` | `calc(${string})`;\n"],"names":["displayIcons","guiIcons","socialIcons","techIcons","productIcons","iconNames","gui","display","social","tech","product"],"mappings":"AAAA,OAASA,YAAY,KAAQ,gCAAiC,AAC9D,QAASC,QAAQ,KAAQ,4BAA6B,AACtD,QAASC,WAAW,KAAQ,+BAAgC,AAC5D,QAASC,SAAS,KAAQ,6BAA8B,AACxD,QAASC,YAAY,KAAQ,gCAAiC,AAE9D,QAAO,MAAMC,UAAY,CACvBC,IAAKL,SACLM,QAASP,aACTQ,OAAQN,YACRO,KAAMN,UACNO,QAASN,YACX,CAAE"}
package/core/Icon.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/Icon.tsx"],"sourcesContent":["import React, { CSSProperties, useCallback, useId, useMemo } from \"react\";\n\nimport {\n defaultIconSecondaryColor,\n getHeroicon,\n setUniqueIds,\n toPascalCase,\n} from \"./Icon/utils\";\nimport * as IconComponents from \"./Icon/components\";\nimport { IconName, IconSize } from \"./Icon/types\";\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport { convertTailwindClassToVar } from \"./styles/colors/utils\";\nimport cn from \"./utils/cn\";\n\nexport type IconProps = {\n name: IconName;\n size?: IconSize;\n color?: ColorClass | ColorThemeSet;\n secondaryColor?: ColorClass | ColorThemeSet;\n additionalCSS?: string;\n variant?: \"outline\" | \"solid\" | \"micro\" | \"mini\";\n};\n\n// Helper function to get a heroicon component from the static map\nconst getHeroiconComponent = (\n iconName: string,\n): React.ComponentType<React.SVGProps<SVGSVGElement>> | null => {\n // Parse the icon name to extract heroicon name and variant\n // Expected format: icon-gui-{heroicon-name}-{variant}\n const match = iconName.match(/^icon-gui-(.+)-(outline|solid|mini|micro)$/);\n if (!match) {\n return null;\n }\n\n const [, heroiconName, variant] = match;\n const component = getHeroicon(heroiconName, variant);\n return component;\n};\n\nconst Icon = ({\n name,\n size = \"0.75rem\",\n color,\n secondaryColor,\n additionalCSS = \"\",\n variant,\n ...additionalAttributes\n}: IconProps) => {\n const uniqueId = useId();\n\n const [lightSecondaryColor, darkSecondaryColor] = (\n secondaryColor ?? \"\"\n ).split(\" dark:\") as [ColorClass, ColorClass | undefined];\n\n const iconName =\n variant && !name.endsWith(`-${variant}`) ? `${name}-${variant}` : name;\n\n // Get the local icon component (memoized)\n const LocalIconComponent = useMemo(():\n | React.ComponentType<React.SVGProps<SVGSVGElement>>\n | undefined => {\n return IconComponents[\n toPascalCase(iconName) as keyof typeof IconComponents\n ];\n }, [iconName]);\n\n // Get the heroicon component only if no local component is found (memoized)\n const HeroiconComponent = useMemo(() => {\n return LocalIconComponent ? null : getHeroiconComponent(iconName);\n }, [LocalIconComponent, iconName]);\n\n const setUniqueIdsRef = useCallback(\n (el: SVGSVGElement | null) => {\n setUniqueIds(el, uniqueId);\n },\n [uniqueId],\n );\n\n const iconSvg = useCallback(\n (secondaryColor?: ColorClass, isDark?: boolean, isThemed?: boolean) => {\n if (LocalIconComponent) {\n let secondaryColorValue;\n if (secondaryColor) {\n secondaryColorValue = convertTailwindClassToVar(secondaryColor);\n } else if (defaultIconSecondaryColor(name)) {\n secondaryColorValue = convertTailwindClassToVar(\n defaultIconSecondaryColor(name),\n );\n }\n\n return (\n <LocalIconComponent\n className={cn(\n { [`${color}`]: color },\n { [`${additionalCSS}`]: additionalCSS },\n {\n \"hidden dark:block\": secondaryColor && !isDark && isThemed,\n },\n {\n \"dark:hidden\": secondaryColor && isDark && isThemed,\n },\n )}\n style={\n {\n width: size,\n height: size,\n ...(secondaryColorValue && {\n \"--ui-icon-secondary-color\": secondaryColorValue,\n }),\n } as CSSProperties\n }\n {...additionalAttributes}\n ref={setUniqueIdsRef}\n />\n );\n }\n\n if (HeroiconComponent) {\n return (\n <HeroiconComponent\n className={cn(\n { [`${color}`]: color },\n { [`${additionalCSS}`]: additionalCSS },\n )}\n style={{\n width: size,\n height: size,\n }}\n {...additionalAttributes}\n />\n );\n }\n },\n [\n LocalIconComponent,\n HeroiconComponent,\n name,\n color,\n additionalCSS,\n size,\n additionalAttributes,\n setUniqueIdsRef,\n ],\n );\n\n if (lightSecondaryColor && darkSecondaryColor) {\n return (\n <>\n {iconSvg(lightSecondaryColor, false, !!darkSecondaryColor)}\n {iconSvg(darkSecondaryColor, true, true)}\n </>\n );\n } else if (lightSecondaryColor) {\n return iconSvg(lightSecondaryColor, false, !!darkSecondaryColor);\n } else {\n return iconSvg();\n }\n};\n\nexport default Icon;\n"],"names":["React","useCallback","useId","useMemo","defaultIconSecondaryColor","getHeroicon","setUniqueIds","toPascalCase","IconComponents","convertTailwindClassToVar","cn","getHeroiconComponent","iconName","match","heroiconName","variant","component","Icon","name","size","color","secondaryColor","additionalCSS","additionalAttributes","uniqueId","lightSecondaryColor","darkSecondaryColor","split","endsWith","LocalIconComponent","HeroiconComponent","setUniqueIdsRef","el","iconSvg","isDark","isThemed","secondaryColorValue","className","style","width","height","ref"],"mappings":"AAAA,OAAOA,OAAwBC,WAAW,CAAEC,KAAK,CAAEC,OAAO,KAAQ,OAAQ,AAE1E,QACEC,yBAAyB,CACzBC,WAAW,CACXC,YAAY,CACZC,YAAY,KACP,cAAe,AACtB,WAAYC,mBAAoB,mBAAoB,AAGpD,QAASC,yBAAyB,KAAQ,uBAAwB,AAClE,QAAOC,OAAQ,YAAa,CAY5B,MAAMC,qBAAuB,AAC3BC,WAIA,MAAMC,MAAQD,SAASC,KAAK,CAAC,8CAC7B,GAAI,CAACA,MAAO,CACV,OAAO,IACT,CAEA,KAAM,EAAGC,aAAcC,QAAQ,CAAGF,MAClC,MAAMG,UAAYX,YAAYS,aAAcC,SAC5C,OAAOC,SACT,EAEA,MAAMC,KAAO,CAAC,CACZC,IAAI,CACJC,KAAO,SAAS,CAChBC,KAAK,CACLC,cAAc,CACdC,cAAgB,EAAE,CAClBP,OAAO,CACP,GAAGQ,qBACO,IACV,MAAMC,SAAWtB,QAEjB,KAAM,CAACuB,oBAAqBC,mBAAmB,CAAG,AAChDL,CAAAA,gBAAkB,EAAC,EACnBM,KAAK,CAAC,UAER,MAAMf,SACJG,SAAW,CAACG,KAAKU,QAAQ,CAAC,CAAC,CAAC,EAAEb,QAAQ,CAAC,EAAI,CAAC,EAAEG,KAAK,CAAC,EAAEH,QAAQ,CAAC,CAAGG,KAGpE,MAAMW,mBAAqB1B,QAAQ,KAGjC,OAAOK,cAAc,CACnBD,aAAaK,UACd,AACH,EAAG,CAACA,SAAS,EAGb,MAAMkB,kBAAoB3B,QAAQ,KAChC,OAAO0B,mBAAqB,KAAOlB,qBAAqBC,SAC1D,EAAG,CAACiB,mBAAoBjB,SAAS,EAEjC,MAAMmB,gBAAkB9B,YACtB,AAAC+B,KACC1B,aAAa0B,GAAIR,SACnB,EACA,CAACA,SAAS,EAGZ,MAAMS,QAAUhC,YACd,CAACoB,eAA6Ba,OAAkBC,YAC9C,GAAIN,mBAAoB,CACtB,IAAIO,oBACJ,GAAIf,eAAgB,CAClBe,oBAAsB3B,0BAA0BY,eAClD,MAAO,GAAIjB,0BAA0Bc,MAAO,CAC1CkB,oBAAsB3B,0BACpBL,0BAA0Bc,MAE9B,CAEA,OACE,oBAACW,oBACCQ,UAAW3B,GACT,CAAE,CAAC,CAAC,EAAEU,MAAM,CAAC,CAAC,CAAEA,KAAM,EACtB,CAAE,CAAC,CAAC,EAAEE,cAAc,CAAC,CAAC,CAAEA,aAAc,EACtC,CACE,oBAAqBD,gBAAkB,CAACa,QAAUC,QACpD,EACA,CACE,cAAed,gBAAkBa,QAAUC,QAC7C,GAEFG,MACE,CACEC,MAAOpB,KACPqB,OAAQrB,KACR,GAAIiB,qBAAuB,CACzB,4BAA6BA,mBAC/B,CAAC,AACH,EAED,GAAGb,oBAAoB,CACxBkB,IAAKV,iBAGX,CAEA,GAAID,kBAAmB,CACrB,OACE,oBAACA,mBACCO,UAAW3B,GACT,CAAE,CAAC,CAAC,EAAEU,MAAM,CAAC,CAAC,CAAEA,KAAM,EACtB,CAAE,CAAC,CAAC,EAAEE,cAAc,CAAC,CAAC,CAAEA,aAAc,GAExCgB,MAAO,CACLC,MAAOpB,KACPqB,OAAQrB,IACV,EACC,GAAGI,oBAAoB,EAG9B,CACF,EACA,CACEM,mBACAC,kBACAZ,KACAE,MACAE,cACAH,KACAI,qBACAQ,gBACD,EAGH,GAAIN,qBAAuBC,mBAAoB,CAC7C,OACE,wCACGO,QAAQR,oBAAqB,MAAO,CAAC,CAACC,oBACtCO,QAAQP,mBAAoB,KAAM,MAGzC,MAAO,GAAID,oBAAqB,CAC9B,OAAOQ,QAAQR,oBAAqB,MAAO,CAAC,CAACC,mBAC/C,KAAO,CACL,OAAOO,SACT,CACF,CAEA,gBAAehB,IAAK"}
1
+ {"version":3,"sources":["../../src/core/Icon.tsx"],"sourcesContent":["import React, { CSSProperties, useCallback, useId, useMemo } from \"react\";\n\nimport {\n defaultIconSecondaryColor,\n getHeroicon,\n setUniqueIds,\n toPascalCase,\n} from \"./Icon/utils\";\nimport * as IconComponents from \"./Icon/components\";\nimport { IconName, IconSize } from \"./Icon/types\";\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport { convertTailwindClassToVar } from \"./styles/colors/utils\";\nimport cn from \"./utils/cn\";\n\nexport type IconProps = {\n name: IconName;\n size?: IconSize;\n color?: ColorClass | ColorThemeSet;\n secondaryColor?: ColorClass | ColorThemeSet;\n additionalCSS?: string;\n variant?: \"outline\" | \"solid\" | \"micro\" | \"mini\";\n};\n\n// Helper function to get a heroicon component from the static map\nconst getHeroiconComponent = (\n iconName: string,\n): React.ComponentType<React.SVGProps<SVGSVGElement>> | null => {\n // Parse the icon name to extract heroicon name and variant\n // Expected format: icon-gui-{heroicon-name}-{variant}\n const match = iconName.match(/^icon-gui-(.+)-(outline|solid|mini|micro)$/);\n if (!match) {\n return null;\n }\n\n const [, heroiconName, variant] = match;\n const component = getHeroicon(heroiconName, variant);\n return component;\n};\n\nconst Icon = ({\n name,\n size = \"0.75rem\",\n color,\n secondaryColor,\n additionalCSS = \"\",\n variant,\n ...additionalAttributes\n}: IconProps) => {\n const uniqueId = useId();\n\n const [lightSecondaryColor, darkSecondaryColor] = (\n secondaryColor ?? \"\"\n ).split(\" dark:\") as [ColorClass, ColorClass | undefined];\n\n const iconName =\n variant && !name.endsWith(`-${variant}`) ? `${name}-${variant}` : name;\n\n // Get the local icon component (memoized)\n const LocalIconComponent = useMemo(():\n React.ComponentType<React.SVGProps<SVGSVGElement>> | undefined => {\n return IconComponents[\n toPascalCase(iconName) as keyof typeof IconComponents\n ];\n }, [iconName]);\n\n // Get the heroicon component only if no local component is found (memoized)\n const HeroiconComponent = useMemo(() => {\n return LocalIconComponent ? null : getHeroiconComponent(iconName);\n }, [LocalIconComponent, iconName]);\n\n const setUniqueIdsRef = useCallback(\n (el: SVGSVGElement | null) => {\n setUniqueIds(el, uniqueId);\n },\n [uniqueId],\n );\n\n const iconSvg = useCallback(\n (secondaryColor?: ColorClass, isDark?: boolean, isThemed?: boolean) => {\n if (LocalIconComponent) {\n let secondaryColorValue;\n if (secondaryColor) {\n secondaryColorValue = convertTailwindClassToVar(secondaryColor);\n } else if (defaultIconSecondaryColor(name)) {\n secondaryColorValue = convertTailwindClassToVar(\n defaultIconSecondaryColor(name),\n );\n }\n\n return (\n <LocalIconComponent\n className={cn(\n { [`${color}`]: color },\n { [`${additionalCSS}`]: additionalCSS },\n {\n \"hidden dark:block\": secondaryColor && !isDark && isThemed,\n },\n {\n \"dark:hidden\": secondaryColor && isDark && isThemed,\n },\n )}\n style={\n {\n width: size,\n height: size,\n ...(secondaryColorValue && {\n \"--ui-icon-secondary-color\": secondaryColorValue,\n }),\n } as CSSProperties\n }\n {...additionalAttributes}\n ref={setUniqueIdsRef}\n />\n );\n }\n\n if (HeroiconComponent) {\n return (\n <HeroiconComponent\n className={cn(\n { [`${color}`]: color },\n { [`${additionalCSS}`]: additionalCSS },\n )}\n style={{\n width: size,\n height: size,\n }}\n {...additionalAttributes}\n />\n );\n }\n },\n [\n LocalIconComponent,\n HeroiconComponent,\n name,\n color,\n additionalCSS,\n size,\n additionalAttributes,\n setUniqueIdsRef,\n ],\n );\n\n if (lightSecondaryColor && darkSecondaryColor) {\n return (\n <>\n {iconSvg(lightSecondaryColor, false, !!darkSecondaryColor)}\n {iconSvg(darkSecondaryColor, true, true)}\n </>\n );\n } else if (lightSecondaryColor) {\n return iconSvg(lightSecondaryColor, false, !!darkSecondaryColor);\n } else {\n return iconSvg();\n }\n};\n\nexport default Icon;\n"],"names":["React","useCallback","useId","useMemo","defaultIconSecondaryColor","getHeroicon","setUniqueIds","toPascalCase","IconComponents","convertTailwindClassToVar","cn","getHeroiconComponent","iconName","match","heroiconName","variant","component","Icon","name","size","color","secondaryColor","additionalCSS","additionalAttributes","uniqueId","lightSecondaryColor","darkSecondaryColor","split","endsWith","LocalIconComponent","HeroiconComponent","setUniqueIdsRef","el","iconSvg","isDark","isThemed","secondaryColorValue","className","style","width","height","ref"],"mappings":"AAAA,OAAOA,OAAwBC,WAAW,CAAEC,KAAK,CAAEC,OAAO,KAAQ,OAAQ,AAE1E,QACEC,yBAAyB,CACzBC,WAAW,CACXC,YAAY,CACZC,YAAY,KACP,cAAe,AACtB,WAAYC,mBAAoB,mBAAoB,AAGpD,QAASC,yBAAyB,KAAQ,uBAAwB,AAClE,QAAOC,OAAQ,YAAa,CAY5B,MAAMC,qBAAuB,AAC3BC,WAIA,MAAMC,MAAQD,SAASC,KAAK,CAAC,8CAC7B,GAAI,CAACA,MAAO,CACV,OAAO,IACT,CAEA,KAAM,EAAGC,aAAcC,QAAQ,CAAGF,MAClC,MAAMG,UAAYX,YAAYS,aAAcC,SAC5C,OAAOC,SACT,EAEA,MAAMC,KAAO,CAAC,CACZC,IAAI,CACJC,KAAO,SAAS,CAChBC,KAAK,CACLC,cAAc,CACdC,cAAgB,EAAE,CAClBP,OAAO,CACP,GAAGQ,qBACO,IACV,MAAMC,SAAWtB,QAEjB,KAAM,CAACuB,oBAAqBC,mBAAmB,CAAG,AAChDL,CAAAA,gBAAkB,EAAC,EACnBM,KAAK,CAAC,UAER,MAAMf,SACJG,SAAW,CAACG,KAAKU,QAAQ,CAAC,CAAC,CAAC,EAAEb,QAAQ,CAAC,EAAI,CAAC,EAAEG,KAAK,CAAC,EAAEH,QAAQ,CAAC,CAAGG,KAGpE,MAAMW,mBAAqB1B,QAAQ,KAEjC,OAAOK,cAAc,CACnBD,aAAaK,UACd,AACH,EAAG,CAACA,SAAS,EAGb,MAAMkB,kBAAoB3B,QAAQ,KAChC,OAAO0B,mBAAqB,KAAOlB,qBAAqBC,SAC1D,EAAG,CAACiB,mBAAoBjB,SAAS,EAEjC,MAAMmB,gBAAkB9B,YACtB,AAAC+B,KACC1B,aAAa0B,GAAIR,SACnB,EACA,CAACA,SAAS,EAGZ,MAAMS,QAAUhC,YACd,CAACoB,eAA6Ba,OAAkBC,YAC9C,GAAIN,mBAAoB,CACtB,IAAIO,oBACJ,GAAIf,eAAgB,CAClBe,oBAAsB3B,0BAA0BY,eAClD,MAAO,GAAIjB,0BAA0Bc,MAAO,CAC1CkB,oBAAsB3B,0BACpBL,0BAA0Bc,MAE9B,CAEA,OACE,oBAACW,oBACCQ,UAAW3B,GACT,CAAE,CAAC,CAAC,EAAEU,MAAM,CAAC,CAAC,CAAEA,KAAM,EACtB,CAAE,CAAC,CAAC,EAAEE,cAAc,CAAC,CAAC,CAAEA,aAAc,EACtC,CACE,oBAAqBD,gBAAkB,CAACa,QAAUC,QACpD,EACA,CACE,cAAed,gBAAkBa,QAAUC,QAC7C,GAEFG,MACE,CACEC,MAAOpB,KACPqB,OAAQrB,KACR,GAAIiB,qBAAuB,CACzB,4BAA6BA,mBAC/B,CAAC,AACH,EAED,GAAGb,oBAAoB,CACxBkB,IAAKV,iBAGX,CAEA,GAAID,kBAAmB,CACrB,OACE,oBAACA,mBACCO,UAAW3B,GACT,CAAE,CAAC,CAAC,EAAEU,MAAM,CAAC,CAAC,CAAEA,KAAM,EACtB,CAAE,CAAC,CAAC,EAAEE,cAAc,CAAC,CAAC,CAAEA,aAAc,GAExCgB,MAAO,CACLC,MAAOpB,KACPqB,OAAQrB,IACV,EACC,GAAGI,oBAAoB,EAG9B,CACF,EACA,CACEM,mBACAC,kBACAZ,KACAE,MACAE,cACAH,KACAI,qBACAQ,gBACD,EAGH,GAAIN,qBAAuBC,mBAAoB,CAC7C,OACE,wCACGO,QAAQR,oBAAqB,MAAO,CAAC,CAACC,oBACtCO,QAAQP,mBAAoB,KAAM,MAGzC,MAAO,GAAID,oBAAqB,CAC9B,OAAOQ,QAAQR,oBAAqB,MAAO,CAAC,CAACC,mBAC/C,KAAO,CACL,OAAOO,SACT,CACF,CAEA,gBAAehB,IAAK"}
@@ -1,2 +1,2 @@
1
- import React from"react";import Accordion from"../Accordion";import{menuItemLinks}from"./data";import cn from"../utils/cn";export const MeganavMobile=({navItems})=>{const menuItemClassname="text-[18px] py-3 font-bold text-neutral-1000 dark:text-neutral-000 hover:text-neutral-1000 dark:hover:text-neutral-000 active:text-neutral-1000 dark:active:text-neutral-000";return React.createElement("div",{className:"overflow-y-auto"},React.createElement(Accordion,{theme:"transparent",className:"px-4 pt-4",data:navItems,icons:{closed:{name:"icon-gui-chevron-down-outline"},open:{name:"icon-gui-chevron-up-outline"}},options:{autoClose:true,hideBorders:true,headerCSS:`px-0 ${menuItemClassname}`,contentCSS:"px-0",selectedHeaderCSS:"text-neutral-1300 dark:text-neutral-000",rowIconSize:"24px"}}),menuItemLinks&&React.createElement("div",{className:"mb-3"},menuItemLinks.map(link=>React.createElement("a",{href:link.link,key:link.name,className:cn("px-4 w-full block ui-text-p1",menuItemClassname)},link.name))))};
1
+ import React from"react";import Accordion from"../Accordion";import{menuItemLinks}from"./data";import cn from"../utils/cn";export const MeganavMobile=({navItems})=>{const menuItemClassname="text-[18px] py-3 font-semibold text-neutral-1000 dark:text-neutral-000 hover:text-neutral-1000 dark:hover:text-neutral-000 active:text-neutral-1000 dark:active:text-neutral-000";return React.createElement("div",{className:"overflow-y-auto"},React.createElement(Accordion,{theme:"transparent",className:"px-4 pt-4",data:navItems,icons:{closed:{name:"icon-gui-chevron-down-outline"},open:{name:"icon-gui-chevron-up-outline"}},options:{autoClose:true,hideBorders:true,headerCSS:`px-0 ${menuItemClassname}`,contentCSS:"px-0",selectedHeaderCSS:"text-neutral-1300 dark:text-neutral-000",rowIconSize:"24px"}}),menuItemLinks&&React.createElement("div",{className:"mb-3"},menuItemLinks.map(link=>React.createElement("a",{href:link.link,key:link.name,className:cn("px-4 w-full block ui-text-p1",menuItemClassname)},link.name))))};
2
2
  //# sourceMappingURL=MeganavMobile.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/Meganav/MeganavMobile.tsx"],"sourcesContent":["import React from \"react\";\nimport Accordion from \"../Accordion\";\nimport { AccordionData } from \"../Accordion/types\";\nimport { menuItemLinks } from \"./data\";\nimport cn from \"../utils/cn\";\n\nexport const MeganavMobile = ({ navItems }: { navItems: AccordionData[] }) => {\n const menuItemClassname =\n \"text-[18px] py-3 font-bold text-neutral-1000 dark:text-neutral-000 hover:text-neutral-1000 dark:hover:text-neutral-000 active:text-neutral-1000 dark:active:text-neutral-000\";\n return (\n <div className=\"overflow-y-auto\">\n <Accordion\n theme=\"transparent\"\n className=\"px-4 pt-4\"\n data={navItems}\n icons={{\n closed: { name: \"icon-gui-chevron-down-outline\" },\n open: { name: \"icon-gui-chevron-up-outline\" },\n }}\n options={{\n autoClose: true,\n hideBorders: true,\n headerCSS: `px-0 ${menuItemClassname}`,\n contentCSS: \"px-0\",\n selectedHeaderCSS: \"text-neutral-1300 dark:text-neutral-000\",\n rowIconSize: \"24px\",\n }}\n />\n {menuItemLinks && (\n <div className=\"mb-3\">\n {menuItemLinks.map((link) => (\n <a\n href={link.link}\n key={link.name}\n className={cn(\"px-4 w-full block ui-text-p1\", menuItemClassname)}\n >\n {link.name}\n </a>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"names":["React","Accordion","menuItemLinks","cn","MeganavMobile","navItems","menuItemClassname","div","className","theme","data","icons","closed","name","open","options","autoClose","hideBorders","headerCSS","contentCSS","selectedHeaderCSS","rowIconSize","map","link","a","href","key"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QAAOC,cAAe,cAAe,AAErC,QAASC,aAAa,KAAQ,QAAS,AACvC,QAAOC,OAAQ,aAAc,AAE7B,QAAO,MAAMC,cAAgB,CAAC,CAAEC,QAAQ,CAAiC,IACvE,MAAMC,kBACJ,+KACF,OACE,oBAACC,OAAIC,UAAU,mBACb,oBAACP,WACCQ,MAAM,cACND,UAAU,YACVE,KAAML,SACNM,MAAO,CACLC,OAAQ,CAAEC,KAAM,+BAAgC,EAChDC,KAAM,CAAED,KAAM,6BAA8B,CAC9C,EACAE,QAAS,CACPC,UAAW,KACXC,YAAa,KACbC,UAAW,CAAC,KAAK,EAAEZ,kBAAkB,CAAC,CACtCa,WAAY,OACZC,kBAAmB,0CACnBC,YAAa,MACf,IAEDnB,eACC,oBAACK,OAAIC,UAAU,QACZN,cAAcoB,GAAG,CAAC,AAACC,MAClB,oBAACC,KACCC,KAAMF,KAAKA,IAAI,CACfG,IAAKH,KAAKV,IAAI,CACdL,UAAWL,GAAG,+BAAgCG,oBAE7CiB,KAAKV,IAAI,IAOxB,CAAE"}
1
+ {"version":3,"sources":["../../../src/core/Meganav/MeganavMobile.tsx"],"sourcesContent":["import React from \"react\";\nimport Accordion from \"../Accordion\";\nimport { AccordionData } from \"../Accordion/types\";\nimport { menuItemLinks } from \"./data\";\nimport cn from \"../utils/cn\";\n\nexport const MeganavMobile = ({ navItems }: { navItems: AccordionData[] }) => {\n const menuItemClassname =\n \"text-[18px] py-3 font-semibold text-neutral-1000 dark:text-neutral-000 hover:text-neutral-1000 dark:hover:text-neutral-000 active:text-neutral-1000 dark:active:text-neutral-000\";\n return (\n <div className=\"overflow-y-auto\">\n <Accordion\n theme=\"transparent\"\n className=\"px-4 pt-4\"\n data={navItems}\n icons={{\n closed: { name: \"icon-gui-chevron-down-outline\" },\n open: { name: \"icon-gui-chevron-up-outline\" },\n }}\n options={{\n autoClose: true,\n hideBorders: true,\n headerCSS: `px-0 ${menuItemClassname}`,\n contentCSS: \"px-0\",\n selectedHeaderCSS: \"text-neutral-1300 dark:text-neutral-000\",\n rowIconSize: \"24px\",\n }}\n />\n {menuItemLinks && (\n <div className=\"mb-3\">\n {menuItemLinks.map((link) => (\n <a\n href={link.link}\n key={link.name}\n className={cn(\"px-4 w-full block ui-text-p1\", menuItemClassname)}\n >\n {link.name}\n </a>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"names":["React","Accordion","menuItemLinks","cn","MeganavMobile","navItems","menuItemClassname","div","className","theme","data","icons","closed","name","open","options","autoClose","hideBorders","headerCSS","contentCSS","selectedHeaderCSS","rowIconSize","map","link","a","href","key"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QAAOC,cAAe,cAAe,AAErC,QAASC,aAAa,KAAQ,QAAS,AACvC,QAAOC,OAAQ,aAAc,AAE7B,QAAO,MAAMC,cAAgB,CAAC,CAAEC,QAAQ,CAAiC,IACvE,MAAMC,kBACJ,mLACF,OACE,oBAACC,OAAIC,UAAU,mBACb,oBAACP,WACCQ,MAAM,cACND,UAAU,YACVE,KAAML,SACNM,MAAO,CACLC,OAAQ,CAAEC,KAAM,+BAAgC,EAChDC,KAAM,CAAED,KAAM,6BAA8B,CAC9C,EACAE,QAAS,CACPC,UAAW,KACXC,YAAa,KACbC,UAAW,CAAC,KAAK,EAAEZ,kBAAkB,CAAC,CACtCa,WAAY,OACZC,kBAAmB,0CACnBC,YAAa,MACf,IAEDnB,eACC,oBAACK,OAAIC,UAAU,QACZN,cAAcoB,GAAG,CAAC,AAACC,MAClB,oBAACC,KACCC,KAAMF,KAAKA,IAAI,CACfG,IAAKH,KAAKV,IAAI,CACdL,UAAWL,GAAG,+BAAgCG,oBAE7CiB,KAAKV,IAAI,IAOxB,CAAE"}
package/core/TabMenu.js CHANGED
@@ -1,2 +1,2 @@
1
- import React,{useEffect}from"react";import*as Tabs from"@radix-ui/react-tabs";import{throttle}from"es-toolkit/compat";import cn from"./utils/cn";const DEFAULT_TAILWIND_ANIMATION_DURATION=150;const TabMenu=({tabs=[],contents=[],tabOnClick,tabClassName,rootClassName,contentClassName,options})=>{const{defaultTabIndex=0,underline=true,animated:animatedOption=true,flexibleTabWidth=false,flexibleTabHeight=false}=options??{};const listRef=React.useRef(null);const[animated,setAnimated]=React.useState(false);const[highlight,setHighlight]=React.useState({offset:0,width:0});useEffect(()=>{if(animatedOption&&highlight.width>0){setTimeout(()=>{setAnimated(true)},DEFAULT_TAILWIND_ANIMATION_DURATION)}},[animatedOption,highlight.width]);const updateHighlightDimensions=element=>{const{left:parentLeft}=listRef.current?.getBoundingClientRect()??{};const{left,width}=element.getBoundingClientRect()??{};setHighlight({offset:(left??0)-(parentLeft??0),width:width??0})};useEffect(()=>{const handleResize=throttle(()=>{const activeTabElement=listRef.current?.querySelector(`[data-state="active"]`);if(activeTabElement){updateHighlightDimensions(activeTabElement)}},100);handleResize();window.addEventListener("resize",handleResize);return()=>{window.removeEventListener("resize",handleResize)}},[]);const handleTabClick=(event,index)=>{tabOnClick?.(index);updateHighlightDimensions(event.currentTarget)};const tabTriggerContent=tab=>{if(!tab){return null}if(React.isValidElement(tab)||typeof tab==="string"){return tab}if(typeof tab==="object"&&"label"in tab){return tab.label}return null};return React.createElement(Tabs.Root,{defaultValue:`tab-${defaultTabIndex}`,className:cn({"h-full":flexibleTabHeight},rootClassName)},React.createElement(Tabs.List,{ref:listRef,className:cn("relative",{"flex border-b border-neutral-300 dark:border-neutral-1000":underline},{"h-full":flexibleTabHeight})},tabs.map((tab,index)=>tab&&React.createElement(Tabs.Trigger,{key:`tab-${index}`,className:cn("lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark disabled:cursor-not-allowed",{"flex-1":flexibleTabWidth},{"h-full":flexibleTabHeight},tabClassName),value:`tab-${index}`,onClick:event=>handleTabClick(event,index),disabled:typeof tab==="object"&&"disabled"in tab?tab.disabled:false},tabTriggerContent(tab))),React.createElement("div",{className:cn("absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6",{"transition-[transform,width]":animated}),style:{transform:`translateX(${highlight.offset}px)`,width:`${highlight.width}px`}})),contents.map((content,index)=>React.createElement(Tabs.Content,{key:`tab-${index}`,value:`tab-${index}`,className:contentClassName},content)))};export default TabMenu;
1
+ import React,{useEffect}from"react";import*as Tabs from"@radix-ui/react-tabs";import{throttle}from"es-toolkit/compat";import cn from"./utils/cn";const DEFAULT_TAILWIND_ANIMATION_DURATION=150;const TabMenu=({tabs=[],contents=[],tabOnClick,tabClassName,rootClassName,contentClassName,options})=>{const{defaultTabIndex=0,underline=true,animated:animatedOption=true,flexibleTabWidth=false,flexibleTabHeight=false}=options??{};const listRef=React.useRef(null);const[animated,setAnimated]=React.useState(false);const[highlight,setHighlight]=React.useState({offset:0,width:0});useEffect(()=>{if(animatedOption&&highlight.width>0){setTimeout(()=>{setAnimated(true)},DEFAULT_TAILWIND_ANIMATION_DURATION)}},[animatedOption,highlight.width]);const updateHighlightDimensions=element=>{const{left:parentLeft}=listRef.current?.getBoundingClientRect()??{};const{left,width}=element.getBoundingClientRect()??{};setHighlight({offset:(left??0)-(parentLeft??0),width:width??0})};useEffect(()=>{const handleResize=throttle(()=>{const activeTabElement=listRef.current?.querySelector(`[data-state="active"]`);if(activeTabElement){updateHighlightDimensions(activeTabElement)}},100);handleResize();window.addEventListener("resize",handleResize);return()=>{window.removeEventListener("resize",handleResize)}},[]);const handleTabClick=(event,index)=>{tabOnClick?.(index);updateHighlightDimensions(event.currentTarget)};const tabTriggerContent=tab=>{if(!tab){return null}if(React.isValidElement(tab)||typeof tab==="string"){return tab}if(typeof tab==="object"&&"label"in tab){return tab.label}return null};return React.createElement(Tabs.Root,{defaultValue:`tab-${defaultTabIndex}`,className:cn({"h-full":flexibleTabHeight},rootClassName)},React.createElement(Tabs.List,{ref:listRef,className:cn("relative",{"flex border-b border-neutral-300 dark:border-neutral-1000":underline},{"h-full":flexibleTabHeight})},tabs.map((tab,index)=>tab&&React.createElement(Tabs.Trigger,{key:`tab-${index}`,className:cn("lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-semibold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark disabled:cursor-not-allowed",{"flex-1":flexibleTabWidth},{"h-full":flexibleTabHeight},tabClassName),value:`tab-${index}`,onClick:event=>handleTabClick(event,index),disabled:typeof tab==="object"&&"disabled"in tab?tab.disabled:false},tabTriggerContent(tab))),React.createElement("div",{className:cn("absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6",{"transition-[transform,width]":animated}),style:{transform:`translateX(${highlight.offset}px)`,width:`${highlight.width}px`}})),contents.map((content,index)=>React.createElement(Tabs.Content,{key:`tab-${index}`,value:`tab-${index}`,className:contentClassName},content)))};export default TabMenu;
2
2
  //# sourceMappingURL=TabMenu.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/TabMenu.tsx"],"sourcesContent":["import React, { ReactNode, useEffect } from \"react\";\nimport * as Tabs from \"@radix-ui/react-tabs\";\nimport { throttle } from \"es-toolkit/compat\";\nimport cn from \"./utils/cn\";\n\ntype TabTriggerContent =\n | string\n | { label: string; disabled?: boolean }\n | ReactNode;\n\n/**\n * Props for the TabMenu component.\n */\n\nexport type TabMenuProps = {\n /**\n * An array of tabs, which can be either a string or an object with a label and an optional disabled state.\n */\n tabs: TabTriggerContent[];\n\n /**\n * An optional array of React nodes representing the content for each tab.\n */\n contents?: ReactNode[];\n\n /**\n * An optional callback function that is called when a tab is clicked, receiving the index of the clicked tab.\n */\n tabOnClick?: (index: number) => void;\n\n /**\n * An optional class name to apply to each tab.\n */\n tabClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Root element.\n */\n rootClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Content element.\n */\n contentClassName?: string;\n\n /**\n * Optional configuration options for the TabMenu.\n */\n options?: {\n /**\n * The index of the tab that should be selected by default.\n */\n defaultTabIndex?: number;\n\n /**\n * Whether to show an underline below the selected tab.\n */\n underline?: boolean;\n\n /**\n * Whether to animate the transition between tabs.\n */\n animated?: boolean;\n\n /**\n * Whether the tab width should be flexible.\n */\n flexibleTabWidth?: boolean;\n\n /**\n * Whether the tab height should be flexible.\n */\n flexibleTabHeight?: boolean;\n };\n};\n\nconst DEFAULT_TAILWIND_ANIMATION_DURATION = 150;\n\nconst TabMenu: React.FC<TabMenuProps> = ({\n tabs = [],\n contents = [],\n tabOnClick,\n tabClassName,\n rootClassName,\n contentClassName,\n options,\n}) => {\n const {\n defaultTabIndex = 0,\n underline = true,\n animated: animatedOption = true,\n flexibleTabWidth = false,\n flexibleTabHeight = false,\n } = options ?? {};\n\n const listRef = React.useRef<HTMLDivElement>(null);\n const [animated, setAnimated] = React.useState(false);\n const [highlight, setHighlight] = React.useState({ offset: 0, width: 0 });\n\n useEffect(() => {\n if (animatedOption && highlight.width > 0) {\n setTimeout(() => {\n setAnimated(true);\n }, DEFAULT_TAILWIND_ANIMATION_DURATION);\n }\n }, [animatedOption, highlight.width]);\n\n const updateHighlightDimensions = (element: HTMLButtonElement) => {\n const { left: parentLeft } = listRef.current?.getBoundingClientRect() ?? {};\n const { left, width } = element.getBoundingClientRect() ?? {};\n\n setHighlight({\n offset: (left ?? 0) - (parentLeft ?? 0),\n width: width ?? 0,\n });\n };\n\n useEffect(() => {\n const handleResize = throttle(() => {\n const activeTabElement =\n listRef.current?.querySelector<HTMLButtonElement>(\n `[data-state=\"active\"]`,\n );\n\n if (activeTabElement) {\n updateHighlightDimensions(activeTabElement);\n }\n }, 100);\n\n handleResize();\n\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n const handleTabClick = (\n event: React.MouseEvent<HTMLButtonElement>,\n index: number,\n ) => {\n tabOnClick?.(index);\n updateHighlightDimensions(event.currentTarget as HTMLButtonElement);\n };\n\n const tabTriggerContent = (tab: TabTriggerContent) => {\n if (!tab) {\n return null;\n }\n\n if (React.isValidElement(tab) || typeof tab === \"string\") {\n return tab;\n }\n\n if (typeof tab === \"object\" && \"label\" in tab) {\n return tab.label;\n }\n\n return null;\n };\n\n return (\n <Tabs.Root\n defaultValue={`tab-${defaultTabIndex}`}\n className={cn({ \"h-full\": flexibleTabHeight }, rootClassName)}\n >\n <Tabs.List\n ref={listRef}\n className={cn(\n \"relative\",\n {\n \"flex border-b border-neutral-300 dark:border-neutral-1000\":\n underline,\n },\n { \"h-full\": flexibleTabHeight },\n )}\n >\n {tabs.map(\n (tab, index) =>\n tab && (\n <Tabs.Trigger\n key={`tab-${index}`}\n className={cn(\n \"lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark disabled:cursor-not-allowed\",\n { \"flex-1\": flexibleTabWidth },\n { \"h-full\": flexibleTabHeight },\n tabClassName,\n )}\n value={`tab-${index}`}\n onClick={(event) => handleTabClick(event, index)}\n disabled={\n typeof tab === \"object\" && \"disabled\" in tab\n ? tab.disabled\n : false\n }\n >\n {tabTriggerContent(tab)}\n </Tabs.Trigger>\n ),\n )}\n <div\n className={cn(\n \"absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6\",\n { \"transition-[transform,width]\": animated },\n )}\n style={{\n transform: `translateX(${highlight.offset}px)`,\n width: `${highlight.width}px`,\n }}\n ></div>\n </Tabs.List>\n {contents.map((content, index) => (\n <Tabs.Content\n key={`tab-${index}`}\n value={`tab-${index}`}\n className={contentClassName}\n >\n {content}\n </Tabs.Content>\n ))}\n </Tabs.Root>\n );\n};\n\nexport default TabMenu;\n"],"names":["React","useEffect","Tabs","throttle","cn","DEFAULT_TAILWIND_ANIMATION_DURATION","TabMenu","tabs","contents","tabOnClick","tabClassName","rootClassName","contentClassName","options","defaultTabIndex","underline","animated","animatedOption","flexibleTabWidth","flexibleTabHeight","listRef","useRef","setAnimated","useState","highlight","setHighlight","offset","width","setTimeout","updateHighlightDimensions","element","left","parentLeft","current","getBoundingClientRect","handleResize","activeTabElement","querySelector","window","addEventListener","removeEventListener","handleTabClick","event","index","currentTarget","tabTriggerContent","tab","isValidElement","label","Root","defaultValue","className","List","ref","map","Trigger","key","value","onClick","disabled","div","style","transform","content","Content"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/TabMenu.tsx"],"sourcesContent":["import React, { ReactNode, useEffect } from \"react\";\nimport * as Tabs from \"@radix-ui/react-tabs\";\nimport { throttle } from \"es-toolkit/compat\";\nimport cn from \"./utils/cn\";\n\ntype TabTriggerContent =\n string | { label: string; disabled?: boolean } | ReactNode;\n\n/**\n * Props for the TabMenu component.\n */\n\nexport type TabMenuProps = {\n /**\n * An array of tabs, which can be either a string or an object with a label and an optional disabled state.\n */\n tabs: TabTriggerContent[];\n\n /**\n * An optional array of React nodes representing the content for each tab.\n */\n contents?: ReactNode[];\n\n /**\n * An optional callback function that is called when a tab is clicked, receiving the index of the clicked tab.\n */\n tabOnClick?: (index: number) => void;\n\n /**\n * An optional class name to apply to each tab.\n */\n tabClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Root element.\n */\n rootClassName?: string;\n\n /**\n * An optional class name to apply to the Tabs.Content element.\n */\n contentClassName?: string;\n\n /**\n * Optional configuration options for the TabMenu.\n */\n options?: {\n /**\n * The index of the tab that should be selected by default.\n */\n defaultTabIndex?: number;\n\n /**\n * Whether to show an underline below the selected tab.\n */\n underline?: boolean;\n\n /**\n * Whether to animate the transition between tabs.\n */\n animated?: boolean;\n\n /**\n * Whether the tab width should be flexible.\n */\n flexibleTabWidth?: boolean;\n\n /**\n * Whether the tab height should be flexible.\n */\n flexibleTabHeight?: boolean;\n };\n};\n\nconst DEFAULT_TAILWIND_ANIMATION_DURATION = 150;\n\nconst TabMenu: React.FC<TabMenuProps> = ({\n tabs = [],\n contents = [],\n tabOnClick,\n tabClassName,\n rootClassName,\n contentClassName,\n options,\n}) => {\n const {\n defaultTabIndex = 0,\n underline = true,\n animated: animatedOption = true,\n flexibleTabWidth = false,\n flexibleTabHeight = false,\n } = options ?? {};\n\n const listRef = React.useRef<HTMLDivElement>(null);\n const [animated, setAnimated] = React.useState(false);\n const [highlight, setHighlight] = React.useState({ offset: 0, width: 0 });\n\n useEffect(() => {\n if (animatedOption && highlight.width > 0) {\n setTimeout(() => {\n setAnimated(true);\n }, DEFAULT_TAILWIND_ANIMATION_DURATION);\n }\n }, [animatedOption, highlight.width]);\n\n const updateHighlightDimensions = (element: HTMLButtonElement) => {\n const { left: parentLeft } = listRef.current?.getBoundingClientRect() ?? {};\n const { left, width } = element.getBoundingClientRect() ?? {};\n\n setHighlight({\n offset: (left ?? 0) - (parentLeft ?? 0),\n width: width ?? 0,\n });\n };\n\n useEffect(() => {\n const handleResize = throttle(() => {\n const activeTabElement =\n listRef.current?.querySelector<HTMLButtonElement>(\n `[data-state=\"active\"]`,\n );\n\n if (activeTabElement) {\n updateHighlightDimensions(activeTabElement);\n }\n }, 100);\n\n handleResize();\n\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n const handleTabClick = (\n event: React.MouseEvent<HTMLButtonElement>,\n index: number,\n ) => {\n tabOnClick?.(index);\n updateHighlightDimensions(event.currentTarget as HTMLButtonElement);\n };\n\n const tabTriggerContent = (tab: TabTriggerContent) => {\n if (!tab) {\n return null;\n }\n\n if (React.isValidElement(tab) || typeof tab === \"string\") {\n return tab;\n }\n\n if (typeof tab === \"object\" && \"label\" in tab) {\n return tab.label;\n }\n\n return null;\n };\n\n return (\n <Tabs.Root\n defaultValue={`tab-${defaultTabIndex}`}\n className={cn({ \"h-full\": flexibleTabHeight }, rootClassName)}\n >\n <Tabs.List\n ref={listRef}\n className={cn(\n \"relative\",\n {\n \"flex border-b border-neutral-300 dark:border-neutral-1000\":\n underline,\n },\n { \"h-full\": flexibleTabHeight },\n )}\n >\n {tabs.map(\n (tab, index) =>\n tab && (\n <Tabs.Trigger\n key={`tab-${index}`}\n className={cn(\n \"lg:px-6 md:px-5 px-4 py-4 ui-text-label1 font-semibold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-disabled-light dark:disabled:text-gui-disabled-dark disabled:cursor-not-allowed\",\n { \"flex-1\": flexibleTabWidth },\n { \"h-full\": flexibleTabHeight },\n tabClassName,\n )}\n value={`tab-${index}`}\n onClick={(event) => handleTabClick(event, index)}\n disabled={\n typeof tab === \"object\" && \"disabled\" in tab\n ? tab.disabled\n : false\n }\n >\n {tabTriggerContent(tab)}\n </Tabs.Trigger>\n ),\n )}\n <div\n className={cn(\n \"absolute bottom-0 bg-neutral-1300 dark:bg-neutral-000 h-[0.1875rem] w-6\",\n { \"transition-[transform,width]\": animated },\n )}\n style={{\n transform: `translateX(${highlight.offset}px)`,\n width: `${highlight.width}px`,\n }}\n ></div>\n </Tabs.List>\n {contents.map((content, index) => (\n <Tabs.Content\n key={`tab-${index}`}\n value={`tab-${index}`}\n className={contentClassName}\n >\n {content}\n </Tabs.Content>\n ))}\n </Tabs.Root>\n );\n};\n\nexport default TabMenu;\n"],"names":["React","useEffect","Tabs","throttle","cn","DEFAULT_TAILWIND_ANIMATION_DURATION","TabMenu","tabs","contents","tabOnClick","tabClassName","rootClassName","contentClassName","options","defaultTabIndex","underline","animated","animatedOption","flexibleTabWidth","flexibleTabHeight","listRef","useRef","setAnimated","useState","highlight","setHighlight","offset","width","setTimeout","updateHighlightDimensions","element","left","parentLeft","current","getBoundingClientRect","handleResize","activeTabElement","querySelector","window","addEventListener","removeEventListener","handleTabClick","event","index","currentTarget","tabTriggerContent","tab","isValidElement","label","Root","defaultValue","className","List","ref","map","Trigger","key","value","onClick","disabled","div","style","transform","content","Content"],"mappings":"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"}
@@ -4,19 +4,19 @@
4
4
  }
5
5
 
6
6
  .ui-button-lg-base {
7
- @apply ui-button-base ui-text-label1 font-bold h-14 px-7 py-[1.0625rem] gap-3 [&>svg]:!w-6 [&>svg]:!h-6;
7
+ @apply ui-button-base ui-text-label1 font-semibold h-14 px-7 py-[1.0625rem] gap-3 [&>svg]:!w-6 [&>svg]:!h-6;
8
8
  }
9
9
 
10
10
  .ui-button-md-base {
11
- @apply ui-button-base ui-text-label2 font-bold h-12 px-6 py-[0.8125rem] gap-2.5 [&>svg]:!w-6 [&>svg]:!h-6;
11
+ @apply ui-button-base ui-text-label2 font-semibold h-12 px-6 py-[0.8125rem] gap-2.5 [&>svg]:!w-6 [&>svg]:!h-6;
12
12
  }
13
13
 
14
14
  .ui-button-sm-base {
15
- @apply ui-button-base ui-text-label3 font-bold h-10 px-5 py-2.5 gap-2 [&>svg]:!w-5 [&>svg]:!h-5;
15
+ @apply ui-button-base ui-text-label3 font-semibold h-10 px-5 py-2.5 gap-2 [&>svg]:!w-5 [&>svg]:!h-5;
16
16
  }
17
17
 
18
18
  .ui-button-xs-base {
19
- @apply ui-button-base ui-text-label4 font-bold h-9 px-3 py-[0.5625rem] gap-1.5 [&>svg]:!w-4 [&>svg]:!h-4;
19
+ @apply ui-button-base ui-text-label4 font-semibold h-9 px-3 py-[0.5625rem] gap-1.5 [&>svg]:!w-4 [&>svg]:!h-4;
20
20
  }
21
21
 
22
22
  .ui-button-disabled-base {