@ably/ui 15.6.0-dev.1a416b3 → 15.6.0-dev.274a3001
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/DropdownMenu.js +1 -1
- package/core/DropdownMenu.js.map +1 -1
- package/core/Flash.js +1 -1
- package/core/Flash.js.map +1 -1
- package/core/Footer.js +1 -1
- package/core/Footer.js.map +1 -1
- package/core/Header/HeaderLinks.js +1 -1
- package/core/Header/HeaderLinks.js.map +1 -1
- package/core/Header.js +1 -1
- package/core/Header.js.map +1 -1
- package/core/Meganav.js.map +1 -1
- package/core/Notice.js +1 -1
- package/core/Notice.js.map +1 -1
- package/core/hooks/use-rails-ujs-hooks.js +2 -0
- package/core/hooks/use-rails-ujs-hooks.js.map +1 -0
- package/core/images/g2-best-meets-requirements-2025.svg +10 -0
- package/core/images/g2-best-support-2025.svg +10 -0
- package/core/images/g2-high-performer-2025.svg +9 -0
- package/core/images/g2-users-most-likely-to-recommend-2025.svg +10 -0
- package/core/styles/colors/computed-colors.json +1 -0
- package/index.d.ts +67 -82
- package/package.json +3 -3
- package/core/Meganav/.DS_Store +0 -0
package/core/DropdownMenu.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{createContext,useContext,useState,useEffect,useRef}from"react";import Icon from"./Icon";
|
|
1
|
+
import React,{createContext,useContext,useState,useEffect,useRef}from"react";import Icon from"./Icon";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,additionalTriggerCSS=""})=>{const{isOpen,setOpen}=useContext(DropdownMenuContext);return React.createElement("button",{id:"menu-trigger",onClick:()=>setOpen(!isOpen),className:`${additionalTriggerCSS} flex items-center p-8 ml-8 group hover:text-gui-hover hover:bg-light-grey active:text-gui-active focus:text-gui-focus focus:outline-none rounded-lg`},React.createElement("span",{className:"leading-normal"},children),React.createElement(Icon,{name:"icon-gui-chevron-down-micro",color:"text-cool-black",size:"1.25rem",additionalCSS:"group-hover:text-gui-hover group-active:text-gui-active group-focus:text-gui-focus"}))};const Content=({children,anchorPosition="right",additionalContentCSS})=>{const{isOpen}=useContext(DropdownMenuContext);if(!isOpen){return null}const anchorPositionClasses=anchorPosition==="right"?"right-0":"left-0";return React.createElement("div",{id:"menu-content",className:`${additionalContentCSS} absolute p-8 z-10 border border-mid-grey bg-white rounded shadow-container ${anchorPositionClasses}`,style:{minWidth:275,top:44}},children)};const Link=({url,title,subtitle,iconName,children})=>{return React.createElement("a",{href:url,className:"menu-link group block p-8 hover:bg-light-grey hover:text-cool-black rounded"},React.createElement("p",{className:"mb-4"},title,iconName?React.createElement(Icon,{name:iconName,size:"1rem",color:"text-cool-black",additionalCSS:"align-middle ml-8 relative -top-1 -left-4"}):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;
|
|
2
2
|
//# sourceMappingURL=DropdownMenu.js.map
|
package/core/DropdownMenu.js.map
CHANGED
|
@@ -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\";\
|
|
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\";\n\nconst DropdownMenuContext = createContext<{\n isOpen: boolean;\n setOpen: Dispatch<React.SetStateAction<boolean>>;\n}>({\n isOpen: false,\n setOpen: () => {},\n});\n\ntype DropdownMenuProps = {\n children: ReactNode;\n};\n\ntype TriggerProps = {\n children: ReactNode;\n additionalTriggerCSS?: string;\n};\n\ntype ContentProps = {\n children: ReactNode;\n anchorPosition?: string;\n additionalContentCSS?: 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\n document.addEventListener(\"click\", clickHandler);\n\n return () => {\n document.removeEventListener(\"click\", clickHandler);\n };\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 = ({ children, additionalTriggerCSS = \"\" }: TriggerProps) => {\n const { isOpen, setOpen } = useContext(DropdownMenuContext);\n\n return (\n <button\n id=\"menu-trigger\"\n onClick={() => setOpen(!isOpen)}\n className={`${additionalTriggerCSS} flex items-center p-8 ml-8 group hover:text-gui-hover hover:bg-light-grey active:text-gui-active focus:text-gui-focus focus:outline-none rounded-lg`}\n >\n <span className=\"leading-normal\">{children}</span>\n <Icon\n name=\"icon-gui-chevron-down-micro\"\n color=\"text-cool-black\"\n size=\"1.25rem\"\n additionalCSS=\"group-hover:text-gui-hover group-active:text-gui-active group-focus:text-gui-focus\"\n />\n </button>\n );\n};\n\nconst Content = ({\n children,\n anchorPosition = \"right\",\n additionalContentCSS,\n}: ContentProps) => {\n const { isOpen } = useContext(DropdownMenuContext);\n\n if (!isOpen) {\n return null;\n }\n\n const anchorPositionClasses =\n anchorPosition === \"right\" ? \"right-0\" : \"left-0\";\n\n return (\n <div\n id=\"menu-content\"\n className={`${additionalContentCSS} absolute p-8 z-10 border border-mid-grey bg-white rounded shadow-container ${anchorPositionClasses}`}\n style={{ minWidth: 275, top: 44 }}\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 hover:bg-light-grey hover:text-cool-black rounded\"\n >\n <p className=\"mb-4\">\n {title}\n {iconName ? (\n <Icon\n name={iconName}\n size=\"1rem\"\n color=\"text-cool-black\"\n additionalCSS=\"align-middle ml-8 relative -top-1 -left-4\"\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;\nexport default DropdownMenu;\n"],"names":["React","createContext","useContext","useState","useEffect","useRef","Icon","DropdownMenuContext","isOpen","setOpen","DropdownMenu","children","ref","clickHandler","e","current","contains","target","document","addEventListener","removeEventListener","Provider","value","div","id","className","Trigger","additionalTriggerCSS","button","onClick","span","name","color","size","additionalCSS","Content","anchorPosition","additionalContentCSS","anchorPositionClasses","style","minWidth","top","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,CAG1B,MAAMC,oBAAsBN,cAGzB,CACDO,OAAQ,MACRC,QAAS,KAAO,CAClB,GAyBA,MAAMC,aAAe,CAAC,CAAEC,QAAQ,CAAqB,IACnD,KAAM,CAACH,OAAQC,QAAQ,CAAGN,SAAS,OACnC,MAAMS,IAAMP,OAAuB,MAEnCD,UAAU,KACR,MAAMS,aAAe,AAACC,IACpB,GAAIF,IAAIG,OAAO,EAAEC,SAASF,EAAEG,MAAM,EAAW,OAC7CR,QAAQ,MACV,EAEAS,SAASC,gBAAgB,CAAC,QAASN,cAEnC,MAAO,KACLK,SAASE,mBAAmB,CAAC,QAASP,aACxC,CACF,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,CAAEf,QAAQ,CAAEgB,qBAAuB,EAAE,CAAgB,IACpE,KAAM,CAAEnB,MAAM,CAAEC,OAAO,CAAE,CAAGP,WAAWK,qBAEvC,OACE,oBAACqB,UACCJ,GAAG,eACHK,QAAS,IAAMpB,QAAQ,CAACD,QACxBiB,UAAW,CAAC,EAAEE,qBAAqB,oJAAoJ,CAAC,EAExL,oBAACG,QAAKL,UAAU,kBAAkBd,UAClC,oBAACL,MACCyB,KAAK,8BACLC,MAAM,kBACNC,KAAK,UACLC,cAAc,uFAItB,EAEA,MAAMC,QAAU,CAAC,CACfxB,QAAQ,CACRyB,eAAiB,OAAO,CACxBC,oBAAoB,CACP,IACb,KAAM,CAAE7B,MAAM,CAAE,CAAGN,WAAWK,qBAE9B,GAAI,CAACC,OAAQ,CACX,OAAO,IACT,CAEA,MAAM8B,sBACJF,iBAAmB,QAAU,UAAY,SAE3C,OACE,oBAACb,OACCC,GAAG,eACHC,UAAW,CAAC,EAAEY,qBAAqB,4EAA4E,EAAEC,sBAAsB,CAAC,CACxIC,MAAO,CAAEC,SAAU,IAAKC,IAAK,EAAG,GAE/B9B,SAGP,EAEA,MAAM+B,KAAO,CAAC,CAAEC,GAAG,CAAEC,KAAK,CAAEC,QAAQ,CAAEC,QAAQ,CAAEnC,QAAQ,CAAa,IACnE,OACE,oBAACoC,KACCC,KAAML,IACNlB,UAAU,+EAEV,oBAACwB,KAAExB,UAAU,QACVmB,MACAE,SACC,oBAACxC,MACCyB,KAAMe,SACNb,KAAK,OACLD,MAAM,kBACNE,cAAc,8CAEd,MAELW,SAAW,oBAACI,KAAExB,UAAU,oBAAoBoB,UAAgB,KAC5DlC,SAGP,CAEAD,CAAAA,aAAagB,OAAO,CAAGA,OACvBhB,CAAAA,aAAayB,OAAO,CAAGA,OACvBzB,CAAAA,aAAagC,IAAI,CAAGA,IACpB,gBAAehC,YAAa"}
|
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","rel"]});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"},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}))]})},[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
|
|
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","rel"]});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"},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;
|
|
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: FlashProps[] };\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\", \"rel\"],\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 >\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 })),\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} removeFlash={removeFlash} />\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","withIcons","iconColor","div","className","data-id","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\", \"rel\"],\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 >\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","withIcons","iconColor","div","className","data-id","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/Footer.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import Icon from"./Icon";import _absUrl from"./url-base.js";import{StatusIcon}from"./Status";const Footer=({paths,urlBase,statusUrl})=>{const absUrl=path=>_absUrl(path,urlBase);return React.createElement("footer",{className:"bg-light-grey font-sans antialiased leading-normal","data-id":"footer"},React.createElement("div",{className:"max-w-screen-xl mx-auto py-32 sm:py-40 md:py-64 ui-grid-gap ui-grid-px grid grid-cols-6"},React.createElement("div",{className:"col-span-full md:col-span-2"},React.createElement("div",{className:"flex flex-row p-menu-row-snug"},React.createElement("img",{className:"mr-24 -mt-16",src:paths.ablyStack,alt:"Ably homepage"}),React.createElement("h2",{className:"ui-text-overline2 col-span-full"},"The Ably Platform")),React.createElement("div",{className:"md:col-span-4 md:w-3/4 xs:w-3/5 w-full"},React.createElement("p",{className:"ui-text-p3 font-bold py-16 p-menu-row-snug"},"Easily power any realtime experience in your application via a simple API that handles everything realtime.")),React.createElement("ul",{className:"grid grid-cols-1"},React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/pubsub"),className:"ui-footer-menu-row-link"},"Pub/sub messaging")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/push-notifications"),className:"ui-footer-menu-row-link"},"Push notifications")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/integrations"),className:"ui-footer-menu-row-link"},"Third-party integrations")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/protocols"),className:"ui-footer-menu-row-link"},"Multiple protocol messaging")))),React.createElement("div",{className:"col-span-full xs:col-span-3 md:col-span-1"},React.createElement("h2",{className:"ui-footer-col-title"},"Ably is for"),React.createElement("ul",null,React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/asset-tracking"),className:"ui-footer-menu-row-link"},"Ably Asset Tracking")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/extend-kafka-to-the-edge"),className:"ui-footer-menu-row-link"},"Extend Kafka to the edge")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/edtech"),className:"ui-footer-menu-row-link"},"EdTech")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/automotive-logistics-and-mobility"),className:"ui-footer-menu-row-link"},"Automotive, Logistics, & Mobility")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/b2b-platforms"),className:"ui-footer-menu-row-link"},"B2B Platforms")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/healthcare"),className:"ui-footer-menu-row-link"},"Healthcare")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/ecommerce-and-retail"),className:"ui-footer-menu-row-link"},"eCommerce & Retail")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/sports-and-media"),className:"ui-footer-menu-row-link"},"Sports & Media")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/gaming"),className:"ui-footer-menu-row-link"},"Gaming")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/iot-and-connected-devices"),className:"ui-footer-menu-row-link"},"IoT & Connected Devices")))),React.createElement("div",{className:"col-span-full xs:col-span-3 md:col-span-1"},React.createElement("h2",{className:"ui-footer-col-title"},"Developers"),React.createElement("ul",null,React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/docs/quick-start-guide"),className:"ui-footer-menu-row-link"},"Start in 5 minutes")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/docs/"),className:"ui-footer-menu-row-link"},"Documentation")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/tutorials"),className:"ui-footer-menu-row-link"},"Tutorials")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:"https://changelog.ably.com/",className:"ui-footer-menu-row-link"},"Changelog")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/support"),className:"ui-footer-menu-row-link"},"Support & FAQs")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/docs/sdks"),className:"ui-footer-menu-row-link"},"SDKs")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{className:"ui-footer-menu-row-link flex items-center gap-4",href:"https://status.ably.com/",target:"_blank",rel:"noreferrer"},"System status",React.createElement(StatusIcon,{statusUrl:statusUrl}))))),React.createElement("div",{className:"col-span-full xs:col-span-3 md:col-span-1"},React.createElement("h2",{className:"ui-footer-col-title"},"WHY ABLY"),React.createElement("ul",null,React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/customers"),className:"ui-footer-menu-row-link"},"Customers")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/case-studies"),className:"ui-footer-menu-row-link"},"Case Studies")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/four-pillars-of-dependability"),className:"ui-footer-menu-row-link"},"Four Pillars of Dependability")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/compare"),className:"ui-footer-menu-row-link"},"Compare our tech")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/protocols"),className:"ui-footer-menu-row-link"},"Multi protocol support")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/integrations"),className:"ui-footer-menu-row-link"},"Third-party integrations")))),React.createElement("div",{className:"col-span-full xs:col-span-3 md:col-span-1"},React.createElement("h2",{className:"ui-footer-col-title"},"ABOUT"),React.createElement("ul",null,React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/about"),className:"ui-footer-menu-row-link"},"About Ably")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/pricing"),className:"ui-footer-menu-row-link"},"Pricing")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/blog"),className:"ui-footer-menu-row-link"},"Blog")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/careers"),className:"ui-footer-menu-row-link"},"Careers")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/open-policy"),className:"ui-footer-menu-row-link"},"Open protocol policy")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/press-center"),className:"ui-footer-menu-row-link"},"Press & Media")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/contact"),className:"ui-footer-menu-row-link"},"Contact us"))))),React.createElement("div",{className:"max-w-screen-xl ui-grid-px mx-auto"},React.createElement("hr",{className:"border-t border-mid-grey my-0"})),React.createElement("div",{className:"max-w-screen-xl mx-auto py-16 grid ui-grid-gap ui-grid-px sm:grid-cols-2"},React.createElement("div",{className:"md:flex md:items-center"},React.createElement("div",{className:"flex flex-col md:flex-row flex-auto ml-8 sm:col-span-1 md:col-span-2"},React.createElement("div",{className:""},React.createElement("div",{className:"flex pb-24"},React.createElement("a",{className:"h-24 pr-24 text-cool-black hover:text-icon-twitter",href:"https://twitter.com/ablyrealtime",title:"Ably on X"},React.createElement(Icon,{name:"icon-social-x",size:"1.5rem"})),React.createElement("a",{className:"h-24 pr-24 text-cool-black hover:text-icon-linkedin",href:"https://www.linkedin.com/company/ably-realtime",title:"Ably on LinkedIn"},React.createElement(Icon,{name:"icon-social-linkedin",size:"1.5rem"})),React.createElement("a",{className:"h-24 pr-24 text-cool-black hover:text-icon-github",href:"https://github.com/ably/",title:"Ably on Github"},React.createElement(Icon,{name:"icon-social-github",size:"1.5rem"})),React.createElement("a",{className:"h-24 pr-24 text-cool-black hover:text-icon-discord",href:"https://discord.gg/jwBPhEZ9g5",title:"Ably on Discord"},React.createElement(Icon,{name:"icon-social-discord",size:"1.5rem"})))),React.createElement("div",{className:"xs:hidden sm:block ui-footer-glassdoor"},React.createElement("div",{className:"flex sm:pt-24 md:pt-0 sm:border-t sm:border-l-0 md:border-t-0 md:border-l sm:border-mid-grey sm:w-3/4 md:w-full md:pl-24"},React.createElement("a",{href:"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm",className:"h-24 text-cool-black hover:text-icon-glassdoor",title:"Ably reviews on glassdoor"},React.createElement(Icon,{name:"icon-social-glassdoor",size:"1.5rem"})),React.createElement("div",{className:"pl-16 text-menu3 font-sans font-medium"},React.createElement("strong",{className:"block font-medium"},"We're hiring!"),React.createElement("a",{href:"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm",className:"ui-footer-link"},"Learn more at Glassdoor"))))),React.createElement("div",{className:"xs:block sm:hidden"},React.createElement("div",{className:"border-t border-mid-grey w-full"}),React.createElement("div",{className:"flex py-24"},React.createElement("a",{className:"h-24 pr-16 text-cool-black hover:text-icon-glassdoor",href:"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm",title:"Ably reviews on glassdoor"},React.createElement(Icon,{name:"icon-social-glassdoor",size:"1.5rem"})),React.createElement("div",{className:"text-menu3 font-sans font-medium"},React.createElement("strong",{className:"block font-medium"},"We're hiring!"),React.createElement("a",{href:"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm",className:"ui-footer-link"},"Learn more at Glassdoor"))))),React.createElement("div",{className:"col-span-full sm:col-span-1 inline-flex sm:ml-auto sm:items-center"},React.createElement("img",{className:"mr-24 h-80",src:paths.highestUserAdoption,alt:"Highest User Adoption 2023"}),React.createElement("img",{className:"mr-24 h-80",src:paths.bestSupport,alt:"Best Support 2023"}),React.createElement("img",{className:"mr-24 h-80",src:paths.fastestImplementation,alt:"Fastest Implementation 2023"}),React.createElement("img",{className:"mr-24 h-80",src:paths.highestPerformer,alt:"High Performer 2023"}))),React.createElement("div",{className:"max-w-screen-xl ui-grid-px mx-auto"},React.createElement("hr",{className:"border-t border-mid-grey my-0"})),React.createElement("div",{className:"max-w-screen-xl mx-auto py-24 sm:py-40 md:py-32 md:grid md:grid-cols-2 ui-grid-gap ui-grid-px"},React.createElement("div",{className:"flex ml-8 col-span-full sm:col-span-1 md:pb-16 items-center ui-footer-bottom-links"},React.createElement("div",{className:"flex"},React.createElement("a",{href:absUrl("/privacy"),className:"pr-24 ui-footer-link"},"Cookies"),React.createElement("a",{href:absUrl("/legals"),className:"pr-24 ui-footer-link"},"Legals"),React.createElement("a",{href:absUrl("/data-protection"),className:"pr-24 ui-footer-link"},"Data Protection"),React.createElement("a",{href:absUrl("/privacy"),className:"ui-footer-link"},"Privacy"))),React.createElement("div",{className:"xs:grid xs:grid-cols-2 sm:grid-cols-4 xs:pl-16 sm:pl-8 md:justify-items-end"},React.createElement("div",{className:"flex mr-24"},React.createElement(Icon,{name:"icon-gui-check-outline",color:"text-active-orange",size:"1.5rem",additionalCSS:"bg-white rounded-full mr-12 ui-footer-tick-icon"}),React.createElement("div",null,React.createElement("p",{className:"ui-footer-compliance-text font-bold whitespace-nowrap"},"SOC 2 Type 2"),React.createElement("p",{className:"ui-footer-compliance-text font-medium mb-24"},"Certified"))),React.createElement("div",{className:"flex mr-24 md:col-start-2"},React.createElement(Icon,{name:"icon-gui-check-outline",color:"text-active-orange",size:"1.5rem",additionalCSS:"bg-white rounded-full mr-12 ui-footer-tick-icon"}),React.createElement("div",null,React.createElement("p",{className:"ui-footer-compliance-text font-bold whitespace-nowrap"},"HIPAA"),React.createElement("p",{className:"ui-footer-compliance-text font-medium mb-24"},"Compliant"))),React.createElement("div",{className:"flex mr-24 md:col-start-3"},React.createElement(Icon,{name:"icon-gui-check-outline",color:"text-active-orange",size:"1.5rem",additionalCSS:"bg-white rounded-full mr-12 ui-footer-tick-icon"}),React.createElement("div",null,React.createElement("p",{className:"ui-footer-compliance-text font-bold whitespace-nowrap"},"EU GDPR"),React.createElement("p",{className:"ui-footer-compliance-text font-medium mb-24"},"Certified"))),React.createElement("div",{className:"flex mr-24 md:col-start-4"},React.createElement(Icon,{name:"icon-gui-check-outline",color:"text-active-orange",size:"1.5rem",additionalCSS:"bg-white rounded-full mr-12 ui-footer-tick-icon"}),React.createElement("div",null,React.createElement("p",{className:"ui-footer-compliance-text font-bold whitespace-nowrap"},"256-bit AES"),React.createElement("p",{className:"ui-footer-compliance-text font-medium mb-24"},"Encryption"))))))};export default Footer;
|
|
1
|
+
import React from"react";import Icon from"./Icon";import _absUrl from"./url-base.js";import{StatusIcon}from"./Status";const Footer=({paths,urlBase,statusUrl})=>{const absUrl=path=>_absUrl(path,urlBase);return React.createElement("footer",{className:"bg-light-grey font-sans antialiased leading-normal","data-id":"footer"},React.createElement("div",{className:"max-w-screen-xl mx-auto py-32 sm:py-40 md:py-64 ui-grid-gap ui-grid-px grid grid-cols-6"},React.createElement("div",{className:"col-span-full md:col-span-2"},React.createElement("div",{className:"flex flex-row p-menu-row-snug"},React.createElement("img",{className:"mr-24 -mt-16",src:paths.ablyStack,alt:"Ably homepage"}),React.createElement("h2",{className:"ui-text-overline2 col-span-full"},"The Ably Platform")),React.createElement("div",{className:"md:col-span-4 md:w-3/4 xs:w-3/5 w-full"},React.createElement("p",{className:"ui-text-p3 font-bold py-16 p-menu-row-snug"},"Easily power any realtime experience in your application via a simple API that handles everything realtime.")),React.createElement("ul",{className:"grid grid-cols-1"},React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/pubsub"),className:"ui-footer-menu-row-link"},"Pub/sub messaging")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/push-notifications"),className:"ui-footer-menu-row-link"},"Push notifications")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/integrations"),className:"ui-footer-menu-row-link"},"Third-party integrations")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/protocols"),className:"ui-footer-menu-row-link"},"Multiple protocol messaging")))),React.createElement("div",{className:"col-span-full xs:col-span-3 md:col-span-1"},React.createElement("h2",{className:"ui-footer-col-title"},"Ably is for"),React.createElement("ul",null,React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/asset-tracking"),className:"ui-footer-menu-row-link"},"Ably Asset Tracking")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/extend-kafka-to-the-edge"),className:"ui-footer-menu-row-link"},"Extend Kafka to the edge")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/edtech"),className:"ui-footer-menu-row-link"},"EdTech")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/automotive-logistics-and-mobility"),className:"ui-footer-menu-row-link"},"Automotive, Logistics, & Mobility")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/b2b-platforms"),className:"ui-footer-menu-row-link"},"B2B Platforms")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/healthcare"),className:"ui-footer-menu-row-link"},"Healthcare")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/ecommerce-and-retail"),className:"ui-footer-menu-row-link"},"eCommerce & Retail")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/sports-and-media"),className:"ui-footer-menu-row-link"},"Sports & Media")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/gaming"),className:"ui-footer-menu-row-link"},"Gaming")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/solutions/iot-and-connected-devices"),className:"ui-footer-menu-row-link"},"IoT & Connected Devices")))),React.createElement("div",{className:"col-span-full xs:col-span-3 md:col-span-1"},React.createElement("h2",{className:"ui-footer-col-title"},"Developers"),React.createElement("ul",null,React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/docs/quick-start-guide"),className:"ui-footer-menu-row-link"},"Start in 5 minutes")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/docs/"),className:"ui-footer-menu-row-link"},"Documentation")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/tutorials"),className:"ui-footer-menu-row-link"},"Tutorials")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:"https://changelog.ably.com/",className:"ui-footer-menu-row-link"},"Changelog")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/support"),className:"ui-footer-menu-row-link"},"Support & FAQs")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/docs/sdks"),className:"ui-footer-menu-row-link"},"SDKs")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{className:"ui-footer-menu-row-link flex items-center gap-4",href:"https://status.ably.com/",target:"_blank",rel:"noreferrer"},"System status",React.createElement(StatusIcon,{statusUrl:statusUrl}))))),React.createElement("div",{className:"col-span-full xs:col-span-3 md:col-span-1"},React.createElement("h2",{className:"ui-footer-col-title"},"WHY ABLY"),React.createElement("ul",null,React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/customers"),className:"ui-footer-menu-row-link"},"Customers")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/case-studies"),className:"ui-footer-menu-row-link"},"Case Studies")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/four-pillars-of-dependability"),className:"ui-footer-menu-row-link"},"Four Pillars of Dependability")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/compare"),className:"ui-footer-menu-row-link"},"Compare our tech")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/protocols"),className:"ui-footer-menu-row-link"},"Multi protocol support")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/integrations"),className:"ui-footer-menu-row-link"},"Third-party integrations")))),React.createElement("div",{className:"col-span-full xs:col-span-3 md:col-span-1"},React.createElement("h2",{className:"ui-footer-col-title"},"ABOUT"),React.createElement("ul",null,React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/about"),className:"ui-footer-menu-row-link"},"About Ably")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/pricing"),className:"ui-footer-menu-row-link"},"Pricing")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/blog"),className:"ui-footer-menu-row-link"},"Blog")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/careers"),className:"ui-footer-menu-row-link"},"Careers")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/open-policy"),className:"ui-footer-menu-row-link"},"Open protocol policy")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/press-center"),className:"ui-footer-menu-row-link"},"Press & Media")),React.createElement("li",{className:"p-menu-row-snug"},React.createElement("a",{href:absUrl("/contact"),className:"ui-footer-menu-row-link"},"Contact us"))))),React.createElement("div",{className:"max-w-screen-xl ui-grid-px mx-auto"},React.createElement("hr",{className:"border-t border-mid-grey my-0"})),React.createElement("div",{className:"max-w-screen-xl mx-auto py-16 grid ui-grid-gap ui-grid-px sm:grid-cols-2"},React.createElement("div",{className:"md:flex md:items-center"},React.createElement("div",{className:"flex flex-col md:flex-row flex-auto ml-8 sm:col-span-1 md:col-span-2"},React.createElement("div",{className:""},React.createElement("div",{className:"flex pb-24"},React.createElement("a",{className:"h-24 pr-24 text-cool-black hover:text-icon-twitter",href:"https://twitter.com/ablyrealtime",title:"Ably on X"},React.createElement(Icon,{name:"icon-social-x",size:"1.5rem"})),React.createElement("a",{className:"h-24 pr-24 text-cool-black hover:text-icon-linkedin",href:"https://www.linkedin.com/company/ably-realtime",title:"Ably on LinkedIn"},React.createElement(Icon,{name:"icon-social-linkedin",size:"1.5rem"})),React.createElement("a",{className:"h-24 pr-24 text-cool-black hover:text-icon-github",href:"https://github.com/ably/",title:"Ably on Github"},React.createElement(Icon,{name:"icon-social-github",size:"1.5rem"})),React.createElement("a",{className:"h-24 pr-24 text-cool-black hover:text-icon-discord",href:"https://discord.gg/jwBPhEZ9g5",title:"Ably on Discord"},React.createElement(Icon,{name:"icon-social-discord",size:"1.5rem"})))),React.createElement("div",{className:"xs:hidden sm:block ui-footer-glassdoor"},React.createElement("div",{className:"flex sm:pt-24 md:pt-0 sm:border-t sm:border-l-0 md:border-t-0 md:border-l sm:border-mid-grey sm:w-3/4 md:w-full md:pl-24"},React.createElement("a",{href:"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm",className:"h-24 text-cool-black hover:text-icon-glassdoor",title:"Ably reviews on glassdoor"},React.createElement(Icon,{name:"icon-social-glassdoor",size:"1.5rem"})),React.createElement("div",{className:"pl-16 text-menu3 font-sans font-medium"},React.createElement("strong",{className:"block font-medium"},"We're hiring!"),React.createElement("a",{href:"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm",className:"ui-footer-link"},"Learn more at Glassdoor"))))),React.createElement("div",{className:"xs:block sm:hidden"},React.createElement("div",{className:"border-t border-mid-grey w-full"}),React.createElement("div",{className:"flex py-24"},React.createElement("a",{className:"h-24 pr-16 text-cool-black hover:text-icon-glassdoor",href:"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm",title:"Ably reviews on glassdoor"},React.createElement(Icon,{name:"icon-social-glassdoor",size:"1.5rem"})),React.createElement("div",{className:"text-menu3 font-sans font-medium"},React.createElement("strong",{className:"block font-medium"},"We're hiring!"),React.createElement("a",{href:"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm",className:"ui-footer-link"},"Learn more at Glassdoor"))))),React.createElement("div",{className:"col-span-full sm:col-span-1 inline-flex sm:ml-auto sm:items-center"},React.createElement("img",{className:"mr-24 h-80",src:paths.bestSupport,alt:"Best Support 2025"}),React.createElement("img",{className:"mr-24 h-80",src:paths.highPerformer,alt:"High Performer 2025"}),React.createElement("img",{className:"mr-24 h-80",src:paths.usersMostLikely,alt:"Users Most Likely To Recommend 2025"}),React.createElement("img",{className:"mr-24 h-80",src:paths.bestMeetsRequirements,alt:"Best Meets Requirements 2025"}))),React.createElement("div",{className:"max-w-screen-xl ui-grid-px mx-auto"},React.createElement("hr",{className:"border-t border-mid-grey my-0"})),React.createElement("div",{className:"max-w-screen-xl mx-auto py-24 sm:py-40 md:py-32 md:grid md:grid-cols-2 ui-grid-gap ui-grid-px"},React.createElement("div",{className:"flex ml-8 col-span-full sm:col-span-1 md:pb-16 items-center ui-footer-bottom-links"},React.createElement("div",{className:"flex"},React.createElement("a",{href:absUrl("/privacy"),className:"pr-24 ui-footer-link"},"Cookies"),React.createElement("a",{href:absUrl("/legals"),className:"pr-24 ui-footer-link"},"Legals"),React.createElement("a",{href:absUrl("/data-protection"),className:"pr-24 ui-footer-link"},"Data Protection"),React.createElement("a",{href:absUrl("/privacy"),className:"ui-footer-link"},"Privacy"))),React.createElement("div",{className:"xs:grid xs:grid-cols-2 sm:grid-cols-4 xs:pl-16 sm:pl-8 md:justify-items-end"},React.createElement("div",{className:"flex mr-24"},React.createElement(Icon,{name:"icon-gui-check-outline",color:"text-active-orange",size:"1.5rem",additionalCSS:"bg-white rounded-full mr-12 ui-footer-tick-icon"}),React.createElement("div",null,React.createElement("p",{className:"ui-footer-compliance-text font-bold whitespace-nowrap"},"SOC 2 Type 2"),React.createElement("p",{className:"ui-footer-compliance-text font-medium mb-24"},"Certified"))),React.createElement("div",{className:"flex mr-24 md:col-start-2"},React.createElement(Icon,{name:"icon-gui-check-outline",color:"text-active-orange",size:"1.5rem",additionalCSS:"bg-white rounded-full mr-12 ui-footer-tick-icon"}),React.createElement("div",null,React.createElement("p",{className:"ui-footer-compliance-text font-bold whitespace-nowrap"},"HIPAA"),React.createElement("p",{className:"ui-footer-compliance-text font-medium mb-24"},"Compliant"))),React.createElement("div",{className:"flex mr-24 md:col-start-3"},React.createElement(Icon,{name:"icon-gui-check-outline",color:"text-active-orange",size:"1.5rem",additionalCSS:"bg-white rounded-full mr-12 ui-footer-tick-icon"}),React.createElement("div",null,React.createElement("p",{className:"ui-footer-compliance-text font-bold whitespace-nowrap"},"EU GDPR"),React.createElement("p",{className:"ui-footer-compliance-text font-medium mb-24"},"Certified"))),React.createElement("div",{className:"flex mr-24 md:col-start-4"},React.createElement(Icon,{name:"icon-gui-check-outline",color:"text-active-orange",size:"1.5rem",additionalCSS:"bg-white rounded-full mr-12 ui-footer-tick-icon"}),React.createElement("div",null,React.createElement("p",{className:"ui-footer-compliance-text font-bold whitespace-nowrap"},"256-bit AES"),React.createElement("p",{className:"ui-footer-compliance-text font-medium mb-24"},"Encryption"))))))};export default Footer;
|
|
2
2
|
//# sourceMappingURL=Footer.js.map
|
package/core/Footer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Footer.tsx"],"sourcesContent":["import React from \"react\";\n\nimport Icon from \"./Icon\";\nimport _absUrl from \"./url-base.js\";\nimport { StatusIcon } from \"./Status\";\n\ntype FooterProps = {\n paths: {\n ablyStack: string;\n highestPerformer: string;\n highestUserAdoption: string;\n bestSupport: string;\n fastestImplementation: string;\n };\n urlBase: string;\n statusUrl: string;\n};\n\nconst Footer = ({ paths, urlBase, statusUrl }: FooterProps) => {\n const absUrl = (path: string) => _absUrl(path, urlBase);\n\n // create a react hook that calls the statusUrl and returns the status of the system every minute\n\n return (\n <footer\n className=\"bg-light-grey font-sans antialiased leading-normal\"\n data-id=\"footer\"\n >\n <div className=\"max-w-screen-xl mx-auto py-32 sm:py-40 md:py-64 ui-grid-gap ui-grid-px grid grid-cols-6\">\n <div className=\"col-span-full md:col-span-2\">\n <div className=\"flex flex-row p-menu-row-snug\">\n <img\n className=\"mr-24 -mt-16\"\n src={paths.ablyStack}\n alt=\"Ably homepage\"\n />\n <h2 className=\"ui-text-overline2 col-span-full\">\n The Ably Platform\n </h2>\n </div>\n <div className=\"md:col-span-4 md:w-3/4 xs:w-3/5 w-full\">\n <p className=\"ui-text-p3 font-bold py-16 p-menu-row-snug\">\n Easily power any realtime experience in your application via a\n simple API that handles everything realtime.\n </p>\n </div>\n\n <ul className=\"grid grid-cols-1\">\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/pubsub\")} className=\"ui-footer-menu-row-link\">\n Pub/sub messaging\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/push-notifications\")}\n className=\"ui-footer-menu-row-link\"\n >\n Push notifications\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/integrations\")}\n className=\"ui-footer-menu-row-link\"\n >\n Third-party integrations\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/protocols\")}\n className=\"ui-footer-menu-row-link\"\n >\n Multiple protocol messaging\n </a>\n </li>\n </ul>\n </div>\n\n <div className=\"col-span-full xs:col-span-3 md:col-span-1\">\n <h2 className=\"ui-footer-col-title\">Ably is for</h2>\n <ul>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/asset-tracking\")}\n className=\"ui-footer-menu-row-link\"\n >\n Ably Asset Tracking\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/extend-kafka-to-the-edge\")}\n className=\"ui-footer-menu-row-link\"\n >\n Extend Kafka to the edge\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/edtech\")}\n className=\"ui-footer-menu-row-link\"\n >\n EdTech\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/automotive-logistics-and-mobility\")}\n className=\"ui-footer-menu-row-link\"\n >\n Automotive, Logistics, & Mobility\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/b2b-platforms\")}\n className=\"ui-footer-menu-row-link\"\n >\n B2B Platforms\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/healthcare\")}\n className=\"ui-footer-menu-row-link\"\n >\n Healthcare\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/ecommerce-and-retail\")}\n className=\"ui-footer-menu-row-link\"\n >\n eCommerce & Retail\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/sports-and-media\")}\n className=\"ui-footer-menu-row-link\"\n >\n Sports & Media\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/gaming\")}\n className=\"ui-footer-menu-row-link\"\n >\n Gaming\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/iot-and-connected-devices\")}\n className=\"ui-footer-menu-row-link\"\n >\n IoT & Connected Devices\n </a>\n </li>\n </ul>\n </div>\n\n <div className=\"col-span-full xs:col-span-3 md:col-span-1\">\n <h2 className=\"ui-footer-col-title\">Developers</h2>\n <ul>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/docs/quick-start-guide\")}\n className=\"ui-footer-menu-row-link\"\n >\n Start in 5 minutes\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/docs/\")} className=\"ui-footer-menu-row-link\">\n Documentation\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/tutorials\")}\n className=\"ui-footer-menu-row-link\"\n >\n Tutorials\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href=\"https://changelog.ably.com/\"\n className=\"ui-footer-menu-row-link\"\n >\n Changelog\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/support\")} className=\"ui-footer-menu-row-link\">\n Support & FAQs\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/docs/sdks\")}\n className=\"ui-footer-menu-row-link\"\n >\n SDKs\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n className=\"ui-footer-menu-row-link flex items-center gap-4\"\n href=\"https://status.ably.com/\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n System status\n <StatusIcon statusUrl={statusUrl} />\n </a>\n </li>\n </ul>\n </div>\n\n <div className=\"col-span-full xs:col-span-3 md:col-span-1\">\n <h2 className=\"ui-footer-col-title\">WHY ABLY</h2>\n <ul>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/customers\")}\n className=\"ui-footer-menu-row-link\"\n >\n Customers\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/case-studies\")}\n className=\"ui-footer-menu-row-link\"\n >\n Case Studies\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/four-pillars-of-dependability\")}\n className=\"ui-footer-menu-row-link\"\n >\n Four Pillars of Dependability\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/compare\")} className=\"ui-footer-menu-row-link\">\n Compare our tech\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/protocols\")}\n className=\"ui-footer-menu-row-link\"\n >\n Multi protocol support\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/integrations\")}\n className=\"ui-footer-menu-row-link\"\n >\n Third-party integrations\n </a>\n </li>\n </ul>\n </div>\n\n <div className=\"col-span-full xs:col-span-3 md:col-span-1\">\n <h2 className=\"ui-footer-col-title\">ABOUT</h2>\n <ul>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/about\")} className=\"ui-footer-menu-row-link\">\n About Ably\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/pricing\")} className=\"ui-footer-menu-row-link\">\n Pricing\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/blog\")} className=\"ui-footer-menu-row-link\">\n Blog\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/careers\")} className=\"ui-footer-menu-row-link\">\n Careers\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/open-policy\")}\n className=\"ui-footer-menu-row-link\"\n >\n Open protocol policy\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/press-center\")}\n className=\"ui-footer-menu-row-link\"\n >\n Press & Media\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/contact\")} className=\"ui-footer-menu-row-link\">\n Contact us\n </a>\n </li>\n </ul>\n </div>\n </div>\n <div className=\"max-w-screen-xl ui-grid-px mx-auto\">\n <hr className=\"border-t border-mid-grey my-0\" />\n </div>\n {/* Twitter + Glassdoor SM & above + Glassdoor XS + Badges*/}\n <div className=\"max-w-screen-xl mx-auto py-16 grid ui-grid-gap ui-grid-px sm:grid-cols-2\">\n <div className=\"md:flex md:items-center\">\n <div className=\"flex flex-col md:flex-row flex-auto ml-8 sm:col-span-1 md:col-span-2\">\n <div className=\"\">\n <div className=\"flex pb-24\">\n <a\n className=\"h-24 pr-24 text-cool-black hover:text-icon-twitter\"\n href=\"https://twitter.com/ablyrealtime\"\n title=\"Ably on X\"\n >\n <Icon name=\"icon-social-x\" size=\"1.5rem\" />\n </a>\n <a\n className=\"h-24 pr-24 text-cool-black hover:text-icon-linkedin\"\n href=\"https://www.linkedin.com/company/ably-realtime\"\n title=\"Ably on LinkedIn\"\n >\n <Icon name=\"icon-social-linkedin\" size=\"1.5rem\" />\n </a>\n <a\n className=\"h-24 pr-24 text-cool-black hover:text-icon-github\"\n href=\"https://github.com/ably/\"\n title=\"Ably on Github\"\n >\n <Icon name=\"icon-social-github\" size=\"1.5rem\" />\n </a>\n <a\n className=\"h-24 pr-24 text-cool-black hover:text-icon-discord\"\n href=\"https://discord.gg/jwBPhEZ9g5\"\n title=\"Ably on Discord\"\n >\n <Icon name=\"icon-social-discord\" size=\"1.5rem\" />\n </a>\n </div>\n </div>\n {/* GLASSDOOR on SM and Above */}\n <div className=\"xs:hidden sm:block ui-footer-glassdoor\">\n <div className=\"flex sm:pt-24 md:pt-0 sm:border-t sm:border-l-0 md:border-t-0 md:border-l sm:border-mid-grey sm:w-3/4 md:w-full md:pl-24\">\n <a\n href=\"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm\"\n className=\"h-24 text-cool-black hover:text-icon-glassdoor\"\n title=\"Ably reviews on glassdoor\"\n >\n <Icon name=\"icon-social-glassdoor\" size=\"1.5rem\" />\n </a>\n <div className=\"pl-16 text-menu3 font-sans font-medium\">\n <strong className=\"block font-medium\">\n We're hiring!\n </strong>\n <a\n href=\"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm\"\n className=\"ui-footer-link\"\n >\n Learn more at Glassdoor\n </a>\n </div>\n </div>\n </div>\n </div>\n {/* GlassDoor on XS ONLY */}\n <div className=\"xs:block sm:hidden\">\n <div className=\"border-t border-mid-grey w-full\"></div>\n <div className=\"flex py-24\">\n <a\n className=\"h-24 pr-16 text-cool-black hover:text-icon-glassdoor\"\n href=\"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm\"\n title=\"Ably reviews on glassdoor\"\n >\n <Icon name=\"icon-social-glassdoor\" size=\"1.5rem\" />\n </a>\n <div className=\"text-menu3 font-sans font-medium\">\n <strong className=\"block font-medium\">\n We're hiring!\n </strong>\n <a\n href=\"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm\"\n className=\"ui-footer-link\"\n >\n Learn more at Glassdoor\n </a>\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"col-span-full sm:col-span-1 inline-flex sm:ml-auto sm:items-center\">\n <img\n className=\"mr-24 h-80\"\n src={paths.highestUserAdoption}\n alt=\"Highest User Adoption 2023\"\n />\n <img\n className=\"mr-24 h-80\"\n src={paths.bestSupport}\n alt=\"Best Support 2023\"\n />\n <img\n className=\"mr-24 h-80\"\n src={paths.fastestImplementation}\n alt=\"Fastest Implementation 2023\"\n />\n <img\n className=\"mr-24 h-80\"\n src={paths.highestPerformer}\n alt=\"High Performer 2023\"\n />\n </div>\n </div>\n\n <div className=\"max-w-screen-xl ui-grid-px mx-auto\">\n <hr className=\"border-t border-mid-grey my-0\" />\n </div>\n <div className=\"max-w-screen-xl mx-auto py-24 sm:py-40 md:py-32 md:grid md:grid-cols-2 ui-grid-gap ui-grid-px\">\n <div className=\"flex ml-8 col-span-full sm:col-span-1 md:pb-16 items-center ui-footer-bottom-links\">\n <div className=\"flex\">\n <a href={absUrl(\"/privacy\")} className=\"pr-24 ui-footer-link\">\n Cookies\n </a>\n <a href={absUrl(\"/legals\")} className=\"pr-24 ui-footer-link\">\n Legals\n </a>\n <a\n href={absUrl(\"/data-protection\")}\n className=\"pr-24 ui-footer-link\"\n >\n Data Protection\n </a>\n <a href={absUrl(\"/privacy\")} className=\"ui-footer-link\">\n Privacy\n </a>\n </div>\n </div>\n <div className=\"xs:grid xs:grid-cols-2 sm:grid-cols-4 xs:pl-16 sm:pl-8 md:justify-items-end\">\n <div className=\"flex mr-24\">\n <Icon\n name=\"icon-gui-check-outline\"\n color=\"text-active-orange\"\n size=\"1.5rem\"\n additionalCSS=\"bg-white rounded-full mr-12 ui-footer-tick-icon\"\n />\n <div>\n <p className=\"ui-footer-compliance-text font-bold whitespace-nowrap\">\n SOC 2 Type 2\n </p>\n <p className=\"ui-footer-compliance-text font-medium mb-24\">\n Certified\n </p>\n </div>\n </div>\n <div className=\"flex mr-24 md:col-start-2\">\n <Icon\n name=\"icon-gui-check-outline\"\n color=\"text-active-orange\"\n size=\"1.5rem\"\n additionalCSS=\"bg-white rounded-full mr-12 ui-footer-tick-icon\"\n />\n <div>\n <p className=\"ui-footer-compliance-text font-bold whitespace-nowrap\">\n HIPAA\n </p>\n <p className=\"ui-footer-compliance-text font-medium mb-24\">\n Compliant\n </p>\n </div>\n </div>\n <div className=\"flex mr-24 md:col-start-3\">\n <Icon\n name=\"icon-gui-check-outline\"\n color=\"text-active-orange\"\n size=\"1.5rem\"\n additionalCSS=\"bg-white rounded-full mr-12 ui-footer-tick-icon\"\n />\n <div>\n <p className=\"ui-footer-compliance-text font-bold whitespace-nowrap\">\n EU GDPR\n </p>\n <p className=\"ui-footer-compliance-text font-medium mb-24\">\n Certified\n </p>\n </div>\n </div>\n <div className=\"flex mr-24 md:col-start-4\">\n <Icon\n name=\"icon-gui-check-outline\"\n color=\"text-active-orange\"\n size=\"1.5rem\"\n additionalCSS=\"bg-white rounded-full mr-12 ui-footer-tick-icon\"\n />\n <div>\n <p className=\"ui-footer-compliance-text font-bold whitespace-nowrap\">\n 256-bit AES\n </p>\n <p className=\"ui-footer-compliance-text font-medium mb-24\">\n Encryption\n </p>\n </div>\n </div>\n </div>\n </div>\n </footer>\n );\n};\n\nexport default Footer;\n"],"names":["React","Icon","_absUrl","StatusIcon","Footer","paths","urlBase","statusUrl","absUrl","path","footer","className","data-id","div","img","src","ablyStack","alt","h2","p","ul","li","a","href","target","rel","hr","title","name","size","strong","highestUserAdoption","bestSupport","fastestImplementation","highestPerformer","color","additionalCSS"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/core/Footer.tsx"],"sourcesContent":["import React from \"react\";\n\nimport Icon from \"./Icon\";\nimport _absUrl from \"./url-base.js\";\nimport { StatusIcon } from \"./Status\";\n\ntype FooterProps = {\n paths: {\n ablyStack: string;\n bestSupport: string;\n highPerformer: string;\n usersMostLikely: string;\n bestMeetsRequirements: string;\n };\n urlBase: string;\n statusUrl: string;\n};\n\nconst Footer = ({ paths, urlBase, statusUrl }: FooterProps) => {\n const absUrl = (path: string) => _absUrl(path, urlBase);\n\n // create a react hook that calls the statusUrl and returns the status of the system every minute\n\n return (\n <footer\n className=\"bg-light-grey font-sans antialiased leading-normal\"\n data-id=\"footer\"\n >\n <div className=\"max-w-screen-xl mx-auto py-32 sm:py-40 md:py-64 ui-grid-gap ui-grid-px grid grid-cols-6\">\n <div className=\"col-span-full md:col-span-2\">\n <div className=\"flex flex-row p-menu-row-snug\">\n <img\n className=\"mr-24 -mt-16\"\n src={paths.ablyStack}\n alt=\"Ably homepage\"\n />\n <h2 className=\"ui-text-overline2 col-span-full\">\n The Ably Platform\n </h2>\n </div>\n <div className=\"md:col-span-4 md:w-3/4 xs:w-3/5 w-full\">\n <p className=\"ui-text-p3 font-bold py-16 p-menu-row-snug\">\n Easily power any realtime experience in your application via a\n simple API that handles everything realtime.\n </p>\n </div>\n\n <ul className=\"grid grid-cols-1\">\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/pubsub\")} className=\"ui-footer-menu-row-link\">\n Pub/sub messaging\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/push-notifications\")}\n className=\"ui-footer-menu-row-link\"\n >\n Push notifications\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/integrations\")}\n className=\"ui-footer-menu-row-link\"\n >\n Third-party integrations\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/protocols\")}\n className=\"ui-footer-menu-row-link\"\n >\n Multiple protocol messaging\n </a>\n </li>\n </ul>\n </div>\n\n <div className=\"col-span-full xs:col-span-3 md:col-span-1\">\n <h2 className=\"ui-footer-col-title\">Ably is for</h2>\n <ul>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/asset-tracking\")}\n className=\"ui-footer-menu-row-link\"\n >\n Ably Asset Tracking\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/extend-kafka-to-the-edge\")}\n className=\"ui-footer-menu-row-link\"\n >\n Extend Kafka to the edge\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/edtech\")}\n className=\"ui-footer-menu-row-link\"\n >\n EdTech\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/automotive-logistics-and-mobility\")}\n className=\"ui-footer-menu-row-link\"\n >\n Automotive, Logistics, & Mobility\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/b2b-platforms\")}\n className=\"ui-footer-menu-row-link\"\n >\n B2B Platforms\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/healthcare\")}\n className=\"ui-footer-menu-row-link\"\n >\n Healthcare\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/ecommerce-and-retail\")}\n className=\"ui-footer-menu-row-link\"\n >\n eCommerce & Retail\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/sports-and-media\")}\n className=\"ui-footer-menu-row-link\"\n >\n Sports & Media\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/gaming\")}\n className=\"ui-footer-menu-row-link\"\n >\n Gaming\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/solutions/iot-and-connected-devices\")}\n className=\"ui-footer-menu-row-link\"\n >\n IoT & Connected Devices\n </a>\n </li>\n </ul>\n </div>\n\n <div className=\"col-span-full xs:col-span-3 md:col-span-1\">\n <h2 className=\"ui-footer-col-title\">Developers</h2>\n <ul>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/docs/quick-start-guide\")}\n className=\"ui-footer-menu-row-link\"\n >\n Start in 5 minutes\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/docs/\")} className=\"ui-footer-menu-row-link\">\n Documentation\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/tutorials\")}\n className=\"ui-footer-menu-row-link\"\n >\n Tutorials\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href=\"https://changelog.ably.com/\"\n className=\"ui-footer-menu-row-link\"\n >\n Changelog\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/support\")} className=\"ui-footer-menu-row-link\">\n Support & FAQs\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/docs/sdks\")}\n className=\"ui-footer-menu-row-link\"\n >\n SDKs\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n className=\"ui-footer-menu-row-link flex items-center gap-4\"\n href=\"https://status.ably.com/\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n System status\n <StatusIcon statusUrl={statusUrl} />\n </a>\n </li>\n </ul>\n </div>\n\n <div className=\"col-span-full xs:col-span-3 md:col-span-1\">\n <h2 className=\"ui-footer-col-title\">WHY ABLY</h2>\n <ul>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/customers\")}\n className=\"ui-footer-menu-row-link\"\n >\n Customers\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/case-studies\")}\n className=\"ui-footer-menu-row-link\"\n >\n Case Studies\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/four-pillars-of-dependability\")}\n className=\"ui-footer-menu-row-link\"\n >\n Four Pillars of Dependability\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/compare\")} className=\"ui-footer-menu-row-link\">\n Compare our tech\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/protocols\")}\n className=\"ui-footer-menu-row-link\"\n >\n Multi protocol support\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/integrations\")}\n className=\"ui-footer-menu-row-link\"\n >\n Third-party integrations\n </a>\n </li>\n </ul>\n </div>\n\n <div className=\"col-span-full xs:col-span-3 md:col-span-1\">\n <h2 className=\"ui-footer-col-title\">ABOUT</h2>\n <ul>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/about\")} className=\"ui-footer-menu-row-link\">\n About Ably\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/pricing\")} className=\"ui-footer-menu-row-link\">\n Pricing\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/blog\")} className=\"ui-footer-menu-row-link\">\n Blog\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/careers\")} className=\"ui-footer-menu-row-link\">\n Careers\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/open-policy\")}\n className=\"ui-footer-menu-row-link\"\n >\n Open protocol policy\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a\n href={absUrl(\"/press-center\")}\n className=\"ui-footer-menu-row-link\"\n >\n Press & Media\n </a>\n </li>\n <li className=\"p-menu-row-snug\">\n <a href={absUrl(\"/contact\")} className=\"ui-footer-menu-row-link\">\n Contact us\n </a>\n </li>\n </ul>\n </div>\n </div>\n <div className=\"max-w-screen-xl ui-grid-px mx-auto\">\n <hr className=\"border-t border-mid-grey my-0\" />\n </div>\n {/* Twitter + Glassdoor SM & above + Glassdoor XS + Badges*/}\n <div className=\"max-w-screen-xl mx-auto py-16 grid ui-grid-gap ui-grid-px sm:grid-cols-2\">\n <div className=\"md:flex md:items-center\">\n <div className=\"flex flex-col md:flex-row flex-auto ml-8 sm:col-span-1 md:col-span-2\">\n <div className=\"\">\n <div className=\"flex pb-24\">\n <a\n className=\"h-24 pr-24 text-cool-black hover:text-icon-twitter\"\n href=\"https://twitter.com/ablyrealtime\"\n title=\"Ably on X\"\n >\n <Icon name=\"icon-social-x\" size=\"1.5rem\" />\n </a>\n <a\n className=\"h-24 pr-24 text-cool-black hover:text-icon-linkedin\"\n href=\"https://www.linkedin.com/company/ably-realtime\"\n title=\"Ably on LinkedIn\"\n >\n <Icon name=\"icon-social-linkedin\" size=\"1.5rem\" />\n </a>\n <a\n className=\"h-24 pr-24 text-cool-black hover:text-icon-github\"\n href=\"https://github.com/ably/\"\n title=\"Ably on Github\"\n >\n <Icon name=\"icon-social-github\" size=\"1.5rem\" />\n </a>\n <a\n className=\"h-24 pr-24 text-cool-black hover:text-icon-discord\"\n href=\"https://discord.gg/jwBPhEZ9g5\"\n title=\"Ably on Discord\"\n >\n <Icon name=\"icon-social-discord\" size=\"1.5rem\" />\n </a>\n </div>\n </div>\n {/* GLASSDOOR on SM and Above */}\n <div className=\"xs:hidden sm:block ui-footer-glassdoor\">\n <div className=\"flex sm:pt-24 md:pt-0 sm:border-t sm:border-l-0 md:border-t-0 md:border-l sm:border-mid-grey sm:w-3/4 md:w-full md:pl-24\">\n <a\n href=\"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm\"\n className=\"h-24 text-cool-black hover:text-icon-glassdoor\"\n title=\"Ably reviews on glassdoor\"\n >\n <Icon name=\"icon-social-glassdoor\" size=\"1.5rem\" />\n </a>\n <div className=\"pl-16 text-menu3 font-sans font-medium\">\n <strong className=\"block font-medium\">\n We're hiring!\n </strong>\n <a\n href=\"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm\"\n className=\"ui-footer-link\"\n >\n Learn more at Glassdoor\n </a>\n </div>\n </div>\n </div>\n </div>\n {/* GlassDoor on XS ONLY */}\n <div className=\"xs:block sm:hidden\">\n <div className=\"border-t border-mid-grey w-full\"></div>\n <div className=\"flex py-24\">\n <a\n className=\"h-24 pr-16 text-cool-black hover:text-icon-glassdoor\"\n href=\"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm\"\n title=\"Ably reviews on glassdoor\"\n >\n <Icon name=\"icon-social-glassdoor\" size=\"1.5rem\" />\n </a>\n <div className=\"text-menu3 font-sans font-medium\">\n <strong className=\"block font-medium\">\n We're hiring!\n </strong>\n <a\n href=\"https://www.glassdoor.co.uk/Overview/Working-at-Ably-EI_IE2184188.11,15.htm\"\n className=\"ui-footer-link\"\n >\n Learn more at Glassdoor\n </a>\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"col-span-full sm:col-span-1 inline-flex sm:ml-auto sm:items-center\">\n <img\n className=\"mr-24 h-80\"\n src={paths.bestSupport}\n alt=\"Best Support 2025\"\n />\n <img\n className=\"mr-24 h-80\"\n src={paths.highPerformer}\n alt=\"High Performer 2025\"\n />\n <img\n className=\"mr-24 h-80\"\n src={paths.usersMostLikely}\n alt=\"Users Most Likely To Recommend 2025\"\n />\n <img\n className=\"mr-24 h-80\"\n src={paths.bestMeetsRequirements}\n alt=\"Best Meets Requirements 2025\"\n />\n </div>\n </div>\n\n <div className=\"max-w-screen-xl ui-grid-px mx-auto\">\n <hr className=\"border-t border-mid-grey my-0\" />\n </div>\n <div className=\"max-w-screen-xl mx-auto py-24 sm:py-40 md:py-32 md:grid md:grid-cols-2 ui-grid-gap ui-grid-px\">\n <div className=\"flex ml-8 col-span-full sm:col-span-1 md:pb-16 items-center ui-footer-bottom-links\">\n <div className=\"flex\">\n <a href={absUrl(\"/privacy\")} className=\"pr-24 ui-footer-link\">\n Cookies\n </a>\n <a href={absUrl(\"/legals\")} className=\"pr-24 ui-footer-link\">\n Legals\n </a>\n <a\n href={absUrl(\"/data-protection\")}\n className=\"pr-24 ui-footer-link\"\n >\n Data Protection\n </a>\n <a href={absUrl(\"/privacy\")} className=\"ui-footer-link\">\n Privacy\n </a>\n </div>\n </div>\n <div className=\"xs:grid xs:grid-cols-2 sm:grid-cols-4 xs:pl-16 sm:pl-8 md:justify-items-end\">\n <div className=\"flex mr-24\">\n <Icon\n name=\"icon-gui-check-outline\"\n color=\"text-active-orange\"\n size=\"1.5rem\"\n additionalCSS=\"bg-white rounded-full mr-12 ui-footer-tick-icon\"\n />\n <div>\n <p className=\"ui-footer-compliance-text font-bold whitespace-nowrap\">\n SOC 2 Type 2\n </p>\n <p className=\"ui-footer-compliance-text font-medium mb-24\">\n Certified\n </p>\n </div>\n </div>\n <div className=\"flex mr-24 md:col-start-2\">\n <Icon\n name=\"icon-gui-check-outline\"\n color=\"text-active-orange\"\n size=\"1.5rem\"\n additionalCSS=\"bg-white rounded-full mr-12 ui-footer-tick-icon\"\n />\n <div>\n <p className=\"ui-footer-compliance-text font-bold whitespace-nowrap\">\n HIPAA\n </p>\n <p className=\"ui-footer-compliance-text font-medium mb-24\">\n Compliant\n </p>\n </div>\n </div>\n <div className=\"flex mr-24 md:col-start-3\">\n <Icon\n name=\"icon-gui-check-outline\"\n color=\"text-active-orange\"\n size=\"1.5rem\"\n additionalCSS=\"bg-white rounded-full mr-12 ui-footer-tick-icon\"\n />\n <div>\n <p className=\"ui-footer-compliance-text font-bold whitespace-nowrap\">\n EU GDPR\n </p>\n <p className=\"ui-footer-compliance-text font-medium mb-24\">\n Certified\n </p>\n </div>\n </div>\n <div className=\"flex mr-24 md:col-start-4\">\n <Icon\n name=\"icon-gui-check-outline\"\n color=\"text-active-orange\"\n size=\"1.5rem\"\n additionalCSS=\"bg-white rounded-full mr-12 ui-footer-tick-icon\"\n />\n <div>\n <p className=\"ui-footer-compliance-text font-bold whitespace-nowrap\">\n 256-bit AES\n </p>\n <p className=\"ui-footer-compliance-text font-medium mb-24\">\n Encryption\n </p>\n </div>\n </div>\n </div>\n </div>\n </footer>\n );\n};\n\nexport default Footer;\n"],"names":["React","Icon","_absUrl","StatusIcon","Footer","paths","urlBase","statusUrl","absUrl","path","footer","className","data-id","div","img","src","ablyStack","alt","h2","p","ul","li","a","href","target","rel","hr","title","name","size","strong","bestSupport","highPerformer","usersMostLikely","bestMeetsRequirements","color","additionalCSS"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from"react";import Icon from"../Icon";import LinkButton from"../LinkButton";import cn from"../utils/cn";const testSessionState={signedIn:false,account:{links:{dashboard:{href:"/dashboard"}}}};export const HeaderLinks=({sessionState=testSessionState,headerLinks,searchButtonVisibility,searchButton,className})=>{const signedIn=sessionState.signedIn;const headerLinkClasses="ui-text-menu2 md:ui-text-menu3 !font-bold py-16 text-neutral-1300 dark:text-neutral-000 md:text-neutral-1000 dark:md:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-1300 dark:active:text-neutral-000 transition-colors";return React.createElement("nav",{className:cn("flex md:flex-1 md:items-center md:justify-end flex-col md:flex-row border-t-[1px] border-neutral-300 md:border-t-0 p-12 md:p-0 gap-12",className)},headerLinks?.map(({href,label,external})=>React.createElement("a",{key:href,className:cn(headerLinkClasses,"flex items-center gap-4 mt-8 md:mt-0"),href:href,target:external?"_blank":undefined,rel:external?"noreferrer noopener":undefined},label,external&&React.createElement(Icon,{name:"icon-gui-arrow-top-right-on-square-outline"}))),searchButtonVisibility!=="mobile"?searchButton:null,signedIn&&sessionState.account?React.createElement(LinkButton,{href:sessionState.account.links?.dashboard.href,variant:"secondary",className:"md:ui-button-secondary-xs","aria-label":"Access your dashboard"},"Dashboard"):React.createElement("div",{className:"flex gap-12"},React.createElement(LinkButton,{href:"/login",variant:"secondary",className:"flex-1 md:flex-none md:ui-button-secondary-xs"},"Login"),React.createElement(LinkButton,{href:"/sign-up",variant:"primary",className:"flex-1 md:flex-none md:ui-button-primary-xs"},"Start free")))};
|
|
2
2
|
//# sourceMappingURL=HeaderLinks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Header/HeaderLinks.tsx"],"sourcesContent":["import React
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Header/HeaderLinks.tsx"],"sourcesContent":["import React from \"react\";\nimport { HeaderProps } from \"../Header\";\nimport Icon from \"../Icon\";\nimport LinkButton from \"../LinkButton\";\nimport cn from \"../utils/cn\";\n\nconst testSessionState = {\n signedIn: false,\n account: {\n links: {\n dashboard: {\n href: \"/dashboard\",\n },\n },\n },\n};\n\nexport const HeaderLinks: React.FC<\n Pick<\n HeaderProps,\n \"sessionState\" | \"headerLinks\" | \"searchButtonVisibility\" | \"searchButton\"\n > & {\n className?: string;\n }\n> = ({\n sessionState = testSessionState,\n headerLinks,\n searchButtonVisibility,\n searchButton,\n className,\n}) => {\n const signedIn = sessionState.signedIn;\n const headerLinkClasses =\n \"ui-text-menu2 md:ui-text-menu3 !font-bold py-16 text-neutral-1300 dark:text-neutral-000 md:text-neutral-1000 dark:md:text-neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-1300 dark:active:text-neutral-000 transition-colors\";\n\n return (\n <nav\n className={cn(\n \"flex md:flex-1 md:items-center md:justify-end flex-col md:flex-row border-t-[1px] border-neutral-300 md:border-t-0 p-12 md:p-0 gap-12\",\n className,\n )}\n >\n {headerLinks?.map(({ href, label, external }) => (\n <a\n key={href}\n className={cn(\n headerLinkClasses,\n \"flex items-center gap-4 mt-8 md:mt-0\",\n )}\n href={href}\n target={external ? \"_blank\" : undefined}\n rel={external ? \"noreferrer noopener\" : undefined}\n >\n {label}\n {external && (\n <Icon name=\"icon-gui-arrow-top-right-on-square-outline\" />\n )}\n </a>\n ))}\n {searchButtonVisibility !== \"mobile\" ? searchButton : null}\n {signedIn && sessionState.account ? (\n <LinkButton\n href={sessionState.account.links?.dashboard.href}\n variant=\"secondary\"\n className=\"md:ui-button-secondary-xs\"\n aria-label=\"Access your dashboard\"\n >\n Dashboard\n </LinkButton>\n ) : (\n <div className=\"flex gap-12\">\n <LinkButton\n href=\"/login\"\n variant=\"secondary\"\n className=\"flex-1 md:flex-none md:ui-button-secondary-xs\"\n >\n Login\n </LinkButton>\n <LinkButton\n href=\"/sign-up\"\n variant=\"primary\"\n className=\"flex-1 md:flex-none md:ui-button-primary-xs\"\n >\n Start free\n </LinkButton>\n </div>\n )}\n </nav>\n );\n};\n"],"names":["React","Icon","LinkButton","cn","testSessionState","signedIn","account","links","dashboard","href","HeaderLinks","sessionState","headerLinks","searchButtonVisibility","searchButton","className","headerLinkClasses","nav","map","label","external","a","key","target","undefined","rel","name","variant","aria-label","div"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAE1B,QAAOC,SAAU,SAAU,AAC3B,QAAOC,eAAgB,eAAgB,AACvC,QAAOC,OAAQ,aAAc,CAE7B,MAAMC,iBAAmB,CACvBC,SAAU,MACVC,QAAS,CACPC,MAAO,CACLC,UAAW,CACTC,KAAM,YACR,CACF,CACF,CACF,CAEA,QAAO,MAAMC,YAOT,CAAC,CACHC,aAAeP,gBAAgB,CAC/BQ,WAAW,CACXC,sBAAsB,CACtBC,YAAY,CACZC,SAAS,CACV,IACC,MAAMV,SAAWM,aAAaN,QAAQ,CACtC,MAAMW,kBACJ,oQAEF,OACE,oBAACC,OACCF,UAAWZ,GACT,wIACAY,YAGDH,aAAaM,IAAI,CAAC,CAAET,IAAI,CAAEU,KAAK,CAAEC,QAAQ,CAAE,GAC1C,oBAACC,KACCC,IAAKb,KACLM,UAAWZ,GACTa,kBACA,wCAEFP,KAAMA,KACNc,OAAQH,SAAW,SAAWI,UAC9BC,IAAKL,SAAW,sBAAwBI,WAEvCL,MACAC,UACC,oBAACnB,MAAKyB,KAAK,iDAIhBb,yBAA2B,SAAWC,aAAe,KACrDT,UAAYM,aAAaL,OAAO,CAC/B,oBAACJ,YACCO,KAAME,aAAaL,OAAO,CAACC,KAAK,EAAEC,UAAUC,KAC5CkB,QAAQ,YACRZ,UAAU,4BACVa,aAAW,yBACZ,aAID,oBAACC,OAAId,UAAU,eACb,oBAACb,YACCO,KAAK,SACLkB,QAAQ,YACRZ,UAAU,iDACX,SAGD,oBAACb,YACCO,KAAK,WACLkB,QAAQ,UACRZ,UAAU,+CACX,eAOX,CAAE"}
|
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";const FLEXIBLE_DESKTOP_CLASSES="hidden md:flex flex-1 items-center h-full";const MAX_MOBILE_MENU_WIDTH="560px";const Header=({searchBar,searchButton,logoHref,headerLinks,nav,mobileNav,sessionState,themedScrollpoints=[],searchButtonVisibility="all"})=>{const[showMenu,setShowMenu]=useState(false);const[fadingOut,setFadingOut]=useState(false);const[scrollpointClasses,setScrollpointClasses]=useState("");const menuRef=useRef(null);const closeMenu=()=>{setFadingOut(true);setTimeout(()=>{setShowMenu(false);setFadingOut(false)},150)};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(()=>{const handleScroll=()=>{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]);const wrappedSearchButton=useMemo(()=>searchButton?React.createElement("div",{className:"text-neutral-1300 dark:text-neutral-000 flex items-center p-6"},searchButton):null,[searchButton]);return React.createElement(React.Fragment,null,React.createElement("header",{role:"banner",className:cn("fixed top-0 left-0 w-full z-10 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300
|
|
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";const FLEXIBLE_DESKTOP_CLASSES="hidden md:flex flex-1 items-center h-full";const MAX_MOBILE_MENU_WIDTH="560px";const Header=({searchBar,searchButton,logoHref,headerLinks,nav,mobileNav,sessionState,themedScrollpoints=[],searchButtonVisibility="all"})=>{const[showMenu,setShowMenu]=useState(false);const[fadingOut,setFadingOut]=useState(false);const[scrollpointClasses,setScrollpointClasses]=useState("");const menuRef=useRef(null);const closeMenu=()=>{setFadingOut(true);setTimeout(()=>{setShowMenu(false);setFadingOut(false)},150)};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(()=>{const handleScroll=()=>{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]);const wrappedSearchButton=useMemo(()=>searchButton?React.createElement("div",{className:"text-neutral-1300 dark:text-neutral-000 flex items-center p-6"},searchButton):null,[searchButton]);return React.createElement(React.Fragment,null,React.createElement("header",{role:"banner",className:cn("fixed top-0 left-0 w-full z-10 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 transition-colors px-24 md:px-64",scrollpointClasses),style:{height:HEADER_HEIGHT}},React.createElement("div",{className:"flex items-center h-full"},React.createElement("nav",{className:"flex flex-1 h-full items-center"},["light","dark"].map(theme=>React.createElement(Logo,{key:theme,href:logoHref,theme:theme,additionalLinkAttrs:{className:cn("h-full focus-base rounded mr-32 w-[108px]",{"flex dark:hidden":theme==="light","hidden dark:flex":theme==="dark"})}})),React.createElement("div",{className:FLEXIBLE_DESKTOP_CLASSES},nav)),React.createElement("div",{className:"flex md:hidden flex-1 items-center justify-end gap-24 h-full"},searchButtonVisibility!=="desktop"?wrappedSearchButton:null,React.createElement("button",{className:"cursor-pointer focus-base rounded flex items-center",onClick:()=>setShowMenu(!showMenu),"aria-expanded":showMenu,"aria-controls":"mobile-menu","aria-label":"Toggle menu"},React.createElement(Icon,{name:showMenu?"icon-gui-x-mark-outline":"icon-gui-bars-3-outline",additionalCSS:"text-neutral-1300 dark:text-neutral-000",size:"1.5rem"}))),searchBar?React.createElement("div",{className:cn(FLEXIBLE_DESKTOP_CLASSES,"justify-center")},searchBar):null,React.createElement(HeaderLinks,{className:FLEXIBLE_DESKTOP_CLASSES,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",{"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]":!fadingOut,"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]":fadingOut}),onClick:closeMenu,onKeyDown:e=>e.key==="Escape"&&closeMenu(),role:"presentation"}),React.createElement("div",{id:"mobile-menu",className:"md:hidden fixed flex flex-col top-[76px] overflow-y-hidden mx-12 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-20",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\";\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 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 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\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 searchBar,\n searchButton,\n logoHref,\n headerLinks,\n nav,\n mobileNav,\n sessionState,\n themedScrollpoints = [],\n searchButtonVisibility = \"all\",\n}) => {\n const [showMenu, setShowMenu] = useState(false);\n const [fadingOut, setFadingOut] = useState(false);\n const [scrollpointClasses, setScrollpointClasses] = useState<string>(\"\");\n const menuRef = useRef<HTMLDivElement>(null);\n\n const closeMenu = () => {\n setFadingOut(true);\n\n setTimeout(() => {\n setShowMenu(false);\n setFadingOut(false);\n }, 150);\n };\n\n useEffect(() => {\n const handleResize = () => {\n if (window.innerWidth >= 1040) {\n setShowMenu(false);\n }\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 useEffect(() => {\n const handleScroll = () => {\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 const wrappedSearchButton = useMemo(\n () =>\n searchButton ? (\n <div className=\"text-neutral-1300 dark:text-neutral-000 flex items-center p-6\">\n {searchButton}\n </div>\n ) : null,\n [searchButton],\n );\n\n return (\n <>\n <header\n role=\"banner\"\n className={cn(\n \"fixed top-0 left-0 w-full z-10 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 dark:border-neutral-1000 transition-colors px-24 md:px-64\",\n scrollpointClasses,\n )}\n style={{ height: HEADER_HEIGHT }}\n >\n <div className=\"flex items-center h-full\">\n <nav className=\"flex flex-1 h-full items-center\">\n {([\"light\", \"dark\"] as Theme[]).map((theme) => (\n <Logo\n key={theme}\n href={logoHref}\n theme={theme}\n additionalLinkAttrs={{\n className: cn(\"h-full focus-base rounded mr-32 w-[108px]\", {\n \"flex dark:hidden\": theme === \"light\",\n \"hidden dark:flex\": theme === \"dark\",\n }),\n }}\n />\n ))}\n <div className={FLEXIBLE_DESKTOP_CLASSES}>{nav}</div>\n </nav>\n <div className=\"flex md:hidden flex-1 items-center justify-end gap-24 h-full\">\n {searchButtonVisibility !== \"desktop\" ? wrappedSearchButton : null}\n <button\n className=\"cursor-pointer focus-base rounded flex items-center\"\n onClick={() => setShowMenu(!showMenu)}\n aria-expanded={showMenu}\n aria-controls=\"mobile-menu\"\n aria-label=\"Toggle menu\"\n >\n <Icon\n name={\n showMenu\n ? \"icon-gui-x-mark-outline\"\n : \"icon-gui-bars-3-outline\"\n }\n additionalCSS=\"text-neutral-1300 dark:text-neutral-000\"\n size=\"1.5rem\"\n />\n </button>\n </div>\n {searchBar ? (\n <div className={cn(FLEXIBLE_DESKTOP_CLASSES, \"justify-center\")}>\n {searchBar}\n </div>\n ) : null}\n <HeaderLinks\n className={FLEXIBLE_DESKTOP_CLASSES}\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\",\n {\n \"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]\":\n !fadingOut,\n \"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]\":\n fadingOut,\n },\n )}\n onClick={closeMenu}\n onKeyDown={(e) => e.key === \"Escape\" && closeMenu()}\n role=\"presentation\"\n />\n <div\n id=\"mobile-menu\"\n className=\"md:hidden fixed flex flex-col top-[76px] overflow-y-hidden mx-12 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-20\"\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","FLEXIBLE_DESKTOP_CLASSES","MAX_MOBILE_MENU_WIDTH","Header","searchBar","searchButton","logoHref","headerLinks","nav","mobileNav","sessionState","themedScrollpoints","searchButtonVisibility","showMenu","setShowMenu","fadingOut","setFadingOut","scrollpointClasses","setScrollpointClasses","menuRef","closeMenu","setTimeout","handleResize","window","innerWidth","addEventListener","removeEventListener","document","body","classList","add","remove","handleScroll","scrollpoint","element","getElementById","id","rect","getBoundingClientRect","top","bottom","className","throttledHandleScroll","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\";\n\nexport type ThemedScrollpoint = {\n id: string;\n className: string;\n};\n\n/**\n * Props for the Header component.\n */\nexport type HeaderProps = {\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 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?: {\n /**\n * Indicates if the user is signed in.\n */\n signedIn: boolean;\n\n /**\n * Account information.\n */\n account: {\n /**\n * Links related to the account.\n */\n links: {\n /**\n * Dashboard link information.\n */\n dashboard: {\n /**\n * URL for the dashboard link.\n */\n href: string;\n };\n };\n };\n };\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\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 searchBar,\n searchButton,\n logoHref,\n headerLinks,\n nav,\n mobileNav,\n sessionState,\n themedScrollpoints = [],\n searchButtonVisibility = \"all\",\n}) => {\n const [showMenu, setShowMenu] = useState(false);\n const [fadingOut, setFadingOut] = useState(false);\n const [scrollpointClasses, setScrollpointClasses] = useState<string>(\"\");\n const menuRef = useRef<HTMLDivElement>(null);\n\n const closeMenu = () => {\n setFadingOut(true);\n\n setTimeout(() => {\n setShowMenu(false);\n setFadingOut(false);\n }, 150);\n };\n\n useEffect(() => {\n const handleResize = () => {\n if (window.innerWidth >= 1040) {\n setShowMenu(false);\n }\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 useEffect(() => {\n const handleScroll = () => {\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 const wrappedSearchButton = useMemo(\n () =>\n searchButton ? (\n <div className=\"text-neutral-1300 dark:text-neutral-000 flex items-center p-6\">\n {searchButton}\n </div>\n ) : null,\n [searchButton],\n );\n\n return (\n <>\n <header\n role=\"banner\"\n className={cn(\n \"fixed top-0 left-0 w-full z-10 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 transition-colors px-24 md:px-64\",\n scrollpointClasses,\n )}\n style={{ height: HEADER_HEIGHT }}\n >\n <div className=\"flex items-center h-full\">\n <nav className=\"flex flex-1 h-full items-center\">\n {([\"light\", \"dark\"] as Theme[]).map((theme) => (\n <Logo\n key={theme}\n href={logoHref}\n theme={theme}\n additionalLinkAttrs={{\n className: cn(\"h-full focus-base rounded mr-32 w-[108px]\", {\n \"flex dark:hidden\": theme === \"light\",\n \"hidden dark:flex\": theme === \"dark\",\n }),\n }}\n />\n ))}\n <div className={FLEXIBLE_DESKTOP_CLASSES}>{nav}</div>\n </nav>\n <div className=\"flex md:hidden flex-1 items-center justify-end gap-24 h-full\">\n {searchButtonVisibility !== \"desktop\" ? wrappedSearchButton : null}\n <button\n className=\"cursor-pointer focus-base rounded flex items-center\"\n onClick={() => setShowMenu(!showMenu)}\n aria-expanded={showMenu}\n aria-controls=\"mobile-menu\"\n aria-label=\"Toggle menu\"\n >\n <Icon\n name={\n showMenu\n ? \"icon-gui-x-mark-outline\"\n : \"icon-gui-bars-3-outline\"\n }\n additionalCSS=\"text-neutral-1300 dark:text-neutral-000\"\n size=\"1.5rem\"\n />\n </button>\n </div>\n {searchBar ? (\n <div className={cn(FLEXIBLE_DESKTOP_CLASSES, \"justify-center\")}>\n {searchBar}\n </div>\n ) : null}\n <HeaderLinks\n className={FLEXIBLE_DESKTOP_CLASSES}\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\",\n {\n \"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]\":\n !fadingOut,\n \"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]\":\n fadingOut,\n },\n )}\n onClick={closeMenu}\n onKeyDown={(e) => e.key === \"Escape\" && closeMenu()}\n role=\"presentation\"\n />\n <div\n id=\"mobile-menu\"\n className=\"md:hidden fixed flex flex-col top-[76px] overflow-y-hidden mx-12 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-20\"\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","FLEXIBLE_DESKTOP_CLASSES","MAX_MOBILE_MENU_WIDTH","Header","searchBar","searchButton","logoHref","headerLinks","nav","mobileNav","sessionState","themedScrollpoints","searchButtonVisibility","showMenu","setShowMenu","fadingOut","setFadingOut","scrollpointClasses","setScrollpointClasses","menuRef","closeMenu","setTimeout","handleResize","window","innerWidth","addEventListener","removeEventListener","document","body","classList","add","remove","handleScroll","scrollpoint","element","getElementById","id","rect","getBoundingClientRect","top","bottom","className","throttledHandleScroll","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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"}
|