@ably/ui 16.2.8 → 17.0.0-dev.3dbbd263

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/core/.DS_Store +0 -0
  2. package/core/Accordion/.DS_Store +0 -0
  3. package/core/Accordion.js +1 -1
  4. package/core/Accordion.js.map +1 -1
  5. package/core/Badge.js +1 -1
  6. package/core/Badge.js.map +1 -1
  7. package/core/Code/.DS_Store +0 -0
  8. package/core/Code.js +1 -1
  9. package/core/Code.js.map +1 -1
  10. package/core/CodeSnippet/ApiKeySelector.js +1 -1
  11. package/core/CodeSnippet/ApiKeySelector.js.map +1 -1
  12. package/core/CodeSnippet/CopyButton.js +1 -1
  13. package/core/CodeSnippet/CopyButton.js.map +1 -1
  14. package/core/CodeSnippet/LanguageSelector.js +1 -1
  15. package/core/CodeSnippet/LanguageSelector.js.map +1 -1
  16. package/core/CodeSnippet/ShellCommandView.js +1 -1
  17. package/core/CodeSnippet/ShellCommandView.js.map +1 -1
  18. package/core/CodeSnippet/TooltipButton.js +1 -1
  19. package/core/CodeSnippet/TooltipButton.js.map +1 -1
  20. package/core/CodeSnippet.js +1 -1
  21. package/core/CodeSnippet.js.map +1 -1
  22. package/core/ContactFooter/.DS_Store +0 -0
  23. package/core/CookieMessage/.DS_Store +0 -0
  24. package/core/CookieMessage/component.css +1 -1
  25. package/core/CookieMessage.js +1 -1
  26. package/core/CookieMessage.js.map +1 -1
  27. package/core/CustomerLogos/.DS_Store +0 -0
  28. package/core/CustomerLogos.js +1 -1
  29. package/core/CustomerLogos.js.map +1 -1
  30. package/core/DropdownMenu/.DS_Store +0 -0
  31. package/core/DropdownMenu.js +1 -1
  32. package/core/DropdownMenu.js.map +1 -1
  33. package/core/Expander.js +1 -1
  34. package/core/Expander.js.map +1 -1
  35. package/core/FeaturedLink/.DS_Store +0 -0
  36. package/core/FeaturedLink.js +1 -1
  37. package/core/FeaturedLink.js.map +1 -1
  38. package/core/Flash/.DS_Store +0 -0
  39. package/core/Flash/component.css +1 -1
  40. package/core/Flash.js +1 -1
  41. package/core/Flash.js.map +1 -1
  42. package/core/Flyout.js +1 -1
  43. package/core/Flyout.js.map +1 -1
  44. package/core/Footer/.DS_Store +0 -0
  45. package/core/Footer.js +1 -1
  46. package/core/Footer.js.map +1 -1
  47. package/core/Header/HeaderLinks.js +1 -1
  48. package/core/Header/HeaderLinks.js.map +1 -1
  49. package/core/Header.js +1 -1
  50. package/core/Header.js.map +1 -1
  51. package/core/Icon/.DS_Store +0 -0
  52. package/core/Loader/.DS_Store +0 -0
  53. package/core/Logo/.DS_Store +0 -0
  54. package/core/Meganav/.DS_Store +0 -0
  55. package/core/Meganav/MeganavMobile.js +1 -1
  56. package/core/Meganav/MeganavMobile.js.map +1 -1
  57. package/core/Meganav/MeganavPanel.js +1 -1
  58. package/core/Meganav/MeganavPanel.js.map +1 -1
  59. package/core/Meganav/MeganavProductTile.js +1 -1
  60. package/core/Meganav/MeganavProductTile.js.map +1 -1
  61. package/core/Meganav/data.js +1 -1
  62. package/core/Meganav/data.js.map +1 -1
  63. package/core/Meganav.js +1 -1
  64. package/core/Meganav.js.map +1 -1
  65. package/core/Notice/.DS_Store +0 -0
  66. package/core/Notice.js +1 -1
  67. package/core/Notice.js.map +1 -1
  68. package/core/Pricing/PricingCards.js +1 -1
  69. package/core/Pricing/PricingCards.js.map +1 -1
  70. package/core/Pricing/data.js +1 -1
  71. package/core/Pricing/data.js.map +1 -1
  72. package/core/ProductTile/ProductIcon.js +1 -1
  73. package/core/ProductTile/ProductIcon.js.map +1 -1
  74. package/core/ProductTile/ProductLabel.js +1 -1
  75. package/core/ProductTile/ProductLabel.js.map +1 -1
  76. package/core/ProductTile.js +1 -1
  77. package/core/ProductTile.js.map +1 -1
  78. package/core/SegmentedControl.js +1 -1
  79. package/core/SegmentedControl.js.map +1 -1
  80. package/core/Slider/.DS_Store +0 -0
  81. package/core/Slider/component.css +1 -1
  82. package/core/Slider.js +1 -1
  83. package/core/Slider.js.map +1 -1
  84. package/core/Status.js +1 -1
  85. package/core/Status.js.map +1 -1
  86. package/core/TabMenu.js +1 -1
  87. package/core/TabMenu.js.map +1 -1
  88. package/core/Table/.DS_Store +0 -0
  89. package/core/Table/Table.js +1 -1
  90. package/core/Table/Table.js.map +1 -1
  91. package/core/Table/TableCell.js +4 -4
  92. package/core/Table/TableCell.js.map +1 -1
  93. package/core/Table/data.js +1 -1
  94. package/core/Table/data.js.map +1 -1
  95. package/core/Toggle.js +1 -1
  96. package/core/Toggle.js.map +1 -1
  97. package/core/Tooltip/.DS_Store +0 -0
  98. package/core/Tooltip.js +1 -1
  99. package/core/Tooltip.js.map +1 -1
  100. package/core/icons/.DS_Store +0 -0
  101. package/core/icons/gui/.DS_Store +0 -0
  102. package/core/icons/product/.DS_Store +0 -0
  103. package/core/images/.DS_Store +0 -0
  104. package/core/images/logo/.DS_Store +0 -0
  105. package/core/styles/buttons.css +11 -11
  106. package/core/styles/dropdowns.css +3 -3
  107. package/core/styles/forms/story-components.js +1 -1
  108. package/core/styles/forms/story-components.js.map +1 -1
  109. package/core/styles/forms.css +10 -10
  110. package/core/styles/layout.css +6 -6
  111. package/core/styles/legacy-buttons.css +3 -3
  112. package/core/styles/text.css +18 -18
  113. package/core/styles.components.css +4 -4
  114. package/package.json +1 -1
  115. package/tailwind.config.js +3 -91
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/CodeSnippet.tsx"],"sourcesContent":["import React, {\n useState,\n useEffect,\n Children,\n isValidElement,\n useRef,\n useCallback,\n useMemo,\n} from \"react\";\nimport Code from \"./Code\";\nimport cn from \"./utils/cn\";\nimport { getLanguageInfo } from \"./CodeSnippet/languages\";\nimport Icon from \"./Icon\";\nimport LanguageSelector from \"./CodeSnippet/LanguageSelector\";\nimport ApiKeySelector from \"./CodeSnippet/ApiKeySelector\";\nimport { IconName } from \"./Icon/types\";\nimport useCopyToClipboard from \"./utils/useCopyToClipboard\";\nimport ShellCommandView from \"./CodeSnippet/ShellCommandView\";\nimport CopyButton from \"./CodeSnippet/CopyButton\";\nimport TooltipButton from \"./CodeSnippet/TooltipButton\";\n\n// Define SDK type\nexport type SDKType = \"realtime\" | \"rest\" | null;\n\nexport interface CodeSnippetProps {\n /**\n * If true, hides the language selector row completely\n */\n fixed?: boolean;\n /**\n * If true, renders a macOS-style window header with buttons and title\n */\n headerRow?: boolean;\n /**\n * Title to display in the header row (when headerRow is true)\n */\n title?: string;\n /**\n * Children elements with lang attribute\n */\n children: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Default language to display. If not found in available languages, first available is used.\n * If found in languages but no matching snippet exists, a message is displayed.\n */\n lang?: string;\n /**\n * Callback fired when the active language changes\n */\n onChange?: (language: string, sdk?: SDKType) => void;\n /**\n * List of API keys to display in a dropdown\n */\n apiKeys?: string[];\n /**\n * Default SDK type to use for the code snippet\n */\n sdk?: SDKType;\n /**\n * 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\n/**\n * CodeSnippet component that displays code with language switching capability\n */\nconst CodeSnippet: React.FC<CodeSnippetProps> = ({\n fixed = false,\n headerRow = false,\n title = \"Code\",\n children,\n className,\n lang,\n onChange,\n apiKeys,\n sdk,\n showCodeLines = true,\n languageOrdering,\n}) => {\n const codeRef = useRef<HTMLDivElement>(null);\n const { isCopied, copy } = useCopyToClipboard();\n\n // Helper function to extract language from code element\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 // Parse children to extract languages and SDK types - only needs to run once\n const {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSingleShellCommand,\n } = useMemo(() => {\n const childrenArray = Children.toArray(children);\n const languages: string[] = [];\n const sdkTypes = new Set<SDKType>();\n const originalLangMap = new Map<string, string>();\n\n // Check if we have a single shell command\n const isSingleShellCommand =\n childrenArray.length === 1 &&\n isValidElement(childrenArray[0]) &&\n isValidElement(childrenArray[0].props.children) &&\n childrenArray[0].props.children.props.className?.includes(\n \"language-shell\",\n );\n\n // Extract all available languages from children and identify SDK types\n childrenArray.forEach((child) => {\n if (!isValidElement(child)) return;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n\n const langName = extractLanguageFromCode(codeElement);\n if (!langName) return;\n\n // Look for SDK prefixes in the language name itself\n if (langName.startsWith(\"realtime_\")) {\n const baseLanguage = langName.substring(9);\n sdkTypes.add(\"realtime\");\n originalLangMap.set(langName, baseLanguage);\n } else if (langName.startsWith(\"rest_\")) {\n const baseLanguage = langName.substring(5);\n sdkTypes.add(\"rest\");\n originalLangMap.set(langName, baseLanguage);\n } else {\n originalLangMap.set(langName, langName);\n }\n\n // Add to languages list if not already included\n if (!languages.includes(langName)) {\n languages.push(langName);\n }\n });\n\n return {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSingleShellCommand,\n };\n }, [children, extractLanguageFromCode]);\n\n // Simplified state management with separate hooks\n const [activeSDKType, setActiveSDKType] = useState<SDKType>(() => {\n if (sdkTypes.size === 0) return null;\n if (sdk && sdkTypes.has(sdk)) return sdk;\n if (sdkTypes.has(\"realtime\")) return \"realtime\";\n if (sdkTypes.has(\"rest\")) return \"rest\";\n return null;\n });\n const [activeLanguage, setActiveLanguage] = useState<string | null>(null);\n const [selectedApiKey, setSelectedApiKey] = useState(() =>\n apiKeys && apiKeys.length > 0 ? apiKeys[0] : \"\",\n );\n const [isHovering, setIsHovering] = useState(false);\n\n // Check if we need to show SDK type selector\n const showSDKSelector = sdkTypes.size > 0;\n\n // Check if there is only a JSON snippet\n const hasOnlyJsonSnippet = useMemo(\n () => languages.length === 1 && languages[0] === \"json\",\n [languages],\n );\n\n // Get languages filtered by active SDK type & apply ordering\n const filteredLanguages = useMemo(() => {\n // Filter by SDK type if needed\n const filtered =\n !activeSDKType || !showSDKSelector\n ? [...languages]\n : languages.filter((lang) => lang.startsWith(`${activeSDKType}_`));\n\n // Apply custom ordering if provided\n if (languageOrdering && languageOrdering.length > 0) {\n filtered.sort((a, b) => {\n const aBase = originalLangMap.get(a) || a;\n const bBase = originalLangMap.get(b) || b;\n\n const aIndex = languageOrdering.indexOf(aBase);\n const bIndex = languageOrdering.indexOf(bBase);\n\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return 0;\n });\n }\n\n return filtered;\n }, [\n activeSDKType,\n showSDKSelector,\n languages,\n languageOrdering,\n originalLangMap,\n ]);\n\n // Determine the initial active language\n const initialActiveLanguage = useMemo((): string | null => {\n if (!lang) {\n return filteredLanguages.length > 0 ? filteredLanguages[0] : null;\n }\n\n // Try with SDK prefix if applicable\n if (activeSDKType) {\n const prefixedLang = `${activeSDKType}_${lang}`;\n if (languages.includes(prefixedLang)) {\n return prefixedLang;\n }\n }\n\n // Try direct match\n if (languages.includes(lang)) {\n return lang;\n }\n\n // Check if it's a known language but not available\n if (getLanguageInfo(lang).label !== lang) {\n return lang;\n }\n\n // Fallback to first available\n return filteredLanguages.length > 0 ? filteredLanguages[0] : null;\n }, [lang, activeSDKType, languages, filteredLanguages]);\n\n // Initialize activeLanguage after filteredLanguages are calculated\n useEffect(() => {\n setActiveLanguage(initialActiveLanguage);\n }, [initialActiveLanguage]);\n\n // Update selected API key if apiKeys changes\n useEffect(() => {\n if (apiKeys && apiKeys.length > 0 && !apiKeys.includes(selectedApiKey)) {\n setSelectedApiKey(apiKeys[0]);\n }\n }, [apiKeys, selectedApiKey]);\n\n // Clean language utilities\n const getCleanLanguage = useCallback(\n (lang: string | null) => (lang ? originalLangMap.get(lang) || lang : null),\n [originalLangMap],\n );\n\n // Get language info for display\n const getLanguageInfoForDisplay = useCallback(\n (lang: string | null) => {\n if (!lang) return null;\n const cleanLang = getCleanLanguage(lang);\n return cleanLang ? getLanguageInfo(cleanLang) : null;\n },\n [getCleanLanguage],\n );\n\n // For language display name and icon (only depends on originalLangMap)\n const getLanguageDisplayName = useCallback(\n (lang: string) => {\n const cleanLang = getCleanLanguage(lang);\n return cleanLang ? getLanguageInfo(cleanLang).label : lang;\n },\n [getCleanLanguage],\n );\n\n const getLanguageIcon = useCallback(\n (lang: string): IconName => {\n const cleanLang = getCleanLanguage(lang);\n return cleanLang\n ? getLanguageInfo(cleanLang).icon\n : \"icon-gui-document-mini\";\n },\n [getCleanLanguage],\n );\n\n // Memoize the active language info\n const activeLanguageInfo = useMemo(\n () => getLanguageInfoForDisplay(activeLanguage),\n [getLanguageInfoForDisplay, activeLanguage],\n );\n\n // Filter and process children for the active language\n const processedChildren = useMemo(() => {\n if (!activeLanguage) return [];\n\n // Target language is either the active one or json in json-only mode\n const targetLanguage = hasOnlyJsonSnippet ? \"json\" : activeLanguage;\n\n return childrenArray\n .filter((child) => {\n if (!isValidElement(child)) return false;\n const codeElement = isValidElement(child.props.children)\n ? child.props.children\n : null;\n const langName = extractLanguageFromCode(codeElement);\n return langName === targetLanguage;\n })\n .map((child) => {\n if (!isValidElement(child)) return child;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n if (!codeElement) return child;\n\n const codeContent = codeElement.props.children;\n const langName = extractLanguageFromCode(codeElement);\n if (!langName) return child;\n\n const cleanLang = hasOnlyJsonSnippet\n ? \"json\"\n : getCleanLanguage(langName) || langName;\n const langInfo = getLanguageInfo(cleanLang);\n\n // Handle primitive content types\n if (\n typeof codeContent === \"string\" ||\n typeof codeContent === \"number\" ||\n typeof codeContent === \"boolean\"\n ) {\n return (\n <Code\n key={langName}\n language={langInfo.syntaxHighlighterKey || cleanLang}\n snippet={String(codeContent)}\n additionalCSS=\"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-24 py-16\"\n showLines={showCodeLines}\n />\n );\n }\n\n return child;\n });\n }, [\n activeLanguage,\n childrenArray,\n extractLanguageFromCode,\n getCleanLanguage,\n hasOnlyJsonSnippet,\n showCodeLines,\n ]);\n\n // Check if there's a snippet available for the active language\n const hasSnippetForActiveLanguage = useMemo(() => {\n if (!activeLanguage) return false;\n if (hasOnlyJsonSnippet) return true;\n\n return childrenArray.some((child) => {\n if (!isValidElement(child)) return false;\n const codeElement = isValidElement(child.props.children)\n ? child.props.children\n : null;\n const langName = extractLanguageFromCode(codeElement);\n return langName === activeLanguage;\n });\n }, [\n activeLanguage,\n childrenArray,\n extractLanguageFromCode,\n hasOnlyJsonSnippet,\n ]);\n\n // Function to get the current code text content\n const getCodeText = useCallback((): string | null => {\n if (!activeLanguage || !hasSnippetForActiveLanguage || !codeRef.current)\n return null;\n\n const allPreElements = codeRef.current.querySelectorAll(\"pre\");\n for (const preElement of Array.from(allPreElements)) {\n const codeElement = preElement.querySelector(\"code\");\n if (!codeElement || !codeElement.className) continue;\n\n const classNames = codeElement.className.split(\" \");\n const langClass = classNames.find((cls) => cls.startsWith(\"language-\"));\n if (!langClass) continue;\n\n const langName = langClass.substring(9);\n if (\n (hasOnlyJsonSnippet && langName === \"json\") ||\n (!hasOnlyJsonSnippet && langName === activeLanguage)\n ) {\n return codeElement.textContent || \"\";\n }\n }\n\n return null;\n }, [activeLanguage, hasSnippetForActiveLanguage, hasOnlyJsonSnippet]);\n\n // Event handlers\n const handleSDKTypeChange = useCallback(\n (type: SDKType) => {\n // pick first language matching the new SDK prefix\n const nextLang = languages.find((l) => l.startsWith(`${type}_`)) ?? null;\n setActiveSDKType(type);\n setActiveLanguage(nextLang);\n },\n [languages],\n );\n\n const handleLanguageChange = useCallback(\n (language: string) => {\n setActiveLanguage(language);\n\n // Call onChange with clean language name\n if (onChange) {\n const cleanLang = getCleanLanguage(language) || language;\n onChange(cleanLang, activeSDKType);\n }\n },\n [onChange, getCleanLanguage, activeSDKType],\n );\n\n const handleApiKeyChange = useCallback((apiKey: string) => {\n setSelectedApiKey(apiKey);\n }, []);\n\n // Optimize no-snippet message as a component\n const NoSnippetMessage = useMemo(() => {\n if (!activeLanguageInfo) return () => null;\n\n return () => (\n <div className=\"px-64 py-24 ui-text-body2 text-neutral-800 dark:text-neutral-400 text-center flex flex-col gap-12 items-center\">\n <Icon\n name=\"icon-gui-exclamation-triangle-outline\"\n color=\"text-yellow-600 dark:text-yellow-400\"\n size=\"24px\"\n />\n <p className=\"ui-text-p3 text-neutral-700 dark:text-neutral-600\">\n You&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 }, [activeLanguageInfo]);\n\n // Determine if we should show the language selector\n const showLanguageSelector = !fixed && filteredLanguages.length > 0;\n const showFullSelector = filteredLanguages.length > 1;\n\n // Memoize renderContent\n const renderContent = useMemo(() => {\n if (!activeLanguage) return null;\n\n if (hasSnippetForActiveLanguage) {\n return processedChildren;\n }\n\n if (activeLanguageInfo) {\n return <NoSnippetMessage />;\n }\n\n return null;\n }, [\n activeLanguage,\n hasSnippetForActiveLanguage,\n processedChildren,\n activeLanguageInfo,\n NoSnippetMessage,\n ]);\n\n // Render special case for shell commands\n if (isSingleShellCommand) {\n const shellChild = childrenArray[0];\n if (\n isValidElement(shellChild) &&\n isValidElement(shellChild.props.children)\n ) {\n const codeElement = shellChild.props.children;\n const codeContent = codeElement.props.children;\n return (\n <ShellCommandView content={String(codeContent)} className={className} />\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[54px]\",\n className,\n )}\n >\n {headerRow && (\n <div className=\"h-[38px] bg-neutral-200 dark:bg-neutral-1100 border-b border-neutral-300 dark:border-neutral-1000 flex items-center py-4 px-12 rounded-t-lg\">\n {/* macOS window buttons */}\n <div className=\"flex space-x-6\">\n <div className=\"w-[12px] h-[12px] rounded-full bg-orange-500\"></div>\n <div className=\"w-[12px] h-[12px] rounded-full bg-yellow-500\"></div>\n <div className=\"w-[12px] h-[12px] rounded-full bg-green-500\"></div>\n </div>\n\n {/* Title */}\n <div className=\"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000\">\n {title}\n </div>\n\n {/* Empty div for balance */}\n <div className=\"w-[48px]\"></div>\n </div>\n )}\n\n {/* SDK Type Selector Row */}\n {showSDKSelector && (\n <div\n className={cn(\n \"p-8 border-b border-neutral-200 dark:border-neutral-1100 h-[56px]\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n <div className=\"flex gap-12 justify-start\">\n {sdkTypes.has(\"realtime\") && (\n <TooltipButton\n tooltip=\"Realtime SDK\"\n active={activeSDKType === \"realtime\"}\n onClick={() => handleSDKTypeChange(\"realtime\")}\n variant=\"segmented\"\n size=\"sm\"\n alwaysShowLabel={true}\n >\n Realtime\n </TooltipButton>\n )}\n\n {sdkTypes.has(\"rest\") && (\n <TooltipButton\n tooltip=\"REST SDK\"\n active={activeSDKType === \"rest\"}\n onClick={() => handleSDKTypeChange(\"rest\")}\n variant=\"segmented\"\n size=\"sm\"\n alwaysShowLabel={true}\n >\n REST\n </TooltipButton>\n )}\n </div>\n </div>\n )}\n\n {/* Language Selector Row */}\n {showLanguageSelector &&\n (showFullSelector ? (\n <LanguageSelector\n languages={filteredLanguages}\n activeLanguage={activeLanguage}\n onLanguageChange={handleLanguageChange}\n getLanguageDisplayName={getLanguageDisplayName}\n getLanguageIcon={getLanguageIcon}\n activeLanguageInfo={activeLanguageInfo}\n />\n ) : (\n <div\n className={cn(\n \"border-b border-neutral-200 dark:border-neutral-1100 h-[34px] inline-flex items-center px-12\",\n { \"rounded-t-lg\": !headerRow },\n { \"cursor-pointer\": filteredLanguages.length > 0 },\n )}\n {...(filteredLanguages.length > 0 && {\n onClick: () => handleLanguageChange(filteredLanguages[0]),\n })}\n >\n {filteredLanguages.length > 0 && (\n <>\n <Icon\n name={getLanguageIcon(filteredLanguages[0])}\n size=\"16px\"\n additionalCSS=\"mr-8\"\n />\n <span className=\"ui-text-label4 font-semibold text-neutral-800 dark:text-neutral-500 select-none\">\n {getLanguageDisplayName(filteredLanguages[0])}\n </span>\n </>\n )}\n </div>\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 tabIndex={0}\n >\n {renderContent}\n\n {/* Copy button - simplified conditional */}\n {isHovering && activeLanguage && hasSnippetForActiveLanguage && (\n <CopyButton\n onCopy={() => {\n const text = getCodeText();\n if (text) copy(text);\n }}\n isCopied={isCopied}\n />\n )}\n </div>\n\n {/* API Key Selector */}\n {apiKeys && (\n <ApiKeySelector\n apiKeys={apiKeys}\n selectedApiKey={selectedApiKey}\n onApiKeyChange={handleApiKeyChange}\n />\n )}\n </div>\n );\n};\n\nexport default CodeSnippet;\n"],"names":["React","useState","useEffect","Children","isValidElement","useRef","useCallback","useMemo","Code","cn","getLanguageInfo","Icon","LanguageSelector","ApiKeySelector","useCopyToClipboard","ShellCommandView","CopyButton","TooltipButton","CodeSnippet","fixed","headerRow","title","children","className","lang","onChange","apiKeys","sdk","showCodeLines","languageOrdering","codeRef","isCopied","copy","extractLanguageFromCode","codeElement","props","classNames","split","langClass","find","cls","startsWith","substring","childrenArray","languages","sdkTypes","originalLangMap","isSingleShellCommand","toArray","Set","Map","length","includes","forEach","child","preElement","langName","baseLanguage","add","set","push","activeSDKType","setActiveSDKType","size","has","activeLanguage","setActiveLanguage","selectedApiKey","setSelectedApiKey","isHovering","setIsHovering","showSDKSelector","hasOnlyJsonSnippet","filteredLanguages","filtered","filter","sort","a","b","aBase","get","bBase","aIndex","indexOf","bIndex","initialActiveLanguage","prefixedLang","label","getCleanLanguage","getLanguageInfoForDisplay","cleanLang","getLanguageDisplayName","getLanguageIcon","icon","activeLanguageInfo","processedChildren","targetLanguage","map","codeContent","langInfo","key","language","syntaxHighlighterKey","snippet","String","additionalCSS","showLines","hasSnippetForActiveLanguage","some","getCodeText","current","allPreElements","querySelectorAll","Array","from","querySelector","textContent","handleSDKTypeChange","type","nextLang","l","handleLanguageChange","handleApiKeyChange","apiKey","NoSnippetMessage","div","name","color","p","showLanguageSelector","showFullSelector","renderContent","shellChild","content","tooltip","active","onClick","variant","alwaysShowLabel","onLanguageChange","span","ref","onMouseEnter","onMouseLeave","onFocus","onBlur","tabIndex","onCopy","text","onApiKeyChange"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/CodeSnippet.tsx"],"sourcesContent":["import React, {\n useState,\n useEffect,\n Children,\n isValidElement,\n useRef,\n useCallback,\n useMemo,\n} from \"react\";\nimport Code from \"./Code\";\nimport cn from \"./utils/cn\";\nimport { getLanguageInfo } from \"./CodeSnippet/languages\";\nimport Icon from \"./Icon\";\nimport LanguageSelector from \"./CodeSnippet/LanguageSelector\";\nimport ApiKeySelector from \"./CodeSnippet/ApiKeySelector\";\nimport { IconName } from \"./Icon/types\";\nimport useCopyToClipboard from \"./utils/useCopyToClipboard\";\nimport ShellCommandView from \"./CodeSnippet/ShellCommandView\";\nimport CopyButton from \"./CodeSnippet/CopyButton\";\nimport TooltipButton from \"./CodeSnippet/TooltipButton\";\n\n// Define SDK type\nexport type SDKType = \"realtime\" | \"rest\" | null;\n\nexport interface CodeSnippetProps {\n /**\n * If true, hides the language selector row completely\n */\n fixed?: boolean;\n /**\n * If true, renders a macOS-style window header with buttons and title\n */\n headerRow?: boolean;\n /**\n * Title to display in the header row (when headerRow is true)\n */\n title?: string;\n /**\n * Children elements with lang attribute\n */\n children: React.ReactNode;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Default language to display. If not found in available languages, first available is used.\n * If found in languages but no matching snippet exists, a message is displayed.\n */\n lang?: string;\n /**\n * Callback fired when the active language changes\n */\n onChange?: (language: string, sdk?: SDKType) => void;\n /**\n * List of API keys to display in a dropdown\n */\n apiKeys?: string[];\n /**\n * Default SDK type to use for the code snippet\n */\n sdk?: SDKType;\n /**\n * 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\n/**\n * CodeSnippet component that displays code with language switching capability\n */\nconst CodeSnippet: React.FC<CodeSnippetProps> = ({\n fixed = false,\n headerRow = false,\n title = \"Code\",\n children,\n className,\n lang,\n onChange,\n apiKeys,\n sdk,\n showCodeLines = true,\n languageOrdering,\n}) => {\n const codeRef = useRef<HTMLDivElement>(null);\n const { isCopied, copy } = useCopyToClipboard();\n\n // Helper function to extract language from code element\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 // Parse children to extract languages and SDK types - only needs to run once\n const {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSingleShellCommand,\n } = useMemo(() => {\n const childrenArray = Children.toArray(children);\n const languages: string[] = [];\n const sdkTypes = new Set<SDKType>();\n const originalLangMap = new Map<string, string>();\n\n // Check if we have a single shell command\n const isSingleShellCommand =\n childrenArray.length === 1 &&\n isValidElement(childrenArray[0]) &&\n isValidElement(childrenArray[0].props.children) &&\n childrenArray[0].props.children.props.className?.includes(\n \"language-shell\",\n );\n\n // Extract all available languages from children and identify SDK types\n childrenArray.forEach((child) => {\n if (!isValidElement(child)) return;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n\n const langName = extractLanguageFromCode(codeElement);\n if (!langName) return;\n\n // Look for SDK prefixes in the language name itself\n if (langName.startsWith(\"realtime_\")) {\n const baseLanguage = langName.substring(9);\n sdkTypes.add(\"realtime\");\n originalLangMap.set(langName, baseLanguage);\n } else if (langName.startsWith(\"rest_\")) {\n const baseLanguage = langName.substring(5);\n sdkTypes.add(\"rest\");\n originalLangMap.set(langName, baseLanguage);\n } else {\n originalLangMap.set(langName, langName);\n }\n\n // Add to languages list if not already included\n if (!languages.includes(langName)) {\n languages.push(langName);\n }\n });\n\n return {\n childrenArray,\n languages,\n sdkTypes,\n originalLangMap,\n isSingleShellCommand,\n };\n }, [children, extractLanguageFromCode]);\n\n // Simplified state management with separate hooks\n const [activeSDKType, setActiveSDKType] = useState<SDKType>(() => {\n if (sdkTypes.size === 0) return null;\n if (sdk && sdkTypes.has(sdk)) return sdk;\n if (sdkTypes.has(\"realtime\")) return \"realtime\";\n if (sdkTypes.has(\"rest\")) return \"rest\";\n return null;\n });\n const [activeLanguage, setActiveLanguage] = useState<string | null>(null);\n const [selectedApiKey, setSelectedApiKey] = useState(() =>\n apiKeys && apiKeys.length > 0 ? apiKeys[0] : \"\",\n );\n const [isHovering, setIsHovering] = useState(false);\n\n // Check if we need to show SDK type selector\n const showSDKSelector = sdkTypes.size > 0;\n\n // Check if there is only a JSON snippet\n const hasOnlyJsonSnippet = useMemo(\n () => languages.length === 1 && languages[0] === \"json\",\n [languages],\n );\n\n // Get languages filtered by active SDK type & apply ordering\n const filteredLanguages = useMemo(() => {\n // Filter by SDK type if needed\n const filtered =\n !activeSDKType || !showSDKSelector\n ? [...languages]\n : languages.filter((lang) => lang.startsWith(`${activeSDKType}_`));\n\n // Apply custom ordering if provided\n if (languageOrdering && languageOrdering.length > 0) {\n filtered.sort((a, b) => {\n const aBase = originalLangMap.get(a) || a;\n const bBase = originalLangMap.get(b) || b;\n\n const aIndex = languageOrdering.indexOf(aBase);\n const bIndex = languageOrdering.indexOf(bBase);\n\n if (aIndex !== -1 && bIndex !== -1) return aIndex - bIndex;\n if (aIndex !== -1) return -1;\n if (bIndex !== -1) return 1;\n return 0;\n });\n }\n\n return filtered;\n }, [\n activeSDKType,\n showSDKSelector,\n languages,\n languageOrdering,\n originalLangMap,\n ]);\n\n // Determine the initial active language\n const initialActiveLanguage = useMemo((): string | null => {\n if (!lang) {\n return filteredLanguages.length > 0 ? filteredLanguages[0] : null;\n }\n\n // Try with SDK prefix if applicable\n if (activeSDKType) {\n const prefixedLang = `${activeSDKType}_${lang}`;\n if (languages.includes(prefixedLang)) {\n return prefixedLang;\n }\n }\n\n // Try direct match\n if (languages.includes(lang)) {\n return lang;\n }\n\n // Check if it's a known language but not available\n if (getLanguageInfo(lang).label !== lang) {\n return lang;\n }\n\n // Fallback to first available\n return filteredLanguages.length > 0 ? filteredLanguages[0] : null;\n }, [lang, activeSDKType, languages, filteredLanguages]);\n\n // Initialize activeLanguage after filteredLanguages are calculated\n useEffect(() => {\n setActiveLanguage(initialActiveLanguage);\n }, [initialActiveLanguage]);\n\n // Update selected API key if apiKeys changes\n useEffect(() => {\n if (apiKeys && apiKeys.length > 0 && !apiKeys.includes(selectedApiKey)) {\n setSelectedApiKey(apiKeys[0]);\n }\n }, [apiKeys, selectedApiKey]);\n\n // Clean language utilities\n const getCleanLanguage = useCallback(\n (lang: string | null) => (lang ? originalLangMap.get(lang) || lang : null),\n [originalLangMap],\n );\n\n // Get language info for display\n const getLanguageInfoForDisplay = useCallback(\n (lang: string | null) => {\n if (!lang) return null;\n const cleanLang = getCleanLanguage(lang);\n return cleanLang ? getLanguageInfo(cleanLang) : null;\n },\n [getCleanLanguage],\n );\n\n // For language display name and icon (only depends on originalLangMap)\n const getLanguageDisplayName = useCallback(\n (lang: string) => {\n const cleanLang = getCleanLanguage(lang);\n return cleanLang ? getLanguageInfo(cleanLang).label : lang;\n },\n [getCleanLanguage],\n );\n\n const getLanguageIcon = useCallback(\n (lang: string): IconName => {\n const cleanLang = getCleanLanguage(lang);\n return cleanLang\n ? getLanguageInfo(cleanLang).icon\n : \"icon-gui-document-mini\";\n },\n [getCleanLanguage],\n );\n\n // Memoize the active language info\n const activeLanguageInfo = useMemo(\n () => getLanguageInfoForDisplay(activeLanguage),\n [getLanguageInfoForDisplay, activeLanguage],\n );\n\n // Filter and process children for the active language\n const processedChildren = useMemo(() => {\n if (!activeLanguage) return [];\n\n // Target language is either the active one or json in json-only mode\n const targetLanguage = hasOnlyJsonSnippet ? \"json\" : activeLanguage;\n\n return childrenArray\n .filter((child) => {\n if (!isValidElement(child)) return false;\n const codeElement = isValidElement(child.props.children)\n ? child.props.children\n : null;\n const langName = extractLanguageFromCode(codeElement);\n return langName === targetLanguage;\n })\n .map((child) => {\n if (!isValidElement(child)) return child;\n\n const preElement = child;\n const codeElement = isValidElement(preElement.props.children)\n ? preElement.props.children\n : null;\n if (!codeElement) return child;\n\n const codeContent = codeElement.props.children;\n const langName = extractLanguageFromCode(codeElement);\n if (!langName) return child;\n\n const cleanLang = hasOnlyJsonSnippet\n ? \"json\"\n : getCleanLanguage(langName) || langName;\n const langInfo = getLanguageInfo(cleanLang);\n\n // Handle primitive content types\n if (\n typeof codeContent === \"string\" ||\n typeof codeContent === \"number\" ||\n typeof codeContent === \"boolean\"\n ) {\n return (\n <Code\n key={langName}\n language={langInfo.syntaxHighlighterKey || cleanLang}\n snippet={String(codeContent)}\n additionalCSS=\"bg-neutral-100 text-neutral-1300 dark:bg-neutral-1200 dark:text-neutral-200 px-6 py-4\"\n showLines={showCodeLines}\n />\n );\n }\n\n return child;\n });\n }, [\n activeLanguage,\n childrenArray,\n extractLanguageFromCode,\n getCleanLanguage,\n hasOnlyJsonSnippet,\n showCodeLines,\n ]);\n\n // Check if there's a snippet available for the active language\n const hasSnippetForActiveLanguage = useMemo(() => {\n if (!activeLanguage) return false;\n if (hasOnlyJsonSnippet) return true;\n\n return childrenArray.some((child) => {\n if (!isValidElement(child)) return false;\n const codeElement = isValidElement(child.props.children)\n ? child.props.children\n : null;\n const langName = extractLanguageFromCode(codeElement);\n return langName === activeLanguage;\n });\n }, [\n activeLanguage,\n childrenArray,\n extractLanguageFromCode,\n hasOnlyJsonSnippet,\n ]);\n\n // Function to get the current code text content\n const getCodeText = useCallback((): string | null => {\n if (!activeLanguage || !hasSnippetForActiveLanguage || !codeRef.current)\n return null;\n\n const allPreElements = codeRef.current.querySelectorAll(\"pre\");\n for (const preElement of Array.from(allPreElements)) {\n const codeElement = preElement.querySelector(\"code\");\n if (!codeElement || !codeElement.className) continue;\n\n const classNames = codeElement.className.split(\" \");\n const langClass = classNames.find((cls) => cls.startsWith(\"language-\"));\n if (!langClass) continue;\n\n const langName = langClass.substring(9);\n if (\n (hasOnlyJsonSnippet && langName === \"json\") ||\n (!hasOnlyJsonSnippet && langName === activeLanguage)\n ) {\n return codeElement.textContent || \"\";\n }\n }\n\n return null;\n }, [activeLanguage, hasSnippetForActiveLanguage, hasOnlyJsonSnippet]);\n\n // Event handlers\n const handleSDKTypeChange = useCallback(\n (type: SDKType) => {\n // pick first language matching the new SDK prefix\n const nextLang = languages.find((l) => l.startsWith(`${type}_`)) ?? null;\n setActiveSDKType(type);\n setActiveLanguage(nextLang);\n },\n [languages],\n );\n\n const handleLanguageChange = useCallback(\n (language: string) => {\n setActiveLanguage(language);\n\n // Call onChange with clean language name\n if (onChange) {\n const cleanLang = getCleanLanguage(language) || language;\n onChange(cleanLang, activeSDKType);\n }\n },\n [onChange, getCleanLanguage, activeSDKType],\n );\n\n const handleApiKeyChange = useCallback((apiKey: string) => {\n setSelectedApiKey(apiKey);\n }, []);\n\n // Optimize no-snippet message as a component\n const NoSnippetMessage = useMemo(() => {\n if (!activeLanguageInfo) return () => null;\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 }, [activeLanguageInfo]);\n\n // Determine if we should show the language selector\n const showLanguageSelector = !fixed && filteredLanguages.length > 0;\n const showFullSelector = filteredLanguages.length > 1;\n\n // Memoize renderContent\n const renderContent = useMemo(() => {\n if (!activeLanguage) return null;\n\n if (hasSnippetForActiveLanguage) {\n return processedChildren;\n }\n\n if (activeLanguageInfo) {\n return <NoSnippetMessage />;\n }\n\n return null;\n }, [\n activeLanguage,\n hasSnippetForActiveLanguage,\n processedChildren,\n activeLanguageInfo,\n NoSnippetMessage,\n ]);\n\n // Render special case for shell commands\n if (isSingleShellCommand) {\n const shellChild = childrenArray[0];\n if (\n isValidElement(shellChild) &&\n isValidElement(shellChild.props.children)\n ) {\n const codeElement = shellChild.props.children;\n const codeContent = codeElement.props.children;\n return (\n <ShellCommandView content={String(codeContent)} className={className} />\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-1200 border border-neutral-300 dark:border-neutral-1000 min-h-[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 {/* macOS window buttons */}\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 {/* Title */}\n <div className=\"flex-1 text-center ui-text-p3 font-bold text-neutral-1300 dark:text-neutral-000\">\n {title}\n </div>\n\n {/* Empty div for balance */}\n <div className=\"w-12\"></div>\n </div>\n )}\n\n {/* SDK Type Selector Row */}\n {showSDKSelector && (\n <div\n className={cn(\n \"p-2 border-b border-neutral-200 dark:border-neutral-1100 h-14\",\n headerRow ? \"\" : \"rounded-t-lg\",\n )}\n >\n <div className=\"flex gap-3 justify-start\">\n {sdkTypes.has(\"realtime\") && (\n <TooltipButton\n tooltip=\"Realtime SDK\"\n active={activeSDKType === \"realtime\"}\n onClick={() => handleSDKTypeChange(\"realtime\")}\n variant=\"segmented\"\n size=\"sm\"\n alwaysShowLabel={true}\n >\n Realtime\n </TooltipButton>\n )}\n\n {sdkTypes.has(\"rest\") && (\n <TooltipButton\n tooltip=\"REST SDK\"\n active={activeSDKType === \"rest\"}\n onClick={() => handleSDKTypeChange(\"rest\")}\n variant=\"segmented\"\n size=\"sm\"\n alwaysShowLabel={true}\n >\n REST\n </TooltipButton>\n )}\n </div>\n </div>\n )}\n\n {/* Language Selector Row */}\n {showLanguageSelector &&\n (showFullSelector ? (\n <LanguageSelector\n languages={filteredLanguages}\n activeLanguage={activeLanguage}\n onLanguageChange={handleLanguageChange}\n getLanguageDisplayName={getLanguageDisplayName}\n getLanguageIcon={getLanguageIcon}\n activeLanguageInfo={activeLanguageInfo}\n />\n ) : (\n <div\n className={cn(\n \"border-b border-neutral-200 dark:border-neutral-1100 h-[2.125rem] inline-flex items-center px-3\",\n { \"rounded-t-lg\": !headerRow },\n { \"cursor-pointer\": filteredLanguages.length > 0 },\n )}\n {...(filteredLanguages.length > 0 && {\n onClick: () => handleLanguageChange(filteredLanguages[0]),\n })}\n >\n {filteredLanguages.length > 0 && (\n <>\n <Icon\n name={getLanguageIcon(filteredLanguages[0])}\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 {getLanguageDisplayName(filteredLanguages[0])}\n </span>\n </>\n )}\n </div>\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 tabIndex={0}\n >\n {renderContent}\n\n {/* Copy button - simplified conditional */}\n {isHovering && activeLanguage && hasSnippetForActiveLanguage && (\n <CopyButton\n onCopy={() => {\n const text = getCodeText();\n if (text) copy(text);\n }}\n isCopied={isCopied}\n />\n )}\n </div>\n\n {/* API Key Selector */}\n {apiKeys && (\n <ApiKeySelector\n apiKeys={apiKeys}\n selectedApiKey={selectedApiKey}\n onApiKeyChange={handleApiKeyChange}\n />\n )}\n </div>\n );\n};\n\nexport default CodeSnippet;\n"],"names":["React","useState","useEffect","Children","isValidElement","useRef","useCallback","useMemo","Code","cn","getLanguageInfo","Icon","LanguageSelector","ApiKeySelector","useCopyToClipboard","ShellCommandView","CopyButton","TooltipButton","CodeSnippet","fixed","headerRow","title","children","className","lang","onChange","apiKeys","sdk","showCodeLines","languageOrdering","codeRef","isCopied","copy","extractLanguageFromCode","codeElement","props","classNames","split","langClass","find","cls","startsWith","substring","childrenArray","languages","sdkTypes","originalLangMap","isSingleShellCommand","toArray","Set","Map","length","includes","forEach","child","preElement","langName","baseLanguage","add","set","push","activeSDKType","setActiveSDKType","size","has","activeLanguage","setActiveLanguage","selectedApiKey","setSelectedApiKey","isHovering","setIsHovering","showSDKSelector","hasOnlyJsonSnippet","filteredLanguages","filtered","filter","sort","a","b","aBase","get","bBase","aIndex","indexOf","bIndex","initialActiveLanguage","prefixedLang","label","getCleanLanguage","getLanguageInfoForDisplay","cleanLang","getLanguageDisplayName","getLanguageIcon","icon","activeLanguageInfo","processedChildren","targetLanguage","map","codeContent","langInfo","key","language","syntaxHighlighterKey","snippet","String","additionalCSS","showLines","hasSnippetForActiveLanguage","some","getCodeText","current","allPreElements","querySelectorAll","Array","from","querySelector","textContent","handleSDKTypeChange","type","nextLang","l","handleLanguageChange","handleApiKeyChange","apiKey","NoSnippetMessage","div","name","color","p","showLanguageSelector","showFullSelector","renderContent","shellChild","content","tooltip","active","onClick","variant","alwaysShowLabel","onLanguageChange","span","ref","onMouseEnter","onMouseLeave","onFocus","onBlur","tabIndex","onCopy","text","onApiKeyChange"],"mappings":"AAAA,OAAOA,OACLC,QAAQ,CACRC,SAAS,CACTC,QAAQ,CACRC,cAAc,CACdC,MAAM,CACNC,WAAW,CACXC,OAAO,KACF,OAAQ,AACf,QAAOC,SAAU,QAAS,AAC1B,QAAOC,OAAQ,YAAa,AAC5B,QAASC,eAAe,KAAQ,yBAA0B,AAC1D,QAAOC,SAAU,QAAS,AAC1B,QAAOC,qBAAsB,gCAAiC,AAC9D,QAAOC,mBAAoB,8BAA+B,AAE1D,QAAOC,uBAAwB,4BAA6B,AAC5D,QAAOC,qBAAsB,gCAAiC,AAC9D,QAAOC,eAAgB,0BAA2B,AAClD,QAAOC,kBAAmB,6BAA8B,CAyDxD,MAAMC,YAA0C,CAAC,CAC/CC,MAAQ,KAAK,CACbC,UAAY,KAAK,CACjBC,MAAQ,MAAM,CACdC,QAAQ,CACRC,SAAS,CACTC,IAAI,CACJC,QAAQ,CACRC,OAAO,CACPC,GAAG,CACHC,cAAgB,IAAI,CACpBC,gBAAgB,CACjB,IACC,MAAMC,QAAUzB,OAAuB,MACvC,KAAM,CAAE0B,QAAQ,CAAEC,IAAI,CAAE,CAAGlB,qBAG3B,MAAMmB,wBAA0B3B,YAC9B,AAAC4B,cACC,GAAI,CAACA,aAAe,CAACA,YAAYC,KAAK,CAACZ,SAAS,CAAE,OAAO,KAEzD,MAAMa,WAAaF,YAAYC,KAAK,CAACZ,SAAS,CAACc,KAAK,CAAC,KACrD,MAAMC,UAAYF,WAAWG,IAAI,CAAC,AAACC,KACjCA,IAAIC,UAAU,CAAC,cAEjB,GAAI,CAACH,UAAW,OAAO,KAEvB,OAAOA,UAAUI,SAAS,CAAC,EAC7B,EACA,EAAE,EAIJ,KAAM,CACJC,aAAa,CACbC,SAAS,CACTC,QAAQ,CACRC,eAAe,CACfC,oBAAoB,CACrB,CAAGxC,QAAQ,KACV,MAAMoC,cAAgBxC,SAAS6C,OAAO,CAAC1B,UACvC,MAAMsB,UAAsB,EAAE,CAC9B,MAAMC,SAAW,IAAII,IACrB,MAAMH,gBAAkB,IAAII,IAG5B,MAAMH,qBACJJ,cAAcQ,MAAM,GAAK,GACzB/C,eAAeuC,aAAa,CAAC,EAAE,GAC/BvC,eAAeuC,aAAa,CAAC,EAAE,CAACR,KAAK,CAACb,QAAQ,GAC9CqB,aAAa,CAAC,EAAE,CAACR,KAAK,CAACb,QAAQ,CAACa,KAAK,CAACZ,SAAS,EAAE6B,SAC/C,kBAIJT,cAAcU,OAAO,CAAC,AAACC,QACrB,GAAI,CAAClD,eAAekD,OAAQ,OAE5B,MAAMC,WAAaD,MACnB,MAAMpB,YAAc9B,eAAemD,WAAWpB,KAAK,CAACb,QAAQ,EACxDiC,WAAWpB,KAAK,CAACb,QAAQ,CACzB,KAEJ,MAAMkC,SAAWvB,wBAAwBC,aACzC,GAAI,CAACsB,SAAU,OAGf,GAAIA,SAASf,UAAU,CAAC,aAAc,CACpC,MAAMgB,aAAeD,SAASd,SAAS,CAAC,GACxCG,SAASa,GAAG,CAAC,YACbZ,gBAAgBa,GAAG,CAACH,SAAUC,aAChC,MAAO,GAAID,SAASf,UAAU,CAAC,SAAU,CACvC,MAAMgB,aAAeD,SAASd,SAAS,CAAC,GACxCG,SAASa,GAAG,CAAC,QACbZ,gBAAgBa,GAAG,CAACH,SAAUC,aAChC,KAAO,CACLX,gBAAgBa,GAAG,CAACH,SAAUA,SAChC,CAGA,GAAI,CAACZ,UAAUQ,QAAQ,CAACI,UAAW,CACjCZ,UAAUgB,IAAI,CAACJ,SACjB,CACF,GAEA,MAAO,CACLb,cACAC,UACAC,SACAC,gBACAC,oBACF,CACF,EAAG,CAACzB,SAAUW,wBAAwB,EAGtC,KAAM,CAAC4B,cAAeC,iBAAiB,CAAG7D,SAAkB,KAC1D,GAAI4C,SAASkB,IAAI,GAAK,EAAG,OAAO,KAChC,GAAIpC,KAAOkB,SAASmB,GAAG,CAACrC,KAAM,OAAOA,IACrC,GAAIkB,SAASmB,GAAG,CAAC,YAAa,MAAO,WACrC,GAAInB,SAASmB,GAAG,CAAC,QAAS,MAAO,OACjC,OAAO,IACT,GACA,KAAM,CAACC,eAAgBC,kBAAkB,CAAGjE,SAAwB,MACpE,KAAM,CAACkE,eAAgBC,kBAAkB,CAAGnE,SAAS,IACnDyB,SAAWA,QAAQyB,MAAM,CAAG,EAAIzB,OAAO,CAAC,EAAE,CAAG,IAE/C,KAAM,CAAC2C,WAAYC,cAAc,CAAGrE,SAAS,OAG7C,MAAMsE,gBAAkB1B,SAASkB,IAAI,CAAG,EAGxC,MAAMS,mBAAqBjE,QACzB,IAAMqC,UAAUO,MAAM,GAAK,GAAKP,SAAS,CAAC,EAAE,GAAK,OACjD,CAACA,UAAU,EAIb,MAAM6B,kBAAoBlE,QAAQ,KAEhC,MAAMmE,SACJ,CAACb,eAAiB,CAACU,gBACf,IAAI3B,UAAU,CACdA,UAAU+B,MAAM,CAAC,AAACnD,MAASA,KAAKiB,UAAU,CAAC,CAAC,EAAEoB,cAAc,CAAC,CAAC,GAGpE,GAAIhC,kBAAoBA,iBAAiBsB,MAAM,CAAG,EAAG,CACnDuB,SAASE,IAAI,CAAC,CAACC,EAAGC,KAChB,MAAMC,MAAQjC,gBAAgBkC,GAAG,CAACH,IAAMA,EACxC,MAAMI,MAAQnC,gBAAgBkC,GAAG,CAACF,IAAMA,EAExC,MAAMI,OAASrD,iBAAiBsD,OAAO,CAACJ,OACxC,MAAMK,OAASvD,iBAAiBsD,OAAO,CAACF,OAExC,GAAIC,SAAW,CAAC,GAAKE,SAAW,CAAC,EAAG,OAAOF,OAASE,OACpD,GAAIF,SAAW,CAAC,EAAG,MAAO,CAAC,EAC3B,GAAIE,SAAW,CAAC,EAAG,OAAO,EAC1B,OAAO,CACT,EACF,CAEA,OAAOV,QACT,EAAG,CACDb,cACAU,gBACA3B,UACAf,iBACAiB,gBACD,EAGD,MAAMuC,sBAAwB9E,QAAQ,KACpC,GAAI,CAACiB,KAAM,CACT,OAAOiD,kBAAkBtB,MAAM,CAAG,EAAIsB,iBAAiB,CAAC,EAAE,CAAG,IAC/D,CAGA,GAAIZ,cAAe,CACjB,MAAMyB,aAAe,CAAC,EAAEzB,cAAc,CAAC,EAAErC,KAAK,CAAC,CAC/C,GAAIoB,UAAUQ,QAAQ,CAACkC,cAAe,CACpC,OAAOA,YACT,CACF,CAGA,GAAI1C,UAAUQ,QAAQ,CAAC5B,MAAO,CAC5B,OAAOA,IACT,CAGA,GAAId,gBAAgBc,MAAM+D,KAAK,GAAK/D,KAAM,CACxC,OAAOA,IACT,CAGA,OAAOiD,kBAAkBtB,MAAM,CAAG,EAAIsB,iBAAiB,CAAC,EAAE,CAAG,IAC/D,EAAG,CAACjD,KAAMqC,cAAejB,UAAW6B,kBAAkB,EAGtDvE,UAAU,KACRgE,kBAAkBmB,sBACpB,EAAG,CAACA,sBAAsB,EAG1BnF,UAAU,KACR,GAAIwB,SAAWA,QAAQyB,MAAM,CAAG,GAAK,CAACzB,QAAQ0B,QAAQ,CAACe,gBAAiB,CACtEC,kBAAkB1C,OAAO,CAAC,EAAE,CAC9B,CACF,EAAG,CAACA,QAASyC,eAAe,EAG5B,MAAMqB,iBAAmBlF,YACvB,AAACkB,MAAyBA,KAAOsB,gBAAgBkC,GAAG,CAACxD,OAASA,KAAO,KACrE,CAACsB,gBAAgB,EAInB,MAAM2C,0BAA4BnF,YAChC,AAACkB,OACC,GAAI,CAACA,KAAM,OAAO,KAClB,MAAMkE,UAAYF,iBAAiBhE,MACnC,OAAOkE,UAAYhF,gBAAgBgF,WAAa,IAClD,EACA,CAACF,iBAAiB,EAIpB,MAAMG,uBAAyBrF,YAC7B,AAACkB,OACC,MAAMkE,UAAYF,iBAAiBhE,MACnC,OAAOkE,UAAYhF,gBAAgBgF,WAAWH,KAAK,CAAG/D,IACxD,EACA,CAACgE,iBAAiB,EAGpB,MAAMI,gBAAkBtF,YACtB,AAACkB,OACC,MAAMkE,UAAYF,iBAAiBhE,MACnC,OAAOkE,UACHhF,gBAAgBgF,WAAWG,IAAI,CAC/B,wBACN,EACA,CAACL,iBAAiB,EAIpB,MAAMM,mBAAqBvF,QACzB,IAAMkF,0BAA0BxB,gBAChC,CAACwB,0BAA2BxB,eAAe,EAI7C,MAAM8B,kBAAoBxF,QAAQ,KAChC,GAAI,CAAC0D,eAAgB,MAAO,EAAE,CAG9B,MAAM+B,eAAiBxB,mBAAqB,OAASP,eAErD,OAAOtB,cACJgC,MAAM,CAAC,AAACrB,QACP,GAAI,CAAClD,eAAekD,OAAQ,OAAO,MACnC,MAAMpB,YAAc9B,eAAekD,MAAMnB,KAAK,CAACb,QAAQ,EACnDgC,MAAMnB,KAAK,CAACb,QAAQ,CACpB,KACJ,MAAMkC,SAAWvB,wBAAwBC,aACzC,OAAOsB,WAAawC,cACtB,GACCC,GAAG,CAAC,AAAC3C,QACJ,GAAI,CAAClD,eAAekD,OAAQ,OAAOA,MAEnC,MAAMC,WAAaD,MACnB,MAAMpB,YAAc9B,eAAemD,WAAWpB,KAAK,CAACb,QAAQ,EACxDiC,WAAWpB,KAAK,CAACb,QAAQ,CACzB,KACJ,GAAI,CAACY,YAAa,OAAOoB,MAEzB,MAAM4C,YAAchE,YAAYC,KAAK,CAACb,QAAQ,CAC9C,MAAMkC,SAAWvB,wBAAwBC,aACzC,GAAI,CAACsB,SAAU,OAAOF,MAEtB,MAAMoC,UAAYlB,mBACd,OACAgB,iBAAiBhC,WAAaA,SAClC,MAAM2C,SAAWzF,gBAAgBgF,WAGjC,GACE,OAAOQ,cAAgB,UACvB,OAAOA,cAAgB,UACvB,OAAOA,cAAgB,UACvB,CACA,OACE,oBAAC1F,MACC4F,IAAK5C,SACL6C,SAAUF,SAASG,oBAAoB,EAAIZ,UAC3Ca,QAASC,OAAON,aAChBO,cAAc,wFACdC,UAAW9E,eAGjB,CAEA,OAAO0B,KACT,EACJ,EAAG,CACDW,eACAtB,cACAV,wBACAuD,iBACAhB,mBACA5C,cACD,EAGD,MAAM+E,4BAA8BpG,QAAQ,KAC1C,GAAI,CAAC0D,eAAgB,OAAO,MAC5B,GAAIO,mBAAoB,OAAO,KAE/B,OAAO7B,cAAciE,IAAI,CAAC,AAACtD,QACzB,GAAI,CAAClD,eAAekD,OAAQ,OAAO,MACnC,MAAMpB,YAAc9B,eAAekD,MAAMnB,KAAK,CAACb,QAAQ,EACnDgC,MAAMnB,KAAK,CAACb,QAAQ,CACpB,KACJ,MAAMkC,SAAWvB,wBAAwBC,aACzC,OAAOsB,WAAaS,cACtB,EACF,EAAG,CACDA,eACAtB,cACAV,wBACAuC,mBACD,EAGD,MAAMqC,YAAcvG,YAAY,KAC9B,GAAI,CAAC2D,gBAAkB,CAAC0C,6BAA+B,CAAC7E,QAAQgF,OAAO,CACrE,OAAO,KAET,MAAMC,eAAiBjF,QAAQgF,OAAO,CAACE,gBAAgB,CAAC,OACxD,IAAK,MAAMzD,cAAc0D,MAAMC,IAAI,CAACH,gBAAiB,CACnD,MAAM7E,YAAcqB,WAAW4D,aAAa,CAAC,QAC7C,GAAI,CAACjF,aAAe,CAACA,YAAYX,SAAS,CAAE,SAE5C,MAAMa,WAAaF,YAAYX,SAAS,CAACc,KAAK,CAAC,KAC/C,MAAMC,UAAYF,WAAWG,IAAI,CAAC,AAACC,KAAQA,IAAIC,UAAU,CAAC,cAC1D,GAAI,CAACH,UAAW,SAEhB,MAAMkB,SAAWlB,UAAUI,SAAS,CAAC,GACrC,GACE,AAAC8B,oBAAsBhB,WAAa,QACnC,CAACgB,oBAAsBhB,WAAaS,eACrC,CACA,OAAO/B,YAAYkF,WAAW,EAAI,EACpC,CACF,CAEA,OAAO,IACT,EAAG,CAACnD,eAAgB0C,4BAA6BnC,mBAAmB,EAGpE,MAAM6C,oBAAsB/G,YAC1B,AAACgH,OAEC,MAAMC,SAAW3E,UAAUL,IAAI,CAAC,AAACiF,GAAMA,EAAE/E,UAAU,CAAC,CAAC,EAAE6E,KAAK,CAAC,CAAC,IAAM,KACpExD,iBAAiBwD,MACjBpD,kBAAkBqD,SACpB,EACA,CAAC3E,UAAU,EAGb,MAAM6E,qBAAuBnH,YAC3B,AAAC+F,WACCnC,kBAAkBmC,UAGlB,GAAI5E,SAAU,CACZ,MAAMiE,UAAYF,iBAAiBa,WAAaA,SAChD5E,SAASiE,UAAW7B,cACtB,CACF,EACA,CAACpC,SAAU+D,iBAAkB3B,cAAc,EAG7C,MAAM6D,mBAAqBpH,YAAY,AAACqH,SACtCvD,kBAAkBuD,OACpB,EAAG,EAAE,EAGL,MAAMC,iBAAmBrH,QAAQ,KAC/B,GAAI,CAACuF,mBAAoB,MAAO,IAAM,KAEtC,MAAO,IACL,oBAAC+B,OAAItG,UAAU,gHACb,oBAACZ,MACCmH,KAAK,wCACLC,MAAM,uCACNhE,KAAK,SAEP,oBAACiE,KAAEzG,UAAU,qDAAoD,gCAC5BuE,mBAAmBP,KAAK,CAAC,+BACjCO,mBAAmBP,KAAK,CAAC,oEACE,IACrDO,mBAAmBP,KAAK,CAAC,6GAKlC,EAAG,CAACO,mBAAmB,EAGvB,MAAMmC,qBAAuB,CAAC9G,OAASsD,kBAAkBtB,MAAM,CAAG,EAClE,MAAM+E,iBAAmBzD,kBAAkBtB,MAAM,CAAG,EAGpD,MAAMgF,cAAgB5H,QAAQ,KAC5B,GAAI,CAAC0D,eAAgB,OAAO,KAE5B,GAAI0C,4BAA6B,CAC/B,OAAOZ,iBACT,CAEA,GAAID,mBAAoB,CACtB,OAAO,oBAAC8B,sBACV,CAEA,OAAO,IACT,EAAG,CACD3D,eACA0C,4BACAZ,kBACAD,mBACA8B,iBACD,EAGD,GAAI7E,qBAAsB,CACxB,MAAMqF,WAAazF,aAAa,CAAC,EAAE,CACnC,GACEvC,eAAegI,aACfhI,eAAegI,WAAWjG,KAAK,CAACb,QAAQ,EACxC,CACA,MAAMY,YAAckG,WAAWjG,KAAK,CAACb,QAAQ,CAC7C,MAAM4E,YAAchE,YAAYC,KAAK,CAACb,QAAQ,CAC9C,OACE,oBAACP,kBAAiBsH,QAAS7B,OAAON,aAAc3E,UAAWA,WAE/D,CACF,CAEA,OACE,oBAACsG,OACCtG,UAAWd,GACT,qIACAc,YAGDH,WACC,oBAACyG,OAAItG,UAAU,kJAEb,oBAACsG,OAAItG,UAAU,oBACb,oBAACsG,OAAItG,UAAU,uCACf,oBAACsG,OAAItG,UAAU,uCACf,oBAACsG,OAAItG,UAAU,uCAIjB,oBAACsG,OAAItG,UAAU,mFACZF,OAIH,oBAACwG,OAAItG,UAAU,UAKlBgD,iBACC,oBAACsD,OACCtG,UAAWd,GACT,gEACAW,UAAY,GAAK,iBAGnB,oBAACyG,OAAItG,UAAU,4BACZsB,SAASmB,GAAG,CAAC,aACZ,oBAAC/C,eACCqH,QAAQ,eACRC,OAAQ1E,gBAAkB,WAC1B2E,QAAS,IAAMnB,oBAAoB,YACnCoB,QAAQ,YACR1E,KAAK,KACL2E,gBAAiB,MAClB,YAKF7F,SAASmB,GAAG,CAAC,SACZ,oBAAC/C,eACCqH,QAAQ,WACRC,OAAQ1E,gBAAkB,OAC1B2E,QAAS,IAAMnB,oBAAoB,QACnCoB,QAAQ,YACR1E,KAAK,KACL2E,gBAAiB,MAClB,UASRT,sBACEC,CAAAA,iBACC,oBAACtH,kBACCgC,UAAW6B,kBACXR,eAAgBA,eAChB0E,iBAAkBlB,qBAClB9B,uBAAwBA,uBACxBC,gBAAiBA,gBACjBE,mBAAoBA,qBAGtB,oBAAC+B,OACCtG,UAAWd,GACT,kGACA,CAAE,eAAgB,CAACW,SAAU,EAC7B,CAAE,iBAAkBqD,kBAAkBtB,MAAM,CAAG,CAAE,GAElD,GAAIsB,kBAAkBtB,MAAM,CAAG,GAAK,CACnCqF,QAAS,IAAMf,qBAAqBhD,iBAAiB,CAAC,EAAE,CAC1D,CAAC,EAEAA,kBAAkBtB,MAAM,CAAG,GAC1B,wCACE,oBAACxC,MACCmH,KAAMlC,gBAAgBnB,iBAAiB,CAAC,EAAE,EAC1CV,KAAK,OACL0C,cAAc,SAEhB,oBAACmC,QAAKrH,UAAU,mFACboE,uBAAuBlB,iBAAiB,CAAC,EAAE,IAKtD,EAEF,oBAACoD,OACCgB,IAAK/G,QACLP,UAAU,WACVuH,aAAc,IAAMxE,cAAc,MAClCyE,aAAc,IAAMzE,cAAc,OAClC0E,QAAS,IAAM1E,cAAc,MAC7B2E,OAAQ,IAAM3E,cAAc,OAC5B4E,SAAU,GAETf,cAGA9D,YAAcJ,gBAAkB0C,6BAC/B,oBAAC3F,YACCmI,OAAQ,KACN,MAAMC,KAAOvC,cACb,GAAIuC,KAAMpH,KAAKoH,KACjB,EACArH,SAAUA,YAMfL,SACC,oBAACb,gBACCa,QAASA,QACTyC,eAAgBA,eAChBkF,eAAgB3B,qBAK1B,CAEA,gBAAexG,WAAY"}
Binary file
Binary file
@@ -3,7 +3,7 @@
3
3
  @apply rounded-lg bg-white font-sans;
4
4
  @apply justify-between items-center;
5
5
  @apply opacity-100 z-50 bottom-0 fixed sm:flex;
6
- @apply p-16 mb-16 ml-16;
6
+ @apply p-4 mb-4 ml-4;
7
7
  max-width: 70vw;
8
8
  box-shadow: 0px 24px 32px 0px #0000000d;
9
9
  border: 1px solid var(--color-mid-grey);
@@ -1,2 +1,2 @@
1
- import React,{useRef,useEffect,useState}from"react";import Cookie from"js-cookie";import _absUrl from"./url-base";const COOKIE_EXPIRY=365;const CookieMessage=({cookieId,urlBase})=>{const ref=useRef(null);const[hideCookieMessage,setHideCookieMessage]=useState(true);useEffect(()=>{const isCookieSet=Cookie.get(cookieId)?true:false;setHideCookieMessage(isCookieSet)},[]);const handleClose=()=>{Cookie.set(cookieId,"1",{expires:COOKIE_EXPIRY});ref.current?.classList.add("bottom-1","opacity-0");setTimeout(()=>setHideCookieMessage(true),500)};const absUrl=path=>_absUrl(path,urlBase);if(hideCookieMessage)return null;return React.createElement("div",{className:"ui-cookie-message",ref:ref},React.createElement("p",{className:"ui-text-p2 pr-32"},React.createElement("a",{href:absUrl("/privacy"),className:"underline"},"How we use cookies")," ","to improve your experience."),React.createElement("button",{className:"ui-btn-secondary mt-12 sm:mt-0 whitespace-nowrap",onClick:handleClose},"Accept and close"))};export default CookieMessage;
1
+ import React,{useRef,useEffect,useState}from"react";import Cookie from"js-cookie";import _absUrl from"./url-base";const COOKIE_EXPIRY=365;const CookieMessage=({cookieId,urlBase})=>{const ref=useRef(null);const[hideCookieMessage,setHideCookieMessage]=useState(true);useEffect(()=>{const isCookieSet=Cookie.get(cookieId)?true:false;setHideCookieMessage(isCookieSet)},[]);const handleClose=()=>{Cookie.set(cookieId,"1",{expires:COOKIE_EXPIRY});ref.current?.classList.add("bottom-px","opacity-0");setTimeout(()=>setHideCookieMessage(true),500)};const absUrl=path=>_absUrl(path,urlBase);if(hideCookieMessage)return null;return React.createElement("div",{className:"ui-cookie-message",ref:ref},React.createElement("p",{className:"ui-text-p2 pr-8"},React.createElement("a",{href:absUrl("/privacy"),className:"underline"},"How we use cookies")," ","to improve your experience."),React.createElement("button",{className:"ui-btn-secondary mt-3 sm:mt-0 whitespace-nowrap",onClick:handleClose},"Accept and close"))};export default CookieMessage;
2
2
  //# sourceMappingURL=CookieMessage.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/CookieMessage.tsx"],"sourcesContent":["import React, { useRef, useEffect, useState } from \"react\";\nimport Cookie from \"js-cookie\";\n\nimport _absUrl from \"./url-base\";\n\nconst COOKIE_EXPIRY = 365;\n\ntype CookieMessageProps = {\n cookieId: string;\n urlBase: string;\n};\n\nconst CookieMessage = ({ cookieId, urlBase }: CookieMessageProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const [hideCookieMessage, setHideCookieMessage] = useState(true);\n\n useEffect(() => {\n const isCookieSet = Cookie.get(cookieId) ? true : false;\n setHideCookieMessage(isCookieSet);\n }, []);\n\n const handleClose = () => {\n Cookie.set(cookieId, \"1\", { expires: COOKIE_EXPIRY });\n\n ref.current?.classList.add(\"bottom-1\", \"opacity-0\");\n setTimeout(() => setHideCookieMessage(true), 500);\n };\n\n const absUrl = (path: string) => _absUrl(path, urlBase);\n\n // Presume the message is hidden by default\n if (hideCookieMessage) return null;\n\n return (\n <div className=\"ui-cookie-message\" ref={ref}>\n <p className=\"ui-text-p2 pr-32\">\n <a href={absUrl(\"/privacy\")} className=\"underline\">\n How we use cookies\n </a>{\" \"}\n to improve your experience.\n </p>\n <button\n className=\"ui-btn-secondary mt-12 sm:mt-0 whitespace-nowrap\"\n onClick={handleClose}\n >\n Accept and close\n </button>\n </div>\n );\n};\n\nexport default CookieMessage;\n"],"names":["React","useRef","useEffect","useState","Cookie","_absUrl","COOKIE_EXPIRY","CookieMessage","cookieId","urlBase","ref","hideCookieMessage","setHideCookieMessage","isCookieSet","get","handleClose","set","expires","current","classList","add","setTimeout","absUrl","path","div","className","p","a","href","button","onClick"],"mappings":"AAAA,OAAOA,OAASC,MAAM,CAAEC,SAAS,CAAEC,QAAQ,KAAQ,OAAQ,AAC3D,QAAOC,WAAY,WAAY,AAE/B,QAAOC,YAAa,YAAa,CAEjC,MAAMC,cAAgB,IAOtB,MAAMC,cAAgB,CAAC,CAAEC,QAAQ,CAAEC,OAAO,CAAsB,IAC9D,MAAMC,IAAMT,OAAuB,MACnC,KAAM,CAACU,kBAAmBC,qBAAqB,CAAGT,SAAS,MAE3DD,UAAU,KACR,MAAMW,YAAcT,OAAOU,GAAG,CAACN,UAAY,KAAO,MAClDI,qBAAqBC,YACvB,EAAG,EAAE,EAEL,MAAME,YAAc,KAClBX,OAAOY,GAAG,CAACR,SAAU,IAAK,CAAES,QAASX,aAAc,EAEnDI,CAAAA,IAAIQ,OAAO,EAAEC,UAAUC,IAAI,WAAY,aACvCC,WAAW,IAAMT,qBAAqB,MAAO,IAC/C,EAEA,MAAMU,OAAS,AAACC,MAAiBlB,QAAQkB,KAAMd,SAG/C,GAAIE,kBAAmB,OAAO,KAE9B,OACE,oBAACa,OAAIC,UAAU,oBAAoBf,IAAKA,KACtC,oBAACgB,KAAED,UAAU,oBACX,oBAACE,KAAEC,KAAMN,OAAO,YAAaG,UAAU,aAAY,sBAE9C,IAAI,+BAGX,oBAACI,UACCJ,UAAU,mDACVK,QAASf,aACV,oBAKP,CAEA,gBAAeR,aAAc"}
1
+ {"version":3,"sources":["../../src/core/CookieMessage.tsx"],"sourcesContent":["import React, { useRef, useEffect, useState } from \"react\";\nimport Cookie from \"js-cookie\";\n\nimport _absUrl from \"./url-base\";\n\nconst COOKIE_EXPIRY = 365;\n\ntype CookieMessageProps = {\n cookieId: string;\n urlBase: string;\n};\n\nconst CookieMessage = ({ cookieId, urlBase }: CookieMessageProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const [hideCookieMessage, setHideCookieMessage] = useState(true);\n\n useEffect(() => {\n const isCookieSet = Cookie.get(cookieId) ? true : false;\n setHideCookieMessage(isCookieSet);\n }, []);\n\n const handleClose = () => {\n Cookie.set(cookieId, \"1\", { expires: COOKIE_EXPIRY });\n\n ref.current?.classList.add(\"bottom-px\", \"opacity-0\");\n setTimeout(() => setHideCookieMessage(true), 500);\n };\n\n const absUrl = (path: string) => _absUrl(path, urlBase);\n\n // Presume the message is hidden by default\n if (hideCookieMessage) return null;\n\n return (\n <div className=\"ui-cookie-message\" ref={ref}>\n <p className=\"ui-text-p2 pr-8\">\n <a href={absUrl(\"/privacy\")} className=\"underline\">\n How we use cookies\n </a>{\" \"}\n to improve your experience.\n </p>\n <button\n className=\"ui-btn-secondary mt-3 sm:mt-0 whitespace-nowrap\"\n onClick={handleClose}\n >\n Accept and close\n </button>\n </div>\n );\n};\n\nexport default CookieMessage;\n"],"names":["React","useRef","useEffect","useState","Cookie","_absUrl","COOKIE_EXPIRY","CookieMessage","cookieId","urlBase","ref","hideCookieMessage","setHideCookieMessage","isCookieSet","get","handleClose","set","expires","current","classList","add","setTimeout","absUrl","path","div","className","p","a","href","button","onClick"],"mappings":"AAAA,OAAOA,OAASC,MAAM,CAAEC,SAAS,CAAEC,QAAQ,KAAQ,OAAQ,AAC3D,QAAOC,WAAY,WAAY,AAE/B,QAAOC,YAAa,YAAa,CAEjC,MAAMC,cAAgB,IAOtB,MAAMC,cAAgB,CAAC,CAAEC,QAAQ,CAAEC,OAAO,CAAsB,IAC9D,MAAMC,IAAMT,OAAuB,MACnC,KAAM,CAACU,kBAAmBC,qBAAqB,CAAGT,SAAS,MAE3DD,UAAU,KACR,MAAMW,YAAcT,OAAOU,GAAG,CAACN,UAAY,KAAO,MAClDI,qBAAqBC,YACvB,EAAG,EAAE,EAEL,MAAME,YAAc,KAClBX,OAAOY,GAAG,CAACR,SAAU,IAAK,CAAES,QAASX,aAAc,EAEnDI,CAAAA,IAAIQ,OAAO,EAAEC,UAAUC,IAAI,YAAa,aACxCC,WAAW,IAAMT,qBAAqB,MAAO,IAC/C,EAEA,MAAMU,OAAS,AAACC,MAAiBlB,QAAQkB,KAAMd,SAG/C,GAAIE,kBAAmB,OAAO,KAE9B,OACE,oBAACa,OAAIC,UAAU,oBAAoBf,IAAKA,KACtC,oBAACgB,KAAED,UAAU,mBACX,oBAACE,KAAEC,KAAMN,OAAO,YAAaG,UAAU,aAAY,sBAE9C,IAAI,+BAGX,oBAACI,UACCJ,UAAU,kDACVK,QAASf,aACV,oBAKP,CAEA,gBAAeR,aAAc"}
Binary file
@@ -1,2 +1,2 @@
1
- import React from"react";const CustomerLogos=({companies,additionalCss=""})=>{return React.createElement("section",{className:"w-full bg-white"},React.createElement("ul",{className:`py-64 flex flex-row flex-wrap md:flex-nowrap content-between m-auto items-center ${additionalCss}`},companies.map(company=>React.createElement("li",{key:company.label,className:"flex-auto text-center sm:w-1/3 w-1/2"},React.createElement("img",{alt:company.label,src:company.logo,className:"mx-auto"})))))};export default CustomerLogos;
1
+ import React from"react";const CustomerLogos=({companies,additionalCss=""})=>{return React.createElement("section",{className:"w-full bg-white"},React.createElement("ul",{className:`py-16 flex flex-row flex-wrap md:flex-nowrap content-between m-auto items-center ${additionalCss}`},companies.map(company=>React.createElement("li",{key:company.label,className:"flex-auto text-center sm:w-1/3 w-1/2"},React.createElement("img",{alt:company.label,src:company.logo,className:"mx-auto"})))))};export default CustomerLogos;
2
2
  //# sourceMappingURL=CustomerLogos.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/CustomerLogos.tsx"],"sourcesContent":["import React from \"react\";\n\ntype CompanyEntity = {\n label: string;\n logo: string;\n};\n\ntype CustomerLogosProps = {\n companies: CompanyEntity[];\n additionalCss?: string;\n};\n\nconst CustomerLogos = ({\n companies,\n additionalCss = \"\",\n}: CustomerLogosProps) => {\n return (\n <section className=\"w-full bg-white\">\n <ul\n className={`py-64 flex flex-row flex-wrap md:flex-nowrap content-between m-auto items-center ${additionalCss}`}\n >\n {companies.map((company) => (\n <li\n key={company.label}\n className=\"flex-auto text-center sm:w-1/3 w-1/2\"\n >\n <img alt={company.label} src={company.logo} className=\"mx-auto\" />\n </li>\n ))}\n </ul>\n </section>\n );\n};\n\nexport default CustomerLogos;\n"],"names":["React","CustomerLogos","companies","additionalCss","section","className","ul","map","company","li","key","label","img","alt","src","logo"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,CAY1B,MAAMC,cAAgB,CAAC,CACrBC,SAAS,CACTC,cAAgB,EAAE,CACC,IACnB,OACE,oBAACC,WAAQC,UAAU,mBACjB,oBAACC,MACCD,UAAW,CAAC,iFAAiF,EAAEF,cAAc,CAAC,EAE7GD,UAAUK,GAAG,CAAC,AAACC,SACd,oBAACC,MACCC,IAAKF,QAAQG,KAAK,CAClBN,UAAU,wCAEV,oBAACO,OAAIC,IAAKL,QAAQG,KAAK,CAAEG,IAAKN,QAAQO,IAAI,CAAEV,UAAU,eAMlE,CAEA,gBAAeJ,aAAc"}
1
+ {"version":3,"sources":["../../src/core/CustomerLogos.tsx"],"sourcesContent":["import React from \"react\";\n\ntype CompanyEntity = {\n label: string;\n logo: string;\n};\n\ntype CustomerLogosProps = {\n companies: CompanyEntity[];\n additionalCss?: string;\n};\n\nconst CustomerLogos = ({\n companies,\n additionalCss = \"\",\n}: CustomerLogosProps) => {\n return (\n <section className=\"w-full bg-white\">\n <ul\n className={`py-16 flex flex-row flex-wrap md:flex-nowrap content-between m-auto items-center ${additionalCss}`}\n >\n {companies.map((company) => (\n <li\n key={company.label}\n className=\"flex-auto text-center sm:w-1/3 w-1/2\"\n >\n <img alt={company.label} src={company.logo} className=\"mx-auto\" />\n </li>\n ))}\n </ul>\n </section>\n );\n};\n\nexport default CustomerLogos;\n"],"names":["React","CustomerLogos","companies","additionalCss","section","className","ul","map","company","li","key","label","img","alt","src","logo"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,CAY1B,MAAMC,cAAgB,CAAC,CACrBC,SAAS,CACTC,cAAgB,EAAE,CACC,IACnB,OACE,oBAACC,WAAQC,UAAU,mBACjB,oBAACC,MACCD,UAAW,CAAC,iFAAiF,EAAEF,cAAc,CAAC,EAE7GD,UAAUK,GAAG,CAAC,AAACC,SACd,oBAACC,MACCC,IAAKF,QAAQG,KAAK,CAClBN,UAAU,wCAEV,oBAACO,OAAIC,IAAKL,QAAQG,KAAK,CAAEG,IAAKN,QAAQO,IAAI,CAAEV,UAAU,eAMlE,CAEA,gBAAeJ,aAAc"}
Binary file
@@ -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,role:"button",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-8 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-4"},title,iconName?React.createElement(Icon,{name:iconName,size:"1rem",additionalCSS:"align-middle ml-8 relative -top-1 -left-4 text-neutral-1300 dark:text-neutral-000"}):null),subtitle?React.createElement("p",{className:"ui-text-p3 mb-16"},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,role:"button",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;
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 role=\"button\"\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-8 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-4\">\n {title}\n {iconName ? (\n <Icon\n name={iconName}\n size=\"1rem\"\n additionalCSS=\"align-middle ml-8 relative -top-1 -left-4 text-neutral-1300 dark:text-neutral-000\"\n />\n ) : null}\n </p>\n {subtitle ? <p className=\"ui-text-p3 mb-16\">{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","role","onClick","name","size","additionalCSS","Content","anchorPosition","contentClassNames","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,KAAK,SACLC,QAAS,IAAMvB,QAAQ,CAACD,QACxBiB,UAAWnB,GACT,wGACAqB,oBAGDhB,SACD,oBAACN,MACC4B,KACEzB,OAAS,2BAA6B,6BAExC0B,KAAK,UACLC,cAAc,4CAItB,EAEA,MAAMC,QAAU,CAAC,CACfzB,QAAQ,CACR0B,eAAiB,OAAO,CACxBC,iBAAiB,CACJ,IACb,KAAM,CAAE9B,MAAM,CAAE,CAAGP,WAAWM,qBAE9B,GAAI,CAACC,OAAQ,CACX,OAAO,IACT,CAEA,OACE,oBAACe,OACCC,GAAG,eACHO,KAAK,OACLN,UAAWnB,GACT,iJACA+B,iBAAmB,QAAU,UAAY,SACzCC,oBAGD3B,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,MACC4B,KAAMU,SACNT,KAAK,OACLC,cAAc,sFAEd,MAELO,SAAW,oBAACI,KAAErB,UAAU,oBAAoBiB,UAAgB,KAC5D/B,SAGP,CAEAD,CAAAA,aAAagB,OAAO,CAAGA,OACvBhB,CAAAA,aAAa0B,OAAO,CAAGA,OACvB1B,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 role=\"button\"\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","role","onClick","name","size","additionalCSS","Content","anchorPosition","contentClassNames","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,KAAK,SACLC,QAAS,IAAMvB,QAAQ,CAACD,QACxBiB,UAAWnB,GACT,wGACAqB,oBAGDhB,SACD,oBAACN,MACC4B,KACEzB,OAAS,2BAA6B,6BAExC0B,KAAK,UACLC,cAAc,4CAItB,EAEA,MAAMC,QAAU,CAAC,CACfzB,QAAQ,CACR0B,eAAiB,OAAO,CACxBC,iBAAiB,CACJ,IACb,KAAM,CAAE9B,MAAM,CAAE,CAAGP,WAAWM,qBAE9B,GAAI,CAACC,OAAQ,CACX,OAAO,IACT,CAEA,OACE,oBAACe,OACCC,GAAG,eACHO,KAAK,OACLN,UAAWnB,GACT,iJACA+B,iBAAmB,QAAU,UAAY,SACzCC,oBAGD3B,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,MACC4B,KAAMU,SACNT,KAAK,OACLC,cAAc,uFAEd,MAELO,SAAW,oBAACI,KAAErB,UAAU,mBAAmBiB,UAAgB,KAC3D/B,SAGP,CAEAD,CAAAA,aAAagB,OAAO,CAAGA,OACvBhB,CAAAA,aAAa0B,OAAO,CAAGA,OACvB1B,CAAAA,aAAa6B,IAAI,CAAGA,IAEpB,gBAAe7B,YAAa"}
package/core/Expander.js CHANGED
@@ -1,2 +1,2 @@
1
- import React,{useEffect,useRef,useState}from"react";import throttle from"lodash.throttle";const Expander=({heightThreshold=200,className,fadeClassName,controlsClassName,controlsOpenedLabel,controlsClosedLabel,children})=>{const innerRef=useRef(null);const[showControls,setShowControls]=useState(false);const[contentHeight,setContentHeight]=useState(heightThreshold);const[height,setHeight]=useState(heightThreshold);const[expanded,setExpanded]=useState(false);useEffect(()=>{if(innerRef.current){setContentHeight(innerRef.current.clientHeight)}if(contentHeight<heightThreshold){setHeight("auto")}else if(expanded){setHeight(contentHeight)}else{setHeight(heightThreshold)}setShowControls(contentHeight>=heightThreshold)},[contentHeight,heightThreshold,expanded]);useEffect(()=>{const onResize=throttle(()=>{if(innerRef.current){setContentHeight(innerRef.current.clientHeight)}},250);window.addEventListener("resize",onResize);return()=>{window.removeEventListener("resize",onResize)}},[]);return React.createElement(React.Fragment,null,React.createElement("div",{style:{height},"data-testid":"expander-container",className:`overflow-hidden transition-all relative ${className??""}`},showControls&&!expanded&&React.createElement("div",{className:`h-64 w-full bg-gradient-to-t from-white to-transparent absolute bottom-0 left-0 right-0 ${fadeClassName??""}`}),React.createElement("div",{ref:innerRef},children)),showControls&&React.createElement("div",{onClick:()=>setExpanded(!expanded),onKeyDown:e=>e.key==="Enter"&&setExpanded(!expanded),tabIndex:0,"data-testid":"expander-controls",className:`${heightThreshold===0&&!expanded?"":"mt-16"} cursor-pointer font-bold text-gui-blue-default-light hover:text-gui-blue-hover-light ${controlsClassName??""}`},expanded?controlsOpenedLabel??"View less -":controlsClosedLabel??"View all +"))};export default Expander;
1
+ import React,{useEffect,useRef,useState}from"react";import throttle from"lodash.throttle";const Expander=({heightThreshold=200,className,fadeClassName,controlsClassName,controlsOpenedLabel,controlsClosedLabel,children})=>{const innerRef=useRef(null);const[showControls,setShowControls]=useState(false);const[contentHeight,setContentHeight]=useState(heightThreshold);const[height,setHeight]=useState(heightThreshold);const[expanded,setExpanded]=useState(false);useEffect(()=>{if(innerRef.current){setContentHeight(innerRef.current.clientHeight)}if(contentHeight<heightThreshold){setHeight("auto")}else if(expanded){setHeight(contentHeight)}else{setHeight(heightThreshold)}setShowControls(contentHeight>=heightThreshold)},[contentHeight,heightThreshold,expanded]);useEffect(()=>{const onResize=throttle(()=>{if(innerRef.current){setContentHeight(innerRef.current.clientHeight)}},250);window.addEventListener("resize",onResize);return()=>{window.removeEventListener("resize",onResize)}},[]);return React.createElement(React.Fragment,null,React.createElement("div",{style:{height},"data-testid":"expander-container",className:`overflow-hidden transition-all relative ${className??""}`},showControls&&!expanded&&React.createElement("div",{className:`h-16 w-full bg-gradient-to-t from-white to-transparent absolute bottom-0 left-0 right-0 ${fadeClassName??""}`}),React.createElement("div",{ref:innerRef},children)),showControls&&React.createElement("div",{onClick:()=>setExpanded(!expanded),onKeyDown:e=>e.key==="Enter"&&setExpanded(!expanded),tabIndex:0,"data-testid":"expander-controls",className:`${heightThreshold===0&&!expanded?"":"mt-4"} cursor-pointer font-bold text-gui-blue-default-light hover:text-gui-blue-hover-light ${controlsClassName??""}`},expanded?controlsOpenedLabel??"View less -":controlsClosedLabel??"View all +"))};export default Expander;
2
2
  //# sourceMappingURL=Expander.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/Expander.tsx"],"sourcesContent":["import React, {\n PropsWithChildren,\n ReactNode,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport throttle from \"lodash.throttle\";\n\ntype ExpanderProps = {\n heightThreshold?: number;\n className?: string;\n fadeClassName?: string;\n controlsClassName?: string;\n controlsOpenedLabel?: string | ReactNode;\n controlsClosedLabel?: string | ReactNode;\n};\n\nconst Expander = ({\n heightThreshold = 200,\n className,\n fadeClassName,\n controlsClassName,\n controlsOpenedLabel,\n controlsClosedLabel,\n children,\n}: PropsWithChildren<ExpanderProps>) => {\n const innerRef = useRef<HTMLDivElement>(null);\n const [showControls, setShowControls] = useState(false);\n const [contentHeight, setContentHeight] = useState<number>(heightThreshold);\n const [height, setHeight] = useState<number | \"auto\">(heightThreshold);\n const [expanded, setExpanded] = useState(false);\n\n useEffect(() => {\n if (innerRef.current) {\n setContentHeight(innerRef.current.clientHeight);\n }\n\n if (contentHeight < heightThreshold) {\n setHeight(\"auto\");\n } else if (expanded) {\n setHeight(contentHeight);\n } else {\n setHeight(heightThreshold);\n }\n\n setShowControls(contentHeight >= heightThreshold);\n }, [contentHeight, heightThreshold, expanded]);\n\n useEffect(() => {\n const onResize = throttle(() => {\n if (innerRef.current) {\n setContentHeight(innerRef.current.clientHeight);\n }\n }, 250);\n\n window.addEventListener(\"resize\", onResize);\n return () => {\n window.removeEventListener(\"resize\", onResize);\n };\n }, []);\n\n return (\n <>\n <div\n style={{ height }}\n data-testid=\"expander-container\"\n className={`overflow-hidden transition-all relative ${className ?? \"\"}`}\n >\n {showControls && !expanded && (\n <div\n className={`h-64 w-full bg-gradient-to-t from-white to-transparent absolute bottom-0 left-0 right-0 ${\n fadeClassName ?? \"\"\n }`}\n ></div>\n )}\n <div ref={innerRef}>{children}</div>\n </div>\n {showControls && (\n <div\n onClick={() => setExpanded(!expanded)}\n onKeyDown={(e) => e.key === \"Enter\" && setExpanded(!expanded)}\n tabIndex={0}\n data-testid=\"expander-controls\"\n className={`${heightThreshold === 0 && !expanded ? \"\" : \"mt-16\"} cursor-pointer font-bold text-gui-blue-default-light hover:text-gui-blue-hover-light ${controlsClassName ?? \"\"}`}\n >\n {expanded\n ? (controlsOpenedLabel ?? \"View less -\")\n : (controlsClosedLabel ?? \"View all +\")}\n </div>\n )}\n </>\n );\n};\n\nexport default Expander;\n"],"names":["React","useEffect","useRef","useState","throttle","Expander","heightThreshold","className","fadeClassName","controlsClassName","controlsOpenedLabel","controlsClosedLabel","children","innerRef","showControls","setShowControls","contentHeight","setContentHeight","height","setHeight","expanded","setExpanded","current","clientHeight","onResize","window","addEventListener","removeEventListener","div","style","data-testid","ref","onClick","onKeyDown","e","key","tabIndex"],"mappings":"AAAA,OAAOA,OAGLC,SAAS,CACTC,MAAM,CACNC,QAAQ,KACH,OAAQ,AACf,QAAOC,aAAc,iBAAkB,CAWvC,MAAMC,SAAW,CAAC,CAChBC,gBAAkB,GAAG,CACrBC,SAAS,CACTC,aAAa,CACbC,iBAAiB,CACjBC,mBAAmB,CACnBC,mBAAmB,CACnBC,QAAQ,CACyB,IACjC,MAAMC,SAAWX,OAAuB,MACxC,KAAM,CAACY,aAAcC,gBAAgB,CAAGZ,SAAS,OACjD,KAAM,CAACa,cAAeC,iBAAiB,CAAGd,SAAiBG,iBAC3D,KAAM,CAACY,OAAQC,UAAU,CAAGhB,SAA0BG,iBACtD,KAAM,CAACc,SAAUC,YAAY,CAAGlB,SAAS,OAEzCF,UAAU,KACR,GAAIY,SAASS,OAAO,CAAE,CACpBL,iBAAiBJ,SAASS,OAAO,CAACC,YAAY,CAChD,CAEA,GAAIP,cAAgBV,gBAAiB,CACnCa,UAAU,OACZ,MAAO,GAAIC,SAAU,CACnBD,UAAUH,cACZ,KAAO,CACLG,UAAUb,gBACZ,CAEAS,gBAAgBC,eAAiBV,gBACnC,EAAG,CAACU,cAAeV,gBAAiBc,SAAS,EAE7CnB,UAAU,KACR,MAAMuB,SAAWpB,SAAS,KACxB,GAAIS,SAASS,OAAO,CAAE,CACpBL,iBAAiBJ,SAASS,OAAO,CAACC,YAAY,CAChD,CACF,EAAG,KAEHE,OAAOC,gBAAgB,CAAC,SAAUF,UAClC,MAAO,KACLC,OAAOE,mBAAmB,CAAC,SAAUH,SACvC,CACF,EAAG,EAAE,EAEL,OACE,wCACE,oBAACI,OACCC,MAAO,CAAEX,MAAO,EAChBY,cAAY,qBACZvB,UAAW,CAAC,wCAAwC,EAAEA,WAAa,GAAG,CAAC,EAEtEO,cAAgB,CAACM,UAChB,oBAACQ,OACCrB,UAAW,CAAC,wFAAwF,EAClGC,eAAiB,GAClB,CAAC,GAGN,oBAACoB,OAAIG,IAAKlB,UAAWD,WAEtBE,cACC,oBAACc,OACCI,QAAS,IAAMX,YAAY,CAACD,UAC5Ba,UAAW,AAACC,GAAMA,EAAEC,GAAG,GAAK,SAAWd,YAAY,CAACD,UACpDgB,SAAU,EACVN,cAAY,oBACZvB,UAAW,CAAC,EAAED,kBAAoB,GAAK,CAACc,SAAW,GAAK,QAAQ,sFAAsF,EAAEX,mBAAqB,GAAG,CAAC,EAEhLW,SACIV,qBAAuB,cACvBC,qBAAuB,cAKtC,CAEA,gBAAeN,QAAS"}
1
+ {"version":3,"sources":["../../src/core/Expander.tsx"],"sourcesContent":["import React, {\n PropsWithChildren,\n ReactNode,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport throttle from \"lodash.throttle\";\n\ntype ExpanderProps = {\n heightThreshold?: number;\n className?: string;\n fadeClassName?: string;\n controlsClassName?: string;\n controlsOpenedLabel?: string | ReactNode;\n controlsClosedLabel?: string | ReactNode;\n};\n\nconst Expander = ({\n heightThreshold = 200,\n className,\n fadeClassName,\n controlsClassName,\n controlsOpenedLabel,\n controlsClosedLabel,\n children,\n}: PropsWithChildren<ExpanderProps>) => {\n const innerRef = useRef<HTMLDivElement>(null);\n const [showControls, setShowControls] = useState(false);\n const [contentHeight, setContentHeight] = useState<number>(heightThreshold);\n const [height, setHeight] = useState<number | \"auto\">(heightThreshold);\n const [expanded, setExpanded] = useState(false);\n\n useEffect(() => {\n if (innerRef.current) {\n setContentHeight(innerRef.current.clientHeight);\n }\n\n if (contentHeight < heightThreshold) {\n setHeight(\"auto\");\n } else if (expanded) {\n setHeight(contentHeight);\n } else {\n setHeight(heightThreshold);\n }\n\n setShowControls(contentHeight >= heightThreshold);\n }, [contentHeight, heightThreshold, expanded]);\n\n useEffect(() => {\n const onResize = throttle(() => {\n if (innerRef.current) {\n setContentHeight(innerRef.current.clientHeight);\n }\n }, 250);\n\n window.addEventListener(\"resize\", onResize);\n return () => {\n window.removeEventListener(\"resize\", onResize);\n };\n }, []);\n\n return (\n <>\n <div\n style={{ height }}\n data-testid=\"expander-container\"\n className={`overflow-hidden transition-all relative ${className ?? \"\"}`}\n >\n {showControls && !expanded && (\n <div\n className={`h-16 w-full bg-gradient-to-t from-white to-transparent absolute bottom-0 left-0 right-0 ${\n fadeClassName ?? \"\"\n }`}\n ></div>\n )}\n <div ref={innerRef}>{children}</div>\n </div>\n {showControls && (\n <div\n onClick={() => setExpanded(!expanded)}\n onKeyDown={(e) => e.key === \"Enter\" && setExpanded(!expanded)}\n tabIndex={0}\n data-testid=\"expander-controls\"\n className={`${heightThreshold === 0 && !expanded ? \"\" : \"mt-4\"} cursor-pointer font-bold text-gui-blue-default-light hover:text-gui-blue-hover-light ${controlsClassName ?? \"\"}`}\n >\n {expanded\n ? (controlsOpenedLabel ?? \"View less -\")\n : (controlsClosedLabel ?? \"View all +\")}\n </div>\n )}\n </>\n );\n};\n\nexport default Expander;\n"],"names":["React","useEffect","useRef","useState","throttle","Expander","heightThreshold","className","fadeClassName","controlsClassName","controlsOpenedLabel","controlsClosedLabel","children","innerRef","showControls","setShowControls","contentHeight","setContentHeight","height","setHeight","expanded","setExpanded","current","clientHeight","onResize","window","addEventListener","removeEventListener","div","style","data-testid","ref","onClick","onKeyDown","e","key","tabIndex"],"mappings":"AAAA,OAAOA,OAGLC,SAAS,CACTC,MAAM,CACNC,QAAQ,KACH,OAAQ,AACf,QAAOC,aAAc,iBAAkB,CAWvC,MAAMC,SAAW,CAAC,CAChBC,gBAAkB,GAAG,CACrBC,SAAS,CACTC,aAAa,CACbC,iBAAiB,CACjBC,mBAAmB,CACnBC,mBAAmB,CACnBC,QAAQ,CACyB,IACjC,MAAMC,SAAWX,OAAuB,MACxC,KAAM,CAACY,aAAcC,gBAAgB,CAAGZ,SAAS,OACjD,KAAM,CAACa,cAAeC,iBAAiB,CAAGd,SAAiBG,iBAC3D,KAAM,CAACY,OAAQC,UAAU,CAAGhB,SAA0BG,iBACtD,KAAM,CAACc,SAAUC,YAAY,CAAGlB,SAAS,OAEzCF,UAAU,KACR,GAAIY,SAASS,OAAO,CAAE,CACpBL,iBAAiBJ,SAASS,OAAO,CAACC,YAAY,CAChD,CAEA,GAAIP,cAAgBV,gBAAiB,CACnCa,UAAU,OACZ,MAAO,GAAIC,SAAU,CACnBD,UAAUH,cACZ,KAAO,CACLG,UAAUb,gBACZ,CAEAS,gBAAgBC,eAAiBV,gBACnC,EAAG,CAACU,cAAeV,gBAAiBc,SAAS,EAE7CnB,UAAU,KACR,MAAMuB,SAAWpB,SAAS,KACxB,GAAIS,SAASS,OAAO,CAAE,CACpBL,iBAAiBJ,SAASS,OAAO,CAACC,YAAY,CAChD,CACF,EAAG,KAEHE,OAAOC,gBAAgB,CAAC,SAAUF,UAClC,MAAO,KACLC,OAAOE,mBAAmB,CAAC,SAAUH,SACvC,CACF,EAAG,EAAE,EAEL,OACE,wCACE,oBAACI,OACCC,MAAO,CAAEX,MAAO,EAChBY,cAAY,qBACZvB,UAAW,CAAC,wCAAwC,EAAEA,WAAa,GAAG,CAAC,EAEtEO,cAAgB,CAACM,UAChB,oBAACQ,OACCrB,UAAW,CAAC,wFAAwF,EAClGC,eAAiB,GAClB,CAAC,GAGN,oBAACoB,OAAIG,IAAKlB,UAAWD,WAEtBE,cACC,oBAACc,OACCI,QAAS,IAAMX,YAAY,CAACD,UAC5Ba,UAAW,AAACC,GAAMA,EAAEC,GAAG,GAAK,SAAWd,YAAY,CAACD,UACpDgB,SAAU,EACVN,cAAY,oBACZvB,UAAW,CAAC,EAAED,kBAAoB,GAAK,CAACc,SAAW,GAAK,OAAO,sFAAsF,EAAEX,mBAAqB,GAAG,CAAC,EAE/KW,SACIV,qBAAuB,cACvBC,qBAAuB,cAKtC,CAEA,gBAAeN,QAAS"}
Binary file
@@ -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-unavailable 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-8":!flush},`ui-${textSize}`,additionalCSS),style:{"--featured-link-icon-size":`var(${textSize.replace("text","--fs")})`},...targetAndRel,onClick:onClick},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-8 relative -top-1 -right-4 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-8 relative -top-1 -left-4 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-bold block group/featured-link",{"text-gui-unavailable 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},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 inline-block",{"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] inline-block",{"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 { \"text-gui-unavailable pointer-events-none\": disabled },\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-8\": !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 >\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-8 relative -top-1 -right-4 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-8 relative -top-1 -left-4 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","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,CAAE,2CAA4CiB,QAAS,EACvD,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,SAERF,QACC,wCACE,oBAACb,MACC0B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOjB,UACPG,cAAeb,GACb,qFACA,CAAE,oCAAqC,CAACiB,QAAS,EACjDC,iBAGHF,UAGH,wCACGA,SACD,oBAACjB,MACC0B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOjB,UACPG,cAAeb,GACb,8DACA,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-bold block group/featured-link\",\n { \"text-gui-unavailable pointer-events-none\": disabled },\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 >\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 inline-block\",\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] inline-block\",\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","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,CAAE,2CAA4CiB,QAAS,EACvD,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,SAERF,QACC,wCACE,oBAACb,MACC0B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOjB,UACPG,cAAeb,GACb,mGACA,CAAE,oCAAqC,CAACiB,QAAS,EACjDC,iBAGHF,UAGH,wCACGA,SACD,oBAACjB,MACC0B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOjB,UACPG,cAAeb,GACb,4EACA,CACE,mCAAoC,CAACiB,QACvC,EACAC,kBAOd,CAEA,gBAAeV,YAAa"}
Binary file
@@ -7,7 +7,7 @@
7
7
  }
8
8
 
9
9
  .ui-flash-message {
10
- @apply font-sans font-light antialiased max-w-screen-xl mx-auto mt-8 opacity-0 relative;
10
+ @apply font-sans font-light antialiased max-w-screen-xl mx-auto mt-2 opacity-0 relative;
11
11
  transition:
12
12
  opacity 200ms,
13
13
  transform 200ms,
package/core/Flash.js CHANGED
@@ -1,2 +1,2 @@
1
- import React,{useEffect,useState,useRef}from"react";import DOMPurify from"dompurify";import{getRemoteDataStore}from"./remote-data-store.js";import ConnectStateWrapper from"./ConnectStateWrapper";import Icon from"./Icon";const REDUCER_KEY="flashes";const FLASH_DATA_ID="ui-flashes";const initialState={items:[]};const reducerFlashes={[REDUCER_KEY]:(state=initialState,action)=>{switch(action.type){case"flash/push":{const flashes=Array.isArray(action.payload)?action.payload:[action.payload];return{items:[...state.items,...flashes]}}default:return state}}};const selectFlashes=store=>store.getState()[REDUCER_KEY];const FLASH_BG_COLOR={error:"bg-gui-error",success:"bg-zingy-green",notice:"bg-electric-cyan",info:"bg-electric-cyan",alert:"bg-active-orange"};const FLASH_TEXT_COLOR={error:"text-white",success:"text-cool-black",notice:"text-cool-black",info:"text-cool-black",alert:"text-white"};const AUTO_HIDE=["success","info","notice"];const AUTO_HIDE_TIME=8e3;const useAutoHide=(type,closeFlash)=>{const timeoutId=useRef(null);useEffect(()=>{if(AUTO_HIDE.includes(type)){timeoutId.current=setTimeout(()=>{closeFlash()},AUTO_HIDE_TIME)}return()=>{if(timeoutId.current){clearTimeout(timeoutId.current)}}},[])};const Flash=({id,type,content,removeFlash})=>{const ref=useRef(null);const[closed,setClosed]=useState(false);const[flashHeight,setFlashHeight]=useState(0);const[triggerEntryAnimation,setTriggerEntryAnimation]=useState(false);const closeFlash=()=>{if(ref.current){setFlashHeight(ref.current.getBoundingClientRect().height)}setClosed(true);setTimeout(()=>{if(id){removeFlash(id)}},100)};useEffect(()=>setTriggerEntryAnimation(true),[]);useAutoHide(type,closeFlash);const animateEntry=triggerEntryAnimation&&!closed;let style;if(flashHeight&&!closed){style={height:`${flashHeight}px`}}else if(closed){style={height:0,marginTop:0,zIndex:-1}}else{style={}}const safeContent=DOMPurify.sanitize(content,{ALLOWED_TAGS:["a"],ALLOWED_ATTR:["href","data-method"],ALLOWED_URI_REGEXP:/^\/[^/]/});const withIcons={notice:"icon-gui-ably-badge",success:"icon-gui-check-outline",error:"icon-gui-exclamation-triangle-outline",alert:"icon-gui-exclamation-triangle-outline",info:""};const iconColor={notice:"text-cool-black",success:"text-cool-black",error:"text-white",alert:"text-white",info:""};return React.createElement("div",{className:`ui-flash-message ui-grid-px ${animateEntry?"ui-flash-message-enter":""}`,style:style,ref:ref,"data-id":"ui-flash","data-testid":"ui-flash"},React.createElement("div",{className:`${FLASH_BG_COLOR[type]} p-32 flex align-center rounded shadow-container-subtle`},withIcons[type]&&iconColor[type]&&React.createElement(Icon,{name:withIcons[type],color:iconColor[type],size:"1.5rem",additionalCSS:"mr-16 self-baseline"}),React.createElement("p",{className:`ui-text-p1 mr-16 ${FLASH_TEXT_COLOR[type]}`,dangerouslySetInnerHTML:{__html:safeContent}}),React.createElement("button",{type:"button",className:"p-0 ml-auto self-start focus:outline-none",onClick:closeFlash},iconColor[type]&&React.createElement(Icon,{name:"icon-gui-x-mark-outline",color:iconColor[type],size:"1.5rem",additionalCSS:"transition-colors"}))))};const Flashes=({flashes})=>{const[flashesWithIds,setFlashesWithIds]=useState([]);const removeFlash=flashId=>setFlashesWithIds(items=>items.filter(item=>item.id!==flashId));useEffect(()=>{setFlashesWithIds(state=>{return[...state,...(flashes?.items??[]).map(flash=>({...flash,id:Math.random().toString(36).slice(2),removed:false,removeFlash}))]})},[flashes]);return React.createElement("div",{className:"ui-flash","data-id":FLASH_DATA_ID},flashesWithIds.filter(item=>!item.removed).map(flash=>React.createElement(Flash,{key:flash.id,...flash})))};const BackendFlashes=({flashes})=>{useEffect(()=>{const transformedFlashes=flashes.map(flash=>{const[type,content]=flash;return{type,content}})||[];if(transformedFlashes.length>0){const store=getRemoteDataStore();store.dispatch({type:"flash/push",payload:transformedFlashes})}},[]);const WrappedFlashes=ConnectStateWrapper(Flashes,{flashes:selectFlashes});return React.createElement(WrappedFlashes,null)};export{reducerFlashes,FLASH_DATA_ID,Flashes};export default BackendFlashes;
1
+ import React,{useEffect,useState,useRef}from"react";import DOMPurify from"dompurify";import{getRemoteDataStore}from"./remote-data-store.js";import ConnectStateWrapper from"./ConnectStateWrapper";import Icon from"./Icon";const REDUCER_KEY="flashes";const FLASH_DATA_ID="ui-flashes";const initialState={items:[]};const reducerFlashes={[REDUCER_KEY]:(state=initialState,action)=>{switch(action.type){case"flash/push":{const flashes=Array.isArray(action.payload)?action.payload:[action.payload];return{items:[...state.items,...flashes]}}default:return state}}};const selectFlashes=store=>store.getState()[REDUCER_KEY];const FLASH_BG_COLOR={error:"bg-gui-error",success:"bg-zingy-green",notice:"bg-electric-cyan",info:"bg-electric-cyan",alert:"bg-active-orange"};const FLASH_TEXT_COLOR={error:"text-white",success:"text-cool-black",notice:"text-cool-black",info:"text-cool-black",alert:"text-white"};const AUTO_HIDE=["success","info","notice"];const AUTO_HIDE_TIME=8e3;const useAutoHide=(type,closeFlash)=>{const timeoutId=useRef(null);useEffect(()=>{if(AUTO_HIDE.includes(type)){timeoutId.current=setTimeout(()=>{closeFlash()},AUTO_HIDE_TIME)}return()=>{if(timeoutId.current){clearTimeout(timeoutId.current)}}},[])};const Flash=({id,type,content,removeFlash})=>{const ref=useRef(null);const[closed,setClosed]=useState(false);const[flashHeight,setFlashHeight]=useState(0);const[triggerEntryAnimation,setTriggerEntryAnimation]=useState(false);const closeFlash=()=>{if(ref.current){setFlashHeight(ref.current.getBoundingClientRect().height)}setClosed(true);setTimeout(()=>{if(id){removeFlash(id)}},100)};useEffect(()=>setTriggerEntryAnimation(true),[]);useAutoHide(type,closeFlash);const animateEntry=triggerEntryAnimation&&!closed;let style;if(flashHeight&&!closed){style={height:`${flashHeight}px`}}else if(closed){style={height:0,marginTop:0,zIndex:-1}}else{style={}}const safeContent=DOMPurify.sanitize(content,{ALLOWED_TAGS:["a"],ALLOWED_ATTR:["href","data-method"],ALLOWED_URI_REGEXP:/^\/[^/]/});const withIcons={notice:"icon-gui-ably-badge",success:"icon-gui-check-outline",error:"icon-gui-exclamation-triangle-outline",alert:"icon-gui-exclamation-triangle-outline",info:""};const iconColor={notice:"text-cool-black",success:"text-cool-black",error:"text-white",alert:"text-white",info:""};return React.createElement("div",{className:`ui-flash-message ui-grid-px ${animateEntry?"ui-flash-message-enter":""}`,style:style,ref:ref,"data-id":"ui-flash","data-testid":"ui-flash"},React.createElement("div",{className:`${FLASH_BG_COLOR[type]} p-8 flex align-center rounded shadow-container-subtle`},withIcons[type]&&iconColor[type]&&React.createElement(Icon,{name:withIcons[type],color:iconColor[type],size:"1.5rem",additionalCSS:"mr-4 self-baseline"}),React.createElement("p",{className:`ui-text-p1 mr-4 ${FLASH_TEXT_COLOR[type]}`,dangerouslySetInnerHTML:{__html:safeContent}}),React.createElement("button",{type:"button",className:"p-0 ml-auto self-start focus:outline-none",onClick:closeFlash},iconColor[type]&&React.createElement(Icon,{name:"icon-gui-x-mark-outline",color:iconColor[type],size:"1.5rem",additionalCSS:"transition-colors"}))))};const Flashes=({flashes})=>{const[flashesWithIds,setFlashesWithIds]=useState([]);const removeFlash=flashId=>setFlashesWithIds(items=>items.filter(item=>item.id!==flashId));useEffect(()=>{setFlashesWithIds(state=>{return[...state,...(flashes?.items??[]).map(flash=>({...flash,id:Math.random().toString(36).slice(2),removed:false,removeFlash}))]})},[flashes]);return React.createElement("div",{className:"ui-flash","data-id":FLASH_DATA_ID},flashesWithIds.filter(item=>!item.removed).map(flash=>React.createElement(Flash,{key:flash.id,...flash})))};const BackendFlashes=({flashes})=>{useEffect(()=>{const transformedFlashes=flashes.map(flash=>{const[type,content]=flash;return{type,content}})||[];if(transformedFlashes.length>0){const store=getRemoteDataStore();store.dispatch({type:"flash/push",payload:transformedFlashes})}},[]);const WrappedFlashes=ConnectStateWrapper(Flashes,{flashes:selectFlashes});return React.createElement(WrappedFlashes,null)};export{reducerFlashes,FLASH_DATA_ID,Flashes};export default BackendFlashes;
2
2
  //# sourceMappingURL=Flash.js.map
package/core/Flash.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/Flash.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from \"react\";\nimport DOMPurify from \"dompurify\";\nimport { getRemoteDataStore } from \"./remote-data-store.js\";\nimport ConnectStateWrapper from \"./ConnectStateWrapper\";\nimport Icon from \"./Icon\";\nimport { ColorClass } from \"./styles/colors/types\";\nimport { IconName } from \"./Icon/types\";\n\ntype FlashPropsType = \"error\" | \"success\" | \"notice\" | \"info\" | \"alert\";\n\ntype FlashProps = {\n id: string;\n removed: boolean;\n type: FlashPropsType;\n content: string;\n removeFlash: (id: string) => void;\n};\n\ntype FlashesProps = {\n flashes: { items: Pick<FlashProps, \"type\" | \"content\">[] };\n};\n\ntype BackendFlashesProps = {\n flashes: string[][];\n};\n\nconst REDUCER_KEY = \"flashes\";\nconst FLASH_DATA_ID = \"ui-flashes\";\n\nconst initialState = { items: [] };\n\nconst reducerFlashes = {\n [REDUCER_KEY]: (\n state: {\n items: FlashProps[];\n } = initialState,\n action: { type: string; payload: FlashProps | FlashProps[] },\n ) => {\n switch (action.type) {\n case \"flash/push\": {\n const flashes = Array.isArray(action.payload)\n ? action.payload\n : [action.payload];\n return { items: [...state.items, ...flashes] };\n }\n default:\n return state;\n }\n },\n};\n\n// Not cool but redux isn't a long term plan here\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst selectFlashes = (store: any): { items: FlashProps[] } =>\n store.getState()[REDUCER_KEY];\n\nconst FLASH_BG_COLOR = {\n error: \"bg-gui-error\",\n success: \"bg-zingy-green\",\n notice: \"bg-electric-cyan\",\n info: \"bg-electric-cyan\",\n alert: \"bg-active-orange\",\n};\n\nconst FLASH_TEXT_COLOR = {\n error: \"text-white\",\n success: \"text-cool-black\",\n notice: \"text-cool-black\",\n info: \"text-cool-black\",\n alert: \"text-white\",\n};\n\nconst AUTO_HIDE = [\"success\", \"info\", \"notice\"];\nconst AUTO_HIDE_TIME = 8000;\n\nconst useAutoHide = (type: string, closeFlash: () => void) => {\n const timeoutId = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (AUTO_HIDE.includes(type)) {\n timeoutId.current = setTimeout(() => {\n closeFlash();\n }, AUTO_HIDE_TIME);\n }\n\n return () => {\n if (timeoutId.current) {\n clearTimeout(timeoutId.current);\n }\n };\n }, []);\n};\n\nconst Flash = ({ id, type, content, removeFlash }: FlashProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const [closed, setClosed] = useState(false);\n const [flashHeight, setFlashHeight] = useState(0);\n const [triggerEntryAnimation, setTriggerEntryAnimation] = useState(false);\n\n const closeFlash = () => {\n if (ref.current) {\n setFlashHeight(ref.current.getBoundingClientRect().height);\n }\n\n setClosed(true);\n\n setTimeout(() => {\n if (id) {\n removeFlash(id);\n }\n }, 100);\n };\n\n useEffect(() => setTriggerEntryAnimation(true), []);\n useAutoHide(type, closeFlash);\n\n const animateEntry = triggerEntryAnimation && !closed;\n\n let style;\n\n if (flashHeight && !closed) {\n style = { height: `${flashHeight}px` };\n } else if (closed) {\n style = { height: 0, marginTop: 0, zIndex: -1 };\n } else {\n style = {};\n }\n\n const safeContent = DOMPurify.sanitize(content, {\n ALLOWED_TAGS: [\"a\"],\n ALLOWED_ATTR: [\"href\", \"data-method\"],\n ALLOWED_URI_REGEXP: /^\\/[^/]/,\n });\n\n const withIcons: Record<FlashPropsType, IconName | \"\"> = {\n notice: \"icon-gui-ably-badge\",\n success: \"icon-gui-check-outline\",\n error: \"icon-gui-exclamation-triangle-outline\",\n alert: \"icon-gui-exclamation-triangle-outline\",\n info: \"\",\n };\n\n const iconColor: Record<FlashPropsType, ColorClass | \"\"> = {\n notice: \"text-cool-black\",\n success: \"text-cool-black\",\n error: \"text-white\",\n alert: \"text-white\",\n info: \"\",\n };\n\n return (\n <div\n className={`ui-flash-message ui-grid-px ${\n animateEntry ? \"ui-flash-message-enter\" : \"\"\n }`}\n style={style}\n ref={ref}\n data-id=\"ui-flash\"\n data-testid=\"ui-flash\"\n >\n <div\n className={`${FLASH_BG_COLOR[type]} p-32 flex align-center rounded shadow-container-subtle`}\n >\n {withIcons[type] && iconColor[type] && (\n <Icon\n name={withIcons[type]}\n color={iconColor[type]}\n size=\"1.5rem\"\n additionalCSS=\"mr-16 self-baseline\"\n />\n )}\n <p\n className={`ui-text-p1 mr-16 ${FLASH_TEXT_COLOR[type]}`}\n dangerouslySetInnerHTML={{ __html: safeContent }}\n />\n <button\n type=\"button\"\n className=\"p-0 ml-auto self-start focus:outline-none\"\n onClick={closeFlash}\n >\n {iconColor[type] && (\n <Icon\n name=\"icon-gui-x-mark-outline\"\n color={iconColor[type]}\n size=\"1.5rem\"\n additionalCSS=\"transition-colors\"\n />\n )}\n </button>\n </div>\n </div>\n );\n};\n\nconst Flashes = ({ flashes }: FlashesProps) => {\n const [flashesWithIds, setFlashesWithIds] = useState<FlashProps[]>([]);\n\n const removeFlash = (flashId: string) =>\n setFlashesWithIds((items) => items.filter((item) => item.id !== flashId));\n\n useEffect(() => {\n setFlashesWithIds((state) => {\n return [\n ...state,\n ...(flashes?.items ?? []).map((flash) => ({\n ...flash,\n id: Math.random().toString(36).slice(2),\n removed: false,\n removeFlash,\n })),\n ];\n });\n }, [flashes]);\n\n return (\n <div className=\"ui-flash\" data-id={FLASH_DATA_ID}>\n {flashesWithIds\n .filter((item) => !item.removed)\n .map((flash) => (\n <Flash key={flash.id} {...flash} />\n ))}\n </div>\n );\n};\n\nconst BackendFlashes = ({ flashes }: BackendFlashesProps) => {\n useEffect(() => {\n const transformedFlashes =\n flashes.map((flash) => {\n const [type, content] = flash;\n return { type, content };\n }) || [];\n\n if (transformedFlashes.length > 0) {\n const store = getRemoteDataStore();\n\n store.dispatch({\n type: \"flash/push\",\n payload: transformedFlashes,\n });\n }\n }, []);\n\n const WrappedFlashes = ConnectStateWrapper(Flashes, {\n flashes: selectFlashes,\n });\n\n return <WrappedFlashes />;\n};\n\nexport { reducerFlashes, FLASH_DATA_ID, Flashes };\nexport default BackendFlashes;\n"],"names":["React","useEffect","useState","useRef","DOMPurify","getRemoteDataStore","ConnectStateWrapper","Icon","REDUCER_KEY","FLASH_DATA_ID","initialState","items","reducerFlashes","state","action","type","flashes","Array","isArray","payload","selectFlashes","store","getState","FLASH_BG_COLOR","error","success","notice","info","alert","FLASH_TEXT_COLOR","AUTO_HIDE","AUTO_HIDE_TIME","useAutoHide","closeFlash","timeoutId","includes","current","setTimeout","clearTimeout","Flash","id","content","removeFlash","ref","closed","setClosed","flashHeight","setFlashHeight","triggerEntryAnimation","setTriggerEntryAnimation","getBoundingClientRect","height","animateEntry","style","marginTop","zIndex","safeContent","sanitize","ALLOWED_TAGS","ALLOWED_ATTR","ALLOWED_URI_REGEXP","withIcons","iconColor","div","className","data-id","data-testid","name","color","size","additionalCSS","p","dangerouslySetInnerHTML","__html","button","onClick","Flashes","flashesWithIds","setFlashesWithIds","flashId","filter","item","map","flash","Math","random","toString","slice","removed","key","BackendFlashes","transformedFlashes","length","dispatch","WrappedFlashes"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/Flash.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from \"react\";\nimport DOMPurify from \"dompurify\";\nimport { getRemoteDataStore } from \"./remote-data-store.js\";\nimport ConnectStateWrapper from \"./ConnectStateWrapper\";\nimport Icon from \"./Icon\";\nimport { ColorClass } from \"./styles/colors/types\";\nimport { IconName } from \"./Icon/types\";\n\ntype FlashPropsType = \"error\" | \"success\" | \"notice\" | \"info\" | \"alert\";\n\ntype FlashProps = {\n id: string;\n removed: boolean;\n type: FlashPropsType;\n content: string;\n removeFlash: (id: string) => void;\n};\n\ntype FlashesProps = {\n flashes: { items: Pick<FlashProps, \"type\" | \"content\">[] };\n};\n\ntype BackendFlashesProps = {\n flashes: string[][];\n};\n\nconst REDUCER_KEY = \"flashes\";\nconst FLASH_DATA_ID = \"ui-flashes\";\n\nconst initialState = { items: [] };\n\nconst reducerFlashes = {\n [REDUCER_KEY]: (\n state: {\n items: FlashProps[];\n } = initialState,\n action: { type: string; payload: FlashProps | FlashProps[] },\n ) => {\n switch (action.type) {\n case \"flash/push\": {\n const flashes = Array.isArray(action.payload)\n ? action.payload\n : [action.payload];\n return { items: [...state.items, ...flashes] };\n }\n default:\n return state;\n }\n },\n};\n\n// Not cool but redux isn't a long term plan here\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst selectFlashes = (store: any): { items: FlashProps[] } =>\n store.getState()[REDUCER_KEY];\n\nconst FLASH_BG_COLOR = {\n error: \"bg-gui-error\",\n success: \"bg-zingy-green\",\n notice: \"bg-electric-cyan\",\n info: \"bg-electric-cyan\",\n alert: \"bg-active-orange\",\n};\n\nconst FLASH_TEXT_COLOR = {\n error: \"text-white\",\n success: \"text-cool-black\",\n notice: \"text-cool-black\",\n info: \"text-cool-black\",\n alert: \"text-white\",\n};\n\nconst AUTO_HIDE = [\"success\", \"info\", \"notice\"];\nconst AUTO_HIDE_TIME = 8000;\n\nconst useAutoHide = (type: string, closeFlash: () => void) => {\n const timeoutId = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (AUTO_HIDE.includes(type)) {\n timeoutId.current = setTimeout(() => {\n closeFlash();\n }, AUTO_HIDE_TIME);\n }\n\n return () => {\n if (timeoutId.current) {\n clearTimeout(timeoutId.current);\n }\n };\n }, []);\n};\n\nconst Flash = ({ id, type, content, removeFlash }: FlashProps) => {\n const ref = useRef<HTMLDivElement>(null);\n const [closed, setClosed] = useState(false);\n const [flashHeight, setFlashHeight] = useState(0);\n const [triggerEntryAnimation, setTriggerEntryAnimation] = useState(false);\n\n const closeFlash = () => {\n if (ref.current) {\n setFlashHeight(ref.current.getBoundingClientRect().height);\n }\n\n setClosed(true);\n\n setTimeout(() => {\n if (id) {\n removeFlash(id);\n }\n }, 100);\n };\n\n useEffect(() => setTriggerEntryAnimation(true), []);\n useAutoHide(type, closeFlash);\n\n const animateEntry = triggerEntryAnimation && !closed;\n\n let style;\n\n if (flashHeight && !closed) {\n style = { height: `${flashHeight}px` };\n } else if (closed) {\n style = { height: 0, marginTop: 0, zIndex: -1 };\n } else {\n style = {};\n }\n\n const safeContent = DOMPurify.sanitize(content, {\n ALLOWED_TAGS: [\"a\"],\n ALLOWED_ATTR: [\"href\", \"data-method\"],\n ALLOWED_URI_REGEXP: /^\\/[^/]/,\n });\n\n const withIcons: Record<FlashPropsType, IconName | \"\"> = {\n notice: \"icon-gui-ably-badge\",\n success: \"icon-gui-check-outline\",\n error: \"icon-gui-exclamation-triangle-outline\",\n alert: \"icon-gui-exclamation-triangle-outline\",\n info: \"\",\n };\n\n const iconColor: Record<FlashPropsType, ColorClass | \"\"> = {\n notice: \"text-cool-black\",\n success: \"text-cool-black\",\n error: \"text-white\",\n alert: \"text-white\",\n info: \"\",\n };\n\n return (\n <div\n className={`ui-flash-message ui-grid-px ${\n animateEntry ? \"ui-flash-message-enter\" : \"\"\n }`}\n style={style}\n ref={ref}\n data-id=\"ui-flash\"\n data-testid=\"ui-flash\"\n >\n <div\n className={`${FLASH_BG_COLOR[type]} p-8 flex align-center rounded shadow-container-subtle`}\n >\n {withIcons[type] && iconColor[type] && (\n <Icon\n name={withIcons[type]}\n color={iconColor[type]}\n size=\"1.5rem\"\n additionalCSS=\"mr-4 self-baseline\"\n />\n )}\n <p\n className={`ui-text-p1 mr-4 ${FLASH_TEXT_COLOR[type]}`}\n dangerouslySetInnerHTML={{ __html: safeContent }}\n />\n <button\n type=\"button\"\n className=\"p-0 ml-auto self-start focus:outline-none\"\n onClick={closeFlash}\n >\n {iconColor[type] && (\n <Icon\n name=\"icon-gui-x-mark-outline\"\n color={iconColor[type]}\n size=\"1.5rem\"\n additionalCSS=\"transition-colors\"\n />\n )}\n </button>\n </div>\n </div>\n );\n};\n\nconst Flashes = ({ flashes }: FlashesProps) => {\n const [flashesWithIds, setFlashesWithIds] = useState<FlashProps[]>([]);\n\n const removeFlash = (flashId: string) =>\n setFlashesWithIds((items) => items.filter((item) => item.id !== flashId));\n\n useEffect(() => {\n setFlashesWithIds((state) => {\n return [\n ...state,\n ...(flashes?.items ?? []).map((flash) => ({\n ...flash,\n id: Math.random().toString(36).slice(2),\n removed: false,\n removeFlash,\n })),\n ];\n });\n }, [flashes]);\n\n return (\n <div className=\"ui-flash\" data-id={FLASH_DATA_ID}>\n {flashesWithIds\n .filter((item) => !item.removed)\n .map((flash) => (\n <Flash key={flash.id} {...flash} />\n ))}\n </div>\n );\n};\n\nconst BackendFlashes = ({ flashes }: BackendFlashesProps) => {\n useEffect(() => {\n const transformedFlashes =\n flashes.map((flash) => {\n const [type, content] = flash;\n return { type, content };\n }) || [];\n\n if (transformedFlashes.length > 0) {\n const store = getRemoteDataStore();\n\n store.dispatch({\n type: \"flash/push\",\n payload: transformedFlashes,\n });\n }\n }, []);\n\n const WrappedFlashes = ConnectStateWrapper(Flashes, {\n flashes: selectFlashes,\n });\n\n return <WrappedFlashes />;\n};\n\nexport { reducerFlashes, FLASH_DATA_ID, Flashes };\nexport default BackendFlashes;\n"],"names":["React","useEffect","useState","useRef","DOMPurify","getRemoteDataStore","ConnectStateWrapper","Icon","REDUCER_KEY","FLASH_DATA_ID","initialState","items","reducerFlashes","state","action","type","flashes","Array","isArray","payload","selectFlashes","store","getState","FLASH_BG_COLOR","error","success","notice","info","alert","FLASH_TEXT_COLOR","AUTO_HIDE","AUTO_HIDE_TIME","useAutoHide","closeFlash","timeoutId","includes","current","setTimeout","clearTimeout","Flash","id","content","removeFlash","ref","closed","setClosed","flashHeight","setFlashHeight","triggerEntryAnimation","setTriggerEntryAnimation","getBoundingClientRect","height","animateEntry","style","marginTop","zIndex","safeContent","sanitize","ALLOWED_TAGS","ALLOWED_ATTR","ALLOWED_URI_REGEXP","withIcons","iconColor","div","className","data-id","data-testid","name","color","size","additionalCSS","p","dangerouslySetInnerHTML","__html","button","onClick","Flashes","flashesWithIds","setFlashesWithIds","flashId","filter","item","map","flash","Math","random","toString","slice","removed","key","BackendFlashes","transformedFlashes","length","dispatch","WrappedFlashes"],"mappings":"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"}
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-12 py-8 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,{onClick:event=>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 p-24 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-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,{onClick:event=>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 p-6 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-12 py-8 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 onClick={(event) => event.preventDefault()}\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 p-24 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","onClick","event","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,oKACF,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,QAAS,AAACC,OAAUA,MAAMC,cAAc,GACxC3B,UAAWP,GACT,4EACA,6DACA,gFACA,oFACAG,0BACAa,oBAGDW,MAEH,oBAAC9B,uBACCU,UAAWP,GACT,mCACAK,gBACAyB,iBAGDF,UAIL,oBAAC7B,oBACCgC,IAAKJ,KACLQ,KAAMN,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-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 onClick={(event) => event.preventDefault()}\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 p-6 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","onClick","event","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,QAAS,AAACC,OAAUA,MAAMC,cAAc,GACxC3B,UAAWP,GACT,4EACA,6DACA,gFACA,oFACAG,0BACAa,oBAGDW,MAEH,oBAAC9B,uBACCU,UAAWP,GACT,kCACAK,gBACAyB,iBAGDF,UAIL,oBAAC7B,oBACCgC,IAAKJ,KACLQ,KAAMN,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"}
Binary file
package/core/Footer.js CHANGED
@@ -1,2 +1,2 @@
1
- import React from"react";import cn from"./utils/cn";import Icon from"./Icon";import Status,{StatusUrl}from"./Status";import Logo from"./Logo";import Badge from"./Badge";import{bottomFooterLinks,footerLinks,socialLinks}from"./Footer/data";import{ablyAwards}from"./Meganav/data";const Footer=()=>{const textColorClassnames="ui-text-label3 font-medium transition-colors text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 hover:dark:text-neutral-000 active:text-neutral-800 active:dark:text-neutral-400 focus:outline focus:outline-gui-focus";return React.createElement("footer",{className:"w-full bg-neutral-100 dark:bg-neutral-1200 border-t border-neutral-300 dark:border-neutral-1000","data-id":"footer"},React.createElement("div",{className:"max-w-screen-xl mx-auto ui-grid-px pt-40 sm:pt-48 md:pt-64 pb-40"},React.createElement("div",{className:"flex flex-col sm:flex-row gap-x-24 gap-y-48 mb-64 justify-between"},React.createElement("div",{className:"flex-1 flex flex-col gap-24"},["light","dark"].map(theme=>React.createElement(Logo,{key:theme,href:"/",theme:theme,additionalLinkAttrs:{className:cn("focus-base rounded w-[102px]",{"flex dark:hidden":theme==="light","hidden dark:flex":theme==="dark"})}})),React.createElement(Status,{statusUrl:StatusUrl,showDescription:true}),React.createElement("div",{className:"flex gap-x-24"},socialLinks.map(link=>React.createElement("a",{key:link.key,href:link.link,target:"_blank",rel:"noreferrer noopener","aria-label":`Visit Ably on ${link.key}`,className:"w-20 h-20 group/social-icon"},React.createElement(Icon,{name:link.monoIcon,size:"20px",additionalCSS:"text-neutral-1000 dark:text-neutral-300 group-hover/social-icon:hidden"}),React.createElement(Icon,{name:link.colorIcon,size:"20px",additionalCSS:"hidden group-hover/social-icon:flex"})))),React.createElement("div",{className:"flex gap-8 mt-16"},ablyAwards.map(award=>React.createElement("img",{key:award.desc,src:award.image,alt:award.desc,width:"57",height:"64"})))),React.createElement("div",{className:"flex-1 md:flex-[2] flex flex-row flex-wrap gap-x-24 gap-y-48"},footerLinks.map(({title,links})=>React.createElement("div",{key:title,className:"flex-1 basis-1/3 md:basis-1"},React.createElement("h3",{className:"ui-text-overline2 text-neutral-700 dark:text-neutral-600 mb-16"},title),React.createElement("ul",{className:"flex flex-col gap-y-12"},links.map(({label,link,badge})=>React.createElement("li",{key:label,className:"flex gap-x-8"},React.createElement("a",{href:link,className:textColorClassnames,"aria-label":`Visit ${label}`},label),badge&&React.createElement(Badge,{size:"xs",className:"ui-text-p4 font-[10px]"},badge)))))))),React.createElement("div",{className:"pt-24 border-t border-neutral-300 dark:border-neutral-1000"},React.createElement("div",{className:"flex gap-24"},bottomFooterLinks.map(link=>React.createElement("a",{key:link.label,href:link.link,className:textColorClassnames,"aria-label":`Visit ${link.label}`},link.label))))))};export default Footer;
1
+ import React from"react";import cn from"./utils/cn";import Icon from"./Icon";import Status,{StatusUrl}from"./Status";import Logo from"./Logo";import Badge from"./Badge";import{bottomFooterLinks,footerLinks,socialLinks}from"./Footer/data";import{ablyAwards}from"./Meganav/data";const Footer=()=>{const textColorClassnames="ui-text-label3 font-medium transition-colors text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 hover:dark:text-neutral-000 active:text-neutral-800 active:dark:text-neutral-400 focus:outline focus:outline-gui-focus";return React.createElement("footer",{className:"w-full bg-neutral-100 dark:bg-neutral-1200 border-t border-neutral-300 dark:border-neutral-1000","data-id":"footer"},React.createElement("div",{className:"max-w-screen-xl mx-auto ui-grid-px pt-10 sm:pt-12 md:pt-16 pb-10"},React.createElement("div",{className:"flex flex-col sm:flex-row gap-x-6 gap-y-12 mb-16 justify-between"},React.createElement("div",{className:"flex-1 flex flex-col gap-6"},["light","dark"].map(theme=>React.createElement(Logo,{key:theme,href:"/",theme:theme,additionalLinkAttrs:{className:cn("focus-base rounded w-[6.375rem]",{"flex dark:hidden":theme==="light","hidden dark:flex":theme==="dark"})}})),React.createElement(Status,{statusUrl:StatusUrl,showDescription:true}),React.createElement("div",{className:"flex gap-x-6"},socialLinks.map(link=>React.createElement("a",{key:link.key,href:link.link,target:"_blank",rel:"noreferrer noopener","aria-label":`Visit Ably on ${link.key}`,className:"w-5 h-5 group/social-icon"},React.createElement(Icon,{name:link.monoIcon,size:"20px",additionalCSS:"text-neutral-1000 dark:text-neutral-300 group-hover/social-icon:hidden"}),React.createElement(Icon,{name:link.colorIcon,size:"20px",additionalCSS:"hidden group-hover/social-icon:flex"})))),React.createElement("div",{className:"flex gap-2 mt-4"},ablyAwards.map(award=>React.createElement("img",{key:award.desc,src:award.image,alt:award.desc,width:"57",height:"64"})))),React.createElement("div",{className:"flex-1 md:flex-[2] flex flex-row flex-wrap gap-x-6 gap-y-12"},footerLinks.map(({title,links})=>React.createElement("div",{key:title,className:"flex-1 basis-1/3 md:basis-1"},React.createElement("h3",{className:"ui-text-overline2 text-neutral-700 dark:text-neutral-600 mb-4"},title),React.createElement("ul",{className:"flex flex-col gap-y-3"},links.map(({label,link,badge})=>React.createElement("li",{key:label,className:"flex gap-x-2"},React.createElement("a",{href:link,className:textColorClassnames,"aria-label":`Visit ${label}`},label),badge&&React.createElement(Badge,{size:"xs",className:"ui-text-p4 font-[10px]"},badge)))))))),React.createElement("div",{className:"pt-6 border-t border-neutral-300 dark:border-neutral-1000"},React.createElement("div",{className:"flex gap-6"},bottomFooterLinks.map(link=>React.createElement("a",{key:link.label,href:link.link,className:textColorClassnames,"aria-label":`Visit ${link.label}`},link.label))))))};export default Footer;
2
2
  //# sourceMappingURL=Footer.js.map