انتقل إلى المحتوى
uiify

Table of contents

تنقل موجز بين العناوين، مع تكبير عند التحويم وتتبّع الموضع أثناء التمرير.

المتصفحات
Chrome 123+Firefox 121+Safari 17.5+
الفئة
2
الحجم المضغوط
4.14 kB
ميزانية التخطيط القسري
0 ms
ميزانية axe
0
متوافق مع SSR
نعم
العقد المنشور
بيئة الاختبار

المختبر

Overview

A table of contents gives readers a quick map of a long page. Follow a heading to jump directly to its section, or keep reading and let the current position update as you scroll.

Installation

Import the client entry to enable scroll tracking and pointer interaction. The native button and heading links are already usable before the page finishes loading.

Configuration

Match every line and link to a unique heading ID. Choose a scroll container and a content boundary when the article lives inside another page.

Examples

Hover a line to see its heading in the contents list. Click the line to jump there. On a touch screen, open the list and select the heading you want to read.

Accessibility

The contents are ordinary navigation links. Use the keyboard to open the list, move through its headings, and dismiss it with Escape. Scrolling never moves keyboard focus.

Styling

Adjust line length, spacing and the panel width with CSS variables. The current section uses bolder text; the heading under the pointer gets a separate hover background.

Conclusion

The same component works beside a document or inside a reader. Its compact rail stays available while the article scrolls, without taking a separate content column.

import { TableOfContents } from "@gunkin/uiify/components/table-of-contents/client";

const sections = ["Overview", "Installation", "Configuration", "Examples", "Accessibility", "Styling", "Conclusion"];
export default function Example() {
  return (
    <div className="toc-reader" id="toc-reader" tabIndex={0} role="region" aria-label="Example article">
      <TableOfContents.Root
        className=""
        aria-label="Contents"
        scrollTarget="toc-reader"
        contentTarget="toc-article"
        offset={24}
      >
        <TableOfContents.Trigger target="toc-panel" aria-label="Contents">
          <TableOfContents.Rail>
            {sections.map((label, index) => (
              <TableOfContents.Indicator key={label} value={`toc-section-${index}`} />
            ))}
          </TableOfContents.Rail>
        </TableOfContents.Trigger>
        <TableOfContents.Content id="toc-panel" side="right" align="center">
          <TableOfContents.List>
            {sections.map((label, index) => (
              <TableOfContents.Link key={label} href={`#toc-section-${index}`}>
                {label}
              </TableOfContents.Link>
            ))}
          </TableOfContents.List>
        </TableOfContents.Content>
      </TableOfContents.Root>
      <article id="toc-article">
        {sections.map((label, index) => (
          <section id={`toc-section-${index}`} key={label}>
            <h2>{label}</h2>
            <p>Read this section, or choose another heading from the contents.</p>
          </section>
        ))}
      </article>
    </div>
  );
}
@layer components {
  [data-uiify-table-of-contents] {
    --uiify-toc-line-size: 12px;
    --uiify-toc-line-max-size: 48px;
    --uiify-toc-line-thickness: 2px;
    --uiify-toc-row-size: 20px;
    --uiify-toc-magnify-radius: 2.5;
    --uiify-toc-indent: 1rem;
    --uiify-toc-panel-size: 18rem;
    --uiify-toc-duration: 140ms;

    color: var(--foreground);
  }
  [data-uiify-table-of-contents] [data-part="trigger"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-inline-size: 44px;
    min-block-size: 44px;
    padding: 0.75rem;
    border: 0;
    border-radius: var(--radius-2);
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: pointer;
  }
  [data-uiify-table-of-contents] [data-part="rail"] {
    display: grid;
    grid-auto-rows: var(--uiify-toc-row-size);
    align-items: center;
    inline-size: var(--uiify-toc-line-max-size);
    max-block-size: calc(100dvb - 8rem);
    overflow: auto;
  }
  [data-uiify-table-of-contents] [data-part="indicator"] {
    display: block;

    --uiify-toc-distance: max(
      calc(var(--uiify-toc-index, 0) - var(--uiify-toc-pointer, -1000)),
      calc(var(--uiify-toc-pointer, -1000) - var(--uiify-toc-index, 0))
    );
    --uiify-toc-proximity: clamp(
      0,
      calc(1 - var(--uiify-toc-distance) / max(0.001, var(--uiify-toc-magnify-radius))),
      1
    );

    inline-size: calc(
      var(--uiify-toc-line-size) + (var(--uiify-toc-line-max-size) - var(--uiify-toc-line-size)) *
        var(--uiify-toc-proximity)
    );
    transition:
      inline-size var(--uiify-toc-duration) ease,
      opacity var(--uiify-toc-duration) ease;
    block-size: var(--uiify-toc-line-thickness);
    border-radius: var(--radius-full);
    background: var(--muted-foreground);
    opacity: 0.5;
  }
  [data-uiify-table-of-contents] [data-part="indicator"][data-selected] {
    background: var(--foreground);
    opacity: 1;
  }
  [data-uiify-table-of-contents] [data-part="indicator"][data-highlighted]:not([data-selected]) {
    background: var(--primary);
    opacity: 1;
  }
  [data-uiify-table-of-contents] [data-part="content"] {
    --uiify-anchor-offset: 0;

    inline-size: min(var(--uiify-toc-panel-size), calc(100dvi - 2rem));
    max-block-size: calc(100dvb - 2rem);
    overflow: auto;
    overscroll-behavior: contain;
    padding: 0.5rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-3);
    background: var(--popover);
    color: var(--popover-foreground);
  }
  [data-uiify-table-of-contents] [data-part="list"] {
    display: grid;
  }
  [data-uiify-table-of-contents] [data-part="link"] {
    display: block;
    padding-block: 0.625rem;
    padding-inline: calc(0.75rem + max(0, var(--uiify-toc-level, 2) - 2) * var(--uiify-toc-indent))
      0.75rem;
    border-radius: var(--radius-2);
    color: var(--muted-foreground);
    text-decoration: none;
    overflow-wrap: anywhere;
    font-size: 0.875rem;
    line-height: 1.4;
  }
  [data-uiify-table-of-contents] [data-part="link"][data-selected] {
    color: var(--foreground);
    font-weight: var(--weight-semibold);
  }
  [data-uiify-table-of-contents] [data-part="link"]:is(:hover, [data-highlighted]) {
    background: var(--accent);
    color: var(--accent-foreground);
  }
  [data-uiify-table-of-contents] :is([data-part="trigger"], [data-part="link"]):focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 2px;
  }

  @media (prefers-reduced-motion: reduce) {
    [data-uiify-table-of-contents] [data-part="indicator"] {
      transition: none;
    }
  }
}
.toc-reader { display: grid; grid-template-columns: 3rem minmax(0, 1fr); align-items: start; block-size: 28rem; overflow: auto; }
.toc-reader > nav { grid-column: 1; grid-row: 1; position: sticky; inset-block-start: 50%; translate: 0 -50%; --uiify-toc-line-size: 6px; --uiify-toc-line-max-size: 24px; }
.toc-reader > article { grid-column: 2; grid-row: 1; min-inline-size: 0; }
.toc-reader section { min-block-size: 18rem; padding: 1rem; scroll-margin-block-start: 24px; }
import { TableOfContents } from "@gunkin/uiify/components/table-of-contents/client";

const sections = ["Overview", "Installation", "Configuration", "Examples", "Accessibility", "Styling", "Conclusion"];
export default function Example() {
  return (
    <div
      className="grid grid-cols-[3rem_minmax(0,1fr)] [block-size:28rem] overflow-auto [&>article]:[min-inline-size:0] [&_section]:[min-block-size:18rem] [&_section]:p-4"
      id="toc-reader"
      tabIndex={0}
      role="region"
      aria-label="Example article"
    >
      <TableOfContents.Root
        className={
          "[--uiify-toc-line-size:12px] [--uiify-toc-line-max-size:48px] [--uiify-toc-line-thickness:2px] [--uiify-t" +
          "oc-row-size:20px] [--uiify-toc-magnify-radius:2.5] [--uiify-toc-indent:1rem] [--uiify-toc-panel-size:18re" +
          "m] [--uiify-toc-duration:140ms] text-foreground [&_[data-part=trigger]]:inline-flex [&_[data-part=trigger" +
          "]]:items-center [&_[data-part=trigger]]:justify-center [&_[data-part=trigger]]:[min-inline-size:44px] [&_" +
          "[data-part=trigger]]:[min-block-size:44px] [&_[data-part=trigger]]:[padding:0.75rem] [&_[data-part=trigge" +
          "r]]:border-0 [&_[data-part=trigger]]:border-current [&_[data-part=trigger]]:border-none [&_[data-part=tri" +
          "gger]]:[border-radius:var(--radius-2)] [&_[data-part=trigger]]:bg-transparent [&_[data-part=trigger]]:tex" +
          "t-inherit [&_[data-part=trigger]]:[font-style:inherit] [&_[data-part=trigger]]:[font-variant:inherit] [&_" +
          "[data-part=trigger]]:[font-weight:inherit] [&_[data-part=trigger]]:[font-stretch:inherit] [&_[data-part=t" +
          "rigger]]:text-[length:inherit] [&_[data-part=trigger]]:leading-[inherit] [&_[data-part=trigger]]:font-[fa" +
          "mily-name:inherit] [&_[data-part=trigger]]:cursor-pointer [&_[data-part=rail]]:grid [&_[data-part=rail]]:" +
          "[grid-auto-rows:var(--uiify-toc-row-size)] [&_[data-part=rail]]:items-center [&_[data-part=rail]]:[inline" +
          "-size:var(--uiify-toc-line-max-size)] [&_[data-part=rail]]:[max-block-size:calc(100dvb_-_8rem)] [&_[data-" +
          "part=rail]]:overflow-auto [&_[data-part=indicator]]:block [&_[data-part=indicator]]:[--uiify-toc-distance" +
          ":max(_calc(var(--uiify-toc-index,_0)_-_var(--uiify-toc-pointer,_-1000)),_calc(var(--uiify-toc-pointer,_-1" +
          "000)_-_var(--uiify-toc-index,_0))_)] [&_[data-part=indicator]]:[--uiify-toc-proximity:clamp(_0,_calc(1_-_" +
          "var(--uiify-toc-distance)_/_max(0.001,_var(--uiify-toc-magnify-radius))),_1_)] [&_[data-part=indicator]]:" +
          "[inline-size:calc(_var(--uiify-toc-line-size)_+_(var(--uiify-toc-line-max-size)_-_var(--uiify-toc-line-si" +
          "ze))_*_var(--uiify-toc-proximity)_)] [&_[data-part=indicator]]:[transition:inline-size_var(--uiify-toc-du" +
          "ration)_ease,_opacity_var(--uiify-toc-duration)_ease] [&_[data-part=indicator]]:[block-size:var(--uiify-t" +
          "oc-line-thickness)] [&_[data-part=indicator]]:rounded-[var(--radius-full)] [&_[data-part=indicator]]:bg-m" +
          "uted-foreground [&_[data-part=indicator]]:opacity-50 [&_[data-part=indicator][data-selected]]:bg-foregrou" +
          "nd [&_[data-part=indicator][data-selected]]:opacity-100 [&_[data-part=indicator][data-highlighted]:not([d" +
          "ata-selected])]:bg-primary [&_[data-part=indicator][data-highlighted]:not([data-selected])]:opacity-100 [" +
          "&_[data-part=content]]:[--uiify-anchor-offset:0] [&_[data-part=content]]:[inline-size:min(var(--uiify-toc" +
          "-panel-size),_calc(100dvi_-_2rem))] [&_[data-part=content]]:[max-block-size:calc(100dvb_-_2rem)] [&_[data" +
          "-part=content]]:overflow-auto [&_[data-part=content]]:overscroll-contain [&_[data-part=content]]:[padding" +
          ":0.5rem] [&_[data-part=content]]:[border-width:1px] [&_[data-part=content]]:border-solid [&_[data-part=co" +
          "ntent]]:border-border [&_[data-part=content]]:[border-radius:var(--radius-3)] [&_[data-part=content]]:bg-" +
          "popover [&_[data-part=content]]:text-popover-foreground [&_[data-part=list]]:grid [&_[data-part=link]]:bl" +
          "ock [&_[data-part=link]]:[padding-block:0.625rem] [&_[data-part=link]]:[padding-inline:calc(0.75rem_+_max" +
          "(0,_var(--uiify-toc-level,_2)_-_2)_*_var(--uiify-toc-indent))_0.75rem] [&_[data-part=link]]:[border-radiu" +
          "s:var(--radius-2)] [&_[data-part=link]]:text-muted-foreground [&_[data-part=link]]:no-underline [&_[data-" +
          "part=link]]:[overflow-wrap:anywhere] [&_[data-part=link]]:[font-size:0.875rem] [&_[data-part=link]]:[line" +
          "-height:1.4] [&_[data-part=link][data-selected]]:text-foreground [&_[data-part=link][data-selected]]:font" +
          "-[number:var(--weight-semibold)] [&_[data-part=link]:is(:hover,[data-highlighted])]:bg-accent [&_[data-pa" +
          "rt=link]:is(:hover,[data-highlighted])]:text-accent-foreground [&_:is([data-part=trigger],[data-part=link" +
          "]):focus-visible]:[outline:2px_solid_var(--ring)] [&_:is([data-part=trigger],[data-part=link]):focus-visi" +
          "ble]:[outline-offset:2px] motion-reduce:[&_[data-part=indicator]]:[transition:none]"
        }
        aria-label="Contents"
        scrollTarget="toc-reader"
        contentTarget="toc-article"
        offset={24}
      >
        <TableOfContents.Trigger target="toc-panel" aria-label="Contents">
          <TableOfContents.Rail>
            {sections.map((label, index) => (
              <TableOfContents.Indicator key={label} value={`toc-section-${index}`} />
            ))}
          </TableOfContents.Rail>
        </TableOfContents.Trigger>
        <TableOfContents.Content id="toc-panel" side="right" align="center">
          <TableOfContents.List>
            {sections.map((label, index) => (
              <TableOfContents.Link key={label} href={`#toc-section-${index}`}>
                {label}
              </TableOfContents.Link>
            ))}
          </TableOfContents.List>
        </TableOfContents.Content>
      </TableOfContents.Root>
      <article id="toc-article">
        {sections.map((label, index) => (
          <section id={`toc-section-${index}`} key={label}>
            <h2>{label}</h2>
            <p>Read this section, or choose another heading from the contents.</p>
          </section>
        ))}
      </article>
    </div>
  );
}
/* app.css */

@layer reset, ui, app, tokens, base, demo, components, utilities, theme;

@import "@gunkin/uiify/styles/reset";

@import "@gunkin/uiify/components/behavior.css";

@import "@gunkin/uiify/styles/tokens";

@import "@gunkin/uiify/styles/tailwind";

@import "tailwindcss/utilities.css";

@theme { --spacing: 0.25rem; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600; --font-weight-bold: 700; }

@source inline('[--uiify-toc-line-size:12px] [--uiify-toc-line-max-size:48px] [--uiify-toc-line-thickness:2px] [--uiify-toc-row-size:20px] [--uiify-toc-magnify-radius:2.5] [--uiify-toc-indent:1rem] [--uiify-toc-panel-size:18rem] [--uiify-toc-duration:140ms] text-foreground [&_[data-part=trigger]]:inline-flex [&_[data-part=trigger]]:items-center [&_[data-part=trigger]]:justify-center [&_[data-part=trigger]]:[min-inline-size:44px] [&_[data-part=trigger]]:[min-block-size:44px] [&_[data-part=trigger]]:[padding:0.75rem] [&_[data-part=trigger]]:border-0 [&_[data-part=trigger]]:border-current [&_[data-part=trigger]]:border-none [&_[data-part=trigger]]:[border-radius:var(--radius-2)] [&_[data-part=trigger]]:bg-transparent [&_[data-part=trigger]]:text-inherit [&_[data-part=trigger]]:[font-style:inherit] [&_[data-part=trigger]]:[font-variant:inherit] [&_[data-part=trigger]]:[font-weight:inherit] [&_[data-part=trigger]]:[font-stretch:inherit] [&_[data-part=trigger]]:text-[length:inherit] [&_[data-part=trigger]]:leading-[inherit] [&_[data-part=trigger]]:font-[family-name:inherit] [&_[data-part=trigger]]:cursor-pointer [&_[data-part=rail]]:grid [&_[data-part=rail]]:[grid-auto-rows:var(--uiify-toc-row-size)] [&_[data-part=rail]]:items-center [&_[data-part=rail]]:[inline-size:var(--uiify-toc-line-max-size)] [&_[data-part=rail]]:[max-block-size:calc(100dvb_-_8rem)] [&_[data-part=rail]]:overflow-auto [&_[data-part=indicator]]:block [&_[data-part=indicator]]:[--uiify-toc-distance:max(_calc(var(--uiify-toc-index,_0)_-_var(--uiify-toc-pointer,_-1000)),_calc(var(--uiify-toc-pointer,_-1000)_-_var(--uiify-toc-index,_0))_)] [&_[data-part=indicator]]:[--uiify-toc-proximity:clamp(_0,_calc(1_-_var(--uiify-toc-distance)_/_max(0.001,_var(--uiify-toc-magnify-radius))),_1_)] [&_[data-part=indicator]]:[inline-size:calc(_var(--uiify-toc-line-size)_+_(var(--uiify-toc-line-max-size)_-_var(--uiify-toc-line-size))_*_var(--uiify-toc-proximity)_)] [&_[data-part=indicator]]:[transition:inline-size_var(--uiify-toc-duration)_ease,_opacity_var(--uiify-toc-duration)_ease] [&_[data-part=indicator]]:[block-size:var(--uiify-toc-line-thickness)] [&_[data-part=indicator]]:rounded-[var(--radius-full)] [&_[data-part=indicator]]:bg-muted-foreground [&_[data-part=indicator]]:opacity-50 [&_[data-part=indicator][data-selected]]:bg-foreground [&_[data-part=indicator][data-selected]]:opacity-100 [&_[data-part=indicator][data-highlighted]:not([data-selected])]:bg-primary [&_[data-part=indicator][data-highlighted]:not([data-selected])]:opacity-100 [&_[data-part=content]]:[--uiify-anchor-offset:0] [&_[data-part=content]]:[inline-size:min(var(--uiify-toc-panel-size),_calc(100dvi_-_2rem))] [&_[data-part=content]]:[max-block-size:calc(100dvb_-_2rem)] [&_[data-part=content]]:overflow-auto [&_[data-part=content]]:overscroll-contain [&_[data-part=content]]:[padding:0.5rem] [&_[data-part=content]]:[border-width:1px] [&_[data-part=content]]:border-solid [&_[data-part=content]]:border-border [&_[data-part=content]]:[border-radius:var(--radius-3)] [&_[data-part=content]]:bg-popover [&_[data-part=content]]:text-popover-foreground [&_[data-part=list]]:grid [&_[data-part=link]]:block [&_[data-part=link]]:[padding-block:0.625rem] [&_[data-part=link]]:[padding-inline:calc(0.75rem_+_max(0,_var(--uiify-toc-level,_2)_-_2)_*_var(--uiify-toc-indent))_0.75rem] [&_[data-part=link]]:[border-radius:var(--radius-2)] [&_[data-part=link]]:text-muted-foreground [&_[data-part=link]]:no-underline [&_[data-part=link]]:[overflow-wrap:anywhere] [&_[data-part=link]]:[font-size:0.875rem] [&_[data-part=link]]:[line-height:1.4] [&_[data-part=link][data-selected]]:text-foreground [&_[data-part=link][data-selected]]:font-[number:var(--weight-semibold)] [&_[data-part=link]:is(:hover,[data-highlighted])]:bg-accent [&_[data-part=link]:is(:hover,[data-highlighted])]:text-accent-foreground [&_:is([data-part=trigger],[data-part=link]):focus-visible]:[outline:2px_solid_var(--ring)] [&_:is([data-part=trigger],[data-part=link]):focus-visible]:[outline-offset:2px] motion-reduce:[&_[data-part=indicator]]:[transition:none] grid grid-cols-[3rem_minmax(0,1fr)] [block-size:28rem] overflow-auto [&>article]:[min-inline-size:0] [&_section]:[min-block-size:18rem] [&_section]:p-4');

@layer base { :root { --uiify-control-text: var(--text-sm); } @media (pointer: coarse) { :root { --uiify-control-text: var(--text-base); } } }

/* Authored animation and registered properties used by the Tailwind skin.
 * Visual rules belong in utility recipes; only at-rule definitions live here. */
@layer components {
  @keyframes uiify-presence-in {
    from {
      opacity: 0;
      scale: var(--presence-scale);
    }
  }
}

@layer components {
  @keyframes uiify-presence-out {
    to {
      opacity: 0;
      scale: var(--presence-scale);
    }
  }
}

@property --uiify-spinner-tail {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

@property --uiify-spinner-length {
  syntax: "<angle>";
  inherits: false;
  initial-value: 36deg;
}

@layer components {
  @keyframes uiify-spinner-rotate {
    to {
      transform: rotate(360deg);
    }
  }
}

@layer components {
  @keyframes uiify-spinner-orbit {
    0% {
      --uiify-spinner-tail: 0deg;
      --uiify-spinner-length: 36deg;
    }

    50% {
      --uiify-spinner-tail: 90deg;
      --uiify-spinner-length: 324deg;
    }

    100% {
      --uiify-spinner-tail: 360deg;
      --uiify-spinner-length: 36deg;
    }
  }
}

@layer components {
  @keyframes uiify-skeleton-pulse {
    50% {
      opacity: 0.45;
    }
  }
}

@layer components {
  @keyframes uiify-skeleton-shimmer {
    to {
      background-position: -200% 0;
    }
  }
}

@layer components {
  @keyframes uiify-skeleton-reveal {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
}

@property --candle-body-height {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

@property --candle-body-top {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --candle-slot {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 100%;
}

@property --candle-wick-height {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

@property --candle-wick-top {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --candle-x {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

@property --candle-scale {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

@property --line-y {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --line-prev-y {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --line-count {
  syntax: "<integer>";
  inherits: false;
  initial-value: 1;
}

@property --line-scale {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

@layer components {
  @keyframes uiify-otp-input-caret-blink {
    50% {
      opacity: 0;
    }
  }
}

API

TableOfContents.Root (/client)

الخاصيةالنوعافتراضيالوصف
scrollSpybooleantrueيتتبّع الوجهات داخل الصفحة بترتيب المستند بعد الإماهة.
scrollTargetstring—معرّف العنصر القابل للتمرير. احذفه لتتبّع النافذة المالكة؛ ولا يُستخدم بديل إذا كان المعرّف مفقودًا.
contentTargetstring—معرّف عنصر المحتوى، ويحدّ اكتشاف الوجهات ويحدّد نهاية المقالة.
offsetnumber0المسافة بالبكسل تحت بداية إطار التمرير المستخدمة لاختيار العنوان الحالي.
valuestring | null—معرّف الوجهة الحالية المتحكّم به. تمسح null التحديد.
defaultValuestring | nullnullالمعرّف الأولي للوجهة الحالية.
onValueChange(value: string | null) => void—تبلّغ عن تغييرات تتبّع التمرير دون نقل التركيز.
openboolean—حالة النافذة المنبثقة المتحكّم بها.
defaultOpenbooleanfalseحالة الفتح الأولية المطبّقة بعد الإماهة.
onOpenChange(open: boolean) => void—تبلّغ عن طلبات التحويم والتفعيل والإغلاق الأصلي.
openOnHoverbooleantrueيفتح عند التحويم بالفأرة؛ ويستخدم اللمس الزر الأصلي.
openDelaynumber100مهلة الفتح بالتحويم بالفأرة بالمللي ثانية.
closeDelaynumber200مهلة السماح للانتقال بين زر التفعيل والقائمة.
renderReactElement | ((props, state) => ReactElement)—استبدل العنصر المعروض مع الحفاظ على توصيلات السلوك وإمكانية الوصول.

TableOfContents.Trigger

الخاصيةالنوعافتراضيالوصف
target*string—معرّف Content فريد، مرتبط بـ popovertarget الأصلية.
aria-labelstring—اسم للتقنيات المساعدة مطلوب حين يقتصر زر التفعيل على الشريط الزخرفي.

TableOfContents.Indicator

الخاصيةالنوعافتراضيالوصف
value*string—معرّف وجهة يطابق جزء الرابط Link؛ مؤشر واحد لكل قسم.
level1 | 2 | 3 | 4 | 5 | 62عمق العنوان المتاح عبر --uiify-toc-level.
selectedbooleanfalseالتحديد في نقطة دخول الخادم؛ ويشتق العميل التحديد من Root.value.
renderReactElement | ((props, state) => ReactElement)—استبدل العنصر المعروض مع الحفاظ على توصيلات السلوك وإمكانية الوصول.

TableOfContents.Content

الخاصيةالنوعافتراضيالوصف
id*string—معرّف فريد للنافذة المنبثقة يطابق Trigger.target.
side"top" | "right" | "bottom" | "left""left"جانب الإرساء الأصلي في CSS؛ ينعكس التخطيط عند الحاجة.
align"start" | "center" | "end""start"المحاذاة بجانب زر التفعيل.
renderReactElement | ((props, state) => ReactElement)—استبدل العنصر المعروض مع الحفاظ على توصيلات السلوك وإمكانية الوصول.

TableOfContents.Link

TableOfContents.Rail / List

الخاصيةالنوعافتراضيالوصف
renderReactElement | ((props, state) => ReactElement)—استبدل العنصر المعروض مع الحفاظ على توصيلات السلوك وإمكانية الوصول.

لوحة المفاتيح

المفتاحالإجراء
Enter / Spaceتبديل نافذة المحتويات المنبثقة الأصلية من زر التفعيل
Tab / Shift+Tabالتنقل بين روابط العناوين العادية
Escapeإغلاق النافذة المنبثقة وإعادة التركيز من القائمة إلى زر تفعيلها

إمكانية الوصول

وفّر تسمية لمَعلم التنقل وزر تفعيله الذي يقتصر على أيقونة. تدعم نقطة دخول الخادم تفعيل النافذة المنبثقة الأصلي وإغلاقها وروابط أجزاء الصفحة قبل الإماهة؛ وتضيف /client التحويم والتثبيت بالنقر والتكبير وتتبّع التمرير. تكشف الروابط الحالية aria-current=location، وتُخفى المؤشرات الزخرفية عن التقنيات المساعدة. لا ينقل تتبّع التمرير التركيز ولا يعلن التمرير أبدًا. ومع تفضيل تقليل الحركة، يعطّل التنسيق الاختياري انتقالات الخطوط.

نقاط التنسيق

data-uiify-table-of-contentsdata-partdata-selecteddata-highlighteddata-statedata-sidedata-aligndata-positioning--uiify-toc-line-size--uiify-toc-line-max-size--uiify-toc-line-thickness--uiify-toc-row-size--uiify-toc-magnify-radius--uiify-toc-indent--uiify-toc-panel-size--uiify-toc-duration--uiify-toc-level--uiify-toc-index--uiify-toc-pointer
تُرجمت هذه الصفحة آليًا ولم تُراجع بعد.