UNPKG

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