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
JavaScript
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