@storybook/design-system
Version:
Storybook design system
187 lines (153 loc) • 8.55 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TableOfContents = TableOfContents;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _TableOfContentsItems = require("./TableOfContentsItems");
var _excluded = ["children", "currentPath", "items"];
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
var toKebabCase = function toKebabCase(string) {
return string.toLowerCase().split(' ').join('-');
};
var hasActiveChildren = function hasActiveChildren(args) {
var children = args.children,
currentPath = args.currentPath;
return !!children.find(function (child) {
return child.path === currentPath || child.children && hasActiveChildren(_objectSpread(_objectSpread({}, args), {}, {
children: child.children
}));
});
};
var getOpenState = function getOpenState(_ref) {
var item = _ref.item,
_ref$globalItemUpdate = _ref.globalItemUpdate,
globalItemUpdate = _ref$globalItemUpdate === void 0 ? {} : _ref$globalItemUpdate,
_ref$singleItemUpdate = _ref.singleItemUpdate,
singleItemUpdate = _ref$singleItemUpdate === void 0 ? {} : _ref$singleItemUpdate,
currentPath = _ref.currentPath,
didChangeCurrentPath = _ref.didChangeCurrentPath;
var withActiveChildren = hasActiveChildren({
children: item.children,
currentPath: currentPath
}); // If there is no 'isOpen' field yet, set a default based on whether or not
// any of the children are active.
if (typeof item.isOpen !== 'boolean') return withActiveChildren; // Path changes should open up a tree for all parents of an active item.
if (didChangeCurrentPath && withActiveChildren) return true;
if (typeof globalItemUpdate.isOpen === 'boolean') return globalItemUpdate.isOpen;
if (typeof singleItemUpdate.isOpen === 'boolean' && singleItemUpdate.id === item.id) return singleItemUpdate.isOpen;
return item.isOpen;
};
var mapItemIds = function mapItemIds(items) {
var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
return items.map(function (item) {
return _objectSpread(_objectSpread({}, item), {}, {
id: "".concat(toKebabCase(item.title), "-").concat(depth)
}, item.children && {
children: mapItemIds(item.children, depth + 1)
});
});
};
// Add UI state to the 'items' that are passed in as props
var mapItemUIState = function mapItemUIState(args) {
var items = args.items,
currentPath = args.currentPath,
didChangeCurrentPath = args.didChangeCurrentPath,
_args$depth = args.depth,
depth = _args$depth === void 0 ? 0 : _args$depth,
globalItemUpdate = args.globalItemUpdate,
singleItemUpdate = args.singleItemUpdate;
return items.map(function (item) {
var isMenuWithChildren = item.type === _TableOfContentsItems.ItemType.MENU && !!item.children;
return _objectSpread(_objectSpread(_objectSpread({}, item), isMenuWithChildren && {
isOpen: getOpenState({
item: item,
globalItemUpdate: globalItemUpdate,
singleItemUpdate: singleItemUpdate,
currentPath: currentPath,
didChangeCurrentPath: didChangeCurrentPath
})
}), item.children && {
children: mapItemUIState(_objectSpread(_objectSpread({}, args), {}, {
items: item.children,
depth: depth + 1
}))
});
});
};
// State management and event handlers for the TableOfContentsItems
function TableOfContents(_ref2) {
var children = _ref2.children,
currentPath = _ref2.currentPath,
items = _ref2.items,
rest = (0, _objectWithoutProperties2["default"])(_ref2, _excluded);
var _useState = (0, _react.useState)(mapItemIds(items)),
_useState2 = (0, _slicedToArray2["default"])(_useState, 1),
itemsWithIds = _useState2[0];
var _useState3 = (0, _react.useState)(mapItemUIState({
currentPath: currentPath,
items: itemsWithIds
})),
_useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
itemsWithUIState = _useState4[0],
setItemsWithUIState = _useState4[1];
var uiStateCommonArgs = {
currentPath: currentPath,
items: itemsWithUIState
};
var toggleAllOpenStates = function toggleAllOpenStates(isOpen) {
return setItemsWithUIState(mapItemUIState(_objectSpread(_objectSpread({}, uiStateCommonArgs), {}, {
globalItemUpdate: {
isOpen: isOpen
}
})));
};
var toggleAllOpen = function toggleAllOpen() {
return toggleAllOpenStates(true);
};
var toggleAllClosed = function toggleAllClosed() {
return toggleAllOpenStates(false);
};
var setMenuOpenStateById = function setMenuOpenStateById(args) {
setItemsWithUIState(mapItemUIState(_objectSpread(_objectSpread({}, uiStateCommonArgs), {}, {
singleItemUpdate: args
})));
};
var didRunCurrentPathEffectOnMount = (0, _react.useRef)(false);
(0, _react.useEffect)(function () {
if (didRunCurrentPathEffectOnMount.current) {
setItemsWithUIState(mapItemUIState(_objectSpread(_objectSpread({}, uiStateCommonArgs), {}, {
didChangeCurrentPath: true
})));
} else {
didRunCurrentPathEffectOnMount.current = true;
}
}, [currentPath]);
var tableOfContentsMenu = /*#__PURE__*/_react["default"].createElement(_TableOfContentsItems.TableOfContentsItems, (0, _extends2["default"])({
currentPath: currentPath,
isTopLevel: true,
items: itemsWithUIState,
setMenuOpenStateById: setMenuOpenStateById
}, rest)); // Top level menu state is used to control expand/collapse buttons in consumers
var allTopLevelMenusAreOpen = itemsWithUIState.every(function (item) {
return item.type === _TableOfContentsItems.ItemType.MENU ? item.isOpen : true;
});
return typeof children === 'function' ? children({
menu: tableOfContentsMenu,
allTopLevelMenusAreOpen: allTopLevelMenusAreOpen,
toggleAllOpen: toggleAllOpen,
toggleAllClosed: toggleAllClosed
}) : tableOfContentsMenu;
}
TableOfContents.defaultProps = {
children: undefined
};