@ably/ui 17.6.1-dev.09b2f62e → 17.6.2-dev.7350af4a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/Header.js +1 -1
- package/core/Header.js.map +1 -1
- package/core/Logo.js +1 -1
- package/core/Logo.js.map +1 -1
- package/core/Meganav.js +1 -1
- package/core/Meganav.js.map +1 -1
- package/core/Notice.js +1 -1
- package/core/Notice.js.map +1 -1
- package/core/remote-blogs-posts.js.map +1 -1
- package/core/remote-session-data.js.map +1 -1
- package/index.d.ts +11 -12
- package/package.json +1 -1
package/core/Header.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useState,useEffect,useRef,useMemo}from"react";import Icon from"./Icon";import cn from"./utils/cn";import Logo from"./Logo";import{componentMaxHeight,HEADER_BOTTOM_MARGIN,HEADER_HEIGHT}from"./utils/heights";import{HeaderLinks}from"./Header/HeaderLinks";import throttle from"lodash.throttle";import{COLLAPSE_TRIGGER_DISTANCE}from"./Notice/component";const FLEXIBLE_DESKTOP_CLASSES="hidden md:flex flex-1 items-center h-full";const MAX_MOBILE_MENU_WIDTH="560px";const Header=({className,isNoticeVisible=false,
|
|
1
|
+
import React,{useState,useEffect,useRef,useMemo}from"react";import Icon from"./Icon";import cn from"./utils/cn";import Logo from"./Logo";import{componentMaxHeight,HEADER_BOTTOM_MARGIN,HEADER_HEIGHT}from"./utils/heights";import{HeaderLinks}from"./Header/HeaderLinks";import throttle from"lodash.throttle";import{COLLAPSE_TRIGGER_DISTANCE}from"./Notice/component";const FLEXIBLE_DESKTOP_CLASSES="hidden md:flex flex-1 items-center h-full";const MAX_MOBILE_MENU_WIDTH="560px";const Header=({className,isNoticeVisible=false,searchBar,searchButton,logoHref,headerLinks,headerLinksClassName,headerCenterClassName,nav,mobileNav,sessionState,themedScrollpoints=[],searchButtonVisibility="all",location,logoBadge})=>{const[showMenu,setShowMenu]=useState(false);const[fadingOut,setFadingOut]=useState(false);const[bannerVisible,setBannerVisible]=useState(isNoticeVisible);const menuRef=useRef(null);const[scrollpointClasses,setScrollpointClasses]=useState(themedScrollpoints.length>0?themedScrollpoints[0].className:"");const closeMenu=()=>{setFadingOut(true);setTimeout(()=>{setShowMenu(false);setFadingOut(false)},150)};useEffect(()=>{const handleScroll=()=>{setBannerVisible(window.scrollY<=COLLAPSE_TRIGGER_DISTANCE&&isNoticeVisible);for(const scrollpoint of themedScrollpoints){const element=document.getElementById(scrollpoint.id);if(element){const rect=element.getBoundingClientRect();if(rect.top<=HEADER_HEIGHT&&rect.bottom>=HEADER_HEIGHT){setScrollpointClasses(scrollpoint.className);return}}}};const throttledHandleScroll=throttle(handleScroll,150);handleScroll();window.addEventListener("scroll",throttledHandleScroll);return()=>window.removeEventListener("scroll",throttledHandleScroll)},[themedScrollpoints]);useEffect(()=>{const handleResize=()=>{if(window.innerWidth>=1040){setShowMenu(false)}};window.addEventListener("resize",handleResize);return()=>window.removeEventListener("resize",handleResize)},[]);useEffect(()=>{if(showMenu){document.body.classList.add("overflow-hidden")}else{document.body.classList.remove("overflow-hidden")}return()=>{document.body.classList.remove("overflow-hidden")}},[showMenu]);useEffect(()=>{if(location&&showMenu){closeMenu()}},[location]);const wrappedSearchButton=useMemo(()=>searchButton?React.createElement("div",{className:"text-neutral-1300 dark:text-neutral-000 flex items-center"},searchButton):null,[searchButton]);return React.createElement(React.Fragment,null,React.createElement("header",{role:"banner",className:cn("fixed left-0 top-0 w-full z-50 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 dark:border-neutral-1000 transition-colors px-6 md:px-16",scrollpointClasses,{"md:top-auto":bannerVisible}),style:{height:HEADER_HEIGHT}},React.createElement("div",{className:cn("flex items-center h-full",className)},React.createElement("nav",{className:"flex flex-1 h-full items-center"},["light","dark"].map(theme=>React.createElement(Logo,{key:theme,href:logoHref,theme:theme,badge:logoBadge,additionalLinkAttrs:{className:cn("h-full focus-base rounded mr-8 w-24 gap-2 items-center",{"flex dark:hidden":theme==="light","hidden dark:flex":theme==="dark"})}})),React.createElement("div",{className:FLEXIBLE_DESKTOP_CLASSES},nav)),React.createElement("div",{className:"flex md:hidden flex-1 items-center justify-end gap-6 h-full"},searchButtonVisibility!=="desktop"?wrappedSearchButton:null,React.createElement("button",{className:"cursor-pointer focus-base rounded flex items-center p-0",onClick:()=>setShowMenu(!showMenu),"aria-expanded":showMenu,"aria-controls":"mobile-menu","aria-label":"Toggle menu"},React.createElement(Icon,{name:showMenu?"icon-gui-x-mark-outline":"icon-gui-bars-3-outline",additionalCSS:"text-neutral-1300 dark:text-neutral-000",size:"1.5rem"}))),searchBar?React.createElement("div",{className:cn(FLEXIBLE_DESKTOP_CLASSES,"justify-center",headerCenterClassName)},searchBar):null,React.createElement(HeaderLinks,{className:cn(FLEXIBLE_DESKTOP_CLASSES,headerLinksClassName),headerLinks:headerLinks,sessionState:sessionState,searchButton:wrappedSearchButton,searchButtonVisibility:searchButtonVisibility}))),showMenu?React.createElement(React.Fragment,null,React.createElement("div",{className:cn("fixed inset-0 bg-neutral-1300 dark:bg-neutral-1300 z-40",{"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]":!fadingOut,"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]":fadingOut}),onClick:closeMenu,onKeyDown:e=>e.key==="Escape"&&closeMenu(),role:"presentation"}),React.createElement("div",{id:"mobile-menu",className:"md:hidden fixed flex flex-col top-[4.75rem] overflow-y-hidden mx-3 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-50",style:{maxWidth:MAX_MOBILE_MENU_WIDTH,maxHeight:componentMaxHeight(HEADER_HEIGHT,HEADER_BOTTOM_MARGIN)},ref:menuRef,role:"navigation"},mobileNav,React.createElement(HeaderLinks,{headerLinks:headerLinks,sessionState:sessionState}))):null)};export default Header;
|
|
2
2
|
//# sourceMappingURL=Header.js.map
|
package/core/Header.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Header.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, ReactNode, useMemo } from \"react\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\nimport Logo from \"./Logo\";\nimport {\n componentMaxHeight,\n HEADER_BOTTOM_MARGIN,\n HEADER_HEIGHT,\n} from \"./utils/heights\";\nimport { HeaderLinks } from \"./Header/HeaderLinks\";\nimport throttle from \"lodash.throttle\";\nimport { Theme } from \"./styles/colors/types\";\nimport { COLLAPSE_TRIGGER_DISTANCE } from \"./Notice/component\";\n\nexport type ThemedScrollpoint = {\n id: string;\n className: string;\n};\n\n/**\n * Represents the state of the user session in the header.\n */\nexport type HeaderSessionState = {\n /**\n * Indicates if the user is signed in.\n */\n signedIn: boolean;\n\n /**\n * Information required to log out the user.\n */\n logOut: {\n /**\n * Token used for logging out.\n */\n token: string;\n\n /**\n * URL to log out the user.\n */\n href: string;\n };\n\n /**\n * Name of the user's account.\n */\n accountName: string;\n};\n\n/**\n * Props for the Header component.\n */\nexport type HeaderProps = {\n /**\n * Optional classnames to add to the header\n */\n className?: string;\n /**\n * Indicates if the notice banner is visible.\n */\n isNoticeVisible?: boolean;\n /**\n * Height of the notice banner in pixels.\n */\n noticeHeight?: number;\n /**\n * Optional search bar element.\n */\n searchBar?: ReactNode;\n\n /**\n * Optional search button element.\n */\n searchButton?: ReactNode;\n\n /**\n * URL for the logo link.\n */\n logoHref?: string;\n\n /**\n * Array of header links.\n */\n headerLinks?: {\n /**\n * URL for the link.\n */\n href: string;\n\n /**\n * Label for the link.\n */\n label: string;\n\n /**\n * Indicates if the link should open in a new tab.\n */\n external?: boolean;\n }[];\n\n /**\n * Optional classname for styling the header links container.\n */\n headerLinksClassName?: string;\n\n /**\n * Optional classname for styling the header center container.\n */\n headerCenterClassName?: string;\n\n /**\n * Optional desktop navigation element.\n */\n nav?: ReactNode;\n\n /**\n * Optional mobile navigation element.\n */\n mobileNav?: ReactNode;\n\n /**\n * State of the user session.\n */\n sessionState?: HeaderSessionState;\n\n /**\n * Array of themed scrollpoints. The header will change its appearance based on the scrollpoint in view.\n */\n themedScrollpoints?: ThemedScrollpoint[];\n\n /**\n * Visibility setting for the search button.\n * - \"all\": Visible on all devices.\n * - \"desktop\": Visible only on desktop devices.\n * - \"mobile\": Visible only on mobile devices.\n */\n searchButtonVisibility?: \"all\" | \"desktop\" | \"mobile\";\n\n /**\n * Optional location object to detect location changes.\n */\n location?: Location;\n};\n\nconst FLEXIBLE_DESKTOP_CLASSES = \"hidden md:flex flex-1 items-center h-full\";\n\n/**\n * Maximum width before the menu expanded into full width\n */\nconst MAX_MOBILE_MENU_WIDTH = \"560px\";\n\nconst Header: React.FC<HeaderProps> = ({\n className,\n isNoticeVisible = false,\n noticeHeight = 0,\n searchBar,\n searchButton,\n logoHref,\n headerLinks,\n headerLinksClassName,\n headerCenterClassName,\n nav,\n mobileNav,\n sessionState,\n themedScrollpoints = [],\n searchButtonVisibility = \"all\",\n location,\n}) => {\n const [showMenu, setShowMenu] = useState(false);\n const [fadingOut, setFadingOut] = useState(false);\n const [bannerVisible, setBannerVisible] = useState(isNoticeVisible);\n const menuRef = useRef<HTMLDivElement>(null);\n const [scrollpointClasses, setScrollpointClasses] = useState<string>(\n themedScrollpoints.length > 0 ? themedScrollpoints[0].className : \"\",\n );\n\n const closeMenu = () => {\n setFadingOut(true);\n\n setTimeout(() => {\n setShowMenu(false);\n setFadingOut(false);\n }, 150);\n };\n\n useEffect(() => {\n const handleNoticeClose = () => {\n setBannerVisible(false);\n };\n\n document.addEventListener(\"notice-closed\", handleNoticeClose);\n return () =>\n document.removeEventListener(\"notice-closed\", handleNoticeClose);\n }, []);\n\n useEffect(() => {\n const handleScroll = () => {\n setBannerVisible(\n window.scrollY <= COLLAPSE_TRIGGER_DISTANCE && isNoticeVisible,\n );\n for (const scrollpoint of themedScrollpoints) {\n const element = document.getElementById(scrollpoint.id);\n if (element) {\n const rect = element.getBoundingClientRect();\n if (rect.top <= HEADER_HEIGHT && rect.bottom >= HEADER_HEIGHT) {\n setScrollpointClasses(scrollpoint.className);\n return;\n }\n }\n }\n };\n\n const throttledHandleScroll = throttle(handleScroll, 150);\n\n handleScroll();\n\n window.addEventListener(\"scroll\", throttledHandleScroll);\n return () => window.removeEventListener(\"scroll\", throttledHandleScroll);\n }, [themedScrollpoints, isNoticeVisible]);\n\n useEffect(() => {\n const handleResize = () => {\n if (window.innerWidth >= 1040) {\n setShowMenu(false);\n }\n };\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (showMenu) {\n document.body.classList.add(\"overflow-hidden\");\n } else {\n document.body.classList.remove(\"overflow-hidden\");\n }\n\n // Cleanup on unmount\n return () => {\n document.body.classList.remove(\"overflow-hidden\");\n };\n }, [showMenu]);\n\n // Close menu when location changes\n useEffect(() => {\n if (location && showMenu) {\n closeMenu();\n }\n }, [location]);\n\n const wrappedSearchButton = useMemo(\n () =>\n searchButton ? (\n <div className=\"text-neutral-1300 dark:text-neutral-000 flex items-center\">\n {searchButton}\n </div>\n ) : null,\n [searchButton],\n );\n return (\n <>\n <header\n role=\"banner\"\n className={cn(\n \"fixed left-0 top-0 w-full z-50 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 dark:border-neutral-1000 transition-all duration-300 ease-in-out px-6 md:px-16\",\n scrollpointClasses,\n {\n \"md:top-auto\": bannerVisible,\n },\n )}\n style={{\n height: HEADER_HEIGHT,\n top: bannerVisible ? `${noticeHeight}px` : \"0\",\n }}\n >\n <div className={cn(\"flex items-center h-full\", className)}>\n <nav className=\"flex flex-1 h-full items-center\">\n {([\"light\", \"dark\"] as Theme[]).map((theme) => (\n <Logo\n key={theme}\n href={logoHref}\n theme={theme}\n additionalLinkAttrs={{\n className: cn(\"h-full focus-base rounded mr-8 w-24\", {\n \"flex dark:hidden\": theme === \"light\",\n \"hidden dark:flex\": theme === \"dark\",\n }),\n }}\n />\n ))}\n <div className={FLEXIBLE_DESKTOP_CLASSES}>{nav}</div>\n </nav>\n <div className=\"flex md:hidden flex-1 items-center justify-end gap-6 h-full\">\n {searchButtonVisibility !== \"desktop\" ? wrappedSearchButton : null}\n <button\n className=\"cursor-pointer focus-base rounded flex items-center p-0\"\n onClick={() => setShowMenu(!showMenu)}\n aria-expanded={showMenu}\n aria-controls=\"mobile-menu\"\n aria-label=\"Toggle menu\"\n >\n <Icon\n name={\n showMenu\n ? \"icon-gui-x-mark-outline\"\n : \"icon-gui-bars-3-outline\"\n }\n additionalCSS=\"text-neutral-1300 dark:text-neutral-000\"\n size=\"1.5rem\"\n />\n </button>\n </div>\n {searchBar ? (\n <div\n className={cn(\n FLEXIBLE_DESKTOP_CLASSES,\n \"justify-center\",\n headerCenterClassName,\n )}\n >\n {searchBar}\n </div>\n ) : null}\n <HeaderLinks\n className={cn(FLEXIBLE_DESKTOP_CLASSES, headerLinksClassName)}\n headerLinks={headerLinks}\n sessionState={sessionState}\n searchButton={wrappedSearchButton}\n searchButtonVisibility={searchButtonVisibility}\n />\n </div>\n </header>\n {showMenu ? (\n <>\n <div\n className={cn(\n \"fixed inset-0 bg-neutral-1300 dark:bg-neutral-1300 z-40\",\n {\n \"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]\":\n !fadingOut,\n \"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]\":\n fadingOut,\n },\n )}\n onClick={closeMenu}\n onKeyDown={(e) => e.key === \"Escape\" && closeMenu()}\n role=\"presentation\"\n />\n <div\n id=\"mobile-menu\"\n className=\"md:hidden fixed flex flex-col top-[4.75rem] overflow-y-hidden mx-3 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-50\"\n style={{\n maxWidth: MAX_MOBILE_MENU_WIDTH,\n maxHeight: componentMaxHeight(\n HEADER_HEIGHT,\n HEADER_BOTTOM_MARGIN,\n ),\n }}\n ref={menuRef}\n role=\"navigation\"\n >\n {mobileNav}\n <HeaderLinks\n headerLinks={headerLinks}\n sessionState={sessionState}\n />\n </div>\n </>\n ) : null}\n </>\n );\n};\n\nexport default Header;\n"],"names":["React","useState","useEffect","useRef","useMemo","Icon","cn","Logo","componentMaxHeight","HEADER_BOTTOM_MARGIN","HEADER_HEIGHT","HeaderLinks","throttle","COLLAPSE_TRIGGER_DISTANCE","FLEXIBLE_DESKTOP_CLASSES","MAX_MOBILE_MENU_WIDTH","Header","className","isNoticeVisible","noticeHeight","searchBar","searchButton","logoHref","headerLinks","headerLinksClassName","headerCenterClassName","nav","mobileNav","sessionState","themedScrollpoints","searchButtonVisibility","location","showMenu","setShowMenu","fadingOut","setFadingOut","bannerVisible","setBannerVisible","menuRef","scrollpointClasses","setScrollpointClasses","length","closeMenu","setTimeout","handleNoticeClose","document","addEventListener","removeEventListener","handleScroll","window","scrollY","scrollpoint","element","getElementById","id","rect","getBoundingClientRect","top","bottom","throttledHandleScroll","handleResize","innerWidth","body","classList","add","remove","wrappedSearchButton","div","header","role","style","height","map","theme","key","href","additionalLinkAttrs","button","onClick","aria-expanded","aria-controls","aria-label","name","additionalCSS","size","onKeyDown","e","maxWidth","maxHeight","ref"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/Header.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, ReactNode, useMemo } from \"react\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\nimport Logo from \"./Logo\";\nimport {\n componentMaxHeight,\n HEADER_BOTTOM_MARGIN,\n HEADER_HEIGHT,\n} from \"./utils/heights\";\nimport { HeaderLinks } from \"./Header/HeaderLinks\";\nimport throttle from \"lodash.throttle\";\nimport { Theme } from \"./styles/colors/types\";\nimport { COLLAPSE_TRIGGER_DISTANCE } from \"./Notice/component\";\n\nexport type ThemedScrollpoint = {\n id: string;\n className: string;\n};\n\n/**\n * Represents the state of the user session in the header.\n */\nexport type HeaderSessionState = {\n /**\n * Indicates if the user is signed in.\n */\n signedIn: boolean;\n\n /**\n * Information required to log out the user.\n */\n logOut: {\n /**\n * Token used for logging out.\n */\n token: string;\n\n /**\n * URL to log out the user.\n */\n href: string;\n };\n\n /**\n * Name of the user's account.\n */\n accountName: string;\n};\n\n/**\n * Props for the Header component.\n */\nexport type HeaderProps = {\n /**\n * Optional classnames to add to the header\n */\n className?: string;\n /**\n * Indicates if the notice banner is visible.\n */\n isNoticeVisible?: boolean;\n /**\n * Optional search bar element.\n */\n searchBar?: ReactNode;\n\n /**\n * Optional search button element.\n */\n searchButton?: ReactNode;\n\n /**\n * URL for the logo link.\n */\n logoHref?: string;\n\n /**\n * Array of header links.\n */\n headerLinks?: {\n /**\n * URL for the link.\n */\n href: string;\n\n /**\n * Label for the link.\n */\n label: string;\n\n /**\n * Indicates if the link should open in a new tab.\n */\n external?: boolean;\n }[];\n\n /**\n * Optional classname for styling the header links container.\n */\n headerLinksClassName?: string;\n\n /**\n * Optional classname for styling the header center container.\n */\n headerCenterClassName?: string;\n\n /**\n * Optional desktop navigation element.\n */\n nav?: ReactNode;\n\n /**\n * Optional mobile navigation element.\n */\n mobileNav?: ReactNode;\n\n /**\n * State of the user session.\n */\n sessionState?: HeaderSessionState;\n\n /**\n * Array of themed scrollpoints. The header will change its appearance based on the scrollpoint in view.\n */\n themedScrollpoints?: ThemedScrollpoint[];\n\n /**\n * Visibility setting for the search button.\n * - \"all\": Visible on all devices.\n * - \"desktop\": Visible only on desktop devices.\n * - \"mobile\": Visible only on mobile devices.\n */\n searchButtonVisibility?: \"all\" | \"desktop\" | \"mobile\";\n\n /**\n * Optional location object to detect location changes.\n */\n location?: Location;\n\n /**\n * Optional badge text to display on the logo.\n */\n logoBadge?: string;\n};\n\nconst FLEXIBLE_DESKTOP_CLASSES = \"hidden md:flex flex-1 items-center h-full\";\n\n/**\n * Maximum width before the menu expanded into full width\n */\nconst MAX_MOBILE_MENU_WIDTH = \"560px\";\n\nconst Header: React.FC<HeaderProps> = ({\n className,\n isNoticeVisible = false,\n searchBar,\n searchButton,\n logoHref,\n headerLinks,\n headerLinksClassName,\n headerCenterClassName,\n nav,\n mobileNav,\n sessionState,\n themedScrollpoints = [],\n searchButtonVisibility = \"all\",\n location,\n logoBadge,\n}) => {\n const [showMenu, setShowMenu] = useState(false);\n const [fadingOut, setFadingOut] = useState(false);\n const [bannerVisible, setBannerVisible] = useState(isNoticeVisible);\n const menuRef = useRef<HTMLDivElement>(null);\n const [scrollpointClasses, setScrollpointClasses] = useState<string>(\n themedScrollpoints.length > 0 ? themedScrollpoints[0].className : \"\",\n );\n\n const closeMenu = () => {\n setFadingOut(true);\n\n setTimeout(() => {\n setShowMenu(false);\n setFadingOut(false);\n }, 150);\n };\n\n useEffect(() => {\n const handleScroll = () => {\n setBannerVisible(\n window.scrollY <= COLLAPSE_TRIGGER_DISTANCE && isNoticeVisible,\n );\n for (const scrollpoint of themedScrollpoints) {\n const element = document.getElementById(scrollpoint.id);\n if (element) {\n const rect = element.getBoundingClientRect();\n if (rect.top <= HEADER_HEIGHT && rect.bottom >= HEADER_HEIGHT) {\n setScrollpointClasses(scrollpoint.className);\n return;\n }\n }\n }\n };\n\n const throttledHandleScroll = throttle(handleScroll, 150);\n\n handleScroll();\n\n window.addEventListener(\"scroll\", throttledHandleScroll);\n return () => window.removeEventListener(\"scroll\", throttledHandleScroll);\n }, [themedScrollpoints]);\n\n useEffect(() => {\n const handleResize = () => {\n if (window.innerWidth >= 1040) {\n setShowMenu(false);\n }\n };\n window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (showMenu) {\n document.body.classList.add(\"overflow-hidden\");\n } else {\n document.body.classList.remove(\"overflow-hidden\");\n }\n\n // Cleanup on unmount\n return () => {\n document.body.classList.remove(\"overflow-hidden\");\n };\n }, [showMenu]);\n\n // Close menu when location changes\n useEffect(() => {\n if (location && showMenu) {\n closeMenu();\n }\n }, [location]);\n\n const wrappedSearchButton = useMemo(\n () =>\n searchButton ? (\n <div className=\"text-neutral-1300 dark:text-neutral-000 flex items-center\">\n {searchButton}\n </div>\n ) : null,\n [searchButton],\n );\n\n return (\n <>\n <header\n role=\"banner\"\n className={cn(\n \"fixed left-0 top-0 w-full z-50 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 dark:border-neutral-1000 transition-colors px-6 md:px-16\",\n scrollpointClasses,\n {\n \"md:top-auto\": bannerVisible,\n },\n )}\n style={{ height: HEADER_HEIGHT }}\n >\n <div className={cn(\"flex items-center h-full\", className)}>\n <nav className=\"flex flex-1 h-full items-center\">\n {([\"light\", \"dark\"] as Theme[]).map((theme) => (\n <Logo\n key={theme}\n href={logoHref}\n theme={theme}\n badge={logoBadge}\n additionalLinkAttrs={{\n className: cn(\n \"h-full focus-base rounded mr-8 w-24 gap-2 items-center\",\n {\n \"flex dark:hidden\": theme === \"light\",\n \"hidden dark:flex\": theme === \"dark\",\n },\n ),\n }}\n />\n ))}\n <div className={FLEXIBLE_DESKTOP_CLASSES}>{nav}</div>\n </nav>\n <div className=\"flex md:hidden flex-1 items-center justify-end gap-6 h-full\">\n {searchButtonVisibility !== \"desktop\" ? wrappedSearchButton : null}\n <button\n className=\"cursor-pointer focus-base rounded flex items-center p-0\"\n onClick={() => setShowMenu(!showMenu)}\n aria-expanded={showMenu}\n aria-controls=\"mobile-menu\"\n aria-label=\"Toggle menu\"\n >\n <Icon\n name={\n showMenu\n ? \"icon-gui-x-mark-outline\"\n : \"icon-gui-bars-3-outline\"\n }\n additionalCSS=\"text-neutral-1300 dark:text-neutral-000\"\n size=\"1.5rem\"\n />\n </button>\n </div>\n {searchBar ? (\n <div\n className={cn(\n FLEXIBLE_DESKTOP_CLASSES,\n \"justify-center\",\n headerCenterClassName,\n )}\n >\n {searchBar}\n </div>\n ) : null}\n <HeaderLinks\n className={cn(FLEXIBLE_DESKTOP_CLASSES, headerLinksClassName)}\n headerLinks={headerLinks}\n sessionState={sessionState}\n searchButton={wrappedSearchButton}\n searchButtonVisibility={searchButtonVisibility}\n />\n </div>\n </header>\n {showMenu ? (\n <>\n <div\n className={cn(\n \"fixed inset-0 bg-neutral-1300 dark:bg-neutral-1300 z-40\",\n {\n \"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]\":\n !fadingOut,\n \"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]\":\n fadingOut,\n },\n )}\n onClick={closeMenu}\n onKeyDown={(e) => e.key === \"Escape\" && closeMenu()}\n role=\"presentation\"\n />\n <div\n id=\"mobile-menu\"\n className=\"md:hidden fixed flex flex-col top-[4.75rem] overflow-y-hidden mx-3 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-50\"\n style={{\n maxWidth: MAX_MOBILE_MENU_WIDTH,\n maxHeight: componentMaxHeight(\n HEADER_HEIGHT,\n HEADER_BOTTOM_MARGIN,\n ),\n }}\n ref={menuRef}\n role=\"navigation\"\n >\n {mobileNav}\n <HeaderLinks\n headerLinks={headerLinks}\n sessionState={sessionState}\n />\n </div>\n </>\n ) : null}\n </>\n );\n};\n\nexport default Header;\n"],"names":["React","useState","useEffect","useRef","useMemo","Icon","cn","Logo","componentMaxHeight","HEADER_BOTTOM_MARGIN","HEADER_HEIGHT","HeaderLinks","throttle","COLLAPSE_TRIGGER_DISTANCE","FLEXIBLE_DESKTOP_CLASSES","MAX_MOBILE_MENU_WIDTH","Header","className","isNoticeVisible","searchBar","searchButton","logoHref","headerLinks","headerLinksClassName","headerCenterClassName","nav","mobileNav","sessionState","themedScrollpoints","searchButtonVisibility","location","logoBadge","showMenu","setShowMenu","fadingOut","setFadingOut","bannerVisible","setBannerVisible","menuRef","scrollpointClasses","setScrollpointClasses","length","closeMenu","setTimeout","handleScroll","window","scrollY","scrollpoint","element","document","getElementById","id","rect","getBoundingClientRect","top","bottom","throttledHandleScroll","addEventListener","removeEventListener","handleResize","innerWidth","body","classList","add","remove","wrappedSearchButton","div","header","role","style","height","map","theme","key","href","badge","additionalLinkAttrs","button","onClick","aria-expanded","aria-controls","aria-label","name","additionalCSS","size","onKeyDown","e","maxWidth","maxHeight","ref"],"mappings":"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"}
|
package/core/Logo.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import LogoAssetMonoStacked from"./images/logo/ably-logo-mono-stacked.svg";import LogoAssetMonoWhiteStacked from"./images/logo/ably-logo-mono-white-stacked.svg";import LogoAssetMonoWhite from"./images/logo/ably-logo-mono-white.svg";import LogoAssetMono from"./images/logo/ably-logo-mono.svg";import LogoAssetStacked from"./images/logo/ably-logo-stacked.svg";import LogoAssetWhiteStacked from"./images/logo/ably-logo-white-stacked.svg";import LogoAssetWhite from"./images/logo/ably-logo-white.svg";import LogoAsset from"./images/logo/ably-logo.svg";const Logo=({dataId,href="/",additionalImgAttrs,additionalLinkAttrs,theme="light",variant="default",orientation="default",logoUrl,logoAlt="Ably logo"})=>{const getLogoSrc=React.useCallback(()=>{if(logoUrl)return logoUrl;if(theme==="dark"){if(variant==="mono"){return orientation==="stacked"?LogoAssetMonoWhiteStacked:LogoAssetMonoWhite}else{return orientation==="stacked"?LogoAssetWhiteStacked:LogoAssetWhite}}else{if(variant==="mono"){return orientation==="stacked"?LogoAssetMonoStacked:LogoAssetMono}else{return orientation==="stacked"?LogoAssetStacked:LogoAsset}}},[logoUrl,theme,variant,orientation]);const logoSrc=getLogoSrc();return React.createElement("a",{href:href,"data-id":dataId,className:"
|
|
1
|
+
import React from"react";import Badge from"./Badge";import cn from"./utils/cn";import LogoAssetMonoStacked from"./images/logo/ably-logo-mono-stacked.svg";import LogoAssetMonoWhiteStacked from"./images/logo/ably-logo-mono-white-stacked.svg";import LogoAssetMonoWhite from"./images/logo/ably-logo-mono-white.svg";import LogoAssetMono from"./images/logo/ably-logo-mono.svg";import LogoAssetStacked from"./images/logo/ably-logo-stacked.svg";import LogoAssetWhiteStacked from"./images/logo/ably-logo-white-stacked.svg";import LogoAssetWhite from"./images/logo/ably-logo-white.svg";import LogoAsset from"./images/logo/ably-logo.svg";const Logo=({dataId,href="/",additionalImgAttrs,additionalLinkAttrs,theme="light",variant="default",orientation="default",logoUrl,logoAlt="Ably logo",badge})=>{const getLogoSrc=React.useCallback(()=>{if(logoUrl)return logoUrl;if(theme==="dark"){if(variant==="mono"){return orientation==="stacked"?LogoAssetMonoWhiteStacked:LogoAssetMonoWhite}else{return orientation==="stacked"?LogoAssetWhiteStacked:LogoAssetWhite}}else{if(variant==="mono"){return orientation==="stacked"?LogoAssetMonoStacked:LogoAssetMono}else{return orientation==="stacked"?LogoAssetStacked:LogoAsset}}},[logoUrl,theme,variant,orientation]);const logoSrc=getLogoSrc();return React.createElement("a",{href:href,"data-id":dataId,...additionalLinkAttrs,className:cn("flex items-center gap-2 justify-center",additionalLinkAttrs?.className)},React.createElement("img",{src:logoSrc,width:"108px",alt:logoAlt,...additionalImgAttrs}),badge&&React.createElement(Badge,{className:"uppercase h-8 bg-transparent dark:bg-transparent rounded border border-neutral-400 dark:border-neutral-900 text-lg p-2 font-semibold text-neutral-800 dark:text-neutral-500"},badge))};export default React.memo(Logo);
|
|
2
2
|
//# sourceMappingURL=Logo.js.map
|
package/core/Logo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Logo.tsx"],"sourcesContent":["import React from \"react\";\nimport LogoAssetMonoStacked from \"./images/logo/ably-logo-mono-stacked.svg\";\nimport LogoAssetMonoWhiteStacked from \"./images/logo/ably-logo-mono-white-stacked.svg\";\nimport LogoAssetMonoWhite from \"./images/logo/ably-logo-mono-white.svg\";\nimport LogoAssetMono from \"./images/logo/ably-logo-mono.svg\";\nimport LogoAssetStacked from \"./images/logo/ably-logo-stacked.svg\";\nimport LogoAssetWhiteStacked from \"./images/logo/ably-logo-white-stacked.svg\";\nimport LogoAssetWhite from \"./images/logo/ably-logo-white.svg\";\nimport LogoAsset from \"./images/logo/ably-logo.svg\";\n\ntype LogoProps = {\n dataId?: string;\n logoUrl?: string;\n logoAlt?: string;\n href?: string;\n additionalImgAttrs?:
|
|
1
|
+
{"version":3,"sources":["../../src/core/Logo.tsx"],"sourcesContent":["import React, { HTMLAttributes } from \"react\";\nimport Badge from \"./Badge\";\nimport cn from \"./utils/cn\";\nimport LogoAssetMonoStacked from \"./images/logo/ably-logo-mono-stacked.svg\";\nimport LogoAssetMonoWhiteStacked from \"./images/logo/ably-logo-mono-white-stacked.svg\";\nimport LogoAssetMonoWhite from \"./images/logo/ably-logo-mono-white.svg\";\nimport LogoAssetMono from \"./images/logo/ably-logo-mono.svg\";\nimport LogoAssetStacked from \"./images/logo/ably-logo-stacked.svg\";\nimport LogoAssetWhiteStacked from \"./images/logo/ably-logo-white-stacked.svg\";\nimport LogoAssetWhite from \"./images/logo/ably-logo-white.svg\";\nimport LogoAsset from \"./images/logo/ably-logo.svg\";\n\ntype LogoProps = {\n dataId?: string;\n logoUrl?: string;\n logoAlt?: string;\n href?: string;\n additionalImgAttrs?: HTMLAttributes<HTMLImageElement>;\n additionalLinkAttrs?: HTMLAttributes<HTMLAnchorElement>;\n theme?: \"light\" | \"dark\";\n variant?: \"default\" | \"mono\";\n orientation?: \"default\" | \"stacked\";\n badge?: string;\n};\n\nconst Logo = ({\n dataId,\n href = \"/\",\n additionalImgAttrs,\n additionalLinkAttrs,\n theme = \"light\",\n variant = \"default\",\n orientation = \"default\",\n logoUrl,\n logoAlt = \"Ably logo\",\n badge,\n}: LogoProps) => {\n const getLogoSrc = React.useCallback(() => {\n if (logoUrl) return logoUrl;\n\n if (theme === \"dark\") {\n if (variant === \"mono\") {\n return orientation === \"stacked\"\n ? LogoAssetMonoWhiteStacked\n : LogoAssetMonoWhite;\n } else {\n return orientation === \"stacked\"\n ? LogoAssetWhiteStacked\n : LogoAssetWhite;\n }\n } else {\n if (variant === \"mono\") {\n return orientation === \"stacked\" ? LogoAssetMonoStacked : LogoAssetMono;\n } else {\n return orientation === \"stacked\" ? LogoAssetStacked : LogoAsset;\n }\n }\n }, [logoUrl, theme, variant, orientation]);\n\n const logoSrc = getLogoSrc();\n\n return (\n <a\n href={href}\n data-id={dataId}\n {...additionalLinkAttrs}\n className={cn(\n \"flex items-center gap-2 justify-center\",\n additionalLinkAttrs?.className,\n )}\n >\n <img src={logoSrc} width=\"108px\" alt={logoAlt} {...additionalImgAttrs} />\n {badge && (\n <Badge className=\"uppercase h-8 bg-transparent dark:bg-transparent rounded border border-neutral-400 dark:border-neutral-900 text-lg p-2 font-semibold text-neutral-800 dark:text-neutral-500\">\n {badge}\n </Badge>\n )}\n </a>\n );\n};\n\nexport default React.memo(Logo);\n"],"names":["React","Badge","cn","LogoAssetMonoStacked","LogoAssetMonoWhiteStacked","LogoAssetMonoWhite","LogoAssetMono","LogoAssetStacked","LogoAssetWhiteStacked","LogoAssetWhite","LogoAsset","Logo","dataId","href","additionalImgAttrs","additionalLinkAttrs","theme","variant","orientation","logoUrl","logoAlt","badge","getLogoSrc","useCallback","logoSrc","a","data-id","className","img","src","width","alt","memo"],"mappings":"AAAA,OAAOA,UAA+B,OAAQ,AAC9C,QAAOC,UAAW,SAAU,AAC5B,QAAOC,OAAQ,YAAa,AAC5B,QAAOC,yBAA0B,0CAA2C,AAC5E,QAAOC,8BAA+B,gDAAiD,AACvF,QAAOC,uBAAwB,wCAAyC,AACxE,QAAOC,kBAAmB,kCAAmC,AAC7D,QAAOC,qBAAsB,qCAAsC,AACnE,QAAOC,0BAA2B,2CAA4C,AAC9E,QAAOC,mBAAoB,mCAAoC,AAC/D,QAAOC,cAAe,6BAA8B,CAepD,MAAMC,KAAO,CAAC,CACZC,MAAM,CACNC,KAAO,GAAG,CACVC,kBAAkB,CAClBC,mBAAmB,CACnBC,MAAQ,OAAO,CACfC,QAAU,SAAS,CACnBC,YAAc,SAAS,CACvBC,OAAO,CACPC,QAAU,WAAW,CACrBC,KAAK,CACK,IACV,MAAMC,WAAatB,MAAMuB,WAAW,CAAC,KACnC,GAAIJ,QAAS,OAAOA,QAEpB,GAAIH,QAAU,OAAQ,CACpB,GAAIC,UAAY,OAAQ,CACtB,OAAOC,cAAgB,UACnBd,0BACAC,kBACN,KAAO,CACL,OAAOa,cAAgB,UACnBV,sBACAC,cACN,CACF,KAAO,CACL,GAAIQ,UAAY,OAAQ,CACtB,OAAOC,cAAgB,UAAYf,qBAAuBG,aAC5D,KAAO,CACL,OAAOY,cAAgB,UAAYX,iBAAmBG,SACxD,CACF,CACF,EAAG,CAACS,QAASH,MAAOC,QAASC,YAAY,EAEzC,MAAMM,QAAUF,aAEhB,OACE,oBAACG,KACCZ,KAAMA,KACNa,UAASd,OACR,GAAGG,mBAAmB,CACvBY,UAAWzB,GACT,yCACAa,qBAAqBY,YAGvB,oBAACC,OAAIC,IAAKL,QAASM,MAAM,QAAQC,IAAKX,QAAU,GAAGN,kBAAkB,GACpEO,OACC,oBAACpB,OAAM0B,UAAU,+KACdN,OAKX,CAEA,gBAAerB,MAAMgC,IAAI,CAACrB,KAAM"}
|
package/core/Meganav.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useEffect,useMemo}from"react";import Header from"./Header";import Flyout from"./Flyout";import{menuItemsForHeader}from"./Meganav/data";import{MeganavMobile}from"./Meganav/MeganavMobile";import Notice from"./Notice";import{HEADER_HEIGHT}from"./utils/heights";const Meganav=({sessionState,notice,theme,themedScrollpoints
|
|
1
|
+
import React,{useEffect,useMemo}from"react";import Header from"./Header";import Flyout from"./Flyout";import{menuItemsForHeader}from"./Meganav/data";import{MeganavMobile}from"./Meganav/MeganavMobile";import Notice from"./Notice";import{HEADER_HEIGHT}from"./utils/heights";const Meganav=({sessionState,notice,theme,themedScrollpoints})=>{const[noticeHeight,setNoticeHeight]=React.useState(0);const mobileNavItems=useMemo(()=>menuItemsForHeader.filter(item=>!item.isHiddenMobile).map(({name,link,content})=>({name,link,content})),[]);const defaultThemedScrollpoints=[{id:"meganav",className:"ui-theme-light !bg-transparent !border-none"},{id:"meganav-theme-dark",className:"ui-theme-dark !bg-transparent !border-none"},{id:"main",className:"ui-theme-light bg-neutral-000 dark:bg-neutral-1300 border-b"},{id:"main-theme-dark",className:"ui-theme-dark bg-neutral-000 dark:bg-neutral-1300 border-b"}];useEffect(()=>{const observeNoticeResize=()=>{const noticeElement=document.querySelector('[data-id="ui-notice"]');if(noticeElement){setNoticeHeight(noticeElement.getBoundingClientRect().height)}};observeNoticeResize();window.addEventListener("resize",observeNoticeResize);return()=>window.removeEventListener("resize",observeNoticeResize)},[]);return React.createElement(React.Fragment,null,React.createElement("div",{className:"absolute inset-0 w-full z-50",id:theme==="dark"?"meganav-theme-dark":"meganav","data-testid":"meganav",style:{height:HEADER_HEIGHT+noticeHeight}},notice&&React.createElement(Notice,{...notice.props,config:notice.config}),React.createElement(Header,{className:"max-w-screen-xl mx-auto px-0 sm:px-8 md:px-10 lg:px-16",isNoticeVisible:!!notice,nav:React.createElement(Flyout,{menuItems:menuItemsForHeader,className:"justify-left z-40",flyOutClassName:"flex justify-left",viewPortClassName:"ui-shadow-lg-medium border border-neutral-200 dark:border-neutral-1100 rounded-2xl -mt-1 bg-neutral-000 dark:bg-neutral-1300"}),mobileNav:React.createElement(MeganavMobile,{navItems:mobileNavItems}),headerLinks:[{href:"/contact",label:"Contact us"}],headerLinksClassName:"md:gap-x-6 ",sessionState:sessionState,themedScrollpoints:themedScrollpoints??defaultThemedScrollpoints})))};export default Meganav;
|
|
2
2
|
//# sourceMappingURL=Meganav.js.map
|
package/core/Meganav.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Meganav.tsx"],"sourcesContent":["import React, { useEffect, useMemo } from \"react\";\nimport Header, { HeaderSessionState, ThemedScrollpoint } from \"./Header\";\nimport Flyout from \"./Flyout\";\nimport { menuItemsForHeader } from \"./Meganav/data\";\nimport { MeganavMobile } from \"./Meganav/MeganavMobile\";\nimport Notice from \"./Notice\";\nimport { HEADER_HEIGHT } from \"./utils/heights\";\n\nexport type MeganavNoticeBannerProps = {\n props: {\n title: string;\n bodyText: string;\n buttonLink: string;\n buttonLabel: string;\n closeBtn: boolean;\n };\n config: {\n cookieId: string;\n noticeId: string | number;\n options: {\n collapse: boolean;\n };\n };\n};\n\nexport type MeganavProps = {\n sessionState: HeaderSessionState;\n notice?: MeganavNoticeBannerProps;\n theme?: string;\n themedScrollpoints?: ThemedScrollpoint[];\n
|
|
1
|
+
{"version":3,"sources":["../../src/core/Meganav.tsx"],"sourcesContent":["import React, { useEffect, useMemo } from \"react\";\nimport Header, { HeaderSessionState, ThemedScrollpoint } from \"./Header\";\nimport Flyout from \"./Flyout\";\nimport { menuItemsForHeader } from \"./Meganav/data\";\nimport { MeganavMobile } from \"./Meganav/MeganavMobile\";\nimport Notice from \"./Notice\";\nimport { HEADER_HEIGHT } from \"./utils/heights\";\n\nexport type MeganavNoticeBannerProps = {\n props: {\n title: string;\n bodyText: string;\n buttonLink: string;\n buttonLabel: string;\n closeBtn: boolean;\n };\n config: {\n cookieId: string;\n noticeId: string | number;\n options: {\n collapse: boolean;\n };\n };\n};\n\nexport type MeganavProps = {\n sessionState: HeaderSessionState;\n notice?: MeganavNoticeBannerProps;\n theme?: string;\n themedScrollpoints?: ThemedScrollpoint[];\n};\n\nconst Meganav = ({\n sessionState,\n notice,\n theme,\n themedScrollpoints,\n}: MeganavProps) => {\n const [noticeHeight, setNoticeHeight] = React.useState(0);\n const mobileNavItems = useMemo(\n () =>\n menuItemsForHeader\n .filter((item) => !item.isHiddenMobile)\n .map(({ name, link, content }) => ({ name, link, content })),\n [],\n );\n\n const defaultThemedScrollpoints = [\n {\n id: \"meganav\",\n className: \"ui-theme-light !bg-transparent !border-none\",\n },\n {\n id: \"meganav-theme-dark\",\n className: \"ui-theme-dark !bg-transparent !border-none\",\n },\n {\n id: \"main\",\n className: \"ui-theme-light bg-neutral-000 dark:bg-neutral-1300 border-b\",\n },\n {\n id: \"main-theme-dark\",\n className: \"ui-theme-dark bg-neutral-000 dark:bg-neutral-1300 border-b\",\n },\n ];\n\n useEffect(() => {\n const observeNoticeResize = () => {\n const noticeElement = document.querySelector('[data-id=\"ui-notice\"]');\n if (noticeElement) {\n setNoticeHeight(noticeElement.getBoundingClientRect().height);\n }\n };\n observeNoticeResize();\n window.addEventListener(\"resize\", observeNoticeResize);\n return () => window.removeEventListener(\"resize\", observeNoticeResize);\n }, []);\n\n return (\n <>\n <div\n className=\"absolute inset-0 w-full z-50\"\n id={theme === \"dark\" ? \"meganav-theme-dark\" : \"meganav\"}\n data-testid=\"meganav\"\n style={{ height: HEADER_HEIGHT + noticeHeight }}\n >\n {notice && <Notice {...notice.props} config={notice.config} />}\n <Header\n className=\"max-w-screen-xl mx-auto px-0 sm:px-8 md:px-10 lg:px-16\"\n isNoticeVisible={!!notice}\n nav={\n <Flyout\n menuItems={menuItemsForHeader}\n className=\"justify-left z-40\"\n flyOutClassName=\"flex justify-left\"\n viewPortClassName=\"ui-shadow-lg-medium border border-neutral-200 dark:border-neutral-1100 rounded-2xl -mt-1 bg-neutral-000 dark:bg-neutral-1300\"\n />\n }\n mobileNav={<MeganavMobile navItems={mobileNavItems} />}\n headerLinks={[{ href: \"/contact\", label: \"Contact us\" }]}\n headerLinksClassName=\"md:gap-x-6 \"\n sessionState={sessionState}\n themedScrollpoints={themedScrollpoints ?? defaultThemedScrollpoints}\n />\n </div>\n </>\n );\n};\n\nexport default Meganav;\n"],"names":["React","useEffect","useMemo","Header","Flyout","menuItemsForHeader","MeganavMobile","Notice","HEADER_HEIGHT","Meganav","sessionState","notice","theme","themedScrollpoints","noticeHeight","setNoticeHeight","useState","mobileNavItems","filter","item","isHiddenMobile","map","name","link","content","defaultThemedScrollpoints","id","className","observeNoticeResize","noticeElement","document","querySelector","getBoundingClientRect","height","window","addEventListener","removeEventListener","div","data-testid","style","props","config","isNoticeVisible","nav","menuItems","flyOutClassName","viewPortClassName","mobileNav","navItems","headerLinks","href","label","headerLinksClassName"],"mappings":"AAAA,OAAOA,OAASC,SAAS,CAAEC,OAAO,KAAQ,OAAQ,AAClD,QAAOC,WAAuD,UAAW,AACzE,QAAOC,WAAY,UAAW,AAC9B,QAASC,kBAAkB,KAAQ,gBAAiB,AACpD,QAASC,aAAa,KAAQ,yBAA0B,AACxD,QAAOC,WAAY,UAAW,AAC9B,QAASC,aAAa,KAAQ,iBAAkB,CA0BhD,MAAMC,QAAU,CAAC,CACfC,YAAY,CACZC,MAAM,CACNC,KAAK,CACLC,kBAAkB,CACL,IACb,KAAM,CAACC,aAAcC,gBAAgB,CAAGf,MAAMgB,QAAQ,CAAC,GACvD,MAAMC,eAAiBf,QACrB,IACEG,mBACGa,MAAM,CAAC,AAACC,MAAS,CAACA,KAAKC,cAAc,EACrCC,GAAG,CAAC,CAAC,CAAEC,IAAI,CAAEC,IAAI,CAAEC,OAAO,CAAE,GAAM,CAAA,CAAEF,KAAMC,KAAMC,OAAQ,CAAA,GAC7D,EAAE,EAGJ,MAAMC,0BAA4B,CAChC,CACEC,GAAI,UACJC,UAAW,6CACb,EACA,CACED,GAAI,qBACJC,UAAW,4CACb,EACA,CACED,GAAI,OACJC,UAAW,6DACb,EACA,CACED,GAAI,kBACJC,UAAW,4DACb,EACD,CAED1B,UAAU,KACR,MAAM2B,oBAAsB,KAC1B,MAAMC,cAAgBC,SAASC,aAAa,CAAC,yBAC7C,GAAIF,cAAe,CACjBd,gBAAgBc,cAAcG,qBAAqB,GAAGC,MAAM,CAC9D,CACF,EACAL,sBACAM,OAAOC,gBAAgB,CAAC,SAAUP,qBAClC,MAAO,IAAMM,OAAOE,mBAAmB,CAAC,SAAUR,oBACpD,EAAG,EAAE,EAEL,OACE,wCACE,oBAACS,OACCV,UAAU,+BACVD,GAAId,QAAU,OAAS,qBAAuB,UAC9C0B,cAAY,UACZC,MAAO,CAAEN,OAAQzB,cAAgBM,YAAa,GAE7CH,QAAU,oBAACJ,QAAQ,GAAGI,OAAO6B,KAAK,CAAEC,OAAQ9B,OAAO8B,MAAM,GAC1D,oBAACtC,QACCwB,UAAU,yDACVe,gBAAiB,CAAC,CAAC/B,OACnBgC,IACE,oBAACvC,QACCwC,UAAWvC,mBACXsB,UAAU,oBACVkB,gBAAgB,oBAChBC,kBAAkB,iIAGtBC,UAAW,oBAACzC,eAAc0C,SAAU/B,iBACpCgC,YAAa,CAAC,CAAEC,KAAM,WAAYC,MAAO,YAAa,EAAE,CACxDC,qBAAqB,cACrB1C,aAAcA,aACdG,mBAAoBA,oBAAsBY,6BAKpD,CAEA,gBAAehB,OAAQ"}
|
package/core/Notice.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useEffect,useRef}from"react";import DOMPurify from"dompurify";import Icon from"./Icon";import cn from"./utils/cn.js";import NoticeScripts from"./Notice/component.js";import useRailsUjsLinks from"./hooks/use-rails-ujs-hooks";const defaultTextColor="text-neutral-1300 dark:text-neutral-000";const contentWrapperClasses="w-full pr-2 ui-text-p4 self-center";const ContentWrapper=({buttonLink,textColor=defaultTextColor,children})=>buttonLink?React.createElement("a",{href:buttonLink,className:cn(contentWrapperClasses,textColor)},children):React.createElement("div",{className:cn(contentWrapperClasses,textColor)},children);const Notice=({buttonLink,buttonLabel,bodyText,title,config,closeBtn,bgColor="bg-orange-100 dark:bg-orange-1100",textColor=defaultTextColor
|
|
1
|
+
import React,{useEffect,useRef}from"react";import DOMPurify from"dompurify";import Icon from"./Icon";import cn from"./utils/cn.js";import NoticeScripts from"./Notice/component.js";import useRailsUjsLinks from"./hooks/use-rails-ujs-hooks";const defaultTextColor="text-neutral-1300 dark:text-neutral-000";const contentWrapperClasses="w-full pr-2 ui-text-p4 self-center";const ContentWrapper=({buttonLink,textColor=defaultTextColor,children})=>buttonLink?React.createElement("a",{href:buttonLink,className:cn(contentWrapperClasses,textColor)},children):React.createElement("div",{className:cn(contentWrapperClasses,textColor)},children);const Notice=({buttonLink,buttonLabel,bodyText,title,config,closeBtn,bgColor="bg-orange-100 dark:bg-orange-1100",textColor=defaultTextColor})=>{const contentRef=useRef(null);useRailsUjsLinks(contentRef);useEffect(()=>{NoticeScripts({bannerContainer:document.querySelector('[data-id="ui-notice"]'),cookieId:config?.cookieId,noticeId:config?.noticeId,options:{collapse:config?.options?.collapse||false}})},[config?.cookieId,config?.noticeId,config?.options?.collapse]);const safeContent=DOMPurify.sanitize(bodyText??"",{ALLOWED_TAGS:["a"],ALLOWED_ATTR:["href","data-method"],ALLOWED_URI_REGEXP:/^\/[^/]/});return React.createElement("div",{className:cn("ui-announcement",bgColor,textColor),"data-id":"ui-notice",style:{maxHeight:0,overflow:"hidden"}},React.createElement("div",{className:"ui-grid-px py-4 max-w-screen-xl mx-auto flex items-start"},React.createElement(ContentWrapper,{buttonLink:buttonLink??"#"},React.createElement("strong",{className:"font-bold whitespace-nowrap pr-1"},title),React.createElement("span",{ref:contentRef,className:"pr-1",dangerouslySetInnerHTML:{__html:safeContent}}),buttonLabel&&React.createElement("span",{className:"cursor-pointer whitespace-nowrap text-gui-blue-default-light dark:text-gui-blue-default-dark"},buttonLabel)),closeBtn&&React.createElement("button",{type:"button",className:"ml-auto h-5 w-5 border-none bg-none self-baseline"},React.createElement(Icon,{name:"icon-gui-x-mark-outline",size:"1.25rem",color:textColor}))))};export default Notice;
|
|
2
2
|
//# sourceMappingURL=Notice.js.map
|
package/core/Notice.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Notice.tsx"],"sourcesContent":["import React, { ReactNode, useEffect, useRef } from \"react\";\nimport DOMPurify from \"dompurify\";\n\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn.js\";\nimport NoticeScripts from \"./Notice/component.js\";\nimport useRailsUjsLinks from \"./hooks/use-rails-ujs-hooks\";\n\ntype ContentWrapperProps = {\n buttonLink: string;\n children: ReactNode;\n textColor?: ColorClass | ColorThemeSet;\n};\n\n// TODO(jamiehenson):\n// This type is a bit messed up currently due to the NoticeScripts import being interpreted as NoticeProps.\n// Plan is to TS-ify the JS assets too, so this can be rectified then. The NoticeScripts-oriented props are\n// the ones after the line break.\nexport type NoticeProps = {\n buttonLink?: string;\n buttonLabel?: string;\n bodyText?: string;\n title?: string;\n closeBtn?: boolean;\n config?: {\n options: {\n collapse: boolean;\n };\n noticeId: string | number;\n cookieId: string;\n };\n bgColor?: string;\n textColor?: ColorClass | ColorThemeSet;\n
|
|
1
|
+
{"version":3,"sources":["../../src/core/Notice.tsx"],"sourcesContent":["import React, { ReactNode, useEffect, useRef } from \"react\";\nimport DOMPurify from \"dompurify\";\n\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn.js\";\nimport NoticeScripts from \"./Notice/component.js\";\nimport useRailsUjsLinks from \"./hooks/use-rails-ujs-hooks\";\n\ntype ContentWrapperProps = {\n buttonLink: string;\n children: ReactNode;\n textColor?: ColorClass | ColorThemeSet;\n};\n\n// TODO(jamiehenson):\n// This type is a bit messed up currently due to the NoticeScripts import being interpreted as NoticeProps.\n// Plan is to TS-ify the JS assets too, so this can be rectified then. The NoticeScripts-oriented props are\n// the ones after the line break.\nexport type NoticeProps = {\n buttonLink?: string;\n buttonLabel?: string;\n bodyText?: string;\n title?: string;\n closeBtn?: boolean;\n config?: {\n options: {\n collapse: boolean;\n };\n noticeId: string | number;\n cookieId: string;\n };\n bgColor?: string;\n textColor?: ColorClass | ColorThemeSet;\n\n bannerContainer?: Element | null;\n cookieId?: string;\n noticeId?: string;\n options?: { collapse: boolean };\n};\n\nconst defaultTextColor = \"text-neutral-1300 dark:text-neutral-000\";\n\nconst contentWrapperClasses = \"w-full pr-2 ui-text-p4 self-center\";\n\nconst ContentWrapper = ({\n buttonLink,\n textColor = defaultTextColor,\n children,\n}: ContentWrapperProps) =>\n buttonLink ? (\n <a href={buttonLink} className={cn(contentWrapperClasses, textColor)}>\n {children}\n </a>\n ) : (\n <div className={cn(contentWrapperClasses, textColor)}>{children}</div>\n );\n\nconst Notice = ({\n buttonLink,\n buttonLabel,\n bodyText,\n title,\n config,\n closeBtn,\n bgColor = \"bg-orange-100 dark:bg-orange-1100\",\n textColor = defaultTextColor,\n}: NoticeProps) => {\n const contentRef = useRef<HTMLSpanElement>(null);\n useRailsUjsLinks(contentRef);\n\n useEffect(() => {\n NoticeScripts({\n bannerContainer: document.querySelector('[data-id=\"ui-notice\"]'),\n cookieId: config?.cookieId,\n noticeId: config?.noticeId,\n options: {\n collapse: config?.options?.collapse || false,\n },\n });\n }, [config?.cookieId, config?.noticeId, config?.options?.collapse]);\n\n const safeContent = DOMPurify.sanitize(bodyText ?? \"\", {\n ALLOWED_TAGS: [\"a\"],\n ALLOWED_ATTR: [\"href\", \"data-method\"],\n ALLOWED_URI_REGEXP: /^\\/[^/]/,\n });\n\n return (\n <div\n className={cn(\"ui-announcement\", bgColor, textColor)}\n data-id=\"ui-notice\"\n style={{ maxHeight: 0, overflow: \"hidden\" }}\n >\n <div className=\"ui-grid-px py-4 max-w-screen-xl mx-auto flex items-start\">\n <ContentWrapper buttonLink={buttonLink ?? \"#\"}>\n <strong className=\"font-bold whitespace-nowrap pr-1\">{title}</strong>\n <span\n ref={contentRef}\n className=\"pr-1\"\n dangerouslySetInnerHTML={{\n __html: safeContent,\n }}\n ></span>\n {buttonLabel && (\n <span className=\"cursor-pointer whitespace-nowrap text-gui-blue-default-light dark:text-gui-blue-default-dark\">\n {buttonLabel}\n </span>\n )}\n </ContentWrapper>\n\n {closeBtn && (\n <button\n type=\"button\"\n className=\"ml-auto h-5 w-5 border-none bg-none self-baseline\"\n >\n <Icon\n name=\"icon-gui-x-mark-outline\"\n size=\"1.25rem\"\n color={textColor}\n />\n </button>\n )}\n </div>\n </div>\n );\n};\n\nexport default Notice;\n"],"names":["React","useEffect","useRef","DOMPurify","Icon","cn","NoticeScripts","useRailsUjsLinks","defaultTextColor","contentWrapperClasses","ContentWrapper","buttonLink","textColor","children","a","href","className","div","Notice","buttonLabel","bodyText","title","config","closeBtn","bgColor","contentRef","bannerContainer","document","querySelector","cookieId","noticeId","options","collapse","safeContent","sanitize","ALLOWED_TAGS","ALLOWED_ATTR","ALLOWED_URI_REGEXP","data-id","style","maxHeight","overflow","strong","span","ref","dangerouslySetInnerHTML","__html","button","type","name","size","color"],"mappings":"AAAA,OAAOA,OAAoBC,SAAS,CAAEC,MAAM,KAAQ,OAAQ,AAC5D,QAAOC,cAAe,WAAY,AAGlC,QAAOC,SAAU,QAAS,AAC1B,QAAOC,OAAQ,eAAgB,AAC/B,QAAOC,kBAAmB,uBAAwB,AAClD,QAAOC,qBAAsB,6BAA8B,CAkC3D,MAAMC,iBAAmB,0CAEzB,MAAMC,sBAAwB,qCAE9B,MAAMC,eAAiB,CAAC,CACtBC,UAAU,CACVC,UAAYJ,gBAAgB,CAC5BK,QAAQ,CACY,GACpBF,WACE,oBAACG,KAAEC,KAAMJ,WAAYK,UAAWX,GAAGI,sBAAuBG,YACvDC,UAGH,oBAACI,OAAID,UAAWX,GAAGI,sBAAuBG,YAAaC,UAG3D,MAAMK,OAAS,CAAC,CACdP,UAAU,CACVQ,WAAW,CACXC,QAAQ,CACRC,KAAK,CACLC,MAAM,CACNC,QAAQ,CACRC,QAAU,mCAAmC,CAC7CZ,UAAYJ,gBAAgB,CAChB,IACZ,MAAMiB,WAAavB,OAAwB,MAC3CK,iBAAiBkB,YAEjBxB,UAAU,KACRK,cAAc,CACZoB,gBAAiBC,SAASC,aAAa,CAAC,yBACxCC,SAAUP,QAAQO,SAClBC,SAAUR,QAAQQ,SAClBC,QAAS,CACPC,SAAUV,QAAQS,SAASC,UAAY,KACzC,CACF,EACF,EAAG,CAACV,QAAQO,SAAUP,QAAQQ,SAAUR,QAAQS,SAASC,SAAS,EAElE,MAAMC,YAAc9B,UAAU+B,QAAQ,CAACd,UAAY,GAAI,CACrDe,aAAc,CAAC,IAAI,CACnBC,aAAc,CAAC,OAAQ,cAAc,CACrCC,mBAAoB,SACtB,GAEA,OACE,oBAACpB,OACCD,UAAWX,GAAG,kBAAmBmB,QAASZ,WAC1C0B,UAAQ,YACRC,MAAO,CAAEC,UAAW,EAAGC,SAAU,QAAS,GAE1C,oBAACxB,OAAID,UAAU,4DACb,oBAACN,gBAAeC,WAAYA,YAAc,KACxC,oBAAC+B,UAAO1B,UAAU,oCAAoCK,OACtD,oBAACsB,QACCC,IAAKnB,WACLT,UAAU,OACV6B,wBAAyB,CACvBC,OAAQb,WACV,IAEDd,aACC,oBAACwB,QAAK3B,UAAU,gGACbG,cAKNI,UACC,oBAACwB,UACCC,KAAK,SACLhC,UAAU,qDAEV,oBAACZ,MACC6C,KAAK,0BACLC,KAAK,UACLC,MAAOvC,cAOrB,CAEA,gBAAeM,MAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/remote-blogs-posts.js"],"sourcesContent":["/* global __ENABLE_FETCH_WITH_CREDENTIALS__ */\n\nimport { isJsonResponse } from \"./remote-data-util\";\n\nconst fetchBlogPosts = async (store, blogUrl) => {\n try {\n if (!blogUrl) {\n console.log(\n `Skipping fetching blog posts, invalid blogUrl: \"${blogUrl}\"`,\n );\n return;\n }\n\n const options = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n if (__ENABLE_FETCH_WITH_CREDENTIALS__) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(blogUrl, options);\n\n if (isJsonResponse(res.headers.get(\"content-type\"))) {\n const payload = await res.json();\n store.dispatch({ type: \"blog/loaded\", payload });\n } else {\n throw new Error(\"Blog posts url is not serving json\");\n }\n } catch (e) {\n console.warn(\"Could not fetch blog posts due to error:\", e);\n }\n};\n\nconst initialState = { recent: null };\n\nconst REDUCER_KEY = \"blogPosts\";\n\nconst reducerBlogPosts = {\n [REDUCER_KEY]: (state = initialState, action) => {\n switch (action.type) {\n case \"blog/loaded\":\n return { ...state, recent: action.payload };\n default:\n return state;\n }\n },\n};\n\nconst selectRecentBlogPosts = (store) => store.getState()[REDUCER_KEY]?.recent;\n\nexport { fetchBlogPosts, reducerBlogPosts, selectRecentBlogPosts };\n"],"names":["isJsonResponse","fetchBlogPosts","store","blogUrl","console","log","options","headers","accept","cache","credentials","res","fetch","get","payload","json","dispatch","type","Error","e","warn","initialState","recent","REDUCER_KEY","reducerBlogPosts","state","action","selectRecentBlogPosts","getState"],"mappings":"AAEA,OAASA,cAAc,KAAQ,oBAAqB,CAEpD,MAAMC,eAAiB,MAAOC,MAAOC,WACnC,GAAI,CACF,GAAI,CAACA,QAAS,CACZC,QAAQC,GAAG,CACT,CAAC,gDAAgD,EAAEF,QAAQ,CAAC,CAAC,EAE/D,MACF,CAEA,MAAMG,QAAU,CACdC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAEA,
|
|
1
|
+
{"version":3,"sources":["../../src/core/remote-blogs-posts.js"],"sourcesContent":["/* global __ENABLE_FETCH_WITH_CREDENTIALS__ */\n\nimport { isJsonResponse } from \"./remote-data-util\";\n\nconst fetchBlogPosts = async (store, blogUrl) => {\n try {\n if (!blogUrl) {\n console.log(\n `Skipping fetching blog posts, invalid blogUrl: \"${blogUrl}\"`,\n );\n return;\n }\n\n const options = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n if (__ENABLE_FETCH_WITH_CREDENTIALS__) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(blogUrl, options);\n\n if (isJsonResponse(res.headers.get(\"content-type\"))) {\n const payload = await res.json();\n store.dispatch({ type: \"blog/loaded\", payload });\n } else {\n throw new Error(\"Blog posts url is not serving json\");\n }\n } catch (e) {\n console.warn(\"Could not fetch blog posts due to error:\", e);\n }\n};\n\nconst initialState = { recent: null };\n\nconst REDUCER_KEY = \"blogPosts\";\n\nconst reducerBlogPosts = {\n [REDUCER_KEY]: (state = initialState, action) => {\n switch (action.type) {\n case \"blog/loaded\":\n return { ...state, recent: action.payload };\n default:\n return state;\n }\n },\n};\n\nconst selectRecentBlogPosts = (store) => store.getState()[REDUCER_KEY]?.recent;\n\nexport { fetchBlogPosts, reducerBlogPosts, selectRecentBlogPosts };\n"],"names":["isJsonResponse","fetchBlogPosts","store","blogUrl","console","log","options","headers","accept","cache","credentials","res","fetch","get","payload","json","dispatch","type","Error","e","warn","initialState","recent","REDUCER_KEY","reducerBlogPosts","state","action","selectRecentBlogPosts","getState"],"mappings":"AAEA,OAASA,cAAc,KAAQ,oBAAqB,CAEpD,MAAMC,eAAiB,MAAOC,MAAOC,WACnC,GAAI,CACF,GAAI,CAACA,QAAS,CACZC,QAAQC,GAAG,CACT,CAAC,gDAAgD,EAAEF,QAAQ,CAAC,CAAC,EAE/D,MACF,CAEA,MAAMG,QAAU,CACdC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAEA,SAAuC,CACrCH,QAAQI,WAAW,CAAG,SACxB,CAEA,MAAMC,IAAM,MAAMC,MAAMT,QAASG,SAEjC,GAAIN,eAAeW,IAAIJ,OAAO,CAACM,GAAG,CAAC,iBAAkB,CACnD,MAAMC,QAAU,MAAMH,IAAII,IAAI,GAC9Bb,MAAMc,QAAQ,CAAC,CAAEC,KAAM,cAAeH,OAAQ,EAChD,KAAO,CACL,MAAM,IAAII,MAAM,qCAClB,CACF,CAAE,MAAOC,EAAG,CACVf,QAAQgB,IAAI,CAAC,2CAA4CD,EAC3D,CACF,EAEA,MAAME,aAAe,CAAEC,OAAQ,IAAK,EAEpC,MAAMC,YAAc,YAEpB,MAAMC,iBAAmB,CACvB,CAACD,YAAY,CAAE,CAACE,MAAQJ,YAAY,CAAEK,UACpC,OAAQA,OAAOT,IAAI,EACjB,IAAK,cACH,MAAO,CAAE,GAAGQ,KAAK,CAAEH,OAAQI,OAAOZ,OAAO,AAAC,CAC5C,SACE,OAAOW,KACX,CACF,CACF,EAEA,MAAME,sBAAwB,AAACzB,OAAUA,MAAM0B,QAAQ,EAAE,CAACL,YAAY,EAAED,MAExE,QAASrB,cAAc,CAAEuB,gBAAgB,CAAEG,qBAAqB,CAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/remote-session-data.js"],"sourcesContent":["/* global __ENABLE_FETCH_WITH_CREDENTIALS__ */\n\n// Fetches current users session data\n// Assumes an authenticated session, so will only work when used on ably.com/ably.io\n\nimport { isJsonResponse } from \"./remote-data-util\";\n\nconst NOT_FOUND_ERROR_CODE = \"not-found\";\n\nconst fetchSessionData = async (store, sessionUrl) => {\n const sessionLoaded = (payload = {}) =>\n store.dispatch({ type: \"session/loaded\", payload });\n\n try {\n if (!sessionUrl) {\n console.log(\n `Skipping fetching session, invalid sessionUrl: \"${sessionUrl}\"`,\n );\n sessionLoaded();\n return;\n }\n\n const options = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n if (__ENABLE_FETCH_WITH_CREDENTIALS__) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(sessionUrl, options);\n const jsonResponse = isJsonResponse(res.headers.get(\"content-type\"));\n\n if (!jsonResponse) {\n throw new Error(\"Session endpoint is not serving json\");\n }\n\n const payload = await res.json();\n\n if (payload.error === NOT_FOUND_ERROR_CODE) {\n sessionLoaded();\n } else {\n sessionLoaded(payload);\n }\n } catch (e) {\n sessionLoaded();\n console.warn(\"Could not fetch session data due to error:\", e);\n }\n};\n\nconst initialState = { data: null };\n\nconst REDUCER_KEY = \"session\";\n\nconst reducerSessionData = {\n [REDUCER_KEY]: (state = initialState, action) => {\n switch (action.type) {\n case \"session/loaded\":\n return { ...state, data: action.payload };\n default:\n return state;\n }\n },\n};\n\nconst selectSessionData = (store) => store.getState()[REDUCER_KEY]?.data;\n\nexport { fetchSessionData, reducerSessionData, selectSessionData };\n"],"names":["isJsonResponse","NOT_FOUND_ERROR_CODE","fetchSessionData","store","sessionUrl","sessionLoaded","payload","dispatch","type","console","log","options","headers","accept","cache","credentials","res","fetch","jsonResponse","get","Error","json","error","e","warn","initialState","data","REDUCER_KEY","reducerSessionData","state","action","selectSessionData","getState"],"mappings":"AAKA,OAASA,cAAc,KAAQ,oBAAqB,CAEpD,MAAMC,qBAAuB,YAE7B,MAAMC,iBAAmB,MAAOC,MAAOC,cACrC,MAAMC,cAAgB,CAACC,QAAU,CAAC,CAAC,GACjCH,MAAMI,QAAQ,CAAC,CAAEC,KAAM,iBAAkBF,OAAQ,GAEnD,GAAI,CACF,GAAI,CAACF,WAAY,CACfK,QAAQC,GAAG,CACT,CAAC,gDAAgD,EAAEN,WAAW,CAAC,CAAC,EAElEC,gBACA,MACF,CAEA,MAAMM,QAAU,CACdC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAEA,
|
|
1
|
+
{"version":3,"sources":["../../src/core/remote-session-data.js"],"sourcesContent":["/* global __ENABLE_FETCH_WITH_CREDENTIALS__ */\n\n// Fetches current users session data\n// Assumes an authenticated session, so will only work when used on ably.com/ably.io\n\nimport { isJsonResponse } from \"./remote-data-util\";\n\nconst NOT_FOUND_ERROR_CODE = \"not-found\";\n\nconst fetchSessionData = async (store, sessionUrl) => {\n const sessionLoaded = (payload = {}) =>\n store.dispatch({ type: \"session/loaded\", payload });\n\n try {\n if (!sessionUrl) {\n console.log(\n `Skipping fetching session, invalid sessionUrl: \"${sessionUrl}\"`,\n );\n sessionLoaded();\n return;\n }\n\n const options = {\n headers: {\n accept: \"application/json\",\n },\n cache: \"no-cache\",\n };\n\n if (__ENABLE_FETCH_WITH_CREDENTIALS__) {\n options.credentials = \"include\";\n }\n\n const res = await fetch(sessionUrl, options);\n const jsonResponse = isJsonResponse(res.headers.get(\"content-type\"));\n\n if (!jsonResponse) {\n throw new Error(\"Session endpoint is not serving json\");\n }\n\n const payload = await res.json();\n\n if (payload.error === NOT_FOUND_ERROR_CODE) {\n sessionLoaded();\n } else {\n sessionLoaded(payload);\n }\n } catch (e) {\n sessionLoaded();\n console.warn(\"Could not fetch session data due to error:\", e);\n }\n};\n\nconst initialState = { data: null };\n\nconst REDUCER_KEY = \"session\";\n\nconst reducerSessionData = {\n [REDUCER_KEY]: (state = initialState, action) => {\n switch (action.type) {\n case \"session/loaded\":\n return { ...state, data: action.payload };\n default:\n return state;\n }\n },\n};\n\nconst selectSessionData = (store) => store.getState()[REDUCER_KEY]?.data;\n\nexport { fetchSessionData, reducerSessionData, selectSessionData };\n"],"names":["isJsonResponse","NOT_FOUND_ERROR_CODE","fetchSessionData","store","sessionUrl","sessionLoaded","payload","dispatch","type","console","log","options","headers","accept","cache","credentials","res","fetch","jsonResponse","get","Error","json","error","e","warn","initialState","data","REDUCER_KEY","reducerSessionData","state","action","selectSessionData","getState"],"mappings":"AAKA,OAASA,cAAc,KAAQ,oBAAqB,CAEpD,MAAMC,qBAAuB,YAE7B,MAAMC,iBAAmB,MAAOC,MAAOC,cACrC,MAAMC,cAAgB,CAACC,QAAU,CAAC,CAAC,GACjCH,MAAMI,QAAQ,CAAC,CAAEC,KAAM,iBAAkBF,OAAQ,GAEnD,GAAI,CACF,GAAI,CAACF,WAAY,CACfK,QAAQC,GAAG,CACT,CAAC,gDAAgD,EAAEN,WAAW,CAAC,CAAC,EAElEC,gBACA,MACF,CAEA,MAAMM,QAAU,CACdC,QAAS,CACPC,OAAQ,kBACV,EACAC,MAAO,UACT,EAEA,GAyC4B,MAzCW,CACrCH,QAAQI,WAAW,CAAG,SACxB,CAEA,MAAMC,IAAM,MAAMC,MAAMb,WAAYO,SACpC,MAAMO,aAAelB,eAAegB,IAAIJ,OAAO,CAACO,GAAG,CAAC,iBAEpD,GAAI,CAACD,aAAc,CACjB,MAAM,IAAIE,MAAM,uCAClB,CAEA,MAAMd,QAAU,MAAMU,IAAIK,IAAI,GAE9B,GAAIf,QAAQgB,KAAK,GAAKrB,qBAAsB,CAC1CI,eACF,KAAO,CACLA,cAAcC,QAChB,CACF,CAAE,MAAOiB,EAAG,CACVlB,gBACAI,QAAQe,IAAI,CAAC,6CAA8CD,EAC7D,CACF,EAEA,MAAME,aAAe,CAAEC,KAAM,IAAK,EAElC,MAAMC,YAAc,UAEpB,MAAMC,mBAAqB,CACzB,CAACD,YAAY,CAAE,CAACE,MAAQJ,YAAY,CAAEK,UACpC,OAAQA,OAAOtB,IAAI,EACjB,IAAK,iBACH,MAAO,CAAE,GAAGqB,KAAK,CAAEH,KAAMI,OAAOxB,OAAO,AAAC,CAC1C,SACE,OAAOuB,KACX,CACF,CACF,EAEA,MAAME,kBAAoB,AAAC5B,OAAUA,MAAM6B,QAAQ,EAAE,CAACL,YAAY,EAAED,IAEpE,QAASxB,gBAAgB,CAAE0B,kBAAkB,CAAEG,iBAAiB,CAAG"}
|
package/index.d.ts
CHANGED
|
@@ -759,10 +759,6 @@ export type HeaderProps = {
|
|
|
759
759
|
* Indicates if the notice banner is visible.
|
|
760
760
|
*/
|
|
761
761
|
isNoticeVisible?: boolean;
|
|
762
|
-
/**
|
|
763
|
-
* Height of the notice banner in pixels.
|
|
764
|
-
*/
|
|
765
|
-
noticeHeight?: number;
|
|
766
762
|
/**
|
|
767
763
|
* Optional search bar element.
|
|
768
764
|
*/
|
|
@@ -827,6 +823,10 @@ export type HeaderProps = {
|
|
|
827
823
|
* Optional location object to detect location changes.
|
|
828
824
|
*/
|
|
829
825
|
location?: Location;
|
|
826
|
+
/**
|
|
827
|
+
* Optional badge text to display on the logo.
|
|
828
|
+
*/
|
|
829
|
+
logoBadge?: string;
|
|
830
830
|
};
|
|
831
831
|
const Header: React.FC<HeaderProps>;
|
|
832
832
|
export default Header;
|
|
@@ -5196,19 +5196,20 @@ export default Loader;
|
|
|
5196
5196
|
}
|
|
5197
5197
|
|
|
5198
5198
|
declare module '@ably/ui/core/Logo' {
|
|
5199
|
-
import React from "react";
|
|
5199
|
+
import React, { HTMLAttributes } from "react";
|
|
5200
5200
|
type LogoProps = {
|
|
5201
5201
|
dataId?: string;
|
|
5202
5202
|
logoUrl?: string;
|
|
5203
5203
|
logoAlt?: string;
|
|
5204
5204
|
href?: string;
|
|
5205
|
-
additionalImgAttrs?:
|
|
5206
|
-
additionalLinkAttrs?:
|
|
5205
|
+
additionalImgAttrs?: HTMLAttributes<HTMLImageElement>;
|
|
5206
|
+
additionalLinkAttrs?: HTMLAttributes<HTMLAnchorElement>;
|
|
5207
5207
|
theme?: "light" | "dark";
|
|
5208
5208
|
variant?: "default" | "mono";
|
|
5209
5209
|
orientation?: "default" | "stacked";
|
|
5210
|
+
badge?: string;
|
|
5210
5211
|
};
|
|
5211
|
-
const _default: React.MemoExoticComponent<({ dataId, href, additionalImgAttrs, additionalLinkAttrs, theme, variant, orientation, logoUrl, logoAlt, }: LogoProps) => import("react/jsx-runtime").JSX.Element>;
|
|
5212
|
+
const _default: React.MemoExoticComponent<({ dataId, href, additionalImgAttrs, additionalLinkAttrs, theme, variant, orientation, logoUrl, logoAlt, badge, }: LogoProps) => import("react/jsx-runtime").JSX.Element>;
|
|
5212
5213
|
export default _default;
|
|
5213
5214
|
//# sourceMappingURL=Logo.d.ts.map
|
|
5214
5215
|
}
|
|
@@ -5353,9 +5354,8 @@ export type MeganavProps = {
|
|
|
5353
5354
|
notice?: MeganavNoticeBannerProps;
|
|
5354
5355
|
theme?: string;
|
|
5355
5356
|
themedScrollpoints?: ThemedScrollpoint[];
|
|
5356
|
-
onNoticeClose?: () => void;
|
|
5357
5357
|
};
|
|
5358
|
-
const Meganav: ({ sessionState, notice, theme, themedScrollpoints,
|
|
5358
|
+
const Meganav: ({ sessionState, notice, theme, themedScrollpoints, }: MeganavProps) => import("react/jsx-runtime").JSX.Element;
|
|
5359
5359
|
export default Meganav;
|
|
5360
5360
|
//# sourceMappingURL=Meganav.d.ts.map
|
|
5361
5361
|
}
|
|
@@ -5389,7 +5389,6 @@ export type NoticeProps = {
|
|
|
5389
5389
|
};
|
|
5390
5390
|
bgColor?: string;
|
|
5391
5391
|
textColor?: ColorClass | ColorThemeSet;
|
|
5392
|
-
onClose?: () => void;
|
|
5393
5392
|
bannerContainer?: Element | null;
|
|
5394
5393
|
cookieId?: string;
|
|
5395
5394
|
noticeId?: string;
|
|
@@ -5397,7 +5396,7 @@ export type NoticeProps = {
|
|
|
5397
5396
|
collapse: boolean;
|
|
5398
5397
|
};
|
|
5399
5398
|
};
|
|
5400
|
-
const Notice: ({ buttonLink, buttonLabel, bodyText, title, config, closeBtn, bgColor, textColor,
|
|
5399
|
+
const Notice: ({ buttonLink, buttonLabel, bodyText, title, config, closeBtn, bgColor, textColor, }: NoticeProps) => import("react/jsx-runtime").JSX.Element;
|
|
5401
5400
|
export default Notice;
|
|
5402
5401
|
//# sourceMappingURL=Notice.d.ts.map
|
|
5403
5402
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ably/ui",
|
|
3
|
-
"version": "17.6.
|
|
3
|
+
"version": "17.6.2-dev.7350af4a",
|
|
4
4
|
"description": "Home of the Ably design system library ([design.ably.com](https://design.ably.com)). It provides a showcase, development/test environment and a publishing pipeline for different distributables.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|