@hig/tabs
Advanced tools
Comparing version 1.0.3 to 1.1.0
@@ -1,68 +0,12 @@ | ||
import memoize from 'lodash.memoize'; | ||
import React, { Component, Children } from 'react'; | ||
import { css } from 'emotion'; | ||
import PropTypes from 'prop-types'; | ||
import { CloseSUI, CloseXsUI } from '@hig/icons'; | ||
import ThemeContext from '@hig/theme-context'; | ||
import { ControlBehavior } from '@hig/behaviors'; | ||
import { cx, css } from 'emotion'; | ||
import Typography from '@hig/typography'; | ||
import { ControlBehavior } from '@hig/behaviors'; | ||
import Fragment from 'render-fragment'; | ||
import { createCustomClassNames, createButtonEventHandlers } from '@hig/utils'; | ||
import { polyfill } from 'react-lifecycles-compat'; | ||
import memoize from 'lodash.memoize'; | ||
function _toConsumableArray(arr) { | ||
if (Array.isArray(arr)) { | ||
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { | ||
arr2[i] = arr[i]; | ||
}return arr2; | ||
} else { | ||
return Array.from(arr); | ||
} | ||
} | ||
/** | ||
* @typedef {Object} ButtonEventHandlers | ||
* @property {function(MouseEvent, ...any): void} handleClick | ||
* @property {function(KeyboardEvent, ...any): void} handleKeyDown | ||
*/ | ||
/** | ||
* @typedef {Object} Options | ||
* @property {boolean} [preventDefault] | ||
*/ | ||
var KEYBOARD_INTERACTIONS = [" ", "Enter"]; | ||
/** | ||
* Create event handlers for native button behavior for non-button elements | ||
* @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role | ||
* | ||
* @param {function(MouseEvent|KeyboardEvent, ...any): void} [handler] the event handler function | ||
* @param {Options} [options] | ||
* @returns {ButtonEventHandlers} | ||
*/ | ||
function createButtonEventHandlers(handler) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
if (!handler) return {}; | ||
var _options$preventDefau = options.preventDefault, | ||
preventDefault = _options$preventDefau === undefined ? true : _options$preventDefau; | ||
return { | ||
handleClick: handler, | ||
handleKeyDown: function handleKeyDown(event) { | ||
var key = event.key; | ||
if (!KEYBOARD_INTERACTIONS.includes(key)) return; | ||
// Prevent space key default scrolling behavior | ||
if (preventDefault) event.preventDefault(); | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
handler.apply(undefined, [event].concat(_toConsumableArray(args))); | ||
} | ||
}; | ||
} | ||
var alignments = Object.freeze({ | ||
@@ -74,160 +18,149 @@ LEFT: "left", | ||
var variants = Object.freeze({ | ||
BOX: "box", | ||
CANVAS: "canvas", | ||
UNDERLINE: "underline" | ||
}); | ||
var orientations = Object.freeze({ | ||
HORIZONTAL: "horizontal", | ||
VERTICAL: "vertical" | ||
}); | ||
var AVAILABLE_ALIGNMENTS = Object.freeze(Object.values(alignments)); | ||
var AVAILABLE_VARIANTS = Object.freeze(Object.values(variants)); | ||
var AVAILABLE_ORIENTATIONS = Object.freeze(Object.values(orientations)); | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
function stylesheet(_ref, themeData) { | ||
var _justifyContent; | ||
function getHaloStyles(_ref, themeData) { | ||
var active = _ref.active, | ||
hasHover = _ref.hasHover, | ||
hasFocus = _ref.hasFocus, | ||
isPressed = _ref.isPressed, | ||
variant = _ref.variant, | ||
orientation = _ref.orientation, | ||
disabled = _ref.disabled; | ||
var align = _ref.align; | ||
var styles = { | ||
position: "absolute", | ||
left: 0, | ||
height: 0, | ||
width: 0, | ||
transitionDuration: "0.3s", | ||
transitionProperty: "height, width" | ||
}; | ||
var justifyContent = (_justifyContent = {}, _defineProperty(_justifyContent, alignments.LEFT, "flex-start"), _defineProperty(_justifyContent, alignments.CENTER, "center"), _defineProperty(_justifyContent, alignments.RIGHT, "flex-end"), _justifyContent); | ||
if (variant === variants.UNDERLINE) { | ||
styles = _extends({}, styles, { | ||
bottom: 0, | ||
width: "100%", | ||
backgroundColor: themeData["tabs.underline.halo.hover.color"], | ||
overflow: "visible", | ||
"&:after": { | ||
position: "absolute", | ||
top: "100%", | ||
left: 0, | ||
backgroundColor: themeData["tabs.general.halo.color"], | ||
content: "\" \"", | ||
width: "100%", | ||
height: !disabled && hasFocus ? themeData["tabs.general.halo.size"] : 0, | ||
transitionDuration: "0.3s", | ||
transitionProperty: "height" | ||
} | ||
}); | ||
return { | ||
tabs: { | ||
boxSizing: "border-box", | ||
flexGrow: 1, | ||
display: "flex", | ||
padding: themeData["density.spacings.extraExtraSmall"] + " 0 " + themeData["density.spacings.extraSmall"] + " 0", | ||
margin: 0, | ||
justifyContent: justifyContent[align] | ||
if (!disabled && (hasHover || active || isPressed)) { | ||
styles = _extends({}, styles, { | ||
height: themeData["tabs.general.halo.size"] | ||
}, (active || isPressed) && { | ||
backgroundColor: themeData["tabs.underline.halo.active.color"] | ||
}); | ||
} | ||
}; | ||
} | ||
} else if (variant === variants.BOX) { | ||
styles = _extends({}, styles, { | ||
top: 0, | ||
backgroundColor: themeData["tabs.general.halo.color"] | ||
}); | ||
function TabsPresenter(_ref) { | ||
var align = _ref.align, | ||
children = _ref.children; | ||
if (orientation === orientations.VERTICAL) { | ||
styles.height = "100%"; | ||
if (!disabled && hasFocus) { | ||
styles.width = themeData["tabs.general.halo.size"]; | ||
} | ||
} else { | ||
styles.width = "100%"; | ||
if (!disabled && hasFocus) { | ||
styles.height = themeData["tabs.general.halo.size"]; | ||
} | ||
} | ||
} | ||
return React.createElement( | ||
ThemeContext.Consumer, | ||
null, | ||
function (_ref2) { | ||
var resolvedRoles = _ref2.resolvedRoles; | ||
return styles; | ||
} | ||
var styles = stylesheet({ align: align }, resolvedRoles); | ||
function getTabBackground(_ref2, themeData) { | ||
var active = _ref2.active, | ||
hasHover = _ref2.hasHover, | ||
isPressed = _ref2.isPressed, | ||
variant = _ref2.variant, | ||
disabled = _ref2.disabled; | ||
return React.createElement( | ||
"ul", | ||
{ className: css(styles.tabs) }, | ||
children | ||
); | ||
if (!disabled && variant !== variants.UNDERLINE) { | ||
if (active || isPressed) { | ||
return themeData["tabs." + variant + ".tab.active.backgroundColor"]; | ||
} | ||
); | ||
if (hasHover) { | ||
return themeData["tabs." + variant + ".tab.hover.backgroundColor"]; | ||
} | ||
} | ||
return "transparent"; | ||
} | ||
TabsPresenter.propTypes = { | ||
align: PropTypes.oneOf(AVAILABLE_ALIGNMENTS), | ||
children: PropTypes.node | ||
}; | ||
function getContentWrapperWidth(_ref3, themeData) { | ||
var label = _ref3.label, | ||
icon = _ref3.icon, | ||
closable = _ref3.closable; | ||
TabsPresenter.defaultProps = { | ||
align: alignments.CENTER | ||
}; | ||
TabsPresenter.__docgenInfo = { | ||
"description": "", | ||
"displayName": "TabsPresenter", | ||
"props": { | ||
"align": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_ALIGNMENTS" | ||
}, | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "alignments.CENTER", | ||
"computed": true | ||
} | ||
}, | ||
"children": { | ||
"type": { | ||
"name": "node" | ||
}, | ||
"required": false, | ||
"description": "" | ||
} | ||
if (label) return "auto"; | ||
if (icon && closable) { | ||
return "calc(" + themeData["tabs.general.icon.size"] + " + " + themeData["tabs.general.icon.gutter"] + " + " + themeData["tabs.general.closeButton.size"] + ")"; | ||
} | ||
}; | ||
if (icon) return themeData["tabs.general.icon.size"]; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
return "0"; | ||
} | ||
function stylesheet$1(_ref, themeData) { | ||
var active = _ref.active, | ||
hasHover = _ref.hasHover, | ||
isPressed = _ref.isPressed, | ||
label = _ref.label; | ||
function stylesheet(props, themeData) { | ||
var active = props.active, | ||
label = props.label, | ||
icon = props.icon, | ||
variant = props.variant, | ||
orientation = props.orientation, | ||
disabled = props.disabled, | ||
closable = props.closable; | ||
return { | ||
tab: { | ||
tab: _extends({ | ||
position: "relative", | ||
display: "flex", | ||
alignContent: "center", | ||
justifyContent: "center", | ||
padding: "0 " + themeData["density.spacings.small"], | ||
margin: 0, | ||
cursor: "pointer", | ||
userSelect: "none", | ||
textAlign: "center", | ||
borderBottom: themeData["tabs.general.borderBottomWidth"] + " solid " + themeData["tabs.general.borderBottomColor"], | ||
margin: "0" | ||
"&:first-of-type": { | ||
paddingLeft: 0 | ||
}, | ||
}, variant === variants.UNDERLINE && { | ||
marginRight: themeData["tabs.underline.tab.gutter"], | ||
"&:last-of-type": { | ||
paddingRight: 0 | ||
}, | ||
"&:before": _extends({ | ||
position: "absolute", | ||
content: "''", | ||
bottom: "-" + themeData["tabs.general.borderBottomWidth"], | ||
left: themeData["density.spacings.small"], | ||
width: "calc(100% - (2 * " + themeData["density.spacings.small"] + "))", | ||
borderBottomColor: "transparent", | ||
borderBottomStyle: "solid", | ||
borderBottomWidth: 0 | ||
}, hasHover && { | ||
borderBottomColor: themeData["tabs.general.tab.hover.borderBottomColor"], | ||
borderBottomWidth: themeData["tabs.general.tab.hover.borderBottomWidth"] | ||
}, (active || isPressed) && { | ||
borderBottomColor: themeData["tabs.general.tab.selected.borderBottomColor"], | ||
borderBottomWidth: themeData["tabs.general.tab.selected.borderBottomWidth"] | ||
}), | ||
"&:first-of-type:before": { | ||
left: 0, | ||
width: "calc(100% - " + themeData["density.spacings.small"] + ")" | ||
}, | ||
"&:last-of-type:before": { | ||
width: "calc(100% - " + themeData["density.spacings.small"] + ")" | ||
}, | ||
"&:after": { | ||
position: "absolute", | ||
content: "''", | ||
bottom: "-" + themeData["tabs.general.tab.focus.halo.width"], | ||
left: themeData["density.spacings.small"], | ||
width: "calc(100% - (2 * " + themeData["density.spacings.small"] + "))" | ||
}, | ||
"&:first-of-type:after": { | ||
left: 0, | ||
width: "calc(100% - " + themeData["density.spacings.small"] + ")" | ||
}, | ||
"&:last-of-type:after": { | ||
width: "calc(100% - " + themeData["density.spacings.small"] + ")" | ||
marginRight: "0" | ||
} | ||
}, | ||
tabLabel: _extends({ | ||
}), | ||
buttonWrapper: _extends({ | ||
position: "relative", | ||
display: "flex", | ||
flexDirection: "column", | ||
justifyContent: "center", | ||
alignItems: "center", | ||
padding: themeData["tabs.general.gutter"] + " 0", | ||
width: orientation === orientations.VERTICAL ? "100%" : "auto", | ||
userSelect: "none", | ||
cursor: disabled ? "default" : "pointer", | ||
border: "0", | ||
transitionDuration: "0.3s", | ||
transitionProperty: "background-color", | ||
backgroundColor: getTabBackground(props, themeData), | ||
@@ -238,3 +171,37 @@ "&:focus": { | ||
}, label && { | ||
}, variant === variants.UNDERLINE && { | ||
marginBottom: "-" + themeData["tabs.underline.wrapper.borderBottomWidth"], | ||
padding: "0 0 " + themeData["tabs.underline.tab.paddingBottom"] + " 0" | ||
}, variant === variants.BOX && { | ||
padding: themeData["tabs.box.tab.verticalPadding"] + " " + themeData["tabs.box.tab.horizontalPadding"] | ||
}, variant === variants.CANVAS && { | ||
padding: themeData["tabs.canvas.tab.verticalPadding"] + " " + themeData["tabs.canvas.tab.horizontalPadding"], | ||
transform: "skewX(-23deg)", | ||
transformOrigin: "0 100%" | ||
}), | ||
contentWrapper: { | ||
position: "relative", | ||
flexGrow: "1", | ||
transform: variant === variants.CANVAS ? "skewX(23deg)" : "none", | ||
opacity: disabled ? themeData["component.disabled.opacity"] : "1", | ||
width: getContentWrapperWidth(props, themeData), | ||
display: orientation === orientations.VERTICAL ? "block" : "flex" | ||
}, | ||
label: { | ||
display: "inline-block", | ||
position: "relative", | ||
background: "transparent", | ||
fontFamily: themeData["tabs.general.tab.fontFamily"], | ||
fontSize: themeData["tabs.general.tab.fontSize"], | ||
fontWeight: active ? themeData["tabs.general.tab.active.fontWeight"] : themeData["tabs.general.tab.fontWeight"], | ||
lineHeight: themeData["tabs.general.tab.lineHeight"], | ||
textAlign: "center", | ||
paddingLeft: icon && variant !== variants.UNDERLINE ? "calc(" + themeData["tabs.general.icon.size"] + " + " + themeData["tabs.general.icon.gutter"] + ")" : "0", | ||
paddingRight: closable && variant !== variants.UNDERLINE ? "calc(" + themeData["tabs.general.closeButton.size"] + " + " + themeData["tabs.general.closeButton.gutter"] + ")" : "0", | ||
color: themeData["tabs.general.tab.color"], | ||
// keep same amount of space whether it's active (bold font weight) | ||
// or not active (regular font weight) | ||
"&:before": { | ||
@@ -245,3 +212,3 @@ display: "block", | ||
fontSize: themeData["tabs.general.tab.fontSize"], | ||
fontWeight: themeData["tabs.general.tab.selected.fontWeight"], | ||
fontWeight: themeData["tabs.general.tab.active.fontWeight"], | ||
height: "0", | ||
@@ -252,24 +219,263 @@ color: "transparent", | ||
} | ||
}, | ||
halo: getHaloStyles(props, themeData), | ||
divider: _extends({}, variant !== variants.UNDERLINE && { | ||
position: "absolute", | ||
top: "50%", | ||
right: "0", | ||
transform: "translateY(-50%)", | ||
height: themeData["tabs." + variant + ".divider.height"], | ||
width: themeData["tabs." + variant + ".divider.width"], | ||
backgroundColor: themeData["tabs." + variant + ".divider.color"] | ||
}), | ||
tabLabelText: _extends({ | ||
fontSize: themeData["tabs.general.tab.fontSize"] | ||
icon: { | ||
display: "inline-block", | ||
position: "absolute", | ||
top: "50%", | ||
left: "0", | ||
transform: "translateY(-50%)", | ||
height: themeData["tabs.general.icon.size"], | ||
width: themeData["tabs.general.icon.size"], | ||
overflow: "hidden" | ||
}, | ||
closeButton: { | ||
position: "absolute", | ||
top: "50%", | ||
right: "0", | ||
transform: "translateY(-50%)" | ||
} | ||
}; | ||
} | ||
}, active && { | ||
fontWeight: themeData["tabs.general.tab.selected.fontWeight"] | ||
}) | ||
function getIconColor(_ref, themeData) { | ||
var hasHover = _ref.hasHover, | ||
isPressed = _ref.isPressed; | ||
if (isPressed) return themeData["tabs.general.closeButton.pressed.color"]; | ||
if (hasHover) return themeData["tabs.general.closeButton.hover.color"]; | ||
return themeData["tabs.general.closeButton.color"]; | ||
} | ||
function stylesheet$1(_ref2, themeData) { | ||
var hasHover = _ref2.hasHover, | ||
isPressed = _ref2.isPressed; | ||
return { | ||
button: { | ||
boxShadow: "none", | ||
backgroundColor: "transparent", | ||
outline: "none", | ||
border: "none", | ||
padding: "0", | ||
margin: "0", | ||
width: themeData["tabs.general.closeButton.size"], | ||
height: themeData["tabs.general.closeButton.size"], | ||
cursor: "pointer", | ||
"& svg *": { | ||
fill: getIconColor({ hasHover: hasHover, isPressed: isPressed }, themeData), | ||
transitionDuration: "0.3s", | ||
transitionProperty: "fill" | ||
} | ||
} | ||
}; | ||
} | ||
/** | ||
* @typedef {Object} TabPresenterProps | ||
* @property {boolean} [active] | ||
* @property {string} label | ||
* @property {Function} [onClick] | ||
* @property {Function} [onKeyDown] | ||
*/ | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
/** | ||
* @param {TabPresenterProps} props | ||
* @returns {JSX.Element} | ||
*/ | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var TabCloseButtonPresenter = function (_React$Component) { | ||
_inherits(TabCloseButtonPresenter, _React$Component); | ||
function TabCloseButtonPresenter() { | ||
_classCallCheck(this, TabCloseButtonPresenter); | ||
return _possibleConstructorReturn(this, (TabCloseButtonPresenter.__proto__ || Object.getPrototypeOf(TabCloseButtonPresenter)).apply(this, arguments)); | ||
} | ||
_createClass(TabCloseButtonPresenter, [{ | ||
key: "render", | ||
value: function render() { | ||
var _props = this.props, | ||
disabled = _props.disabled, | ||
onBlur = _props.onBlur, | ||
onFocus = _props.onFocus, | ||
onMouseDown = _props.onMouseDown, | ||
onMouseEnter = _props.onMouseEnter, | ||
onMouseLeave = _props.onMouseLeave, | ||
onMouseUp = _props.onMouseUp, | ||
onClick = _props.onClick, | ||
otherProps = _objectWithoutProperties(_props, ["disabled", "onBlur", "onFocus", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseUp", "onClick"]); | ||
function handleClick(event) { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
onClick(event); | ||
} | ||
return React.createElement( | ||
ControlBehavior, | ||
{ | ||
onBlur: onBlur, | ||
onFocus: onFocus, | ||
onMouseDown: onMouseDown, | ||
onMouseEnter: onMouseEnter, | ||
onMouseLeave: onMouseLeave, | ||
onMouseUp: onMouseUp | ||
}, | ||
function (_ref) { | ||
var hasFocus = _ref.hasFocus, | ||
hasHover = _ref.hasHover, | ||
isPressed = _ref.isPressed, | ||
handleBlur = _ref.onBlur, | ||
handleFocus = _ref.onFocus, | ||
handleMouseDown = _ref.onMouseDown, | ||
handleMouseEnter = _ref.onMouseEnter, | ||
handleMouseLeave = _ref.onMouseLeave, | ||
handleMouseUp = _ref.onMouseUp; | ||
return React.createElement( | ||
ThemeContext.Consumer, | ||
null, | ||
function (_ref2) { | ||
var resolvedRoles = _ref2.resolvedRoles, | ||
metadata = _ref2.metadata; | ||
var styles = stylesheet$1({ hasFocus: hasFocus, hasHover: hasHover, isPressed: isPressed }, resolvedRoles, metadata); | ||
var className = otherProps.className; | ||
var CloseIcon = metadata.densityId === "medium-density" ? CloseSUI : CloseXsUI; | ||
return React.createElement( | ||
"button", | ||
{ | ||
onBlur: handleBlur, | ||
onFocus: handleFocus, | ||
onMouseDown: handleMouseDown, | ||
onMouseEnter: handleMouseEnter, | ||
onMouseLeave: handleMouseLeave, | ||
onMouseUp: handleMouseUp, | ||
className: cx(css(styles.button), className), | ||
tabIndex: "-1", | ||
onClick: handleClick, | ||
disabled: disabled, | ||
title: "close" | ||
}, | ||
React.createElement(CloseIcon, null) | ||
); | ||
} | ||
); | ||
} | ||
); | ||
} | ||
}]); | ||
return TabCloseButtonPresenter; | ||
}(React.Component); | ||
TabCloseButtonPresenter.propTypes = { | ||
/** | ||
* Prevents user actions on the button | ||
*/ | ||
disabled: PropTypes.bool, | ||
/** | ||
* Called when user moves focus away from the button | ||
*/ | ||
onBlur: PropTypes.func, | ||
/** | ||
* Called when user clicks the button | ||
*/ | ||
onClick: PropTypes.func, | ||
/** | ||
* Called when user moves focus onto the button | ||
*/ | ||
onFocus: PropTypes.func, | ||
/** | ||
* Called when mouse is pressed over the button | ||
*/ | ||
onMouseDown: PropTypes.func, | ||
/** | ||
* Called when mouse begins to move over the button | ||
*/ | ||
onMouseEnter: PropTypes.func, | ||
/** | ||
* Called when mouse stops moving over the button | ||
*/ | ||
onMouseLeave: PropTypes.func, | ||
/** | ||
* Called when mouse is released over the button | ||
*/ | ||
onMouseUp: PropTypes.func | ||
}; | ||
TabCloseButtonPresenter.__docgenInfo = { | ||
"description": "", | ||
"displayName": "TabCloseButtonPresenter", | ||
"props": { | ||
"disabled": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "Prevents user actions on the button" | ||
}, | ||
"onBlur": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when user moves focus away from the button" | ||
}, | ||
"onClick": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when user clicks the button" | ||
}, | ||
"onFocus": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when user moves focus onto the button" | ||
}, | ||
"onMouseDown": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when mouse is pressed over the button" | ||
}, | ||
"onMouseEnter": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when mouse begins to move over the button" | ||
}, | ||
"onMouseLeave": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when mouse stops moving over the button" | ||
}, | ||
"onMouseUp": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when mouse is released over the button" | ||
} | ||
} | ||
}; | ||
function _objectWithoutProperties$1(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
function TabPresenter(_ref) { | ||
@@ -281,2 +487,8 @@ var active = _ref.active, | ||
label = _ref.label, | ||
icon = _ref.icon, | ||
disabled = _ref.disabled, | ||
closable = _ref.closable, | ||
variant = _ref.variant, | ||
orientation = _ref.orientation, | ||
showDivider = _ref.showDivider, | ||
onBlur = _ref.onBlur, | ||
@@ -286,6 +498,6 @@ onFocus = _ref.onFocus, | ||
onKeyDown = _ref.onKeyDown, | ||
onMouseDown = _ref.onMouseDown, | ||
onMouseEnter = _ref.onMouseEnter, | ||
onMouseLeave = _ref.onMouseLeave, | ||
onMouseUp = _ref.onMouseUp; | ||
onClose = _ref.onClose, | ||
otherProps = _objectWithoutProperties$1(_ref, ["active", "hasFocus", "hasHover", "isPressed", "label", "icon", "disabled", "closable", "variant", "orientation", "showDivider", "onBlur", "onFocus", "onClick", "onKeyDown", "onMouseEnter", "onMouseLeave", "onClose"]); | ||
@@ -296,9 +508,40 @@ return React.createElement( | ||
function (_ref2) { | ||
var resolvedRoles = _ref2.resolvedRoles; | ||
var resolvedRoles = _ref2.resolvedRoles, | ||
metadata = _ref2.metadata; | ||
var styles = stylesheet$1({ active: active, hasFocus: hasFocus, hasHover: hasHover, isPressed: isPressed, label: label }, resolvedRoles); | ||
var styles = stylesheet({ | ||
active: active, | ||
hasFocus: hasFocus, | ||
hasHover: hasHover, | ||
isPressed: isPressed, | ||
label: label, | ||
icon: icon, | ||
variant: variant, | ||
orientation: orientation, | ||
disabled: disabled, | ||
closable: closable | ||
}, resolvedRoles, metadata); | ||
var className = otherProps.className; | ||
var showIcon = variant !== variants.UNDERLINE && icon; | ||
var showClose = variant !== variants.UNDERLINE && closable; | ||
var showHalo = variant !== variants.CANVAS; | ||
var buttonClassName = createCustomClassNames(otherProps.className, "button"); | ||
var iconClassName = createCustomClassNames(otherProps.className, "icon"); | ||
var labelClassName = createCustomClassNames(otherProps.className, "label"); | ||
var closeButtonClassName = createCustomClassNames(otherProps.className, "close-button"); | ||
var haloClassName = createCustomClassNames(otherProps.className, "halo"); | ||
var dividerClassName = createCustomClassNames(otherProps.className, "divider"); | ||
return React.createElement( | ||
"li", | ||
{ className: css(styles.tab) }, | ||
{ className: cx(css(styles.tab), className) }, | ||
React.createElement( | ||
@@ -311,15 +554,29 @@ "div", | ||
onKeyDown: onKeyDown, | ||
onMouseDown: onMouseDown, | ||
onMouseEnter: onMouseEnter, | ||
onMouseLeave: onMouseLeave, | ||
onMouseUp: onMouseUp, | ||
disabled: disabled, | ||
tabIndex: disabled ? "-1" : "0", | ||
role: "button", | ||
tabIndex: "0", | ||
className: css(styles.tabLabel) | ||
className: cx(css(styles.buttonWrapper), buttonClassName) | ||
}, | ||
React.createElement( | ||
Typography, | ||
{ style: styles.tabLabelText }, | ||
label | ||
) | ||
"div", | ||
{ className: css(styles.contentWrapper) }, | ||
showIcon && React.createElement( | ||
"span", | ||
{ className: cx(css(styles.icon), iconClassName) }, | ||
icon | ||
), | ||
React.createElement( | ||
Typography, | ||
{ className: cx(css(styles.label), labelClassName) }, | ||
label | ||
), | ||
showClose && React.createElement(TabCloseButtonPresenter, { | ||
className: cx(css(styles.closeButton), closeButtonClassName), | ||
onClick: onClose | ||
}) | ||
), | ||
showHalo && React.createElement("div", { className: cx(css(styles.halo), haloClassName) }), | ||
showDivider && React.createElement("div", { className: cx(css(styles.divider), dividerClassName) }) | ||
) | ||
@@ -334,2 +591,8 @@ ); | ||
label: PropTypes.string, | ||
icon: PropTypes.node, | ||
disabled: PropTypes.bool, | ||
closable: PropTypes.bool, | ||
variant: PropTypes.oneOf(AVAILABLE_VARIANTS), | ||
orientation: PropTypes.oneOf(AVAILABLE_ORIENTATIONS), | ||
showDivider: PropTypes.bool, | ||
hasFocus: PropTypes.bool, | ||
@@ -342,9 +605,14 @@ hasHover: PropTypes.bool, | ||
onKeyDown: PropTypes.func, | ||
onMouseDown: PropTypes.func, | ||
onMouseEnter: PropTypes.func, | ||
onMouseLeave: PropTypes.func, | ||
onMouseUp: PropTypes.func | ||
onClose: PropTypes.func | ||
}; | ||
TabPresenter.defaultProps = { | ||
variant: variants.UNDERLINE, | ||
label: "", | ||
orientation: orientations.HORIZONTAL | ||
}; | ||
TabPresenter.__docgenInfo = { | ||
"description": "@param {TabPresenterProps} props\n@returns {JSX.Element}", | ||
"description": "", | ||
"displayName": "TabPresenter", | ||
@@ -364,4 +632,62 @@ "props": { | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "\"\"", | ||
"computed": false | ||
} | ||
}, | ||
"icon": { | ||
"type": { | ||
"name": "node" | ||
}, | ||
"required": false, | ||
"description": "" | ||
}, | ||
"disabled": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "" | ||
}, | ||
"closable": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "" | ||
}, | ||
"variant": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_VARIANTS" | ||
}, | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "variants.UNDERLINE", | ||
"computed": true | ||
} | ||
}, | ||
"orientation": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_ORIENTATIONS" | ||
}, | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "orientations.HORIZONTAL", | ||
"computed": true | ||
} | ||
}, | ||
"showDivider": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "" | ||
}, | ||
"hasFocus": { | ||
@@ -416,9 +742,2 @@ "type": { | ||
}, | ||
"onMouseDown": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "" | ||
}, | ||
"onMouseEnter": { | ||
@@ -438,3 +757,3 @@ "type": { | ||
}, | ||
"onMouseUp": { | ||
"onClose": { | ||
"type": { | ||
@@ -451,117 +770,380 @@ "name": "func" | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
var _createClass$1 = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
/** | ||
* @typedef {Object} RenderTabPayload | ||
* @property {string} key | ||
* @property {boolean} [active] | ||
* @property {string} [label] | ||
* @property {Function} [handleClick] | ||
* @property {Function} [handleKeyDown] | ||
*/ | ||
function _objectWithoutProperties$2(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
/** | ||
* @typedef {Object} TabProps | ||
* @property {boolean} [active] | ||
* @property {string} [children] | ||
* @property {string} [label] | ||
* @property {Function} [onClick] | ||
* @property {string} render A render prop allowing for custom tab components to be rendered | ||
*/ | ||
function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
/** | ||
* This component is a facade for interfacing with the `Tabs` component. | ||
* The logic within the `Tabs` component is strictly separated from the `TabPresenter`. | ||
* | ||
* @param {TabProps} props | ||
* @returns {null} | ||
*/ | ||
function Tab() { | ||
return null; | ||
} | ||
function _possibleConstructorReturn$1(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
Tab.defaultProps = { | ||
function _inherits$1(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var Tab = function (_Component) { | ||
_inherits$1(Tab, _Component); | ||
function Tab() { | ||
_classCallCheck$1(this, Tab); | ||
return _possibleConstructorReturn$1(this, (Tab.__proto__ || Object.getPrototypeOf(Tab)).apply(this, arguments)); | ||
} | ||
_createClass$1(Tab, [{ | ||
key: "render", | ||
value: function render() { | ||
var _props = this.props, | ||
active = _props.active, | ||
label = _props.label, | ||
icon = _props.icon, | ||
disabled = _props.disabled, | ||
closable = _props.closable, | ||
otherProps = _objectWithoutProperties$2(_props, ["active", "label", "icon", "disabled", "closable"]); | ||
var className = otherProps.className; | ||
var variant = otherProps.variant, | ||
orientation = otherProps.orientation, | ||
showDivider = otherProps.showDivider, | ||
onMouseEnter = otherProps.onMouseEnter, | ||
onMouseLeave = otherProps.onMouseLeave, | ||
handleClick = otherProps.handleClick, | ||
handleKeyDown = otherProps.handleKeyDown, | ||
onClose = otherProps.onClose, | ||
render = otherProps.render; | ||
if (render) { | ||
return render(_extends$1({}, this.props)); | ||
} | ||
return React.createElement( | ||
ControlBehavior, | ||
{ onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave }, | ||
function (_ref) { | ||
var hasFocus = _ref.hasFocus, | ||
hasHover = _ref.hasHover, | ||
isPressed = _ref.isPressed, | ||
onBlur = _ref.onBlur, | ||
onFocus = _ref.onFocus, | ||
handleMouseEnter = _ref.onMouseEnter, | ||
handleMouseLeave = _ref.onMouseLeave; | ||
return React.createElement(TabPresenter, { | ||
active: active, | ||
disabled: disabled, | ||
closable: closable, | ||
hasFocus: hasFocus, | ||
hasHover: hasHover, | ||
isPressed: isPressed, | ||
label: label, | ||
icon: icon, | ||
variant: variant, | ||
orientation: orientation, | ||
showDivider: showDivider, | ||
onBlur: onBlur, | ||
onFocus: onFocus, | ||
onMouseEnter: handleMouseEnter, | ||
onMouseLeave: handleMouseLeave, | ||
onClick: handleClick, | ||
onKeyDown: handleKeyDown, | ||
onClose: onClose, | ||
className: className | ||
}); | ||
} | ||
); | ||
} | ||
}]); | ||
return Tab; | ||
}(Component); | ||
Tab.propTypes = { | ||
/** | ||
* @param {RenderTabPayload} props | ||
* @returns {JSX.Element} | ||
* Specify if the tab is active | ||
* If more than one tabs are marked as active, the first one will take effect | ||
*/ | ||
render: function render(_ref) { | ||
var handleClick = _ref.handleClick, | ||
handleKeyDown = _ref.handleKeyDown, | ||
label = _ref.label, | ||
onBlur = _ref.onBlur, | ||
onFocus = _ref.onFocus, | ||
onMouseDown = _ref.onMouseDown, | ||
onMouseEnter = _ref.onMouseEnter, | ||
onMouseLeave = _ref.onMouseLeave, | ||
onMouseUp = _ref.onMouseUp, | ||
otherProps = _objectWithoutProperties(_ref, ["handleClick", "handleKeyDown", "label", "onBlur", "onFocus", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseUp"]); | ||
active: PropTypes.bool, | ||
/** | ||
* Sets the label of a tab | ||
*/ | ||
label: PropTypes.string, | ||
/** | ||
* A @hig/icon element | ||
* Icon will only be displayed when varient prop of parent Tabs is set to "box" or "canvas" | ||
*/ | ||
icon: PropTypes.node, | ||
/** | ||
* Specify if the tab is disabled | ||
*/ | ||
disabled: PropTypes.bool, | ||
/** | ||
* Specify if the tab will have a close button | ||
* Only works when varient prop of parent Tabs is set to "box" or "canvas" | ||
*/ | ||
closable: PropTypes.bool | ||
}; | ||
Tab.defaultProps = { | ||
active: false, | ||
disabled: false, | ||
closable: false | ||
}; | ||
Tab.__docgenInfo = { | ||
"description": "", | ||
"displayName": "Tab", | ||
"props": { | ||
"active": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "Specify if the tab is active\nIf more than one tabs are marked as active, the first one will take effect", | ||
"defaultValue": { | ||
"value": "false", | ||
"computed": false | ||
} | ||
}, | ||
"label": { | ||
"type": { | ||
"name": "string" | ||
}, | ||
"required": false, | ||
"description": "Sets the label of a tab" | ||
}, | ||
"icon": { | ||
"type": { | ||
"name": "node" | ||
}, | ||
"required": false, | ||
"description": "A @hig/icon element\nIcon will only be displayed when varient prop of parent Tabs is set to \"box\" or \"canvas\"" | ||
}, | ||
"disabled": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "Specify if the tab is disabled", | ||
"defaultValue": { | ||
"value": "false", | ||
"computed": false | ||
} | ||
}, | ||
"closable": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "Specify if the tab will have a close button\nOnly works when varient prop of parent Tabs is set to \"box\" or \"canvas\"", | ||
"defaultValue": { | ||
"value": "false", | ||
"computed": false | ||
} | ||
} | ||
} | ||
}; | ||
return React.createElement( | ||
ControlBehavior, | ||
{ | ||
key: label, | ||
onBlur: onBlur, | ||
onFocus: onFocus, | ||
onMouseDown: onMouseDown, | ||
onMouseEnter: onMouseEnter, | ||
onMouseLeave: onMouseLeave, | ||
onMouseUp: onMouseUp | ||
function stylesheet$2(_ref) { | ||
var orientation = _ref.orientation; | ||
return { | ||
wrapper: { | ||
display: "flex", | ||
flexWrap: "nowrap", | ||
justifyContent: "flex-start", | ||
alignItems: "stretch", | ||
flexDirection: orientation === orientations.HORIZONTAL ? "column" : "row" | ||
} | ||
}; | ||
} | ||
var _extends$2 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function getBackgroundColor(variant, themeData) { | ||
if (variant === variants.BOX) { | ||
return themeData["tabs.box.wrapper.backgroundColor"]; | ||
} | ||
if (variant === variants.CANVAS) { | ||
return themeData["tabs.canvas.wrapper.backgroundColor"]; | ||
} | ||
return "transparent"; | ||
} | ||
function stylesheet$3(_ref, themeData) { | ||
var _justifyContent; | ||
var align = _ref.align, | ||
variant = _ref.variant, | ||
orientation = _ref.orientation; | ||
var justifyContent = (_justifyContent = {}, _defineProperty(_justifyContent, alignments.LEFT, "flex-start"), _defineProperty(_justifyContent, alignments.CENTER, "center"), _defineProperty(_justifyContent, alignments.RIGHT, "flex-end"), _justifyContent); | ||
return { | ||
tabsWrapper: _extends$2({ | ||
boxSizing: "border-box", | ||
flexGrow: 0, | ||
flexShrink: 0, | ||
display: "flex", | ||
padding: 0, | ||
margin: 0, | ||
justifyContent: justifyContent[align], | ||
borderBottom: variant === variants.UNDERLINE ? themeData["tabs.underline.wrapper.borderBottomWidth"] + " solid " + themeData["tabs.underline.wrapper.borderBottomColor"] : 0, | ||
backgroundColor: getBackgroundColor(variant, themeData) | ||
}, orientation === orientations.VERTICAL && { | ||
flexDirection: "column", | ||
justifyContent: "flex-start", | ||
alignItems: "stretch" | ||
}) | ||
}; | ||
} | ||
function _objectWithoutProperties$3(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
function TabsPresenter(_ref) { | ||
var children = _ref.children, | ||
align = _ref.align, | ||
variant = _ref.variant, | ||
orientation = _ref.orientation, | ||
otherProps = _objectWithoutProperties$3(_ref, ["children", "align", "variant", "orientation"]); | ||
return React.createElement( | ||
ThemeContext.Consumer, | ||
null, | ||
function (_ref2) { | ||
var resolvedRoles = _ref2.resolvedRoles; | ||
var styles = stylesheet$3({ align: align, variant: variant, orientation: orientation }, resolvedRoles); | ||
var className = otherProps.className; | ||
var customClassName = createCustomClassNames(className, "tabs"); | ||
return React.createElement( | ||
"ul", | ||
{ className: cx(css(styles.tabsWrapper), customClassName) }, | ||
children | ||
); | ||
} | ||
); | ||
} | ||
TabsPresenter.propTypes = { | ||
align: PropTypes.oneOf(AVAILABLE_ALIGNMENTS), | ||
variant: PropTypes.oneOf(AVAILABLE_VARIANTS), | ||
orientation: PropTypes.oneOf(AVAILABLE_ORIENTATIONS), | ||
children: PropTypes.node | ||
}; | ||
TabsPresenter.defaultProps = { | ||
align: alignments.LEFT, | ||
variant: variants.UNDERLINE, | ||
orientation: orientations.HORIZONTAL | ||
}; | ||
TabsPresenter.__docgenInfo = { | ||
"description": "", | ||
"displayName": "TabsPresenter", | ||
"props": { | ||
"align": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_ALIGNMENTS" | ||
}, | ||
function (_ref2) { | ||
var hasFocus = _ref2.hasFocus, | ||
hasHover = _ref2.hasHover, | ||
isPressed = _ref2.isPressed, | ||
handleBlur = _ref2.onBlur, | ||
handleFocus = _ref2.onFocus, | ||
handleMouseDown = _ref2.onMouseDown, | ||
handleMouseEnter = _ref2.onMouseEnter, | ||
handleMouseLeave = _ref2.onMouseLeave, | ||
handleMouseUp = _ref2.onMouseUp; | ||
return React.createElement(TabPresenter, _extends$1({ | ||
hasFocus: hasFocus, | ||
hasHover: hasHover, | ||
isPressed: isPressed, | ||
label: label, | ||
onBlur: handleBlur, | ||
onFocus: handleFocus, | ||
onMouseDown: handleMouseDown, | ||
onMouseEnter: handleMouseEnter, | ||
onMouseLeave: handleMouseLeave, | ||
onMouseUp: handleMouseUp, | ||
onClick: handleClick, | ||
onKeyDown: handleKeyDown | ||
}, otherProps)); | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "alignments.LEFT", | ||
"computed": true | ||
} | ||
); | ||
}, | ||
"variant": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_VARIANTS" | ||
}, | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "variants.UNDERLINE", | ||
"computed": true | ||
} | ||
}, | ||
"orientation": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_ORIENTATIONS" | ||
}, | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "orientations.HORIZONTAL", | ||
"computed": true | ||
} | ||
}, | ||
"children": { | ||
"type": { | ||
"name": "node" | ||
}, | ||
"required": false, | ||
"description": "" | ||
} | ||
} | ||
}; | ||
Tab.propTypes = { | ||
active: PropTypes.bool, | ||
children: PropTypes.node, | ||
label: PropTypes.string, | ||
onBlur: PropTypes.func, | ||
onFocus: PropTypes.func, | ||
onClick: PropTypes.func, | ||
render: PropTypes.func.isRequired | ||
function stylesheet$4() { | ||
return { | ||
content: { | ||
flexGrow: 1, | ||
flexShrink: 1 | ||
} | ||
}; | ||
} | ||
function _objectWithoutProperties$4(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
function ContentPresenter(_ref) { | ||
var children = _ref.children, | ||
otherProps = _objectWithoutProperties$4(_ref, ["children"]); | ||
var styles = stylesheet$4(); | ||
var customClassName = createCustomClassNames(otherProps.className, "content"); | ||
return React.createElement( | ||
"div", | ||
{ className: cx(css(styles.content), customClassName) }, | ||
children | ||
); | ||
} | ||
ContentPresenter.propTypes = { | ||
children: PropTypes.node | ||
}; | ||
ContentPresenter.__docgenInfo = { | ||
"description": "", | ||
"displayName": "ContentPresenter", | ||
"props": { | ||
"children": { | ||
"type": { | ||
"name": "node" | ||
}, | ||
"required": false, | ||
"description": "" | ||
} | ||
} | ||
}; | ||
var _extends$2 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _extends$3 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _createClass$2 = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _possibleConstructorReturn$2(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
function _inherits$2(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var FIRST_TAB_INDEX = 0; | ||
var DEFAULT_HOVERED_TAB_INDEX = -1; | ||
/** | ||
* @typedef {import("./Tab").RenderTabPayload} RenderTabPayload | ||
*/ | ||
/** | ||
* @typedef {Object} TabMeta | ||
@@ -575,2 +1157,7 @@ * @property {string} key | ||
* @property {string} [align] | ||
* @property {string} [variant] | ||
* @property {string} [orientation] | ||
* @property {bool} [showTabDivider] | ||
* @property {function} [onTabChange] | ||
* @property {function} [onTabClose] | ||
* @property {ReactNode} [children] | ||
@@ -582,2 +1169,6 @@ */ | ||
* @property {number} activeTabIndex | ||
* @property {number} hoveredTabIndex | ||
* @property {string} effectiveAlign | ||
* @property {string} effectiveOrientation | ||
* @property {bool} effectiveShowTabDivider | ||
*/ | ||
@@ -606,3 +1197,3 @@ | ||
var Tabs = function (_Component) { | ||
_inherits(Tabs, _Component); | ||
_inherits$2(Tabs, _Component); | ||
@@ -614,3 +1205,3 @@ function Tabs() { | ||
_classCallCheck(this, Tabs); | ||
_classCallCheck$2(this, Tabs); | ||
@@ -621,24 +1212,61 @@ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Tabs.__proto__ || Object.getPrototypeOf(Tabs)).call.apply(_ref, [this].concat(args))), _this), _this.state = { | ||
activeTabIndex: FIRST_TAB_INDEX | ||
}, _this.createTabEventHandlers = memoize(function (index) { | ||
return createButtonEventHandlers(function () { | ||
return _this.setActiveTab(index); | ||
return _ret = (_temp = (_this = _possibleConstructorReturn$2(this, (_ref = Tabs.__proto__ || Object.getPrototypeOf(Tabs)).call.apply(_ref, [this].concat(args))), _this), _this.state = { | ||
activeTabIndex: FIRST_TAB_INDEX, | ||
hoveredTabIndex: DEFAULT_HOVERED_TAB_INDEX, | ||
effectiveAlign: alignments.LEFT, | ||
effectiveShowTabDivider: true, | ||
effectiveOrientation: orientations.HORIZONTAL | ||
}, _this.createTabEventHandlers = memoize(function (index, _ref2) { | ||
var disabled = _ref2.disabled; | ||
return _extends$3({}, createButtonEventHandlers(function () { | ||
return _this.setActiveTab(index, { disabled: disabled }); | ||
}), { | ||
onMouseEnter: function onMouseEnter() { | ||
return _this.setHoveredTab(index, { disabled: disabled }); | ||
}, | ||
onMouseLeave: function onMouseLeave() { | ||
return _this.removeHoveredTab(index); | ||
}, | ||
onClose: function onClose() { | ||
return _this.props.onTabClose(index); | ||
} | ||
}); | ||
}), _this.renderTab = function (_ref2, index) { | ||
var key = _ref2.key, | ||
props = _ref2.props; | ||
var render = props.render, | ||
label = props.label; | ||
var activeTabIndex = _this.state.activeTabIndex; | ||
/** @type {RenderTabPayload} */ | ||
}), _this.renderTab = function (_ref3, index) { | ||
var key = _ref3.key, | ||
props = _ref3.props; | ||
var disabled = props.disabled, | ||
tabClassName = props.className; | ||
var _this$props = _this.props, | ||
variant = _this$props.variant, | ||
tabsClassName = _this$props.className; | ||
var _this$state = _this.state, | ||
activeTabIndex = _this$state.activeTabIndex, | ||
hoveredTabIndex = _this$state.hoveredTabIndex, | ||
effectiveAlign = _this$state.effectiveAlign, | ||
effectiveOrientation = _this$state.effectiveOrientation, | ||
effectiveShowTabDivider = _this$state.effectiveShowTabDivider; | ||
var payload = _extends$2({ | ||
var showTabDivider = effectiveShowTabDivider; | ||
if (index === activeTabIndex || index === activeTabIndex - 1) { | ||
showTabDivider = false; | ||
} | ||
if (index === hoveredTabIndex || index === hoveredTabIndex - 1) { | ||
showTabDivider = false; | ||
} | ||
var className = cx(tabClassName, createCustomClassNames(tabsClassName, "tab")); | ||
var payload = _extends$3({}, props, { | ||
key: key, | ||
label: label, | ||
variant: variant, | ||
className: className, | ||
showDivider: showTabDivider, | ||
align: effectiveAlign, | ||
orientation: effectiveOrientation, | ||
active: activeTabIndex === index | ||
}, _this.createTabEventHandlers(index)); | ||
}, _this.createTabEventHandlers(index, { disabled: disabled })); | ||
return render(payload); | ||
}, _temp), _possibleConstructorReturn(_this, _ret); | ||
return React.createElement(Tab, payload); | ||
}, _temp), _possibleConstructorReturn$2(_this, _ret); | ||
} | ||
@@ -649,3 +1277,3 @@ | ||
_createClass(Tabs, [{ | ||
_createClass$2(Tabs, [{ | ||
key: "getTabs", | ||
@@ -672,2 +1300,3 @@ | ||
* @param {number} nextActiveTabIndex | ||
* @param {TabMeta} tab | ||
*/ | ||
@@ -677,3 +1306,4 @@ | ||
key: "setActiveTab", | ||
value: function setActiveTab(nextActiveTabIndex) { | ||
value: function setActiveTab(nextActiveTabIndex, _ref4) { | ||
var disabled = _ref4.disabled; | ||
var prevActiveTabIndex = this.state.activeTabIndex; | ||
@@ -683,3 +1313,3 @@ var onTabChange = this.props.onTabChange; | ||
if (prevActiveTabIndex === nextActiveTabIndex) return; | ||
if (disabled || prevActiveTabIndex === nextActiveTabIndex) return; | ||
@@ -691,4 +1321,33 @@ onTabChange(nextActiveTabIndex); | ||
/** | ||
* @param {number} nextHoveredTabIndex | ||
* @param {TabMeta} tab | ||
*/ | ||
}, { | ||
key: "setHoveredTab", | ||
value: function setHoveredTab(nextHoveredTabIndex, _ref5) { | ||
var disabled = _ref5.disabled; | ||
var prevHoveredTabIndex = this.state.hoveredTabIndex; | ||
if (disabled || prevHoveredTabIndex === nextHoveredTabIndex) return; | ||
this.setState({ hoveredTabIndex: nextHoveredTabIndex }); | ||
} | ||
/** | ||
* @param {number} index | ||
*/ | ||
}, { | ||
key: "removeHoveredTab", | ||
value: function removeHoveredTab(index) { | ||
var hoveredTabIndex = this.state.hoveredTabIndex; | ||
if (hoveredTabIndex === index) { | ||
this.setState({ hoveredTabIndex: DEFAULT_HOVERED_TAB_INDEX }); | ||
} | ||
} | ||
/** | ||
* @param {TabMeta} tab | ||
* @param {number} index | ||
* @returns {JSX.Element} | ||
@@ -705,5 +1364,17 @@ */ | ||
value: function renderTabs() { | ||
var _props = this.props, | ||
variant = _props.variant, | ||
className = _props.className; | ||
var _state = this.state, | ||
effectiveAlign = _state.effectiveAlign, | ||
effectiveOrientation = _state.effectiveOrientation; | ||
return React.createElement( | ||
TabsPresenter, | ||
{ align: this.props.align }, | ||
{ | ||
variant: variant, | ||
align: effectiveAlign, | ||
orientation: effectiveOrientation, | ||
className: className | ||
}, | ||
this.getTabs().map(this.renderTab) | ||
@@ -713,3 +1384,5 @@ ); | ||
/** @returns {ReactNode} */ | ||
/** | ||
* @returns {JSX.Element} | ||
*/ | ||
@@ -719,5 +1392,11 @@ }, { | ||
value: function renderContent() { | ||
var className = this.props.className; | ||
var activeTab = this.getActiveTab(); | ||
return activeTab ? activeTab.props.children : null; | ||
return React.createElement( | ||
ContentPresenter, | ||
{ className: className }, | ||
activeTab ? activeTab.props.children : null | ||
); | ||
} | ||
@@ -727,5 +1406,9 @@ }, { | ||
value: function render() { | ||
var effectiveOrientation = this.state.effectiveOrientation; | ||
var styles = stylesheet$2({ orientation: effectiveOrientation }); | ||
return React.createElement( | ||
Fragment, | ||
null, | ||
"div", | ||
{ className: cx(css(styles.wrapper), this.props.className) }, | ||
this.renderTabs(), | ||
@@ -745,23 +1428,52 @@ this.renderContent() | ||
value: function getDerivedStateFromProps(nextProps, prevState) { | ||
var children = nextProps.children; | ||
var children = nextProps.children, | ||
align = nextProps.align, | ||
variant = nextProps.variant, | ||
orientation = nextProps.orientation, | ||
showTabDivider = nextProps.showTabDivider; | ||
var prevActiveTabIndex = prevState.activeTabIndex, | ||
prevEffectiveAlign = prevState.effectiveAlign, | ||
prevEffectiveOrientation = prevState.effectiveOrientation, | ||
prevEffectiveShowTabDivider = prevState.effectiveShowTabDivider; | ||
var hasStateChanged = false; | ||
var newState = {}; | ||
var nextTabs = createTabs(children); | ||
var nextActiveTabIndex = nextTabs.findIndex(function (_ref3) { | ||
var props = _ref3.props; | ||
var nextActiveTabIndex = nextTabs.findIndex(function (_ref6) { | ||
var props = _ref6.props; | ||
return props.active; | ||
}); | ||
var prevActiveTabIndex = prevState.activeTabIndex; | ||
if (nextActiveTabIndex > 0 && nextActiveTabIndex !== prevActiveTabIndex) { | ||
newState.activeTabIndex = nextActiveTabIndex; | ||
hasStateChanged = true; | ||
} | ||
// vertical tabs will only work when variant is "box" | ||
var nextEffectiveOrientation = variant === variants.BOX ? orientation : orientations.HORIZONTAL; | ||
if (nextEffectiveOrientation !== prevEffectiveOrientation) { | ||
newState.effectiveOrientation = nextEffectiveOrientation; | ||
hasStateChanged = true; | ||
} | ||
if ( | ||
// If no active tab was declared | ||
nextActiveTabIndex < 0 || | ||
// If the declared active tab is the same as the current active tab | ||
nextActiveTabIndex === prevActiveTabIndex) { | ||
return null; | ||
// align prop will not take effect when orientation is "vertical" or variant is "canvas" | ||
var nextEffectiveAlign = nextEffectiveOrientation === orientations.VERTICAL || variant === variants.CANVAS ? alignments.LEFT : align; | ||
if (nextEffectiveAlign !== prevEffectiveAlign) { | ||
newState.effectiveAlign = nextEffectiveAlign; | ||
hasStateChanged = true; | ||
} | ||
return { | ||
activeTabIndex: nextActiveTabIndex | ||
}; | ||
// tab divider will not show when orientation is "vertical" or variant is "underline" | ||
var nextEffectiveShowTabDivider = nextEffectiveOrientation === orientations.VERTICAL || variant === variants.UNDERLINE ? false : showTabDivider; | ||
if (nextEffectiveShowTabDivider !== prevEffectiveShowTabDivider) { | ||
newState.effectiveShowTabDivider = nextEffectiveShowTabDivider; | ||
hasStateChanged = true; | ||
} | ||
if (hasStateChanged) { | ||
return newState; | ||
} | ||
return null; | ||
} | ||
@@ -775,6 +1487,21 @@ }]); | ||
/** | ||
* The visual variant of the tabs | ||
*/ | ||
variant: PropTypes.oneOf(AVAILABLE_VARIANTS), | ||
/** | ||
* Specify how to justify the tabs within their container | ||
* When variant is set to "canvas", the effective alignment will always be "left" | ||
*/ | ||
align: PropTypes.oneOf(AVAILABLE_ALIGNMENTS), | ||
/** | ||
* The list orientation of the tabs | ||
* Vertical tabs only works when variant is set to "box" | ||
*/ | ||
orientation: PropTypes.oneOf(AVAILABLE_ORIENTATIONS), | ||
/** | ||
* Show dividers between tabs | ||
* Only works in horizontal tabs and when variant is set to "box" or "canvas" | ||
*/ | ||
showTabDivider: PropTypes.bool, | ||
/** | ||
* Accepts Tab components | ||
@@ -786,7 +1513,15 @@ */ | ||
*/ | ||
onTabChange: PropTypes.func | ||
onTabChange: PropTypes.func, | ||
/** | ||
* Called when user closes a tab | ||
*/ | ||
onTabClose: PropTypes.func | ||
}; | ||
Tabs.defaultProps = { | ||
align: alignments.CENTER, | ||
onTabChange: function onTabChange() {} | ||
align: alignments.LEFT, | ||
onTabChange: function onTabChange() {}, | ||
onTabClose: function onTabClose() {}, | ||
variant: variants.UNDERLINE, | ||
orientation: orientations.HORIZONTAL, | ||
showTabDivider: true | ||
}; | ||
@@ -800,2 +1535,15 @@ | ||
"props": { | ||
"variant": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_VARIANTS" | ||
}, | ||
"required": false, | ||
"description": "The visual variant of the tabs", | ||
"defaultValue": { | ||
"value": "variants.UNDERLINE", | ||
"computed": true | ||
} | ||
}, | ||
"align": { | ||
@@ -808,8 +1556,32 @@ "type": { | ||
"required": false, | ||
"description": "Specify how to justify the tabs within their container", | ||
"description": "Specify how to justify the tabs within their container\nWhen variant is set to \"canvas\", the effective alignment will always be \"left\"", | ||
"defaultValue": { | ||
"value": "alignments.CENTER", | ||
"value": "alignments.LEFT", | ||
"computed": true | ||
} | ||
}, | ||
"orientation": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_ORIENTATIONS" | ||
}, | ||
"required": false, | ||
"description": "The list orientation of the tabs\nVertical tabs only works when variant is set to \"box\"", | ||
"defaultValue": { | ||
"value": "orientations.HORIZONTAL", | ||
"computed": true | ||
} | ||
}, | ||
"showTabDivider": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "Show dividers between tabs\nOnly works in horizontal tabs and when variant is set to \"box\" or \"canvas\"", | ||
"defaultValue": { | ||
"value": "true", | ||
"computed": false | ||
} | ||
}, | ||
"children": { | ||
@@ -832,2 +1604,13 @@ "type": { | ||
} | ||
}, | ||
"onTabClose": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when user closes a tab", | ||
"defaultValue": { | ||
"value": "() => {}", | ||
"computed": false | ||
} | ||
} | ||
@@ -838,2 +1621,2 @@ } | ||
export default Tabs$1; | ||
export { Tab, alignments, AVAILABLE_ALIGNMENTS }; | ||
export { Tab, alignments, variants, orientations, AVAILABLE_ALIGNMENTS, AVAILABLE_VARIANTS, AVAILABLE_ORIENTATIONS }; |
1533
build/index.js
@@ -7,70 +7,14 @@ 'use strict'; | ||
var memoize = _interopDefault(require('lodash.memoize')); | ||
var React = require('react'); | ||
var React__default = _interopDefault(React); | ||
var emotion = require('emotion'); | ||
var PropTypes = _interopDefault(require('prop-types')); | ||
var icons = require('@hig/icons'); | ||
var ThemeContext = _interopDefault(require('@hig/theme-context')); | ||
var behaviors = require('@hig/behaviors'); | ||
var emotion = require('emotion'); | ||
var Typography = _interopDefault(require('@hig/typography')); | ||
var behaviors = require('@hig/behaviors'); | ||
var Fragment = _interopDefault(require('render-fragment')); | ||
var utils = require('@hig/utils'); | ||
var reactLifecyclesCompat = require('react-lifecycles-compat'); | ||
var memoize = _interopDefault(require('lodash.memoize')); | ||
function _toConsumableArray(arr) { | ||
if (Array.isArray(arr)) { | ||
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { | ||
arr2[i] = arr[i]; | ||
}return arr2; | ||
} else { | ||
return Array.from(arr); | ||
} | ||
} | ||
/** | ||
* @typedef {Object} ButtonEventHandlers | ||
* @property {function(MouseEvent, ...any): void} handleClick | ||
* @property {function(KeyboardEvent, ...any): void} handleKeyDown | ||
*/ | ||
/** | ||
* @typedef {Object} Options | ||
* @property {boolean} [preventDefault] | ||
*/ | ||
var KEYBOARD_INTERACTIONS = [" ", "Enter"]; | ||
/** | ||
* Create event handlers for native button behavior for non-button elements | ||
* @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role | ||
* | ||
* @param {function(MouseEvent|KeyboardEvent, ...any): void} [handler] the event handler function | ||
* @param {Options} [options] | ||
* @returns {ButtonEventHandlers} | ||
*/ | ||
function createButtonEventHandlers(handler) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
if (!handler) return {}; | ||
var _options$preventDefau = options.preventDefault, | ||
preventDefault = _options$preventDefau === undefined ? true : _options$preventDefau; | ||
return { | ||
handleClick: handler, | ||
handleKeyDown: function handleKeyDown(event) { | ||
var key = event.key; | ||
if (!KEYBOARD_INTERACTIONS.includes(key)) return; | ||
// Prevent space key default scrolling behavior | ||
if (preventDefault) event.preventDefault(); | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
handler.apply(undefined, [event].concat(_toConsumableArray(args))); | ||
} | ||
}; | ||
} | ||
var alignments = Object.freeze({ | ||
@@ -82,160 +26,149 @@ LEFT: "left", | ||
var variants = Object.freeze({ | ||
BOX: "box", | ||
CANVAS: "canvas", | ||
UNDERLINE: "underline" | ||
}); | ||
var orientations = Object.freeze({ | ||
HORIZONTAL: "horizontal", | ||
VERTICAL: "vertical" | ||
}); | ||
var AVAILABLE_ALIGNMENTS = Object.freeze(Object.values(alignments)); | ||
var AVAILABLE_VARIANTS = Object.freeze(Object.values(variants)); | ||
var AVAILABLE_ORIENTATIONS = Object.freeze(Object.values(orientations)); | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
function stylesheet(_ref, themeData) { | ||
var _justifyContent; | ||
function getHaloStyles(_ref, themeData) { | ||
var active = _ref.active, | ||
hasHover = _ref.hasHover, | ||
hasFocus = _ref.hasFocus, | ||
isPressed = _ref.isPressed, | ||
variant = _ref.variant, | ||
orientation = _ref.orientation, | ||
disabled = _ref.disabled; | ||
var align = _ref.align; | ||
var styles = { | ||
position: "absolute", | ||
left: 0, | ||
height: 0, | ||
width: 0, | ||
transitionDuration: "0.3s", | ||
transitionProperty: "height, width" | ||
}; | ||
var justifyContent = (_justifyContent = {}, _defineProperty(_justifyContent, alignments.LEFT, "flex-start"), _defineProperty(_justifyContent, alignments.CENTER, "center"), _defineProperty(_justifyContent, alignments.RIGHT, "flex-end"), _justifyContent); | ||
if (variant === variants.UNDERLINE) { | ||
styles = _extends({}, styles, { | ||
bottom: 0, | ||
width: "100%", | ||
backgroundColor: themeData["tabs.underline.halo.hover.color"], | ||
overflow: "visible", | ||
"&:after": { | ||
position: "absolute", | ||
top: "100%", | ||
left: 0, | ||
backgroundColor: themeData["tabs.general.halo.color"], | ||
content: "\" \"", | ||
width: "100%", | ||
height: !disabled && hasFocus ? themeData["tabs.general.halo.size"] : 0, | ||
transitionDuration: "0.3s", | ||
transitionProperty: "height" | ||
} | ||
}); | ||
return { | ||
tabs: { | ||
boxSizing: "border-box", | ||
flexGrow: 1, | ||
display: "flex", | ||
padding: themeData["density.spacings.extraExtraSmall"] + " 0 " + themeData["density.spacings.extraSmall"] + " 0", | ||
margin: 0, | ||
justifyContent: justifyContent[align] | ||
if (!disabled && (hasHover || active || isPressed)) { | ||
styles = _extends({}, styles, { | ||
height: themeData["tabs.general.halo.size"] | ||
}, (active || isPressed) && { | ||
backgroundColor: themeData["tabs.underline.halo.active.color"] | ||
}); | ||
} | ||
}; | ||
} | ||
} else if (variant === variants.BOX) { | ||
styles = _extends({}, styles, { | ||
top: 0, | ||
backgroundColor: themeData["tabs.general.halo.color"] | ||
}); | ||
function TabsPresenter(_ref) { | ||
var align = _ref.align, | ||
children = _ref.children; | ||
if (orientation === orientations.VERTICAL) { | ||
styles.height = "100%"; | ||
if (!disabled && hasFocus) { | ||
styles.width = themeData["tabs.general.halo.size"]; | ||
} | ||
} else { | ||
styles.width = "100%"; | ||
if (!disabled && hasFocus) { | ||
styles.height = themeData["tabs.general.halo.size"]; | ||
} | ||
} | ||
} | ||
return React__default.createElement( | ||
ThemeContext.Consumer, | ||
null, | ||
function (_ref2) { | ||
var resolvedRoles = _ref2.resolvedRoles; | ||
return styles; | ||
} | ||
var styles = stylesheet({ align: align }, resolvedRoles); | ||
function getTabBackground(_ref2, themeData) { | ||
var active = _ref2.active, | ||
hasHover = _ref2.hasHover, | ||
isPressed = _ref2.isPressed, | ||
variant = _ref2.variant, | ||
disabled = _ref2.disabled; | ||
return React__default.createElement( | ||
"ul", | ||
{ className: emotion.css(styles.tabs) }, | ||
children | ||
); | ||
if (!disabled && variant !== variants.UNDERLINE) { | ||
if (active || isPressed) { | ||
return themeData["tabs." + variant + ".tab.active.backgroundColor"]; | ||
} | ||
); | ||
if (hasHover) { | ||
return themeData["tabs." + variant + ".tab.hover.backgroundColor"]; | ||
} | ||
} | ||
return "transparent"; | ||
} | ||
TabsPresenter.propTypes = { | ||
align: PropTypes.oneOf(AVAILABLE_ALIGNMENTS), | ||
children: PropTypes.node | ||
}; | ||
function getContentWrapperWidth(_ref3, themeData) { | ||
var label = _ref3.label, | ||
icon = _ref3.icon, | ||
closable = _ref3.closable; | ||
TabsPresenter.defaultProps = { | ||
align: alignments.CENTER | ||
}; | ||
TabsPresenter.__docgenInfo = { | ||
"description": "", | ||
"displayName": "TabsPresenter", | ||
"props": { | ||
"align": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_ALIGNMENTS" | ||
}, | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "alignments.CENTER", | ||
"computed": true | ||
} | ||
}, | ||
"children": { | ||
"type": { | ||
"name": "node" | ||
}, | ||
"required": false, | ||
"description": "" | ||
} | ||
if (label) return "auto"; | ||
if (icon && closable) { | ||
return "calc(" + themeData["tabs.general.icon.size"] + " + " + themeData["tabs.general.icon.gutter"] + " + " + themeData["tabs.general.closeButton.size"] + ")"; | ||
} | ||
}; | ||
if (icon) return themeData["tabs.general.icon.size"]; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
return "0"; | ||
} | ||
function stylesheet$1(_ref, themeData) { | ||
var active = _ref.active, | ||
hasHover = _ref.hasHover, | ||
isPressed = _ref.isPressed, | ||
label = _ref.label; | ||
function stylesheet(props, themeData) { | ||
var active = props.active, | ||
label = props.label, | ||
icon = props.icon, | ||
variant = props.variant, | ||
orientation = props.orientation, | ||
disabled = props.disabled, | ||
closable = props.closable; | ||
return { | ||
tab: { | ||
tab: _extends({ | ||
position: "relative", | ||
display: "flex", | ||
alignContent: "center", | ||
justifyContent: "center", | ||
padding: "0 " + themeData["density.spacings.small"], | ||
margin: 0, | ||
cursor: "pointer", | ||
userSelect: "none", | ||
textAlign: "center", | ||
borderBottom: themeData["tabs.general.borderBottomWidth"] + " solid " + themeData["tabs.general.borderBottomColor"], | ||
margin: "0" | ||
"&:first-of-type": { | ||
paddingLeft: 0 | ||
}, | ||
}, variant === variants.UNDERLINE && { | ||
marginRight: themeData["tabs.underline.tab.gutter"], | ||
"&:last-of-type": { | ||
paddingRight: 0 | ||
}, | ||
"&:before": _extends({ | ||
position: "absolute", | ||
content: "''", | ||
bottom: "-" + themeData["tabs.general.borderBottomWidth"], | ||
left: themeData["density.spacings.small"], | ||
width: "calc(100% - (2 * " + themeData["density.spacings.small"] + "))", | ||
borderBottomColor: "transparent", | ||
borderBottomStyle: "solid", | ||
borderBottomWidth: 0 | ||
}, hasHover && { | ||
borderBottomColor: themeData["tabs.general.tab.hover.borderBottomColor"], | ||
borderBottomWidth: themeData["tabs.general.tab.hover.borderBottomWidth"] | ||
}, (active || isPressed) && { | ||
borderBottomColor: themeData["tabs.general.tab.selected.borderBottomColor"], | ||
borderBottomWidth: themeData["tabs.general.tab.selected.borderBottomWidth"] | ||
}), | ||
"&:first-of-type:before": { | ||
left: 0, | ||
width: "calc(100% - " + themeData["density.spacings.small"] + ")" | ||
}, | ||
"&:last-of-type:before": { | ||
width: "calc(100% - " + themeData["density.spacings.small"] + ")" | ||
}, | ||
"&:after": { | ||
position: "absolute", | ||
content: "''", | ||
bottom: "-" + themeData["tabs.general.tab.focus.halo.width"], | ||
left: themeData["density.spacings.small"], | ||
width: "calc(100% - (2 * " + themeData["density.spacings.small"] + "))" | ||
}, | ||
"&:first-of-type:after": { | ||
left: 0, | ||
width: "calc(100% - " + themeData["density.spacings.small"] + ")" | ||
}, | ||
"&:last-of-type:after": { | ||
width: "calc(100% - " + themeData["density.spacings.small"] + ")" | ||
marginRight: "0" | ||
} | ||
}, | ||
tabLabel: _extends({ | ||
}), | ||
buttonWrapper: _extends({ | ||
position: "relative", | ||
display: "flex", | ||
flexDirection: "column", | ||
justifyContent: "center", | ||
alignItems: "center", | ||
padding: themeData["tabs.general.gutter"] + " 0", | ||
width: orientation === orientations.VERTICAL ? "100%" : "auto", | ||
userSelect: "none", | ||
cursor: disabled ? "default" : "pointer", | ||
border: "0", | ||
transitionDuration: "0.3s", | ||
transitionProperty: "background-color", | ||
backgroundColor: getTabBackground(props, themeData), | ||
@@ -246,3 +179,37 @@ "&:focus": { | ||
}, label && { | ||
}, variant === variants.UNDERLINE && { | ||
marginBottom: "-" + themeData["tabs.underline.wrapper.borderBottomWidth"], | ||
padding: "0 0 " + themeData["tabs.underline.tab.paddingBottom"] + " 0" | ||
}, variant === variants.BOX && { | ||
padding: themeData["tabs.box.tab.verticalPadding"] + " " + themeData["tabs.box.tab.horizontalPadding"] | ||
}, variant === variants.CANVAS && { | ||
padding: themeData["tabs.canvas.tab.verticalPadding"] + " " + themeData["tabs.canvas.tab.horizontalPadding"], | ||
transform: "skewX(-23deg)", | ||
transformOrigin: "0 100%" | ||
}), | ||
contentWrapper: { | ||
position: "relative", | ||
flexGrow: "1", | ||
transform: variant === variants.CANVAS ? "skewX(23deg)" : "none", | ||
opacity: disabled ? themeData["component.disabled.opacity"] : "1", | ||
width: getContentWrapperWidth(props, themeData), | ||
display: orientation === orientations.VERTICAL ? "block" : "flex" | ||
}, | ||
label: { | ||
display: "inline-block", | ||
position: "relative", | ||
background: "transparent", | ||
fontFamily: themeData["tabs.general.tab.fontFamily"], | ||
fontSize: themeData["tabs.general.tab.fontSize"], | ||
fontWeight: active ? themeData["tabs.general.tab.active.fontWeight"] : themeData["tabs.general.tab.fontWeight"], | ||
lineHeight: themeData["tabs.general.tab.lineHeight"], | ||
textAlign: "center", | ||
paddingLeft: icon && variant !== variants.UNDERLINE ? "calc(" + themeData["tabs.general.icon.size"] + " + " + themeData["tabs.general.icon.gutter"] + ")" : "0", | ||
paddingRight: closable && variant !== variants.UNDERLINE ? "calc(" + themeData["tabs.general.closeButton.size"] + " + " + themeData["tabs.general.closeButton.gutter"] + ")" : "0", | ||
color: themeData["tabs.general.tab.color"], | ||
// keep same amount of space whether it's active (bold font weight) | ||
// or not active (regular font weight) | ||
"&:before": { | ||
@@ -253,3 +220,3 @@ display: "block", | ||
fontSize: themeData["tabs.general.tab.fontSize"], | ||
fontWeight: themeData["tabs.general.tab.selected.fontWeight"], | ||
fontWeight: themeData["tabs.general.tab.active.fontWeight"], | ||
height: "0", | ||
@@ -260,24 +227,263 @@ color: "transparent", | ||
} | ||
}, | ||
halo: getHaloStyles(props, themeData), | ||
divider: _extends({}, variant !== variants.UNDERLINE && { | ||
position: "absolute", | ||
top: "50%", | ||
right: "0", | ||
transform: "translateY(-50%)", | ||
height: themeData["tabs." + variant + ".divider.height"], | ||
width: themeData["tabs." + variant + ".divider.width"], | ||
backgroundColor: themeData["tabs." + variant + ".divider.color"] | ||
}), | ||
tabLabelText: _extends({ | ||
fontSize: themeData["tabs.general.tab.fontSize"] | ||
icon: { | ||
display: "inline-block", | ||
position: "absolute", | ||
top: "50%", | ||
left: "0", | ||
transform: "translateY(-50%)", | ||
height: themeData["tabs.general.icon.size"], | ||
width: themeData["tabs.general.icon.size"], | ||
overflow: "hidden" | ||
}, | ||
closeButton: { | ||
position: "absolute", | ||
top: "50%", | ||
right: "0", | ||
transform: "translateY(-50%)" | ||
} | ||
}; | ||
} | ||
}, active && { | ||
fontWeight: themeData["tabs.general.tab.selected.fontWeight"] | ||
}) | ||
function getIconColor(_ref, themeData) { | ||
var hasHover = _ref.hasHover, | ||
isPressed = _ref.isPressed; | ||
if (isPressed) return themeData["tabs.general.closeButton.pressed.color"]; | ||
if (hasHover) return themeData["tabs.general.closeButton.hover.color"]; | ||
return themeData["tabs.general.closeButton.color"]; | ||
} | ||
function stylesheet$1(_ref2, themeData) { | ||
var hasHover = _ref2.hasHover, | ||
isPressed = _ref2.isPressed; | ||
return { | ||
button: { | ||
boxShadow: "none", | ||
backgroundColor: "transparent", | ||
outline: "none", | ||
border: "none", | ||
padding: "0", | ||
margin: "0", | ||
width: themeData["tabs.general.closeButton.size"], | ||
height: themeData["tabs.general.closeButton.size"], | ||
cursor: "pointer", | ||
"& svg *": { | ||
fill: getIconColor({ hasHover: hasHover, isPressed: isPressed }, themeData), | ||
transitionDuration: "0.3s", | ||
transitionProperty: "fill" | ||
} | ||
} | ||
}; | ||
} | ||
/** | ||
* @typedef {Object} TabPresenterProps | ||
* @property {boolean} [active] | ||
* @property {string} label | ||
* @property {Function} [onClick] | ||
* @property {Function} [onKeyDown] | ||
*/ | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
/** | ||
* @param {TabPresenterProps} props | ||
* @returns {JSX.Element} | ||
*/ | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var TabCloseButtonPresenter = function (_React$Component) { | ||
_inherits(TabCloseButtonPresenter, _React$Component); | ||
function TabCloseButtonPresenter() { | ||
_classCallCheck(this, TabCloseButtonPresenter); | ||
return _possibleConstructorReturn(this, (TabCloseButtonPresenter.__proto__ || Object.getPrototypeOf(TabCloseButtonPresenter)).apply(this, arguments)); | ||
} | ||
_createClass(TabCloseButtonPresenter, [{ | ||
key: "render", | ||
value: function render() { | ||
var _props = this.props, | ||
disabled = _props.disabled, | ||
onBlur = _props.onBlur, | ||
onFocus = _props.onFocus, | ||
onMouseDown = _props.onMouseDown, | ||
onMouseEnter = _props.onMouseEnter, | ||
onMouseLeave = _props.onMouseLeave, | ||
onMouseUp = _props.onMouseUp, | ||
onClick = _props.onClick, | ||
otherProps = _objectWithoutProperties(_props, ["disabled", "onBlur", "onFocus", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseUp", "onClick"]); | ||
function handleClick(event) { | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
onClick(event); | ||
} | ||
return React__default.createElement( | ||
behaviors.ControlBehavior, | ||
{ | ||
onBlur: onBlur, | ||
onFocus: onFocus, | ||
onMouseDown: onMouseDown, | ||
onMouseEnter: onMouseEnter, | ||
onMouseLeave: onMouseLeave, | ||
onMouseUp: onMouseUp | ||
}, | ||
function (_ref) { | ||
var hasFocus = _ref.hasFocus, | ||
hasHover = _ref.hasHover, | ||
isPressed = _ref.isPressed, | ||
handleBlur = _ref.onBlur, | ||
handleFocus = _ref.onFocus, | ||
handleMouseDown = _ref.onMouseDown, | ||
handleMouseEnter = _ref.onMouseEnter, | ||
handleMouseLeave = _ref.onMouseLeave, | ||
handleMouseUp = _ref.onMouseUp; | ||
return React__default.createElement( | ||
ThemeContext.Consumer, | ||
null, | ||
function (_ref2) { | ||
var resolvedRoles = _ref2.resolvedRoles, | ||
metadata = _ref2.metadata; | ||
var styles = stylesheet$1({ hasFocus: hasFocus, hasHover: hasHover, isPressed: isPressed }, resolvedRoles, metadata); | ||
var className = otherProps.className; | ||
var CloseIcon = metadata.densityId === "medium-density" ? icons.CloseSUI : icons.CloseXsUI; | ||
return React__default.createElement( | ||
"button", | ||
{ | ||
onBlur: handleBlur, | ||
onFocus: handleFocus, | ||
onMouseDown: handleMouseDown, | ||
onMouseEnter: handleMouseEnter, | ||
onMouseLeave: handleMouseLeave, | ||
onMouseUp: handleMouseUp, | ||
className: emotion.cx(emotion.css(styles.button), className), | ||
tabIndex: "-1", | ||
onClick: handleClick, | ||
disabled: disabled, | ||
title: "close" | ||
}, | ||
React__default.createElement(CloseIcon, null) | ||
); | ||
} | ||
); | ||
} | ||
); | ||
} | ||
}]); | ||
return TabCloseButtonPresenter; | ||
}(React__default.Component); | ||
TabCloseButtonPresenter.propTypes = { | ||
/** | ||
* Prevents user actions on the button | ||
*/ | ||
disabled: PropTypes.bool, | ||
/** | ||
* Called when user moves focus away from the button | ||
*/ | ||
onBlur: PropTypes.func, | ||
/** | ||
* Called when user clicks the button | ||
*/ | ||
onClick: PropTypes.func, | ||
/** | ||
* Called when user moves focus onto the button | ||
*/ | ||
onFocus: PropTypes.func, | ||
/** | ||
* Called when mouse is pressed over the button | ||
*/ | ||
onMouseDown: PropTypes.func, | ||
/** | ||
* Called when mouse begins to move over the button | ||
*/ | ||
onMouseEnter: PropTypes.func, | ||
/** | ||
* Called when mouse stops moving over the button | ||
*/ | ||
onMouseLeave: PropTypes.func, | ||
/** | ||
* Called when mouse is released over the button | ||
*/ | ||
onMouseUp: PropTypes.func | ||
}; | ||
TabCloseButtonPresenter.__docgenInfo = { | ||
"description": "", | ||
"displayName": "TabCloseButtonPresenter", | ||
"props": { | ||
"disabled": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "Prevents user actions on the button" | ||
}, | ||
"onBlur": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when user moves focus away from the button" | ||
}, | ||
"onClick": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when user clicks the button" | ||
}, | ||
"onFocus": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when user moves focus onto the button" | ||
}, | ||
"onMouseDown": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when mouse is pressed over the button" | ||
}, | ||
"onMouseEnter": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when mouse begins to move over the button" | ||
}, | ||
"onMouseLeave": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when mouse stops moving over the button" | ||
}, | ||
"onMouseUp": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when mouse is released over the button" | ||
} | ||
} | ||
}; | ||
function _objectWithoutProperties$1(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
function TabPresenter(_ref) { | ||
@@ -289,2 +495,8 @@ var active = _ref.active, | ||
label = _ref.label, | ||
icon = _ref.icon, | ||
disabled = _ref.disabled, | ||
closable = _ref.closable, | ||
variant = _ref.variant, | ||
orientation = _ref.orientation, | ||
showDivider = _ref.showDivider, | ||
onBlur = _ref.onBlur, | ||
@@ -294,6 +506,6 @@ onFocus = _ref.onFocus, | ||
onKeyDown = _ref.onKeyDown, | ||
onMouseDown = _ref.onMouseDown, | ||
onMouseEnter = _ref.onMouseEnter, | ||
onMouseLeave = _ref.onMouseLeave, | ||
onMouseUp = _ref.onMouseUp; | ||
onClose = _ref.onClose, | ||
otherProps = _objectWithoutProperties$1(_ref, ["active", "hasFocus", "hasHover", "isPressed", "label", "icon", "disabled", "closable", "variant", "orientation", "showDivider", "onBlur", "onFocus", "onClick", "onKeyDown", "onMouseEnter", "onMouseLeave", "onClose"]); | ||
@@ -304,9 +516,40 @@ return React__default.createElement( | ||
function (_ref2) { | ||
var resolvedRoles = _ref2.resolvedRoles; | ||
var resolvedRoles = _ref2.resolvedRoles, | ||
metadata = _ref2.metadata; | ||
var styles = stylesheet$1({ active: active, hasFocus: hasFocus, hasHover: hasHover, isPressed: isPressed, label: label }, resolvedRoles); | ||
var styles = stylesheet({ | ||
active: active, | ||
hasFocus: hasFocus, | ||
hasHover: hasHover, | ||
isPressed: isPressed, | ||
label: label, | ||
icon: icon, | ||
variant: variant, | ||
orientation: orientation, | ||
disabled: disabled, | ||
closable: closable | ||
}, resolvedRoles, metadata); | ||
var className = otherProps.className; | ||
var showIcon = variant !== variants.UNDERLINE && icon; | ||
var showClose = variant !== variants.UNDERLINE && closable; | ||
var showHalo = variant !== variants.CANVAS; | ||
var buttonClassName = utils.createCustomClassNames(otherProps.className, "button"); | ||
var iconClassName = utils.createCustomClassNames(otherProps.className, "icon"); | ||
var labelClassName = utils.createCustomClassNames(otherProps.className, "label"); | ||
var closeButtonClassName = utils.createCustomClassNames(otherProps.className, "close-button"); | ||
var haloClassName = utils.createCustomClassNames(otherProps.className, "halo"); | ||
var dividerClassName = utils.createCustomClassNames(otherProps.className, "divider"); | ||
return React__default.createElement( | ||
"li", | ||
{ className: emotion.css(styles.tab) }, | ||
{ className: emotion.cx(emotion.css(styles.tab), className) }, | ||
React__default.createElement( | ||
@@ -319,15 +562,29 @@ "div", | ||
onKeyDown: onKeyDown, | ||
onMouseDown: onMouseDown, | ||
onMouseEnter: onMouseEnter, | ||
onMouseLeave: onMouseLeave, | ||
onMouseUp: onMouseUp, | ||
disabled: disabled, | ||
tabIndex: disabled ? "-1" : "0", | ||
role: "button", | ||
tabIndex: "0", | ||
className: emotion.css(styles.tabLabel) | ||
className: emotion.cx(emotion.css(styles.buttonWrapper), buttonClassName) | ||
}, | ||
React__default.createElement( | ||
Typography, | ||
{ style: styles.tabLabelText }, | ||
label | ||
) | ||
"div", | ||
{ className: emotion.css(styles.contentWrapper) }, | ||
showIcon && React__default.createElement( | ||
"span", | ||
{ className: emotion.cx(emotion.css(styles.icon), iconClassName) }, | ||
icon | ||
), | ||
React__default.createElement( | ||
Typography, | ||
{ className: emotion.cx(emotion.css(styles.label), labelClassName) }, | ||
label | ||
), | ||
showClose && React__default.createElement(TabCloseButtonPresenter, { | ||
className: emotion.cx(emotion.css(styles.closeButton), closeButtonClassName), | ||
onClick: onClose | ||
}) | ||
), | ||
showHalo && React__default.createElement("div", { className: emotion.cx(emotion.css(styles.halo), haloClassName) }), | ||
showDivider && React__default.createElement("div", { className: emotion.cx(emotion.css(styles.divider), dividerClassName) }) | ||
) | ||
@@ -342,2 +599,8 @@ ); | ||
label: PropTypes.string, | ||
icon: PropTypes.node, | ||
disabled: PropTypes.bool, | ||
closable: PropTypes.bool, | ||
variant: PropTypes.oneOf(AVAILABLE_VARIANTS), | ||
orientation: PropTypes.oneOf(AVAILABLE_ORIENTATIONS), | ||
showDivider: PropTypes.bool, | ||
hasFocus: PropTypes.bool, | ||
@@ -350,9 +613,14 @@ hasHover: PropTypes.bool, | ||
onKeyDown: PropTypes.func, | ||
onMouseDown: PropTypes.func, | ||
onMouseEnter: PropTypes.func, | ||
onMouseLeave: PropTypes.func, | ||
onMouseUp: PropTypes.func | ||
onClose: PropTypes.func | ||
}; | ||
TabPresenter.defaultProps = { | ||
variant: variants.UNDERLINE, | ||
label: "", | ||
orientation: orientations.HORIZONTAL | ||
}; | ||
TabPresenter.__docgenInfo = { | ||
"description": "@param {TabPresenterProps} props\n@returns {JSX.Element}", | ||
"description": "", | ||
"displayName": "TabPresenter", | ||
@@ -372,4 +640,62 @@ "props": { | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "\"\"", | ||
"computed": false | ||
} | ||
}, | ||
"icon": { | ||
"type": { | ||
"name": "node" | ||
}, | ||
"required": false, | ||
"description": "" | ||
}, | ||
"disabled": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "" | ||
}, | ||
"closable": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "" | ||
}, | ||
"variant": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_VARIANTS" | ||
}, | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "variants.UNDERLINE", | ||
"computed": true | ||
} | ||
}, | ||
"orientation": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_ORIENTATIONS" | ||
}, | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "orientations.HORIZONTAL", | ||
"computed": true | ||
} | ||
}, | ||
"showDivider": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "" | ||
}, | ||
"hasFocus": { | ||
@@ -424,9 +750,2 @@ "type": { | ||
}, | ||
"onMouseDown": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "" | ||
}, | ||
"onMouseEnter": { | ||
@@ -446,3 +765,3 @@ "type": { | ||
}, | ||
"onMouseUp": { | ||
"onClose": { | ||
"type": { | ||
@@ -459,117 +778,380 @@ "name": "func" | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
var _createClass$1 = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
/** | ||
* @typedef {Object} RenderTabPayload | ||
* @property {string} key | ||
* @property {boolean} [active] | ||
* @property {string} [label] | ||
* @property {Function} [handleClick] | ||
* @property {Function} [handleKeyDown] | ||
*/ | ||
function _objectWithoutProperties$2(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
/** | ||
* @typedef {Object} TabProps | ||
* @property {boolean} [active] | ||
* @property {string} [children] | ||
* @property {string} [label] | ||
* @property {Function} [onClick] | ||
* @property {string} render A render prop allowing for custom tab components to be rendered | ||
*/ | ||
function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
/** | ||
* This component is a facade for interfacing with the `Tabs` component. | ||
* The logic within the `Tabs` component is strictly separated from the `TabPresenter`. | ||
* | ||
* @param {TabProps} props | ||
* @returns {null} | ||
*/ | ||
function Tab() { | ||
return null; | ||
} | ||
function _possibleConstructorReturn$1(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
Tab.defaultProps = { | ||
function _inherits$1(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var Tab = function (_Component) { | ||
_inherits$1(Tab, _Component); | ||
function Tab() { | ||
_classCallCheck$1(this, Tab); | ||
return _possibleConstructorReturn$1(this, (Tab.__proto__ || Object.getPrototypeOf(Tab)).apply(this, arguments)); | ||
} | ||
_createClass$1(Tab, [{ | ||
key: "render", | ||
value: function render() { | ||
var _props = this.props, | ||
active = _props.active, | ||
label = _props.label, | ||
icon = _props.icon, | ||
disabled = _props.disabled, | ||
closable = _props.closable, | ||
otherProps = _objectWithoutProperties$2(_props, ["active", "label", "icon", "disabled", "closable"]); | ||
var className = otherProps.className; | ||
var variant = otherProps.variant, | ||
orientation = otherProps.orientation, | ||
showDivider = otherProps.showDivider, | ||
onMouseEnter = otherProps.onMouseEnter, | ||
onMouseLeave = otherProps.onMouseLeave, | ||
handleClick = otherProps.handleClick, | ||
handleKeyDown = otherProps.handleKeyDown, | ||
onClose = otherProps.onClose, | ||
render = otherProps.render; | ||
if (render) { | ||
return render(_extends$1({}, this.props)); | ||
} | ||
return React__default.createElement( | ||
behaviors.ControlBehavior, | ||
{ onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave }, | ||
function (_ref) { | ||
var hasFocus = _ref.hasFocus, | ||
hasHover = _ref.hasHover, | ||
isPressed = _ref.isPressed, | ||
onBlur = _ref.onBlur, | ||
onFocus = _ref.onFocus, | ||
handleMouseEnter = _ref.onMouseEnter, | ||
handleMouseLeave = _ref.onMouseLeave; | ||
return React__default.createElement(TabPresenter, { | ||
active: active, | ||
disabled: disabled, | ||
closable: closable, | ||
hasFocus: hasFocus, | ||
hasHover: hasHover, | ||
isPressed: isPressed, | ||
label: label, | ||
icon: icon, | ||
variant: variant, | ||
orientation: orientation, | ||
showDivider: showDivider, | ||
onBlur: onBlur, | ||
onFocus: onFocus, | ||
onMouseEnter: handleMouseEnter, | ||
onMouseLeave: handleMouseLeave, | ||
onClick: handleClick, | ||
onKeyDown: handleKeyDown, | ||
onClose: onClose, | ||
className: className | ||
}); | ||
} | ||
); | ||
} | ||
}]); | ||
return Tab; | ||
}(React.Component); | ||
Tab.propTypes = { | ||
/** | ||
* @param {RenderTabPayload} props | ||
* @returns {JSX.Element} | ||
* Specify if the tab is active | ||
* If more than one tabs are marked as active, the first one will take effect | ||
*/ | ||
render: function render(_ref) { | ||
var handleClick = _ref.handleClick, | ||
handleKeyDown = _ref.handleKeyDown, | ||
label = _ref.label, | ||
onBlur = _ref.onBlur, | ||
onFocus = _ref.onFocus, | ||
onMouseDown = _ref.onMouseDown, | ||
onMouseEnter = _ref.onMouseEnter, | ||
onMouseLeave = _ref.onMouseLeave, | ||
onMouseUp = _ref.onMouseUp, | ||
otherProps = _objectWithoutProperties(_ref, ["handleClick", "handleKeyDown", "label", "onBlur", "onFocus", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseUp"]); | ||
active: PropTypes.bool, | ||
/** | ||
* Sets the label of a tab | ||
*/ | ||
label: PropTypes.string, | ||
/** | ||
* A @hig/icon element | ||
* Icon will only be displayed when varient prop of parent Tabs is set to "box" or "canvas" | ||
*/ | ||
icon: PropTypes.node, | ||
/** | ||
* Specify if the tab is disabled | ||
*/ | ||
disabled: PropTypes.bool, | ||
/** | ||
* Specify if the tab will have a close button | ||
* Only works when varient prop of parent Tabs is set to "box" or "canvas" | ||
*/ | ||
closable: PropTypes.bool | ||
}; | ||
Tab.defaultProps = { | ||
active: false, | ||
disabled: false, | ||
closable: false | ||
}; | ||
Tab.__docgenInfo = { | ||
"description": "", | ||
"displayName": "Tab", | ||
"props": { | ||
"active": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "Specify if the tab is active\nIf more than one tabs are marked as active, the first one will take effect", | ||
"defaultValue": { | ||
"value": "false", | ||
"computed": false | ||
} | ||
}, | ||
"label": { | ||
"type": { | ||
"name": "string" | ||
}, | ||
"required": false, | ||
"description": "Sets the label of a tab" | ||
}, | ||
"icon": { | ||
"type": { | ||
"name": "node" | ||
}, | ||
"required": false, | ||
"description": "A @hig/icon element\nIcon will only be displayed when varient prop of parent Tabs is set to \"box\" or \"canvas\"" | ||
}, | ||
"disabled": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "Specify if the tab is disabled", | ||
"defaultValue": { | ||
"value": "false", | ||
"computed": false | ||
} | ||
}, | ||
"closable": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "Specify if the tab will have a close button\nOnly works when varient prop of parent Tabs is set to \"box\" or \"canvas\"", | ||
"defaultValue": { | ||
"value": "false", | ||
"computed": false | ||
} | ||
} | ||
} | ||
}; | ||
return React__default.createElement( | ||
behaviors.ControlBehavior, | ||
{ | ||
key: label, | ||
onBlur: onBlur, | ||
onFocus: onFocus, | ||
onMouseDown: onMouseDown, | ||
onMouseEnter: onMouseEnter, | ||
onMouseLeave: onMouseLeave, | ||
onMouseUp: onMouseUp | ||
function stylesheet$2(_ref) { | ||
var orientation = _ref.orientation; | ||
return { | ||
wrapper: { | ||
display: "flex", | ||
flexWrap: "nowrap", | ||
justifyContent: "flex-start", | ||
alignItems: "stretch", | ||
flexDirection: orientation === orientations.HORIZONTAL ? "column" : "row" | ||
} | ||
}; | ||
} | ||
var _extends$2 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function getBackgroundColor(variant, themeData) { | ||
if (variant === variants.BOX) { | ||
return themeData["tabs.box.wrapper.backgroundColor"]; | ||
} | ||
if (variant === variants.CANVAS) { | ||
return themeData["tabs.canvas.wrapper.backgroundColor"]; | ||
} | ||
return "transparent"; | ||
} | ||
function stylesheet$3(_ref, themeData) { | ||
var _justifyContent; | ||
var align = _ref.align, | ||
variant = _ref.variant, | ||
orientation = _ref.orientation; | ||
var justifyContent = (_justifyContent = {}, _defineProperty(_justifyContent, alignments.LEFT, "flex-start"), _defineProperty(_justifyContent, alignments.CENTER, "center"), _defineProperty(_justifyContent, alignments.RIGHT, "flex-end"), _justifyContent); | ||
return { | ||
tabsWrapper: _extends$2({ | ||
boxSizing: "border-box", | ||
flexGrow: 0, | ||
flexShrink: 0, | ||
display: "flex", | ||
padding: 0, | ||
margin: 0, | ||
justifyContent: justifyContent[align], | ||
borderBottom: variant === variants.UNDERLINE ? themeData["tabs.underline.wrapper.borderBottomWidth"] + " solid " + themeData["tabs.underline.wrapper.borderBottomColor"] : 0, | ||
backgroundColor: getBackgroundColor(variant, themeData) | ||
}, orientation === orientations.VERTICAL && { | ||
flexDirection: "column", | ||
justifyContent: "flex-start", | ||
alignItems: "stretch" | ||
}) | ||
}; | ||
} | ||
function _objectWithoutProperties$3(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
function TabsPresenter(_ref) { | ||
var children = _ref.children, | ||
align = _ref.align, | ||
variant = _ref.variant, | ||
orientation = _ref.orientation, | ||
otherProps = _objectWithoutProperties$3(_ref, ["children", "align", "variant", "orientation"]); | ||
return React__default.createElement( | ||
ThemeContext.Consumer, | ||
null, | ||
function (_ref2) { | ||
var resolvedRoles = _ref2.resolvedRoles; | ||
var styles = stylesheet$3({ align: align, variant: variant, orientation: orientation }, resolvedRoles); | ||
var className = otherProps.className; | ||
var customClassName = utils.createCustomClassNames(className, "tabs"); | ||
return React__default.createElement( | ||
"ul", | ||
{ className: emotion.cx(emotion.css(styles.tabsWrapper), customClassName) }, | ||
children | ||
); | ||
} | ||
); | ||
} | ||
TabsPresenter.propTypes = { | ||
align: PropTypes.oneOf(AVAILABLE_ALIGNMENTS), | ||
variant: PropTypes.oneOf(AVAILABLE_VARIANTS), | ||
orientation: PropTypes.oneOf(AVAILABLE_ORIENTATIONS), | ||
children: PropTypes.node | ||
}; | ||
TabsPresenter.defaultProps = { | ||
align: alignments.LEFT, | ||
variant: variants.UNDERLINE, | ||
orientation: orientations.HORIZONTAL | ||
}; | ||
TabsPresenter.__docgenInfo = { | ||
"description": "", | ||
"displayName": "TabsPresenter", | ||
"props": { | ||
"align": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_ALIGNMENTS" | ||
}, | ||
function (_ref2) { | ||
var hasFocus = _ref2.hasFocus, | ||
hasHover = _ref2.hasHover, | ||
isPressed = _ref2.isPressed, | ||
handleBlur = _ref2.onBlur, | ||
handleFocus = _ref2.onFocus, | ||
handleMouseDown = _ref2.onMouseDown, | ||
handleMouseEnter = _ref2.onMouseEnter, | ||
handleMouseLeave = _ref2.onMouseLeave, | ||
handleMouseUp = _ref2.onMouseUp; | ||
return React__default.createElement(TabPresenter, _extends$1({ | ||
hasFocus: hasFocus, | ||
hasHover: hasHover, | ||
isPressed: isPressed, | ||
label: label, | ||
onBlur: handleBlur, | ||
onFocus: handleFocus, | ||
onMouseDown: handleMouseDown, | ||
onMouseEnter: handleMouseEnter, | ||
onMouseLeave: handleMouseLeave, | ||
onMouseUp: handleMouseUp, | ||
onClick: handleClick, | ||
onKeyDown: handleKeyDown | ||
}, otherProps)); | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "alignments.LEFT", | ||
"computed": true | ||
} | ||
); | ||
}, | ||
"variant": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_VARIANTS" | ||
}, | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "variants.UNDERLINE", | ||
"computed": true | ||
} | ||
}, | ||
"orientation": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_ORIENTATIONS" | ||
}, | ||
"required": false, | ||
"description": "", | ||
"defaultValue": { | ||
"value": "orientations.HORIZONTAL", | ||
"computed": true | ||
} | ||
}, | ||
"children": { | ||
"type": { | ||
"name": "node" | ||
}, | ||
"required": false, | ||
"description": "" | ||
} | ||
} | ||
}; | ||
Tab.propTypes = { | ||
active: PropTypes.bool, | ||
children: PropTypes.node, | ||
label: PropTypes.string, | ||
onBlur: PropTypes.func, | ||
onFocus: PropTypes.func, | ||
onClick: PropTypes.func, | ||
render: PropTypes.func.isRequired | ||
function stylesheet$4() { | ||
return { | ||
content: { | ||
flexGrow: 1, | ||
flexShrink: 1 | ||
} | ||
}; | ||
} | ||
function _objectWithoutProperties$4(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
function ContentPresenter(_ref) { | ||
var children = _ref.children, | ||
otherProps = _objectWithoutProperties$4(_ref, ["children"]); | ||
var styles = stylesheet$4(); | ||
var customClassName = utils.createCustomClassNames(otherProps.className, "content"); | ||
return React__default.createElement( | ||
"div", | ||
{ className: emotion.cx(emotion.css(styles.content), customClassName) }, | ||
children | ||
); | ||
} | ||
ContentPresenter.propTypes = { | ||
children: PropTypes.node | ||
}; | ||
ContentPresenter.__docgenInfo = { | ||
"description": "", | ||
"displayName": "ContentPresenter", | ||
"props": { | ||
"children": { | ||
"type": { | ||
"name": "node" | ||
}, | ||
"required": false, | ||
"description": "" | ||
} | ||
} | ||
}; | ||
var _extends$2 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _extends$3 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _createClass$2 = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _possibleConstructorReturn$2(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
function _inherits$2(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var FIRST_TAB_INDEX = 0; | ||
var DEFAULT_HOVERED_TAB_INDEX = -1; | ||
/** | ||
* @typedef {import("./Tab").RenderTabPayload} RenderTabPayload | ||
*/ | ||
/** | ||
* @typedef {Object} TabMeta | ||
@@ -583,2 +1165,7 @@ * @property {string} key | ||
* @property {string} [align] | ||
* @property {string} [variant] | ||
* @property {string} [orientation] | ||
* @property {bool} [showTabDivider] | ||
* @property {function} [onTabChange] | ||
* @property {function} [onTabClose] | ||
* @property {ReactNode} [children] | ||
@@ -590,2 +1177,6 @@ */ | ||
* @property {number} activeTabIndex | ||
* @property {number} hoveredTabIndex | ||
* @property {string} effectiveAlign | ||
* @property {string} effectiveOrientation | ||
* @property {bool} effectiveShowTabDivider | ||
*/ | ||
@@ -614,3 +1205,3 @@ | ||
var Tabs = function (_Component) { | ||
_inherits(Tabs, _Component); | ||
_inherits$2(Tabs, _Component); | ||
@@ -622,3 +1213,3 @@ function Tabs() { | ||
_classCallCheck(this, Tabs); | ||
_classCallCheck$2(this, Tabs); | ||
@@ -629,24 +1220,61 @@ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Tabs.__proto__ || Object.getPrototypeOf(Tabs)).call.apply(_ref, [this].concat(args))), _this), _this.state = { | ||
activeTabIndex: FIRST_TAB_INDEX | ||
}, _this.createTabEventHandlers = memoize(function (index) { | ||
return createButtonEventHandlers(function () { | ||
return _this.setActiveTab(index); | ||
return _ret = (_temp = (_this = _possibleConstructorReturn$2(this, (_ref = Tabs.__proto__ || Object.getPrototypeOf(Tabs)).call.apply(_ref, [this].concat(args))), _this), _this.state = { | ||
activeTabIndex: FIRST_TAB_INDEX, | ||
hoveredTabIndex: DEFAULT_HOVERED_TAB_INDEX, | ||
effectiveAlign: alignments.LEFT, | ||
effectiveShowTabDivider: true, | ||
effectiveOrientation: orientations.HORIZONTAL | ||
}, _this.createTabEventHandlers = memoize(function (index, _ref2) { | ||
var disabled = _ref2.disabled; | ||
return _extends$3({}, utils.createButtonEventHandlers(function () { | ||
return _this.setActiveTab(index, { disabled: disabled }); | ||
}), { | ||
onMouseEnter: function onMouseEnter() { | ||
return _this.setHoveredTab(index, { disabled: disabled }); | ||
}, | ||
onMouseLeave: function onMouseLeave() { | ||
return _this.removeHoveredTab(index); | ||
}, | ||
onClose: function onClose() { | ||
return _this.props.onTabClose(index); | ||
} | ||
}); | ||
}), _this.renderTab = function (_ref2, index) { | ||
var key = _ref2.key, | ||
props = _ref2.props; | ||
var render = props.render, | ||
label = props.label; | ||
var activeTabIndex = _this.state.activeTabIndex; | ||
/** @type {RenderTabPayload} */ | ||
}), _this.renderTab = function (_ref3, index) { | ||
var key = _ref3.key, | ||
props = _ref3.props; | ||
var disabled = props.disabled, | ||
tabClassName = props.className; | ||
var _this$props = _this.props, | ||
variant = _this$props.variant, | ||
tabsClassName = _this$props.className; | ||
var _this$state = _this.state, | ||
activeTabIndex = _this$state.activeTabIndex, | ||
hoveredTabIndex = _this$state.hoveredTabIndex, | ||
effectiveAlign = _this$state.effectiveAlign, | ||
effectiveOrientation = _this$state.effectiveOrientation, | ||
effectiveShowTabDivider = _this$state.effectiveShowTabDivider; | ||
var payload = _extends$2({ | ||
var showTabDivider = effectiveShowTabDivider; | ||
if (index === activeTabIndex || index === activeTabIndex - 1) { | ||
showTabDivider = false; | ||
} | ||
if (index === hoveredTabIndex || index === hoveredTabIndex - 1) { | ||
showTabDivider = false; | ||
} | ||
var className = emotion.cx(tabClassName, utils.createCustomClassNames(tabsClassName, "tab")); | ||
var payload = _extends$3({}, props, { | ||
key: key, | ||
label: label, | ||
variant: variant, | ||
className: className, | ||
showDivider: showTabDivider, | ||
align: effectiveAlign, | ||
orientation: effectiveOrientation, | ||
active: activeTabIndex === index | ||
}, _this.createTabEventHandlers(index)); | ||
}, _this.createTabEventHandlers(index, { disabled: disabled })); | ||
return render(payload); | ||
}, _temp), _possibleConstructorReturn(_this, _ret); | ||
return React__default.createElement(Tab, payload); | ||
}, _temp), _possibleConstructorReturn$2(_this, _ret); | ||
} | ||
@@ -657,3 +1285,3 @@ | ||
_createClass(Tabs, [{ | ||
_createClass$2(Tabs, [{ | ||
key: "getTabs", | ||
@@ -680,2 +1308,3 @@ | ||
* @param {number} nextActiveTabIndex | ||
* @param {TabMeta} tab | ||
*/ | ||
@@ -685,3 +1314,4 @@ | ||
key: "setActiveTab", | ||
value: function setActiveTab(nextActiveTabIndex) { | ||
value: function setActiveTab(nextActiveTabIndex, _ref4) { | ||
var disabled = _ref4.disabled; | ||
var prevActiveTabIndex = this.state.activeTabIndex; | ||
@@ -691,3 +1321,3 @@ var onTabChange = this.props.onTabChange; | ||
if (prevActiveTabIndex === nextActiveTabIndex) return; | ||
if (disabled || prevActiveTabIndex === nextActiveTabIndex) return; | ||
@@ -699,4 +1329,33 @@ onTabChange(nextActiveTabIndex); | ||
/** | ||
* @param {number} nextHoveredTabIndex | ||
* @param {TabMeta} tab | ||
*/ | ||
}, { | ||
key: "setHoveredTab", | ||
value: function setHoveredTab(nextHoveredTabIndex, _ref5) { | ||
var disabled = _ref5.disabled; | ||
var prevHoveredTabIndex = this.state.hoveredTabIndex; | ||
if (disabled || prevHoveredTabIndex === nextHoveredTabIndex) return; | ||
this.setState({ hoveredTabIndex: nextHoveredTabIndex }); | ||
} | ||
/** | ||
* @param {number} index | ||
*/ | ||
}, { | ||
key: "removeHoveredTab", | ||
value: function removeHoveredTab(index) { | ||
var hoveredTabIndex = this.state.hoveredTabIndex; | ||
if (hoveredTabIndex === index) { | ||
this.setState({ hoveredTabIndex: DEFAULT_HOVERED_TAB_INDEX }); | ||
} | ||
} | ||
/** | ||
* @param {TabMeta} tab | ||
* @param {number} index | ||
* @returns {JSX.Element} | ||
@@ -713,5 +1372,17 @@ */ | ||
value: function renderTabs() { | ||
var _props = this.props, | ||
variant = _props.variant, | ||
className = _props.className; | ||
var _state = this.state, | ||
effectiveAlign = _state.effectiveAlign, | ||
effectiveOrientation = _state.effectiveOrientation; | ||
return React__default.createElement( | ||
TabsPresenter, | ||
{ align: this.props.align }, | ||
{ | ||
variant: variant, | ||
align: effectiveAlign, | ||
orientation: effectiveOrientation, | ||
className: className | ||
}, | ||
this.getTabs().map(this.renderTab) | ||
@@ -721,3 +1392,5 @@ ); | ||
/** @returns {ReactNode} */ | ||
/** | ||
* @returns {JSX.Element} | ||
*/ | ||
@@ -727,5 +1400,11 @@ }, { | ||
value: function renderContent() { | ||
var className = this.props.className; | ||
var activeTab = this.getActiveTab(); | ||
return activeTab ? activeTab.props.children : null; | ||
return React__default.createElement( | ||
ContentPresenter, | ||
{ className: className }, | ||
activeTab ? activeTab.props.children : null | ||
); | ||
} | ||
@@ -735,5 +1414,9 @@ }, { | ||
value: function render() { | ||
var effectiveOrientation = this.state.effectiveOrientation; | ||
var styles = stylesheet$2({ orientation: effectiveOrientation }); | ||
return React__default.createElement( | ||
Fragment, | ||
null, | ||
"div", | ||
{ className: emotion.cx(emotion.css(styles.wrapper), this.props.className) }, | ||
this.renderTabs(), | ||
@@ -753,23 +1436,52 @@ this.renderContent() | ||
value: function getDerivedStateFromProps(nextProps, prevState) { | ||
var children = nextProps.children; | ||
var children = nextProps.children, | ||
align = nextProps.align, | ||
variant = nextProps.variant, | ||
orientation = nextProps.orientation, | ||
showTabDivider = nextProps.showTabDivider; | ||
var prevActiveTabIndex = prevState.activeTabIndex, | ||
prevEffectiveAlign = prevState.effectiveAlign, | ||
prevEffectiveOrientation = prevState.effectiveOrientation, | ||
prevEffectiveShowTabDivider = prevState.effectiveShowTabDivider; | ||
var hasStateChanged = false; | ||
var newState = {}; | ||
var nextTabs = createTabs(children); | ||
var nextActiveTabIndex = nextTabs.findIndex(function (_ref3) { | ||
var props = _ref3.props; | ||
var nextActiveTabIndex = nextTabs.findIndex(function (_ref6) { | ||
var props = _ref6.props; | ||
return props.active; | ||
}); | ||
var prevActiveTabIndex = prevState.activeTabIndex; | ||
if (nextActiveTabIndex > 0 && nextActiveTabIndex !== prevActiveTabIndex) { | ||
newState.activeTabIndex = nextActiveTabIndex; | ||
hasStateChanged = true; | ||
} | ||
// vertical tabs will only work when variant is "box" | ||
var nextEffectiveOrientation = variant === variants.BOX ? orientation : orientations.HORIZONTAL; | ||
if (nextEffectiveOrientation !== prevEffectiveOrientation) { | ||
newState.effectiveOrientation = nextEffectiveOrientation; | ||
hasStateChanged = true; | ||
} | ||
if ( | ||
// If no active tab was declared | ||
nextActiveTabIndex < 0 || | ||
// If the declared active tab is the same as the current active tab | ||
nextActiveTabIndex === prevActiveTabIndex) { | ||
return null; | ||
// align prop will not take effect when orientation is "vertical" or variant is "canvas" | ||
var nextEffectiveAlign = nextEffectiveOrientation === orientations.VERTICAL || variant === variants.CANVAS ? alignments.LEFT : align; | ||
if (nextEffectiveAlign !== prevEffectiveAlign) { | ||
newState.effectiveAlign = nextEffectiveAlign; | ||
hasStateChanged = true; | ||
} | ||
return { | ||
activeTabIndex: nextActiveTabIndex | ||
}; | ||
// tab divider will not show when orientation is "vertical" or variant is "underline" | ||
var nextEffectiveShowTabDivider = nextEffectiveOrientation === orientations.VERTICAL || variant === variants.UNDERLINE ? false : showTabDivider; | ||
if (nextEffectiveShowTabDivider !== prevEffectiveShowTabDivider) { | ||
newState.effectiveShowTabDivider = nextEffectiveShowTabDivider; | ||
hasStateChanged = true; | ||
} | ||
if (hasStateChanged) { | ||
return newState; | ||
} | ||
return null; | ||
} | ||
@@ -783,6 +1495,21 @@ }]); | ||
/** | ||
* The visual variant of the tabs | ||
*/ | ||
variant: PropTypes.oneOf(AVAILABLE_VARIANTS), | ||
/** | ||
* Specify how to justify the tabs within their container | ||
* When variant is set to "canvas", the effective alignment will always be "left" | ||
*/ | ||
align: PropTypes.oneOf(AVAILABLE_ALIGNMENTS), | ||
/** | ||
* The list orientation of the tabs | ||
* Vertical tabs only works when variant is set to "box" | ||
*/ | ||
orientation: PropTypes.oneOf(AVAILABLE_ORIENTATIONS), | ||
/** | ||
* Show dividers between tabs | ||
* Only works in horizontal tabs and when variant is set to "box" or "canvas" | ||
*/ | ||
showTabDivider: PropTypes.bool, | ||
/** | ||
* Accepts Tab components | ||
@@ -794,7 +1521,15 @@ */ | ||
*/ | ||
onTabChange: PropTypes.func | ||
onTabChange: PropTypes.func, | ||
/** | ||
* Called when user closes a tab | ||
*/ | ||
onTabClose: PropTypes.func | ||
}; | ||
Tabs.defaultProps = { | ||
align: alignments.CENTER, | ||
onTabChange: function onTabChange() {} | ||
align: alignments.LEFT, | ||
onTabChange: function onTabChange() {}, | ||
onTabClose: function onTabClose() {}, | ||
variant: variants.UNDERLINE, | ||
orientation: orientations.HORIZONTAL, | ||
showTabDivider: true | ||
}; | ||
@@ -808,2 +1543,15 @@ | ||
"props": { | ||
"variant": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_VARIANTS" | ||
}, | ||
"required": false, | ||
"description": "The visual variant of the tabs", | ||
"defaultValue": { | ||
"value": "variants.UNDERLINE", | ||
"computed": true | ||
} | ||
}, | ||
"align": { | ||
@@ -816,8 +1564,32 @@ "type": { | ||
"required": false, | ||
"description": "Specify how to justify the tabs within their container", | ||
"description": "Specify how to justify the tabs within their container\nWhen variant is set to \"canvas\", the effective alignment will always be \"left\"", | ||
"defaultValue": { | ||
"value": "alignments.CENTER", | ||
"value": "alignments.LEFT", | ||
"computed": true | ||
} | ||
}, | ||
"orientation": { | ||
"type": { | ||
"name": "enum", | ||
"computed": true, | ||
"value": "AVAILABLE_ORIENTATIONS" | ||
}, | ||
"required": false, | ||
"description": "The list orientation of the tabs\nVertical tabs only works when variant is set to \"box\"", | ||
"defaultValue": { | ||
"value": "orientations.HORIZONTAL", | ||
"computed": true | ||
} | ||
}, | ||
"showTabDivider": { | ||
"type": { | ||
"name": "bool" | ||
}, | ||
"required": false, | ||
"description": "Show dividers between tabs\nOnly works in horizontal tabs and when variant is set to \"box\" or \"canvas\"", | ||
"defaultValue": { | ||
"value": "true", | ||
"computed": false | ||
} | ||
}, | ||
"children": { | ||
@@ -840,2 +1612,13 @@ "type": { | ||
} | ||
}, | ||
"onTabClose": { | ||
"type": { | ||
"name": "func" | ||
}, | ||
"required": false, | ||
"description": "Called when user closes a tab", | ||
"defaultValue": { | ||
"value": "() => {}", | ||
"computed": false | ||
} | ||
} | ||
@@ -848,2 +1631,6 @@ } | ||
exports.alignments = alignments; | ||
exports.variants = variants; | ||
exports.orientations = orientations; | ||
exports.AVAILABLE_ALIGNMENTS = AVAILABLE_ALIGNMENTS; | ||
exports.AVAILABLE_VARIANTS = AVAILABLE_VARIANTS; | ||
exports.AVAILABLE_ORIENTATIONS = AVAILABLE_ORIENTATIONS; |
@@ -0,1 +1,8 @@ | ||
# [@hig/tabs-v1.1.0](https://github.com/Autodesk/hig/compare/@hig/tabs@1.0.3...@hig/tabs@1.1.0) (2019-09-19) | ||
### Features | ||
* update Tabs to match the new design ([a6ab419](https://github.com/Autodesk/hig/commit/a6ab419)) | ||
# [@hig/tabs-v1.0.3](https://github.com/Autodesk/hig/compare/@hig/tabs@1.0.2...@hig/tabs@1.0.3) (2019-04-25) | ||
@@ -2,0 +9,0 @@ |
{ | ||
"name": "@hig/tabs", | ||
"version": "1.0.3", | ||
"version": "1.1.0", | ||
"description": "HIG Tabs", | ||
@@ -22,11 +22,12 @@ "author": "Autodesk Inc.", | ||
"@hig/typography": "^1.0.3", | ||
"@hig/icons": "^3.1.0", | ||
"@hig/utils": "^0.4.0", | ||
"emotion": "^10.0.0", | ||
"lodash.memoize": "^4.1.2", | ||
"prop-types": "^15.7.1", | ||
"react-lifecycles-compat": "^3.0.4", | ||
"render-fragment": "^0.1.1" | ||
"react-lifecycles-compat": "^3.0.4" | ||
}, | ||
"peerDependencies": { | ||
"@hig/theme-context": "^3.0.0", | ||
"@hig/theme-data": "^2.4.0", | ||
"@hig/theme-data": "^2.12.0", | ||
"react": "^15.4.1 || ^16.3.2" | ||
@@ -33,0 +34,0 @@ }, |
@@ -24,7 +24,29 @@ # Tabs | ||
```jsx | ||
<Tabs align="center"> | ||
<Tab label="Details">Details content</Tab> | ||
<Tab label="Activities">Activities content</Tab> | ||
<Tab label="Inspector">Inspector content</Tab> | ||
<Tabs> | ||
<Tab key="details" label="Details">Details content</Tab> | ||
<Tab key="activities" label="Activities">Activities content</Tab> | ||
<Tab key="inspector" label="Inspector">Inspector content</Tab> | ||
</Tabs> | ||
``` | ||
## Customization | ||
The visual styles of `Tabs` can be customized by its props, available values can be found via: | ||
```js | ||
import { | ||
AVAILABLE_ALIGNMENTS, | ||
AVAILABLE_VARIANTS, | ||
AVAILABLE_ORIENTATIONS, | ||
alignments, | ||
variants, | ||
orientations | ||
} from "@hig/tabs"; | ||
``` | ||
### Complex Tabs | ||
Complex tabs are composed of an interactive container, text label, divider and optional close icon. Complex tabs only works when `varient` is set to `box` or `canvas`. | ||
### Custom CSS | ||
Use the `className` prop to pass in a css class name to the outermost container of the component. The class name will also pass down to most of the other styled elements within the component. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
105917
21
2850
52
11
1
+ Added@hig/icons@^3.1.0
+ Added@hig/utils@^0.4.0
+ Added@hig/icons@3.4.4(transitive)
+ Added@hig/utils@0.4.1(transitive)
- Removedrender-fragment@^0.1.1
- Removedrender-fragment@0.1.1(transitive)