@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 +17 -2
- package/dist/index.d.ts +1 -2
- package/lib/components/ListItem/ListItem.types.js.map +1 -1
- package/lib/components/ListItem/useListItem.js +17 -13
- package/lib/components/ListItem/useListItem.js.map +1 -1
- package/lib-commonjs/components/ListItem/ListItem.types.js.map +1 -1
- package/lib-commonjs/components/ListItem/useListItem.js +17 -13
- package/lib-commonjs/components/ListItem/useListItem.js.map +1 -1
- package/package.json +7 -7
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,
|
|
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
|
|
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":"
|
|
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
|
|
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(
|
|
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 (
|
|
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 (
|
|
118
|
-
|
|
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 (!
|
|
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
|
-
...
|
|
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:
|
|
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:
|
|
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:
|
|
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":"
|
|
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
|
|
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(
|
|
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 (
|
|
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 (
|
|
121
|
-
|
|
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 (!
|
|
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
|
-
...
|
|
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:
|
|
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:
|
|
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:
|
|
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":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluentui/react-list",
|
|
3
|
-
"version": "9.
|
|
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.
|
|
30
|
-
"@fluentui/react-context-selector": "^9.2.
|
|
31
|
-
"@fluentui/react-jsx-runtime": "^9.1.
|
|
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.
|
|
33
|
+
"@fluentui/react-tabster": "^9.26.4",
|
|
34
34
|
"@fluentui/react-theme": "^9.2.0",
|
|
35
|
-
"@fluentui/react-utilities": "^9.
|
|
36
|
-
"@fluentui/react-shared-contexts": "^9.
|
|
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
|
},
|