UNPKG

@danilandreev/material-docs

Version:

material-docs - react framework for easy creating documentation site in material design style.

474 lines (360 loc) 18.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.displayName = void 0; var _react = _interopRequireDefault(require("react")); var _styles = require("./styles"); var _SearchMenuItem = _interopRequireDefault(require("./SearchMenuItem")); var _ListItemText = _interopRequireDefault(require("@material-ui/core/ListItemText")); var _ListItemIcon = _interopRequireDefault(require("@material-ui/core/ListItemIcon")); var _ClickAwayListener = _interopRequireDefault(require("@material-ui/core/ClickAwayListener")); var _ListItem = _interopRequireDefault(require("@material-ui/core/ListItem")); var _Popper = _interopRequireDefault(require("@material-ui/core/Popper")); var _List = _interopRequireDefault(require("@material-ui/core/List")); var _Paper = _interopRequireDefault(require("@material-ui/core/Paper")); var _InputBase = _interopRequireDefault(require("@material-ui/core/InputBase")); var _ErrorOutline = _interopRequireDefault(require("@material-ui/icons/ErrorOutline")); var _Close = _interopRequireDefault(require("@material-ui/icons/Close")); var _Search = _interopRequireDefault(require("@material-ui/icons/Search")); var _propTypes = _interopRequireDefault(require("prop-types")); var _SearchDataItemValidator = _interopRequireDefault(require("../../validators/SearchDataItemValidator")); var _styles2 = require("@material-ui/styles"); var _routingManager = require("routing-manager"); var _clsx = _interopRequireDefault(require("clsx")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var displayName = "MatDocSearchField"; exports.displayName = displayName; var SearchField = /*#__PURE__*/_react.default.forwardRef(function SearchField(props, _ref) { var className = props.className, style = props.style, _props$searchData = props.searchData, searchData = _props$searchData === void 0 ? [] : _props$searchData, doSearch = props.doSearch, classes = props.classes, other = _objectWithoutProperties(props, ["className", "style", "searchData", "doSearch", "classes"]); var _useChangeRoute = (0, _routingManager.useChangeRoute)(), changeRoute = _useChangeRoute.changeRoute; var _React$useState = _react.default.useState(""), _React$useState2 = _slicedToArray(_React$useState, 2), text = _React$useState2[0], setText = _React$useState2[1]; var _React$useState3 = _react.default.useState(false), _React$useState4 = _slicedToArray(_React$useState3, 2), focused = _React$useState4[0], setFocused = _React$useState4[1]; var _React$useState5 = _react.default.useState([]), _React$useState6 = _slicedToArray(_React$useState5, 2), found = _React$useState6[0], setFound = _React$useState6[1]; var _React$useState7 = _react.default.useState(0), _React$useState8 = _slicedToArray(_React$useState7, 2), selected = _React$useState8[0], setSelected = _React$useState8[1]; var rootRef = _react.default.useRef(null); var inputRef = _react.default.useRef(null); function handleSearchItemSelected() { setFocused(false); inputRef.current && inputRef.current.blur(); } function handleTextInput(event) { setText(event.target.value); if (doSearch && typeof doSearch !== "function") throw new TypeError("MaterialDocs: Incorrect type for doSearch prop, expected function, got ".concat(_typeof(doSearch))); if (doSearch) { doSearch(event.target.value, searchData).then(function (result) { return setFound(result); }); } else { search(event.target.value || "").then(function (result) { return setFound(result); }); } } function handleItemAction(data) { switch (_typeof(data.redirect)) { case "string": window.location.href = data.redirect; break; case "function": data.redirect(); break; case "object": changeRoute(data.redirect); break; default: throw new TypeError("MaterialDocs: Incorrect type for redirect. Got ".concat(_typeof(data.redirect), ", expected object | string | function")); } } function handleKeyDown(event) { switch (event.key) { case "ArrowUp": setSelected(function (prev) { return prev > 0 ? prev - 1 : found.length - 1; }); event.preventDefault(); event.stopPropagation(); break; case "ArrowDown": setSelected(function (prev) { return prev < found.length - 1 ? prev + 1 : 0; }); event.preventDefault(); event.stopPropagation(); break; case "Enter": found[selected] && handleItemAction(found[selected]); found[selected] && setText(""); inputRef.current.blur(); setFocused(false); break; case "Escape": inputRef.current.blur(); setFocused(false); break; } } /** * search - function, designed to do search from searchData by query string input. * @function * @param {string} input * @returns {SearchDataItem[]} */ function search(_x) { return _search.apply(this, arguments); } function _search() { _search = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(input) { var query, result, _iterator, _step, keyword, _iterator2, _step2, item, added, _iterator3, _step3, tag; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (!(input && typeof input !== "string")) { _context.next = 2; break; } throw new TypeError("MaterialDocs: incorrect type ".concat(_typeof(input), " for search query, expected string!")); case 2: if (input) { _context.next = 4; break; } return _context.abrupt("return", []); case 4: query = input.toLowerCase().replace(/ /g, "").split(" ").filter(function (item) { return item; }); result = new Set(); _iterator = _createForOfIteratorHelper(query); _context.prev = 7; _iterator.s(); case 9: if ((_step = _iterator.n()).done) { _context.next = 58; break; } keyword = _step.value; _iterator2 = _createForOfIteratorHelper(searchData); _context.prev = 12; _iterator2.s(); case 14: if ((_step2 = _iterator2.n()).done) { _context.next = 48; break; } item = _step2.value; added = false; if (item) { _context.next = 19; break; } throw new TypeError("MaterialDocs: invalid search data object, expected SearchDataItem, got ".concat(item)); case 19: if (!(typeof item.label !== "string")) { _context.next = 21; break; } throw new TypeError("MaterialDocs: incorrect type ".concat(_typeof(item.label), " for label, expected string!")); case 21: if (!(item.description && typeof item.description !== "string")) { _context.next = 23; break; } throw new TypeError("MaterialDocs: incorrect type ".concat(_typeof(item.description), " for description, expected string!")); case 23: _iterator3 = _createForOfIteratorHelper(item.tags); _context.prev = 24; _iterator3.s(); case 26: if ((_step3 = _iterator3.n()).done) { _context.next = 36; break; } tag = _step3.value; if (!(typeof tag !== "string")) { _context.next = 30; break; } throw new TypeError("MaterialDocs: incorrect type ".concat(_typeof(tag), " for tag, expected string!")); case 30: if (!tag.toLowerCase().includes(keyword)) { _context.next = 34; break; } result.add(item); added = true; return _context.abrupt("break", 36); case 34: _context.next = 26; break; case 36: _context.next = 41; break; case 38: _context.prev = 38; _context.t0 = _context["catch"](24); _iterator3.e(_context.t0); case 41: _context.prev = 41; _iterator3.f(); return _context.finish(41); case 44: if (!added && item.label.toLowerCase().includes(keyword)) { result.add(item); added = true; } if (!added && item.description && item.description.toLowerCase().includes(keyword)) result.add(item); case 46: _context.next = 14; break; case 48: _context.next = 53; break; case 50: _context.prev = 50; _context.t1 = _context["catch"](12); _iterator2.e(_context.t1); case 53: _context.prev = 53; _iterator2.f(); return _context.finish(53); case 56: _context.next = 9; break; case 58: _context.next = 63; break; case 60: _context.prev = 60; _context.t2 = _context["catch"](7); _iterator.e(_context.t2); case 63: _context.prev = 63; _iterator.f(); return _context.finish(63); case 66: return _context.abrupt("return", _toConsumableArray(result)); case 67: case "end": return _context.stop(); } } }, _callee, null, [[7, 60, 63, 66], [12, 50, 53, 56], [24, 38, 41, 44]]); })); return _search.apply(this, arguments); } return /*#__PURE__*/_react.default.createElement(_ClickAwayListener.default, { onClickAway: function onClickAway(event) { setFocused(false); inputRef.current && inputRef.current.blur(); } }, /*#__PURE__*/_react.default.createElement(_Paper.default, { elevation: 0, className: (0, _clsx.default)(classes.root, focused && classes.rootFocused, className), ref: function ref(element) { rootRef.current = element; if (_ref) _ref.current = element; }, style: style, onClick: function onClick(event) { return inputRef.current && inputRef.current.focus(); } }, /*#__PURE__*/_react.default.createElement(_Search.default, { className: classes.icon }), /*#__PURE__*/_react.default.createElement(_InputBase.default, { onChange: handleTextInput, value: text, className: classes.input, placeholder: "Search", onFocus: function onFocus(event) { return setFocused(true); } // onFocus={event => console.log(event)} // onBlur={event => console.log(("blur"))} , onKeyDown: handleKeyDown, inputRef: inputRef }), /*#__PURE__*/_react.default.createElement(_Close.default, { className: (0, _clsx.default)(classes.icon, classes.iconClickable), onClick: function onClick(event) { return setText(""); } }), /*#__PURE__*/_react.default.createElement(_Popper.default, { id: "search-menu", disablePortal: false, anchorEl: rootRef.current, open: !!text && focused, placement: "bottom-end", className: classes.popper, popperOptions: { positionFixed: true } }, /*#__PURE__*/_react.default.createElement(_Paper.default, { className: classes.listPaper, elevation: 2 }, /*#__PURE__*/_react.default.createElement(_List.default, { disablePadding: true }, found.map(function (item, index) { return /*#__PURE__*/_react.default.createElement(_SearchMenuItem.default, { onBeforeSelected: handleSearchItemSelected, active: index === selected, onMouseMove: function onMouseMove(event) { return setSelected(index); }, data: item, key: "search-menu-item-".concat(item.label) }); }), !found.length && /*#__PURE__*/_react.default.createElement(_ListItem.default, null, /*#__PURE__*/_react.default.createElement(_ListItemIcon.default, null, /*#__PURE__*/_react.default.createElement(_ErrorOutline.default, null)), /*#__PURE__*/_react.default.createElement(_ListItemText.default, { primary: "No results found", secondary: "Try to rephrase the query" }))))))); }); SearchField.displayName = displayName; SearchField.propTypes = { // SearchFieldProps searchData: _propTypes.default.arrayOf(_SearchDataItemValidator.default), doSearch: _propTypes.default.func, // Stylable style: _propTypes.default.object, className: _propTypes.default.string, classes: _propTypes.default.object }; var _default = (0, _styles2.withStyles)(_styles.styles, { name: displayName })(SearchField); exports.default = _default;