UNPKG

@enact/sandstone

Version:

Large-screen/TV support library for Enact, containing a variety of UI components.

363 lines (358 loc) 14.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.ItemDecorator = exports.ItemBase = exports.Item = void 0; var _classnames = _interopRequireDefault(require("classnames")); var _propTypes = _interopRequireDefault(require("@enact/core/internal/prop-types")); var _kind = _interopRequireDefault(require("@enact/core/kind")); var _Spottable = _interopRequireDefault(require("@enact/spotlight/Spottable")); var _Slottable = _interopRequireDefault(require("@enact/ui/Slottable")); var _Item = require("@enact/ui/Item"); var _Layout = require("@enact/ui/Layout"); var _Measurable = require("@enact/ui/Measurable"); var _Pure = _interopRequireDefault(require("@enact/ui/internal/Pure")); var _compose = _interopRequireDefault(require("ramda/src/compose")); var _propTypes2 = _interopRequireDefault(require("prop-types")); var _Marquee = require("../Marquee"); var _Skinnable = _interopRequireDefault(require("../Skinnable")); var _ItemModule = _interopRequireDefault(require("./Item.module.css")); var _jsxRuntime = require("react/jsx-runtime"); var _excluded = ["componentRef", "content", "contentSize", "css", "label", "labelPosition", "marqueeOn"], _excluded2 = ["centered", "children", "componentRef", "contentRef", "contentSize", "css", "inline", "label", "labelPosition", "marqueeOn", "slotAfter", "slotBefore"]; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 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; } 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 _objectDestructuringEmpty(obj) { if (obj == null) throw new TypeError("Cannot destructure " + obj); } /** * Provides Sandstone styled item components and behaviors. Useful for content in lists. * * @example * <Item>Hello Enact!</Item> * * @module sandstone/Item * @exports Item * @exports ItemBase * @exports ItemDecorator */ var MarqueeBase = function MarqueeBase(_ref) { var rest = Object.assign({}, (_objectDestructuringEmpty(_ref), _ref)); // eslint-disable-next-line enact/prop-types delete rest.contentSize; return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", _objectSpread({}, rest)); }; var Marquee = (0, _Marquee.MarqueeDecorator)({ invalidateProps: ['remeasure', 'contentSize'] }, MarqueeBase); // eslint-disable-next-line enact/prop-types var ItemContent = function ItemContent(_ref2) { var componentRef = _ref2.componentRef, content = _ref2.content, contentSize = _ref2.contentSize, css = _ref2.css, label = _ref2.label, labelPosition = _ref2.labelPosition, marqueeOn = _ref2.marqueeOn, rest = _objectWithoutProperties(_ref2, _excluded); var LabelPositionClassname = _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, css.labelAbove, labelPosition === 'above'), css.labelAfter, labelPosition === 'after'), css.labelBefore, labelPosition === 'before'), css.labelBelow, labelPosition === 'below'); var orientation = labelPosition === 'above' || labelPosition === 'below' ? 'vertical' : 'horizontal'; var itemContentClasses = (0, _classnames["default"])(css.itemContent, LabelPositionClassname); var marqueeProps = { contentSize: contentSize, marqueeOn: marqueeOn }; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, _objectSpread(_objectSpread({}, rest), {}, { ref: componentRef, className: itemContentClasses, children: !label ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, _objectSpread(_objectSpread({ component: Marquee, className: css.content }, marqueeProps), {}, { children: content })) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Layout.Layout, { orientation: orientation, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, _objectSpread(_objectSpread({ component: Marquee, className: css.content }, marqueeProps), {}, { shrink: true, children: content })), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, _objectSpread(_objectSpread({ component: Marquee, className: css.label }, marqueeProps), {}, { shrink: true, children: label }))] }) })); }; ItemContent.displayName = 'ItemContent'; ItemContent.propTypes = { componentRef: _propTypes["default"].ref, content: _propTypes2["default"].any, css: _propTypes2["default"].object, label: _propTypes2["default"].any, labelPosition: _propTypes2["default"].any }; /** * A Sandstone styled item without any behavior. * * @class ItemBase * @memberof sandstone/Item * @extends ui/Item.ItemBase * @ui * @public */ var ItemBase = exports.ItemBase = (0, _kind["default"])({ name: 'Item', propTypes: /** @lends sandstone/Item.ItemBase.prototype */{ /** * Centers the slots and content. * * @type {Boolean} * @public */ centered: _propTypes2["default"].bool, /** * Called with a reference to the root component. * * @type {Object|Function} * @public */ componentRef: _propTypes["default"].ref, /** * The method which receives the reference node to the content element, used to determine * the `contentSize`. * * @type {Function|Object} * @private */ contentRef: _propTypes["default"].ref, /** * The size for content. * This size is set by ItemMeasurementDecorator for invalidating Marquee. * * @type {Number} * @private */ contentSize: _propTypes2["default"].number, /** * Customizes the component by mapping the supplied collection of CSS class names to the * corresponding internal elements and states of this component. * * The following classes are supported: * * * `item` - The root class name * * `slotBefore` - The slot (container) preceding the text of this component * * `slotAfter` - The slot (container) following the text of this component * * `selected` - Applied to a `selected` button * * @type {Object} * @public */ css: _propTypes2["default"].object, /** * Applies a disabled style and the control becomes non-interactive. * * @type {Boolean} * @public */ disabled: _propTypes2["default"].bool, /** * Applies inline styling to the item. * * @type {Boolean} * @public */ inline: _propTypes2["default"].bool, /** * The label to be displayed along with the text. * * @type {Node} * @public */ label: _propTypes2["default"].node, /** * The position of the label relative to the primary content, `children`. * * @type {('above'|'after'|'before'|'below')} * @public */ labelPosition: _propTypes2["default"].oneOf(['above', 'after', 'before', 'below']), /** * Determines what triggers the marquee to start its animation. * * @type {('focus'|'hover'|'render')} * @public */ marqueeOn: _propTypes2["default"].oneOf(['focus', 'hover', 'render']), /** * Applies a selected style to the component. * * @type {Boolean} * @private */ selected: _propTypes2["default"].bool, /** * The size of the item. * * @type {('large'|'small')} * @default 'large' * @private */ size: _propTypes2["default"].oneOf(['large', 'small']), /** * Nodes to be inserted after `children`. * * For LTR locales, the nodes are inserted to the right of the primary content. For RTL * locales, the nodes are inserted to the left. If nothing is specified, nothing, not even * an empty container, is rendered in this place. * * @type {Node} * @public */ slotAfter: _propTypes2["default"].node, /** * Nodes to be inserted before `children` and `label`. * * For LTR locales, the nodes are inserted to the left of the primary content. For RTL * locales, the nodes are inserted to the right. If nothing is specified, nothing, not even * an empty container, is rendered in this place. * * @type {Node} * @public */ slotBefore: _propTypes2["default"].node }, defaultProps: { labelPosition: 'below', size: 'large' }, styles: { css: _ItemModule["default"], publicClassNames: ['item', 'itemContent', 'content', 'label', 'bg', 'slotAfter', 'slotBefore', 'selected'] }, computed: { className: function className(_ref3) { var centered = _ref3.centered, label = _ref3.label, selected = _ref3.selected, size = _ref3.size, styler = _ref3.styler; return styler.append({ centered: centered, selected: selected, hasLabel: label != null }, size); }, label: function label(_ref4) { var _label = _ref4.label; return typeof _label === 'number' ? _label.toString() : _label; } }, render: function render(_ref5) { var centered = _ref5.centered, children = _ref5.children, componentRef = _ref5.componentRef, contentRef = _ref5.contentRef, contentSize = _ref5.contentSize, css = _ref5.css, inline = _ref5.inline, label = _ref5.label, labelPosition = _ref5.labelPosition, marqueeOn = _ref5.marqueeOn, slotAfter = _ref5.slotAfter, slotBefore = _ref5.slotBefore, rest = _objectWithoutProperties(_ref5, _excluded2); delete rest.size; var keys = Object.keys(rest); var voiceProps = !keys.includes('data-webos-voice-label') && !keys.includes('data-webos-voice-labels') && label && typeof label === 'string' && children && children[0] && typeof children[0] === 'string' ? { 'data-webos-voice-labels': JSON.stringify([label, children[0]]) } : {}; return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Item.ItemBase, _objectSpread(_objectSpread(_objectSpread({ "data-webos-voice-intent": "Select", component: _Layout.Row, align: centered ? 'center center' : 'center', ref: componentRef }, voiceProps), rest), {}, { inline: inline, css: css, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", { className: css.bg }), slotBefore ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, { className: css.slotBefore, shrink: true, children: slotBefore }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(ItemContent, { componentRef: contentRef, content: children, contentSize: contentSize, css: css, label: label, labelPosition: labelPosition, marqueeOn: marqueeOn, shrink: inline }), slotAfter ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, { className: css.slotAfter, shrink: true, children: slotAfter }) : null] })); } }); var ItemMeasurementDecorator = function ItemMeasurementDecorator(Wrapped) { return function ItemMeasurementDecorator(props) { // eslint-disable-line no-shadow var _useMeasurable = (0, _Measurable.useMeasurable)(), contentRef = _useMeasurable.ref, _useMeasurable$measur = _useMeasurable.measurement, _useMeasurable$measur2 = _useMeasurable$measur === void 0 ? {} : _useMeasurable$measur, _useMeasurable$measur3 = _useMeasurable$measur2.width, contentWidth = _useMeasurable$measur3 === void 0 ? 0 : _useMeasurable$measur3; var measurableProps = { contentRef: contentRef, contentSize: contentWidth }; return /*#__PURE__*/(0, _jsxRuntime.jsx)(Wrapped, _objectSpread(_objectSpread({}, props), measurableProps)); }; }; /** * Sandstone specific item behaviors to apply to {@link sandstone/Item.ItemBase|Item}. * * @class ItemDecorator * @hoc * @memberof sandstone/Item * @mixes ui/Item.ItemDecorator * @mixes ui/Slottable.Slottable * @mixes spotlight/Spottable.Spottable * @mixes sandstone/Marquee.MarqueeController * @mixes sandstone/Skinnable.Skinnable * @public */ var ItemDecorator = exports.ItemDecorator = (0, _compose["default"])(_Item.ItemDecorator, (0, _Slottable["default"])({ slots: ['label', 'slotAfter', 'slotBefore'] }), _Spottable["default"], (0, _Marquee.MarqueeController)({ marqueeOnFocus: true }), ItemMeasurementDecorator, _Skinnable["default"]); /** * A Sandstone styled item with built-in support for marqueed text, and Spotlight focus. * * Usage: * ``` * <Item>Item Content</Item> * ``` * * @class Item * @memberof sandstone/Item * @extends sandstone/Item.ItemBase * @mixes sandstone/Item.ItemDecorator * @ui * @public */ var Item = exports.Item = (0, _Pure["default"])(ItemDecorator(ItemBase)); var _default = exports["default"] = Item;