Skip to content
Open
5 changes: 5 additions & 0 deletions .changeset/sour-cobras-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitbook": minor
---

Update site layout and blocks with container queries and better transitions
14 changes: 8 additions & 6 deletions packages/gitbook/src/components/AIChat/AIChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { t, tString, useLanguage } from '@/intl/client';
import type { TranslationLanguage } from '@/intl/translations';
import { tcls } from '@/lib/tailwind';
import { Icon } from '@gitbook/icons';
import React from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
Expand Down Expand Up @@ -65,16 +66,17 @@ export function AIChat(props: { trademark: boolean }) {
}
}, [chat.opened, trackEvent]);

if (!chat.opened) {
return null;
}

return (
<div
data-testid="ai-chat"
className="ai-chat inset-y-0 right-0 z-40 mx-auto flex max-w-3xl animate-present scroll-mt-36 px-4 py-4 transition-all duration-300 sm:px-6 lg:fixed lg:w-80 lg:animate-enter-from-right lg:pr-4 lg:pl-0 xl:w-96"
className={tcls(
'ai-chat inset-y-0 right-0 z-40 mx-auto flex max-w-3xl scroll-mt-36 px-4 py-4 transition-[width,opacity,margin,display] transition-discrete duration-300 sm:px-6 lg:fixed lg:w-80 lg:pr-4 lg:pl-0 xl:w-96',
chat.opened
? 'lg:starting:ml-0 lg:starting:w-0 lg:starting:opacity-0'
: 'hidden lg:ml-0 lg:w-0! lg:opacity-0'
)}
>
<EmbeddableFrame className="relative circular-corners:rounded-3xl rounded-corners:rounded-md depth-subtle:shadow-lg shadow-tint ring-1 ring-tint-subtle">
<EmbeddableFrame className="relative shrink-0 circular-corners:rounded-3xl rounded-corners:rounded-md border border-tint-subtle depth-subtle:shadow-lg shadow-tint transition-all duration-300 lg:w-76 xl:w-92">
<EmbeddableFrameHeader>
<AIChatDynamicIcon trademark={trademark} />
<EmbeddableFrameHeaderMain>
Expand Down
2 changes: 1 addition & 1 deletion packages/gitbook/src/components/AIChat/AIChatButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function AIChatButton(props: {
iconOnly={!showLabel}
size="medium"
variant="header"
className="h-9 px-2.5 max-md:[&_.button-content]:hidden"
className="h-9 px-2.5 @max-2xl:[&_.button-content]:hidden"
label={
<div className="flex items-center gap-2">
{t(language, 'ai_chat_ask', assistant.label)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export function Column(props: {
<div
className={tcls(
'flex flex-col',
'@container/column',
(verticalAlignment === VerticalAlignment.Top || !verticalAlignment) &&
'justify-start',
verticalAlignment === VerticalAlignment.Middle && 'justify-center',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export async function RecordCard(
'overflow-hidden',
'[&_.heading>div:first-child]:hidden',
'[&_.heading>div]:text-[.8em]',
'md:[&_.heading>div]:text-[1em]',
'@xl:[&_.heading>div]:text-[1em]',
'[&_.blocks:first-child_.heading]:pt-0', // Remove padding-top on first heading in card

// On mobile, check if we can display the cover responsively or not:
Expand All @@ -69,10 +69,10 @@ export async function RecordCard(
lightCoverIsSquareOrPortrait || darkCoverIsSquareOrPortrait
? [
lightCoverIsSquareOrPortrait
? 'grid-cols-[40%__1fr] min-[432px]:grid-cols-none min-[432px]:grid-rows-[auto_1fr]'
? '@sm:grid-cols-none grid-cols-[40%__1fr] @sm:grid-rows-[auto_1fr]'
: '',
darkCoverIsSquareOrPortrait
? 'dark:grid-cols-[40%__1fr] dark:min-[432px]:grid-cols-none dark:min-[432px]:grid-rows-[auto_1fr]'
? 'dark:@sm:grid-cols-none dark:grid-cols-[40%__1fr] dark:@sm:grid-rows-[auto_1fr]'
: '',
].filter(Boolean)
: 'grid-rows-[auto_1fr]'
Expand Down Expand Up @@ -112,11 +112,9 @@ export async function RecordCard(
'bg-tint-subtle',
lightCoverIsSquareOrPortrait || darkCoverIsSquareOrPortrait
? [
lightCoverIsSquareOrPortrait
? 'min-[432px]:aspect-video min-[432px]:h-auto'
: '',
lightCoverIsSquareOrPortrait ? '@sm:aspect-video @sm:h-auto' : '',
darkCoverIsSquareOrPortrait
? 'dark:min-[432px]:aspect-video dark:min-[432px]:h-auto'
? 'dark:@sm:aspect-video dark:@sm:h-auto'
: '',
].filter(Boolean)
: ['h-auto', 'aspect-video'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export function ViewCards(props: TableViewProps<DocumentTableViewCards>) {
'inline-grid',
'gap-4',
'grid-cols-1',
'min-[432px]:grid-cols-2',
view.cardSize === 'large' ? 'md:grid-cols-2' : 'md:grid-cols-3',
'@sm:grid-cols-2',
view.cardSize === 'large' ? '@xl:grid-cols-2' : '@xl:grid-cols-3',
block.data.fullWidth ? 'large:flex-column' : null
)}
>
Expand Down
6 changes: 3 additions & 3 deletions packages/gitbook/src/components/DocumentView/spacing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ export function getBlockTextStyle(block: DocumentBlock): {
};
case 'heading-1':
return {
textSize: 'text-3xl font-semibold',
textSize: 'text-xl @xs:text-2xl @lg:text-3xl font-semibold',
lineHeight: 'leading-tight',
marginTop: 'column-first-of-type:pt-0 pt-[1em]',
};
case 'heading-2':
return {
textSize: 'text-2xl font-semibold',
textSize: 'text-lg @xs:text-xl @lg:text-2xl font-semibold',
lineHeight: 'leading-snug',
marginTop: 'column-first-of-type:pt-0 pt-[0.75em]',
};
case 'heading-3':
return {
textSize: 'text-xl font-semibold',
textSize: 'text-base @xs:text-lg @lg:text-xl font-semibold',
lineHeight: 'leading-snug',
marginTop: 'column-first-of-type:pt-0 pt-[0.5em]',
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const EmbeddableFrame = React.forwardRef<HTMLDivElement, EmbeddableFrameP
<div
{...divProps}
className={tcls(
'flex h-full grow animate-fade-in-slow flex-col overflow-hidden bg-tint-base text-sm text-tint',
'flex h-full grow flex-col overflow-hidden bg-tint-base text-sm text-tint',
divProps.className
)}
ref={ref}
Expand Down
201 changes: 106 additions & 95 deletions packages/gitbook/src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,112 +29,123 @@ export function Footer(props: { context: GitBookSiteContext }) {
className={tcls(
'border-tint-subtle border-t',
// If the footer only contains a mode toggle, we only show it on smaller screens
mobileOnly ? 'xl:hidden' : null
mobileOnly ? '@7xl:hidden' : null
)}
>
<div className={tcls(CONTAINER_STYLE, 'px-4', 'py-8', 'lg:py-12', 'mx-auto')}>
<div className="motion-safe:transition-[padding] motion-safe:duration-300 lg:chat-open:pr-80 xl:chat-open:pr-96">
<div
className={tcls(
'mx-auto grid max-w-3xl site-width-wide:max-w-screen-2xl justify-between gap-12 lg:max-w-none!',
'grid-cols-[auto_auto]',
'lg:grid-cols-[18rem_minmax(auto,48rem)_auto]',
'xl:grid-cols-[18rem_minmax(auto,48rem)_14rem]',
'lg:site-width-wide:grid-cols-[18rem_minmax(auto,80rem)_auto]',
'xl:site-width-wide:grid-cols-[18rem_minmax(auto,80rem)_14rem]',
'lg:page-no-toc:grid-cols-[minmax(auto,48rem)_auto]',
'xl:page-no-toc:grid-cols-[14rem_minmax(auto,48rem)_14rem]',
'lg:[body:has(.site-width-wide,.page-no-toc)_&]:grid-cols-[minmax(auto,90rem)_auto]',
'xl:[body:has(.site-width-wide,.page-no-toc)_&]:grid-cols-[14rem_minmax(auto,90rem)_14rem]'
CONTAINER_STYLE,
'px-4',
'py-8',
'@4xl:py-12',
'mx-auto',
'@container/footer'
)}
>
{
// Footer Logo
customization.footer.logo ? (
<div className="col-start-1 row-start-1">
<Image
alt="Logo"
resize={context.imageResizer}
sources={{
light: {
src: customization.footer.logo.light,
},
dark: customization.footer.logo.dark
? {
src: customization.footer.logo.dark,
}
: null,
}}
loading="lazy"
style={[
'w-auto',
'max-w-40',
'lg:max-w-64',
'max-h-10',
'lg:max-h-12',
'object-contain',
'object-left',
'rounded-sm',
'straight-corners:rounded-xs',
]}
sizes={[
{
width: 320,
},
]}
/>
</div>
) : null
}
<div
className={tcls(
'mx-auto flex @xs:grid @4xl:max-w-none! max-w-3xl site-width-wide:max-w-screen-2xl flex-col justify-between gap-12',
'grid-cols-[auto_auto]',
'@4xl:grid-cols-[18rem_minmax(auto,48rem)_auto]',
'@7xl:grid-cols-[18rem_minmax(auto,48rem)_14rem]',
'@4xl:site-width-wide:grid-cols-[18rem_minmax(auto,80rem)_auto]',
'@7xl:site-width-wide:grid-cols-[18rem_minmax(auto,80rem)_14rem]',
'@4xl:page-no-toc:grid-cols-[minmax(auto,48rem)_auto]',
'@7xl:page-no-toc:grid-cols-[14rem_minmax(auto,48rem)_14rem]',
'@4xl:[body:has(.site-width-wide,.page-no-toc)_&]:grid-cols-[minmax(auto,90rem)_auto]',
'@7xl:[body:has(.site-width-wide,.page-no-toc)_&]:grid-cols-[14rem_minmax(auto,90rem)_14rem]'
)}
>
{
// Footer Logo
customization.footer.logo ? (
<div className="col-start-1 row-start-1">
<Image
alt="Logo"
resize={context.imageResizer}
sources={{
light: {
src: customization.footer.logo.light,
},
dark: customization.footer.logo.dark
? {
src: customization.footer.logo.dark,
}
: null,
}}
loading="lazy"
style={[
'w-auto',
'max-w-40',
'@4xl:max-w-64',
'max-h-10',
'@4xl:max-h-12',
'object-contain',
'object-left',
'rounded-sm',
'straight-corners:rounded-xs',
]}
sizes={[
{
width: 320,
},
]}
/>
</div>
) : null
}

{
// Theme Toggle
customization.themes.toggeable ? (
<div className="-col-start-2 row-start-1 flex items-start justify-end xl:hidden">
<React.Suspense fallback={null}>
<ThemeToggler />
</React.Suspense>
</div>
) : null
}
{
// Theme Toggle
customization.themes.toggeable ? (
<div className="-col-start-2 row-start-1 flex items-start @xs:justify-end xl:hidden">
<React.Suspense fallback={null}>
<ThemeToggler />
</React.Suspense>
</div>
) : null
}

{
// Navigation groups (split into equal columns)
customization.footer.groups?.length > 0 ? (
<div
className={tcls(
'col-span-2 lg:page-has-toc:col-span-1 lg:page-has-toc:col-start-2 xl:page-no-toc:col-span-1 xl:page-no-toc:col-start-2'
)}
>
<div className="mx-auto flex max-w-3xl site-width-wide:max-w-screen-2xl flex-col gap-10 sm:flex-row sm:gap-6">
{partition(customization.footer.groups, FOOTER_COLUMNS).map(
(column, columnIndex) => (
<div
key={columnIndex}
className="flex flex-1 grow flex-col gap-10"
>
{column.map((group, groupIndex) => (
<FooterLinksGroup
key={groupIndex}
group={group}
context={context}
/>
))}
</div>
)
{
// Navigation groups (split into equal columns)
customization.footer.groups?.length > 0 ? (
<div
className={tcls(
'@4xl:page-has-toc:col-span-1 @7xl:page-no-toc:col-span-1 col-span-2 @4xl:page-has-toc:col-start-2 @7xl:page-no-toc:col-start-2'
)}
>
<div className="mx-auto flex max-w-3xl site-width-wide:max-w-screen-2xl @xl:flex-row flex-col @xl:gap-6 gap-10">
{partition(customization.footer.groups, FOOTER_COLUMNS).map(
(column, columnIndex) => (
<div
key={columnIndex}
className="flex flex-1 grow flex-col gap-10"
>
{column.map((group, groupIndex) => (
<FooterLinksGroup
key={groupIndex}
group={group}
context={context}
/>
))}
</div>
)
)}
</div>
</div>
</div>
) : null
}
) : null
}

{
// Legal
customization.footer.copyright ? (
<div className="order-last col-span-full flex w-full grow flex-col items-center gap-2 text-center text-tint text-xs">
<p>{customization.footer.copyright}</p>
</div>
) : null
}
{
// Legal
customization.footer.copyright ? (
<div className="order-last col-span-full flex w-full grow flex-col items-center gap-2 text-center text-tint text-xs">
<p>{customization.footer.copyright}</p>
</div>
) : null
}
</div>
</div>
</div>
</footer>
Expand Down
Loading
Loading