diff --git a/js/documentation/pages/_app.tsx b/js/documentation/pages/_app.tsx
index 356ec612a1..b7cb23e843 100644
--- a/js/documentation/pages/_app.tsx
+++ b/js/documentation/pages/_app.tsx
@@ -42,6 +42,7 @@ import MainContent from '@src/components/MainContent'
import PageFooter from '@src/components/PageFooter'
import {
ContentContainer,
+ MainColumn,
PageGrid,
SideCarContainer,
SideNavContainer,
@@ -56,6 +57,7 @@ import {
ROOT_TITLE,
} from '@src/consts'
import { NavDataProvider } from '@src/contexts/NavDataContext'
+import { RestNavProvider } from '@src/contexts/RestNavContext'
import { collectHeadings } from '@src/markdoc/utils/parseHeadings'
import { getNavData } from '@src/NavData'
@@ -169,29 +171,35 @@ function App({ Component, pageProps = {}, swrConfig }: MyAppProps) {
)}
-
-
-
-
-
- {isClient ? (
- Loading table of contents...}>
-
-
- ) : (
-
+
+
+
+
+ {toc?.length > 0 && (
+
+ {isClient ? (
+ Loading table of contents...}
+ >
+
+
+ ) : (
+
+ )}
+
)}
-
+
)}
@@ -211,13 +219,15 @@ function App({ Component, pageProps = {}, swrConfig }: MyAppProps) {
-
-
-
- {app}
-
-
-
+
+
+
+
+ {app}
+
+
+
+
diff --git a/js/documentation/src/components/DocsSearch.tsx b/js/documentation/src/components/DocsSearch.tsx
new file mode 100644
index 0000000000..28f7ed991c
--- /dev/null
+++ b/js/documentation/src/components/DocsSearch.tsx
@@ -0,0 +1,184 @@
+import {
+ AiSparkleFilledIcon,
+ Button,
+ IconFrame,
+ SearchIcon,
+} from '@pluralsh/design-system'
+
+import styled from 'styled-components'
+
+import { mqs } from './Breakpoints'
+
+function SearchTrigger({ compact = false }: { compact?: boolean }) {
+ if (compact) {
+ return (
+ }
+ className="docs-search-trigger"
+ />
+ )
+ }
+
+ return (
+
+
+ Search docs...
+ ⌘K
+
+ )
+}
+
+function AskAiTrigger({ compact = false }: { compact?: boolean }) {
+ if (compact) {
+ return (
+ }
+ className="docs-ai-trigger"
+ />
+ )
+ }
+
+ return (
+ }
+ >
+ Ask AI
+
+ )
+}
+
+export function DocsSearch() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
+
+const AskAiButton = styled(Button)({
+ height: 40,
+ minHeight: 40,
+})
+
+const SearchBar = styled.button(({ theme }) => ({
+ display: 'flex',
+ alignItems: 'center',
+ gap: theme.spacing.small,
+ width: 220,
+ [mqs.threeColumn]: {
+ width: 360,
+ maxWidth: '32vw',
+ },
+ height: 40,
+ padding: `0 ${theme.spacing.xsmall}px 0 ${theme.spacing.medium}px`,
+ border: theme.borders.input,
+ borderRadius: theme.borderRadiuses.medium,
+ background: theme.colors['fill-one'],
+ color: theme.colors['text-xlight'],
+ cursor: 'pointer',
+ ...theme.partials.text.body2,
+ '.searchIcon': {
+ flexShrink: 0,
+ color: theme.colors['text-light'],
+ },
+ '.placeholder': {
+ flex: 1,
+ minWidth: 0,
+ textAlign: 'left',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'nowrap',
+ },
+ '&:hover': {
+ background: theme.colors['fill-one-hover'],
+ color: theme.colors['text-light'],
+ },
+ '&:focus, &:focus-visible': {
+ outline: 'none',
+ },
+ '&:focus-visible': {
+ ...theme.partials.focus.default,
+ },
+}))
+
+const Kbd = styled.span(({ theme }) => ({
+ ...theme.partials.text.caption,
+ display: 'inline-flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ flexShrink: 0,
+ minWidth: 28,
+ height: 22,
+ padding: `0 ${theme.spacing.xsmall}px`,
+ borderRadius: theme.borderRadiuses.medium,
+ background: theme.colors['fill-two'],
+ color: theme.colors['text-xlight'],
+}))
+
+const CenterCluster = styled.div(({ theme }) => ({
+ display: 'none',
+ [mqs.fullHeader]: {
+ display: 'flex',
+ alignItems: 'center',
+ gap: theme.spacing.small,
+ position: 'absolute',
+ left: '50%',
+ top: '50%',
+ transform: 'translate(-50%, -50%)',
+ zIndex: 1,
+ },
+}))
+
+const ToolbarCluster = styled.div(({ theme }) => ({
+ display: 'flex',
+ alignItems: 'center',
+ gap: theme.spacing.xsmall,
+ [mqs.fullHeader]: {
+ display: 'none',
+ },
+}))
+
+const WideAskAi = styled.div({
+ display: 'none',
+ [mqs.threeColumn]: {
+ display: 'block',
+ },
+})
+
+const NarrowAskAi = styled.div({
+ display: 'block',
+ [mqs.threeColumn]: {
+ display: 'none',
+ },
+})
diff --git a/js/documentation/src/components/ExternalScripts.tsx b/js/documentation/src/components/ExternalScripts.tsx
index daad5052d6..0d6b7ce632 100644
--- a/js/documentation/src/components/ExternalScripts.tsx
+++ b/js/documentation/src/components/ExternalScripts.tsx
@@ -102,13 +102,27 @@ function KapaWidget() {
src="https://widget.kapa.ai/kapa-widget.bundle.js"
data-website-id="8288b978-8aca-4409-9cbd-de12c446cf07"
data-project-name="Plural"
- data-view-mode="sidebar"
+ data-view-mode="default"
+ data-button-hide="true"
+ data-launcher-button-hidden="true"
data-modal-open-on-command-k="true"
+ data-modal-command-k-search-mode-default="true"
data-search-mode-enabled="true"
+ data-modal-override-open-selector-search=".docs-search-trigger"
+ data-modal-override-open-selector=".docs-ai-trigger"
data-mcp-enabled="true"
data-mcp-server-url="https://plural.mcp.kapa.ai"
data-project-color="#5D63F4"
data-project-logo="https://docs.plural.sh/favicon-192.png"
+ data-kapa-branding-hidden="true"
+ data-color-scheme="dark"
+ data-surface-color-dark="#12151B"
+ data-surface-elevated-color-dark="#1B1F27"
+ data-surface-hover-color-dark="#252932"
+ data-text-color-dark="#EEF0F1"
+ data-text-muted-color-dark="#A1A5B0"
+ data-border-color-dark="#303540"
+ data-anchor-color-dark="#5D63F4"
/>
)
}
diff --git a/js/documentation/src/components/FullNav.tsx b/js/documentation/src/components/FullNav.tsx
index 77473face1..14bd00cdb0 100644
--- a/js/documentation/src/components/FullNav.tsx
+++ b/js/documentation/src/components/FullNav.tsx
@@ -72,6 +72,8 @@ export const NavButtons = styled(NavButtonsUnstyled)<{ desktop: boolean }>(
export const NavWrap = styled.div((_) => ({
position: 'relative',
flexGrow: 1,
+ flex: 1,
+ minHeight: 0,
}))
function NavButton({
@@ -102,7 +104,7 @@ export function FullNav({
const previousPath = usePrevious(thisPath)
useEffect(() => {
- if (thisPath !== previousPath) {
+ if (previousPath && thisPath !== previousPath) {
if (setIsOpen) {
setIsOpen(false)
}
diff --git a/js/documentation/src/components/GlobalStyles.tsx b/js/documentation/src/components/GlobalStyles.tsx
index 2f7704bf84..b74c552985 100644
--- a/js/documentation/src/components/GlobalStyles.tsx
+++ b/js/documentation/src/components/GlobalStyles.tsx
@@ -22,6 +22,8 @@ const GlobalStyles = createGlobalStyle(({ theme }) => ({
':root': {
'--top-nav-height': '72px',
'--menu-extra-bpad': '0px',
+ '--docs-sidenav-width': '306px',
+ '--docs-sidecar-width': '220px',
},
'a:any-link': {
color: 'unset',
@@ -39,7 +41,7 @@ const GlobalStyles = createGlobalStyle(({ theme }) => ({
},
body: {
margin: 0,
- overflowX: 'hidden',
+ overflowX: 'clip',
color: theme.colors.text,
backgroundColor: theme.colors['fill-zero'],
...fillAvailable('minHeight'),
diff --git a/js/documentation/src/components/MainContent.tsx b/js/documentation/src/components/MainContent.tsx
index e2f32fbdc2..9f90a194c2 100644
--- a/js/documentation/src/components/MainContent.tsx
+++ b/js/documentation/src/components/MainContent.tsx
@@ -15,12 +15,21 @@ import Breadcrumbs from './Breadcrumbs'
import { FooterLink } from './PageFooter'
import { PagePropsContext } from './PagePropsContext'
-const ContentWrapper = styled.div(({ theme }) => ({
- marginTop: theme.spacing.xlarge,
+const ContentWrapper = styled.div((_) => ({
+ minWidth: 0,
}))
const BreadcrumbsWrapper = styled.div(({ theme }) => ({
- marginTop: theme.spacing.xlarge,
+ display: 'flex',
+ alignItems: 'center',
+ width: '100%',
+ minWidth: 0,
+ minHeight: 40,
+ marginBottom: theme.spacing.large,
+ '& > *': {
+ minWidth: 0,
+ width: '100%',
+ },
}))
const Title = styled.h1(({ theme }) => ({
diff --git a/js/documentation/src/components/MobileMenu.tsx b/js/documentation/src/components/MobileMenu.tsx
index 4ed11f12be..c9909f450d 100644
--- a/js/documentation/src/components/MobileMenu.tsx
+++ b/js/documentation/src/components/MobileMenu.tsx
@@ -1,15 +1,19 @@
-import { DiscordIcon } from '@pluralsh/design-system'
+import { useRef, useState } from 'react'
+
+import { ArrowLeftIcon, Button, DiscordIcon } from '@pluralsh/design-system'
import styled from 'styled-components'
import { useIsomorphicLayoutEffect } from 'usehooks-ts'
import { DISCORD_LINK } from '@src/consts'
+import { useRestNav } from '@src/contexts/RestNavContext'
-import { FullNav, type NavContextValue } from './FullNav'
+import { FullNav, NavButtons, type NavContextValue } from './FullNav'
import GithubStars from './GithubStars'
import useScrollLock from './hooks/useScrollLock'
import { MainLink } from './PageHeader'
import { SocialLink } from './PageHeaderButtons'
+import { SidebarNav } from './RestApiReference/SidebarNav'
import { TopHeading } from './SideNav'
type MobileMenuProps = NavContextValue & {
@@ -73,6 +77,20 @@ export const PluralMenu = styled(PluralMenuContent)(
})
)
+const Panel = styled.div<{ $hidden: boolean }>(({ $hidden }) => ({
+ display: $hidden ? 'none' : 'flex',
+ flexDirection: 'column',
+ flex: 1,
+ minHeight: 0,
+}))
+
+const DocsNavWrap = styled.div({
+ display: 'flex',
+ flexDirection: 'column',
+ flex: 1,
+ minHeight: 0,
+})
+
const Content = styled.div(({ theme }) => ({
pointerEvents: 'all',
position: 'absolute',
@@ -84,23 +102,66 @@ const Content = styled.div(({ theme }) => ({
background: theme.colors['fill-one'],
display: 'flex',
flexDirection: 'column',
+ minHeight: 0,
+ overflow: 'hidden',
+ [`${NavButtons}`]: {
+ position: 'relative',
+ zIndex: 1,
+ flexShrink: 0,
+ },
}))
function MobileMenu({ isOpen, setIsOpen, className }: MobileMenuProps) {
const [, setScrollLock] = useScrollLock(false)
+ const restNav = useRestNav()
+ const [showDocsMenu, setShowDocsMenu] = useState(false)
useIsomorphicLayoutEffect(() => {
setScrollLock(isOpen)
}, [isOpen, setScrollLock])
+ const wasOpen = useRef(isOpen)
+
+ useIsomorphicLayoutEffect(() => {
+ if (isOpen && !wasOpen.current) {
+ setShowDocsMenu(false)
+ }
+ wasOpen.current = isOpen
+ }, [isOpen])
+
+ const showRestNav = !!restNav && !showDocsMenu
+
return (
-
+ {restNav && (
+
+
+ }
+ onClick={() => setShowDocsMenu(true)}
+ >
+ Docs menu
+
+
+
+
+ )}
+
+
+
+
+
)
diff --git a/js/documentation/src/components/PageGrid.tsx b/js/documentation/src/components/PageGrid.tsx
index e34243bb9a..d8493a92dd 100644
--- a/js/documentation/src/components/PageGrid.tsx
+++ b/js/documentation/src/components/PageGrid.tsx
@@ -2,23 +2,37 @@ import styled from 'styled-components'
import { mqs } from './Breakpoints'
-export const PageGrid = styled.div((_p) => ({
- display: 'flex',
- flexDirection: 'row',
+export const PageGrid = styled.div({
+ display: 'grid',
+ gridTemplateColumns: 'minmax(0, 1fr)',
width: '100%',
- maxWidth: 1588,
- marginLeft: 'auto',
- marginRight: 'auto',
- position: 'relative',
-}))
+ minHeight: 'calc(100vh - var(--top-nav-height))',
+ [mqs.twoColumn]: {
+ gridTemplateColumns: 'var(--docs-sidenav-width) minmax(0, 1fr)',
+ },
+})
export const SideNavContainer = styled.div(({ theme }) => ({
display: 'none',
[mqs.twoColumn]: {
display: 'block',
- flex: '0 0 300px',
- marginRight: 'auto',
- marginLeft: theme.spacing.large,
+ minWidth: 0,
+ backgroundColor: theme.colors['fill-one'],
+ },
+}))
+
+export const MainColumn = styled.div(({ theme }) => ({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'flex-start',
+ minWidth: 0,
+ width: '100%',
+ padding: `0 ${theme.spacing.large}px`,
+ [mqs.twoColumn]: {
+ padding: `0 ${theme.spacing.xlarge}px`,
+ },
+ [mqs.maxWidth]: {
+ padding: '0 64px',
},
}))
@@ -27,25 +41,38 @@ export const SideCarContainer = styled.div(({ theme }) => ({
[mqs.threeColumn]: {
position: 'sticky',
- marginRight: theme.spacing.large,
top: 'var(--top-nav-height)',
- bottom: 0,
+ alignSelf: 'flex-start',
+ flex: '0 0 var(--docs-sidecar-width)',
+ width: 'var(--docs-sidecar-width)',
maxHeight: 'calc(100vh - var(--top-nav-height))',
- flex: '0 0 200px',
+ overflow: 'auto',
display: 'block',
- },
-}))
-
-export const ContentContainer = styled.main(({ theme }) => ({
- flex: '1 1',
- marginRight: theme.spacing.large,
- marginLeft: theme.spacing.large,
- // Don't remove this min width, or it will paradoxically allow
- // the content to stretch wider than the flex container
- minWidth: '100px',
- [mqs.threeColumn]: {
- maxWidth: 896,
- marginRight: theme.spacing.xlarge,
marginLeft: theme.spacing.xlarge,
},
}))
+
+export const ContentContainer = styled.main<{ $wide?: boolean }>(
+ ({ theme, $wide }) => ({
+ flex: '1 1 auto',
+ minWidth: 0,
+ width: '100%',
+ padding: `${theme.spacing.medium}px 0 ${theme.spacing.xxxlarge}px`,
+ ...(!$wide
+ ? {
+ maxWidth: 896,
+ [mqs.threeColumn]: {
+ maxWidth: 960,
+ },
+ [mqs.maxWidth]: {
+ maxWidth: 1120,
+ },
+ }
+ : {
+ maxWidth: 1120,
+ [mqs.maxWidth]: {
+ maxWidth: 1280,
+ },
+ }),
+ })
+)
diff --git a/js/documentation/src/components/PageHeader.tsx b/js/documentation/src/components/PageHeader.tsx
index c431373c38..a2b724c3c6 100644
--- a/js/documentation/src/components/PageHeader.tsx
+++ b/js/documentation/src/components/PageHeader.tsx
@@ -8,8 +8,10 @@ import { useKey } from 'rooks'
import styled from 'styled-components'
import { DISCORD_LINK } from '@src/consts'
+import { getBarePathFromPath } from '@src/utils/text'
import { BreakpointIsGreaterOrEqual, mqs, useBreakpoint } from './Breakpoints'
+import { DocsSearch } from './DocsSearch'
import GithubStars from './GithubStars'
import MobileMenu from './MobileMenu'
import { HamburgerButton, SocialLink } from './PageHeaderButtons'
@@ -20,8 +22,9 @@ const Filler = styled.div((_) => ({
function PageHeaderUnstyled({ ...props }) {
const [menuIsOpen, setMenuIsOpen] = useState(false)
- const { pathname } = useRouter()
- const prevPathname = usePrevious(pathname)
+ const { asPath } = useRouter()
+ const thisPath = getBarePathFromPath(asPath)
+ const prevPath = usePrevious(thisPath)
const breakpoint = useBreakpoint()
@@ -32,10 +35,10 @@ function PageHeaderUnstyled({ ...props }) {
}, [breakpoint])
useEffect(() => {
- if (pathname !== prevPathname) {
+ if (prevPath && thisPath !== prevPath) {
setMenuIsOpen(false)
}
- }, [pathname, prevPathname])
+ }, [thisPath, prevPath])
useKey(['Escape'], () => {
setMenuIsOpen(false)
@@ -59,6 +62,7 @@ function PageHeaderUnstyled({ ...props }) {
+
({
display: 'flex',
alignItems: 'center',
justifyContent: 'left',
- paddingLeft: theme.spacing.large,
+ paddingLeft: 40,
paddingRight: theme.spacing.large,
+ borderBottom: theme.borders['fill-one'],
[mqs.fullHeader]: {
- paddingLeft: 40,
+ paddingLeft: 0,
paddingRight: 40,
},
'.socialIcons': {
display: 'none',
- [mqs.fullHeader]: {
+ [mqs.maxWidth]: {
display: 'flex',
flexDirection: 'row',
gap: theme.spacing.medium,
@@ -136,11 +141,20 @@ const PageHeader = styled(PageHeaderUnstyled)(({ theme }) => ({
},
'.logo': {
width: 162,
+ maxWidth: '100%',
+ minWidth: 0,
+ display: 'block',
+ },
+ '.leftSection': {
+ display: 'flex',
+ alignItems: 'center',
+ gap: theme.spacing.medium,
[mqs.fullHeader]: {
- // width: 216,
+ paddingLeft: 40,
+ paddingRight: theme.spacing.large,
},
},
- '.rightSection, .leftSection': {
+ '.rightSection': {
display: 'flex',
alignItems: 'center',
gap: theme.spacing.medium,
@@ -171,7 +185,7 @@ const PageHeaderLinks = styled(({ ...props }) => (
))(({ theme }) => ({
display: 'none',
- [mqs.fullHeader]: {
+ [mqs.threeColumn]: {
display: 'flex',
gap: theme.spacing.xsmall,
},
diff --git a/js/documentation/src/components/PageHeaderButtons.tsx b/js/documentation/src/components/PageHeaderButtons.tsx
index e3d532c18c..93b50be4a1 100644
--- a/js/documentation/src/components/PageHeaderButtons.tsx
+++ b/js/documentation/src/components/PageHeaderButtons.tsx
@@ -38,6 +38,7 @@ export const SocialLink = styled(ButtonFillTwo)(({ theme }) => ({
export const HamburgerButtonWrap = styled(ButtonFillTwo)((_) => ({
width: 40,
height: 40,
+ flexShrink: 0,
alignItems: 'center',
justifyContent: 'center',
[mqs.fullHeader]: {
@@ -50,7 +51,10 @@ export function HamburgerButton({
...props
}: { isOpen: boolean } & ComponentPropsWithoutRef<'a'>) {
return (
-
+
{!isOpen && }
{isOpen && }
diff --git a/js/documentation/src/components/RestApiReference/RestApiReference.styles.ts b/js/documentation/src/components/RestApiReference/RestApiReference.styles.ts
index f910316297..5b9a4c8f3d 100644
--- a/js/documentation/src/components/RestApiReference/RestApiReference.styles.ts
+++ b/js/documentation/src/components/RestApiReference/RestApiReference.styles.ts
@@ -2,14 +2,21 @@ import styled from 'styled-components'
// ─── Content layout (uses shared PageGrid from PageGrid.tsx) ───────────────────
-export const RestContentWrapper = styled.div(({ theme }) => ({
- marginTop: theme.spacing.xlarge,
- padding: `0 ${theme.spacing.xlarge}px`,
+export const RestContentWrapper = styled.div((_) => ({
+ minWidth: 0,
}))
export const BreadcrumbsWrapper = styled.div(({ theme }) => ({
- marginTop: theme.spacing.xlarge,
+ display: 'flex',
+ alignItems: 'center',
+ width: '100%',
+ minWidth: 0,
+ minHeight: 40,
marginBottom: theme.spacing.large,
+ '& > *': {
+ minWidth: 0,
+ width: '100%',
+ },
}))
export const ContentGrid = styled.div(({ theme }) => ({
diff --git a/js/documentation/src/components/RestApiReference/SidebarNav.tsx b/js/documentation/src/components/RestApiReference/SidebarNav.tsx
index 6d8f78f00f..6b7e4b1dec 100644
--- a/js/documentation/src/components/RestApiReference/SidebarNav.tsx
+++ b/js/documentation/src/components/RestApiReference/SidebarNav.tsx
@@ -5,6 +5,7 @@
import { useMemo, useState } from 'react'
+import { Input2, SearchIcon } from '@pluralsh/design-system'
import NextLink from 'next/link'
import isEmpty from 'lodash/isEmpty'
@@ -14,62 +15,60 @@ import { MethodBadge } from './MethodBadge'
import type { ApiSection, Endpoint } from '@src/lib/openapi-rest'
-const Sidebar = styled.aside(({ theme: _theme }) => ({
- position: 'sticky',
- top: 'var(--top-nav-height)',
- height: 'calc(100vh - var(--top-nav-height))',
- width: 300,
- flexShrink: 0,
+const Sidebar = styled.aside<{ $overlay?: boolean }>(({ $overlay }) => ({
display: 'flex',
flexDirection: 'column',
overflow: 'hidden',
+ width: '100%',
+ ...($overlay
+ ? {
+ flex: 1,
+ minHeight: 0,
+ position: 'relative',
+ }
+ : {
+ position: 'sticky',
+ top: 'var(--top-nav-height)',
+ height: 'calc(100vh - var(--top-nav-height))',
+ flexShrink: 0,
+ }),
}))
-const SidebarInner = styled.div(({ theme }) => ({
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- bottom: 0,
- overflowY: 'auto',
- backgroundColor: theme.colors['fill-one'],
- borderRight: theme.borders.default,
- paddingBottom: theme.spacing.xlarge,
-}))
+const SidebarInner = styled.div<{ $overlay?: boolean }>(
+ ({ theme, $overlay }) => ({
+ overflowY: 'auto',
+ backgroundColor: theme.colors['fill-one'],
+ borderRight: $overlay ? 'none' : theme.borders['fill-one'],
+ paddingBottom: theme.spacing.xlarge,
+ paddingLeft: theme.spacing.medium,
+ paddingRight: theme.spacing.medium,
+ ...($overlay
+ ? {
+ flex: 1,
+ minHeight: 0,
+ position: 'relative',
+ }
+ : {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ }),
+ })
+)
const SearchWrapper = styled.div(({ theme }) => ({
- padding: `${theme.spacing.medium}px ${theme.spacing.medium}px`,
+ padding: `${theme.spacing.medium}px 0`,
position: 'sticky',
top: 0,
backgroundColor: theme.colors['fill-one'],
zIndex: 1,
}))
-const SearchInput = styled.div(({ theme }) => ({
- display: 'flex',
- alignItems: 'center',
- gap: theme.spacing.small,
- background: theme.colors['fill-two'] ?? theme.colors['fill-zero'],
- border: theme.borders.default,
- borderRadius: theme.borderRadiuses.medium,
- padding: `${theme.spacing.xsmall}px ${theme.spacing.medium}px`,
- '&:focus-within': {
- borderColor: theme.colors['border-primary'],
- },
- '.icon': {
- color: theme.colors['text-xlight'],
- flexShrink: 0,
- },
- input: {
- flex: 1,
- background: 'transparent',
- border: 'none',
- outline: 'none',
- color: theme.colors.text,
- ...theme.partials.text.body2,
- '::placeholder': { color: theme.colors['text-xlight'] },
- },
-}))
+const FilterInput = styled(Input2)({
+ width: '100%',
+})
const SectionGroup = styled.div(({ theme }) => ({
display: 'block',
@@ -94,7 +93,7 @@ const EndpointLabel = styled.span(({ theme }) => ({
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
...theme.partials.text.body2,
- color: theme.colors['text-light'],
+ color: theme.colors['text-xlight'],
}))
const EndpointRowLink = styled(NextLink)<{ $active: boolean }>(
@@ -110,10 +109,7 @@ const EndpointRowLink = styled(NextLink)<{ $active: boolean }>(
textAlign: 'left',
textDecoration: 'none',
color: 'inherit',
- borderStartStartRadius: theme.borderRadiuses.medium,
- borderEndStartRadius: theme.borderRadiuses.medium,
- borderStartEndRadius: 0,
- borderEndEndRadius: 0,
+ borderRadius: theme.borderRadiuses.medium,
backgroundColor: $active ? theme.colors['action-primary'] : 'transparent',
'&:hover': {
backgroundColor: $active
@@ -126,32 +122,6 @@ const EndpointRowLink = styled(NextLink)<{ $active: boolean }>(
})
)
-function SearchIcon() {
- return (
-
- )
-}
-
export const AUTH_PAGE_ID = '__authentication__'
const TopNavItemLink = styled(NextLink)<{ $active: boolean }>(
@@ -167,12 +137,9 @@ const TopNavItemLink = styled(NextLink)<{ $active: boolean }>(
cursor: 'pointer',
textAlign: 'left',
textDecoration: 'none',
- borderStartStartRadius: theme.borderRadiuses.medium,
- borderEndStartRadius: theme.borderRadiuses.medium,
- borderStartEndRadius: 0,
- borderEndEndRadius: 0,
+ borderRadius: theme.borderRadiuses.medium,
backgroundColor: $active ? theme.colors['action-primary'] : 'transparent',
- color: $active ? theme.colors.text : theme.colors['text-light'],
+ color: $active ? theme.colors.text : theme.colors['text-xlight'],
'&:hover': {
backgroundColor: $active
? theme.colors['action-primary-hover']
@@ -191,9 +158,11 @@ const TopNavDivider = styled.hr(({ theme }) => ({
export function SidebarNav({
sections,
selectedId,
+ overlay = false,
}: {
sections: ApiSection[]
selectedId: string
+ overlay?: boolean
}) {
const [filter, setFilter] = useState('')
@@ -220,24 +189,16 @@ export function SidebarNav({
const showAuthItem = !filter
return (
-
-
+
+
-
-
-
-
- setFilter(e.target.value)}
- aria-label="Filter API endpoints"
- />
-
+ }
+ value={filter}
+ onChange={(e) => setFilter(e.currentTarget.value)}
+ inputProps={{ 'aria-label': 'Filter API endpoints' }}
+ />