@data-slot/accordion 0.2.150 → 0.2.152

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,14 +11,23 @@ npm install @data-slot/accordion
11
11
  ## Quick Start
12
12
 
13
13
  ```html
14
- <div data-slot="accordion">
14
+ <div data-slot="accordion" data-default-value="one">
15
15
  <div data-slot="accordion-item" data-value="one">
16
- <button data-slot="accordion-trigger">Section One</button>
17
- <div data-slot="accordion-content">Content for section one</div>
16
+ <button data-slot="accordion-trigger">
17
+ <span>Section One</span>
18
+ <svg data-slot="accordion-trigger-icon" viewBox="0 0 12 12" aria-hidden="true">
19
+ <path d="M6.75 0H5.25V5.25H0V6.75H5.25V12H6.75V6.75H12V5.25H6.75V0Z" />
20
+ </svg>
21
+ </button>
22
+ <div data-slot="accordion-content">
23
+ <div data-slot="accordion-content-inner">Content for section one</div>
24
+ </div>
18
25
  </div>
19
26
  <div data-slot="accordion-item" data-value="two">
20
27
  <button data-slot="accordion-trigger">Section Two</button>
21
- <div data-slot="accordion-content">Content for section two</div>
28
+ <div data-slot="accordion-content">
29
+ <div data-slot="accordion-content-inner">Content for section two</div>
30
+ </div>
22
31
  </div>
23
32
  </div>
24
33
 
@@ -51,117 +60,221 @@ import { createAccordion } from "@data-slot/accordion";
51
60
  const accordion = createAccordion(element, {
52
61
  multiple: true,
53
62
  defaultValue: ["one"],
54
- collapsible: true,
63
+ orientation: "vertical",
64
+ loopFocus: true,
65
+ hiddenUntilFound: false,
55
66
  onValueChange: (values) => console.log(values),
56
67
  });
57
68
  ```
58
69
 
59
70
  ### Options
60
71
 
61
- | Option | Type | Default | Description |
62
- | --------------- | --------------------------- | ----------- | ------------------------------------------------------- |
63
- | `multiple` | `boolean` | `false` | Allow multiple items open at once |
64
- | `defaultValue` | `string \| string[]` | `undefined` | Initially expanded item(s) |
65
- | `collapsible` | `boolean` | `true` | Whether items can be fully collapsed (single mode only) |
66
- | `onValueChange` | `(value: string[]) => void` | `undefined` | Callback when expanded items change |
72
+ | Option | Type | Default | Description |
73
+ | --- | --- | --- | --- |
74
+ | `multiple` | `boolean` | `false` | Allow multiple items open at once |
75
+ | `defaultValue` | `string \| string[]` | `undefined` | Initially expanded item(s) |
76
+ | `disabled` | `boolean` | `false` | Disable all user interaction for the accordion |
77
+ | `orientation` | `"horizontal" \| "vertical"` | `"vertical"` | Controls roving-focus arrow keys |
78
+ | `loopFocus` | `boolean` | `true` | Wrap roving focus at the ends |
79
+ | `hiddenUntilFound` | `boolean` | `false` | Use `hidden="until-found"` on closed panels |
80
+ | `onValueChange` | `(value: string[]) => void` | `undefined` | Callback when expanded items change |
81
+ | `collapsible` | `boolean` | `true` | Deprecated single-mode alias for “can close the last open item” |
82
+
83
+ ### Deprecated Option
84
+
85
+ The following option is deprecated and will be removed in the next major release:
86
+
87
+ ```typescript
88
+ createAccordion(element, {
89
+ // Deprecated: use the default Base UI-style collapsible behavior instead.
90
+ collapsible: false,
91
+ });
92
+ ```
67
93
 
68
94
  ### Data Attributes
69
95
 
70
96
  Options can also be set via data attributes on the root element. JS options take precedence.
71
97
 
72
98
  | Attribute | Type | Default | Description |
73
- |-----------|------|---------|-------------|
74
- | `data-multiple` | boolean | `false` | Allow multiple items open at once |
75
- | `data-default-value` | string | none | Initially expanded item |
76
- | `data-collapsible` | boolean | `true` | Whether items can be fully collapsed |
99
+ | --- | --- | --- | --- |
100
+ | `data-multiple` | `boolean` | `false` | Allow multiple items open at once |
101
+ | `data-default-value` | `string` | none | Initially expanded item, or a JSON array string for multiple defaults |
102
+ | `data-disabled` | `boolean` | `false` | Disable the entire accordion |
103
+ | `data-orientation` | `"horizontal" \| "vertical"` | `"vertical"` | Controls roving-focus arrow keys |
104
+ | `data-loop-focus` | `boolean` | `true` | Wrap roving focus at the ends |
105
+ | `data-hidden-until-found` | `boolean` | `false` | Use `hidden="until-found"` on closed panels |
106
+ | `data-collapsible` | `boolean` | `true` | Deprecated single-mode compatibility alias |
77
107
 
78
108
  Boolean attributes: present or `"true"` = true, `"false"` = false, absent = default.
79
109
 
80
110
  ```html
81
- <!-- Multiple items can be open, starting with "one" expanded -->
82
- <div data-slot="accordion" data-multiple data-default-value="one">
111
+ <div
112
+ data-slot="accordion"
113
+ data-multiple
114
+ data-default-value="one"
115
+ data-orientation="horizontal"
116
+ >
83
117
  ...
84
118
  </div>
119
+ ```
85
120
 
86
- <!-- Single mode that cannot be fully collapsed -->
87
- <div data-slot="accordion" data-collapsible="false">
121
+ For multiple default items in HTML, encode the value as JSON:
122
+
123
+ ```html
124
+ <div
125
+ data-slot="accordion"
126
+ data-multiple
127
+ data-default-value='["one","two"]'
128
+ >
88
129
  ...
89
130
  </div>
90
131
  ```
91
132
 
92
133
  ### Controller
93
134
 
94
- | Method/Property | Description |
95
- | ----------------- | ----------------------------------------------- |
96
- | `expand(value)` | Expand an item by value |
97
- | `collapse(value)` | Collapse an item by value |
98
- | `toggle(value)` | Toggle an item by value |
99
- | `value` | Currently expanded values (readonly `string[]`) |
100
- | `destroy()` | Cleanup all event listeners |
135
+ | Method/Property | Description |
136
+ | --- | --- |
137
+ | `expand(value)` | Expand an item by value |
138
+ | `collapse(value)` | Collapse an item by value |
139
+ | `toggle(value)` | Toggle an item by value |
140
+ | `value` | Currently expanded values (readonly `string[]`) |
141
+ | `destroy()` | Cleanup all event listeners |
101
142
 
102
143
  ## Markup Structure
103
144
 
104
145
  ```html
105
146
  <div data-slot="accordion">
106
147
  <div data-slot="accordion-item" data-value="unique-id">
107
- <button data-slot="accordion-trigger">Trigger</button>
108
- <div data-slot="accordion-content">Content</div>
148
+ <button data-slot="accordion-trigger">
149
+ <span>Trigger</span>
150
+ <span data-slot="accordion-trigger-icon">+</span>
151
+ </button>
152
+ <div data-slot="accordion-content">
153
+ <div data-slot="accordion-content-inner">Content</div>
154
+ </div>
109
155
  </div>
110
156
  </div>
111
157
  ```
112
158
 
159
+ `data-slot="accordion-trigger-icon"` and `data-slot="accordion-content-inner"` are optional styling hooks.
160
+
113
161
  ## Styling
114
162
 
115
- Use `data-state` attributes for CSS styling:
163
+ ### State Hooks
164
+
165
+ The accordion exposes these useful styling hooks:
166
+
167
+ | Element | Hooks |
168
+ | --- | --- |
169
+ | root | `data-disabled`, `data-orientation` |
170
+ | item | `data-state`, `data-open`, `data-closed`, `data-index`, `data-disabled` |
171
+ | trigger | `data-state`, `data-panel-open`, `data-disabled`, `aria-expanded` |
172
+ | content | `data-state`, `data-open`, `data-closed`, `data-index`, `data-disabled`, `data-orientation`, `data-starting-style`, `data-ending-style` |
173
+
174
+ ### CSS Variables
175
+
176
+ The content element exposes size variables for height or width transitions:
177
+
178
+ | Variable | Description |
179
+ | --- | --- |
180
+ | `--accordion-panel-height` | Panel height (`auto` at rest, measured px during transitions, `0px` when closed) |
181
+ | `--accordion-panel-width` | Panel width (`auto` at rest, measured px during transitions, `0px` when closed) |
182
+ | `--radix-accordion-content-height` | Compatibility alias for Tailwind/Radix accordion keyframes |
183
+ | `--radix-accordion-content-width` | Compatibility alias for width-based integrations |
184
+
185
+ ### CSS Example
116
186
 
117
187
  ```css
118
- /* Closed state */
119
- [data-slot="accordion-content"][data-state="closed"] {
120
- display: none;
188
+ [data-slot="accordion-item"] {
189
+ border-bottom: 1px solid #e5e7eb;
121
190
  }
122
191
 
123
- /* Open state */
124
- [data-slot="accordion-content"][data-state="open"] {
125
- display: block;
192
+ [data-slot="accordion-trigger"] {
193
+ width: 100%;
194
+ display: flex;
195
+ align-items: center;
196
+ gap: 1rem;
197
+ padding: 1rem;
198
+ background: transparent;
199
+ border: 0;
200
+ text-align: left;
126
201
  }
127
202
 
128
- /* Animate with grid */
129
- [data-slot="accordion-item"] {
130
- display: grid;
131
- grid-template-rows: auto 0fr;
132
- transition: grid-template-rows 0.3s;
203
+ [data-slot="accordion-trigger-icon"] {
204
+ margin-left: auto;
205
+ width: 1rem;
206
+ height: 1rem;
207
+ color: #6b7280;
208
+ transition: transform 0.2s ease;
133
209
  }
134
210
 
135
- [data-slot="accordion-item"][data-state="open"] {
136
- grid-template-rows: auto 1fr;
211
+ [data-slot="accordion-item"][data-state="open"] [data-slot="accordion-trigger-icon"] {
212
+ transform: rotate(45deg);
137
213
  }
138
214
 
139
215
  [data-slot="accordion-content"] {
140
216
  overflow: hidden;
217
+ height: var(--accordion-panel-height);
218
+ transition: height 0.2s ease;
219
+ }
220
+
221
+ [data-slot="accordion-content"][data-starting-style] {
222
+ height: 0;
223
+ }
224
+
225
+ [data-slot="accordion-content-inner"] {
226
+ padding: 0 1rem 1rem;
141
227
  }
142
228
  ```
143
229
 
144
- With Tailwind:
230
+ ### Tailwind Example
145
231
 
146
232
  ```html
147
- <div
148
- data-slot="accordion-item"
149
- class="grid grid-rows-[auto_0fr] data-[state=open]:grid-rows-[auto_1fr] transition-[grid-template-rows]"
150
- >
151
- <button data-slot="accordion-trigger">...</button>
152
- <div data-slot="accordion-content" class="overflow-hidden">...</div>
233
+ <div data-slot="accordion" class="overflow-hidden rounded-2xl border">
234
+ <div
235
+ data-slot="accordion-item"
236
+ data-value="one"
237
+ class="group border-b data-[open]:bg-muted/50"
238
+ >
239
+ <button
240
+ data-slot="accordion-trigger"
241
+ class="flex w-full items-center gap-6 p-4 text-left text-sm font-medium hover:underline"
242
+ >
243
+ <span>Section One</span>
244
+ <svg
245
+ data-slot="accordion-trigger-icon"
246
+ viewBox="0 0 12 12"
247
+ class="ml-auto size-4 shrink-0 text-muted-foreground transition-transform group-data-[state=open]:rotate-45"
248
+ >
249
+ <path d="M6.75 0H5.25V5.25H0V6.75H5.25V12H6.75V6.75H12V5.25H6.75V0Z" />
250
+ </svg>
251
+ </button>
252
+ <div
253
+ data-slot="accordion-content"
254
+ class="overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
255
+ >
256
+ <div
257
+ data-slot="accordion-content-inner"
258
+ class="h-(--accordion-panel-height) px-4 pb-4 pt-0 data-ending-style:h-0 data-starting-style:h-0"
259
+ >
260
+ Content
261
+ </div>
262
+ </div>
263
+ </div>
153
264
  </div>
154
265
  ```
155
266
 
156
267
  ## Keyboard Navigation
157
268
 
158
- | Key | Action |
159
- | ----------------- | ------------------------------ |
160
- | `Enter` / `Space` | Toggle focused item |
161
- | `ArrowDown` | Move focus to next trigger |
162
- | `ArrowUp` | Move focus to previous trigger |
163
- | `Home` | Move focus to first trigger |
164
- | `End` | Move focus to last trigger |
269
+ | Key | Action |
270
+ | --- | --- |
271
+ | `Enter` / `Space` | Toggle focused item |
272
+ | `ArrowDown` / `ArrowUp` | Move focus in vertical accordions |
273
+ | `ArrowRight` / `ArrowLeft` | Move focus in horizontal accordions |
274
+ | `Home` | Move focus to first enabled trigger |
275
+ | `End` | Move focus to last enabled trigger |
276
+
277
+ Disabled items are skipped during roving focus.
165
278
 
166
279
  ## Events
167
280
 
@@ -180,22 +293,20 @@ element.addEventListener("accordion:change", (e) => {
180
293
  Control the accordion via events:
181
294
 
182
295
  | Event | Detail | Description |
183
- |-------|--------|-------------|
296
+ | --- | --- | --- |
184
297
  | `accordion:set` | `{ value: string \| string[] }` | Set expanded items programmatically |
185
298
 
186
299
  ```javascript
187
- // Expand a single item
188
300
  element.dispatchEvent(
189
301
  new CustomEvent("accordion:set", { detail: { value: "one" } })
190
302
  );
191
303
 
192
- // Expand multiple items (when data-multiple is set)
193
304
  element.dispatchEvent(
194
305
  new CustomEvent("accordion:set", { detail: { value: ["one", "two"] } })
195
306
  );
196
307
  ```
197
308
 
198
- **Note:** Respects `multiple` and `collapsible` options. In single mode, only the first value is used. When `collapsible` is false, the last open item cannot be closed.
309
+ `accordion:set` and controller methods still work when the accordion is disabled. User-triggered click and keyboard interaction do not.
199
310
 
200
311
  ## License
201
312
 
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@data-slot/core`);const t=`@data-slot/accordion`;function n(n,r={}){let i=(0,e.reuseRootBinding)(n,t,`[@data-slot/accordion] createAccordion() called more than once for the same root. Returning the existing controller. Destroy it before rebinding with new options.`);if(i)return i;let a=(0,e.getParts)(n,`accordion-item`);if(a.length===0)throw Error(`Accordion requires at least one accordion-item`);let o=r.multiple??(0,e.getDataBool)(n,`multiple`)??!1,s=r.onValueChange,c=r.collapsible??(0,e.getDataBool)(n,`collapsible`)??!0,l=r.defaultValue??(0,e.getDataString)(n,`defaultValue`),u=l?Array.isArray(l)?l:[l]:[],d=new Set(u),f=[],p=[];a.forEach(t=>{let r=t.dataset.value;if(!r)return;let i=(0,e.getPart)(t,`accordion-trigger`),a=(0,e.getPart)(t,`accordion-content`);if(!i||!a)return;p.push(i);let l=(0,e.ensureId)(a,`accordion-content`),u=(0,e.ensureId)(i,`accordion-trigger`);i.setAttribute(`aria-controls`,l),a.setAttribute(`aria-labelledby`,u),a.setAttribute(`role`,`region`),f.push((0,e.on)(i,`click`,()=>{if(d.has(r)){if(!c&&!o&&d.size===1)return;d.delete(r)}else o?d.add(r):d=new Set([r]);m(),(0,e.emit)(n,`accordion:change`,{value:[...d]}),s?.([...d])}))}),f.push((0,e.on)(n,`keydown`,e=>{let t=e.target,n=p.indexOf(t);if(n===-1)return;let r=n;switch(e.key){case`ArrowDown`:r=n+1,r>=p.length&&(r=0);break;case`ArrowUp`:r=n-1,r<0&&(r=p.length-1);break;case`Home`:r=0;break;case`End`:r=p.length-1;break;default:return}e.preventDefault(),p[r]?.focus()}));let m=()=>{a.forEach(t=>{let n=t.dataset.value;if(!n)return;let r=(0,e.getPart)(t,`accordion-trigger`),i=(0,e.getPart)(t,`accordion-content`);if(!r||!i)return;let a=d.has(n),o=r.getAttribute(`aria-expanded`)===`true`;if((0,e.setAria)(r,`expanded`,a),t.setAttribute(`data-state`,a?`open`:`closed`),i.setAttribute(`data-state`,a?`open`:`closed`),a)i.hidden=!1,i._accordionTimeout&&=(clearTimeout(i._accordionTimeout),null);else if(o){i._accordionTimeout&&clearTimeout(i._accordionTimeout);let e=i.parentElement,t=n=>{n.propertyName===`grid-template-rows`&&(i.getAttribute(`data-state`)===`closed`&&(i.hidden=!0),e?.removeEventListener(`transitionend`,t),i._accordionTimeout&&=(clearTimeout(i._accordionTimeout),null))};e?(e.addEventListener(`transitionend`,t),i._accordionTimeout=setTimeout(()=>{i.getAttribute(`data-state`)===`closed`&&(i.hidden=!0),e.removeEventListener(`transitionend`,t),i._accordionTimeout=null},350)):i._accordionTimeout=setTimeout(()=>{i.hidden=!0,i._accordionTimeout=null},300)}else i.hidden=!0})};m(),f.push((0,e.on)(n,`accordion:set`,t=>{let r=t.detail?.value;if(r===void 0)return;let i=(Array.isArray(r)?r:[r]).filter(e=>a.some(t=>t.dataset.value===e)),l=o?new Set(i):new Set(i.slice(0,1));!o&&!c&&l.size===0&&d.size>0||(l.size!==d.size||[...l].some(e=>!d.has(e)))&&(d=l,m(),(0,e.emit)(n,`accordion:change`,{value:[...d]}),s?.([...d]))}));let h={expand:t=>{d.has(t)||(o?d.add(t):d=new Set([t]),m(),(0,e.emit)(n,`accordion:change`,{value:[...d]}),s?.([...d]))},collapse:t=>{d.has(t)&&(!c&&!o&&d.size===1||(d.delete(t),m(),(0,e.emit)(n,`accordion:change`,{value:[...d]}),s?.([...d])))},toggle:e=>{d.has(e)?h.collapse(e):h.expand(e)},get value(){return[...d]},destroy:()=>{f.forEach(e=>e()),f.length=0,a.forEach(t=>{let n=(0,e.getPart)(t,`accordion-content`);n&&n._accordionTimeout&&(clearTimeout(n._accordionTimeout),n._accordionTimeout=null)}),(0,e.clearRootBinding)(n,t,h)}};return(0,e.setRootBinding)(n,t,h),h}function r(r=document){let i=[];for(let a of(0,e.getRoots)(r,`accordion`))(0,e.hasRootBinding)(a,t)||i.push(n(a));return i}exports.create=r,exports.createAccordion=n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@data-slot/core`);const t=[`horizontal`,`vertical`],n=new Set([`all`,`height`,`width`,`block-size`,`inline-size`]),r=new Set([`Enter`,` `]),i=e=>!!e&&(e.hasAttribute(`disabled`)||e.hasAttribute(`data-disabled`)||e.getAttribute(`aria-disabled`)===`true`),a=(e,t,n)=>{n?e.setAttribute(t,``):e.removeAttribute(t)},o=(e,t)=>{e.setAttribute(`data-state`,t?`open`:`closed`),t?(e.setAttribute(`data-open`,``),e.removeAttribute(`data-closed`)):(e.setAttribute(`data-closed`,``),e.removeAttribute(`data-open`))},s=e=>{let t=e.trim();return t?t.endsWith(`ms`)?Number.parseFloat(t.slice(0,-2))||0:t.endsWith(`s`)?(Number.parseFloat(t.slice(0,-1))||0)*1e3:Number.parseFloat(t)||0:0},c=(e,t)=>{let n=e.split(`,`),r=t.split(`,`),i=Math.max(n.length,r.length),a=0;for(let e=0;e<i;e+=1){let t=s(n[e]??n[n.length-1]??`0`),i=s(r[e]??r[r.length-1]??`0`);a=Math.max(a,t+i)}return a},l=e=>{let t=getComputedStyle(e),n=c(t.transitionDuration,t.transitionDelay),r=c(t.animationDuration,t.animationDelay);return Math.max(n,r)},u=e=>c(e.animationDuration,e.animationDelay)<=0?!1:e.animationName.split(`,`).map(e=>e.trim()).some(e=>e!==``&&e!==`none`),d=(e,t)=>{let n=getComputedStyle(e),r=n.transitionProperty.split(`,`).map(e=>e.trim()),i=n.transitionDuration.split(`,`),a=n.transitionDelay.split(`,`),o=Math.max(r.length,i.length,a.length),c=0;for(let e=0;e<o;e+=1){if(!t(r[e]??r[r.length-1]??`all`))continue;let n=s(i[e]??i[i.length-1]??`0`),o=s(a[e]??a[a.length-1]??`0`);c=Math.max(c,n+o)}return c},f=e=>d(e,e=>n.has(e)),ee=e=>{if(e===void 0)return;let t=e.trim();if(!t.startsWith(`[`)||!t.endsWith(`]`))return e;try{let n=JSON.parse(t);return Array.isArray(n)?n.filter(e=>typeof e==`string`):e}catch{return e}},p=`@data-slot/accordion`;function m(s,c={}){let d=(0,e.reuseRootBinding)(s,p,`[@data-slot/accordion] createAccordion() called more than once for the same root. Returning the existing controller. Destroy it before rebinding with new options.`);if(d)return d;let m=s,h=(0,e.getParts)(s,`accordion-item`);if(h.length===0)throw Error(`Accordion requires at least one accordion-item`);let g=s.ownerDocument?.defaultView??window,_=c.multiple??(0,e.getDataBool)(s,`multiple`)??!1,v=c.onValueChange,y=c.disabled??(0,e.getDataBool)(s,`disabled`)??i(s),b=c.orientation??(0,e.getDataEnum)(s,`orientation`,t)??`vertical`,x=c.loopFocus??(0,e.getDataBool)(s,`loopFocus`)??!0,S=c.hiddenUntilFound??(0,e.getDataBool)(s,`hiddenUntilFound`)??!1,C=c.collapsible??(0,e.getDataBool)(s,`collapsible`)??!0,w=[],T=[],E=(e,t,n)=>{e.content.style.setProperty(`--accordion-panel-height`,t),e.content.style.setProperty(`--accordion-panel-width`,n),e.content.style.setProperty(`--radix-accordion-content-height`,t),e.content.style.setProperty(`--radix-accordion-content-width`,n)},D=(e,t,n)=>{E(e,`${t}px`,`${n}px`)},O=e=>{E(e,`auto`,`auto`)},k=e=>{D(e,0,0)},A=(e,{resetVarsToAuto:t=!1}={})=>{t&&O(e),D(e,e.content.scrollHeight,e.content.scrollWidth)},j=e=>{let t=e.content.style.getPropertyValue(`--accordion-panel-height`).trim(),n=e.content.style.getPropertyValue(`--accordion-panel-width`).trim();return t===`auto`&&n===`auto`},M=e=>{e.suppressClick=!1,e.suppressClickTimeoutId!==null&&(g.clearTimeout(e.suppressClickTimeoutId),e.suppressClickTimeoutId=null)},N=e=>{e.openSettleRafId!==null&&(g.cancelAnimationFrame(e.openSettleRafId),e.openSettleRafId=null),e.openSettleTimeoutId!==null&&(g.clearTimeout(e.openSettleTimeoutId),e.openSettleTimeoutId=null),e.openSettleCleanups.forEach(e=>e()),e.openSettleCleanups=[]},P=e=>{e.closeZeroRafId!==null&&(g.cancelAnimationFrame(e.closeZeroRafId),e.closeZeroRafId=null)},F=e=>{N(e),P(e)},I=e=>{let t=getComputedStyle(e.content),n=f(e.content)>0,r=u(t);return r&&!n?`css-animation`:n?`css-transition`:r?`css-animation`:`none`},L=(e,t)=>{let n=e.content.style.getPropertyValue(`animation-name`);e.content.style.setProperty(`animation-name`,`none`);try{t()}finally{n?e.content.style.setProperty(`animation-name`,n):e.content.style.removeProperty(`animation-name`)}},R=e=>{e.content.removeAttribute(`hidden`)},z=e=>{S?e.content.setAttribute(`hidden`,`until-found`):e.content.hidden=!0,k(e)},B=new Set,V=e=>{N(e),!(!B.has(e.value)||e.presence.isExiting)&&O(e)},H=e=>{N(e);let t=l(e.content),r=f(e.content),i=r||t;if(i>0){let t=typeof g.performance?.now==`function`?g.performance.now():Date.now(),a=e=>(typeof g.performance?.now==`function`?g.performance.now():Date.now())-t>=Math.max(0,e-5),o=t=>{if(t.target!==e.content)return;let o=`propertyName`in t?String(t.propertyName):``;if(r>0){if(!n.has(o)||!a(r))return}else if(!a(i))return;V(e)},s=t=>{t.target===e.content&&(r>0||a(i)&&V(e))};e.content.addEventListener(`transitionend`,o),e.content.addEventListener(`animationend`,s),e.openSettleCleanups.push(()=>e.content.removeEventListener(`transitionend`,o)),e.openSettleCleanups.push(()=>e.content.removeEventListener(`animationend`,s)),e.openSettleTimeoutId=g.setTimeout(()=>{e.openSettleTimeoutId=null,V(e)},Math.ceil(i)+50);return}e.openSettleRafId=g.requestAnimationFrame(()=>{e.openSettleRafId=null,V(e)})},U=e=>{P(e),e.closeZeroRafId=g.requestAnimationFrame(()=>{e.closeZeroRafId=null,!B.has(e.value)&&e.presence.isExiting&&k(e)})},W=e=>{e.el.setAttribute(`data-index`,String(e.index)),e.content.setAttribute(`data-index`,String(e.index)),e.content.setAttribute(`data-orientation`,b),a(e.el,`data-disabled`,e.disabled),a(e.trigger,`data-disabled`,e.disabled),a(e.content,`data-disabled`,e.disabled),e.disabled?(e.trigger.setAttribute(`aria-disabled`,`true`),e.trigger instanceof HTMLButtonElement&&(e.trigger.disabled=!0)):(e.trigger.removeAttribute(`aria-disabled`),e.trigger instanceof HTMLButtonElement&&(e.trigger.disabled=!1))},G=(e,t)=>{e.trigger.setAttribute(`data-state`,t?`open`:`closed`),a(e.trigger,`data-panel-open`,t)},K=t=>{let n=B.has(t.value);W(t),(0,e.setAria)(t.trigger,`expanded`,n),o(t.el,n),o(t.content,n),G(t,n),t.content.removeAttribute(`data-starting-style`),t.content.removeAttribute(`data-ending-style`);let r=I(t);n?(R(t),r===`css-animation`?L(t,()=>{A(t,{resetVarsToAuto:!0})}):A(t),H(t)):z(t)},q=t=>{let n=B.has(t.value),r=t.trigger.getAttribute(`aria-expanded`)===`true`;W(t),(0,e.setAria)(t.trigger,`expanded`,n),o(t.el,n),o(t.content,n),G(t,n);let i=I(t);if(n){if(P(t),R(t),r&&!t.presence.isExiting&&j(t))return;i===`css-animation`?L(t,()=>{A(t,{resetVarsToAuto:!0}),r||t.presence.enter()}):(A(t),r||t.presence.enter()),H(t);return}if(r){N(t),i===`css-animation`?L(t,()=>{A(t,{resetVarsToAuto:!0}),t.presence.exit()}):(A(t),t.presence.exit(),U(t));return}F(t),t.content.removeAttribute(`data-starting-style`),t.content.removeAttribute(`data-ending-style`),z(t)},J=e=>{let t=[],n=new Set;for(let r of e)if(!(n.has(r)||!h.some(e=>e.dataset.value===r))&&(n.add(r),t.push(r),!_&&t.length===1))break;return t},te=e=>e.size===B.size?[...e].some(e=>!B.has(e)):!0,ne=()=>{T.forEach(q)},re=()=>{let t=[...B];(0,e.emit)(s,`accordion:change`,{value:t}),v?.(t)},Y=e=>{let t=J(e);if(!_&&!C&&t.length===0&&B.size>0)return!1;let n=new Set(t);return te(n)?(B=n,ne(),re(),!0):!1},X=e=>(e.getAttribute(`dir`)??m.getAttribute(`dir`))===`rtl`||(getComputedStyle(e).direction||getComputedStyle(m).direction||s.ownerDocument?.documentElement.getAttribute(`dir`)||``)===`rtl`?`rtl`:`ltr`;m.setAttribute(`data-orientation`,b),a(m,`data-disabled`,!!y),h.forEach((t,n)=>{let a=t.dataset.value;if(!a)return;let o=(0,e.getPart)(t,`accordion-trigger`),s=(0,e.getPart)(t,`accordion-content`);if(!o||!s)return;let c=(0,e.ensureId)(s,`accordion-content`),l=(0,e.ensureId)(o,`accordion-trigger`);o.setAttribute(`aria-controls`,c),s.setAttribute(`aria-labelledby`,l),s.setAttribute(`role`,`region`);let u=!!y||i(t)||i(o),d;d={el:t,value:a,index:n,disabled:u,trigger:o,content:s,presence:(0,e.createPresenceLifecycle)({element:s,onExitComplete:()=>{P(d),z(d)}}),sizeObserver:null,openSettleRafId:null,openSettleTimeoutId:null,closeZeroRafId:null,openSettleCleanups:[],suppressClick:!1,suppressClickTimeoutId:null},typeof ResizeObserver<`u`&&(d.sizeObserver=new ResizeObserver(()=>{!B.has(d.value)||d.presence.isExiting||j(d)||A(d)}),d.sizeObserver.observe(s)),w.push((0,e.on)(o,`click`,()=>{if(d.suppressClick){M(d);return}d.disabled||(B.has(d.value)?Y([...B].filter(e=>e!==d.value)):Y(_?[...B,d.value]:[d.value]))})),w.push((0,e.on)(o,`keydown`,e=>{if(r.has(e.key)){if(d.disabled){e.preventDefault();return}e.preventDefault(),M(d),d.suppressClick=!0,d.suppressClickTimeoutId=g.setTimeout(()=>{d.suppressClick=!1,d.suppressClickTimeoutId=null},0),B.has(d.value)?Y([...B].filter(e=>e!==d.value)):Y(_?[...B,d.value]:[d.value])}})),S&&w.push((0,e.on)(s,`beforematch`,()=>{Y(_?[...B,d.value]:[d.value])})),T.push(d)});let Z=new Set(T.map(e=>e.value)),Q=c.defaultValue??ee((0,e.getDataString)(s,`defaultValue`)),ie=J((Q?Array.isArray(Q)?Q:[Q]:[]).filter(e=>Z.has(e)));B=new Set(ie),T.forEach(K),w.push((0,e.on)(m,`keydown`,e=>{let t=e.target;if(!t)return;let n=T.find(e=>e.trigger===t);if(!n)return;let r=T.filter(e=>!e.disabled),i=r.findIndex(e=>e.trigger===t);if(i===-1)return;let a=r.length-1,o=-1,s=()=>{o=x?i+1>a?0:i+1:Math.min(i+1,a)},c=()=>{o=x?i===0?a:i-1:Math.max(i-1,0)};switch(e.key){case`ArrowDown`:b===`vertical`&&s();break;case`ArrowUp`:b===`vertical`&&c();break;case`ArrowRight`:b===`horizontal`&&(X(n.trigger)===`rtl`?c():s());break;case`ArrowLeft`:b===`horizontal`&&(X(n.trigger)===`rtl`?s():c());break;case`Home`:o=0;break;case`End`:o=a;break;default:return}o<0||(e.preventDefault(),r[o]?.trigger.focus())})),w.push((0,e.on)(s,`accordion:set`,e=>{let t=e.detail?.value;t!==void 0&&Y(Array.isArray(t)?t:[t])}));let $={expand:e=>{!Z.has(e)||B.has(e)||Y(_?[...B,e]:[e])},collapse:e=>{!Z.has(e)||!B.has(e)||Y([...B].filter(t=>t!==e))},toggle:e=>{Z.has(e)&&(B.has(e)?$.collapse(e):$.expand(e))},get value(){return[...B]},destroy:()=>{T.forEach(e=>{M(e),e.presence.cleanup(),F(e),e.sizeObserver?.disconnect(),e.sizeObserver=null}),w.forEach(e=>e()),w.length=0,(0,e.clearRootBinding)(s,p,$)}};return(0,e.setRootBinding)(s,p,$),$}function h(t=document){let n=[];for(let r of(0,e.getRoots)(t,`accordion`))(0,e.hasRootBinding)(r,p)||n.push(m(r));return n}exports.create=h,exports.createAccordion=m;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,6 @@
1
1
  //#region src/index.d.ts
2
+ declare const ORIENTATIONS: readonly ["horizontal", "vertical"];
3
+ type AccordionOrientation = (typeof ORIENTATIONS)[number];
2
4
  interface AccordionOptions {
3
5
  /** Allow multiple items open at once */
4
6
  multiple?: boolean;
@@ -6,7 +8,18 @@ interface AccordionOptions {
6
8
  defaultValue?: string | string[];
7
9
  /** Callback when expanded items change */
8
10
  onValueChange?: (value: string[]) => void;
9
- /** Whether items can be fully collapsed (only applies to single mode) */
11
+ /** Disable the entire accordion */
12
+ disabled?: boolean;
13
+ /** Accordion orientation for roving focus */
14
+ orientation?: AccordionOrientation;
15
+ /** Whether arrow-key focus wraps at the ends */
16
+ loopFocus?: boolean;
17
+ /** Use hidden="until-found" on closed panels */
18
+ hiddenUntilFound?: boolean;
19
+ /**
20
+ * @deprecated Use the Base UI-style default collapsible behavior instead.
21
+ * Kept for backward compatibility and planned for removal in the next major.
22
+ */
10
23
  collapsible?: boolean;
11
24
  }
12
25
  interface AccordionController {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  //#region src/index.d.ts
2
+ declare const ORIENTATIONS: readonly ["horizontal", "vertical"];
3
+ type AccordionOrientation = (typeof ORIENTATIONS)[number];
2
4
  interface AccordionOptions {
3
5
  /** Allow multiple items open at once */
4
6
  multiple?: boolean;
@@ -6,7 +8,18 @@ interface AccordionOptions {
6
8
  defaultValue?: string | string[];
7
9
  /** Callback when expanded items change */
8
10
  onValueChange?: (value: string[]) => void;
9
- /** Whether items can be fully collapsed (only applies to single mode) */
11
+ /** Disable the entire accordion */
12
+ disabled?: boolean;
13
+ /** Accordion orientation for roving focus */
14
+ orientation?: AccordionOrientation;
15
+ /** Whether arrow-key focus wraps at the ends */
16
+ loopFocus?: boolean;
17
+ /** Use hidden="until-found" on closed panels */
18
+ hiddenUntilFound?: boolean;
19
+ /**
20
+ * @deprecated Use the Base UI-style default collapsible behavior instead.
21
+ * Kept for backward compatibility and planned for removal in the next major.
22
+ */
10
23
  collapsible?: boolean;
11
24
  }
12
25
  interface AccordionController {
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{clearRootBinding as e,emit as t,ensureId as n,getDataBool as r,getDataString as i,getPart as a,getParts as o,getRoots as s,hasRootBinding as c,on as l,reuseRootBinding as u,setAria as d,setRootBinding as f}from"@data-slot/core";const p=`@data-slot/accordion`;function m(s,c={}){let m=u(s,p,`[@data-slot/accordion] createAccordion() called more than once for the same root. Returning the existing controller. Destroy it before rebinding with new options.`);if(m)return m;let h=o(s,`accordion-item`);if(h.length===0)throw Error(`Accordion requires at least one accordion-item`);let g=c.multiple??r(s,`multiple`)??!1,_=c.onValueChange,v=c.collapsible??r(s,`collapsible`)??!0,y=c.defaultValue??i(s,`defaultValue`),b=y?Array.isArray(y)?y:[y]:[],x=new Set(b),S=[],C=[];h.forEach(e=>{let r=e.dataset.value;if(!r)return;let i=a(e,`accordion-trigger`),o=a(e,`accordion-content`);if(!i||!o)return;C.push(i);let c=n(o,`accordion-content`),u=n(i,`accordion-trigger`);i.setAttribute(`aria-controls`,c),o.setAttribute(`aria-labelledby`,u),o.setAttribute(`role`,`region`),S.push(l(i,`click`,()=>{if(x.has(r)){if(!v&&!g&&x.size===1)return;x.delete(r)}else g?x.add(r):x=new Set([r]);w(),t(s,`accordion:change`,{value:[...x]}),_?.([...x])}))}),S.push(l(s,`keydown`,e=>{let t=e.target,n=C.indexOf(t);if(n===-1)return;let r=n;switch(e.key){case`ArrowDown`:r=n+1,r>=C.length&&(r=0);break;case`ArrowUp`:r=n-1,r<0&&(r=C.length-1);break;case`Home`:r=0;break;case`End`:r=C.length-1;break;default:return}e.preventDefault(),C[r]?.focus()}));let w=()=>{h.forEach(e=>{let t=e.dataset.value;if(!t)return;let n=a(e,`accordion-trigger`),r=a(e,`accordion-content`);if(!n||!r)return;let i=x.has(t),o=n.getAttribute(`aria-expanded`)===`true`;if(d(n,`expanded`,i),e.setAttribute(`data-state`,i?`open`:`closed`),r.setAttribute(`data-state`,i?`open`:`closed`),i)r.hidden=!1,r._accordionTimeout&&=(clearTimeout(r._accordionTimeout),null);else if(o){r._accordionTimeout&&clearTimeout(r._accordionTimeout);let e=r.parentElement,t=n=>{n.propertyName===`grid-template-rows`&&(r.getAttribute(`data-state`)===`closed`&&(r.hidden=!0),e?.removeEventListener(`transitionend`,t),r._accordionTimeout&&=(clearTimeout(r._accordionTimeout),null))};e?(e.addEventListener(`transitionend`,t),r._accordionTimeout=setTimeout(()=>{r.getAttribute(`data-state`)===`closed`&&(r.hidden=!0),e.removeEventListener(`transitionend`,t),r._accordionTimeout=null},350)):r._accordionTimeout=setTimeout(()=>{r.hidden=!0,r._accordionTimeout=null},300)}else r.hidden=!0})};w(),S.push(l(s,`accordion:set`,e=>{let n=e.detail?.value;if(n===void 0)return;let r=(Array.isArray(n)?n:[n]).filter(e=>h.some(t=>t.dataset.value===e)),i=g?new Set(r):new Set(r.slice(0,1));!g&&!v&&i.size===0&&x.size>0||(i.size!==x.size||[...i].some(e=>!x.has(e)))&&(x=i,w(),t(s,`accordion:change`,{value:[...x]}),_?.([...x]))}));let T={expand:e=>{x.has(e)||(g?x.add(e):x=new Set([e]),w(),t(s,`accordion:change`,{value:[...x]}),_?.([...x]))},collapse:e=>{x.has(e)&&(!v&&!g&&x.size===1||(x.delete(e),w(),t(s,`accordion:change`,{value:[...x]}),_?.([...x])))},toggle:e=>{x.has(e)?T.collapse(e):T.expand(e)},get value(){return[...x]},destroy:()=>{S.forEach(e=>e()),S.length=0,h.forEach(e=>{let t=a(e,`accordion-content`);t&&t._accordionTimeout&&(clearTimeout(t._accordionTimeout),t._accordionTimeout=null)}),e(s,p,T)}};return f(s,p,T),T}function h(e=document){let t=[];for(let n of s(e,`accordion`))c(n,p)||t.push(m(n));return t}export{h as create,m as createAccordion};
1
+ import{clearRootBinding as e,createPresenceLifecycle as t,emit as n,ensureId as r,getDataBool as i,getDataEnum as a,getDataString as o,getPart as s,getParts as c,getRoots as l,hasRootBinding as u,on as d,reuseRootBinding as f,setAria as ee,setRootBinding as te}from"@data-slot/core";const ne=[`horizontal`,`vertical`],p=new Set([`all`,`height`,`width`,`block-size`,`inline-size`]),re=new Set([`Enter`,` `]),m=e=>!!e&&(e.hasAttribute(`disabled`)||e.hasAttribute(`data-disabled`)||e.getAttribute(`aria-disabled`)===`true`),h=(e,t,n)=>{n?e.setAttribute(t,``):e.removeAttribute(t)},g=(e,t)=>{e.setAttribute(`data-state`,t?`open`:`closed`),t?(e.setAttribute(`data-open`,``),e.removeAttribute(`data-closed`)):(e.setAttribute(`data-closed`,``),e.removeAttribute(`data-open`))},_=e=>{let t=e.trim();return t?t.endsWith(`ms`)?Number.parseFloat(t.slice(0,-2))||0:t.endsWith(`s`)?(Number.parseFloat(t.slice(0,-1))||0)*1e3:Number.parseFloat(t)||0:0},v=(e,t)=>{let n=e.split(`,`),r=t.split(`,`),i=Math.max(n.length,r.length),a=0;for(let e=0;e<i;e+=1){let t=_(n[e]??n[n.length-1]??`0`),i=_(r[e]??r[r.length-1]??`0`);a=Math.max(a,t+i)}return a},ie=e=>{let t=getComputedStyle(e),n=v(t.transitionDuration,t.transitionDelay),r=v(t.animationDuration,t.animationDelay);return Math.max(n,r)},ae=e=>v(e.animationDuration,e.animationDelay)<=0?!1:e.animationName.split(`,`).map(e=>e.trim()).some(e=>e!==``&&e!==`none`),y=(e,t)=>{let n=getComputedStyle(e),r=n.transitionProperty.split(`,`).map(e=>e.trim()),i=n.transitionDuration.split(`,`),a=n.transitionDelay.split(`,`),o=Math.max(r.length,i.length,a.length),s=0;for(let e=0;e<o;e+=1){if(!t(r[e]??r[r.length-1]??`all`))continue;let n=_(i[e]??i[i.length-1]??`0`),o=_(a[e]??a[a.length-1]??`0`);s=Math.max(s,n+o)}return s},b=e=>y(e,e=>p.has(e)),oe=e=>{if(e===void 0)return;let t=e.trim();if(!t.startsWith(`[`)||!t.endsWith(`]`))return e;try{let n=JSON.parse(t);return Array.isArray(n)?n.filter(e=>typeof e==`string`):e}catch{return e}},x=`@data-slot/accordion`;function S(l,u={}){let _=f(l,x,`[@data-slot/accordion] createAccordion() called more than once for the same root. Returning the existing controller. Destroy it before rebinding with new options.`);if(_)return _;let v=l,y=c(l,`accordion-item`);if(y.length===0)throw Error(`Accordion requires at least one accordion-item`);let S=l.ownerDocument?.defaultView??window,C=u.multiple??i(l,`multiple`)??!1,se=u.onValueChange,w=u.disabled??i(l,`disabled`)??m(l),T=u.orientation??a(l,`orientation`,ne)??`vertical`,E=u.loopFocus??i(l,`loopFocus`)??!0,ce=u.hiddenUntilFound??i(l,`hiddenUntilFound`)??!1,le=u.collapsible??i(l,`collapsible`)??!0,D=[],O=[],k=(e,t,n)=>{e.content.style.setProperty(`--accordion-panel-height`,t),e.content.style.setProperty(`--accordion-panel-width`,n),e.content.style.setProperty(`--radix-accordion-content-height`,t),e.content.style.setProperty(`--radix-accordion-content-width`,n)},A=(e,t,n)=>{k(e,`${t}px`,`${n}px`)},j=e=>{k(e,`auto`,`auto`)},M=e=>{A(e,0,0)},N=(e,{resetVarsToAuto:t=!1}={})=>{t&&j(e),A(e,e.content.scrollHeight,e.content.scrollWidth)},P=e=>{let t=e.content.style.getPropertyValue(`--accordion-panel-height`).trim(),n=e.content.style.getPropertyValue(`--accordion-panel-width`).trim();return t===`auto`&&n===`auto`},F=e=>{e.suppressClick=!1,e.suppressClickTimeoutId!==null&&(S.clearTimeout(e.suppressClickTimeoutId),e.suppressClickTimeoutId=null)},I=e=>{e.openSettleRafId!==null&&(S.cancelAnimationFrame(e.openSettleRafId),e.openSettleRafId=null),e.openSettleTimeoutId!==null&&(S.clearTimeout(e.openSettleTimeoutId),e.openSettleTimeoutId=null),e.openSettleCleanups.forEach(e=>e()),e.openSettleCleanups=[]},L=e=>{e.closeZeroRafId!==null&&(S.cancelAnimationFrame(e.closeZeroRafId),e.closeZeroRafId=null)},R=e=>{I(e),L(e)},z=e=>{let t=getComputedStyle(e.content),n=b(e.content)>0,r=ae(t);return r&&!n?`css-animation`:n?`css-transition`:r?`css-animation`:`none`},B=(e,t)=>{let n=e.content.style.getPropertyValue(`animation-name`);e.content.style.setProperty(`animation-name`,`none`);try{t()}finally{n?e.content.style.setProperty(`animation-name`,n):e.content.style.removeProperty(`animation-name`)}},V=e=>{e.content.removeAttribute(`hidden`)},H=e=>{ce?e.content.setAttribute(`hidden`,`until-found`):e.content.hidden=!0,M(e)},U=new Set,W=e=>{I(e),!(!U.has(e.value)||e.presence.isExiting)&&j(e)},G=e=>{I(e);let t=ie(e.content),n=b(e.content),r=n||t;if(r>0){let t=typeof S.performance?.now==`function`?S.performance.now():Date.now(),i=e=>(typeof S.performance?.now==`function`?S.performance.now():Date.now())-t>=Math.max(0,e-5),a=t=>{if(t.target!==e.content)return;let a=`propertyName`in t?String(t.propertyName):``;if(n>0){if(!p.has(a)||!i(n))return}else if(!i(r))return;W(e)},o=t=>{t.target===e.content&&(n>0||i(r)&&W(e))};e.content.addEventListener(`transitionend`,a),e.content.addEventListener(`animationend`,o),e.openSettleCleanups.push(()=>e.content.removeEventListener(`transitionend`,a)),e.openSettleCleanups.push(()=>e.content.removeEventListener(`animationend`,o)),e.openSettleTimeoutId=S.setTimeout(()=>{e.openSettleTimeoutId=null,W(e)},Math.ceil(r)+50);return}e.openSettleRafId=S.requestAnimationFrame(()=>{e.openSettleRafId=null,W(e)})},ue=e=>{L(e),e.closeZeroRafId=S.requestAnimationFrame(()=>{e.closeZeroRafId=null,!U.has(e.value)&&e.presence.isExiting&&M(e)})},K=e=>{e.el.setAttribute(`data-index`,String(e.index)),e.content.setAttribute(`data-index`,String(e.index)),e.content.setAttribute(`data-orientation`,T),h(e.el,`data-disabled`,e.disabled),h(e.trigger,`data-disabled`,e.disabled),h(e.content,`data-disabled`,e.disabled),e.disabled?(e.trigger.setAttribute(`aria-disabled`,`true`),e.trigger instanceof HTMLButtonElement&&(e.trigger.disabled=!0)):(e.trigger.removeAttribute(`aria-disabled`),e.trigger instanceof HTMLButtonElement&&(e.trigger.disabled=!1))},q=(e,t)=>{e.trigger.setAttribute(`data-state`,t?`open`:`closed`),h(e.trigger,`data-panel-open`,t)},de=e=>{let t=U.has(e.value);K(e),ee(e.trigger,`expanded`,t),g(e.el,t),g(e.content,t),q(e,t),e.content.removeAttribute(`data-starting-style`),e.content.removeAttribute(`data-ending-style`);let n=z(e);t?(V(e),n===`css-animation`?B(e,()=>{N(e,{resetVarsToAuto:!0})}):N(e),G(e)):H(e)},fe=e=>{let t=U.has(e.value),n=e.trigger.getAttribute(`aria-expanded`)===`true`;K(e),ee(e.trigger,`expanded`,t),g(e.el,t),g(e.content,t),q(e,t);let r=z(e);if(t){if(L(e),V(e),n&&!e.presence.isExiting&&P(e))return;r===`css-animation`?B(e,()=>{N(e,{resetVarsToAuto:!0}),n||e.presence.enter()}):(N(e),n||e.presence.enter()),G(e);return}if(n){I(e),r===`css-animation`?B(e,()=>{N(e,{resetVarsToAuto:!0}),e.presence.exit()}):(N(e),e.presence.exit(),ue(e));return}R(e),e.content.removeAttribute(`data-starting-style`),e.content.removeAttribute(`data-ending-style`),H(e)},J=e=>{let t=[],n=new Set;for(let r of e)if(!(n.has(r)||!y.some(e=>e.dataset.value===r))&&(n.add(r),t.push(r),!C&&t.length===1))break;return t},pe=e=>e.size===U.size?[...e].some(e=>!U.has(e)):!0,me=()=>{O.forEach(fe)},he=()=>{let e=[...U];n(l,`accordion:change`,{value:e}),se?.(e)},Y=e=>{let t=J(e);if(!C&&!le&&t.length===0&&U.size>0)return!1;let n=new Set(t);return pe(n)?(U=n,me(),he(),!0):!1},X=e=>(e.getAttribute(`dir`)??v.getAttribute(`dir`))===`rtl`||(getComputedStyle(e).direction||getComputedStyle(v).direction||l.ownerDocument?.documentElement.getAttribute(`dir`)||``)===`rtl`?`rtl`:`ltr`;v.setAttribute(`data-orientation`,T),h(v,`data-disabled`,!!w),y.forEach((e,n)=>{let i=e.dataset.value;if(!i)return;let a=s(e,`accordion-trigger`),o=s(e,`accordion-content`);if(!a||!o)return;let c=r(o,`accordion-content`),l=r(a,`accordion-trigger`);a.setAttribute(`aria-controls`,c),o.setAttribute(`aria-labelledby`,l),o.setAttribute(`role`,`region`);let u=!!w||m(e)||m(a),f;f={el:e,value:i,index:n,disabled:u,trigger:a,content:o,presence:t({element:o,onExitComplete:()=>{L(f),H(f)}}),sizeObserver:null,openSettleRafId:null,openSettleTimeoutId:null,closeZeroRafId:null,openSettleCleanups:[],suppressClick:!1,suppressClickTimeoutId:null},typeof ResizeObserver<`u`&&(f.sizeObserver=new ResizeObserver(()=>{!U.has(f.value)||f.presence.isExiting||P(f)||N(f)}),f.sizeObserver.observe(o)),D.push(d(a,`click`,()=>{if(f.suppressClick){F(f);return}f.disabled||(U.has(f.value)?Y([...U].filter(e=>e!==f.value)):Y(C?[...U,f.value]:[f.value]))})),D.push(d(a,`keydown`,e=>{if(re.has(e.key)){if(f.disabled){e.preventDefault();return}e.preventDefault(),F(f),f.suppressClick=!0,f.suppressClickTimeoutId=S.setTimeout(()=>{f.suppressClick=!1,f.suppressClickTimeoutId=null},0),U.has(f.value)?Y([...U].filter(e=>e!==f.value)):Y(C?[...U,f.value]:[f.value])}})),ce&&D.push(d(o,`beforematch`,()=>{Y(C?[...U,f.value]:[f.value])})),O.push(f)});let Z=new Set(O.map(e=>e.value)),Q=u.defaultValue??oe(o(l,`defaultValue`)),ge=J((Q?Array.isArray(Q)?Q:[Q]:[]).filter(e=>Z.has(e)));U=new Set(ge),O.forEach(de),D.push(d(v,`keydown`,e=>{let t=e.target;if(!t)return;let n=O.find(e=>e.trigger===t);if(!n)return;let r=O.filter(e=>!e.disabled),i=r.findIndex(e=>e.trigger===t);if(i===-1)return;let a=r.length-1,o=-1,s=()=>{o=E?i+1>a?0:i+1:Math.min(i+1,a)},c=()=>{o=E?i===0?a:i-1:Math.max(i-1,0)};switch(e.key){case`ArrowDown`:T===`vertical`&&s();break;case`ArrowUp`:T===`vertical`&&c();break;case`ArrowRight`:T===`horizontal`&&(X(n.trigger)===`rtl`?c():s());break;case`ArrowLeft`:T===`horizontal`&&(X(n.trigger)===`rtl`?s():c());break;case`Home`:o=0;break;case`End`:o=a;break;default:return}o<0||(e.preventDefault(),r[o]?.trigger.focus())})),D.push(d(l,`accordion:set`,e=>{let t=e.detail?.value;t!==void 0&&Y(Array.isArray(t)?t:[t])}));let $={expand:e=>{!Z.has(e)||U.has(e)||Y(C?[...U,e]:[e])},collapse:e=>{!Z.has(e)||!U.has(e)||Y([...U].filter(t=>t!==e))},toggle:e=>{Z.has(e)&&(U.has(e)?$.collapse(e):$.expand(e))},get value(){return[...U]},destroy:()=>{O.forEach(e=>{F(e),e.presence.cleanup(),R(e),e.sizeObserver?.disconnect(),e.sizeObserver=null}),D.forEach(e=>e()),D.length=0,e(l,x,$)}};return te(l,x,$),$}function C(e=document){let t=[];for(let n of l(e,`accordion`))u(n,x)||t.push(S(n));return t}export{C as create,S as createAccordion};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-slot/accordion",
3
- "version": "0.2.150",
3
+ "version": "0.2.152",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.cjs",
@@ -34,6 +34,6 @@
34
34
  ],
35
35
  "license": "MIT",
36
36
  "dependencies": {
37
- "@data-slot/core": "0.2.150"
37
+ "@data-slot/core": "0.2.152"
38
38
  }
39
39
  }