@fluentui/react-list 9.4.2 → 9.5.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.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,27 @@
1
1
  # Change Log - @fluentui/react-list
2
2
 
3
- This log was last generated on Thu, 07 Aug 2025 09:59:13 GMT and should not be manually modified.
3
+ This log was last generated on Thu, 21 Aug 2025 12:20:41 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## [9.5.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-list_v9.5.0)
8
+
9
+ Thu, 21 Aug 2025 12:20:41 GMT
10
+ [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-list_v9.4.2..@fluentui/react-list_v9.5.0)
11
+
12
+ ### Minor changes
13
+
14
+ - Feat: Add support for disabling selection per item ([PR #34851](https://github.com/microsoft/fluentui/pull/34851) by jirivyhnalek@microsoft.com)
15
+ - Bump @fluentui/react-checkbox to v9.5.4 ([PR #35055](https://github.com/microsoft/fluentui/pull/35055) by beachball)
16
+ - Bump @fluentui/react-context-selector to v9.2.6 ([PR #35055](https://github.com/microsoft/fluentui/pull/35055) by beachball)
17
+ - Bump @fluentui/react-jsx-runtime to v9.1.6 ([PR #35055](https://github.com/microsoft/fluentui/pull/35055) by beachball)
18
+ - Bump @fluentui/react-tabster to v9.26.4 ([PR #35055](https://github.com/microsoft/fluentui/pull/35055) by beachball)
19
+ - Bump @fluentui/react-utilities to v9.24.0 ([PR #35055](https://github.com/microsoft/fluentui/pull/35055) by beachball)
20
+ - Bump @fluentui/react-shared-contexts to v9.25.0 ([PR #35055](https://github.com/microsoft/fluentui/pull/35055) by beachball)
21
+
7
22
  ## [9.4.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-list_v9.4.2)
8
23
 
9
- Thu, 07 Aug 2025 09:59:13 GMT
24
+ Thu, 07 Aug 2025 10:03:33 GMT
10
25
  [Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-list_v9.4.1..@fluentui/react-list_v9.4.2)
11
26
 
12
27
  ### Patches
package/dist/index.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- /// <reference types="react" />
2
-
3
1
  import { Checkbox } from '@fluentui/react-checkbox';
4
2
  import type { ComponentProps } from '@fluentui/react-utilities';
5
3
  import type { ComponentState } from '@fluentui/react-utilities';
@@ -48,6 +46,7 @@ export declare const listItemClassNames: SlotClassNames<ListItemSlots>;
48
46
  export declare type ListItemProps = ComponentProps<ListItemSlots> & {
49
47
  value?: ListItemValue;
50
48
  onAction?: EventHandler<ListItemActionEventData>;
49
+ disabledSelection?: boolean;
51
50
  };
52
51
 
53
52
  export declare type ListItemSlots = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ListItem/ListItem.types.ts"],"sourcesContent":["import { Checkbox } from '@fluentui/react-checkbox';\nimport type { ComponentProps, ComponentState, EventData, EventHandler, Slot } from '@fluentui/react-utilities';\nimport { ListItemActionEvent, ListItemActionEventName } from '../../events/ListItemActionEvent';\n\nexport type ListItemSlots = {\n root: NonNullable<Slot<'li', 'div'>>;\n checkmark?: Slot<typeof Checkbox>;\n};\n\nexport type ListItemValue = string | number;\n\nexport type ListItemActionEventData = EventData<typeof ListItemActionEventName, ListItemActionEvent> & {\n value: ListItemValue;\n};\n/**\n * ListItem Props\n */\nexport type ListItemProps = ComponentProps<ListItemSlots> & {\n value?: ListItemValue;\n onAction?: EventHandler<ListItemActionEventData>;\n};\n\n/**\n * State used in rendering ListItem\n */\nexport type ListItemState = ComponentState<ListItemSlots> & { selectable: boolean; navigable: boolean };\n"],"names":[],"mappings":"AAsBA;;CAEC,GACD,WAAwG"}
1
+ {"version":3,"sources":["../src/components/ListItem/ListItem.types.ts"],"sourcesContent":["import { Checkbox } from '@fluentui/react-checkbox';\nimport type { ComponentProps, ComponentState, EventData, EventHandler, Slot } from '@fluentui/react-utilities';\nimport { ListItemActionEvent, ListItemActionEventName } from '../../events/ListItemActionEvent';\n\nexport type ListItemSlots = {\n root: NonNullable<Slot<'li', 'div'>>;\n checkmark?: Slot<typeof Checkbox>;\n};\n\nexport type ListItemValue = string | number;\n\nexport type ListItemActionEventData = EventData<typeof ListItemActionEventName, ListItemActionEvent> & {\n value: ListItemValue;\n};\n/**\n * ListItem Props\n */\nexport type ListItemProps = ComponentProps<ListItemSlots> & {\n value?: ListItemValue;\n onAction?: EventHandler<ListItemActionEventData>;\n disabledSelection?: boolean;\n};\n\n/**\n * State used in rendering ListItem\n */\nexport type ListItemState = ComponentState<ListItemSlots> & { selectable: boolean; navigable: boolean };\n"],"names":[],"mappings":"AAuBA;;CAEC,GACD,WAAwG"}
@@ -16,13 +16,13 @@ const DEFAULT_ROOT_EL_TYPE = 'li';
16
16
  * @param ref - reference to root HTMLLIElement | HTMLDivElementof ListItem
17
17
  */ export const useListItem_unstable = (props, ref)=>{
18
18
  const id = useId('listItem');
19
- const { value = id, onKeyDown, onClick, tabIndex, role, onAction } = props;
19
+ const { value = id, onKeyDown, onClick, tabIndex, role, onAction, disabledSelection } = props;
20
20
  const toggleItem = useListContext_unstable((ctx)=>{
21
21
  var _ctx_selection;
22
22
  return (_ctx_selection = ctx.selection) === null || _ctx_selection === void 0 ? void 0 : _ctx_selection.toggleItem;
23
23
  });
24
24
  const { navigationMode, listItemRole } = useListSynchronousContext();
25
- const isSelectionEnabled = useListContext_unstable((ctx)=>!!ctx.selection);
25
+ const isSelectionModeEnabled = useListContext_unstable((ctx)=>!!ctx.selection);
26
26
  const isSelected = useListContext_unstable((ctx)=>{
27
27
  var _ctx_selection;
28
28
  return (_ctx_selection = ctx.selection) === null || _ctx_selection === void 0 ? void 0 : _ctx_selection.isSelected(value);
@@ -30,7 +30,7 @@ const DEFAULT_ROOT_EL_TYPE = 'li';
30
30
  const validateListItem = useListContext_unstable((ctx)=>ctx.validateListItem);
31
31
  const as = props.as || navigationMode === 'composite' ? 'div' : DEFAULT_ROOT_EL_TYPE;
32
32
  const finalListItemRole = role || listItemRole;
33
- const focusableItems = Boolean(isSelectionEnabled || navigationMode || tabIndex === 0);
33
+ const focusableItems = Boolean(isSelectionModeEnabled || navigationMode || tabIndex === 0);
34
34
  const rootRef = React.useRef(null);
35
35
  const checkmarkRef = React.useRef(null);
36
36
  const handleAction = useEventCallback((event)=>{
@@ -42,7 +42,7 @@ const DEFAULT_ROOT_EL_TYPE = 'li';
42
42
  if (event.defaultPrevented) {
43
43
  return;
44
44
  }
45
- if (isSelectionEnabled) {
45
+ if (isSelectionModeEnabled && !disabledSelection) {
46
46
  toggleItem === null || toggleItem === void 0 ? void 0 : toggleItem(event.detail.originalEvent, value);
47
47
  }
48
48
  });
@@ -114,8 +114,10 @@ const DEFAULT_ROOT_EL_TYPE = 'li';
114
114
  // we have to prevent default here otherwise the space key will scroll the page
115
115
  e.preventDefault();
116
116
  // Space always toggles selection (if enabled)
117
- if (isSelectionEnabled) {
118
- toggleItem === null || toggleItem === void 0 ? void 0 : toggleItem(e, value);
117
+ if (isSelectionModeEnabled) {
118
+ if (!disabledSelection) {
119
+ toggleItem === null || toggleItem === void 0 ? void 0 : toggleItem(e, value);
120
+ }
119
121
  } else {
120
122
  triggerAction(e);
121
123
  }
@@ -133,7 +135,7 @@ const DEFAULT_ROOT_EL_TYPE = 'li';
133
135
  }
134
136
  });
135
137
  const onCheckboxChange = useEventCallback((e, data)=>{
136
- if (!isSelectionEnabled || e.defaultPrevented) {
138
+ if (!isSelectionModeEnabled || e.defaultPrevented) {
137
139
  return;
138
140
  }
139
141
  toggleItem === null || toggleItem === void 0 ? void 0 : toggleItem(e, value);
@@ -147,22 +149,24 @@ const DEFAULT_ROOT_EL_TYPE = 'li';
147
149
  tabIndex: focusableItems ? 0 : undefined,
148
150
  role: finalListItemRole,
149
151
  id: String(value),
150
- ...isSelectionEnabled && {
151
- 'aria-selected': isSelected
152
+ ...isSelectionModeEnabled && {
153
+ 'aria-selected': isSelected,
154
+ 'aria-disabled': disabledSelection && !onAction || undefined
152
155
  },
153
156
  ...props,
154
157
  ...tabsterAttributes,
155
158
  onKeyDown: handleKeyDown,
156
- onClick: isSelectionEnabled || onClick || onAction ? handleClick : undefined
159
+ onClick: isSelectionModeEnabled || onClick || onAction ? handleClick : undefined
157
160
  }), {
158
161
  elementType: as
159
162
  });
160
163
  const checkmark = slot.optional(props.checkmark, {
161
164
  defaultProps: {
162
165
  checked: isSelected,
163
- tabIndex: -1
166
+ tabIndex: -1,
167
+ disabled: disabledSelection
164
168
  },
165
- renderByDefault: isSelectionEnabled,
169
+ renderByDefault: isSelectionModeEnabled,
166
170
  elementType: Checkbox
167
171
  });
168
172
  const mergedCheckmarkRef = useMergedRefs(checkmark === null || checkmark === void 0 ? void 0 : checkmark.ref, checkmarkRef);
@@ -177,7 +181,7 @@ const DEFAULT_ROOT_EL_TYPE = 'li';
177
181
  },
178
182
  root,
179
183
  checkmark,
180
- selectable: isSelectionEnabled,
184
+ selectable: isSelectionModeEnabled,
181
185
  navigable: focusableItems
182
186
  };
183
187
  return state;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ListItem/useListItem.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n GroupperMoveFocusEvent,\n MoverMoveFocusEvent,\n GroupperMoveFocusActions,\n MoverKeys,\n useArrowNavigationGroup,\n useFocusableGroup,\n useMergedTabsterAttributes_unstable,\n type TabsterDOMAttribute,\n} from '@fluentui/react-tabster';\nimport {\n elementContains,\n getIntrinsicElementProps,\n mergeCallbacks,\n slot,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport type { ListItemProps, ListItemState } from './ListItem.types';\nimport { useListSynchronousContext, useListContext_unstable } from '../List/listContext';\nimport { Enter, Space, ArrowUp, ArrowDown, ArrowRight, ArrowLeft } from '@fluentui/keyboard-keys';\nimport { Checkbox, CheckboxOnChangeData } from '@fluentui/react-checkbox';\nimport {\n createListItemActionEvent,\n ListItemActionEvent,\n ListItemActionEventName,\n} from '../../events/ListItemActionEvent';\n\nconst DEFAULT_ROOT_EL_TYPE = 'li';\n\n/**\n * Create the state required to render ListItem.\n *\n * The returned state can be modified with hooks such as useListItemStyles_unstable,\n * before being passed to renderListItem_unstable.\n *\n * @param props - props from this instance of ListItem\n * @param ref - reference to root HTMLLIElement | HTMLDivElementof ListItem\n */\nexport const useListItem_unstable = (\n props: ListItemProps,\n ref: React.Ref<HTMLLIElement | HTMLDivElement>,\n): ListItemState => {\n const id = useId('listItem');\n const { value = id, onKeyDown, onClick, tabIndex, role, onAction } = props;\n\n const toggleItem = useListContext_unstable(ctx => ctx.selection?.toggleItem);\n\n const { navigationMode, listItemRole } = useListSynchronousContext();\n\n const isSelectionEnabled = useListContext_unstable(ctx => !!ctx.selection);\n const isSelected = useListContext_unstable(ctx => ctx.selection?.isSelected(value));\n const validateListItem = useListContext_unstable(ctx => ctx.validateListItem);\n\n const as = props.as || navigationMode === 'composite' ? 'div' : DEFAULT_ROOT_EL_TYPE;\n\n const finalListItemRole = role || listItemRole;\n\n const focusableItems = Boolean(isSelectionEnabled || navigationMode || tabIndex === 0);\n\n const rootRef = React.useRef<HTMLLIElement | HTMLDivElement>(null);\n const checkmarkRef = React.useRef<HTMLInputElement | null>(null);\n\n const handleAction: (event: ListItemActionEvent) => void = useEventCallback(event => {\n onAction?.(event, { event, value, type: ListItemActionEventName });\n\n if (event.defaultPrevented) {\n return;\n }\n\n if (isSelectionEnabled) {\n toggleItem?.(event.detail.originalEvent, value);\n }\n });\n\n React.useEffect(() => {\n if (rootRef.current) {\n validateListItem(rootRef.current);\n }\n }, [validateListItem]);\n\n const triggerAction = (e: React.MouseEvent | React.KeyboardEvent) => {\n const actionEvent = createListItemActionEvent(e);\n handleAction(actionEvent);\n e.target.dispatchEvent(actionEvent);\n };\n\n const focusableGroupAttrs = useFocusableGroup({\n ignoreDefaultKeydown: { Enter: true },\n tabBehavior: 'limited-trap-focus',\n });\n\n const handleClick: React.MouseEventHandler<HTMLLIElement & HTMLDivElement> = useEventCallback(e => {\n onClick?.(e);\n\n if (e.defaultPrevented) {\n return;\n }\n\n const isFromCheckbox = elementContains(checkmarkRef.current, e.target as Node);\n if (isFromCheckbox) {\n return;\n }\n\n triggerAction(e);\n });\n\n const handleKeyDown: React.KeyboardEventHandler<HTMLLIElement & HTMLDivElement> = useEventCallback(e => {\n onKeyDown?.(e);\n\n if (e.defaultPrevented) {\n return;\n }\n\n // If the event is fired from an element inside the list item\n if (e.target !== e.currentTarget) {\n if (focusableItems) {\n // If the items are focusable, we need to handle the arrow keys to move focus to them\n switch (e.key) {\n // If it's one of the Arrows defined, jump out of the list item to focus on the ListItem itself\n // The ArrowLeft will only trigger if the target element is the leftmost, otherwise the\n // arrowNavigationAttributes handles it and prevents it from bubbling here.\n case ArrowLeft:\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Escape }));\n break;\n\n case ArrowDown:\n case ArrowUp:\n e.preventDefault();\n // Press ESC on the original target to get focus to the parent group (List)\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Escape }));\n // Now dispatch the original key to move up or down in the list\n e.currentTarget.dispatchEvent(new MoverMoveFocusEvent({ key: MoverKeys[e.key] }));\n }\n return;\n }\n return;\n }\n\n switch (e.key) {\n case Space:\n // we have to prevent default here otherwise the space key will scroll the page\n e.preventDefault();\n\n // Space always toggles selection (if enabled)\n if (isSelectionEnabled) {\n toggleItem?.(e, value);\n } else {\n triggerAction(e);\n }\n\n break;\n\n case Enter:\n triggerAction(e);\n break;\n\n case ArrowRight:\n if (navigationMode === 'composite') {\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Enter }));\n }\n\n break;\n }\n });\n\n const onCheckboxChange = useEventCallback((e: React.ChangeEvent<HTMLInputElement>, data: CheckboxOnChangeData) => {\n if (!isSelectionEnabled || e.defaultPrevented) {\n return;\n }\n\n toggleItem?.(e, value);\n });\n\n const arrowNavigationAttributes = useArrowNavigationGroup({\n axis: 'horizontal',\n });\n\n const tabsterAttributes = useMergedTabsterAttributes_unstable(\n focusableItems ? arrowNavigationAttributes : {},\n focusableGroupAttrs,\n props as Partial<TabsterDOMAttribute>,\n );\n\n const root = slot.always(\n getIntrinsicElementProps(as, {\n ref: useMergedRefs(rootRef, ref) as React.Ref<HTMLLIElement & HTMLDivElement>,\n tabIndex: focusableItems ? 0 : undefined,\n role: finalListItemRole,\n id: String(value),\n ...(isSelectionEnabled && {\n 'aria-selected': isSelected,\n }),\n ...props,\n ...tabsterAttributes,\n onKeyDown: handleKeyDown,\n onClick: isSelectionEnabled || onClick || onAction ? handleClick : undefined,\n }),\n { elementType: as },\n );\n\n const checkmark = slot.optional(props.checkmark, {\n defaultProps: {\n checked: isSelected,\n tabIndex: -1,\n },\n renderByDefault: isSelectionEnabled,\n elementType: Checkbox,\n });\n\n const mergedCheckmarkRef = useMergedRefs(checkmark?.ref, checkmarkRef);\n if (checkmark) {\n checkmark.onChange = mergeCallbacks(checkmark.onChange, onCheckboxChange);\n checkmark.ref = mergedCheckmarkRef;\n }\n\n const state: ListItemState = {\n components: {\n root: as,\n checkmark: Checkbox,\n },\n root,\n checkmark,\n selectable: isSelectionEnabled,\n navigable: focusableItems,\n };\n\n return state;\n};\n"],"names":["React","GroupperMoveFocusEvent","MoverMoveFocusEvent","GroupperMoveFocusActions","MoverKeys","useArrowNavigationGroup","useFocusableGroup","useMergedTabsterAttributes_unstable","elementContains","getIntrinsicElementProps","mergeCallbacks","slot","useEventCallback","useId","useMergedRefs","useListSynchronousContext","useListContext_unstable","Enter","Space","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","Checkbox","createListItemActionEvent","ListItemActionEventName","DEFAULT_ROOT_EL_TYPE","useListItem_unstable","props","ref","id","value","onKeyDown","onClick","tabIndex","role","onAction","toggleItem","ctx","selection","navigationMode","listItemRole","isSelectionEnabled","isSelected","validateListItem","as","finalListItemRole","focusableItems","Boolean","rootRef","useRef","checkmarkRef","handleAction","event","type","defaultPrevented","detail","originalEvent","useEffect","current","triggerAction","e","actionEvent","target","dispatchEvent","focusableGroupAttrs","ignoreDefaultKeydown","tabBehavior","handleClick","isFromCheckbox","handleKeyDown","currentTarget","key","action","Escape","preventDefault","onCheckboxChange","data","arrowNavigationAttributes","axis","tabsterAttributes","root","always","undefined","String","elementType","checkmark","optional","defaultProps","checked","renderByDefault","mergedCheckmarkRef","onChange","state","components","selectable","navigable"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/components/ListItem/useListItem.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n GroupperMoveFocusEvent,\n MoverMoveFocusEvent,\n GroupperMoveFocusActions,\n MoverKeys,\n useArrowNavigationGroup,\n useFocusableGroup,\n useMergedTabsterAttributes_unstable,\n type TabsterDOMAttribute,\n} from '@fluentui/react-tabster';\nimport {\n elementContains,\n getIntrinsicElementProps,\n mergeCallbacks,\n slot,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport type { ListItemProps, ListItemState } from './ListItem.types';\nimport { useListSynchronousContext, useListContext_unstable } from '../List/listContext';\nimport { Enter, Space, ArrowUp, ArrowDown, ArrowRight, ArrowLeft } from '@fluentui/keyboard-keys';\nimport { Checkbox, CheckboxOnChangeData } from '@fluentui/react-checkbox';\nimport {\n createListItemActionEvent,\n ListItemActionEvent,\n ListItemActionEventName,\n} from '../../events/ListItemActionEvent';\n\nconst DEFAULT_ROOT_EL_TYPE = 'li';\n\n/**\n * Create the state required to render ListItem.\n *\n * The returned state can be modified with hooks such as useListItemStyles_unstable,\n * before being passed to renderListItem_unstable.\n *\n * @param props - props from this instance of ListItem\n * @param ref - reference to root HTMLLIElement | HTMLDivElementof ListItem\n */\nexport const useListItem_unstable = (\n props: ListItemProps,\n ref: React.Ref<HTMLLIElement | HTMLDivElement>,\n): ListItemState => {\n const id = useId('listItem');\n const { value = id, onKeyDown, onClick, tabIndex, role, onAction, disabledSelection } = props;\n\n const toggleItem = useListContext_unstable(ctx => ctx.selection?.toggleItem);\n\n const { navigationMode, listItemRole } = useListSynchronousContext();\n\n const isSelectionModeEnabled = useListContext_unstable(ctx => !!ctx.selection);\n const isSelected = useListContext_unstable(ctx => ctx.selection?.isSelected(value));\n const validateListItem = useListContext_unstable(ctx => ctx.validateListItem);\n\n const as = props.as || navigationMode === 'composite' ? 'div' : DEFAULT_ROOT_EL_TYPE;\n\n const finalListItemRole = role || listItemRole;\n\n const focusableItems = Boolean(isSelectionModeEnabled || navigationMode || tabIndex === 0);\n\n const rootRef = React.useRef<HTMLLIElement | HTMLDivElement>(null);\n const checkmarkRef = React.useRef<HTMLInputElement | null>(null);\n\n const handleAction: (event: ListItemActionEvent) => void = useEventCallback(event => {\n onAction?.(event, { event, value, type: ListItemActionEventName });\n\n if (event.defaultPrevented) {\n return;\n }\n\n if (isSelectionModeEnabled && !disabledSelection) {\n toggleItem?.(event.detail.originalEvent, value);\n }\n });\n\n React.useEffect(() => {\n if (rootRef.current) {\n validateListItem(rootRef.current);\n }\n }, [validateListItem]);\n\n const triggerAction = (e: React.MouseEvent | React.KeyboardEvent) => {\n const actionEvent = createListItemActionEvent(e);\n handleAction(actionEvent);\n e.target.dispatchEvent(actionEvent);\n };\n\n const focusableGroupAttrs = useFocusableGroup({\n ignoreDefaultKeydown: { Enter: true },\n tabBehavior: 'limited-trap-focus',\n });\n\n const handleClick: React.MouseEventHandler<HTMLLIElement & HTMLDivElement> = useEventCallback(e => {\n onClick?.(e);\n\n if (e.defaultPrevented) {\n return;\n }\n\n const isFromCheckbox = elementContains(checkmarkRef.current, e.target as Node);\n if (isFromCheckbox) {\n return;\n }\n\n triggerAction(e);\n });\n\n const handleKeyDown: React.KeyboardEventHandler<HTMLLIElement & HTMLDivElement> = useEventCallback(e => {\n onKeyDown?.(e);\n\n if (e.defaultPrevented) {\n return;\n }\n\n // If the event is fired from an element inside the list item\n if (e.target !== e.currentTarget) {\n if (focusableItems) {\n // If the items are focusable, we need to handle the arrow keys to move focus to them\n switch (e.key) {\n // If it's one of the Arrows defined, jump out of the list item to focus on the ListItem itself\n // The ArrowLeft will only trigger if the target element is the leftmost, otherwise the\n // arrowNavigationAttributes handles it and prevents it from bubbling here.\n case ArrowLeft:\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Escape }));\n break;\n\n case ArrowDown:\n case ArrowUp:\n e.preventDefault();\n // Press ESC on the original target to get focus to the parent group (List)\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Escape }));\n // Now dispatch the original key to move up or down in the list\n e.currentTarget.dispatchEvent(new MoverMoveFocusEvent({ key: MoverKeys[e.key] }));\n }\n return;\n }\n return;\n }\n\n switch (e.key) {\n case Space:\n // we have to prevent default here otherwise the space key will scroll the page\n e.preventDefault();\n\n // Space always toggles selection (if enabled)\n if (isSelectionModeEnabled) {\n if (!disabledSelection) {\n toggleItem?.(e, value);\n }\n } else {\n triggerAction(e);\n }\n\n break;\n\n case Enter:\n triggerAction(e);\n break;\n\n case ArrowRight:\n if (navigationMode === 'composite') {\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Enter }));\n }\n\n break;\n }\n });\n\n const onCheckboxChange = useEventCallback((e: React.ChangeEvent<HTMLInputElement>, data: CheckboxOnChangeData) => {\n if (!isSelectionModeEnabled || e.defaultPrevented) {\n return;\n }\n\n toggleItem?.(e, value);\n });\n\n const arrowNavigationAttributes = useArrowNavigationGroup({\n axis: 'horizontal',\n });\n\n const tabsterAttributes = useMergedTabsterAttributes_unstable(\n focusableItems ? arrowNavigationAttributes : {},\n focusableGroupAttrs,\n props as Partial<TabsterDOMAttribute>,\n );\n\n const root = slot.always(\n getIntrinsicElementProps(as, {\n ref: useMergedRefs(rootRef, ref) as React.Ref<HTMLLIElement & HTMLDivElement>,\n tabIndex: focusableItems ? 0 : undefined,\n role: finalListItemRole,\n id: String(value),\n ...(isSelectionModeEnabled && {\n 'aria-selected': isSelected,\n 'aria-disabled': (disabledSelection && !onAction) || undefined,\n }),\n ...props,\n ...tabsterAttributes,\n onKeyDown: handleKeyDown,\n onClick: isSelectionModeEnabled || onClick || onAction ? handleClick : undefined,\n }),\n { elementType: as },\n );\n\n const checkmark = slot.optional(props.checkmark, {\n defaultProps: {\n checked: isSelected,\n tabIndex: -1,\n disabled: disabledSelection,\n },\n renderByDefault: isSelectionModeEnabled,\n elementType: Checkbox,\n });\n\n const mergedCheckmarkRef = useMergedRefs(checkmark?.ref, checkmarkRef);\n if (checkmark) {\n checkmark.onChange = mergeCallbacks(checkmark.onChange, onCheckboxChange);\n checkmark.ref = mergedCheckmarkRef;\n }\n\n const state: ListItemState = {\n components: {\n root: as,\n checkmark: Checkbox,\n },\n root,\n checkmark,\n selectable: isSelectionModeEnabled,\n navigable: focusableItems,\n };\n\n return state;\n};\n"],"names":["React","GroupperMoveFocusEvent","MoverMoveFocusEvent","GroupperMoveFocusActions","MoverKeys","useArrowNavigationGroup","useFocusableGroup","useMergedTabsterAttributes_unstable","elementContains","getIntrinsicElementProps","mergeCallbacks","slot","useEventCallback","useId","useMergedRefs","useListSynchronousContext","useListContext_unstable","Enter","Space","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","Checkbox","createListItemActionEvent","ListItemActionEventName","DEFAULT_ROOT_EL_TYPE","useListItem_unstable","props","ref","id","value","onKeyDown","onClick","tabIndex","role","onAction","disabledSelection","toggleItem","ctx","selection","navigationMode","listItemRole","isSelectionModeEnabled","isSelected","validateListItem","as","finalListItemRole","focusableItems","Boolean","rootRef","useRef","checkmarkRef","handleAction","event","type","defaultPrevented","detail","originalEvent","useEffect","current","triggerAction","e","actionEvent","target","dispatchEvent","focusableGroupAttrs","ignoreDefaultKeydown","tabBehavior","handleClick","isFromCheckbox","handleKeyDown","currentTarget","key","action","Escape","preventDefault","onCheckboxChange","data","arrowNavigationAttributes","axis","tabsterAttributes","root","always","undefined","String","elementType","checkmark","optional","defaultProps","checked","disabled","renderByDefault","mergedCheckmarkRef","onChange","state","components","selectable","navigable"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ListItem/ListItem.types.ts"],"sourcesContent":["import { Checkbox } from '@fluentui/react-checkbox';\nimport type { ComponentProps, ComponentState, EventData, EventHandler, Slot } from '@fluentui/react-utilities';\nimport { ListItemActionEvent, ListItemActionEventName } from '../../events/ListItemActionEvent';\n\nexport type ListItemSlots = {\n root: NonNullable<Slot<'li', 'div'>>;\n checkmark?: Slot<typeof Checkbox>;\n};\n\nexport type ListItemValue = string | number;\n\nexport type ListItemActionEventData = EventData<typeof ListItemActionEventName, ListItemActionEvent> & {\n value: ListItemValue;\n};\n/**\n * ListItem Props\n */\nexport type ListItemProps = ComponentProps<ListItemSlots> & {\n value?: ListItemValue;\n onAction?: EventHandler<ListItemActionEventData>;\n};\n\n/**\n * State used in rendering ListItem\n */\nexport type ListItemState = ComponentState<ListItemSlots> & { selectable: boolean; navigable: boolean };\n"],"names":[],"mappings":"AAsBA;;CAEC,GACD,WAAwG"}
1
+ {"version":3,"sources":["../src/components/ListItem/ListItem.types.ts"],"sourcesContent":["import { Checkbox } from '@fluentui/react-checkbox';\nimport type { ComponentProps, ComponentState, EventData, EventHandler, Slot } from '@fluentui/react-utilities';\nimport { ListItemActionEvent, ListItemActionEventName } from '../../events/ListItemActionEvent';\n\nexport type ListItemSlots = {\n root: NonNullable<Slot<'li', 'div'>>;\n checkmark?: Slot<typeof Checkbox>;\n};\n\nexport type ListItemValue = string | number;\n\nexport type ListItemActionEventData = EventData<typeof ListItemActionEventName, ListItemActionEvent> & {\n value: ListItemValue;\n};\n/**\n * ListItem Props\n */\nexport type ListItemProps = ComponentProps<ListItemSlots> & {\n value?: ListItemValue;\n onAction?: EventHandler<ListItemActionEventData>;\n disabledSelection?: boolean;\n};\n\n/**\n * State used in rendering ListItem\n */\nexport type ListItemState = ComponentState<ListItemSlots> & { selectable: boolean; navigable: boolean };\n"],"names":[],"mappings":"AAuBA;;CAEC,GACD,WAAwG"}
@@ -19,13 +19,13 @@ const _ListItemActionEvent = require("../../events/ListItemActionEvent");
19
19
  const DEFAULT_ROOT_EL_TYPE = 'li';
20
20
  const useListItem_unstable = (props, ref)=>{
21
21
  const id = (0, _reactutilities.useId)('listItem');
22
- const { value = id, onKeyDown, onClick, tabIndex, role, onAction } = props;
22
+ const { value = id, onKeyDown, onClick, tabIndex, role, onAction, disabledSelection } = props;
23
23
  const toggleItem = (0, _listContext.useListContext_unstable)((ctx)=>{
24
24
  var _ctx_selection;
25
25
  return (_ctx_selection = ctx.selection) === null || _ctx_selection === void 0 ? void 0 : _ctx_selection.toggleItem;
26
26
  });
27
27
  const { navigationMode, listItemRole } = (0, _listContext.useListSynchronousContext)();
28
- const isSelectionEnabled = (0, _listContext.useListContext_unstable)((ctx)=>!!ctx.selection);
28
+ const isSelectionModeEnabled = (0, _listContext.useListContext_unstable)((ctx)=>!!ctx.selection);
29
29
  const isSelected = (0, _listContext.useListContext_unstable)((ctx)=>{
30
30
  var _ctx_selection;
31
31
  return (_ctx_selection = ctx.selection) === null || _ctx_selection === void 0 ? void 0 : _ctx_selection.isSelected(value);
@@ -33,7 +33,7 @@ const useListItem_unstable = (props, ref)=>{
33
33
  const validateListItem = (0, _listContext.useListContext_unstable)((ctx)=>ctx.validateListItem);
34
34
  const as = props.as || navigationMode === 'composite' ? 'div' : DEFAULT_ROOT_EL_TYPE;
35
35
  const finalListItemRole = role || listItemRole;
36
- const focusableItems = Boolean(isSelectionEnabled || navigationMode || tabIndex === 0);
36
+ const focusableItems = Boolean(isSelectionModeEnabled || navigationMode || tabIndex === 0);
37
37
  const rootRef = _react.useRef(null);
38
38
  const checkmarkRef = _react.useRef(null);
39
39
  const handleAction = (0, _reactutilities.useEventCallback)((event)=>{
@@ -45,7 +45,7 @@ const useListItem_unstable = (props, ref)=>{
45
45
  if (event.defaultPrevented) {
46
46
  return;
47
47
  }
48
- if (isSelectionEnabled) {
48
+ if (isSelectionModeEnabled && !disabledSelection) {
49
49
  toggleItem === null || toggleItem === void 0 ? void 0 : toggleItem(event.detail.originalEvent, value);
50
50
  }
51
51
  });
@@ -117,8 +117,10 @@ const useListItem_unstable = (props, ref)=>{
117
117
  // we have to prevent default here otherwise the space key will scroll the page
118
118
  e.preventDefault();
119
119
  // Space always toggles selection (if enabled)
120
- if (isSelectionEnabled) {
121
- toggleItem === null || toggleItem === void 0 ? void 0 : toggleItem(e, value);
120
+ if (isSelectionModeEnabled) {
121
+ if (!disabledSelection) {
122
+ toggleItem === null || toggleItem === void 0 ? void 0 : toggleItem(e, value);
123
+ }
122
124
  } else {
123
125
  triggerAction(e);
124
126
  }
@@ -136,7 +138,7 @@ const useListItem_unstable = (props, ref)=>{
136
138
  }
137
139
  });
138
140
  const onCheckboxChange = (0, _reactutilities.useEventCallback)((e, data)=>{
139
- if (!isSelectionEnabled || e.defaultPrevented) {
141
+ if (!isSelectionModeEnabled || e.defaultPrevented) {
140
142
  return;
141
143
  }
142
144
  toggleItem === null || toggleItem === void 0 ? void 0 : toggleItem(e, value);
@@ -150,22 +152,24 @@ const useListItem_unstable = (props, ref)=>{
150
152
  tabIndex: focusableItems ? 0 : undefined,
151
153
  role: finalListItemRole,
152
154
  id: String(value),
153
- ...isSelectionEnabled && {
154
- 'aria-selected': isSelected
155
+ ...isSelectionModeEnabled && {
156
+ 'aria-selected': isSelected,
157
+ 'aria-disabled': disabledSelection && !onAction || undefined
155
158
  },
156
159
  ...props,
157
160
  ...tabsterAttributes,
158
161
  onKeyDown: handleKeyDown,
159
- onClick: isSelectionEnabled || onClick || onAction ? handleClick : undefined
162
+ onClick: isSelectionModeEnabled || onClick || onAction ? handleClick : undefined
160
163
  }), {
161
164
  elementType: as
162
165
  });
163
166
  const checkmark = _reactutilities.slot.optional(props.checkmark, {
164
167
  defaultProps: {
165
168
  checked: isSelected,
166
- tabIndex: -1
169
+ tabIndex: -1,
170
+ disabled: disabledSelection
167
171
  },
168
- renderByDefault: isSelectionEnabled,
172
+ renderByDefault: isSelectionModeEnabled,
169
173
  elementType: _reactcheckbox.Checkbox
170
174
  });
171
175
  const mergedCheckmarkRef = (0, _reactutilities.useMergedRefs)(checkmark === null || checkmark === void 0 ? void 0 : checkmark.ref, checkmarkRef);
@@ -180,7 +184,7 @@ const useListItem_unstable = (props, ref)=>{
180
184
  },
181
185
  root,
182
186
  checkmark,
183
- selectable: isSelectionEnabled,
187
+ selectable: isSelectionModeEnabled,
184
188
  navigable: focusableItems
185
189
  };
186
190
  return state;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ListItem/useListItem.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n GroupperMoveFocusEvent,\n MoverMoveFocusEvent,\n GroupperMoveFocusActions,\n MoverKeys,\n useArrowNavigationGroup,\n useFocusableGroup,\n useMergedTabsterAttributes_unstable,\n type TabsterDOMAttribute,\n} from '@fluentui/react-tabster';\nimport {\n elementContains,\n getIntrinsicElementProps,\n mergeCallbacks,\n slot,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport type { ListItemProps, ListItemState } from './ListItem.types';\nimport { useListSynchronousContext, useListContext_unstable } from '../List/listContext';\nimport { Enter, Space, ArrowUp, ArrowDown, ArrowRight, ArrowLeft } from '@fluentui/keyboard-keys';\nimport { Checkbox, CheckboxOnChangeData } from '@fluentui/react-checkbox';\nimport {\n createListItemActionEvent,\n ListItemActionEvent,\n ListItemActionEventName,\n} from '../../events/ListItemActionEvent';\n\nconst DEFAULT_ROOT_EL_TYPE = 'li';\n\n/**\n * Create the state required to render ListItem.\n *\n * The returned state can be modified with hooks such as useListItemStyles_unstable,\n * before being passed to renderListItem_unstable.\n *\n * @param props - props from this instance of ListItem\n * @param ref - reference to root HTMLLIElement | HTMLDivElementof ListItem\n */\nexport const useListItem_unstable = (\n props: ListItemProps,\n ref: React.Ref<HTMLLIElement | HTMLDivElement>,\n): ListItemState => {\n const id = useId('listItem');\n const { value = id, onKeyDown, onClick, tabIndex, role, onAction } = props;\n\n const toggleItem = useListContext_unstable(ctx => ctx.selection?.toggleItem);\n\n const { navigationMode, listItemRole } = useListSynchronousContext();\n\n const isSelectionEnabled = useListContext_unstable(ctx => !!ctx.selection);\n const isSelected = useListContext_unstable(ctx => ctx.selection?.isSelected(value));\n const validateListItem = useListContext_unstable(ctx => ctx.validateListItem);\n\n const as = props.as || navigationMode === 'composite' ? 'div' : DEFAULT_ROOT_EL_TYPE;\n\n const finalListItemRole = role || listItemRole;\n\n const focusableItems = Boolean(isSelectionEnabled || navigationMode || tabIndex === 0);\n\n const rootRef = React.useRef<HTMLLIElement | HTMLDivElement>(null);\n const checkmarkRef = React.useRef<HTMLInputElement | null>(null);\n\n const handleAction: (event: ListItemActionEvent) => void = useEventCallback(event => {\n onAction?.(event, { event, value, type: ListItemActionEventName });\n\n if (event.defaultPrevented) {\n return;\n }\n\n if (isSelectionEnabled) {\n toggleItem?.(event.detail.originalEvent, value);\n }\n });\n\n React.useEffect(() => {\n if (rootRef.current) {\n validateListItem(rootRef.current);\n }\n }, [validateListItem]);\n\n const triggerAction = (e: React.MouseEvent | React.KeyboardEvent) => {\n const actionEvent = createListItemActionEvent(e);\n handleAction(actionEvent);\n e.target.dispatchEvent(actionEvent);\n };\n\n const focusableGroupAttrs = useFocusableGroup({\n ignoreDefaultKeydown: { Enter: true },\n tabBehavior: 'limited-trap-focus',\n });\n\n const handleClick: React.MouseEventHandler<HTMLLIElement & HTMLDivElement> = useEventCallback(e => {\n onClick?.(e);\n\n if (e.defaultPrevented) {\n return;\n }\n\n const isFromCheckbox = elementContains(checkmarkRef.current, e.target as Node);\n if (isFromCheckbox) {\n return;\n }\n\n triggerAction(e);\n });\n\n const handleKeyDown: React.KeyboardEventHandler<HTMLLIElement & HTMLDivElement> = useEventCallback(e => {\n onKeyDown?.(e);\n\n if (e.defaultPrevented) {\n return;\n }\n\n // If the event is fired from an element inside the list item\n if (e.target !== e.currentTarget) {\n if (focusableItems) {\n // If the items are focusable, we need to handle the arrow keys to move focus to them\n switch (e.key) {\n // If it's one of the Arrows defined, jump out of the list item to focus on the ListItem itself\n // The ArrowLeft will only trigger if the target element is the leftmost, otherwise the\n // arrowNavigationAttributes handles it and prevents it from bubbling here.\n case ArrowLeft:\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Escape }));\n break;\n\n case ArrowDown:\n case ArrowUp:\n e.preventDefault();\n // Press ESC on the original target to get focus to the parent group (List)\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Escape }));\n // Now dispatch the original key to move up or down in the list\n e.currentTarget.dispatchEvent(new MoverMoveFocusEvent({ key: MoverKeys[e.key] }));\n }\n return;\n }\n return;\n }\n\n switch (e.key) {\n case Space:\n // we have to prevent default here otherwise the space key will scroll the page\n e.preventDefault();\n\n // Space always toggles selection (if enabled)\n if (isSelectionEnabled) {\n toggleItem?.(e, value);\n } else {\n triggerAction(e);\n }\n\n break;\n\n case Enter:\n triggerAction(e);\n break;\n\n case ArrowRight:\n if (navigationMode === 'composite') {\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Enter }));\n }\n\n break;\n }\n });\n\n const onCheckboxChange = useEventCallback((e: React.ChangeEvent<HTMLInputElement>, data: CheckboxOnChangeData) => {\n if (!isSelectionEnabled || e.defaultPrevented) {\n return;\n }\n\n toggleItem?.(e, value);\n });\n\n const arrowNavigationAttributes = useArrowNavigationGroup({\n axis: 'horizontal',\n });\n\n const tabsterAttributes = useMergedTabsterAttributes_unstable(\n focusableItems ? arrowNavigationAttributes : {},\n focusableGroupAttrs,\n props as Partial<TabsterDOMAttribute>,\n );\n\n const root = slot.always(\n getIntrinsicElementProps(as, {\n ref: useMergedRefs(rootRef, ref) as React.Ref<HTMLLIElement & HTMLDivElement>,\n tabIndex: focusableItems ? 0 : undefined,\n role: finalListItemRole,\n id: String(value),\n ...(isSelectionEnabled && {\n 'aria-selected': isSelected,\n }),\n ...props,\n ...tabsterAttributes,\n onKeyDown: handleKeyDown,\n onClick: isSelectionEnabled || onClick || onAction ? handleClick : undefined,\n }),\n { elementType: as },\n );\n\n const checkmark = slot.optional(props.checkmark, {\n defaultProps: {\n checked: isSelected,\n tabIndex: -1,\n },\n renderByDefault: isSelectionEnabled,\n elementType: Checkbox,\n });\n\n const mergedCheckmarkRef = useMergedRefs(checkmark?.ref, checkmarkRef);\n if (checkmark) {\n checkmark.onChange = mergeCallbacks(checkmark.onChange, onCheckboxChange);\n checkmark.ref = mergedCheckmarkRef;\n }\n\n const state: ListItemState = {\n components: {\n root: as,\n checkmark: Checkbox,\n },\n root,\n checkmark,\n selectable: isSelectionEnabled,\n navigable: focusableItems,\n };\n\n return state;\n};\n"],"names":["React","GroupperMoveFocusEvent","MoverMoveFocusEvent","GroupperMoveFocusActions","MoverKeys","useArrowNavigationGroup","useFocusableGroup","useMergedTabsterAttributes_unstable","elementContains","getIntrinsicElementProps","mergeCallbacks","slot","useEventCallback","useId","useMergedRefs","useListSynchronousContext","useListContext_unstable","Enter","Space","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","Checkbox","createListItemActionEvent","ListItemActionEventName","DEFAULT_ROOT_EL_TYPE","useListItem_unstable","props","ref","id","value","onKeyDown","onClick","tabIndex","role","onAction","toggleItem","ctx","selection","navigationMode","listItemRole","isSelectionEnabled","isSelected","validateListItem","as","finalListItemRole","focusableItems","Boolean","rootRef","useRef","checkmarkRef","handleAction","event","type","defaultPrevented","detail","originalEvent","useEffect","current","triggerAction","e","actionEvent","target","dispatchEvent","focusableGroupAttrs","ignoreDefaultKeydown","tabBehavior","handleClick","isFromCheckbox","handleKeyDown","currentTarget","key","action","Escape","preventDefault","onCheckboxChange","data","arrowNavigationAttributes","axis","tabsterAttributes","root","always","undefined","String","elementType","checkmark","optional","defaultProps","checked","renderByDefault","mergedCheckmarkRef","onChange","state","components","selectable","navigable"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/components/ListItem/useListItem.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n GroupperMoveFocusEvent,\n MoverMoveFocusEvent,\n GroupperMoveFocusActions,\n MoverKeys,\n useArrowNavigationGroup,\n useFocusableGroup,\n useMergedTabsterAttributes_unstable,\n type TabsterDOMAttribute,\n} from '@fluentui/react-tabster';\nimport {\n elementContains,\n getIntrinsicElementProps,\n mergeCallbacks,\n slot,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport type { ListItemProps, ListItemState } from './ListItem.types';\nimport { useListSynchronousContext, useListContext_unstable } from '../List/listContext';\nimport { Enter, Space, ArrowUp, ArrowDown, ArrowRight, ArrowLeft } from '@fluentui/keyboard-keys';\nimport { Checkbox, CheckboxOnChangeData } from '@fluentui/react-checkbox';\nimport {\n createListItemActionEvent,\n ListItemActionEvent,\n ListItemActionEventName,\n} from '../../events/ListItemActionEvent';\n\nconst DEFAULT_ROOT_EL_TYPE = 'li';\n\n/**\n * Create the state required to render ListItem.\n *\n * The returned state can be modified with hooks such as useListItemStyles_unstable,\n * before being passed to renderListItem_unstable.\n *\n * @param props - props from this instance of ListItem\n * @param ref - reference to root HTMLLIElement | HTMLDivElementof ListItem\n */\nexport const useListItem_unstable = (\n props: ListItemProps,\n ref: React.Ref<HTMLLIElement | HTMLDivElement>,\n): ListItemState => {\n const id = useId('listItem');\n const { value = id, onKeyDown, onClick, tabIndex, role, onAction, disabledSelection } = props;\n\n const toggleItem = useListContext_unstable(ctx => ctx.selection?.toggleItem);\n\n const { navigationMode, listItemRole } = useListSynchronousContext();\n\n const isSelectionModeEnabled = useListContext_unstable(ctx => !!ctx.selection);\n const isSelected = useListContext_unstable(ctx => ctx.selection?.isSelected(value));\n const validateListItem = useListContext_unstable(ctx => ctx.validateListItem);\n\n const as = props.as || navigationMode === 'composite' ? 'div' : DEFAULT_ROOT_EL_TYPE;\n\n const finalListItemRole = role || listItemRole;\n\n const focusableItems = Boolean(isSelectionModeEnabled || navigationMode || tabIndex === 0);\n\n const rootRef = React.useRef<HTMLLIElement | HTMLDivElement>(null);\n const checkmarkRef = React.useRef<HTMLInputElement | null>(null);\n\n const handleAction: (event: ListItemActionEvent) => void = useEventCallback(event => {\n onAction?.(event, { event, value, type: ListItemActionEventName });\n\n if (event.defaultPrevented) {\n return;\n }\n\n if (isSelectionModeEnabled && !disabledSelection) {\n toggleItem?.(event.detail.originalEvent, value);\n }\n });\n\n React.useEffect(() => {\n if (rootRef.current) {\n validateListItem(rootRef.current);\n }\n }, [validateListItem]);\n\n const triggerAction = (e: React.MouseEvent | React.KeyboardEvent) => {\n const actionEvent = createListItemActionEvent(e);\n handleAction(actionEvent);\n e.target.dispatchEvent(actionEvent);\n };\n\n const focusableGroupAttrs = useFocusableGroup({\n ignoreDefaultKeydown: { Enter: true },\n tabBehavior: 'limited-trap-focus',\n });\n\n const handleClick: React.MouseEventHandler<HTMLLIElement & HTMLDivElement> = useEventCallback(e => {\n onClick?.(e);\n\n if (e.defaultPrevented) {\n return;\n }\n\n const isFromCheckbox = elementContains(checkmarkRef.current, e.target as Node);\n if (isFromCheckbox) {\n return;\n }\n\n triggerAction(e);\n });\n\n const handleKeyDown: React.KeyboardEventHandler<HTMLLIElement & HTMLDivElement> = useEventCallback(e => {\n onKeyDown?.(e);\n\n if (e.defaultPrevented) {\n return;\n }\n\n // If the event is fired from an element inside the list item\n if (e.target !== e.currentTarget) {\n if (focusableItems) {\n // If the items are focusable, we need to handle the arrow keys to move focus to them\n switch (e.key) {\n // If it's one of the Arrows defined, jump out of the list item to focus on the ListItem itself\n // The ArrowLeft will only trigger if the target element is the leftmost, otherwise the\n // arrowNavigationAttributes handles it and prevents it from bubbling here.\n case ArrowLeft:\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Escape }));\n break;\n\n case ArrowDown:\n case ArrowUp:\n e.preventDefault();\n // Press ESC on the original target to get focus to the parent group (List)\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Escape }));\n // Now dispatch the original key to move up or down in the list\n e.currentTarget.dispatchEvent(new MoverMoveFocusEvent({ key: MoverKeys[e.key] }));\n }\n return;\n }\n return;\n }\n\n switch (e.key) {\n case Space:\n // we have to prevent default here otherwise the space key will scroll the page\n e.preventDefault();\n\n // Space always toggles selection (if enabled)\n if (isSelectionModeEnabled) {\n if (!disabledSelection) {\n toggleItem?.(e, value);\n }\n } else {\n triggerAction(e);\n }\n\n break;\n\n case Enter:\n triggerAction(e);\n break;\n\n case ArrowRight:\n if (navigationMode === 'composite') {\n e.target.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Enter }));\n }\n\n break;\n }\n });\n\n const onCheckboxChange = useEventCallback((e: React.ChangeEvent<HTMLInputElement>, data: CheckboxOnChangeData) => {\n if (!isSelectionModeEnabled || e.defaultPrevented) {\n return;\n }\n\n toggleItem?.(e, value);\n });\n\n const arrowNavigationAttributes = useArrowNavigationGroup({\n axis: 'horizontal',\n });\n\n const tabsterAttributes = useMergedTabsterAttributes_unstable(\n focusableItems ? arrowNavigationAttributes : {},\n focusableGroupAttrs,\n props as Partial<TabsterDOMAttribute>,\n );\n\n const root = slot.always(\n getIntrinsicElementProps(as, {\n ref: useMergedRefs(rootRef, ref) as React.Ref<HTMLLIElement & HTMLDivElement>,\n tabIndex: focusableItems ? 0 : undefined,\n role: finalListItemRole,\n id: String(value),\n ...(isSelectionModeEnabled && {\n 'aria-selected': isSelected,\n 'aria-disabled': (disabledSelection && !onAction) || undefined,\n }),\n ...props,\n ...tabsterAttributes,\n onKeyDown: handleKeyDown,\n onClick: isSelectionModeEnabled || onClick || onAction ? handleClick : undefined,\n }),\n { elementType: as },\n );\n\n const checkmark = slot.optional(props.checkmark, {\n defaultProps: {\n checked: isSelected,\n tabIndex: -1,\n disabled: disabledSelection,\n },\n renderByDefault: isSelectionModeEnabled,\n elementType: Checkbox,\n });\n\n const mergedCheckmarkRef = useMergedRefs(checkmark?.ref, checkmarkRef);\n if (checkmark) {\n checkmark.onChange = mergeCallbacks(checkmark.onChange, onCheckboxChange);\n checkmark.ref = mergedCheckmarkRef;\n }\n\n const state: ListItemState = {\n components: {\n root: as,\n checkmark: Checkbox,\n },\n root,\n checkmark,\n selectable: isSelectionModeEnabled,\n navigable: focusableItems,\n };\n\n return state;\n};\n"],"names":["React","GroupperMoveFocusEvent","MoverMoveFocusEvent","GroupperMoveFocusActions","MoverKeys","useArrowNavigationGroup","useFocusableGroup","useMergedTabsterAttributes_unstable","elementContains","getIntrinsicElementProps","mergeCallbacks","slot","useEventCallback","useId","useMergedRefs","useListSynchronousContext","useListContext_unstable","Enter","Space","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","Checkbox","createListItemActionEvent","ListItemActionEventName","DEFAULT_ROOT_EL_TYPE","useListItem_unstable","props","ref","id","value","onKeyDown","onClick","tabIndex","role","onAction","disabledSelection","toggleItem","ctx","selection","navigationMode","listItemRole","isSelectionModeEnabled","isSelected","validateListItem","as","finalListItemRole","focusableItems","Boolean","rootRef","useRef","checkmarkRef","handleAction","event","type","defaultPrevented","detail","originalEvent","useEffect","current","triggerAction","e","actionEvent","target","dispatchEvent","focusableGroupAttrs","ignoreDefaultKeydown","tabBehavior","handleClick","isFromCheckbox","handleKeyDown","currentTarget","key","action","Escape","preventDefault","onCheckboxChange","data","arrowNavigationAttributes","axis","tabsterAttributes","root","always","undefined","String","elementType","checkmark","optional","defaultProps","checked","disabled","renderByDefault","mergedCheckmarkRef","onChange","state","components","selectable","navigable"],"mappings":";;;;+BAyCa2B;;;;;;;iEAzCU,QAAQ;8BAUxB,0BAA0B;gCAS1B,4BAA4B;6BAEgC,sBAAsB;8BACjB,0BAA0B;+BACnD,2BAA2B;qCAKnE,mCAAmC;AAE1C,MAAMD,uBAAuB;AAWtB,6BAA6B,CAClCE,OACAC;IAEA,MAAMC,SAAKjB,qBAAAA,EAAM;IACjB,MAAM,EAAEkB,QAAQD,EAAE,EAAEE,SAAS,EAAEC,OAAO,EAAEC,QAAQ,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,iBAAiB,EAAE,GAAGT;IAExF,MAAMU,iBAAatB,oCAAAA,EAAwBuB,CAAAA;YAAOA;gBAAAA,iBAAAA,IAAIC,SAAAA,AAAS,MAAA,QAAbD,mBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,eAAeD,UAAU;;IAE3E,MAAM,EAAEG,cAAc,EAAEC,YAAY,EAAE,OAAG3B,sCAAAA;IAEzC,MAAM4B,6BAAyB3B,oCAAAA,EAAwBuB,CAAAA,MAAO,CAAC,CAACA,IAAIC,SAAS;IAC7E,MAAMI,iBAAa5B,oCAAAA,EAAwBuB,CAAAA;YAAOA;gBAAAA,iBAAAA,IAAIC,SAAAA,AAAS,MAAA,QAAbD,mBAAAA,KAAAA,IAAAA,KAAAA,IAAAA,eAAeK,UAAU,CAACb;;IAC5E,MAAMc,mBAAmB7B,wCAAAA,EAAwBuB,CAAAA,MAAOA,IAAIM,gBAAgB;IAE5E,MAAMC,KAAKlB,MAAMkB,EAAE,IAAIL,mBAAmB,cAAc,QAAQf;IAEhE,MAAMqB,oBAAoBZ,QAAQO;IAElC,MAAMM,iBAAiBC,QAAQN,0BAA0BF,kBAAkBP,aAAa;IAExF,MAAMgB,UAAUlD,OAAMmD,MAAM,CAAiC;IAC7D,MAAMC,eAAepD,OAAMmD,MAAM,CAA0B;IAE3D,MAAME,mBAAqDzC,gCAAAA,EAAiB0C,CAAAA;QAC1ElB,aAAAA,QAAAA,aAAAA,KAAAA,IAAAA,KAAAA,IAAAA,SAAWkB,OAAO;YAAEA;YAAOvB;YAAOwB,MAAM9B,4CAAAA;QAAwB;QAEhE,IAAI6B,MAAME,gBAAgB,EAAE;YAC1B;QACF;QAEA,IAAIb,0BAA0B,CAACN,mBAAmB;YAChDC,eAAAA,QAAAA,eAAAA,KAAAA,IAAAA,KAAAA,IAAAA,WAAagB,MAAMG,MAAM,CAACC,aAAa,EAAE3B;QAC3C;IACF;IAEA/B,OAAM2D,SAAS,CAAC;QACd,IAAIT,QAAQU,OAAO,EAAE;YACnBf,iBAAiBK,QAAQU,OAAO;QAClC;IACF,GAAG;QAACf;KAAiB;IAErB,MAAMgB,gBAAgB,CAACC;QACrB,MAAMC,cAAcvC,kDAAAA,EAA0BsC;QAC9CT,aAAaU;QACbD,EAAEE,MAAM,CAACC,aAAa,CAACF;IACzB;IAEA,MAAMG,0BAAsB5D,+BAAAA,EAAkB;QAC5C6D,sBAAsB;YAAElD,OAAO;QAAK;QACpCmD,aAAa;IACf;IAEA,MAAMC,kBAAuEzD,gCAAAA,EAAiBkD,CAAAA;QAC5F7B,YAAAA,QAAAA,YAAAA,KAAAA,IAAAA,KAAAA,IAAAA,QAAU6B;QAEV,IAAIA,EAAEN,gBAAgB,EAAE;YACtB;QACF;QAEA,MAAMc,qBAAiB9D,+BAAAA,EAAgB4C,aAAaQ,OAAO,EAAEE,EAAEE,MAAM;QACrE,IAAIM,gBAAgB;YAClB;QACF;QAEAT,cAAcC;IAChB;IAEA,MAAMS,oBAA4E3D,gCAAAA,EAAiBkD,CAAAA;QACjG9B,cAAAA,QAAAA,cAAAA,KAAAA,IAAAA,KAAAA,IAAAA,UAAY8B;QAEZ,IAAIA,EAAEN,gBAAgB,EAAE;YACtB;QACF;QAEA,6DAA6D;QAC7D,IAAIM,EAAEE,MAAM,KAAKF,EAAEU,aAAa,EAAE;YAChC,IAAIxB,gBAAgB;gBAClB,qFAAqF;gBACrF,OAAQc,EAAEW,GAAG;oBACX,+FAA+F;oBAC/F,uFAAuF;oBACvF,2EAA2E;oBAC3E,KAAKnD,uBAAAA;wBACHwC,EAAEE,MAAM,CAACC,aAAa,CAAC,IAAIhE,oCAAAA,CAAuB;4BAAEyE,QAAQvE,sCAAAA,CAAyBwE,MAAM;wBAAC;wBAC5F;oBAEF,KAAKvD,uBAAAA;oBACL,KAAKD,qBAAAA;wBACH2C,EAAEc,cAAc;wBAChB,2EAA2E;wBAC3Ed,EAAEE,MAAM,CAACC,aAAa,CAAC,IAAIhE,oCAAAA,CAAuB;4BAAEyE,QAAQvE,sCAAAA,CAAyBwE,MAAM;wBAAC;wBAC5F,+DAA+D;wBAC/Db,EAAEU,aAAa,CAACP,aAAa,CAAC,IAAI/D,iCAAAA,CAAoB;4BAAEuE,KAAKrE,uBAAS,CAAC0D,EAAEW,GAAG,CAAC;wBAAC;gBAClF;gBACA;YACF;YACA;QACF;QAEA,OAAQX,EAAEW,GAAG;YACX,KAAKvD,mBAAAA;gBACH,+EAA+E;gBAC/E4C,EAAEc,cAAc;gBAEhB,8CAA8C;gBAC9C,IAAIjC,wBAAwB;oBAC1B,IAAI,CAACN,mBAAmB;wBACtBC,eAAAA,QAAAA,eAAAA,KAAAA,IAAAA,KAAAA,IAAAA,WAAawB,GAAG/B;oBAClB;gBACF,OAAO;oBACL8B,cAAcC;gBAChB;gBAEA;YAEF,KAAK7C,mBAAAA;gBACH4C,cAAcC;gBACd;YAEF,KAAKzC,wBAAAA;gBACH,IAAIoB,mBAAmB,aAAa;oBAClCqB,EAAEE,MAAM,CAACC,aAAa,CAAC,IAAIhE,oCAAAA,CAAuB;wBAAEyE,QAAQvE,sCAAAA,CAAyBc,KAAK;oBAAC;gBAC7F;gBAEA;QACJ;IACF;IAEA,MAAM4D,uBAAmBjE,gCAAAA,EAAiB,CAACkD,GAAwCgB;QACjF,IAAI,CAACnC,0BAA0BmB,EAAEN,gBAAgB,EAAE;YACjD;QACF;QAEAlB,eAAAA,QAAAA,eAAAA,KAAAA,IAAAA,KAAAA,IAAAA,WAAawB,GAAG/B;IAClB;IAEA,MAAMgD,gCAA4B1E,qCAAAA,EAAwB;QACxD2E,MAAM;IACR;IAEA,MAAMC,wBAAoB1E,iDAAAA,EACxByC,iBAAiB+B,4BAA4B,CAAC,GAC9Cb,qBACAtC;IAGF,MAAMsD,OAAOvE,oBAAAA,CAAKwE,MAAM,CACtB1E,4CAAAA,EAAyBqC,IAAI;QAC3BjB,SAAKf,6BAAAA,EAAcoC,SAASrB;QAC5BK,UAAUc,iBAAiB,IAAIoC;QAC/BjD,MAAMY;QACNjB,IAAIuD,OAAOtD;QACX,GAAIY,0BAA0B;YAC5B,iBAAiBC;YACjB,iBAAkBP,qBAAqB,CAACD,YAAagD;QACvD,CAAC;QACD,GAAGxD,KAAK;QACR,GAAGqD,iBAAiB;QACpBjD,WAAWuC;QACXtC,SAASU,0BAA0BV,WAAWG,WAAWiC,cAAce;IACzE,IACA;QAAEE,aAAaxC;IAAG;IAGpB,MAAMyC,YAAY5E,oBAAAA,CAAK6E,QAAQ,CAAC5D,MAAM2D,SAAS,EAAE;QAC/CE,cAAc;YACZC,SAAS9C;YACTV,UAAU,CAAC;YACXyD,UAAUtD;QACZ;QACAuD,iBAAiBjD;QACjB2C,aAAa/D,uBAAAA;IACf;IAEA,MAAMsE,yBAAqB/E,6BAAAA,EAAcyE,cAAAA,QAAAA,cAAAA,KAAAA,IAAAA,KAAAA,IAAAA,UAAW1D,GAAG,EAAEuB;IACzD,IAAImC,WAAW;QACbA,UAAUO,QAAQ,OAAGpF,8BAAAA,EAAe6E,UAAUO,QAAQ,EAAEjB;QACxDU,UAAU1D,GAAG,GAAGgE;IAClB;IAEA,MAAME,QAAuB;QAC3BC,YAAY;YACVd,MAAMpC;YACNyC,WAAWhE,uBAAAA;QACb;QACA2D;QACAK;QACAU,YAAYtD;QACZuD,WAAWlD;IACb;IAEA,OAAO+C;AACT,EAAE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui/react-list",
3
- "version": "9.4.2",
3
+ "version": "9.5.0",
4
4
  "description": "React List v9",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -26,14 +26,14 @@
26
26
  "@fluentui/scripts-cypress": "*"
27
27
  },
28
28
  "dependencies": {
29
- "@fluentui/react-checkbox": "^9.5.3",
30
- "@fluentui/react-context-selector": "^9.2.5",
31
- "@fluentui/react-jsx-runtime": "^9.1.5",
29
+ "@fluentui/react-checkbox": "^9.5.4",
30
+ "@fluentui/react-context-selector": "^9.2.6",
31
+ "@fluentui/react-jsx-runtime": "^9.1.6",
32
32
  "@fluentui/keyboard-keys": "^9.0.8",
33
- "@fluentui/react-tabster": "^9.26.3",
33
+ "@fluentui/react-tabster": "^9.26.4",
34
34
  "@fluentui/react-theme": "^9.2.0",
35
- "@fluentui/react-utilities": "^9.23.2",
36
- "@fluentui/react-shared-contexts": "^9.24.1",
35
+ "@fluentui/react-utilities": "^9.24.0",
36
+ "@fluentui/react-shared-contexts": "^9.25.0",
37
37
  "@griffel/react": "^1.5.22",
38
38
  "@swc/helpers": "^0.5.1"
39
39
  },