MCPcopy Create free account
hub / github.com/adobe/react-spectrum / useGridListItem

Function useGridListItem

packages/react-aria/src/gridlist/useGridListItem.ts:98–477  ·  view source on GitHub ↗
(
  props: AriaGridListItemOptions,
  state: ListState<T> | TreeState<T>,
  ref: RefObject<FocusableElement | null>
)

Source from the content-addressed store, hash-verified

96 * @param ref - The ref attached to the row element.
97 */
98export function useGridListItem<T>(
99 props: AriaGridListItemOptions,
100 state: ListState<T> | TreeState<T>,
101 ref: RefObject<FocusableElement | null>
102): GridListItemAria {
103 // Copied from useGridCell + some modifications to make it not so grid specific
104 let {node, isVirtualized, focusMode = 'row', allowsArrowNavigation} = props;
105
106 // let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/gridlist');
107 let {direction} = useLocale();
108 let {onAction, linkBehavior, keyboardNavigationBehavior, shouldSelectOnPressUp} =
109 listMap.get(state)!;
110 let descriptionId = useSlotId();
111
112 // We need to track the key of the item at the time it was last focused so that we force
113 // focus to go to the item when the DOM node is reused for a different item in a virtualizer.
114 let keyWhenFocused = useRef<Key | null>(null);
115 let focus = () => {
116 if (ref.current === null) {
117 return;
118 }
119
120 if (focusMode === 'child') {
121 // If focus is already on a focusable child within the row, early return so we don't shift focus
122 if (
123 isFocusWithin(ref.current) &&
124 ref.current !== getActiveElement(getOwnerDocument(ref.current))
125 ) {
126 return;
127 }
128
129 let treeWalker = getFocusableTreeWalker(ref.current, {tabbable: true});
130 let focusable = treeWalker.firstChild() as FocusableElement;
131 if (focusable) {
132 focusSafely(focusable);
133 scrollIntoViewport(focusable, {containingElement: getScrollParent(focusable)});
134 return;
135 }
136 }
137
138 // Don't shift focus to the row if the active element is a element within the row already
139 // (e.g. clicking on a row button)
140 if (
141 (keyWhenFocused.current != null && node.key !== keyWhenFocused.current) ||
142 !isFocusWithin(ref.current)
143 ) {
144 focusSafely(ref.current);
145 }
146 };
147
148 let treeGridRowProps: HTMLAttributes<HTMLElement> = {};
149 let hasChildRows = props.hasChildItems;
150 let hasLink = state.selectionManager.isLink(node.key);
151 if (node != null && 'expandedKeys' in state) {
152 // TODO: ideally node.hasChildNodes would be a way to tell if a row has child nodes, but the row's contents make it so that value is always
153 // true...
154 let children = state.collection.getChildren?.(node.key);
155 hasChildRows = hasChildRows || [...(children ?? [])].length > 1;

Callers 5

useTagFunction · 0.90
useTreeItemFunction · 0.90
GridList.tsxFile · 0.90
ListViewItemFunction · 0.90
GridList.tsxFile · 0.90

Calls 15

useLocaleFunction · 0.90
useSlotIdFunction · 0.90
useSelectableItemFunction · 0.90
chainFunction · 0.90
useSyntheticLinkPropsFunction · 0.90
mergePropsFunction · 0.90
getRowIdFunction · 0.90
getDirectChildrenFunction · 0.85
onKeyDownFunction · 0.70
isLinkMethod · 0.65
getChildrenMethod · 0.65
toggleKeyMethod · 0.65

Tested by

no test coverage detected