]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Clean up some Astro and Docs stuff (#42355)
authorMark Otto <markd.otto@gmail.com>
Thu, 30 Apr 2026 17:12:11 +0000 (10:12 -0700)
committerGitHub <noreply@github.com>
Thu, 30 Apr 2026 17:12:11 +0000 (10:12 -0700)
53 files changed:
eslint.config.js
site/.prettierrc.json
site/astro.config.ts
site/src/assets/application.js
site/src/assets/partials/sidebar.js
site/src/assets/partials/snippets.js
site/src/assets/partials/sticky.js
site/src/assets/partials/toc.js
site/src/assets/search.js
site/src/assets/snippets.js [deleted file]
site/src/assets/stackblitz.js
site/src/components/Ads.astro
site/src/components/DocsScripts.astro
site/src/components/DocsSidebar.astro
site/src/components/HelperReferenceTable.astro
site/src/components/NewBadge.astro
site/src/components/PageMeta.astro
site/src/components/ReferenceTable.astro
site/src/components/TableOfContents.astro
site/src/components/UtilityReferenceTable.astro
site/src/components/head/Head.astro
site/src/components/head/Scss.astro
site/src/components/head/ScssProd.astro
site/src/components/head/Stylesheet.astro
site/src/components/header/LinkItem.astro
site/src/components/header/Navigation.astro
site/src/components/home/CSSVariables.astro
site/src/components/home/GetStarted.astro
site/src/components/home/MastHead.astro
site/src/components/icons/CssTricksIcon.astro
site/src/components/icons/HamburgerIcon.astro
site/src/components/icons/MdnIcon.astro
site/src/components/icons/Symbols.astro
site/src/components/shortcodes/ButtonPlayground.astro
site/src/components/shortcodes/CSSVariables.astro
site/src/components/shortcodes/Callout.astro
site/src/components/shortcodes/CloseButton.astro
site/src/components/shortcodes/Code.astro
site/src/components/shortcodes/CodeCopy.astro
site/src/components/shortcodes/Details.astro
site/src/components/shortcodes/Example.astro
site/src/components/shortcodes/MenuPlacementPlayground.astro
site/src/components/shortcodes/NavbarPlacementPlayground.astro
site/src/components/shortcodes/ResizableExample.astro
site/src/components/shortcodes/Swatch.astro
site/src/layouts/BaseLayout.astro
site/src/layouts/DocsLayout.astro
site/src/layouts/ExamplesLayout.astro
site/src/layouts/partials/ThemeToggler.astro
site/src/libs/clipboard.ts
site/src/libs/data.ts
site/src/libs/utils.ts
site/tsconfig.json

index d807078449a1a48e13c8c118def72b57f7df611f..e0351f153fcad9034a68aecc727c660205f846a8 100644 (file)
@@ -288,7 +288,6 @@ const eslintConfig = [
       'site/src/assets/application.js',
       'site/src/assets/partials/*.js',
       'site/src/assets/search.js',
-      'site/src/assets/snippets.js',
       'site/src/assets/stackblitz.js',
       'site/src/plugins/*.js'
     ],
index a723ce1e1ee0ff8ba63e99fb88065a5fcd05a493..b3ef3394272bdcd06267a96b97243a69fa102a32 100644 (file)
@@ -1,6 +1,7 @@
 {
   "$schema": "http://json.schemastore.org/prettierrc",
   "arrowParens": "always",
+  "plugins": ["prettier-plugin-astro"],
   "printWidth": 120,
   "semi": false,
   "singleQuote": true,
index 14534850423ac11055c95dcd06d122f75832d28a..45142be4aaba72b3745f92bdb31c2053dd672974 100644 (file)
@@ -1,3 +1,5 @@
+import { fileURLToPath } from 'node:url'
+
 import { defineConfig } from 'astro/config'
 import astroBrokenLinksChecker from 'astro-broken-links-checker'
 import bootstrapLight from 'bootstrap-vscode-theme/themes/bootstrap-light.json'
@@ -9,6 +11,11 @@ import { getConfig } from './src/libs/config'
 import { algoliaPlugin } from './src/plugins/algolia-plugin'
 import { stackblitzPlugin } from './src/plugins/stackblitz-plugin'
 
+// Resolve `@bootstrap` to the same on-disk Bootstrap bundle the docs ship, so
+// every docs script imports from a single module instance (no duplicated
+// component registries). Mirrors the `@bootstrap` alias in `tsconfig.json`.
+const bootstrapBundlePath = fileURLToPath(new URL('../dist/js/bootstrap.bundle.js', import.meta.url))
+
 const isDev = process.env.NODE_ENV === 'development'
 
 const site = isDev
@@ -62,6 +69,11 @@ export default defineConfig({
   },
   site,
   vite: {
-    plugins: [algoliaPlugin(), stackblitzPlugin()]
+    plugins: [algoliaPlugin(), stackblitzPlugin()],
+    resolve: {
+      alias: {
+        '@bootstrap': bootstrapBundlePath
+      }
+    }
   }
 })
index 2936465acc6ada3685ad8af0ab6989f4f79a958f..2a758ca314afebfafa745ace56dfc6fdc550d165 100644 (file)
@@ -1,6 +1,4 @@
-// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
-// IT'S ALL JUST JUNK FOR OUR DOCS!
-// ++++++++++++++++++++++++++++++++++++++++++
+// NOTICE: Internal docs helpers — not shipped in Bootstrap; not for reuse.
 
 /*!
  * JavaScript for Bootstrap's docs (https://getbootstrap.com/)
index ca90442da471e95afb5081fa34591e05a6384396..ce8292e3df07066f95a6d669bb5a2272e3ee61ae 100644 (file)
@@ -1,6 +1,4 @@
-// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
-// IT'S ALL JUST JUNK FOR OUR DOCS!
-// ++++++++++++++++++++++++++++++++++++++++++
+// NOTICE: Internal docs helpers — not shipped in Bootstrap; not for reuse.
 
 /*
  * JavaScript for Bootstrap's docs (https://getbootstrap.com/)
index 2e7fa5e27564f5dc3a37b88bb8e1f6d206360c64..60e7664907ad750c4bea4737b7a7d44f697f483b 100644 (file)
@@ -1,8 +1,5 @@
-// NOTICE!!! Initially embedded in our docs this JavaScript
-// file contains elements that can help you create reproducible
-// use cases in StackBlitz for instance.
-// In a real project please adapt this content to your needs.
-// ++++++++++++++++++++++++++++++++++++++++++
+// NOTICE: Embedded as-is into StackBlitz playgrounds via `?raw` import.
+// Adapt to your needs in real projects.
 
 /*
  * JavaScript for Bootstrap's docs (https://getbootstrap.com/)
@@ -16,7 +13,7 @@ import {
   Popover,
   Toast,
   Carousel
-} from '../../../../dist/js/bootstrap.bundle.js'
+} from '@bootstrap'
 
 export default () => {
   // --------
index 8e673895e866cd9d9898924a7276bac782342e8f..4db97bfa270ed268cd6c46f40fe97eaa11246794 100644 (file)
@@ -1,6 +1,4 @@
-// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
-// IT'S ALL JUST JUNK FOR OUR DOCS!
-// ++++++++++++++++++++++++++++++++++++++++++
+// NOTICE: Internal docs helpers — not shipped in Bootstrap; not for reuse.
 
 /*
  * JavaScript for Bootstrap's docs (https://getbootstrap.com/)
index 5198fbe13b043ee30a3709c341d1e9c99fb7df85..1ebed1c0cdb070b9f8d5b6d00876b8039392448b 100644 (file)
@@ -1,6 +1,4 @@
-// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
-// IT'S ALL JUST JUNK FOR OUR DOCS!
-// ++++++++++++++++++++++++++++++++++++++++++
+// NOTICE: Internal docs helpers — not shipped in Bootstrap; not for reuse.
 
 /*
  * JavaScript for Bootstrap's docs (https://getbootstrap.com/)
@@ -9,7 +7,7 @@
  * For details, see https://creativecommons.org/licenses/by/3.0/.
  */
 
-import { Drawer } from '../../../../dist/js/bootstrap.bundle.js'
+import { Drawer } from '@bootstrap'
 
 export default () => {
   const tocSidebar = document.querySelector('#bdTocSidebar')
index 2d8e868c85f131dae22621120ba08aba20a4c5d4..4b8781deef0d5ae7ced2d6579c0f33b0a6dc3147 100644 (file)
@@ -1,6 +1,4 @@
-// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
-// IT'S ALL JUST JUNK FOR OUR DOCS!
-// ++++++++++++++++++++++++++++++++++++++++++
+// NOTICE: Internal docs helpers — not shipped in Bootstrap; not for reuse.
 
 /*!
  * JavaScript for Bootstrap's docs (https://getbootstrap.com/)
diff --git a/site/src/assets/snippets.js b/site/src/assets/snippets.js
deleted file mode 100644 (file)
index 3ca0bf6..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * JavaScript for Bootstrap's docs (https://getbootstrap.com/)
- * Copyright 2011-2026 The Bootstrap Authors
- * Licensed under the Creative Commons Attribution 3.0 Unported License.
- * For details, see https://creativecommons.org/licenses/by/3.0/.
- */
-
-// Note that this file is not published; we only include it in scripts.html
-// for StackBlitz to work
-
-import snippets from 'js/partials/snippets.js'
-
-snippets()
index a944ef8a00534a7e3836fa2ee15886b44a821c9b..ddb3d32cb80f813b161209d455c4e77a0b38a27d 100644 (file)
@@ -1,8 +1,5 @@
-// NOTICE!!! Initially embedded in our docs this JavaScript
-// file contains elements that can help you create reproducible
-// use cases in StackBlitz for instance.
-// In a real project please adapt this content to your needs.
-// ++++++++++++++++++++++++++++++++++++++++++
+// NOTICE: Drives the "Open in StackBlitz" button on docs examples; bundles
+// `partials/snippets.js` as raw text into the generated playground.
 
 /*!
  * JavaScript for Bootstrap's docs (https://getbootstrap.com/)
index e7e87e2cffbb57092a776939f719405325c2d29f..1c9ebd096e7e8536b0dd0bbbae26963256724123 100644 (file)
@@ -1,9 +1,9 @@
 ---
+
 ---
 
 <script
   is:inline
   async
   src="https://cdn.carbonads.com/carbon.js?serve=CKYIKKJL&placement=getbootstrapcom&format=responsive"
-  id="_carbonads_js"
-></script>
+  id="_carbonads_js"></script>
index 320d91e5f4de9e5790d8db72bd9f3f9cff7212ab..503f175df824453d456fbe4f90f9e04032953989 100644 (file)
@@ -1,4 +1,7 @@
 ---
+// Loaded only on docs pages from `Scripts.astro`. Astro extracts/bundles
+// `<script>` tags per component, so this stays in its own file to keep the
+// StackBlitz SDK import out of non-docs entry chunks.
 ---
 
 <script>
index 93e3054990af4c2c5fa37632d3364c2e58522e0d..4da2d840b4c597053c0ac372802395c3082e77c1 100644 (file)
@@ -1,5 +1,5 @@
 ---
-import { getData } from '@libs/data'
+import { getData, type SidebarItem, type SidebarSubItem } from '@libs/data'
 import { getConfig } from '@libs/config'
 import { docsPages, getDocsPageSlug } from '@libs/content'
 import { getSlug } from '@libs/utils'
@@ -20,7 +20,10 @@ const sidebar = getData('sidebar')
               {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));`}
+                  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}`} />
@@ -29,15 +32,13 @@ const sidebar = getData('sidebar')
               {group.title}
             </strong>
             <ul class="nav flex-column bd-links-nav">
-              {group.pages?.map((item: any) => {
+              {group.pages?.map((item: SidebarItem) => {
                 // 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) => {
+                      <li class="bd-links-subgroup fw-semibold mt-3">{item.group}</li>
+                      {item.pages.map((page: SidebarSubItem) => {
                         const docSlug = getSlug(page.title)
                         const unversionedPageSlug = `${groupSlug}/${docSlug}`
 
@@ -53,7 +54,7 @@ const sidebar = getData('sidebar')
                           )
                         }
 
-                        const addedMeta = page.meta?.find((m: any) => m.added)
+                        const addedMeta = page.meta?.find((m) => m.added)
 
                         return (
                           <li>
@@ -73,6 +74,10 @@ const sidebar = getData('sidebar')
                 }
 
                 // Handle regular pages
+                if (!item.title) {
+                  return null
+                }
+
                 const docSlug = getSlug(item.title)
                 const unversionedPageSlug = `${groupSlug}/${docSlug}`
 
@@ -88,7 +93,7 @@ const sidebar = getData('sidebar')
                   )
                 }
 
-                const itemAddedMeta = item.meta?.find((m: any) => m.added)
+                const itemAddedMeta = item.meta?.find((m) => m.added)
 
                 return (
                   <li>
index 48bb566fa4e4a1db69098446e6955db111565596..57d063e50a87908a545d700d55cdf8df64907bf1 100644 (file)
@@ -1,24 +1,21 @@
 ---
 interface ClassItem {
-  class: string;
-  description: string;
+  class: string
+  description: string
 }
 
 interface Props {
-  classes: ClassItem[];
-  className?: string;
+  classes: ClassItem[]
+  className?: string
 }
 
-const {
-  classes,
-  className = "table reference-table"
-} = Astro.props;
+const { classes, className = 'table reference-table' } = Astro.props
 
 // Format class names with dot prefix if needed
-const tableData = classes.map(item => ({
+const tableData = classes.map((item) => ({
   class: item.class.startsWith('.') ? item.class : `.${item.class}`,
   description: item.description
-}));
+}))
 ---
 
 <div class="table-responsive bd-reference-table">
@@ -30,12 +27,16 @@ const tableData = classes.map(item => ({
       </tr>
     </thead>
     <tbody>
-      {tableData.map((row) => (
-        <tr>
-          <td><code>{row.class}</code></td>
-          <td>{row.description}</td>
-        </tr>
-      ))}
+      {
+        tableData.map((row) => (
+          <tr>
+            <td>
+              <code>{row.class}</code>
+            </td>
+            <td>{row.description}</td>
+          </tr>
+        ))
+      }
     </tbody>
   </table>
 </div>
index 1f699f847ad8bbe7d40b87be7c37907215671383..41a61221b7a89897fe016cded034fa92f2041339 100644 (file)
@@ -6,11 +6,7 @@ interface Props {
 const { version } = Astro.props
 ---
 
-<span
-  class="badge bg-3 ms-auto fg-3 fw-normal me--1"
-  data-bs-toggle="tooltip"
-  data-bs-title={`Added in v${version}`}
->
+<span class="badge bg-3 ms-auto fg-3 fw-normal me--1" data-bs-toggle="tooltip" data-bs-title={`Added in v${version}`}>
   New
   <span class="visually-hidden">{` (Added in v${version})`}</span>
 </span>
index d96d5444739e34b4f70958536c89105a44687081..46cf4fcf549c91cdc6ff8779db2603333ce9e7ca 100644 (file)
@@ -40,76 +40,130 @@ const depsCount = deps.length
 ---
 
 <div class="bd-page-meta w-100 d-grid md:grid-cols-2 lg:d-flex gap-5 row-gap-2 px-4 py-3 bg-1 fg-2 fs-sm rounded-3">
-  {frontmatter.js === 'required' && (
-    <div class="d-flex align-items-center gap-2">
-      <svg class="bi fg-warning" aria-hidden="true"><use href="#filetype-js" /></svg>
-      Requires JavaScript
-    </div>
-  )}
-  {frontmatter.js === 'optional' && (
-    <div class="d-flex align-items-center gap-2">
-      <svg class="bi fg-warning opacity-50" aria-hidden="true"><use href="#filetype-js" /></svg>
-      JavaScript is optional
-    </div>
-  )}
-  {frontmatter.css_layer && (
-    <div class="d-flex align-items-center gap-2">
-      <svg class="bi fg-accent" aria-hidden="true"><use href="#css" /></svg>
-      <span>In <code class="fg-body">{frontmatter.css_layer}</code> layer</span>
-    </div>
-  )}
-  {frontmatter.css_media === 'container' && (
-    <div class="d-flex align-items-center gap-2">
-      <svg class="bi" aria-hidden="true" style="color: var(--bs-pink-500);"><use href="#bounding-box-fill" /></svg>
-      Container queries
-    </div>
-  )}
-  {frontmatter.css_media === 'viewport' && (
-    <div class="d-flex align-items-center gap-2">
-      <svg class="bi" aria-hidden="true" style="color: var(--bs-purple-500);"><use href="#aspect-ratio-fill" /></svg>
-      Viewport queries
-    </div>
-  )}
-  {depsCount > 0 && (
-    <div class="d-flex align-items-center gap-2">
-      <svg class="bi fg-2" aria-hidden="true"><use href="#box-seam-fill" /></svg>
-      <div>
-        Depends on
-        {deps.map((dep, i) => (
-          <Fragment>{i > 0 && ', '}{dep.url?.startsWith('http') ? (
-              <a class="fg-2 text-decoration-none" href={dep.url} target="_blank" rel="noopener">{dep.title}</a>
-            ) : dep.url ? (
-              <a class="fg-2 text-decoration-none" href={dep.url}>{dep.title}</a>
-            ) : (
-              <a class="fg-2 text-decoration-none" href={getVersionedDocsPath(`components/${getSlug(dep.title)}/`)}>{dep.title}</a>
-            )}</Fragment>
-        ))}
+  {
+    frontmatter.js === 'required' && (
+      <div class="d-flex align-items-center gap-2">
+        <svg class="bi fg-warning" aria-hidden="true">
+          <use href="#filetype-js" />
+        </svg>
+        Requires JavaScript
       </div>
-    </div>
-  )}
-  {frontmatter.added &&
-    ((frontmatter.added.show_badge === undefined || frontmatter.added.show_badge === true)) && (
-    <div class="d-flex align-items-center gap-2">
-      <svg class="bi fg-success" aria-hidden="true"><use href="#plus" /></svg>
-      Added in v{frontmatter.added.version}
-    </div>
-  )}
-  {frontmatter.mdn && (
-    <div class="d-flex align-items-center gap-2">
-      <MdnIcon height={16} width={16} class="bi fg-2" />
-      <a class="fg-2 text-decoration-none" href={frontmatter.mdn} target="_blank" rel="noopener">MDN Reference</a>
-    </div>
-  )}
-  {frontmatter.csstricks && (
-    <div class="d-flex align-items-center gap-2">
-      <CssTricksIcon height={16} width={16} class="bi fg-2" />
-      <a class="fg-2 text-decoration-none" href={typeof frontmatter.csstricks === 'string' ? frontmatter.csstricks : frontmatter.csstricks.url} target="_blank" rel="noopener">
-        {typeof frontmatter.csstricks === 'string' ? 'CSS-Tricks' : (frontmatter.csstricks.label || 'CSS-Tricks')}
-      </a>
-    </div>
-  )}
+    )
+  }
+  {
+    frontmatter.js === 'optional' && (
+      <div class="d-flex align-items-center gap-2">
+        <svg class="bi fg-warning opacity-50" aria-hidden="true">
+          <use href="#filetype-js" />
+        </svg>
+        JavaScript is optional
+      </div>
+    )
+  }
+  {
+    frontmatter.css_layer && (
+      <div class="d-flex align-items-center gap-2">
+        <svg class="bi fg-accent" aria-hidden="true">
+          <use href="#css" />
+        </svg>
+        <span>
+          In <code class="fg-body">{frontmatter.css_layer}</code> layer
+        </span>
+      </div>
+    )
+  }
+  {
+    frontmatter.css_media === 'container' && (
+      <div class="d-flex align-items-center gap-2">
+        <svg class="bi" aria-hidden="true" style="color: var(--bs-pink-500);">
+          <use href="#bounding-box-fill" />
+        </svg>
+        Container queries
+      </div>
+    )
+  }
+  {
+    frontmatter.css_media === 'viewport' && (
+      <div class="d-flex align-items-center gap-2">
+        <svg class="bi" aria-hidden="true" style="color: var(--bs-purple-500);">
+          <use href="#aspect-ratio-fill" />
+        </svg>
+        Viewport queries
+      </div>
+    )
+  }
+  {
+    depsCount > 0 && (
+      <div class="d-flex align-items-center gap-2">
+        <svg class="bi fg-2" aria-hidden="true">
+          <use href="#box-seam-fill" />
+        </svg>
+        <div>
+          Depends on
+          {deps.map((dep, i) => (
+            <Fragment>
+              {i > 0 && ', '}
+              {dep.url?.startsWith('http') ? (
+                <a class="fg-2 text-decoration-none" href={dep.url} target="_blank" rel="noopener">
+                  {dep.title}
+                </a>
+              ) : dep.url ? (
+                <a class="fg-2 text-decoration-none" href={dep.url}>
+                  {dep.title}
+                </a>
+              ) : (
+                <a class="fg-2 text-decoration-none" href={getVersionedDocsPath(`components/${getSlug(dep.title)}/`)}>
+                  {dep.title}
+                </a>
+              )}
+            </Fragment>
+          ))}
+        </div>
+      </div>
+    )
+  }
+  {
+    frontmatter.added && (frontmatter.added.show_badge === undefined || frontmatter.added.show_badge === true) && (
+      <div class="d-flex align-items-center gap-2">
+        <svg class="bi fg-success" aria-hidden="true">
+          <use href="#plus" />
+        </svg>
+        Added in v{frontmatter.added.version}
+      </div>
+    )
+  }
+  {
+    frontmatter.mdn && (
+      <div class="d-flex align-items-center gap-2">
+        <MdnIcon height={16} width={16} class="bi fg-2" />
+        <a class="fg-2 text-decoration-none" href={frontmatter.mdn} target="_blank" rel="noopener">
+          MDN Reference
+        </a>
+      </div>
+    )
+  }
+  {
+    frontmatter.csstricks && (
+      <div class="d-flex align-items-center gap-2">
+        <CssTricksIcon height={16} width={16} class="bi fg-2" />
+        <a
+          class="fg-2 text-decoration-none"
+          href={typeof frontmatter.csstricks === 'string' ? frontmatter.csstricks : frontmatter.csstricks.url}
+          target="_blank"
+          rel="noopener"
+        >
+          {typeof frontmatter.csstricks === 'string' ? 'CSS-Tricks' : frontmatter.csstricks.label || 'CSS-Tricks'}
+        </a>
+      </div>
+    )
+  }
   <div class="d-flex align-items-center gap-2">
-    <svg class="bi fg-2" aria-hidden="true"><use href="#github" /></svg>
-    <a class="fg-2 text-decoration-none" href={`${getConfig().repo}/blob/v${getConfig().current_version}/site/src/content/docs/${id}`} target="_blank" rel="noopener">View & Edit</a>
+    <svg class="bi fg-2" aria-hidden="true"><use href="#github"></use></svg>
+    <a
+      class="fg-2 text-decoration-none"
+      href={`${getConfig().repo}/blob/v${getConfig().current_version}/site/src/content/docs/${id}`}
+      target="_blank"
+      rel="noopener">View & Edit</a
+    >
   </div>
 </div>
index ff9b33838b3456c0911d3f5c067395851728cddc..f91f4322c252c124281f82f35aee6453d0577bb4 100644 (file)
 ---
-import { readFileSync } from 'node:fs';
-import { join } from 'node:path';
+import { readFileSync } from 'node:fs'
+import { join } from 'node:path'
 
 interface ReferenceItem {
-  class: string;
-  styles?: string | string[] | Record<string, string>;
-  description?: string;
-  comment?: string; // Optional manual comment to append
-  [key: string]: any; // Allow additional properties
+  class: string
+  styles?: string | string[] | Record<string, string>
+  description?: string
+  comment?: string // Optional manual comment to append
+  [key: string]: any // Allow additional properties
 }
 
 interface Props {
-  className?: string;
-  columns?: Array<{ label: string; key: string }>;
-  data?: Array<any>;
-  reference?: Array<ReferenceItem>; // Direct prop for reference data
+  className?: string
+  columns?: Array<{ label: string; key: string }>
+  data?: Array<any>
+  reference?: Array<ReferenceItem> // Direct prop for reference data
 }
 
-const {
-  className = "table reference-table",
-  columns,
-  data,
-  reference
-} = Astro.props;
+const { className = 'table reference-table', columns, data, reference } = Astro.props
 
 // Use explicit reference prop or data prop
-const referenceData = reference || data || [];
+const referenceData = reference || data || []
 
 // Parse CSS variables from _root.scss at build time
 function parseCSSVariables(): Record<string, string> {
   try {
-    const projectRoot = process.cwd();
-    const rootScssPath = join(projectRoot, 'scss/_root.scss');
-    const scssContent = readFileSync(rootScssPath, 'utf-8');
+    const projectRoot = process.cwd()
+    const rootScssPath = join(projectRoot, 'scss/_root.scss')
+    const scssContent = readFileSync(rootScssPath, 'utf-8')
 
-    const cssVarValues: Record<string, string> = {};
+    const cssVarValues: Record<string, string> = {}
 
     // Match CSS variable declarations: --#{$prefix}variable-name: value;
     // This regex captures the variable name and its value
-    const varRegex = /--#\{\$prefix\}([a-z0-9-]+):\s*([^;]+);/gi;
-    let match;
+    const varRegex = /--#\{\$prefix\}([a-z0-9-]+):\s*([^;]+);/gi
+    let match
 
     while ((match = varRegex.exec(scssContent)) !== null) {
-      const varName = `--bs-${match[1]}`;
-      let value = match[2].trim();
+      const varName = `--bs-${match[1]}`
+      let value = match[2].trim()
 
       // Clean up SCSS interpolation syntax (e.g., #{$variable})
-      value = value.replace(/#\{[^}]+\}/g, '').trim();
+      value = value.replace(/#\{[^}]+\}/g, '').trim()
 
       // Remove inline comments
-      value = value.replace(/\/\/.*$/gm, '').trim();
+      value = value.replace(/\/\/.*$/gm, '').trim()
 
       // Only store if we have a clean value (not empty after removing interpolations)
       if (value) {
-        cssVarValues[varName] = value;
+        cssVarValues[varName] = value
       }
     }
 
-    return cssVarValues;
+    return cssVarValues
   } catch (error) {
-    console.warn('Could not parse CSS variables from _root.scss:', error);
-    return {};
+    console.warn('Could not parse CSS variables from _root.scss:', error)
+    return {}
   }
 }
 
-const cssVarValues = parseCSSVariables();
+const cssVarValues = parseCSSVariables()
 
 // Function to add CSS variable value comments
 function addVarComments(cssValue: string): string {
-  const comments: string[] = [];
+  const comments: string[] = []
 
   // Collect resolved values for all CSS variables
   cssValue.replace(/var\((--[a-z0-9-]+)\)/gi, (match, varName) => {
-    const resolvedValue = cssVarValues[varName];
+    const resolvedValue = cssVarValues[varName]
     if (resolvedValue) {
-      comments.push(`<span class="fg-3">/* ${resolvedValue} */</span>`);
+      comments.push(`<span class="fg-3">/* ${resolvedValue} */</span>`)
     }
-    return match;
-  });
+    return match
+  })
 
   // Append comments after the last semicolon or at the end
   if (comments.length > 0) {
-    const hasSemicolon = cssValue.trimEnd().endsWith(';');
-    return `${cssValue}${hasSemicolon ? '' : ';'} ${comments.join(' ')}`;
+    const hasSemicolon = cssValue.trimEnd().endsWith(';')
+    return `${cssValue}${hasSemicolon ? '' : ';'} ${comments.join(' ')}`
   }
 
-  return cssValue;
+  return cssValue
 }
 
 // If no explicit columns provided, infer from the first data item
-const inferredColumns = columns || (() => {
-  if (referenceData.length === 0) {
-    return [
-      { label: 'Class', key: 'class' },
-      { label: 'Styles', key: 'styles' }
-    ];
-  }
+const inferredColumns =
+  columns ||
+  (() => {
+    if (referenceData.length === 0) {
+      return [
+        { label: 'Class', key: 'class' },
+        { label: 'Styles', key: 'styles' }
+      ]
+    }
 
-  const firstItem = referenceData[0];
-  return Object.keys(firstItem)
-    .filter(key => key !== 'comment') // Exclude comment field from columns
-    .map(key => ({
-      label: key.charAt(0).toUpperCase() + key.slice(1),
-      key: key
-    }));
-})();
+    const firstItem = referenceData[0]
+    return Object.keys(firstItem)
+      .filter((key) => key !== 'comment') // Exclude comment field from columns
+      .map((key) => ({
+        label: key.charAt(0).toUpperCase() + key.slice(1),
+        key: key
+      }))
+  })()
 
 // Transform frontmatter format to table format
 const tableData = referenceData.map((item: ReferenceItem) => {
-  const transformedItem: Record<string, any> = {};
+  const transformedItem: Record<string, any> = {}
 
-  inferredColumns.forEach(column => {
-    const key = column.key;
-    let value = item[key];
+  inferredColumns.forEach((column) => {
+    const key = column.key
+    let value = item[key]
 
     if (key === 'class' && typeof value === 'string' && !value.startsWith('.')) {
-      value = `.${value}`;
+      value = `.${value}`
     }
 
     if (key === 'styles') {
-      let processedStyles = '';
+      let processedStyles = ''
 
       if (typeof value === 'string') {
-        processedStyles = addVarComments(value);
+        processedStyles = addVarComments(value)
       } else if (typeof value === 'object' && !Array.isArray(value)) {
         // Handle object syntax: { prop: value, prop2: value2 }
         processedStyles = Object.entries(value)
           .map(([prop, val]) => {
-            const cssLine = `${prop}: ${val};`;
-            return addVarComments(cssLine);
+            const cssLine = `${prop}: ${val};`
+            return addVarComments(cssLine)
           })
-          .join('<br/>');
+          .join('<br/>')
       } else if (Array.isArray(value)) {
-        processedStyles = value.map((style: any) => {
-          if (typeof style === 'string') {
-            const formattedStyle = style.includes(':') ? style + (style.endsWith(';') ? '' : ';') : style;
-            return addVarComments(formattedStyle);
-          }
-          if (typeof style === 'object') {
-            const cssLine = Object.entries(style).map(([prop, val]) => `${prop}: ${val};`).join(' ');
-            return addVarComments(cssLine);
-          }
-          return style;
-        }).join('<br/>');
+        processedStyles = value
+          .map((style: any) => {
+            if (typeof style === 'string') {
+              const formattedStyle = style.includes(':') ? style + (style.endsWith(';') ? '' : ';') : style
+              return addVarComments(formattedStyle)
+            }
+            if (typeof style === 'object') {
+              const cssLine = Object.entries(style)
+                .map(([prop, val]) => `${prop}: ${val};`)
+                .join(' ')
+              return addVarComments(cssLine)
+            }
+            return style
+          })
+          .join('<br/>')
       } else {
-        processedStyles = value || '';
+        processedStyles = value || ''
       }
 
       // Append manual comment if provided in frontmatter
       if (item.comment) {
-        processedStyles += `<br/><span class="color-3">/* ${item.comment} */</span>`;
+        processedStyles += `<br/><span class="color-3">/* ${item.comment} */</span>`
       }
 
-      transformedItem[key] = processedStyles;
+      transformedItem[key] = processedStyles
     } else {
-      transformedItem[key] = value;
+      transformedItem[key] = value
     }
-  });
+  })
 
-  return transformedItem;
-});
+  return transformedItem
+})
 ---
 
 <div class="table-responsive bd-reference-table">
   <table class={className}>
     <thead>
       <tr>
-        {inferredColumns.map(column => (
-          <th scope="col">{column.label}</th>
-        ))}
+        {inferredColumns.map((column) => <th scope="col">{column.label}</th>)}
       </tr>
     </thead>
     <tbody>
-      {tableData.map((row: any) => (
-        <tr>
-          {inferredColumns.map(column => (
-            <td>
-              {column.key === 'styles' ? (
-                <Fragment set:html={row[column.key]} />
-              ) : (
-                row[column.key]
-              )}
-            </td>
-          ))}
-        </tr>
-      ))}
+      {
+        tableData.map((row: any) => (
+          <tr>
+            {inferredColumns.map((column) => (
+              <td>{column.key === 'styles' ? <Fragment set:html={row[column.key]} /> : row[column.key]}</td>
+            ))}
+          </tr>
+        ))
+      }
     </tbody>
   </table>
 </div>
index 734aa363b195177c1ad688ffa41e762f4615acc9..8f8cc5f7b45007c96d7358fdcf1cc2e4c155c7b0 100644 (file)
@@ -17,7 +17,9 @@ const toc = entries ? entries : generateToc(headings ?? [])
     toc.map(({ children, slug, text }) => {
       return (
         <li>
-          <a class="nav-link" href={`#${slug}`}>{text}</a>
+          <a class="nav-link" href={`#${slug}`}>
+            {text}
+          </a>
           {children.length > 0 && <Astro.self entries={children} />}
         </li>
       )
index 1b5669f4ae2c4e74b34946a2f6bd07662f4a9450..9150b1519b5c54cb22d264bad153b24e8878403e 100644 (file)
 ---
-import { readFileSync } from 'node:fs';
-import { join } from 'node:path';
+import { readFileSync } from 'node:fs'
+import { join } from 'node:path'
 
 interface Props {
-  utility: string | string[]; // The utility key(s) from the metadata (e.g., "font-size" or ["font-size", "text-size"])
-  className?: string;
+  utility: string | string[] // The utility key(s) from the metadata (e.g., "font-size" or ["font-size", "text-size"])
+  className?: string
 }
 
-const {
-  utility,
-  className = "table reference-table"
-} = Astro.props;
+const { utility, className = 'table reference-table' } = Astro.props
 
 // Normalize to array
-const utilities = Array.isArray(utility) ? utility : [utility];
+const utilities = Array.isArray(utility) ? utility : [utility]
 
 // Parse CSS variables from _root.scss at build time
 function parseCSSVariables(): Record<string, string> {
   try {
-    const projectRoot = process.cwd();
-    const rootScssPath = join(projectRoot, 'scss/_root.scss');
-    const scssContent = readFileSync(rootScssPath, 'utf-8');
+    const projectRoot = process.cwd()
+    const rootScssPath = join(projectRoot, 'scss/_root.scss')
+    const scssContent = readFileSync(rootScssPath, 'utf-8')
 
-    const cssVarValues: Record<string, string> = {};
-    const varRegex = /--#\{\$prefix\}([a-z0-9-]+):\s*([^;]+);/gi;
-    let match;
+    const cssVarValues: Record<string, string> = {}
+    const varRegex = /--#\{\$prefix\}([a-z0-9-]+):\s*([^;]+);/gi
+    let match
 
     while ((match = varRegex.exec(scssContent)) !== null) {
-      const varName = `--bs-${match[1]}`;
-      let value = match[2].trim();
-      value = value.replace(/#\{[^}]+\}/g, '').trim();
-      value = value.replace(/\/\/.*$/gm, '').trim();
+      const varName = `--bs-${match[1]}`
+      let value = match[2].trim()
+      value = value.replace(/#\{[^}]+\}/g, '').trim()
+      value = value.replace(/\/\/.*$/gm, '').trim()
 
       if (value) {
-        cssVarValues[varName] = value;
+        cssVarValues[varName] = value
       }
     }
 
-    return cssVarValues;
+    return cssVarValues
   } catch (error) {
-    console.warn('Could not parse CSS variables from _root.scss:', error);
-    return {};
+    console.warn('Could not parse CSS variables from _root.scss:', error)
+    return {}
   }
 }
 
 // Load utilities metadata
 function loadUtilitiesMetadata(): any {
   try {
-    const projectRoot = process.cwd();
-    const metadataPath = join(projectRoot, 'dist/css/bootstrap-utilities.metadata.json');
-    const metadataContent = readFileSync(metadataPath, 'utf-8');
-    return JSON.parse(metadataContent);
+    const projectRoot = process.cwd()
+    const metadataPath = join(projectRoot, 'dist/css/bootstrap-utilities.metadata.json')
+    const metadataContent = readFileSync(metadataPath, 'utf-8')
+    return JSON.parse(metadataContent)
   } catch (error) {
-    console.warn('Could not load utilities metadata:', error);
-    return { utilities: {} };
+    console.warn('Could not load utilities metadata:', error)
+    return { utilities: {} }
   }
 }
 
 // Parse compiled CSS to extract styles for given class selectors
 function parseCompiledCSS(classNames: string[]): Record<string, string[]> {
   try {
-    const projectRoot = process.cwd();
-    const bootstrapCssPath = join(projectRoot, 'dist/css/bootstrap.css');
-    const cssContent = readFileSync(bootstrapCssPath, 'utf-8');
+    const projectRoot = process.cwd()
+    const bootstrapCssPath = join(projectRoot, 'dist/css/bootstrap.css')
+    const cssContent = readFileSync(bootstrapCssPath, 'utf-8')
 
-    const classStyles: Record<string, string[]> = {};
+    const classStyles: Record<string, string[]> = {}
 
-    classNames.forEach(className => {
+    classNames.forEach((className) => {
       // Match class selectors, including :where() wrapped child-selector utilities
-      const escapedClass = className.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+      const escapedClass = className.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
       const selectorRegex = new RegExp(
         `(?:^|\\n)\\s*(?::where\\()?\\s*\\.${escapedClass}(?:\\s[^{]*)?\\)?\\s*\\{([^}]+)\\}`,
         'gm'
-      );
+      )
 
-      let match;
-      let foundDeclarations: string[] = [];
+      let match
+      let foundDeclarations: string[] = []
 
       while ((match = selectorRegex.exec(cssContent)) !== null) {
         const declarations = match[1]
           .split(';')
-          .map(decl => decl.trim())
-          .filter(decl => decl.length > 0)
-          .map(decl => `${decl};`);
+          .map((decl) => decl.trim())
+          .filter((decl) => decl.length > 0)
+          .map((decl) => `${decl};`)
 
         if (declarations.length > 0) {
-          foundDeclarations = declarations;
-          break;
+          foundDeclarations = declarations
+          break
         }
       }
 
-      classStyles[className] = foundDeclarations;
-    });
+      classStyles[className] = foundDeclarations
+    })
 
-    return classStyles;
+    return classStyles
   } catch (error) {
-    console.warn('Could not parse compiled CSS:', error);
-    return {};
+    console.warn('Could not parse compiled CSS:', error)
+    return {}
   }
 }
 
-const cssVarValues = parseCSSVariables();
-const metadata = loadUtilitiesMetadata();
+const cssVarValues = parseCSSVariables()
+const metadata = loadUtilitiesMetadata()
 
 // Collect classes from all specified utilities
-let allClasses: string[] = [];
+let allClasses: string[] = []
 
-utilities.forEach(util => {
-  const utilityMeta = metadata.utilities[util];
+utilities.forEach((util) => {
+  const utilityMeta = metadata.utilities[util]
 
   if (!utilityMeta) {
-    console.warn(`Utility "${util}" not found in metadata. Available utilities: ${Object.keys(metadata.utilities).join(', ')}`);
-    return;
+    console.warn(
+      `Utility "${util}" not found in metadata. Available utilities: ${Object.keys(metadata.utilities).join(', ')}`
+    )
+    return
   }
 
-  const classes = utilityMeta.classes || [];
-  allClasses = allClasses.concat(classes);
-});
+  const classes = utilityMeta.classes || []
+  allClasses = allClasses.concat(classes)
+})
 
 if (allClasses.length === 0) {
-  throw new Error(`No classes found for utilities: ${utilities.join(', ')}`);
+  throw new Error(`No classes found for utilities: ${utilities.join(', ')}`)
 }
 
-const classStyles = parseCompiledCSS(allClasses);
+const classStyles = parseCompiledCSS(allClasses)
 
 // Function to add CSS variable value comments
 function addVarComments(cssValue: string): string {
-  const comments: string[] = [];
+  const comments: string[] = []
 
   cssValue.replace(/var\((--[a-z0-9-]+)\)/gi, (match, varName) => {
-    const resolvedValue = cssVarValues[varName];
+    const resolvedValue = cssVarValues[varName]
     if (resolvedValue) {
-      comments.push(`<span class="fg-3">/* ${resolvedValue} */</span>`);
+      comments.push(`<span class="fg-3">/* ${resolvedValue} */</span>`)
     }
-    return match;
-  });
+    return match
+  })
 
   if (comments.length > 0) {
-    const hasSemicolon = cssValue.trimEnd().endsWith(';');
-    return `${cssValue}${hasSemicolon ? '' : ';'} ${comments.join(' ')}`;
+    const hasSemicolon = cssValue.trimEnd().endsWith(';')
+    return `${cssValue}${hasSemicolon ? '' : ';'} ${comments.join(' ')}`
   }
 
-  return cssValue;
+  return cssValue
 }
 
 // Build table data
-const tableData = allClasses.map(cls => {
-  const styles = classStyles[cls] || [];
-  const formattedStyles = styles.map(style => addVarComments(style)).join('<br/>');
+const tableData = allClasses.map((cls) => {
+  const styles = classStyles[cls] || []
+  const formattedStyles = styles.map((style) => addVarComments(style)).join('<br/>')
 
   return {
     class: `.${cls}`,
     styles: formattedStyles || '<em>Not found</em>'
-  };
-});
+  }
+})
 ---
 
 <div class="table-responsive bd-reference-table">
@@ -165,12 +164,16 @@ const tableData = allClasses.map(cls => {
       </tr>
     </thead>
     <tbody>
-      {tableData.map((row) => (
-        <tr>
-          <td>{row.class}</td>
-          <td><Fragment set:html={row.styles} /></td>
-        </tr>
-      ))}
+      {
+        tableData.map((row) => (
+          <tr>
+            <td>{row.class}</td>
+            <td>
+              <Fragment set:html={row.styles} />
+            </td>
+          </tr>
+        ))
+      }
     </tbody>
   </table>
 </div>
index 323877efd4dff39ff6712de27ac183c4c3085041..a9f1048caf072f49d9e14dedb6c1a584171cf240 100644 (file)
@@ -43,32 +43,33 @@ const ScssProd = import.meta.env.PROD ? await import('@components/head/ScssProd.
 
 <link rel="preconnect" href=`https://${getConfig().algolia.app_id}-dsn.algolia.net` crossorigin />
 
-<link rel="preconnect" href="https://fonts.googleapis.com">
-<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
-<link href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&family=Geist:wght@100..900&display=swap" rel="stylesheet">
+<link rel="preconnect" href="https://fonts.googleapis.com" />
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
+<link
+  href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&family=Geist:wght@100..900&display=swap"
+  rel="stylesheet"
+/>
 
 <title>{pageTitle}</title>
 
 {robots && <meta name="robots" content={robots} />}
 
+{/* Loaded as `is:inline` (not via Vite) so the theme is applied before paint. */}
+{/* The script lives in `site/static/docs/[version]/assets/js/` so it can */}
+{/* render-block at this exact spot in the head without going through the */}
+{/* bundler (which would defer it and cause a flash of the wrong theme). */}
 <script is:inline src={getVersionedDocsPath('assets/js/color-modes.js')}></script>
 
-<!-- CSS Anchor Positioning polyfill for Firefox/Safari -->
-<script is:inline type="module">
-  if (!CSS.supports('anchor-name', '--test')) {
-    import('https://unpkg.com/@oddbird/css-anchor-positioning/dist/css-anchor-positioning-fn.js')
-      .then(mod => mod.default())
-  }
-</script>
-
-{import.meta.env.PROD && ScssProd && (
-  <Stylesheet layout={layout} />
-  <ScssProd.default />
-)}
-
-{!import.meta.env.PROD && Scss && (
-  <Scss.default />
-)}
+{
+  import.meta.env.PROD && ScssProd && (
+    <>
+      <Stylesheet />
+      <ScssProd.default />
+    </>
+  )
+}
+
+{!import.meta.env.PROD && Scss && <Scss.default />}
 
 <Favicons />
 <Social description={description} layout={layout} thumbnail={thumbnail} title={title} />
index 6f01717cbd23738d2ffcab390417f42addbfc4f9..da90eb6779120f182b5df22a38aad1f4c98b3be8 100644 (file)
@@ -1,4 +1,5 @@
 ---
+
 ---
 
 <link rel="stylesheet" href="/src/scss/docs-dev.scss" />
index 4a639403f3785bce1168e3e041889918babe40bc..bf17edaa4732bf45b3c17db06f04ed9950014ad4 100644 (file)
@@ -1,4 +1,5 @@
 ---
+
 ---
 
 <style is:global lang="scss">
index 81a760143d3e291bbce9b2225fb1764ae5b65173..a4e3c7fb6f54ab3487aa2fb564898851a1683225 100644 (file)
@@ -1,10 +1,5 @@
 ---
 import { getVersionedBsCssProps } from '@libs/bootstrap'
-import type { Layout } from '@libs/layout'
-
-interface Props {
-  layout: Layout
-}
 ---
 
 <link {...getVersionedBsCssProps()} />
index ed5dd2e169e4dd4c6658552d1af5e435d53fe7fa..49d59babb4305912737c616e1142525379417f83 100644 (file)
@@ -14,11 +14,7 @@ const content = await Astro.slots.render('default')
 ---
 
 <li class="nav-item">
-  <a
-    aria-current={active ? true : undefined}
-    class:list={['nav-link px-2', className, { active }]}
-    {...props}
-  >
+  <a aria-current={active ? true : undefined} class:list={['nav-link px-2', className, { active }]} {...props}>
     <slot />
   </a>
 </li>
index 43e3ef1e2d6a14cf5bf1608846bcf81a9dfac9d0..d75b991e211f00f16cf92f948bde37b7a6535da6 100644 (file)
@@ -47,21 +47,36 @@ const activeSection = !layout ? 'Home' : title === 'Examples' ? 'Examples' : 'Do
         <div class="menu">
           <a class:list={['menu-item', { active: !layout }]} href="/">
             Home
-            {!layout && <svg class="bi ms-auto" aria-hidden="true"><use href="#check2"></use></svg>}
+            {
+              !layout && (
+                <svg class="bi ms-auto" aria-hidden="true">
+                  <use href="#check2" />
+                </svg>
+              )
+            }
           </a>
           <a
             class:list={['menu-item', { active: layout === 'docs' }]}
             href={getVersionedDocsPath('getting-started/install/')}
           >
             Docs
-            {layout === 'docs' && <svg class="bi ms-auto" aria-hidden="true"><use href="#check2"></use></svg>}
+            {
+              layout === 'docs' && (
+                <svg class="bi ms-auto" aria-hidden="true">
+                  <use href="#check2" />
+                </svg>
+              )
+            }
           </a>
-          <a
-            class:list={['menu-item', { active: title === 'Examples' }]}
-            href={getVersionedDocsPath('examples/')}
-          >
+          <a class:list={['menu-item', { active: title === 'Examples' }]} href={getVersionedDocsPath('examples/')}>
             Examples
-            {title === 'Examples' && <svg class="bi ms-auto" aria-hidden="true"><use href="#check2"></use></svg>}
+            {
+              title === 'Examples' && (
+                <svg class="bi ms-auto" aria-hidden="true">
+                  <use href="#check2" />
+                </svg>
+              )
+            }
           </a>
           <a class="menu-item" href={getConfig().icons} target="_blank" rel="noopener">
             Icons
@@ -101,12 +116,12 @@ const activeSection = !layout ? 'Home' : title === 'Examples' ? 'Examples' : 'Do
     <ul class="nav navbar-nav flex-row ms-auto">
       <li class="nav-item nav-link px-1" id="docsearch" data-bd-docs-version={getConfig().docs_version}></li>
 
-      <Versions layout={layout} addedIn={addedIn} />
-
       <LinkItem class="px-1 d-none lg:d-flex" href={getConfig().github_org} target="_blank" rel="noopener">
         <GitHubIcon class="navbar-nav-svg" height={16} width={16} />
       </LinkItem>
 
+      <Versions layout={layout} addedIn={addedIn} />
+
       <li class="nav-item">
         <ThemeToggler layout={layout} />
       </li>
index 91169dc6d8a74a96fbb39ae0fe7f27f59678da32..721bbe98b363a4994448159f5d4fbadb136f48e2 100644 (file)
@@ -17,7 +17,10 @@ import Code from '@shortcodes/Code.astro'
       be modified.
     </p>
     <p class="d-flex flex-column lead fw-normal mb-0">
-      <a href={getVersionedDocsPath('getting-started/css-variables')} class="icon-link icon-link-hover fw-semibold mb-3">
+      <a
+        href={getVersionedDocsPath('getting-started/css-variables')}
+        class="icon-link icon-link-hover fw-semibold mb-3"
+      >
         Learn more about CSS variables
         <svg class="bi" aria-hidden="true"><use href="#arrow-right"></use></svg>
       </a>
index e7e18820517d86badc4156b656617ae926ddd7bf..4395ed94e1acc2b5c622f19c8a3ed3ee5c1530cd 100644 (file)
@@ -43,9 +43,9 @@ import Code from '@shortcodes/Code.astro'
     <p class="lg:pe-5">
       When you only need to include Bootstrap’s compiled CSS or JS, you can use <a
         href="https://www.jsdelivr.com/package/npm/bootstrap">jsDelivr</a
-      >. See it in action with our simple <a href={getVersionedDocsPath('guides/quickstart/')}
-        >quick start</a
-      >, or <a href={getVersionedDocsPath('examples')}>browse the examples</a> to jumpstart your next project.
+      >. See it in action with our simple <a href={getVersionedDocsPath('guides/quickstart/')}>quick start</a>, or <a
+        href={getVersionedDocsPath('examples')}>browse the examples</a
+      > to jumpstart your next project.
     </p>
     <Code
       code={`<link href="${getConfig().cdn.css}" rel="stylesheet" integrity="${
index f4547bc4caf711a06bf2146b7869be9e9d330266..afeff6162ef18f7b3e9031b07a2e608b9308d8d2 100644 (file)
@@ -15,7 +15,9 @@ import ResponsiveImage from '@layouts/partials/ResponsiveImage.astro'
         rel="noopener"
         target="_blank"
       >
-        <span class="sm:d-inline-flex align-items-center gap-1 py-2 px-3 me-2 mb-2 lg:mb-0 rounded-5 masthead-notice theme-subtle theme-warning ">
+        <span
+          class="sm:d-inline-flex align-items-center gap-1 py-2 px-3 me-2 mb-2 lg:mb-0 rounded-5 masthead-notice theme-subtle theme-warning"
+        >
           Get Security Updates for Bootstrap 3 &amp; 4
           <svg class="bi" style="width: 20px; height: 20px; margin-block: -2px;" aria-hidden="true"
             ><use href="#arrow-right-short"></use></svg
index 4df46d4c023ad21016e72b329ed33f87c41b0643..51c414bb421f22dec5f869cb329130f07dc18862 100644 (file)
@@ -15,5 +15,7 @@ const { class: className, height, width } = Astro.props
   width={width}
 >
   <title>CSS-Tricks</title>
-  <path d="M156.58,239l-88.3,64.75c-10.59,7.06-18.84,11.77-29.43,11.77-21.19,0-38.85-18.84-38.85-40C0,257.83,14.13,244.88,27.08,239l103.6-44.74L27.08,148.34C13,142.46,0,129.51,0,111.85,0,90.66,18.84,73,40,73c10.6,0,17.66,3.53,28.25,11.77l88.3,64.75L144.81,44.74C141.28,20,157.76,0,181.31,0s40,18.84,36.5,43.56L206,149.52l88.3-64.75C304.93,76.53,313.17,73,323.77,73a39.2,39.2,0,0,1,38.85,38.85c0,18.84-12.95,30.61-27.08,36.5L231.93,194.26,335.54,239c14.13,5.88,27.08,18.83,27.08,37.67,0,21.19-18.84,38.85-40,38.85-9.42,0-17.66-4.71-28.26-11.77L206,239l11.77,104.78c3.53,24.72-12.95,44.74-36.5,44.74s-40-18.84-36.5-43.56Z"></path>
+  <path
+    d="M156.58,239l-88.3,64.75c-10.59,7.06-18.84,11.77-29.43,11.77-21.19,0-38.85-18.84-38.85-40C0,257.83,14.13,244.88,27.08,239l103.6-44.74L27.08,148.34C13,142.46,0,129.51,0,111.85,0,90.66,18.84,73,40,73c10.6,0,17.66,3.53,28.25,11.77l88.3,64.75L144.81,44.74C141.28,20,157.76,0,181.31,0s40,18.84,36.5,43.56L206,149.52l88.3-64.75C304.93,76.53,313.17,73,323.77,73a39.2,39.2,0,0,1,38.85,38.85c0,18.84-12.95,30.61-27.08,36.5L231.93,194.26,335.54,239c14.13,5.88,27.08,18.83,27.08,37.67,0,21.19-18.84,38.85-40,38.85-9.42,0-17.66-4.71-28.26-11.77L206,239l11.77,104.78c3.53,24.72-12.95,44.74-36.5,44.74s-40-18.84-36.5-43.56Z"
+  ></path>
 </svg>
index 2e17d759c747adc8d90bda7e9d0cad47430959a5..a5becda5109d82837d8f8d7ddcd9aee96e2f9b09 100644 (file)
@@ -18,5 +18,5 @@ const { class: className, height, width } = Astro.props
   stroke-width="1"
   stroke-linecap="round"
 >
-  <path d="M1 3.5h14M1 8h14M1 12.5h14" />
+  <path d="M1 3.5h14M1 8h14M1 12.5h14"></path>
 </svg>
index 941363dca7e1f0c93a465ff0654412b4dd58320a..0ac515b0f9dc043432ab70a2c0e1f2a1e8e4af98 100644 (file)
@@ -4,14 +4,9 @@ type Props = SvgIconProps
 const { class: className, height, width } = Astro.props
 ---
 
-<svg
-  xmlns="http://www.w3.org/2000/svg"
-  viewBox="0 0 16 16"
-  role="img"
-  class={className}
-  height={height}
-  width={width}
->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" role="img" class={className} height={height} width={width}>
   <title>MDN</title>
-  <path d="M6.359.734 1.846 15.266H0L4.497.734h1.862ZM8 .734v14.532H6.359V.734H8ZM16 .734v14.532h-1.641V.734H16ZM14.359.734 9.862 15.266H8.016L12.513.734h1.846Z"></path>
+  <path
+    d="M6.359.734 1.846 15.266H0L4.497.734h1.862ZM8 .734v14.532H6.359V.734H8ZM16 .734v14.532h-1.641V.734H16ZM14.359.734 9.862 15.266H8.016L12.513.734h1.846Z"
+  ></path>
 </svg>
index 9cabe2e5f5977a32d88b7e1c2ea1bc3c4df0acbb..740fe77e013cc861a13b75f6effd39442c83c503 100644 (file)
@@ -1,4 +1,5 @@
 ---
+
 ---
 
 <svg xmlns="http://www.w3.org/2000/svg" class="d-none">
     ></path>
   </symbol>
   <symbol id="aspect-ratio" viewBox="0 0 16 16">
-    <path d="M0 3.5A1.5 1.5 0 0 1 1.5 2h13A1.5 1.5 0 0 1 16 3.5v9a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 0 12.5zM1.5 3a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5h13a.5.5 0 0 0 .5-.5v-9a.5.5 0 0 0-.5-.5z"></path>
-    <path d="M2 4.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1H3v2.5a.5.5 0 0 1-1 0zm12 7a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1 0-1H13V8.5a.5.5 0 0 1 1 0z"></path>
+    <path
+      d="M0 3.5A1.5 1.5 0 0 1 1.5 2h13A1.5 1.5 0 0 1 16 3.5v9a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 0 12.5zM1.5 3a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5h13a.5.5 0 0 0 .5-.5v-9a.5.5 0 0 0-.5-.5z"
+    ></path>
+    <path
+      d="M2 4.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1H3v2.5a.5.5 0 0 1-1 0zm12 7a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1 0-1H13V8.5a.5.5 0 0 1 1 0z"
+    ></path>
   </symbol>
   <symbol id="aspect-ratio-fill" viewBox="0 0 16 16">
-    <path fill="currentcolor" fill-rule="evenodd" d="M13.5 1A2.5 2.5 0 0 1 16 3.5v9a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5v-9A2.5 2.5 0 0 1 2.5 1zm0 8a.5.5 0 0 0-.5.5V12h-2.5a.5.5 0 0 0 0 1h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5m-11-6a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 1 0V4h2.5a.5.5 0 0 0 0-1z" clip-rule="evenodd"/>
+    <path
+      fill="currentcolor"
+      fill-rule="evenodd"
+      d="M13.5 1A2.5 2.5 0 0 1 16 3.5v9a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5v-9A2.5 2.5 0 0 1 2.5 1zm0 8a.5.5 0 0 0-.5.5V12h-2.5a.5.5 0 0 0 0 1h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5m-11-6a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 1 0V4h2.5a.5.5 0 0 0 0-1z"
+      clip-rule="evenodd"></path>
   </symbol>
   <symbol id="book-half" viewBox="0 0 16 16">
     <path
     ></path>
   </symbol>
   <symbol id="bounding-box" viewBox="0 0 16 16">
-    <path d="M5 2V0H0v5h2v6H0v5h5v-2h6v2h5v-5h-2V5h2V0h-5v2zm6 1v2h2v6h-2v2H5v-2H3V5h2V3zm1-2h3v3h-3zm3 11v3h-3v-3zM4 15H1v-3h3zM1 4V1h3v3z"></path>
+    <path
+      d="M5 2V0H0v5h2v6H0v5h5v-2h6v2h5v-5h-2V5h2V0h-5v2zm6 1v2h2v6h-2v2H5v-2H3V5h2V3zm1-2h3v3h-3zm3 11v3h-3v-3zM4 15H1v-3h3zM1 4V1h3v3z"
+    ></path>
   </symbol>
   <symbol id="box-arrow-up-right" viewBox="0 0 16 16">
-    <path fill-rule="evenodd" d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"/>
-    <path fill-rule="evenodd" d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"/>
+    <path
+      fill-rule="evenodd"
+      d="M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5"
+    ></path>
+    <path
+      fill-rule="evenodd"
+      d="M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0z"
+    ></path>
   </symbol>
   <symbol id="box-seam" viewBox="0 0 16 16">
     <path
     ></path>
   </symbol>
   <symbol id="box-seam-fill" viewBox="0 0 16 16">
-    <path fill-rule="evenodd" d="M15.528 2.973a.75.75 0 0 1 .472.696v8.662a.75.75 0 0 1-.472.696l-7.25 2.9a.75.75 0 0 1-.557 0l-7.25-2.9A.75.75 0 0 1 0 12.331V3.669a.75.75 0 0 1 .471-.696L7.443.184l.01-.003.268-.108a.75.75 0 0 1 .558 0l.269.108.01.003zM10.404 2 4.25 4.461 1.846 3.5 1 3.839v.4l6.5 2.6v7.922l.5.2.5-.2V6.84l6.5-2.6v-.4l-.846-.339L8 5.961 5.596 5l6.154-2.461z"/>
+    <path
+      fill-rule="evenodd"
+      d="M15.528 2.973a.75.75 0 0 1 .472.696v8.662a.75.75 0 0 1-.472.696l-7.25 2.9a.75.75 0 0 1-.557 0l-7.25-2.9A.75.75 0 0 1 0 12.331V3.669a.75.75 0 0 1 .471-.696L7.443.184l.01-.003.268-.108a.75.75 0 0 1 .558 0l.269.108.01.003zM10.404 2 4.25 4.461 1.846 3.5 1 3.839v.4l6.5 2.6v7.922l.5.2.5-.2V6.84l6.5-2.6v-.4l-.846-.339L8 5.961 5.596 5l6.154-2.461z"
+    ></path>
   </symbol>
   <symbol id="braces" viewBox="0 0 16 16">
     <path
     ></path>
   </symbol>
   <symbol id="calendar-week" viewBox="0 0 16 16">
-    <path d="M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm-3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm-5 3a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z"/>
-    <path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"/>
+    <path
+      d="M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm-3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm-5 3a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5zm3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5z"
+    ></path>
+    <path
+      d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5M1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4z"
+    ></path>
   </symbol>
   <symbol id="check2" viewBox="0 0 16 16">
     <path
     ></path>
   </symbol>
   <symbol id="copy" viewBox="0 0 16 16">
-    <path fill-rule="evenodd" d="M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z"/>
+    <path
+      fill-rule="evenodd"
+      d="M4 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 5a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1h1v1a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h1v1z"
+    ></path>
   </symbol>
   <symbol id="css" viewBox="0 0 16 16">
-    <path fill="currentcolor" fill-rule="evenodd" d="M13 0a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H3a3 3 0 0 1-3-3V0zM4.002 6.498q-.908 0-1.455.508Q2 7.513 2 8.49v3.106q0 .986.527 1.484t1.407.498a2.2 2.2 0 0 0 1.015-.224q.45-.225.703-.674.255-.449.254-1.114v-.185h-1.22v.176q0 .45-.186.683t-.527.235q-.371-.01-.557-.264-.186-.255-.186-.752V8.686q0-.547.166-.811.177-.264.577-.264.322 0 .517.225.196.224.196.693v.205h1.23V8.52q0-.674-.244-1.124a1.55 1.55 0 0 0-.664-.673q-.42-.225-1.006-.225m4.214-.01q-.585 0-1.006.244a1.67 1.67 0 0 0-.635.674 2.1 2.1 0 0 0-.224.996q0 .753.293 1.182.302.42.966.732l.47.215q.438.186.624.43t.186.635q0 .478-.166.703-.157.224-.528.224-.36 0-.547-.244-.185-.243-.205-.752H6.282q.02.996.498 1.524.48.527 1.387.527.908 0 1.416-.518.508-.517.508-1.484 0-.81-.332-1.289-.333-.479-1.045-.79l-.45-.196q-.39-.166-.556-.381-.165-.214-.166-.576 0-.4.166-.596.176-.195.508-.195.36 0 .508.234.156.234.175.703h1.124q-.03-.976-.499-1.484-.468-.518-1.308-.518m4.057 0q-.586 0-1.005.244a1.67 1.67 0 0 0-.635.674 2.1 2.1 0 0 0-.225.996q0 .753.293 1.182.303.42.967.732l.469.215q.44.186.625.43t.185.635q0 .478-.166.703-.156.224-.527.224-.36 0-.547-.244-.186-.243-.205-.752H10.34q.02.996.498 1.524.478.527 1.387.527.908 0 1.416-.518.507-.517.507-1.484 0-.81-.332-1.289t-1.045-.79l-.449-.196q-.39-.166-.556-.381-.166-.214-.166-.576 0-.4.166-.596.176-.195.507-.195.361 0 .508.234.156.234.176.703h1.123q-.03-.976-.498-1.484-.469-.518-1.309-.518" clip-rule="evenodd"/>
+    <path
+      fill="currentcolor"
+      fill-rule="evenodd"
+      d="M13 0a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H3a3 3 0 0 1-3-3V0zM4.002 6.498q-.908 0-1.455.508Q2 7.513 2 8.49v3.106q0 .986.527 1.484t1.407.498a2.2 2.2 0 0 0 1.015-.224q.45-.225.703-.674.255-.449.254-1.114v-.185h-1.22v.176q0 .45-.186.683t-.527.235q-.371-.01-.557-.264-.186-.255-.186-.752V8.686q0-.547.166-.811.177-.264.577-.264.322 0 .517.225.196.224.196.693v.205h1.23V8.52q0-.674-.244-1.124a1.55 1.55 0 0 0-.664-.673q-.42-.225-1.006-.225m4.214-.01q-.585 0-1.006.244a1.67 1.67 0 0 0-.635.674 2.1 2.1 0 0 0-.224.996q0 .753.293 1.182.302.42.966.732l.47.215q.438.186.624.43t.186.635q0 .478-.166.703-.157.224-.528.224-.36 0-.547-.244-.185-.243-.205-.752H6.282q.02.996.498 1.524.48.527 1.387.527.908 0 1.416-.518.508-.517.508-1.484 0-.81-.332-1.289-.333-.479-1.045-.79l-.45-.196q-.39-.166-.556-.381-.165-.214-.166-.576 0-.4.166-.596.176-.195.508-.195.36 0 .508.234.156.234.175.703h1.124q-.03-.976-.499-1.484-.468-.518-1.308-.518m4.057 0q-.586 0-1.005.244a1.67 1.67 0 0 0-.635.674 2.1 2.1 0 0 0-.225.996q0 .753.293 1.182.303.42.967.732l.469.215q.44.186.625.43t.185.635q0 .478-.166.703-.156.224-.527.224-.36 0-.547-.244-.186-.243-.205-.752H10.34q.02.996.498 1.524.478.527 1.387.527.908 0 1.416-.518.507-.517.507-1.484 0-.81-.332-1.289t-1.045-.79l-.449-.196q-.39-.166-.556-.381-.166-.214-.166-.576 0-.4.166-.596.176-.195.507-.195.361 0 .508.234.156.234.176.703h1.123q-.03-.976-.498-1.484-.469-.518-1.309-.518"
+      clip-rule="evenodd"></path>
   </symbol>
   <symbol id="envelope" viewBox="0 0 16 16">
-    <path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1zm13 2.383-4.708 2.825L15 11.105zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741M1 11.105l4.708-2.897L1 5.383z"/>
+    <path
+      d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1zm13 2.383-4.708 2.825L15 11.105zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741M1 11.105l4.708-2.897L1 5.383z"
+    ></path>
   </symbol>
   <symbol id="exclamation-triangle-fill" viewBox="0 0 16 16">
-    <path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5m.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2"/>
+    <path
+      d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5m.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2"
+    ></path>
   </symbol>
   <symbol id="file-earmark-richtext" viewBox="0 0 16 16">
     <path
     ></path>
   </symbol>
   <symbol id="github" viewBox="0 0 16 16">
-    <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/>
+    <path
+      d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"
+    ></path>
   </symbol>
   <symbol id="globe2" viewBox="0 0 16 16">
     <path
     ></path>
   </symbol>
   <symbol id="filetype-js" viewBox="0 0 16 16">
-    <path fill-rule="evenodd" d="M13 0a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H3a3 3 0 0 1-3-3V3a3 3 0 0 1 3-3zM8.053 6.596v3.127l-.007 1.752q0 .498-.186.752t-.556.263q-.342 0-.528-.234-.185-.234-.185-.684v-.175H5.37v.185q0 .665.253 1.113.255.45.703.674.44.225 1.016.225.88 0 1.406-.498.527-.498.527-1.485l.007-1.752V6.596zm3.808-.108q-.585 0-1.006.244a1.67 1.67 0 0 0-.634.674 2.1 2.1 0 0 0-.225.996q0 .753.293 1.182.303.42.967.732l.469.215q.438.186.625.43.185.244.185.635 0 .478-.166.703-.156.224-.527.224-.361.001-.547-.244-.186-.243-.205-.752H9.928q.02.996.498 1.524.479.527 1.386.527.909 0 1.417-.518.507-.517.507-1.484 0-.81-.332-1.289t-1.045-.79L11.91 9.3q-.39-.166-.556-.381-.166-.214-.166-.576 0-.4.165-.596.177-.195.508-.195.361 0 .508.234.156.234.176.703h1.123q-.03-.976-.498-1.484-.47-.518-1.309-.518" clip-rule="evenodd"></path>
+    <path
+      fill-rule="evenodd"
+      d="M13 0a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H3a3 3 0 0 1-3-3V3a3 3 0 0 1 3-3zM8.053 6.596v3.127l-.007 1.752q0 .498-.186.752t-.556.263q-.342 0-.528-.234-.185-.234-.185-.684v-.175H5.37v.185q0 .665.253 1.113.255.45.703.674.44.225 1.016.225.88 0 1.406-.498.527-.498.527-1.485l.007-1.752V6.596zm3.808-.108q-.585 0-1.006.244a1.67 1.67 0 0 0-.634.674 2.1 2.1 0 0 0-.225.996q0 .753.293 1.182.303.42.967.732l.469.215q.438.186.625.43.185.244.185.635 0 .478-.166.703-.156.224-.527.224-.361.001-.547-.244-.186-.243-.205-.752H9.928q.02.996.498 1.524.479.527 1.386.527.909 0 1.417-.518.507-.517.507-1.484 0-.81-.332-1.289t-1.045-.79L11.91 9.3q-.39-.166-.556-.381-.166-.214-.166-.576 0-.4.165-.596.177-.195.508-.195.361 0 .508.234.156.234.176.703h1.123q-.03-.976-.498-1.484-.47-.518-1.309-.518"
+      clip-rule="evenodd"></path>
   </symbol>
   <symbol id="grid-fill" viewBox="0 0 16 16">
     <path
     ></path>
   </symbol>
   <symbol id="layers" viewBox="0 0 16 16">
-    <path d="M15.106 11.554a.5.5 0 0 1 0 .894l-6.659 3.33-.107.045a1 1 0 0 1-.68 0l-.107-.046-6.658-3.329a.5.5 0 0 1 0-.895l1.988-.994 1.677.838-1.206.604L8 14.323l4.646-2.322-1.207-.604 1.678-.838z" opacity=".5"></path>
-    <path fill-rule="evenodd" d="M7.553.223a1 1 0 0 1 .894 0l6.659 3.33a.5.5 0 0 1 0 .894l-6.659 3.33-.107.045a1 1 0 0 1-.68 0l-.107-.046L.895 4.447a.5.5 0 0 1 0-.894zM3.354 4 8 6.322 12.646 4 8 1.677z" clip-rule="evenodd" opacity=".5"></path>
-    <path d="M15.106 7.554a.5.5 0 0 1 0 .894l-6.659 3.33c-.281.14-.613.14-.894 0L.895 8.447a.5.5 0 0 1 0-.894l1.988-.995 4.222 2.112a2 2 0 0 0 1.79 0l4.222-2.112z"></path>
+    <path
+      d="M15.106 11.554a.5.5 0 0 1 0 .894l-6.659 3.33-.107.045a1 1 0 0 1-.68 0l-.107-.046-6.658-3.329a.5.5 0 0 1 0-.895l1.988-.994 1.677.838-1.206.604L8 14.323l4.646-2.322-1.207-.604 1.678-.838z"
+      opacity=".5"></path>
+    <path
+      fill-rule="evenodd"
+      d="M7.553.223a1 1 0 0 1 .894 0l6.659 3.33a.5.5 0 0 1 0 .894l-6.659 3.33-.107.045a1 1 0 0 1-.68 0l-.107-.046L.895 4.447a.5.5 0 0 1 0-.894zM3.354 4 8 6.322 12.646 4 8 1.677z"
+      clip-rule="evenodd"
+      opacity=".5"></path>
+    <path
+      d="M15.106 7.554a.5.5 0 0 1 0 .894l-6.659 3.33c-.281.14-.613.14-.894 0L.895 8.447a.5.5 0 0 1 0-.894l1.988-.995 4.222 2.112a2 2 0 0 0 1.79 0l4.222-2.112z"
+    ></path>
   </symbol>
   <symbol id="list" viewBox="0 0 16 16">
     <path
     ></path>
   </symbol>
   <symbol id="map" viewBox="0 0 16 16">
-    <path fill-rule="evenodd" d="M15.817.113A.5.5 0 0 1 16 .5v14a.5.5 0 0 1-.402.49l-5 1a.5.5 0 0 1-.196 0L5.5 15.01l-4.902.98A.5.5 0 0 1 0 15.5v-14a.5.5 0 0 1 .402-.49l5-1a.5.5 0 0 1 .196 0L10.5.99l4.902-.98a.5.5 0 0 1 .415.103M10 1.91l-4-.8v12.98l4 .8zm1 12.98 4-.8V1.11l-4 .8zm-6-.8V1.11l-4 .8v12.98z"/>
+    <path
+      fill-rule="evenodd"
+      d="M15.817.113A.5.5 0 0 1 16 .5v14a.5.5 0 0 1-.402.49l-5 1a.5.5 0 0 1-.196 0L5.5 15.01l-4.902.98A.5.5 0 0 1 0 15.5v-14a.5.5 0 0 1 .402-.49l5-1a.5.5 0 0 1 .196 0L10.5.99l4.902-.98a.5.5 0 0 1 .415.103M10 1.91l-4-.8v12.98l4 .8zm1 12.98 4-.8V1.11l-4 .8zm-6-.8V1.11l-4 .8v12.98z"
+    ></path>
   </symbol>
   <symbol id="menu-button-wide-fill" viewBox="0 0 16 16">
     <path
     ></path>
   </symbol>
   <symbol id="search" viewBox="0 0 16 16">
-    <path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0"/>
+    <path
+      d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0"
+    ></path>
   </symbol>
   <symbol id="stack" viewBox="0 0 16 16">
-    <path d="m14.12 10.163 1.715.858c.22.11.22.424 0 .534L8.267 15.34a.6.6 0 0 1-.534 0L.165 11.555a.299.299 0 0 1 0-.534l1.716-.858 5.317 2.659c.505.252 1.1.252 1.604 0l5.317-2.66zM7.733.063a.6.6 0 0 1 .534 0l7.568 3.784a.3.3 0 0 1 0 .535L8.267 8.165a.6.6 0 0 1-.534 0L.165 4.382a.299.299 0 0 1 0-.535z"/>
-    <path d="m14.12 6.576 1.715.858c.22.11.22.424 0 .534l-7.568 3.784a.6.6 0 0 1-.534 0L.165 7.968a.299.299 0 0 1 0-.534l1.716-.858 5.317 2.659c.505.252 1.1.252 1.604 0z"/>
+    <path
+      d="m14.12 10.163 1.715.858c.22.11.22.424 0 .534L8.267 15.34a.6.6 0 0 1-.534 0L.165 11.555a.299.299 0 0 1 0-.534l1.716-.858 5.317 2.659c.505.252 1.1.252 1.604 0l5.317-2.66zM7.733.063a.6.6 0 0 1 .534 0l7.568 3.784a.3.3 0 0 1 0 .535L8.267 8.165a.6.6 0 0 1-.534 0L.165 4.382a.299.299 0 0 1 0-.535z"
+    ></path>
+    <path
+      d="m14.12 6.576 1.715.858c.22.11.22.424 0 .534l-7.568 3.784a.6.6 0 0 1-.534 0L.165 7.968a.299.299 0 0 1 0-.534l1.716-.858 5.317 2.659c.505.252 1.1.252 1.604 0z"
+    ></path>
   </symbol>
   <symbol id="sun-fill" viewBox="0 0 16 16">
     <path
index 0aed05701533b15424fb69d9d9cc37db6dfe73ff..212db94df92559a5bf80e7f0021d65df2e2e2896 100644 (file)
@@ -15,13 +15,21 @@ const rounded = ['default', 'pill', 'square']
 
 <svg xmlns="http://www.w3.org/2000/svg" class="d-none">
   <symbol id="arrow-left" viewBox="0 0 16 16">
-    <path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8"/>
+    <path
+      fill-rule="evenodd"
+      d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8"
+    ></path>
   </symbol>
   <symbol id="arrow-right" viewBox="0 0 16 16">
-    <path fill-rule="evenodd" d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8"/>
+    <path
+      fill-rule="evenodd"
+      d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8"
+    ></path>
   </symbol>
   <symbol id="plus-lg" viewBox="0 0 16 16">
-    <path fill-rule="evenodd" d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2Z"/>
+    <path
+      fill-rule="evenodd"
+      d="M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2Z"></path>
   </symbol>
 </svg>
 
@@ -40,20 +48,22 @@ const rounded = ['default', 'pill', 'square']
         >
           <span>Primary</span>
           <svg class="bi ms-1" width="16" height="16" aria-hidden="true">
-            <use href="#chevron-expand" />
+            <use href="#chevron-expand"></use>
           </svg>
         </button>
         <div class="menu">
-          {themeColors.map((themeColor) => (
-            <a
-              class:list={['menu-item', { 'active': themeColor.name === 'primary' }]}
-              href="#"
-              data-color={themeColor.name}
-              data-selected={themeColor.name === 'primary'}
-            >
-              {themeColor.title}
-            </a>
-          ))}
+          {
+            themeColors.map((themeColor) => (
+              <a
+                class:list={['menu-item', { active: themeColor.name === 'primary' }]}
+                href="#"
+                data-color={themeColor.name}
+                data-selected={themeColor.name === 'primary'}
+              >
+                {themeColor.title}
+              </a>
+            ))
+          }
         </div>
       </div>
     </div>
@@ -61,18 +71,14 @@ const rounded = ['default', 'pill', 'square']
     <div class="vstack gap-1 flex-grow-0">
       <label class="form-label fw-semibold mb-0">Style</label>
       <div class="btn-group text-capitalize btn-group-sm" role="group" aria-label="Button style">
-        {styles.map((style) => (
-          <label class="btn-check btn-outline theme-secondary">
-            <input
-              type="radio"
-              name="btn-style"
-              value={style}
-              checked={style === 'styled'}
-              data-style={style}
-            />
-            {style || 'default'}
-          </label>
-        ))}
+        {
+          styles.map((style) => (
+            <label class="btn-check btn-outline theme-secondary">
+              <input type="radio" name="btn-style" value={style} checked={style === 'styled'} data-style={style} />
+              {style || 'default'}
+            </label>
+          ))
+        }
       </div>
     </div>
 
@@ -89,20 +95,22 @@ const rounded = ['default', 'pill', 'square']
         >
           <span>Medium</span>
           <svg class="bi ms-1" width="16" height="16" aria-hidden="true">
-            <use href="#chevron-expand" />
+            <use href="#chevron-expand"></use>
           </svg>
         </button>
         <div class="menu">
-          {sizes.map((size) => (
-            <a
-              class:list={['menu-item', { 'active': size.value === '' }]}
-              href="#"
-              data-size={size.value}
-              data-selected={size.value === ''}
-            >
-              {size.label}
-            </a>
-          ))}
+          {
+            sizes.map((size) => (
+              <a
+                class:list={['menu-item', { active: size.value === '' }]}
+                href="#"
+                data-size={size.value}
+                data-selected={size.value === ''}
+              >
+                {size.label}
+              </a>
+            ))
+          }
         </div>
       </div>
     </div>
@@ -110,18 +118,14 @@ const rounded = ['default', 'pill', 'square']
     <div class="vstack gap-1 flex-grow-0">
       <label class="form-label fw-semibold mb-0">Rounded</label>
       <div class="btn-group text-capitalize btn-group-sm" role="group" aria-label="Button rounded">
-        {rounded.map((round) => (
-          <label class="btn-check btn-outline theme-secondary">
-            <input
-              type="radio"
-              name="btn-rounded"
-              value={round}
-              checked={round === 'default'}
-              data-rounded={round}
-            />
-            {round}
-          </label>
-        ))}
+        {
+          rounded.map((round) => (
+            <label class="btn-check btn-outline theme-secondary">
+              <input type="radio" name="btn-rounded" value={round} checked={round === 'default'} data-rounded={round} />
+              {round}
+            </label>
+          ))
+        }
       </div>
     </div>
   </div>
@@ -151,7 +155,7 @@ const rounded = ['default', 'pill', 'square']
 />
 
 <script>
-  import { Menu } from '../../../../dist/js/bootstrap.bundle.js'
+  import { Menu } from '@bootstrap'
 
   const colorMenuButton = document.querySelector('#btn-color-menu') as HTMLButtonElement
   const colorMenuItems = document.querySelectorAll('#btn-color-menu + .menu .menu-item')
@@ -161,15 +165,18 @@ const rounded = ['default', 'pill', 'square']
   const roundedInputs = document.querySelectorAll('input[name="btn-rounded"]')
   const previewButtons = document.querySelectorAll('#button-preview button')
   // Find the code snippet inside the Example component
-  const codeSnippet = document.querySelector('#button-preview')?.closest('.bd-example-snippet')?.querySelector('.highlight code') as HTMLElement
+  const codeSnippet = document
+    .querySelector('#button-preview')
+    ?.closest('.bd-example-snippet')
+    ?.querySelector('.highlight code') as HTMLElement
 
   // Get all theme color names for removal
-  const themeColorNames = Array.from(colorMenuItems).map(item => (item as HTMLElement).dataset.color || '')
+  const themeColorNames = Array.from(colorMenuItems).map((item) => (item as HTMLElement).dataset.color || '')
 
   function generateHTML(button: HTMLElement): string {
-    const classes = Array.from(button.classList).filter(cls =>
-      cls === 'btn' || cls.startsWith('btn-') || cls.startsWith('theme-') || cls.startsWith('rounded')
-    ).join(' ')
+    const classes = Array.from(button.classList)
+      .filter((cls) => cls === 'btn' || cls.startsWith('btn-') || cls.startsWith('theme-') || cls.startsWith('rounded'))
+      .join(' ')
     const buttonType = button.getAttribute('data-button-type')
     const ariaLabel = button.getAttribute('aria-label')
 
@@ -182,9 +189,11 @@ const rounded = ['default', 'pill', 'square']
     if (buttonType === 'text') {
       html += 'Click me'
     } else if (buttonType === 'left-icon') {
-      html += '\n  <svg class="bi me-1" width="16" height="16" aria-hidden="true">\n    <use href="#arrow-left" />\n  </svg>\n  With left icon'
+      html +=
+        '\n  <svg class="bi me-1" width="16" height="16" aria-hidden="true">\n    <use href="#arrow-left" />\n  </svg>\n  With left icon'
     } else if (buttonType === 'right-icon') {
-      html += 'With right icon\n  <svg class="bi ms-1" width="16" height="16" aria-hidden="true">\n    <use href="#arrow-right" />\n  </svg>'
+      html +=
+        'With right icon\n  <svg class="bi ms-1" width="16" height="16" aria-hidden="true">\n    <use href="#arrow-right" />\n  </svg>'
     } else if (buttonType === 'icon-only') {
       html += '\n  <svg class="bi" width="16" height="16" aria-hidden="true">\n    <use href="#plus-lg" />\n  </svg>'
     }
@@ -196,7 +205,7 @@ const rounded = ['default', 'pill', 'square']
   function updateCodeSnippet() {
     if (!codeSnippet) return
 
-    const htmlSnippets = Array.from(previewButtons).map(button => generateHTML(button as HTMLElement))
+    const htmlSnippets = Array.from(previewButtons).map((button) => generateHTML(button as HTMLElement))
     const htmlCode = htmlSnippets.join('\n\n')
 
     // Update the code content
@@ -206,13 +215,15 @@ const rounded = ['default', 'pill', 'square']
 
   function updateButtons() {
     const selectedColor = colorMenuButton?.dataset.color || 'primary'
-    const selectedStyle = (document.querySelector('input[name="btn-style"]:checked') as HTMLInputElement)?.value || 'solid'
+    const selectedStyle =
+      (document.querySelector('input[name="btn-style"]:checked') as HTMLInputElement)?.value || 'solid'
     const selectedSize = sizeMenuButton?.dataset.size || ''
-    const selectedRounded = (document.querySelector('input[name="btn-rounded"]:checked') as HTMLInputElement)?.value || 'default'
+    const selectedRounded =
+      (document.querySelector('input[name="btn-rounded"]:checked') as HTMLInputElement)?.value || 'default'
 
     previewButtons.forEach((button) => {
       // Remove all theme color classes
-      themeColorNames.forEach(color => button.classList.remove(`theme-${color}`))
+      themeColorNames.forEach((color) => button.classList.remove(`theme-${color}`))
       // Add selected theme color
       button.classList.add(`theme-${selectedColor}`)
 
@@ -236,7 +247,7 @@ const rounded = ['default', 'pill', 'square']
 
       // Handle rounded - remove all rounded classes first
       const roundedClasses = ['rounded-pill', 'rounded-0', 'rounded']
-      roundedClasses.forEach(cls => button.classList.remove(cls))
+      roundedClasses.forEach((cls) => button.classList.remove(cls))
 
       if (selectedRounded === 'pill') {
         button.classList.add('rounded-pill')
index 43d1ecf0c7a9e1b3904e4c9483a38733db0743fa..648a2114c00463590d309fec73757637fe5dfc9e 100644 (file)
@@ -8,6 +8,6 @@ const { component, className } = Astro.props
 ---
 
 <p>
-  {component} use local CSS variables on <code>.{className}</code> for real-time customization.
-  Values for the CSS variables are generated from Sass maps unique to each component and applied to the aforementioned class.
+  {component} use local CSS variables on <code>.{className}</code> for real-time customization. Values for the CSS variables
+  are generated from Sass maps unique to each component and applied to the aforementioned class.
 </p>
index 8215361ddf8db604e90ce9a75d057afea6ed9245..45ce0c1d3195cda0dafd40053e1622a425afe223 100644 (file)
@@ -28,13 +28,13 @@ const { name, type = 'info' } = Astro.props
 let Content: MarkdownInstance<{}>['Content'] | undefined
 
 if (name) {
-  const callout = await getCalloutByName(name) as any
+  const callout = (await getCalloutByName(name)) as any
 
   if (!callout) {
     throw new Error(`Could not find callout with name '${name}'.`)
   }
 
-  const namedCallout = await render(callout) as any
+  const namedCallout = (await render(callout)) as any
   Content = namedCallout.Content
 }
 ---
index 0bfd095705feb3f1be3ed68aaaf890b2d318fa46..d7c33d59b3f2b70669183a866155ac83182ddb8b 100644 (file)
@@ -19,8 +19,16 @@ interface Props {
 const { class: className, dismiss, target } = Astro.props
 ---
 
-<button type="button" class:list={["btn-close", className]} data-bs-dismiss={dismiss} aria-label="Close" data-bs-target={target}>
+<button
+  type="button"
+  class:list={['btn-close', className]}
+  data-bs-dismiss={dismiss}
+  aria-label="Close"
+  data-bs-target={target}
+>
   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="20" height="20" fill="none">
-    <path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm3.354 4.646L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 1 1 .708-.708"/>
+    <path
+      d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm3.354 4.646L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 1 1 .708-.708"
+    ></path>
   </svg>
 </button>
index 292877ee031bd5f2adf42518ad5341cb099630a8..607c56f495c8250b5faca09dfbc1a75f35c78f25 100644 (file)
@@ -87,9 +87,7 @@ const {
   tabs
 } = Astro.props
 
-const fileUrl = file
-  ? `${getConfig().repo}/blob/v${getConfig().current_version}/${file}`.replaceAll('\\', '/')
-  : null
+const fileUrl = file ? `${getConfig().repo}/blob/v${getConfig().current_version}/${file}`.replaceAll('\\', '/') : null
 
 // Extract language from multiple possible sources (for markdown code blocks)
 // Priority: lang prop > data-language attribute > className pattern
@@ -103,14 +101,21 @@ if (!detectedLang && className) {
 
 // Format language for display (e.g., "html" -> "HTML", "javascript" -> "JavaScript")
 const displayLang = detectedLang
-  ? detectedLang === 'js' ? 'JavaScript'
-  : detectedLang === 'ts' ? 'TypeScript'
-  : detectedLang === 'html' ? 'HTML'
-  : detectedLang === 'css' ? 'CSS'
-  : detectedLang === 'scss' ? 'SCSS'
-  : detectedLang === 'bash' || detectedLang === 'sh' ? 'Shell'
-  : detectedLang === 'powershell' ? 'PowerShell'
-  : detectedLang.toUpperCase()
+  ? detectedLang === 'js'
+    ? 'JavaScript'
+    : detectedLang === 'ts'
+      ? 'TypeScript'
+      : detectedLang === 'html'
+        ? 'HTML'
+        : detectedLang === 'css'
+          ? 'CSS'
+          : detectedLang === 'scss'
+            ? 'SCSS'
+            : detectedLang === 'bash' || detectedLang === 'sh'
+              ? 'Shell'
+              : detectedLang === 'powershell'
+                ? 'PowerShell'
+                : detectedLang.toUpperCase()
   : ''
 
 let codeToDisplay = filePath
@@ -126,13 +131,10 @@ if (filePath && fileMatch && codeToDisplay) {
     throw new Error(`The file at ${filePath} does not contain a match for the regex '${fileMatch}'.`)
   }
 
-  codeToDisplay = matches.map(m => m[0]).join('\n\n')
+  codeToDisplay = matches.map((m) => m[0]).join('\n\n')
 }
 
-const diffTransformers = [
-  transformerNotationDiff(),
-  transformerNotationHighlight()
-]
+const diffTransformers = [transformerNotationDiff(), transformerNotationHighlight()]
 
 // Process tabs if provided
 let highlightedTabs: Array<{ label: string; code: string }> | null = null
@@ -140,22 +142,17 @@ if (tabs && tabs.length > 0) {
   highlightedTabs = await Promise.all(
     tabs.map(async (tab) => ({
       label: tab.label,
-      code: await highlightCode(
-        replaceConfigInText(tab.code),
-        tab.lang || detectedLang || 'bash',
-        diffTransformers
-      )
+      code: await highlightCode(replaceConfigInText(tab.code), tab.lang || detectedLang || 'bash', diffTransformers)
     }))
   )
 }
 
-const highlightedCode = codeToDisplay && detectedLang
-  ? await highlightCode(codeToDisplay, detectedLang, diffTransformers)
-  : null
+const highlightedCode =
+  codeToDisplay && detectedLang ? await highlightCode(codeToDisplay, detectedLang, diffTransformers) : null
 ---
 
 <script>
-  import { Tooltip } from '../../../../dist/js/bootstrap.bundle.js'
+  import { Tooltip } from '@bootstrap'
   import { initCopyButtons } from '@libs/clipboard'
 
   document.querySelectorAll('.btn-edit').forEach((btn) => {
@@ -165,9 +162,10 @@ const highlightedCode = codeToDisplay && detectedLang
   // Handle tab switching
   document.querySelectorAll('.code-tabs').forEach((tabContainer) => {
     const buttons = tabContainer.querySelectorAll('.code-tab-btn')
-    const parentContainer = tabContainer.closest('.bd-code-snippet') ||
-                           tabContainer.closest('.bd-example-snippet') ||
-                           tabContainer.parentElement?.parentElement
+    const parentContainer =
+      tabContainer.closest('.bd-code-snippet') ||
+      tabContainer.closest('.bd-example-snippet') ||
+      tabContainer.parentElement?.parentElement
     const codeBlocks = parentContainer?.querySelectorAll('.code-tab-content')
 
     buttons.forEach((button, index) => {
@@ -192,98 +190,108 @@ const highlightedCode = codeToDisplay && detectedLang
   })
 </script>
 
-{nestedInExample ? (
-  <>
-    {!noToolbar && (
-      <div class="hstack highlight-toolbar align-items-center">
-        {highlightedTabs ? (
-          <div class="code-tabs">
-            {highlightedTabs.map((tab, index) => (
-              <button
-                type="button"
-                class:list={['code-tab-btn', { active: index === 0 }]}
-              >
-                {tab.label}
+{
+  nestedInExample ? (
+    <>
+      {!noToolbar && (
+        <div class="hstack highlight-toolbar align-items-center">
+          {highlightedTabs ? (
+            <div class="code-tabs">
+              {highlightedTabs.map((tab, index) => (
+                <button type="button" class:list={['code-tab-btn', { active: index === 0 }]}>
+                  {tab.label}
+                </button>
+              ))}
+            </div>
+          ) : file ? (
+            <a
+              class="text-decoration-none font-monospace fs-xs fg-3"
+              href={fileUrl}
+              target="_blank"
+              rel="noopener noreferrer"
+            >
+              {file}
+            </a>
+          ) : (
+            <div class="font-monospace text-uppercase fs-xs fg-3">{displayLang}</div>
+          )}
+          <div class="d-flex ms-auto">
+            {addStackblitzJs && (
+              <button type="button" class="btn-edit text-nowrap" title="Try it on StackBlitz">
+                <svg class="bi" aria-hidden="true">
+                  <use href="#lightning-charge-fill" />
+                </svg>
               </button>
-            ))}
-          </div>
-        ) : file ? (
-          <a class="text-decoration-none font-monospace fs-xs fg-3" href={fileUrl} target="_blank" rel="noopener noreferrer">{file}</a>
-        ) : (
-          <div class="font-monospace text-uppercase fs-xs fg-3">{displayLang}</div>
-        )}
-        <div class="d-flex ms-auto">
-          {addStackblitzJs && (
-            <button type="button" class="btn-edit text-nowrap" title="Try it on StackBlitz">
-              <svg class="bi" aria-hidden="true">
-                <use href="#lightning-charge-fill" />
+            )}
+            <button type="button" class="btn btn-xs btn-icon bg-transparent" title="Copy" data-bd-clipboard>
+              <svg class="bi fs-md" aria-hidden="true">
+                <use href="#copy" />
               </svg>
             </button>
-          )}
-          <button type="button" class="btn btn-xs btn-icon bg-transparent" title="Copy" data-bd-clipboard>
-            <svg class="bi fs-md" aria-hidden="true">
-              <use href="#copy" />
-            </svg>
-          </button>
-        </div>
-      </div>
-    )}
-    {highlightedTabs ? (
-      <>
-        {highlightedTabs.map((tab, index) => (
-          <div class:list={['code-tab-content', { active: index === 0 }]}>
-            <Fragment set:html={tab.code} />
           </div>
-        ))}
-      </>
-    ) : highlightedCode ? (
-      <Fragment set:html={highlightedCode} />
-    ) : (
-      /* prettier-ignore */ <pre class={className}><slot /></pre>
-    )}
-  </>
-) : (
-  <div class:list={["bd-code-snippet", containerClass]}>
-    {!noToolbar && (
-      <div class="hstack highlight-toolbar align-items-center">
-        {highlightedTabs ? (
-          <div class="code-tabs">
-            {highlightedTabs.map((tab, index) => (
-              <button
-                type="button"
-                class:list={['code-tab-btn', { active: index === 0 }]}
-              >
-                {tab.label}
-              </button>
-            ))}
+        </div>
+      )}
+      {highlightedTabs ? (
+        <>
+          {highlightedTabs.map((tab, index) => (
+            <div class:list={['code-tab-content', { active: index === 0 }]}>
+              <Fragment set:html={tab.code} />
+            </div>
+          ))}
+        </>
+      ) : highlightedCode ? (
+        <Fragment set:html={highlightedCode} />
+      ) : (
+        /* prettier-ignore */ <pre class={className}><slot /></pre>
+      )}
+    </>
+  ) : (
+    <div class:list={['bd-code-snippet', containerClass]}>
+      {!noToolbar && (
+        <div class="hstack highlight-toolbar align-items-center">
+          {highlightedTabs ? (
+            <div class="code-tabs">
+              {highlightedTabs.map((tab, index) => (
+                <button type="button" class:list={['code-tab-btn', { active: index === 0 }]}>
+                  {tab.label}
+                </button>
+              ))}
+            </div>
+          ) : file ? (
+            <a
+              class="text-decoration-none font-monospace fs-xs fg-3"
+              href={fileUrl}
+              target="_blank"
+              rel="noopener noreferrer"
+            >
+              {file}
+            </a>
+          ) : (
+            <div class="font-monospace text-uppercase fs-xs fg-3">{displayLang}</div>
+          )}
+          <div class="d-flex ms-auto">
+            <button type="button" class="btn btn-xs btn-icon bg-transparent" title="Copy" data-bd-clipboard>
+              <svg class="bi fs-md" aria-hidden="true">
+                <use href="#copy" />
+              </svg>
+            </button>
           </div>
-        ) : file ? (
-          <a class="text-decoration-none font-monospace fs-xs fg-3" href={fileUrl} target="_blank" rel="noopener noreferrer">{file}</a>
-        ) : (
-          <div class="font-monospace text-uppercase fs-xs fg-3">{displayLang}</div>
-        )}
-        <div class="d-flex ms-auto">
-          <button type="button" class="btn btn-xs btn-icon bg-transparent" title="Copy" data-bd-clipboard>
-            <svg class="bi fs-md" aria-hidden="true">
-              <use href="#copy" />
-            </svg>
-          </button>
         </div>
-      </div>
-    )}
+      )}
 
-    {highlightedTabs ? (
-      <>
-        {highlightedTabs.map((tab, index) => (
-          <div class:list={['code-tab-content', { active: index === 0 }]}>
-            <Fragment set:html={tab.code} />
-          </div>
-        ))}
-      </>
-    ) : highlightedCode ? (
-      <Fragment set:html={highlightedCode} />
-    ) : (
-      /* prettier-ignore */ <pre class={className}><slot /></pre>
-    )}
-  </div>
-)}
+      {highlightedTabs ? (
+        <>
+          {highlightedTabs.map((tab, index) => (
+            <div class:list={['code-tab-content', { active: index === 0 }]}>
+              <Fragment set:html={tab.code} />
+            </div>
+          ))}
+        </>
+      ) : highlightedCode ? (
+        <Fragment set:html={highlightedCode} />
+      ) : (
+        /* prettier-ignore */ <pre class={className}><slot /></pre>
+      )}
+    </div>
+  )
+}
index 888bf5294f0fcd27c5c4519e10826947588096af..210f6d32a020830b155894faacaf5966749e5167 100644 (file)
@@ -30,7 +30,7 @@ const highlightedCode = await highlightCode(code, lang)
   <Fragment set:html={highlightedCode} />
   <button type="button" class="btn btn-xs btn-icon bg-transparent" title="Copy" data-bd-clipboard>
     <svg class="bi fs-md" aria-hidden="true">
-      <use href="#copy" />
+      <use href="#copy"></use>
     </svg>
   </button>
 </div>
@@ -41,10 +41,10 @@ const highlightedCode = await highlightCode(code, lang)
     display: inline-flex;
     align-items: center;
     justify-content: center;
-    gap: .5rem;
+    gap: 0.5rem;
     min-height: 2.5rem;
     margin: 0;
-    padding: .75rem 1rem;
+    padding: 0.75rem 1rem;
     font-size: var(--font-size-md);
     background-color: var(--bg-1);
     border: 1px solid var(--border-color-translucent);
@@ -65,6 +65,6 @@ const highlightedCode = await highlightCode(code, lang)
     height: 1.5rem;
     flex-shrink: 0;
     padding: 0;
-    margin: -.5rem -.25rem -.5rem 1rem;
+    margin: -0.5rem -0.25rem -0.5rem 1rem;
   }
 </style>
index a30c3b7b54828f9955acd7fde5de993d1b720c75..8db884631f06a21fba073ff180e002c1e728332e 100644 (file)
@@ -8,11 +8,7 @@ interface Props {
    * The name of an existing details content to display located in `src/content/details`.
    * This will override any content passed in via the default slot.
    */
-  name?:
-    | 'danger-example'
-    | 'info-example'
-    | 'warning-color-assistive-technologies'
-    | 'warning-example'
+  name?: 'danger-example' | 'info-example' | 'warning-color-assistive-technologies' | 'warning-example'
   /**
    * The summary text displayed before the details are expanded.
    * If not provided and `name` is set, will use the `title` from the markdown frontmatter.
@@ -26,7 +22,7 @@ let { summary } = Astro.props
 let Content: MarkdownInstance<{}>['Content'] | undefined
 
 if (name) {
-  const details = await getDetailsByName(name) as any
+  const details = (await getDetailsByName(name)) as any
 
   if (!details) {
     throw new Error(`Could not find details with name '${name}'.`)
@@ -37,7 +33,7 @@ if (name) {
     summary = details.data.title
   }
 
-  const namedDetails = await render(details) as any
+  const namedDetails = (await render(details)) as any
   Content = namedDetails.Content
 }
 
@@ -49,8 +45,18 @@ if (!summary) {
 
 <details class="bd-details">
   <summary class="bd-details-summary">
-    <svg class="bd-details-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
-      <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708"/>
+    <svg
+      class="bd-details-icon"
+      xmlns="http://www.w3.org/2000/svg"
+      width="16"
+      height="16"
+      fill="currentColor"
+      viewBox="0 0 16 16"
+    >
+      <path
+        fill-rule="evenodd"
+        d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708"
+      ></path>
     </svg>
     {summary}
   </summary>
index 081737924e59afe3d822e4decc223705c68cf2b8..b6c94eedec42268a82978653f766f1c791373193 100644 (file)
@@ -63,9 +63,7 @@ let markup = Array.isArray(code) ? code.join('\n') : code
 markup = replacePlaceholdersInHtml(markup)
 
 // Use customMarkup for source code display if provided, otherwise use the processed markup
-let sourceMarkup = customMarkup
-  ? (Array.isArray(customMarkup) ? customMarkup.join('\n') : customMarkup)
-  : markup
+let sourceMarkup = customMarkup ? (Array.isArray(customMarkup) ? customMarkup.join('\n') : customMarkup) : markup
 
 const simplifiedMarkup = sourceMarkup
   .replace(
@@ -79,12 +77,16 @@ const simplifiedMarkup = sourceMarkup
 ---
 
 <div class="bd-example-snippet bd-code-snippet not-prose">
-  {showPreview && (
-    <div id={id} class:list={['bd-example', className]}>
-      <Fragment set:html={markup} />
-    </div>
-  )}
-  {showMarkup && (
-    <Code code={simplifiedMarkup} lang={lang} file={file} nestedInExample={true} addStackblitzJs={addStackblitzJs} />
-  )}
+  {
+    showPreview && (
+      <div id={id} class:list={['bd-example', className]}>
+        <Fragment set:html={markup} />
+      </div>
+    )
+  }
+  {
+    showMarkup && (
+      <Code code={simplifiedMarkup} lang={lang} file={file} nestedInExample={true} addStackblitzJs={addStackblitzJs} />
+    )
+  }
 </div>
index ce4ec5f90892e8ffda93e138b31ddfb525a209ec..ab408c7acea93f9f4aebe52cec678359ea813249 100644 (file)
@@ -34,22 +34,11 @@ const logicalPlacements = [
       <label class="form-label fw-semibold mb-0">Placement type</label>
       <div class="btn-group btn-group-sm" role="group" aria-label="Placement type">
         <label class="btn-check btn-outline theme-secondary">
-          <input
-            type="radio"
-            name="menu-placement-type"
-            value="physical"
-            checked
-            data-placement-type="physical"
-          />
+          <input type="radio" name="menu-placement-type" value="physical" checked data-placement-type="physical" />
           Physical
         </label>
         <label class="btn-check btn-outline theme-secondary">
-          <input
-            type="radio"
-            name="menu-placement-type"
-            value="logical"
-            data-placement-type="logical"
-          />
+          <input type="radio" name="menu-placement-type" value="logical" data-placement-type="logical" />
           Logical
         </label>
       </div>
@@ -69,30 +58,29 @@ const logicalPlacements = [
         >
           <span>bottom-start</span>
           <svg class="bi ms-1" width="16" height="16" aria-hidden="true">
-            <use href="#chevron-expand" />
+            <use href="#chevron-expand"></use>
           </svg>
         </button>
         <div class="menu" id="menu-placement-selector-menu">
-          {physicalPlacements.map((p) => (
-            <button
-              class:list={['menu-item', { 'active': p.value === 'bottom-start' }]}
-              type="button"
-              data-placement-group="physical"
-              data-placement={p.value}
-            >
-              {p.label}
-            </button>
-          ))}
-          {logicalPlacements.map((p) => (
-            <button
-              class="menu-item d-none"
-              type="button"
-              data-placement-group="logical"
-              data-placement={p.value}
-            >
-              {p.label}
-            </button>
-          ))}
+          {
+            physicalPlacements.map((p) => (
+              <button
+                class:list={['menu-item', { active: p.value === 'bottom-start' }]}
+                type="button"
+                data-placement-group="physical"
+                data-placement={p.value}
+              >
+                {p.label}
+              </button>
+            ))
+          }
+          {
+            logicalPlacements.map((p) => (
+              <button class="menu-item d-none" type="button" data-placement-group="logical" data-placement={p.value}>
+                {p.label}
+              </button>
+            ))
+          }
         </div>
       </div>
     </div>
@@ -114,7 +102,7 @@ const logicalPlacements = [
 />
 
 <script>
-  import { Menu } from '../../../../dist/js/bootstrap.bundle.js'
+  import { Menu } from '@bootstrap'
 
   const selectorButton = document.querySelector('#menu-placement-selector') as HTMLButtonElement
   const selectorItems = document.querySelectorAll('#menu-placement-selector-menu .menu-item')
@@ -124,12 +112,13 @@ const logicalPlacements = [
   const codeSnippet = previewContainer?.closest('.bd-example-snippet')?.querySelector('.highlight code') as HTMLElement
 
   function updateSelectorItems() {
-    const selectedType = (document.querySelector('input[name="menu-placement-type"]:checked') as HTMLInputElement)?.value || 'physical'
+    const selectedType =
+      (document.querySelector('input[name="menu-placement-type"]:checked') as HTMLInputElement)?.value || 'physical'
 
-    document.querySelectorAll('#menu-placement-selector-menu [data-placement-group="physical"]').forEach(el => {
+    document.querySelectorAll('#menu-placement-selector-menu [data-placement-group="physical"]').forEach((el) => {
       el.classList.toggle('d-none', selectedType !== 'physical')
     })
-    document.querySelectorAll('#menu-placement-selector-menu [data-placement-group="logical"]').forEach(el => {
+    document.querySelectorAll('#menu-placement-selector-menu [data-placement-group="logical"]').forEach((el) => {
       el.classList.toggle('d-none', selectedType !== 'logical')
     })
 
@@ -150,7 +139,7 @@ const logicalPlacements = [
     if (labelSpan) labelSpan.textContent = placement
     selectorButton.dataset.placement = placement
 
-    selectorItems.forEach(item => {
+    selectorItems.forEach((item) => {
       const itemPlacement = (item as HTMLElement).dataset.placement
       item.classList.toggle('active', itemPlacement === placement)
     })
@@ -185,7 +174,7 @@ const logicalPlacements = [
   if (selectorButton) {
     const selectorMenu = Menu.getOrCreateInstance(selectorButton)
 
-    selectorItems.forEach(item => {
+    selectorItems.forEach((item) => {
       item.addEventListener('click', (e) => {
         e.preventDefault()
         const placement = (item as HTMLElement).dataset.placement || 'bottom-start'
@@ -195,7 +184,7 @@ const logicalPlacements = [
     })
   }
 
-  placementTypeInputs.forEach(input => {
+  placementTypeInputs.forEach((input) => {
     input.addEventListener('change', updateSelectorItems)
   })
 
index d0542cc05eb8af6cf73f79c0f34474cbd1a05868..a4d05d746c15a555a9fda24c5d0c2d5bc58698c0 100644 (file)
@@ -24,19 +24,17 @@ const placements = [
       >
         <span>Default (static)</span>
         <svg class="bi ms-1" width="16" height="16" aria-hidden="true">
-          <use href="#chevron-expand" />
+          <use href="#chevron-expand"></use>
         </svg>
       </button>
       <div class="menu">
-        {placements.map((p) => (
-          <a
-            class:list={['menu-item', { 'active': p.value === '' }]}
-            href="#"
-            data-placement={p.value}
-          >
-            {p.label}
-          </a>
-        ))}
+        {
+          placements.map((p) => (
+            <a class:list={['menu-item', { active: p.value === '' }]} href="#" data-placement={p.value}>
+              {p.label}
+            </a>
+          ))
+        }
       </div>
     </div>
   </div>
@@ -52,7 +50,7 @@ const placements = [
 />
 
 <script>
-  import { Menu } from '../../../../dist/js/bootstrap.bundle.js'
+  import { Menu } from '@bootstrap'
 
   const placementMenuButton = document.querySelector('#navbar-placement-menu') as HTMLButtonElement
   const placementMenuItems = document.querySelectorAll('#navbar-placement-menu + .menu .menu-item')
@@ -75,17 +73,19 @@ const placements = [
 
     const labelSpan = placementMenuButton.querySelector('span')
     if (labelSpan) {
-      labelSpan.textContent = placementLabels[placement] ? `${placementLabels[placement]}${placement ? '' : ' (static)'}` : 'Default (static)'
+      labelSpan.textContent = placementLabels[placement]
+        ? `${placementLabels[placement]}${placement ? '' : ' (static)'}`
+        : 'Default (static)'
     }
     placementMenuButton.dataset.placement = placement
 
-    placementMenuItems.forEach(item => {
+    placementMenuItems.forEach((item) => {
       const itemPlacement = (item as HTMLElement).dataset.placement
       item.classList.toggle('active', itemPlacement === placement)
     })
 
     // Remove all placement classes
-    placementClasses.forEach(cls => {
+    placementClasses.forEach((cls) => {
       previewNavbar.classList.remove(cls)
     })
 
@@ -123,7 +123,7 @@ const placements = [
   if (placementMenuButton) {
     const placementMenu = Menu.getOrCreateInstance(placementMenuButton)
 
-    placementMenuItems.forEach(item => {
+    placementMenuItems.forEach((item) => {
       item.addEventListener('click', (e) => {
         e.preventDefault()
         const placement = (item as HTMLElement).dataset.placement || ''
index 9fed55d811eb8f3190137eb195859161fe220d09..b07ce85fa6dad313cf164c73f82574dee0957f39 100644 (file)
@@ -47,11 +47,10 @@ const containerClass = className || classFromClass
 let markup = Array.isArray(code) ? code.join('\n') : code
 markup = replacePlaceholdersInHtml(markup)
 
-const simplifiedMarkup = markup
-  .replace(
-    /<svg.*class="bd-placeholder-img(?:-lg)?(?: *?bd-placeholder-img-lg)? ?(.*?)".*?<\/svg>/g,
-    (match, classes) => `<img src="..."${classes ? ` class="${classes}"` : ''} alt="...">`
-  )
+const simplifiedMarkup = markup.replace(
+  /<svg.*class="bd-placeholder-img(?:-lg)?(?: *?bd-placeholder-img-lg)? ?(.*?)".*?<\/svg>/g,
+  (match, classes) => `<img src="..."${classes ? ` class="${classes}"` : ''} alt="...">`
+)
 ---
 
 <div class="bd-example-snippet bd-code-snippet">
@@ -63,7 +62,5 @@ const simplifiedMarkup = markup
       <Fragment set:html={markup} />
     </div>
   </div>
-  {showMarkup && (
-    <Code code={simplifiedMarkup} lang="html" nestedInExample={true} />
-  )}
+  {showMarkup && <Code code={simplifiedMarkup} lang="html" nestedInExample={true} />}
 </div>
index 9b68ddef0aeda9d9ba2796c27e8a34f7795f009a..cb836eec2bd986faf9ab8f4fb0c720182aea52a2 100644 (file)
@@ -46,7 +46,7 @@ const isLowContrastDark = contrastDarkRatio !== null && contrastDarkRatio < 4.5
 
 const contrastStyles = {
   marginLeft: 'auto',
-  opacity: .5,
+  opacity: 0.5,
   fontSize: '.75rem',
   fontFamily: 'var(--bs-font-monospace)',
   color: isLowContrast ? 'red' : 'inherit'
@@ -69,11 +69,11 @@ const displayCssVar = bg
   }
 
   /* Show dark contrast in dark mode */
-  :global([data-bs-theme="dark"]) .contrast-light {
+  :global([data-bs-theme='dark']) .contrast-light {
     display: none;
   }
 
-  :global([data-bs-theme="dark"]) .contrast-dark {
+  :global([data-bs-theme='dark']) .contrast-dark {
     display: inline;
   }
 
@@ -92,49 +92,75 @@ const displayCssVar = bg
   }
 
   /* Show dark value in dark mode */
-  :global([data-bs-theme="dark"]) .css-var-light {
+  :global([data-bs-theme='dark']) .css-var-light {
     display: none;
   }
 
-  :global([data-bs-theme="dark"]) .css-var-dark {
+  :global([data-bs-theme='dark']) .css-var-dark {
     display: inline;
   }
 </style>
 
-{size === 'inline' ? (
-  <>
+{
+  size === 'inline' ? (
+    <>
+      <span style={combinedStyles}>
+        <slot />
+        {contrast && (
+          <span style={contrastStyles} class="contrast-light">
+            {contrast}
+          </span>
+        )}
+        {contrastDark && (
+          <span style={{ ...contrastStyles, color: isLowContrastDark ? 'red' : 'inherit' }} class="contrast-dark">
+            {contrastDark}
+          </span>
+        )}
+      </span>
+      {showVar && displayCssVar && (
+        <code class="css-var" data-css-var={`--bs-${displayCssVar}`}>
+          <span class="css-var-light">Loading...</span>
+          <span class="css-var-dark">Loading...</span>
+        </code>
+      )}
+    </>
+  ) : size === 'large' ? (
     <span style={combinedStyles}>
       <slot />
-      {contrast && <span style={contrastStyles} class="contrast-light">{contrast}</span>}
-      {contrastDark && <span style={{...contrastStyles, color: isLowContrastDark ? 'red' : 'inherit'}} class="contrast-dark">{contrastDark}</span>}
+      {contrast && (
+        <span style={contrastStyles} class="contrast-light">
+          {contrast}
+        </span>
+      )}
+      {contrastDark && (
+        <span style={{ ...contrastStyles, color: isLowContrastDark ? 'red' : 'inherit' }} class="contrast-dark">
+          {contrastDark}
+        </span>
+      )}
     </span>
-    {showVar && displayCssVar && (
-      <code class="css-var" data-css-var={`--bs-${displayCssVar}`}>
-        <span class="css-var-light">Loading...</span>
-        <span class="css-var-dark">Loading...</span>
-      </code>
-    )}
-  </>
-) : size === 'large' ? (
-  <span style={combinedStyles}>
-    <slot />
-    {contrast && <span style={contrastStyles} class="contrast-light">{contrast}</span>}
-    {contrastDark && <span style={{...contrastStyles, color: isLowContrastDark ? 'red' : 'inherit'}} class="contrast-dark">{contrastDark}</span>}
-  </span>
-) : (
-  <div style={combinedStyles}>
-    <slot />
-    {contrast && <span style={contrastStyles} class="contrast-light">{contrast}</span>}
-    {contrastDark && <span style={{...contrastStyles, color: isLowContrastDark ? 'red' : 'inherit'}} class="contrast-dark">{contrastDark}</span>}
-  </div>
-)}
+  ) : (
+    <div style={combinedStyles}>
+      <slot />
+      {contrast && (
+        <span style={contrastStyles} class="contrast-light">
+          {contrast}
+        </span>
+      )}
+      {contrastDark && (
+        <span style={{ ...contrastStyles, color: isLowContrastDark ? 'red' : 'inherit' }} class="contrast-dark">
+          {contrastDark}
+        </span>
+      )}
+    </div>
+  )
+}
 
 <script>
   // Handle dynamic CSS variable display with light-dark() function support
   document.addEventListener('DOMContentLoaded', () => {
     const cssVarElements = document.querySelectorAll('.css-var[data-css-var]')
 
-    cssVarElements.forEach(element => {
+    cssVarElements.forEach((element) => {
       const cssVarName = element.getAttribute('data-css-var')
 
       if (cssVarName) {
index 4ac506139e6bbfd39e917b503fcbea4074a2c4b9..d12421e5509c2c9d46b8bfd5178aa8ae8ea42946 100644 (file)
@@ -44,16 +44,10 @@ const bodyProps = overrides?.body ?? {}
 const mainProps = overrides?.main ?? {}
 ---
 
-<!DOCTYPE html>
+<!doctype html>
 <html lang="en" data-bs-theme="auto">
   <head>
-    <Head
-      description={description}
-      layout={layout}
-      robots={robots}
-      thumbnail={thumbnail}
-      title={title}
-    />
+    <Head description={description} layout={layout} robots={robots} thumbnail={thumbnail} title={title} />
   </head>
   <body {...bodyProps}>
     <div class="navbar-translucent sticky-top bd-sticky-navbar">
index 2812b81d4607b95bae9d1815540d55cf46dc6906..bb9cf87f549984843fb3c8895b3bdf9b434b09fd 100644 (file)
@@ -12,7 +12,7 @@ import TableOfContents from '@components/TableOfContents.astro'
 import ReferenceTable from '@components/ReferenceTable.astro'
 import UtilityReferenceTable from '@components/UtilityReferenceTable.astro'
 import HelperReferenceTable from '@components/HelperReferenceTable.astro'
-import { getData } from '@libs/data'
+import { getData, type SidebarItem, type SidebarSubItem } from '@libs/data'
 import CloseButton from '@components/shortcodes/CloseButton.astro'
 import PageMeta from '@components/PageMeta.astro'
 
@@ -51,31 +51,32 @@ let nextPage: NavigationPage | undefined
 // Create a flat array of all pages with their groups, handling nested groups
 const allPages: NavigationPage[] = sidebar.flatMap((group) => {
   if (!group.pages) return []
-  return group.pages.flatMap((item: any) => {
+  return group.pages.flatMap((item: SidebarItem) => {
     // Handle nested groups (e.g., Utilities > Borders > Border)
     if (item.group && item.pages) {
-      return item.pages.map((page: any) => ({
+      const subgroupTitle = item.group
+      return item.pages.map((page: SidebarSubItem) => ({
         title: page.title,
         url: `/docs/${getConfig().docs_version}/${getSlug(group.title)}/${getSlug(page.title)}/`,
-        groupTitle: item.group
+        groupTitle: subgroupTitle
       }))
     }
     // Handle direct pages
     if (item.title) {
-      return [{
-        title: item.title,
-        url: `/docs/${getConfig().docs_version}/${getSlug(group.title)}/${getSlug(item.title)}/`,
-        groupTitle: group.title
-      }]
+      return [
+        {
+          title: item.title,
+          url: `/docs/${getConfig().docs_version}/${getSlug(group.title)}/${getSlug(item.title)}/`,
+          groupTitle: group.title
+        }
+      ]
     }
     return []
   })
 })
 
 // Find the current page index
-const currentPageIndex = allPages.findIndex(
-  (page) => page.url === `/docs/${getConfig().docs_version}/${slug}/`
-)
+const currentPageIndex = allPages.findIndex((page) => page.url === `/docs/${getConfig().docs_version}/${slug}/`)
 
 if (currentPageIndex > 0) {
   prevPage = allPages[currentPageIndex - 1]
@@ -164,23 +165,11 @@ if (currentPageIndex < allPages.length - 1) {
           )
         }
 
-        {
-          frontmatter.reference && (
-            <ReferenceTable reference={frontmatter.reference} />
-          )
-        }
+        {frontmatter.reference && <ReferenceTable reference={frontmatter.reference} />}
 
-        {
-          frontmatter.utility && (
-            <UtilityReferenceTable utility={frontmatter.utility} />
-          )
-        }
+        {frontmatter.utility && <UtilityReferenceTable utility={frontmatter.utility} />}
 
-        {
-          frontmatter.classes && (
-            <HelperReferenceTable classes={frontmatter.classes} />
-          )
-        }
+        {frontmatter.classes && <HelperReferenceTable classes={frontmatter.classes} />}
 
         <slot />
 
index 8925c0118ec4738bbae2701a97a152180c9d53d2..4a232df09c9a3e8a33c46a0a4439bfeaf9954db1 100644 (file)
@@ -17,7 +17,7 @@ const pageTitle = `${title} · ${getConfig().title} v${getConfig().docs_version}
 const canonicalUrl = new URL(Astro.url.pathname, Astro.site)
 ---
 
-<!DOCTYPE html>
+<!doctype html>
 <html lang="en" class:list={html_class} data-bs-theme="auto">
   <head>
     <meta charset="utf-8" />
@@ -29,9 +29,13 @@ const canonicalUrl = new URL(Astro.url.pathname, Astro.site)
 
     <link rel="canonical" href={canonicalUrl} />
 
+    {/* Loaded as `is:inline` (not via Vite) so the theme is applied before paint. */}
+    {/* The script lives in `site/static/docs/[version]/assets/js/` so it can */}
+    {/* render-block at this exact spot in the head without going through the */}
+    {/* bundler (which would defer it and cause a flash of the wrong theme). */}
     <script is:inline src={getVersionedDocsPath('assets/js/color-modes.js')}></script>
 
-    <Stylesheet layout="examples" />
+    <Stylesheet />
     <Favicons />
 
     <style is:global>
@@ -55,7 +59,9 @@ const canonicalUrl = new URL(Astro.url.pathname, Astro.site)
         background-color: rgba(0, 0, 0, 0.1);
         border: solid rgba(0, 0, 0, 0.15);
         border-width: 1px 0;
-        box-shadow: inset 0 0.5em 1.5em rgba(0, 0, 0, 0.1), inset 0 0.125em 0.5em rgba(0, 0, 0, 0.15);
+        box-shadow:
+          inset 0 0.5em 1.5em rgba(0, 0, 0, 0.1),
+          inset 0 0.125em 0.5em rgba(0, 0, 0, 0.15);
       }
 
       .b-example-vr {
index 869b6179aae8071a740b49f974b980912e1acdb8..57bee84c3eae401f5fdd12fdd33f1a26da25364e 100644 (file)
@@ -22,32 +22,17 @@ const { layout } = Astro.props
   <svg class="bi bi-sm" aria-hidden="true"><use href="#chevron-expand"></use></svg>
 </button>
 <div class="menu" id="bd-theme-menu" aria-labelledby="bd-theme" style="--bs-menu-min-width: 8rem;">
-  <button
-    type="button"
-    class="menu-item"
-    data-bs-theme-value="light"
-    aria-pressed="false"
-  >
+  <button type="button" class="menu-item" data-bs-theme-value="light" aria-pressed="false">
     <svg class="bi opacity-50" aria-hidden="true"><use href="#sun-fill"></use></svg>
     Light
     <svg class="bi ms-auto d-none" aria-hidden="true"><use href="#check2"></use></svg>
   </button>
-  <button
-    type="button"
-    class="menu-item"
-    data-bs-theme-value="dark"
-    aria-pressed="false"
-  >
+  <button type="button" class="menu-item" data-bs-theme-value="dark" aria-pressed="false">
     <svg class="bi opacity-50" aria-hidden="true"><use href="#moon-stars-fill"></use></svg>
     Dark
     <svg class="bi ms-auto d-none" aria-hidden="true"><use href="#check2"></use></svg>
   </button>
-  <button
-    type="button"
-    class="menu-item active"
-    data-bs-theme-value="auto"
-    aria-pressed="true"
-  >
+  <button type="button" class="menu-item active" data-bs-theme-value="auto" aria-pressed="true">
     <svg class="bi opacity-50" aria-hidden="true"><use href="#circle-half"></use></svg>
     Auto
     <svg class="bi ms-auto d-none" aria-hidden="true"><use href="#check2"></use></svg>
index 7aa79f81be93920cee4747160d8d84568a2274c6..1c9b239959498ff810c11433bf2fac8f6164ed77 100644 (file)
@@ -1,5 +1,5 @@
 import ClipboardJS from 'clipboard'
-import { Tooltip } from '../../../dist/js/bootstrap.bundle.js'
+import { Tooltip } from '@bootstrap'
 
 const btnTitle = 'Copy'
 
index 1a6ca6d6c2ed8198388a5235ed50eceecf7b5cb1..4a9d0f0b3ec7f3028529e2220ccbc5ec2505258e 100644 (file)
@@ -114,6 +114,13 @@ const dataDefinitions = {
     .array()
 } satisfies Record<string, DataSchema>
 
+// Inferred types for individual data files. Exported so consumers can avoid
+// re-deriving them via `ReturnType<typeof getData<'sidebar'>>` and don't have
+// to fall back to `any` when iterating nested arrays.
+export type SidebarGroup = z.infer<typeof dataDefinitions.sidebar>[number]
+export type SidebarItem = NonNullable<SidebarGroup['pages']>[number]
+export type SidebarSubItem = NonNullable<SidebarItem['pages']>[number]
+
 let data = new Map<DataType, z.infer<DataSchema>>()
 
 // A helper to get data loaded fom a yml file in the `./site/data/` directory. If the data does not match its associated
index fcdd33e7841ef5984ec05c0003365de429e1a231..d8ef535b3db5192df4a7cb50320c794c02afe5ad 100644 (file)
@@ -1,8 +1,7 @@
 import { slug } from 'github-slugger'
-import fromMarkdown from 'mdast-util-from-markdown'
-import toString from 'mdast-util-to-string'
 import { remark } from 'remark'
 import remarkHtml from 'remark-html'
+import type { Node, Parent } from 'unist'
 
 export function capitalizeFirstLetter(str: string) {
   return str.charAt(0).toUpperCase() + str.slice(1)
@@ -33,12 +32,28 @@ export function trimLeadingAndTrailingSlashes(str: string) {
   return str.replace(/^\/+|\/+$/g, '')
 }
 
+// Single shared `remark` pipeline for every markdown helper below — keeps the
+// dependency list to just `remark` + `remark-html` (no transitively-resolved
+// `mdast-util-*` imports) and avoids paying parser setup cost per call.
+const markdownParser = remark()
+const htmlProcessor = remark().use(remarkHtml)
+
+function nodeToText(node: Node): string {
+  if ('value' in node && typeof node.value === 'string') {
+    return node.value
+  }
+
+  if ('children' in node) {
+    return (node as Parent).children.map((child) => nodeToText(child)).join('')
+  }
+
+  return ''
+}
+
 export function stripMarkdown(str: string) {
-  return toString(fromMarkdown(str))
+  return nodeToText(markdownParser.parse(str))
 }
 
 export function processMarkdownToHtml(markdown: string): string {
-  // Use remark to process markdown to HTML
-  const result = remark().use(remarkHtml).processSync(markdown)
-  return result.toString()
+  return htmlProcessor.processSync(markdown).toString()
 }
index f53ee0242f0ea5350fd209fdcb39886dc8ef791c..e697f801584c41225bf6c1c4378f03ad91c561eb 100644 (file)
@@ -3,7 +3,7 @@
   "compilerOptions": {
     "baseUrl": ".",
     "paths": {
-      "@assets/*": ["src/assets/*"],
+      "@bootstrap": ["../dist/js/bootstrap.bundle.js"],
       "@components/*": ["src/components/*"],
       "@layouts/*": ["src/layouts/*"],
       "@libs/*": ["src/libs/*"],