react-lightning-design-system
Version:
Salesforce Lightning Design System components built with React
314 lines (295 loc) • 11.6 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["className", "active", "children"],
_excluded2 = ["icon", "children"],
_excluded3 = ["tabItemRenderer", "rendererProps"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import React, { createContext, useId, useContext, useMemo, useRef, useState, useEffect } from 'react';
import classnames from 'classnames';
import { registerStyle } from './util';
import { DropdownButton } from './DropdownButton';
import { useControlledValue, useEventCallback } from './hooks';
import { TooltipContent } from './TooltipContent';
/**
*
*/
/**
*
*/
var TabsHandlersContext = /*#__PURE__*/createContext({});
/**
*
*/
var TabsActiveKeyContext = /*#__PURE__*/createContext(undefined);
/**
*
*/
var TabsContext = /*#__PURE__*/createContext({
type: 'default'
});
/**
* Custom hook to generate unique tab IDs
*/
var useTabIds = function useTabIds(eventKey) {
var _useContext = useContext(TabsContext),
tabIdPrefix = _useContext.tabIdPrefix;
var tabIndex = eventKey ? String(eventKey) : '0';
var tabId = "".concat(tabIdPrefix, "-").concat(tabIndex);
return {
tabId: tabId
};
};
/**
*
*/
/**
*
*/
var TabContent = function TabContent(props) {
var className = props.className,
active = props.active,
children = props.children,
rprops = _objectWithoutProperties(props, _excluded);
var _useContext2 = useContext(TabsContext),
type = _useContext2.type;
var tabClassNames = classnames(className, "slds-tabs_".concat(type, "__content"), "slds-".concat(active ? 'show' : 'hide'));
return /*#__PURE__*/React.createElement("div", _extends({
className: tabClassNames,
role: "tabpanel"
}, rprops), children);
};
/**
*
*/
/**
*
*/
var TabMenu = function TabMenu(props) {
var _props$icon = props.icon,
icon = _props$icon === void 0 ? 'down' : _props$icon,
children = props.children,
rprops = _objectWithoutProperties(props, _excluded2);
return /*#__PURE__*/React.createElement(DropdownButton, _extends({}, rprops, {
className: "react-slds-tab-menu",
icon: icon,
type: "icon",
iconSize: "small",
tabIndex: -1,
nubbinTop: true
}), children);
};
/**
*
*/
var DefaultTabItemRenderer = function DefaultTabItemRenderer(props) {
var el = React.Children.only(props.children);
return /*#__PURE__*/React.isValidElement(el) ? el : /*#__PURE__*/React.createElement(React.Fragment, null, el);
};
/**
*
*/
/**
*
*/
var TabItem = function TabItem(props) {
var _ref;
var title = props.title,
alt = props.alt,
eventKey = props.eventKey,
menu = props.menu,
menuIcon = props.menuIcon,
tooltip = props.tooltip,
tooltipIcon = props.tooltipIcon;
var _useContext3 = useContext(TabsContext),
type = _useContext3.type,
activeTabRef = _useContext3.activeTabRef;
var activeKey = useContext(TabsActiveKeyContext);
var _useContext4 = useContext(TabsHandlersContext),
onTabClick = _useContext4.onTabClick,
onTabKeyDown = _useContext4.onTabKeyDown;
var _useTabIds = useTabIds(eventKey),
tabId = _useTabIds.tabId;
var menuItems = props.menuItems;
menuItems = menu ? React.Children.toArray(menu.props.children || []).map(function (el) {
return /*#__PURE__*/React.isValidElement(el) ? el : /*#__PURE__*/React.createElement(React.Fragment, null, el);
}) : menuItems;
var menuProps = (_ref = menu === null || menu === void 0 ? void 0 : menu.props) !== null && _ref !== void 0 ? _ref : {};
var isActive = eventKey === activeKey;
var tabItemClassName = classnames('react-slds-tab-item', "slds-tabs_".concat(type, "__item"), {
'slds-is-active': isActive
}, {
'react-slds-tab-with-menu': menu || menuItems
});
var tabLinkClassName = "slds-tabs_".concat(type, "__link");
var _props$tabItemRendere = props.tabItemRenderer,
TabItemRenderer = _props$tabItemRendere === void 0 ? DefaultTabItemRenderer : _props$tabItemRendere,
rendererProps = props.rendererProps,
rprops = _objectWithoutProperties(props, _excluded3);
var itemRendererProps = _objectSpread(_objectSpread(_objectSpread({}, rendererProps), rprops), {}, {
type: type,
activeKey: activeKey,
activeTabRef: activeTabRef,
onTabClick: onTabClick,
onTabKeyDown: onTabKeyDown
});
return /*#__PURE__*/React.createElement("li", {
className: tabItemClassName,
title: alt,
role: "presentation"
}, /*#__PURE__*/React.createElement(TabItemRenderer, itemRendererProps, /*#__PURE__*/React.createElement("span", {
className: "react-slds-tab-item-content ".concat(tooltip ? 'react-slds-tooltip-enabled' : '')
}, /*#__PURE__*/React.createElement("a", {
className: tabLinkClassName,
role: "tab",
ref: isActive ? activeTabRef : undefined,
tabIndex: isActive ? 0 : -1,
"aria-selected": isActive,
"aria-controls": tabId,
onClick: eventKey != null ? function () {
return onTabClick === null || onTabClick === void 0 ? void 0 : onTabClick(eventKey);
} : undefined,
onKeyDown: eventKey != null ? function (e) {
return onTabKeyDown === null || onTabKeyDown === void 0 ? void 0 : onTabKeyDown(eventKey, e);
} : undefined
}, title), tooltip ? /*#__PURE__*/React.createElement(TooltipContent, {
icon: tooltipIcon
}, tooltip) : null, menuItems ? /*#__PURE__*/React.createElement(TabMenu, _extends({
icon: menuIcon
}, menuProps), menuItems) : undefined)));
};
/**
*
*/
var TabNav = function TabNav(props) {
var children = props.children;
var _useContext5 = useContext(TabsContext),
type = _useContext5.type;
var tabNavClassName = "slds-tabs_".concat(type, "__nav");
return /*#__PURE__*/React.createElement("ul", {
className: tabNavClassName,
role: "tablist"
}, React.Children.map(children, function (tab) {
if (! /*#__PURE__*/React.isValidElement(tab)) {
return null;
}
return /*#__PURE__*/React.createElement(TabItem, tab.props);
}));
};
/**
*
*/
export var Tab = function Tab(props) {
var className = props.className,
eventKey = props.eventKey,
children = props.children;
var activeKey = useContext(TabsActiveKeyContext);
var _useTabIds2 = useTabIds(eventKey),
tabId = _useTabIds2.tabId;
return /*#__PURE__*/React.createElement(TabContent, {
id: tabId,
className: className,
active: eventKey != null && eventKey === activeKey
}, children);
};
/**
*
*/
/**
*
*/
function useInitComponentStyle() {
useEffect(function () {
registerStyle('tab-menu', [['.react-slds-tab-item.react-slds-tab-with-menu', '{ position: relative !important; overflow: visible !important; }'], ['.react-slds-tab-item.react-slds-tab-with-menu > .react-slds-tab-item-content', '{ overflow: hidden }'], ['.react-slds-tab-item.react-slds-tab-with-menu > .react-slds-tab-item-content > a', '{ padding-right: 2rem; }'], ['.react-slds-tab-item.react-slds-tab-with-menu > .react-slds-tab-item-content.react-slds-tooltip-enabled > a', '{ padding-right: 3.5rem; }'], ['.react-slds-tab-menu', '{ position: absolute; top: 0; right: 0; }'], ['.react-slds-tab-item.react-slds-tab-with-menu .react-slds-tab-item-content .react-slds-tooltip-content', '{ position: absolute; top: 0.6rem; right: 2.25rem; }'], ['.react-slds-tab-menu button', '{ height: 2.5rem; line-height: 2rem; width: 2rem; visibility: hidden; justify-content: center }'], ['.react-slds-tab-item.slds-is-active .react-slds-tab-menu button', '.react-slds-tab-item:hover .react-slds-tab-menu button', '.react-slds-tab-item .react-slds-tab-menu button:focus', '{ visibility: visible }']]);
}, []);
}
/**
*
*/
export var Tabs = function Tabs(props) {
var className = props.className,
_props$type = props.type,
type = _props$type === void 0 ? 'default' : _props$type,
activeKey_ = props.activeKey,
defaultActiveKey = props.defaultActiveKey,
children = props.children,
onSelect = props.onSelect;
var tabsClassNames = classnames(className, "slds-tabs_".concat(type));
var activeTabRef = useRef(null);
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
focusTab = _useState2[0],
setFocusTab = _useState2[1];
var _useControlledValue = useControlledValue(activeKey_, defaultActiveKey !== null && defaultActiveKey !== void 0 ? defaultActiveKey : null),
_useControlledValue2 = _slicedToArray(_useControlledValue, 2),
activeKey = _useControlledValue2[0],
setActiveKey = _useControlledValue2[1];
var tabKeys = React.Children.map(children, function (tab) {
if ( /*#__PURE__*/React.isValidElement(tab)) {
var _ref2 = tab.props,
_eventKey = _ref2.eventKey;
return _eventKey;
}
return undefined;
});
useInitComponentStyle();
var onTabClick = useEventCallback(function (tabKey) {
onSelect === null || onSelect === void 0 || onSelect(tabKey);
setActiveKey(tabKey);
setFocusTab(true);
});
var onTabKeyDown = useEventCallback(function (tabKey, e) {
if (e.keyCode === 37 || e.keyCode === 39) {
// left/right cursor key
var idx = tabKeys.findIndex(function (key) {
return key === tabKey;
});
if (idx < 0) {
return;
}
var dir = e.keyCode === 37 ? -1 : 1;
var activeIdx = (idx + dir + tabKeys.length) % tabKeys.length;
var _activeKey = tabKeys[activeIdx];
if (_activeKey) {
onTabClick(_activeKey);
}
e.preventDefault();
e.stopPropagation();
}
});
useEffect(function () {
if (focusTab) {
var _activeTabRef$current;
(_activeTabRef$current = activeTabRef.current) === null || _activeTabRef$current === void 0 || _activeTabRef$current.focus();
setFocusTab(false);
}
}, [focusTab]);
var tabIdPrefix = useId();
var tabItemIdPrefix = useId();
var tabCtx = useMemo(function () {
return {
type: type,
activeTabRef: activeTabRef,
tabIdPrefix: tabIdPrefix,
tabItemIdPrefix: tabItemIdPrefix
};
}, [type, tabIdPrefix, tabItemIdPrefix]);
var handlers = useMemo(function () {
return {
onTabClick: onTabClick,
onTabKeyDown: onTabKeyDown
};
}, [onTabClick, onTabKeyDown]);
return /*#__PURE__*/React.createElement(TabsContext.Provider, {
value: tabCtx
}, /*#__PURE__*/React.createElement(TabsActiveKeyContext.Provider, {
value: activeKey !== null && activeKey !== void 0 ? activeKey : undefined
}, /*#__PURE__*/React.createElement(TabsHandlersContext.Provider, {
value: handlers
}, /*#__PURE__*/React.createElement("div", {
className: tabsClassNames
}, /*#__PURE__*/React.createElement(TabNav, null, children), children))));
};
//# sourceMappingURL=Tabs.js.map