Compare commits

...

8 Commits

Author SHA1 Message Date
Zeno Kapitein c924e296aa Clean up 2025-01-23 14:18:38 +01:00
Zeno Kapitein e0f7190229 Format & lint 2025-01-23 14:17:54 +01:00
Zeno Kapitein a65654edfb Balance links with search bar and variant dropdown 2025-01-23 14:17:54 +01:00
Zeno Kapitein 3c21a5e820 Header links and search button styling 2025-01-23 14:16:54 +01:00
Zeno Kapitein 71141d7f26 Styling tweaks 2025-01-23 14:16:54 +01:00
Zeno Kapitein ece3f2078e Update Header.tsx 2025-01-23 14:16:54 +01:00
Zeno Kapitein 05627965fb Changeset 2025-01-23 14:16:54 +01:00
Zeno Kapitein 41cba63f27 Grow search bar conditionally if <5 header links are present 2025-01-23 14:16:54 +01:00
9 changed files with 87 additions and 42 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'gitbook': patch
---
Grow search bar conditionally if <5 header links are present
@@ -17,6 +17,8 @@ import { SearchButton } from '../Search';
import { SiteSectionTabs } from '../SiteSections'; import { SiteSectionTabs } from '../SiteSections';
import { HeaderMobileMenu } from './HeaderMobileMenu'; import { HeaderMobileMenu } from './HeaderMobileMenu';
const MAX_HEADER_LINKS_FOR_BIG_SEARCHBAR = 4;
/** /**
* Render the header for the space. * Render the header for the space.
*/ */
@@ -73,7 +75,7 @@ export function Header(props: {
<div <div
className={tcls( className={tcls(
'gap-4', 'gap-4',
'lg:gap-8', 'lg:gap-6',
'flex', 'flex',
'items-center', 'items-center',
'justify-between', 'justify-between',
@@ -90,6 +92,11 @@ export function Header(props: {
'flex max-w-full', 'flex max-w-full',
isMultiVariants && 'page-no-toc:max-[400px]:w-full', isMultiVariants && 'page-no-toc:max-[400px]:w-full',
'shrink min-w-0 gap-2 lg:gap-4 justify-start items-center', 'shrink min-w-0 gap-2 lg:gap-4 justify-start items-center',
customization.header.links.length <=
MAX_HEADER_LINKS_FOR_BIG_SEARCHBAR
? 'lg:basis-72'
: '',
isMultiVariants && 'page-no-toc:lg:basis-auto',
)} )}
> >
<HeaderMobileMenu <HeaderMobileMenu
@@ -130,33 +137,29 @@ export function Header(props: {
</div> </div>
)} )}
{customization.header.links.length > 0 && (
<HeaderLinks>
{customization.header.links.map((link, index) => {
return (
<HeaderLink
key={index}
link={link}
context={context}
customization={customization}
/>
);
})}
<HeaderLinkMore
label={t(getSpaceLanguage(customization), 'more')}
links={customization.header.links}
context={context}
customization={customization}
/>
</HeaderLinks>
)}
<div <div
className={tcls( className={tcls(
'flex', 'flex',
'gap-4',
'md:min-w-56', 'md:min-w-56',
'grow-0', 'items-center',
'shrink-0', 'grow-0 shrink-0',
'justify-self-end', customization.header.links.length <=
MAX_HEADER_LINKS_FOR_BIG_SEARCHBAR
? [
'lg:grow',
'lg:min-w-40',
'max-w-lg',
'lg:ml-[max(calc((100%-18rem-48rem-3rem)/2),1.5rem)]',
'xl:ml-[max(calc((100%-18rem-48rem-14rem-3rem)/2),1.5rem)]',
'lg:mr-auto',
'page-no-toc:xl:ml-[max(calc((100%-18rem-48rem-18rem-3rem)/2),1.5rem)]',
isMultiVariants &&
'page-no-toc:lg:ml-0 page-no-toc:xl:ml-0',
'order-last',
'lg:order-[unset]',
]
: ['order-last'],
)} )}
> >
<Suspense fallback={null}> <Suspense fallback={null}>
@@ -172,7 +175,9 @@ export function Header(props: {
'text-header-link/8', 'text-header-link/8',
'dark:text-header-link/8', 'dark:text-header-link/8',
'hover:text-header-link', 'hover:text-header-link',
'focus:text-header-link',
'dark:hover:text-header-link', 'dark:hover:text-header-link',
'dark:focus:text-header-link',
'ring-header-link/4', 'ring-header-link/4',
'dark:ring-header-link/4', 'dark:ring-header-link/4',
@@ -182,7 +187,9 @@ export function Header(props: {
'[&_svg]:text-header-link/10', '[&_svg]:text-header-link/10',
'dark:[&_svg]:text-header-link/10', 'dark:[&_svg]:text-header-link/10',
'[&_.shortcut]:text-header-link/8', '[&_.shortcut]:text-header-link/8',
'[&_.shortcut_kbd]:border-header-link/2',
'dark:[&_.shortcut]:text-header-link/8', 'dark:[&_.shortcut]:text-header-link/8',
'dark:[&_.shortcut_kbd]:border-header-link/2',
'contrast-more:bg-header-background', 'contrast-more:bg-header-background',
'contrast-more:text-header-link', 'contrast-more:text-header-link',
@@ -218,6 +225,27 @@ export function Header(props: {
</SearchButton> </SearchButton>
</Suspense> </Suspense>
</div> </div>
{customization.header.links.length > 0 && (
<HeaderLinks>
{customization.header.links.map((link, index) => {
return (
<HeaderLink
key={index}
link={link}
context={context}
customization={customization}
/>
);
})}
<HeaderLinkMore
label={t(getSpaceLanguage(customization), 'more')}
links={customization.header.links}
context={context}
customization={customization}
/>
</HeaderLinks>
)}
</div> </div>
</div> </div>
</div> </div>
@@ -35,7 +35,7 @@ export async function HeaderLink(props: {
if (link.links && link.links.length > 0) { if (link.links && link.links.length > 0) {
return ( return (
<Dropdown <Dropdown
className="shrink" className="shrink left-auto right-0"
button={(buttonProps) => { button={(buttonProps) => {
if (!target || !link.to) { if (!target || !link.to) {
return ( return (
@@ -159,7 +159,7 @@ function getHeaderLinkClassName(props: { headerPreset: CustomizationHeaderPreset
return tcls( return tcls(
'flex items-center shrink', 'flex items-center shrink',
'hover:text-header-link-400 dark:hover:text-light', 'hover:text-header-link-400 dark:hover:text-light',
'min-w-0', 'min-w-0 hover:min-w-max',
'contrast-more:underline', 'contrast-more:underline',
props.headerPreset === CustomizationHeaderPreset.Default props.headerPreset === CustomizationHeaderPreset.Default
@@ -53,7 +53,7 @@ export function HeaderLinkMore(props: {
return ( return (
<div className={`${styles.linkEllipsis} items-center z-20`}> <div className={`${styles.linkEllipsis} items-center z-20`}>
<Dropdown button={renderButton} className="-translate-x-48 md:translate-x-0"> <Dropdown button={renderButton} className="left-auto right-0 md:right-auto md:left-0">
<DropdownMenu> <DropdownMenu>
{links.map((link, index) => ( {links.map((link, index) => (
<MoreMenuLink key={index} link={link} context={context} /> <MoreMenuLink key={index} link={link} context={context} />
@@ -13,7 +13,7 @@ export async function HeaderLinks({ children }: HeaderLinksProps) {
<div <div
className={tcls( className={tcls(
styles.containerHeaderlinks, styles.containerHeaderlinks,
'grow shrink flex justify-end items-center gap-x-4 lg:gap-x-6 min-w-9 z-20 lg:[&>.button+.button]:-ml-2', 'grow-[2.5] shrink flex justify-end items-center gap-x-4 lg:gap-x-6 min-w-9 z-20 lg:[&>.button+.button]:-ml-2',
)} )}
> >
{children} {children}
@@ -95,7 +95,7 @@ function LogoFallback(props: HeaderLogoProps) {
<div <div
className={tcls( className={tcls(
'text-pretty', 'text-pretty',
'line-clamp-3', 'line-clamp-2',
'tracking-tight', 'tracking-tight',
'max-w-[18ch]', 'max-w-[18ch]',
'lg:max-w-[24ch]', 'lg:max-w-[24ch]',
@@ -69,7 +69,7 @@ export function SpacesDropdown(props: { space: Space; spaces: Space[]; className
className, className,
)} )}
> >
<span className={tcls('line-clamp-2', 'grow')}>{space.title}</span> <span className={tcls('line-clamp-1', 'grow')}>{space.title}</span>
<DropdownChevron /> <DropdownChevron />
</div> </div>
)} )}
@@ -1,8 +1,3 @@
.containerHeaderlinks {
container-type: inline-size;
container-name: headerlinks;
}
.linkEllipsis { .linkEllipsis {
display: none; display: none;
& div > a { & div > a {
@@ -10,6 +5,11 @@
} }
} }
.containerHeaderlinks {
container-type: inline-size;
container-name: headerlinks;
}
@container headerlinks ( width < 150px ) { @container headerlinks ( width < 150px ) {
.containerHeaderlinks > :nth-child(n + 1) { .containerHeaderlinks > :nth-child(n + 1) {
display: none; display: none;
@@ -43,7 +43,7 @@
} }
} }
} }
@container headerlinks ( width < 600px ) { @container headerlinks ( width < 550px ) {
.containerHeaderlinks > :nth-child(n + 4) { .containerHeaderlinks > :nth-child(n + 4) {
display: none; display: none;
} }
@@ -54,7 +54,7 @@
} }
} }
} }
@container headerlinks ( width < 750px ) { @container headerlinks ( width < 650px ) {
.containerHeaderlinks > :nth-child(n + 5) { .containerHeaderlinks > :nth-child(n + 5) {
display: none; display: none;
} }
@@ -65,7 +65,7 @@
} }
} }
} }
@container headerlinks ( width < 850px ) { @container headerlinks ( width < 750px ) {
.containerHeaderlinks > :nth-child(n + 6) { .containerHeaderlinks > :nth-child(n + 6) {
display: none; display: none;
} }
@@ -72,7 +72,7 @@ export function SearchButton(props: { children?: React.ReactNode; style?: ClassV
'transition-all', 'transition-all',
'hover:shadow-md', 'hover:shadow-md',
'hover:scale-102', 'hover:scale-102',
'hover:ring-dark/2', 'hover:ring-dark/4',
'hover:text-dark/10', 'hover:text-dark/10',
'focus:shadow-md', 'focus:shadow-md',
'focus:scale-102', 'focus:scale-102',
@@ -93,7 +93,7 @@ export function SearchButton(props: { children?: React.ReactNode; style?: ClassV
'dark:contrast-more:focus:ring-light', 'dark:contrast-more:focus:ring-light',
'active:shadow-sm', 'active:shadow-sm',
'active:scale-98', 'active:scale-100',
'md:justify-start', 'md:justify-start',
'md:w-full', 'md:w-full',
@@ -131,18 +131,30 @@ const Shortcut = () => {
className={tcls( className={tcls(
'shortcut', 'shortcut',
'hidden', 'hidden',
'md:inline', 'md:flex',
'justify-end', 'justify-end',
'text-xs', 'text-xs',
'font-mono',
'text-dark/7', 'text-dark/7',
'leading-none',
'contrast-more:text-dark', 'contrast-more:text-dark',
'dark:text-light-4/7', 'dark:text-light-4/7',
'contrast-more:dark:text-light', 'contrast-more:dark:text-light',
'whitespace-nowrap', 'whitespace-nowrap',
`[font-feature-settings:"calt",_"case"]`, `[font-feature-settings:"calt",_"case"]`,
'gap-0.5',
'shrink-0',
'-mr-1',
)} )}
> >
{operatingSystem === 'mac' ? '⌘' : 'Ctrl +'} K <kbd
className={`rounded border border-dark/2 dark:border-light/2 px-1 min-w-5 h-5 flex justify-center items-center ${operatingSystem === 'mac' ? 'text-sm' : ''}`}
>
{operatingSystem === 'mac' ? '⌘' : 'Ctrl'}
</kbd>
<kbd className="rounded border border-dark/2 dark:border-light/2 size-5 flex justify-center items-center">
K
</kbd>
</div> </div>
); );
}; };