@@ -19,7 +19,7 @@ import DragUtils from '../DragUtils';
1919import Button from '../Button' ;
2020import NavTab from './NavTab' ;
2121import './NavTabList.scss' ;
22- import { ResolvableContextAction } from '../context-actions' ;
22+ import { ContextAction , ResolvableContextAction } from '../context-actions' ;
2323
2424// mouse hold timeout to act as hold instead of click
2525const CLICK_TIMEOUT = 500 ;
@@ -29,28 +29,70 @@ const START_SPEED = 0.01;
2929const ACCELERATION = 0.0005 ;
3030
3131export interface NavTabItem {
32+ /**
33+ * Unique key for the tab.
34+ */
3235 key : string ;
36+
37+ /**
38+ * Title to display on the tab.
39+ */
3340 title : string ;
41+
42+ /**
43+ * Whether the tab is closable.
44+ * If omitted, the tab will be closeable if onClose exists.
45+ */
3446 isClosable ?: boolean ;
3547}
3648
3749type NavTabListProps < T extends NavTabItem = NavTabItem > = {
50+ /**
51+ * The key of the active tab.
52+ * If this does not match a tab key, no tab will be active.
53+ */
3854 activeKey : string ;
55+
56+ /**
57+ * Array of tabs to display.
58+ * @see {@link NavTabItem } for the minimum required properties.
59+ */
3960 tabs : T [ ] ;
61+
62+ /**
63+ * Function called when a tab is selected.
64+ *
65+ * @param key The key of the tab to select
66+ */
4067 onSelect : ( key : string ) => void ;
68+
69+ /**
70+ * Function called when a tab is closed.
71+ * If the function is provided, all tabs will be closeable by default.
72+ * Tabs may set their own closeable property to override this behavior.
73+ *
74+ * @param key The key of the tab to close
75+ */
4176 onClose ?: ( key : string ) => void ;
42- onReorder : ( sourceIndex : number , destinationIndex : number ) => void ;
43- isReorderAllowed : boolean ;
4477
4578 /**
46- * Context items to add to the tab in addition to the default items.
47- * The default items are Close, Close to the Right, and Close All.
48- * The default items have a group value of 20.
79+ * Function called when a tab is reordered.
80+ * If the function is omitted, the tab list will not be reorderable.
81+ *
82+ * @param sourceIndex Index in the tab list the drag started from
83+ * @param destinationIndex Index in the tab list the drag ended at
84+ */
85+ onReorder ?: ( sourceIndex : number , destinationIndex : number ) => void ;
86+
87+ /**
88+ * Context actions to add to the tab in addition to the default actions.
89+ * The default actions are Close, Close to the Right, and Close All.
90+ * The default actions have a group value of 20.
4991 *
5092 * @param tab The tab to make context items for
5193 * @returns Additional context items for the tab
5294 */
53- makeContextItems ?: ( tab : T ) => ResolvableContextAction [ ] ;
95+ makeContextActions ?: ( tab : T ) => ContextAction | ContextAction [ ] ;
5496} ;
5597
5698function isScrolledLeft ( element : HTMLElement ) : boolean {
@@ -64,13 +106,13 @@ function isScrolledRight(element: HTMLElement): boolean {
64106 ) ;
65107}
66108
67- function makeBaseContextItems (
109+ function makeBaseContextActions (
68110 tab : NavTabItem ,
69111 tabs : NavTabItem [ ] ,
70112 onClose : ( ( key : string ) => void ) | undefined
71- ) : ResolvableContextAction [ ] {
113+ ) : ContextAction [ ] {
72114 const { isClosable = false , key } = tab ;
73- const contextActions : ResolvableContextAction [ ] = [ ] ;
115+ const contextActions : ContextAction [ ] = [ ] ;
74116 if ( isClosable && onClose != null ) {
75117 contextActions . push ( {
76118 title : 'Close' ,
@@ -81,7 +123,16 @@ function makeBaseContextItems(
81123 } ,
82124 } ) ;
83125
84- contextActions . push ( ( ) => ( {
126+ let disabled = true ;
127+ for ( let i = tabs . length - 1 ; i > 0 ; i -= 1 ) {
128+ if ( tabs [ i ] . key === tab . key ) break ;
129+ if ( tabs [ i ] . isClosable === true ) {
130+ disabled = false ;
131+ break ;
132+ }
133+ }
134+
135+ contextActions . push ( {
85136 title : 'Close to the Right' ,
86137 order : 20 ,
87138 group : 20 ,
@@ -91,19 +142,8 @@ function makeBaseContextItems(
91142 if ( tabs [ i ] . isClosable === true ) onClose ( tabs [ i ] . key ) ;
92143 }
93144 } ,
94- // IIFE to run when called
95- disabled : ( ( ) => {
96- let disable = true ;
97- for ( let i = tabs . length - 1 ; i > 0 ; i -= 1 ) {
98- if ( tabs [ i ] . key === tab . key ) break ;
99- if ( tabs [ i ] . isClosable === true ) {
100- disable = false ;
101- break ;
102- }
103- }
104- return disable ;
105- } ) ( ) ,
106- } ) ) ;
145+ disabled,
146+ } ) ;
107147
108148 contextActions . push ( {
109149 title : 'Close All' ,
@@ -126,8 +166,7 @@ function NavTabList({
126166 onSelect,
127167 onReorder,
128168 onClose,
129- isReorderAllowed,
130- makeContextItems,
169+ makeContextActions,
131170} : NavTabListProps ) : React . ReactElement {
132171 const containerRef = useRef < HTMLDivElement > ( ) ;
133172 const [ isOverflowing , setIsOverflowing ] = useState ( true ) ;
@@ -161,7 +200,7 @@ function NavTabList({
161200 return ;
162201 }
163202
164- onReorder ( result . source . index , result . destination . index ) ;
203+ onReorder ?. ( result . source . index , result . destination . index ) ;
165204 } ,
166205 [ onReorder ]
167206 ) ;
@@ -351,16 +390,16 @@ function NavTabList({
351390 tabs . forEach ( tab => {
352391 const { key } = tab ;
353392 const contextActions = [
354- ... makeBaseContextItems ( tab , tabs , onClose ) ,
355- ... ( makeContextItems ?.( tab ) ?? [ ] ) ,
393+ ( ) => makeBaseContextActions ( tab , tabs , onClose ) ,
394+ ( ) => makeContextActions ?.( tab ) ?? [ ] ,
356395 ] ;
357396 tabContextActions . set ( key , contextActions ) ;
358397 } ) ;
359398 return tabContextActions ;
360- } , [ makeContextItems , tabs , onClose ] ) ;
399+ } , [ makeContextActions , tabs , onClose ] ) ;
361400
362401 const activeTabRef = useRef < HTMLDivElement > ( null ) ;
363- const activeTab = tabs . find ( tab => tab . key === activeKey ) ?? tabs [ 0 ] ;
402+ const activeTab = tabs . find ( tab => tab . key === activeKey ) ;
364403 const navTabs = tabs . map ( ( tab , index ) => {
365404 const { key } = tab ;
366405 const isActive = tab === activeTab ;
@@ -374,7 +413,7 @@ function NavTabList({
374413 activeRef = { activeTabRef }
375414 onSelect = { onSelect }
376415 onClose = { onClose }
377- isDraggable = { isReorderAllowed }
416+ isDraggable = { onReorder != null }
378417 contextActions = { tabContextActionMap . get ( key ) }
379418 />
380419 ) ;
0 commit comments