import React from 'react'; import {ListRenderItemContext} from '@workday/canvas-kit-react/collection'; import { ExtractProps, createElemPropsHook, createSubcomponent, slugify, useMountLayout, } from '@workday/canvas-kit-react/common'; import {Box} from '@workday/canvas-kit-react/layout'; import {useTabsModel} from './useTabsModel'; export interface TabPanelProps extends ExtractProps { /** * The contents of the TabPanel. */ children: React.ReactNode; /** * The identifier of the tab. This identifier will be used in change events and for `initialTab`. * Must match the `data-id` of the associated tab item. If this property is not provided, it will * default to a string representation of the the zero-based index of the Tab when it was * initialized. */ 'data-id'?: string; /** * Part of the ARIA specification for tabs. By default, all `tabpanel` elements have a `tabIndex` * of `0` which makes the whole content area receive focus. If you have a focusable item near the * top of the tab panel content area, you may set `tabIndex` to `undefined` to prevent the tab * panel element from receiving focus. Only do this is a child of the tab panel can receive focus. */ tabIndex?: number; } export const useTabsPanel = createElemPropsHook(useTabsModel)(( {state, events}, _, elemProps: {'data-id'?: string} = {} ) => { const {item} = React.useContext(ListRenderItemContext); const [localId, setLocalId] = React.useState(elemProps['data-id'] || item?.id || ''); useMountLayout(() => { if (item) { return; } const defaultId = state.panelIndexRef.current; const itemId = localId || String(defaultId); events.registerPanel({id: itemId, textValue: ''}); setLocalId(itemId); return () => { events.unregisterPanel({id: itemId}); }; }); return { role: 'tabpanel' as const, 'aria-labelledby': slugify(`${state.id}-${localId}`), hidden: !!localId && localId !== state.selectedIds[0], id: slugify(`tabpanel-${state.id}-${localId}`), tabIndex: 0 as const, }; }); export const TabsPanel = createSubcomponent('div')({ displayName: 'Tabs.Panel', modelHook: useTabsModel, elemPropsHook: useTabsPanel, })(({children, ...elemProps}, Element) => { return ( {children} ); });