* Add some CSS vars to nav component, use nav in sidebar more, update toc and ads
* more iterations on ToC and ads layout
// scss-docs-start nav-variables
$nav-gap: .125rem !default;
$nav-link-gap: .5rem !default;
+$nav-link-align: center !default;
+$nav-link-justify: center !default;
$nav-link-padding-y: .5rem !default;
$nav-link-padding-x: 1rem !default;
$nav-link-color: var(--fg-2) !default;
// scss-docs-start nav-css-vars
--nav-gap: #{$nav-gap};
--nav-link-gap: #{$nav-link-gap};
+ --nav-link-align: #{$nav-link-align};
+ --nav-link-justify: #{$nav-link-justify};
--nav-link-padding-x: #{$nav-link-padding-x};
--nav-link-padding-y: #{$nav-link-padding-y};
--nav-link-color: #{$nav-link-color};
.nav-link {
display: flex;
gap: var(--nav-link-gap);
- align-items: center;
- justify-content: center;
+ align-items: var(--nav-link-align);
+ justify-content: var(--nav-link-justify);
padding: var(--nav-link-padding-y) var(--nav-link-padding-x);
font-weight: var(--nav-link-font-weight);
color: var(--nav-link-color);
const sidebar = getData('sidebar')
---
-<nav class="bd-links w-100" id="bd-docs-nav" aria-label="Docs navigation">
- <ul class="bd-links-nav list-unstyled mb-0 pb-3 pb-md-2 pe-lg-2">
- {
- sidebar.map((group) => {
- const groupSlug = getSlug(group.title)
+<nav class="nav vstack bd-links w-100 pb-3 pb-md-2 pe-lg-2" id="bd-docs-nav" aria-label="Docs navigation">
+ {
+ sidebar.map((group) => {
+ const groupSlug = getSlug(group.title)
- if (group.pages) {
- return (
- <li class="bd-links-group py-2">
- <strong class="bd-links-heading d-flex w-100 align-items-center fw-semibold">
- {group.icon && (
- <svg
- class="bi me-2"
- style={group.icon_color && `color: light-dark(var(--bs-${group.icon_color}-500), var(--bs-${group.icon_color}-400));`}
- aria-hidden="true"
- >
- <use href={`#${group.icon}`} />
- </svg>
- )}
- {group.title}
- </strong>
- <ul class="list-unstyled fw-normal pb-2 small">
- {group.pages?.map((item: any) => {
- // Handle sub-groups
- if (item.group && item.pages) {
- return (
- <li class="mb-2">
- <div class="bd-links-subgroup fw-semibold mt-3">
- {item.group}
- </div>
- <ul class="list-unstyled">
- {item.pages.map((page: any) => {
- const docSlug = getSlug(page.title)
- const unversionedPageSlug = `${groupSlug}/${docSlug}`
-
- const url = `/docs/${getConfig().docs_version}/${unversionedPageSlug}`
- const active = Astro.params.slug === unversionedPageSlug
+ if (group.pages) {
+ return (
+ <div class="vstack bd-links-group py-2">
+ <strong class="bd-links-heading d-flex w-100 align-items-center fw-semibold">
+ {group.icon && (
+ <svg
+ class="bi me-2"
+ style={group.icon_color && `color: light-dark(var(--bs-${group.icon_color}-500), var(--bs-${group.icon_color}-400));`}
+ aria-hidden="true"
+ >
+ <use href={`#${group.icon}`} />
+ </svg>
+ )}
+ {group.title}
+ </strong>
+ <ul class="nav flex-column bd-links-nav">
+ {group.pages?.map((item: any) => {
+ // Handle sub-groups
+ if (item.group && item.pages) {
+ return (
+ <>
+ <li class="bd-links-subgroup fw-semibold mt-3">
+ {item.group}
+ </li>
+ {item.pages.map((page: any) => {
+ const docSlug = getSlug(page.title)
+ const unversionedPageSlug = `${groupSlug}/${docSlug}`
- const generatedPage = docsPages.find((page) => page.slug === unversionedPageSlug)
+ const url = `/docs/${getConfig().docs_version}/${unversionedPageSlug}`
+ const active = Astro.params.slug === unversionedPageSlug
- // This test should not be necessary, see comments for `getSlug()` in `src/libs/utils.ts`.
- if (!generatedPage) {
- throw new Error(
- `The page '${page.title}' referenced in 'site/data/sidebar.yml' does not exist at '${url}'.`
- )
- }
+ const generatedPage = docsPages.find((page) => page.slug === unversionedPageSlug)
- return (
- <li>
- <a
- href={url}
- class:list={['bd-links-link', { active }]}
- aria-current={active ? 'page' : undefined}
- >
- {page.title}
- </a>
- </li>
- )
- })}
- </ul>
- </li>
- )
- }
+ // This test should not be necessary, see comments for `getSlug()` in `src/libs/utils.ts`.
+ if (!generatedPage) {
+ throw new Error(
+ `The page '${page.title}' referenced in 'site/data/sidebar.yml' does not exist at '${url}'.`
+ )
+ }
- // Handle regular pages
- const docSlug = getSlug(item.title)
- const unversionedPageSlug = `${groupSlug}/${docSlug}`
+ return (
+ <li>
+ <a
+ href={url}
+ class:list={['nav-link bd-links-link', { active }]}
+ aria-current={active ? 'page' : undefined}
+ >
+ {page.title}
+ </a>
+ </li>
+ )
+ })}
+ </>
+ )
+ }
- const url = `/docs/${getConfig().docs_version}/${unversionedPageSlug}`
- const active = Astro.params.slug === unversionedPageSlug
+ // Handle regular pages
+ const docSlug = getSlug(item.title)
+ const unversionedPageSlug = `${groupSlug}/${docSlug}`
- const generatedPage = docsPages.find((page) => page.slug === unversionedPageSlug)
+ const url = `/docs/${getConfig().docs_version}/${unversionedPageSlug}`
+ const active = Astro.params.slug === unversionedPageSlug
- // This test should not be necessary, see comments for `getSlug()` in `src/libs/utils.ts`.
- if (!generatedPage) {
- throw new Error(
- `The page '${item.title}' referenced in 'site/data/sidebar.yml' does not exist at '${url}'.`
- )
- }
+ const generatedPage = docsPages.find((page) => page.slug === unversionedPageSlug)
- return (
- <li>
- <a
- href={url}
- class:list={['bd-links-link', { active }]}
- aria-current={active ? 'page' : undefined}
- >
- {item.title}
- </a>
- </li>
+ // This test should not be necessary, see comments for `getSlug()` in `src/libs/utils.ts`.
+ if (!generatedPage) {
+ throw new Error(
+ `The page '${item.title}' referenced in 'site/data/sidebar.yml' does not exist at '${url}'.`
)
- })}
- </ul>
- </li>
- )
- } else {
- const active = Astro.params.slug === groupSlug
+ }
- return (
- <>
- <li class="bd-links-span-all mt-1 mb-3 mx-4 border-top" />
- <li class="bd-links-span-all">
- <a
- href={`/docs/${getConfig().docs_version}/${groupSlug}/`}
- class:list={['bd-links-link', { active }]}
- aria-current={active ? 'page' : undefined}
- >
- {group.title}
- </a>
- </li>
- </>
- )
- }
- })
- }
- </ul>
+ return (
+ <li>
+ <a
+ href={url}
+ class:list={['nav-link bd-links-link', { active }]}
+ aria-current={active ? 'page' : undefined}
+ >
+ {item.title}
+ </a>
+ </li>
+ )
+ })}
+ </ul>
+ </div>
+ )
+ } else {
+ const active = Astro.params.slug === groupSlug
+
+ return (
+ <>
+ <div class="bd-links-span-all mt-1 mb-3 mx-4 border-top" />
+ <a
+ href={`/docs/${getConfig().docs_version}/${groupSlug}/`}
+ class:list={['bd-links-link bd-links-span-all', { active }]}
+ aria-current={active ? 'page' : undefined}
+ >
+ {group.title}
+ </a>
+ </>
+ )
+ }
+ })
+ }
</nav>
const toc = entries ? entries : generateToc(headings ?? [])
---
-<ul>
+<ul class="nav flex-column">
{
toc.map(({ children, slug, text }) => {
return (
<li>
- <a href={`#${slug}`}>{text}</a>
+ <a class="nav-link" href={`#${slug}`}>{text}</a>
{children.length > 0 && <Astro.self entries={children} />}
</li>
)
const { addedIn, layout, title } = Astro.props
---
-<header class="navbar navbar-expand-lg bg-body bd-navbar border-bottom border-subtle sticky-top bd-sticky-navbar">
+<header class="navbar navbar-expand-lg bg-body bd-navbar border-bottom sticky-top bd-sticky-navbar">
<nav class="container-2xl bd-gutter flex-wrap flex-lg-nowrap" aria-label="Main navigation">
{
layout === 'docs' && (
<div class="container-2xl bd-gutter">
<div class="col-md-8 mx-auto text-center">
<a
- class="d-flex flex-column flex-lg-row justify-content-center align-items-center mb-4 text-dark lh-sm text-decoration-none"
+ class="d-flex flex-column flex-lg-row justify-content-center align-items-center mb-4 lh-sm text-decoration-none"
href="https://www.herodevs.com/support/nes-bootstrap?utm_source=Bootstrap_site&utm_medium=Banner&utm_campaign=v3and4_eol"
rel="noopener"
target="_blank"
>
- <span class="d-sm-inline-flex align-items-center gap-1 py-2 px-3 me-2 mb-2 mb-lg-0 rounded-5 masthead-notice">
+ <span class="d-sm-inline-flex align-items-center gap-1 py-2 px-3 me-2 mb-2 mb-lg-0 rounded-5 masthead-notice theme-subtle theme-warning ">
Get Security Updates for Bootstrap 3 & 4
<svg class="bi" style="width: 20px; height: 20px; margin-block: -2px;" aria-hidden="true"
><use href="#arrow-right-short"></use></svg
<CodeCopy code={`npm i bootstrap@${getConfig().current_version}`} />
<a
href={getVersionedDocsPath('getting-started/install')}
- class="btn btn-lg bd-btn-lg btn-bd-primary d-flex align-items-center justify-content-center fw-semibold"
+ class="btn-solid theme-accent btn-lg justify-content-center"
>
<svg class="bi me-2" aria-hidden="true"><use href="#book-half"></use></svg>
Read the docs
</div>
- <div class="bd-toc mt-3 mb-5 my-lg-0 mb-lg-5 px-sm-1 text-body-secondary">
+ <div class="vstack bd-toc mt-3 mb-5 my-lg-0 mb-lg-5 px-sm-1 fg-3">
+ <div class="overflow-y-auto">
{
frontmatter.toc && headings && (
<button
- class="btn btn-link p-md-0 mb-2 mb-md-0 text-decoration-none bd-toc-toggle d-flex align-items-center d-md-none"
+ class="btn btn-link p-lg-0 mb-2 mb-lg-0 text-decoration-none bd-toc-toggle d-flex align-items-center d-lg-none"
type="button"
data-bs-toggle="collapse"
data-bs-target="#tocContents"
aria-controls="tocContents"
>
On this page
- <svg class="bi d-md-none ms-2" aria-hidden="true">
+ <svg class="bi d-lg-none ms-2" aria-hidden="true">
<use href="#chevron-expand" />
</svg>
</button>
- <div class="d-none d-md-block h6 my-2 ms-3" id="docs-tocs">On this page</div>
- <hr class="d-none d-md-block my-2 ms-3" />
<div class="collapse bd-toc-collapse" id="tocContents">
<nav id="TableOfContents" aria-labelledby="docs-tocs">
<TableOfContents headings={headings} />
</div>
)
}
+ </div>
<Ads />
</div>
#carbonads {
position: static;
max-width: 400px;
- padding: 15px 15px 15px 160px;
+ padding: .75rem .75rem .75rem 160px;
margin: 1rem 0;
overflow: hidden;
- font-size: .8125rem;
+ font-size: var(--bs-font-size-sm);
line-height: 1.4;
text-align: start;
background-color: var(--bs-bg-1);
+ @include border-radius(var(--bs-border-radius-lg));
a {
color: var(--bs-body-color);
text-decoration: none;
}
-
- @include media-breakpoint-up(sm) {
- @include border-radius(.5rem);
- }
}
.carbon-img {
float: inline-start;
margin-inline-start: -145px;
+
+ > img {
+ @include border-radius(var(--bs-border-radius-sm));
+ }
}
@container (max-width: 240px) {
#carbonads {
- padding-inline-start: 15px;
+ position: sticky;
+ bottom: 0;
+ flex-shrink: 0;
+ padding-block: 1.25rem;
+ padding-inline: 0;
+ background-color: var(--bs-bg-body);
+ border-top: 1px solid var(--bs-border-color);
+ @include border-radius(0);
}
.carbon-img {
+ position: relative;
display: block;
float: none;
+ width: fit-content;
margin-inline-start: 0;
+
+ &::after {
+ position: absolute;
+ inset: 0;
+ display: block;
+ content: "";
+ border: 1px solid var(--bs-border-color-translucent);
+ @include border-radius(var(--bs-border-radius-sm));
+ }
}
.carbon-wrap {
flex-direction: column;
gap: .5rem;
}
-
- .carbon-img > img {
- width: 100%;
- max-width: 100% !important;
- height: auto;
- @include border-radius(var(--bs-border-radius-sm));
- }
}
.carbon-poweredby {
display: block;
- margin-top: .75rem;
+ margin-top: .5rem;
color: var(--bs-fg-3) !important;
}
}
}
.bd-navbar {
+ --bs-border-color: color-mix(in oklch, var(--bs-fg-body) 12%, transparent);
padding: .75rem 0;
- // background-color: transparent;
- // box-shadow: 0 .5rem 1rem rgba($black, .15), inset 0 -1px 0 rgba($white, .15);
-
- // @media (forced-colors) {
- // background-color: Canvas;
- // }
-
- // &::after {
- // position: absolute;
- // inset: 0;
- // z-index: -1;
- // display: block;
- // content: "";
- // background-image: linear-gradient(var(--bd-violet), color-mix(in srgb, var(--bd-violet), transparent 5%));
- // // background-image: linear-gradient(color-mix(in srgb, var(--bs-gray-900), $black 10%), color-mix(in srgb, var(--bs-gray-900), $black 15%));
- // }
+ margin-bottom: -1px;
+ background-clip: padding-box;
.bd-navbar-toggle {
@include media-breakpoint-down(lg) {
}
}
- .bd-links-heading {
- gap: .25rem;
- color: var(--bs-emphasis-color);
- }
- .bd-links-heading .bi {
- width: 16px;
- height: 16px;
- }
+ .bd-links {
+ .nav {
+ --bs-nav-gap: 2px;
+ --bs-nav-link-justify: flex-start;
+ --bs-nav-link-font-size: #{$font-size-sm};
+ --bs-nav-link-padding-x: .75rem;
+ --bs-nav-link-padding-y: .25rem;
+ margin-top: .25rem;
+ }
- .bd-links-subgroup {
- margin-inline-start: 1.75rem;
- color: var(--bs-fg-3);
- }
+ .nav-link {
+ margin-inline-start: 1rem;
+ }
- .bd-links-nav {
@include media-breakpoint-between(xs, lg) {
column-count: 2;
column-gap: 1.5rem;
}
}
- .bd-links-link {
- display: block;
- padding: .25rem .75rem;
- margin-inline-start: 1rem;
- margin-top: .125rem;
- font-size: .875rem;
- color: var(--bs-body-color);
- text-decoration: none;
- @include border-radius(var(--bs-border-radius));
-
- &:hover {
- background-color: var(--bs-bg-1);
- }
-
- &:focus-visible {
- @include focus-ring();
- }
+ .bd-links-heading {
+ gap: .25rem;
+ color: var(--bs-emphasis-color);
+ }
+ .bd-links-heading .bi {
+ width: 16px;
+ height: 16px;
+ }
- &.active {
- font-weight: 500;
- color: var(--bs-emphasis-color);
- background-color: var(--bs-bg-2);
- }
+ .bd-links-subgroup {
+ margin-inline-start: 1.75rem;
+ color: var(--bs-fg-body);
}
}
@use "../../../scss/layout/breakpoints" as *;
@use "../../../scss/mixins/border-radius" as *;
-// stylelint-disable selector-max-type, selector-no-qualifying-type
-
@layer custom {
.bd-toc {
container-type: inline-size;
top: 5rem;
right: 0;
z-index: 2;
- height: calc(100vh - 7rem);
- overflow-y: auto;
+ height: calc(100vh - 6em);
+ // overflow-y: auto;
}
- nav {
- font-size: .875rem;
- // @include font-size(.875rem);
-
- ul {
- padding-inline-start: 0;
- margin-bottom: 0;
- list-style: none;
-
- ul {
- padding-inline-start: 1rem;
- }
+ .nav {
+ --bs-nav-link-justify: flex-start;
+ --bs-nav-link-padding-x: .75rem;
+ --bs-nav-link-padding-y: .125rem;
+ --bs-nav-link-font-size: .875rem;
+ --bs-nav-link-hover-bg: transparent;
+ --bs-nav-link-active-bg: transparent;
+ --bs-nav-link-active-color: var(--bs-fg-body);
+ --bs-border-radius: 0;
+
+ .nav .nav-link{
+ padding-inline-start: 1.75rem;
}
+ }
- a {
- display: block;
- padding: .125rem 0 .125rem .75rem;
- color: inherit;
- text-decoration: none;
- border-inline-start: .125rem solid transparent;
-
- &:hover,
- &.active {
- color: var(--bd-toc-color);
- border-inline-start-color: var(--bd-toc-color);
- }
+ .nav-link {
+ border-inline-start: .125rem solid transparent;
- &.active {
- font-weight: 500;
- }
+ &.active {
+ font-weight: 500;
+ border-inline-start-color: var(--bs-fg-body);
+ }
- code {
- font: inherit;
- }
+ code {
+ font: inherit;
}
}
}
+
.bd-toc-toggle {
display: flex;
align-items: center;
- @include media-breakpoint-down(sm) {
+ @include media-breakpoint-down(md) {
justify-content: space-between;
width: 100%;
}
- @include media-breakpoint-down(md) {
+ @include media-breakpoint-down(lg) {
color: var(--bs-color-body);
border: 1px solid var(--bs-border-color);
@include border-radius(var(--bs-border-radius));
}
.bd-toc-collapse {
- @include media-breakpoint-down(md) {
+ @include media-breakpoint-down(lg) {
nav {
padding: 1.25rem 1.25rem 1.25rem 1rem;
background-color: var(--bs-bg-subtle);
}
}
- @include media-breakpoint-up(md) {
+ @include media-breakpoint-up(lg) {
display: block !important; // stylelint-disable-line declaration-no-important
}
}
--bd-violet: #{$bd-violet};
--bd-accent: #{$bd-accent};
--bd-violet-bg: var(--bd-violet);
- --bd-toc-color: light-dark(var(--bd-violet), var(--bs-indigo-300));
+ --bd-toc-color: var(--bs-fg-body);
--bd-sidebar-link-bg: light-dark(color-mix(in srgb, var(--bd-violet), transparent 90%), color-mix(in srgb, var(--bd-violet), transparent 70%));
--bd-callout-link: var(--blue-600);
--bd-callout-code-color: light-dark(var(--bs-pink-600), var(--bs-pink-300));