@code-hike/mini-editor
Advanced tools
Comparing version 0.0.0-6a7ffe8 to 0.0.0-6dfbe3d
@@ -13,2 +13,3 @@ /// <reference types="react" /> | ||
export declare function Code({ prevCode, prevFocus, nextCode, nextFocus, progress, language, parentHeight, minColumns, }: CodeProps): JSX.Element; | ||
export declare function flatMap<T, U>(array: T[], callbackfn: (value: T, index: number, array: T[]) => U[]): U[]; | ||
export {}; |
import React from "react"; | ||
import "./editor-frame.css"; | ||
import "./index.scss"; | ||
export { EditorFrame, TerminalPanel }; | ||
@@ -9,4 +9,6 @@ declare type EditorFrameProps = { | ||
terminalPanel: React.ReactNode; | ||
button?: React.ReactNode; | ||
classes?: Record<string, string>; | ||
} & React.PropsWithoutRef<JSX.IntrinsicElements["div"]>; | ||
declare function EditorFrame({ files, active, children, terminalPanel, height, style, ...rest }: EditorFrameProps): JSX.Element; | ||
declare function EditorFrame({ files, active, children, terminalPanel, height, style, button, classes, ...rest }: EditorFrameProps): JSX.Element; | ||
declare type TerminalPanelProps = { | ||
@@ -13,0 +15,0 @@ height?: number; |
@@ -7,6 +7,4 @@ declare type LineIndex = number; | ||
export declare function getFocusExtremes(focus: string | null, lines: any[]): [number, number]; | ||
/** | ||
* Return the first and last indexes to focus, both included | ||
*/ | ||
export declare function getFocusIndexes(focus: string | null, lines: any[]): number[]; | ||
export declare function getFocusByKey(focus: string | null, keys: number[]): Record<number, boolean> | Record<number, true | number[]>; | ||
export declare function parseFocus(focus: string): Record<number, true | number[]>; | ||
@@ -13,0 +11,0 @@ export declare function getFocusSize(focus: Record<LineIndex, true | ColumnIndex[]>): { |
@@ -7,5 +7,7 @@ 'use strict'; | ||
var miniFrame = require('@code-hike/mini-frame'); | ||
var utils = require('@code-hike/utils'); | ||
var miniTerminal = require('@code-hike/mini-terminal'); | ||
var codeDiff = require('@code-hike/code-diff'); | ||
var smoothLines = require('@code-hike/smooth-lines'); | ||
var useSpring = require('use-spring'); | ||
@@ -91,21 +93,23 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
var e=[],t=[];function n(n,r){if(n&&"undefined"!=typeof document){var a,s=!0===r.prepend?"prepend":"append",d=!0===r.singleTag,i="string"==typeof r.container?document.querySelector(r.container):document.getElementsByTagName("head")[0];if(d){var u=e.indexOf(i);-1===u&&(u=e.push(i)-1,t[u]={}),a=t[u]&&t[u][s]?t[u][s]:t[u][s]=c();}else a=c();65279===n.charCodeAt(0)&&(n=n.substring(1)),a.styleSheet?a.styleSheet.cssText+=n:a.appendChild(document.createTextNode(n));}function c(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),r.attributes)for(var t=Object.keys(r.attributes),n=0;n<t.length;n++)e.setAttribute(t[n],r.attributes[t[n]]);var a="prepend"===s?"afterbegin":"beforeend";return i.insertAdjacentElement(a,e),e}} | ||
var css = ".ch-editor-tab{border-right:1px solid #252526;width:120px;min-width:-webkit-fit-content;min-width:-moz-fit-content;min-width:fit-content;flex-shrink:0;position:relative;display:flex;white-space:nowrap;cursor:pointer;height:100%;box-sizing:border-box;padding-left:15px;padding-right:15px;background-color:#2d2d2d;color:hsla(0,0%,100%,.5)}.ch-editor-tab[data-active]{background-color:#1e1e1e;color:#fff}.ch-editor-tab>div{margin-top:auto;margin-bottom:auto;font-size:12px;line-height:1.4em;text-overflow:ellipsis}.ch-editor-body{background-color:#1e1e1e;height:100%;color:#ccc;font-size:15px;padding:5px 10px;line-height:1.1rem;box-sizing:border-box}.ch-editor-body code{line-height:20px}.ch-editor-terminal{position:absolute;overflow:hidden;bottom:0;width:100%;background-color:#1e1e1e;color:#e7e7e7;border-top:1px solid hsla(0,0%,50.2%,.35);padding:0 8px;box-sizing:border-box}.ch-editor-terminal-tab{text-transform:uppercase;padding:4px 10px 3px;font-size:11px;line-height:24px;display:flex}.ch-editor-terminal-tab>span{border-bottom:1px solid #e7e7e7}.ch-editor-terminal-content{margin-top:8px;height:calc(100% - 40px);box-sizing:border-box}.ch-editor-terminal-content .ch-terminal{font-size:12px;margin:0}"; | ||
n(css,{"singleTag":true}); | ||
var c = utils.classNamesWithPrefix("ch-editor"); | ||
var DEFAULT_HEIGHT = 200; | ||
function EditorFrame(_a) { | ||
var files = _a.files, active = _a.active, children = _a.children, terminalPanel = _a.terminalPanel, height = _a.height, style = _a.style, rest = __rest(_a, ["files", "active", "children", "terminalPanel", "height", "style"]); | ||
return (React__default['default'].createElement(miniFrame.MiniFrame, __assign({ titleBar: React__default['default'].createElement(TabsContainer, { files: files, active: active }), style: __assign({ height: height !== null && height !== void 0 ? height : DEFAULT_HEIGHT }, style) }, rest), | ||
React__default['default'].createElement("div", { className: "ch-editor-body" }, children), | ||
var files = _a.files, active = _a.active, children = _a.children, terminalPanel = _a.terminalPanel, height = _a.height, style = _a.style, button = _a.button, classes = _a.classes, rest = __rest(_a, ["files", "active", "children", "terminalPanel", "height", "style", "button", "classes"]); | ||
return (React__default['default'].createElement(miniFrame.MiniFrame, __assign({ titleBar: React__default['default'].createElement(TabsContainer, { files: files, active: active, button: button, classes: classes }), classes: classes, style: __assign({ height: height !== null && height !== void 0 ? height : DEFAULT_HEIGHT }, style) }, rest), | ||
React__default['default'].createElement("div", { className: c("-body", classes) }, children), | ||
terminalPanel)); | ||
} | ||
function TabsContainer(_a) { | ||
var files = _a.files, active = _a.active; | ||
var files = _a.files, active = _a.active, button = _a.button, classes = _a.classes; | ||
return (React__default['default'].createElement(React__default['default'].Fragment, null, | ||
React__default['default'].createElement(miniFrame.FrameButtons, null), | ||
files.map(function (fileName) { return (React__default['default'].createElement("div", { key: fileName, className: "ch-editor-tab", "data-active": fileName === active || undefined }, | ||
React__default['default'].createElement(miniFrame.FrameButtons, { classes: classes }), | ||
files.map(function (fileName) { return (React__default['default'].createElement("div", { key: fileName, className: c([ | ||
"-tab", | ||
fileName === active | ||
? "-tab-active" | ||
: "-tab-inactive", | ||
], classes) }, | ||
React__default['default'].createElement("div", null, fileName))); }), | ||
React__default['default'].createElement("div", { style: { flex: 1 } }))); | ||
React__default['default'].createElement("div", { style: { flex: 1 } }), | ||
button)); | ||
} | ||
@@ -127,2 +131,4 @@ function TerminalPanel(_a) { | ||
var _a = __read(React__default['default'].useState(null), 2), dimensions = _a[0], setDimensions = _a[1]; | ||
var windowWidth = useWindowWidth(); | ||
var fullDeps = __spread(deps, [windowWidth]); | ||
useLayoutEffect(function () { | ||
@@ -151,7 +157,8 @@ var _a, _b, _c, _d, _e, _f, _g, _h; | ||
colWidth: colWidth, | ||
deps: deps, | ||
deps: fullDeps, | ||
}); | ||
} | ||
}, deps); | ||
if (!dimensions || depsChanged(dimensions.deps, deps)) { | ||
}, fullDeps); | ||
if (!dimensions || | ||
depsChanged(dimensions.deps, fullDeps)) { | ||
return [ref, null]; | ||
@@ -170,6 +177,16 @@ } | ||
} | ||
function useWindowWidth() { | ||
var _a = __read(React__default['default'].useState(undefined), 2), width = _a[0], setWidth = _a[1]; | ||
React__default['default'].useEffect(function () { | ||
function handleResize() { | ||
setWidth(window.innerWidth); | ||
} | ||
window.addEventListener("resize", handleResize); | ||
return function () { | ||
return window.removeEventListener("resize", handleResize); | ||
}; | ||
}, []); | ||
return width; | ||
} | ||
/** | ||
* Return the first and last indexes to focus, both included | ||
*/ | ||
function getFocusIndexes(focus, lines) { | ||
@@ -187,2 +204,17 @@ if (!focus) { | ||
} | ||
function getFocusByKey(focus, keys) { | ||
if (!focus) { | ||
// focus all lines | ||
return fromEntries(keys.map(function (key) { return [key, true]; })); | ||
} | ||
else { | ||
var parsed_1 = parseFocus(focus); | ||
var byKey_1 = {}; | ||
Object.keys(parsed_1).forEach(function (i) { | ||
var key = keys[parseInt(i, 10)]; | ||
byKey_1[key] = parsed_1[parseInt(i, 10)]; | ||
}); | ||
return byKey_1; | ||
} | ||
} | ||
function parseFocus(focus) { | ||
@@ -287,3 +319,3 @@ if (!focus) { | ||
var prevCode = _a.prevCode, prevFocus = _a.prevFocus, nextCode = _a.nextCode, nextFocus = _a.nextFocus, progress = _a.progress, language = _a.language, parentHeight = _a.parentHeight, minColumns = _a.minColumns; | ||
var _b = useLineProps(prevCode, nextCode, language, prevFocus, nextFocus), prevLines = _b.prevLines, nextLines = _b.nextLines, prevFocusPair = _b.prevFocusPair, nextFocusPair = _b.nextFocusPair, prevLongestLine = _b.prevLongestLine, nextLongestLine = _b.nextLongestLine; | ||
var _b = useLineProps(prevCode, nextCode, language, prevFocus, nextFocus), prevLines = _b.prevLines, nextLines = _b.nextLines, prevFocusIndexes = _b.prevFocusIndexes, nextFocusIndexes = _b.nextFocusIndexes, prevLongestLine = _b.prevLongestLine, nextLongestLine = _b.nextLongestLine; | ||
var _c = __read(useDimensions([ | ||
@@ -306,3 +338,3 @@ parentHeight, | ||
return Math.max(lw, dimensions.colWidth * minColumns); | ||
}), prevFocus: prevFocusPair, nextFocus: nextFocusPair, maxZoom: 1 })) : (React__default['default'].createElement(React__default['default'].Fragment, null, | ||
}), prevFocus: prevFocusIndexes, nextFocus: nextFocusIndexes, maxZoom: 1 })) : (React__default['default'].createElement(React__default['default'].Fragment, null, | ||
React__default['default'].createElement("div", { className: "prev-longest-line" }, prevLongestLine), | ||
@@ -319,17 +351,47 @@ React__default['default'].createElement("div", { className: "next-longest-line" }, nextLongestLine)))))); | ||
}), prevKeys = _c.prevKeys, nextKeys = _c.nextKeys, codeMap = _c.codeMap; | ||
var prevLines = prevKeys.map(function (key) { return ({ | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
}); }); | ||
var prevFocusPair = getFocusIndexes(prevFocus, prevLines); | ||
var prevLongestLineIndex = longestLineIndex(prevCode, prevFocusPair); | ||
var prevFocusByKey = getFocusByKey(prevFocus, prevKeys); | ||
var prevFocusIndexes = getFocusIndexes(prevFocus, prevKeys); | ||
var prevLongestLineIndex = longestLineIndex(prevCode, prevFocusIndexes); | ||
var nextFocusByKey = getFocusByKey(nextFocus, nextKeys); | ||
var nextFocusIndexes = getFocusIndexes(nextFocus, nextKeys); | ||
var nextLongestLineIndex = longestLineIndex(nextCode, nextFocusIndexes); | ||
var prevLines = prevKeys.map(function (key) { | ||
var prevFocus = prevFocusByKey[key]; | ||
var nextFocus = nextFocusByKey[key]; | ||
var focusPerColumn = Array.isArray(prevFocus) || Array.isArray(nextFocus); | ||
if (!focusPerColumn) { | ||
return { | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
}; | ||
} | ||
else { | ||
return { | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
elementWithProgress: function (progress) { return (React__default['default'].createElement(ColumnedLine, { line: codeMap[key], progress: progress, prevFocus: prevFocus, nextFocus: nextFocus })); }, | ||
}; | ||
} | ||
}); | ||
var prevLongestLine = prevLongestLineIndex == null | ||
? null | ||
: (_a = prevLines[prevLongestLineIndex]) === null || _a === void 0 ? void 0 : _a.element; | ||
var nextLines = nextKeys.map(function (key) { return ({ | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
}); }); | ||
var nextFocusPair = getFocusIndexes(nextFocus, nextLines); | ||
var nextLongestLineIndex = longestLineIndex(nextCode, nextFocusPair); | ||
var nextLines = nextKeys.map(function (key) { | ||
var prevFocus = prevFocusByKey[key]; | ||
var nextFocus = nextFocusByKey[key]; | ||
var focusPerColumn = Array.isArray(prevFocus) || Array.isArray(nextFocus); | ||
if (!focusPerColumn) { | ||
return { | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
}; | ||
} | ||
else { | ||
return { | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
elementWithProgress: function (progress) { return (React__default['default'].createElement(ColumnedLine, { line: codeMap[key], progress: progress, prevFocus: prevFocus, nextFocus: nextFocus })); }, | ||
}; | ||
} | ||
}); | ||
var nextLongestLine = nextLongestLineIndex == null | ||
@@ -341,4 +403,4 @@ ? null | ||
nextLines: nextLines, | ||
prevFocusPair: prevFocusPair, | ||
nextFocusPair: nextFocusPair, | ||
prevFocusIndexes: prevFocusIndexes, | ||
nextFocusIndexes: nextFocusIndexes, | ||
prevLongestLine: prevLongestLine, | ||
@@ -358,2 +420,41 @@ nextLongestLine: nextLongestLine, | ||
} | ||
var OFF_OPACITY = 0.33; | ||
function ColumnedLine(_a) { | ||
var line = _a.line, progress = _a.progress, prevFocus = _a.prevFocus, nextFocus = _a.nextFocus; | ||
var columns = React__default['default'].useMemo(function () { | ||
var chars = flatMap(line, function (_a) { | ||
var _b = __read(_a, 2), token = _b[0], type = _b[1]; | ||
return token.split("").map(function (char) { return [char, type]; }); | ||
}); | ||
return chars.map(function (_a, i) { | ||
var _b = __read(_a, 2), char = _b[0], type = _b[1]; | ||
return ({ | ||
char: char, | ||
type: type, | ||
fromOpacity: !prevFocus | ||
? 0.99 // because the line is already transparent | ||
: prevFocus === true || prevFocus.includes(i) | ||
? 0.99 | ||
: OFF_OPACITY, | ||
toOpacity: !nextFocus | ||
? 0.99 // because the line is already transparent | ||
: nextFocus === true || nextFocus.includes(i) | ||
? 0.99 | ||
: OFF_OPACITY, | ||
}); | ||
}); | ||
}, [line, prevFocus, nextFocus]); | ||
return (React__default['default'].createElement("div", { style: { | ||
display: "inline-block", | ||
width: "100%", | ||
} }, columns.map(function (_a, i) { | ||
var char = _a.char, type = _a.type, fromOpacity = _a.fromOpacity, toOpacity = _a.toOpacity; | ||
return (React__default['default'].createElement("span", { className: "token " + type, key: i + 1, style: { | ||
opacity: tween(fromOpacity, toOpacity, progress), | ||
} }, char)); | ||
}))); | ||
} | ||
function tween(p, n, t) { | ||
return (n - p) * t + p; | ||
} | ||
var newlineRe = /\r\n|\r|\n/; | ||
@@ -378,2 +479,6 @@ function longestLineIndex(code, focusIndexes) { | ||
} | ||
function flatMap(array, callbackfn) { | ||
var _a; | ||
return (_a = Array.prototype).concat.apply(_a, __spread(array.map(callbackfn))); | ||
} | ||
@@ -443,10 +548,4 @@ function useForwardTransitions(steps) { | ||
var css$1 = "code[class*=language-],pre[class*=language-]{color:#d4d4d4;font-size:13px;text-shadow:none;font-family:Menlo,Monaco,Consolas,Andale Mono,Ubuntu Mono,Courier New,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection{text-shadow:none;background:#75a7ca}code[class*=language-]::selection,code[class*=language-] ::selection,pre[class*=language-]::selection,pre[class*=language-] ::selection{text-shadow:none;background:#75a7ca}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;background:#1e1e1e}:not(pre)>code[class*=language-]{padding:.1em .3em;border-radius:.3em;color:#db4c69;background:#f9f2f4}.namespace{opacity:.7}.token.doctype .token.doctype-tag{color:#569cd6}.token.doctype .token.name{color:#9cdcfe}.token.comment,.token.prolog{color:#6a9955}.language-html .language-css .token.punctuation,.language-html .language-javascript .token.punctuation,.token.punctuation{color:#d4d4d4}.token.boolean,.token.constant,.token.inserted,.token.number,.token.property,.token.symbol,.token.tag,.token.unit{color:#b5cea8}.token.attr-name,.token.builtin,.token.char,.token.deleted,.token.selector,.token.string{color:#ce9178}.language-css .token.string.url{text-decoration:underline}.token.entity,.token.operator{color:#d4d4d4}.token.operator.arrow{color:#569cd6}.token.atrule{color:#ce9178}.token.atrule .token.rule{color:#c586c0}.token.atrule .token.url{color:#9cdcfe}.token.atrule .token.url .token.function{color:#dcdcaa}.token.atrule .token.url .token.punctuation{color:#d4d4d4}.token.keyword{color:#569cd6}.token.keyword.control-flow,.token.keyword.module{color:#c586c0}.token.function,.token.function .token.maybe-class-name{color:#dcdcaa}.token.regex{color:#d16969}.token.important{color:#569cd6}.token.italic{font-style:italic}.token.constant{color:#9cdcfe}.token.class-name,.token.maybe-class-name{color:#4ec9b0}.token.console,.token.interpolation,.token.parameter{color:#9cdcfe}.token.boolean,.token.punctuation.interpolation-punctuation{color:#569cd6}.token.exports .token.maybe-class-name,.token.imports .token.maybe-class-name,.token.property,.token.variable{color:#9cdcfe}.token.escape,.token.selector{color:#d7ba7d}.token.tag{color:#569cd6}.token.cdata,.token.tag .token.punctuation{color:grey}.token.attr-name{color:#9cdcfe}.token.attr-value,.token.attr-value .token.punctuation{color:#ce9178}.token.attr-value .token.punctuation.attr-equals{color:#d4d4d4}.token.entity{color:#569cd6}.token.namespace{color:#4ec9b0}code[class*=language-javascript],code[class*=language-jsx],code[class*=language-tsx],code[class*=language-typescript],pre[class*=language-javascript],pre[class*=language-jsx],pre[class*=language-tsx],pre[class*=language-typescript]{color:#9cdcfe}code[class*=language-css],pre[class*=language-css]{color:#ce9178}code[class*=language-html],pre[class*=language-html]{color:#d4d4d4}.language-regex .token.anchor{color:#dcdcaa}.language-html .token.punctuation{color:grey}pre[data-line]{position:relative}pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}.line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:#f7ebc6;box-shadow:inset 5px 0 0 #f7d87c;z-index:0;pointer-events:none;line-height:inherit;white-space:pre}"; | ||
n(css$1,{"singleTag":true}); | ||
function MiniEditor(props) { | ||
var _a = props.progress, progress = _a === void 0 ? 0 : _a, _b = props.backward, backward = _b === void 0 ? false : _b, code = props.code, focus = props.focus, lang = props.lang, file = props.file, ogSteps = props.steps, _c = props.minColumns, minColumns = _c === void 0 ? 50 : _c, height = props.height, rest = __rest(props | ||
// console.log({ props }) | ||
, ["progress", "backward", "code", "focus", "lang", "file", "steps", "minColumns", "height"]); | ||
// console.log({ props }) | ||
var _a = props.progress, progress = _a === void 0 ? 0 : _a, _b = props.backward, backward = _b === void 0 ? false : _b, code = props.code, focus = props.focus, lang = props.lang, file = props.file, ogSteps = props.steps, ogTabs = props.tabs, _c = props.minColumns, minColumns = _c === void 0 ? 50 : _c, height = props.height, rest = __rest(props, ["progress", "backward", "code", "focus", "lang", "file", "steps", "tabs", "minColumns", "height"]); | ||
var _d = useSteps(ogSteps, { | ||
@@ -457,2 +556,3 @@ code: code, | ||
file: file, | ||
tabs: ogTabs, | ||
}), steps = _d.steps, files = _d.files, stepsByFile = _d.stepsByFile; | ||
@@ -498,8 +598,6 @@ var activeStepIndex = backward | ||
: fwdTransitions[transitionIndex], prevCode = _b.prevCode, nextCode = _b.nextCode, prevFocus = _b.prevFocus, nextFocus = _b.nextFocus, lang = _b.lang; | ||
return (React__default['default'].createElement(Code, { prevCode: prevCode || nextCode, nextCode: nextCode || prevCode, prevFocus: prevFocus, nextFocus: nextFocus, language: lang, progress: progress - transitionIndex + 1, parentHeight: parentHeight, | ||
// TODO make prop | ||
minColumns: minColumns })); | ||
return (React__default['default'].createElement(Code, { prevCode: prevCode || nextCode, nextCode: nextCode || prevCode, prevFocus: prevFocus, nextFocus: nextFocus, language: lang, progress: progress - transitionIndex + 1, parentHeight: parentHeight, minColumns: minColumns })); | ||
} | ||
function useSteps(ogSteps, _a) { | ||
var _b = _a.code, code = _b === void 0 ? "" : _b, focus = _a.focus, lang = _a.lang, file = _a.file; | ||
var _b = _a.code, code = _b === void 0 ? "" : _b, focus = _a.focus, lang = _a.lang, file = _a.file, tabs = _a.tabs; | ||
return React__default['default'].useMemo(function () { | ||
@@ -509,3 +607,4 @@ var steps = (ogSteps === null || ogSteps === void 0 ? void 0 : ogSteps.map(function (s) { return (__assign({ code: code, | ||
lang: lang, | ||
file: file }, s)); })) || [{ code: code, focus: focus, lang: lang, file: file }]; | ||
file: file, | ||
tabs: tabs }, s)); })) || [{ code: code, focus: focus, lang: lang, file: file, tabs: tabs }]; | ||
var files = __spread(new Set(steps | ||
@@ -524,3 +623,3 @@ .map(function (s) { return s.file; }) | ||
return { steps: steps, files: files, stepsByFile: stepsByFile }; | ||
}, [ogSteps, code, focus, lang, file]); | ||
}, [ogSteps, code, focus, lang, file, tabs]); | ||
} | ||
@@ -545,2 +644,29 @@ var MAX_HEIGHT = 150; | ||
function MiniEditorWithState(_a) { | ||
var focus = _a.focus, code = _a.code, rest = __rest(_a, ["focus", "code"]); | ||
var _b = __read(usePrevFocus(code, focus), 2), steps = _b[0], progress = _b[1]; | ||
return (React__default['default'].createElement(MiniEditor, __assign({ progress: progress, steps: steps }, rest))); | ||
} | ||
function usePrevFocus(code, focus) { | ||
var _a = __read(React__default['default'].useState({ | ||
target: 0, | ||
steps: [{ focus: focus, code: code }], | ||
}), 2), state = _a[0], setState = _a[1]; | ||
React__default['default'].useEffect(function () { | ||
var last = state.steps[state.steps.length - 1]; | ||
if (last.focus !== focus || last.code !== code) { | ||
setState(function (s) { return ({ | ||
target: s.target + 1, | ||
steps: __spread(s.steps, [{ focus: focus, code: code }]), | ||
}); }); | ||
} | ||
}, [focus, code]); | ||
var _b = __read(useSpring.useSpring(state.target, { | ||
stiffness: 100, | ||
decimals: 3, | ||
}), 1), progress = _b[0]; | ||
return [state.steps, progress]; | ||
} | ||
exports.MiniEditor = MiniEditor; | ||
exports.MiniEditorWithState = MiniEditorWithState; |
@@ -1,2 +0,3 @@ | ||
import { MiniEditor } from "./mini-editor"; | ||
export { MiniEditor }; | ||
import { MiniEditor, MiniEditorProps } from "./mini-editor"; | ||
import { MiniEditorWithState, StatefulEditorProps } from "./stateful-editor"; | ||
export { MiniEditor, MiniEditorWithState, MiniEditorProps, StatefulEditorProps, }; |
import React from 'react'; | ||
import { MiniFrame, FrameButtons } from '@code-hike/mini-frame'; | ||
import { classNamesWithPrefix } from '@code-hike/utils'; | ||
import { InnerTerminal } from '@code-hike/mini-terminal'; | ||
import { codeDiff } from '@code-hike/code-diff'; | ||
import { SmoothLines } from '@code-hike/smooth-lines'; | ||
import { useSpring } from 'use-spring'; | ||
@@ -82,21 +84,23 @@ /*! ***************************************************************************** | ||
var e=[],t=[];function n(n,r){if(n&&"undefined"!=typeof document){var a,s=!0===r.prepend?"prepend":"append",d=!0===r.singleTag,i="string"==typeof r.container?document.querySelector(r.container):document.getElementsByTagName("head")[0];if(d){var u=e.indexOf(i);-1===u&&(u=e.push(i)-1,t[u]={}),a=t[u]&&t[u][s]?t[u][s]:t[u][s]=c();}else a=c();65279===n.charCodeAt(0)&&(n=n.substring(1)),a.styleSheet?a.styleSheet.cssText+=n:a.appendChild(document.createTextNode(n));}function c(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),r.attributes)for(var t=Object.keys(r.attributes),n=0;n<t.length;n++)e.setAttribute(t[n],r.attributes[t[n]]);var a="prepend"===s?"afterbegin":"beforeend";return i.insertAdjacentElement(a,e),e}} | ||
var css = ".ch-editor-tab{border-right:1px solid #252526;width:120px;min-width:-webkit-fit-content;min-width:-moz-fit-content;min-width:fit-content;flex-shrink:0;position:relative;display:flex;white-space:nowrap;cursor:pointer;height:100%;box-sizing:border-box;padding-left:15px;padding-right:15px;background-color:#2d2d2d;color:hsla(0,0%,100%,.5)}.ch-editor-tab[data-active]{background-color:#1e1e1e;color:#fff}.ch-editor-tab>div{margin-top:auto;margin-bottom:auto;font-size:12px;line-height:1.4em;text-overflow:ellipsis}.ch-editor-body{background-color:#1e1e1e;height:100%;color:#ccc;font-size:15px;padding:5px 10px;line-height:1.1rem;box-sizing:border-box}.ch-editor-body code{line-height:20px}.ch-editor-terminal{position:absolute;overflow:hidden;bottom:0;width:100%;background-color:#1e1e1e;color:#e7e7e7;border-top:1px solid hsla(0,0%,50.2%,.35);padding:0 8px;box-sizing:border-box}.ch-editor-terminal-tab{text-transform:uppercase;padding:4px 10px 3px;font-size:11px;line-height:24px;display:flex}.ch-editor-terminal-tab>span{border-bottom:1px solid #e7e7e7}.ch-editor-terminal-content{margin-top:8px;height:calc(100% - 40px);box-sizing:border-box}.ch-editor-terminal-content .ch-terminal{font-size:12px;margin:0}"; | ||
n(css,{"singleTag":true}); | ||
var c = classNamesWithPrefix("ch-editor"); | ||
var DEFAULT_HEIGHT = 200; | ||
function EditorFrame(_a) { | ||
var files = _a.files, active = _a.active, children = _a.children, terminalPanel = _a.terminalPanel, height = _a.height, style = _a.style, rest = __rest(_a, ["files", "active", "children", "terminalPanel", "height", "style"]); | ||
return (React.createElement(MiniFrame, __assign({ titleBar: React.createElement(TabsContainer, { files: files, active: active }), style: __assign({ height: height !== null && height !== void 0 ? height : DEFAULT_HEIGHT }, style) }, rest), | ||
React.createElement("div", { className: "ch-editor-body" }, children), | ||
var files = _a.files, active = _a.active, children = _a.children, terminalPanel = _a.terminalPanel, height = _a.height, style = _a.style, button = _a.button, classes = _a.classes, rest = __rest(_a, ["files", "active", "children", "terminalPanel", "height", "style", "button", "classes"]); | ||
return (React.createElement(MiniFrame, __assign({ titleBar: React.createElement(TabsContainer, { files: files, active: active, button: button, classes: classes }), classes: classes, style: __assign({ height: height !== null && height !== void 0 ? height : DEFAULT_HEIGHT }, style) }, rest), | ||
React.createElement("div", { className: c("-body", classes) }, children), | ||
terminalPanel)); | ||
} | ||
function TabsContainer(_a) { | ||
var files = _a.files, active = _a.active; | ||
var files = _a.files, active = _a.active, button = _a.button, classes = _a.classes; | ||
return (React.createElement(React.Fragment, null, | ||
React.createElement(FrameButtons, null), | ||
files.map(function (fileName) { return (React.createElement("div", { key: fileName, className: "ch-editor-tab", "data-active": fileName === active || undefined }, | ||
React.createElement(FrameButtons, { classes: classes }), | ||
files.map(function (fileName) { return (React.createElement("div", { key: fileName, className: c([ | ||
"-tab", | ||
fileName === active | ||
? "-tab-active" | ||
: "-tab-inactive", | ||
], classes) }, | ||
React.createElement("div", null, fileName))); }), | ||
React.createElement("div", { style: { flex: 1 } }))); | ||
React.createElement("div", { style: { flex: 1 } }), | ||
button)); | ||
} | ||
@@ -118,2 +122,4 @@ function TerminalPanel(_a) { | ||
var _a = __read(React.useState(null), 2), dimensions = _a[0], setDimensions = _a[1]; | ||
var windowWidth = useWindowWidth(); | ||
var fullDeps = __spread(deps, [windowWidth]); | ||
useLayoutEffect(function () { | ||
@@ -142,7 +148,8 @@ var _a, _b, _c, _d, _e, _f, _g, _h; | ||
colWidth: colWidth, | ||
deps: deps, | ||
deps: fullDeps, | ||
}); | ||
} | ||
}, deps); | ||
if (!dimensions || depsChanged(dimensions.deps, deps)) { | ||
}, fullDeps); | ||
if (!dimensions || | ||
depsChanged(dimensions.deps, fullDeps)) { | ||
return [ref, null]; | ||
@@ -161,6 +168,16 @@ } | ||
} | ||
function useWindowWidth() { | ||
var _a = __read(React.useState(undefined), 2), width = _a[0], setWidth = _a[1]; | ||
React.useEffect(function () { | ||
function handleResize() { | ||
setWidth(window.innerWidth); | ||
} | ||
window.addEventListener("resize", handleResize); | ||
return function () { | ||
return window.removeEventListener("resize", handleResize); | ||
}; | ||
}, []); | ||
return width; | ||
} | ||
/** | ||
* Return the first and last indexes to focus, both included | ||
*/ | ||
function getFocusIndexes(focus, lines) { | ||
@@ -178,2 +195,17 @@ if (!focus) { | ||
} | ||
function getFocusByKey(focus, keys) { | ||
if (!focus) { | ||
// focus all lines | ||
return fromEntries(keys.map(function (key) { return [key, true]; })); | ||
} | ||
else { | ||
var parsed_1 = parseFocus(focus); | ||
var byKey_1 = {}; | ||
Object.keys(parsed_1).forEach(function (i) { | ||
var key = keys[parseInt(i, 10)]; | ||
byKey_1[key] = parsed_1[parseInt(i, 10)]; | ||
}); | ||
return byKey_1; | ||
} | ||
} | ||
function parseFocus(focus) { | ||
@@ -278,3 +310,3 @@ if (!focus) { | ||
var prevCode = _a.prevCode, prevFocus = _a.prevFocus, nextCode = _a.nextCode, nextFocus = _a.nextFocus, progress = _a.progress, language = _a.language, parentHeight = _a.parentHeight, minColumns = _a.minColumns; | ||
var _b = useLineProps(prevCode, nextCode, language, prevFocus, nextFocus), prevLines = _b.prevLines, nextLines = _b.nextLines, prevFocusPair = _b.prevFocusPair, nextFocusPair = _b.nextFocusPair, prevLongestLine = _b.prevLongestLine, nextLongestLine = _b.nextLongestLine; | ||
var _b = useLineProps(prevCode, nextCode, language, prevFocus, nextFocus), prevLines = _b.prevLines, nextLines = _b.nextLines, prevFocusIndexes = _b.prevFocusIndexes, nextFocusIndexes = _b.nextFocusIndexes, prevLongestLine = _b.prevLongestLine, nextLongestLine = _b.nextLongestLine; | ||
var _c = __read(useDimensions([ | ||
@@ -297,3 +329,3 @@ parentHeight, | ||
return Math.max(lw, dimensions.colWidth * minColumns); | ||
}), prevFocus: prevFocusPair, nextFocus: nextFocusPair, maxZoom: 1 })) : (React.createElement(React.Fragment, null, | ||
}), prevFocus: prevFocusIndexes, nextFocus: nextFocusIndexes, maxZoom: 1 })) : (React.createElement(React.Fragment, null, | ||
React.createElement("div", { className: "prev-longest-line" }, prevLongestLine), | ||
@@ -310,17 +342,47 @@ React.createElement("div", { className: "next-longest-line" }, nextLongestLine)))))); | ||
}), prevKeys = _c.prevKeys, nextKeys = _c.nextKeys, codeMap = _c.codeMap; | ||
var prevLines = prevKeys.map(function (key) { return ({ | ||
key: key, | ||
element: React.createElement(Line, { line: codeMap[key] }), | ||
}); }); | ||
var prevFocusPair = getFocusIndexes(prevFocus, prevLines); | ||
var prevLongestLineIndex = longestLineIndex(prevCode, prevFocusPair); | ||
var prevFocusByKey = getFocusByKey(prevFocus, prevKeys); | ||
var prevFocusIndexes = getFocusIndexes(prevFocus, prevKeys); | ||
var prevLongestLineIndex = longestLineIndex(prevCode, prevFocusIndexes); | ||
var nextFocusByKey = getFocusByKey(nextFocus, nextKeys); | ||
var nextFocusIndexes = getFocusIndexes(nextFocus, nextKeys); | ||
var nextLongestLineIndex = longestLineIndex(nextCode, nextFocusIndexes); | ||
var prevLines = prevKeys.map(function (key) { | ||
var prevFocus = prevFocusByKey[key]; | ||
var nextFocus = nextFocusByKey[key]; | ||
var focusPerColumn = Array.isArray(prevFocus) || Array.isArray(nextFocus); | ||
if (!focusPerColumn) { | ||
return { | ||
key: key, | ||
element: React.createElement(Line, { line: codeMap[key] }), | ||
}; | ||
} | ||
else { | ||
return { | ||
key: key, | ||
element: React.createElement(Line, { line: codeMap[key] }), | ||
elementWithProgress: function (progress) { return (React.createElement(ColumnedLine, { line: codeMap[key], progress: progress, prevFocus: prevFocus, nextFocus: nextFocus })); }, | ||
}; | ||
} | ||
}); | ||
var prevLongestLine = prevLongestLineIndex == null | ||
? null | ||
: (_a = prevLines[prevLongestLineIndex]) === null || _a === void 0 ? void 0 : _a.element; | ||
var nextLines = nextKeys.map(function (key) { return ({ | ||
key: key, | ||
element: React.createElement(Line, { line: codeMap[key] }), | ||
}); }); | ||
var nextFocusPair = getFocusIndexes(nextFocus, nextLines); | ||
var nextLongestLineIndex = longestLineIndex(nextCode, nextFocusPair); | ||
var nextLines = nextKeys.map(function (key) { | ||
var prevFocus = prevFocusByKey[key]; | ||
var nextFocus = nextFocusByKey[key]; | ||
var focusPerColumn = Array.isArray(prevFocus) || Array.isArray(nextFocus); | ||
if (!focusPerColumn) { | ||
return { | ||
key: key, | ||
element: React.createElement(Line, { line: codeMap[key] }), | ||
}; | ||
} | ||
else { | ||
return { | ||
key: key, | ||
element: React.createElement(Line, { line: codeMap[key] }), | ||
elementWithProgress: function (progress) { return (React.createElement(ColumnedLine, { line: codeMap[key], progress: progress, prevFocus: prevFocus, nextFocus: nextFocus })); }, | ||
}; | ||
} | ||
}); | ||
var nextLongestLine = nextLongestLineIndex == null | ||
@@ -332,4 +394,4 @@ ? null | ||
nextLines: nextLines, | ||
prevFocusPair: prevFocusPair, | ||
nextFocusPair: nextFocusPair, | ||
prevFocusIndexes: prevFocusIndexes, | ||
nextFocusIndexes: nextFocusIndexes, | ||
prevLongestLine: prevLongestLine, | ||
@@ -349,2 +411,41 @@ nextLongestLine: nextLongestLine, | ||
} | ||
var OFF_OPACITY = 0.33; | ||
function ColumnedLine(_a) { | ||
var line = _a.line, progress = _a.progress, prevFocus = _a.prevFocus, nextFocus = _a.nextFocus; | ||
var columns = React.useMemo(function () { | ||
var chars = flatMap(line, function (_a) { | ||
var _b = __read(_a, 2), token = _b[0], type = _b[1]; | ||
return token.split("").map(function (char) { return [char, type]; }); | ||
}); | ||
return chars.map(function (_a, i) { | ||
var _b = __read(_a, 2), char = _b[0], type = _b[1]; | ||
return ({ | ||
char: char, | ||
type: type, | ||
fromOpacity: !prevFocus | ||
? 0.99 // because the line is already transparent | ||
: prevFocus === true || prevFocus.includes(i) | ||
? 0.99 | ||
: OFF_OPACITY, | ||
toOpacity: !nextFocus | ||
? 0.99 // because the line is already transparent | ||
: nextFocus === true || nextFocus.includes(i) | ||
? 0.99 | ||
: OFF_OPACITY, | ||
}); | ||
}); | ||
}, [line, prevFocus, nextFocus]); | ||
return (React.createElement("div", { style: { | ||
display: "inline-block", | ||
width: "100%", | ||
} }, columns.map(function (_a, i) { | ||
var char = _a.char, type = _a.type, fromOpacity = _a.fromOpacity, toOpacity = _a.toOpacity; | ||
return (React.createElement("span", { className: "token " + type, key: i + 1, style: { | ||
opacity: tween(fromOpacity, toOpacity, progress), | ||
} }, char)); | ||
}))); | ||
} | ||
function tween(p, n, t) { | ||
return (n - p) * t + p; | ||
} | ||
var newlineRe = /\r\n|\r|\n/; | ||
@@ -369,2 +470,6 @@ function longestLineIndex(code, focusIndexes) { | ||
} | ||
function flatMap(array, callbackfn) { | ||
var _a; | ||
return (_a = Array.prototype).concat.apply(_a, __spread(array.map(callbackfn))); | ||
} | ||
@@ -434,10 +539,4 @@ function useForwardTransitions(steps) { | ||
var css$1 = "code[class*=language-],pre[class*=language-]{color:#d4d4d4;font-size:13px;text-shadow:none;font-family:Menlo,Monaco,Consolas,Andale Mono,Ubuntu Mono,Courier New,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection{text-shadow:none;background:#75a7ca}code[class*=language-]::selection,code[class*=language-] ::selection,pre[class*=language-]::selection,pre[class*=language-] ::selection{text-shadow:none;background:#75a7ca}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;background:#1e1e1e}:not(pre)>code[class*=language-]{padding:.1em .3em;border-radius:.3em;color:#db4c69;background:#f9f2f4}.namespace{opacity:.7}.token.doctype .token.doctype-tag{color:#569cd6}.token.doctype .token.name{color:#9cdcfe}.token.comment,.token.prolog{color:#6a9955}.language-html .language-css .token.punctuation,.language-html .language-javascript .token.punctuation,.token.punctuation{color:#d4d4d4}.token.boolean,.token.constant,.token.inserted,.token.number,.token.property,.token.symbol,.token.tag,.token.unit{color:#b5cea8}.token.attr-name,.token.builtin,.token.char,.token.deleted,.token.selector,.token.string{color:#ce9178}.language-css .token.string.url{text-decoration:underline}.token.entity,.token.operator{color:#d4d4d4}.token.operator.arrow{color:#569cd6}.token.atrule{color:#ce9178}.token.atrule .token.rule{color:#c586c0}.token.atrule .token.url{color:#9cdcfe}.token.atrule .token.url .token.function{color:#dcdcaa}.token.atrule .token.url .token.punctuation{color:#d4d4d4}.token.keyword{color:#569cd6}.token.keyword.control-flow,.token.keyword.module{color:#c586c0}.token.function,.token.function .token.maybe-class-name{color:#dcdcaa}.token.regex{color:#d16969}.token.important{color:#569cd6}.token.italic{font-style:italic}.token.constant{color:#9cdcfe}.token.class-name,.token.maybe-class-name{color:#4ec9b0}.token.console,.token.interpolation,.token.parameter{color:#9cdcfe}.token.boolean,.token.punctuation.interpolation-punctuation{color:#569cd6}.token.exports .token.maybe-class-name,.token.imports .token.maybe-class-name,.token.property,.token.variable{color:#9cdcfe}.token.escape,.token.selector{color:#d7ba7d}.token.tag{color:#569cd6}.token.cdata,.token.tag .token.punctuation{color:grey}.token.attr-name{color:#9cdcfe}.token.attr-value,.token.attr-value .token.punctuation{color:#ce9178}.token.attr-value .token.punctuation.attr-equals{color:#d4d4d4}.token.entity{color:#569cd6}.token.namespace{color:#4ec9b0}code[class*=language-javascript],code[class*=language-jsx],code[class*=language-tsx],code[class*=language-typescript],pre[class*=language-javascript],pre[class*=language-jsx],pre[class*=language-tsx],pre[class*=language-typescript]{color:#9cdcfe}code[class*=language-css],pre[class*=language-css]{color:#ce9178}code[class*=language-html],pre[class*=language-html]{color:#d4d4d4}.language-regex .token.anchor{color:#dcdcaa}.language-html .token.punctuation{color:grey}pre[data-line]{position:relative}pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}.line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:#f7ebc6;box-shadow:inset 5px 0 0 #f7d87c;z-index:0;pointer-events:none;line-height:inherit;white-space:pre}"; | ||
n(css$1,{"singleTag":true}); | ||
function MiniEditor(props) { | ||
var _a = props.progress, progress = _a === void 0 ? 0 : _a, _b = props.backward, backward = _b === void 0 ? false : _b, code = props.code, focus = props.focus, lang = props.lang, file = props.file, ogSteps = props.steps, _c = props.minColumns, minColumns = _c === void 0 ? 50 : _c, height = props.height, rest = __rest(props | ||
// console.log({ props }) | ||
, ["progress", "backward", "code", "focus", "lang", "file", "steps", "minColumns", "height"]); | ||
// console.log({ props }) | ||
var _a = props.progress, progress = _a === void 0 ? 0 : _a, _b = props.backward, backward = _b === void 0 ? false : _b, code = props.code, focus = props.focus, lang = props.lang, file = props.file, ogSteps = props.steps, ogTabs = props.tabs, _c = props.minColumns, minColumns = _c === void 0 ? 50 : _c, height = props.height, rest = __rest(props, ["progress", "backward", "code", "focus", "lang", "file", "steps", "tabs", "minColumns", "height"]); | ||
var _d = useSteps(ogSteps, { | ||
@@ -448,2 +547,3 @@ code: code, | ||
file: file, | ||
tabs: ogTabs, | ||
}), steps = _d.steps, files = _d.files, stepsByFile = _d.stepsByFile; | ||
@@ -489,8 +589,6 @@ var activeStepIndex = backward | ||
: fwdTransitions[transitionIndex], prevCode = _b.prevCode, nextCode = _b.nextCode, prevFocus = _b.prevFocus, nextFocus = _b.nextFocus, lang = _b.lang; | ||
return (React.createElement(Code, { prevCode: prevCode || nextCode, nextCode: nextCode || prevCode, prevFocus: prevFocus, nextFocus: nextFocus, language: lang, progress: progress - transitionIndex + 1, parentHeight: parentHeight, | ||
// TODO make prop | ||
minColumns: minColumns })); | ||
return (React.createElement(Code, { prevCode: prevCode || nextCode, nextCode: nextCode || prevCode, prevFocus: prevFocus, nextFocus: nextFocus, language: lang, progress: progress - transitionIndex + 1, parentHeight: parentHeight, minColumns: minColumns })); | ||
} | ||
function useSteps(ogSteps, _a) { | ||
var _b = _a.code, code = _b === void 0 ? "" : _b, focus = _a.focus, lang = _a.lang, file = _a.file; | ||
var _b = _a.code, code = _b === void 0 ? "" : _b, focus = _a.focus, lang = _a.lang, file = _a.file, tabs = _a.tabs; | ||
return React.useMemo(function () { | ||
@@ -500,3 +598,4 @@ var steps = (ogSteps === null || ogSteps === void 0 ? void 0 : ogSteps.map(function (s) { return (__assign({ code: code, | ||
lang: lang, | ||
file: file }, s)); })) || [{ code: code, focus: focus, lang: lang, file: file }]; | ||
file: file, | ||
tabs: tabs }, s)); })) || [{ code: code, focus: focus, lang: lang, file: file, tabs: tabs }]; | ||
var files = __spread(new Set(steps | ||
@@ -515,3 +614,3 @@ .map(function (s) { return s.file; }) | ||
return { steps: steps, files: files, stepsByFile: stepsByFile }; | ||
}, [ogSteps, code, focus, lang, file]); | ||
}, [ogSteps, code, focus, lang, file, tabs]); | ||
} | ||
@@ -536,2 +635,28 @@ var MAX_HEIGHT = 150; | ||
export { MiniEditor }; | ||
function MiniEditorWithState(_a) { | ||
var focus = _a.focus, code = _a.code, rest = __rest(_a, ["focus", "code"]); | ||
var _b = __read(usePrevFocus(code, focus), 2), steps = _b[0], progress = _b[1]; | ||
return (React.createElement(MiniEditor, __assign({ progress: progress, steps: steps }, rest))); | ||
} | ||
function usePrevFocus(code, focus) { | ||
var _a = __read(React.useState({ | ||
target: 0, | ||
steps: [{ focus: focus, code: code }], | ||
}), 2), state = _a[0], setState = _a[1]; | ||
React.useEffect(function () { | ||
var last = state.steps[state.steps.length - 1]; | ||
if (last.focus !== focus || last.code !== code) { | ||
setState(function (s) { return ({ | ||
target: s.target + 1, | ||
steps: __spread(s.steps, [{ focus: focus, code: code }]), | ||
}); }); | ||
} | ||
}, [focus, code]); | ||
var _b = __read(useSpring(state.target, { | ||
stiffness: 100, | ||
decimals: 3, | ||
}), 1), progress = _b[0]; | ||
return [state.steps, progress]; | ||
} | ||
export { MiniEditor, MiniEditorWithState }; |
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@code-hike/mini-frame'), require('@code-hike/mini-terminal'), require('@code-hike/code-diff'), require('@code-hike/smooth-lines')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'react', '@code-hike/mini-frame', '@code-hike/mini-terminal', '@code-hike/code-diff', '@code-hike/smooth-lines'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.foo = {}, global.React, global.miniFrame, global.miniTerminal, global.codeDiff, global.smoothLines)); | ||
}(this, (function (exports, React, miniFrame, miniTerminal, codeDiff, smoothLines) { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@code-hike/mini-frame'), require('@code-hike/utils'), require('@code-hike/mini-terminal'), require('@code-hike/code-diff'), require('@code-hike/smooth-lines'), require('use-spring')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'react', '@code-hike/mini-frame', '@code-hike/utils', '@code-hike/mini-terminal', '@code-hike/code-diff', '@code-hike/smooth-lines', 'use-spring'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ch = {}, global.React, global.miniFrame, global.utils, global.miniTerminal, global.codeDiff, global.smoothLines, global.useSpring)); | ||
}(this, (function (exports, React, miniFrame, utils, miniTerminal, codeDiff, smoothLines, useSpring) { 'use strict'; | ||
@@ -86,21 +86,23 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
var e=[],t=[];function n(n,r){if(n&&"undefined"!=typeof document){var a,s=!0===r.prepend?"prepend":"append",d=!0===r.singleTag,i="string"==typeof r.container?document.querySelector(r.container):document.getElementsByTagName("head")[0];if(d){var u=e.indexOf(i);-1===u&&(u=e.push(i)-1,t[u]={}),a=t[u]&&t[u][s]?t[u][s]:t[u][s]=c();}else a=c();65279===n.charCodeAt(0)&&(n=n.substring(1)),a.styleSheet?a.styleSheet.cssText+=n:a.appendChild(document.createTextNode(n));}function c(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),r.attributes)for(var t=Object.keys(r.attributes),n=0;n<t.length;n++)e.setAttribute(t[n],r.attributes[t[n]]);var a="prepend"===s?"afterbegin":"beforeend";return i.insertAdjacentElement(a,e),e}} | ||
var css = ".ch-editor-tab{border-right:1px solid #252526;width:120px;min-width:-webkit-fit-content;min-width:-moz-fit-content;min-width:fit-content;flex-shrink:0;position:relative;display:flex;white-space:nowrap;cursor:pointer;height:100%;box-sizing:border-box;padding-left:15px;padding-right:15px;background-color:#2d2d2d;color:hsla(0,0%,100%,.5)}.ch-editor-tab[data-active]{background-color:#1e1e1e;color:#fff}.ch-editor-tab>div{margin-top:auto;margin-bottom:auto;font-size:12px;line-height:1.4em;text-overflow:ellipsis}.ch-editor-body{background-color:#1e1e1e;height:100%;color:#ccc;font-size:15px;padding:5px 10px;line-height:1.1rem;box-sizing:border-box}.ch-editor-body code{line-height:20px}.ch-editor-terminal{position:absolute;overflow:hidden;bottom:0;width:100%;background-color:#1e1e1e;color:#e7e7e7;border-top:1px solid hsla(0,0%,50.2%,.35);padding:0 8px;box-sizing:border-box}.ch-editor-terminal-tab{text-transform:uppercase;padding:4px 10px 3px;font-size:11px;line-height:24px;display:flex}.ch-editor-terminal-tab>span{border-bottom:1px solid #e7e7e7}.ch-editor-terminal-content{margin-top:8px;height:calc(100% - 40px);box-sizing:border-box}.ch-editor-terminal-content .ch-terminal{font-size:12px;margin:0}"; | ||
n(css,{"singleTag":true}); | ||
var c = utils.classNamesWithPrefix("ch-editor"); | ||
var DEFAULT_HEIGHT = 200; | ||
function EditorFrame(_a) { | ||
var files = _a.files, active = _a.active, children = _a.children, terminalPanel = _a.terminalPanel, height = _a.height, style = _a.style, rest = __rest(_a, ["files", "active", "children", "terminalPanel", "height", "style"]); | ||
return (React__default['default'].createElement(miniFrame.MiniFrame, __assign({ titleBar: React__default['default'].createElement(TabsContainer, { files: files, active: active }), style: __assign({ height: height !== null && height !== void 0 ? height : DEFAULT_HEIGHT }, style) }, rest), | ||
React__default['default'].createElement("div", { className: "ch-editor-body" }, children), | ||
var files = _a.files, active = _a.active, children = _a.children, terminalPanel = _a.terminalPanel, height = _a.height, style = _a.style, button = _a.button, classes = _a.classes, rest = __rest(_a, ["files", "active", "children", "terminalPanel", "height", "style", "button", "classes"]); | ||
return (React__default['default'].createElement(miniFrame.MiniFrame, __assign({ titleBar: React__default['default'].createElement(TabsContainer, { files: files, active: active, button: button, classes: classes }), classes: classes, style: __assign({ height: height !== null && height !== void 0 ? height : DEFAULT_HEIGHT }, style) }, rest), | ||
React__default['default'].createElement("div", { className: c("-body", classes) }, children), | ||
terminalPanel)); | ||
} | ||
function TabsContainer(_a) { | ||
var files = _a.files, active = _a.active; | ||
var files = _a.files, active = _a.active, button = _a.button, classes = _a.classes; | ||
return (React__default['default'].createElement(React__default['default'].Fragment, null, | ||
React__default['default'].createElement(miniFrame.FrameButtons, null), | ||
files.map(function (fileName) { return (React__default['default'].createElement("div", { key: fileName, className: "ch-editor-tab", "data-active": fileName === active || undefined }, | ||
React__default['default'].createElement(miniFrame.FrameButtons, { classes: classes }), | ||
files.map(function (fileName) { return (React__default['default'].createElement("div", { key: fileName, className: c([ | ||
"-tab", | ||
fileName === active | ||
? "-tab-active" | ||
: "-tab-inactive", | ||
], classes) }, | ||
React__default['default'].createElement("div", null, fileName))); }), | ||
React__default['default'].createElement("div", { style: { flex: 1 } }))); | ||
React__default['default'].createElement("div", { style: { flex: 1 } }), | ||
button)); | ||
} | ||
@@ -122,2 +124,4 @@ function TerminalPanel(_a) { | ||
var _a = __read(React__default['default'].useState(null), 2), dimensions = _a[0], setDimensions = _a[1]; | ||
var windowWidth = useWindowWidth(); | ||
var fullDeps = __spread(deps, [windowWidth]); | ||
useLayoutEffect(function () { | ||
@@ -146,7 +150,8 @@ var _a, _b, _c, _d, _e, _f, _g, _h; | ||
colWidth: colWidth, | ||
deps: deps, | ||
deps: fullDeps, | ||
}); | ||
} | ||
}, deps); | ||
if (!dimensions || depsChanged(dimensions.deps, deps)) { | ||
}, fullDeps); | ||
if (!dimensions || | ||
depsChanged(dimensions.deps, fullDeps)) { | ||
return [ref, null]; | ||
@@ -165,6 +170,16 @@ } | ||
} | ||
function useWindowWidth() { | ||
var _a = __read(React__default['default'].useState(undefined), 2), width = _a[0], setWidth = _a[1]; | ||
React__default['default'].useEffect(function () { | ||
function handleResize() { | ||
setWidth(window.innerWidth); | ||
} | ||
window.addEventListener("resize", handleResize); | ||
return function () { | ||
return window.removeEventListener("resize", handleResize); | ||
}; | ||
}, []); | ||
return width; | ||
} | ||
/** | ||
* Return the first and last indexes to focus, both included | ||
*/ | ||
function getFocusIndexes(focus, lines) { | ||
@@ -182,2 +197,17 @@ if (!focus) { | ||
} | ||
function getFocusByKey(focus, keys) { | ||
if (!focus) { | ||
// focus all lines | ||
return fromEntries(keys.map(function (key) { return [key, true]; })); | ||
} | ||
else { | ||
var parsed_1 = parseFocus(focus); | ||
var byKey_1 = {}; | ||
Object.keys(parsed_1).forEach(function (i) { | ||
var key = keys[parseInt(i, 10)]; | ||
byKey_1[key] = parsed_1[parseInt(i, 10)]; | ||
}); | ||
return byKey_1; | ||
} | ||
} | ||
function parseFocus(focus) { | ||
@@ -282,3 +312,3 @@ if (!focus) { | ||
var prevCode = _a.prevCode, prevFocus = _a.prevFocus, nextCode = _a.nextCode, nextFocus = _a.nextFocus, progress = _a.progress, language = _a.language, parentHeight = _a.parentHeight, minColumns = _a.minColumns; | ||
var _b = useLineProps(prevCode, nextCode, language, prevFocus, nextFocus), prevLines = _b.prevLines, nextLines = _b.nextLines, prevFocusPair = _b.prevFocusPair, nextFocusPair = _b.nextFocusPair, prevLongestLine = _b.prevLongestLine, nextLongestLine = _b.nextLongestLine; | ||
var _b = useLineProps(prevCode, nextCode, language, prevFocus, nextFocus), prevLines = _b.prevLines, nextLines = _b.nextLines, prevFocusIndexes = _b.prevFocusIndexes, nextFocusIndexes = _b.nextFocusIndexes, prevLongestLine = _b.prevLongestLine, nextLongestLine = _b.nextLongestLine; | ||
var _c = __read(useDimensions([ | ||
@@ -301,3 +331,3 @@ parentHeight, | ||
return Math.max(lw, dimensions.colWidth * minColumns); | ||
}), prevFocus: prevFocusPair, nextFocus: nextFocusPair, maxZoom: 1 })) : (React__default['default'].createElement(React__default['default'].Fragment, null, | ||
}), prevFocus: prevFocusIndexes, nextFocus: nextFocusIndexes, maxZoom: 1 })) : (React__default['default'].createElement(React__default['default'].Fragment, null, | ||
React__default['default'].createElement("div", { className: "prev-longest-line" }, prevLongestLine), | ||
@@ -314,17 +344,47 @@ React__default['default'].createElement("div", { className: "next-longest-line" }, nextLongestLine)))))); | ||
}), prevKeys = _c.prevKeys, nextKeys = _c.nextKeys, codeMap = _c.codeMap; | ||
var prevLines = prevKeys.map(function (key) { return ({ | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
}); }); | ||
var prevFocusPair = getFocusIndexes(prevFocus, prevLines); | ||
var prevLongestLineIndex = longestLineIndex(prevCode, prevFocusPair); | ||
var prevFocusByKey = getFocusByKey(prevFocus, prevKeys); | ||
var prevFocusIndexes = getFocusIndexes(prevFocus, prevKeys); | ||
var prevLongestLineIndex = longestLineIndex(prevCode, prevFocusIndexes); | ||
var nextFocusByKey = getFocusByKey(nextFocus, nextKeys); | ||
var nextFocusIndexes = getFocusIndexes(nextFocus, nextKeys); | ||
var nextLongestLineIndex = longestLineIndex(nextCode, nextFocusIndexes); | ||
var prevLines = prevKeys.map(function (key) { | ||
var prevFocus = prevFocusByKey[key]; | ||
var nextFocus = nextFocusByKey[key]; | ||
var focusPerColumn = Array.isArray(prevFocus) || Array.isArray(nextFocus); | ||
if (!focusPerColumn) { | ||
return { | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
}; | ||
} | ||
else { | ||
return { | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
elementWithProgress: function (progress) { return (React__default['default'].createElement(ColumnedLine, { line: codeMap[key], progress: progress, prevFocus: prevFocus, nextFocus: nextFocus })); }, | ||
}; | ||
} | ||
}); | ||
var prevLongestLine = prevLongestLineIndex == null | ||
? null | ||
: (_a = prevLines[prevLongestLineIndex]) === null || _a === void 0 ? void 0 : _a.element; | ||
var nextLines = nextKeys.map(function (key) { return ({ | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
}); }); | ||
var nextFocusPair = getFocusIndexes(nextFocus, nextLines); | ||
var nextLongestLineIndex = longestLineIndex(nextCode, nextFocusPair); | ||
var nextLines = nextKeys.map(function (key) { | ||
var prevFocus = prevFocusByKey[key]; | ||
var nextFocus = nextFocusByKey[key]; | ||
var focusPerColumn = Array.isArray(prevFocus) || Array.isArray(nextFocus); | ||
if (!focusPerColumn) { | ||
return { | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
}; | ||
} | ||
else { | ||
return { | ||
key: key, | ||
element: React__default['default'].createElement(Line, { line: codeMap[key] }), | ||
elementWithProgress: function (progress) { return (React__default['default'].createElement(ColumnedLine, { line: codeMap[key], progress: progress, prevFocus: prevFocus, nextFocus: nextFocus })); }, | ||
}; | ||
} | ||
}); | ||
var nextLongestLine = nextLongestLineIndex == null | ||
@@ -336,4 +396,4 @@ ? null | ||
nextLines: nextLines, | ||
prevFocusPair: prevFocusPair, | ||
nextFocusPair: nextFocusPair, | ||
prevFocusIndexes: prevFocusIndexes, | ||
nextFocusIndexes: nextFocusIndexes, | ||
prevLongestLine: prevLongestLine, | ||
@@ -353,2 +413,41 @@ nextLongestLine: nextLongestLine, | ||
} | ||
var OFF_OPACITY = 0.33; | ||
function ColumnedLine(_a) { | ||
var line = _a.line, progress = _a.progress, prevFocus = _a.prevFocus, nextFocus = _a.nextFocus; | ||
var columns = React__default['default'].useMemo(function () { | ||
var chars = flatMap(line, function (_a) { | ||
var _b = __read(_a, 2), token = _b[0], type = _b[1]; | ||
return token.split("").map(function (char) { return [char, type]; }); | ||
}); | ||
return chars.map(function (_a, i) { | ||
var _b = __read(_a, 2), char = _b[0], type = _b[1]; | ||
return ({ | ||
char: char, | ||
type: type, | ||
fromOpacity: !prevFocus | ||
? 0.99 // because the line is already transparent | ||
: prevFocus === true || prevFocus.includes(i) | ||
? 0.99 | ||
: OFF_OPACITY, | ||
toOpacity: !nextFocus | ||
? 0.99 // because the line is already transparent | ||
: nextFocus === true || nextFocus.includes(i) | ||
? 0.99 | ||
: OFF_OPACITY, | ||
}); | ||
}); | ||
}, [line, prevFocus, nextFocus]); | ||
return (React__default['default'].createElement("div", { style: { | ||
display: "inline-block", | ||
width: "100%", | ||
} }, columns.map(function (_a, i) { | ||
var char = _a.char, type = _a.type, fromOpacity = _a.fromOpacity, toOpacity = _a.toOpacity; | ||
return (React__default['default'].createElement("span", { className: "token " + type, key: i + 1, style: { | ||
opacity: tween(fromOpacity, toOpacity, progress), | ||
} }, char)); | ||
}))); | ||
} | ||
function tween(p, n, t) { | ||
return (n - p) * t + p; | ||
} | ||
var newlineRe = /\r\n|\r|\n/; | ||
@@ -373,2 +472,6 @@ function longestLineIndex(code, focusIndexes) { | ||
} | ||
function flatMap(array, callbackfn) { | ||
var _a; | ||
return (_a = Array.prototype).concat.apply(_a, __spread(array.map(callbackfn))); | ||
} | ||
@@ -438,10 +541,4 @@ function useForwardTransitions(steps) { | ||
var css$1 = "code[class*=language-],pre[class*=language-]{color:#d4d4d4;font-size:13px;text-shadow:none;font-family:Menlo,Monaco,Consolas,Andale Mono,Ubuntu Mono,Courier New,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection{text-shadow:none;background:#75a7ca}code[class*=language-]::selection,code[class*=language-] ::selection,pre[class*=language-]::selection,pre[class*=language-] ::selection{text-shadow:none;background:#75a7ca}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;background:#1e1e1e}:not(pre)>code[class*=language-]{padding:.1em .3em;border-radius:.3em;color:#db4c69;background:#f9f2f4}.namespace{opacity:.7}.token.doctype .token.doctype-tag{color:#569cd6}.token.doctype .token.name{color:#9cdcfe}.token.comment,.token.prolog{color:#6a9955}.language-html .language-css .token.punctuation,.language-html .language-javascript .token.punctuation,.token.punctuation{color:#d4d4d4}.token.boolean,.token.constant,.token.inserted,.token.number,.token.property,.token.symbol,.token.tag,.token.unit{color:#b5cea8}.token.attr-name,.token.builtin,.token.char,.token.deleted,.token.selector,.token.string{color:#ce9178}.language-css .token.string.url{text-decoration:underline}.token.entity,.token.operator{color:#d4d4d4}.token.operator.arrow{color:#569cd6}.token.atrule{color:#ce9178}.token.atrule .token.rule{color:#c586c0}.token.atrule .token.url{color:#9cdcfe}.token.atrule .token.url .token.function{color:#dcdcaa}.token.atrule .token.url .token.punctuation{color:#d4d4d4}.token.keyword{color:#569cd6}.token.keyword.control-flow,.token.keyword.module{color:#c586c0}.token.function,.token.function .token.maybe-class-name{color:#dcdcaa}.token.regex{color:#d16969}.token.important{color:#569cd6}.token.italic{font-style:italic}.token.constant{color:#9cdcfe}.token.class-name,.token.maybe-class-name{color:#4ec9b0}.token.console,.token.interpolation,.token.parameter{color:#9cdcfe}.token.boolean,.token.punctuation.interpolation-punctuation{color:#569cd6}.token.exports .token.maybe-class-name,.token.imports .token.maybe-class-name,.token.property,.token.variable{color:#9cdcfe}.token.escape,.token.selector{color:#d7ba7d}.token.tag{color:#569cd6}.token.cdata,.token.tag .token.punctuation{color:grey}.token.attr-name{color:#9cdcfe}.token.attr-value,.token.attr-value .token.punctuation{color:#ce9178}.token.attr-value .token.punctuation.attr-equals{color:#d4d4d4}.token.entity{color:#569cd6}.token.namespace{color:#4ec9b0}code[class*=language-javascript],code[class*=language-jsx],code[class*=language-tsx],code[class*=language-typescript],pre[class*=language-javascript],pre[class*=language-jsx],pre[class*=language-tsx],pre[class*=language-typescript]{color:#9cdcfe}code[class*=language-css],pre[class*=language-css]{color:#ce9178}code[class*=language-html],pre[class*=language-html]{color:#d4d4d4}.language-regex .token.anchor{color:#dcdcaa}.language-html .token.punctuation{color:grey}pre[data-line]{position:relative}pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}.line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:#f7ebc6;box-shadow:inset 5px 0 0 #f7d87c;z-index:0;pointer-events:none;line-height:inherit;white-space:pre}"; | ||
n(css$1,{"singleTag":true}); | ||
function MiniEditor(props) { | ||
var _a = props.progress, progress = _a === void 0 ? 0 : _a, _b = props.backward, backward = _b === void 0 ? false : _b, code = props.code, focus = props.focus, lang = props.lang, file = props.file, ogSteps = props.steps, _c = props.minColumns, minColumns = _c === void 0 ? 50 : _c, height = props.height, rest = __rest(props | ||
// console.log({ props }) | ||
, ["progress", "backward", "code", "focus", "lang", "file", "steps", "minColumns", "height"]); | ||
// console.log({ props }) | ||
var _a = props.progress, progress = _a === void 0 ? 0 : _a, _b = props.backward, backward = _b === void 0 ? false : _b, code = props.code, focus = props.focus, lang = props.lang, file = props.file, ogSteps = props.steps, ogTabs = props.tabs, _c = props.minColumns, minColumns = _c === void 0 ? 50 : _c, height = props.height, rest = __rest(props, ["progress", "backward", "code", "focus", "lang", "file", "steps", "tabs", "minColumns", "height"]); | ||
var _d = useSteps(ogSteps, { | ||
@@ -452,2 +549,3 @@ code: code, | ||
file: file, | ||
tabs: ogTabs, | ||
}), steps = _d.steps, files = _d.files, stepsByFile = _d.stepsByFile; | ||
@@ -493,8 +591,6 @@ var activeStepIndex = backward | ||
: fwdTransitions[transitionIndex], prevCode = _b.prevCode, nextCode = _b.nextCode, prevFocus = _b.prevFocus, nextFocus = _b.nextFocus, lang = _b.lang; | ||
return (React__default['default'].createElement(Code, { prevCode: prevCode || nextCode, nextCode: nextCode || prevCode, prevFocus: prevFocus, nextFocus: nextFocus, language: lang, progress: progress - transitionIndex + 1, parentHeight: parentHeight, | ||
// TODO make prop | ||
minColumns: minColumns })); | ||
return (React__default['default'].createElement(Code, { prevCode: prevCode || nextCode, nextCode: nextCode || prevCode, prevFocus: prevFocus, nextFocus: nextFocus, language: lang, progress: progress - transitionIndex + 1, parentHeight: parentHeight, minColumns: minColumns })); | ||
} | ||
function useSteps(ogSteps, _a) { | ||
var _b = _a.code, code = _b === void 0 ? "" : _b, focus = _a.focus, lang = _a.lang, file = _a.file; | ||
var _b = _a.code, code = _b === void 0 ? "" : _b, focus = _a.focus, lang = _a.lang, file = _a.file, tabs = _a.tabs; | ||
return React__default['default'].useMemo(function () { | ||
@@ -504,3 +600,4 @@ var steps = (ogSteps === null || ogSteps === void 0 ? void 0 : ogSteps.map(function (s) { return (__assign({ code: code, | ||
lang: lang, | ||
file: file }, s)); })) || [{ code: code, focus: focus, lang: lang, file: file }]; | ||
file: file, | ||
tabs: tabs }, s)); })) || [{ code: code, focus: focus, lang: lang, file: file, tabs: tabs }]; | ||
var files = __spread(new Set(steps | ||
@@ -519,3 +616,3 @@ .map(function (s) { return s.file; }) | ||
return { steps: steps, files: files, stepsByFile: stepsByFile }; | ||
}, [ogSteps, code, focus, lang, file]); | ||
}, [ogSteps, code, focus, lang, file, tabs]); | ||
} | ||
@@ -540,3 +637,30 @@ var MAX_HEIGHT = 150; | ||
function MiniEditorWithState(_a) { | ||
var focus = _a.focus, code = _a.code, rest = __rest(_a, ["focus", "code"]); | ||
var _b = __read(usePrevFocus(code, focus), 2), steps = _b[0], progress = _b[1]; | ||
return (React__default['default'].createElement(MiniEditor, __assign({ progress: progress, steps: steps }, rest))); | ||
} | ||
function usePrevFocus(code, focus) { | ||
var _a = __read(React__default['default'].useState({ | ||
target: 0, | ||
steps: [{ focus: focus, code: code }], | ||
}), 2), state = _a[0], setState = _a[1]; | ||
React__default['default'].useEffect(function () { | ||
var last = state.steps[state.steps.length - 1]; | ||
if (last.focus !== focus || last.code !== code) { | ||
setState(function (s) { return ({ | ||
target: s.target + 1, | ||
steps: __spread(s.steps, [{ focus: focus, code: code }]), | ||
}); }); | ||
} | ||
}, [focus, code]); | ||
var _b = __read(useSpring.useSpring(state.target, { | ||
stiffness: 100, | ||
decimals: 3, | ||
}), 1), progress = _b[0]; | ||
return [state.steps, progress]; | ||
} | ||
exports.MiniEditor = MiniEditor; | ||
exports.MiniEditorWithState = MiniEditorWithState; | ||
@@ -543,0 +667,0 @@ Object.defineProperty(exports, '__esModule', { value: true }); |
import React from "react"; | ||
import "./theme.css"; | ||
export { MiniEditor }; | ||
@@ -12,3 +11,3 @@ declare type MiniEditorStep = { | ||
}; | ||
declare type MiniEditorProps = { | ||
export declare type MiniEditorProps = { | ||
progress?: number; | ||
@@ -20,6 +19,9 @@ backward?: boolean; | ||
file?: string; | ||
tabs?: string[]; | ||
steps?: MiniEditorStep[]; | ||
height?: number; | ||
minColumns?: number; | ||
button?: React.ReactNode; | ||
classes?: Record<string, string>; | ||
} & React.PropsWithoutRef<JSX.IntrinsicElements["div"]>; | ||
declare function MiniEditor(props: MiniEditorProps): JSX.Element; |
{ | ||
"name": "@code-hike/mini-editor", | ||
"version": "0.0.0-6a7ffe8", | ||
"version": "0.0.0-6dfbe3d", | ||
"main": "dist/index.js", | ||
"typings": "dist/index.d.ts", | ||
"module": "dist/index.esm.js", | ||
"style": "dist/index.css", | ||
"files": [ | ||
@@ -20,6 +21,8 @@ "dist" | ||
"dependencies": { | ||
"@code-hike/mini-terminal": "0.0.0-6a7ffe8", | ||
"@code-hike/mini-frame": "0.0.0-6a7ffe8", | ||
"@code-hike/smooth-lines": "0.0.0-6a7ffe8", | ||
"@code-hike/code-diff": "0.0.0-6a7ffe8" | ||
"@code-hike/code-diff": "0.0.0-6dfbe3d", | ||
"@code-hike/mini-frame": "0.0.0-6dfbe3d", | ||
"@code-hike/mini-terminal": "0.0.0-6dfbe3d", | ||
"@code-hike/smooth-lines": "0.0.0-6dfbe3d", | ||
"@code-hike/utils": "0.0.0-6dfbe3d", | ||
"use-spring": "^0.2.3" | ||
}, | ||
@@ -34,2 +37,3 @@ "peerDependencies": { | ||
"repository": "code-hike/codehike", | ||
"author": "Rodrigo Pombo", | ||
"license": "MIT", | ||
@@ -36,0 +40,0 @@ "funding": { |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
102017
18
2098
1
1
7
+ Addeduse-spring@^0.2.3
+ Added@code-hike/code-diff@0.0.0-6dfbe3d(transitive)
+ Added@code-hike/mini-frame@0.0.0-6dfbe3d(transitive)
+ Added@code-hike/mini-terminal@0.0.0-6dfbe3d(transitive)
+ Added@code-hike/smooth-lines@0.0.0-6dfbe3d(transitive)
+ Added@code-hike/utils@0.0.0-6dfbe3d(transitive)
+ Addedjs-tokens@4.0.0(transitive)
+ Addedloose-envify@1.4.0(transitive)
+ Addedreact@18.3.1(transitive)
+ Addedreact-dom@18.3.1(transitive)
+ Addedscheduler@0.23.2(transitive)
+ Addeduse-spring@0.2.4(transitive)
- Removed@code-hike/code-diff@0.0.0-6a7ffe8(transitive)
- Removed@code-hike/mini-frame@0.0.0-6a7ffe8(transitive)
- Removed@code-hike/mini-terminal@0.0.0-6a7ffe8(transitive)
- Removed@code-hike/smooth-lines@0.0.0-6a7ffe8(transitive)