@@ -695,6 +726,7 @@
{{ render_doc_toc([
+ {"id": "release-1-1-0", "label": "v1.1.0"},
{"id": "release-1-1-0-dev-1", "label": "v1.1.0-dev.1"},
{"id": "release-1-0-0", "label": "v1.0.0"},
{"id": "release-1-0-0-rc-11", "label": "v1.0.0-rc.11"},
diff --git a/site/src/pages/components/table-of-contents.html.jinja b/site/src/pages/components/table-of-contents.html.jinja
index d0016ecb..03585ca2 100644
--- a/site/src/pages/components/table-of-contents.html.jinja
+++ b/site/src/pages/components/table-of-contents.html.jinja
@@ -1,23 +1,9 @@
{% extends "layouts/catalog.html.jinja" %}
-{% from "components/toc.html.jinja" import table_of_contents %}
+{% from "includes/block-example.html.jinja" import render_block_example %}
+{% from "includes/code-snippet.html.jinja" import render_code_snippet %}
{% from "includes/documentation-reference.html.jinja" import render_reference with context %}
-{% from "includes/example.html.jinja" import render_component_intro, render_component_example, render_rtl_example with context %}
{% from "includes/page-header.html.jinja" import render_page_header with context %}
-
-{% macro section_example(prefix, presentation="list", label="On this page", overview_label="Overview", labels=["Introduction", "Content and configuration", "Languages"]) -%}
- {% set items = [
- {"target_id": prefix ~ '-intro', "label": labels[0]},
- {"target_id": prefix ~ '-content', "label": labels[1]},
- {"target_id": prefix ~ '-languages', "label": labels[2]}
- ] %}
-
- {{ table_of_contents(prefix ~ '-toc', items, presentation=presentation, label=label, overview_label=overview_label, content_id=prefix ~ '-content-scope', scroll_root_id='main-content', extra_class="mb-3") }}
- {% for item in items %}
- {{ item.label }}
- The host supplies this native heading and its stable fragment ID.
- {% endfor %}
-
-{%- endmacro %}
+{% from "pages/blocks/previews/toc.html.jinja" import toc_demo with context %}
{% block title %}Table of Contents — Moo UI{% endblock %}
@@ -25,36 +11,48 @@
{{ render_page_header("Table of Contents", "Navigate sections of a document with a list or a compact control that shows the current section.") }}
- {% set intro %}{{ section_example('toc-intro') }}{% endset %}
- {% set usage %}
-
Supply ordered section IDs and plain-text labels. Moo UI renders native fragment links; the host owns headings, content and layout. Empty sections render nothing. A single section remains available.
-
Use the list beside a wide article or the compact presentation before narrow content. The compact menu spans its navigation row, wraps long labels and uses Bootstrap's Dropdown keyboard and dismissal behavior.
-
Initialize the optional TableOfContents module to synchronize the current section and active links. Importing the module alone does not initialize a document. For a JavaScript-disabled host, use the list.
+ {% set demo %}{{ toc_demo() }}{% endset %}
+ {{ render_block_example(
+ "toc-document", "Placement guide", "Explore one document at desktop, tablet and mobile widths.", demo,
+ preview_class="moo-example__preview--shell",
+ frame_src=site_href("blocks/previews/toc.html", root_path),
+ frame_width=1280, frame_height=900,
+ frame_viewports=[
+ {"label": "Mobile", "icon": "smartphone", "width": 390, "height": 900},
+ {"label": "Tablet", "icon": "tablet", "width": 768, "height": 900},
+ {"label": "Desktop", "icon": "monitor", "width": 1280, "height": 900, "active": true}
+ ],
+ show_header=false
+ ) }}
+
+
Usage
+
Supply ordered section IDs and plain-text labels. Moo UI renders native fragment links; the host owns headings, content and layout. Empty sections render nothing. A single section remains available.
+
Use the viewport controls to resize the same live document. Choose a section or scroll inside the preview to follow its active indicator. The preview owns its URL fragments and scroll area independently from this documentation page.
+
+
Responsive placement
+
The desktop list stays beside the article. Below lg, the compact presentation moves into the header above the scrolling content. Both use the same section data with unique navigation IDs and complementary Bootstrap visibility utilities.
+
The compact menu spans its navigation row, wraps long labels and uses Bootstrap's Dropdown keyboard and dismissal behavior. Supporting blocks render once and follow the article when the columns stack. Translate the labels for each document; logical spacing follows its text direction.
+
+
Runtime and placement
+
Import TableOfContents from @wpmoo/ui/toc.js and initialize each supplied [data-toc] root. Use refresh() after replacing targets and dispose() when removing a view. The previous @wpmoo/ui/table-of-contents.js entrypoint remains a compatibility re-export of the same constructor.
+ {% set init_code %}
+ import TableOfContents from "@wpmoo/ui/toc.js";
+
+ const reader = document.getElementById("main-content");
+ reader.classList.add("scroll-smooth");
+
+ document.querySelectorAll("[data-toc]").forEach(element => {
+ TableOfContents.getOrCreateInstance(element);
+ });
{% endset %}
- {{ render_component_intro(intro, usage) }}
-
- {% set list_example %}{{ section_example('toc-list-example') }}{% endset %}
- {{ render_component_example("table-of-contents", "Table of Contents", "list", "Section list", "Keep native section links visible in a content aside. The host chooses its column, breakpoint and position.", list_example) }}
-
- {% set compact_example %}{{ section_example('toc-compact-example', presentation='compact') }}{% endset %}
- {{ render_component_example("table-of-contents", "Table of Contents", "compact", "Compact navigation", "Open the full-width menu to select a section. Overview is shown before the first tracked heading.", compact_example) }}
+ {{ render_code_snippet("toc-initialization", init_code, language="js") }}
+
Importing the module alone does not initialize a document. For a JavaScript-disabled host, use the list.
+
content_id limits resolution to an explicit content region inside the same Moo owner. scroll_root_id identifies the scrolling ancestor of that content. Omitted values use the nearest Moo owner and document scrolling. A missing scope leaves the native links available and skips tracking.
+
The host owns fixed header geometry. With the App layout, place the compact navigation in the header above the scrolling main region, and supply that region's ID. For other layouts, a finite nonnegative activationOffset option sets the tracking line. The component does not change layout styles or override native scrolling.
+
For animated native fragment navigation, apply the Core scroll-smooth utility to the actual scroll container inside its Moo owner. The utility uses scroll-behavior and switches to immediate scrolling when the visitor prefers reduced motion. Links retain their native URL fragments and browser history.
+
Two presentations can share section data with unique IDs and complementary Bootstrap visibility utilities. Ordinary aside content renders once and can stack below the article on narrow screens.
- {% set arabic %}
- {{ section_example('toc-arabic', presentation='compact', label='في هذه الصفحة', overview_label='نظرة عامة', labels=['مقدمة', 'المحتوى والإعدادات', 'اللغات']) }}
- {% endset %}
- {% set hebrew %}
- {{ section_example('toc-hebrew', presentation='compact', label='בעמוד זה', overview_label='סקירה כללית', labels=['מבוא', 'תוכן והגדרות', 'שפות']) }}
- {% endset %}
- {% set english %}{{ section_example('toc-english', presentation='compact') }}{% endset %}
- {{ render_rtl_example("table-of-contents", "Keep section labels readable and fragment navigation native in each direction.", arabic, hebrew, english) }}
-
Runtime and placement
-
Import TableOfContents from @wpmoo/ui/table-of-contents.js and call TableOfContents.getOrCreateInstance(element) for each supplied [data-toc] root. Use refresh() after replacing targets and dispose() when removing a view.
-
content_id limits resolution to an explicit content region inside the same Moo owner. scroll_root_id identifies the scrolling ancestor of that content. Omitted values use the nearest Moo owner and document scrolling. A missing scope leaves the native links available and skips tracking.
-
The host owns fixed header geometry. With the App layout, place the compact navigation in the header above the scrolling main region, and supply that region's ID. For other layouts, a finite nonnegative activationOffset option sets the tracking line. The component does not change layout styles or override native scrolling.
-
For animated native fragment navigation, apply the Core scroll-smooth utility to the actual scroll container inside its Moo owner. The utility uses scroll-behavior and switches to immediate scrolling when the visitor prefers reduced motion. Links retain their native URL fragments and browser history.
-
Two presentations can share section data with unique IDs and complementary Bootstrap visibility utilities. Ordinary aside content renders once and can stack below the article on narrow screens.
-
{{ render_reference("For the compact control's native behavior, see the", "https://getbootstrap.com/docs/5.3/components/dropdowns/", "Bootstrap Dropdown documentation") }}
{% endblock %}
diff --git a/src/certification/api-freeze-1.1.0.json b/src/certification/api-freeze-1.1.0.json
new file mode 100644
index 00000000..f28fdcaf
--- /dev/null
+++ b/src/certification/api-freeze-1.1.0.json
@@ -0,0 +1,465 @@
+{
+ "freezeVersion": "1.1.0",
+ "frozenAt": "2026-10-09",
+ "description": "API inventory for the Moo UI 1.1.0 stable public contract. It preserves the 1.0.0 surface and adds the shared TableOfContents module and aggregate export. The preferred standalone entrypoint is toc.js; table-of-contents.js remains a compatibility re-export of the same constructor. Component certification remains preview. The immutable 1.0.0 and release-candidate inventories remain removal guards; incompatible changes to a documented public contract require a major release.",
+ "packageExports": [
+ "./moo-ui.css",
+ "./moo-ui.min.css",
+ "./moo.css",
+ "./moo.min.css",
+ "./moo-ui.js",
+ "./moo-ui.min.js",
+ "./combobox.js",
+ "./sidebar.js",
+ "./context-menu.js",
+ "./datatable.js",
+ "./slider.js",
+ "./toc.js",
+ "./table-of-contents.js",
+ "./sheet.js",
+ "./chart.js",
+ "./chart.min.js",
+ "./datepicker.js",
+ "./datepicker.min.js",
+ "./state.js",
+ "./release-manifest.json",
+ "./scss/config",
+ "./scss/moo-ui",
+ "./scss/moo-core",
+ "./scss/components",
+ "./scss/settings",
+ "./certification.json",
+ "./package.json"
+ ],
+ "packageFiles": [
+ "dist/assets/css/moo-ui.css",
+ "dist/assets/css/moo-ui.min.css",
+ "dist/assets/css/moo.css",
+ "dist/assets/css/moo.min.css",
+ "dist/js/moo-ui.js",
+ "dist/js/moo-ui.min.js",
+ "dist/js/combobox.js",
+ "dist/js/sidebar.js",
+ "dist/js/context-menu.js",
+ "dist/js/datatable.js",
+ "dist/js/slider.js",
+ "dist/js/toc.js",
+ "dist/js/table-of-contents.js",
+ "dist/js/sheet.js",
+ "dist/js/chart.js",
+ "dist/js/chart.min.js",
+ "dist/js/datepicker.js",
+ "dist/js/datepicker.min.js",
+ "dist/js/state.js",
+ "dist/release-manifest.json",
+ "scss/*.scss",
+ "scss/**/*.scss",
+ "certification.json",
+ "README.md",
+ "LICENSE",
+ "ASSET_LICENSE.md"
+ ],
+ "sassFacadeAllowList": [
+ "$primary",
+ "$secondary",
+ "$success",
+ "$info",
+ "$warning",
+ "$danger",
+ "$light",
+ "$dark",
+ "$body-color",
+ "$body-bg",
+ "$border-color",
+ "$border-radius",
+ "$border-radius-sm",
+ "$border-radius-lg",
+ "$font-size-base"
+ ],
+ "sassEntrypoints": [
+ {
+ "export": "./scss/config",
+ "source": "scss/_config.scss",
+ "scope": "public variable allow-list"
+ },
+ {
+ "export": "./scss/moo-ui",
+ "source": "scss/moo-ui.scss",
+ "scope": "full Bootstrap-compatible source entrypoint"
+ },
+ {
+ "export": "./scss/moo-core",
+ "source": "scss/moo-core.scss",
+ "scope": "scoped .moo-ui source entrypoint"
+ },
+ {
+ "export": "./scss/components",
+ "source": "scss/_components.scss",
+ "scope": "component layer source entrypoint"
+ },
+ {
+ "export": "./scss/settings",
+ "source": "scss/_settings.scss",
+ "scope": "settings aggregate loaded before Bootstrap variables"
+ }
+ ],
+ "esmModules": [
+ {
+ "module": "moo-ui.js",
+ "export": "./moo-ui.js",
+ "lifecycle": [
+ "side-effect-free import",
+ "default namespace export",
+ "named lifecycle class exports",
+ "explicit asynchronous Chart loader"
+ ],
+ "source": "src/js/moo-ui.js",
+ "bundled": true,
+ "buildTool": "esbuild",
+ "note": "Side-effect-free convenience aggregate; loadChart() returns a promise for the adjacent chart.js default export. Both aggregate variants use the same Chart module; no Chart.js runtime is included in the aggregate.",
+ "defaultExport": "MooUI",
+ "namedExports": [
+ "Combobox",
+ "ContextMenu",
+ "DataTable",
+ "Datepicker",
+ "MooCalendar",
+ "MooDateRangePicker",
+ "Sidebar",
+ "Slider",
+ "initSheets",
+ "loadChart",
+ "TableOfContents"
+ ],
+ "lazyModules": {
+ "loadChart": "./chart.js"
+ }
+ },
+ {
+ "module": "combobox.js",
+ "export": "./combobox.js",
+ "lifecycle": [
+ "constructor",
+ "getInstance",
+ "getOrCreateInstance",
+ "dispose"
+ ],
+ "source": "src/js/components/combobox.js"
+ },
+ {
+ "module": "sidebar.js",
+ "export": "./sidebar.js",
+ "lifecycle": [
+ "constructor",
+ "getInstance",
+ "getOrCreateInstance",
+ "dispose"
+ ],
+ "source": "src/js/components/sidebar.js"
+ },
+ {
+ "module": "context-menu.js",
+ "export": "./context-menu.js",
+ "lifecycle": [
+ "constructor",
+ "getInstance",
+ "getOrCreateInstance",
+ "dispose"
+ ],
+ "source": "src/js/components/context-menu.js"
+ },
+ {
+ "module": "datatable.js",
+ "export": "./datatable.js",
+ "lifecycle": [
+ "constructor",
+ "getInstance",
+ "getOrCreateInstance",
+ "dispose"
+ ],
+ "source": "src/js/components/datatable.js"
+ },
+ {
+ "module": "sheet.js",
+ "export": "./sheet.js",
+ "source": "src/js/components/sheet.js",
+ "lifecycle": [
+ "side-effect-free import",
+ "explicit initSheets(root)",
+ "Bootstrap Offcanvas instance lifecycle"
+ ],
+ "namedExports": [
+ "initSheets"
+ ],
+ "note": "Explicitly opens data-sheet-open-on-load sheets through native Bootstrap; importing the module never scans the document."
+ },
+ {
+ "module": "chart.js",
+ "export": "./chart.js",
+ "lifecycle": [
+ "constructor",
+ "getInstance",
+ "getOrCreateInstance",
+ "dispose"
+ ],
+ "source": "src/js/components/chart.js",
+ "bundled": true,
+ "runtime": "chart.js@4.5.1",
+ "getters": [
+ "chart",
+ "element"
+ ],
+ "markup": {
+ "rootClass": "chart",
+ "typeAttribute": "data-chart",
+ "dataAttribute": "data-chart-data",
+ "optionsAttribute": "data-chart-options",
+ "supportedTypes": [
+ "area",
+ "line",
+ "bar",
+ "pie",
+ "doughnut",
+ "polarArea",
+ "radar",
+ "scatter",
+ "bubble"
+ ],
+ "canvas": ":scope > canvas",
+ "optionsContract": "JSON-object-only Chart.js options pass-through; functions/callbacks are not serializable and must use programmatic config"
+ }
+ },
+ {
+ "module": "datepicker.js",
+ "export": "./datepicker.js",
+ "lifecycle": [
+ "constructor",
+ "getInstance",
+ "getOrCreateInstance",
+ "dispose"
+ ],
+ "source": "src/js/components/datepicker.js",
+ "bundled": false,
+ "buildTool": "esbuild",
+ "note": "esbuild-produced canonical + minified artifact pair; the module is self-contained Moo UI ESM with no third-party runtime bundled",
+ "namedExports": [
+ "MooCalendar",
+ "MooDateRangePicker"
+ ],
+ "publicMethods": {
+ "MooDatepicker": [
+ "show",
+ "hide",
+ "toggle",
+ "isOpen",
+ "getDate",
+ "setDate",
+ "clear",
+ "dispose"
+ ],
+ "MooDateRangePicker": [
+ "show",
+ "hide",
+ "toggle",
+ "isOpen",
+ "getDates",
+ "setDates",
+ "clear",
+ "dispose"
+ ],
+ "MooCalendar": [
+ "getDate",
+ "getDates",
+ "setDate",
+ "setDates",
+ "clear",
+ "focusActiveDay",
+ "dispose"
+ ]
+ },
+ "markup": {
+ "rootClass": "moo-datepicker",
+ "rootAttribute": "data-datepicker",
+ "triggerAttribute": "data-datepicker-trigger",
+ "popoverAttribute": "data-datepicker-popover",
+ "calendarAttribute": "data-calendar",
+ "labelAttribute": "data-datepicker-label"
+ }
+ },
+ {
+ "module": "slider.js",
+ "export": "./slider.js",
+ "lifecycle": [
+ "constructor",
+ "getInstance",
+ "getOrCreateInstance",
+ "dispose"
+ ],
+ "source": "src/js/components/slider.js",
+ "bundled": false,
+ "nativeElement": "input[type=\"range\"]",
+ "publicMethods": [
+ "dispose"
+ ],
+ "markup": {
+ "rootClass": "slider",
+ "rootAttribute": "data-slider",
+ "trackAttribute": "data-slider-track",
+ "rangeAttribute": "data-slider-range",
+ "inputAttribute": "data-slider-input",
+ "outputAttribute": "data-slider-output"
+ }
+ },
+ {
+ "module": "toc.js",
+ "export": "./toc.js",
+ "source": "src/js/components/toc.js",
+ "defaultExport": "TableOfContents",
+ "lifecycle": [
+ "constructor",
+ "getInstance",
+ "getOrCreateInstance",
+ "refresh",
+ "dispose"
+ ]
+ },
+ {
+ "module": "table-of-contents.js",
+ "export": "./table-of-contents.js",
+ "source": "src/js/components/table-of-contents.js",
+ "defaultExport": "TableOfContents",
+ "lifecycle": [
+ "constructor",
+ "getInstance",
+ "getOrCreateInstance",
+ "refresh",
+ "dispose"
+ ]
+ }
+ ],
+ "artifactVariants": {
+ "moo-ui.min.js": {
+ "canonical": "moo-ui.js",
+ "relationship": "Minified artifact variant of moo-ui.js; shares aggregate exports and side-effect-free import behavior"
+ },
+ "chart.min.js": {
+ "canonical": "chart.js",
+ "relationship": "Minified artifact variant of chart.js; shares source, exports, lifecycle, and runtime ownership"
+ },
+ "datepicker.min.js": {
+ "canonical": "datepicker.js",
+ "relationship": "Minified artifact variant of datepicker.js; shares source, exports, lifecycle, and runtime ownership"
+ }
+ },
+ "cssEntrypoints": [
+ {
+ "export": "./moo-ui.css",
+ "purpose": "Full expanded Bootstrap-compatible CSS build",
+ "scope": "unscoped"
+ },
+ {
+ "export": "./moo-ui.min.css",
+ "purpose": "Full minified CSS build",
+ "scope": "unscoped"
+ },
+ {
+ "export": "./moo.css",
+ "purpose": "Scoped expanded component layer for .moo-ui",
+ "scope": "scoped"
+ },
+ {
+ "export": "./moo.min.css",
+ "purpose": "Scoped minified component layer",
+ "scope": "scoped"
+ }
+ ],
+ "metadataEntrypoints": [
+ {
+ "export": "./certification.json",
+ "purpose": "Versioned support/evidence manifest",
+ "scope": "metadata",
+ "source": "certification.json",
+ "key": "publicEntrypoints.metadata[0]"
+ },
+ {
+ "export": "./package.json",
+ "purpose": "Package metadata",
+ "scope": "metadata",
+ "source": "package.json",
+ "key": "exports[\"./package.json\"]"
+ },
+ {
+ "export": "./release-manifest.json",
+ "purpose": "SHA-256 manifest for the adapter-facing CSS and state bootstrap artifacts.",
+ "scope": "metadata",
+ "source": "dist/release-manifest.json",
+ "key": "publicEntrypoints.metadata[2]"
+ }
+ ],
+ "bootstrapSupport": {
+ "canonicalVersion": "5.3.3",
+ "targetRange": ">=5.3.0 <5.4",
+ "testedVersions": [
+ "5.3.0",
+ "5.3.3",
+ "5.3.8"
+ ],
+ "source": "certification.json"
+ },
+ "browserPolicy": {
+ "policy": "Certification is in progress; see SUPPORT.md for the intended browser policy.",
+ "exactEvidenceInAttestation": false,
+ "source": "certification.json"
+ },
+ "certificationManifest": {
+ "schemaVersion": "0.1",
+ "requiredFields": [
+ "schemaVersion",
+ "status",
+ "coreVersion",
+ "bootstrap",
+ "browserPolicy",
+ "certifiedComponents",
+ "publicEntrypoints",
+ "supportPolicy"
+ ],
+ "source": "src/certification/manifest.schema.json"
+ },
+ "documentationSurfaces": [
+ {
+ "file": "README.md",
+ "tracks": [
+ "package exports",
+ "runtime ownership",
+ "installation paths"
+ ]
+ },
+ {
+ "file": "SUPPORT.md",
+ "tracks": [
+ "SemVer policy",
+ "breaking changes",
+ "Bootstrap compatibility",
+ "browser policy",
+ "maturity definitions"
+ ]
+ },
+ {
+ "file": "site/public/llms.txt",
+ "tracks": [
+ "package exports",
+ "installation facts",
+ "runtime ownership"
+ ]
+ }
+ ],
+ "browserEntrypoints": [
+ {
+ "export": "./state.js",
+ "purpose": "Classic placement-dependent bootstrap restoring Theme, Direction, and keyed Sidebar state before owner content paints.",
+ "scope": "browser",
+ "source": "src/js/state.js",
+ "key": "publicEntrypoints.browser[0]"
+ }
+ ]
+}
diff --git a/src/js/components/table-of-contents.js b/src/js/components/table-of-contents.js
index 3782ba8b..a0e257a8 100644
--- a/src/js/components/table-of-contents.js
+++ b/src/js/components/table-of-contents.js
@@ -1,202 +1 @@
-const instances = new WeakMap();
-const ownerSelector = '.moo-ui[data-bs-theme="light"], .moo-ui[data-bs-theme="dark"]';
-
-function activationOffset(options, previous = 0) {
- if (!options || typeof options !== "object" || Array.isArray(options)) {
- throw new TypeError("TableOfContents options must be an object.");
- }
- const value = options.activationOffset === undefined ? previous : options.activationOffset;
- if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
- throw new TypeError("TableOfContents activationOffset must be a finite nonnegative number.");
- }
- return value;
-}
-
-function fragmentId(href) {
- if (!href?.startsWith("#") || href.length === 1) return null;
- try {
- return decodeURIComponent(href.slice(1));
- } catch {
- return null;
- }
-}
-
-export default class TableOfContents {
- static getInstance(element) {
- return element?.nodeType === 1 ? instances.get(element) || null : null;
- }
-
- static getOrCreateInstance(element, options = {}) {
- return TableOfContents.getInstance(element) || new TableOfContents(element, options);
- }
-
- constructor(element, options = {}) {
- if (element?.nodeType !== 1 || !element.matches("[data-toc]")) {
- throw new TypeError("TableOfContents requires a [data-toc] root element.");
- }
- const existing = instances.get(element);
- if (existing) return existing;
- this._element = element;
- this._document = element.ownerDocument;
- this._window = this._document.defaultView;
- this._offset = activationOffset(options);
- this._listeners = [];
- this._originalLinks = new Map();
- this._originalStatus = new Map();
- this._originalMarker = {
- attribute: element.getAttribute("data-toc-marker"),
- properties: ["--moo-toc-marker-offset", "--moo-toc-marker-height"].map((name) => ({
- name,
- value: element.style.getPropertyValue(name),
- priority: element.style.getPropertyPriority(name),
- })),
- };
- this._links = [];
- this._targets = [];
- this._frame = 0;
- this._disposed = false;
- instances.set(element, this);
- this.refresh();
- }
-
- refresh(options = {}) {
- if (this._disposed) return this;
- const offset = activationOffset(options, this._offset);
- this._clearListeners();
- this._offset = offset;
- const owner = this._element.closest(ownerSelector);
- const contentId = this._element.getAttribute("data-toc-content");
- const scope = contentId ? this._document.getElementById(contentId) : owner;
- const rootId = this._element.getAttribute("data-toc-scroll-root");
- this._scrollElement = rootId ? this._document.getElementById(rootId) : null;
- this._status = Array.from(this._element.querySelectorAll("[data-toc-current]"))
- .find((node) => node.closest("[data-toc]") === this._element) || null;
- if (this._status && !this._originalStatus.has(this._status)) {
- this._originalStatus.set(this._status, this._status.textContent);
- }
- this._overview = this._status ? this._originalStatus.get(this._status) : "";
- this._links = Array.from(this._element.querySelectorAll('a[href^="#"]'))
- .filter((link) => link.closest("[data-toc]") === this._element)
- .map((link) => ({ link, id: fragmentId(link.getAttribute("href")) }));
- this._links.forEach(({ link }) => {
- if (!this._originalLinks.has(link)) {
- this._originalLinks.set(link, {
- active: link.classList.contains("active"),
- current: link.getAttribute("aria-current"),
- });
- }
- });
- this._targets = [];
- this._activate(null);
- if (!owner || !scope || scope.closest(ownerSelector) !== owner ||
- (rootId && (!this._scrollElement || !this._scrollElement.contains(scope)))) {
- return this;
- }
- const seen = new Set();
- this._links.forEach(({ id, link }) => {
- const target = id ? this._document.getElementById(id) : null;
- if (!target || seen.has(id) || !scope.contains(target) || target.closest(ownerSelector) !== owner) return;
- seen.add(id);
- this._targets.push({ id, target, label: link.textContent.trim() });
- });
- if (!this._targets.length) return this;
- const queue = () => this._requestUpdate();
- this._listen(this._scrollElement || this._window, "scroll", queue, { passive: true });
- this._listen(this._window, "resize", queue);
- this._listen(this._window, "hashchange", queue);
- this._listen(this._element, "click", queue);
- this._update();
- return this;
- }
-
- dispose() {
- if (this._disposed) return;
- this._disposed = true;
- this._clearListeners();
- this._originalLinks.forEach(({ active, current }, link) => {
- link.classList.toggle("active", active);
- if (current === null) link.removeAttribute("aria-current");
- else link.setAttribute("aria-current", current);
- });
- this._originalStatus.forEach((text, node) => { node.textContent = text; });
- const { attribute, properties } = this._originalMarker;
- if (attribute === null) this._element.removeAttribute("data-toc-marker");
- else this._element.setAttribute("data-toc-marker", attribute);
- properties.forEach(({ name, value, priority }) => {
- if (value) this._element.style.setProperty(name, value, priority);
- else this._element.style.removeProperty(name);
- });
- this._originalLinks.clear();
- this._originalStatus.clear();
- this._targets = [];
- this._links = [];
- if (instances.get(this._element) === this) instances.delete(this._element);
- }
-
- _listen(target, type, handler, options) {
- target.addEventListener(type, handler, options);
- this._listeners.push({ target, type, handler, options });
- }
-
- _clearListeners() {
- this._listeners.forEach(({ target, type, handler, options }) => target.removeEventListener(type, handler, options));
- this._listeners = [];
- if (this._frame) this._window.cancelAnimationFrame(this._frame);
- this._frame = 0;
- }
-
- _requestUpdate() {
- if (this._disposed || this._frame) return;
- this._frame = this._window.requestAnimationFrame(() => {
- this._frame = 0;
- this._update();
- });
- }
-
- _update() {
- if (this._disposed) return;
- const targets = this._targets.filter(({ target }) => target.isConnected && target.getClientRects().length > 0);
- const scroller = this._scrollElement || this._document.scrollingElement;
- const line = (this._scrollElement ? this._scrollElement.getBoundingClientRect().top + this._scrollElement.clientTop : 0) + this._offset;
- let active = null;
- targets.forEach((entry) => {
- if (entry.target.getBoundingClientRect().top <= line + 1) active = entry;
- });
- const canScroll = scroller && scroller.scrollHeight > scroller.clientHeight + 1;
- if (!canScroll) {
- const hashId = fragmentId(this._window.location.hash);
- active = targets.find(({ id }) => id === hashId) || active;
- }
- if (targets.length && canScroll &&
- scroller.scrollTop + scroller.clientHeight >= scroller.scrollHeight - 1) {
- active = targets[targets.length - 1];
- }
- this._activate(active);
- }
-
- _activate(active) {
- let activeLink = null;
- this._links.forEach(({ link, id }) => {
- const current = active !== null && id === active.id;
- link.classList.toggle("active", current);
- if (current) {
- link.setAttribute("aria-current", "location");
- activeLink ||= link;
- } else link.removeAttribute("aria-current");
- });
- if (this._status) this._status.textContent = active ? active.label : this._overview;
- this._updateMarker(activeLink);
- }
-
- _updateMarker(link) {
- const list = this._element.querySelector(":scope > .nav");
- const text = link?.querySelector("span");
- if (!list?.contains(link) || !text?.offsetHeight || !this._element.getClientRects().length) {
- this._element.removeAttribute("data-toc-marker");
- return;
- }
- this._element.style.setProperty("--moo-toc-marker-offset", `${link.offsetTop + text.offsetTop}px`);
- this._element.style.setProperty("--moo-toc-marker-height", `${text.offsetHeight}px`);
- this._element.setAttribute("data-toc-marker", "");
- }
-}
+export { default } from "./toc.js";
diff --git a/src/js/components/toc.js b/src/js/components/toc.js
new file mode 100644
index 00000000..3782ba8b
--- /dev/null
+++ b/src/js/components/toc.js
@@ -0,0 +1,202 @@
+const instances = new WeakMap();
+const ownerSelector = '.moo-ui[data-bs-theme="light"], .moo-ui[data-bs-theme="dark"]';
+
+function activationOffset(options, previous = 0) {
+ if (!options || typeof options !== "object" || Array.isArray(options)) {
+ throw new TypeError("TableOfContents options must be an object.");
+ }
+ const value = options.activationOffset === undefined ? previous : options.activationOffset;
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
+ throw new TypeError("TableOfContents activationOffset must be a finite nonnegative number.");
+ }
+ return value;
+}
+
+function fragmentId(href) {
+ if (!href?.startsWith("#") || href.length === 1) return null;
+ try {
+ return decodeURIComponent(href.slice(1));
+ } catch {
+ return null;
+ }
+}
+
+export default class TableOfContents {
+ static getInstance(element) {
+ return element?.nodeType === 1 ? instances.get(element) || null : null;
+ }
+
+ static getOrCreateInstance(element, options = {}) {
+ return TableOfContents.getInstance(element) || new TableOfContents(element, options);
+ }
+
+ constructor(element, options = {}) {
+ if (element?.nodeType !== 1 || !element.matches("[data-toc]")) {
+ throw new TypeError("TableOfContents requires a [data-toc] root element.");
+ }
+ const existing = instances.get(element);
+ if (existing) return existing;
+ this._element = element;
+ this._document = element.ownerDocument;
+ this._window = this._document.defaultView;
+ this._offset = activationOffset(options);
+ this._listeners = [];
+ this._originalLinks = new Map();
+ this._originalStatus = new Map();
+ this._originalMarker = {
+ attribute: element.getAttribute("data-toc-marker"),
+ properties: ["--moo-toc-marker-offset", "--moo-toc-marker-height"].map((name) => ({
+ name,
+ value: element.style.getPropertyValue(name),
+ priority: element.style.getPropertyPriority(name),
+ })),
+ };
+ this._links = [];
+ this._targets = [];
+ this._frame = 0;
+ this._disposed = false;
+ instances.set(element, this);
+ this.refresh();
+ }
+
+ refresh(options = {}) {
+ if (this._disposed) return this;
+ const offset = activationOffset(options, this._offset);
+ this._clearListeners();
+ this._offset = offset;
+ const owner = this._element.closest(ownerSelector);
+ const contentId = this._element.getAttribute("data-toc-content");
+ const scope = contentId ? this._document.getElementById(contentId) : owner;
+ const rootId = this._element.getAttribute("data-toc-scroll-root");
+ this._scrollElement = rootId ? this._document.getElementById(rootId) : null;
+ this._status = Array.from(this._element.querySelectorAll("[data-toc-current]"))
+ .find((node) => node.closest("[data-toc]") === this._element) || null;
+ if (this._status && !this._originalStatus.has(this._status)) {
+ this._originalStatus.set(this._status, this._status.textContent);
+ }
+ this._overview = this._status ? this._originalStatus.get(this._status) : "";
+ this._links = Array.from(this._element.querySelectorAll('a[href^="#"]'))
+ .filter((link) => link.closest("[data-toc]") === this._element)
+ .map((link) => ({ link, id: fragmentId(link.getAttribute("href")) }));
+ this._links.forEach(({ link }) => {
+ if (!this._originalLinks.has(link)) {
+ this._originalLinks.set(link, {
+ active: link.classList.contains("active"),
+ current: link.getAttribute("aria-current"),
+ });
+ }
+ });
+ this._targets = [];
+ this._activate(null);
+ if (!owner || !scope || scope.closest(ownerSelector) !== owner ||
+ (rootId && (!this._scrollElement || !this._scrollElement.contains(scope)))) {
+ return this;
+ }
+ const seen = new Set();
+ this._links.forEach(({ id, link }) => {
+ const target = id ? this._document.getElementById(id) : null;
+ if (!target || seen.has(id) || !scope.contains(target) || target.closest(ownerSelector) !== owner) return;
+ seen.add(id);
+ this._targets.push({ id, target, label: link.textContent.trim() });
+ });
+ if (!this._targets.length) return this;
+ const queue = () => this._requestUpdate();
+ this._listen(this._scrollElement || this._window, "scroll", queue, { passive: true });
+ this._listen(this._window, "resize", queue);
+ this._listen(this._window, "hashchange", queue);
+ this._listen(this._element, "click", queue);
+ this._update();
+ return this;
+ }
+
+ dispose() {
+ if (this._disposed) return;
+ this._disposed = true;
+ this._clearListeners();
+ this._originalLinks.forEach(({ active, current }, link) => {
+ link.classList.toggle("active", active);
+ if (current === null) link.removeAttribute("aria-current");
+ else link.setAttribute("aria-current", current);
+ });
+ this._originalStatus.forEach((text, node) => { node.textContent = text; });
+ const { attribute, properties } = this._originalMarker;
+ if (attribute === null) this._element.removeAttribute("data-toc-marker");
+ else this._element.setAttribute("data-toc-marker", attribute);
+ properties.forEach(({ name, value, priority }) => {
+ if (value) this._element.style.setProperty(name, value, priority);
+ else this._element.style.removeProperty(name);
+ });
+ this._originalLinks.clear();
+ this._originalStatus.clear();
+ this._targets = [];
+ this._links = [];
+ if (instances.get(this._element) === this) instances.delete(this._element);
+ }
+
+ _listen(target, type, handler, options) {
+ target.addEventListener(type, handler, options);
+ this._listeners.push({ target, type, handler, options });
+ }
+
+ _clearListeners() {
+ this._listeners.forEach(({ target, type, handler, options }) => target.removeEventListener(type, handler, options));
+ this._listeners = [];
+ if (this._frame) this._window.cancelAnimationFrame(this._frame);
+ this._frame = 0;
+ }
+
+ _requestUpdate() {
+ if (this._disposed || this._frame) return;
+ this._frame = this._window.requestAnimationFrame(() => {
+ this._frame = 0;
+ this._update();
+ });
+ }
+
+ _update() {
+ if (this._disposed) return;
+ const targets = this._targets.filter(({ target }) => target.isConnected && target.getClientRects().length > 0);
+ const scroller = this._scrollElement || this._document.scrollingElement;
+ const line = (this._scrollElement ? this._scrollElement.getBoundingClientRect().top + this._scrollElement.clientTop : 0) + this._offset;
+ let active = null;
+ targets.forEach((entry) => {
+ if (entry.target.getBoundingClientRect().top <= line + 1) active = entry;
+ });
+ const canScroll = scroller && scroller.scrollHeight > scroller.clientHeight + 1;
+ if (!canScroll) {
+ const hashId = fragmentId(this._window.location.hash);
+ active = targets.find(({ id }) => id === hashId) || active;
+ }
+ if (targets.length && canScroll &&
+ scroller.scrollTop + scroller.clientHeight >= scroller.scrollHeight - 1) {
+ active = targets[targets.length - 1];
+ }
+ this._activate(active);
+ }
+
+ _activate(active) {
+ let activeLink = null;
+ this._links.forEach(({ link, id }) => {
+ const current = active !== null && id === active.id;
+ link.classList.toggle("active", current);
+ if (current) {
+ link.setAttribute("aria-current", "location");
+ activeLink ||= link;
+ } else link.removeAttribute("aria-current");
+ });
+ if (this._status) this._status.textContent = active ? active.label : this._overview;
+ this._updateMarker(activeLink);
+ }
+
+ _updateMarker(link) {
+ const list = this._element.querySelector(":scope > .nav");
+ const text = link?.querySelector("span");
+ if (!list?.contains(link) || !text?.offsetHeight || !this._element.getClientRects().length) {
+ this._element.removeAttribute("data-toc-marker");
+ return;
+ }
+ this._element.style.setProperty("--moo-toc-marker-offset", `${link.offsetTop + text.offsetTop}px`);
+ this._element.style.setProperty("--moo-toc-marker-height", `${text.offsetHeight}px`);
+ this._element.setAttribute("data-toc-marker", "");
+ }
+}
diff --git a/src/js/moo-ui.js b/src/js/moo-ui.js
index 40475b21..767a92b4 100644
--- a/src/js/moo-ui.js
+++ b/src/js/moo-ui.js
@@ -7,7 +7,7 @@ import Datepicker, {
} from "./components/datepicker.js";
import Sidebar from "./components/sidebar.js";
import Slider from "./components/slider.js";
-import TableOfContents from "./components/table-of-contents.js";
+import TableOfContents from "./components/toc.js";
import { initSheets } from "./components/sheet.js";
async function loadChart() {
diff --git a/tests/fixtures/boundary-baseline.json b/tests/fixtures/boundary-baseline.json
index 55fed6de..0e481b25 100644
--- a/tests/fixtures/boundary-baseline.json
+++ b/tests/fixtures/boundary-baseline.json
@@ -1,24 +1,25 @@
{
"coreOutputs": {
- "dist/assets/css/moo-ui.css": "d6947a3a27a4315591cf9f6b92e1fd1d958a5fceb1523b709487d54fcbefc815",
- "dist/assets/css/moo-ui.min.css": "e96d6d78ccb119f83aea7bd8e5d16b40bddf4251209f67abebb408f78f0bbcba",
- "dist/assets/css/moo.css": "38bb85c89e2f1f2f043119a9290cb58dd74a1572090b5fc41930c7c57a90c894",
- "dist/assets/css/moo.min.css": "2546a980bc41ef0c941b8c9cd8e65f6349ec37ff72d1506ba0a6ef6eec81f944",
- "dist/js/chart.js": "0c3b2039d4b06993937da243c320cf8fa9fe48e2132935f76073879b0d21ee18",
- "dist/js/chart.min.js": "3395911a9140f50cc5a8026682fea6151245492f421eb8660ec4938c8bbd6c2c",
- "dist/js/combobox.js": "7e749aa39740349f12f95c2811b194a007f088c6c9c578f980c118958e80c07e",
- "dist/js/context-menu.js": "27168c4b1ac42064338ad2746daaa602f22de717259aec5bfcf9d55d8e5d353c",
- "dist/js/datatable.js": "730dfff81863801ede8f54e3810f6fd2219d533b4365ac9e1fb5fec3be9d886d",
- "dist/js/datepicker.js": "570402e7d77598bfeccb5a929c1f4be6615196f287badc79ec13dd8b80300c5b",
- "dist/js/datepicker.min.js": "c6c9057abbe41d774f23374f6c2e9f9f7e346f211ee7b61a8dc9129d056ff90d",
- "dist/js/moo-ui.js": "9c498912d40b8b8a18bd515c5a53cb19f5546f5ab706ec6e8f4447b3f175e869",
- "dist/js/moo-ui.min.js": "1dd4f3bfcc2effddb39b2fce0e00dbc00456aa3dc8a54595c8ce1f3822d064c6",
- "dist/js/sheet.js": "35c31e3252b9510de4747a5a64e77dbec47f4cbb342337be21b75b6f46ff5b6a",
- "dist/js/sidebar.js": "8fbb61af28a04e572c61f7df76d4c72f8048a92661dd9f129d41bcf3795c1bce",
- "dist/js/slider.js": "cd61370895ce3d166aee99cea9772a59f1be4018c7114564e124c82fdf1caa26",
- "dist/js/state.js": "3560c86c8623a3d523ec763456d984e009d8a7fa5834de168b153ba9d242f1c2",
- "dist/js/table-of-contents.js": "b2322ad90148b91b75788e05f492b09065ba61257f934c74b916c1fdc5ce69e1",
- "dist/release-manifest.json": "95ac88143922ba2a4b3f6e42406f0b50d0bf878187c14052d212ff8bb002cede"
+ "dist/assets/css/moo-ui.css": "39f8b612e0307052f250aa1df471f995f2008980e025beee96b8878771ef30d0",
+ "dist/assets/css/moo-ui.min.css": "9ba4af6aaa9394d530a5a43db4b775c2fbb2fce5a6ae9656e69e27a6358bbbb6",
+ "dist/assets/css/moo.css": "c3845a6391648eb2623bb03d6fe7ad37f03c6f481d4e5c9c7e0bb535e5047ae4",
+ "dist/assets/css/moo.min.css": "749a6e4d844bcdda6c449d724c20ed2661633158b83ef8eebf4716c43cd0d522",
+ "dist/js/chart.js": "73cb9136035a23ace9b5e8d832a61eae91edaa5524a53c569020a58937b7d0e3",
+ "dist/js/chart.min.js": "4bca338f3e379feb0fb239ae01469b6f514ad0490d921089a70e64e94035f7c5",
+ "dist/js/combobox.js": "421eea7f0947a64b11566bae5b2ce5ee2d0f5095b6fc8a1f24c56bf9ce11c6f6",
+ "dist/js/context-menu.js": "a76f810e50e8ab7b49ab7388e54c9ff54afe3560b29841c66dbb0191a4deb8d1",
+ "dist/js/datatable.js": "67d8a2f214644bccc1f5259410ff343be16d2b9560645f13e0de1915832200d8",
+ "dist/js/datepicker.js": "ed6c05db926acc46ef0925b90b3d6d9913f55a5b77aba7a5ed2a9939b5172e1c",
+ "dist/js/datepicker.min.js": "d2c74a960b79dae4c99c949aedef1613a086d94f06cf6c0011686df9f9caa845",
+ "dist/js/moo-ui.js": "4cd644ce29a39e0f0a0e35b0cd63993dc42df22cb8a5d05d4d2d9c26f95ed341",
+ "dist/js/moo-ui.min.js": "75944001ed86eb1641524e3915497d54f2c5110629ee49eed9352c589de9562d",
+ "dist/js/sheet.js": "5344b30c652bed676432c6b8b350b04061eeb7f0247c3d61bfc0a71c69402b63",
+ "dist/js/sidebar.js": "afb677b5289215ccfca0238f52a15b5a8869c57fdab427098ce7a26b014c5bbf",
+ "dist/js/slider.js": "209001958ceff89ee780fea0622de68c51861927866b85a121f1d757ef3d6fad",
+ "dist/js/state.js": "3c88bb64406688eb17abadd8b1f52bf096a1760a867d6f3ee9f0a317711f47bd",
+ "dist/js/table-of-contents.js": "89223fd9afd3fd1e6c5765a0ebf003b66833de5dc95b802cd5facc910d773831",
+ "dist/js/toc.js": "ce9ea72a162e3fb69784235a58878e532ef0841de901f000885a8bed689baddd",
+ "dist/release-manifest.json": "05d687ac31e8b207029a0aa4f446d93470d8e300f7034b9131b263a327ff8965"
},
"distFiles": [
"dist/assets/css/moo-ui.css",
@@ -39,6 +40,7 @@
"dist/js/slider.js",
"dist/js/state.js",
"dist/js/table-of-contents.js",
+ "dist/js/toc.js",
"dist/release-manifest.json"
],
"npmPackFiles": [
@@ -64,6 +66,7 @@
"dist/js/slider.js",
"dist/js/state.js",
"dist/js/table-of-contents.js",
+ "dist/js/toc.js",
"dist/release-manifest.json",
"package.json",
"scss/_components.scss",
@@ -171,7 +174,8 @@
"./sidebar.js": "./dist/js/sidebar.js",
"./slider.js": "./dist/js/slider.js",
"./state.js": "./dist/js/state.js",
- "./table-of-contents.js": "./dist/js/table-of-contents.js"
+ "./table-of-contents.js": "./dist/js/table-of-contents.js",
+ "./toc.js": "./dist/js/toc.js"
},
"files": [
"ASSET_LICENSE.md",
@@ -196,6 +200,7 @@
"dist/js/slider.js",
"dist/js/state.js",
"dist/js/table-of-contents.js",
+ "dist/js/toc.js",
"dist/release-manifest.json",
"scss/**/*.scss",
"scss/*.scss"
@@ -207,7 +212,7 @@
"sideEffects": [
"dist/assets/css/*.css"
],
- "version": "1.1.0-dev.1"
+ "version": "1.1.0"
},
"siteDistFiles": [
"site-dist/acceptance/rc2/index.html",
@@ -357,6 +362,7 @@
"site-dist/assets/js/components/sidebar.js",
"site-dist/assets/js/components/slider.js",
"site-dist/assets/js/components/table-of-contents.js",
+ "site-dist/assets/js/components/toc.js",
"site-dist/assets/js/state.js",
"site-dist/assets/js/theme-owner.js",
"site-dist/blocks/index.html",
@@ -366,6 +372,7 @@
"site-dist/blocks/previews/datatable-tasks/index.html",
"site-dist/blocks/previews/sidebar-floating/index.html",
"site-dist/blocks/previews/sidebar-inset/index.html",
+ "site-dist/blocks/previews/toc/index.html",
"site-dist/blocks/sidebar-floating/index.html",
"site-dist/blocks/sidebar-inset/index.html",
"site-dist/changelog/index.html",
@@ -414,6 +421,7 @@
"site-dist/components/tabs/index.html",
"site-dist/components/textarea/index.html",
"site-dist/components/toast/index.html",
+ "site-dist/components/toc/index.html",
"site-dist/components/toggle-group/index.html",
"site-dist/components/tooltip/index.html",
"site-dist/components/typography/index.html",
@@ -436,6 +444,7 @@
"site-dist/dist/js/slider.js",
"site-dist/dist/js/state.js",
"site-dist/dist/js/table-of-contents.js",
+ "site-dist/dist/js/toc.js",
"site-dist/dist/release-manifest.json",
"site-dist/examples/auth/forgot-password/index.html",
"site-dist/examples/auth/sign-in/index.html",
@@ -469,6 +478,7 @@
"site-dist/js/sidebar.js",
"site-dist/js/slider.js",
"site-dist/js/table-of-contents.js",
+ "site-dist/js/toc.js",
"site-dist/layout/index.html",
"site-dist/layouts/previews/app-none/index.html",
"site-dist/layouts/previews/app-sidebar/index.html",
@@ -544,21 +554,21 @@
"site-dist/vendor/bootstrap/dist/js/bootstrap.bundle.min.js.map"
],
"siteOutputs": {
- "site-dist/acceptance/rc2/index.html": "c9cdf1541e1186716644a1c83a5fd237560f84eb7fe8e61c7bc66986e9f8ee17",
- "site-dist/acceptance/rc3/index.html": "d1cd3d122f23b1854fcad8c47a1f7a2d1bfa6cce369dba8f4c5ee7488f7dff79",
- "site-dist/acceptance/rc4/index.html": "e69714edd14a8f475f38899533307624042d937d5db5668a525897549434f7bd",
- "site-dist/acceptance/rc5/index.html": "f0b7deb47cff68f095ab44cba77a208839a60662d10e140aaa9de40e5f08b31c",
- "site-dist/acceptance/rc6/index.html": "6d74e862cfecf2dec758abf22adf214faa77f45133a83785a74097b6a4a0b1bb",
- "site-dist/acceptance/rc7/index.html": "8d5c6211be464284807c03d809703fb2a05a2941f5749eb6abda17a122249466",
+ "site-dist/acceptance/rc2/index.html": "3644e1c7e32228c60ef10425b0a423b318205e230a3cc0f5b6ffa4c4cd110c21",
+ "site-dist/acceptance/rc3/index.html": "07a4a66ce914f55b0f0755d670888f1e9c6b64c79f1103ba0be3e6c091548f17",
+ "site-dist/acceptance/rc4/index.html": "716813f6839c22db44b4b80dff57f7921be81b2e9044bd3e46492aa151668103",
+ "site-dist/acceptance/rc5/index.html": "c6e905a96c6c9457177411c85e16a9264e911f55d845ef226fca4230116d3591",
+ "site-dist/acceptance/rc6/index.html": "749a7c76ee87a16f4d0601c0e79347d8937b60de45cccaf6117f90d4274903eb",
+ "site-dist/acceptance/rc7/index.html": "978f69f1d664999d0ca48181857df1b8ee15de8d0f6a493e4f265fcbcb56d021",
"site-dist/apple-touch-icon.png": "0369a32660a4679bbc8a2da846d38041ecffcea1266e07c7c688936b7f41713e",
"site-dist/assets/css/catalog-state.css": "4563872a77fb4ed697b5fb08213b407a0db897da9e7de5163b6917f3c04494bb",
"site-dist/assets/css/catalog.css": "4bfba3caaf6c675da27501d3275b72a4e9fbbc1659fc2060c72876ac0c852e6e",
"site-dist/assets/css/catalog.min.css": "e7f4cf6b3424714131dd7372a8e8605670e5de6caafdaae47cb8ee6d7fdbfa98",
"site-dist/assets/css/codepen-demo.css": "b6145a590303b6f118616a082471129155324476da22fbbe8f5dcc04844465c6",
- "site-dist/assets/css/moo-ui.css": "d6947a3a27a4315591cf9f6b92e1fd1d958a5fceb1523b709487d54fcbefc815",
- "site-dist/assets/css/moo-ui.min.css": "e96d6d78ccb119f83aea7bd8e5d16b40bddf4251209f67abebb408f78f0bbcba",
- "site-dist/assets/css/moo.css": "38bb85c89e2f1f2f043119a9290cb58dd74a1572090b5fc41930c7c57a90c894",
- "site-dist/assets/css/moo.min.css": "2546a980bc41ef0c941b8c9cd8e65f6349ec37ff72d1506ba0a6ef6eec81f944",
+ "site-dist/assets/css/moo-ui.css": "39f8b612e0307052f250aa1df471f995f2008980e025beee96b8878771ef30d0",
+ "site-dist/assets/css/moo-ui.min.css": "9ba4af6aaa9394d530a5a43db4b775c2fbb2fce5a6ae9656e69e27a6358bbbb6",
+ "site-dist/assets/css/moo.css": "c3845a6391648eb2623bb03d6fe7ad37f03c6f481d4e5c9c7e0bb535e5047ae4",
+ "site-dist/assets/css/moo.min.css": "749a6e4d844bcdda6c449d724c20ed2661633158b83ef8eebf4716c43cd0d522",
"site-dist/assets/fonts/geist/Geist-Variable.woff2": "a369fcf5628ea2aa4e1b9e2ec6a5b3624e365bda588e1f0f2f12b564f728fbb8",
"site-dist/assets/images/README.md": "31903daae7facf88dc4a5114081b42ae56be4b711ebecc9741571cd83b27641d",
"site-dist/assets/images/avatars/bull.webp": "0eb5c3aed8fb08cf10cd94d7beaa1791333de2b6f399b88c780ffb771369b0a1",
@@ -656,7 +666,7 @@
"site-dist/assets/js/bootstrap.bundle.min.js": "0833b2e9c3a26c258476c46266e6877fc75218625162e0460be9a3a098a61c6c",
"site-dist/assets/js/bootstrap.bundle.min.js.map": "5e3e0763164143baaa1ca0706b6100ba0452f911d6ce9713b48e3dbe07b35125",
"site-dist/assets/js/catalog-state.js": "6dc59bc3606d431ee62b38f679b5048b56e5568f72f1ac428f32ce4714878041",
- "site-dist/assets/js/catalog-theme-state.js": "8d80abf4bb224dda0eeb25808b0f56c8fb069b807c161572477ee8103d07753e",
+ "site-dist/assets/js/catalog-theme-state.js": "b923c7f41051c087f52aaff9442e8deff30a9900d5052f6bc8ada595f64a2dac",
"site-dist/assets/js/catalog/acceptance.js": "a4794396548080d0d91b6e038dfbbe4e9e1f16af8a471c57a3a343b7851eca2f",
"site-dist/assets/js/catalog/block-frame.js": "71972d32ae738a99507ca17f931d4fbb74688bd3934aca201c7cc3a60e5a7a72",
"site-dist/assets/js/catalog/bootstrap-preview.js": "b5e7ada504705f7cd31812e819042228504b1dcff5e9048e5efd4b78fffed58d",
@@ -665,155 +675,160 @@
"site-dist/assets/js/catalog/catalog-view-toggle.js": "9212c34f419f1081ddadbcf45713fe343182f16b10e226f18a95fbdca924fc6a",
"site-dist/assets/js/catalog/code-preview.js": "15d06605f6cfb6dde8b729aa44d6460e5ed06fe44aef400c747871236e8b4df0",
"site-dist/assets/js/catalog/command.js": "79e8ddf096512706ee2e81d6453283c60a31cde605789f4716bb0ce01c170f28",
- "site-dist/assets/js/catalog/examples-chart.js": "3112a4c99cca098d93c7ff1c02a1fe8a116a7407b3f2b4ebbc3269198c715a38",
+ "site-dist/assets/js/catalog/examples-chart.js": "f8d25d55998760f410de37da6ee9fab3dcd13eaa72a0551defc3a9669c5e8f14",
"site-dist/assets/js/catalog/examples-forms.js": "7b3b408fa559336d4b7c8c077a161099f9f8bef1deecb44752b7d0b4e7098768",
- "site-dist/assets/js/catalog/examples-tasks.js": "39ff4ae4b15d02510ab871862b931fe0d9e24c0e2f7c64b48c8fd84df9f4f180",
- "site-dist/assets/js/catalog/examples-users.js": "922ad51762acbc528a60c8ecc76d9dfd12d80fdba3dfd7d528a4bdbb488a4687",
+ "site-dist/assets/js/catalog/examples-tasks.js": "433891c4ad941fddc33bca7ba2edc37771a15ea8a503570ba972e3e951aaeeac",
+ "site-dist/assets/js/catalog/examples-users.js": "ddd2423d2304b4f5f285c515e3a81204e460f55fb7c9f2e0c29109a4ecb4432c",
"site-dist/assets/js/catalog/home-motion.js": "cfb6747563aee16049a71adff6f51c42eeafd9795db785f0dc537b423b234679",
- "site-dist/assets/js/catalog/index.js": "a1b62300bd36b4120918769dcdba82f0e5990d561ba9253d58493641d0ac485a",
+ "site-dist/assets/js/catalog/index.js": "9cb2874b5a773d542d29677a333f4f9704ce39854762ae39a34bad07299c8401",
"site-dist/assets/js/catalog/scroll-host.js": "905723ccf4fb885a84e9f5919137725d2a4c8c9ccc215369c2520edd2ae42f8d",
"site-dist/assets/js/catalog/settings-panel.js": "5ae2f3ae84cabd19b42f3dbaf6338a2fa776bf102d1c2ca58644404e4b64f4e0",
"site-dist/assets/js/catalog/theme-builder-export.js": "a6713d278217a81300b61806d4e5bd84ee0cd99314b68f561c03071b89dfe5cc",
"site-dist/assets/js/catalog/theme-builder-schema.js": "c9b33dddc9d5ffab96b075dc1d68087a7055e020a66e44305462a3c6c7e9db57",
"site-dist/assets/js/catalog/theme.js": "a961a18b6aa6f64a4b6ee39af041fe763bfc1176fad82c9cd344c7ff0d29f8ed",
- "site-dist/assets/js/catalog/toc.js": "c6d6900f8a22cc1e9270dfabd414efcc61bd932ef158fdac650d0fb7535c2787",
+ "site-dist/assets/js/catalog/toc.js": "b6c13014e454f42ec0b1360a12fd166eda230a2b89a74785a2c616b9d05f0d7b",
"site-dist/assets/js/codepen-demo.js": "61cc63865e1d072a01125ea0b6ce1be0cc9067d166e0e218526a97de1b752bd2",
- "site-dist/assets/js/components/chart.js": "0c3b2039d4b06993937da243c320cf8fa9fe48e2132935f76073879b0d21ee18",
- "site-dist/assets/js/components/chart.min.js": "3395911a9140f50cc5a8026682fea6151245492f421eb8660ec4938c8bbd6c2c",
- "site-dist/assets/js/components/combobox.js": "7e749aa39740349f12f95c2811b194a007f088c6c9c578f980c118958e80c07e",
- "site-dist/assets/js/components/context-menu.js": "27168c4b1ac42064338ad2746daaa602f22de717259aec5bfcf9d55d8e5d353c",
- "site-dist/assets/js/components/datatable.js": "730dfff81863801ede8f54e3810f6fd2219d533b4365ac9e1fb5fec3be9d886d",
- "site-dist/assets/js/components/datepicker.js": "570402e7d77598bfeccb5a929c1f4be6615196f287badc79ec13dd8b80300c5b",
- "site-dist/assets/js/components/datepicker.min.js": "c6c9057abbe41d774f23374f6c2e9f9f7e346f211ee7b61a8dc9129d056ff90d",
- "site-dist/assets/js/components/moo-ui.js": "9c498912d40b8b8a18bd515c5a53cb19f5546f5ab706ec6e8f4447b3f175e869",
- "site-dist/assets/js/components/moo-ui.min.js": "1dd4f3bfcc2effddb39b2fce0e00dbc00456aa3dc8a54595c8ce1f3822d064c6",
- "site-dist/assets/js/components/sheet.js": "35c31e3252b9510de4747a5a64e77dbec47f4cbb342337be21b75b6f46ff5b6a",
- "site-dist/assets/js/components/sidebar.js": "8fbb61af28a04e572c61f7df76d4c72f8048a92661dd9f129d41bcf3795c1bce",
- "site-dist/assets/js/components/slider.js": "cd61370895ce3d166aee99cea9772a59f1be4018c7114564e124c82fdf1caa26",
- "site-dist/assets/js/components/table-of-contents.js": "b2322ad90148b91b75788e05f492b09065ba61257f934c74b916c1fdc5ce69e1",
- "site-dist/assets/js/state.js": "3560c86c8623a3d523ec763456d984e009d8a7fa5834de168b153ba9d242f1c2",
+ "site-dist/assets/js/components/chart.js": "73cb9136035a23ace9b5e8d832a61eae91edaa5524a53c569020a58937b7d0e3",
+ "site-dist/assets/js/components/chart.min.js": "4bca338f3e379feb0fb239ae01469b6f514ad0490d921089a70e64e94035f7c5",
+ "site-dist/assets/js/components/combobox.js": "421eea7f0947a64b11566bae5b2ce5ee2d0f5095b6fc8a1f24c56bf9ce11c6f6",
+ "site-dist/assets/js/components/context-menu.js": "a76f810e50e8ab7b49ab7388e54c9ff54afe3560b29841c66dbb0191a4deb8d1",
+ "site-dist/assets/js/components/datatable.js": "67d8a2f214644bccc1f5259410ff343be16d2b9560645f13e0de1915832200d8",
+ "site-dist/assets/js/components/datepicker.js": "ed6c05db926acc46ef0925b90b3d6d9913f55a5b77aba7a5ed2a9939b5172e1c",
+ "site-dist/assets/js/components/datepicker.min.js": "d2c74a960b79dae4c99c949aedef1613a086d94f06cf6c0011686df9f9caa845",
+ "site-dist/assets/js/components/moo-ui.js": "4cd644ce29a39e0f0a0e35b0cd63993dc42df22cb8a5d05d4d2d9c26f95ed341",
+ "site-dist/assets/js/components/moo-ui.min.js": "75944001ed86eb1641524e3915497d54f2c5110629ee49eed9352c589de9562d",
+ "site-dist/assets/js/components/sheet.js": "5344b30c652bed676432c6b8b350b04061eeb7f0247c3d61bfc0a71c69402b63",
+ "site-dist/assets/js/components/sidebar.js": "afb677b5289215ccfca0238f52a15b5a8869c57fdab427098ce7a26b014c5bbf",
+ "site-dist/assets/js/components/slider.js": "209001958ceff89ee780fea0622de68c51861927866b85a121f1d757ef3d6fad",
+ "site-dist/assets/js/components/table-of-contents.js": "89223fd9afd3fd1e6c5765a0ebf003b66833de5dc95b802cd5facc910d773831",
+ "site-dist/assets/js/components/toc.js": "ce9ea72a162e3fb69784235a58878e532ef0841de901f000885a8bed689baddd",
+ "site-dist/assets/js/state.js": "3c88bb64406688eb17abadd8b1f52bf096a1760a867d6f3ee9f0a317711f47bd",
"site-dist/assets/js/theme-owner.js": "7b7e9ca121536a8a8b5d0b596d1ceb14384b8bae195160e05e50e97a5da35b8c",
- "site-dist/blocks/index.html": "3e12aac71f9bd84d0f135fafb91f3f43728e5dc853ed7b6614cc9d1b2b82b78e",
- "site-dist/blocks/previews/datatable-release-review-responsive/index.html": "957a0fc7e3b5f0d2916260d8db7be08964c9c66aa6166fb463bd55f9c28d8802",
- "site-dist/blocks/previews/datatable-release-review-toggle/index.html": "a9f933a8be6771ab5f3cfabfdd2cb3c5b270be1fc4c8769f9026032e8be60da1",
- "site-dist/blocks/previews/datatable-release-review/index.html": "8338fe8128fad18a719efe1d0a24e03a6049916b8a6b7d1913b79b707d32affd",
- "site-dist/blocks/previews/datatable-tasks/index.html": "b776256181fe70898d004798f262509dfca6843471a904ab13a16ec5aad1ed04",
- "site-dist/blocks/previews/sidebar-floating/index.html": "83225b84734ed16cbe8e2be988804f7355e9943355fd07ffb4b084a33ba62dbf",
- "site-dist/blocks/previews/sidebar-inset/index.html": "c603a097e825f81b50cb5e97e665716d33094249f976aefb7ca92448e9d4540b",
- "site-dist/blocks/sidebar-floating/index.html": "72eeaedd362f04726902777119c023407be2c203f46199854f7e41722e25718c",
- "site-dist/blocks/sidebar-inset/index.html": "8bb4fa31d7459abba1674433d8c1693b10ec5f7811ef3b04ae55c5826c258620",
- "site-dist/changelog/index.html": "f6763b91bf7506a91ec96fdb4692b3f5270a10c2b50ed11686dfcf4a35cffc62",
- "site-dist/charts/index.html": "41dddf970ed0044943c54d1692d82586238f5b68b6058e1410ca586a599c1c89",
- "site-dist/components/accordion/index.html": "ebfbaca04a7ce021e9c76d98249b1d24be5cab80a5cdd5d6f7225502afa42c38",
- "site-dist/components/alert-dialog/index.html": "4cf8751398d6edcb016df9a914db99510d45f71c06344e185aa3af23db925551",
- "site-dist/components/alert/index.html": "a3f9c1ff83a593191b1a26465024e645ecc13d35515c0bd3edb32d324962318f",
- "site-dist/components/avatar/index.html": "d716a54d1877b6628a833c1cd9a8ed7716bfb9c566af1ac809a428105bea4e25",
- "site-dist/components/badge/index.html": "96ea5599b04f65519e27fb6b951badb4c5b478b84598dd8cf74c9c5baac2071f",
- "site-dist/components/breadcrumb/index.html": "7f98a05ab9c3ae31605b58160d170bc24e81372af42e8b5ea80a552bf32bccb2",
- "site-dist/components/button-group/index.html": "4e66de404c44b6f596910fa3f5ccdad2fbbe256ebc5ff352b8e641d1bdd2576c",
- "site-dist/components/button/index.html": "b1c4b1ae6b670fb8af3b43443fff00a97dc0a951395cba0e58b301e204a1ac33",
- "site-dist/components/card/index.html": "bea68d5879363047179442dc43757fb0511fe59c19a442a1bc810e0d7ee46ea2",
- "site-dist/components/chart/index.html": "e458306effd4ee23df4fc77edf72f83dd4a122b4076af960e7005df51e3edfcb",
- "site-dist/components/checkbox/index.html": "f393c68341f563b7339debf37df03e7a91560c8e3d4a9f1d6361f982fa8b08a7",
- "site-dist/components/close-button/index.html": "709a6fc41feab5297d56fb16f87f059008c82cb847d0805615c0879087059698",
- "site-dist/components/collapsible/index.html": "b3077168b89fbf8345410edcea83ed007f9f2e423f85bef10608726ed0044603",
- "site-dist/components/combobox/index.html": "64f43873864b9d657790d274405d6ab1994a3f4dfc99eda54a30b1cc8d3fe7e3",
- "site-dist/components/context-menu/index.html": "62dddcc6835e548b5b1ee500089f9e4ef516d61e7f30add211f1486dce711e1d",
- "site-dist/components/datatable/index.html": "e4217160977fa278b99c35a57cfc5e55861a8606e007158a9fe12e06c80a95ef",
- "site-dist/components/datepicker/index.html": "ae06bdf8ec1d4bd16d8087c467b3c80dcc41b39fa89416967449f30b1bc8f86b",
- "site-dist/components/dialog/index.html": "ed9fc02652dcc2038a906399ff1a8038e4672e27c108ea6bfa82f0977ee4ece0",
- "site-dist/components/dropdown-menu/index.html": "00cc2a93edbcc8035ab6f5a4eca6d7b04efcc0fc7af06c2e8d738c9f36592a97",
- "site-dist/components/field/index.html": "d6017eec2c64ee5fda8e99494842734e1fb94e705b54cdd9a291ad928e019d8b",
- "site-dist/components/form/index.html": "7df5336704fa85a5f53046254e5b3edf35cef36d63b21f83e43a729ce7d6ce7e",
- "site-dist/components/index.html": "83b98407127f39354508c398768eb6412870796bcdc44c5a4713062d6827186a",
- "site-dist/components/input-group/index.html": "c2db02d1ce0ec06a4f15f2b7dd042feb8e8a9a626cbab8d27f30b5b6085ba8db",
- "site-dist/components/input/index.html": "d296c8a67fddefc23584e5e45b6459b729bd46feb5e53769d7e712533f92f333",
- "site-dist/components/kbd/index.html": "71de9de725d80d9e6248839b6ce3f81950d85676ee24427542683229c71cf93d",
- "site-dist/components/menubar/index.html": "fdf6675f65acfbf78f2a7f8087007daad2d36e9976aa13c307262f38d731ddd6",
- "site-dist/components/navigation/index.html": "dd44b5c3e81ffa34c62c40474b4ce199df6b7cd4cbb6893f84b9f833c44abe73",
- "site-dist/components/pagination/index.html": "1b0555daa76059aea942d40ccbf4655bd6f685ce370f68057f71dead103f9939",
- "site-dist/components/popover/index.html": "c25b1afc37fa6b2824944559c65fbd7c7ed4a21f89c1e9cdfef2196c4f008b61",
- "site-dist/components/progress/index.html": "5aca411452d7b488846b3250d5c3fea9c9b420579ae94850a7fc5b1338a6dc9c",
- "site-dist/components/radio-group/index.html": "be22f8cbf9425e49c6523e82980c57cf6acdb6513670a21554ca3718fa1ef51e",
- "site-dist/components/select/index.html": "42ba643037ff38b91aa38587d59edb5af3a2f1490908a32e803922ea324d906d",
- "site-dist/components/separator/index.html": "e8385912ea13fcc6553607217fab8e64e4d32e8edec10c726cc0eda88887cc15",
- "site-dist/components/sheet/index.html": "36099d158ecbd37953e8393a4ceca2e053d73f2179f1dfe893cee4ee8b489ec1",
- "site-dist/components/sidebar/index.html": "e7c606191cae7cde245ee123f2618f89559944d5bdf7ee02217aa69dff7b71f3",
- "site-dist/components/skeleton/index.html": "bd59f93d2174e2f1c516deb0b5ee0089540501db1a9ecdb20db30d514c93fa9c",
- "site-dist/components/slider/index.html": "5befbe48b57951a952bbe3bc7da357589072a8a8ad8b5eb476c9a8ec006f555b",
- "site-dist/components/spinner/index.html": "fd12194b7048229afd96db112bd7dec278ae25718dedb247792bbaf8b5f423c4",
- "site-dist/components/switch/index.html": "f1010ccc94f4e7ea729f69dc96bc636548036dd950926d1e26113378088d23e0",
- "site-dist/components/table-of-contents/index.html": "9147f8c7042360d1e04214f5b5da1d2c78191fe0ed990e3616001d1c6546fed4",
- "site-dist/components/table/index.html": "dc0e1aaf76025d68f29b0945cf9b88ed399fe7b4159add3f711fe25fa946e214",
- "site-dist/components/tabs/index.html": "66a3778645391b2cfc51912e71663d37d4fbc08eaabb96e7f75bbffef0f2e4ae",
- "site-dist/components/textarea/index.html": "a6aa8d7b3486821c33d65f00fc253a88378a3c96e9631948974477182f2fd5d3",
- "site-dist/components/toast/index.html": "0ce40b7bd30f720a061f277106ebc46c5c1d032c4dedcab82c980e791b6ed232",
- "site-dist/components/toggle-group/index.html": "46b9be79dfcc9ca2504561489e189a91c7af6393586eb09275299c9e9513bfbe",
- "site-dist/components/tooltip/index.html": "743f4535ff44cebb5fbef845a586473c105fa2e76e0caf558d64ea1b86549def",
- "site-dist/components/typography/index.html": "efc6853144ffe1cef65cf94f9c3569225ae8237a6fbee863237ce4658addf667",
- "site-dist/contributing/index.html": "c7dd26f30a0bf5a8a1c885a39199185496231a827c54e7160a856c37131fd099",
- "site-dist/dist/assets/css/moo-ui.css": "d6947a3a27a4315591cf9f6b92e1fd1d958a5fceb1523b709487d54fcbefc815",
- "site-dist/dist/assets/css/moo-ui.min.css": "e96d6d78ccb119f83aea7bd8e5d16b40bddf4251209f67abebb408f78f0bbcba",
- "site-dist/dist/assets/css/moo.css": "38bb85c89e2f1f2f043119a9290cb58dd74a1572090b5fc41930c7c57a90c894",
- "site-dist/dist/assets/css/moo.min.css": "2546a980bc41ef0c941b8c9cd8e65f6349ec37ff72d1506ba0a6ef6eec81f944",
- "site-dist/dist/js/chart.js": "0c3b2039d4b06993937da243c320cf8fa9fe48e2132935f76073879b0d21ee18",
- "site-dist/dist/js/chart.min.js": "3395911a9140f50cc5a8026682fea6151245492f421eb8660ec4938c8bbd6c2c",
- "site-dist/dist/js/combobox.js": "7e749aa39740349f12f95c2811b194a007f088c6c9c578f980c118958e80c07e",
- "site-dist/dist/js/context-menu.js": "27168c4b1ac42064338ad2746daaa602f22de717259aec5bfcf9d55d8e5d353c",
- "site-dist/dist/js/datatable.js": "730dfff81863801ede8f54e3810f6fd2219d533b4365ac9e1fb5fec3be9d886d",
- "site-dist/dist/js/datepicker.js": "570402e7d77598bfeccb5a929c1f4be6615196f287badc79ec13dd8b80300c5b",
- "site-dist/dist/js/datepicker.min.js": "c6c9057abbe41d774f23374f6c2e9f9f7e346f211ee7b61a8dc9129d056ff90d",
- "site-dist/dist/js/moo-ui.js": "9c498912d40b8b8a18bd515c5a53cb19f5546f5ab706ec6e8f4447b3f175e869",
- "site-dist/dist/js/moo-ui.min.js": "1dd4f3bfcc2effddb39b2fce0e00dbc00456aa3dc8a54595c8ce1f3822d064c6",
- "site-dist/dist/js/sheet.js": "35c31e3252b9510de4747a5a64e77dbec47f4cbb342337be21b75b6f46ff5b6a",
- "site-dist/dist/js/sidebar.js": "8fbb61af28a04e572c61f7df76d4c72f8048a92661dd9f129d41bcf3795c1bce",
- "site-dist/dist/js/slider.js": "cd61370895ce3d166aee99cea9772a59f1be4018c7114564e124c82fdf1caa26",
- "site-dist/dist/js/state.js": "3560c86c8623a3d523ec763456d984e009d8a7fa5834de168b153ba9d242f1c2",
- "site-dist/dist/js/table-of-contents.js": "b2322ad90148b91b75788e05f492b09065ba61257f934c74b916c1fdc5ce69e1",
- "site-dist/dist/release-manifest.json": "95ac88143922ba2a4b3f6e42406f0b50d0bf878187c14052d212ff8bb002cede",
- "site-dist/examples/auth/forgot-password/index.html": "fee080f01acdd6d58e9511486c4dad49a4ed25aa58c6820d42824c3c4cdc2156",
- "site-dist/examples/auth/sign-in/index.html": "404649ea20fe4820fb653f32062e10010659fb33e3eda8715cab9a092b189579",
- "site-dist/examples/auth/sign-up/index.html": "523b549753851b82b94a6a5715518a845f6a9a480cb45dcddb4e49e3bc5432ab",
- "site-dist/examples/dashboard/overview/index.html": "9e534197d9e7082eb50ee1591f2b39cf19cc11c4c6e3f3fa31e1028cfc9d00a6",
- "site-dist/examples/dashboard/tasks/index.html": "bc77b425ec140040072b5c4236e07eec4cd54ea5a4e3883f5a6d86a5139251e8",
- "site-dist/examples/dashboard/users/index.html": "74ea36b20eec5eed041ea003039c38d5443393f8b5950fc30a3e3340f985a5bb",
- "site-dist/examples/index.html": "1c2c8a07a6cef0dbb0718fd3933e2fac5284ec473bc59ca23e143b7cde9663cb",
- "site-dist/examples/marketing/faq/index.html": "02e73419d34798da55f9e7547b0c8b60bfc5cfeec718f883b3b252992265d979",
- "site-dist/examples/marketing/pricing/index.html": "56e5ba16a590536aca03393ed1d3e22fd1b42471b4a41088f58bc39300a0da2f",
- "site-dist/examples/settings/account/index.html": "eaeacd17daef9afa94986de653ae1dca166b82f7f0e013883eaebe5e5cd72b68",
- "site-dist/examples/settings/appearance/index.html": "7a406397804387c2314456dd6ecc90477b21181a1685c270e57871e5ae0bb0c8",
- "site-dist/examples/settings/profile/index.html": "03f6f1dbb7d7ee67682dab3f52ce363a2cad32c49a13a36c8e3c45b08ae9dcb7",
+ "site-dist/blocks/index.html": "8b2fa2076233fd0f56341cdd3724f415d7ca645d1c5d3521b2499cbf90191f4b",
+ "site-dist/blocks/previews/datatable-release-review-responsive/index.html": "caf0ac6c0e22044d45ddd77d55d567dc42b87eb64916c7a0d788b783e7883c04",
+ "site-dist/blocks/previews/datatable-release-review-toggle/index.html": "666c454a451ff7802c692edf10bb3338301eb5283810ff9f83fb4f66f798ceec",
+ "site-dist/blocks/previews/datatable-release-review/index.html": "db00e6714ceb8797d3a1b02fb6d283b0b38ae7059fc5285ff3838afe8a5adc18",
+ "site-dist/blocks/previews/datatable-tasks/index.html": "81a767603ef6d4a31c028748a421d82ade34c9a3bf9f72c8591c858d4bef65d7",
+ "site-dist/blocks/previews/sidebar-floating/index.html": "846e36a71962e246fea740ed979653365e9a0a9c614a35e890e5dae6d07db2de",
+ "site-dist/blocks/previews/sidebar-inset/index.html": "a8997ab70f75d307fa1cfc99a17fc6c11bcf4d0957d68958170e44a53229f86c",
+ "site-dist/blocks/previews/toc/index.html": "1905933e1381153fe95280102e38540c8c9f8f39a3683b5fc06d7bb6b706d606",
+ "site-dist/blocks/sidebar-floating/index.html": "cbf7973faedff7534b7e93cde5f904d26a7b36c697b6129f01d0411c9f3afda6",
+ "site-dist/blocks/sidebar-inset/index.html": "ea5afb51a77923e6655ee4c4697969929fa40e8a9696210b33d775e6dc66fae4",
+ "site-dist/changelog/index.html": "f7a1dfe9319f6dcdffe6b372968e88a0c10a0ce3cc363b4d7395457bdbf0ac56",
+ "site-dist/charts/index.html": "5528b76215c27a1569e238f8231c9486403c79ac7202853af20ec5a5d82bb612",
+ "site-dist/components/accordion/index.html": "3fa15e5619d26e4ce69d12c7130b683b9eee034635a2058a2ac0a1b5f8f7eb20",
+ "site-dist/components/alert-dialog/index.html": "41782f1748db3180bbf8978bedb05bec765b2d832ec8d2ab409eb2cee83aa56a",
+ "site-dist/components/alert/index.html": "abd960052bd83a567b6f578f0c2ab0ae2405b4430bc8956b041f2a728eaf5622",
+ "site-dist/components/avatar/index.html": "04de2988fc33382096bf6187c2cdca624be8a70a098cd6ac2bce830ec4ebb2f7",
+ "site-dist/components/badge/index.html": "b551804a1620042893a01476a98ac2ab5c267809d07b6e110e50ed776dc46219",
+ "site-dist/components/breadcrumb/index.html": "72aa16392c6fd1320e4499d59a1b29d61fb9cc714c0c17356310195055a8ee35",
+ "site-dist/components/button-group/index.html": "237503dc983f5fd53b5b665b9ec6233e04e7b3419495efc77f7e1c3b5487d827",
+ "site-dist/components/button/index.html": "1c2bf8995b80970f420f487147a1db2511b5d008bd96c4fa9f265de4a2f241b7",
+ "site-dist/components/card/index.html": "823f38f3ad6952070d363db00f50f44ad18e8a08884b7da3ba2d239fe64d78dd",
+ "site-dist/components/chart/index.html": "5e90af1895d3ef587102dcce6b285fafc0665d632044abd6a7a5c9ce80adcb41",
+ "site-dist/components/checkbox/index.html": "f04ffc83c85df165e651629aeca2a6d55b4254168b5ade080394f5c7c270d375",
+ "site-dist/components/close-button/index.html": "4b79061139590d85ea196c9736de175e7f729cabc70fe57f8ce7eb73d8d21bb5",
+ "site-dist/components/collapsible/index.html": "b490ba43e5c716fa059b3b1ba54d1d256462ac82069351eef2a261d5e5a63ddb",
+ "site-dist/components/combobox/index.html": "08a5dfd8200c664eda33bacefb09884987387560c80f5022b272aa79009cb91a",
+ "site-dist/components/context-menu/index.html": "032c6645a910cdcbf5bb23e7b42e23c8245e5c0922abac8cbd6f7bcc8c2752d9",
+ "site-dist/components/datatable/index.html": "db8bad81e2730553b5847302e6138ef5aab614451f2e31a617e59a380cf726a8",
+ "site-dist/components/datepicker/index.html": "ae8ba49347297701a8831437c1122822a3fb9f706934abb157843f12ac40d26b",
+ "site-dist/components/dialog/index.html": "d4de64f6fd6e8da42135d2abf8661369cc406036b5b59fa123f2d459e36c2179",
+ "site-dist/components/dropdown-menu/index.html": "193f9056251a3158c9bb20624ee943edb9d2c6cb0526a2db149c5953f9dba757",
+ "site-dist/components/field/index.html": "bb0432e236761c7dd32cfd061fedee37d53c193738ab25db24cac1a7e0256363",
+ "site-dist/components/form/index.html": "1b9a3b16e533b610baeb997b0fe0c816b997fa2faa479a5a0a6af8be9a89c59f",
+ "site-dist/components/index.html": "129c925dc66420b5538806e915430bb52a54bf1413e4d8ee9435033eddfbe793",
+ "site-dist/components/input-group/index.html": "9793e6eea7a0f7680ef9cf779771ebd0175e826bf7e9b168263ad4ce966d6c43",
+ "site-dist/components/input/index.html": "4fd2053aaee4461074397156c8d28de3d5ebb7c7f1b7824d09b7ce64388f507e",
+ "site-dist/components/kbd/index.html": "3a6bfe48bf06c169746b2e29f25b41664f9f09bb80334ae4b7109208bbcd1f27",
+ "site-dist/components/menubar/index.html": "2e78b459526716547a7ddb56f2b60d85065e2942b2bda47025fa1b5b6e5c2dd5",
+ "site-dist/components/navigation/index.html": "e93fe4e1485be5c58a89ae656cdcff616dffc8ca00e4666f5345ee2c8f94b221",
+ "site-dist/components/pagination/index.html": "f73aa6019142cccec0ca3250cfdfefdd3116c0bf865b6f41774fa2f057fcec4b",
+ "site-dist/components/popover/index.html": "0b0526707240060563d28fc823b775004b0c1634a0eab82fa6418185d01fb326",
+ "site-dist/components/progress/index.html": "9e541cfc1708ae89bd1c3ddc6fc32db6b3af312bc9ed27852d6220eeb0143544",
+ "site-dist/components/radio-group/index.html": "c24d5944829d2a973eeb35167198b800177e0f1a1a5f87435c545f2be23cac95",
+ "site-dist/components/select/index.html": "5d5e0029e4fa0fb3fe9bc8749107f3191b78a54571d379739f8da46ab9f5175e",
+ "site-dist/components/separator/index.html": "36f8ae3b096b496e10461cc63014fe3cd8ae1ea6ff6abce38b68d812a2b16f81",
+ "site-dist/components/sheet/index.html": "0d45c7633f59e9957411078f2f29154df66a8e42b1e3b9a3502853b6e2b19b00",
+ "site-dist/components/sidebar/index.html": "4e4cdc708c1f356a07314b1290a93bd296a827583b7fa6e1523643da1bc5df44",
+ "site-dist/components/skeleton/index.html": "a62995f19454227b21a2cedee957b6621e61337c0b02d1ed442248e29975ac70",
+ "site-dist/components/slider/index.html": "9a839866592287b479285beea3006d87e1421c8cfd96667f4b40c81217e6126d",
+ "site-dist/components/spinner/index.html": "1595ce29b6b36d4aa961d7f06976479dd1561732855fa6f7442df91f716b0db0",
+ "site-dist/components/switch/index.html": "6a2b6f77bba2dcff57a45dbc5c9dc50152a31dc6d91f28bbcbde516bba38c80a",
+ "site-dist/components/table-of-contents/index.html": "502173a93a04caa61444b3ca98b98965dbe32bc44dc6f0e3170a3e554f396bb7",
+ "site-dist/components/table/index.html": "fe3fedc8c20d474e7fbca4924462e0439e8312bc0a38356a26f5498d425669d3",
+ "site-dist/components/tabs/index.html": "73a4c6fb7985fef7c8c644f575b8adc562205088732190d066e6af47acf70413",
+ "site-dist/components/textarea/index.html": "a09b2acb027656d1737dcc0067225e62eb6ce6e1a8e0879f1822978ea7b35b8c",
+ "site-dist/components/toast/index.html": "b5dd2a7aca77553207285a18db0bf7b1cfe934ce33fcf59948cd33c8697dda53",
+ "site-dist/components/toc/index.html": "502173a93a04caa61444b3ca98b98965dbe32bc44dc6f0e3170a3e554f396bb7",
+ "site-dist/components/toggle-group/index.html": "6f09011f8496755f3b92e9f4ec7231a78d5339c8270027bb429a3d34a35bd46e",
+ "site-dist/components/tooltip/index.html": "05834c3ab2c66da9cc819ff69f925f2c005a34688c2a6daccdf4fa397b4f4508",
+ "site-dist/components/typography/index.html": "b227d11a0e417a40c2c97716030c389d5ea8406c21da50904f2a2595c3b4d80e",
+ "site-dist/contributing/index.html": "f89132820e87a45bdbbbade88719272ecf5979c9e76deed269dbfc880da798cb",
+ "site-dist/dist/assets/css/moo-ui.css": "39f8b612e0307052f250aa1df471f995f2008980e025beee96b8878771ef30d0",
+ "site-dist/dist/assets/css/moo-ui.min.css": "9ba4af6aaa9394d530a5a43db4b775c2fbb2fce5a6ae9656e69e27a6358bbbb6",
+ "site-dist/dist/assets/css/moo.css": "c3845a6391648eb2623bb03d6fe7ad37f03c6f481d4e5c9c7e0bb535e5047ae4",
+ "site-dist/dist/assets/css/moo.min.css": "749a6e4d844bcdda6c449d724c20ed2661633158b83ef8eebf4716c43cd0d522",
+ "site-dist/dist/js/chart.js": "73cb9136035a23ace9b5e8d832a61eae91edaa5524a53c569020a58937b7d0e3",
+ "site-dist/dist/js/chart.min.js": "4bca338f3e379feb0fb239ae01469b6f514ad0490d921089a70e64e94035f7c5",
+ "site-dist/dist/js/combobox.js": "421eea7f0947a64b11566bae5b2ce5ee2d0f5095b6fc8a1f24c56bf9ce11c6f6",
+ "site-dist/dist/js/context-menu.js": "a76f810e50e8ab7b49ab7388e54c9ff54afe3560b29841c66dbb0191a4deb8d1",
+ "site-dist/dist/js/datatable.js": "67d8a2f214644bccc1f5259410ff343be16d2b9560645f13e0de1915832200d8",
+ "site-dist/dist/js/datepicker.js": "ed6c05db926acc46ef0925b90b3d6d9913f55a5b77aba7a5ed2a9939b5172e1c",
+ "site-dist/dist/js/datepicker.min.js": "d2c74a960b79dae4c99c949aedef1613a086d94f06cf6c0011686df9f9caa845",
+ "site-dist/dist/js/moo-ui.js": "4cd644ce29a39e0f0a0e35b0cd63993dc42df22cb8a5d05d4d2d9c26f95ed341",
+ "site-dist/dist/js/moo-ui.min.js": "75944001ed86eb1641524e3915497d54f2c5110629ee49eed9352c589de9562d",
+ "site-dist/dist/js/sheet.js": "5344b30c652bed676432c6b8b350b04061eeb7f0247c3d61bfc0a71c69402b63",
+ "site-dist/dist/js/sidebar.js": "afb677b5289215ccfca0238f52a15b5a8869c57fdab427098ce7a26b014c5bbf",
+ "site-dist/dist/js/slider.js": "209001958ceff89ee780fea0622de68c51861927866b85a121f1d757ef3d6fad",
+ "site-dist/dist/js/state.js": "3c88bb64406688eb17abadd8b1f52bf096a1760a867d6f3ee9f0a317711f47bd",
+ "site-dist/dist/js/table-of-contents.js": "89223fd9afd3fd1e6c5765a0ebf003b66833de5dc95b802cd5facc910d773831",
+ "site-dist/dist/js/toc.js": "ce9ea72a162e3fb69784235a58878e532ef0841de901f000885a8bed689baddd",
+ "site-dist/dist/release-manifest.json": "05d687ac31e8b207029a0aa4f446d93470d8e300f7034b9131b263a327ff8965",
+ "site-dist/examples/auth/forgot-password/index.html": "5fd6ee87570a83740f441aecfc7712e031407d58e2c7118ec8ddc81f164c0daa",
+ "site-dist/examples/auth/sign-in/index.html": "91625778cc4f73c16e5273b51397a0e5e511a09df3b180076efb7a3a05d4660f",
+ "site-dist/examples/auth/sign-up/index.html": "71b39a3fc0ff9a037a97d6b5587838a2b3977a4e3e2171b1f1db9f3500ec165c",
+ "site-dist/examples/dashboard/overview/index.html": "e788423767d6d89ba1ae1e81fa34384d712b10d8c18230962f3eb7a7b9be3489",
+ "site-dist/examples/dashboard/tasks/index.html": "8ef4627ae7a4a98aae9d1eefc44167bba57b538324224c5785cea438e170a6ae",
+ "site-dist/examples/dashboard/users/index.html": "2fee6abae835b119e38e283c0efca8b4c38d852e2c7f389e62a2d6efc79a0c3f",
+ "site-dist/examples/index.html": "7a7336007b828c23342900ceda04e7d8ee239be3600bc857b9f62fdc5a615ed0",
+ "site-dist/examples/marketing/faq/index.html": "1486c3f131761403a2577de59a05ad992aa9e834eeb85deb8d37e90d6e0ae736",
+ "site-dist/examples/marketing/pricing/index.html": "9487542fb43fbaa413d4dbb9563c2bd51237ff2c9d71250274060a6b6f3a5a04",
+ "site-dist/examples/settings/account/index.html": "29b07eb21ea5a7340376c241b961eb01935fbd5f7ec6e5cc6895abe7cc2377b1",
+ "site-dist/examples/settings/appearance/index.html": "8751525fb57962dff067ed36cdea235b4992b65a7b58c9f39e648e331524a774",
+ "site-dist/examples/settings/profile/index.html": "615875b9700563c34c4a5719557865fec37d290a3bb9b06ccd5eeb76ac29d31d",
"site-dist/favicon.ico": "cb05ca1ff03f045852a46a2be53f931a76618323c8de2ed26bb03dd4b07c9893",
"site-dist/favicon.svg": "faf1d513e3c7cdd2c17ee5fc2db6667fb7f99313562c6218cb8e2395aec0dc39",
"site-dist/icon-192.png": "681080a5b14510b267344f67c6c0384a87480e6e919ad5d4003190d56c10050b",
"site-dist/icon-512.png": "0f9e72886c967ba2a2e83bc68be51ce14a0967d641ec1f176ff850a1d9b91dec",
- "site-dist/index.html": "237d341bc8400bfc78f69894167cee9ae3a0790d646a31342256751ac5406bf8",
- "site-dist/installation/index.html": "28a5da36b4742b8c7f41e03e16105e685d5286cd876e7705bd8830082d7e74fe",
- "site-dist/introduction/index.html": "8618bf45a2dcd6b88a4d9b7c8a74e01f59695887c8ea3168c95a368657fdf2d8",
- "site-dist/js/chart.js": "0c3b2039d4b06993937da243c320cf8fa9fe48e2132935f76073879b0d21ee18",
- "site-dist/js/chart.min.js": "3395911a9140f50cc5a8026682fea6151245492f421eb8660ec4938c8bbd6c2c",
- "site-dist/js/combobox.js": "7e749aa39740349f12f95c2811b194a007f088c6c9c578f980c118958e80c07e",
- "site-dist/js/context-menu.js": "27168c4b1ac42064338ad2746daaa602f22de717259aec5bfcf9d55d8e5d353c",
- "site-dist/js/datatable.js": "730dfff81863801ede8f54e3810f6fd2219d533b4365ac9e1fb5fec3be9d886d",
- "site-dist/js/datepicker.js": "570402e7d77598bfeccb5a929c1f4be6615196f287badc79ec13dd8b80300c5b",
- "site-dist/js/datepicker.min.js": "c6c9057abbe41d774f23374f6c2e9f9f7e346f211ee7b61a8dc9129d056ff90d",
- "site-dist/js/moo-ui.js": "9c498912d40b8b8a18bd515c5a53cb19f5546f5ab706ec6e8f4447b3f175e869",
- "site-dist/js/moo-ui.min.js": "1dd4f3bfcc2effddb39b2fce0e00dbc00456aa3dc8a54595c8ce1f3822d064c6",
- "site-dist/js/sheet.js": "35c31e3252b9510de4747a5a64e77dbec47f4cbb342337be21b75b6f46ff5b6a",
- "site-dist/js/sidebar.js": "8fbb61af28a04e572c61f7df76d4c72f8048a92661dd9f129d41bcf3795c1bce",
- "site-dist/js/slider.js": "cd61370895ce3d166aee99cea9772a59f1be4018c7114564e124c82fdf1caa26",
- "site-dist/js/table-of-contents.js": "b2322ad90148b91b75788e05f492b09065ba61257f934c74b916c1fdc5ce69e1",
- "site-dist/layout/index.html": "780889537fdc8738548bc5e03c11ebaf61ab64c06edc1531d7ed734d29f39e41",
- "site-dist/layouts/previews/app-none/index.html": "c1a96a6790a06f3d1820f5f78f4f78dd2cf298bc3ea6bcd78fe5eee793a61b72",
- "site-dist/layouts/previews/app-sidebar/index.html": "af56d5b93d8af7addf781104994ac13fe9522b464cdceb52d5ee8a0ec451c538",
- "site-dist/layouts/previews/page/index.html": "1f6866b99e0cf2702f9554ee884c9b11015df9321a41cbf6e4cc63856262478b",
- "site-dist/license/index.html": "277efdd1637b4c25174dd67d46b01efddd9f3f39cab66cf46b014c49b234e80c",
- "site-dist/llms.txt": "d7f26db58c899611c2b04343c090645026f5a322bd236e27a61b1d68b71e4819",
+ "site-dist/index.html": "3eb71230ed9dee5187a4f81faa38704d806b65a225f6bc222125d63a311875d7",
+ "site-dist/installation/index.html": "1d8684958a2a2cd062021be39f3e399f3cc0328c854e9dadda4b68d417f00378",
+ "site-dist/introduction/index.html": "62110886f43c79f00f1700e7e4700e144721ac2456f998775999456d075b61f1",
+ "site-dist/js/chart.js": "73cb9136035a23ace9b5e8d832a61eae91edaa5524a53c569020a58937b7d0e3",
+ "site-dist/js/chart.min.js": "4bca338f3e379feb0fb239ae01469b6f514ad0490d921089a70e64e94035f7c5",
+ "site-dist/js/combobox.js": "421eea7f0947a64b11566bae5b2ce5ee2d0f5095b6fc8a1f24c56bf9ce11c6f6",
+ "site-dist/js/context-menu.js": "a76f810e50e8ab7b49ab7388e54c9ff54afe3560b29841c66dbb0191a4deb8d1",
+ "site-dist/js/datatable.js": "67d8a2f214644bccc1f5259410ff343be16d2b9560645f13e0de1915832200d8",
+ "site-dist/js/datepicker.js": "ed6c05db926acc46ef0925b90b3d6d9913f55a5b77aba7a5ed2a9939b5172e1c",
+ "site-dist/js/datepicker.min.js": "d2c74a960b79dae4c99c949aedef1613a086d94f06cf6c0011686df9f9caa845",
+ "site-dist/js/moo-ui.js": "4cd644ce29a39e0f0a0e35b0cd63993dc42df22cb8a5d05d4d2d9c26f95ed341",
+ "site-dist/js/moo-ui.min.js": "75944001ed86eb1641524e3915497d54f2c5110629ee49eed9352c589de9562d",
+ "site-dist/js/sheet.js": "5344b30c652bed676432c6b8b350b04061eeb7f0247c3d61bfc0a71c69402b63",
+ "site-dist/js/sidebar.js": "afb677b5289215ccfca0238f52a15b5a8869c57fdab427098ce7a26b014c5bbf",
+ "site-dist/js/slider.js": "209001958ceff89ee780fea0622de68c51861927866b85a121f1d757ef3d6fad",
+ "site-dist/js/table-of-contents.js": "89223fd9afd3fd1e6c5765a0ebf003b66833de5dc95b802cd5facc910d773831",
+ "site-dist/js/toc.js": "ce9ea72a162e3fb69784235a58878e532ef0841de901f000885a8bed689baddd",
+ "site-dist/layout/index.html": "9b0e810c6f96796d11f4a97476ea487dfc5016f4133a740dc11c7f6fdc18a35c",
+ "site-dist/layouts/previews/app-none/index.html": "23d94a74c42e24d676266edd95e04f2c99be0ac9cb0d081f92f9240e38af17b6",
+ "site-dist/layouts/previews/app-sidebar/index.html": "13b2f70cbbfed844918267e25d7fd5891badb13cf09a74cfae06eb95a1ada9bc",
+ "site-dist/layouts/previews/page/index.html": "de25669ee2310656e448bd83598e9d4b232639c414679b5268d2180d9eb0ed9e",
+ "site-dist/license/index.html": "66bb0eb234eef9b0f7806815114475d167eff402afef3e4ea5a5cb0ffe556cc8",
+ "site-dist/llms.txt": "e5084e4e5c10a5a96ce5d3b4bb284852203cdb4f2cb2c441f28868f584f56d64",
"site-dist/robots.txt": "bf13521a8ca29a68a5ba125d21c65b84b1679a0aae915a9fd08794d1dc6d9fbf",
"site-dist/site.webmanifest": "af971266a10396df62c991d9e1f4b86be68d7d2bb248b83386a7ba7f1820fbde",
- "site-dist/sitemap.xml": "ebb2e72c1806e2951d65bae9f04add6922c3873405c50e1e1e3b01f942b57f56",
- "site-dist/skills/index.html": "35f204b3c3d02d1a0a47f926225d6a4ab96888dea8787f072834ce25668cfc29",
- "site-dist/support/index.html": "9c446a0cf2c0d7e0dc01c6c54294d02afb2186232d936929cbbf0673d9048e28",
+ "site-dist/sitemap.xml": "8595f67bb7b24e43463a9ba5c3610185044cbeb707006f30d2a044108660d79b",
+ "site-dist/skills/index.html": "39dde4fc94aa1fbd8f031d8ce44d80fc38716b16d9010a63588aa54025c88c07",
+ "site-dist/support/index.html": "30ce92abebc3b304a6a24caa96ed6d2d52acdd1bfd8164f26504ccc0e8935bcf",
"site-dist/tests/fixtures/certification/accordion.html": "44b3319ff9e4ff52ae742d4bd31a5adeeaa790317f1ef2e856fa9c687d582896",
"site-dist/tests/fixtures/certification/alert-dialog.html": "fcaa0b7d0c62cd2c56601a6b7d10d6a58a2f537bcdd6e93b8b1802167191c51e",
"site-dist/tests/fixtures/certification/alert.html": "de8ac00fe4f60c3b691e8599a87da3c6b417a69b01030566f476b2f8c413e778",
@@ -871,9 +886,9 @@
"site-dist/tests/fixtures/certification/toggle-group.html": "b7043e803a085f8b79eedff7774e6c47296a71498a871027a41181be93aca131",
"site-dist/tests/fixtures/certification/tooltip.html": "c3b799391ba952efa243ee62ec42ff186dd2b6928a3dcb7944cc6541cf92fb3a",
"site-dist/tests/fixtures/certification/typography.html": "999180358adbe189113f7c9338478056701683cafd6a6dd609b45637d3d534d6",
- "site-dist/utils/border/index.html": "3ddb32978a0d164c389062b69b2e9c2efa295e8ec6c64297dbbe3944b06d0522",
- "site-dist/utils/index.html": "57d870f74d2ccd0b1987c97d30e9e6dbb0298cc69d8bb54c8d9467e78b07c180",
- "site-dist/utils/scroll-fade/index.html": "4ae471c5f849299e0ebc5bc4d0db356d4e957ce061056cc3e57387128d0bf5e7",
+ "site-dist/utils/border/index.html": "e808372cede7cbca91c30a4f339afcb5a556e31981338c51184c9203d109ed0e",
+ "site-dist/utils/index.html": "15553e3f284dd9184474e63fa8750a7ddd64533d6c2101dab069d079366de999",
+ "site-dist/utils/scroll-fade/index.html": "c4685757988a61d15ea76c636a349ee90bfecd8d5d0e55464960b0e62d2603e5",
"site-dist/vendor/bootstrap/dist/js/bootstrap.bundle.min.js": "0833b2e9c3a26c258476c46266e6877fc75218625162e0460be9a3a098a61c6c",
"site-dist/vendor/bootstrap/dist/js/bootstrap.bundle.min.js.map": "5e3e0763164143baaa1ca0706b6100ba0452f911d6ce9713b48e3dbe07b35125"
}
diff --git a/tests/fixtures/moo-core-baseline.sha256 b/tests/fixtures/moo-core-baseline.sha256
index 5142d32d..7aed38d0 100644
--- a/tests/fixtures/moo-core-baseline.sha256
+++ b/tests/fixtures/moo-core-baseline.sha256
@@ -1 +1 @@
-38dae5b4de52040bfe01083c37cb9bb07aacd06ff75c342cb7ef93568386d243
+6619afad2948af875d4d35685dd6b9d069ed76aaf6e68f4b50f6a6293e55182a
diff --git a/tests/fixtures/moo-ui-baseline.sha256 b/tests/fixtures/moo-ui-baseline.sha256
index c1a208d8..c7470d9c 100644
--- a/tests/fixtures/moo-ui-baseline.sha256
+++ b/tests/fixtures/moo-ui-baseline.sha256
@@ -1 +1 @@
-fe98f06b700ab2b9a65b173c24372e3fe98a6a9597d8285256cc0bbb93089a01
+439f87271747381f41f58c45d1db14101040159fcbdbd66e254beabdfa6ed8fa
diff --git a/tests/test_catalog.py b/tests/test_catalog.py
index 7734e568..3ba93ef9 100644
--- a/tests/test_catalog.py
+++ b/tests/test_catalog.py
@@ -1507,7 +1507,7 @@ def test_llms_txt_lists_ready_components_alphabetically(self) -> None:
(ROOT / "src/registry/components.json").read_text(encoding="utf-8")
)
expected = [
- f"- [{item['label']}](https://ui.wpmoo.org/components/{item['slug']}/)"
+ f"- [{item['label']}]({site_build.canonical_url('components/' + item['slug'] + '.html')})"
for item in sorted(
(item for item in catalog if item["status"] == "ready"),
key=lambda item: item["label"].casefold(),
@@ -3105,13 +3105,13 @@ def test_examples_catalog_pages_use_shell_footer_for_demo_meta(self) -> None:
preview_link, learn_more = popover_content_parser.links
self.assertEqual(
preview_link.get("href"),
- f"https://ui.wpmoo.org/components/{slug}/",
+ site_build.canonical_url(f"components/{slug}.html"),
)
self.assertEqual(preview_link.get("target"), "_blank")
self.assertEqual(preview_link.get("rel"), "noopener noreferrer")
self.assertEqual(
learn_more.get("href"),
- f"https://ui.wpmoo.org/components/{slug}/",
+ site_build.canonical_url(f"components/{slug}.html"),
)
self.assertEqual(learn_more.get("target"), "_blank")
self.assertEqual(learn_more.get("rel"), "noopener noreferrer")
@@ -3245,11 +3245,11 @@ def test_auth_example_component_references_use_popovers(self) -> None:
preview_link, learn_more = popover_content_parser.links
self.assertEqual(
preview_link.get("href"),
- f"https://ui.wpmoo.org/components/{slug}/",
+ site_build.canonical_url(f"components/{slug}.html"),
)
self.assertEqual(
learn_more.get("href"),
- f"https://ui.wpmoo.org/components/{slug}/",
+ site_build.canonical_url(f"components/{slug}.html"),
)
def test_compact_doc_toc_reuses_curated_labels_and_native_fragments(self) -> None:
@@ -3274,6 +3274,18 @@ def test_catalog_toc_rejects_unsupported_presentations(self) -> None:
with self.assertRaisesRegex(ValueError, "Unknown catalog TOC presentation"):
template.render()
+ def test_toc_routes_resolve_to_the_short_canonical_address(self) -> None:
+ for route in (
+ "components/table-of-contents.html",
+ "components/table-of-contents/",
+ "components/table-of-contents/index.html",
+ "components/toc.html",
+ "components/toc/",
+ ):
+ with self.subTest(route=route):
+ self.assertEqual(site_build.site_href(route), "components/toc/")
+ self.assertEqual(site_build.canonical_url(route), "https://ui.wpmoo.org/components/toc/")
+
def test_primary_docs_render_a_right_side_table_of_contents(self) -> None:
result = self.run_build()
@@ -4034,7 +4046,7 @@ def test_registered_components_have_pages_and_ownership_classification(self) ->
(ROOT / "site/src/pages/components" / f"{slug}.html.jinja").is_file()
)
self.assertTrue((DIST / "components" / slug / "index.html").is_file())
- self.assertIn(f'href="../components/{slug}/"', components_index)
+ self.assertIn(f'href="{site_build.site_href("components/" + slug + ".html", "../")}"', components_index)
self.assertIn(component["label"], components_index)
if slug == "datatable":
self.assertIn(component["description"], components_index)
diff --git a/tests/test_catalog_browser.py b/tests/test_catalog_browser.py
index 673ec6e9..b902317b 100644
--- a/tests/test_catalog_browser.py
+++ b/tests/test_catalog_browser.py
@@ -40,6 +40,39 @@ def setUpClass(cls) -> None:
cls.browser = launch_certification_browser(cls.playwright)
cls.addClassCleanup(cls.browser.close)
+ def test_toc_document_preview_keeps_fragment_navigation_inside_its_frame(self) -> None:
+ context = self.browser.new_context(viewport={"width": 1540, "height": 1314})
+ self.addCleanup(context.close)
+ page = context.new_page()
+ evidence = BrowserEvidence(page)
+ page.goto(f"{self.base_url}/site-dist/components/toc/index.html")
+ frame = page.frame_locator('iframe[data-moo-block-frame]')
+ expect(frame.locator('#demo-toc-list')).to_be_visible()
+ expect(frame.locator('#demo-toc-compact')).to_be_hidden()
+ expect(page.locator('iframe[data-moo-block-frame]')).to_have_count(1)
+ before = page.evaluate("() => ({url:location.href, y:scrollY, main:document.getElementById('main-content').scrollTop})")
+ for label, target in [('Languages', 'languages'), ('Navigation', 'navigation'), ('Introduction', 'introduction')]:
+ frame.locator('#demo-toc-list').get_by_role('link', name=label, exact=True).click()
+ expect(frame.locator(f'#demo-toc-list a[href="#{target}"]')).to_have_attribute('aria-current', 'location')
+ after = page.evaluate("() => ({url:location.href, y:scrollY, main:document.getElementById('main-content').scrollTop})")
+ self.assertEqual(after, before)
+ for label, width in [('Tablet', 768), ('Mobile', 390), ('Desktop', 1280)]:
+ page.get_by_role('button', name=f'{label} preview', exact=True).click()
+ expect(page.locator('iframe[data-moo-block-frame]')).to_have_attribute('width', str(width))
+ if width < 992:
+ expect(frame.locator('#demo-toc-list')).to_be_hidden()
+ expect(frame.locator('#demo-toc-compact')).to_be_visible()
+ frame.locator('#demo-toc-compact').get_by_role('button', name='On this page').click()
+ frame.locator('#demo-toc-compact').get_by_role('link', name='Languages', exact=True).click()
+ expect(frame.locator('#demo-toc-compact [data-toc-current]')).to_have_text('Languages')
+ expect(frame.locator('#demo-toc-compact .dropdown-menu')).to_be_hidden()
+ else:
+ expect(frame.locator('#demo-toc-list')).to_be_visible()
+ expect(frame.locator('#demo-toc-compact')).to_be_hidden()
+ after = page.evaluate("() => ({url:location.href, y:scrollY, main:document.getElementById('main-content').scrollTop})")
+ self.assertEqual(after, before)
+ evidence.assert_clean()
+
def test_external_state_restores_the_first_content_frame_and_sidebar_reload(self) -> None:
for case in CERTIFICATION_CASES:
with self.subTest(case=case.name):
diff --git a/tests/test_certification_contract.py b/tests/test_certification_contract.py
index 8c69680f..6f22132b 100644
--- a/tests/test_certification_contract.py
+++ b/tests/test_certification_contract.py
@@ -1177,6 +1177,34 @@ def test_rc11_api_freeze_remains_a_historical_removal_guard(self) -> None:
self.assertTrue(set(freeze["packageExports"]).issubset(package["exports"]))
self.assertTrue(set(freeze["packageFiles"]).issubset(package["files"]))
+ def test_1_1_api_freeze_preserves_the_released_toc_surface(self) -> None:
+ freeze = self._read_json("src/certification/api-freeze-1.1.0.json")
+ package = self._read_json("package.json")
+ self.assertEqual(freeze["freezeVersion"], "1.1.0")
+ self.assertEqual(freeze["freezeVersion"], package["version"])
+ self.assertEqual(set(freeze["packageExports"]), set(package["exports"]))
+ self.assertEqual(set(freeze["packageFiles"]), set(package["files"]))
+ aggregate = next(record for record in freeze["esmModules"] if record["module"] == "moo-ui.js")
+ self.assertIn("TableOfContents", aggregate["namedExports"])
+ toc = next(record for record in freeze["esmModules"] if record["module"] == "table-of-contents.js")
+ self.assertEqual(toc["export"], "./table-of-contents.js")
+ self.assertEqual(
+ toc["lifecycle"],
+ ["constructor", "getInstance", "getOrCreateInstance", "refresh", "dispose"],
+ )
+ imported = subprocess.run(
+ [
+ "node", "--input-type=module", "--eval",
+ 'import Toc from "./src/js/components/table-of-contents.js"; '
+ + 'const instance = Object.getOwnPropertyNames(Toc.prototype).filter(key => !key.startsWith("_")); '
+ + 'const statics = ["getInstance", "getOrCreateInstance"].filter(key => typeof Toc[key] === "function"); '
+ + 'process.stdout.write(JSON.stringify([...instance, ...statics]));',
+ ],
+ cwd=ROOT, capture_output=True, text=True, check=False, env=npm_env(),
+ )
+ self.assertEqual(imported.returncode, 0, imported.stderr)
+ self.assertTrue(set(toc["lifecycle"]).issubset(set(json.loads(imported.stdout))))
+
def test_stable_api_freeze_matches_current_package_and_runtime_exports(self) -> None:
"""The unchanged 1.0.0 inventory remains a removal guard for additive development."""
self.assertTrue((CERTIFICATION_ROOT / "api-freeze-1.0.0.json").is_file())
diff --git a/tests/test_code_examples.py b/tests/test_code_examples.py
index 7293f144..dc5f2b63 100644
--- a/tests/test_code_examples.py
+++ b/tests/test_code_examples.py
@@ -615,10 +615,12 @@ def test_render_component_intro_centralizes_hero_and_usage_layout(self) -> None:
self.assertIn('aria-labelledby="usage"', template)
self.assertIn('
Usage
', template)
- # These pages own bespoke intro layouts instead of the shared
- # render_component_intro surface. Removing an entry means the page
- # adopted the shared macro.
- excluded_component_intro_pages = {"chart", "datatable", "sidebar"}
+ # These pages use framed block previews or chart-specific layouts
+ # instead of the shared render_component_intro surface. Removing an
+ # entry means the page adopted the component intro macro.
+ excluded_component_intro_pages = {
+ "chart", "datatable", "sidebar", "table-of-contents",
+ }
catalog = json.loads(
(ROOT / "src/registry/components.json").read_text(encoding="utf-8")
)
diff --git a/tests/test_core_docs_boundary.py b/tests/test_core_docs_boundary.py
index f87fb46b..200a9a07 100644
--- a/tests/test_core_docs_boundary.py
+++ b/tests/test_core_docs_boundary.py
@@ -30,6 +30,7 @@
"dist/js/sidebar.js",
"dist/js/slider.js",
"dist/js/sheet.js",
+ "dist/js/toc.js",
"dist/js/table-of-contents.js",
"dist/js/moo-ui.js",
"dist/js/moo-ui.min.js",
@@ -164,6 +165,7 @@ def test_package_and_site_outputs_are_separate(self) -> None:
"js/sidebar.js",
"js/slider.js",
"js/sheet.js",
+ "js/toc.js",
"js/table-of-contents.js",
"js/moo-ui.js",
"js/moo-ui.min.js",
@@ -453,7 +455,7 @@ def test_public_asset_prose_uses_site_static_source_path(self) -> None:
def test_public_policy_docs_track_current_release_line(self) -> None:
package = json.loads((ROOT / "package.json").read_text(encoding="utf-8"))
- self.assertEqual(package["version"], "1.1.0-dev.1")
+ self.assertEqual(package["version"], "1.1.0")
published_version = package["version"]
if "-dev." in published_version:
freeze = json.loads((ROOT / "src/certification/api-freeze-1.0.0.json").read_text(encoding="utf-8"))
diff --git a/tests/test_package.py b/tests/test_package.py
index d4efc33d..20c1c4be 100644
--- a/tests/test_package.py
+++ b/tests/test_package.py
@@ -104,6 +104,7 @@
"dist/js/datatable.js",
"dist/js/slider.js",
"dist/js/sheet.js",
+ "dist/js/toc.js",
"dist/js/table-of-contents.js",
"dist/js/moo-ui.js",
"dist/js/moo-ui.min.js",
@@ -131,6 +132,7 @@
"./datatable.js": "./dist/js/datatable.js",
"./slider.js": "./dist/js/slider.js",
"./sheet.js": "./dist/js/sheet.js",
+ "./toc.js": "./dist/js/toc.js",
"./table-of-contents.js": "./dist/js/table-of-contents.js",
"./moo-ui.js": "./dist/js/moo-ui.js",
"./moo-ui.min.js": "./dist/js/moo-ui.min.js",
@@ -254,7 +256,7 @@ def test_root_package_publishes_canonical_wpmoo_scope(self) -> None:
def test_stable_package_declares_the_state_artifact_surface(self) -> None:
package = self._read_package()
- self.assertEqual(package["version"], "1.1.0-dev.1")
+ self.assertEqual(package["version"], "1.1.0")
self.assertEqual(
package["exports"]["./state.js"],
"./dist/js/state.js",
@@ -480,6 +482,7 @@ def test_public_component_module_surface_is_explicit(self) -> None:
"datatable.js",
"slider.js",
"sheet.js",
+ "toc.js",
"table-of-contents.js",
"chart.js",
"datepicker.js",
@@ -670,6 +673,8 @@ def test_real_tarball_resolves_from_a_clean_consumer(self) -> None:
import ContextMenu from "@wpmoo/ui/context-menu.js";
import DataTable from "@wpmoo/ui/datatable.js";
import Slider from "@wpmoo/ui/slider.js";
+import Toc from "@wpmoo/ui/toc.js";
+import LegacyToc from "@wpmoo/ui/table-of-contents.js";
import { initSheets } from "@wpmoo/ui/sheet.js";
import MooUI, {
loadChart as AggregateLoadChart,
@@ -702,6 +707,8 @@ def test_real_tarball_resolves_from_a_clean_consumer(self) -> None:
ContextMenu.name !== "ContextMenu" ||
DataTable.name !== "DataTable" ||
Slider.name !== "MooSlider" ||
+ Toc !== LegacyToc ||
+ typeof Toc.getOrCreateInstance !== "function" ||
typeof AggregateCombobox.getOrCreateInstance !== "function" ||
typeof AggregateSidebar.getOrCreateInstance !== "function" ||
typeof AggregateContextMenu.getOrCreateInstance !== "function" ||
@@ -939,6 +946,8 @@ def test_component_module_imports_have_no_document_side_effect(self) -> None:
"datatable.js",
"sheet.js",
"slider.js",
+ "toc.js",
+ "table-of-contents.js",
"src/js/moo-ui.js",
"chart.js",
"datepicker.js",
diff --git a/tests/test_table_of_contents.py b/tests/test_table_of_contents.py
index ec7cfbd1..d02dced8 100644
--- a/tests/test_table_of_contents.py
+++ b/tests/test_table_of_contents.py
@@ -1,6 +1,8 @@
from __future__ import annotations
+import subprocess
import unittest
+from pathlib import Path
from markupsafe import Markup
@@ -8,6 +10,19 @@
class TableOfContentsTests(unittest.TestCase):
+ def test_short_runtime_entrypoint_preserves_the_existing_constructor(self) -> None:
+ result = subprocess.run(
+ [
+ "node", "--input-type=module", "--eval",
+ 'import Toc from "./src/js/components/toc.js"; '
+ + 'import Legacy from "./src/js/components/table-of-contents.js"; '
+ + 'process.stdout.write(JSON.stringify(Toc === Legacy));',
+ ],
+ cwd=Path(__file__).resolve().parents[1], capture_output=True, text=True,
+ )
+ self.assertEqual(result.returncode, 0, result.stderr)
+ self.assertEqual(result.stdout, "true")
+
def render_toc(self, **props: object) -> str:
options = {
"id": "page-toc",