code-surfer
Version:
Rad code slides
391 lines (334 loc) • 10.4 kB
JavaScript
;
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var React = _interopDefault(require('react'));
var mdxDeck = require('mdx-deck');
var standalone = require('@code-surfer/standalone');
var shellQuote = require('shell-quote');
var useSpring = require('use-spring');
var themes = require('@code-surfer/themes');
function Step() {
return null;
}
function _extends() {
_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 _extends.apply(this, arguments);
}
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
/**
* The metastring is the thing that comes after the language in markdown codeblocks
*
* ```js this is the metastring
* code goes here
* ```
*/
function parseMetastring(metastring) {
if (!metastring) {
return {};
}
var argv = shellQuote.parse(metastring);
var result = {};
argv.forEach(function (arg) {
if (!arg.includes("=")) {
if (arg === "showNumbers") {
result["showNumbers"] = true;
} else {
result.focus = arg;
}
} else {
var _arg$split = arg.split(/=(.*)/),
key = _arg$split[0],
value = _arg$split[1];
if (value === "true") {
result[key] = true;
} else {
result[key] = value;
}
}
});
return result;
}
function isCode(element) {
return element && element.props && element.props.mdxType === "pre";
}
function readStepFromElement(element) {
if (!isCode(element)) {
throw new Error("Invalid element inside <CodeSurfer/>. Make sure to add empty lines (no spaces) before and after each codeblock.");
}
var props = element.props.children.props;
var className = props.className && props.className.split(" ")[0];
return _extends({
code: props.children,
lang: className && className.substring("language-".length)
}, parseMetastring(props.metastring));
}
var ErrorBoundary =
/*#__PURE__*/
function (_React$Component) {
_inheritsLoose(ErrorBoundary, _React$Component);
function ErrorBoundary(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.state = {};
return _this;
}
ErrorBoundary.getDerivedStateFromError = function getDerivedStateFromError(error) {
return {
error: error
};
};
var _proto = ErrorBoundary.prototype;
_proto.componentDidCatch = function componentDidCatch(error, info) {// console.log(error, info);
};
_proto.render = function render() {
if (!this.state.error) {
return this.props.children;
} else if (this.state.error.element) {
return this.state.error.element;
} else {
console.error(this.state.error);
return React.createElement(standalone.UnknownError, {
error: this.state.error
});
}
};
return ErrorBoundary;
}(React.Component);
function useSteps (stepsCount) {
var step = mdxDeck.useSteps(stepsCount);
return step === Infinity ? 0 : step;
}
function useStepSpring(stepsCount) {
// step index according to mdx-deck
var targetStepIndex = useSteps(stepsCount - 1); // real number between 0 and stepsCount - 1
var _useSpring = useSpring.useSpring(targetStepIndex, {
decimals: 3,
stiffness: 80,
damping: 48,
mass: 8
}),
currentStepSpring = _useSpring[0];
return currentStepSpring;
}
function CodeSurferLayout(_ref) {
var children = _ref.children,
theme = _ref.theme;
var deck = mdxDeck.useDeck();
var steps = React.useMemo(getStepsFromChildren(children), [deck.index]); // useNotes(steps.map(s => s.notesElement));
var progress = useStepSpring(steps.length);
return React.createElement("div", {
style: {
width: "100vw",
maxWidth: "100%",
height: "100vh",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
},
className: "cs-layout"
}, React.createElement(standalone.CodeSurfer, {
steps: steps,
progress: progress,
theme: theme
}));
}
var getStepsFromChildren = function getStepsFromChildren(children) {
return function () {
var steps = React.Children.map(children || [], function (child) {
return readStepFromElement(child);
}).filter(function (x) {
return x;
});
if (steps.length === 0) {
throw Error("No codeblocks found inside <CodeSurfer/>.");
}
return steps;
};
};
var layout = (function (props) {
return React.createElement(ErrorBoundary, null, React.createElement(CodeSurferLayout, Object.assign({}, props)));
});
function useNotes(notesElements) {
var context = mdxDeck.useDeck();
React.useEffect(function () {
if (!context || !context.register) return;
if (typeof context.index === "undefined") return;
var notes = getNotesFromElements(notesElements);
context.register(context.index, {
notes: notes
});
}, []);
}
function getNotesFromElements(notesElements) {
var notes = notesElements.map(function (element) {
if (!element) {
// this is a step with empty notes
return null;
}
var props = element.props;
if (props.inline) {
// this is <Notes inline={true} />
return {
inline: true,
text: props.children
};
} // this is <Notes>something</Notes>
// we shouldn't return an object here,
// to be compatible with the default Presenter
return props && props.children;
});
if (notes.length) {
var lastNotes = notes[notes.length - 1]; // we add an extra EOL to the last step
notes[notes.length - 1] = (lastNotes || "") + "\n";
}
return notes;
}
function ColumnLayout(_ref) {
var children = _ref.children,
_ref$themes = _ref.themes,
themes$1 = _ref$themes === void 0 ? [] : _ref$themes,
sizes = _ref.sizes;
var deck = mdxDeck.useDeck();
var _React$useMemo = React.useMemo(function () {
return getColumnsFromChildren(children, sizes);
}, [deck.index]),
columns = _React$useMemo[0],
titles = _React$useMemo[1],
subtitles = _React$useMemo[2],
notesElements = _React$useMemo[3];
useNotes(notesElements);
var progress = useStepSpring(columns[0].steps.length);
var stepIndex = Math.round(progress);
return React.createElement("div", {
style: {
width: "100vw",
maxWidth: "100%",
height: "100vh",
display: "flex",
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
fontSize: "0.8em",
position: "relative"
},
className: "cs-col-layout"
}, columns.map(function (column, i) {
return React.createElement(Column, {
key: i,
column: column,
progress: progress,
theme: themes$1[i]
});
}), React.createElement(themes.StylesProvider, null, React.createElement(Title, {
text: titles[stepIndex]
}), React.createElement(Subtitle, {
text: subtitles[stepIndex]
})));
}
function Column(_ref2) {
var column = _ref2.column,
progress = _ref2.progress,
theme = _ref2.theme;
return React.createElement("div", {
style: {
flex: column.flex,
overflow: "hidden",
height: "100%"
}
}, column.isCode ? React.createElement(standalone.CodeSurfer, {
steps: column.steps,
progress: progress,
theme: theme
}) : React.createElement("div", {
style: {
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100%"
}
}, column.steps[Math.round(progress)].element));
}
function Title(_ref3) {
var text = _ref3.text;
if (!text) return null;
return React.createElement(themes.Styled.Title, {
className: "cs-title"
}, React.createElement("span", null, text));
}
function Subtitle(_ref4) {
var text = _ref4.text;
if (!text) return null;
return React.createElement(themes.Styled.Subtitle, {
className: "cs-subtitle",
style: {
margin: "0.3em 0"
}
}, React.createElement("span", null, text));
}
function getColumnsFromChildren(children, sizes) {
if (sizes === void 0) {
sizes = [];
}
var columns = [];
var stepElements = React.Children.toArray(children);
if (stepElements.length === 0) {
throw Error("No <Step/> found inside <CodeSurferColumns/>.");
}
stepElements.forEach(function (stepElement, stepIndex) {
React.Children.toArray(stepElement.props.children).forEach(function (cellElement, columnIndex) {
if (!cellElement || !cellElement.props) {
throw Error("Invalid element inside <Step/>. Make sure to add empty lines (no spaces) before and after each element.");
}
columns[columnIndex] = columns[columnIndex] || {
steps: [],
isCode: true
};
var step = isCode(cellElement) ? readStepFromElement(cellElement) : {
element: cellElement
};
columns[columnIndex].steps[stepIndex] = step;
columns[columnIndex].isCode = columns[columnIndex].isCode && isCode(cellElement);
});
});
if (columns.length === 0) {
throw Error("<Step/> shouldn't be empty.");
}
columns.forEach(function (column, columnIndex) {
column.flex = sizes[columnIndex] || 1;
});
var titles = stepElements.map(function (stepElement) {
return stepElement.props.title;
});
var subtitles = stepElements.map(function (stepElement) {
return stepElement.props.subtitle;
});
var notesElements = stepElements.map(function (stepElement) {
var stepChildren = React.Children.toArray(stepElement.props.children);
var notesElement = stepChildren.find(function (element) {
return element.props && element.props.originalType === mdxDeck.Notes;
});
return notesElement;
});
return [columns, titles, subtitles, notesElements];
}
var columnLayout = (function (props) {
return React.createElement(ErrorBoundary, null, React.createElement(ColumnLayout, Object.assign({}, props)));
});
exports.CodeSurfer = layout;
exports.CodeSurferColumns = columnLayout;
exports.Step = Step;
//# sourceMappingURL=code-surfer.cjs.development.js.map