UNPKG

3.45 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import * as React from 'react';
3import { useTabsContext } from '../Tabs';
4import { TabsListActionTypes } from './useTabsList.types';
5import { useCompoundParent } from '../utils/useCompound';
6import useList from '../useList';
7import tabsListReducer from './tabsListReducer';
8
9/**
10 *
11 * Demos:
12 *
13 * - [Tabs](https://mui.com/base/react-tabs/#hooks)
14 *
15 * API:
16 *
17 * - [useTabsList API](https://mui.com/base/react-tabs/hooks-api/#use-tabs-list)
18 */
19function useTabsList(parameters) {
20 const {
21 rootRef: externalRef
22 } = parameters;
23 const {
24 direction = 'ltr',
25 onSelected,
26 orientation = 'horizontal',
27 value,
28 registerTabIdLookup,
29 selectionFollowsFocus
30 } = useTabsContext();
31 const {
32 subitems,
33 contextValue: compoundComponentContextValue
34 } = useCompoundParent();
35 const tabIdLookup = React.useCallback(tabValue => {
36 return subitems.get(tabValue)?.id;
37 }, [subitems]);
38 registerTabIdLookup(tabIdLookup);
39 const subitemKeys = React.useMemo(() => Array.from(subitems.keys()), [subitems]);
40 const getTabElement = React.useCallback(tabValue => {
41 if (tabValue == null) {
42 return null;
43 }
44 return subitems.get(tabValue)?.ref.current ?? null;
45 }, [subitems]);
46 const isRtl = direction === 'rtl';
47 let listOrientation;
48 if (orientation === 'vertical') {
49 listOrientation = 'vertical';
50 } else {
51 listOrientation = isRtl ? 'horizontal-rtl' : 'horizontal-ltr';
52 }
53 const handleChange = React.useCallback((event, newValue) => {
54 onSelected(event, newValue[0] ?? null);
55 }, [onSelected]);
56 const controlledProps = React.useMemo(() => {
57 if (value === undefined) {
58 return {};
59 }
60 return value != null ? {
61 selectedValues: [value]
62 } : {
63 selectedValues: []
64 };
65 }, [value]);
66 const isItemDisabled = React.useCallback(item => subitems.get(item)?.disabled ?? false, [subitems]);
67 const {
68 contextValue: listContextValue,
69 dispatch,
70 getRootProps: getListboxRootProps,
71 state: {
72 highlightedValue,
73 selectedValues
74 },
75 rootRef: mergedRootRef
76 } = useList({
77 controlledProps,
78 disabledItemsFocusable: !selectionFollowsFocus,
79 focusManagement: 'DOM',
80 getItemDomElement: getTabElement,
81 isItemDisabled,
82 items: subitemKeys,
83 rootRef: externalRef,
84 onChange: handleChange,
85 orientation: listOrientation,
86 reducerActionContext: React.useMemo(() => ({
87 selectionFollowsFocus: selectionFollowsFocus || false
88 }), [selectionFollowsFocus]),
89 selectionMode: 'single',
90 stateReducer: tabsListReducer
91 });
92 React.useEffect(() => {
93 if (value === undefined) {
94 return;
95 }
96
97 // when a value changes externally, the highlighted value should be synced to it
98 if (value != null) {
99 dispatch({
100 type: TabsListActionTypes.valueChange,
101 value
102 });
103 }
104 }, [dispatch, value]);
105 const getRootProps = (otherHandlers = {}) => {
106 return _extends({}, otherHandlers, getListboxRootProps(otherHandlers), {
107 'aria-orientation': orientation === 'vertical' ? 'vertical' : undefined,
108 role: 'tablist'
109 });
110 };
111 return {
112 contextValue: _extends({}, compoundComponentContextValue, listContextValue),
113 dispatch,
114 getRootProps,
115 highlightedValue,
116 isRtl,
117 orientation,
118 rootRef: mergedRootRef,
119 selectedValue: selectedValues[0] ?? null
120 };
121}
122export default useTabsList;
\No newline at end of file