@mortenbrudvik/waveui 0.15.0 → 0.16.0

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.
Files changed (155) hide show
  1. package/README.md +274 -24
  2. package/dist/components/data-display/List.cjs +1 -1
  3. package/dist/components/data-display/List.cjs.map +1 -1
  4. package/dist/components/data-display/List.mjs +405 -219
  5. package/dist/components/data-display/List.mjs.map +1 -1
  6. package/dist/components/data-display/List.registry.cjs +1 -1
  7. package/dist/components/data-display/List.registry.cjs.map +1 -1
  8. package/dist/components/data-display/List.registry.mjs +12 -6
  9. package/dist/components/data-display/List.registry.mjs.map +1 -1
  10. package/dist/components/input/Combobox.cjs +1 -1
  11. package/dist/components/input/Combobox.cjs.map +1 -1
  12. package/dist/components/input/Combobox.mjs +163 -148
  13. package/dist/components/input/Combobox.mjs.map +1 -1
  14. package/dist/components/input/Dropdown.cjs +1 -1
  15. package/dist/components/input/Dropdown.cjs.map +1 -1
  16. package/dist/components/input/Dropdown.mjs +132 -117
  17. package/dist/components/input/Dropdown.mjs.map +1 -1
  18. package/dist/components/input/Listbox.cjs +1 -1
  19. package/dist/components/input/Listbox.cjs.map +1 -1
  20. package/dist/components/input/Listbox.mjs +90 -78
  21. package/dist/components/input/Listbox.mjs.map +1 -1
  22. package/dist/components/input/Option.cjs +1 -1
  23. package/dist/components/input/Option.cjs.map +1 -1
  24. package/dist/components/input/Option.data.cjs +2 -0
  25. package/dist/components/input/Option.data.cjs.map +1 -0
  26. package/dist/components/input/Option.data.mjs +114 -0
  27. package/dist/components/input/Option.data.mjs.map +1 -0
  28. package/dist/components/input/Option.mjs +21 -17
  29. package/dist/components/input/Option.mjs.map +1 -1
  30. package/dist/components/layout/FlatTree.cjs +2 -0
  31. package/dist/components/layout/FlatTree.cjs.map +1 -0
  32. package/dist/components/layout/FlatTree.context.cjs +2 -0
  33. package/dist/components/layout/FlatTree.context.cjs.map +1 -0
  34. package/dist/components/layout/FlatTree.context.mjs +20 -0
  35. package/dist/components/layout/FlatTree.context.mjs.map +1 -0
  36. package/dist/components/layout/FlatTree.item.cjs +2 -0
  37. package/dist/components/layout/FlatTree.item.cjs.map +1 -0
  38. package/dist/components/layout/FlatTree.item.mjs +90 -0
  39. package/dist/components/layout/FlatTree.item.mjs.map +1 -0
  40. package/dist/components/layout/FlatTree.mjs +276 -0
  41. package/dist/components/layout/FlatTree.mjs.map +1 -0
  42. package/dist/components/layout/Tree.core.cjs +1 -1
  43. package/dist/components/layout/Tree.core.cjs.map +1 -1
  44. package/dist/components/layout/Tree.core.mjs +166 -165
  45. package/dist/components/layout/Tree.core.mjs.map +1 -1
  46. package/dist/components/layout/Tree.selection.cjs +1 -1
  47. package/dist/components/layout/Tree.selection.cjs.map +1 -1
  48. package/dist/components/layout/Tree.selection.mjs +11 -57
  49. package/dist/components/layout/Tree.selection.mjs.map +1 -1
  50. package/dist/components/layout/useFlatTree.cjs +2 -0
  51. package/dist/components/layout/useFlatTree.cjs.map +1 -0
  52. package/dist/components/layout/useFlatTree.mjs +83 -0
  53. package/dist/components/layout/useFlatTree.mjs.map +1 -0
  54. package/dist/components/table/DataGrid.cjs +1 -1
  55. package/dist/components/table/DataGrid.cjs.map +1 -1
  56. package/dist/components/table/DataGrid.context.cjs +2 -0
  57. package/dist/components/table/DataGrid.context.cjs.map +1 -0
  58. package/dist/components/table/DataGrid.context.mjs +74 -0
  59. package/dist/components/table/DataGrid.context.mjs.map +1 -0
  60. package/dist/components/table/DataGrid.header.cjs +2 -0
  61. package/dist/components/table/DataGrid.header.cjs.map +1 -0
  62. package/dist/components/table/DataGrid.header.mjs +168 -0
  63. package/dist/components/table/DataGrid.header.mjs.map +1 -0
  64. package/dist/components/table/DataGrid.mjs +488 -591
  65. package/dist/components/table/DataGrid.mjs.map +1 -1
  66. package/dist/components/table/DataGrid.sizing.cjs +2 -0
  67. package/dist/components/table/DataGrid.sizing.cjs.map +1 -0
  68. package/dist/components/table/DataGrid.sizing.mjs +187 -0
  69. package/dist/components/table/DataGrid.sizing.mjs.map +1 -0
  70. package/dist/components/table/DataGrid.store.cjs +2 -0
  71. package/dist/components/table/DataGrid.store.cjs.map +1 -0
  72. package/dist/components/table/DataGrid.store.mjs +108 -0
  73. package/dist/components/table/DataGrid.store.mjs.map +1 -0
  74. package/dist/components/table/DataGrid.window.cjs +2 -0
  75. package/dist/components/table/DataGrid.window.cjs.map +1 -0
  76. package/dist/components/table/DataGrid.window.mjs +165 -0
  77. package/dist/components/table/DataGrid.window.mjs.map +1 -0
  78. package/dist/components/table/Table.cjs +1 -1
  79. package/dist/components/table/Table.cjs.map +1 -1
  80. package/dist/components/table/Table.mjs +74 -72
  81. package/dist/components/table/Table.mjs.map +1 -1
  82. package/dist/components/table/Table.resize.cjs +2 -0
  83. package/dist/components/table/Table.resize.cjs.map +1 -0
  84. package/dist/components/table/Table.resize.mjs +98 -0
  85. package/dist/components/table/Table.resize.mjs.map +1 -0
  86. package/dist/components/table/useGridNavigation.cjs +1 -1
  87. package/dist/components/table/useGridNavigation.cjs.map +1 -1
  88. package/dist/components/table/useGridNavigation.mjs +343 -140
  89. package/dist/components/table/useGridNavigation.mjs.map +1 -1
  90. package/dist/components/table/useTableColumnSizing.cjs +2 -0
  91. package/dist/components/table/useTableColumnSizing.cjs.map +1 -0
  92. package/dist/components/table/useTableColumnSizing.mjs +76 -0
  93. package/dist/components/table/useTableColumnSizing.mjs.map +1 -0
  94. package/dist/components/table/useTableFeatures.cjs +2 -0
  95. package/dist/components/table/useTableFeatures.cjs.map +1 -0
  96. package/dist/components/table/useTableFeatures.mjs +110 -0
  97. package/dist/components/table/useTableFeatures.mjs.map +1 -0
  98. package/dist/components/table/useTableSelection.cjs +2 -0
  99. package/dist/components/table/useTableSelection.cjs.map +1 -0
  100. package/dist/components/table/useTableSelection.mjs +39 -0
  101. package/dist/components/table/useTableSelection.mjs.map +1 -0
  102. package/dist/components/table/useTableSort.cjs +2 -0
  103. package/dist/components/table/useTableSort.cjs.map +1 -0
  104. package/dist/components/table/useTableSort.mjs +58 -0
  105. package/dist/components/table/useTableSort.mjs.map +1 -0
  106. package/dist/hooks/useActiveDescendant.cjs +1 -1
  107. package/dist/hooks/useActiveDescendant.cjs.map +1 -1
  108. package/dist/hooks/useActiveDescendant.mjs +33 -25
  109. package/dist/hooks/useActiveDescendant.mjs.map +1 -1
  110. package/dist/hooks/useListbox.cjs +1 -1
  111. package/dist/hooks/useListbox.cjs.map +1 -1
  112. package/dist/hooks/useListbox.mjs +140 -130
  113. package/dist/hooks/useListbox.mjs.map +1 -1
  114. package/dist/hooks/useRovingTabIndex.cjs +1 -1
  115. package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
  116. package/dist/hooks/useRovingTabIndex.mjs +1 -1
  117. package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
  118. package/dist/hooks/useSelection.cjs +2 -0
  119. package/dist/hooks/useSelection.cjs.map +1 -0
  120. package/dist/hooks/useSelection.mjs +57 -0
  121. package/dist/hooks/useSelection.mjs.map +1 -0
  122. package/dist/hooks/useVirtualWindow.cjs +2 -0
  123. package/dist/hooks/useVirtualWindow.cjs.map +1 -0
  124. package/dist/hooks/useVirtualWindow.mjs +102 -0
  125. package/dist/hooks/useVirtualWindow.mjs.map +1 -0
  126. package/dist/index.cjs +1 -1
  127. package/dist/index.d.cts +1542 -53
  128. package/dist/index.d.ts +1542 -53
  129. package/dist/index.mjs +147 -136
  130. package/dist/lib/classNames.cjs +1 -1
  131. package/dist/lib/classNames.cjs.map +1 -1
  132. package/dist/lib/classNames.mjs +68 -49
  133. package/dist/lib/classNames.mjs.map +1 -1
  134. package/dist/lib/columnSizing.cjs +2 -0
  135. package/dist/lib/columnSizing.cjs.map +1 -0
  136. package/dist/lib/columnSizing.mjs +27 -0
  137. package/dist/lib/columnSizing.mjs.map +1 -0
  138. package/dist/lib/flatTree.cjs +2 -0
  139. package/dist/lib/flatTree.cjs.map +1 -0
  140. package/dist/lib/flatTree.mjs +118 -0
  141. package/dist/lib/flatTree.mjs.map +1 -0
  142. package/dist/lib/selection.cjs +2 -0
  143. package/dist/lib/selection.cjs.map +1 -0
  144. package/dist/lib/selection.mjs +28 -0
  145. package/dist/lib/selection.mjs.map +1 -0
  146. package/dist/lib/treeCascade.cjs +2 -0
  147. package/dist/lib/treeCascade.cjs.map +1 -0
  148. package/dist/lib/treeCascade.mjs +52 -0
  149. package/dist/lib/treeCascade.mjs.map +1 -0
  150. package/dist/lib/virtual.cjs +2 -0
  151. package/dist/lib/virtual.cjs.map +1 -0
  152. package/dist/lib/virtual.mjs +54 -0
  153. package/dist/lib/virtual.mjs.map +1 -0
  154. package/dist/styles.css +1 -1
  155. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/children.cjs"),r=require("../../lib/dev.cjs"),i=require("../../lib/slot.cjs"),a=require("../../lib/composeEventHandlers.cjs"),o=require("../../lib/classNames.cjs"),s=require("../../hooks/useEventCallback.cjs"),c=require("../../hooks/useControllable.cjs"),ee=require("../../hooks/useId.cjs"),l=require("../../lib/direction.cjs"),u=require("../../lib/focus.cjs"),d=require("../../hooks/useRovingTabIndex.cjs"),te=require("../../hooks/useMergedRefs.cjs"),f=require("../../lib/aria.cjs"),ne=require("../../lib/styles.cjs"),p=require("../../lib/icons.cjs"),m=require("../../lib/events.cjs"),h=require("./List.registry.cjs");let g=require("react");g=e.__toESM(g,1);let _=require("react/jsx-runtime");var v=g.createContext(null);v.displayName=`ListContext`;var y=null;function b(){return y??={mode:`list`,navigable:!1,selection:!1,checkmark:!1,selectedValues:new Set,toggleItem:()=>{},getTabIndex:()=>-1,registry:new h.ListRegistry},y}function re(e){return g.useContext(v)||(r.reportMissingContext(e,`a List`),b())}var x=[];function S(e,t,n){return n===`composite`||e&&t?{mode:`grid`,navigation:`composite`}:e?{mode:`listbox`,navigation:`items`}:{mode:`list`,navigation:n===`items`?`items`:`none`}}function C(e){r.warnOnce(`List:duplicate:${e}`,`List: several items share the value "${e}". Item values must be unique within a List; items with the same value are selected (and tab stops) together.`)}function ie(e){return n.flattenChildren(e).some(({node:e})=>n.isElementOfType(e,z)&&i.slotRendersContent(e.props.action))}var w={interactive:`${m.INTERACTIVE_SELECTOR}, [data-list-action]`};function T(e){return m.isForeignEvent(e,w)}function E(e){return e.ctrlKey||e.altKey||e.metaKey?!1:e.key===`Enter`||e.key===` `}var D=new Set([`textbox`,`searchbox`,`combobox`,`spinbutton`,`slider`]),O=new Set([`button`,`checkbox`,`color`,`file`,`hidden`,`image`,`radio`,`reset`,`submit`]);function k(e){let t=e.getAttribute(`role`);if(t!==null&&D.has(t))return!0;let n=e.localName;return n===`textarea`||n===`select`?!0:n===`input`?!O.has(e.type):e.matches(`[contenteditable]:not([contenteditable="false"])`)}function A(e){return Array.from(e.querySelectorAll(u.FOCUSABLE_SELECTOR)).filter(e=>u.isFocusable(e))}function j(e){if(!e.parentElement)return-1;let t=0;for(let n=e.previousElementSibling;n;n=n.previousElementSibling)t++;return t}function M(e,t){let n=null,r=null,i=null,a=0;for(let o=e.firstElementChild;o;o=o.nextElementSibling,a++){if(t.value!==void 0&&o.getAttribute(`data-roving-value`)===t.value){n=o;break}a===t.index&&(r=o),i=o}let o=n??r??(t.index>=0?i:null);return o?o.hasAttribute(`tabindex`)?o:A(o)[0]??null:null}function N(e){for(let t=e.firstElementChild;t;t=t.nextElementSibling)if(t.hasAttribute(`data-list-action`))return t;return null}function P(e){let t=[];for(let n of A(e)){let r=k(n)?e:n;t.includes(r)||t.push(r)}return t}var F=e=>{let{selectable:n=!1,selectionMode:i,selectedItems:s,defaultSelectedItems:ee,onSelectionChange:l,selectedItem:u,defaultSelectedItem:f,onSelectedItemChange:ne,navigationMode:p,checkmark:m=!1,className:y,children:b,ref:re,onKeyDown:w,onKeyDownCapture:T,onFocus:E,...D}=e;i===`multi`&&r.warnDeprecated(`List`,`selectionMode="multi"`,`selectionMode="multiple"`);let O=i===`multiple`||i===`multi`,k=g.useMemo(()=>!O&&u!==void 0?u===null?x:[u]:s,[O,u,s]),j=g.useMemo(()=>!O&&f!=null?[f]:ee??x,[O,f,ee]),[N,P]=c.useControllable(k,j,e=>{let t=[...e];l?.(t),O||ne?.(t[0]??null)}),[F]=g.useState(()=>new h.ListRegistry),I=g.useSyncExternalStore(F.subscribe,F.getSnapshot,F.getServerSnapshot),L=g.useMemo(()=>I?N.filter(e=>I.valueSet.has(e)):N,[I,N]),R=g.useMemo(()=>new Set(L),[L]),z=n&&p!==`composite`&&(I?I.hasActions:ie(b)),{mode:B,navigation:V}=S(n,z,p),H=V!==`none`,U=n&&m;g.useLayoutEffect(()=>{F.setActive(H)},[F,H]);let W=I?I.values.find(e=>R.has(e))??null:L[0]??null,{containerProps:G,getTabIndex:K}=d.useRovingTabIndex({activeValue:n?W:null,orientation:`vertical`,typeahead:(I?.count??0)>7,tabStop:n?`active`:`last-focused`,itemSelector:`:scope > [data-roving-value]`}),{ref:ae,onKeyDown:q,onKeyDownCapture:J,onFocus:Y}=G,X=g.useRef(null),Z=te.useMergedRefs(re,H?ae:null,X);g.useLayoutEffect(()=>{let e=F.takeFocusLoss(),t=X.current;if(!e||!t)return;let n=t.ownerDocument,r=n.activeElement;r&&r!==n.body&&r.isConnected||M(t,e)?.focus()},[B,F]),g.useLayoutEffect(()=>{if(H)return;let e=X.current,t=e?.ownerDocument.activeElement;t&&t.parentElement===e&&!t.hasAttribute(`tabindex`)&&A(t)[0]?.focus()},[H]),g.useLayoutEffect(()=>{F.syncOrder(X.current)});let Q=g.useCallback(e=>{P(t=>{let n=F.prune(t),r=n.includes(e);return O?r?n.filter(t=>t!==e):[...n,e]:r?[]:[e]})},[O,F,P]),oe=I?.duplicates??x;g.useEffect(()=>{for(let e of oe)C(e)},[oe]);let $=L.length;g.useEffect(()=>{n&&!O&&$>1&&r.warnOnce(`List:single-several-selected`,`List: a single-selection list (selectionMode "single") received ${$} selected items. Pass one value with \`selectedItem\`, or use selectionMode="multiple".`)},[n,O,$]);let se=n&&p===`items`&&z,ce=n&&p===`none`;g.useEffect(()=>{se&&r.warnOnce(`List:items-with-actions`,`List: a selectable list whose items have actions is a grid (an option cannot hold interactive content), so navigationMode="items" acts as "composite". Set navigationMode="composite".`),ce&&r.warnOnce(`List:none-selectable`,`List: navigationMode="none" has no effect on a selectable list, whose items are always reached with the arrow keys. Remove it, or use "items" or "composite".`)},[se,ce]);let le=g.useMemo(()=>({mode:B,navigable:H,selection:n,checkmark:U,selectedValues:R,toggleItem:Q,getTabIndex:K,registry:F}),[B,H,n,U,R,Q,K,F]),ue=B===`grid`?`div`:`ul`,de=B===`grid`?`grid`:B===`listbox`?`listbox`:`list`;return(0,_.jsx)(v.Provider,{value:le,children:(0,_.jsx)(ue,{role:de,"aria-multiselectable":n&&O?!0:void 0,"data-navigation-mode":V,"data-checkmark":U?``:void 0,className:t.cn(o.listClassNames.root,`m-0 list-none p-0`,y),...D,ref:Z,"data-roving-container":H?``:void 0,onKeyDown:H?a.composeEventHandlers(w,q):w,onKeyDownCapture:H?a.composeEventHandlers(T,J):T,onFocus:H?a.composeEventHandlers(E,Y,{checkDefaultPrevented:!1}):E,children:b})})};F.displayName=`List`;var I=`forced-colors:text-[Highlight] forced-colors:forced-color-adjust-none`,L=`forced-colors:text-[GrayText] forced-colors:forced-color-adjust-none`;function R(e,{selected:n,disabled:r}){let a=t.cn(o.listItemClassNames.checkmark,`order-first me-2 inline-flex shrink-0 items-center justify-center`,r?[`text-muted-foreground`,L]:[`text-primary`,I],!n&&`invisible`);return e===void 0?(0,_.jsx)(`span`,{"aria-hidden":`true`,className:a,children:(0,_.jsx)(p.CheckIcon,{})}):i.renderSlot(e,`span`,a,{"aria-hidden":!0})}var z=({value:e,action:n,onAction:c,disabledSelection:u=!1,checkmark:d,className:p,children:m,onClick:h,onKeyDown:v,ref:y,...b})=>{let{mode:x,navigable:S,selection:C,checkmark:ie,selectedValues:w,toggleItem:D,getTabIndex:O,registry:M}=re(`ListItem`),F=ee.useId(`list-item`),I=e||void 0,L=I??F,z=i.slotRendersContent(n),[B]=g.useState(()=>({})),V=g.useRef(null),H=te.useMergedRefs(y,V);g.useLayoutEffect(()=>{M.set(B,{value:I,hasAction:z,element:V})},[M,B,I,z]),g.useLayoutEffect(()=>()=>M.delete(B),[M,B]);let W=s.useEventCallback(e=>{let t=e.parentElement;M.recordFocusLoss({value:I,index:t?j(t):-1})});g.useLayoutEffect(()=>{let e=V.current;return()=>{if(!e)return;let t=e.ownerDocument.activeElement;t&&e.contains(t)&&M.recordFocusLoss({value:I,index:j(e)})}},[M,I]);let G=c!==void 0&&!S;g.useEffect(()=>{G&&r.warnOnce(`List.Item:action-not-navigable`,'List.Item: `onAction` runs only on clicks here: the List does not navigate its items, so keyboard users cannot reach them. Set navigationMode="items" (or "composite") on the List, or make it selectable.')},[G]);let K=C&&I!==void 0&&w.has(I),ae=C&&I!==void 0,q=C&&u,J=q&&c===void 0,Y=()=>{C&&!u&&I!==void 0&&D(I)},X=e=>{c?.(e),e.isDefaultPrevented()||Y()},Z=e=>{T(e)||X(e)},Q=e=>{if(e.key===` `&&ae){e.preventDefault(),Y();return}(C||c!==void 0)&&(X(e),e.preventDefault())},oe=e=>{T(e)||E(e)&&Q(e)},$=e=>{let t=e.currentTarget,n=e.target,r=N(t);if(!r||!r.contains(n)){if(n!==t)return;if(E(e)){Q(e);return}let i=l.getArrowIntent(e.key,{orientation:`horizontal`,dir:l.getDirection(t)})===`next`&&r?P(r)[0]:void 0;i&&(e.preventDefault(),i.focus());return}if(n!==r&&k(n)){e.key===`Escape`&&(e.preventDefault(),r.focus());return}if(n===r&&(e.key===`Enter`||e.key===`F2`)){let t=A(r).find(e=>k(e));t&&(e.preventDefault(),t.focus());return}let i=l.getArrowIntent(e.key,{orientation:`horizontal`,dir:l.getDirection(t)});if(!i)return;e.preventDefault();let a=P(r),o=a.indexOf(n);i===`next`?a[o+1]?.focus():o>0?a[o-1].focus():t.focus()},se=x===`grid`?`div`:`li`,ce=x===`grid`?`div`:`span`,le=x===`grid`?`row`:x===`listbox`?`option`:`listitem`,ue=S?{"aria-selected":C?K:void 0,tabIndex:O(L),"data-roving-value":L,"data-selected":K?``:void 0,...f.focusableDisabledProps(J,{reachable:!0}),onClick:a.composeEventHandlers(h,Z),onKeyDown:a.composeEventHandlers(v,x===`grid`?$:oe)}:{onClick:c?a.composeEventHandlers(h,Z):h,onKeyDown:v},de=C?J?`cursor-default`:`cursor-pointer`:c&&`cursor-pointer`,fe=C?!J:c!==void 0,pe=d!=null&&i.slotRendersContent(d),me=C&&(d==null?ie:pe);return(0,_.jsxs)(se,{role:le,"data-disabled-selection":q?``:void 0,className:t.cn(o.listItemClassNames.root,`flex items-center border-b border-border px-4 py-2 text-body-1`,S?[`relative`,de,ne.focusRingInset]:de,K?[`bg-subtle-selected before:absolute before:inset-y-2 before:start-0 before:w-0.5 before:rounded-full before:bg-primary`,ne.forcedColors.selectedContainer]:fe&&`hover:bg-subtle-hover`,p),...b,ref:H,...ue,children:[(0,_.jsx)(ce,{role:x===`grid`?`gridcell`:void 0,className:t.cn(o.listItemClassNames.content,`min-w-0 flex-1`),children:m}),z&&(0,_.jsx)(U,{grid:x===`grid`,onRemovedWithFocus:W,children:i.materialiseSlotContent(n)}),me&&R(pe?d:void 0,{selected:K,disabled:q})]})};z.displayName=`ListItem`;var B=[`[data-roving-container]`,...[`toolbar`,`radiogroup`,`listbox`,`grid`,`treegrid`,`tablist`,`menu`,`menubar`,`tree`].map(e=>`[role="${e}"]`)].join(`, `),V=[`tabindex`,`href`,`contenteditable`,`controls`];function H(e){let t=new Map,n=new WeakSet,r=()=>{for(let n of t.keys())e.contains(n)||t.delete(n);for(let r of e.querySelectorAll(u.FOCUSABLE_SELECTOR)){let i=r.getAttribute(`tabindex`);if(i===`-1`||n.has(r))continue;let a=r.closest(B);a&&e.contains(a)||(t.set(r,i),r.setAttribute(`tabindex`,`-1`))}};if(r(),typeof MutationObserver>`u`)return()=>{};let i=new MutationObserver(e=>{let a=new Set;for(let n of e){let e=n.target;n.attributeName===`tabindex`&&t.has(e)&&a.add(e)}for(let e of a){let r=e.getAttribute(`tabindex`);r!==`-1`&&r===t.get(e)?(t.delete(e),n.add(e)):t.set(e,r)}r(),i.takeRecords()});return i.observe(e,{subtree:!0,childList:!0,attributes:!0,attributeFilter:V}),()=>{i.disconnect();for(let[e,n]of t)n===null?e.removeAttribute(`tabindex`):e.setAttribute(`tabindex`,n);t.clear()}}function U({grid:e,onRemovedWithFocus:n,children:r}){let i=g.useRef(null);return g.useLayoutEffect(()=>{let e=i.current;return()=>{if(!e)return;let t=e.ownerDocument.activeElement;t&&e.contains(t)&&n(e)}},[n,e]),g.useLayoutEffect(()=>{let t=i.current;return e&&t?H(t):void 0},[e]),(0,_.jsx)(e?`div`:`span`,{ref:i,role:e?`gridcell`:void 0,tabIndex:e?-1:void 0,"data-list-action":``,className:t.cn(o.listItemClassNames.action,`ms-2 shrink-0`,e&&`focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring`),children:r})}U.displayName=`ListActionCell`;var W=Object.assign(F,{Item:z});exports.List=W,exports.ListItem=z;
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/children.cjs"),r=require("../../lib/dev.cjs"),i=require("../../lib/slot.cjs"),a=require("../../lib/composeEventHandlers.cjs"),o=require("../../lib/classNames.cjs"),s=require("../../hooks/useEventCallback.cjs"),c=require("../../hooks/useControllable.cjs"),ee=require("../../hooks/useId.cjs"),l=require("../../lib/direction.cjs"),u=require("../../lib/focus.cjs"),d=require("../../hooks/useRovingTabIndex.cjs"),te=require("../../hooks/useMergedRefs.cjs"),f=require("../../lib/aria.cjs"),p=require("../../lib/styles.cjs"),ne=require("../../lib/icons.cjs"),m=require("../../lib/events.cjs"),re=require("./List.registry.cjs");let h=require("react");h=e.__toESM(h,1);let g=require("react/jsx-runtime");var _=h.createContext(null);_.displayName=`ListContext`;var ie=h.createContext(null);ie.displayName=`ListItemIndexContext`;var v=null;function y(){return v??={mode:`list`,navigable:!1,selection:!1,checkmark:!1,selectedValues:new Set,toggleItem:()=>{},getTabIndex:()=>-1,registry:new re.ListRegistry,listWindow:null},v}function ae(e){return h.useContext(_)||(r.reportMissingContext(e,`a List`),y())}var oe=[];function b(e,t,n){return n===`composite`||e&&t?{mode:`grid`,navigation:`composite`}:e?{mode:`listbox`,navigation:`items`}:{mode:`list`,navigation:n===`items`?`items`:`none`}}function se(e){r.warnOnce(`List:duplicate:${e}`,`List: several items share the value "${e}". Item values must be unique within a List; items with the same value are selected (and tab stops) together.`)}function x(e){return n.flattenChildren(e).some(({node:e})=>n.isElementOfType(e,H)&&i.slotRendersContent(e.props.action))}var ce={interactive:`${m.INTERACTIVE_SELECTOR}, [data-list-action]`};function S(e){return m.isForeignEvent(e,ce)}function le(e){return e.ctrlKey||e.altKey||e.metaKey?!1:e.key===`Enter`||e.key===` `}var C=new Set([`textbox`,`searchbox`,`combobox`,`spinbutton`,`slider`]),w=new Set([`button`,`checkbox`,`color`,`file`,`hidden`,`image`,`radio`,`reset`,`submit`]);function T(e){let t=e.getAttribute(`role`);if(t!==null&&C.has(t))return!0;let n=e.localName;return n===`textarea`||n===`select`?!0:n===`input`?!w.has(e.type):e.matches(`[contenteditable]:not([contenteditable="false"])`)}function E(e){return Array.from(e.querySelectorAll(u.FOCUSABLE_SELECTOR)).filter(e=>u.isFocusable(e))}function D(e){if(!e.parentElement)return-1;let t=0;for(let n=e.previousElementSibling;n;n=n.previousElementSibling)t++;return t}function O(e){return e.hasAttribute(`tabindex`)?e:E(e)[0]??null}function k(e,t,n){let r=null,i=null,a=null,o=0;for(let s=e.firstElementChild;s;s=s.nextElementSibling,o++){let e=n?j(s):o;if(e!==null){if(t.value!==void 0&&s.getAttribute(`data-roving-value`)===t.value){r=s;break}e===t.index&&(i=s),a=s}}let s=r??i??(t.index>=0?a:null);return s?O(s):null}function A(e){return e!==void 0&&Number.isFinite(e)?Math.max(0,Math.floor(e)):0}function ue(...e){return e.filter(e=>e!==null)}function j(e){let t=e.getAttribute(`data-index`);return t!==null&&/^\d+$/.test(t)?Number(t):null}function de(e,t){let n=t instanceof Element?t:null;for(;n&&n.parentElement!==e;)n=n.parentElement;return n?j(n):null}function M(e,t){for(let n=e.firstElementChild;n;n=n.nextElementSibling)if(j(n)===t)return n;return null}var N=10;function P(e,t,n){let r=n-1,i=t===null?null:Math.min(t,r);switch(e){case`ArrowDown`:return i===null||i===r?0:i+1;case`ArrowUp`:return i===null||i===0?r:i-1;case`PageDown`:return i===null?0:Math.min(i+N,r);case`PageUp`:return i===null?r:Math.max(i-N,0);case`Home`:return 0;case`End`:return r;default:return}}var F={focused:null,pending:null},I=class{state=F;listeners=new Set;subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)});getSnapshot=()=>this.state;getServerSnapshot=()=>F;update(e){let t={...this.state,...e};if(t.focused!==this.state.focused||t.pending!==this.state.pending){this.state=t;for(let e of this.listeners)e()}}};function fe({grid:e,size:t}){return(0,g.jsx)(e?`div`:`li`,{"aria-hidden":`true`,role:`presentation`,"data-virtual-spacer":``,className:o.listClassNames.spacer,style:{height:t}})}fe.displayName=`ListSpacer`;function L(e){for(let t=e.firstElementChild;t;t=t.nextElementSibling)if(t.hasAttribute(`data-list-action`))return t;return null}function R(e){let t=[];for(let n of E(e)){let r=T(n)?e:n;t.includes(r)||t.push(r)}return t}var z=e=>{let{selectable:n=!1,selectionMode:i,selectedItems:ee,defaultSelectedItems:l,onSelectionChange:u,selectedItem:f,defaultSelectedItem:p,onSelectedItemChange:ne,navigationMode:m,checkmark:v=!1,virtualWindow:y,count:ae,className:ce,children:S,ref:le,onKeyDown:C,onKeyDownCapture:w,onFocus:T,onBlur:D,...j}=e,N=typeof S==`function`?S:null,L=y!==void 0&&ae!==void 0&&N?y:null,R=L!==null,z=!R&&(y!==void 0||ae!==void 0||N!==null),B=R?A(ae):0,V=L?.itemSize,pe=h.useMemo(()=>V===void 0?null:{count:B,itemSize:V},[B,V]);i===`multi`&&r.warnDeprecated(`List`,`selectionMode="multi"`,`selectionMode="multiple"`);let H=i===`multiple`||i===`multi`,U=h.useMemo(()=>!H&&f!==void 0?f===null?oe:[f]:ee,[H,f,ee]),W=h.useMemo(()=>!H&&p!=null?[p]:l??oe,[H,p,l]),[G,me]=c.useControllable(U,W,e=>{let t=[...e];u?.(t),H||ne?.(t[0]??null)}),[K]=h.useState(()=>new re.ListRegistry),q=h.useSyncExternalStore(K.subscribe,K.getSnapshot,K.getServerSnapshot),J=h.useMemo(()=>q&&!R?G.filter(e=>q.valueSet.has(e)):G,[q,G,R]),he=h.useMemo(()=>new Set(J),[J]),[Y]=h.useState(()=>new I),{focused:ge,pending:_e}=h.useSyncExternalStore(Y.subscribe,Y.getSnapshot,Y.getServerSnapshot),ve=h.useMemo(()=>ue(ge,_e),[ge,_e]),X=L&&N?L.layout(B,{keep:ve}).map(e=>e.kind===`item`?{...e,node:N(e.index)}:e):null,ye=N?null:S,be=n&&m!==`composite`&&(q?q.hasActions:x(X?X.map(e=>e.kind===`item`?e.node:null):ye)),xe=be&&!R,Se=be&&R,{mode:Z,navigation:Ce}=b(n,xe,m),Q=Ce!==`none`,we=n&&v;h.useLayoutEffect(()=>{K.setActive(Q)},[K,Q]);let Te=q?q.values.find(e=>he.has(e))??null:J[0]??null,Ee=s.useEventCallback((e,t)=>{let n=t.currentTarget,r=n.ownerDocument.activeElement,i=r?de(n,r):null;i!==null&&L?.scrollToIndex(i,{align:`auto`})}),{containerProps:De,getTabIndex:Oe}=d.useRovingTabIndex({activeValue:n?Te:null,orientation:`vertical`,onFocusMove:R?Ee:void 0,typeahead:(R?B:q?.count??0)>7,tabStop:n&&!(R&&ge!==null)?`active`:`last-focused`,itemSelector:`:scope > [data-roving-value]`}),{ref:ke,onKeyDown:Ae,onKeyDownCapture:je,onFocus:Me}=De,$=h.useRef(null),Ne=te.useMergedRefs(le,Q?ke:null,$,L?.scrollRef),Pe=h.useRef(!1),Fe=s.useEventCallback(e=>{Q&&Me(e);let t=e.currentTarget;Pe.current=!t.contains(e.target);let n=de(t,e.target);n!==null&&Y.update({focused:n,pending:null})}),Ie=R?Fe:Q?Me:void 0,Le=s.useEventCallback(e=>{let t=e.currentTarget,n=e.relatedTarget;n&&t.contains(n)||(Pe.current=!1,queueMicrotask(()=>{if(!t.isConnected||Pe.current)return;let e=t.ownerDocument.activeElement;e&&t.contains(e)||Y.update(F)}))}),Re=s.useEventCallback(e=>{if(!L||e.defaultPrevented||B===0||e.ctrlKey||e.altKey||e.metaKey)return;let t=e.currentTarget;if(!t.contains(e.target)||d.ownsArrowKeys(e.target))return;let n=de(t,e.target),r=P(e.key,Y.getSnapshot().pending??n,B);if(r===void 0)return;if(e.preventDefault(),r===n){Y.update({pending:null}),L.scrollToIndex(r,{align:`auto`});return}let i=M(t,r);if(i){Y.update({pending:null}),i.scrollIntoView?.({block:`nearest`}),O(i)?.focus();return}let a=Y.getSnapshot().pending;Y.update({pending:r}),a!==r&&L.scrollToIndex(r,{align:`auto`})}),ze=s.useEventCallback(e=>{R&&Re(e),Ae(e)});h.useLayoutEffect(()=>{let e=K.takeFocusLoss(),t=$.current;if(!e||!t)return;let n=t.ownerDocument,r=n.activeElement;r&&r!==n.body&&r.isConnected||k(t,e,R)?.focus()},[Z,K,R]),h.useLayoutEffect(()=>{let e=$.current;if(!R||!e){Y.update(F);return}let t=e.ownerDocument,n=t.activeElement,r=!n||n===t.body||!n.isConnected||n===e,{pending:i}=Y.getSnapshot();if(i!==null){Y.update({pending:null});let t=i<B?M(e,i):null;t&&(r||e.contains(n))&&O(t)?.focus()}let{focused:a}=Y.getSnapshot();if(!(a===null||a<B)){if(r&&B>0){let t=M(e,B-1);if(t)O(t)?.focus();else{Y.update({focused:null,pending:B-1}),L?.scrollToIndex(B-1,{align:`auto`});return}}Y.getSnapshot().focused===a&&Y.update({focused:null})}}),h.useLayoutEffect(()=>{if(Q)return;let e=$.current,t=e?.ownerDocument.activeElement;t&&t.parentElement===e&&!t.hasAttribute(`tabindex`)&&E(t)[0]?.focus()},[Q]),h.useLayoutEffect(()=>{K.syncOrder($.current)});let Be=h.useCallback(e=>{me(t=>{let n=R?t:K.prune(t),r=n.includes(e);return H?r?n.filter(t=>t!==e):[...n,e]:r?[]:[e]})},[H,K,me,R]),Ve=q?.duplicates??oe;h.useEffect(()=>{for(let e of Ve)se(e)},[Ve]);let He=J.length;h.useEffect(()=>{n&&!H&&He>1&&r.warnOnce(`List:single-several-selected`,`List: a single-selection list (selectionMode "single") received ${He} selected items. Pass one value with \`selectedItem\`, or use selectionMode="multiple".`)},[n,H,He]);let Ue=n&&m===`items`&&xe,We=n&&m===`none`;h.useEffect(()=>{Ue&&r.warnOnce(`List:items-with-actions`,`List: a selectable list whose items have actions is a grid (an option cannot hold interactive content), so navigationMode="items" acts as "composite". Set navigationMode="composite".`),We&&r.warnOnce(`List:none-selectable`,`List: navigationMode="none" has no effect on a selectable list, whose items are always reached with the arrow keys. Remove it, or use "items" or "composite".`)},[Ue,We]),h.useEffect(()=>{z&&r.warnOnce(`List:virtual-window-children`,"List: a windowed list needs `virtualWindow`, `count` and a function child that returns the `List.Item` at an index; without one of them the window is ignored (a function child then renders nothing, and element children are all rendered).")},[z]),h.useEffect(()=>{Se&&r.warnOnce(`List:virtual-window-actions`,`List: a selectable windowed list keeps its listbox structure whatever items are rendered, so an item action sits inside an option, which cannot hold interactive content. Set navigationMode="composite" to render a grid whose rows hold the actions.`)},[Se]);let Ge=h.useMemo(()=>({mode:Z,navigable:Q,selection:n,checkmark:we,selectedValues:he,toggleItem:Be,getTabIndex:Oe,registry:K,listWindow:pe}),[Z,Q,n,we,he,Be,Oe,K,pe]),Ke=Z===`grid`?`div`:`ul`,qe=Z===`grid`?`grid`:Z===`listbox`?`listbox`:`list`,Je=X?X.map(e=>e.kind===`item`?(0,g.jsx)(ie.Provider,{value:e.index,children:e.node},e.index):(0,g.jsx)(fe,{grid:Z===`grid`,size:e.size},e.key)):ye;return(0,g.jsx)(_.Provider,{value:Ge,children:(0,g.jsx)(Ke,{role:qe,"aria-multiselectable":n&&H?!0:void 0,"aria-rowcount":R&&Z===`grid`?B:void 0,"data-navigation-mode":Ce,"data-checkmark":we?``:void 0,tabIndex:R&&Q?-1:void 0,className:t.cn(o.listClassNames.root,`m-0 list-none p-0`,R&&`overflow-y-auto [overflow-anchor:none]`,ce),...j,ref:Ne,"data-roving-container":Q?``:void 0,onKeyDown:Q?a.composeEventHandlers(C,ze):C,onKeyDownCapture:Q?a.composeEventHandlers(w,je):w,onFocus:Ie?a.composeEventHandlers(T,Ie,{checkDefaultPrevented:!1}):T,onBlur:R?a.composeEventHandlers(D,Le,{checkDefaultPrevented:!1}):D,children:Je})})};z.displayName=`List`;var B=`forced-colors:text-[Highlight] forced-colors:forced-color-adjust-none`,V=`forced-colors:text-[GrayText] forced-colors:forced-color-adjust-none`;function pe(e,{selected:n,disabled:r}){let a=t.cn(o.listItemClassNames.checkmark,`order-first me-2 inline-flex shrink-0 items-center justify-center`,r?[`text-muted-foreground`,V]:[`text-primary`,B],!n&&`invisible`);return e===void 0?(0,g.jsx)(`span`,{"aria-hidden":`true`,className:a,children:(0,g.jsx)(ne.CheckIcon,{})}):i.renderSlot(e,`span`,a,{"aria-hidden":!0})}var H=({value:e,action:n,onAction:c,disabledSelection:u=!1,checkmark:d,className:ne,style:m,children:re,onClick:_,onKeyDown:v,ref:y,...oe})=>{let{mode:b,navigable:se,selection:x,checkmark:ce,selectedValues:C,toggleItem:w,getTabIndex:O,registry:k,listWindow:A}=ae(`ListItem`),ue=h.useContext(ie),j=A?ue:null,de=ee.useId(`list-item`),M=e||void 0,N=M??de,P=i.slotRendersContent(n),[F]=h.useState(()=>({})),I=h.useRef(null),fe=te.useMergedRefs(y,I);h.useLayoutEffect(()=>{k.set(F,{value:M,hasAction:P,element:I,index:j??void 0})},[k,F,M,P,j]),h.useLayoutEffect(()=>()=>k.delete(F),[k,F]);let z=s.useEventCallback(e=>{let t=e.parentElement;k.recordFocusLoss({value:M,index:j??(t?D(t):-1)})});h.useLayoutEffect(()=>{let e=I.current;return()=>{if(!e)return;let t=e.ownerDocument.activeElement;t&&e.contains(t)&&k.recordFocusLoss({value:M,index:j??D(e)})}},[k,M,j]);let B=c!==void 0&&!se;h.useEffect(()=>{B&&r.warnOnce(`List.Item:action-not-navigable`,'List.Item: `onAction` runs only on clicks here: the List does not navigate its items, so keyboard users cannot reach them. Set navigationMode="items" (or "composite") on the List, or make it selectable.')},[B]);let V=x&&M!==void 0&&C.has(M),H=x&&M!==void 0,U=x&&u,W=U&&c===void 0,G=()=>{x&&!u&&M!==void 0&&w(M)},K=e=>{c?.(e),e.isDefaultPrevented()||G()},q=e=>{S(e)||K(e)},J=e=>{if(e.key===` `&&H){e.preventDefault(),G();return}(x||c!==void 0)&&(K(e),e.preventDefault())},he=e=>{S(e)||le(e)&&J(e)},Y=e=>{let t=e.currentTarget,n=e.target,r=L(t);if(!r||!r.contains(n)){if(n!==t)return;if(le(e)){J(e);return}let i=l.getArrowIntent(e.key,{orientation:`horizontal`,dir:l.getDirection(t)})===`next`&&r?R(r)[0]:void 0;i&&(e.preventDefault(),i.focus());return}if(n!==r&&T(n)){e.key===`Escape`&&(e.preventDefault(),r.focus());return}if(n===r&&(e.key===`Enter`||e.key===`F2`)){let t=E(r).find(e=>T(e));t&&(e.preventDefault(),t.focus());return}let i=l.getArrowIntent(e.key,{orientation:`horizontal`,dir:l.getDirection(t)});if(!i)return;e.preventDefault();let a=R(r),o=a.indexOf(n);i===`next`?a[o+1]?.focus():o>0?a[o-1].focus():t.focus()},ge=b===`grid`?`div`:`li`,_e=b===`grid`?`div`:`span`,ve=b===`grid`?`row`:b===`listbox`?`option`:`listitem`,X=se?{"aria-selected":x?V:void 0,tabIndex:O(N),"data-roving-value":N,"data-selected":V?``:void 0,...f.focusableDisabledProps(W,{reachable:!0}),onClick:a.composeEventHandlers(_,q),onKeyDown:a.composeEventHandlers(v,b===`grid`?Y:he)}:{onClick:c?a.composeEventHandlers(_,q):_,onKeyDown:v},ye=x?W?`cursor-default`:`cursor-pointer`:c&&`cursor-pointer`,be=x?!W:c!==void 0,xe=d!=null&&i.slotRendersContent(d),Se=x&&(d==null?ce:xe),Z=A&&j!==null?{"data-index":j,...b===`grid`?{"aria-rowindex":j+1}:{"aria-setsize":A.count,"aria-posinset":j+1}}:{};return(0,g.jsxs)(ge,{role:ve,"data-disabled-selection":U?``:void 0,className:t.cn(o.listItemClassNames.root,`flex items-center border-b border-border px-4 py-2 text-body-1`,j!==null&&`box-border`,se?[`relative`,ye,p.focusRingInset]:ye,V?[`bg-subtle-selected before:absolute before:inset-y-2 before:start-0 before:w-0.5 before:rounded-full before:bg-primary`,p.forcedColors.selectedContainer]:be&&`hover:bg-subtle-hover`,ne),style:A&&j!==null?{...m,height:A.itemSize}:m,...oe,ref:fe,...X,...Z,children:[(0,g.jsx)(_e,{role:b===`grid`?`gridcell`:void 0,className:t.cn(o.listItemClassNames.content,`min-w-0 flex-1`),children:re}),P&&(0,g.jsx)(me,{grid:b===`grid`,onRemovedWithFocus:z,children:i.materialiseSlotContent(n)}),Se&&pe(xe?d:void 0,{selected:V,disabled:U})]})};H.displayName=`ListItem`;var U=[`[data-roving-container]`,...[`toolbar`,`radiogroup`,`listbox`,`grid`,`treegrid`,`tablist`,`menu`,`menubar`,`tree`].map(e=>`[role="${e}"]`)].join(`, `),W=[`tabindex`,`href`,`contenteditable`,`controls`];function G(e){let t=new Map,n=new WeakSet,r=()=>{for(let n of t.keys())e.contains(n)||t.delete(n);for(let r of e.querySelectorAll(u.FOCUSABLE_SELECTOR)){let i=r.getAttribute(`tabindex`);if(i===`-1`||n.has(r))continue;let a=r.closest(U);a&&e.contains(a)||(t.set(r,i),r.setAttribute(`tabindex`,`-1`))}};if(r(),typeof MutationObserver>`u`)return()=>{};let i=new MutationObserver(e=>{let a=new Set;for(let n of e){let e=n.target;n.attributeName===`tabindex`&&t.has(e)&&a.add(e)}for(let e of a){let r=e.getAttribute(`tabindex`);r!==`-1`&&r===t.get(e)?(t.delete(e),n.add(e)):t.set(e,r)}r(),i.takeRecords()});return i.observe(e,{subtree:!0,childList:!0,attributes:!0,attributeFilter:W}),()=>{i.disconnect();for(let[e,n]of t)n===null?e.removeAttribute(`tabindex`):e.setAttribute(`tabindex`,n);t.clear()}}function me({grid:e,onRemovedWithFocus:n,children:r}){let i=h.useRef(null);return h.useLayoutEffect(()=>{let e=i.current;return()=>{if(!e)return;let t=e.ownerDocument.activeElement;t&&e.contains(t)&&n(e)}},[n,e]),h.useLayoutEffect(()=>{let t=i.current;return e&&t?G(t):void 0},[e]),(0,g.jsx)(e?`div`:`span`,{ref:i,role:e?`gridcell`:void 0,tabIndex:e?-1:void 0,"data-list-action":``,className:t.cn(o.listItemClassNames.action,`ms-2 shrink-0`,e&&`focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring`),children:r})}me.displayName=`ListActionCell`;var K=Object.assign(z,{Item:H});exports.List=K,exports.ListItem=H;
2
2
  //# sourceMappingURL=List.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"List.cjs","names":["React","ListRegistry","flattenChildren","isElementOfType","slotRendersContent","INTERACTIVE_SELECTOR","isForeignEvent","FOCUSABLE_SELECTOR","isFocusable","useControllable","useRovingTabIndex","useMergedRefs","cn","listClassNames","composeEventHandlers","listItemClassNames","CheckIcon","renderSlot","useId","useEventCallback","getArrowIntent","getDirection","focusableDisabledProps","focusRingInset","forcedColors","materialiseSlotContent","require_runtime","require_cn","require_children","require_dev","require_slot","require_composeEventHandlers","require_classNames","require_useEventCallback","require_useControllable","require_useId","require_direction","require_focus","require_useRovingTabIndex","require_useMergedRefs","require_aria","require_styles","require_icons","require_events","require_List_registry","react","react_jsx_runtime","ListContext","inertContext","getInertContext","useListContext","componentName","EMPTY","resolveNavigation","navigationMode","selectable","hasActions","warnDuplicateValue","value","childrenHaveAction","children","node","ListItem","ITEM_FOREIGN_EVENTS","isForeignItemEvent","event","isActivationKey","TEXT_ENTRY_ROLES","NON_TEXT_INPUT_TYPES","isTextEntry","role","el","tag","getFocusables","cell","getItemIndex","item","index","getFocusRestoreTarget","byValue","atIndex","last","root","loss","getActionCell","child","getActionStops","stops","stop","ListRoot","rest","props","selectionMode","multiple","controlledSelection","selectedItem","selectedItems","defaultSelection","defaultSelectedItem","defaultSelectedItems","selected","setSelected","selection","next","onSelectionChange","onSelectedItemChange","registry","registered","effective","selectedValues","navigable","navigation","drawsCheckmark","checkmark","tabStopValue","rovingRef","rovingKeyDown","rovingKeyDownCapture","rovingFocus","containerProps","rootElementRef","rootRef","ref","doc","active","mode","toggleItem","current","previous","isSelected","duplicates","selectedCount","itemsWithActions","noneSelectable","contextValue","getTabIndex","Root","className","onKeyDown","onKeyDownCapture","onFocus","CHECKMARK_FORCED_COLORS","CHECKMARK_DISABLED_FORCED_COLORS","renderCheckmark","classes","disabled","glyph","listCheckmark","autoValue","selectableValue","rovingValue","hasAction","action","token","itemRef","itemRefs","recordActionFocusLoss","actionNotNavigable","onAction","itemSelectable","selectionDisabled","disabledSelection","ariaDisabled","toggle","activate","handleClick","handleActivationKey","handleOptionKeyDown","handleRowKeyDown","rowElement","target","first","entry","intent","Element","ContentCell","interactiveProps","onClick","cursor","hoverable","customCheckmark","showCheckmark","ListActionCell","COMPOSITE_SELECTOR","STAMP_OBSERVED_ATTRIBUTES","stampActionCell","stamped","yielded","stamp","tabIndex","composite","observer","changed","record","records","original","cellRef","onRemovedWithFocus","grid","List"],"sources":["../../../src/components/data-display/List.tsx"],"sourcesContent":["import * as React from 'react';\nimport { focusableDisabledProps } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport { listClassNames, listItemClassNames } from '../../lib/classNames';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { reportMissingContext, warnDeprecated, warnOnce } from '../../lib/dev';\nimport { getArrowIntent, getDirection } from '../../lib/direction';\nimport { INTERACTIVE_SELECTOR, isForeignEvent, type ForeignEventOptions } from '../../lib/events';\nimport { FOCUSABLE_SELECTOR, isFocusable } from '../../lib/focus';\nimport { CheckIcon } from '../../lib/icons';\nimport { materialiseSlotContent, renderSlot, slotRendersContent, type Slot } from '../../lib/slot';\nimport { focusRingInset, forcedColors } from '../../lib/styles';\nimport type { SelectionMode } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useRovingTabIndex } from '../../hooks/useRovingTabIndex';\nimport { ListRegistry, type ListFocusLoss } from './List.registry';\n\n/** Selection modes of {@link List}: the shared `SelectionMode` plus the deprecated `'multi'`. */\nexport type ListSelectionMode = SelectionMode | 'multi';\n\n/**\n * How the keyboard reaches the items of a {@link List} (Fluent's `navigationMode`): `'none'`, no\n * item is a Tab stop; `'items'`, the items are one Tab stop moved with the arrow keys; `'composite'`,\n * a grid whose rows are moved with Up/Down and whose actions are reached with Right/Left.\n */\nexport type ListNavigationMode = 'none' | 'items' | 'composite';\n\n/** The event that activated a list item: a click, or Enter or Space on the focused item. */\nexport type ListItemActionEvent = React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>;\n\n/**\n * Properties for the List component.\n *\n * The type parameter `M` is the `selectionMode` literal. It makes the single-selection props\n * (`selectedItem`, `defaultSelectedItem`, `onSelectedItemChange`) type errors when\n * `selectionMode=\"multiple\"` is passed; `ListProps` without a type argument accepts every mode\n * (the 0.4 shape, extendable by interfaces).\n */\nexport interface ListProps<\n M extends ListSelectionMode = ListSelectionMode,\n> extends React.HTMLAttributes<HTMLUListElement> {\n /** Whether list items can be selected.\n * @default false\n */\n selectable?: boolean;\n /**\n * Selection behavior when `selectable` is true. `'multi'` is a deprecated alias of `'multiple'`.\n * @default 'single'\n */\n selectionMode?: M;\n /**\n * Controlled array of selected item values (both modes). In single mode prefer `selectedItem`;\n * a single-selection list that receives several values warns in development.\n */\n selectedItems?: readonly string[];\n /** Default selected items for uncontrolled usage.\n * @default []\n */\n defaultSelectedItems?: readonly string[];\n /** Called with the next array of selected values when the selection changes (both modes). */\n onSelectionChange?: (selected: string[]) => void;\n /** Single mode: the controlled selected value (`null`: nothing selected). */\n selectedItem?: M extends 'single' ? string | null : never;\n /** Single mode: the initially selected value for uncontrolled usage. */\n defaultSelectedItem?: M extends 'single' ? string | null : never;\n /** Single mode: called with the newly selected value, or `null` when it was deselected. */\n onSelectedItemChange?: M extends 'single' ? (item: string | null) => void : never;\n /**\n * How the keyboard reaches the items. Unset, the list picks the mode itself: `'none'` for a plain\n * list, `'items'` for a selectable one (a listbox) and `'composite'` (a grid) for a selectable\n * list whose items have actions, which remounts the items when the first action appears or the\n * last one disappears. An explicit value pins the structure:\n *\n * - `'none'`: a plain list; its items are no Tab stops (their actions stay in the Tab order). A\n * selectable list always navigates its items: there `'none'` is ignored, with a development\n * warning.\n * - `'items'`: the items are one Tab stop (the first selected item, else the first item; in a\n * list without selection the item that last had focus), moved with ArrowUp/ArrowDown (wrapping)\n * and Home/End, with typeahead for more than 7 items. A plain list keeps `role=\"list\"` and its\n * items carry no `aria-selected`; their actions stay in the Tab order. A selectable list whose\n * items have actions acts as `'composite'`, with a development warning.\n * - `'composite'`: a grid (`role=\"grid\"`, `row`s and `gridcell`s) from the first render, so the\n * items never remount when actions appear. One Tab stop; Up/Down move between the rows and\n * Right/Left (mirrored in right-to-left layouts) into and out of their actions, which leave\n * the Tab order. The rows of a list without selection carry no `aria-selected`.\n *\n * The resolved mode is rendered as `data-navigation-mode`. Changing it while mounted can switch\n * between `ul`/`li` and `div` elements, which remounts the items (see {@link List}).\n */\n navigationMode?: ListNavigationMode;\n /**\n * Draws a check mark at the start of every item of a selectable list, shown while the item is\n * selected (decorative: `aria-selected` carries the state). An item's own `checkmark` replaces\n * or hides it. Renders `data-checkmark` on the list while it draws them.\n * @default false\n */\n checkmark?: boolean;\n /**\n * Ref to the root element: a `<ul>`, or a `<div role=\"grid\">` for a selectable list whose items\n * have actions and for `navigationMode=\"composite\"`.\n */\n ref?: React.Ref<HTMLUListElement | HTMLDivElement>;\n}\n\n/** Properties for the ListItem component. */\nexport interface ListItemProps extends React.HTMLAttributes<HTMLLIElement> {\n /**\n * Unique value identifying this item for selection tracking. An item without a value cannot be\n * selected (its `onClick` still runs). Items of a selectable list that share a value are\n * selected together (a development warning names the value).\n */\n value?: string;\n /**\n * Action element rendered at the end of the list item (e.g. a Delete button). Clicks and keys\n * that start inside it, or inside a popup it opens, never toggle the item's selection. An\n * action that renders nothing (`[]`, `null`, `false`, `''`, `<></>`) is no action. In a\n * selectable list, items with actions switch the list to grid semantics: the actions are reached\n * with the arrow keys, and their focusable elements (also ones added later) get\n * `tabindex=\"-1\"`, except inside a nested composite widget such as a Toolbar, which keeps its own\n * Tab stop. When the first action appears or the last one disappears, the items remount (see\n * {@link List}), unless the List's `navigationMode=\"composite\"` keeps the grid.\n */\n action?: React.ReactNode;\n /**\n * Called when the item is activated: a click on it, or Enter on the focused item, and Space on\n * an item that cannot be selected (in a list without selection, or without a `value`); in a\n * selectable item Space only toggles the selection. Clicks and keys that start in an action or\n * in interactive content never run it. It runs after the item's `onClick` (whose\n * `preventDefault()` skips it) and before the selection toggles: call `event.preventDefault()`\n * to keep the selection as it is. Fires on every activation. The items of a list that does not\n * navigate them (`navigationMode` `'none'`, not selectable) cannot be reached with the keyboard:\n * there it runs on clicks only, and a development warning says so.\n */\n onAction?: (event: ListItemActionEvent) => void;\n /**\n * In a selectable list: the item's selection cannot be toggled (click, Enter or Space; a\n * selected item stays selected). The item stays focusable and in the arrow-key order and renders\n * `data-disabled-selection`. Without `onAction` it is also `aria-disabled` (with `data-disabled`\n * and `data-disabled-focusable`); with `onAction`, clicks and Enter still run the action, while\n * Space, the selection key, does nothing. The item's `onClick` runs either way.\n * @default false\n */\n disabledSelection?: boolean;\n /**\n * The item's check mark in a selectable list, a decorative `<span>` at the start of the item\n * shown while it is selected. `null` and `undefined` follow the List's `checkmark` (the default\n * check, or none); content replaces the glyph, also when the List draws none; `false`, or\n * content that renders nothing, hides it.\n */\n checkmark?: Slot<'span'>;\n /** Ref to the item element: an `<li>`, or a `<div role=\"row\">` in grid mode. */\n ref?: React.Ref<HTMLLIElement | HTMLDivElement>;\n}\n\n/* ------------------------------------------------------------------ */\n/* Context */\n/* ------------------------------------------------------------------ */\n\n/**\n * The list's structure: `list` (`ul`/`li`, `role=\"list\"`), `listbox` (selectable, `option`s) or\n * `grid` (`div`s with `row`s: a selectable list with item actions, or `navigationMode=\"composite\"`).\n */\ntype ListMode = 'list' | 'listbox' | 'grid';\n\ninterface ListContextValue {\n mode: ListMode;\n /** The items are the list's arrow-key stops (a selectable list, or `items`/`composite`). */\n navigable: boolean;\n /** The list is selectable: its items carry `aria-selected`. */\n selection: boolean;\n /** The List draws the default check mark on its items (a selectable list with `checkmark`). */\n checkmark: boolean;\n selectedValues: ReadonlySet<string>;\n toggleItem: (value: string) => void;\n getTabIndex: (value: string) => 0 | -1;\n registry: ListRegistry;\n}\n\nconst ListContext = React.createContext<ListContextValue | null>(null);\nListContext.displayName = 'ListContext';\n\nlet inertContext: ListContextValue | null = null;\n\nfunction getInertContext(): ListContextValue {\n inertContext ??= {\n mode: 'list',\n navigable: false,\n selection: false,\n checkmark: false,\n selectedValues: new Set<string>(),\n toggleItem: () => {},\n getTabIndex: () => -1,\n registry: new ListRegistry(),\n };\n return inertContext;\n}\n\nfunction useListContext(componentName: string): ListContextValue {\n const context = React.useContext(ListContext);\n if (context) return context;\n reportMissingContext(componentName, 'a List');\n return getInertContext();\n}\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nconst EMPTY: readonly string[] = [];\n\n/**\n * The structure and the effective navigation mode of a list. Unset, a selectable list is a listbox,\n * or a grid while an item has an action. In a selectable list, `'none'` is ignored and `'items'`\n * with actions acts as `'composite'` (an option cannot hold interactive content); both warn.\n */\nfunction resolveNavigation(\n selectable: boolean,\n hasActions: boolean,\n navigationMode: ListNavigationMode | undefined,\n): { mode: ListMode; navigation: ListNavigationMode } {\n if (navigationMode === 'composite' || (selectable && hasActions)) {\n return { mode: 'grid', navigation: 'composite' };\n }\n if (selectable) return { mode: 'listbox', navigation: 'items' };\n return { mode: 'list', navigation: navigationMode === 'items' ? 'items' : 'none' };\n}\n\n/** Items that share a value are selected together and share their roving value. */\nfunction warnDuplicateValue(value: string): void {\n warnOnce(\n `List:duplicate:${value}`,\n `List: several items share the value \"${value}\". Item values must be unique within a ` +\n 'List; items with the same value are selected (and tab stops) together.',\n );\n}\n\n/**\n * Static look-ahead for the server and the first render: a direct `List.Item` (Fragments\n * flattened, also an item written in a Server Component) whose action renders content.\n */\nfunction childrenHaveAction(children: React.ReactNode): boolean {\n return flattenChildren(children).some(\n ({ node }) =>\n isElementOfType<ListItemProps>(node, ListItem) && slotRendersContent(node.props.action),\n );\n}\n\n/** Elements whose events belong to themselves, not to the item: also the item's action cell. */\nconst ITEM_FOREIGN_EVENTS: ForeignEventOptions = {\n interactive: `${INTERACTIVE_SELECTOR}, [data-list-action]`,\n};\n\n/**\n * Whether an item must leave `event` alone (no selection toggle): it started inside the action\n * cell or a nested interactive element, or outside the item's DOM. React bubbles the events of a\n * popup portaled from an action (a Popover, Menu or Dialog) through the item's handlers although\n * their target lives elsewhere in the document; those never toggle the item (as in Card).\n */\nfunction isForeignItemEvent(event: React.SyntheticEvent<HTMLElement>): boolean {\n return isForeignEvent(event, ITEM_FOREIGN_EVENTS);\n}\n\n/**\n * Enter or Space without Ctrl, Alt or Meta: the keys that activate an item. With a modifier\n * (Ctrl+Alt with Space included) the key is a shortcut, left to the page.\n */\nfunction isActivationKey(event: React.KeyboardEvent): boolean {\n if (event.ctrlKey || event.altKey || event.metaKey) return false;\n return event.key === 'Enter' || event.key === ' ';\n}\n\nconst TEXT_ENTRY_ROLES: ReadonlySet<string> = new Set([\n 'textbox',\n 'searchbox',\n 'combobox',\n 'spinbutton',\n 'slider',\n]);\n\nconst NON_TEXT_INPUT_TYPES: ReadonlySet<string> = new Set([\n 'button',\n 'checkbox',\n 'color',\n 'file',\n 'hidden',\n 'image',\n 'radio',\n 'reset',\n 'submit',\n]);\n\n/** Text-entry widgets keep the arrow keys (caret movement) and are entered with Enter/F2. */\nfunction isTextEntry(el: Element): boolean {\n const role = el.getAttribute('role');\n if (role !== null && TEXT_ENTRY_ROLES.has(role)) return true;\n const tag = el.localName;\n if (tag === 'textarea' || tag === 'select') return true;\n if (tag === 'input') return !NON_TEXT_INPUT_TYPES.has((el as HTMLInputElement).type);\n return el.matches('[contenteditable]:not([contenteditable=\"false\"])');\n}\n\nfunction getFocusables(cell: HTMLElement): HTMLElement[] {\n return Array.from(cell.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter((el) =>\n isFocusable(el),\n );\n}\n\n/*\n * The helpers below walk element children with `firstElementChild`/`nextElementSibling`, never\n * through a `children` collection: jsdom before 30.1 does not cache indexed `HTMLCollection`\n * access, so `Array.from(root.children)` or an indexed loop over a large list is O(n²) in the test\n * suites of consumers on those versions (table-core#22).\n */\n\n/** Position of an item element among its list's items (the root's element children). */\nfunction getItemIndex(item: HTMLElement): number {\n if (!item.parentElement) return -1;\n let index = 0;\n for (let el = item.previousElementSibling; el; el = el.previousElementSibling) index++;\n return index;\n}\n\n/**\n * Where focus goes after the items remounted: the item with the same explicit value, else the item\n * now at the same position (the next one when the focused item itself was removed), else the last.\n * An item that cannot take focus itself (a plain list item) passes it to its first focusable\n * descendant.\n */\nfunction getFocusRestoreTarget(root: HTMLElement, loss: ListFocusLoss): HTMLElement | null {\n let byValue: Element | null = null;\n let atIndex: Element | null = null;\n let last: Element | null = null;\n let index = 0;\n for (let el = root.firstElementChild; el; el = el.nextElementSibling, index++) {\n if (loss.value !== undefined && el.getAttribute('data-roving-value') === loss.value) {\n byValue = el;\n break;\n }\n if (index === loss.index) atIndex = el;\n last = el;\n }\n const item = (byValue ?? atIndex ?? (loss.index >= 0 ? last : null)) as HTMLElement | null;\n if (!item) return null;\n return item.hasAttribute('tabindex') ? item : (getFocusables(item)[0] ?? null);\n}\n\n/** The action cell of an item element (its direct `[data-list-action]` child), read at event time. */\nfunction getActionCell(item: HTMLElement): HTMLElement | null {\n for (let child = item.firstElementChild; child; child = child.nextElementSibling) {\n if (child.hasAttribute('data-list-action')) return child as HTMLElement;\n }\n return null;\n}\n\n/**\n * The arrow-key stops inside an action cell, in DOM order. A text-entry widget is represented by\n * the cell itself (the cell takes focus; Enter/F2 enter the widget, Escape returns to the cell).\n */\nfunction getActionStops(cell: HTMLElement): HTMLElement[] {\n const stops: HTMLElement[] = [];\n for (const el of getFocusables(cell)) {\n const stop = isTextEntry(el) ? cell : el;\n if (!stops.includes(stop)) stops.push(stop);\n }\n return stops;\n}\n\n/* ------------------------------------------------------------------ */\n/* List */\n/* ------------------------------------------------------------------ */\n\n// The List root, documented on the exported `List` const.\nconst ListRoot = <M extends ListSelectionMode = 'single'>(props: ListProps<M>): React.ReactNode => {\n const {\n selectable = false,\n selectionMode,\n selectedItems,\n defaultSelectedItems,\n onSelectionChange,\n selectedItem,\n defaultSelectedItem,\n onSelectedItemChange,\n navigationMode,\n checkmark = false,\n className,\n children,\n ref,\n onKeyDown,\n onKeyDownCapture,\n onFocus,\n ...rest\n } = props as ListProps;\n\n if (selectionMode === 'multi') {\n warnDeprecated('List', 'selectionMode=\"multi\"', 'selectionMode=\"multiple\"');\n }\n const multiple = selectionMode === 'multiple' || selectionMode === 'multi';\n\n const controlledSelection = React.useMemo<readonly string[] | undefined>(() => {\n if (!multiple && selectedItem !== undefined) {\n return selectedItem === null ? EMPTY : [selectedItem];\n }\n return selectedItems;\n }, [multiple, selectedItem, selectedItems]);\n const defaultSelection = React.useMemo<readonly string[]>(() => {\n if (!multiple && defaultSelectedItem !== undefined && defaultSelectedItem !== null) {\n return [defaultSelectedItem];\n }\n return defaultSelectedItems ?? EMPTY;\n }, [multiple, defaultSelectedItem, defaultSelectedItems]);\n\n const [selected, setSelected] = useControllable<readonly string[]>(\n controlledSelection,\n defaultSelection,\n (next) => {\n // The callbacks receive their own mutable copy (the props accept readonly arrays).\n const selection = [...next];\n onSelectionChange?.(selection);\n if (!multiple) onSelectedItemChange?.(selection[0] ?? null);\n },\n );\n\n const [registry] = React.useState(() => new ListRegistry());\n const registered = React.useSyncExternalStore(\n registry.subscribe,\n registry.getSnapshot,\n registry.getServerSnapshot,\n );\n\n // Effective selection: selected ∩ registered item values, derived during render (table-core#22).\n const effective = React.useMemo(\n () => (registered ? selected.filter((value) => registered.valueSet.has(value)) : selected),\n [registered, selected],\n );\n const selectedValues = React.useMemo<ReadonlySet<string>>(() => new Set(effective), [effective]);\n\n // Only a selectable list without the `composite` pin decides its structure by its actions.\n const hasActions =\n selectable &&\n navigationMode !== 'composite' &&\n (registered ? registered.hasActions : childrenHaveAction(children));\n const { mode, navigation } = resolveNavigation(selectable, hasActions, navigationMode);\n const navigable = navigation !== 'none';\n const drawsCheckmark = selectable && checkmark;\n\n // A navigable list reads its items' registrations (count, values, order); a plain one never does.\n React.useLayoutEffect(() => {\n registry.setActive(navigable);\n }, [registry, navigable]);\n\n // The first selected item in DOM order (the registry keeps its values in DOM order).\n const tabStopValue = registered\n ? (registered.values.find((value) => selectedValues.has(value)) ?? null)\n : (effective[0] ?? null);\n\n const { containerProps, getTabIndex } = useRovingTabIndex({\n activeValue: selectable ? tabStopValue : null,\n orientation: 'vertical',\n typeahead: (registered?.count ?? 0) > 7,\n // A list without selection returns to the item that last had focus.\n tabStop: selectable ? 'active' : 'last-focused',\n // The items are the root's children. A composite in an item action (a Toolbar, a radio group)\n // is part of its row, not an item: arrows and typeahead never move into it.\n itemSelector: ':scope > [data-roving-value]',\n });\n const {\n ref: rovingRef,\n onKeyDown: rovingKeyDown,\n onKeyDownCapture: rovingKeyDownCapture,\n onFocus: rovingFocus,\n } = containerProps;\n const rootElementRef = React.useRef<HTMLUListElement | HTMLDivElement | null>(null);\n const rootRef = useMergedRefs<HTMLUListElement | HTMLDivElement>(\n ref,\n navigable ? rovingRef : null,\n rootElementRef,\n );\n\n // Switching between list and grid semantics changes the root and item elements (`ul`/`li` ↔\n // `div`), so React remounts the items and the focused one is removed. Items record, while they\n // are still in the document, that they held focus (see ListItem); after the new items mounted,\n // focus moves to the same item (C-DISABLED: focus is never dropped to <body>).\n React.useLayoutEffect(() => {\n const loss = registry.takeFocusLoss();\n const root = rootElementRef.current;\n if (!loss || !root) return;\n const doc = root.ownerDocument;\n const active = doc.activeElement;\n // Focus placed elsewhere in this commit (an autoFocus, a restore-focus hook) wins.\n if (active && active !== doc.body && active.isConnected) return;\n getFocusRestoreTarget(root, loss)?.focus();\n }, [mode, registry]);\n\n // A plain list that stops navigating (`items` to `none`) keeps its item elements, but they lose\n // their tabindex: focus on one moves to its first focusable content, as after a remount.\n React.useLayoutEffect(() => {\n if (navigable) return;\n const root = rootElementRef.current;\n const active = root?.ownerDocument.activeElement;\n if (!active || active.parentElement !== root || active.hasAttribute('tabindex')) return;\n getFocusables(active as HTMLElement)[0]?.focus();\n }, [navigable]);\n\n // After every commit (the items' layout effects ran first): keep the registered values in DOM\n // order, so `tabStopValue` is the first selected item in the DOM even after items were inserted\n // between others or reordered by key (table-core#22). O(n); re-renders only when the order changed.\n React.useLayoutEffect(() => {\n registry.syncOrder(rootElementRef.current);\n });\n\n const toggleItem = React.useCallback(\n (value: string) => {\n setSelected((previous) => {\n // From the effective selection, so values of removed items are never reported again.\n const current = registry.prune(previous);\n const isSelected = current.includes(value);\n if (multiple) {\n return isSelected ? current.filter((item) => item !== value) : [...current, value];\n }\n return isSelected ? [] : [value];\n });\n },\n [multiple, registry, setSelected],\n );\n\n // Registered values of a selectable list that more than one item holds (development warning).\n const duplicates = registered?.duplicates ?? EMPTY;\n React.useEffect(() => {\n for (const value of duplicates) warnDuplicateValue(value);\n }, [duplicates]);\n\n const selectedCount = effective.length;\n React.useEffect(() => {\n if (selectable && !multiple && selectedCount > 1) {\n warnOnce(\n 'List:single-several-selected',\n `List: a single-selection list (selectionMode \"single\") received ${selectedCount} selected items. Pass one value with \\`selectedItem\\`, or use selectionMode=\"multiple\".`,\n );\n }\n }, [selectable, multiple, selectedCount]);\n\n const itemsWithActions = selectable && navigationMode === 'items' && hasActions;\n const noneSelectable = selectable && navigationMode === 'none';\n React.useEffect(() => {\n if (itemsWithActions) {\n warnOnce(\n 'List:items-with-actions',\n 'List: a selectable list whose items have actions is a grid (an option cannot hold interactive content), so navigationMode=\"items\" acts as \"composite\". Set navigationMode=\"composite\".',\n );\n }\n if (noneSelectable) {\n warnOnce(\n 'List:none-selectable',\n 'List: navigationMode=\"none\" has no effect on a selectable list, whose items are always reached with the arrow keys. Remove it, or use \"items\" or \"composite\".',\n );\n }\n }, [itemsWithActions, noneSelectable]);\n\n const contextValue = React.useMemo<ListContextValue>(\n () => ({\n mode,\n navigable,\n selection: selectable,\n checkmark: drawsCheckmark,\n selectedValues,\n toggleItem,\n getTabIndex,\n registry,\n }),\n [\n mode,\n navigable,\n selectable,\n drawsCheckmark,\n selectedValues,\n toggleItem,\n getTabIndex,\n registry,\n ],\n );\n\n const Root = (mode === 'grid' ? 'div' : 'ul') as React.ElementType;\n const role = mode === 'grid' ? 'grid' : mode === 'listbox' ? 'listbox' : 'list';\n\n return (\n <ListContext.Provider value={contextValue}>\n <Root\n role={role}\n aria-multiselectable={selectable && multiple ? true : undefined}\n data-navigation-mode={navigation}\n data-checkmark={drawsCheckmark ? '' : undefined}\n className={cn(listClassNames.root, 'm-0 list-none p-0', className)}\n {...rest}\n ref={rootRef}\n data-roving-container={navigable ? '' : undefined}\n onKeyDown={navigable ? composeEventHandlers(onKeyDown, rovingKeyDown) : onKeyDown}\n onKeyDownCapture={\n navigable\n ? composeEventHandlers(onKeyDownCapture, rovingKeyDownCapture)\n : onKeyDownCapture\n }\n onFocus={\n navigable\n ? composeEventHandlers(onFocus, rovingFocus, { checkDefaultPrevented: false })\n : onFocus\n }\n >\n {children}\n </Root>\n </ListContext.Provider>\n );\n};\nListRoot.displayName = 'List';\n\n/* ------------------------------------------------------------------ */\n/* ListItem */\n/* ------------------------------------------------------------------ */\n\n/**\n * Forced colors: the check takes the `Highlight` of the selected item's outline, `GrayText` while\n * its selection is disabled. Both opt the check (a leaf indicator) out of forced colors, so the\n * system color reaches the glyph.\n */\nconst CHECKMARK_FORCED_COLORS =\n 'forced-colors:text-[Highlight] forced-colors:forced-color-adjust-none';\nconst CHECKMARK_DISABLED_FORCED_COLORS =\n 'forced-colors:text-[GrayText] forced-colors:forced-color-adjust-none';\n\n/**\n * The check mark of an item of a selectable list: decorative, kept in its place but not drawn while\n * the item is not selected, so the item texts line up. It is the item's last element and is drawn\n * first (flex order): the item's text, which typeahead reads, starts with its content. `glyph` is\n * the item's `checkmark` when it renders content, else `undefined` for the default check.\n */\nfunction renderCheckmark(\n glyph: Slot<'span'> | undefined,\n { selected, disabled }: { selected: boolean; disabled: boolean },\n): React.ReactNode {\n const classes = cn(\n listItemClassNames.checkmark,\n 'order-first me-2 inline-flex shrink-0 items-center justify-center',\n disabled\n ? ['text-muted-foreground', CHECKMARK_DISABLED_FORCED_COLORS]\n : ['text-primary', CHECKMARK_FORCED_COLORS],\n !selected && 'invisible',\n );\n return glyph === undefined ? (\n <span aria-hidden=\"true\" className={classes}>\n <CheckIcon />\n </span>\n ) : (\n renderSlot(glyph, 'span', classes, { 'aria-hidden': true })\n );\n}\n\n/**\n * An item of a {@link List} (also available as `List.Item`). Renders an `<li>` (`listitem`, or\n * `option` in a selectable list), or a `<div role=\"row\">` in a grid (a selectable list with\n * actions, or `navigationMode=\"composite\"`). In a selectable list, Enter and Space toggle the\n * selection without calling `onClick`, which receives pointer clicks; `onAction` runs on clicks\n * and Enter (and Space where the item cannot be selected), before the selection toggles.\n *\n * Exported under the flat name `ListItem` so React Server Components can import it; `List.Item`\n * (dotted access) needs a client module.\n */\nexport const ListItem = ({\n value,\n action,\n onAction,\n disabledSelection = false,\n checkmark,\n className,\n children,\n onClick,\n onKeyDown,\n ref,\n ...rest\n}: ListItemProps) => {\n const {\n mode,\n navigable,\n selection,\n checkmark: listCheckmark,\n selectedValues,\n toggleItem,\n getTabIndex,\n registry,\n } = useListContext('ListItem');\n const autoValue = useId('list-item');\n const selectableValue = value ? value : undefined;\n const rovingValue = selectableValue ?? autoValue;\n // An action that renders nothing (`[]`, `null`, booleans, `''`) is no action.\n const hasAction = slotRendersContent(action);\n const [token] = React.useState(() => ({}));\n const itemRef = React.useRef<HTMLLIElement | HTMLDivElement | null>(null);\n const itemRefs = useMergedRefs<HTMLLIElement | HTMLDivElement>(ref, itemRef);\n\n // The record is updated in place when the value or the action changes and removed only on\n // unmount, so the item keeps its place in the registry (table-core#22).\n React.useLayoutEffect(() => {\n registry.set(token, { value: selectableValue, hasAction, element: itemRef });\n }, [registry, token, selectableValue, hasAction]);\n React.useLayoutEffect(() => () => registry.delete(token), [registry, token]);\n\n // Focus inside the action when it disappears: if that switches the list from grid to listbox, the\n // List moves focus to this item in the next commit (see ListActionCell and ListRoot).\n const recordActionFocusLoss = useEventCallback((cell: HTMLElement) => {\n const item = cell.parentElement;\n registry.recordFocusLoss({ value: selectableValue, index: item ? getItemIndex(item) : -1 });\n });\n\n // Unmount: a layout-effect cleanup runs while the element is still in the document, so it can\n // tell whether it held focus. The List moves focus to the same item when its items remount\n // (list ↔ grid semantics); see ListRoot.\n React.useLayoutEffect(() => {\n const node = itemRef.current;\n return () => {\n if (!node) return;\n const active = node.ownerDocument.activeElement;\n if (active && node.contains(active)) {\n registry.recordFocusLoss({ value: selectableValue, index: getItemIndex(node) });\n }\n };\n }, [registry, selectableValue]);\n\n // C-DEV: an item that is no Tab stop cannot be activated with the keyboard.\n const actionNotNavigable = onAction !== undefined && !navigable;\n React.useEffect(() => {\n if (actionNotNavigable) {\n warnOnce(\n 'List.Item:action-not-navigable',\n 'List.Item: `onAction` runs only on clicks here: the List does not navigate its items, so keyboard users cannot reach them. Set navigationMode=\"items\" (or \"composite\") on the List, or make it selectable.',\n );\n }\n }, [actionNotNavigable]);\n\n const isSelected =\n selection && selectableValue !== undefined && selectedValues.has(selectableValue);\n // The item can be selected (a selectable list, and a value); `disabledSelection` keeps it as is.\n const itemSelectable = selection && selectableValue !== undefined;\n const selectionDisabled = selection && disabledSelection;\n // Without an action, an item whose selection is disabled can do nothing: it is aria-disabled.\n const ariaDisabled = selectionDisabled && onAction === undefined;\n\n const toggle = () => {\n if (selection && !disabledSelection && selectableValue !== undefined) {\n toggleItem(selectableValue);\n }\n };\n\n /** A click or Enter: `onAction`, then the selection unless `onAction` called preventDefault(). */\n const activate = (event: ListItemActionEvent) => {\n onAction?.(event);\n if (!event.isDefaultPrevented()) toggle();\n };\n\n const handleClick = (event: React.MouseEvent<HTMLElement>) => {\n if (isForeignItemEvent(event)) return;\n activate(event);\n };\n\n /** Enter or Space on the focused item itself. */\n const handleActivationKey = (event: React.KeyboardEvent<HTMLElement>) => {\n if (event.key === ' ' && itemSelectable) {\n // Space is the selection key of an item that can be selected: it never runs onAction.\n event.preventDefault();\n toggle();\n return;\n }\n // An item with nothing to activate leaves the key to the page.\n if (!selection && onAction === undefined) return;\n // Not prevented before: `onAction` may cancel the selection with preventDefault().\n activate(event);\n // Space would scroll the page.\n event.preventDefault();\n };\n\n const handleOptionKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n if (isForeignItemEvent(event)) return;\n if (isActivationKey(event)) handleActivationKey(event);\n };\n\n const handleRowKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n const rowElement = event.currentTarget;\n const target = event.target as HTMLElement;\n const cell = getActionCell(rowElement);\n\n if (!cell || !cell.contains(target)) {\n if (target !== rowElement) return;\n if (isActivationKey(event)) {\n handleActivationKey(event);\n return;\n }\n const intent = getArrowIntent(event.key, {\n orientation: 'horizontal',\n dir: getDirection(rowElement),\n });\n const first = intent === 'next' && cell ? getActionStops(cell)[0] : undefined;\n if (first) {\n event.preventDefault();\n first.focus();\n }\n return;\n }\n\n // Inside the action cell.\n if (target !== cell && isTextEntry(target)) {\n // The widget keeps its keys (caret movement, typing); Escape returns to the cell.\n if (event.key === 'Escape') {\n event.preventDefault();\n cell.focus();\n }\n return;\n }\n if (target === cell && (event.key === 'Enter' || event.key === 'F2')) {\n const entry = getFocusables(cell).find((el) => isTextEntry(el));\n if (entry) {\n event.preventDefault();\n entry.focus();\n }\n return;\n }\n const intent = getArrowIntent(event.key, {\n orientation: 'horizontal',\n dir: getDirection(rowElement),\n });\n if (!intent) return;\n event.preventDefault();\n const stops = getActionStops(cell);\n const index = stops.indexOf(target);\n if (intent === 'next') {\n stops[index + 1]?.focus();\n } else if (index > 0) {\n stops[index - 1].focus();\n } else {\n rowElement.focus();\n }\n };\n\n const Element = (mode === 'grid' ? 'div' : 'li') as React.ElementType;\n const ContentCell = (mode === 'grid' ? 'div' : 'span') as React.ElementType;\n const role = mode === 'grid' ? 'row' : mode === 'listbox' ? 'option' : 'listitem';\n\n const interactiveProps: Record<string, unknown> = navigable\n ? {\n 'aria-selected': selection ? isSelected : undefined,\n tabIndex: getTabIndex(rovingValue),\n 'data-roving-value': rovingValue,\n 'data-selected': isSelected ? '' : undefined,\n // C-DISABLED: focusable, and kept in the arrow-key order.\n ...focusableDisabledProps(ariaDisabled, { reachable: true }),\n onClick: composeEventHandlers(onClick, handleClick),\n onKeyDown: composeEventHandlers(\n onKeyDown,\n mode === 'grid' ? handleRowKeyDown : handleOptionKeyDown,\n ),\n }\n : {\n // Clicks only (see the warning above); an item without onAction is left as it is.\n onClick: onAction ? composeEventHandlers(onClick, handleClick) : onClick,\n onKeyDown,\n };\n\n // A selectable list's items are clickable unless their selection is disabled and they have no\n // action; in a list without selection only the items with an action are.\n const cursor = selection\n ? ariaDisabled\n ? 'cursor-default'\n : 'cursor-pointer'\n : onAction && 'cursor-pointer';\n const hoverable = selection ? !ariaDisabled : onAction !== undefined;\n\n // `checkmark` is an optional indicator (C-SLOTS): unset follows the List, content replaces the\n // check, a value that renders nothing hides it.\n const customCheckmark = checkmark != null && slotRendersContent(checkmark);\n const showCheckmark = selection && (checkmark == null ? listCheckmark : customCheckmark);\n\n return (\n <Element\n role={role}\n data-disabled-selection={selectionDisabled ? '' : undefined}\n className={cn(\n listItemClassNames.root,\n 'flex items-center border-b border-border px-4 py-2 text-body-1',\n navigable ? ['relative', cursor, focusRingInset] : cursor,\n isSelected\n ? [\n 'bg-subtle-selected before:absolute before:inset-y-2 before:start-0 before:w-0.5 before:rounded-full before:bg-primary',\n forcedColors.selectedContainer,\n ]\n : hoverable && 'hover:bg-subtle-hover',\n className,\n )}\n {...rest}\n ref={itemRefs}\n {...interactiveProps}\n >\n <ContentCell\n role={mode === 'grid' ? 'gridcell' : undefined}\n className={cn(listItemClassNames.content, 'min-w-0 flex-1')}\n >\n {children}\n </ContentCell>\n {hasAction && (\n <ListActionCell grid={mode === 'grid'} onRemovedWithFocus={recordActionFocusLoss}>\n {/* A generator was read once by the check above: render its items. */}\n {materialiseSlotContent(action)}\n </ListActionCell>\n )}\n {showCheckmark &&\n renderCheckmark(customCheckmark ? checkmark : undefined, {\n selected: isSelected,\n disabled: selectionDisabled,\n })}\n </Element>\n );\n};\nListItem.displayName = 'ListItem';\n\n/**\n * Nested composite widgets (a Toolbar, a RadioGroup, …) manage their own tab indexes, so the action\n * cell never writes `tabindex` on or inside one (the same rule as the DataGrid's cell widgets).\n */\nconst COMPOSITE_SELECTOR = [\n '[data-roving-container]',\n ...[\n 'toolbar',\n 'radiogroup',\n 'listbox',\n 'grid',\n 'treegrid',\n 'tablist',\n 'menu',\n 'menubar',\n 'tree',\n ].map((role) => `[role=\"${role}\"]`),\n].join(', ');\n\n/** Attributes that can put an element of an action cell (back) into the Tab order. */\nconst STAMP_OBSERVED_ATTRIBUTES = ['tabindex', 'href', 'contenteditable', 'controls'];\n\n/**\n * Grid mode: takes the focusable elements of an action cell out of the Tab order (the row is the\n * only Tab stop; the actions are reached with the arrow keys) and keeps them out while the cell is\n * mounted. Returns the cleanup that disconnects the observer and restores the original values.\n *\n * It runs once per cell, not on every render of every item (an inline `action` has a new identity\n * on every parent render): a `MutationObserver` re-stamps when elements are added to the cell or an\n * element's `tabindex` is changed by someone else, including by an action component's own state.\n * Every candidate of `FOCUSABLE_SELECTOR` is stamped, disabled or hidden ones too, so an element\n * that is enabled or shown later is already out of the Tab order and no computed style is read.\n * Removed elements are dropped from the record on each pass. Nested composites are skipped (see\n * `COMPOSITE_SELECTOR`), and an element whose replaced `tabindex` something else re-applies (a\n * script that manages it) is left alone from then on, so the two never overwrite each other in an\n * endless loop of observer callbacks.\n */\nfunction stampActionCell(cell: HTMLElement): () => void {\n /** Stamped elements with the `tabindex` they had before (`null`: none). */\n const stamped = new Map<HTMLElement, string | null>();\n /** Elements whose `tabindex` something else keeps re-applying: they are left to it. */\n const yielded = new WeakSet<HTMLElement>();\n const stamp = () => {\n for (const el of stamped.keys()) {\n if (!cell.contains(el)) stamped.delete(el);\n }\n for (const el of cell.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)) {\n const tabIndex = el.getAttribute('tabindex');\n if (tabIndex === '-1' || yielded.has(el)) continue;\n const composite = el.closest(COMPOSITE_SELECTOR);\n if (composite && cell.contains(composite)) continue;\n stamped.set(el, tabIndex);\n el.setAttribute('tabindex', '-1');\n }\n };\n stamp();\n if (typeof MutationObserver === 'undefined') return () => {};\n\n const observer = new MutationObserver((records) => {\n // The records of this cell's own writes are taken below, so these values were set by someone\n // else: a changed prop (the new value to restore), or a script that manages the element's\n // tabindex and re-applied the value this cell replaced. Yielding to the latter keeps the two\n // from overwriting each other forever.\n const changed = new Set<HTMLElement>();\n for (const record of records) {\n const target = record.target as HTMLElement;\n if (record.attributeName === 'tabindex' && stamped.has(target)) changed.add(target);\n }\n for (const el of changed) {\n const value = el.getAttribute('tabindex');\n if (value !== '-1' && value === stamped.get(el)) {\n stamped.delete(el);\n yielded.add(el);\n } else {\n stamped.set(el, value);\n }\n }\n stamp();\n observer.takeRecords();\n });\n observer.observe(cell, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeFilter: STAMP_OBSERVED_ATTRIBUTES,\n });\n return () => {\n observer.disconnect();\n for (const [el, original] of stamped) {\n if (original === null) el.removeAttribute('tabindex');\n else el.setAttribute('tabindex', original);\n }\n stamped.clear();\n };\n}\n\ninterface ListActionCellProps {\n /** Grid mode: a focusable `gridcell` div whose widgets leave the Tab order; otherwise a `span`. */\n grid: boolean;\n /** Called when the cell is removed while focus is inside it (the cell is still in the document). */\n onRemovedWithFocus: (cell: HTMLElement) => void;\n children: React.ReactNode;\n}\n\n/**\n * The action cell of a {@link ListItem} (internal). React runs the layout-effect cleanups of a\n * removed subtree before it removes the subtree's DOM, but a component's own cleanups only after\n * its removed children are gone. So this cleanup, unlike one in ListItem, still sees focus inside\n * the cell when the action disappears (data-display#2).\n *\n * `grid` never changes for a mounted cell: switching between list and grid semantics changes the\n * List's root element, which remounts the items and their cells.\n */\nfunction ListActionCell({ grid, onRemovedWithFocus, children }: ListActionCellProps) {\n const cellRef = React.useRef<HTMLElement | null>(null);\n\n React.useLayoutEffect(() => {\n const cell = cellRef.current;\n return () => {\n if (!cell) return;\n const active = cell.ownerDocument.activeElement;\n if (active && cell.contains(active)) onRemovedWithFocus(cell);\n };\n }, [onRemovedWithFocus, grid]);\n\n React.useLayoutEffect(() => {\n const cell = cellRef.current;\n return grid && cell ? stampActionCell(cell) : undefined;\n }, [grid]);\n\n const Cell = (grid ? 'div' : 'span') as React.ElementType;\n return (\n <Cell\n ref={cellRef}\n role={grid ? 'gridcell' : undefined}\n tabIndex={grid ? -1 : undefined}\n data-list-action=\"\"\n className={cn(listItemClassNames.action, 'ms-2 shrink-0', grid && focusRingInset)}\n >\n {children}\n </Cell>\n );\n}\nListActionCell.displayName = 'ListActionCell';\n\n/**\n * A vertical list of items, optionally selectable.\n *\n * - **Plain** (`selectable` false): `role=\"list\"` with `listitem`s; item actions stay in the\n * normal Tab order.\n * - **Selectable** (APG Listbox): `role=\"listbox\"` with `option`s and one Tab stop (the first\n * selected option, else the first option). ArrowUp/Down move focus (wrapping), Home/End jump to\n * the ends, typeahead is on for more than 7 items, Enter/Space and clicks toggle selection (a\n * Space typed within 500 ms of a typeahead character continues the search instead; with Ctrl,\n * Alt or Meta, Enter and Space are left to the page).\n * - **Selectable with item actions** (APG Grid): `role=\"grid\"` with `row`s (carrying\n * `aria-selected`) and `gridcell`s for the content and the action. One Tab stop; Up/Down move\n * between rows, Right/Left (mirrored in RTL) move into and out of the actions. A cell that holds\n * a text-entry widget takes focus itself: Enter/F2 enter the widget, Escape returns to the cell.\n * Clicks and keys that start inside an action, or inside a popup it opens (a Popover, a Menu),\n * never toggle selection.\n * - **Navigation without selection** (`navigationMode`): `'items'` makes the items of a plain list\n * one Tab stop (the item that last had focus) with the listbox's arrow keys, Home/End and\n * typeahead, keeping `role=\"list\"`; `'composite'` renders the grid above from the first render,\n * for a selectable list too, so the items never remount when actions appear. The items of a\n * list without selection carry no `aria-selected`. The resolved mode is `data-navigation-mode`.\n * - **Actions on the item itself** (`List.Item onAction`): clicks and Enter run it, and Space on\n * an item that cannot be selected; in a selectable item it runs before the selection toggles,\n * and its `preventDefault()` keeps the selection. `List.Item disabledSelection` keeps an item's\n * selection as it is while the item stays focusable and in the arrow-key order.\n * - **Check marks** (`checkmark`, opt-in): a decorative check at the start of every item of a\n * selectable list, shown while the item is selected; `List.Item checkmark` replaces or hides it.\n * - **Switching semantics remounts the items.** Listbox/list and grid use different elements\n * (`ul`/`li` and `div`), so when a selectable list gains its first item action, loses its last\n * one, or `selectable` or `navigationMode` changes the structure, React remounts the items and\n * their content: state inside them (an inline rename input's draft, an uncontrolled checkbox) is\n * reset. Focus that is on an item or inside it when the list switches moves to the same item (by\n * `value`, else by position; the next item when the focused one was removed), or to its first\n * focusable content when the item is no Tab stop any more, so the switch never drops it to\n * `<body>`. This includes focus inside the last action when that action removes itself (an\n * inline rename input that unmounts on Enter). An action that removes itself while focused\n * without causing a switch drops focus, like any removed element. When the list may switch,\n * keep such state in the parent, or pin the grid with `navigationMode=\"composite\"`.\n * - Selection: `selectionMode` `'single'` (default) or `'multiple'`; controlled with\n * `selectedItems` (or `selectedItem` in single mode) or uncontrolled with the `default*` props.\n * Values of items that are no longer rendered are dropped from the reported selection.\n * - Sub-component: `List.Item` (also exported as `ListItem` for React Server Components).\n *\n * @example\n * <List selectable selectionMode=\"multiple\" aria-label=\"Fruits\" onSelectionChange={setFruits}>\n * <List.Item value=\"apple\">Apple</List.Item>\n * <List.Item value=\"banana\">Banana</List.Item>\n * </List>\n *\n * @example\n * <List navigationMode=\"items\" aria-label=\"Recent files\">\n * <List.Item value=\"report\" onAction={() => open('report')}>Report</List.Item>\n * <List.Item value=\"budget\" onAction={() => open('budget')}>Budget</List.Item>\n * </List>\n */\nexport const List = /* @__PURE__ */ Object.assign(ListRoot, {\n Item: ListItem,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"List.cjs","names":["React","ListRegistry","flattenChildren","isElementOfType","slotRendersContent","INTERACTIVE_SELECTOR","isForeignEvent","FOCUSABLE_SELECTOR","isFocusable","listClassNames","useControllable","useEventCallback","useRovingTabIndex","useMergedRefs","ownsArrowKeys","cn","composeEventHandlers","listItemClassNames","CheckIcon","renderSlot","useId","getArrowIntent","getDirection","focusableDisabledProps","focusRingInset","forcedColors","materialiseSlotContent","require_runtime","require_cn","require_children","require_dev","require_slot","require_composeEventHandlers","require_classNames","require_useEventCallback","require_useControllable","require_useId","require_direction","require_focus","require_useRovingTabIndex","require_useMergedRefs","require_aria","require_styles","require_icons","require_events","require_List_registry","react","react_jsx_runtime","ListContext","ListItemIndexContext","inertContext","getInertContext","useListContext","componentName","EMPTY","resolveNavigation","navigationMode","selectable","hasActions","warnDuplicateValue","value","childrenHaveAction","children","node","ListItem","ITEM_FOREIGN_EVENTS","isForeignItemEvent","event","isActivationKey","TEXT_ENTRY_ROLES","NON_TEXT_INPUT_TYPES","isTextEntry","role","el","tag","getFocusables","cell","getItemIndex","item","index","getItemFocusTarget","getFocusRestoreTarget","byValue","atIndex","last","root","position","windowed","getIndexAttribute","loss","toItemCount","count","keptIndexes","indexes","getWindowItemIndex","target","getWindowItem","WINDOW_PAGE_SIZE","getWindowKeyTarget","at","from","key","NO_WINDOW_FOCUS","WindowFocusStore","listener","state","next","ListSpacer","grid","size","getActionCell","child","getActionStops","stops","stop","ListRoot","rest","props","renderItem","activeWindow","virtualWindow","windowIgnored","itemCount","itemSize","listWindow","selectionMode","multiple","controlledSelection","selectedItem","selectedItems","defaultSelection","defaultSelectedItem","defaultSelectedItems","selected","setSelected","selection","onSelectionChange","onSelectedItemChange","registry","registered","effective","selectedValues","windowFocus","focusedIndex","pendingIndex","keep","windowEntries","entry","elementChildren","itemActions","windowActions","navigable","navigation","drawsCheckmark","checkmark","tabStopValue","followRovingFocus","active","rovingRef","rovingKeyDown","rovingKeyDownCapture","rovingFocus","containerProps","rootElementRef","rootRef","ref","focusInPopupRef","handleWindowFocus","internalFocus","handleWindowBlur","handleWindowKeyDown","current","element","previous","internalKeyDown","doc","mode","lost","pending","focused","toggleItem","isSelected","duplicates","selectedCount","itemsWithActions","noneSelectable","contextValue","getTabIndex","Root","content","className","onKeyDown","onKeyDownCapture","onFocus","onBlur","CHECKMARK_FORCED_COLORS","CHECKMARK_DISABLED_FORCED_COLORS","renderCheckmark","classes","disabled","glyph","listCheckmark","providedIndex","windowIndex","autoValue","selectableValue","rovingValue","hasAction","action","token","itemRef","itemRefs","recordActionFocusLoss","actionNotNavigable","onAction","itemSelectable","selectionDisabled","disabledSelection","ariaDisabled","toggle","activate","handleClick","handleActivationKey","handleOptionKeyDown","handleRowKeyDown","rowElement","first","intent","Element","ContentCell","interactiveProps","onClick","cursor","hoverable","customCheckmark","showCheckmark","windowProps","style","ListActionCell","COMPOSITE_SELECTOR","STAMP_OBSERVED_ATTRIBUTES","stampActionCell","stamped","yielded","stamp","tabIndex","composite","observer","changed","record","records","original","cellRef","onRemovedWithFocus","List"],"sources":["../../../src/components/data-display/List.tsx"],"sourcesContent":["import * as React from 'react';\nimport { focusableDisabledProps } from '../../lib/aria';\nimport { cn } from '../../lib/cn';\nimport { listClassNames, listItemClassNames } from '../../lib/classNames';\nimport { flattenChildren, isElementOfType } from '../../lib/children';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { reportMissingContext, warnDeprecated, warnOnce } from '../../lib/dev';\nimport { getArrowIntent, getDirection } from '../../lib/direction';\nimport { INTERACTIVE_SELECTOR, isForeignEvent, type ForeignEventOptions } from '../../lib/events';\nimport { FOCUSABLE_SELECTOR, isFocusable } from '../../lib/focus';\nimport { CheckIcon } from '../../lib/icons';\nimport { materialiseSlotContent, renderSlot, slotRendersContent, type Slot } from '../../lib/slot';\nimport { focusRingInset, forcedColors } from '../../lib/styles';\nimport type { SelectionMode } from '../../lib/types';\nimport { useControllable } from '../../hooks/useControllable';\nimport { useEventCallback } from '../../hooks/useEventCallback';\nimport { useId } from '../../hooks/useId';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { ownsArrowKeys, useRovingTabIndex } from '../../hooks/useRovingTabIndex';\nimport type { VirtualWindow } from '../../hooks/useVirtualWindow';\nimport { ListRegistry, type ListFocusLoss } from './List.registry';\n\n/** Selection modes of {@link List}: the shared `SelectionMode` plus the deprecated `'multi'`. */\nexport type ListSelectionMode = SelectionMode | 'multi';\n\n/**\n * How the keyboard reaches the items of a {@link List} (Fluent's `navigationMode`): `'none'`, no\n * item is a Tab stop; `'items'`, the items are one Tab stop moved with the arrow keys; `'composite'`,\n * a grid whose rows are moved with Up/Down and whose actions are reached with Right/Left.\n */\nexport type ListNavigationMode = 'none' | 'items' | 'composite';\n\n/** The event that activated a list item: a click, or Enter or Space on the focused item. */\nexport type ListItemActionEvent = React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>;\n\n/**\n * Properties for the List component.\n *\n * The type parameter `M` is the `selectionMode` literal. It makes the single-selection props\n * (`selectedItem`, `defaultSelectedItem`, `onSelectedItemChange`) type errors when\n * `selectionMode=\"multiple\"` is passed; `ListProps` without a type argument accepts every mode\n * (the 0.4 shape, extendable by interfaces).\n */\nexport interface ListProps<M extends ListSelectionMode = ListSelectionMode> extends Omit<\n React.HTMLAttributes<HTMLUListElement>,\n 'children'\n> {\n /**\n * The items: `List.Item` elements. In a windowed list (`virtualWindow` and `count`), a function\n * `(index) => <List.Item … />` that returns the item at an index: the list calls it for the\n * rendered indexes only and keys each item by its index. Without `virtualWindow` and `count` a\n * function renders nothing (a development warning says so).\n */\n children?: React.ReactNode | ((index: number) => React.ReactNode);\n /**\n * Renders only the items in view, plus an overscan, of a long list: pass the result of\n * `useVirtualWindow({ itemSize })` (or an object of your own that implements `VirtualWindow`)\n * with `count`, and a function child that returns the `List.Item` at an index. The items that\n * are not rendered are replaced by spacers (`aria-hidden`, `data-virtual-spacer`) of their\n * height.\n *\n * The list element becomes the window's scroller (it scrolls vertically, without the browser's\n * scroll anchoring): give it a bounded height, a height or a maximum height (a class or a style);\n * without one the window measures the whole list and renders every item. Where the list\n * navigates its items, one item is its Tab stop and the list element is none of its own\n * (`tabIndex` -1, as Firefox would stop on a scroller); a plain windowed list keeps the browser's\n * default, under which WebKit does not let the keyboard reach and scroll it: pass `tabIndex={0}`\n * or navigate its items (`navigationMode=\"items\"`). A `tabIndex` you pass wins.\n *\n * Every item has the window's `itemSize` as its height (the list sets it, after the item's own\n * `style`), so an item's content must fit in it. Each item carries `data-index` (its 0-based\n * index) and its place in the whole list: `aria-setsize` and `aria-posinset`, or in a grid\n * (`navigationMode=\"composite\"`) the list's `aria-rowcount` and the row's `aria-rowindex`.\n *\n * The item that has focus stays rendered when it is scrolled away (also while focus is in a\n * popup it opened), so it keeps focus, and while focus is in the list it is the list's Tab stop.\n * Once focus leaves the list it is no longer kept, and the Tab stop follows the rule of a list\n * without focus among the rendered items (the first selected item, else the first item; in a\n * list without selection the item that last had focus while it is rendered). When `count` drops\n * to or below the focused item, focus moves to the last item.\n *\n * The keys move by index over the whole list, rendered or not, where the list navigates its\n * items (`navigationMode` `'items'` or `'composite'`, or a selectable list): ArrowUp/ArrowDown\n * (wrapping at the ends), Home/End, and PageUp/PageDown, which move ten items and stop at the\n * ends. The target is scrolled into view before it is focused, the least that shows it whole: a\n * rendered one by the browser (`scrollIntoView`, nearest), which the window follows, one that is\n * not rendered through the window's `scrollToIndex`, and focused once it renders. An item that a\n * pointer press focuses is not scrolled. Typeahead matches the labels of the rendered items\n * only.\n *\n * Selection covers every value: the values of items that are not rendered stay selected, and\n * `onSelectionChange` reports them (a list without a window drops the values of items it no\n * longer renders).\n *\n * The structure never depends on which items are rendered: a selectable windowed list stays a\n * listbox (its items are options) unless `navigationMode=\"composite\"` makes it a grid from the\n * first render, so scrolling never replaces the list element (which would reset its scroll\n * position and remount every item). Its items' actions do not switch it to a grid as they do in\n * a list without a window: an item with an action in a selectable windowed list without that\n * pin is a development warning, since an option cannot hold interactive content. Pin\n * `navigationMode=\"composite\"` when items have actions.\n *\n * Applies only with `count` and a function child; otherwise it is ignored, with a development\n * warning.\n */\n virtualWindow?: VirtualWindow;\n /**\n * The number of items of a windowed list (with `virtualWindow`): the function child is called\n * for the indexes from 0 to `count - 1` that are rendered. A value that is not a whole number\n * counts as its whole part, and one below 0 (or not finite) as 0.\n */\n count?: number;\n /** Whether list items can be selected.\n * @default false\n */\n selectable?: boolean;\n /**\n * Selection behavior when `selectable` is true. `'multi'` is a deprecated alias of `'multiple'`.\n * @default 'single'\n */\n selectionMode?: M;\n /**\n * Controlled array of selected item values (both modes). In single mode prefer `selectedItem`;\n * a single-selection list that receives several values warns in development.\n */\n selectedItems?: readonly string[];\n /** Default selected items for uncontrolled usage.\n * @default []\n */\n defaultSelectedItems?: readonly string[];\n /** Called with the next array of selected values when the selection changes (both modes). */\n onSelectionChange?: (selected: string[]) => void;\n /** Single mode: the controlled selected value (`null`: nothing selected). */\n selectedItem?: M extends 'single' ? string | null : never;\n /** Single mode: the initially selected value for uncontrolled usage. */\n defaultSelectedItem?: M extends 'single' ? string | null : never;\n /** Single mode: called with the newly selected value, or `null` when it was deselected. */\n onSelectedItemChange?: M extends 'single' ? (item: string | null) => void : never;\n /**\n * How the keyboard reaches the items. Unset, the list picks the mode itself: `'none'` for a plain\n * list, `'items'` for a selectable one (a listbox) and `'composite'` (a grid) for a selectable\n * list whose items have actions, which remounts the items when the first action appears or the\n * last one disappears. An explicit value pins the structure:\n *\n * - `'none'`: a plain list; its items are no Tab stops (their actions stay in the Tab order). A\n * selectable list always navigates its items: there `'none'` is ignored, with a development\n * warning.\n * - `'items'`: the items are one Tab stop (the first selected item, else the first item; in a\n * list without selection the item that last had focus), moved with ArrowUp/ArrowDown (wrapping)\n * and Home/End, with typeahead for more than 7 items. A plain list keeps `role=\"list\"` and its\n * items carry no `aria-selected`; their actions stay in the Tab order. A selectable list whose\n * items have actions acts as `'composite'`, with a development warning.\n * - `'composite'`: a grid (`role=\"grid\"`, `row`s and `gridcell`s) from the first render, so the\n * items never remount when actions appear. One Tab stop; Up/Down move between the rows and\n * Right/Left (mirrored in right-to-left layouts) into and out of their actions, which leave\n * the Tab order. The rows of a list without selection carry no `aria-selected`.\n *\n * The resolved mode is rendered as `data-navigation-mode`. Changing it while mounted can switch\n * between `ul`/`li` and `div` elements, which remounts the items (see {@link List}). A windowed\n * list (`virtualWindow`) never switches for its items' actions: unset or `'items'`, a selectable\n * one is a listbox; only `'composite'` makes it a grid. In a windowed list the keys move by\n * index over the whole list, PageUp/PageDown included (see `virtualWindow`).\n */\n navigationMode?: ListNavigationMode;\n /**\n * Draws a check mark at the start of every item of a selectable list, shown while the item is\n * selected (decorative: `aria-selected` carries the state). An item's own `checkmark` replaces\n * or hides it. Renders `data-checkmark` on the list while it draws them.\n * @default false\n */\n checkmark?: boolean;\n /**\n * Ref to the root element: a `<ul>`, or a `<div role=\"grid\">` for a selectable list whose items\n * have actions and for `navigationMode=\"composite\"`.\n */\n ref?: React.Ref<HTMLUListElement | HTMLDivElement>;\n}\n\n/** Properties for the ListItem component. */\nexport interface ListItemProps extends React.HTMLAttributes<HTMLLIElement> {\n /**\n * Unique value identifying this item for selection tracking. An item without a value cannot be\n * selected (its `onClick` still runs). Items of a selectable list that share a value are\n * selected together (a development warning names the value).\n */\n value?: string;\n /**\n * Action element rendered at the end of the list item (e.g. a Delete button). Clicks and keys\n * that start inside it, or inside a popup it opens, never toggle the item's selection. An\n * action that renders nothing (`[]`, `null`, `false`, `''`, `<></>`) is no action. In a\n * selectable list, items with actions switch the list to grid semantics: the actions are reached\n * with the arrow keys, and their focusable elements (also ones added later) get\n * `tabindex=\"-1\"`, except inside a nested composite widget such as a Toolbar, which keeps its own\n * Tab stop. When the first action appears or the last one disappears, the items remount (see\n * {@link List}), unless the List's `navigationMode=\"composite\"` keeps the grid.\n */\n action?: React.ReactNode;\n /**\n * Called when the item is activated: a click on it, or Enter on the focused item, and Space on\n * an item that cannot be selected (in a list without selection, or without a `value`); in a\n * selectable item Space only toggles the selection. Clicks and keys that start in an action or\n * in interactive content never run it. It runs after the item's `onClick` (whose\n * `preventDefault()` skips it) and before the selection toggles: call `event.preventDefault()`\n * to keep the selection as it is. Fires on every activation. The items of a list that does not\n * navigate them (`navigationMode` `'none'`, not selectable) cannot be reached with the keyboard:\n * there it runs on clicks only, and a development warning says so.\n */\n onAction?: (event: ListItemActionEvent) => void;\n /**\n * In a selectable list: the item's selection cannot be toggled (click, Enter or Space; a\n * selected item stays selected). The item stays focusable and in the arrow-key order and renders\n * `data-disabled-selection`. Without `onAction` it is also `aria-disabled` (with `data-disabled`\n * and `data-disabled-focusable`); with `onAction`, clicks and Enter still run the action, while\n * Space, the selection key, does nothing. The item's `onClick` runs either way.\n * @default false\n */\n disabledSelection?: boolean;\n /**\n * The item's check mark in a selectable list, a decorative `<span>` at the start of the item\n * shown while it is selected. `null` and `undefined` follow the List's `checkmark` (the default\n * check, or none); content replaces the glyph, also when the List draws none; `false`, or\n * content that renders nothing, hides it.\n */\n checkmark?: Slot<'span'>;\n /** Ref to the item element: an `<li>`, or a `<div role=\"row\">` in grid mode. */\n ref?: React.Ref<HTMLLIElement | HTMLDivElement>;\n}\n\n/* ------------------------------------------------------------------ */\n/* Context */\n/* ------------------------------------------------------------------ */\n\n/**\n * The list's structure: `list` (`ul`/`li`, `role=\"list\"`), `listbox` (selectable, `option`s) or\n * `grid` (`div`s with `row`s: a selectable list with item actions, or `navigationMode=\"composite\"`).\n * The structure of a windowed list does not depend on its rendered items' actions, so a windowed\n * selectable list is a grid only with `navigationMode=\"composite\"`.\n */\ntype ListMode = 'list' | 'listbox' | 'grid';\n\n/** The window of a windowed list, as its items read it. */\ninterface ListWindow {\n /** The number of items of the whole list (`count`). */\n count: number;\n /** The height of every item, in pixels (the window's `itemSize`). */\n itemSize: number;\n}\n\ninterface ListContextValue {\n mode: ListMode;\n /** The items are the list's arrow-key stops (a selectable list, or `items`/`composite`). */\n navigable: boolean;\n /** The list is selectable: its items carry `aria-selected`. */\n selection: boolean;\n /** The List draws the default check mark on its items (a selectable list with `checkmark`). */\n checkmark: boolean;\n selectedValues: ReadonlySet<string>;\n toggleItem: (value: string) => void;\n getTabIndex: (value: string) => 0 | -1;\n registry: ListRegistry;\n /** The window of a windowed list; `null` in a list that renders every item. */\n listWindow: ListWindow | null;\n}\n\nconst ListContext = React.createContext<ListContextValue | null>(null);\nListContext.displayName = 'ListContext';\n\n/**\n * The index of the item around it in a windowed list (the List provides one per rendered item);\n * `null` outside a windowed list.\n */\nconst ListItemIndexContext = React.createContext<number | null>(null);\nListItemIndexContext.displayName = 'ListItemIndexContext';\n\nlet inertContext: ListContextValue | null = null;\n\nfunction getInertContext(): ListContextValue {\n inertContext ??= {\n mode: 'list',\n navigable: false,\n selection: false,\n checkmark: false,\n selectedValues: new Set<string>(),\n toggleItem: () => {},\n getTabIndex: () => -1,\n registry: new ListRegistry(),\n listWindow: null,\n };\n return inertContext;\n}\n\nfunction useListContext(componentName: string): ListContextValue {\n const context = React.useContext(ListContext);\n if (context) return context;\n reportMissingContext(componentName, 'a List');\n return getInertContext();\n}\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nconst EMPTY: readonly string[] = [];\n\n/**\n * The structure and the effective navigation mode of a list. Unset, a selectable list is a listbox,\n * or a grid while an item has an action. In a selectable list, `'none'` is ignored and `'items'`\n * with actions acts as `'composite'` (an option cannot hold interactive content); both warn.\n */\nfunction resolveNavigation(\n selectable: boolean,\n hasActions: boolean,\n navigationMode: ListNavigationMode | undefined,\n): { mode: ListMode; navigation: ListNavigationMode } {\n if (navigationMode === 'composite' || (selectable && hasActions)) {\n return { mode: 'grid', navigation: 'composite' };\n }\n if (selectable) return { mode: 'listbox', navigation: 'items' };\n return { mode: 'list', navigation: navigationMode === 'items' ? 'items' : 'none' };\n}\n\n/** Items that share a value are selected together and share their roving value. */\nfunction warnDuplicateValue(value: string): void {\n warnOnce(\n `List:duplicate:${value}`,\n `List: several items share the value \"${value}\". Item values must be unique within a ` +\n 'List; items with the same value are selected (and tab stops) together.',\n );\n}\n\n/**\n * Static look-ahead for the server and the first render: a direct `List.Item` (Fragments\n * flattened, also an item written in a Server Component) whose action renders content.\n */\nfunction childrenHaveAction(children: React.ReactNode): boolean {\n return flattenChildren(children).some(\n ({ node }) =>\n isElementOfType<ListItemProps>(node, ListItem) && slotRendersContent(node.props.action),\n );\n}\n\n/** Elements whose events belong to themselves, not to the item: also the item's action cell. */\nconst ITEM_FOREIGN_EVENTS: ForeignEventOptions = {\n interactive: `${INTERACTIVE_SELECTOR}, [data-list-action]`,\n};\n\n/**\n * Whether an item must leave `event` alone (no selection toggle): it started inside the action\n * cell or a nested interactive element, or outside the item's DOM. React bubbles the events of a\n * popup portaled from an action (a Popover, Menu or Dialog) through the item's handlers although\n * their target lives elsewhere in the document; those never toggle the item (as in Card).\n */\nfunction isForeignItemEvent(event: React.SyntheticEvent<HTMLElement>): boolean {\n return isForeignEvent(event, ITEM_FOREIGN_EVENTS);\n}\n\n/**\n * Enter or Space without Ctrl, Alt or Meta: the keys that activate an item. With a modifier\n * (Ctrl+Alt with Space included) the key is a shortcut, left to the page.\n */\nfunction isActivationKey(event: React.KeyboardEvent): boolean {\n if (event.ctrlKey || event.altKey || event.metaKey) return false;\n return event.key === 'Enter' || event.key === ' ';\n}\n\nconst TEXT_ENTRY_ROLES: ReadonlySet<string> = new Set([\n 'textbox',\n 'searchbox',\n 'combobox',\n 'spinbutton',\n 'slider',\n]);\n\nconst NON_TEXT_INPUT_TYPES: ReadonlySet<string> = new Set([\n 'button',\n 'checkbox',\n 'color',\n 'file',\n 'hidden',\n 'image',\n 'radio',\n 'reset',\n 'submit',\n]);\n\n/** Text-entry widgets keep the arrow keys (caret movement) and are entered with Enter/F2. */\nfunction isTextEntry(el: Element): boolean {\n const role = el.getAttribute('role');\n if (role !== null && TEXT_ENTRY_ROLES.has(role)) return true;\n const tag = el.localName;\n if (tag === 'textarea' || tag === 'select') return true;\n if (tag === 'input') return !NON_TEXT_INPUT_TYPES.has((el as HTMLInputElement).type);\n return el.matches('[contenteditable]:not([contenteditable=\"false\"])');\n}\n\nfunction getFocusables(cell: HTMLElement): HTMLElement[] {\n return Array.from(cell.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter((el) =>\n isFocusable(el),\n );\n}\n\n/*\n * The helpers below walk element children with `firstElementChild`/`nextElementSibling`, never\n * through a `children` collection: jsdom before 30.1 does not cache indexed `HTMLCollection`\n * access, so `Array.from(root.children)` or an indexed loop over a large list is O(n²) in the test\n * suites of consumers on those versions (table-core#22).\n */\n\n/** Position of an item element among its list's items (the root's element children). */\nfunction getItemIndex(item: HTMLElement): number {\n if (!item.parentElement) return -1;\n let index = 0;\n for (let el = item.previousElementSibling; el; el = el.previousElementSibling) index++;\n return index;\n}\n\n/** The element that takes focus for an item: the item itself, else its first focusable content. */\nfunction getItemFocusTarget(item: HTMLElement): HTMLElement | null {\n return item.hasAttribute('tabindex') ? item : (getFocusables(item)[0] ?? null);\n}\n\n/**\n * Where focus goes after the items remounted: the item with the same explicit value, else the item\n * now at the same position (the next one when the focused item itself was removed), else the last.\n * The position is the item's place among the root's children, or in a windowed list (`windowed`)\n * its index (`data-index`; the spacers are no items). An item that cannot take focus itself (a\n * plain list item) passes it to its first focusable descendant.\n */\nfunction getFocusRestoreTarget(\n root: HTMLElement,\n loss: ListFocusLoss,\n windowed: boolean,\n): HTMLElement | null {\n let byValue: Element | null = null;\n let atIndex: Element | null = null;\n let last: Element | null = null;\n let index = 0;\n for (let el = root.firstElementChild; el; el = el.nextElementSibling, index++) {\n const position = windowed ? getIndexAttribute(el) : index;\n if (position === null) continue;\n if (loss.value !== undefined && el.getAttribute('data-roving-value') === loss.value) {\n byValue = el;\n break;\n }\n if (position === loss.index) atIndex = el;\n last = el;\n }\n const item = (byValue ?? atIndex ?? (loss.index >= 0 ? last : null)) as HTMLElement | null;\n return item ? getItemFocusTarget(item) : null;\n}\n\n/** A windowed list's `count` as a whole number of 0 or more (`NaN`, infinite and negative: 0). */\nfunction toItemCount(count: number | undefined): number {\n return count !== undefined && Number.isFinite(count) ? Math.max(0, Math.floor(count)) : 0;\n}\n\n/** The indexes a windowed list keeps rendered outside its window, the unset ones left out. */\nfunction keptIndexes(...indexes: readonly (number | null)[]): readonly number[] {\n return indexes.filter((index): index is number => index !== null);\n}\n\n/** The index an item element of a windowed list carries (`data-index`); `null` for a spacer. */\nfunction getIndexAttribute(el: Element): number | null {\n const value = el.getAttribute('data-index');\n return value !== null && /^\\d+$/.test(value) ? Number(value) : null;\n}\n\n/**\n * The `data-index` of the item of a windowed list (an element child of `root`) that holds\n * `target`; `null` for the root itself and for a target outside its DOM (a portal's, C-COMPOSE).\n */\nfunction getWindowItemIndex(root: Element, target: EventTarget): number | null {\n let el = target instanceof Element ? target : null;\n while (el && el.parentElement !== root) el = el.parentElement;\n return el ? getIndexAttribute(el) : null;\n}\n\n/** The rendered item of a windowed list at `index`, or `null` when it is not rendered. */\nfunction getWindowItem(root: Element, index: number): HTMLElement | null {\n for (let el = root.firstElementChild; el; el = el.nextElementSibling) {\n if (getIndexAttribute(el) === index) return el as HTMLElement;\n }\n return null;\n}\n\n/**\n * How many items PageUp and PageDown move in a windowed list: the APG listbox's ten (a\n * `VirtualWindow` exposes no viewport size), as DataGrid's rows.\n */\nconst WINDOW_PAGE_SIZE = 10;\n\n/**\n * The index a key moves to in a windowed list of `count` items (1 or more), from the item at\n * `from` (`null`: from the list element itself), or `undefined` for a key that does not move by\n * index. The arrows wrap around the ends as the roving tab index does; PageUp and PageDown stop\n * at them.\n */\nfunction getWindowKeyTarget(key: string, from: number | null, count: number): number | undefined {\n const last = count - 1;\n const at = from === null ? null : Math.min(from, last);\n switch (key) {\n case 'ArrowDown':\n return at === null || at === last ? 0 : at + 1;\n case 'ArrowUp':\n return at === null || at === 0 ? last : at - 1;\n case 'PageDown':\n return at === null ? 0 : Math.min(at + WINDOW_PAGE_SIZE, last);\n case 'PageUp':\n return at === null ? last : Math.max(at - WINDOW_PAGE_SIZE, 0);\n case 'Home':\n return 0;\n case 'End':\n return last;\n default:\n return undefined;\n }\n}\n\n/** The focused and the awaited item of a windowed list (see {@link WindowFocusStore}). */\ninterface WindowFocus {\n /**\n * The index of the item that has focus, or holds it while focus is in a popup it opened: kept\n * rendered, and the Tab stop. `null` while focus is outside the list.\n */\n focused: number | null;\n /**\n * The index a key moved to that was not rendered: scrolled into view, kept rendered, and\n * focused after the commit that renders it.\n */\n pending: number | null;\n}\n\nconst NO_WINDOW_FOCUS: WindowFocus = { focused: null, pending: null };\n\n/**\n * The focused and the awaited item of a windowed list, read during render through\n * `useSyncExternalStore` and written by the List's handlers and layout effects (C-HOOKS: no state\n * set in an effect, no ref read during render).\n */\nclass WindowFocusStore {\n private state: WindowFocus = NO_WINDOW_FOCUS;\n private readonly listeners = new Set<() => void>();\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n };\n\n getSnapshot = (): WindowFocus => this.state;\n\n getServerSnapshot = (): WindowFocus => NO_WINDOW_FOCUS;\n\n /** Changes the given fields; notifies only when one of them changed. */\n update(next: Partial<WindowFocus>): void {\n const state = { ...this.state, ...next };\n if (state.focused === this.state.focused && state.pending === this.state.pending) return;\n this.state = state;\n for (const listener of this.listeners) listener();\n }\n}\n\n/**\n * An element that stands in for the items of a windowed list that are not rendered: as tall as\n * they are, out of the accessibility tree and never focused. A `<div>` in a grid, else an `<li>`.\n */\nfunction ListSpacer({ grid, size }: { grid: boolean; size: number }) {\n const Spacer = (grid ? 'div' : 'li') as React.ElementType;\n return (\n <Spacer\n aria-hidden=\"true\"\n role=\"presentation\"\n data-virtual-spacer=\"\"\n className={listClassNames.spacer}\n style={{ height: size }}\n />\n );\n}\nListSpacer.displayName = 'ListSpacer';\n\n/** The action cell of an item element (its direct `[data-list-action]` child), read at event time. */\nfunction getActionCell(item: HTMLElement): HTMLElement | null {\n for (let child = item.firstElementChild; child; child = child.nextElementSibling) {\n if (child.hasAttribute('data-list-action')) return child as HTMLElement;\n }\n return null;\n}\n\n/**\n * The arrow-key stops inside an action cell, in DOM order. A text-entry widget is represented by\n * the cell itself (the cell takes focus; Enter/F2 enter the widget, Escape returns to the cell).\n */\nfunction getActionStops(cell: HTMLElement): HTMLElement[] {\n const stops: HTMLElement[] = [];\n for (const el of getFocusables(cell)) {\n const stop = isTextEntry(el) ? cell : el;\n if (!stops.includes(stop)) stops.push(stop);\n }\n return stops;\n}\n\n/* ------------------------------------------------------------------ */\n/* List */\n/* ------------------------------------------------------------------ */\n\n// The List root, documented on the exported `List` const.\nconst ListRoot = <M extends ListSelectionMode = 'single'>(props: ListProps<M>): React.ReactNode => {\n const {\n selectable = false,\n selectionMode,\n selectedItems,\n defaultSelectedItems,\n onSelectionChange,\n selectedItem,\n defaultSelectedItem,\n onSelectedItemChange,\n navigationMode,\n checkmark = false,\n virtualWindow,\n count,\n className,\n children,\n ref,\n onKeyDown,\n onKeyDownCapture,\n onFocus,\n onBlur,\n ...rest\n } = props as ListProps;\n\n // The window applies with `virtualWindow`, `count` and a function child together.\n const renderItem = typeof children === 'function' ? children : null;\n const activeWindow =\n virtualWindow !== undefined && count !== undefined && renderItem ? virtualWindow : null;\n const windowed = activeWindow !== null;\n const windowIgnored =\n !windowed && (virtualWindow !== undefined || count !== undefined || renderItem !== null);\n const itemCount = windowed ? toItemCount(count) : 0;\n const itemSize = activeWindow?.itemSize;\n const listWindow = React.useMemo<ListWindow | null>(\n () => (itemSize === undefined ? null : { count: itemCount, itemSize }),\n [itemCount, itemSize],\n );\n\n if (selectionMode === 'multi') {\n warnDeprecated('List', 'selectionMode=\"multi\"', 'selectionMode=\"multiple\"');\n }\n const multiple = selectionMode === 'multiple' || selectionMode === 'multi';\n\n const controlledSelection = React.useMemo<readonly string[] | undefined>(() => {\n if (!multiple && selectedItem !== undefined) {\n return selectedItem === null ? EMPTY : [selectedItem];\n }\n return selectedItems;\n }, [multiple, selectedItem, selectedItems]);\n const defaultSelection = React.useMemo<readonly string[]>(() => {\n if (!multiple && defaultSelectedItem !== undefined && defaultSelectedItem !== null) {\n return [defaultSelectedItem];\n }\n return defaultSelectedItems ?? EMPTY;\n }, [multiple, defaultSelectedItem, defaultSelectedItems]);\n\n const [selected, setSelected] = useControllable<readonly string[]>(\n controlledSelection,\n defaultSelection,\n (next) => {\n // The callbacks receive their own mutable copy (the props accept readonly arrays).\n const selection = [...next];\n onSelectionChange?.(selection);\n if (!multiple) onSelectedItemChange?.(selection[0] ?? null);\n },\n );\n\n const [registry] = React.useState(() => new ListRegistry());\n const registered = React.useSyncExternalStore(\n registry.subscribe,\n registry.getSnapshot,\n registry.getServerSnapshot,\n );\n\n // Effective selection: selected ∩ registered item values, derived during render (table-core#22).\n // A windowed list keeps every value: most of its items are not rendered, so not registered.\n const effective = React.useMemo(\n () =>\n registered && !windowed\n ? selected.filter((value) => registered.valueSet.has(value))\n : selected,\n [registered, selected, windowed],\n );\n const selectedValues = React.useMemo<ReadonlySet<string>>(() => new Set(effective), [effective]);\n\n // A windowed list keeps the focused item rendered outside the window, so a focused item scrolled\n // away keeps focus and its Tab stop, and the item a key moved to until it is focused.\n const [windowFocus] = React.useState(() => new WindowFocusStore());\n const { focused: focusedIndex, pending: pendingIndex } = React.useSyncExternalStore(\n windowFocus.subscribe,\n windowFocus.getSnapshot,\n windowFocus.getServerSnapshot,\n );\n const keep = React.useMemo(\n () => keptIndexes(focusedIndex, pendingIndex),\n [focusedIndex, pendingIndex],\n );\n // The entries of the window, each item rendered by the function child (only its indexes).\n const windowEntries =\n activeWindow && renderItem\n ? activeWindow\n .layout(itemCount, { keep })\n .map((entry) =>\n entry.kind === 'item' ? { ...entry, node: renderItem(entry.index) } : entry,\n )\n : null;\n // A function child renders nothing without a window (a development warning says so).\n const elementChildren = renderItem ? null : (children as React.ReactNode);\n\n // Whether a rendered item of a selectable list without the `composite` pin has an action.\n const itemActions =\n selectable &&\n navigationMode !== 'composite' &&\n (registered\n ? registered.hasActions\n : childrenHaveAction(\n windowEntries\n ? windowEntries.map((entry) => (entry.kind === 'item' ? entry.node : null))\n : elementChildren,\n ));\n // Only such a list decides its structure by its actions. A windowed list does not: which items\n // are rendered changes as it scrolls, and a new root element would remount the scroller, reset\n // its scroll position and every item (it stays a listbox, with a development warning).\n const hasActions = itemActions && !windowed;\n const windowActions = itemActions && windowed;\n const { mode, navigation } = resolveNavigation(selectable, hasActions, navigationMode);\n const navigable = navigation !== 'none';\n const drawsCheckmark = selectable && checkmark;\n\n // A navigable list reads its items' registrations (count, values, order); a plain one never does.\n React.useLayoutEffect(() => {\n registry.setActive(navigable);\n }, [registry, navigable]);\n\n // The first selected item in DOM order (the registry keeps its values in DOM order).\n const tabStopValue = registered\n ? (registered.values.find((value) => selectedValues.has(value)) ?? null)\n : (effective[0] ?? null);\n\n // A windowed list leaves only typeahead (and a grid's moves into its actions) to the roving tab\n // index, which focuses a rendered item: the window moves to it in the same update, so no frame\n // shows the browser's focus scrolling without the items around it.\n const followRovingFocus = useEventCallback((_value: string, event: React.KeyboardEvent) => {\n const root = event.currentTarget;\n const active = root.ownerDocument.activeElement;\n const index = active ? getWindowItemIndex(root, active) : null;\n if (index !== null) activeWindow?.scrollToIndex(index, { align: 'auto' });\n });\n\n const { containerProps, getTabIndex } = useRovingTabIndex({\n activeValue: selectable ? tabStopValue : null,\n orientation: 'vertical',\n onFocusMove: windowed ? followRovingFocus : undefined,\n // A windowed list counts its items from `count` (most of them are not rendered).\n typeahead: (windowed ? itemCount : (registered?.count ?? 0)) > 7,\n // A list without selection returns to the item that last had focus. While focus is in a\n // windowed list, the focused item is its Tab stop (it stays rendered, scrolled away or not).\n tabStop: selectable && !(windowed && focusedIndex !== null) ? 'active' : 'last-focused',\n // The items are the root's children. A composite in an item action (a Toolbar, a radio group)\n // is part of its row, not an item: arrows and typeahead never move into it.\n itemSelector: ':scope > [data-roving-value]',\n });\n const {\n ref: rovingRef,\n onKeyDown: rovingKeyDown,\n onKeyDownCapture: rovingKeyDownCapture,\n onFocus: rovingFocus,\n } = containerProps;\n const rootElementRef = React.useRef<HTMLUListElement | HTMLDivElement | null>(null);\n const rootRef = useMergedRefs<HTMLUListElement | HTMLDivElement>(\n ref,\n navigable ? rovingRef : null,\n rootElementRef,\n // The list is the window's scroller.\n activeWindow?.scrollRef,\n );\n\n /**\n * Whether focus is in a popup that an item of a windowed list opened (an element outside the\n * list's DOM whose focus React bubbles through the list): the item stays kept. Written by the\n * focus and blur handlers.\n */\n const focusInPopupRef = React.useRef(false);\n\n // A windowed list records the index of the item that focus moves into (after the roving\n // bookkeeping of a navigable list); an item that takes focus is no longer awaited.\n const handleWindowFocus = useEventCallback((event: React.FocusEvent) => {\n if (navigable) rovingFocus(event);\n const root = event.currentTarget;\n focusInPopupRef.current = !root.contains(event.target as Node);\n const index = getWindowItemIndex(root, event.target);\n if (index !== null) windowFocus.update({ focused: index, pending: null });\n });\n const internalFocus = windowed ? handleWindowFocus : navigable ? rovingFocus : undefined;\n\n // Focus leaving a windowed list (for an element outside it, or for nothing) ends the keeping of\n // its focused item; the Tab stop then follows the rule of a list without focus. Decided once\n // focus has landed: a popup an item opened takes focus in the same task (`focusInPopupRef`).\n const handleWindowBlur = useEventCallback((event: React.FocusEvent) => {\n const root = event.currentTarget;\n const next = event.relatedTarget as Node | null;\n if (next && root.contains(next)) return;\n focusInPopupRef.current = false;\n queueMicrotask(() => {\n if (!root.isConnected || focusInPopupRef.current) return;\n const active = root.ownerDocument.activeElement;\n if (active && root.contains(active)) return;\n windowFocus.update(NO_WINDOW_FOCUS);\n });\n });\n\n /**\n * The keys of a windowed list in the `items` and `composite` modes (before the roving tab index,\n * which then skips them): ArrowUp/ArrowDown, Home/End and PageUp/PageDown move by index over the\n * whole list, from the item the key started in (or the item a key is awaiting). A rendered target\n * is scrolled into view and focused; one that is not is kept rendered, scrolled into view and\n * focused after the commit that renders it. A key whose target is the focused item drops an\n * awaited item and scrolls the focused one into view. The keys the roving tab index leaves alone\n * are left alone too.\n */\n const handleWindowKeyDown = useEventCallback((event: React.KeyboardEvent<HTMLElement>) => {\n if (!activeWindow || event.defaultPrevented || itemCount === 0) return;\n if (event.ctrlKey || event.altKey || event.metaKey) return;\n const root = event.currentTarget;\n // A key from a popup is the popup's; a text field keeps its keys.\n if (!root.contains(event.target as Node) || ownsArrowKeys(event.target)) return;\n const current = getWindowItemIndex(root, event.target);\n const target = getWindowKeyTarget(\n event.key,\n windowFocus.getSnapshot().pending ?? current,\n itemCount,\n );\n if (target === undefined) return;\n event.preventDefault();\n if (target === current) {\n windowFocus.update({ pending: null });\n activeWindow.scrollToIndex(target, { align: 'auto' });\n return;\n }\n const element = getWindowItem(root, target);\n if (element) {\n windowFocus.update({ pending: null });\n // A rendered target is at most the overscan away from the view, so the least scroll that\n // shows it whole keeps the view on rendered items while the window follows from the scroll\n // event. A browser's own focus scrolling would centre a hidden item, past the rendered ones\n // (a blank frame), or in Firefox leave a partly visible one clipped; and moving the window in\n // this update (`scrollToIndex`) gives Firefox long frames while a key is held.\n // jsdom has no `scrollIntoView`: a consumer's test without a stub still moves focus.\n element.scrollIntoView?.({ block: 'nearest' });\n getItemFocusTarget(element)?.focus();\n return;\n }\n const previous = windowFocus.getSnapshot().pending;\n windowFocus.update({ pending: target });\n if (previous !== target) activeWindow.scrollToIndex(target, { align: 'auto' });\n });\n const internalKeyDown = useEventCallback((event: React.KeyboardEvent<HTMLElement>) => {\n if (windowed) handleWindowKeyDown(event);\n rovingKeyDown(event);\n });\n\n // Switching between list and grid semantics changes the root and item elements (`ul`/`li` ↔\n // `div`), so React remounts the items and the focused one is removed. Items record, while they\n // are still in the document, that they held focus (see ListItem); after the new items mounted,\n // focus moves to the same item (C-DISABLED: focus is never dropped to <body>), found in a\n // windowed list by its index.\n React.useLayoutEffect(() => {\n const loss = registry.takeFocusLoss();\n const root = rootElementRef.current;\n if (!loss || !root) return;\n const doc = root.ownerDocument;\n const active = doc.activeElement;\n // Focus placed elsewhere in this commit (an autoFocus, a restore-focus hook) wins.\n if (active && active !== doc.body && active.isConnected) return;\n getFocusRestoreTarget(root, loss, windowed)?.focus();\n }, [mode, registry, windowed]);\n\n // After every commit of a windowed list: focus the awaited item, which the commit rendered (it\n // is kept), unless focus went outside the list meanwhile; and when `count` dropped to or below\n // the focused item, move focus (the list had it: the item was removed with it) and with it the\n // Tab stop to the last item, awaited as a key's target when the window is elsewhere (the focused\n // item was kept outside it). A list that is not windowed keeps nothing.\n React.useLayoutEffect(() => {\n const root = rootElementRef.current;\n if (!windowed || !root) {\n windowFocus.update(NO_WINDOW_FOCUS);\n return;\n }\n const doc = root.ownerDocument;\n const active = doc.activeElement;\n // Focus lost to nothing (to the body, or with a removed item).\n const lost = !active || active === doc.body || !active.isConnected || active === root;\n const { pending } = windowFocus.getSnapshot();\n if (pending !== null) {\n windowFocus.update({ pending: null });\n const element = pending < itemCount ? getWindowItem(root, pending) : null;\n // The focus handler records it as the focused item.\n if (element && (lost || root.contains(active))) getItemFocusTarget(element)?.focus();\n }\n const { focused } = windowFocus.getSnapshot();\n if (focused === null || focused < itemCount) return;\n if (lost && itemCount > 0) {\n const last = getWindowItem(root, itemCount - 1);\n if (last) {\n getItemFocusTarget(last)?.focus();\n } else {\n windowFocus.update({ focused: null, pending: itemCount - 1 });\n activeWindow?.scrollToIndex(itemCount - 1, { align: 'auto' });\n return;\n }\n }\n if (windowFocus.getSnapshot().focused === focused) windowFocus.update({ focused: null });\n });\n\n // A plain list that stops navigating (`items` to `none`) keeps its item elements, but they lose\n // their tabindex: focus on one moves to its first focusable content, as after a remount.\n React.useLayoutEffect(() => {\n if (navigable) return;\n const root = rootElementRef.current;\n const active = root?.ownerDocument.activeElement;\n if (!active || active.parentElement !== root || active.hasAttribute('tabindex')) return;\n getFocusables(active as HTMLElement)[0]?.focus();\n }, [navigable]);\n\n // After every commit (the items' layout effects ran first): keep the registered values in DOM\n // order, so `tabStopValue` is the first selected item in the DOM even after items were inserted\n // between others or reordered by key (table-core#22). O(n); re-renders only when the order changed.\n React.useLayoutEffect(() => {\n registry.syncOrder(rootElementRef.current);\n });\n\n const toggleItem = React.useCallback(\n (value: string) => {\n setSelected((previous) => {\n // From the effective selection, so values of removed items are never reported again; a\n // windowed list keeps the values of the items it does not render.\n const current = windowed ? previous : registry.prune(previous);\n const isSelected = current.includes(value);\n if (multiple) {\n return isSelected ? current.filter((item) => item !== value) : [...current, value];\n }\n return isSelected ? [] : [value];\n });\n },\n [multiple, registry, setSelected, windowed],\n );\n\n // Registered values of a selectable list that more than one item holds (development warning).\n const duplicates = registered?.duplicates ?? EMPTY;\n React.useEffect(() => {\n for (const value of duplicates) warnDuplicateValue(value);\n }, [duplicates]);\n\n const selectedCount = effective.length;\n React.useEffect(() => {\n if (selectable && !multiple && selectedCount > 1) {\n warnOnce(\n 'List:single-several-selected',\n `List: a single-selection list (selectionMode \"single\") received ${selectedCount} selected items. Pass one value with \\`selectedItem\\`, or use selectionMode=\"multiple\".`,\n );\n }\n }, [selectable, multiple, selectedCount]);\n\n const itemsWithActions = selectable && navigationMode === 'items' && hasActions;\n const noneSelectable = selectable && navigationMode === 'none';\n React.useEffect(() => {\n if (itemsWithActions) {\n warnOnce(\n 'List:items-with-actions',\n 'List: a selectable list whose items have actions is a grid (an option cannot hold interactive content), so navigationMode=\"items\" acts as \"composite\". Set navigationMode=\"composite\".',\n );\n }\n if (noneSelectable) {\n warnOnce(\n 'List:none-selectable',\n 'List: navigationMode=\"none\" has no effect on a selectable list, whose items are always reached with the arrow keys. Remove it, or use \"items\" or \"composite\".',\n );\n }\n }, [itemsWithActions, noneSelectable]);\n\n React.useEffect(() => {\n if (windowIgnored) {\n warnOnce(\n 'List:virtual-window-children',\n 'List: a windowed list needs `virtualWindow`, `count` and a function child that returns ' +\n 'the `List.Item` at an index; without one of them the window is ignored (a function ' +\n 'child then renders nothing, and element children are all rendered).',\n );\n }\n }, [windowIgnored]);\n\n React.useEffect(() => {\n if (windowActions) {\n warnOnce(\n 'List:virtual-window-actions',\n 'List: a selectable windowed list keeps its listbox structure whatever items are ' +\n 'rendered, so an item action sits inside an option, which cannot hold interactive ' +\n 'content. Set navigationMode=\"composite\" to render a grid whose rows hold the actions.',\n );\n }\n }, [windowActions]);\n\n const contextValue = React.useMemo<ListContextValue>(\n () => ({\n mode,\n navigable,\n selection: selectable,\n checkmark: drawsCheckmark,\n selectedValues,\n toggleItem,\n getTabIndex,\n registry,\n listWindow,\n }),\n [\n mode,\n navigable,\n selectable,\n drawsCheckmark,\n selectedValues,\n toggleItem,\n getTabIndex,\n registry,\n listWindow,\n ],\n );\n\n const Root = (mode === 'grid' ? 'div' : 'ul') as React.ElementType;\n const role = mode === 'grid' ? 'grid' : mode === 'listbox' ? 'listbox' : 'list';\n\n // A windowed list renders its window: each item with its index, each gap as a spacer.\n const content = windowEntries\n ? windowEntries.map((entry) =>\n entry.kind === 'item' ? (\n <ListItemIndexContext.Provider key={entry.index} value={entry.index}>\n {entry.node}\n </ListItemIndexContext.Provider>\n ) : (\n <ListSpacer key={entry.key} grid={mode === 'grid'} size={entry.size} />\n ),\n )\n : elementChildren;\n\n return (\n <ListContext.Provider value={contextValue}>\n <Root\n role={role}\n aria-multiselectable={selectable && multiple ? true : undefined}\n aria-rowcount={windowed && mode === 'grid' ? itemCount : undefined}\n data-navigation-mode={navigation}\n data-checkmark={drawsCheckmark ? '' : undefined}\n // A windowed list that navigates its items has its Tab stop on an item: the scroller is\n // none of its own (Firefox makes a scroller a Tab stop). The consumer's `tabIndex` wins.\n tabIndex={windowed && navigable ? -1 : undefined}\n className={cn(\n listClassNames.root,\n 'm-0 list-none p-0',\n // The window lays the items out: the browser's scroll anchoring only fights it.\n windowed && 'overflow-y-auto [overflow-anchor:none]',\n className,\n )}\n {...rest}\n ref={rootRef}\n data-roving-container={navigable ? '' : undefined}\n onKeyDown={navigable ? composeEventHandlers(onKeyDown, internalKeyDown) : onKeyDown}\n onKeyDownCapture={\n navigable\n ? composeEventHandlers(onKeyDownCapture, rovingKeyDownCapture)\n : onKeyDownCapture\n }\n onFocus={\n internalFocus\n ? composeEventHandlers(onFocus, internalFocus, { checkDefaultPrevented: false })\n : onFocus\n }\n onBlur={\n windowed\n ? composeEventHandlers(onBlur, handleWindowBlur, { checkDefaultPrevented: false })\n : onBlur\n }\n >\n {content}\n </Root>\n </ListContext.Provider>\n );\n};\nListRoot.displayName = 'List';\n\n/* ------------------------------------------------------------------ */\n/* ListItem */\n/* ------------------------------------------------------------------ */\n\n/**\n * Forced colors: the check takes the `Highlight` of the selected item's outline, `GrayText` while\n * its selection is disabled. Both opt the check (a leaf indicator) out of forced colors, so the\n * system color reaches the glyph.\n */\nconst CHECKMARK_FORCED_COLORS =\n 'forced-colors:text-[Highlight] forced-colors:forced-color-adjust-none';\nconst CHECKMARK_DISABLED_FORCED_COLORS =\n 'forced-colors:text-[GrayText] forced-colors:forced-color-adjust-none';\n\n/**\n * The check mark of an item of a selectable list: decorative, kept in its place but not drawn while\n * the item is not selected, so the item texts line up. It is the item's last element and is drawn\n * first (flex order): the item's text, which typeahead reads, starts with its content. `glyph` is\n * the item's `checkmark` when it renders content, else `undefined` for the default check.\n */\nfunction renderCheckmark(\n glyph: Slot<'span'> | undefined,\n { selected, disabled }: { selected: boolean; disabled: boolean },\n): React.ReactNode {\n const classes = cn(\n listItemClassNames.checkmark,\n 'order-first me-2 inline-flex shrink-0 items-center justify-center',\n disabled\n ? ['text-muted-foreground', CHECKMARK_DISABLED_FORCED_COLORS]\n : ['text-primary', CHECKMARK_FORCED_COLORS],\n !selected && 'invisible',\n );\n return glyph === undefined ? (\n <span aria-hidden=\"true\" className={classes}>\n <CheckIcon />\n </span>\n ) : (\n renderSlot(glyph, 'span', classes, { 'aria-hidden': true })\n );\n}\n\n/**\n * An item of a {@link List} (also available as `List.Item`). Renders an `<li>` (`listitem`, or\n * `option` in a selectable list), or a `<div role=\"row\">` in a grid (a selectable list with\n * actions, or `navigationMode=\"composite\"`). In a selectable list, Enter and Space toggle the\n * selection without calling `onClick`, which receives pointer clicks; `onAction` runs on clicks\n * and Enter (and Space where the item cannot be selected), before the selection toggles.\n *\n * In a windowed list (the List's `virtualWindow`) an item has the window's item size as its\n * height, after its own `style` (its content must fit), and carries `data-index` and its place\n * in the whole list: `aria-setsize` and `aria-posinset`, or `aria-rowindex` in a grid.\n *\n * Exported under the flat name `ListItem` so React Server Components can import it; `List.Item`\n * (dotted access) needs a client module.\n */\nexport const ListItem = ({\n value,\n action,\n onAction,\n disabledSelection = false,\n checkmark,\n className,\n style,\n children,\n onClick,\n onKeyDown,\n ref,\n ...rest\n}: ListItemProps) => {\n const {\n mode,\n navigable,\n selection,\n checkmark: listCheckmark,\n selectedValues,\n toggleItem,\n getTabIndex,\n registry,\n listWindow,\n } = useListContext('ListItem');\n const providedIndex = React.useContext(ListItemIndexContext);\n // The item's index in a windowed list; `null` in a list that renders every item.\n const windowIndex = listWindow ? providedIndex : null;\n const autoValue = useId('list-item');\n const selectableValue = value ? value : undefined;\n const rovingValue = selectableValue ?? autoValue;\n // An action that renders nothing (`[]`, `null`, booleans, `''`) is no action.\n const hasAction = slotRendersContent(action);\n const [token] = React.useState(() => ({}));\n const itemRef = React.useRef<HTMLLIElement | HTMLDivElement | null>(null);\n const itemRefs = useMergedRefs<HTMLLIElement | HTMLDivElement>(ref, itemRef);\n\n // The record is updated in place when the value or the action changes and removed only on\n // unmount, so the item keeps its place in the registry (table-core#22).\n React.useLayoutEffect(() => {\n registry.set(token, {\n value: selectableValue,\n hasAction,\n element: itemRef,\n index: windowIndex ?? undefined,\n });\n }, [registry, token, selectableValue, hasAction, windowIndex]);\n React.useLayoutEffect(() => () => registry.delete(token), [registry, token]);\n\n // Focus inside the action when it disappears: if that switches the list from grid to listbox, the\n // List moves focus to this item in the next commit (see ListActionCell and ListRoot). The item's\n // position is its index in a windowed list (spacers are no items), else its place in the DOM.\n const recordActionFocusLoss = useEventCallback((cell: HTMLElement) => {\n const item = cell.parentElement;\n registry.recordFocusLoss({\n value: selectableValue,\n index: windowIndex ?? (item ? getItemIndex(item) : -1),\n });\n });\n\n // Unmount: a layout-effect cleanup runs while the element is still in the document, so it can\n // tell whether it held focus. The List moves focus to the same item when its items remount\n // (list ↔ grid semantics); see ListRoot.\n React.useLayoutEffect(() => {\n const node = itemRef.current;\n return () => {\n if (!node) return;\n const active = node.ownerDocument.activeElement;\n if (active && node.contains(active)) {\n registry.recordFocusLoss({\n value: selectableValue,\n index: windowIndex ?? getItemIndex(node),\n });\n }\n };\n }, [registry, selectableValue, windowIndex]);\n\n // C-DEV: an item that is no Tab stop cannot be activated with the keyboard.\n const actionNotNavigable = onAction !== undefined && !navigable;\n React.useEffect(() => {\n if (actionNotNavigable) {\n warnOnce(\n 'List.Item:action-not-navigable',\n 'List.Item: `onAction` runs only on clicks here: the List does not navigate its items, so keyboard users cannot reach them. Set navigationMode=\"items\" (or \"composite\") on the List, or make it selectable.',\n );\n }\n }, [actionNotNavigable]);\n\n const isSelected =\n selection && selectableValue !== undefined && selectedValues.has(selectableValue);\n // The item can be selected (a selectable list, and a value); `disabledSelection` keeps it as is.\n const itemSelectable = selection && selectableValue !== undefined;\n const selectionDisabled = selection && disabledSelection;\n // Without an action, an item whose selection is disabled can do nothing: it is aria-disabled.\n const ariaDisabled = selectionDisabled && onAction === undefined;\n\n const toggle = () => {\n if (selection && !disabledSelection && selectableValue !== undefined) {\n toggleItem(selectableValue);\n }\n };\n\n /** A click or Enter: `onAction`, then the selection unless `onAction` called preventDefault(). */\n const activate = (event: ListItemActionEvent) => {\n onAction?.(event);\n if (!event.isDefaultPrevented()) toggle();\n };\n\n const handleClick = (event: React.MouseEvent<HTMLElement>) => {\n if (isForeignItemEvent(event)) return;\n activate(event);\n };\n\n /** Enter or Space on the focused item itself. */\n const handleActivationKey = (event: React.KeyboardEvent<HTMLElement>) => {\n if (event.key === ' ' && itemSelectable) {\n // Space is the selection key of an item that can be selected: it never runs onAction.\n event.preventDefault();\n toggle();\n return;\n }\n // An item with nothing to activate leaves the key to the page.\n if (!selection && onAction === undefined) return;\n // Not prevented before: `onAction` may cancel the selection with preventDefault().\n activate(event);\n // Space would scroll the page.\n event.preventDefault();\n };\n\n const handleOptionKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n if (isForeignItemEvent(event)) return;\n if (isActivationKey(event)) handleActivationKey(event);\n };\n\n const handleRowKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n const rowElement = event.currentTarget;\n const target = event.target as HTMLElement;\n const cell = getActionCell(rowElement);\n\n if (!cell || !cell.contains(target)) {\n if (target !== rowElement) return;\n if (isActivationKey(event)) {\n handleActivationKey(event);\n return;\n }\n const intent = getArrowIntent(event.key, {\n orientation: 'horizontal',\n dir: getDirection(rowElement),\n });\n const first = intent === 'next' && cell ? getActionStops(cell)[0] : undefined;\n if (first) {\n event.preventDefault();\n first.focus();\n }\n return;\n }\n\n // Inside the action cell.\n if (target !== cell && isTextEntry(target)) {\n // The widget keeps its keys (caret movement, typing); Escape returns to the cell.\n if (event.key === 'Escape') {\n event.preventDefault();\n cell.focus();\n }\n return;\n }\n if (target === cell && (event.key === 'Enter' || event.key === 'F2')) {\n const entry = getFocusables(cell).find((el) => isTextEntry(el));\n if (entry) {\n event.preventDefault();\n entry.focus();\n }\n return;\n }\n const intent = getArrowIntent(event.key, {\n orientation: 'horizontal',\n dir: getDirection(rowElement),\n });\n if (!intent) return;\n event.preventDefault();\n const stops = getActionStops(cell);\n const index = stops.indexOf(target);\n if (intent === 'next') {\n stops[index + 1]?.focus();\n } else if (index > 0) {\n stops[index - 1].focus();\n } else {\n rowElement.focus();\n }\n };\n\n const Element = (mode === 'grid' ? 'div' : 'li') as React.ElementType;\n const ContentCell = (mode === 'grid' ? 'div' : 'span') as React.ElementType;\n const role = mode === 'grid' ? 'row' : mode === 'listbox' ? 'option' : 'listitem';\n\n const interactiveProps: Record<string, unknown> = navigable\n ? {\n 'aria-selected': selection ? isSelected : undefined,\n tabIndex: getTabIndex(rovingValue),\n 'data-roving-value': rovingValue,\n 'data-selected': isSelected ? '' : undefined,\n // C-DISABLED: focusable, and kept in the arrow-key order.\n ...focusableDisabledProps(ariaDisabled, { reachable: true }),\n onClick: composeEventHandlers(onClick, handleClick),\n onKeyDown: composeEventHandlers(\n onKeyDown,\n mode === 'grid' ? handleRowKeyDown : handleOptionKeyDown,\n ),\n }\n : {\n // Clicks only (see the warning above); an item without onAction is left as it is.\n onClick: onAction ? composeEventHandlers(onClick, handleClick) : onClick,\n onKeyDown,\n };\n\n // A selectable list's items are clickable unless their selection is disabled and they have no\n // action; in a list without selection only the items with an action are.\n const cursor = selection\n ? ariaDisabled\n ? 'cursor-default'\n : 'cursor-pointer'\n : onAction && 'cursor-pointer';\n const hoverable = selection ? !ariaDisabled : onAction !== undefined;\n\n // `checkmark` is an optional indicator (C-SLOTS): unset follows the List, content replaces the\n // check, a value that renders nothing hides it.\n const customCheckmark = checkmark != null && slotRendersContent(checkmark);\n const showCheckmark = selection && (checkmark == null ? listCheckmark : customCheckmark);\n\n // In a windowed list: the item's index and its place in the whole list (a grid's rows carry\n // `aria-rowindex` against the list's `aria-rowcount`), after `rest` (the window depends on them).\n const windowProps: Record<string, unknown> =\n listWindow && windowIndex !== null\n ? {\n 'data-index': windowIndex,\n ...(mode === 'grid'\n ? { 'aria-rowindex': windowIndex + 1 }\n : { 'aria-setsize': listWindow.count, 'aria-posinset': windowIndex + 1 }),\n }\n : {};\n\n return (\n <Element\n role={role}\n data-disabled-selection={selectionDisabled ? '' : undefined}\n className={cn(\n listItemClassNames.root,\n 'flex items-center border-b border-border px-4 py-2 text-body-1',\n // A windowed item is exactly the window's item size, its bottom rule included.\n windowIndex !== null && 'box-border',\n navigable ? ['relative', cursor, focusRingInset] : cursor,\n isSelected\n ? [\n 'bg-subtle-selected before:absolute before:inset-y-2 before:start-0 before:w-0.5 before:rounded-full before:bg-primary',\n forcedColors.selectedContainer,\n ]\n : hoverable && 'hover:bg-subtle-hover',\n className,\n )}\n style={listWindow && windowIndex !== null ? { ...style, height: listWindow.itemSize } : style}\n {...rest}\n ref={itemRefs}\n {...interactiveProps}\n {...windowProps}\n >\n <ContentCell\n role={mode === 'grid' ? 'gridcell' : undefined}\n className={cn(listItemClassNames.content, 'min-w-0 flex-1')}\n >\n {children}\n </ContentCell>\n {hasAction && (\n <ListActionCell grid={mode === 'grid'} onRemovedWithFocus={recordActionFocusLoss}>\n {/* A generator was read once by the check above: render its items. */}\n {materialiseSlotContent(action)}\n </ListActionCell>\n )}\n {showCheckmark &&\n renderCheckmark(customCheckmark ? checkmark : undefined, {\n selected: isSelected,\n disabled: selectionDisabled,\n })}\n </Element>\n );\n};\nListItem.displayName = 'ListItem';\n\n/**\n * Nested composite widgets (a Toolbar, a RadioGroup, …) manage their own tab indexes, so the action\n * cell never writes `tabindex` on or inside one (the same rule as the DataGrid's cell widgets).\n */\nconst COMPOSITE_SELECTOR = [\n '[data-roving-container]',\n ...[\n 'toolbar',\n 'radiogroup',\n 'listbox',\n 'grid',\n 'treegrid',\n 'tablist',\n 'menu',\n 'menubar',\n 'tree',\n ].map((role) => `[role=\"${role}\"]`),\n].join(', ');\n\n/** Attributes that can put an element of an action cell (back) into the Tab order. */\nconst STAMP_OBSERVED_ATTRIBUTES = ['tabindex', 'href', 'contenteditable', 'controls'];\n\n/**\n * Grid mode: takes the focusable elements of an action cell out of the Tab order (the row is the\n * only Tab stop; the actions are reached with the arrow keys) and keeps them out while the cell is\n * mounted. Returns the cleanup that disconnects the observer and restores the original values.\n *\n * It runs once per cell, not on every render of every item (an inline `action` has a new identity\n * on every parent render): a `MutationObserver` re-stamps when elements are added to the cell or an\n * element's `tabindex` is changed by someone else, including by an action component's own state.\n * Every candidate of `FOCUSABLE_SELECTOR` is stamped, disabled or hidden ones too, so an element\n * that is enabled or shown later is already out of the Tab order and no computed style is read.\n * Removed elements are dropped from the record on each pass. Nested composites are skipped (see\n * `COMPOSITE_SELECTOR`), and an element whose replaced `tabindex` something else re-applies (a\n * script that manages it) is left alone from then on, so the two never overwrite each other in an\n * endless loop of observer callbacks.\n */\nfunction stampActionCell(cell: HTMLElement): () => void {\n /** Stamped elements with the `tabindex` they had before (`null`: none). */\n const stamped = new Map<HTMLElement, string | null>();\n /** Elements whose `tabindex` something else keeps re-applying: they are left to it. */\n const yielded = new WeakSet<HTMLElement>();\n const stamp = () => {\n for (const el of stamped.keys()) {\n if (!cell.contains(el)) stamped.delete(el);\n }\n for (const el of cell.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)) {\n const tabIndex = el.getAttribute('tabindex');\n if (tabIndex === '-1' || yielded.has(el)) continue;\n const composite = el.closest(COMPOSITE_SELECTOR);\n if (composite && cell.contains(composite)) continue;\n stamped.set(el, tabIndex);\n el.setAttribute('tabindex', '-1');\n }\n };\n stamp();\n if (typeof MutationObserver === 'undefined') return () => {};\n\n const observer = new MutationObserver((records) => {\n // The records of this cell's own writes are taken below, so these values were set by someone\n // else: a changed prop (the new value to restore), or a script that manages the element's\n // tabindex and re-applied the value this cell replaced. Yielding to the latter keeps the two\n // from overwriting each other forever.\n const changed = new Set<HTMLElement>();\n for (const record of records) {\n const target = record.target as HTMLElement;\n if (record.attributeName === 'tabindex' && stamped.has(target)) changed.add(target);\n }\n for (const el of changed) {\n const value = el.getAttribute('tabindex');\n if (value !== '-1' && value === stamped.get(el)) {\n stamped.delete(el);\n yielded.add(el);\n } else {\n stamped.set(el, value);\n }\n }\n stamp();\n observer.takeRecords();\n });\n observer.observe(cell, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeFilter: STAMP_OBSERVED_ATTRIBUTES,\n });\n return () => {\n observer.disconnect();\n for (const [el, original] of stamped) {\n if (original === null) el.removeAttribute('tabindex');\n else el.setAttribute('tabindex', original);\n }\n stamped.clear();\n };\n}\n\ninterface ListActionCellProps {\n /** Grid mode: a focusable `gridcell` div whose widgets leave the Tab order; otherwise a `span`. */\n grid: boolean;\n /** Called when the cell is removed while focus is inside it (the cell is still in the document). */\n onRemovedWithFocus: (cell: HTMLElement) => void;\n children: React.ReactNode;\n}\n\n/**\n * The action cell of a {@link ListItem} (internal). React runs the layout-effect cleanups of a\n * removed subtree before it removes the subtree's DOM, but a component's own cleanups only after\n * its removed children are gone. So this cleanup, unlike one in ListItem, still sees focus inside\n * the cell when the action disappears (data-display#2).\n *\n * `grid` never changes for a mounted cell: switching between list and grid semantics changes the\n * List's root element, which remounts the items and their cells.\n */\nfunction ListActionCell({ grid, onRemovedWithFocus, children }: ListActionCellProps) {\n const cellRef = React.useRef<HTMLElement | null>(null);\n\n React.useLayoutEffect(() => {\n const cell = cellRef.current;\n return () => {\n if (!cell) return;\n const active = cell.ownerDocument.activeElement;\n if (active && cell.contains(active)) onRemovedWithFocus(cell);\n };\n }, [onRemovedWithFocus, grid]);\n\n React.useLayoutEffect(() => {\n const cell = cellRef.current;\n return grid && cell ? stampActionCell(cell) : undefined;\n }, [grid]);\n\n const Cell = (grid ? 'div' : 'span') as React.ElementType;\n return (\n <Cell\n ref={cellRef}\n role={grid ? 'gridcell' : undefined}\n tabIndex={grid ? -1 : undefined}\n data-list-action=\"\"\n className={cn(listItemClassNames.action, 'ms-2 shrink-0', grid && focusRingInset)}\n >\n {children}\n </Cell>\n );\n}\nListActionCell.displayName = 'ListActionCell';\n\n/**\n * A vertical list of items, optionally selectable.\n *\n * - **Plain** (`selectable` false): `role=\"list\"` with `listitem`s; item actions stay in the\n * normal Tab order.\n * - **Selectable** (APG Listbox): `role=\"listbox\"` with `option`s and one Tab stop (the first\n * selected option, else the first option). ArrowUp/Down move focus (wrapping), Home/End jump to\n * the ends, typeahead is on for more than 7 items, Enter/Space and clicks toggle selection (a\n * Space typed within 500 ms of a typeahead character continues the search instead; with Ctrl,\n * Alt or Meta, Enter and Space are left to the page).\n * - **Selectable with item actions** (APG Grid): `role=\"grid\"` with `row`s (carrying\n * `aria-selected`) and `gridcell`s for the content and the action. One Tab stop; Up/Down move\n * between rows, Right/Left (mirrored in RTL) move into and out of the actions. A cell that holds\n * a text-entry widget takes focus itself: Enter/F2 enter the widget, Escape returns to the cell.\n * Clicks and keys that start inside an action, or inside a popup it opens (a Popover, a Menu),\n * never toggle selection.\n * - **Navigation without selection** (`navigationMode`): `'items'` makes the items of a plain list\n * one Tab stop (the item that last had focus) with the listbox's arrow keys, Home/End and\n * typeahead, keeping `role=\"list\"`; `'composite'` renders the grid above from the first render,\n * for a selectable list too, so the items never remount when actions appear. The items of a\n * list without selection carry no `aria-selected`. The resolved mode is `data-navigation-mode`.\n * - **Actions on the item itself** (`List.Item onAction`): clicks and Enter run it, and Space on\n * an item that cannot be selected; in a selectable item it runs before the selection toggles,\n * and its `preventDefault()` keeps the selection. `List.Item disabledSelection` keeps an item's\n * selection as it is while the item stays focusable and in the arrow-key order.\n * - **Check marks** (`checkmark`, opt-in): a decorative check at the start of every item of a\n * selectable list, shown while the item is selected; `List.Item checkmark` replaces or hides it.\n * - **Switching semantics remounts the items.** Listbox/list and grid use different elements\n * (`ul`/`li` and `div`), so when a selectable list without a window gains its first item\n * action, loses its last one, or `selectable` or `navigationMode` changes the structure, React\n * remounts the items and their content: state inside them (an inline rename input's draft, an\n * uncontrolled checkbox) is reset. Focus that is on an item or inside it when the list switches\n * moves to the same item (by `value`, else by position; the next item when the focused one was\n * removed), or to its first focusable content when the item is no Tab stop any more, so the\n * switch never drops it to `<body>`. This includes focus inside the last action when that action\n * removes itself (an inline rename input that unmounts on Enter). An action that removes itself\n * while focused without causing a switch drops focus, like any removed element. When the list\n * may switch, keep such state in the parent, or pin the grid with `navigationMode=\"composite\"`.\n * - Selection: `selectionMode` `'single'` (default) or `'multiple'`; controlled with\n * `selectedItems` (or `selectedItem` in single mode) or uncontrolled with the `default*` props.\n * Values of items that are no longer rendered are dropped from the reported selection (a\n * windowed list keeps them).\n * - **Windowing** (`virtualWindow` and `count`, for long lists): a window from `useVirtualWindow`\n * and a function child that returns the item at an index render only the items in view plus an\n * overscan, with spacers for the others. The list element scrolls (give it a bounded height),\n * every item has the window's item size as its height, the focused item stays rendered and is\n * the Tab stop while focus is in the list, each item carries its place in the whole list, and\n * the values selected outside the window stay selected. The keys move by index over the whole\n * list (ArrowUp/ArrowDown, Home/End, and PageUp/PageDown by ten), scrolling the target into view\n * before focusing it, rendered or not; typeahead matches the rendered items. Its structure\n * never follows the rendered items: a selectable windowed list is a listbox unless\n * `navigationMode=\"composite\"` pins the grid (pin it when items have actions; a development\n * warning says so).\n * - Sub-component: `List.Item` (also exported as `ListItem` for React Server Components).\n *\n * @example\n * <List selectable selectionMode=\"multiple\" aria-label=\"Fruits\" onSelectionChange={setFruits}>\n * <List.Item value=\"apple\">Apple</List.Item>\n * <List.Item value=\"banana\">Banana</List.Item>\n * </List>\n *\n * @example\n * <List navigationMode=\"items\" aria-label=\"Recent files\">\n * <List.Item value=\"report\" onAction={() => open('report')}>Report</List.Item>\n * <List.Item value=\"budget\" onAction={() => open('budget')}>Budget</List.Item>\n * </List>\n *\n * @example\n * const virtualWindow = useVirtualWindow({ itemSize: 40 });\n * <List\n * selectable\n * aria-label=\"Files\"\n * virtualWindow={virtualWindow}\n * count={files.length}\n * style={{ height: 320 }}\n * >\n * {(index) => <List.Item value={files[index].id}>{files[index].name}</List.Item>}\n * </List>\n */\nexport const List = /* @__PURE__ */ Object.assign(ListRoot, {\n Item: ListItem,\n});\n"],"mappings":"+yBAwQA,IAAMgD,EAAchD,EAAM,cAAuC,IAAI,EACrE,EAAY,YAAc,cAM1B,IAAMiD,GAAuBjD,EAAM,cAA6B,IAAI,EACpE,GAAqB,YAAc,uBAEnC,IAAIkD,EAAwC,KAE5C,SAASC,GAAoC,CAY3C,MAXA,KAAiB,CACf,KAAM,OACN,UAAW,GACX,UAAW,GACX,UAAW,GACX,eAAgB,IAAI,IACpB,eAAkB,CAAC,EACnB,gBAAmB,GACnB,SAAU,IAAIlD,GAAAA,aACd,WAAY,IACd,EACOiD,CACT,CAEA,SAASE,GAAe,EAAyC,CAI/D,OAHgBpD,EAAM,WAAWgD,CAC7B,IACJlB,EAAA,qBAAqBuB,EAAe,QAAQ,EACrCF,EAAgB,EACzB,CAMA,IAAMG,GAA2B,CAAC,EAOlC,SAASC,EACP,EACA,EACA,EACoD,CAKpD,OAJIC,IAAmB,aAAgBC,GAAcC,EAC5C,CAAE,KAAM,OAAQ,WAAY,WAAY,EAE7CD,EAAmB,CAAE,KAAM,UAAW,WAAY,OAAQ,EACvD,CAAE,KAAM,OAAQ,WAAYD,IAAmB,QAAU,QAAU,MAAO,CACnF,CAGA,SAASG,GAAmB,EAAqB,CAC/C7B,EAAA,SACE,kBAAkB8B,IAClB,wCAAwCA,EAAM,8GAEhD,CACF,CAMA,SAASC,EAAmB,EAAoC,CAC9D,OAAO3D,EAAAA,gBAAgB4D,CAAQ,CAAC,CAAC,MAC9B,CAAE,UACD3D,EAAAA,gBAA+B4D,EAAMC,CAAQ,GAAK5D,EAAAA,mBAAmB2D,EAAK,MAAM,MAAM,CAC1F,CACF,CAGA,IAAME,GAA2C,CAC/C,YAAa,GAAG5D,EAAAA,qBAAqB,qBACvC,EAQA,SAAS6D,EAAmB,EAAmD,CAC7E,OAAO5D,EAAAA,eAAe6D,EAAOF,EAAmB,CAClD,CAMA,SAASG,GAAgB,EAAqC,CAE5D,OADID,EAAM,SAAWA,EAAM,QAAUA,EAAM,QAAgB,GACpDA,EAAM,MAAQ,SAAWA,EAAM,MAAQ,GAChD,CAEA,IAAME,EAAwC,IAAI,IAAI,CACpD,UACA,YACA,WACA,aACA,QACF,CAAC,EAEKC,EAA4C,IAAI,IAAI,CACxD,SACA,WACA,QACA,OACA,SACA,QACA,QACA,QACA,QACF,CAAC,EAGD,SAASC,EAAY,EAAsB,CACzC,IAAMC,EAAOC,EAAG,aAAa,MAAM,EACnC,GAAID,IAAS,MAAQH,EAAiB,IAAIG,CAAI,EAAG,MAAO,GACxD,IAAME,EAAMD,EAAG,UAGf,OAFIC,IAAQ,YAAcA,IAAQ,SAAiB,GAC/CA,IAAQ,QAAgB,CAACJ,EAAqB,IAAKG,EAAwB,IAAI,EAC5EA,EAAG,QAAQ,kDAAkD,CACtE,CAEA,SAASE,EAAc,EAAkC,CACvD,OAAO,MAAM,KAAKC,EAAK,iBAA8BrE,EAAAA,kBAAkB,CAAC,CAAC,CAAC,OAAQ,GAChFC,EAAAA,YAAYiE,CAAE,CAChB,CACF,CAUA,SAASI,EAAa,EAA2B,CAC/C,GAAI,CAACC,EAAK,cAAe,MAAO,GAChC,IAAIC,EAAQ,EACZ,IAAK,IAAIN,EAAKK,EAAK,uBAAwBL,EAAI,EAAKA,EAAG,uBAAwB,IAC/E,OAAOM,CACT,CAGA,SAASC,EAAmB,EAAuC,CACjE,OAAOF,EAAK,aAAa,UAAU,EAAIA,EAAQH,EAAcG,CAAI,CAAC,CAAC,IAAM,IAC3E,CASA,SAASG,EACP,EACA,EACA,EACoB,CACpB,IAAIC,EAA0B,KAC1BC,EAA0B,KAC1BC,EAAuB,KACvBL,EAAQ,EACZ,IAAK,IAAIN,EAAKY,EAAK,kBAAmBZ,EAAI,EAAKA,EAAG,mBAAoB,IAAS,CAC7E,IAAMa,EAAWC,EAAWC,EAAkBf,CAAE,EAAIM,EACpD,GAAIO,IAAa,KACjB,IAAIG,EAAK,QAAU,IAAA,IAAahB,EAAG,aAAa,mBAAmB,IAAMgB,EAAK,MAAO,CACnF,EAAUhB,EACV,KACF,CACIa,IAAaG,EAAK,QAAO,EAAUhB,GACvC,EAAOA,CAFP,CAGF,CACA,IAAMK,EAAQI,GAAWC,IAAYM,EAAK,OAAS,EAAIL,EAAO,MAC9D,OAAON,EAAOE,EAAmBF,CAAI,EAAI,IAC3C,CAGA,SAASY,EAAY,EAAmC,CACtD,OAAOC,IAAU,IAAA,IAAa,OAAO,SAASA,CAAK,EAAI,KAAK,IAAI,EAAG,KAAK,MAAMA,CAAK,CAAC,EAAI,CAC1F,CAGA,SAASC,GAAY,GAAGC,EAAwD,CAC9E,OAAOA,EAAQ,OAAQ,GAA2Bd,IAAU,IAAI,CAClE,CAGA,SAASS,EAAkB,EAA4B,CACrD,IAAM5B,EAAQa,EAAG,aAAa,YAAY,EAC1C,OAAOb,IAAU,MAAQ,QAAQ,KAAKA,CAAK,EAAI,OAAOA,CAAK,EAAI,IACjE,CAMA,SAASkC,GAAmB,EAAe,EAAoC,CAC7E,IAAIrB,EAAKsB,aAAkB,QAAUA,EAAS,KAC9C,KAAOtB,GAAMA,EAAG,gBAAkBY,GAAM,EAAKZ,EAAG,cAChD,OAAOA,EAAKe,EAAkBf,CAAE,EAAI,IACtC,CAGA,SAASuB,EAAc,EAAe,EAAmC,CACvE,IAAK,IAAIvB,EAAKY,EAAK,kBAAmBZ,EAAI,EAAKA,EAAG,mBAChD,GAAIe,EAAkBf,CAAE,IAAMM,EAAO,OAAON,EAE9C,OAAO,IACT,CAMA,IAAMwB,EAAmB,GAQzB,SAASC,EAAmB,EAAa,EAAqB,EAAmC,CAC/F,IAAMd,EAAOO,EAAQ,EACfQ,EAAKC,IAAS,KAAO,KAAO,KAAK,IAAIA,EAAMhB,CAAI,EACrD,OAAQiB,EAAR,CACE,IAAK,YACH,OAAOF,IAAO,MAAQA,IAAOf,EAAO,EAAIe,EAAK,EAC/C,IAAK,UACH,OAAOA,IAAO,MAAQA,IAAO,EAAIf,EAAOe,EAAK,EAC/C,IAAK,WACH,OAAOA,IAAO,KAAO,EAAI,KAAK,IAAIA,EAAKF,EAAkBb,CAAI,EAC/D,IAAK,SACH,OAAOe,IAAO,KAAOf,EAAO,KAAK,IAAIe,EAAKF,EAAkB,CAAC,EAC/D,IAAK,OACH,MAAO,GACT,IAAK,MACH,OAAOb,EACT,QACE,MACJ,CACF,CAgBA,IAAMkB,EAA+B,CAAE,QAAS,KAAM,QAAS,IAAK,EAO9DC,EAAN,KAAuB,CACrB,MAA6BD,EAC7B,UAA6B,IAAI,IAEjC,UAAa,IACX,KAAK,UAAU,IAAIE,CAAQ,MACd,CACX,KAAK,UAAU,OAAOA,CAAQ,CAChC,GAGF,gBAAiC,KAAK,MAEtC,sBAAuCF,EAGvC,OAAO,EAAkC,CACvC,IAAMG,EAAQ,CAAE,GAAG,KAAK,MAAO,GAAGC,CAAK,EACvC,GAAID,EAAM,UAAY,KAAK,MAAM,SAAWA,EAAM,UAAY,KAAK,MAAM,QACzE,MAAK,MAAQA,EACb,IAAK,IAAMD,KAAY,KAAK,UAAWA,EAAS,CADnC,CAEf,CACF,EAMA,SAASG,GAAW,CAAE,OAAM,QAAyC,CAEnE,OACE,EAAA5D,EAAA,IAAA,CAFc6D,EAAO,MAAQ,KAE7B,CACE,cAAY,OACZ,KAAK,eACL,sBAAoB,GACpB,UAAWnG,EAAAA,eAAe,OAC1B,MAAO,CAAE,OAAQoG,CAAK,CACvB,CAAA,CAEL,CACA,GAAW,YAAc,aAGzB,SAASC,EAAc,EAAuC,CAC5D,IAAK,IAAIC,EAAQjC,EAAK,kBAAmBiC,EAAO,EAAQA,EAAM,mBAC5D,GAAIA,EAAM,aAAa,kBAAkB,EAAG,OAAOA,EAErD,OAAO,IACT,CAMA,SAASC,EAAe,EAAkC,CACxD,IAAMC,EAAuB,CAAC,EAC9B,IAAK,IAAMxC,KAAME,EAAcC,CAAI,EAAG,CACpC,IAAMsC,EAAO3C,EAAYE,CAAE,EAAIG,EAAOH,EACjCwC,EAAM,SAASC,CAAI,GAAGD,EAAM,KAAKC,CAAI,CAC5C,CACA,OAAOD,CACT,CAOA,IAAME,EAAoD,GAAyC,CACjG,GAAM,CACJ,aAAa,GACb,gBACA,iBACA,uBACA,oBACA,eACA,sBACA,wBACA,iBACA,YAAY,GACZ,gBACA,SACA,aACA,WACA,OACA,YACA,mBACA,UACA,SACA,GAAGC,GACDC,EAGEC,EAAa,OAAOxD,GAAa,WAAaA,EAAW,KACzDyD,EACJC,IAAkB,IAAA,IAAa7B,KAAU,IAAA,IAAa2B,EAAaE,EAAgB,KAC/EjC,EAAWgC,IAAiB,KAC5BE,EACJ,CAAClC,IAAaiC,IAAkB,IAAA,IAAa7B,KAAU,IAAA,IAAa2B,IAAe,MAC/EI,EAAYnC,EAAWG,EAAYC,EAAK,EAAI,EAC5CgC,EAAWJ,GAAc,SACzBK,GAAa5H,EAAM,YAChB2H,IAAa,IAAA,GAAY,KAAO,CAAE,MAAOD,EAAW,UAAS,EACpE,CAACA,EAAWC,CAAQ,CACtB,EAEIE,IAAkB,SACpB/F,EAAA,eAAe,OAAQ,wBAAyB,0BAA0B,EAE5E,IAAMgG,EAAWD,IAAkB,YAAcA,IAAkB,QAE7DE,EAAsB/H,EAAM,YAC5B,CAAC8H,GAAYE,IAAiB,IAAA,GACzBA,IAAiB,KAAO1E,GAAQ,CAAC0E,CAAY,EAE/CC,GACN,CAACH,EAAUE,EAAcC,EAAa,CAAC,EACpCC,EAAmBlI,EAAM,YACzB,CAAC8H,GAAYK,GAA6D,KACrE,CAACA,CAAmB,EAEtBC,GAAwB9E,GAC9B,CAACwE,EAAUK,EAAqBC,CAAoB,CAAC,EAElD,CAACC,EAAUC,IAAe5H,EAAAA,gBAC9BqH,EACAG,EACC,GAAS,CAER,IAAMK,EAAY,CAAC,GAAG7B,CAAI,EAC1B8B,IAAoBD,CAAS,EACxBT,GAAUW,KAAuBF,EAAU,IAAM,IAAI,CAC5D,CACF,EAEM,CAACG,GAAY1I,EAAM,aAAe,IAAIC,GAAAA,YAAc,EACpD0I,EAAa3I,EAAM,qBACvB0I,EAAS,UACTA,EAAS,YACTA,EAAS,iBACX,EAIME,EAAY5I,EAAM,YAEpB2I,GAAc,CAACpD,EACX8C,EAAS,OAAQ,GAAUM,EAAW,SAAS,IAAI/E,CAAK,CAAC,EACzDyE,EACN,CAACM,EAAYN,EAAU9C,CAAQ,CACjC,EACMsD,GAAiB7I,EAAM,YAAmC,IAAI,IAAI4I,CAAS,EAAG,CAACA,CAAS,CAAC,EAIzF,CAACE,GAAe9I,EAAM,aAAe,IAAIuG,CAAkB,EAC3D,CAAE,QAASwC,GAAc,QAASC,IAAiBhJ,EAAM,qBAC7D8I,EAAY,UACZA,EAAY,YACZA,EAAY,iBACd,EACMG,GAAOjJ,EAAM,YACX4F,GAAYmD,GAAcC,EAAY,EAC5C,CAACD,GAAcC,EAAY,CAC7B,EAEME,EACJ3B,GAAgBD,EACZC,EACG,OAAOG,EAAW,CAAE,OAAK,CAAC,CAAC,CAC3B,IAAK,GACJyB,EAAM,OAAS,OAAS,CAAE,GAAGA,EAAO,KAAM7B,EAAW6B,EAAM,KAAK,CAAE,EAAIA,CACxE,EACF,KAEAC,GAAkB9B,EAAa,KAAQxD,EAGvCuF,GACJ5F,GACAD,IAAmB,cAClBmF,EACGA,EAAW,WACX9E,EACEqF,EACIA,EAAc,IAAK,GAAWC,EAAM,OAAS,OAASA,EAAM,KAAO,IAAK,EACxEC,EACN,GAIA1F,GAAa2F,IAAe,CAAC9D,EAC7B+D,GAAgBD,IAAe9D,EAC/B,CAAE,OAAM,eAAehC,EAAkBE,EAAYC,GAAYF,CAAc,EAC/E+F,EAAYC,KAAe,OAC3BC,GAAiBhG,GAAciG,EAGrC5G,EAAM,oBAAsB,CAC1B4F,EAAS,UAAUa,CAAS,CAC9B,EAAG,CAACb,EAAUa,CAAS,CAAC,EAGxB,IAAMI,GAAehB,EAChBA,EAAW,OAAO,KAAM,GAAUE,GAAe,IAAIjF,CAAK,CAAC,GAAK,KAChEgF,EAAU,IAAM,KAKfgB,GAAoBjJ,EAAAA,kBAAkB,EAAgB,IAA+B,CACzF,IAAM0E,EAAOlB,EAAM,cACb0F,EAASxE,EAAK,cAAc,cAC5BN,EAAQ8E,EAAS/D,GAAmBT,EAAMwE,CAAM,EAAI,KACtD9E,IAAU,MAAMwC,GAAc,cAAcxC,EAAO,CAAE,MAAO,MAAO,CAAC,CAC1E,CAAC,EAEK,CAAE,kBAAgB,gBAAgBnE,EAAAA,kBAAkB,CACxD,YAAa6C,EAAakG,GAAe,KACzC,YAAa,WACb,YAAapE,EAAWqE,GAAoB,IAAA,GAE5C,WAAYrE,EAAWmC,EAAaiB,GAAY,OAAS,GAAM,EAG/D,QAASlF,GAAc,EAAE8B,GAAYwD,KAAiB,MAAQ,SAAW,eAGzE,aAAc,8BAChB,CAAC,EACK,CACJ,IAAKe,GACL,UAAWC,GACX,iBAAkBC,GAClB,QAASC,IACPC,GACEC,EAAiBnK,EAAM,OAAiD,IAAI,EAC5EoK,GAAUvJ,GAAAA,cACdwJ,GACAd,EAAYO,GAAY,KACxBK,EAEA5C,GAAc,SAChB,EAOM+C,GAAkBtK,EAAM,OAAO,EAAK,EAIpCuK,GAAoB5J,EAAAA,iBAAkB,GAA4B,CAClE4I,GAAWU,GAAY9F,CAAK,EAChC,IAAMkB,EAAOlB,EAAM,cACnB,GAAgB,QAAU,CAACkB,EAAK,SAASlB,EAAM,MAAc,EAC7D,IAAMY,EAAQe,GAAmBT,EAAMlB,EAAM,MAAM,EAC/CY,IAAU,MAAM+D,EAAY,OAAO,CAAE,QAAS/D,EAAO,QAAS,IAAK,CAAC,CAC1E,CAAC,EACKyF,GAAgBjF,EAAWgF,GAAoBhB,EAAYU,GAAc,IAAA,GAKzEQ,GAAmB9J,EAAAA,iBAAkB,GAA4B,CACrE,IAAM0E,EAAOlB,EAAM,cACbuC,EAAOvC,EAAM,cACfuC,GAAQrB,EAAK,SAASqB,CAAI,IAC9B,GAAgB,QAAU,GAC1B,mBAAqB,CACnB,GAAI,CAACrB,EAAK,aAAeiF,GAAgB,QAAS,OAClD,IAAMT,EAASxE,EAAK,cAAc,cAC9BwE,GAAUxE,EAAK,SAASwE,CAAM,GAClCf,EAAY,OAAOxC,CAAe,CACpC,CAAC,EACH,CAAC,EAWKoE,GAAsB/J,EAAAA,iBAAkB,GAA4C,CAExF,GADI,CAAC4G,GAAgBpD,EAAM,kBAAoBuD,IAAc,GACzDvD,EAAM,SAAWA,EAAM,QAAUA,EAAM,QAAS,OACpD,IAAMkB,EAAOlB,EAAM,cAEnB,GAAI,CAACkB,EAAK,SAASlB,EAAM,MAAc,GAAKrD,EAAAA,cAAcqD,EAAM,MAAM,EAAG,OACzE,IAAMwG,EAAU7E,GAAmBT,EAAMlB,EAAM,MAAM,EAC/C4B,EAASG,EACb/B,EAAM,IACN2E,EAAY,YAAY,CAAC,CAAC,SAAW6B,EACrCjD,CACF,EACA,GAAI3B,IAAW,IAAA,GAAW,OAE1B,GADA5B,EAAM,eAAe,EACjB4B,IAAW4E,EAAS,CACtB7B,EAAY,OAAO,CAAE,QAAS,IAAK,CAAC,EACpCvB,EAAa,cAAcxB,EAAQ,CAAE,MAAO,MAAO,CAAC,EACpD,MACF,CACA,IAAM6E,EAAU5E,EAAcX,EAAMU,CAAM,EAC1C,GAAI6E,EAAS,CACX9B,EAAY,OAAO,CAAE,QAAS,IAAK,CAAC,EAOpC8B,EAAQ,iBAAiB,CAAE,MAAO,SAAU,CAAC,EAC7C5F,EAAmB4F,CAAO,CAAC,EAAE,MAAM,EACnC,MACF,CACA,IAAMC,EAAW/B,EAAY,YAAY,CAAC,CAAC,QAC3CA,EAAY,OAAO,CAAE,QAAS/C,CAAO,CAAC,EAClC8E,IAAa9E,GAAQwB,EAAa,cAAcxB,EAAQ,CAAE,MAAO,MAAO,CAAC,CAC/E,CAAC,EACK+E,GAAkBnK,EAAAA,iBAAkB,GAA4C,CAChF4E,GAAUmF,GAAoBvG,CAAK,EACvC4F,GAAc5F,CAAK,CACrB,CAAC,EAODrB,EAAM,oBAAsB,CAC1B,IAAM2C,EAAOiD,EAAS,cAAc,EAC9BrD,EAAO8E,EAAe,QAC5B,GAAI,CAAC1E,GAAQ,CAACJ,EAAM,OACpB,IAAM0F,EAAM1F,EAAK,cACXwE,EAASkB,EAAI,cAEflB,GAAUA,IAAWkB,EAAI,MAAQlB,EAAO,aAC5C5E,EAAsBI,EAAMI,EAAMF,CAAQ,CAAC,EAAE,MAAM,CACrD,EAAG,CAACyF,EAAMtC,EAAUnD,CAAQ,CAAC,EAO7BzC,EAAM,oBAAsB,CAC1B,IAAMuC,EAAO8E,EAAe,QAC5B,GAAI,CAAC5E,GAAY,CAACF,EAAM,CACtByD,EAAY,OAAOxC,CAAe,EAClC,MACF,CACA,IAAMyE,EAAM1F,EAAK,cACXwE,EAASkB,EAAI,cAEbE,EAAO,CAACpB,GAAUA,IAAWkB,EAAI,MAAQ,CAAClB,EAAO,aAAeA,IAAWxE,EAC3E,CAAE,WAAYyD,EAAY,YAAY,EAC5C,GAAIoC,IAAY,KAAM,CACpBpC,EAAY,OAAO,CAAE,QAAS,IAAK,CAAC,EACpC,IAAM8B,EAAUM,EAAUxD,EAAY1B,EAAcX,EAAM6F,CAAO,EAAI,KAEjEN,IAAYK,GAAQ5F,EAAK,SAASwE,CAAM,IAAI7E,EAAmB4F,CAAO,CAAC,EAAE,MAAM,CACrF,CACA,GAAM,CAAE,WAAY9B,EAAY,YAAY,EAC5C,GAAI,MAAY,MAAQqC,EAAUzD,GAClC,IAAIuD,GAAQvD,EAAY,EAAG,CACzB,IAAMtC,EAAOY,EAAcX,EAAMqC,EAAY,CAAC,EAC9C,GAAItC,EACFJ,EAAmBI,CAAI,CAAC,EAAE,MAAM,MAC3B,CACL0D,EAAY,OAAO,CAAE,QAAS,KAAM,QAASpB,EAAY,CAAE,CAAC,EAC5DH,GAAc,cAAcG,EAAY,EAAG,CAAE,MAAO,MAAO,CAAC,EAC5D,MACF,CACF,CACIoB,EAAY,YAAY,CAAC,CAAC,UAAYqC,GAASrC,EAAY,OAAO,CAAE,QAAS,IAAK,CAAC,CADvF,CAEF,CAAC,EAIDhG,EAAM,oBAAsB,CAC1B,GAAIyG,EAAW,OACf,IAAMlE,EAAO8E,EAAe,QACtBN,EAASxE,GAAM,cAAc,cAC9BwE,GAAUA,EAAO,gBAAkBxE,GAAQ,GAAO,aAAa,UAAU,GAC9EV,EAAckF,CAAqB,CAAC,CAAC,EAAE,EAAE,MAAM,CACjD,EAAG,CAACN,CAAS,CAAC,EAKdzG,EAAM,oBAAsB,CAC1B4F,EAAS,UAAUyB,EAAe,OAAO,CAC3C,CAAC,EAED,IAAMiB,GAAapL,EAAM,YACtB,GAAkB,CACjBsI,GAAa,GAAa,CAGxB,IAAMqC,EAAUpF,EAAWsF,EAAWnC,EAAS,MAAMmC,CAAQ,EACvDQ,EAAaV,EAAQ,SAAS/G,CAAK,EAIzC,OAHIkE,EACKuD,EAAaV,EAAQ,OAAQ,GAAS7F,IAASlB,CAAK,EAAI,CAAC,GAAG+G,EAAS/G,CAAK,EAE5EyH,EAAa,CAAC,EAAI,CAACzH,CAAK,CACjC,CAAC,CACH,EACA,CAACkE,EAAUY,EAAUJ,GAAa/C,CAAQ,CAC5C,EAGM+F,GAAa3C,GAAY,YAAcrF,GAC7CR,EAAM,cAAgB,CACpB,IAAK,IAAMc,KAAS0H,GAAY3H,GAAmBC,CAAK,CAC1D,EAAG,CAAC0H,EAAU,CAAC,EAEf,IAAMC,GAAgB3C,EAAU,OAChC9F,EAAM,cAAgB,CAChBW,GAAc,CAACqE,GAAYyD,GAAgB,GAC7CzJ,EAAA,SACE,+BACA,mEAAmEyJ,GAAc,wFACnF,CAEJ,EAAG,CAAC9H,EAAYqE,EAAUyD,EAAa,CAAC,EAExC,IAAMC,GAAmB/H,GAAcD,IAAmB,SAAWE,GAC/D+H,GAAiBhI,GAAcD,IAAmB,OACxDV,EAAM,cAAgB,CAChB0I,IACF1J,EAAA,SACE,0BACA,wLACF,EAEE2J,IACF3J,EAAA,SACE,uBACA,+JACF,CAEJ,EAAG,CAAC0J,GAAkBC,EAAc,CAAC,EAErC3I,EAAM,cAAgB,CAChB2E,GACF3F,EAAA,SACE,+BACA,+OAGF,CAEJ,EAAG,CAAC2F,CAAa,CAAC,EAElB3E,EAAM,cAAgB,CAChBwG,IACFxH,EAAA,SACE,8BACA,wPAGF,CAEJ,EAAG,CAACwH,EAAa,CAAC,EAElB,IAAMoC,GAAe1L,EAAM,aAClB,CACL,OACA,YACA,UAAWyD,EACX,UAAWgG,GACX,kBACA,cACA,eACA,WACA,aACF,GACA,CACEuB,EACAzB,EACA9F,EACAgG,GACAZ,GACAuC,GACAO,GACAjD,EACAd,EACF,CACF,EAEMgE,GAAQZ,IAAS,OAAS,MAAQ,KAClCxG,GAAOwG,IAAS,OAAS,OAASA,IAAS,UAAY,UAAY,OAGnEa,GAAU3C,EACZA,EAAc,IAAK,GACjBC,EAAM,OAAS,QACb,EAAApG,EAAA,IAAA,CAACE,GAAqB,SAAtB,CAAiD,MAAOkG,EAAM,MAC3D,SAAAA,EAAM,IACsB,EAFKA,EAAM,KAEX,GAE/B,EAAApG,EAAA,IAAA,CAAC4D,GAAD,CAA4B,KAAMqE,IAAS,OAAQ,KAAM7B,EAAM,IAAO,EAArDA,EAAM,GAA+C,CAE1E,EACAC,GAEJ,OACE,EAAArG,EAAA,IAAA,CAACC,EAAY,SAAb,CAAsB,MAAO0I,GAC3B,UAAA,EAAA3I,EAAA,IAAA,CAAC6I,GAAD,CACQ,QACN,uBAAsBnI,GAAcqE,EAAW,GAAO,IAAA,GACtD,gBAAevC,GAAYyF,IAAS,OAAStD,EAAY,IAAA,GACzD,uBAAsB8B,GACtB,iBAAgBC,GAAiB,GAAK,IAAA,GAGtC,SAAUlE,GAAYgE,EAAY,GAAK,IAAA,GACvC,UAAWxI,EAAAA,GACTN,EAAAA,eAAe,KACf,oBAEA8E,GAAY,yCACZuG,EACF,EACA,GAAI1E,EACJ,IAAKgD,GACL,wBAAuBb,EAAY,GAAK,IAAA,GACxC,UAAWA,EAAYvI,EAAAA,qBAAqB+K,EAAWjB,EAAe,EAAIiB,EAC1E,iBACExC,EACIvI,EAAAA,qBAAqBgL,EAAkBhC,EAAoB,EAC3DgC,EAEN,QACExB,GACIxJ,EAAAA,qBAAqBiL,EAASzB,GAAe,CAAE,sBAAuB,EAAM,CAAC,EAC7EyB,EAEN,OACE1G,EACIvE,EAAAA,qBAAqBkL,EAAQzB,GAAkB,CAAE,sBAAuB,EAAM,CAAC,EAC/EyB,EAGL,SAAAL,EACG,CAAA,CACc,CAAA,CAE1B,EACA,EAAS,YAAc,OAWvB,IAAMM,EACJ,wEACIC,EACJ,uEAQF,SAASC,GACP,EACA,CAAE,WAAU,YACK,CACjB,IAAMC,EAAUvL,EAAAA,GACdE,EAAAA,mBAAmB,UACnB,oEACAsL,EACI,CAAC,wBAAyBH,CAAgC,EAC1D,CAAC,eAAgBD,CAAuB,EAC5C,CAAC9D,GAAY,WACf,EACA,OAAOmE,IAAU,IAAA,IACf,EAAAzJ,EAAA,IAAA,CAAC,OAAD,CAAM,cAAY,OAAO,UAAWuJ,EAClC,UAAA,EAAAvJ,EAAA,IAAA,CAAC7B,GAAAA,UAAD,CAAY,CAAA,CACR,CAAA,EAENC,EAAAA,WAAWqL,EAAO,OAAQF,EAAS,CAAE,cAAe,EAAK,CAAC,CAE9D,CAgBA,IAAatI,GAAY,CACvB,QACA,SACA,WACA,oBAAoB,GACpB,YACA,aACA,QACA,YACA,UACA,YACA,MACA,GAAGoD,MACgB,CACnB,GAAM,CACJ,OACA,aACA,YACA,UAAWqF,GACX,iBACA,aACA,cACA,WACA,cACErJ,GAAe,UAAU,EACvBsJ,GAAgB1M,EAAM,WAAWiD,EAAoB,EAErD0J,EAAc/E,EAAa8E,GAAgB,KAC3CE,GAAYxL,GAAAA,MAAM,WAAW,EAC7ByL,EAAkBjJ,GAAgB,IAAA,GAClCkJ,EAAcD,GAAmBD,GAEjCG,EAAY3M,EAAAA,mBAAmB4M,CAAM,EACrC,CAACC,GAASjN,EAAM,cAAgB,CAAC,EAAE,EACnCkN,EAAUlN,EAAM,OAA8C,IAAI,EAClEmN,GAAWtM,GAAAA,cAA8CwJ,EAAK6C,CAAO,EAI3EpK,EAAM,oBAAsB,CAC1B4F,EAAS,IAAIuE,EAAO,CAClB,MAAOJ,EACP,YACA,QAASK,EACT,MAAOP,GAAe,IAAA,EACxB,CAAC,CACH,EAAG,CAACjE,EAAUuE,EAAOJ,EAAiBE,EAAWJ,CAAW,CAAC,EAC7D7J,EAAM,wBAA4B4F,EAAS,OAAOuE,CAAK,EAAG,CAACvE,EAAUuE,CAAK,CAAC,EAK3E,IAAMG,EAAwBzM,EAAAA,iBAAkB,GAAsB,CACpE,IAAMmE,EAAOF,EAAK,cAClB8D,EAAS,gBAAgB,CACvB,MAAOmE,EACP,MAAOF,IAAgB7H,EAAOD,EAAaC,CAAI,EAAI,GACrD,CAAC,CACH,CAAC,EAKDhC,EAAM,oBAAsB,CAC1B,IAAMiB,EAAOmJ,EAAQ,QACrB,UAAa,CACX,GAAI,CAACnJ,EAAM,OACX,IAAM8F,EAAS9F,EAAK,cAAc,cAC9B8F,GAAU9F,EAAK,SAAS8F,CAAM,GAChCnB,EAAS,gBAAgB,CACvB,MAAOmE,EACP,MAAOF,GAAe9H,EAAad,CAAI,CACzC,CAAC,CAEL,CACF,EAAG,CAAC2E,EAAUmE,EAAiBF,CAAW,CAAC,EAG3C,IAAMU,EAAqBC,IAAa,IAAA,IAAa,CAAC/D,GACtDzG,EAAM,cAAgB,CAChBuK,GACFvL,EAAA,SACE,iCACA,4MACF,CAEJ,EAAG,CAACuL,CAAkB,CAAC,EAEvB,IAAMhC,EACJ9C,GAAasE,IAAoB,IAAA,IAAahE,EAAe,IAAIgE,CAAe,EAE5EU,EAAiBhF,GAAasE,IAAoB,IAAA,GAClDW,EAAoBjF,GAAakF,EAEjCC,EAAeF,GAAqBF,IAAa,IAAA,GAEjDK,MAAe,CACfpF,GAAa,CAACkF,GAAqBZ,IAAoB,IAAA,IACzDzB,EAAWyB,CAAe,CAE9B,EAGMe,EAAY,GAA+B,CAC/CN,IAAWnJ,CAAK,EACXA,EAAM,mBAAmB,GAAGwJ,EAAO,CAC1C,EAEME,EAAe,GAAyC,CACxD3J,EAAmBC,CAAK,GAC5ByJ,EAASzJ,CAAK,CAChB,EAGM2J,EAAuB,GAA4C,CACvE,GAAI3J,EAAM,MAAQ,KAAOoJ,EAAgB,CAEvCpJ,EAAM,eAAe,EACrBwJ,EAAO,EACP,MACF,EAEKpF,GAAa+E,IAAa,IAAA,MAE/BM,EAASzJ,CAAK,EAEdA,EAAM,eAAe,EACvB,EAEM4J,GAAuB,GAA4C,CACnE7J,EAAmBC,CAAK,GACxBC,GAAgBD,CAAK,GAAG2J,EAAoB3J,CAAK,CACvD,EAEM6J,EAAoB,GAA4C,CACpE,IAAMC,EAAa9J,EAAM,cACnB4B,EAAS5B,EAAM,OACfS,EAAOkC,EAAcmH,CAAU,EAErC,GAAI,CAACrJ,GAAQ,CAACA,EAAK,SAASmB,CAAM,EAAG,CACnC,GAAIA,IAAWkI,EAAY,OAC3B,GAAI7J,GAAgBD,CAAK,EAAG,CAC1B2J,EAAoB3J,CAAK,EACzB,MACF,CAKA,IAAM+J,EAJS7M,EAAAA,eAAe8C,EAAM,IAAK,CACvC,YAAa,aACb,IAAK7C,EAAAA,aAAa2M,CAAU,CAC9B,CACc,IAAW,QAAUrJ,EAAOoC,EAAepC,CAAI,CAAC,CAAC,GAAK,IAAA,GAChEsJ,IACF/J,EAAM,eAAe,EACrB+J,EAAM,MAAM,GAEd,MACF,CAGA,GAAInI,IAAWnB,GAAQL,EAAYwB,CAAM,EAAG,CAEtC5B,EAAM,MAAQ,WAChBA,EAAM,eAAe,EACrBS,EAAK,MAAM,GAEb,MACF,CACA,GAAImB,IAAWnB,IAAST,EAAM,MAAQ,SAAWA,EAAM,MAAQ,MAAO,CACpE,IAAMgF,EAAQxE,EAAcC,CAAI,CAAC,CAAC,KAAM,GAAOL,EAAYE,CAAE,CAAC,EAC1D0E,IACFhF,EAAM,eAAe,EACrBgF,EAAM,MAAM,GAEd,MACF,CACA,IAAMgF,EAAS9M,EAAAA,eAAe8C,EAAM,IAAK,CACvC,YAAa,aACb,IAAK7C,EAAAA,aAAa2M,CAAU,CAC9B,CAAC,EACD,GAAI,CAACE,EAAQ,OACbhK,EAAM,eAAe,EACrB,IAAM8C,EAAQD,EAAepC,CAAI,EAC3BG,EAAQkC,EAAM,QAAQlB,CAAM,EAC9BoI,IAAW,OACblH,EAAMlC,EAAQ,EAAE,EAAE,MAAM,EACfA,EAAQ,EACjBkC,EAAMlC,EAAQ,EAAE,CAAC,MAAM,EAEvBkJ,EAAW,MAAM,CAErB,EAEMG,GAAWpD,IAAS,OAAS,MAAQ,KACrCqD,GAAerD,IAAS,OAAS,MAAQ,OACzCxG,GAAOwG,IAAS,OAAS,MAAQA,IAAS,UAAY,SAAW,WAEjEsD,EAA4C/E,GAC9C,CACE,gBAAiBhB,EAAY8C,EAAa,IAAA,GAC1C,SAAUM,EAAYmB,CAAW,EACjC,oBAAqBA,EACrB,gBAAiBzB,EAAa,GAAK,IAAA,GAEnC,GAAG9J,EAAAA,uBAAuBmM,EAAc,CAAE,UAAW,EAAK,CAAC,EAC3D,QAAS1M,EAAAA,qBAAqBuN,EAASV,CAAW,EAClD,UAAW7M,EAAAA,qBACT+K,EACAf,IAAS,OAASgD,EAAmBD,EACvC,CACF,EACA,CAEE,QAAST,EAAWtM,EAAAA,qBAAqBuN,EAASV,CAAW,EAAIU,EACjE,WACF,EAIEC,GAASjG,EACXmF,EACE,iBACA,iBACFJ,GAAY,iBACVmB,GAAYlG,EAAY,CAACmF,EAAeJ,IAAa,IAAA,GAIrDoB,GAAkBhF,GAAa,MAAQtJ,EAAAA,mBAAmBsJ,CAAS,EACnEiF,GAAgBpG,IAAcmB,GAAa,KAAO+C,GAAgBiC,IAIlEE,EACJhH,GAAc+E,IAAgB,KAC1B,CACE,aAAcA,EACd,GAAI3B,IAAS,OACT,CAAE,gBAAiB2B,EAAc,CAAE,EACnC,CAAE,eAAgB/E,EAAW,MAAO,gBAAiB+E,EAAc,CAAE,CAC3E,EACA,CAAC,EAEP,OACE,EAAA5J,EAAA,KAAA,CAACqL,GAAD,CACQ,QACN,0BAAyBZ,EAAoB,GAAK,IAAA,GAClD,UAAWzM,EAAAA,GACTE,EAAAA,mBAAmB,KACnB,iEAEA0L,IAAgB,MAAQ,aACxBpD,GAAY,CAAC,WAAYiF,GAAQhN,EAAAA,cAAc,EAAIgN,GACnDnD,EACI,CACE,wHACA5J,EAAAA,aAAa,iBACf,EACAgN,IAAa,wBACjB3C,EACF,EACA,MAAOlE,GAAc+E,IAAgB,KAAO,CAAE,GAAGkC,EAAO,OAAQjH,EAAW,QAAS,EAAIiH,EACxF,GAAIzH,GACJ,IAAK+F,GACL,GAAImB,EACJ,GAAIM,EArBN,SAAA,EAuBE,EAAA7L,EAAA,IAAA,CAACsL,GAAD,CACE,KAAMrD,IAAS,OAAS,WAAa,IAAA,GACrC,UAAWjK,EAAAA,GAAGE,EAAAA,mBAAmB,QAAS,gBAAgB,EAEzD,WACU,CAAA,EACZ8L,IACC,EAAAhK,EAAA,IAAA,CAAC+L,GAAD,CAAgB,KAAM9D,IAAS,OAAQ,mBAAoBoC,EAExD,SAAA1L,EAAAA,uBAAuBsL,CAAM,CAChB,CAAA,EAEjB2B,IACCtC,GAAgBqC,GAAkBhF,EAAY,IAAA,GAAW,CACvD,SAAU2B,EACV,SAAUmC,CACZ,CAAC,CACI,GAEb,EACA,EAAS,YAAc,WAMvB,IAAMuB,EAAqB,CACzB,0BACA,GAAG,CACD,UACA,aACA,UACA,OACA,WACA,UACA,OACA,UACA,MACF,CAAC,CAAC,IAAK,GAAS,UAAUvK,EAAK,GAAG,CACpC,CAAC,CAAC,KAAK,IAAI,EAGLwK,EAA4B,CAAC,WAAY,OAAQ,kBAAmB,UAAU,EAiBpF,SAASC,EAAgB,EAA+B,CAEtD,IAAMC,EAAU,IAAI,IAEdC,EAAU,IAAI,QACdC,MAAc,CAClB,IAAK,IAAM3K,KAAMyK,EAAQ,KAAK,EACvBtK,EAAK,SAASH,CAAE,GAAGyK,EAAQ,OAAOzK,CAAE,EAE3C,IAAK,IAAMA,KAAMG,EAAK,iBAA8BrE,EAAAA,kBAAkB,EAAG,CACvE,IAAM8O,EAAW5K,EAAG,aAAa,UAAU,EAC3C,GAAI4K,IAAa,MAAQF,EAAQ,IAAI1K,CAAE,EAAG,SAC1C,IAAM6K,EAAY7K,EAAG,QAAQsK,CAAkB,EAC3CO,GAAa1K,EAAK,SAAS0K,CAAS,IACxCJ,EAAQ,IAAIzK,EAAI4K,CAAQ,EACxB5K,EAAG,aAAa,WAAY,IAAI,EAClC,CACF,EAEA,GADA2K,EAAM,EACF,OAAO,iBAAqB,IAAa,UAAa,CAAC,EAE3D,IAAMG,EAAW,IAAI,iBAAkB,GAAY,CAKjD,IAAMC,EAAU,IAAI,IACpB,IAAK,IAAMC,KAAUC,EAAS,CAC5B,IAAM3J,EAAS0J,EAAO,OAClBA,EAAO,gBAAkB,YAAcP,EAAQ,IAAInJ,CAAM,GAAGyJ,EAAQ,IAAIzJ,CAAM,CACpF,CACA,IAAK,IAAMtB,KAAM+K,EAAS,CACxB,IAAM5L,EAAQa,EAAG,aAAa,UAAU,EACpCb,IAAU,MAAQA,IAAUsL,EAAQ,IAAIzK,CAAE,GAC5CyK,EAAQ,OAAOzK,CAAE,EACjB0K,EAAQ,IAAI1K,CAAE,GAEdyK,EAAQ,IAAIzK,EAAIb,CAAK,CAEzB,CACAwL,EAAM,EACNG,EAAS,YAAY,CACvB,CAAC,EAOD,OANAA,EAAS,QAAQ3K,EAAM,CACrB,QAAS,GACT,UAAW,GACX,WAAY,GACZ,gBAAiBoK,CACnB,CAAC,MACY,CACXO,EAAS,WAAW,EACpB,IAAK,GAAM,CAAC9K,EAAIkL,KAAaT,EACvBS,IAAa,KAAMlL,EAAG,gBAAgB,UAAU,EAC/CA,EAAG,aAAa,WAAYkL,CAAQ,EAE3CT,EAAQ,MAAM,CAChB,CACF,CAmBA,SAASJ,GAAe,CAAE,OAAM,qBAAoB,YAAiC,CACnF,IAAMc,EAAU5P,EAAM,OAA2B,IAAI,EAiBrD,OAfA8C,EAAM,oBAAsB,CAC1B,IAAM8B,EAAOgL,EAAQ,QACrB,UAAa,CACX,GAAI,CAAChL,EAAM,OACX,IAAMiF,EAASjF,EAAK,cAAc,cAC9BiF,GAAUjF,EAAK,SAASiF,CAAM,GAAGgG,EAAmBjL,CAAI,CAC9D,CACF,EAAG,CAACiL,EAAoBjJ,CAAI,CAAC,EAE7B9D,EAAM,oBAAsB,CAC1B,IAAM8B,EAAOgL,EAAQ,QACrB,OAAOhJ,GAAQhC,EAAOqK,EAAgBrK,CAAI,EAAI,IAAA,EAChD,EAAG,CAACgC,CAAI,CAAC,GAIP,EAAA7D,EAAA,IAAA,CAFY6D,EAAO,MAAQ,OAE3B,CACE,IAAKgJ,EACL,KAAMhJ,EAAO,WAAa,IAAA,GAC1B,SAAUA,EAAO,GAAK,IAAA,GACtB,mBAAiB,GACjB,UAAW7F,EAAAA,GAAGE,EAAAA,mBAAmB,OAAQ,gBAAiB2F,GAAA,oFAAsB,EAE/E,UACG,CAAA,CAEV,CACA,GAAe,YAAc,iBAiF7B,IAAakJ,EAAuB,OAAO,OAAO3I,EAAU,CAC1D,KAAMnD,CACR,CAAC"}