@mortenbrudvik/waveui 0.13.0 → 0.14.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 (83) hide show
  1. package/README.md +302 -49
  2. package/dist/components/data-display/Avatar.context.cjs.map +1 -1
  3. package/dist/components/data-display/Avatar.context.mjs.map +1 -1
  4. package/dist/components/data-display/List.cjs +1 -1
  5. package/dist/components/data-display/List.cjs.map +1 -1
  6. package/dist/components/data-display/List.mjs +245 -195
  7. package/dist/components/data-display/List.mjs.map +1 -1
  8. package/dist/components/data-display/List.registry.cjs.map +1 -1
  9. package/dist/components/data-display/List.registry.mjs.map +1 -1
  10. package/dist/components/layout/Overflow.cjs +1 -1
  11. package/dist/components/layout/Overflow.cjs.map +1 -1
  12. package/dist/components/layout/Overflow.mjs +240 -192
  13. package/dist/components/layout/Overflow.mjs.map +1 -1
  14. package/dist/components/layout/Overflow.store.cjs +2 -0
  15. package/dist/components/layout/Overflow.store.cjs.map +1 -0
  16. package/dist/components/layout/Overflow.store.mjs +209 -0
  17. package/dist/components/layout/Overflow.store.mjs.map +1 -0
  18. package/dist/components/navigation/Breadcrumb.cjs +1 -1
  19. package/dist/components/navigation/Breadcrumb.cjs.map +1 -1
  20. package/dist/components/navigation/Breadcrumb.mjs +239 -84
  21. package/dist/components/navigation/Breadcrumb.mjs.map +1 -1
  22. package/dist/components/overlays/Dialog.slots.cjs +1 -1
  23. package/dist/components/overlays/Dialog.slots.cjs.map +1 -1
  24. package/dist/components/overlays/Dialog.slots.mjs +19 -15
  25. package/dist/components/overlays/Dialog.slots.mjs.map +1 -1
  26. package/dist/components/overlays/TeachingPopover.cjs +1 -1
  27. package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
  28. package/dist/components/overlays/TeachingPopover.context.cjs +2 -0
  29. package/dist/components/overlays/TeachingPopover.context.cjs.map +1 -0
  30. package/dist/components/overlays/TeachingPopover.context.mjs +51 -0
  31. package/dist/components/overlays/TeachingPopover.context.mjs.map +1 -0
  32. package/dist/components/overlays/TeachingPopover.mjs +15 -185
  33. package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
  34. package/dist/components/overlays/TeachingPopover.parts.cjs +2 -0
  35. package/dist/components/overlays/TeachingPopover.parts.cjs.map +1 -0
  36. package/dist/components/overlays/TeachingPopover.parts.mjs +398 -0
  37. package/dist/components/overlays/TeachingPopover.parts.mjs.map +1 -0
  38. package/dist/components/overlays/TeachingPopover.root.cjs +2 -0
  39. package/dist/components/overlays/TeachingPopover.root.cjs.map +1 -0
  40. package/dist/components/overlays/TeachingPopover.root.mjs +150 -0
  41. package/dist/components/overlays/TeachingPopover.root.mjs.map +1 -0
  42. package/dist/components/overlays/TeachingPopover.stack.cjs +2 -0
  43. package/dist/components/overlays/TeachingPopover.stack.cjs.map +1 -0
  44. package/dist/components/overlays/TeachingPopover.stack.mjs +86 -0
  45. package/dist/components/overlays/TeachingPopover.stack.mjs.map +1 -0
  46. package/dist/components/table/DataGrid.cjs +1 -1
  47. package/dist/components/table/DataGrid.cjs.map +1 -1
  48. package/dist/components/table/DataGrid.mjs +540 -311
  49. package/dist/components/table/DataGrid.mjs.map +1 -1
  50. package/dist/components/table/Table.cjs +1 -1
  51. package/dist/components/table/Table.cjs.map +1 -1
  52. package/dist/components/table/Table.mjs +183 -60
  53. package/dist/components/table/Table.mjs.map +1 -1
  54. package/dist/components/table/Table.shared.cjs +2 -0
  55. package/dist/components/table/Table.shared.cjs.map +1 -0
  56. package/dist/components/table/Table.shared.mjs +65 -0
  57. package/dist/components/table/Table.shared.mjs.map +1 -0
  58. package/dist/index.cjs +1 -1
  59. package/dist/index.d.cts +1742 -158
  60. package/dist/index.d.ts +1742 -158
  61. package/dist/index.mjs +135 -132
  62. package/dist/lib/breadcrumb.cjs +2 -0
  63. package/dist/lib/breadcrumb.cjs.map +1 -0
  64. package/dist/lib/breadcrumb.mjs +26 -0
  65. package/dist/lib/breadcrumb.mjs.map +1 -0
  66. package/dist/lib/classNames.cjs +1 -1
  67. package/dist/lib/classNames.cjs.map +1 -1
  68. package/dist/lib/classNames.mjs +66 -38
  69. package/dist/lib/classNames.mjs.map +1 -1
  70. package/dist/lib/events.cjs +1 -1
  71. package/dist/lib/events.cjs.map +1 -1
  72. package/dist/lib/events.mjs +35 -8
  73. package/dist/lib/events.mjs.map +1 -1
  74. package/dist/lib/icons.cjs +1 -1
  75. package/dist/lib/icons.cjs.map +1 -1
  76. package/dist/lib/icons.mjs +34 -20
  77. package/dist/lib/icons.mjs.map +1 -1
  78. package/dist/lib/table.cjs +2 -0
  79. package/dist/lib/table.cjs.map +1 -0
  80. package/dist/lib/table.mjs +16 -0
  81. package/dist/lib/table.mjs.map +1 -0
  82. package/dist/styles.css +1 -1
  83. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.context.cjs","names":["React","require_runtime","react","AvatarBadgeSizeContext","AvatarSizeContext"],"sources":["../../../src/components/data-display/Avatar.context.ts"],"sourcesContent":["import * as React from 'react';\nimport type { Size } from '../../lib/types';\n\n/*\n * The box a container gives the Avatars inside it that set no `size`: Tag and\n * InteractionTag.Primary provide it around their `media`, so a person's Avatar there matches the\n * tag's size. Internal (never exported from a barrel); imports no component, so a Tag that reads\n * it holds no Avatar code.\n */\n\n/**\n * The box a container gives the Avatars inside it that set no `size` (Tag and InteractionTag\n * media). Internal.\n */\nexport interface AvatarSizeContextValue {\n /** The box in pixels: a tag's 24px (Avatar's `extra-small`), 20px or 16px box, or a group's size. */\n size: number;\n /** The shape the container gives its Avatars: a rounded Tag gives `square`. */\n shape?: 'circular' | 'square';\n}\n\n/**\n * The size a badge in an Avatar's `badge` slot takes when it sets none (PresenceBadge): derived from\n * the avatar's pixel size. Internal.\n */\nexport const AvatarBadgeSizeContext = React.createContext<Size | null>(null);\nAvatarBadgeSizeContext.displayName = 'AvatarBadgeSizeContext';\n\n/** Internal: provided by Tag and InteractionTag.Primary around their `media`; `null` elsewhere. */\nexport const AvatarSizeContext = React.createContext<AvatarSizeContextValue | null>(null);\nAvatarSizeContext.displayName = 'AvatarSizeContext';\n"],"mappings":"6GAyBA,IAAaG,EAAyBH,EAAM,cAA2B,IAAI,EAC3E,EAAuB,YAAc,yBAGrC,IAAaI,EAAoBJ,EAAM,cAA6C,IAAI,EACxF,EAAkB,YAAc"}
1
+ {"version":3,"file":"Avatar.context.cjs","names":["React","require_runtime","react","AvatarBadgeSizeContext","AvatarSizeContext"],"sources":["../../../src/components/data-display/Avatar.context.ts"],"sourcesContent":["import * as React from 'react';\nimport type { Size } from '../../lib/types';\n\n/*\n * The box a container gives the Avatars inside it that set no `size`: Tag and\n * InteractionTag.Primary provide it around their `media`, so a person's Avatar there matches the\n * tag's size, and Table.CellLayout a 32px box around its `media`. Internal (never exported\n * from a barrel); imports no component, so a Tag that reads it holds no Avatar code.\n */\n\n/**\n * The box a container gives the Avatars inside it that set no `size` (Tag, InteractionTag and\n * Table.CellLayout media). Internal.\n */\nexport interface AvatarSizeContextValue {\n /** The box in pixels: a tag's 24px (Avatar's `extra-small`), 20px or 16px box, or a group's size. */\n size: number;\n /** The shape the container gives its Avatars: a rounded Tag gives `square`. */\n shape?: 'circular' | 'square';\n}\n\n/**\n * The size a badge in an Avatar's `badge` slot takes when it sets none (PresenceBadge): derived from\n * the avatar's pixel size. Internal.\n */\nexport const AvatarBadgeSizeContext = React.createContext<Size | null>(null);\nAvatarBadgeSizeContext.displayName = 'AvatarBadgeSizeContext';\n\n/**\n * Internal: provided by Tag, InteractionTag.Primary and Table.CellLayout around their `media`;\n * `null` elsewhere.\n */\nexport const AvatarSizeContext = React.createContext<AvatarSizeContextValue | null>(null);\nAvatarSizeContext.displayName = 'AvatarSizeContext';\n"],"mappings":"6GAyBA,IAAaG,EAAyBH,EAAM,cAA2B,IAAI,EAC3E,EAAuB,YAAc,yBAMrC,IAAaI,EAAoBJ,EAAM,cAA6C,IAAI,EACxF,EAAkB,YAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.context.mjs","names":["React","AvatarBadgeSizeContext","AvatarSizeContext"],"sources":["../../../src/components/data-display/Avatar.context.ts"],"sourcesContent":["import * as React from 'react';\nimport type { Size } from '../../lib/types';\n\n/*\n * The box a container gives the Avatars inside it that set no `size`: Tag and\n * InteractionTag.Primary provide it around their `media`, so a person's Avatar there matches the\n * tag's size. Internal (never exported from a barrel); imports no component, so a Tag that reads\n * it holds no Avatar code.\n */\n\n/**\n * The box a container gives the Avatars inside it that set no `size` (Tag and InteractionTag\n * media). Internal.\n */\nexport interface AvatarSizeContextValue {\n /** The box in pixels: a tag's 24px (Avatar's `extra-small`), 20px or 16px box, or a group's size. */\n size: number;\n /** The shape the container gives its Avatars: a rounded Tag gives `square`. */\n shape?: 'circular' | 'square';\n}\n\n/**\n * The size a badge in an Avatar's `badge` slot takes when it sets none (PresenceBadge): derived from\n * the avatar's pixel size. Internal.\n */\nexport const AvatarBadgeSizeContext = React.createContext<Size | null>(null);\nAvatarBadgeSizeContext.displayName = 'AvatarBadgeSizeContext';\n\n/** Internal: provided by Tag and InteractionTag.Primary around their `media`; `null` elsewhere. */\nexport const AvatarSizeContext = React.createContext<AvatarSizeContextValue | null>(null);\nAvatarSizeContext.displayName = 'AvatarSizeContext';\n"],"mappings":";;;AAyBA,IAAaC,IAAyBD,EAAM,cAA2B,IAAI;AAC3E,EAAuB,cAAc;AAGrC,IAAaE,IAAoBF,EAAM,cAA6C,IAAI;AACxF,EAAkB,cAAc"}
1
+ {"version":3,"file":"Avatar.context.mjs","names":["React","AvatarBadgeSizeContext","AvatarSizeContext"],"sources":["../../../src/components/data-display/Avatar.context.ts"],"sourcesContent":["import * as React from 'react';\nimport type { Size } from '../../lib/types';\n\n/*\n * The box a container gives the Avatars inside it that set no `size`: Tag and\n * InteractionTag.Primary provide it around their `media`, so a person's Avatar there matches the\n * tag's size, and Table.CellLayout a 32px box around its `media`. Internal (never exported\n * from a barrel); imports no component, so a Tag that reads it holds no Avatar code.\n */\n\n/**\n * The box a container gives the Avatars inside it that set no `size` (Tag, InteractionTag and\n * Table.CellLayout media). Internal.\n */\nexport interface AvatarSizeContextValue {\n /** The box in pixels: a tag's 24px (Avatar's `extra-small`), 20px or 16px box, or a group's size. */\n size: number;\n /** The shape the container gives its Avatars: a rounded Tag gives `square`. */\n shape?: 'circular' | 'square';\n}\n\n/**\n * The size a badge in an Avatar's `badge` slot takes when it sets none (PresenceBadge): derived from\n * the avatar's pixel size. Internal.\n */\nexport const AvatarBadgeSizeContext = React.createContext<Size | null>(null);\nAvatarBadgeSizeContext.displayName = 'AvatarBadgeSizeContext';\n\n/**\n * Internal: provided by Tag, InteractionTag.Primary and Table.CellLayout around their `media`;\n * `null` elsewhere.\n */\nexport const AvatarSizeContext = React.createContext<AvatarSizeContextValue | null>(null);\nAvatarSizeContext.displayName = 'AvatarSizeContext';\n"],"mappings":";;;AAyBA,IAAaC,IAAyBD,EAAM,cAA2B,IAAI;AAC3E,EAAuB,cAAc;AAMrC,IAAaE,IAAoBF,EAAM,cAA6C,IAAI;AACxF,EAAkB,cAAc"}
@@ -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"),l=require("../../hooks/useId.cjs"),u=require("../../lib/direction.cjs"),d=require("../../lib/focus.cjs"),f=require("../../hooks/useRovingTabIndex.cjs"),p=require("../../hooks/useMergedRefs.cjs"),m=require("../../lib/styles.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`,selectedValues:new Set,toggleItem:()=>{},getTabIndex:()=>-1,registry:new h.ListRegistry},y}function x(e){return g.useContext(v)||(r.reportMissingContext(e,`a List`),b())}var S=[];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 w(e){return n.flattenChildren(e).some(({node:e})=>n.isElementOfType(e,L)&&i.slotRendersContent(e.props.action))}var T=[d.FOCUSABLE_SELECTOR,`[data-list-action]`,`label`,`[role="button"]`,`[role="link"]`,`[role="checkbox"]`,`[role="switch"]`,`[role="radio"]`,`[role="menuitem"]`,`[role="textbox"]`,`[role="combobox"]`,`[role="slider"]`,`[role="spinbutton"]`].join(`, `);function E(e){let t=e.currentTarget,n=e.target;if(!n||typeof n.nodeType!=`number`||!t.contains(n))return!0;let r=n.nodeType===Node.ELEMENT_NODE?n:n.parentElement??null;for(;r&&r!==t;r=r.parentElement)if(r.matches(T))return!0;return!1}function D(e){return e.ctrlKey||e.altKey||e.metaKey?!1:e.key===`Enter`||e.key===` `}var O=new Set([`textbox`,`searchbox`,`combobox`,`spinbutton`,`slider`]),k=new Set([`button`,`checkbox`,`color`,`file`,`hidden`,`image`,`radio`,`reset`,`submit`]);function A(e){let t=e.getAttribute(`role`);if(t!==null&&O.has(t))return!0;let n=e.localName;return n===`textarea`||n===`select`?!0:n===`input`?!k.has(e.type):e.matches(`[contenteditable]:not([contenteditable="false"])`)}function j(e){return Array.from(e.querySelectorAll(d.FOCUSABLE_SELECTOR)).filter(e=>d.isFocusable(e))}function M(e){if(!e.parentElement)return-1;let t=0;for(let n=e.previousElementSibling;n;n=n.previousElementSibling)t++;return t}function N(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:j(o)[0]??null:null}function P(e){for(let t=e.firstElementChild;t;t=t.nextElementSibling)if(t.hasAttribute(`data-list-action`))return t;return null}function F(e){let t=[];for(let n of j(e)){let r=A(n)?e:n;t.includes(r)||t.push(r)}return t}var I=e=>{let{selectable:n=!1,selectionMode:i,selectedItems:s,defaultSelectedItems:l,onSelectionChange:u,selectedItem:d,defaultSelectedItem:m,onSelectedItemChange:y,className:b,children:x,ref:T,onKeyDown:E,onKeyDownCapture:D,onFocus:O,...k}=e;i===`multi`&&r.warnDeprecated(`List`,`selectionMode="multi"`,`selectionMode="multiple"`);let A=i===`multiple`||i===`multi`,j=g.useMemo(()=>!A&&d!==void 0?d===null?S:[d]:s,[A,d,s]),M=g.useMemo(()=>!A&&m!=null?[m]:l??S,[A,m,l]),[P,F]=c.useControllable(j,M,e=>{let t=[...e];u?.(t),A||y?.(t[0]??null)}),[I]=g.useState(()=>new h.ListRegistry);g.useLayoutEffect(()=>{I.setActive(n)},[I,n]);let L=g.useSyncExternalStore(I.subscribe,I.getSnapshot,I.getServerSnapshot),R=g.useMemo(()=>L?P.filter(e=>L.valueSet.has(e)):P,[L,P]),z=g.useMemo(()=>new Set(R),[R]),B=n&&(L?L.hasActions:w(x)),V=n?B?`grid`:`listbox`:`list`,H=L?L.values.find(e=>z.has(e))??null:R[0]??null,{containerProps:U,getTabIndex:W}=f.useRovingTabIndex({activeValue:H,orientation:`vertical`,typeahead:(L?.count??0)>7,tabStop:`active`,itemSelector:`:scope > [data-roving-value]`}),{ref:G,onKeyDown:K,onKeyDownCapture:q,onFocus:J}=U,Y=g.useRef(null),X=p.useMergedRefs(T,n?G:null,Y);g.useLayoutEffect(()=>{let e=I.takeFocusLoss(),t=Y.current;if(!e||!t)return;let n=t.ownerDocument,r=n.activeElement;r&&r!==n.body&&r.isConnected||N(t,e)?.focus()},[V,I]),g.useLayoutEffect(()=>{I.syncOrder(Y.current)});let Z=g.useCallback(e=>{F(t=>{let n=I.prune(t),r=n.includes(e);return A?r?n.filter(t=>t!==e):[...n,e]:r?[]:[e]})},[A,I,F]),Q=L?.duplicates??S;g.useEffect(()=>{for(let e of Q)C(e)},[Q]);let $=R.length;g.useEffect(()=>{n&&!A&&$>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,A,$]);let ee=g.useMemo(()=>({mode:V,selectedValues:z,toggleItem:Z,getTabIndex:W,registry:I}),[V,z,Z,W,I]),te=V===`grid`?`div`:`ul`,ne=V===`grid`?`grid`:V===`listbox`?`listbox`:`list`;return(0,_.jsx)(v.Provider,{value:ee,children:(0,_.jsx)(te,{role:ne,"aria-multiselectable":n&&A?!0:void 0,className:t.cn(o.listClassNames.root,`m-0 list-none p-0`,b),...k,ref:X,"data-roving-container":n?``:void 0,onKeyDown:n?a.composeEventHandlers(E,K):E,onKeyDownCapture:n?a.composeEventHandlers(D,q):D,onFocus:n?a.composeEventHandlers(O,J,{checkDefaultPrevented:!1}):O,children:x})})};I.displayName=`List`;var L=({value:e,action:n,className:r,children:c,onClick:d,onKeyDown:f,ref:h,...v})=>{let{mode:y,selectedValues:b,toggleItem:S,getTabIndex:C,registry:w}=x(`ListItem`),T=l.useId(`list-item`),O=e||void 0,k=O??T,N=i.slotRendersContent(n),[I]=g.useState(()=>({})),L=g.useRef(null),R=p.useMergedRefs(h,L);g.useLayoutEffect(()=>{w.set(I,{value:O,hasAction:N,element:L})},[w,I,O,N]),g.useLayoutEffect(()=>()=>w.delete(I),[w,I]);let z=s.useEventCallback(e=>{let t=e.parentElement;w.recordFocusLoss({value:O,index:t?M(t):-1})});g.useLayoutEffect(()=>{let e=L.current;return()=>{if(!e)return;let t=e.ownerDocument.activeElement;t&&e.contains(t)&&w.recordFocusLoss({value:O,index:M(e)})}},[w,O]);let B=O!==void 0&&b.has(O),H=y!==`list`,U=()=>{O!==void 0&&S(O)},W=e=>{E(e)||U()},G=e=>{E(e)||D(e)&&(e.preventDefault(),U())},K=e=>{let t=e.currentTarget,n=e.target,r=P(t);if(!r||!r.contains(n)){if(n!==t)return;if(D(e)){e.preventDefault(),U();return}let i=u.getArrowIntent(e.key,{orientation:`horizontal`,dir:u.getDirection(t)})===`next`&&r?F(r)[0]:void 0;i&&(e.preventDefault(),i.focus());return}if(n!==r&&A(n)){e.key===`Escape`&&(e.preventDefault(),r.focus());return}if(n===r&&(e.key===`Enter`||e.key===`F2`)){let t=j(r).find(e=>A(e));t&&(e.preventDefault(),t.focus());return}let i=u.getArrowIntent(e.key,{orientation:`horizontal`,dir:u.getDirection(t)});if(!i)return;e.preventDefault();let a=F(r),o=a.indexOf(n);i===`next`?a[o+1]?.focus():o>0?a[o-1].focus():t.focus()},q=y===`grid`?`div`:`li`,J=y===`grid`?`div`:`span`,Y=y===`grid`?`row`:y===`listbox`?`option`:`listitem`,X=H?{"aria-selected":B,tabIndex:C(k),"data-roving-value":k,"data-selected":B?``:void 0,onClick:a.composeEventHandlers(d,W),onKeyDown:a.composeEventHandlers(f,y===`grid`?K:G)}:{onClick:d,onKeyDown:f};return(0,_.jsxs)(q,{role:Y,className:t.cn(o.listItemClassNames.root,`flex items-center border-b border-border px-4 py-2 text-body-1`,H&&[`relative cursor-pointer`,`focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring`],H&&(B?[`bg-subtle-selected before:absolute before:inset-y-2 before:start-0 before:w-0.5 before:rounded-full before:bg-primary`,m.forcedColors.selectedContainer]:`hover:bg-subtle-hover`),r),...v,ref:R,...X,children:[(0,_.jsx)(J,{role:y===`grid`?`gridcell`:void 0,className:t.cn(o.listItemClassNames.content,`min-w-0 flex-1`),children:c}),N&&(0,_.jsx)(V,{grid:y===`grid`,onRemovedWithFocus:z,children:i.materialiseSlotContent(n)})]})};L.displayName=`ListItem`;var R=[`[data-roving-container]`,...[`toolbar`,`radiogroup`,`listbox`,`grid`,`treegrid`,`tablist`,`menu`,`menubar`,`tree`].map(e=>`[role="${e}"]`)].join(`, `),z=[`tabindex`,`href`,`contenteditable`,`controls`];function B(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(d.FOCUSABLE_SELECTOR)){let i=r.getAttribute(`tabindex`);if(i===`-1`||n.has(r))continue;let a=r.closest(R);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:z}),()=>{i.disconnect();for(let[e,n]of t)n===null?e.removeAttribute(`tabindex`):e.setAttribute(`tabindex`,n);t.clear()}}function V({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?B(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})}V.displayName=`ListActionCell`;var H=Object.assign(I,{Item:L});exports.List=H,exports.ListItem=L;
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;
2
2
  //# sourceMappingURL=List.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"List.cjs","names":["React","ListRegistry","flattenChildren","isElementOfType","slotRendersContent","FOCUSABLE_SELECTOR","isFocusable","useControllable","useRovingTabIndex","useMergedRefs","cn","listClassNames","composeEventHandlers","useId","useEventCallback","getArrowIntent","getDirection","listItemClassNames","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_styles","require_List_registry","react","react_jsx_runtime","ListContext","inertContext","getInertContext","useListContext","componentName","EMPTY","warnDuplicateValue","value","childrenHaveAction","children","node","ListItem","INTERACTIVE_SELECTOR","isForeignEvent","item","event","target","isActivationKey","TEXT_ENTRY_ROLES","NON_TEXT_INPUT_TYPES","isTextEntry","role","el","tag","getFocusables","cell","getItemIndex","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","selectable","registered","effective","selectedValues","hasActions","mode","tabStopValue","rovingRef","rovingKeyDown","rovingKeyDownCapture","rovingFocus","containerProps","rootElementRef","rootRef","ref","doc","active","toggleItem","current","previous","isSelected","duplicates","selectedCount","contextValue","getTabIndex","Root","className","onKeyDown","onKeyDownCapture","onFocus","autoValue","selectableValue","rovingValue","hasAction","action","token","itemRef","itemRefs","recordActionFocusLoss","activate","handleClick","handleOptionKeyDown","handleRowKeyDown","rowElement","first","entry","intent","Element","ContentCell","interactiveProps","onClick","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 { 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 { FOCUSABLE_SELECTOR, isFocusable } from '../../lib/focus';\nimport { materialiseSlotContent, slotRendersContent } 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 * 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 * Ref to the root element: a `<ul>`, or a `<div role=\"grid\">` for a selectable list whose items\n * have actions.\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}).\n */\n action?: React.ReactNode;\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/** `list`: plain list; `listbox`: selectable; `grid`: selectable with item actions. */\ntype ListMode = 'list' | 'listbox' | 'grid';\n\ninterface ListContextValue {\n mode: ListMode;\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 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/** 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 that contains them. */\nconst INTERACTIVE_SELECTOR = [\n FOCUSABLE_SELECTOR,\n '[data-list-action]',\n 'label',\n '[role=\"button\"]',\n '[role=\"link\"]',\n '[role=\"checkbox\"]',\n '[role=\"switch\"]',\n '[role=\"radio\"]',\n '[role=\"menuitem\"]',\n '[role=\"textbox\"]',\n '[role=\"combobox\"]',\n '[role=\"slider\"]',\n '[role=\"spinbutton\"]',\n].join(', ');\n\n/**\n * Whether an item must leave `event` alone (no selection toggle): it started inside the action\n * container or a nested interactive element, or outside the item's DOM. React bubbles the events\n * of a popup portaled from an action (a Popover, Menu or Dialog) through the item's handlers\n * although their target lives elsewhere in the document; those never toggle the item (as in\n * Card).\n */\nfunction isForeignEvent(event: React.SyntheticEvent<HTMLElement>): boolean {\n const item = event.currentTarget;\n const target = event.target as Partial<Node> | null;\n if (!target || typeof target.nodeType !== 'number' || !item.contains(target as Node)) {\n return true;\n }\n let node: Element | null =\n target.nodeType === Node.ELEMENT_NODE ? (target as Element) : (target.parentElement ?? null);\n for (; node && node !== item; node = node.parentElement) {\n if (node.matches(INTERACTIVE_SELECTOR)) return true;\n }\n return false;\n}\n\n/**\n * Enter or Space without Ctrl, Alt or Meta: the keys that toggle an item. With a modifier (Ctrl+Alt\n * 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 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 React.useLayoutEffect(() => {\n registry.setActive(selectable);\n }, [registry, selectable]);\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 const hasActions =\n selectable && (registered ? registered.hasActions : childrenHaveAction(children));\n const mode: ListMode = !selectable ? 'list' : hasActions ? 'grid' : 'listbox';\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: tabStopValue,\n orientation: 'vertical',\n typeahead: (registered?.count ?? 0) > 7,\n tabStop: 'active',\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 selectable ? 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 // 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 contextValue = React.useMemo<ListContextValue>(\n () => ({ mode, selectedValues, toggleItem, getTabIndex, registry }),\n [mode, selectedValues, toggleItem, getTabIndex, registry],\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 className={cn(listClassNames.root, 'm-0 list-none p-0', className)}\n {...rest}\n ref={rootRef}\n data-roving-container={selectable ? '' : undefined}\n onKeyDown={selectable ? composeEventHandlers(onKeyDown, rovingKeyDown) : onKeyDown}\n onKeyDownCapture={\n selectable\n ? composeEventHandlers(onKeyDownCapture, rovingKeyDownCapture)\n : onKeyDownCapture\n }\n onFocus={\n selectable\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 * 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 selectable list with actions. In a\n * selectable list, Enter and Space toggle the selection without calling `onClick`, which receives\n * pointer clicks.\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 className,\n children,\n onClick,\n onKeyDown,\n ref,\n ...rest\n}: ListItemProps) => {\n const { mode, selectedValues, toggleItem, getTabIndex, registry } = 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 const isSelected = selectableValue !== undefined && selectedValues.has(selectableValue);\n const selectable = mode !== 'list';\n\n const activate = () => {\n if (selectableValue !== undefined) toggleItem(selectableValue);\n };\n\n const handleClick = (event: React.MouseEvent<HTMLElement>) => {\n if (isForeignEvent(event)) return;\n activate();\n };\n\n const handleOptionKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n if (isForeignEvent(event)) return;\n if (isActivationKey(event)) {\n event.preventDefault();\n activate();\n }\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 event.preventDefault();\n activate();\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> = selectable\n ? {\n 'aria-selected': isSelected,\n tabIndex: getTabIndex(rovingValue),\n 'data-roving-value': rovingValue,\n 'data-selected': isSelected ? '' : undefined,\n onClick: composeEventHandlers(onClick, handleClick),\n onKeyDown: composeEventHandlers(\n onKeyDown,\n mode === 'grid' ? handleRowKeyDown : handleOptionKeyDown,\n ),\n }\n : { onClick, onKeyDown };\n\n return (\n <Element\n role={role}\n className={cn(\n listItemClassNames.root,\n 'flex items-center border-b border-border px-4 py-2 text-body-1',\n selectable && ['relative cursor-pointer', focusRingInset],\n selectable &&\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 : '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 </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 * - **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` changes while items have actions, React remounts the items and their\n * content: state inside them (an inline rename input's draft, an uncontrolled checkbox) is reset.\n * 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), so the switch\n * 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 keep an action on at least one item).\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 */\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","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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"}