@ably/ui 16.0.0-dev.4ca56ef5 → 16.0.0-dev.6a76a414
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/README.md +1 -1
- package/core/.DS_Store +0 -0
- package/core/Accordion/types.js.map +1 -1
- package/core/Accordion.js +1 -1
- package/core/Accordion.js.map +1 -1
- package/core/FeaturedLink.js +1 -1
- package/core/FeaturedLink.js.map +1 -1
- package/core/Flyout.js +1 -1
- package/core/Flyout.js.map +1 -1
- package/core/Footer/data.js +2 -0
- package/core/Footer/data.js.map +1 -0
- 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/LegacyFooter/LegacyFooter.js +2 -0
- package/core/LegacyFooter/LegacyFooter.js.map +1 -0
- package/core/Meganav/.DS_Store +0 -0
- package/core/Meganav/MeganavMobile.js +1 -1
- package/core/Meganav/MeganavMobile.js.map +1 -1
- package/core/Meganav/MeganavPanel.js +1 -1
- package/core/Meganav/MeganavPanel.js.map +1 -1
- package/core/Meganav/data.js +1 -1
- package/core/Meganav/data.js.map +1 -1
- package/core/Meganav/images/fan-engagement-nav-image.png +0 -0
- package/core/Meganav/images/founders-nav-image.png +0 -0
- package/core/Meganav.js +1 -1
- package/core/Meganav.js.map +1 -1
- package/core/Notice.js +1 -1
- package/core/Notice.js.map +1 -1
- package/core/ProductTile/ProductDescription.js +1 -1
- package/core/ProductTile/ProductDescription.js.map +1 -1
- package/core/ProductTile/ProductLabel.js +1 -1
- package/core/ProductTile/ProductLabel.js.map +1 -1
- package/core/ProductTile/data.js +1 -1
- package/core/ProductTile/data.js.map +1 -1
- package/core/SegmentedControl.js +2 -0
- package/core/SegmentedControl.js.map +1 -0
- package/core/insights/command-queue.js +2 -0
- package/core/insights/command-queue.js.map +1 -0
- package/core/insights/datalayer.js +2 -0
- package/core/insights/datalayer.js.map +1 -0
- package/core/insights/index.js +1 -1
- package/core/insights/index.js.map +1 -1
- package/core/insights/index.test.js +2 -0
- package/core/insights/index.test.js.map +1 -0
- package/core/insights/logger.js +2 -0
- package/core/insights/logger.js.map +1 -0
- package/core/insights/mixpanel.js +1 -1
- package/core/insights/mixpanel.js.map +1 -1
- package/core/insights/posthog.js +1 -1
- package/core/insights/posthog.js.map +1 -1
- package/core/insights/service.js +2 -0
- package/core/insights/service.js.map +1 -0
- package/core/insights/types.js.map +1 -1
- package/core/scripts.js +1 -1
- package/core/scripts.js.map +1 -1
- package/core/utils/heights.js +1 -1
- package/core/utils/heights.js.map +1 -1
- package/index.d.ts +98 -38
- package/package.json +10 -6
- package/core/ContactFooter/component.css +0 -11
- package/core/ContactFooter/component.js +0 -2
- package/core/ContactFooter/component.js.map +0 -1
- package/core/ContactFooter.js +0 -2
- package/core/ContactFooter.js.map +0 -1
- package/core/hubspot-chat-toggle.js +0 -2
- package/core/hubspot-chat-toggle.js.map +0 -1
- /package/core/{Footer → LegacyFooter}/component.css +0 -0
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ module.exports = extendConfig((ablyUIConfig) => ({
|
|
|
108
108
|
@import "@ably/ui/reset/styles.css"; /* needed as we disable the default Tailwind reset */
|
|
109
109
|
@import "@ably/ui/core/styles.css"; /* styles for core module components and more */
|
|
110
110
|
@import "@ably/ui/core/Meganav/component.css";
|
|
111
|
-
@import "@ably/ui/core/
|
|
111
|
+
@import "@ably/ui/core/Flash/component.css";
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
#### Importing React components
|
package/core/.DS_Store
CHANGED
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Accordion/types.ts"],"sourcesContent":["import { ReactNode } from \"react\";\nimport { IconName, IconSize } from \"../Icon/types\";\nimport { ColorThemeSet } from \"../styles/colors/types\";\n\n/**\n * Represents the data structure for an Accordion component.\n */\nexport type AccordionData = {\n /**\n * The name of the accordion item.\n */\n name: string;\n\n /**\n * The optional icon name to be displayed alongside the accordion item.\n */\n icon?: IconName;\n\n /**\n * The content to be displayed when the accordion item is expanded.\n */\n content: ReactNode;\n\n /**\n * Optional click handler function that is called when the accordion item is clicked.\n * @param index - The index of the clicked accordion item.\n */\n onClick?: (index: number) => void;\n};\n\nexport type AccordionIcons = {\n closed: {\n name: IconName;\n css?: string;\n };\n open: {\n name: IconName;\n css?: string;\n };\n};\n\nexport const accordionThemes = [\"default\", \"transparent\", \"static\"] as const;\n\nexport type AccordionTheme = (typeof accordionThemes)[number];\n\n/**\n * Represents the theme colors for an accordion component.\n */\nexport type AccordionThemeColors = {\n /**\n * Background color class for the accordion.\n */\n bg: ColorThemeSet;\n\n /**\n * Background color when the accordion item is hovered.\n */\n hoverBg: ColorThemeSet;\n\n /**\n * Text color class for the accordion.\n */\n text: ColorThemeSet;\n\n /**\n * Color class for the toggle icon of the accordion.\n */\n toggleIconColor: ColorThemeSet;\n\n /**\n * Optional background color class for selectable accordion items.\n */\n selectableBg?: ColorThemeSet;\n\n /**\n * Optional text color class for selectable accordion items.\n */\n selectableText?: ColorThemeSet;\n\n /**\n * Optional border color for the accordion.\n */\n border?: string;\n};\n\n/**\n * Options for configuring the Accordion component.\n */\nexport type AccordionOptions = {\n /**\n * If true, only one accordion item can be open at a time.\n * @default false\n */\n autoClose?: boolean;\n\n /**\n * If true, accordion items can be selected.\n * @default false\n */\n selectable?: boolean;\n\n /**\n * If true, the accordion header will stick to the top when scrolling.\n * @default false\n */\n sticky?: boolean;\n\n /**\n * An array of indexes indicating which accordion items should be open by default.\n * @default []\n */\n defaultOpenIndexes?: number[];\n\n /**\n * If true, all accordion items will be fully open.\n * @default false\n */\n fullyOpen?: boolean;\n\n /**\n * Custom CSS class to apply to the accordion header.\n * @default \"\"\n */\n headerCSS?: string;\n\n /**\n * If true, borders between accordion items will be hidden.\n * @default false\n */\n hideBorders?: boolean;\n\n /**\n * Size of the row icon.\n * @default \"32px\"\n */\n rowIconSize?: IconSize;\n\n /**\n * Size of the accordion icon.\n * @default \"16px\"\n */\n iconSize?: IconSize;\n\n /**\n * Custom CSS classes to apply to the selected accordion header.\n * @default \"\"\n */\n selectedHeaderCSS?: string;\n\n /**\n * Custom CSS classes to apply to the accordion content.\n * @default \"\"\n */\n contentCSS?: string;\n};\n"],"names":["accordionThemes"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Accordion/types.ts"],"sourcesContent":["import { ReactNode } from \"react\";\nimport { IconName, IconSize } from \"../Icon/types\";\nimport { ColorThemeSet } from \"../styles/colors/types\";\n\n/**\n * Represents the data structure for an Accordion component.\n */\nexport type AccordionData = {\n /**\n * The name of the accordion item.\n */\n name: string;\n\n /**\n * The optional icon name to be displayed alongside the accordion item.\n */\n icon?: IconName;\n\n /**\n * The content to be displayed when the accordion item is expanded.\n */\n content: ReactNode;\n\n /**\n * Optional click handler function that is called when the accordion item is clicked.\n * @param index - The index of the clicked accordion item.\n */\n onClick?: (index: number) => void;\n\n /**\n * Indicates whether the accordion item is interactive.\n * When false, the item cannot be expanded or collapsed by user interaction.\n * @default true\n */\n interactive?: boolean;\n};\n\nexport type AccordionIcons = {\n closed: {\n name: IconName;\n css?: string;\n };\n open: {\n name: IconName;\n css?: string;\n };\n};\n\nexport const accordionThemes = [\"default\", \"transparent\", \"static\"] as const;\n\nexport type AccordionTheme = (typeof accordionThemes)[number];\n\n/**\n * Represents the theme colors for an accordion component.\n */\nexport type AccordionThemeColors = {\n /**\n * Background color class for the accordion.\n */\n bg: ColorThemeSet;\n\n /**\n * Background color when the accordion item is hovered.\n */\n hoverBg: ColorThemeSet;\n\n /**\n * Text color class for the accordion.\n */\n text: ColorThemeSet;\n\n /**\n * Color class for the toggle icon of the accordion.\n */\n toggleIconColor: ColorThemeSet;\n\n /**\n * Optional background color class for selectable accordion items.\n */\n selectableBg?: ColorThemeSet;\n\n /**\n * Optional text color class for selectable accordion items.\n */\n selectableText?: ColorThemeSet;\n\n /**\n * Optional border color for the accordion.\n */\n border?: string;\n};\n\n/**\n * Options for configuring the Accordion component.\n */\nexport type AccordionOptions = {\n /**\n * If true, only one accordion item can be open at a time.\n * @default false\n */\n autoClose?: boolean;\n\n /**\n * If true, accordion items can be selected.\n * @default false\n */\n selectable?: boolean;\n\n /**\n * If true, the accordion header will stick to the top when scrolling.\n * @default false\n */\n sticky?: boolean;\n\n /**\n * An array of indexes indicating which accordion items should be open by default.\n * @default []\n */\n defaultOpenIndexes?: number[];\n\n /**\n * If true, all accordion items will be fully open.\n * @default false\n */\n fullyOpen?: boolean;\n\n /**\n * Custom CSS class to apply to the accordion header.\n * @default \"\"\n */\n headerCSS?: string;\n\n /**\n * If true, borders between accordion items will be hidden.\n * @default false\n */\n hideBorders?: boolean;\n\n /**\n * Size of the row icon.\n * @default \"32px\"\n */\n rowIconSize?: IconSize;\n\n /**\n * Size of the accordion icon.\n * @default \"16px\"\n */\n iconSize?: IconSize;\n\n /**\n * Custom CSS classes to apply to the selected accordion header.\n * @default \"\"\n */\n selectedHeaderCSS?: string;\n\n /**\n * Custom CSS classes to apply to the accordion content.\n * @default \"\"\n */\n contentCSS?: string;\n};\n"],"names":["accordionThemes"],"mappings":"AAgDA,OAAO,MAAMA,gBAAkB,CAAC,UAAW,cAAe,SAAS,AAAU"}
|
package/core/Accordion.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useMemo,useState,forwardRef}from"react";import{AccordionContent,AccordionItem,AccordionTrigger,Accordion as RadixAccordion}from"@radix-ui/react-accordion";import Icon from"./Icon";import{themeClasses,isNonTransparentTheme,isStaticTheme}from"./Accordion/utils";import cn from"./utils/cn";const AccordionRow=({name,children,rowIcon,options,toggleIcons,theme,index,onClick,openRowValues})=>{const{selectable,sticky}=options||{};const rowKey=`accordion-item-${index}`;const isOpen=openRowValues.includes(rowKey);const{text,bg,hoverBg,selectableBg,selectableText,border,toggleIconColor}=themeClasses[theme];const textClass=selectable&&isOpen&&selectableText||text;return React.createElement(AccordionItem,{value:rowKey,className:cn({[`${border}`]:border&&!options?.hideBorders})},React.createElement(AccordionTrigger,{onClick:onClick,className:cn({"flex w-full group/accordion-trigger py-16 ui-text-p1 font-bold text-left items-center gap-12 transition-colors focus:outline-none":true,"px-16 mb-16 rounded-lg":isNonTransparentTheme(theme),"rounded-none":!isNonTransparentTheme(theme),"pointer-events-none focus-visible:outline-none":isStaticTheme(theme),"focus-base":!isStaticTheme(theme),"sticky top-0":sticky,[`${bg} ${hoverBg} ${text}`]:!(selectable&&isOpen),[`${selectableBg} ${selectableText}`]:selectable&&isOpen,[options?.headerCSS??""]:options?.headerCSS,[options?.selectedHeaderCSS??""]:options?.selectedHeaderCSS&&isOpen})},rowIcon?React.createElement(Icon,{name:rowIcon,color:textClass,size:options?.rowIconSize??"32px"}):null,React.createElement("span",null,name),!selectable&&!isStaticTheme(theme)?React.createElement("span",{className:"flex-1 justify-end flex items-center"},React.createElement(Icon,{name:isOpen?toggleIcons.open.name:toggleIcons.closed.name,color:toggleIconColor,size:options?.iconSize??"16px"})):null),React.createElement(AccordionContent,{className:cn({"ui-text-p2 overflow-hidden transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down":true,[options?.contentCSS??""]:options?.contentCSS})},React.createElement("div",{className:"pb-16"},children)))};const Accordion=forwardRef(({data,theme="transparent",icons={closed:{name:"icon-gui-plus-outline"},open:{name:"icon-gui-minus-outline"}},options,...props},ref)=>{const openIndexes=useMemo(()=>{const indexValues=data.map((_,i)=>`accordion-item-${i}`);return options?.fullyOpen?indexValues:indexValues.filter((_,index)=>options?.defaultOpenIndexes?.includes(index))},[options?.defaultOpenIndexes,options?.fullyOpen,data.length]);const[openRowValues,setOpenRowValues]=useState(openIndexes);const innerAccordion=data.map((item,index)=>React.createElement(AccordionRow,{key:item.name,name:item.name,rowIcon:item.icon,toggleIcons:icons,theme:theme,options:options,index:index,onClick:()=>{item.onClick?.(index)},openRowValues:openRowValues},item.content));return React.createElement("div",{ref:ref,...props},options?.autoClose?React.createElement(RadixAccordion,{type:"single",collapsible:true,defaultValue:openIndexes[0],onValueChange:values=>setOpenRowValues(values)},innerAccordion):React.createElement(RadixAccordion,{type:"multiple",defaultValue:openIndexes,onValueChange:values=>setOpenRowValues(values)},innerAccordion))});Accordion.displayName="Accordion";export default Accordion;
|
|
1
|
+
import React,{useMemo,useState,forwardRef}from"react";import{AccordionContent,AccordionItem,AccordionTrigger,Accordion as RadixAccordion}from"@radix-ui/react-accordion";import Icon from"./Icon";import{themeClasses,isNonTransparentTheme,isStaticTheme}from"./Accordion/utils";import cn from"./utils/cn";const AccordionRow=({name,children,rowIcon,options,toggleIcons,theme,index,onClick,openRowValues,rowInteractive=true})=>{const{selectable,sticky}=options||{};const rowKey=`accordion-item-${index}`;const isOpen=openRowValues.includes(rowKey);const{text,bg,hoverBg,selectableBg,selectableText,border,toggleIconColor}=themeClasses[theme];const textClass=selectable&&isOpen&&selectableText||text;return React.createElement(AccordionItem,{value:rowKey,className:cn({[`${border}`]:border&&!options?.hideBorders})},React.createElement(AccordionTrigger,{onClick:onClick,className:cn({"flex w-full group/accordion-trigger py-16 ui-text-p1 font-bold text-left items-center gap-12 transition-colors focus:outline-none":true,"px-16 mb-16 rounded-lg":isNonTransparentTheme(theme),"px-0 rounded-none":!isNonTransparentTheme(theme),"pointer-events-none focus-visible:outline-none":isStaticTheme(theme),"focus-base":!isStaticTheme(theme),"sticky top-0":sticky,[`${bg} ${hoverBg} ${text}`]:!(selectable&&isOpen),[`${selectableBg} ${selectableText}`]:selectable&&isOpen,[options?.headerCSS??""]:options?.headerCSS,[options?.selectedHeaderCSS??""]:options?.selectedHeaderCSS&&isOpen})},rowIcon?React.createElement(Icon,{name:rowIcon,color:textClass,size:options?.rowIconSize??"32px"}):null,React.createElement("span",null,name),!selectable&&!isStaticTheme(theme)&&rowInteractive?React.createElement("span",{className:"flex-1 justify-end flex items-center"},React.createElement(Icon,{name:isOpen?toggleIcons.open.name:toggleIcons.closed.name,color:toggleIconColor,size:options?.iconSize??"16px"})):null),rowInteractive&&React.createElement(AccordionContent,{className:cn({"ui-text-p2 overflow-hidden transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down":true,[options?.contentCSS??""]:options?.contentCSS})},React.createElement("div",{className:"pb-16"},children)))};const Accordion=forwardRef(({data,theme="transparent",icons={closed:{name:"icon-gui-plus-outline"},open:{name:"icon-gui-minus-outline"}},options,...props},ref)=>{const openIndexes=useMemo(()=>{const indexValues=data.map((_,i)=>`accordion-item-${i}`);return options?.fullyOpen?indexValues:indexValues.filter((_,index)=>options?.defaultOpenIndexes?.includes(index))},[options?.defaultOpenIndexes,options?.fullyOpen,data.length]);const[openRowValues,setOpenRowValues]=useState(openIndexes);const innerAccordion=data.map((item,index)=>React.createElement(AccordionRow,{key:item.name,name:item.name,rowIcon:item.icon,toggleIcons:icons,theme:theme,options:options,index:index,onClick:()=>{item.onClick?.(index)},openRowValues:openRowValues,rowInteractive:item.interactive},item.content));return React.createElement("div",{ref:ref,...props},options?.autoClose?React.createElement(RadixAccordion,{type:"single",collapsible:true,defaultValue:openIndexes[0],onValueChange:values=>setOpenRowValues(values)},innerAccordion):React.createElement(RadixAccordion,{type:"multiple",defaultValue:openIndexes,onValueChange:values=>setOpenRowValues(values)},innerAccordion))});Accordion.displayName="Accordion";export default Accordion;
|
|
2
2
|
//# sourceMappingURL=Accordion.js.map
|
package/core/Accordion.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Accordion.tsx"],"sourcesContent":["import React, { ReactNode, useMemo, useState, forwardRef } from \"react\";\nimport {\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n Accordion as RadixAccordion,\n} from \"@radix-ui/react-accordion\";\n\nimport Icon from \"./Icon\";\nimport type { IconName } from \"./Icon/types\";\nimport type {\n AccordionData,\n AccordionIcons,\n AccordionOptions,\n AccordionTheme,\n} from \"./Accordion/types\";\nimport {\n themeClasses,\n isNonTransparentTheme,\n isStaticTheme,\n} from \"./Accordion/utils\";\nimport cn from \"./utils/cn\";\n\ntype AccordionRowProps = {\n children: ReactNode;\n name: string;\n rowIcon?: IconName;\n theme: AccordionTheme;\n toggleIcons: AccordionIcons;\n options?: AccordionOptions;\n index: number;\n onClick: () => void;\n openRowValues: string | string[];\n};\n\nexport type AccordionProps = {\n /**\n * The data for the accordion items.\n */\n data: AccordionData[];\n\n /**\n * Icons for the accordion toggle.\n */\n icons?: AccordionIcons;\n\n /**\n * Theme for the accordion.\n */\n theme?: AccordionTheme;\n\n /**\n * Options for the accordion behavior.\n */\n options?: AccordionOptions;\n} & React.HTMLAttributes<HTMLDivElement>;\n\nconst AccordionRow = ({\n name,\n children,\n rowIcon,\n options,\n toggleIcons,\n theme,\n index,\n onClick,\n openRowValues,\n}: AccordionRowProps) => {\n const { selectable, sticky } = options || {};\n const rowKey = `accordion-item-${index}`;\n const isOpen = openRowValues.includes(rowKey);\n\n const {\n text,\n bg,\n hoverBg,\n selectableBg,\n selectableText,\n border,\n toggleIconColor,\n } = themeClasses[theme];\n\n const textClass = (selectable && isOpen && selectableText) || text;\n\n return (\n <AccordionItem\n value={rowKey}\n className={cn({\n [`${border}`]: border && !options?.hideBorders,\n })}\n >\n <AccordionTrigger\n onClick={onClick}\n className={cn({\n \"flex w-full group/accordion-trigger py-16 ui-text-p1 font-bold text-left items-center gap-12 transition-colors focus:outline-none\":\n true,\n \"px-16 mb-16 rounded-lg\": isNonTransparentTheme(theme),\n \"rounded-none\": !isNonTransparentTheme(theme),\n \"pointer-events-none focus-visible:outline-none\":\n isStaticTheme(theme),\n \"focus-base\": !isStaticTheme(theme),\n \"sticky top-0\": sticky,\n [`${bg} ${hoverBg} ${text}`]: !(selectable && isOpen),\n [`${selectableBg} ${selectableText}`]: selectable && isOpen,\n [options?.headerCSS ?? \"\"]: options?.headerCSS,\n [options?.selectedHeaderCSS ?? \"\"]:\n options?.selectedHeaderCSS && isOpen,\n })}\n >\n {rowIcon ? (\n <Icon\n name={rowIcon}\n color={textClass}\n size={options?.rowIconSize ?? \"32px\"}\n />\n ) : null}\n <span>{name}</span>\n {!selectable && !isStaticTheme(theme) ? (\n <span className=\"flex-1 justify-end flex items-center\">\n <Icon\n name={isOpen ? toggleIcons.open.name : toggleIcons.closed.name}\n color={toggleIconColor}\n size={options?.iconSize ?? \"16px\"}\n />\n </span>\n ) : null}\n </AccordionTrigger>\n <AccordionContent\n
|
|
1
|
+
{"version":3,"sources":["../../src/core/Accordion.tsx"],"sourcesContent":["import React, { ReactNode, useMemo, useState, forwardRef } from \"react\";\nimport {\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n Accordion as RadixAccordion,\n} from \"@radix-ui/react-accordion\";\n\nimport Icon from \"./Icon\";\nimport type { IconName } from \"./Icon/types\";\nimport type {\n AccordionData,\n AccordionIcons,\n AccordionOptions,\n AccordionTheme,\n} from \"./Accordion/types\";\nimport {\n themeClasses,\n isNonTransparentTheme,\n isStaticTheme,\n} from \"./Accordion/utils\";\nimport cn from \"./utils/cn\";\n\ntype AccordionRowProps = {\n children: ReactNode;\n name: string;\n rowIcon?: IconName;\n theme: AccordionTheme;\n toggleIcons: AccordionIcons;\n options?: AccordionOptions;\n index: number;\n onClick: () => void;\n openRowValues: string | string[];\n rowInteractive?: boolean;\n};\n\nexport type AccordionProps = {\n /**\n * The data for the accordion items.\n */\n data: AccordionData[];\n\n /**\n * Icons for the accordion toggle.\n */\n icons?: AccordionIcons;\n\n /**\n * Theme for the accordion.\n */\n theme?: AccordionTheme;\n\n /**\n * Options for the accordion behavior.\n */\n options?: AccordionOptions;\n} & React.HTMLAttributes<HTMLDivElement>;\n\nconst AccordionRow = ({\n name,\n children,\n rowIcon,\n options,\n toggleIcons,\n theme,\n index,\n onClick,\n openRowValues,\n rowInteractive = true,\n}: AccordionRowProps) => {\n const { selectable, sticky } = options || {};\n const rowKey = `accordion-item-${index}`;\n const isOpen = openRowValues.includes(rowKey);\n\n const {\n text,\n bg,\n hoverBg,\n selectableBg,\n selectableText,\n border,\n toggleIconColor,\n } = themeClasses[theme];\n\n const textClass = (selectable && isOpen && selectableText) || text;\n\n return (\n <AccordionItem\n value={rowKey}\n className={cn({\n [`${border}`]: border && !options?.hideBorders,\n })}\n >\n <AccordionTrigger\n onClick={onClick}\n className={cn({\n \"flex w-full group/accordion-trigger py-16 ui-text-p1 font-bold text-left items-center gap-12 transition-colors focus:outline-none\":\n true,\n \"px-16 mb-16 rounded-lg\": isNonTransparentTheme(theme),\n \"px-0 rounded-none\": !isNonTransparentTheme(theme),\n \"pointer-events-none focus-visible:outline-none\":\n isStaticTheme(theme),\n \"focus-base\": !isStaticTheme(theme),\n \"sticky top-0\": sticky,\n [`${bg} ${hoverBg} ${text}`]: !(selectable && isOpen),\n [`${selectableBg} ${selectableText}`]: selectable && isOpen,\n [options?.headerCSS ?? \"\"]: options?.headerCSS,\n [options?.selectedHeaderCSS ?? \"\"]:\n options?.selectedHeaderCSS && isOpen,\n })}\n >\n {rowIcon ? (\n <Icon\n name={rowIcon}\n color={textClass}\n size={options?.rowIconSize ?? \"32px\"}\n />\n ) : null}\n <span>{name}</span>\n {!selectable && !isStaticTheme(theme) && rowInteractive ? (\n <span className=\"flex-1 justify-end flex items-center\">\n <Icon\n name={isOpen ? toggleIcons.open.name : toggleIcons.closed.name}\n color={toggleIconColor}\n size={options?.iconSize ?? \"16px\"}\n />\n </span>\n ) : null}\n </AccordionTrigger>\n {rowInteractive && (\n <AccordionContent\n className={cn({\n \"ui-text-p2 overflow-hidden transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\":\n true,\n [options?.contentCSS ?? \"\"]: options?.contentCSS,\n })}\n >\n <div className=\"pb-16\">{children}</div>\n </AccordionContent>\n )}\n </AccordionItem>\n );\n};\n\nconst Accordion = forwardRef<HTMLDivElement, AccordionProps>(\n (\n {\n data,\n theme = \"transparent\",\n icons = {\n closed: { name: \"icon-gui-plus-outline\" },\n open: { name: \"icon-gui-minus-outline\" },\n },\n options,\n ...props\n },\n ref,\n ) => {\n const openIndexes = useMemo(() => {\n const indexValues = data.map((_, i) => `accordion-item-${i}`);\n return options?.fullyOpen\n ? indexValues\n : indexValues.filter((_, index) =>\n options?.defaultOpenIndexes?.includes(index),\n );\n }, [options?.defaultOpenIndexes, options?.fullyOpen, data.length]);\n\n const [openRowValues, setOpenRowValues] = useState<string | string[]>(\n openIndexes,\n );\n const innerAccordion = data.map((item, index) => (\n <AccordionRow\n key={item.name}\n name={item.name}\n rowIcon={item.icon}\n toggleIcons={icons}\n theme={theme}\n options={options}\n index={index}\n onClick={() => {\n item.onClick?.(index);\n }}\n openRowValues={openRowValues}\n rowInteractive={item.interactive}\n >\n {item.content}\n </AccordionRow>\n ));\n\n return (\n <div ref={ref} {...props}>\n {options?.autoClose ? (\n <RadixAccordion\n type=\"single\"\n collapsible\n defaultValue={openIndexes[0]}\n onValueChange={(values) => setOpenRowValues(values)}\n >\n {innerAccordion}\n </RadixAccordion>\n ) : (\n <RadixAccordion\n type=\"multiple\"\n defaultValue={openIndexes}\n onValueChange={(values) => setOpenRowValues(values)}\n >\n {innerAccordion}\n </RadixAccordion>\n )}\n </div>\n );\n },\n);\n\nAccordion.displayName = \"Accordion\";\n\nexport default Accordion;\n"],"names":["React","useMemo","useState","forwardRef","AccordionContent","AccordionItem","AccordionTrigger","Accordion","RadixAccordion","Icon","themeClasses","isNonTransparentTheme","isStaticTheme","cn","AccordionRow","name","children","rowIcon","options","toggleIcons","theme","index","onClick","openRowValues","rowInteractive","selectable","sticky","rowKey","isOpen","includes","text","bg","hoverBg","selectableBg","selectableText","border","toggleIconColor","textClass","value","className","hideBorders","headerCSS","selectedHeaderCSS","color","size","rowIconSize","span","open","closed","iconSize","contentCSS","div","data","icons","props","ref","openIndexes","indexValues","map","_","i","fullyOpen","filter","defaultOpenIndexes","length","setOpenRowValues","innerAccordion","item","key","icon","interactive","content","autoClose","type","collapsible","defaultValue","onValueChange","values","displayName"],"mappings":"AAAA,OAAOA,OAAoBC,OAAO,CAAEC,QAAQ,CAAEC,UAAU,KAAQ,OAAQ,AACxE,QACEC,gBAAgB,CAChBC,aAAa,CACbC,gBAAgB,CAChBC,aAAaC,cAAc,KACtB,2BAA4B,AAEnC,QAAOC,SAAU,QAAS,AAQ1B,QACEC,YAAY,CACZC,qBAAqB,CACrBC,aAAa,KACR,mBAAoB,AAC3B,QAAOC,OAAQ,YAAa,CAqC5B,MAAMC,aAAe,CAAC,CACpBC,IAAI,CACJC,QAAQ,CACRC,OAAO,CACPC,OAAO,CACPC,WAAW,CACXC,KAAK,CACLC,KAAK,CACLC,OAAO,CACPC,aAAa,CACbC,eAAiB,IAAI,CACH,IAClB,KAAM,CAAEC,UAAU,CAAEC,MAAM,CAAE,CAAGR,SAAW,CAAC,EAC3C,MAAMS,OAAS,CAAC,eAAe,EAAEN,MAAM,CAAC,CACxC,MAAMO,OAASL,cAAcM,QAAQ,CAACF,QAEtC,KAAM,CACJG,IAAI,CACJC,EAAE,CACFC,OAAO,CACPC,YAAY,CACZC,cAAc,CACdC,MAAM,CACNC,eAAe,CAChB,CAAG1B,YAAY,CAACU,MAAM,CAEvB,MAAMiB,UAAY,AAACZ,YAAcG,QAAUM,gBAAmBJ,KAE9D,OACE,oBAACzB,eACCiC,MAAOX,OACPY,UAAW1B,GAAG,CACZ,CAAC,CAAC,EAAEsB,OAAO,CAAC,CAAC,CAAEA,QAAU,CAACjB,SAASsB,WACrC,IAEA,oBAAClC,kBACCgB,QAASA,QACTiB,UAAW1B,GAAG,CACZ,oIACE,KACF,yBAA0BF,sBAAsBS,OAChD,oBAAqB,CAACT,sBAAsBS,OAC5C,iDACER,cAAcQ,OAChB,aAAc,CAACR,cAAcQ,OAC7B,eAAgBM,OAChB,CAAC,CAAC,EAAEK,GAAG,CAAC,EAAEC,QAAQ,CAAC,EAAEF,KAAK,CAAC,CAAC,CAAE,CAAEL,CAAAA,YAAcG,MAAK,EACnD,CAAC,CAAC,EAAEK,aAAa,CAAC,EAAEC,eAAe,CAAC,CAAC,CAAET,YAAcG,OACrD,CAACV,SAASuB,WAAa,GAAG,CAAEvB,SAASuB,UACrC,CAACvB,SAASwB,mBAAqB,GAAG,CAChCxB,SAASwB,mBAAqBd,MAClC,IAECX,QACC,oBAACR,MACCM,KAAME,QACN0B,MAAON,UACPO,KAAM1B,SAAS2B,aAAe,SAE9B,KACJ,oBAACC,YAAM/B,MACN,CAACU,YAAc,CAACb,cAAcQ,QAAUI,eACvC,oBAACsB,QAAKP,UAAU,wCACd,oBAAC9B,MACCM,KAAMa,OAAST,YAAY4B,IAAI,CAAChC,IAAI,CAAGI,YAAY6B,MAAM,CAACjC,IAAI,CAC9D4B,MAAOP,gBACPQ,KAAM1B,SAAS+B,UAAY,UAG7B,MAELzB,gBACC,oBAACpB,kBACCmC,UAAW1B,GAAG,CACZ,8HACE,KACF,CAACK,SAASgC,YAAc,GAAG,CAAEhC,SAASgC,UACxC,IAEA,oBAACC,OAAIZ,UAAU,SAASvB,WAKlC,EAEA,MAAMT,UAAYJ,WAChB,CACE,CACEiD,IAAI,CACJhC,MAAQ,aAAa,CACrBiC,MAAQ,CACNL,OAAQ,CAAEjC,KAAM,uBAAwB,EACxCgC,KAAM,CAAEhC,KAAM,wBAAyB,CACzC,CAAC,CACDG,OAAO,CACP,GAAGoC,MACJ,CACDC,OAEA,MAAMC,YAAcvD,QAAQ,KAC1B,MAAMwD,YAAcL,KAAKM,GAAG,CAAC,CAACC,EAAGC,IAAM,CAAC,eAAe,EAAEA,EAAE,CAAC,EAC5D,OAAO1C,SAAS2C,UACZJ,YACAA,YAAYK,MAAM,CAAC,CAACH,EAAGtC,QACrBH,SAAS6C,oBAAoBlC,SAASR,OAE9C,EAAG,CAACH,SAAS6C,mBAAoB7C,SAAS2C,UAAWT,KAAKY,MAAM,CAAC,EAEjE,KAAM,CAACzC,cAAe0C,iBAAiB,CAAG/D,SACxCsD,aAEF,MAAMU,eAAiBd,KAAKM,GAAG,CAAC,CAACS,KAAM9C,QACrC,oBAACP,cACCsD,IAAKD,KAAKpD,IAAI,CACdA,KAAMoD,KAAKpD,IAAI,CACfE,QAASkD,KAAKE,IAAI,CAClBlD,YAAakC,MACbjC,MAAOA,MACPF,QAASA,QACTG,MAAOA,MACPC,QAAS,KACP6C,KAAK7C,OAAO,GAAGD,MACjB,EACAE,cAAeA,cACfC,eAAgB2C,KAAKG,WAAW,EAE/BH,KAAKI,OAAO,GAIjB,OACE,oBAACpB,OAAII,IAAKA,IAAM,GAAGD,KAAK,EACrBpC,SAASsD,UACR,oBAAChE,gBACCiE,KAAK,SACLC,YAAAA,KACAC,aAAcnB,WAAW,CAAC,EAAE,CAC5BoB,cAAe,AAACC,QAAWZ,iBAAiBY,SAE3CX,gBAGH,oBAAC1D,gBACCiE,KAAK,WACLE,aAAcnB,YACdoB,cAAe,AAACC,QAAWZ,iBAAiBY,SAE3CX,gBAKX,EAGF3D,CAAAA,UAAUuE,WAAW,CAAG,WAExB,gBAAevE,SAAU"}
|
package/core/FeaturedLink.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React from"react";import Icon from"./Icon";import cn from"./utils/cn";const buildTargetAndRel=(url,newWindow)=>{const props={};if(newWindow){props.target="_blank";if(url.startsWith("/")&&!url.startsWith("//")){props.rel="noopener"}else{props.rel="noopenner noreferrer"}}return props};const FeaturedLink=({url,textSize="text-p2",iconColor,flush=false,reverse=false,additionalCSS="",newWindow=false,onClick=undefined,children,disabled=false})=>{const targetAndRel=buildTargetAndRel(url,newWindow);return React.createElement("a",{...onClick?{}:{href:url},className:cn("font-sans font-bold block group/featured-link",{"text-gui-unavailable pointer-events-none":disabled},{"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus":!disabled},{"py-8":!flush},`ui-${textSize}`,additionalCSS),style:{"--featured-link-icon-size":`var(${textSize.replace("text","--fs")})`},...targetAndRel,onClick:onClick},reverse?React.createElement(React.Fragment,null,React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:`calc(var(--featured-link-icon-size) * 1.25)`,color:iconColor,additionalCSS:cn("align-middle mr-8 relative -top-1 -right-4 transition-[right] transform rotate-180",{"group-hover/featured-link:right-0":!disabled})}),children):React.createElement(React.Fragment,null,children,React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:`calc(var(--featured-link-icon-size) * 1.25)`,color:iconColor,additionalCSS:cn("align-middle ml-8 relative -top-1 -left-4 transition-[left]",{"group-hover/featured-link:left-0":!disabled})})))};export default FeaturedLink;
|
|
1
|
+
import React from"react";import Icon from"./Icon";import cn from"./utils/cn";const buildTargetAndRel=(url,newWindow)=>{const props={};if(newWindow){props.target="_blank";if(url.startsWith("/")&&!url.startsWith("//")){props.rel="noopener"}else{props.rel="noopenner noreferrer"}}return props};const FeaturedLink=({url,textSize="text-p2",iconColor,flush=false,reverse=false,additionalCSS="",newWindow=false,onClick=undefined,children,disabled=false,iconClassName=""})=>{const targetAndRel=buildTargetAndRel(url,newWindow);return React.createElement("a",{...onClick?{}:{href:url},className:cn("font-sans font-bold block group/featured-link",{"text-gui-unavailable pointer-events-none":disabled},{"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus":!disabled},{"py-8":!flush},`ui-${textSize}`,additionalCSS),style:{"--featured-link-icon-size":`var(${textSize.replace("text","--fs")})`},...targetAndRel,onClick:onClick},reverse?React.createElement(React.Fragment,null,React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:`calc(var(--featured-link-icon-size) * 1.25)`,color:iconColor,additionalCSS:cn("align-middle mr-8 relative -top-1 -right-4 transition-[right] transform rotate-180",{"group-hover/featured-link:right-0":!disabled},iconClassName)}),children):React.createElement(React.Fragment,null,children,React.createElement(Icon,{name:"icon-gui-arrow-long-right-outline",size:`calc(var(--featured-link-icon-size) * 1.25)`,color:iconColor,additionalCSS:cn("align-middle ml-8 relative -top-1 -left-4 transition-[left]",{"group-hover/featured-link:left-0":!disabled},iconClassName)})))};export default FeaturedLink;
|
|
2
2
|
//# sourceMappingURL=FeaturedLink.js.map
|
package/core/FeaturedLink.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/FeaturedLink.tsx"],"sourcesContent":["import React, { CSSProperties, ReactNode } from \"react\";\n\nimport Icon from \"./Icon\";\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport cn from \"./utils/cn\";\n\ntype FeaturedLinkProps = {\n url: string;\n children: ReactNode;\n textSize?: string;\n iconColor?: ColorClass | ColorThemeSet;\n flush?: boolean;\n reverse?: boolean;\n additionalCSS?: string;\n newWindow?: boolean;\n onClick?: () => void;\n disabled?: boolean;\n};\n\ntype TargetProps = { target?: string; rel?: string };\n\n// When generating links with target=_blank, we only add `noreferrer` to\n// links that don't start with `/`, so we can continue tracking referrers\n// across our own domains\nconst buildTargetAndRel = (url: string, newWindow: boolean) => {\n const props: TargetProps = {};\n\n if (newWindow) {\n props.target = \"_blank\";\n\n if (url.startsWith(\"/\") && !url.startsWith(\"//\")) {\n props.rel = \"noopener\";\n } else {\n props.rel = \"noopenner noreferrer\";\n }\n }\n\n return props;\n};\n\nconst FeaturedLink = ({\n url,\n textSize = \"text-p2\",\n iconColor,\n flush = false,\n reverse = false,\n additionalCSS = \"\",\n newWindow = false,\n onClick = undefined,\n children,\n disabled = false,\n}: FeaturedLinkProps) => {\n const targetAndRel = buildTargetAndRel(url, newWindow);\n\n return (\n <a\n {...(onClick ? {} : { href: url })}\n className={cn(\n \"font-sans font-bold block group/featured-link\",\n { \"text-gui-unavailable pointer-events-none\": disabled },\n {\n \"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus\":\n !disabled,\n },\n { \"py-8\": !flush },\n `ui-${textSize}`,\n additionalCSS,\n )}\n style={\n {\n \"--featured-link-icon-size\": `var(${textSize.replace(\n \"text\",\n \"--fs\",\n )})`,\n } as CSSProperties\n }\n {...targetAndRel}\n onClick={onClick}\n >\n {reverse ? (\n <>\n <Icon\n name=\"icon-gui-arrow-long-right-outline\"\n size={`calc(var(--featured-link-icon-size) * 1.25)`}\n color={iconColor}\n additionalCSS={cn(\n \"align-middle mr-8 relative -top-1 -right-4 transition-[right] transform rotate-180\",\n { \"group-hover/featured-link:right-0\": !disabled },\n )}\n />\n {children}\n </>\n ) : (\n <>\n {children}\n <Icon\n name=\"icon-gui-arrow-long-right-outline\"\n size={`calc(var(--featured-link-icon-size) * 1.25)`}\n color={iconColor}\n additionalCSS={cn(\n \"align-middle ml-8 relative -top-1 -left-4 transition-[left]\",\n {
|
|
1
|
+
{"version":3,"sources":["../../src/core/FeaturedLink.tsx"],"sourcesContent":["import React, { CSSProperties, ReactNode } from \"react\";\n\nimport Icon from \"./Icon\";\nimport { ColorClass, ColorThemeSet } from \"./styles/colors/types\";\nimport cn from \"./utils/cn\";\n\ntype FeaturedLinkProps = {\n url: string;\n children: ReactNode;\n textSize?: string;\n iconColor?: ColorClass | ColorThemeSet;\n flush?: boolean;\n reverse?: boolean;\n additionalCSS?: string;\n newWindow?: boolean;\n onClick?: () => void;\n disabled?: boolean;\n /**\n * Optional class name for the icon.\n */\n iconClassName?: string;\n};\n\ntype TargetProps = { target?: string; rel?: string };\n\n// When generating links with target=_blank, we only add `noreferrer` to\n// links that don't start with `/`, so we can continue tracking referrers\n// across our own domains\nconst buildTargetAndRel = (url: string, newWindow: boolean) => {\n const props: TargetProps = {};\n\n if (newWindow) {\n props.target = \"_blank\";\n\n if (url.startsWith(\"/\") && !url.startsWith(\"//\")) {\n props.rel = \"noopener\";\n } else {\n props.rel = \"noopenner noreferrer\";\n }\n }\n\n return props;\n};\n\nconst FeaturedLink = ({\n url,\n textSize = \"text-p2\",\n iconColor,\n flush = false,\n reverse = false,\n additionalCSS = \"\",\n newWindow = false,\n onClick = undefined,\n children,\n disabled = false,\n iconClassName = \"\",\n}: FeaturedLinkProps) => {\n const targetAndRel = buildTargetAndRel(url, newWindow);\n\n return (\n <a\n {...(onClick ? {} : { href: url })}\n className={cn(\n \"font-sans font-bold block group/featured-link\",\n { \"text-gui-unavailable pointer-events-none\": disabled },\n {\n \"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus\":\n !disabled,\n },\n { \"py-8\": !flush },\n `ui-${textSize}`,\n additionalCSS,\n )}\n style={\n {\n \"--featured-link-icon-size\": `var(${textSize.replace(\n \"text\",\n \"--fs\",\n )})`,\n } as CSSProperties\n }\n {...targetAndRel}\n onClick={onClick}\n >\n {reverse ? (\n <>\n <Icon\n name=\"icon-gui-arrow-long-right-outline\"\n size={`calc(var(--featured-link-icon-size) * 1.25)`}\n color={iconColor}\n additionalCSS={cn(\n \"align-middle mr-8 relative -top-1 -right-4 transition-[right] transform rotate-180\",\n { \"group-hover/featured-link:right-0\": !disabled },\n iconClassName,\n )}\n />\n {children}\n </>\n ) : (\n <>\n {children}\n <Icon\n name=\"icon-gui-arrow-long-right-outline\"\n size={`calc(var(--featured-link-icon-size) * 1.25)`}\n color={iconColor}\n additionalCSS={cn(\n \"align-middle ml-8 relative -top-1 -left-4 transition-[left]\",\n {\n \"group-hover/featured-link:left-0\": !disabled,\n },\n iconClassName,\n )}\n />\n </>\n )}\n </a>\n );\n};\n\nexport default FeaturedLink;\n"],"names":["React","Icon","cn","buildTargetAndRel","url","newWindow","props","target","startsWith","rel","FeaturedLink","textSize","iconColor","flush","reverse","additionalCSS","onClick","undefined","children","disabled","iconClassName","targetAndRel","a","href","className","style","replace","name","size","color"],"mappings":"AAAA,OAAOA,UAAyC,OAAQ,AAExD,QAAOC,SAAU,QAAS,AAE1B,QAAOC,OAAQ,YAAa,CAwB5B,MAAMC,kBAAoB,CAACC,IAAaC,aACtC,MAAMC,MAAqB,CAAC,EAE5B,GAAID,UAAW,CACbC,MAAMC,MAAM,CAAG,SAEf,GAAIH,IAAII,UAAU,CAAC,MAAQ,CAACJ,IAAII,UAAU,CAAC,MAAO,CAChDF,MAAMG,GAAG,CAAG,UACd,KAAO,CACLH,MAAMG,GAAG,CAAG,sBACd,CACF,CAEA,OAAOH,KACT,EAEA,MAAMI,aAAe,CAAC,CACpBN,GAAG,CACHO,SAAW,SAAS,CACpBC,SAAS,CACTC,MAAQ,KAAK,CACbC,QAAU,KAAK,CACfC,cAAgB,EAAE,CAClBV,UAAY,KAAK,CACjBW,QAAUC,SAAS,CACnBC,QAAQ,CACRC,SAAW,KAAK,CAChBC,cAAgB,EAAE,CACA,IAClB,MAAMC,aAAelB,kBAAkBC,IAAKC,WAE5C,OACE,oBAACiB,KACE,GAAIN,QAAU,CAAC,EAAI,CAAEO,KAAMnB,GAAI,CAAC,CACjCoB,UAAWtB,GACT,gDACA,CAAE,2CAA4CiB,QAAS,EACvD,CACE,gHACE,CAACA,QACL,EACA,CAAE,OAAQ,CAACN,KAAM,EACjB,CAAC,GAAG,EAAEF,SAAS,CAAC,CAChBI,eAEFU,MACE,CACE,4BAA6B,CAAC,IAAI,EAAEd,SAASe,OAAO,CAClD,OACA,QACA,CAAC,CAAC,AACN,EAED,GAAGL,YAAY,CAChBL,QAASA,SAERF,QACC,wCACE,oBAACb,MACC0B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOjB,UACPG,cAAeb,GACb,qFACA,CAAE,oCAAqC,CAACiB,QAAS,EACjDC,iBAGHF,UAGH,wCACGA,SACD,oBAACjB,MACC0B,KAAK,oCACLC,KAAM,CAAC,2CAA2C,CAAC,CACnDC,MAAOjB,UACPG,cAAeb,GACb,8DACA,CACE,mCAAoC,CAACiB,QACvC,EACAC,kBAOd,CAEA,gBAAeV,YAAa"}
|
package/core/Flyout.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useState}from"react";import{NavigationMenu,NavigationMenuItem,NavigationMenuList,NavigationMenuTrigger,NavigationMenuContent,NavigationMenuViewport,NavigationMenuLink}from"@radix-ui/react-navigation-menu";import cn from"./utils/cn";import{componentMaxHeight,HEADER_HEIGHT}from"./utils/heights";const DEFAULT_MENU_LINK_STYLING="ui-text-menu3 font-bold text-neutral-1000 dark:neutral-300
|
|
1
|
+
import React,{useState}from"react";import{NavigationMenu,NavigationMenuItem,NavigationMenuList,NavigationMenuTrigger,NavigationMenuContent,NavigationMenuViewport,NavigationMenuLink}from"@radix-ui/react-navigation-menu";import cn from"./utils/cn";import{componentMaxHeight,HEADER_HEIGHT}from"./utils/heights";const DEFAULT_MENU_LINK_STYLING="ui-text-menu3 font-bold text-neutral-1000 dark:neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 px-12 py-8 flex items-center justify-between";const DEFAULT_VIEWPORT_STYLING="relative overflow-hidden w-full h-[var(--radix-navigation-menu-viewport-height)] origin-[top_center] transition-[width,_height] duration-300 data-[state=closed]:animate-scale-out data-[state=open]:animate-scale-in sm:w-[var(--radix-navigation-menu-viewport-width)]";const PANEL_ANIMATION="data-[motion=from-end]:animate-enter-from-right data-[motion=from-start]:animate-enter-from-left data-[motion=to-end]:animate-exit-to-right data-[motion=to-start]:animate-exit-to-left";const FlyOverlay=({className,fadingOut})=>React.createElement("div",{className:cn("absolute left-0 right-0 h-screen w-full opacity-0",{"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]":!fadingOut,"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]":fadingOut},className),style:{height:componentMaxHeight(HEADER_HEIGHT),top:HEADER_HEIGHT}});const Flyout=({menuItems,className,flyOutClassName,menuLinkClassName,viewPortClassName})=>{const[isOpen,setIsOpen]=useState(false);const[fadingOut,setFadingOut]=useState(false);const closeMenu=()=>{setFadingOut(true);setTimeout(()=>{setIsOpen(false);setFadingOut(false)},150)};return React.createElement(React.Fragment,null,React.createElement(NavigationMenu,{className:cn(className,"flex w-full"),onValueChange:val=>val?setIsOpen(true):closeMenu(),delayDuration:0},React.createElement(NavigationMenuList,{className:"flex list-none center"},menuItems.map(({name,content,link,panelClassName})=>content?React.createElement(NavigationMenuItem,{key:name},React.createElement(NavigationMenuTrigger,{className:cn("group outline-none focus:outline-none select-none cursor-pointer relative","rounded-md hover:bg-neutral-100 dark:hover:bg-neutral-1200","[&[data-state=open]]:bg-neutral-100 dark:[&[data-state=open]]:bg-neutral-1200","[&[data-state=open]]:text-neutral-1300 dark:[&[data-state=open]]:text-neutral-000",DEFAULT_MENU_LINK_STYLING,menuLinkClassName)},name),React.createElement(NavigationMenuContent,{className:cn("absolute right-0 top-0 p-24 z-10",PANEL_ANIMATION,panelClassName)},content)):React.createElement(NavigationMenuLink,{key:name,href:link,className:cn(DEFAULT_MENU_LINK_STYLING,menuLinkClassName)},name))),React.createElement("div",{className:cn("absolute top-full",flyOutClassName)},React.createElement(NavigationMenuViewport,{className:cn(DEFAULT_VIEWPORT_STYLING,viewPortClassName)}))),isOpen?React.createElement(FlyOverlay,{className:"bg-neutral-1300 opacity-10 z-20 h-screen mix-blend-multiply",fadingOut:fadingOut}):null)};export default Flyout;
|
|
2
2
|
//# sourceMappingURL=Flyout.js.map
|
package/core/Flyout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Flyout.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport {\n NavigationMenu,\n NavigationMenuItem,\n NavigationMenuList,\n NavigationMenuTrigger,\n NavigationMenuContent,\n NavigationMenuViewport,\n NavigationMenuLink,\n} from \"@radix-ui/react-navigation-menu\";\nimport cn from \"./utils/cn\";\nimport { componentMaxHeight, HEADER_HEIGHT } from \"./utils/heights\";\n\n/**\n * Props for the Flyout component.\n */\ntype FlyoutProps = {\n /**\n * Array of menu items to be displayed in the flyout.\n */\n menuItems: {\n /**\n * Name for the menu item.\n */\n name: string;\n /**\n * Optional content to be displayed in the flyout panel.\n */\n content?: React.ReactNode;\n /**\n * Optional link for the menu item.\n */\n link?: string;\n /**\n * Optional styling for the flyout panel.\n */\n panelClassName?: string;\n }[];\n /**\n * Optional class name for the flyout container.\n */\n className?: string;\n /**\n * Optional class name for the flyout element.\n */\n flyOutClassName?: string;\n /**\n * Optional class name for the menu link.\n */\n menuLinkClassName?: string;\n /**\n * Optional class name for the viewport.\n */\n viewPortClassName?: string;\n
|
|
1
|
+
{"version":3,"sources":["../../src/core/Flyout.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport {\n NavigationMenu,\n NavigationMenuItem,\n NavigationMenuList,\n NavigationMenuTrigger,\n NavigationMenuContent,\n NavigationMenuViewport,\n NavigationMenuLink,\n} from \"@radix-ui/react-navigation-menu\";\nimport cn from \"./utils/cn\";\nimport { componentMaxHeight, HEADER_HEIGHT } from \"./utils/heights\";\n\n/**\n * Props for the Flyout component.\n */\ntype FlyoutProps = {\n /**\n * Array of menu items to be displayed in the flyout.\n */\n menuItems: {\n /**\n * Name for the menu item.\n */\n name: string;\n /**\n * Optional content to be displayed in the flyout panel.\n */\n content?: React.ReactNode;\n /**\n * Optional link for the menu item.\n */\n link?: string;\n /**\n * Optional styling for the flyout panel.\n */\n panelClassName?: string;\n }[];\n /**\n * Optional class name for the flyout container.\n */\n className?: string;\n /**\n * Optional class name for the flyout element.\n */\n flyOutClassName?: string;\n /**\n * Optional class name for the menu link.\n */\n menuLinkClassName?: string;\n /**\n * Optional class name for the viewport.\n */\n viewPortClassName?: string;\n};\n\nconst DEFAULT_MENU_LINK_STYLING =\n \"ui-text-menu3 font-bold text-neutral-1000 dark:neutral-300 hover:text-neutral-1300 dark:hover:text-neutral-000 px-12 py-8 flex items-center justify-between\";\nconst DEFAULT_VIEWPORT_STYLING =\n \"relative overflow-hidden w-full h-[var(--radix-navigation-menu-viewport-height)] origin-[top_center] transition-[width,_height] duration-300 data-[state=closed]:animate-scale-out data-[state=open]:animate-scale-in sm:w-[var(--radix-navigation-menu-viewport-width)]\";\nconst PANEL_ANIMATION =\n \"data-[motion=from-end]:animate-enter-from-right data-[motion=from-start]:animate-enter-from-left data-[motion=to-end]:animate-exit-to-right data-[motion=to-start]:animate-exit-to-left\";\n\nconst FlyOverlay = ({\n className,\n fadingOut,\n}: {\n className: string;\n fadingOut: boolean;\n}) => (\n <div\n className={cn(\n \"absolute left-0 right-0 h-screen w-full opacity-0\",\n {\n \"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]\": !fadingOut,\n \"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]\": fadingOut,\n },\n className,\n )}\n style={{ height: componentMaxHeight(HEADER_HEIGHT), top: HEADER_HEIGHT }}\n ></div>\n);\n\nconst Flyout = ({\n menuItems,\n className,\n flyOutClassName,\n menuLinkClassName,\n viewPortClassName,\n}: FlyoutProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [fadingOut, setFadingOut] = useState(false);\n\n const closeMenu = () => {\n setFadingOut(true);\n\n setTimeout(() => {\n setIsOpen(false);\n setFadingOut(false);\n }, 150);\n };\n\n return (\n <>\n <NavigationMenu\n className={cn(className, \"flex w-full\")}\n onValueChange={(val) => (val ? setIsOpen(true) : closeMenu())}\n delayDuration={0}\n >\n <NavigationMenuList className=\"flex list-none center\">\n {menuItems.map(({ name, content, link, panelClassName }) =>\n content ? (\n <NavigationMenuItem key={name}>\n <NavigationMenuTrigger\n className={cn(\n \"group outline-none focus:outline-none select-none cursor-pointer relative\",\n \"rounded-md hover:bg-neutral-100 dark:hover:bg-neutral-1200\",\n \"[&[data-state=open]]:bg-neutral-100 dark:[&[data-state=open]]:bg-neutral-1200\",\n \"[&[data-state=open]]:text-neutral-1300 dark:[&[data-state=open]]:text-neutral-000\",\n DEFAULT_MENU_LINK_STYLING,\n menuLinkClassName,\n )}\n >\n {name}\n </NavigationMenuTrigger>\n <NavigationMenuContent\n className={cn(\n \"absolute right-0 top-0 p-24 z-10\",\n PANEL_ANIMATION,\n panelClassName,\n )}\n >\n {content}\n </NavigationMenuContent>\n </NavigationMenuItem>\n ) : (\n <NavigationMenuLink\n key={name}\n href={link}\n className={cn(DEFAULT_MENU_LINK_STYLING, menuLinkClassName)}\n >\n {name}\n </NavigationMenuLink>\n ),\n )}\n </NavigationMenuList>\n\n <div className={cn(\"absolute top-full\", flyOutClassName)}>\n <NavigationMenuViewport\n className={cn(DEFAULT_VIEWPORT_STYLING, viewPortClassName)}\n />\n </div>\n </NavigationMenu>\n {isOpen ? (\n <FlyOverlay\n className=\"bg-neutral-1300 opacity-10 z-20 h-screen mix-blend-multiply\"\n fadingOut={fadingOut}\n />\n ) : null}\n </>\n );\n};\n\nexport default Flyout;\n"],"names":["React","useState","NavigationMenu","NavigationMenuItem","NavigationMenuList","NavigationMenuTrigger","NavigationMenuContent","NavigationMenuViewport","NavigationMenuLink","cn","componentMaxHeight","HEADER_HEIGHT","DEFAULT_MENU_LINK_STYLING","DEFAULT_VIEWPORT_STYLING","PANEL_ANIMATION","FlyOverlay","className","fadingOut","div","style","height","top","Flyout","menuItems","flyOutClassName","menuLinkClassName","viewPortClassName","isOpen","setIsOpen","setFadingOut","closeMenu","setTimeout","onValueChange","val","delayDuration","map","name","content","link","panelClassName","key","href"],"mappings":"AAAA,OAAOA,OAASC,QAAQ,KAAQ,OAAQ,AACxC,QACEC,cAAc,CACdC,kBAAkB,CAClBC,kBAAkB,CAClBC,qBAAqB,CACrBC,qBAAqB,CACrBC,sBAAsB,CACtBC,kBAAkB,KACb,iCAAkC,AACzC,QAAOC,OAAQ,YAAa,AAC5B,QAASC,kBAAkB,CAAEC,aAAa,KAAQ,iBAAkB,CA6CpE,MAAMC,0BACJ,8JACF,MAAMC,yBACJ,2QACF,MAAMC,gBACJ,0LAEF,MAAMC,WAAa,CAAC,CAClBC,SAAS,CACTC,SAAS,CAIV,GACC,oBAACC,OACCF,UAAWP,GACT,oDACA,CACE,2DAA4D,CAACQ,UAC7D,4DAA6DA,SAC/D,EACAD,WAEFG,MAAO,CAAEC,OAAQV,mBAAmBC,eAAgBU,IAAKV,aAAc,IAI3E,MAAMW,OAAS,CAAC,CACdC,SAAS,CACTP,SAAS,CACTQ,eAAe,CACfC,iBAAiB,CACjBC,iBAAiB,CACL,IACZ,KAAM,CAACC,OAAQC,UAAU,CAAG3B,SAAS,OACrC,KAAM,CAACgB,UAAWY,aAAa,CAAG5B,SAAS,OAE3C,MAAM6B,UAAY,KAChBD,aAAa,MAEbE,WAAW,KACTH,UAAU,OACVC,aAAa,MACf,EAAG,IACL,EAEA,OACE,wCACE,oBAAC3B,gBACCc,UAAWP,GAAGO,UAAW,eACzBgB,cAAe,AAACC,KAASA,IAAML,UAAU,MAAQE,YACjDI,cAAe,GAEf,oBAAC9B,oBAAmBY,UAAU,yBAC3BO,UAAUY,GAAG,CAAC,CAAC,CAAEC,IAAI,CAAEC,OAAO,CAAEC,IAAI,CAAEC,cAAc,CAAE,GACrDF,QACE,oBAAClC,oBAAmBqC,IAAKJ,MACvB,oBAAC/B,uBACCW,UAAWP,GACT,4EACA,6DACA,gFACA,oFACAG,0BACAa,oBAGDW,MAEH,oBAAC9B,uBACCU,UAAWP,GACT,mCACAK,gBACAyB,iBAGDF,UAIL,oBAAC7B,oBACCgC,IAAKJ,KACLK,KAAMH,KACNtB,UAAWP,GAAGG,0BAA2Ba,oBAExCW,QAMT,oBAAClB,OAAIF,UAAWP,GAAG,oBAAqBe,kBACtC,oBAACjB,wBACCS,UAAWP,GAAGI,yBAA0Ba,uBAI7CC,OACC,oBAACZ,YACCC,UAAU,8DACVC,UAAWA,YAEX,KAGV,CAEA,gBAAeK,MAAO"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export const footerLinks=[{title:"Products",links:[{label:"Ably Pub/Sub",link:"/pubsub"},{label:"Ably LiveSync",link:"/livesync"},{label:"Ably Chat",link:"/chat"},{label:"Ably Spaces",link:"/spaces"},{label:"Ably Asset Tracking",link:"/docs/asset-tracking"},{label:"Compare our tech",link:"/compare"}]},{title:"Platform",links:[{label:"Infrastructure",link:"/four-pillars-of-dependability"},{label:"Integrations",link:"/integrations"},{label:"SDKs",link:"/docs/sdks"},{label:"Changelog",link:"https://changelog.ably.com/"},{label:"Security & Compliance",link:"/security-and-compliance"}]},{title:"Get started",links:[{label:"Documentation",link:"/docs"},{label:"Examples",link:"/examples"},{label:"Pricing",link:"/pricing"},{label:"Realtime A-Z",link:"/topics"},{label:"Support",link:"/support"}]},{title:"Company",links:[{label:"About Ably",link:"/about"},{label:"Blog",link:"/blog"},{label:"Careers",link:"/careers",badge:"WE’RE HIRING"},{label:"Contact us",link:"/contact"}]}];export const bottomFooterLinks=[{label:"Data protection",link:"/data-protection"},{label:"Privacy",link:"/privacy"},{label:"Legals",link:"/legals"},{label:"Cookies",link:"/privacy"}];export const socialLinks=[{key:"x",colorIcon:"icon-social-x",monoIcon:"icon-social-x-mono",link:"https://x.com/ablyrealtime"},{key:"linkedin",colorIcon:"icon-social-linkedin",monoIcon:"icon-social-linkedin-mono",link:"https://www.linkedin.com/company/ably-realtime"},{key:"github",colorIcon:"icon-social-github",monoIcon:"icon-social-github-mono",link:"https://github.com/ably/"},{key:"discord",colorIcon:"icon-social-discord",monoIcon:"icon-social-discord-mono",link:"https://discord.gg/g8yqePUVDn"},{key:"youtube",colorIcon:"icon-social-youtube",monoIcon:"icon-social-youtube-mono",link:"https://www.youtube.com/c/AblyRealtime"}];
|
|
2
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Footer/data.ts"],"sourcesContent":["import { IconName } from \"../Icon/types\";\n\ntype FooterLinksProps = {\n title: string;\n links: {\n label: string;\n link: string;\n badge?: string;\n }[];\n};\n\nexport const footerLinks: FooterLinksProps[] = [\n {\n title: \"Products\",\n links: [\n { label: \"Ably Pub/Sub\", link: \"/pubsub\" },\n { label: \"Ably LiveSync\", link: \"/livesync\" },\n { label: \"Ably Chat\", link: \"/chat\" },\n { label: \"Ably Spaces\", link: \"/spaces\" },\n { label: \"Ably Asset Tracking\", link: \"/docs/asset-tracking\" },\n { label: \"Compare our tech\", link: \"/compare\" },\n ],\n },\n {\n title: \"Platform\",\n links: [\n { label: \"Infrastructure\", link: \"/four-pillars-of-dependability\" },\n { label: \"Integrations\", link: \"/integrations\" },\n { label: \"SDKs\", link: \"/docs/sdks\" },\n { label: \"Changelog\", link: \"https://changelog.ably.com/\" },\n { label: \"Security & Compliance\", link: \"/security-and-compliance\" },\n ],\n },\n {\n title: \"Get started\",\n links: [\n { label: \"Documentation\", link: \"/docs\" },\n { label: \"Examples\", link: \"/examples\" },\n { label: \"Pricing\", link: \"/pricing\" },\n { label: \"Realtime A-Z\", link: \"/topics\" },\n { label: \"Support\", link: \"/support\" },\n ],\n },\n {\n title: \"Company\",\n links: [\n { label: \"About Ably\", link: \"/about\" },\n { label: \"Blog\", link: \"/blog\" },\n { label: \"Careers\", link: \"/careers\", badge: \"WE’RE HIRING\" },\n { label: \"Contact us\", link: \"/contact\" },\n ],\n },\n];\n\nexport const bottomFooterLinks = [\n { label: \"Data protection\", link: \"/data-protection\" },\n { label: \"Privacy\", link: \"/privacy\" },\n { label: \"Legals\", link: \"/legals\" },\n { label: \"Cookies\", link: \"/privacy\" },\n];\n\nexport const socialLinks: {\n key: string;\n colorIcon: IconName;\n monoIcon: IconName;\n link: string;\n}[] = [\n {\n key: \"x\",\n colorIcon: \"icon-social-x\",\n monoIcon: \"icon-social-x-mono\",\n link: \"https://x.com/ablyrealtime\",\n },\n {\n key: \"linkedin\",\n colorIcon: \"icon-social-linkedin\",\n monoIcon: \"icon-social-linkedin-mono\",\n link: \"https://www.linkedin.com/company/ably-realtime\",\n },\n {\n key: \"github\",\n colorIcon: \"icon-social-github\",\n monoIcon: \"icon-social-github-mono\",\n link: \"https://github.com/ably/\",\n },\n {\n key: \"discord\",\n colorIcon: \"icon-social-discord\",\n monoIcon: \"icon-social-discord-mono\",\n link: \"https://discord.gg/g8yqePUVDn\",\n },\n {\n key: \"youtube\",\n colorIcon: \"icon-social-youtube\",\n monoIcon: \"icon-social-youtube-mono\",\n link: \"https://www.youtube.com/c/AblyRealtime\",\n },\n];\n"],"names":["footerLinks","title","links","label","link","badge","bottomFooterLinks","socialLinks","key","colorIcon","monoIcon"],"mappings":"AAWA,OAAO,MAAMA,YAAkC,CAC7C,CACEC,MAAO,WACPC,MAAO,CACL,CAAEC,MAAO,eAAgBC,KAAM,SAAU,EACzC,CAAED,MAAO,gBAAiBC,KAAM,WAAY,EAC5C,CAAED,MAAO,YAAaC,KAAM,OAAQ,EACpC,CAAED,MAAO,cAAeC,KAAM,SAAU,EACxC,CAAED,MAAO,sBAAuBC,KAAM,sBAAuB,EAC7D,CAAED,MAAO,mBAAoBC,KAAM,UAAW,EAC/C,AACH,EACA,CACEH,MAAO,WACPC,MAAO,CACL,CAAEC,MAAO,iBAAkBC,KAAM,gCAAiC,EAClE,CAAED,MAAO,eAAgBC,KAAM,eAAgB,EAC/C,CAAED,MAAO,OAAQC,KAAM,YAAa,EACpC,CAAED,MAAO,YAAaC,KAAM,6BAA8B,EAC1D,CAAED,MAAO,wBAAyBC,KAAM,0BAA2B,EACpE,AACH,EACA,CACEH,MAAO,cACPC,MAAO,CACL,CAAEC,MAAO,gBAAiBC,KAAM,OAAQ,EACxC,CAAED,MAAO,WAAYC,KAAM,WAAY,EACvC,CAAED,MAAO,UAAWC,KAAM,UAAW,EACrC,CAAED,MAAO,eAAgBC,KAAM,SAAU,EACzC,CAAED,MAAO,UAAWC,KAAM,UAAW,EACtC,AACH,EACA,CACEH,MAAO,UACPC,MAAO,CACL,CAAEC,MAAO,aAAcC,KAAM,QAAS,EACtC,CAAED,MAAO,OAAQC,KAAM,OAAQ,EAC/B,CAAED,MAAO,UAAWC,KAAM,WAAYC,MAAO,cAAe,EAC5D,CAAEF,MAAO,aAAcC,KAAM,UAAW,EACzC,AACH,EACD,AAAC,AAEF,QAAO,MAAME,kBAAoB,CAC/B,CAAEH,MAAO,kBAAmBC,KAAM,kBAAmB,EACrD,CAAED,MAAO,UAAWC,KAAM,UAAW,EACrC,CAAED,MAAO,SAAUC,KAAM,SAAU,EACnC,CAAED,MAAO,UAAWC,KAAM,UAAW,EACtC,AAAC,AAEF,QAAO,MAAMG,YAKP,CACJ,CACEC,IAAK,IACLC,UAAW,gBACXC,SAAU,qBACVN,KAAM,4BACR,EACA,CACEI,IAAK,WACLC,UAAW,uBACXC,SAAU,4BACVN,KAAM,gDACR,EACA,CACEI,IAAK,SACLC,UAAW,qBACXC,SAAU,0BACVN,KAAM,0BACR,EACA,CACEI,IAAK,UACLC,UAAW,sBACXC,SAAU,2BACVN,KAAM,+BACR,EACA,CACEI,IAAK,UACLC,UAAW,sBACXC,SAAU,2BACVN,KAAM,wCACR,EACD,AAAC"}
|
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.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;
|
|
1
|
+
import React from"react";import cn from"./utils/cn";import Icon from"./Icon";import Status,{StatusUrl}from"./Status";import Logo from"./Logo";import Badge from"./Badge";import{bottomFooterLinks,footerLinks,socialLinks}from"./Footer/data";import{ablyAwards}from"./Meganav/data";const Footer=()=>{const textColorClassnames="ui-text-menu3 font-medium transition-colors text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 hover:dark:text-neutral-000 active:text-neutral-800 active:dark:text-neutral-400 focus:outline focus:outline-gui-focus";return React.createElement("footer",{className:"max-w-screen-xl mx-auto ui-grid-px pt-40 sm:pt-48 md:pt-64 pb-40 bg-neutral-100 dark:bg-neutral-1200 border-t border-neutral-300 dark:border-neutral-1000","data-id":"footer"},React.createElement("div",{className:"flex flex-col sm:flex-row gap-x-24 gap-y-48 mb-64 justify-between"},React.createElement("div",{className:"flex-1 flex flex-col gap-24"},["light","dark"].map(theme=>React.createElement(Logo,{key:theme,href:"/",theme:theme,additionalLinkAttrs:{className:cn("focus-base rounded w-[102px]",{"flex dark:hidden":theme==="light","hidden dark:flex":theme==="dark"})}})),React.createElement(Status,{statusUrl:StatusUrl,showDescription:true}),React.createElement("div",{className:"flex gap-x-24"},socialLinks.map(link=>React.createElement("a",{key:link.key,href:link.link,target:"_blank",rel:"noreferrer noopener","aria-label":`Visit Ably on ${link.key}`,className:"w-20 h-20 group/social-icon"},React.createElement(Icon,{name:link.monoIcon,size:"20px",additionalCSS:"text-neutral-1000 dark:text-neutral-300 group-hover/social-icon:hidden"}),React.createElement(Icon,{name:link.colorIcon,size:"20px",additionalCSS:"hidden group-hover/social-icon:flex"})))),React.createElement("div",{className:"flex gap-8 mt-16"},ablyAwards.map(award=>React.createElement("img",{key:award.desc,src:award.image,alt:award.desc,width:"57",height:"64"})))),React.createElement("div",{className:"flex-1 md:flex-[2] flex flex-row flex-wrap gap-x-24 gap-y-48"},footerLinks.map(({title,links})=>React.createElement("div",{key:title,className:"flex-1 basis-1/3 md:basis-1"},React.createElement("h3",{className:"ui-text-overline2 text-neutral-700 dark:text-neutral-600 mb-16"},title),React.createElement("ul",{className:"flex flex-col gap-y-12"},links.map(({label,link,badge})=>React.createElement("li",{key:label,className:"flex gap-x-8"},React.createElement("a",{href:link,className:textColorClassnames,"aria-label":`Visit ${label}`},label),badge&&React.createElement(Badge,{size:"xs",className:"ui-text-p4 font-[10px]"},badge)))))))),React.createElement("div",{className:"pt-24 border-t border-neutral-300 dark:border-neutral-1000"},React.createElement("div",{className:"flex gap-24"},bottomFooterLinks.map(link=>React.createElement("a",{key:link.label,href:link.link,className:textColorClassnames,"aria-label":`Visit ${link.label}`},link.label)))))};export default Footer;
|
|
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 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
|
+
{"version":3,"sources":["../../src/core/Footer.tsx"],"sourcesContent":["import React from \"react\";\nimport cn from \"./utils/cn\";\nimport Icon from \"./Icon\";\nimport Status, { StatusUrl } from \"./Status\";\nimport { Theme } from \"./styles/colors/types\";\nimport Logo from \"./Logo\";\nimport Badge from \"./Badge\";\nimport { bottomFooterLinks, footerLinks, socialLinks } from \"./Footer/data\";\nimport { ablyAwards } from \"./Meganav/data\";\n\nconst Footer = () => {\n const textColorClassnames =\n \"ui-text-menu3 font-medium transition-colors text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1300 hover:dark:text-neutral-000 active:text-neutral-800 active:dark:text-neutral-400 focus:outline focus:outline-gui-focus\";\n\n return (\n <footer\n className=\"max-w-screen-xl mx-auto ui-grid-px pt-40 sm:pt-48 md:pt-64 pb-40 bg-neutral-100 dark:bg-neutral-1200 border-t border-neutral-300 dark:border-neutral-1000\"\n data-id=\"footer\"\n >\n <div className=\"flex flex-col sm:flex-row gap-x-24 gap-y-48 mb-64 justify-between\">\n <div className=\"flex-1 flex flex-col gap-24\">\n {([\"light\", \"dark\"] as Theme[]).map((theme) => (\n <Logo\n key={theme}\n href=\"/\"\n theme={theme}\n additionalLinkAttrs={{\n className: cn(\"focus-base rounded w-[102px]\", {\n \"flex dark:hidden\": theme === \"light\",\n \"hidden dark:flex\": theme === \"dark\",\n }),\n }}\n />\n ))}\n\n <Status statusUrl={StatusUrl} showDescription />\n\n <div className=\"flex gap-x-24\">\n {socialLinks.map((link) => (\n <a\n key={link.key}\n href={link.link}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n aria-label={`Visit Ably on ${link.key}`}\n className=\"w-20 h-20 group/social-icon\"\n >\n <Icon\n name={link.monoIcon}\n size=\"20px\"\n additionalCSS=\"text-neutral-1000 dark:text-neutral-300 group-hover/social-icon:hidden\"\n />\n <Icon\n name={link.colorIcon}\n size=\"20px\"\n additionalCSS=\"hidden group-hover/social-icon:flex\"\n />\n </a>\n ))}\n </div>\n <div className=\"flex gap-8 mt-16\">\n {ablyAwards.map((award) => (\n <img\n key={award.desc}\n src={award.image}\n alt={award.desc}\n width=\"57\"\n height=\"64\"\n />\n ))}\n </div>\n </div>\n <div className=\"flex-1 md:flex-[2] flex flex-row flex-wrap gap-x-24 gap-y-48\">\n {footerLinks.map(({ title, links }) => (\n <div key={title} className=\"flex-1 basis-1/3 md:basis-1\">\n <h3 className=\"ui-text-overline2 text-neutral-700 dark:text-neutral-600 mb-16\">\n {title}\n </h3>\n <ul className=\"flex flex-col gap-y-12\">\n {links.map(({ label, link, badge }) => (\n <li key={label} className=\"flex gap-x-8\">\n <a\n href={link}\n className={textColorClassnames}\n aria-label={`Visit ${label}`}\n >\n {label}\n </a>\n {badge && (\n <Badge size=\"xs\" className=\"ui-text-p4 font-[10px]\">\n {badge}\n </Badge>\n )}\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n </div>\n\n <div className=\"pt-24 border-t border-neutral-300 dark:border-neutral-1000\">\n <div className=\"flex gap-24\">\n {bottomFooterLinks.map((link) => (\n <a\n key={link.label}\n href={link.link}\n className={textColorClassnames}\n aria-label={`Visit ${link.label}`}\n >\n {link.label}\n </a>\n ))}\n </div>\n </div>\n </footer>\n );\n};\n\nexport default Footer;\n"],"names":["React","cn","Icon","Status","StatusUrl","Logo","Badge","bottomFooterLinks","footerLinks","socialLinks","ablyAwards","Footer","textColorClassnames","footer","className","data-id","div","map","theme","key","href","additionalLinkAttrs","statusUrl","showDescription","link","a","target","rel","aria-label","name","monoIcon","size","additionalCSS","colorIcon","award","img","desc","src","image","alt","width","height","title","links","h3","ul","label","badge","li"],"mappings":"AAAA,OAAOA,UAAW,OAAQ,AAC1B,QAAOC,OAAQ,YAAa,AAC5B,QAAOC,SAAU,QAAS,AAC1B,QAAOC,QAAUC,SAAS,KAAQ,UAAW,AAE7C,QAAOC,SAAU,QAAS,AAC1B,QAAOC,UAAW,SAAU,AAC5B,QAASC,iBAAiB,CAAEC,WAAW,CAAEC,WAAW,KAAQ,eAAgB,AAC5E,QAASC,UAAU,KAAQ,gBAAiB,CAE5C,MAAMC,OAAS,KACb,MAAMC,oBACJ,qOAEF,OACE,oBAACC,UACCC,UAAU,4JACVC,UAAQ,UAER,oBAACC,OAAIF,UAAU,qEACb,oBAACE,OAAIF,UAAU,+BACZ,AAAC,CAAC,QAAS,OAAO,CAAaG,GAAG,CAAC,AAACC,OACnC,oBAACb,MACCc,IAAKD,MACLE,KAAK,IACLF,MAAOA,MACPG,oBAAqB,CACnBP,UAAWb,GAAG,+BAAgC,CAC5C,mBAAoBiB,QAAU,QAC9B,mBAAoBA,QAAU,MAChC,EACF,KAIJ,oBAACf,QAAOmB,UAAWlB,UAAWmB,gBAAAA,OAE9B,oBAACP,OAAIF,UAAU,iBACZL,YAAYQ,GAAG,CAAC,AAACO,MAChB,oBAACC,KACCN,IAAKK,KAAKL,GAAG,CACbC,KAAMI,KAAKA,IAAI,CACfE,OAAO,SACPC,IAAI,sBACJC,aAAY,CAAC,cAAc,EAAEJ,KAAKL,GAAG,CAAC,CAAC,CACvCL,UAAU,+BAEV,oBAACZ,MACC2B,KAAML,KAAKM,QAAQ,CACnBC,KAAK,OACLC,cAAc,2EAEhB,oBAAC9B,MACC2B,KAAML,KAAKS,SAAS,CACpBF,KAAK,OACLC,cAAc,2CAKtB,oBAAChB,OAAIF,UAAU,oBACZJ,WAAWO,GAAG,CAAC,AAACiB,OACf,oBAACC,OACChB,IAAKe,MAAME,IAAI,CACfC,IAAKH,MAAMI,KAAK,CAChBC,IAAKL,MAAME,IAAI,CACfI,MAAM,KACNC,OAAO,UAKf,oBAACzB,OAAIF,UAAU,gEACZN,YAAYS,GAAG,CAAC,CAAC,CAAEyB,KAAK,CAAEC,KAAK,CAAE,GAChC,oBAAC3B,OAAIG,IAAKuB,MAAO5B,UAAU,+BACzB,oBAAC8B,MAAG9B,UAAU,kEACX4B,OAEH,oBAACG,MAAG/B,UAAU,0BACX6B,MAAM1B,GAAG,CAAC,CAAC,CAAE6B,KAAK,CAAEtB,IAAI,CAAEuB,KAAK,CAAE,GAChC,oBAACC,MAAG7B,IAAK2B,MAAOhC,UAAU,gBACxB,oBAACW,KACCL,KAAMI,KACNV,UAAWF,oBACXgB,aAAY,CAAC,MAAM,EAAEkB,MAAM,CAAC,EAE3BA,OAEFC,OACC,oBAACzC,OAAMyB,KAAK,KAAKjB,UAAU,0BACxBiC,cAWnB,oBAAC/B,OAAIF,UAAU,8DACb,oBAACE,OAAIF,UAAU,eACZP,kBAAkBU,GAAG,CAAC,AAACO,MACtB,oBAACC,KACCN,IAAKK,KAAKsB,KAAK,CACf1B,KAAMI,KAAKA,IAAI,CACfV,UAAWF,oBACXgB,aAAY,CAAC,MAAM,EAAEJ,KAAKsB,KAAK,CAAC,CAAC,EAEhCtB,KAAKsB,KAAK,KAOzB,CAEA,gBAAenC,MAAO"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import React,{useRef}from"react";import Icon from"../Icon";import LinkButton from"../LinkButton";import cn from"../utils/cn";import DropdownMenu from"../DropdownMenu";const testSessionState={signedIn:false,logOut:{token:"0000",href:"accounts/sign_out"},accountName:"Ably"};export const HeaderLinks=({sessionState=testSessionState,headerLinks,searchButtonVisibility,searchButton,className})=>{const{signedIn,logOut}=sessionState;const formRef=useRef(null);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";const dropdownMenuLinkClasses="block p-8 ui-text-menu3 font-semibold text-neutral-1000 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 rounded-lg";const onClickLogout=e=>{e.preventDefault();formRef.current?.submit()};const DashboardLink=({className})=>React.createElement("a",{href:"/dashboard",className:className},"Dashboard");const LogoutForm=React.createElement("form",{ref:formRef,method:"post",action:logOut.href,className:"hidden"},React.createElement("input",{name:"_method",value:"delete",type:"hidden"}),React.createElement("input",{name:"authenticity_token",value:logOut.token,type:"hidden"}));return React.createElement("nav",{className:cn("flex md:flex-1 md:items-center md:justify-end flex-col md:flex-row border-t-[1px] border-neutral-300 md:border-t-0 md:gap-
|
|
1
|
+
import React,{useRef}from"react";import Icon from"../Icon";import LinkButton from"../LinkButton";import cn from"../utils/cn";import DropdownMenu from"../DropdownMenu";const testSessionState={signedIn:false,logOut:{token:"0000",href:"accounts/sign_out"},accountName:"Ably"};export const HeaderLinks=({sessionState=testSessionState,headerLinks,searchButtonVisibility,searchButton,className})=>{const{signedIn,logOut}=sessionState;const formRef=useRef(null);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";const dropdownMenuLinkClasses="block p-8 ui-text-menu3 font-semibold text-neutral-1000 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 rounded-lg";const onClickLogout=e=>{e.preventDefault();formRef.current?.submit()};const DashboardLink=({className})=>React.createElement("a",{href:"/dashboard",className:className},"Dashboard");const LogoutForm=React.createElement("form",{ref:formRef,method:"post",action:logOut.href,className:"hidden"},React.createElement("input",{name:"_method",value:"delete",type:"hidden"}),React.createElement("input",{name:"authenticity_token",value:logOut.token,type:"hidden"}));return React.createElement("nav",{className:cn("flex md:flex-1 md:items-center md:justify-end flex-col md:flex-row border-t-[1px] border-neutral-300 md:border-t-0 md:gap-16 pt-12 pb-16 md:py-0",className)},signedIn&&React.createElement(React.Fragment,null,LogoutForm,React.createElement("div",{className:"block md:hidden"},React.createElement("div",{className:"flex flex-col border-b-[1px] border-neutral-300 px-16 pb-12 mb-12"},React.createElement("span",{className:"py-12 ui-text-sub-header text-[18px] text-neutral-700 dark:text-neutral-600 font-bold"},sessionState.accountName),React.createElement(DashboardLink,{className:headerLinkClasses})))),headerLinks?.map(({href,label,external})=>React.createElement("a",{key:href,className:cn(headerLinkClasses,"flex items-center gap-6 px-16 md:px-0 leading-none"),href:href,target:external?"_blank":undefined,rel:external?"noreferrer noopener":undefined},label,external&&React.createElement(Icon,{name:"icon-gui-arrow-top-right-on-square-mini",size:"20px"}))),searchButtonVisibility!=="mobile"?searchButton:null,signedIn?React.createElement(React.Fragment,null,React.createElement("div",{className:"hidden md:block relative"},React.createElement(DropdownMenu,null,React.createElement(DropdownMenu.Trigger,{description:`Account menu for ${sessionState.accountName}`},React.createElement("span",{className:"block text-ellipsis overflow-hidden whitespace-nowrap w-full max-w-[150px] leading-normal"},sessionState.accountName)),React.createElement(DropdownMenu.Content,{anchorPosition:"right",contentClassNames:"w-[240px] mt-[12px]"},React.createElement("div",{className:"p-8"},React.createElement(DashboardLink,{className:dropdownMenuLinkClasses}),React.createElement("a",{onClick:onClickLogout,href:"#",className:dropdownMenuLinkClasses},"Logout"))))),React.createElement("div",{className:"block md:hidden px-16 pt-16 pb-0"},React.createElement(LinkButton,{onClick:onClickLogout,variant:"secondary",className:"w-full md:ui-button-secondary-xs","aria-label":"Logout",rightIcon:"icon-gui-arrow-right-end-on-rectangle-outline"},"Logout"))):React.createElement("div",{className:"flex gap-16 pt-12 md:py-0 px-16 md:px-0"},React.createElement(LinkButton,{href:"/login",variant:"secondary",className:"flex-1 md:flex-none md:ui-button-secondary-xs hover:text-neutral-1300 dark:hover:text-neutral-000"},"Login"),React.createElement(LinkButton,{href:"/sign-up",variant:"primary",className:"flex-1 md:flex-none md:ui-button-primary-xs hover:text-neutral-000 dark:hover:text-neutral-1300"},"Start free")))};
|
|
2
2
|
//# sourceMappingURL=HeaderLinks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/Header/HeaderLinks.tsx"],"sourcesContent":["import React, { MouseEvent, useRef } from \"react\";\nimport { HeaderProps } from \"../Header\";\nimport Icon from \"../Icon\";\nimport LinkButton from \"../LinkButton\";\nimport cn from \"../utils/cn\";\nimport DropdownMenu from \"../DropdownMenu\";\n\nconst testSessionState = {\n signedIn: false,\n logOut: {\n token: \"0000\",\n href: \"accounts/sign_out\",\n },\n accountName: \"Ably\",\n};\n\nexport const HeaderLinks: React.FC<\n Pick<\n HeaderProps,\n | \"sessionState\"\n | \"headerLinks\"\n | \"searchButtonVisibility\"\n | \"searchButton\"\n | \"className\"\n >\n> = ({\n sessionState = testSessionState,\n headerLinks,\n searchButtonVisibility,\n searchButton,\n className,\n}) => {\n const { signedIn, logOut } = sessionState;\n const formRef = useRef<HTMLFormElement>(null);\n\n const headerLinkClasses =\n \"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 const dropdownMenuLinkClasses =\n \"block p-8 ui-text-menu3 font-semibold text-neutral-1000 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 rounded-lg\";\n\n const onClickLogout = (e: MouseEvent) => {\n e.preventDefault();\n formRef.current?.submit();\n };\n\n const DashboardLink = ({ className }: { className: string }) => (\n <a href=\"/dashboard\" className={className}>\n Dashboard\n </a>\n );\n\n const LogoutForm = (\n <form ref={formRef} method=\"post\" action={logOut.href} className=\"hidden\">\n <input name=\"_method\" value=\"delete\" type=\"hidden\" />\n <input name=\"authenticity_token\" value={logOut.token} type=\"hidden\" />\n </form>\n );\n\n return (\n <nav\n className={cn(\n \"flex md:flex-1 md:items-center md:justify-end flex-col md:flex-row border-t-[1px] border-neutral-300 md:border-t-0 md:gap-
|
|
1
|
+
{"version":3,"sources":["../../../src/core/Header/HeaderLinks.tsx"],"sourcesContent":["import React, { MouseEvent, useRef } from \"react\";\nimport { HeaderProps } from \"../Header\";\nimport Icon from \"../Icon\";\nimport LinkButton from \"../LinkButton\";\nimport cn from \"../utils/cn\";\nimport DropdownMenu from \"../DropdownMenu\";\n\nconst testSessionState = {\n signedIn: false,\n logOut: {\n token: \"0000\",\n href: \"accounts/sign_out\",\n },\n accountName: \"Ably\",\n};\n\nexport const HeaderLinks: React.FC<\n Pick<\n HeaderProps,\n | \"sessionState\"\n | \"headerLinks\"\n | \"searchButtonVisibility\"\n | \"searchButton\"\n | \"className\"\n >\n> = ({\n sessionState = testSessionState,\n headerLinks,\n searchButtonVisibility,\n searchButton,\n className,\n}) => {\n const { signedIn, logOut } = sessionState;\n const formRef = useRef<HTMLFormElement>(null);\n\n const headerLinkClasses =\n \"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 const dropdownMenuLinkClasses =\n \"block p-8 ui-text-menu3 font-semibold text-neutral-1000 dark:text-neutral-300 hover:bg-neutral-100 dark:hover:bg-neutral-1200 active:bg-neutral-200 dark:active:bg-neutral-1100 rounded-lg\";\n\n const onClickLogout = (e: MouseEvent) => {\n e.preventDefault();\n formRef.current?.submit();\n };\n\n const DashboardLink = ({ className }: { className: string }) => (\n <a href=\"/dashboard\" className={className}>\n Dashboard\n </a>\n );\n\n const LogoutForm = (\n <form ref={formRef} method=\"post\" action={logOut.href} className=\"hidden\">\n <input name=\"_method\" value=\"delete\" type=\"hidden\" />\n <input name=\"authenticity_token\" value={logOut.token} type=\"hidden\" />\n </form>\n );\n\n return (\n <nav\n className={cn(\n \"flex md:flex-1 md:items-center md:justify-end flex-col md:flex-row border-t-[1px] border-neutral-300 md:border-t-0 md:gap-16 pt-12 pb-16 md:py-0\",\n className,\n )}\n >\n {signedIn && (\n <>\n {LogoutForm}\n <div className=\"block md:hidden\">\n <div className=\"flex flex-col border-b-[1px] border-neutral-300 px-16 pb-12 mb-12\">\n <span className=\"py-12 ui-text-sub-header text-[18px] text-neutral-700 dark:text-neutral-600 font-bold\">\n {sessionState.accountName}\n </span>\n {<DashboardLink className={headerLinkClasses} />}\n </div>\n </div>\n </>\n )}\n\n {headerLinks?.map(({ href, label, external }) => (\n <a\n key={href}\n className={cn(\n headerLinkClasses,\n \"flex items-center gap-6 px-16 md:px-0 leading-none\",\n )}\n href={href}\n target={external ? \"_blank\" : undefined}\n rel={external ? \"noreferrer noopener\" : undefined}\n >\n {label}\n {external && (\n <Icon name=\"icon-gui-arrow-top-right-on-square-mini\" size=\"20px\" />\n )}\n </a>\n ))}\n\n {searchButtonVisibility !== \"mobile\" ? searchButton : null}\n {signedIn ? (\n <>\n <div className=\"hidden md:block relative\">\n <DropdownMenu>\n <DropdownMenu.Trigger\n description={`Account menu for ${sessionState.accountName}`}\n >\n <span className=\"block text-ellipsis overflow-hidden whitespace-nowrap w-full max-w-[150px] leading-normal\">\n {sessionState.accountName}\n </span>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content\n anchorPosition=\"right\"\n contentClassNames=\"w-[240px] mt-[12px]\"\n >\n <div className=\"p-8\">\n {<DashboardLink className={dropdownMenuLinkClasses} />}\n <a\n onClick={onClickLogout}\n href=\"#\"\n className={dropdownMenuLinkClasses}\n >\n Logout\n </a>\n </div>\n </DropdownMenu.Content>\n </DropdownMenu>\n </div>\n <div className=\"block md:hidden px-16 pt-16 pb-0\">\n <LinkButton\n onClick={onClickLogout}\n variant=\"secondary\"\n className=\"w-full md:ui-button-secondary-xs\"\n aria-label=\"Logout\"\n rightIcon=\"icon-gui-arrow-right-end-on-rectangle-outline\"\n >\n Logout\n </LinkButton>\n </div>\n </>\n ) : (\n <div className=\"flex gap-16 pt-12 md:py-0 px-16 md:px-0\">\n <LinkButton\n href=\"/login\"\n variant=\"secondary\"\n className=\"flex-1 md:flex-none md:ui-button-secondary-xs hover:text-neutral-1300 dark:hover:text-neutral-000\"\n >\n Login\n </LinkButton>\n <LinkButton\n href=\"/sign-up\"\n variant=\"primary\"\n className=\"flex-1 md:flex-none md:ui-button-primary-xs hover:text-neutral-000 dark:hover:text-neutral-1300\"\n >\n Start free\n </LinkButton>\n </div>\n )}\n </nav>\n );\n};\n"],"names":["React","useRef","Icon","LinkButton","cn","DropdownMenu","testSessionState","signedIn","logOut","token","href","accountName","HeaderLinks","sessionState","headerLinks","searchButtonVisibility","searchButton","className","formRef","headerLinkClasses","dropdownMenuLinkClasses","onClickLogout","e","preventDefault","current","submit","DashboardLink","a","LogoutForm","form","ref","method","action","input","name","value","type","nav","div","span","map","label","external","key","target","undefined","rel","size","Trigger","description","Content","anchorPosition","contentClassNames","onClick","variant","aria-label","rightIcon"],"mappings":"AAAA,OAAOA,OAAqBC,MAAM,KAAQ,OAAQ,AAElD,QAAOC,SAAU,SAAU,AAC3B,QAAOC,eAAgB,eAAgB,AACvC,QAAOC,OAAQ,aAAc,AAC7B,QAAOC,iBAAkB,iBAAkB,CAE3C,MAAMC,iBAAmB,CACvBC,SAAU,MACVC,OAAQ,CACNC,MAAO,OACPC,KAAM,mBACR,EACAC,YAAa,MACf,CAEA,QAAO,MAAMC,YAST,CAAC,CACHC,aAAeP,gBAAgB,CAC/BQ,WAAW,CACXC,sBAAsB,CACtBC,YAAY,CACZC,SAAS,CACV,IACC,KAAM,CAAEV,QAAQ,CAAEC,MAAM,CAAE,CAAGK,aAC7B,MAAMK,QAAUjB,OAAwB,MAExC,MAAMkB,kBACJ,oQAEF,MAAMC,wBACJ,6LAEF,MAAMC,cAAgB,AAACC,IACrBA,EAAEC,cAAc,EAChBL,CAAAA,QAAQM,OAAO,EAAEC,QACnB,EAEA,MAAMC,cAAgB,CAAC,CAAET,SAAS,CAAyB,GACzD,oBAACU,KAAEjB,KAAK,aAAaO,UAAWA,WAAW,aAK7C,MAAMW,WACJ,oBAACC,QAAKC,IAAKZ,QAASa,OAAO,OAAOC,OAAQxB,OAAOE,IAAI,CAAEO,UAAU,UAC/D,oBAACgB,SAAMC,KAAK,UAAUC,MAAM,SAASC,KAAK,WAC1C,oBAACH,SAAMC,KAAK,qBAAqBC,MAAO3B,OAAOC,KAAK,CAAE2B,KAAK,YAI/D,OACE,oBAACC,OACCpB,UAAWb,GACT,mJACAa,YAGDV,UACC,wCACGqB,WACD,oBAACU,OAAIrB,UAAU,mBACb,oBAACqB,OAAIrB,UAAU,qEACb,oBAACsB,QAAKtB,UAAU,yFACbJ,aAAaF,WAAW,EAE1B,oBAACe,eAAcT,UAAWE,uBAMlCL,aAAa0B,IAAI,CAAC,CAAE9B,IAAI,CAAE+B,KAAK,CAAEC,QAAQ,CAAE,GAC1C,oBAACf,KACCgB,IAAKjC,KACLO,UAAWb,GACTe,kBACA,sDAEFT,KAAMA,KACNkC,OAAQF,SAAW,SAAWG,UAC9BC,IAAKJ,SAAW,sBAAwBG,WAEvCJ,MACAC,UACC,oBAACxC,MAAKgC,KAAK,0CAA0Ca,KAAK,WAK/DhC,yBAA2B,SAAWC,aAAe,KACrDT,SACC,wCACE,oBAAC+B,OAAIrB,UAAU,4BACb,oBAACZ,kBACC,oBAACA,aAAa2C,OAAO,EACnBC,YAAa,CAAC,iBAAiB,EAAEpC,aAAaF,WAAW,CAAC,CAAC,EAE3D,oBAAC4B,QAAKtB,UAAU,6FACbJ,aAAaF,WAAW,GAG7B,oBAACN,aAAa6C,OAAO,EACnBC,eAAe,QACfC,kBAAkB,uBAElB,oBAACd,OAAIrB,UAAU,OACZ,oBAACS,eAAcT,UAAWG,0BAC3B,oBAACO,KACC0B,QAAShC,cACTX,KAAK,IACLO,UAAWG,yBACZ,cAOT,oBAACkB,OAAIrB,UAAU,oCACb,oBAACd,YACCkD,QAAShC,cACTiC,QAAQ,YACRrC,UAAU,mCACVsC,aAAW,SACXC,UAAU,iDACX,YAML,oBAAClB,OAAIrB,UAAU,2CACb,oBAACd,YACCO,KAAK,SACL4C,QAAQ,YACRrC,UAAU,qGACX,SAGD,oBAACd,YACCO,KAAK,WACL4C,QAAQ,UACRrC,UAAU,mGACX,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";import{COLLAPSE_TRIGGER_DISTANCE}from"./Notice/component";const FLEXIBLE_DESKTOP_CLASSES="hidden md:flex flex-1 items-center h-full";const MAX_MOBILE_MENU_WIDTH="560px";const Header=({className,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[bannerVisible,setBannerVisible]=useState(
|
|
1
|
+
import React,{useState,useEffect,useRef,useMemo}from"react";import Icon from"./Icon";import cn from"./utils/cn";import Logo from"./Logo";import{componentMaxHeight,HEADER_BOTTOM_MARGIN,HEADER_HEIGHT}from"./utils/heights";import{HeaderLinks}from"./Header/HeaderLinks";import throttle from"lodash.throttle";import{COLLAPSE_TRIGGER_DISTANCE}from"./Notice/component";const FLEXIBLE_DESKTOP_CLASSES="hidden md:flex flex-1 items-center h-full";const MAX_MOBILE_MENU_WIDTH="560px";const Header=({className,isNoticeVisible=false,searchBar,searchButton,logoHref,headerLinks,headerLinksClassName,nav,mobileNav,sessionState,themedScrollpoints=[],searchButtonVisibility="all",location})=>{const[showMenu,setShowMenu]=useState(false);const[fadingOut,setFadingOut]=useState(false);const[scrollpointClasses,setScrollpointClasses]=useState("");const[bannerVisible,setBannerVisible]=useState(isNoticeVisible);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(()=>{if(location&&showMenu){closeMenu()}},[location]);useEffect(()=>{const handleScroll=()=>{setBannerVisible(window.scrollY<=COLLAPSE_TRIGGER_DISTANCE&&isNoticeVisible);for(const scrollpoint of themedScrollpoints){const element=document.getElementById(scrollpoint.id);if(element){const rect=element.getBoundingClientRect();if(rect.top<=HEADER_HEIGHT&&rect.bottom>=HEADER_HEIGHT){setScrollpointClasses(scrollpoint.className);return}}}};const throttledHandleScroll=throttle(handleScroll,150);handleScroll();window.addEventListener("scroll",throttledHandleScroll);return()=>window.removeEventListener("scroll",throttledHandleScroll)},[themedScrollpoints]);const wrappedSearchButton=useMemo(()=>searchButton?React.createElement("div",{className:"text-neutral-1300 dark:text-neutral-000 flex items-center"},searchButton):null,[searchButton]);return React.createElement(React.Fragment,null,React.createElement("header",{role:"banner",className:cn("fixed left-0 top-0 w-full z-50 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 dark:border-neutral-1000 transition-colors px-24 md:px-64",scrollpointClasses,{"md:top-auto":bannerVisible}),style:{height:HEADER_HEIGHT}},React.createElement("div",{className:cn("flex items-center h-full",className)},React.createElement("nav",{className:"flex flex-1 h-full items-center"},["light","dark"].map(theme=>React.createElement(Logo,{key:theme,href:logoHref,theme:theme,additionalLinkAttrs:{className:cn("h-full focus-base rounded mr-32 w-[96px]",{"flex dark:hidden":theme==="light","hidden dark:flex":theme==="dark"})}})),React.createElement("div",{className:FLEXIBLE_DESKTOP_CLASSES},nav)),React.createElement("div",{className:"flex md:hidden flex-1 items-center justify-end gap-24 h-full"},searchButtonVisibility!=="desktop"?wrappedSearchButton:null,React.createElement("button",{className:"cursor-pointer focus-base rounded flex items-center p-0",onClick:()=>setShowMenu(!showMenu),"aria-expanded":showMenu,"aria-controls":"mobile-menu","aria-label":"Toggle menu"},React.createElement(Icon,{name:showMenu?"icon-gui-x-mark-outline":"icon-gui-bars-3-outline",additionalCSS:"text-neutral-1300 dark:text-neutral-000",size:"1.5rem"}))),searchBar?React.createElement("div",{className:cn(FLEXIBLE_DESKTOP_CLASSES,"justify-center")},searchBar):null,React.createElement(HeaderLinks,{className:cn(FLEXIBLE_DESKTOP_CLASSES,headerLinksClassName),headerLinks:headerLinks,sessionState:sessionState,searchButton:wrappedSearchButton,searchButtonVisibility:searchButtonVisibility}))),showMenu?React.createElement(React.Fragment,null,React.createElement("div",{className:cn("fixed inset-0 bg-neutral-1300 dark:bg-neutral-1300 z-40",{"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]":!fadingOut,"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]":fadingOut}),onClick:closeMenu,onKeyDown:e=>e.key==="Escape"&&closeMenu(),role:"presentation"}),React.createElement("div",{id:"mobile-menu",className:"md:hidden fixed flex flex-col top-[76px] overflow-y-hidden mx-12 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-50",style:{maxWidth:MAX_MOBILE_MENU_WIDTH,maxHeight:componentMaxHeight(HEADER_HEIGHT,HEADER_BOTTOM_MARGIN)},ref:menuRef,role:"navigation"},mobileNav,React.createElement(HeaderLinks,{headerLinks:headerLinks,sessionState:sessionState}))):null)};export default Header;
|
|
2
2
|
//# sourceMappingURL=Header.js.map
|
package/core/Header.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/Header.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, ReactNode, useMemo } from \"react\";\nimport Icon from \"./Icon\";\nimport cn from \"./utils/cn\";\nimport Logo from \"./Logo\";\nimport {\n componentMaxHeight,\n HEADER_BOTTOM_MARGIN,\n HEADER_HEIGHT,\n} from \"./utils/heights\";\nimport { HeaderLinks } from \"./Header/HeaderLinks\";\nimport throttle from \"lodash.throttle\";\nimport { Theme } from \"./styles/colors/types\";\nimport { COLLAPSE_TRIGGER_DISTANCE } from \"./Notice/component\";\n\nexport type ThemedScrollpoint = {\n id: string;\n className: string;\n};\n\n/**\n * Represents the state of the user session in the header.\n */\nexport type HeaderSessionState = {\n /**\n * Indicates if the user is signed in.\n */\n signedIn: boolean;\n\n /**\n * Information required to log out the user.\n */\n logOut: {\n /**\n * Token used for logging out.\n */\n token: string;\n\n /**\n * URL to log out the user.\n */\n href: string;\n };\n\n /**\n * Name of the user's account.\n */\n accountName: string;\n};\n\n/**\n * Props for the Header component.\n */\nexport type HeaderProps = {\n /**\n * Optional classnames to add to the header\n */\n className?: string;\n /**\n * 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 className,\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 [bannerVisible, setBannerVisible] = useState(true);\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 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 setBannerVisible(window.scrollY <= COLLAPSE_TRIGGER_DISTANCE);\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 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 \"md:top-0 transition-transform duration-300 ease-in-out\":\n !bannerVisible,\n },\n )}\n style={{ height: HEADER_HEIGHT }}\n >\n <div className={cn(\"flex items-center h-full\", className)}>\n <nav className=\"flex flex-1 h-full items-center\">\n {([\"light\", \"dark\"] as Theme[]).map((theme) => (\n <Logo\n key={theme}\n href={logoHref}\n theme={theme}\n additionalLinkAttrs={{\n className: cn(\"h-full focus-base rounded mr-32 w-[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","COLLAPSE_TRIGGER_DISTANCE","FLEXIBLE_DESKTOP_CLASSES","MAX_MOBILE_MENU_WIDTH","Header","className","searchBar","searchButton","logoHref","headerLinks","nav","mobileNav","sessionState","themedScrollpoints","searchButtonVisibility","showMenu","setShowMenu","fadingOut","setFadingOut","scrollpointClasses","setScrollpointClasses","bannerVisible","setBannerVisible","menuRef","closeMenu","setTimeout","handleResize","window","innerWidth","addEventListener","removeEventListener","document","body","classList","add","remove","handleScroll","scrollpoint","element","getElementById","id","rect","getBoundingClientRect","top","bottom","scrollY","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\";\nimport { COLLAPSE_TRIGGER_DISTANCE } from \"./Notice/component\";\n\nexport type ThemedScrollpoint = {\n id: string;\n className: string;\n};\n\n/**\n * Represents the state of the user session in the header.\n */\nexport type HeaderSessionState = {\n /**\n * Indicates if the user is signed in.\n */\n signedIn: boolean;\n\n /**\n * Information required to log out the user.\n */\n logOut: {\n /**\n * Token used for logging out.\n */\n token: string;\n\n /**\n * URL to log out the user.\n */\n href: string;\n };\n\n /**\n * Name of the user's account.\n */\n accountName: string;\n};\n\n/**\n * Props for the Header component.\n */\nexport type HeaderProps = {\n /**\n * Optional classnames to add to the header\n */\n className?: string;\n /**\n * Indicates if the notice banner is visible.\n */\n isNoticeVisible?: boolean;\n /**\n * Optional search bar element.\n */\n searchBar?: ReactNode;\n\n /**\n * Optional search button element.\n */\n searchButton?: ReactNode;\n\n /**\n * URL for the logo link.\n */\n logoHref?: string;\n\n /**\n * Array of header links.\n */\n headerLinks?: {\n /**\n * URL for the link.\n */\n href: string;\n\n /**\n * Label for the link.\n */\n label: string;\n\n /**\n * Indicates if the link should open in a new tab.\n */\n external?: boolean;\n }[];\n\n /**\n * Optional classname for styling the header links container.\n */\n headerLinksClassName?: string;\n\n /**\n * Optional desktop navigation element.\n */\n nav?: ReactNode;\n\n /**\n * Optional mobile navigation element.\n */\n mobileNav?: ReactNode;\n\n /**\n * State of the user session.\n */\n sessionState?: HeaderSessionState;\n\n /**\n * Array of themed scrollpoints. The header will change its appearance based on the scrollpoint in view.\n */\n themedScrollpoints?: ThemedScrollpoint[];\n\n /**\n * Visibility setting for the search button.\n * - \"all\": Visible on all devices.\n * - \"desktop\": Visible only on desktop devices.\n * - \"mobile\": Visible only on mobile devices.\n */\n searchButtonVisibility?: \"all\" | \"desktop\" | \"mobile\";\n\n /**\n * Optional location object to detect location changes.\n */\n location?: Location;\n};\n\nconst FLEXIBLE_DESKTOP_CLASSES = \"hidden md:flex flex-1 items-center h-full\";\n\n/**\n * Maximum width before the menu expanded into full width\n */\nconst MAX_MOBILE_MENU_WIDTH = \"560px\";\n\nconst Header: React.FC<HeaderProps> = ({\n className,\n isNoticeVisible = false,\n searchBar,\n searchButton,\n logoHref,\n headerLinks,\n headerLinksClassName,\n nav,\n mobileNav,\n sessionState,\n themedScrollpoints = [],\n searchButtonVisibility = \"all\",\n location,\n}) => {\n const [showMenu, setShowMenu] = useState(false);\n const [fadingOut, setFadingOut] = useState(false);\n const [scrollpointClasses, setScrollpointClasses] = useState<string>(\"\");\n const [bannerVisible, setBannerVisible] = useState(isNoticeVisible);\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 window.addEventListener(\"resize\", handleResize);\n return () => window.removeEventListener(\"resize\", handleResize);\n }, []);\n\n useEffect(() => {\n if (showMenu) {\n document.body.classList.add(\"overflow-hidden\");\n } else {\n document.body.classList.remove(\"overflow-hidden\");\n }\n\n // Cleanup on unmount\n return () => {\n document.body.classList.remove(\"overflow-hidden\");\n };\n }, [showMenu]);\n\n // Close menu when location changes\n useEffect(() => {\n if (location && showMenu) {\n closeMenu();\n }\n }, [location]);\n\n useEffect(() => {\n const handleScroll = () => {\n setBannerVisible(\n window.scrollY <= COLLAPSE_TRIGGER_DISTANCE && isNoticeVisible,\n );\n for (const scrollpoint of themedScrollpoints) {\n const element = document.getElementById(scrollpoint.id);\n if (element) {\n const rect = element.getBoundingClientRect();\n if (rect.top <= HEADER_HEIGHT && rect.bottom >= HEADER_HEIGHT) {\n setScrollpointClasses(scrollpoint.className);\n return;\n }\n }\n }\n };\n\n const throttledHandleScroll = throttle(handleScroll, 150);\n\n handleScroll();\n\n window.addEventListener(\"scroll\", throttledHandleScroll);\n return () => window.removeEventListener(\"scroll\", throttledHandleScroll);\n }, [themedScrollpoints]);\n\n const wrappedSearchButton = useMemo(\n () =>\n searchButton ? (\n <div className=\"text-neutral-1300 dark:text-neutral-000 flex items-center\">\n {searchButton}\n </div>\n ) : null,\n [searchButton],\n );\n\n return (\n <>\n <header\n role=\"banner\"\n className={cn(\n \"fixed left-0 top-0 w-full z-50 bg-neutral-000 dark:bg-neutral-1300 border-b border-neutral-300 dark:border-neutral-1000 transition-colors px-24 md:px-64\",\n scrollpointClasses,\n {\n \"md:top-auto\": bannerVisible,\n },\n )}\n style={{ height: HEADER_HEIGHT }}\n >\n <div className={cn(\"flex items-center h-full\", className)}>\n <nav className=\"flex flex-1 h-full items-center\">\n {([\"light\", \"dark\"] as Theme[]).map((theme) => (\n <Logo\n key={theme}\n href={logoHref}\n theme={theme}\n additionalLinkAttrs={{\n className: cn(\"h-full focus-base rounded mr-32 w-[96px]\", {\n \"flex dark:hidden\": theme === \"light\",\n \"hidden dark:flex\": theme === \"dark\",\n }),\n }}\n />\n ))}\n <div className={FLEXIBLE_DESKTOP_CLASSES}>{nav}</div>\n </nav>\n <div className=\"flex md:hidden flex-1 items-center justify-end gap-24 h-full\">\n {searchButtonVisibility !== \"desktop\" ? wrappedSearchButton : null}\n <button\n className=\"cursor-pointer focus-base rounded flex items-center p-0\"\n onClick={() => setShowMenu(!showMenu)}\n aria-expanded={showMenu}\n aria-controls=\"mobile-menu\"\n aria-label=\"Toggle menu\"\n >\n <Icon\n name={\n showMenu\n ? \"icon-gui-x-mark-outline\"\n : \"icon-gui-bars-3-outline\"\n }\n additionalCSS=\"text-neutral-1300 dark:text-neutral-000\"\n size=\"1.5rem\"\n />\n </button>\n </div>\n {searchBar ? (\n <div className={cn(FLEXIBLE_DESKTOP_CLASSES, \"justify-center\")}>\n {searchBar}\n </div>\n ) : null}\n <HeaderLinks\n className={cn(FLEXIBLE_DESKTOP_CLASSES, headerLinksClassName)}\n headerLinks={headerLinks}\n sessionState={sessionState}\n searchButton={wrappedSearchButton}\n searchButtonVisibility={searchButtonVisibility}\n />\n </div>\n </header>\n {showMenu ? (\n <>\n <div\n className={cn(\n \"fixed inset-0 bg-neutral-1300 dark:bg-neutral-1300 z-40\",\n {\n \"animate-[fade-in-ten-percent_150ms_ease-in-out_forwards]\":\n !fadingOut,\n \"animate-[fade-out-ten-percent_150ms_ease-in-out_forwards]\":\n fadingOut,\n },\n )}\n onClick={closeMenu}\n onKeyDown={(e) => e.key === \"Escape\" && closeMenu()}\n role=\"presentation\"\n />\n <div\n id=\"mobile-menu\"\n className=\"md:hidden fixed flex flex-col top-[76px] overflow-y-hidden mx-12 right-0 w-[calc(100%-24px)] bg-neutral-000 dark:bg-neutral-1300 rounded-2xl ui-shadow-lg-medium z-50\"\n style={{\n maxWidth: MAX_MOBILE_MENU_WIDTH,\n maxHeight: componentMaxHeight(\n HEADER_HEIGHT,\n HEADER_BOTTOM_MARGIN,\n ),\n }}\n ref={menuRef}\n role=\"navigation\"\n >\n {mobileNav}\n <HeaderLinks\n headerLinks={headerLinks}\n sessionState={sessionState}\n />\n </div>\n </>\n ) : null}\n </>\n );\n};\n\nexport default Header;\n"],"names":["React","useState","useEffect","useRef","useMemo","Icon","cn","Logo","componentMaxHeight","HEADER_BOTTOM_MARGIN","HEADER_HEIGHT","HeaderLinks","throttle","COLLAPSE_TRIGGER_DISTANCE","FLEXIBLE_DESKTOP_CLASSES","MAX_MOBILE_MENU_WIDTH","Header","className","isNoticeVisible","searchBar","searchButton","logoHref","headerLinks","headerLinksClassName","nav","mobileNav","sessionState","themedScrollpoints","searchButtonVisibility","location","showMenu","setShowMenu","fadingOut","setFadingOut","scrollpointClasses","setScrollpointClasses","bannerVisible","setBannerVisible","menuRef","closeMenu","setTimeout","handleResize","window","innerWidth","addEventListener","removeEventListener","document","body","classList","add","remove","handleScroll","scrollY","scrollpoint","element","getElementById","id","rect","getBoundingClientRect","top","bottom","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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"}
|