@enact/sandstone
Version:
Large-screen/TV support library for Enact, containing a variety of UI components.
346 lines (341 loc) • 15.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.TabGroup = void 0;
var _handle = _interopRequireWildcard(require("@enact/core/handle"));
var _kind = _interopRequireDefault(require("@enact/core/kind"));
var _spotlight = _interopRequireDefault(require("@enact/spotlight"));
var _SpotlightContainerDecorator = _interopRequireDefault(require("@enact/spotlight/SpotlightContainerDecorator"));
var _Group = _interopRequireDefault(require("@enact/ui/Group"));
var _IdProvider = _interopRequireDefault(require("@enact/ui/internal/IdProvider"));
var _Layout = require("@enact/ui/Layout");
var _Toggleable = _interopRequireDefault(require("@enact/ui/Toggleable"));
var _IString = _interopRequireDefault(require("ilib/lib/IString"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _compose = _interopRequireDefault(require("ramda/src/compose"));
var _react = require("react");
var _$L = _interopRequireDefault(require("../internal/$L"));
var _DebounceDecorator = _interopRequireDefault(require("../internal/DebounceDecorator"));
var _Button = _interopRequireDefault(require("../Button"));
var _Skinnable = _interopRequireDefault(require("../Skinnable"));
var _Scroller = _interopRequireDefault(require("../Scroller"));
var _Sprite = _interopRequireDefault(require("../Sprite"));
var _TabGroupModule = _interopRequireDefault(require("./TabGroup.module.css"));
var _jsxRuntime = require("react/jsx-runtime");
var _excluded = ["buttonSize"],
_excluded2 = ["children", "collapsed", "css", "orientation", "size"],
_excluded3 = ["css", "collapsed", "id", "noIcons", "onBlur", "onBlurList", "onFocus", "onFocusTab", "onSelect", "orientation", "selectedIndex", "spotlightId", "spotlightDisabled", "tabs", "tabSize", "tabsDisabled", "tabsSpotlightDisabled"],
_excluded4 = ["icon", "title", "tabKey", "sprite"];
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
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; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
var MAX_TABS_BEFORE_SCROLLING = 7;
// Since Button and Cell both have a `size` prop, TabButton is required to relay the Button.size to Button, rather than Cell.
// eslint-disable-next-line enact/prop-types
var TabButton = function TabButton(_ref) {
var buttonSize = _ref.buttonSize,
rest = _objectWithoutProperties(_ref, _excluded);
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], _objectSpread(_objectSpread({
size: buttonSize
}, rest), {}, {
css: _TabGroupModule["default"]
}));
};
var TabBase = (0, _kind["default"])({
name: 'Tab',
propTypes: {
collapsed: _propTypes["default"].bool,
css: _propTypes["default"].object,
icon: _propTypes["default"].string,
index: _propTypes["default"].number,
onFocusTab: _propTypes["default"].func,
onTabClick: _propTypes["default"].func,
orientation: _propTypes["default"].string,
selected: _propTypes["default"].bool,
size: _propTypes["default"].number,
sprite: _propTypes["default"].object,
stopped: _propTypes["default"].bool
},
defaultProps: {
orientation: 'vertical'
},
styles: {
css: _TabGroupModule["default"],
className: 'tab',
publicClassNames: ['bg', 'button', 'client', 'selected', 'tab', 'vertical']
},
handlers: {
onClick: (0, _handle["default"])((0, _handle.forward)('onClick'), (0, _handle.not)((0, _handle.forProp)('disabled', true)), (0, _handle.forwardCustom)('onTabClick', function (ev, _ref2) {
var index = _ref2.index;
return {
selected: index
};
})),
onFocus: (0, _handle["default"])((0, _handle.forward)('onFocus'), (0, _handle.not)((0, _handle.forProp)('disabled', true)), function () {
return !_spotlight["default"].getPointerMode();
}, (0, _handle.forwardCustom)('onFocusTab', function (ev, _ref3) {
var index = _ref3.index;
return {
selected: index
};
}))
},
computed: {
className: function className(_ref4) {
var collapsed = _ref4.collapsed,
orientation = _ref4.orientation,
styler = _ref4.styler;
return styler.append({
collapsed: collapsed
}, orientation);
},
iconComponent: function iconComponent(_ref5) {
var sprite = _ref5.sprite,
stopped = _ref5.stopped;
if (sprite) {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Sprite["default"], _objectSpread({
stopped: stopped
}, sprite));
}
}
},
render: function render(_ref6) {
var children = _ref6.children,
collapsed = _ref6.collapsed,
css = _ref6.css,
orientation = _ref6.orientation,
size = _ref6.size,
rest = _objectWithoutProperties(_ref6, _excluded2);
delete rest.index;
delete rest.onFocusTab;
delete rest.onTabClick;
delete rest.stopped;
delete rest.sprite;
if (collapsed) children = null;
var commonProps = {
backgroundOpacity: 'transparent',
children: children,
collapsable: true,
css: css,
focusEffect: 'static',
minWidth: false,
role: 'tab'
};
switch (orientation) {
// Horizontal Cell sizing can auto-size width or be set to a finite value, stretching the Button.
case 'horizontal':
{
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, _objectSpread(_objectSpread({}, rest), {}, {
size: size,
component: TabButton
}, commonProps));
}
case 'vertical':
{
// Vertical sizing depends on Button establishing the dimensions of the Cell.
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], _objectSpread(_objectSpread({}, rest), commonProps));
}
}
}
});
var Tab = (0, _Toggleable["default"])({
prop: 'stopped',
activate: 'onBlur',
deactivate: 'onFocus'
}, (0, _Skinnable["default"])(TabBase));
var GroupComponent = (0, _SpotlightContainerDecorator["default"])({
// using default-element so we always land on the selected tab in order to avoid changing
// the view when re-entering the tab group
defaultElement: ".".concat(_TabGroupModule["default"].selected),
enterTo: 'default-element',
partition: true,
// When swapping from unscrolled to scrolled tab group, the container config is lost so this
// preserves it across unmounts / remounts
preserveId: true
}, _Group["default"]);
/**
* A group of tabs
*
* @class TabGroup
* @memberof sandstone/TabLayout
* @ui
* @private
*/
var TabGroupBase = (0, _kind["default"])({
name: 'TabGroup',
functional: true,
propTypes: /** @lends sandstone/TabGroup.TabGroup.prototype */{
tabs: _propTypes["default"].array.isRequired,
collapsed: _propTypes["default"].bool,
css: _propTypes["default"].object,
id: _propTypes["default"].string,
onBlur: _propTypes["default"].func,
onBlurList: _propTypes["default"].func,
onFocus: _propTypes["default"].func,
onFocusTab: _propTypes["default"].func,
onSelect: _propTypes["default"].func,
orientation: _propTypes["default"].string,
selectedIndex: _propTypes["default"].number,
spotlightDisabled: _propTypes["default"].bool,
spotlightId: _propTypes["default"].string,
tabSize: _propTypes["default"].number
},
styles: {
css: _TabGroupModule["default"],
className: 'tabGroup',
publicClassNames: ['bg', 'button', 'client', 'selected', 'tab', 'tabGroup', 'vertical']
},
computed: {
className: function className(_ref7) {
var collapsed = _ref7.collapsed,
orientation = _ref7.orientation,
styler = _ref7.styler;
return styler.append({
collapsed: collapsed
}, orientation);
},
// check if there's no tab icons
noIcons: function noIcons(_ref8) {
var collapsed = _ref8.collapsed,
orientation = _ref8.orientation,
tabs = _ref8.tabs;
return orientation === 'vertical' && collapsed && tabs.filter(function (tab) {
return !tab.icon && !tab.sprite;
}).length;
},
tabsDisabled: function tabsDisabled(_ref9) {
var tabs = _ref9.tabs;
return tabs.find(function (tab) {
return tab && !tab.disabled;
}) == null;
},
tabsSpotlightDisabled: function tabsSpotlightDisabled(_ref10) {
var spotlightDisabled = _ref10.spotlightDisabled,
tabs = _ref10.tabs;
return spotlightDisabled || tabs.find(function (tab) {
return tab && !tab.spotlightDisabled;
}) == null;
}
},
render: function render(_ref11) {
var css = _ref11.css,
collapsed = _ref11.collapsed,
id = _ref11.id,
noIcons = _ref11.noIcons,
onBlur = _ref11.onBlur,
onBlurList = _ref11.onBlurList,
onFocus = _ref11.onFocus,
onFocusTab = _ref11.onFocusTab,
onSelect = _ref11.onSelect,
orientation = _ref11.orientation,
selectedIndex = _ref11.selectedIndex,
spotlightId = _ref11.spotlightId,
spotlightDisabled = _ref11.spotlightDisabled,
tabs = _ref11.tabs,
tabSize = _ref11.tabSize,
tabsDisabled = _ref11.tabsDisabled,
tabsSpotlightDisabled = _ref11.tabsSpotlightDisabled,
rest = _objectWithoutProperties(_ref11, _excluded3);
delete rest.children;
// eslint-disable-next-line react-hooks/rules-of-hooks
var itemProps = (0, _react.useMemo)(function () {
return {
css: css,
collapsed: collapsed,
orientation: orientation,
size: tabSize
};
}, [css, collapsed, orientation, tabSize]);
// eslint-disable-next-line react-hooks/rules-of-hooks
var children = (0, _react.useMemo)(function () {
return tabs.map(function (tab) {
if (tab) {
// eslint-disable-next-line no-shadow
var icon = tab.icon,
title = tab.title,
tabKey = tab.tabKey,
sprite = tab.sprite,
_rest = _objectWithoutProperties(tab, _excluded4);
var key = tabKey || tabKey === 0 ? tabKey : "tabs_".concat(title + (typeof icon === 'string' ? icon : ''));
return _objectSpread({
children: title,
defaultStopped: Boolean(sprite),
icon: icon,
key: key,
onFocusTab: onFocusTab,
sprite: sprite
}, _rest);
} else {
return null;
}
}).filter(function (tab) {
return tab != null;
});
}, [onFocusTab, tabs]);
var isHorizontal = orientation === 'horizontal';
var groupComponent = isHorizontal ? _Layout.Layout : 'div'; // Only horizontal needs the arrangement capabilities of `Layout`
// Only vertical with more than MAX_TABS should use scroller
var useScroller = !isHorizontal && children.length > MAX_TABS_BEFORE_SCROLLING;
var scrollerProps = useScroller ? {
horizontalScrollbar: 'hidden',
verticalScrollbar: 'hidden'
} : null;
var Component = useScroller ? _Scroller["default"] : 'div';
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Component, _objectSpread(_objectSpread(_objectSpread({}, rest), {}, {
onBlur: onBlur,
onFocus: onFocus
}, scrollerProps), {}, {
children: [noIcons ? /*#__PURE__*/(0, _jsxRuntime.jsx)(TabBase, {
icon: "list",
collapsed: true,
disabled: tabsDisabled,
onSpotlightDisappear: onBlurList,
spotlightDisabled: tabsSpotlightDisabled
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
role: "region",
"aria-labelledby": "".concat(id, "_tabgroup"),
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(GroupComponent, {
id: "".concat(id, "_tabgroup"),
childComponent: Tab,
"aria-label": "".concat(new _IString["default"]((0, _$L["default"])('{total} items in total')).format({
'total': tabs.length
})),
className: _TabGroupModule["default"].tabs,
component: groupComponent,
indexProp: "index",
itemProps: itemProps,
onSelect: onSelect,
orientation: orientation,
role: "tablist",
select: "radio",
selected: selectedIndex,
selectedProp: "selected",
spotlightId: spotlightId,
spotlightDisabled: spotlightDisabled,
children: children
})
}), isHorizontal ? /*#__PURE__*/(0, _jsxRuntime.jsx)("hr", {
className: _TabGroupModule["default"].horizontalLine
}) : null]
}));
}
});
var TabGroupDecorator = (0, _compose["default"])((0, _DebounceDecorator["default"])({
cancel: 'onBlur',
debounce: 'onFocusTab',
delay: 300
}), (0, _IdProvider["default"])({
generateProp: null,
prefix: 'tg_'
}));
// Only documenting TabGroup since base is not useful for extension as-is
var TabGroup = exports.TabGroup = TabGroupDecorator(TabGroupBase);
var _default = exports["default"] = TabGroup;