UNPKG

@wordpress/components

Version:
173 lines (157 loc) 5.29 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import { createElement } from "@wordpress/element"; /** * External dependencies */ import classnames from 'classnames'; /** * WordPress dependencies */ import { useState, useEffect, useLayoutEffect, useCallback } from '@wordpress/element'; import { useInstanceId } from '@wordpress/compose'; /** * Internal dependencies */ import { NavigableMenu } from '../navigable-container'; import Button from '../button'; const TabButton = _ref => { let { tabId, children, selected, ...rest } = _ref; return createElement(Button, _extends({ role: "tab", tabIndex: selected ? undefined : -1, "aria-selected": selected, id: tabId, __experimentalIsFocusable: true }, rest), children); }; /** * TabPanel is an ARIA-compliant tabpanel. * * TabPanels organize content across different screens, data sets, and interactions. * It has two sections: a list of tabs, and the view to show when tabs are chosen. * * ```jsx * import { TabPanel } from '@wordpress/components'; * * const onSelect = ( tabName ) => { * console.log( 'Selecting tab', tabName ); * }; * * const MyTabPanel = () => ( * <TabPanel * className="my-tab-panel" * activeClass="active-tab" * onSelect={ onSelect } * tabs={ [ * { * name: 'tab1', * title: 'Tab 1', * className: 'tab-one', * }, * { * name: 'tab2', * title: 'Tab 2', * className: 'tab-two', * }, * ] } * > * { ( tab ) => <p>{ tab.title }</p> } * </TabPanel> * ); * ``` */ export function TabPanel(_ref2) { var _selectedTab$name; let { className, children, tabs, selectOnMove = true, initialTabName, orientation = 'horizontal', activeClass = 'is-active', onSelect } = _ref2; const instanceId = useInstanceId(TabPanel, 'tab-panel'); const [selected, setSelected] = useState(); const handleTabSelection = useCallback(tabKey => { setSelected(tabKey); onSelect === null || onSelect === void 0 ? void 0 : onSelect(tabKey); }, [onSelect]); // Simulate a click on the newly focused tab, which causes the component // to show the `tab-panel` associated with the clicked tab. const activateTabAutomatically = (_childIndex, child) => { child.click(); }; const selectedTab = tabs.find(_ref3 => { let { name } = _ref3; return name === selected; }); const selectedId = `${instanceId}-${(_selectedTab$name = selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.name) !== null && _selectedTab$name !== void 0 ? _selectedTab$name : 'none'}`; // Handle selecting the initial tab. useLayoutEffect(() => { // If there's a selected tab, don't override it. if (selectedTab) { return; } const initialTab = tabs.find(tab => tab.name === initialTabName); // Wait for the denoted initial tab to be declared before making a // selection. This ensures that if a tab is declared lazily it can // still receive initial selection. if (initialTabName && !initialTab) { return; } if (initialTab && !initialTab.disabled) { // Select the initial tab if it's not disabled. handleTabSelection(initialTab.name); } else { // Fallback to the first enabled tab when the initial is disabled. const firstEnabledTab = tabs.find(tab => !tab.disabled); if (firstEnabledTab) handleTabSelection(firstEnabledTab.name); } }, [tabs, selectedTab, initialTabName, handleTabSelection]); // Handle the currently selected tab becoming disabled. useEffect(() => { // This effect only runs when the selected tab is defined and becomes disabled. if (!(selectedTab !== null && selectedTab !== void 0 && selectedTab.disabled)) { return; } const firstEnabledTab = tabs.find(tab => !tab.disabled); // If the currently selected tab becomes disabled, select the first enabled tab. // (if there is one). if (firstEnabledTab) { handleTabSelection(firstEnabledTab.name); } }, [tabs, selectedTab === null || selectedTab === void 0 ? void 0 : selectedTab.disabled, handleTabSelection]); return createElement("div", { className: className }, createElement(NavigableMenu, { role: "tablist", orientation: orientation, onNavigate: selectOnMove ? activateTabAutomatically : undefined, className: "components-tab-panel__tabs" }, tabs.map(tab => createElement(TabButton, { className: classnames('components-tab-panel__tabs-item', tab.className, { [activeClass]: tab.name === selected }), tabId: `${instanceId}-${tab.name}`, "aria-controls": `${instanceId}-${tab.name}-view`, selected: tab.name === selected, key: tab.name, onClick: () => handleTabSelection(tab.name), disabled: tab.disabled, label: tab.icon && tab.title, icon: tab.icon, showTooltip: !!tab.icon }, !tab.icon && tab.title))), selectedTab && createElement("div", { key: selectedId, "aria-labelledby": selectedId, role: "tabpanel", id: `${selectedId}-view`, className: "components-tab-panel__tab-content" }, children(selectedTab))); } export default TabPanel; //# sourceMappingURL=index.js.map