@code-surfer/standalone
Version:
Code Surfer React component
1,099 lines (979 loc) • 32.8 kB
JavaScript
import React from 'react';
import { parseSteps } from '@code-surfer/step-parser';
import { useUnfocusedStyle, Styled, StylesProvider } from '@code-surfer/themes';
import 'prismjs/components/prism-markup';
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-clike';
import 'prismjs/components/prism-c';
import 'prismjs/components/prism-cpp';
import 'prismjs/components/prism-css';
import 'prismjs/components/prism-css-extras';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-jsx';
import 'prismjs/components/prism-js-extras';
import 'prismjs/components/prism-coffeescript';
import 'prismjs/components/prism-diff';
import 'prismjs/components/prism-git';
import 'prismjs/components/prism-go';
import 'prismjs/components/prism-graphql';
import 'prismjs/components/prism-json';
import 'prismjs/components/prism-less';
import 'prismjs/components/prism-makefile';
import 'prismjs/components/prism-markdown';
import 'prismjs/components/prism-objectivec';
import 'prismjs/components/prism-ocaml';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-reason';
import 'prismjs/components/prism-sass';
import 'prismjs/components/prism-scss';
import 'prismjs/components/prism-sql';
import 'prismjs/components/prism-stylus';
import 'prismjs/components/prism-typescript';
import 'prismjs/components/prism-wasm';
import 'prismjs/components/prism-yaml';
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;
}
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;
}
function UnknownError(_ref) {
var error = _ref.error;
// TODO link to create issue
return React.createElement(ErrorBox, {
header: "Oops, there's a problem",
body: error.toString()
});
}
function ErrorBox(_ref3) {
var header = _ref3.header,
body = _ref3.body;
return React.createElement("div", {
style: {
background: "#290000",
color: "#b96f70",
border: "2px solid #b96f70",
padding: "10px 30px",
maxWidth: "90vw",
margin: "0 auto",
fontFamily: "monospace",
fontSize: "1rem"
}
}, React.createElement("h3", null, header), React.createElement("p", null, body));
}
// type addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
function useWindowResize(handler, deps) {
React.useEffect(function () {
window.addEventListener("resize", handler);
return function () {
window.removeEventListener("resize", handler);
};
}, deps);
}
function useDimensions(ref, steps) {
var _React$useState = React.useState(null),
result = _React$useState[0],
setResult = _React$useState[1]; // TODO reset only if container size changed
useWindowResize(function () {
return setResult(null);
}, [setResult]);
React.useLayoutEffect(function () {
if (!ref.current) return;
if (result) return;
var containers = ref.current.querySelectorAll(".cs-container");
var stepsDimensions = Array.from(containers).map(function (container, i) {
return getStepDimensions(container, steps[i]);
});
var containerHeight = Math.max.apply(Math, stepsDimensions.map(function (d) {
return d.containerHeight;
}));
var containerWidth = Math.max.apply(Math, stepsDimensions.map(function (d) {
return d.containerWidth;
}));
var contentWidth = Math.max.apply(Math, stepsDimensions.map(function (d) {
return d.contentWidth;
}));
var lineHeight = Math.max.apply(Math, stepsDimensions.map(function (d) {
return d.lineHeight;
}));
setResult({
dimensions: {
lineHeight: lineHeight,
contentWidth: contentWidth,
containerHeight: containerHeight,
containerWidth: containerWidth,
// TODO set or remove
contentHeight: undefined
},
steps: steps.map(function (step, i) {
return _extends({}, step, {
dimensions: {
paddingTop: stepsDimensions[i].paddingTop,
paddingBottom: stepsDimensions[i].paddingBottom
}
});
})
});
}, [result]);
return result || {};
}
function getStepDimensions(container, step) {
var longestLineKey = step.lines[step.longestLineIndex];
var longestLineSpan = container.querySelector(".cs-line-" + longestLineKey);
var containerParent = container.parentElement;
var title = container.querySelector(".cs-title");
var subtitle = container.querySelector(".cs-subtitle");
var lineCount = step.lines.length;
var heightOverflow = containerParent.scrollHeight - containerParent.clientHeight;
var avaliableHeight = container.scrollHeight - heightOverflow;
var lineHeight = longestLineSpan ? longestLineSpan.clientHeight : 0;
var paddingTop = title ? outerHeight(title) : lineHeight;
var paddingBottom = subtitle ? outerHeight(subtitle) : lineHeight;
var codeHeight = lineCount * lineHeight * 2; // const maxContentHeight = codeHeight + paddingTop + paddingBottom;
// const containerHeight = Math.min(maxContentHeight, avaliableHeight);
var containerHeight = avaliableHeight;
var containerWidth = container.clientWidth;
var contentHeight = codeHeight + containerHeight;
var contentWidth = longestLineSpan ? longestLineSpan.clientWidth : 0;
return {
lineHeight: lineHeight,
contentHeight: contentHeight,
contentWidth: contentWidth,
paddingTop: paddingTop,
paddingBottom: paddingBottom,
containerHeight: containerHeight,
containerWidth: containerWidth
};
}
function outerHeight(element) {
var styles = window.getComputedStyle(element);
var margin = parseFloat(styles["marginTop"] || "0") + parseFloat(styles["marginBottom"] || "0");
return element.offsetHeight + margin;
}
var easing = {
// no easing, no acceleration
linear: function linear(t) {
return t;
},
// accelerating from zero velocity
easeInQuad: function easeInQuad(t) {
return t * t;
},
// decelerating to zero velocity
easeOutQuad: function easeOutQuad(t) {
return t * (2 - t);
},
// acceleration until halfway, then deceleration
easeInOutQuad: function easeInOutQuad(t) {
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
},
// accelerating from zero velocity
easeInCubic: function easeInCubic(t) {
return t * t * t;
},
// decelerating to zero velocity
easeOutCubic: function easeOutCubic(t) {
return --t * t * t + 1;
},
// acceleration until halfway, then deceleration
easeInOutCubic: function easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
},
// accelerating from zero velocity
easeInQuart: function easeInQuart(t) {
return t * t * t * t;
},
// decelerating to zero velocity
easeOutQuart: function easeOutQuart(t) {
return 1 - --t * t * t * t;
},
// acceleration until halfway, then deceleration
easeInOutQuart: function easeInOutQuart(t) {
return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
},
// accelerating from zero velocity
easeInQuint: function easeInQuint(t) {
return t * t * t * t * t;
},
// decelerating to zero velocity
easeOutQuint: function easeOutQuint(t) {
return 1 + --t * t * t * t * t;
},
// acceleration until halfway, then deceleration
easeInOutQuint: function easeInOutQuint(t) {
return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;
}
};
var distx = 250;
var outHeight = 0;
var EXIT = 0.25,
SCROLL = 0.75,
ENTER = 1;
function emptyStyle() {
return {};
}
function exitLine(fromOpacity, toOpacity, staggerIndex, staggerLength, lineHeight) {
if (lineHeight === void 0) {
lineHeight = 100;
}
return chain([[EXIT, stagger(slideToLeft(fromOpacity, toOpacity), staggerIndex, staggerLength)], [SCROLL, shrinkHeight(lineHeight)], [ENTER, undefined]], {
height: lineHeight
});
}
function enterLine(fromOpacity, toOpacity, staggerIndex, staggerLength, lineHeight) {
if (lineHeight === void 0) {
lineHeight = 100;
}
return chain([[EXIT, undefined], [SCROLL, growHeight(lineHeight)], [ENTER, stagger(slideFromRight(fromOpacity, toOpacity), staggerIndex, staggerLength)]], {
transform: "translateX(" + distx + "px)",
height: 0,
opacity: 0
});
}
function fadeInFocus(fromOpacity, toOpacity, staggerIndex, staggerLength) {
return chain([[EXIT, undefined], [SCROLL, undefined], [ENTER, stagger(function (t) {
return {
opacity: tween(fromOpacity, toOpacity, t)
};
}, staggerIndex, staggerLength)]], {
opacity: fromOpacity
});
}
function fadeOutFocus(fromOpacity, toOpacity, staggerIndex, staggerLength) {
return chain([[EXIT, stagger(function (t) {
return {
opacity: tween(fromOpacity, toOpacity, t)
};
}, staggerIndex, staggerLength)], [SCROLL, undefined], [ENTER, undefined]], {
opacity: fromOpacity
});
}
function fadeOutIn(offOpacity) {
if (offOpacity === void 0) {
offOpacity = 0;
}
return chain([[0.5, fadeOut(offOpacity)], [1, fadeIn(offOpacity)]]);
}
function halfFadeIn(offOpacity) {
if (offOpacity === void 0) {
offOpacity = 0;
}
return chain([[0.5, undefined], [1, fadeIn(offOpacity)]], {
opacity: 0
});
}
function halfFadeOut(offOpacity) {
if (offOpacity === void 0) {
offOpacity = 0;
}
return chain([[0.5, fadeOut(offOpacity)], [1, undefined]]);
}
function scrollToFocus(stepPair, dimensions) {
if (!dimensions) {
return function () {
return 0;
};
}
var _stepPair$spread = stepPair.spread(),
prevStep = _stepPair$spread[0],
nextStep = _stepPair$spread[1];
var prevCenter = prevStep ? prevStep.focusCenter * dimensions.lineHeight : 0;
var nextCenter = nextStep ? nextStep.focusCenter * dimensions.lineHeight : 0;
var animation = chain([[EXIT, undefined], [SCROLL, function (t) {
return {
scroll: tween(prevCenter, nextCenter, t, easing.easeInOutCubic)
};
}], [ENTER, undefined]], {
scroll: prevCenter
});
return function (t) {
return animation(t).scroll;
};
}
function scaleToFocus(stepPair, dimensions) {
if (!dimensions) {
return function () {
return 1;
};
}
var _stepPair$spread2 = stepPair.spread(),
prev = _stepPair$spread2[0],
next = _stepPair$spread2[1];
var prevZoom = getZoom(prev, dimensions);
var nextZoom = getZoom(next, dimensions);
return function (t) {
return tween(prevZoom || nextZoom, nextZoom || prevZoom, t, easing.easeInOutQuad);
};
} //
function slideToLeft(startOpacity, endOpacity) {
return function (t) {
return {
opacity: tween(startOpacity, endOpacity, t),
transform: "translateX(" + tween(0, -distx, t) + "px)"
};
};
}
function slideFromRight(startOpacity, endOpacity) {
return function (t) {
return {
opacity: tween(startOpacity, endOpacity, t),
transform: "translateX(" + tween(distx, 0, t) + "px)"
};
};
}
function shrinkHeight(lineHeight) {
return function (t) {
return {
height: tween(lineHeight, outHeight, t, easing.easeInOutCubic)
};
};
}
function growHeight(lineHeight) {
return function (t) {
return {
height: tween(outHeight, lineHeight, t, easing.easeInOutCubic)
};
};
}
function fadeOut(offOpacity) {
if (offOpacity === void 0) {
offOpacity = 0;
}
return function (t) {
return {
opacity: tween(1, offOpacity, t)
};
};
}
function fadeIn(offOpacity) {
if (offOpacity === void 0) {
offOpacity = 0;
}
return function (t) {
return {
opacity: tween(offOpacity, 1, t)
};
};
}
function tween(from, to, t, ease) {
if (ease === void 0) {
ease = easing.linear;
}
return from + (to - from) * ease(t);
}
function chain(steps, start) {
if (start === void 0) {
start = {};
}
return function (t) {
var style = Object.assign({}, start);
var prevTop = 0;
for (var i = 0; i < steps.length; i++) {
var _steps$i = steps[i],
top = _steps$i[0],
fn = _steps$i[1];
var stept = t > top ? 1 : (t - prevTop) / (top - prevTop);
if (fn) {
Object.assign(style, fn(stept));
}
if (t < top) {
return style;
}
prevTop = top;
}
return style;
};
}
function stagger(animation, staggerIndex, staggerLength, interval) {
if (interval === void 0) {
interval = 0.3;
}
if (staggerLength <= 1) return animation;
var steps = interval / (staggerLength - 1);
var start = steps * staggerIndex;
var end = 1 - interval + start;
return function (t) {
var st = Math.max(0, Math.min(1, (t - start) / (end - start)));
return animation(st);
};
}
function getZoom(step, dimensions) {
if (!step) return null;
if (!dimensions || !step.dimensions) throw new Error("Can't get zoom without dimensions");
var containerHeight = dimensions.containerHeight,
containerWidth = dimensions.containerWidth,
contentWidth = dimensions.contentWidth,
lineHeight = dimensions.lineHeight;
var _step$dimensions = step.dimensions,
paddingBottom = _step$dimensions.paddingBottom,
paddingTop = _step$dimensions.paddingTop;
var contentHeight = step.focusCount * lineHeight;
var availableHeight = containerHeight - Math.max(paddingBottom, paddingTop) * 2;
var yZoom = availableHeight / contentHeight; // if there are lines that are too long for the container
var xZoom = 0.9 * containerWidth / contentWidth;
return Math.min(yZoom, 1, xZoom);
}
function LineList(_ref) {
var stepPair = _ref.stepPair,
t = _ref.t,
tokens = _ref.tokens,
types = _ref.types,
dimensions = _ref.dimensions,
unfocusedStyle = _ref.unfocusedStyle,
maxLineCount = _ref.maxLineCount,
showNumbers = _ref.showNumbers;
var lines = React.useMemo(function () {
var linesPair = stepPair.selectMany(function (step) {
return step.lines.map(function (lineKey, lineIndex) {
return {
key: lineKey,
lineNumber: lineIndex + 1,
focus: step.focus[lineIndex]
};
});
});
var fadeInLines = linesPair.map(function (linePair, lineKey) {
var _linePair$spread = linePair.spread(),
prev = _linePair$spread[0];
var _linePair$select$spre = linePair.select(function (l) {
return l.focus;
}).spread(),
prevFocus = _linePair$select$spre[0],
nextFocus = _linePair$select$spre[1];
var isFadeIn = !prev || !prevFocus && nextFocus || nextFocus && Array.isArray(prevFocus);
return isFadeIn ? lineKey : -1;
}).filter(function (key) {
return key !== -1;
});
var fadeOutLines = linesPair.map(function (linePair, lineKey) {
var _linePair$spread2 = linePair.spread(),
next = _linePair$spread2[1];
var _linePair$select$spre2 = linePair.select(function (l) {
return l.focus;
}).spread(),
prevFocus = _linePair$select$spre2[0],
nextFocus = _linePair$select$spre2[1];
var isFadeOut = !next || !nextFocus && prevFocus || prevFocus && Array.isArray(nextFocus);
return isFadeOut ? lineKey : -1;
}).filter(function (key) {
return key !== -1;
});
return linesPair.map(function (lineTuple, lineKey) {
var offOpacity = unfocusedStyle.opacity;
var _lineTuple$spread = lineTuple.spread(),
prevLine = _lineTuple$spread[0],
nextLine = _lineTuple$spread[1];
var _lineTuple$select$spr = lineTuple.select(function (l) {
return l.focus;
}).spread(),
prevFocus = _lineTuple$select$spr[0],
nextFocus = _lineTuple$select$spr[1];
var isMoving = !prevLine || !nextLine;
var isChangingFocus = prevFocus !== nextFocus;
var isStatic = !isMoving && !isChangingFocus;
var areTokensAnimated = !isStatic && (Array.isArray(prevFocus) || Array.isArray(nextFocus));
var areTokensStatic = !areTokensAnimated;
var tokenElements = areTokensStatic && tokens[lineKey].map(function (token, tokeni) {
return React.createElement("span", {
className: "token-" + types[lineKey][tokeni],
key: tokeni
}, token);
});
var _ref2 = dimensions || {},
lineHeight = _ref2.lineHeight;
var anyLine = lineTuple.any();
var pad = maxLineCount.toString().replace(/./g, " ");
var lineNumber = anyLine ? (pad + anyLine.lineNumber).slice(-pad.length) : "";
var lineNumberElement = showNumbers && React.createElement("span", {
className: "token-line-number"
}, lineNumber + " ");
var lineElement = isStatic && React.createElement("div", {
style: {
overflow: "hidden",
opacity: prevFocus ? undefined : offOpacity,
height: lineHeight
},
key: lineKey
}, lineNumberElement, React.createElement("div", {
style: {
display: "inline-block"
},
className: "cs-line cs-line-" + lineKey
}, tokenElements));
var getLineStyle = emptyStyle;
if (!isStatic) {
if (!prevLine) {
var fadeInIndex = fadeInLines.indexOf(lineKey);
var fromOpacity = Array.isArray(nextFocus) ? 1 : 0;
var toOpacity = nextFocus ? 1 : offOpacity;
getLineStyle = enterLine(fromOpacity, toOpacity, fadeInIndex, fadeInLines.length, lineHeight);
} else if (!nextLine) {
var fadeOutIndex = fadeOutLines.indexOf(lineKey);
var _fromOpacity = prevFocus ? 1 : offOpacity;
var _toOpacity = Array.isArray(prevFocus) ? 1 : 0;
getLineStyle = exitLine(_fromOpacity, _toOpacity, fadeOutIndex, fadeOutLines.length, lineHeight);
} else if (!prevFocus && nextFocus && !Array.isArray(nextFocus)) {
var _fadeInIndex = fadeInLines.indexOf(lineKey);
getLineStyle = fadeInFocus(offOpacity, 1, _fadeInIndex, fadeInLines.length);
} else if (prevFocus && !nextFocus && !Array.isArray(prevFocus)) {
var _fadeOutIndex = fadeOutLines.indexOf(lineKey);
getLineStyle = fadeOutFocus(1, offOpacity, _fadeOutIndex, fadeOutLines.length);
}
}
var getTokenStyle = emptyStyle;
if (!areTokensStatic) {
var fromFocus = tokens[lineKey].map(function (_, tokeni) {
return Array.isArray(prevFocus) ? prevFocus.includes(tokeni) : prevFocus;
});
var toFocus = tokens[lineKey].map(function (_, tokeni) {
return Array.isArray(nextFocus) ? nextFocus.includes(tokeni) : nextFocus;
});
var _fadeInIndex2 = fadeInLines.indexOf(lineKey);
var _fadeOutIndex2 = fadeOutLines.indexOf(lineKey);
getTokenStyle = function getTokenStyle(t, i) {
var fromOpacity = !prevLine ? 0 : fromFocus[i] ? 1 : offOpacity;
var toOpacity = !nextLine ? 0 : toFocus[i] ? 1 : offOpacity;
var animation = fromOpacity < toOpacity ? fadeInFocus(fromOpacity, toOpacity, _fadeInIndex2, fadeInLines.length) : fadeOutFocus(fromOpacity, toOpacity, _fadeOutIndex2, fadeOutLines.length);
return animation(t);
};
}
return {
lineKey: lineKey,
lineElement: lineElement,
tokenElements: tokenElements,
getLineStyle: getLineStyle,
getTokenStyle: getTokenStyle,
lineNumberElement: lineNumberElement
};
});
}, [stepPair]);
return React.createElement(React.Fragment, null, lines.map(function (_ref3) {
var lineElement = _ref3.lineElement,
lineKey = _ref3.lineKey,
tokenElements = _ref3.tokenElements,
getLineStyle = _ref3.getLineStyle,
getTokenStyle = _ref3.getTokenStyle,
lineNumberElement = _ref3.lineNumberElement;
return lineElement || React.createElement("div", {
style: _extends({
overflow: "hidden"
}, getLineStyle(t)),
key: lineKey
}, React.createElement("div", {
style: {
display: "inline-block"
},
className: "cs-line cs-line-" + lineKey
}, lineNumberElement, tokenElements || tokens[lineKey].map(function (token, tokeni) {
return React.createElement("span", {
className: "token-" + types[lineKey][tokeni],
style: getTokenStyle(t, tokeni),
key: tokeni
}, token);
})));
}));
}
var Tuple =
/*#__PURE__*/
function () {
function Tuple(prev, next) {
this.prev = prev;
this.next = next;
}
var _proto = Tuple.prototype;
_proto.spread = function spread() {
var prev = this.prev;
var next = this.next;
return [prev, next];
};
_proto.select = function select(selector) {
var _this$spread = this.spread(),
prev = _this$spread[0],
next = _this$spread[1];
var newPrev = prev === null ? null : prev === undefined ? undefined : selector(prev),
newNext = next === null ? null : next === undefined ? undefined : selector(next);
return new Tuple(newPrev, newNext);
};
_proto.selectMany = function selectMany(selector) {
var _this$spread2 = this.spread(),
prev = _this$spread2[0],
next = _this$spread2[1];
var newPrev = prev === null ? null : prev === undefined ? undefined : selector(prev),
newNext = next === null ? null : next === undefined ? undefined : selector(next);
return new ArrayTuple(newPrev, newNext);
};
_proto.any = function any() {
var _this$spread3 = this.spread(),
prev = _this$spread3[0],
next = _this$spread3[1];
return prev == null ? next : prev;
};
_proto.get = function get(_key) {
throw Error("Get only supported in ArrayTuple");
};
_proto.map = function map(_mapper) {
throw Error("Map only supported in ArrayTuple");
};
return Tuple;
}();
var ArrayTuple =
/*#__PURE__*/
function (_Tuple) {
_inheritsLoose(ArrayTuple, _Tuple);
function ArrayTuple() {
return _Tuple.apply(this, arguments) || this;
}
var _proto2 = ArrayTuple.prototype;
_proto2._getChildrenMap = function _getChildrenMap() {
if (!this._dict) {
var _this$spread4 = this.spread(),
maybePrevs = _this$spread4[0],
maybeNexts = _this$spread4[1];
var prevs = maybePrevs || [];
var nexts = maybeNexts || [];
var unsortedMap = new Map(prevs.map(function (prev) {
return [prev.key, {
prev: prev
}];
}));
nexts.forEach(function (next) {
var _ref = unsortedMap.get(next.key) || {
prev: undefined
},
prev = _ref.prev;
unsortedMap.set(next.key, {
prev: prev,
next: next
});
});
var sortedKeys = Array.from(unsortedMap.keys());
sortedKeys.sort(function (a, b) {
return a < b ? -1 : a > b ? 1 : 0;
});
this._dict = new Map(sortedKeys.map(function (key) {
var _ref2 = unsortedMap.get(key) || {},
_ref2$prev = _ref2.prev,
prev = _ref2$prev === void 0 ? undefined : _ref2$prev,
_ref2$next = _ref2.next,
next = _ref2$next === void 0 ? undefined : _ref2$next;
return [key, new Tuple(prev, next)];
}));
}
return this._dict;
};
_proto2.get = function get(key) {
var childrenMap = this._getChildrenMap();
return childrenMap.get(key);
};
_proto2.map = function map(mapper) {
var _this = this;
var childrenMap = this._getChildrenMap();
var result = [];
childrenMap.forEach(function (tuple, key) {
return result.push(mapper(tuple, key, _this));
});
return result;
};
return ArrayTuple;
}(Tuple);
function CodeSurferContainer(_ref) {
var progress = _ref.progress,
dimensions = _ref.dimensions,
steps = _ref.steps,
tokens = _ref.tokens,
types = _ref.types,
maxLineCount = _ref.maxLineCount,
showNumbers = _ref.showNumbers;
var prev = steps[Math.floor(progress)];
var next = steps[Math.floor(progress) + 1];
var stepPair = React.useMemo(function () {
return new Tuple(prev, next);
}, [prev, next]);
var titlePair = React.useMemo(function () {
return stepPair.select(function (step) {
return step.title;
});
}, [stepPair]);
var subtitlePair = React.useMemo(function () {
return stepPair.select(function (step) {
return step.subtitle;
});
}, [stepPair]);
var t = progress % 1;
return React.createElement("div", {
className: "cs-container",
style: {
width: "100%",
height: dimensions ? dimensions.containerHeight : "100%",
maxHeight: "100%",
position: "relative"
}
}, React.createElement(CodeSurferContent, {
dimensions: dimensions,
stepPair: stepPair,
t: t,
tokens: tokens,
types: types,
maxLineCount: maxLineCount,
showNumbers: showNumbers
}), React.createElement(Title, {
textPair: titlePair,
t: t
}), React.createElement(Subtitle, {
textPair: subtitlePair,
t: t
}));
}
function CodeSurferContent(_ref2) {
var dimensions = _ref2.dimensions,
stepPair = _ref2.stepPair,
t = _ref2.t,
tokens = _ref2.tokens,
types = _ref2.types,
maxLineCount = _ref2.maxLineCount,
showNumbers = _ref2.showNumbers;
var ref = React.useRef(null);
var scaleAnimation = React.useMemo(function () {
return scaleToFocus(stepPair, dimensions);
}, [stepPair, dimensions]);
var scrollAnimation = React.useMemo(function () {
return scrollToFocus(stepPair, dimensions);
}, [stepPair, dimensions]);
var scale = scaleAnimation(t);
var scrollTop = scrollAnimation(t);
var verticalOrigin = dimensions ? dimensions.containerHeight / 2 + scrollTop : 0;
React.useLayoutEffect(function () {
if (ref.current == null) return;
ref.current.scrollTop = scrollTop;
}, [scrollTop]);
var unfocusedStyle = useUnfocusedStyle();
return React.createElement(Styled.Pre, {
className: "cs-content",
ref: ref,
style: {
margin: 0,
height: "100%",
overflow: "hidden"
}
}, React.createElement(Styled.Code, {
className: "cs-scaled-content",
style: {
display: "block",
//TODO isnt contentHeight always undefined?
height: dimensions ? dimensions.contentHeight : "100%",
width: dimensions && dimensions.contentWidth,
margin: dimensions && "0 " + (dimensions.containerWidth - dimensions.contentWidth) / 2 + "px",
transform: "scale(" + scale + ")",
transformOrigin: "center " + verticalOrigin + "px"
}
}, React.createElement("div", {
style: {
height: dimensions && dimensions.containerHeight / 2
}
}), React.createElement(LineList, {
stepPair: stepPair,
t: t,
tokens: tokens,
types: types,
dimensions: dimensions,
unfocusedStyle: unfocusedStyle,
maxLineCount: maxLineCount,
showNumbers: showNumbers
}), React.createElement("div", {
style: {
height: dimensions && dimensions.containerHeight / 2
}
})));
}
function Title(_ref3) {
var textPair = _ref3.textPair,
t = _ref3.t;
if (!textPair.any()) {
return null;
}
var _textPair$spread = textPair.spread(),
prev = _textPair$spread[0],
next = _textPair$spread[1];
var text = t < 0.5 ? prev : next;
var textStyle = prev !== next ? fadeOutIn()(t) : undefined;
var backgroundStyle = prev && next ? undefined : !prev ? halfFadeIn()(t) : halfFadeOut()(t);
return React.createElement(Styled.Title, {
className: "cs-title",
style: backgroundStyle
}, React.createElement("span", {
style: textStyle
}, text));
}
function Subtitle(_ref4) {
var textPair = _ref4.textPair,
t = _ref4.t;
if (!textPair.any()) {
return null;
}
var _textPair$spread2 = textPair.spread(),
prev = _textPair$spread2[0],
next = _textPair$spread2[1];
var text = t < 0.5 ? prev : next;
var textStyle = prev !== next ? fadeOutIn()(t) : undefined;
var backgroundStyle = prev && next ? undefined : !prev ? halfFadeIn()(t) : halfFadeOut()(t);
return React.createElement(Styled.Subtitle, {
className: "cs-subtitle",
style: backgroundStyle
}, React.createElement("span", {
style: textStyle
}, text));
}
function CodeSurfer(_ref) {
var progress = _ref.progress,
steps = _ref.steps,
tokens = _ref.tokens,
types = _ref.types,
maxLineCount = _ref.maxLineCount,
_ref$showNumbers = _ref.showNumbers,
showNumbers = _ref$showNumbers === void 0 ? false : _ref$showNumbers;
var fakeSteps = React.useMemo(function () {
return getFakeSteps(steps, tokens);
}, [steps]);
var ref = React.useRef(null);
var _useDimensions = useDimensions(ref, steps),
dimensions = _useDimensions.dimensions,
stepsWithDimensions = _useDimensions.steps;
if (!dimensions || !stepsWithDimensions) {
return React.createElement("div", {
ref: ref,
style: {
overflow: "auto",
height: "100%",
width: "100%"
}
}, fakeSteps.map(function (_step, i) {
return React.createElement("div", {
key: i,
style: {
overflow: "auto",
height: "100%",
width: "100%"
}
}, React.createElement(CodeSurferContainer, {
steps: fakeSteps,
progress: i,
tokens: tokens,
types: types,
maxLineCount: maxLineCount,
showNumbers: showNumbers
}));
}));
} else {
return React.createElement("div", {
style: {
height: "100%",
width: "100%",
overflow: "auto"
},
ref: ref
}, React.createElement(CodeSurferContainer, {
steps: stepsWithDimensions,
progress: progress,
dimensions: dimensions,
tokens: tokens,
types: types,
maxLineCount: maxLineCount,
showNumbers: showNumbers
}));
}
}
function getFakeSteps(parsedSteps, tokens) {
var shortLineKey = 0;
var length = 100;
for (var i = 1; i < tokens.length; i++) {
if (tokens[i].length < length) {
length = tokens[i].length;
shortLineKey = i;
}
if (length <= 1) {
break;
}
}
var fakeSteps = parsedSteps.map(function (step) {
var fakeStep = _extends({}, step, {
lines: step.lines.map(function (_) {
return shortLineKey;
}),
longestLineIndex: 0
});
fakeStep.lines[0] = step.lines[step.longestLineIndex];
return fakeStep;
});
fakeSteps[0] = parsedSteps[0];
return fakeSteps;
}
function InnerCodeSurfer(_ref) {
var progress = _ref.progress,
inputSteps = _ref.steps,
parsedSteps = _ref.parsedSteps;
var _React$useMemo = React.useMemo(function () {
if (parsedSteps) return parsedSteps;
return parseSteps(inputSteps);
}, [inputSteps, parsedSteps]),
steps = _React$useMemo.steps,
tokens = _React$useMemo.tokens,
types = _React$useMemo.types,
maxLineCount = _React$useMemo.maxLineCount,
showNumbers = _React$useMemo.showNumbers;
if (!steps || steps.length === 0) {
throw new Error("No steps");
}
return React.createElement(CodeSurfer, {
progress: progress,
steps: steps,
tokens: tokens,
types: types,
maxLineCount: maxLineCount,
showNumbers: showNumbers
});
}
function CodeSurferWrapper(_ref2) {
var theme = _ref2.theme,
nonblocking = _ref2.nonblocking,
props = _objectWithoutPropertiesLoose(_ref2, ["theme", "nonblocking"]);
var _React$useState = React.useState(nonblocking),
wait = _React$useState[0],
setWait = _React$useState[1];
React.useEffect(function () {
if (!wait) return;
setWait(false);
}, []);
if (wait) return React.createElement(StylesProvider, {
theme: theme
}, React.createElement(Styled.Placeholder, null));
return React.createElement(StylesProvider, {
theme: theme
}, React.createElement(InnerCodeSurfer, Object.assign({}, props)));
}
export { CodeSurferWrapper as CodeSurfer, UnknownError };
//# sourceMappingURL=standalone.esm.js.map