Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 18 additions & 37 deletions docusaurus/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,43 +39,15 @@ const config = {
{
src: '/js/hotjar.js',
type: 'module',
async: true,
},
{
src: '/js/particle.js',
type: 'module',
async: true,
},
{
src: '/js/firework.js',
type: 'module',
async: true,
},
{
src: '/js/ball.js',
type: 'module',
async: true,
},
{
src: '/js/bar.js',
type: 'module',
async: true,
},
{
src: '/js/game.js',
type: 'module',
async: true,
},
{
src: '/js/particleProfiles.js',
type: 'module',
async: true,
},
{
// src: 'https://unpkg.com/@phosphor-icons/[email protected]',
src: 'https://cdn.jsdelivr.net/npm/@phosphor-icons/[email protected]', // fallback
async: true,
defer: true,
},
{ src: '/js/particle.js', type: 'module', defer: true },
{ src: '/js/firework.js', type: 'module', defer: true },
{ src: '/js/ball.js', type: 'module', defer: true },
{ src: '/js/bar.js', type: 'module', defer: true },
{ src: '/js/game.js', type: 'module', defer: true },
{ src: '/js/particleProfiles.js', type: 'module', defer: true },
// Removed async script for Phosphor Icons to avoid reflow; rely on CSS stylesheets below
{
/**
* Kapa AI widget script and parameters
Expand Down Expand Up @@ -108,14 +80,23 @@ const config = {
'data-modal-y-offset': '3vh', // Default is 10vh
'data-modal-inner-max-width': '100%',
'data-user-satisfaction-feedback-enabled': 'false',
async: true,
defer: true,
},
// {
// src: `https://cdn.amplitude.com/script/181a95e5a6b8053f7ffb7da9f0ef7ef4.experiment.js`,
// async: true,
// },
],
stylesheets: [
// Preconnects to speed up Google Fonts and reduce layout shift
{ href: 'https://fonts.googleapis.com', rel: 'preconnect' },
{ href: 'https://fonts.gstatic.com', rel: 'preconnect', crossorigin: 'anonymous' },
// Load Poppins early so header/nav metrics are stable at first paint
{
href: 'https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;700&display=optional',
type: 'text/css',
rel: 'stylesheet',
},
{
href: 'https://cdn.jsdelivr.net/npm/@phosphor-icons/[email protected]/src/regular/style.css', // fallback
type: 'text/css',
Expand Down
28 changes: 27 additions & 1 deletion docusaurus/src/scss/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,30 @@ main {
border-radius: 2px;
padding: 1px;
}
}
}

/**
* Prevent layout shifts from scrollbar appearance
* Reserve vertical scrollbar space so content width stays stable
*/
html {
/* On modern browsers, keep gutter space so content width stays stable */
scrollbar-gutter: stable both-edges;
}

/** Reserve desktop TOC width to avoid content width shifts */
@include medium-up {
.theme-doc-toc-desktop {
--toc-desktop-width: 300px;
width: var(--toc-desktop-width);
flex: 0 0 var(--toc-desktop-width);
}
}

/* Fallback for browsers without scrollbar-gutter support */
@supports not (scrollbar-gutter: stable) {
html {
/* Always show vertical scrollbar to avoid width jumps */
overflow-y: scroll;
}
}
3 changes: 2 additions & 1 deletion docusaurus/src/scss/_fonts.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/** Fonts */

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;700&display=swap');
/* Google Fonts are now loaded early via <link rel="stylesheet"> in docusaurus.config.js
to minimize layout shift; avoid late @import here. */

.font-poppins,
.font-poppins button,
Expand Down
6 changes: 4 additions & 2 deletions docusaurus/src/scss/ai-toolbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
width: 2rem; /* keep fixed trigger width */
padding: 0.5rem 0;
border: none;
border-radius: 0 0.25rem 0.25rem 0;
Expand Down Expand Up @@ -156,7 +156,9 @@
}

&__button-text {
// Text styling if needed
// Stabilize text slot to avoid width growth on first paint
display: inline-block;
min-width: 8ch;
}
&__dropdown-arrow {
margin-left: 0.25rem;
Expand Down
10 changes: 9 additions & 1 deletion docusaurus/src/scss/badge.scss
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@
margin-left: 2px;
}

/* Stabilize feature/update/content badges to avoid width tweaks */
&--feature,
&--updated,
&--content {
display: inline-block;
min-width: 48px;
}

&--alpha,
&--beta,
&--version {
Expand Down Expand Up @@ -817,4 +825,4 @@ h4 + .badge:not(.badge--inline),
h5 + .badge:not(.badge--inline),
h6 + .badge:not(.badge--inline) {
margin-top: 0.5rem;
}
}
26 changes: 25 additions & 1 deletion docusaurus/src/scss/images.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,31 @@
/** General: Images */
@use './mixins' as *;

/** Reserve space for hero/first images to avoid initial layout shift */
@include medium-up {
.theme-doc-markdown.markdown > p:first-child > img,
.theme-doc-markdown.markdown > figure:first-child img,
.markdown > p:first-child > img,
.markdown > figure:first-child img {
/* If no dimensions provided, reserve a conservative aspect ratio */
aspect-ratio: var(--doc-first-image-aspect, 16 / 9);
height: auto;
width: 100%;
display: block;
}

/* Also cover ThemedImage/picture wrappers often used for hero images */
.theme-doc-markdown.markdown > *:first-child [class*="themedImage"] img,
.theme-doc-markdown.markdown > *:first-child picture > img,
.markdown > *:first-child [class*="themedImage"] img,
.markdown > *:first-child picture > img {
aspect-ratio: var(--doc-first-image-aspect, 16 / 9);
height: auto;
width: 100%;
display: block;
}
}

/** Dark Mode images border */
.theme-doc-markdown.markdown [class*="themedImage--dark"],
.theme-doc-markdown.markdown [class*="themedComponent"] {
Expand Down Expand Up @@ -28,4 +53,3 @@ li > img {
background-color: white;
}
}

16 changes: 16 additions & 0 deletions docusaurus/src/scss/navbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,16 @@ $selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]';
font-size: var(--custom-navbar-items-font-size);
border-radius: 4px;
border: solid 1px transparent;
display: inline-flex;
align-items: center;
i {
position: relative;
top: 1px;
display: inline-block;
width: 1em;
height: 1em;
line-height: 1;
flex: 0 0 1em;
}

&--active {
Expand Down Expand Up @@ -127,6 +134,15 @@ $selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]';
color: var(--custom-navbar-icon-color);
}

// Ensure any icon font/pseudo within links has a stable inline box
&__link .strapi-icons {
display: inline-block;
width: 1em;
height: 1em;
line-height: 1;
flex: 0 0 1em;
}

.navbar-sidebar__close,
#{$selector-color-mode-toggle-button} {
--ifm-color-emphasis-600: currentColor;
Expand Down
28 changes: 25 additions & 3 deletions docusaurus/src/scss/sidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ $selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]';
--doc-sidebar-width: 280px;
}

/**
* Prevent CLS: reserve sidebar width at desktop
* In some builds the sidebar container gets a hashed class (e.g. .sidebar_xxx)
* so we defensively pin width/flex-basis for both canonical and hashed variants.
*/
@include medium-up {
.theme-doc-sidebar-container,
[class*='sidebar_'] {
width: var(--doc-sidebar-width);
flex: 0 0 var(--doc-sidebar-width);
}
}

.navbar-sidebar {
--ifm-navbar-background-color: var(--strapi-neutral-0);

Expand Down Expand Up @@ -407,6 +420,8 @@ $selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]';
position: sticky;
top: 12px;
height: calc(100vh + 180px);
width: var(--doc-sidebar-width);
flex: 0 0 var(--doc-sidebar-width);
}

.theme-doc-sidebar-menu.menu__list {
Expand All @@ -422,12 +437,17 @@ $selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]';
left: 0;
color: var(--strapi-neutral-600);
font-weight: 500;
/* Stabilize icon box to prevent width/height changes on font swap */
display: inline-block;
width: 1.25rem;
height: 1.25rem;
line-height: 1.25rem;
}

[class*="collapseSidebar"] {
border-bottom: none;
min-height: 38px;

min-height: 38px; /* keep button size stable */
&::after {
content:'\E128';
}
Expand All @@ -446,6 +466,8 @@ $selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]';
}
}

/* Revert collapse button positioning change to avoid rendering glitch */

/** Dark mode */
@include dark {
--ifm-menu-color: var(--strapi-neutral-1000);
Expand Down Expand Up @@ -880,4 +902,4 @@ $selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]';
}
}
}
}
}
10 changes: 8 additions & 2 deletions docusaurus/src/theme/SearchBar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,15 @@ function SearchBarContent() {
}

export default function SearchBar() {
// Reserve a stable placeholder to avoid CLS while MeiliSearch mounts
const placeholder = (
<div className="navbar__search" style={{minWidth: 300, minHeight: 40}}>
<div />
</div>
);
return (
<BrowserOnly fallback={<div className="navbar__search"><div></div></div>}>
<BrowserOnly fallback={placeholder}>
{() => <SearchBarContent />}
</BrowserOnly>
);
}
}