UNPKG

react-doc-helper

Version:

A React component library for building interactive documentation layouts with code examples, tables, tags, and automatic table of contents support.

340 lines (328 loc) 12.2 kB
import React, { useState, useEffect, createContext, useContext } from 'react'; import { scroller, Element } from 'react-scroll'; import { CopyBlock, dracula, github } from 'react-code-blocks'; import { CopyToClipboard } from 'react-copy-to-clipboard'; function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } var defaultSettings = { offsetTop: '1rem', codeBlockTheme: 'github' }; var DHContext = /*#__PURE__*/createContext(undefined); var DHProvider = function DHProvider(_ref) { var children = _ref.children, initialSettings = _ref.settings; var _useState = useState(_extends({}, defaultSettings, initialSettings)), settings = _useState[0], setSettings = _useState[1]; useEffect(function () { if (initialSettings && typeof initialSettings === 'object') { setSettings(function (prevState) { return _extends({}, prevState, initialSettings); }); } }, [initialSettings]); return React.createElement(DHContext.Provider, { value: { settings: settings, setSettings: setSettings } }, children); }; // Hook for easier access var useDHContext = function useDHContext() { var context = useContext(DHContext); if (!context) { throw new Error('useDHContext must be used within a DHProvider'); } return context; }; /** * Creates a scroll handler function for smooth scrolling to a specific section. * * @param sectionName - The name of the element to scroll to (matches react-scroll's <Element name="">) * @param config - Optional scroll configuration * @returns A function that can be called directly or passed as an event handler */ var scrollTo = function scrollTo(sectionName, config) { if (config === void 0) { config = {}; } return function (e) { if (e && typeof e.preventDefault === 'function') { e.preventDefault(); } scroller.scrollTo(sectionName, _extends({ duration: 400, delay: 0, smooth: 'easeInOutQuart' }, config)); }; }; var DHContainer = function DHContainer(_ref) { var title = _ref.title, content = _ref.content, children = _ref.children; var _useDHContext = useDHContext(), settings = _useDHContext.settings; var _useState = useState([]), toc = _useState[0], setToc = _useState[1]; useEffect(function () { var generateToc = function generateToc(items) { var tocItems = []; var _traverse = function traverse(items, level) { if (level === void 0) { level = 0; } React.Children.forEach(React.Children.toArray(items), function (item) { var _item$type; var elementType = ((_item$type = item.type) == null ? void 0 : _item$type.displayName) || ''; if (React.isValidElement(item) && elementType === 'DHBlock') { var element = item; tocItems.push({ id: element.props.id, title: element.props.title, level: level }); if (element.props.children) _traverse(element.props.children, level + 1); } }); }; _traverse(items); return tocItems; }; setToc(generateToc(children)); }, [children]); var onScroll = function onScroll(e, id) { e.preventDefault(); scrollTo("doc-helper__" + id, { offset: -130 })(e); }; return React.createElement("div", null, React.createElement("div", { className: "doc-helper doc-helper__container" }, React.createElement("nav", { className: "doc-helper__toc" }, React.createElement("ul", { className: '', style: { top: (settings == null ? void 0 : settings.offsetTop) || '0px' } }, toc.map(function (item) { return React.createElement("li", { style: { paddingLeft: item.level * 15 + 12 }, key: item.id }, React.createElement("a", { onClick: function onClick(e) { return onScroll(e, item.id); }, className: "doc-helper__toc-item " + (item.level > 0 ? 'doc-helper__toc-nested' : '') }, item.level > 0 && React.createElement("span", null, "-"), React.createElement("span", null, item.title))); }))), React.createElement("div", { className: "doc-helper__body" }, React.createElement("div", { className: "" }, React.createElement("h1", { className: "" }, title), content && React.createElement("div", null, content)), children))); }; DHContainer.displayName = 'DHContainer'; var DHCode = function DHCode(_ref) { var _ref$lang = _ref.lang, lang = _ref$lang === void 0 ? 'javascript' : _ref$lang, code = _ref.code, _ref$showLineNumbers = _ref.showLineNumbers, showLineNumbers = _ref$showLineNumbers === void 0 ? false : _ref$showLineNumbers, className = _ref.className, filename = _ref.filename; var _useDHContext = useDHContext(), settings = _useDHContext.settings; // Pick theme from context or fallback to 'github' var theme = settings.codeBlockTheme === 'dracula' ? dracula : settings.codeBlockTheme === 'github' ? github : github; return React.createElement("div", { className: "doc-helper__code " + (className || '') }, filename && React.createElement("div", { className: "doc-helper__code-filename" }, filename), React.createElement("div", { className: "doc-helper__code-block" }, React.createElement(CopyBlock, { language: lang, text: code, codeBlock: true, theme: theme, showLineNumbers: showLineNumbers }))); }; DHCode.displayName = 'DHCode'; var DHScrollTo = function DHScrollTo(_ref) { var id = _ref.id, className = _ref.className, children = _ref.children; var onScroll = function onScroll(e, id) { e.preventDefault(); scrollTo("doc-helper__" + id, { offset: -130 })(); }; return React.createElement("a", { className: "doc-helper__anchor " + className, href: "#", onClick: function onClick(e) { return onScroll(e, id); } }, children); }; DHScrollTo.displayName = 'DHScrollTo'; var DHBlock = function DHBlock(_ref) { var id = _ref.id, _ref$titleType = _ref.titleType, Tag = _ref$titleType === void 0 ? 'h2' : _ref$titleType, title = _ref.title, content = _ref.content, children = _ref.children; return React.createElement(Element, { name: "doc-helper__" + id }, React.createElement("div", { className: "doc-helper__block" }, React.createElement(Tag, { className: "doc-helper__title", id: "doc-helper__" + id }, React.createElement(DHScrollTo, { id: id }, title)), content && React.createElement("div", { className: "doc-helper__content" }, content), children && React.createElement("div", { className: "doc-helper__children" }, children))); }; DHBlock.displayName = 'DHBlock'; var CopiedIcon = function CopiedIcon(_ref) { var className = _ref.className; return React.createElement("svg", { className: className, viewBox: "0 0 384 512", width: "1em", height: "1em", fill: "currentColor" }, React.createElement("path", { d: "M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm121.2 231.8l-143 141.8c-4.7 4.7-12.3 4.6-17-.1l-82.6-83.3c-4.7-4.7-4.6-12.3.1-17L99.1 285c4.7-4.7 12.3-4.6 17 .1l46 46.4 106-105.2c4.7-4.7 12.3-4.6 17 .1l28.2 28.4c4.7 4.8 4.6 12.3-.1 17z" })); }; var CopyIcon = function CopyIcon(_ref2) { var className = _ref2.className; return React.createElement("svg", { className: className, viewBox: "0 0 384 512", width: "1em", height: "1em", fill: "currentColor" }, React.createElement("path", { d: "M280 240H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zm0 96H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zM112 232c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zM336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 48c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm144 408c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V120c0-4.4 3.6-8 8-8h40v32c0 8.8 7.2 16 16 16h160c8.8 0 16-7.2 16-16v-32h40c4.4 0 8 3.6 8 8v336z" })); }; var DHTags = function DHTags(_ref3) { var tags = _ref3.tags, _ref3$showCopyIcon = _ref3.showCopyIcon, showCopyIcon = _ref3$showCopyIcon === void 0 ? true : _ref3$showCopyIcon, _ref3$className = _ref3.className, className = _ref3$className === void 0 ? '' : _ref3$className, _ref3$size = _ref3.size, size = _ref3$size === void 0 ? 'default' : _ref3$size; var _useState = useState(null), copied = _useState[0], setCopied = _useState[1]; var _onCopy = function onCopy(value) { setCopied(value); setTimeout(function () { return setCopied(null); }, 3000); // reset copied after 3s }; return React.createElement("div", { className: "doc-helper__tags " + className }, tags.map(function (item, i) { return React.createElement(CopyToClipboard, { text: item, onCopy: function onCopy() { return _onCopy(item); }, key: i }, React.createElement("span", { className: "doc-helper__tag " + (size === 'default' ? '' : 'doc-helper__tag--sm') }, React.createElement("span", null, item), showCopyIcon && React.createElement("button", { className: "doc-helper__tag-copy " + (copied === item ? 'doc-helper__tag-copy--active' : ''), type: "button" }, copied === item ? React.createElement(CopiedIcon, null) : React.createElement(CopyIcon, null)))); })); }; DHTags.displayName = 'DHTags'; var DHTable = function DHTable(_ref) { var data = _ref.data, _ref$header = _ref.header, header = _ref$header === void 0 ? ['Property', 'Description', 'Type', 'Default'] : _ref$header; return React.createElement("div", { className: "doc-helper__table" }, React.createElement("table", { className: "doc-helper__table-element" }, React.createElement("thead", { className: "doc-helper__table-head" }, React.createElement("tr", null, header.map(function (item, i) { return React.createElement("th", { key: i, className: "doc-helper__table-header" }, item); }))), React.createElement("tbody", { className: "doc-helper__table-body" }, data.map(function (row, i) { return React.createElement("tr", { key: i }, row.map(function (item, ii) { return React.createElement("td", { key: ii, className: "doc-helper__table-cell" }, Array.isArray(item) && !item.some(React.isValidElement) ? React.createElement(DHTags, { size: "sm", tags: item, className: "!mb-0" }) : item); })); })))); }; DHTable.displayName = 'DHTable'; var DHTabs = function DHTabs(_ref) { var _tabs$find; var tabs = _ref.tabs, initialTab = _ref.initialTab; var _useState = useState(initialTab), activeTab = _useState[0], setActiveTab = _useState[1]; var tabContent = (_tabs$find = tabs.find(function (e) { return e.key === activeTab; })) == null ? void 0 : _tabs$find.content; return React.createElement("div", { className: "doc-helper__tabs" }, React.createElement("div", { className: "doc-helper__tabs-header" }, tabs.map(function (tab) { return React.createElement("button", { className: "doc-helper__tabs-button " + (tab.key === activeTab ? 'active' : ''), onClick: function onClick() { return setActiveTab(tab.key); } }, tab.label); })), React.createElement("div", { className: "doc-helper__tabs-content" }, tabContent)); }; DHTabs.displayName = 'DHTabs'; export { DHBlock, DHCode, DHContainer, DHProvider, DHScrollTo, DHTable, DHTabs, DHTags }; //# sourceMappingURL=react-doc-helper.esm.js.map