@data-slot/collapsible

中文文档
1.1.3发布于 2026/11/05MITTypeScriptESM + CJS构建来源已验证近 30 天下载 5296

Headless collapsible (show/hide) component for vanilla JavaScript. Accessible, unstyled, tiny.

原始使用文档
文档目录13 节
  1. Installation
  2. Quick Start
  3. API
  4. Initialization
  5. Slots
  6. Data Attributes
  7. Options
  8. Controller
  9. Events
  10. Styling
  11. Accessibility
  12. Behavior
  13. License

@data-slot/collapsible

Headless collapsible (show/hide) component for vanilla JavaScript. Accessible, unstyled, tiny.

Installation

npm install @data-slot/collapsible

Quick Start

<div data-slot="collapsible">
  <button data-slot="collapsible-trigger">Toggle Content</button>
  <div data-slot="collapsible-content" hidden>
    Hidden content revealed on click.
  </div>
</div>

<script type="module">
  import { create } from "@data-slot/collapsible";
  
  const controllers = create();
</script>

API

Initialization

create(scope?)

Auto-discover and bind all collapsible instances in a scope (defaults to document).

import { create } from "@data-slot/collapsible";

const controllers = create(); // Returns CollapsibleController[]

createCollapsible(root, options?)

Create a controller for a specific element.

import { createCollapsible } from "@data-slot/collapsible";

const collapsible = createCollapsible(element, {
  defaultOpen: false,
  hiddenUntilFound: false,
  closeOnEscape: false,
  closeOnClickOutside: false,
  onOpenChange: (open) => console.log(open),
});

Slots

Runtime Slots

  • collapsible - Root element that manages the open state.
  • collapsible-trigger - Required button that toggles the content and receives aria-expanded.
  • collapsible-content - Required panel that is shown or hidden with the open state.

Markup

<div data-slot="collapsible">
  <button data-slot="collapsible-trigger">Toggle</button>
  <div data-slot="collapsible-content">Content</div>
</div>

Data Attributes

Options can also be set via data attributes on the root element. JS options take precedence.

AttributeTypeDefaultDescription
data-default-openbooleanfalseInitial open state
data-hidden-until-foundbooleanfalseUse hidden="until-found" when closed
data-close-on-escapebooleanfalseClose when pressing Escape
data-close-on-click-outsidebooleanfalseClose on a pointer press outside the collapsible

Boolean attributes: present or "true" = true, "false" = false, absent = default.

<!-- Start expanded -->
<div data-slot="collapsible" data-default-open>
  ...
</div>

Options

OptionTypeDefaultDescription
defaultOpenbooleanfalseInitial open state
hiddenUntilFoundbooleanfalseUse hidden="until-found" when closed
closeOnEscapebooleanfalseClose when pressing Escape
closeOnClickOutsidebooleanfalseClose on a pointer press outside the collapsible
onOpenChange(open: boolean) => voidundefinedCallback when open state changes (not called on init)

Controller

Method/PropertyDescription
open()Open the collapsible
close()Close the collapsible
toggle()Toggle the collapsible
isOpenCurrent open state (readonly boolean)
destroy()Cleanup all event listeners

Events

Outbound Events

Listen for changes via custom events:

element.addEventListener("collapsible:change", (e) => {
  console.log("Collapsible open:", e.detail.open);
});

Inbound Events

Control the collapsible via events:

EventDetailDescription
collapsible:set{ open: boolean }Set open state programmatically
// Open the collapsible
element.dispatchEvent(
  new CustomEvent("collapsible:set", { detail: { open: true } })
);

// Close the collapsible
element.dispatchEvent(
  new CustomEvent("collapsible:set", { detail: { open: false } })
);

Note: Blocked when trigger is disabled (has disabled attribute or aria-disabled="true").

Deprecated Shapes

The following shape is deprecated and will be removed in v1.0:

// Deprecated: { value: boolean }
element.dispatchEvent(
  new CustomEvent("collapsible:set", { detail: { value: true } })
);

Use { open: boolean } instead.

Styling

Use data-state attributes for CSS styling (available on both root and content):

/* Hidden state */
[data-slot="collapsible-content"][hidden] {
  display: none;
}

/* Or use data-state */
[data-slot="collapsible"][data-state="closed"] [data-slot="collapsible-content"] {
  display: none;
}

/* Animate using data-state on content */
[data-slot="collapsible-content"] {
  overflow: hidden;
  transition: max-height 0.3s;
  max-height: 0;
}

[data-slot="collapsible-content"][data-state="open"] {
  max-height: 500px;
}

/* Presence lifecycle markers */
[data-slot="collapsible-content"][data-starting-style] {
  opacity: 0;
}

[data-slot="collapsible-content"][data-ending-style] {
  opacity: 0;
}

CSS Variables

The content element exposes size variables you can use for dimension animations:

VariableDescription
--collapsible-panel-heightPanel height (auto at open rest, measured px during transitions, 0px when closed)
--collapsible-panel-widthPanel width (auto at open rest, measured px during transitions, 0px when closed)

Example:

[data-slot="collapsible-content"] {
  overflow: hidden;
  height: var(--collapsible-panel-height);
  width: var(--collapsible-panel-width);
  transition: height 0.25s ease, width 0.25s ease, opacity 0.2s ease;
}

[data-slot="collapsible-content"][data-starting-style],
[data-slot="collapsible-content"][data-ending-style] {
  height: 0;
  opacity: 0;
}

Accessibility

The component automatically handles:

  • aria-expanded state on trigger
  • aria-controls linking trigger to content
  • role="region" on content
  • aria-labelledby linking content back to trigger
  • Unique ID generation for trigger and content
  • Disabled trigger support (respects disabled attribute and aria-disabled="true")
  • Focus returns to the trigger when Escape closes the collapsible while focus is inside it

Behavior

Dismissal

Collapsibles stay open until toggled by default. Enable closeOnEscape and closeOnClickOutside (or data-close-on-escape and data-close-on-click-outside) for disclosures that behave like a light-dismiss layer, such as a mobile navigation panel.

<div data-slot="collapsible" data-close-on-escape data-close-on-click-outside>
  <button data-slot="collapsible-trigger">Menu</button>
  <nav data-slot="collapsible-content" aria-label="Main">...</nav>
</div>

Dismissal uses the same layer stack as popovers, dialogs and menus:

  • Escape closes only the most recently opened layer, so a popover inside the panel closes first.
  • Presses inside portaled descendants, such as a popover opened from the panel, count as inside.
  • On touch devices, an outside press closes the panel on click, so scrolling the page does not dismiss it.
  • Dismissal is blocked while the trigger is disabled.

Find-in-Page Support

Enable hiddenUntilFound (or data-hidden-until-found) to close panels with hidden="until-found". This allows browser find-in-page to reveal matching text.

With Tailwind:

<div data-slot="collapsible" class="group">
  <button data-slot="collapsible-trigger" class="flex items-center gap-2">
    <span>Show more</span>
    <svg class="group-data-[state=open]:rotate-180 transition-transform">...</svg>
  </button>
  <div data-slot="collapsible-content" class="hidden group-data-[state=open]:block">
    Content here
  </div>
</div>

License

MIT

版本与发布记录

@data-slot/collapsible 共发布 156 个版本,首次发布于 2026/01/20;过去 12 个月发布了 156 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.1.3latest2026/11/056 天前
1.1.22026/10/1428 天前
1.1.12026/10/051 个月前
1.1.02026/10/021 个月前
1.0.22026/09/271 个月前
1.0.12026/09/261 个月前

关于 @data-slot/collapsible 的常见问题

@data-slot/collapsible 是什么?

Headless collapsible (show/hide) component for vanilla JavaScript. Accessible, unstyled, tiny.

如何安装 @data-slot/collapsible?

在项目目录运行 npm install @data-slot/collapsible,或使用 pnpm add / yarn add / bun add。

@data-slot/collapsible 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@data-slot/collapsible 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@data-slot/collapsible 可以商用吗?

@data-slot/collapsible 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@data-slot/collapsible 的下载量有多少?

根据 npm 官方下载统计,@data-slot/collapsible 在 2026/10/12 – 2026/11/10 这 30 天内被下载 5,296 次,日均约 177 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@data-slot/collapsible 还在维护吗?

最新版本 1.1.3 发布于 2026/11/05(6 天前);至今共发布 156 个版本,其中过去 12 个月发布了 156 个;首次发布于 2026/01/20。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。