Collapsible
אזור שהמשתמש יכול להציג או להסתיר.
- דפדפנים
- Chrome 123+Firefox 121+Safari 17.5+
- שכבה
- 0
- גודל חבילה דחוסה
- 447 B
- מגבלת פריסה כפויה
- 0 ms
- מגבלת Axe
- 0
- תואם SSR
- כן
- מבוסס על
- elements/details
- חוזה מפורסם
- סביבת בדיקות
מגרש ניסויים
import { Collapsible } from "@gunkin/uiify";
export default function Example() {
return (
<Collapsible
className=""
slotProps={{
trigger: { className: "" },
panel: { className: "" },
}}
id="release-notes"
label="Release notes"
content={<>New keyboard navigation and accessibility improvements.</>}
/>
);
}/* Collapsible — a single native <details>/<summary> disclosure. Same shape
as accordion.css: [data-part] selectors let styles apply without opting
into the BEM classes, both rules kept together so they can't drift apart. */
@layer components {
:where([data-uiify-collapsible], [data-uiify-collapsible]) {
inline-size: 100%;
border: var(--border-width) solid var(--border);
border-radius: var(--radius-xl);
overflow: hidden;
}
[data-uiify-collapsible] [data-part="trigger"] {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-md);
padding: var(--space-lg);
font-size: var(--text-sm);
font-weight: var(--weight-medium);
cursor: pointer;
list-style: none;
}
[data-uiify-collapsible] [data-part="trigger"]::-webkit-details-marker {
display: none;
}
[data-uiify-collapsible] [data-part="trigger"]:hover {
background-color: var(--secondary);
}
[data-uiify-collapsible] [data-part="trigger"]:focus-visible {
outline: none;
box-shadow: inset 0 0 0 var(--ring-width) color-mix(in oklch, var(--ring) 20%, transparent);
}
[data-uiify-collapsible] [data-part="trigger"]::after {
content: "+";
display: grid;
place-items: center;
inline-size: 1.5rem;
block-size: 1.5rem;
flex: 0 0 1.5rem;
color: var(--muted-foreground);
font:
1.25rem/1 ui-monospace,
monospace;
transition: rotate var(--duration-fast) var(--ease-out);
}
[data-uiify-collapsible][open] [data-part="trigger"]::after {
content: "−";
}
[data-uiify-collapsible][open] [data-part="trigger"] {
color: var(--primary);
}
[data-uiify-collapsible] [data-part="panel"] {
padding-block: 0 var(--space-lg);
padding-inline: var(--space-lg);
color: var(--muted-foreground);
font-size: var(--text-sm);
}
[data-uiify-collapsible] {
interpolate-size: allow-keywords;
}
:where([data-uiify-collapsible], [data-uiify-collapsible])::details-content {
block-size: 0;
overflow: clip;
}
:where([data-uiify-collapsible], [data-uiify-collapsible])[open]::details-content {
block-size: auto;
}
/* Shared presence timing; block-size only interpolates where the block above applies. */
@media (prefers-reduced-motion: no-preference) {
:where([data-uiify-collapsible], [data-uiify-collapsible])::details-content {
opacity: 0;
transition:
opacity var(--duration-fast) var(--ease-out),
block-size var(--duration-fast) var(--ease-out),
content-visibility var(--duration-fast) allow-discrete;
}
:where([data-uiify-collapsible], [data-uiify-collapsible])[open]::details-content {
opacity: 1;
}
}
}import { Collapsible } from "@gunkin/uiify";
export default function Example() {
return (
<Collapsible
className={
"group/collapsible [inline-size:100%] border-[length:var(--border-width)] border-solid border-border rounded" +
"-xl overflow-hidden [interpolate-size:allow-keywords] [&::details-content]:[block-size:0] [&::details-conte" +
"nt]:overflow-clip [&[open]::details-content]:[block-size:auto] motion-safe:[&::details-content]:opacity-0 m" +
"otion-safe:[&::details-content]:[transition:opacity_var(--duration-fast)_var(--ease-out),_block-size_var(--" +
"duration-fast)_var(--ease-out),_content-visibility_var(--duration-fast)_allow-discrete] motion-safe:[&[open" +
"]::details-content]:opacity-100"
}
slotProps={{
trigger: {
className:
"flex items-center justify-between gap-md p-lg text-sm " +
"[line-height:var(--leading-normal)] font-[number:var(--weight-medium)] " +
"cursor-pointer list-none [&::-webkit-details-marker]:hidden hover:bg-secondary " +
"focus-visible:[outline:none] " +
"focus-visible:[box-shadow:inset_0_0_0_var(--ring-width)_color-mix(in_oklch,_var(--ring)_20%,_transparent)] " +
'after:content-["+"] after:grid after:place-items-center ' +
"after:[inline-size:1.5rem] after:[block-size:1.5rem] after:[flex:0_0_1.5rem] " +
"after:text-muted-foreground after:not-italic after:[font-variant:normal] " +
"after:font-normal after:[font-stretch:normal] after:[font-size:1.25rem] " +
"after:leading-none after:[font-family:ui-monospace,_monospace] " +
"after:[transition:rotate_var(--duration-fast)_var(--ease-out)] " +
'group-open/collapsible:after:content-["−"] group-open/collapsible:text-primary',
},
panel: { className: "[padding-block:0_var(--space-lg)] px-lg text-muted-foreground text-sm" },
}}
id="release-notes"
label="Release notes"
content={<>New keyboard navigation and accessibility improvements.</>}
/>
);
}API
Collapsible
| מאפיין | טיפוס | ברירת מחדל | תיאור |
|---|---|---|---|
id* | string | — | מזהה אלמנט ה-<details> הבסיסי. |
label* | ReactNode | — | תוכן הסיכום הפותח וסוגר את האזור. |
content* | ReactNode | — | תוכן הלוח הנחשף כשהאזור פתוח. |
defaultOpen | boolean | false | הפריטים הפתוחים בהצגה הראשונה. אינו מבוקר, ולכן נשמר גם ללא JavaScript. |
disabled | boolean | false | חוסם החלפת מצב ומסמן את הסיכום ב-aria-disabled וב-data-disabled. |
className | string | — | המחלקה המוחלת על שורש ה-<details>. |
slotProps | CollapsibleSlotProps | — | מאפיינים מובנים לאלמנטי הסיכום והלוח שנוצרים. |
מקלדת
| מקש | פעולה |
|---|---|
| Tab | העברת המיקוד אל הפקד או ממנו |
| Enter / Space | הפעלה כשהפקד ממוקד (פקדים דמויי כפתור) |
נגישות
משתמש ב-HTML סמנטי ככל האפשר. בדקו את הסימון המרונדר במגרש הניסויים — ARIA נוסף רק כאשר האלמנטים המובנים אינם מספיקים.
נקודות חיבור לעיצוב
data-disabled