UNPKG

@enact/sandstone

Version:

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

326 lines (322 loc) 12.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.ButtonDecorator = exports.ButtonBase = exports.Button = void 0; var _hoc = _interopRequireDefault(require("@enact/core/hoc")); var _kind = _interopRequireDefault(require("@enact/core/kind")); var _util = require("@enact/core/util"); var _propTypes = _interopRequireDefault(require("@enact/core/internal/prop-types")); var _Spottable = _interopRequireDefault(require("@enact/spotlight/Spottable")); var _Button = require("@enact/ui/Button"); var _Pure = _interopRequireDefault(require("@enact/ui/internal/Pure")); var _propTypes2 = _interopRequireDefault(require("prop-types")); var _compose = _interopRequireDefault(require("ramda/src/compose")); var _react = require("react"); var _Icon = _interopRequireDefault(require("../Icon")); var _Marquee = require("../Marquee"); var _Skinnable = _interopRequireDefault(require("../Skinnable")); var _TooltipDecorator = _interopRequireDefault(require("../TooltipDecorator")); var _ButtonModule = _interopRequireDefault(require("./Button.module.css")); var _jsxRuntime = require("react/jsx-runtime"); var _excluded = ["css"]; /** * Sandstone styled button components and behaviors. * * @example * <Button>Hello Enact!</Button> * * @module sandstone/Button * @exports Button * @exports ButtonBase * @exports ButtonDecorator */ /** * A button component. * * This component is most often not used directly but may be composed within another component as it * is within {@link sandstone/Button.Button|Button}. * * @class ButtonBase * @memberof sandstone/Button * @extends ui/Button.ButtonBase * @ui * @public */ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 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 ButtonBase = exports.ButtonBase = (0, _kind["default"])({ name: 'Button', propTypes: /** @lends sandstone/Button.ButtonBase.prototype */{ /** * The background opacity of this button. * * Text buttons and icon+text buttons, by default are opaque, while icon-only buttons * default to transparent. This value can be overridden by setting this prop. * * Valid values are: `'opaque'`, and `'transparent'`. * * @type {('opaque'|'transparent')} * @default 'opaque' * @public */ backgroundOpacity: _propTypes2["default"].oneOf(['opaque', 'transparent']), /** * Enables the `collapsed` feature. * * This requires that both the text and {@link ui/Button.ButtonBase.icon|icon} are * defined. * * Use {@link sandstone/Button.ButtonBase.collapsed|collapsed} to toggle the collapsed state. * * @type {Boolean} * @default false * @see {@link sandstone/Button.ButtonBase.collapsed} * @private */ collapsable: _propTypes2["default"].bool, /** * Toggles the collapsed state of this button, down to just its icon. * * This requires that {@link sandstone/Button.ButtonBase.collapsable|collapsable} is enabled * and both the text and {@link ui/Button.ButtonBase.icon|icon} are defined. * * @type {Boolean} * @default false * @see {@link sandstone/Button.ButtonBase.collapsable} * @private */ collapsed: _propTypes2["default"].bool, /** * The color of the underline beneath button's content. * * Accepts one of the following color names, which correspond with the colored buttons on a * standard remote control: `'red'`, `'green'`, `'yellow'`, `'blue'`. * * @type {('red'|'green'|'yellow'|'blue')} * @public */ color: _propTypes2["default"].oneOf(['red', 'green', 'yellow', 'blue']), /** * 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: * * * `button` - The root class name * * `bg` - The background node of the button * * `large` - Applied to a `size='large'` button * * `selected` - Applied to a `selected` button * * `small` - Applied to a `size='small'` button * * @type {Object} * @public */ // `client` was intentionally excluded from the above documented exported classes as they do // not appear to provide value to the end-developer, but are needed by PopupTabLayout // internally for its design guidelines. Same for `pressed` which is used by Dropdown to // nullify the key-press activate animation. css: _propTypes2["default"].object, /** * Set the visual effect applied to the button when focused. * * @type {('expand'|'static')} * @default 'expand' * @private */ focusEffect: _propTypes2["default"].oneOf(['expand', 'static']), /** * The component used to render the {@link sandstone/Button.ButtonBase.icon|icon}. * * This component will receive the `icon` class to customize its styling. * * @type {Component|Node} * @private */ iconComponent: _propTypes["default"].componentOverride, /** * True if button is an icon only button. * * @type {Boolean} * @default false * @private */ iconOnly: _propTypes2["default"].bool, /** * Specifies on which side (`'before'` or `'after'`) of the text the icon appears. * * @type {('before'|'after')} * @default 'before' * @public */ iconPosition: _propTypes2["default"].oneOf(['before', 'after']), /** * Boolean controlling whether this component should enforce the "minimum width" rules. * * *NOTE*: If you don't specify this prop, it works as `false` for icon only Button * and as `true` for other Buttons. * * @type {Boolean} * @public */ minWidth: _propTypes2["default"].bool, /** * True if both sides of button are fully rounded. * * @type {Boolean} * @public */ roundBorder: _propTypes2["default"].bool, /** * Adds shadow to the text. * It is only applied when the background opacity of the button is `transparent`. * * @type {Boolean} * @public */ shadowed: _propTypes2["default"].bool, /** * The size of the button. * * @type {('large'|'small')} * @default 'large' * @public */ size: _propTypes2["default"].oneOf(['large', 'small']) }, defaultProps: { backgroundOpacity: null, collapsable: false, collapsed: false, focusEffect: 'expand', iconComponent: _Icon["default"], iconOnly: false, iconPosition: 'before', roundBorder: false, size: 'large' }, styles: { css: _ButtonModule["default"], publicClassNames: ['button', 'bg', 'client', 'hasIcon', 'icon', 'iconAfter', 'iconBefore', 'large', 'pressed', 'selected', 'small'] }, computed: { className: function className(_ref) { var backgroundOpacity = _ref.backgroundOpacity, collapsable = _ref.collapsable, collapsed = _ref.collapsed, color = _ref.color, focusEffect = _ref.focusEffect, iconOnly = _ref.iconOnly, iconPosition = _ref.iconPosition, roundBorder = _ref.roundBorder, shadowed = _ref.shadowed, size = _ref.size, styler = _ref.styler; return styler.append({ hasColor: color, iconOnly: iconOnly, collapsable: collapsable, collapsed: collapsed, roundBorder: roundBorder, shadowed: shadowed && (backgroundOpacity ? backgroundOpacity === 'transparent' : iconOnly) }, backgroundOpacity || (iconOnly ? 'transparent' : 'opaque'), // Defaults to opaque, unless otherwise specified color, "focus".concat((0, _util.cap)(focusEffect)), // iconBefore/iconAfter only applies when using text and an icon !iconOnly && "icon".concat((0, _util.cap)(iconPosition)), size); }, minWidth: function minWidth(_ref2) { var iconOnly = _ref2.iconOnly, _minWidth = _ref2.minWidth; return _minWidth != null ? _minWidth : !iconOnly; } }, render: function render(_ref3) { var css = _ref3.css, rest = _objectWithoutProperties(_ref3, _excluded); delete rest.backgroundOpacity; delete rest.color; delete rest.collapsable; delete rest.collapsed; delete rest.iconOnly; delete rest.iconPosition; delete rest.focusEffect; delete rest.roundBorder; delete rest.shadowed; return _Button.ButtonBase.inline(_objectSpread(_objectSpread({ 'data-webos-voice-intent': 'Select' }, rest), {}, { css: css })); } }); /** * A higher-order component that determines if it is a button that only displays an icon. * * @class IconButtonDecorator * @memberof sandstone/Button * @hoc * @private */ var IconButtonDecorator = (0, _hoc["default"])(function (config, Wrapped) { return (0, _kind["default"])({ name: 'IconButtonDecorator', computed: { iconOnly: function iconOnly(_ref4) { var children = _ref4.children; return _react.Children.toArray(children).filter(Boolean).length === 0; } }, render: function render(props) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(Wrapped, _objectSpread({}, props)); } }); }); /** * Applies Sandstone specific behaviors to {@link sandstone/Button.ButtonBase|Button} components. * * @hoc * @memberof sandstone/Button * @mixes sandstone/TooltipDecorator.TooltipDecorator * @mixes sandstone/Marquee.MarqueeDecorator * @mixes ui/Button.ButtonDecorator * @mixes spotlight/Spottable.Spottable * @mixes sandstone/Skinnable.Skinnable * @public */ var ButtonDecorator = exports.ButtonDecorator = (0, _compose["default"])(_Pure["default"], IconButtonDecorator, (0, _TooltipDecorator["default"])({ tooltipDestinationProp: 'decoration' }), // Future note: This should eventually be conditionally applied via hooks (after refactoring) (0, _Marquee.MarqueeDecorator)({ css: _ButtonModule["default"] }), _Button.ButtonDecorator, _Spottable["default"], _Skinnable["default"]); /** * A button component, ready to use in Sandstone applications. * * Usage: * ``` * <Button * backgroundOpacity="transparent" * size="small" * icon="home" * > * Press me! * </Button> * ``` * * @class Button * @memberof sandstone/Button * @extends sandstone/Button.ButtonBase * @mixes sandstone/Button.ButtonDecorator * @ui * @public */ var Button = exports.Button = ButtonDecorator(ButtonBase); var _default = exports["default"] = Button;