@code-hike/mini-editor
Advanced tools
Comparing version 0.3.0--canary.77.6c844fa.0 to 0.3.0--canary.77.7150a39.0
import React from "react"; | ||
import { Classes } from "@code-hike/classer"; | ||
import { EditorTheme } from "@code-hike/smooth-code/dist/themes"; | ||
export { EditorFrameProps, getPanelStyles, Snapshot, OutputPanel, TabsSnapshot, Tab, }; | ||
@@ -17,2 +18,3 @@ declare type Tab = { | ||
southPanel?: OutputPanel | null; | ||
theme: EditorTheme; | ||
terminalPanel?: React.ReactNode; | ||
@@ -26,2 +28,3 @@ height?: number; | ||
southPanel?: OutputPanel | null | undefined; | ||
theme: EditorTheme; | ||
terminalPanel?: React.ReactNode; | ||
@@ -28,0 +31,0 @@ height?: number | undefined; |
@@ -8,4 +8,4 @@ 'use strict'; | ||
var classer = require('@code-hike/classer'); | ||
var miniTerminal = require('@code-hike/mini-terminal'); | ||
var smoothCode = require('@code-hike/smooth-code'); | ||
var miniTerminal = require('@code-hike/mini-terminal'); | ||
var useSpring = require('use-spring'); | ||
@@ -78,11 +78,103 @@ | ||
var DEFAULT_HEIGHT = 200; | ||
var ColorName; | ||
(function (ColorName) { | ||
ColorName[ColorName["EditorBackground"] = 0] = "EditorBackground"; | ||
ColorName[ColorName["ActiveTabBackground"] = 1] = "ActiveTabBackground"; | ||
ColorName[ColorName["ActiveTabForeground"] = 2] = "ActiveTabForeground"; | ||
ColorName[ColorName["InactiveTabBackground"] = 3] = "InactiveTabBackground"; | ||
ColorName[ColorName["InactiveTabForeground"] = 4] = "InactiveTabForeground"; | ||
ColorName[ColorName["EditorGroupBorder"] = 5] = "EditorGroupBorder"; | ||
ColorName[ColorName["EditorGroupHeaderBackground"] = 6] = "EditorGroupHeaderBackground"; | ||
ColorName[ColorName["TabBorder"] = 7] = "TabBorder"; | ||
ColorName[ColorName["ActiveTabBottomBorder"] = 8] = "ActiveTabBottomBorder"; | ||
})(ColorName || (ColorName = {})); | ||
var contrastBorder = "#6FC3DF"; | ||
// defaults from: https://github.com/microsoft/vscode/blob/main/src/vs/workbench/common/theme.ts | ||
// keys from : https://code.visualstudio.com/api/references/theme-color#editor-groups-tabs | ||
function getColor(theme, colorName) { | ||
var colors = theme.colors || {}; | ||
switch (colorName) { | ||
case ColorName.EditorBackground: | ||
return (colors["editor.background"] || | ||
getDefault(theme, { | ||
light: "#fffffe", | ||
dark: "#1E1E1E", | ||
hc: "#000000", | ||
})); | ||
case ColorName.ActiveTabBackground: | ||
return (colors["tab.activeBackground"] || | ||
getColor(theme, ColorName.EditorBackground)); | ||
case ColorName.ActiveTabForeground: | ||
return (colors["tab.activeForeground"] || | ||
getDefault(theme, { | ||
dark: "#ffffff", | ||
light: "#333333", | ||
hc: "#ffffff", | ||
})); | ||
case ColorName.InactiveTabBackground: | ||
return (colors["tab.inactiveBackground"] || | ||
getDefault(theme, { | ||
dark: "#2D2D2D", | ||
light: "#ECECEC", | ||
hc: undefined, | ||
})); | ||
case ColorName.InactiveTabForeground: | ||
return (colors["tab.inactiveForeground"] || | ||
getDefault(theme, { | ||
dark: transparent(getColor(theme, ColorName.ActiveTabForeground), 0.5), | ||
light: transparent(getColor(theme, ColorName.ActiveTabForeground), 0.7), | ||
hc: "#ffffff", | ||
})); | ||
case ColorName.TabBorder: | ||
return (colors["tab.border"] || | ||
getDefault(theme, { | ||
dark: "#252526", | ||
light: "#F3F3F3", | ||
hc: contrastBorder, | ||
})); | ||
case ColorName.ActiveTabBottomBorder: | ||
return (colors["tab.activeBorder"] || | ||
getColor(theme, ColorName.ActiveTabBackground)); | ||
case ColorName.EditorGroupBorder: | ||
return (colors["editorGroup.border"] || | ||
getDefault(theme, { | ||
dark: "#444444", | ||
light: "#E7E7E7", | ||
hc: contrastBorder, | ||
})); | ||
case ColorName.EditorGroupHeaderBackground: | ||
return (colors["editorGroupHeader.tabsBackground"] || | ||
getDefault(theme, { | ||
dark: "#252526", | ||
light: "#F3F3F3", | ||
hc: undefined, | ||
})); | ||
default: | ||
return "#f00"; | ||
} | ||
} | ||
function transparent(color, opacity) { | ||
var _opacity = Math.round(Math.min(Math.max(opacity || 1, 0), 1) * 255); | ||
return !color | ||
? color | ||
: color + _opacity.toString(16).toUpperCase(); | ||
} | ||
function getDefault(theme, defaults) { | ||
var _a; | ||
var themeType = (theme.type | ||
? theme.type | ||
: ((_a = theme.name) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes("light")) ? "light" | ||
: "dark"); | ||
return defaults[themeType]; | ||
} | ||
var EditorFrame = React__default['default'].forwardRef(function InnerEditorFrame(_a, ref) { | ||
var northPanel = _a.northPanel, southPanel = _a.southPanel, terminalPanel = _a.terminalPanel, style = _a.style, height = _a.height, button = _a.button, className = _a.className, rest = __rest(_a, ["northPanel", "southPanel", "terminalPanel", "style", "height", "button", "className"]); | ||
var _b; | ||
var northPanel = _a.northPanel, southPanel = _a.southPanel, terminalPanel = _a.terminalPanel, style = _a.style, height = _a.height, button = _a.button, theme = _a.theme, className = _a.className, rest = __rest(_a, ["northPanel", "southPanel", "terminalPanel", "style", "height", "button", "theme", "className"]); | ||
var c = classer.useClasser("ch-editor"); | ||
return (React__default['default'].createElement(miniFrame.MiniFrame, __assign({ ref: ref, style: __assign({ height: height !== null && height !== void 0 ? height : DEFAULT_HEIGHT }, style), className: c("frame") + " " + className, overflow: "unset", titleBar: React__default['default'].createElement(TabsContainer, { tabs: northPanel.tabs, showFrameButtons: true, button: button, panel: "north" }) }, rest), | ||
return (React__default['default'].createElement(miniFrame.MiniFrame, __assign({ ref: ref, style: __assign((_b = { height: height }, _b["--ch-content-background"] = getColor(theme, ColorName.EditorGroupHeaderBackground), _b), style), className: c("frame") + " " + className, overflow: "unset", titleBar: React__default['default'].createElement(TabsContainer, { tabs: northPanel.tabs, showFrameButtons: true, button: button, panel: "north", theme: theme }) }, rest), | ||
React__default['default'].createElement("div", { "data-ch-panel": "north", className: c("body"), style: northPanel.style, children: northPanel.children }), | ||
southPanel && (React__default['default'].createElement("div", { "data-ch-panel": "south", style: __assign({ display: "flex", flexDirection: "column" }, southPanel.style) }, | ||
React__default['default'].createElement("div", { className: "ch-frame-title-bar", style: { background: "none" } }, | ||
React__default['default'].createElement(TabsContainer, { tabs: southPanel.tabs, showFrameButtons: false, topBorder: true, panel: "south" })), | ||
React__default['default'].createElement(TabsContainer, { tabs: southPanel.tabs, showFrameButtons: false, topBorder: true, panel: "south", theme: theme })), | ||
React__default['default'].createElement("div", { className: c("body"), children: southPanel.children, style: { | ||
@@ -96,3 +188,3 @@ flexGrow: 1, | ||
function TabsContainer(_a) { | ||
var tabs = _a.tabs, button = _a.button, showFrameButtons = _a.showFrameButtons, topBorder = _a.topBorder, panel = _a.panel; | ||
var tabs = _a.tabs, button = _a.button, showFrameButtons = _a.showFrameButtons, topBorder = _a.topBorder, panel = _a.panel, theme = _a.theme; | ||
var c = classer.useClasser("ch-editor-tab"); | ||
@@ -103,3 +195,3 @@ return (React__default['default'].createElement(React__default['default'].Fragment, null, | ||
height: "1px", | ||
background: "#151515", | ||
background: getColor(theme, ColorName.EditorGroupBorder), | ||
width: "100%", | ||
@@ -112,3 +204,9 @@ top: 0, | ||
var title = _a.title, active = _a.active, style = _a.style; | ||
return (React__default['default'].createElement("div", { key: title, title: title, "data-ch-tab": panel, className: c("", active ? "active" : "inactive"), style: style }, | ||
return (React__default['default'].createElement("div", { key: title, title: title, "data-ch-tab": panel, className: c("", active ? "active" : "inactive"), style: __assign(__assign({}, style), { background: getColor(theme, active | ||
? ColorName.ActiveTabBackground | ||
: ColorName.InactiveTabBackground), color: getColor(theme, active | ||
? ColorName.ActiveTabForeground | ||
: ColorName.InactiveTabForeground), borderRightColor: getColor(theme, ColorName.TabBorder), borderBottomColor: getColor(theme, active | ||
? ColorName.ActiveTabBottomBorder | ||
: ColorName.InactiveTabBackground) }) }, | ||
React__default['default'].createElement("div", null, title))); | ||
@@ -119,2 +217,206 @@ }), | ||
} | ||
function TerminalPanel(_a) { | ||
var prev = _a.prev, next = _a.next, t = _a.t, backward = _a.backward; | ||
var height = getHeight({ prev: prev, next: next, t: t, backward: backward }); | ||
return !height ? null : (React__default['default'].createElement("div", { className: "ch-editor-terminal", style: { height: height } }, | ||
React__default['default'].createElement("div", { className: "ch-editor-terminal-tab" }, | ||
React__default['default'].createElement("span", null, "Terminal")), | ||
React__default['default'].createElement("div", { className: "ch-editor-terminal-content" }, | ||
React__default['default'].createElement(miniTerminal.InnerTerminal, { steps: [ | ||
{ text: prev || "" }, | ||
{ text: next || "" }, | ||
], progress: t }), | ||
")"))); | ||
} | ||
function getHeight(_a) { | ||
var prev = _a.prev, next = _a.next, t = _a.t; _a.backward; | ||
if (!prev && !next) | ||
return 0; | ||
if (!prev && next) | ||
return MAX_HEIGHT * Math.min(t * 4, 1); | ||
if (prev && !next) | ||
return MAX_HEIGHT * Math.max(1 - t * 4, 0); | ||
return MAX_HEIGHT; | ||
} | ||
var MAX_HEIGHT = 150; | ||
function useTransition(ref, prev, next, t, backward, codeConfig) { | ||
var _a = useSnapshots(ref, prev, next), prevSnapshot = _a.prevSnapshot, nextSnapshot = _a.nextSnapshot; | ||
if (!prevSnapshot) { | ||
return startingPosition(prev, next, codeConfig); | ||
} | ||
if (!nextSnapshot) { | ||
return endingPosition(prev, next, codeConfig); | ||
} | ||
// if (t === 0) { | ||
// return startingPosition(prev, next, codeConfig) | ||
// } | ||
if (t === 1) { | ||
return endingPosition(prev, next, codeConfig); | ||
} | ||
var inputSouthPanel = prev.southPanel || next.southPanel; | ||
var _b = getStepFiles(prev, next, t == 0 || backward), prevNorthFile = _b.prevNorthFile, prevSouthFile = _b.prevSouthFile, nextNorthFile = _b.nextNorthFile, nextSouthFile = _b.nextSouthFile; | ||
var _c = getPanelStyles(prevSnapshot, nextSnapshot, t), northStyle = _c.northStyle, southStyle = _c.southStyle; | ||
var _d = getTabs(prevSnapshot, nextSnapshot, prevNorthFile.name, prevSouthFile === null || prevSouthFile === void 0 ? void 0 : prevSouthFile.name, t), northTabs = _d.northTabs, southTabs = _d.southTabs; | ||
return { | ||
northPanel: { | ||
tabs: northTabs, | ||
style: northStyle, | ||
children: (React__default['default'].createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevNorthFile, nextFile: nextNorthFile, t: t, parentHeight: northStyle.height })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: southTabs, | ||
style: southStyle, | ||
children: (React__default['default'].createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevSouthFile, nextFile: nextSouthFile, t: t, parentHeight: southStyle === null || southStyle === void 0 ? void 0 : southStyle.height })), | ||
}, | ||
}; | ||
} | ||
// Returns the t=0 state of the transition | ||
function startingPosition(prev, next, codeConfig) { | ||
var inputNorthPanel = prev.northPanel; | ||
var inputSouthPanel = prev.southPanel; | ||
var _a = getStepFiles(prev, next, true), prevNorthFile = _a.prevNorthFile, prevSouthFile = _a.prevSouthFile, nextNorthFile = _a.nextNorthFile, nextSouthFile = _a.nextSouthFile; | ||
var northHeight = inputSouthPanel | ||
? "calc((100% - var(--ch-title-bar-height)) * " + inputNorthPanel.heightRatio + ")" | ||
: "100%"; | ||
var southHeight = "calc((100% - var(--ch-title-bar-height)) * " + (inputSouthPanel === null || inputSouthPanel === void 0 ? void 0 : inputSouthPanel.heightRatio) + " + var(--ch-title-bar-height))"; | ||
return { | ||
northPanel: { | ||
tabs: inputNorthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputNorthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: northHeight, | ||
}, | ||
children: (React__default['default'].createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevNorthFile, nextFile: nextNorthFile, t: 0, parentHeight: northHeight })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: inputSouthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputSouthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: "calc((100% - var(--ch-title-bar-height)) * " + inputSouthPanel.heightRatio + " + var(--ch-title-bar-height))", | ||
}, | ||
children: (React__default['default'].createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevSouthFile, nextFile: nextSouthFile, t: 0, parentHeight: southHeight })), | ||
}, | ||
}; | ||
} | ||
// Returns the t=1 state of the transition | ||
function endingPosition(prev, next, codeConfig) { | ||
var _a; | ||
var inputNorthPanel = next.northPanel; | ||
var inputSouthPanel = next.southPanel; | ||
var _b = getStepFiles(prev, next, false), prevNorthFile = _b.prevNorthFile, prevSouthFile = _b.prevSouthFile, nextNorthFile = _b.nextNorthFile, nextSouthFile = _b.nextSouthFile; | ||
// getStepFiles return the intermediate files, we need to patch the ending state (2to1south) | ||
var isTwoToOneSouth = !inputSouthPanel && | ||
inputNorthPanel.active === ((_a = prev === null || prev === void 0 ? void 0 : prev.southPanel) === null || _a === void 0 ? void 0 : _a.active); | ||
if (isTwoToOneSouth) { | ||
nextNorthFile = nextSouthFile; | ||
} | ||
var northHeight = inputSouthPanel | ||
? "calc((100% - var(--ch-title-bar-height)) * " + inputNorthPanel.heightRatio + ")" | ||
: "100%"; | ||
var southHeight = "calc((100% - var(--ch-title-bar-height)) * " + (inputSouthPanel === null || inputSouthPanel === void 0 ? void 0 : inputSouthPanel.heightRatio) + " + var(--ch-title-bar-height))"; | ||
return { | ||
northPanel: { | ||
tabs: inputNorthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputNorthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: northHeight, | ||
}, | ||
children: (React__default['default'].createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevNorthFile, nextFile: nextNorthFile, t: 1, parentHeight: northHeight })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: inputSouthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputSouthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: southHeight, | ||
}, | ||
children: (React__default['default'].createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevSouthFile, nextFile: nextSouthFile, t: 1, parentHeight: southHeight })), | ||
}, | ||
}; | ||
} | ||
function CodeTransition(_a) { | ||
var _b; | ||
var prevFile = _a.prevFile, nextFile = _a.nextFile, t = _a.t, codeConfig = _a.codeConfig, parentHeight = _a.parentHeight; | ||
var htmlProps = __assign(__assign({}, codeConfig === null || codeConfig === void 0 ? void 0 : codeConfig.htmlProps), { style: __assign({ height: "unset" }, (_b = codeConfig === null || codeConfig === void 0 ? void 0 : codeConfig.htmlProps) === null || _b === void 0 ? void 0 : _b.style) }); | ||
return (React__default['default'].createElement(smoothCode.CodeTween, __assign({ progress: t, tween: { prev: prevFile, next: nextFile }, config: __assign(__assign({}, codeConfig), { parentHeight: parentHeight }) }, htmlProps))); | ||
} | ||
/** | ||
* Get the StepFiles for a transition | ||
* in each panel, if the prev and next active files are the same | ||
* we return the prev and next version of that panel | ||
* if the active files are different, we return the same file twice, | ||
* if backward is true we return the prev active file twice, | ||
* or else the next active file twice | ||
*/ | ||
function getStepFiles(prev, next, backward) { | ||
var _a, _b; | ||
// The active file in each panel before and after: | ||
// +----+----+ | ||
// | pn | nn | | ||
// +----+----+ | ||
// | ps | ns | | ||
// +----+----+ | ||
// | ||
var pn = prev.northPanel.active; | ||
var nn = next.northPanel.active; | ||
var ps = (_a = prev.southPanel) === null || _a === void 0 ? void 0 : _a.active; | ||
var ns = (_b = next.southPanel) === null || _b === void 0 ? void 0 : _b.active; | ||
var pnFile = prev.files.find(function (f) { return f.name === pn; }); | ||
var nnFile = next.files.find(function (f) { return f.name === nn; }); | ||
var psFile = ps | ||
? prev.files.find(function (f) { return f.name === ps; }) | ||
: null; | ||
var nsFile = ns | ||
? next.files.find(function (f) { return f.name === ns; }) | ||
: null; | ||
var oneToTwoSouth = !ps && pn === ns; | ||
if (oneToTwoSouth) { | ||
return { | ||
prevNorthFile: nnFile, | ||
nextNorthFile: nnFile, | ||
prevSouthFile: pnFile, | ||
nextSouthFile: nsFile, | ||
}; | ||
} | ||
var twoToOneSouth = !ns && nn === ps; | ||
if (twoToOneSouth) { | ||
return { | ||
prevNorthFile: pnFile, | ||
nextNorthFile: pnFile, | ||
prevSouthFile: psFile, | ||
nextSouthFile: nnFile, | ||
}; | ||
} | ||
var prevNorthFile = pn === nn ? pnFile : backward ? pnFile : nnFile; | ||
var nextNorthFile = pn === nn ? nnFile : backward ? pnFile : nnFile; | ||
var prevSouthFile = ps === ns | ||
? psFile | ||
: backward | ||
? psFile || nsFile | ||
: nsFile || psFile; | ||
var nextSouthFile = ps === ns | ||
? nsFile | ||
: backward | ||
? psFile || nsFile | ||
: nsFile || psFile; | ||
return { | ||
prevNorthFile: prevNorthFile, | ||
nextNorthFile: nextNorthFile, | ||
prevSouthFile: prevSouthFile, | ||
nextSouthFile: nextSouthFile, | ||
}; | ||
} | ||
function getPanelStyles(prev, next, t) { | ||
@@ -224,71 +526,2 @@ // +---+---+ | ||
} | ||
var useLayoutEffect = typeof window !== "undefined" | ||
? React__default['default'].useLayoutEffect | ||
: React__default['default'].useEffect; | ||
function useSnapshots(ref, prev, next) { | ||
var _a = __read(React__default['default'].useState({ | ||
prevSnapshot: null, | ||
nextSnapshot: null, | ||
}), 2), _b = _a[0], prevSnapshot = _b.prevSnapshot, nextSnapshot = _b.nextSnapshot, setState = _a[1]; | ||
useLayoutEffect(function () { | ||
if (prevSnapshot || nextSnapshot) { | ||
setState({ | ||
prevSnapshot: null, | ||
nextSnapshot: null, | ||
}); | ||
} | ||
}, [prev, next]); | ||
useLayoutEffect(function () { | ||
if (!prevSnapshot) { | ||
setState(function (s) { return (__assign(__assign({}, s), { prevSnapshot: __assign(__assign({}, getPanelSnapshot(ref.current, prev)), getTabsSnapshot(ref.current, prev)) })); }); | ||
} | ||
else if (!nextSnapshot) { | ||
setState(function (s) { return (__assign(__assign({}, s), { nextSnapshot: __assign(__assign({}, getPanelSnapshot(ref.current, next)), getTabsSnapshot(ref.current, next)) })); }); | ||
} | ||
}); | ||
return { prevSnapshot: prevSnapshot, nextSnapshot: nextSnapshot }; | ||
} | ||
function getPanelSnapshot(parent, step) { | ||
var _a; | ||
var northElement = parent.querySelector("[data-ch-panel='north']"); | ||
var southElement = parent.querySelector("[data-ch-panel='south']"); | ||
var bar = parent.querySelector(".ch-frame-title-bar"); | ||
return { | ||
titleBarHeight: bar.getBoundingClientRect().height, | ||
northHeight: northElement.getBoundingClientRect() | ||
.height, | ||
northKey: step.northPanel.active, | ||
southHeight: (southElement === null || southElement === void 0 ? void 0 : southElement.getBoundingClientRect().height) || null, | ||
southKey: (_a = step.southPanel) === null || _a === void 0 ? void 0 : _a.active, | ||
}; | ||
} | ||
function getTabsSnapshot(parent, step) { | ||
var _a; | ||
var northTabs = Array.from(parent.querySelectorAll("[data-ch-tab='north']")); | ||
var southTabs = Array.from(parent.querySelectorAll("[data-ch-tab='south']")); | ||
return { | ||
northTabs: getTabsDimensions(northTabs, step.northPanel.active), | ||
southTabs: getTabsDimensions(southTabs, (_a = step.southPanel) === null || _a === void 0 ? void 0 : _a.active), | ||
}; | ||
} | ||
function getTabsDimensions(tabElements, active) { | ||
if (!tabElements[0]) { | ||
return null; | ||
} | ||
var parent = tabElements[0].parentElement; | ||
var parentLeft = parent.getBoundingClientRect().left; | ||
var dimensions = {}; | ||
tabElements.forEach(function (child) { | ||
var filename = child.getAttribute("title"); | ||
var rect = child.getBoundingClientRect(); | ||
dimensions[filename] = { | ||
left: rect.left - parentLeft, | ||
width: rect.width, | ||
active: filename === active, | ||
}; | ||
}); | ||
return dimensions; | ||
} | ||
function getTabs(prevSnapshot, nextSnapshot, northActive, southActive, t) { | ||
@@ -416,231 +649,113 @@ // TODO simplify | ||
} | ||
function TerminalPanel(_a) { | ||
var prev = _a.prev, next = _a.next, t = _a.t, backward = _a.backward; | ||
var height = getHeight({ prev: prev, next: next, t: t, backward: backward }); | ||
return !height ? null : (React__default['default'].createElement("div", { className: "ch-editor-terminal", style: { height: height } }, | ||
React__default['default'].createElement("div", { className: "ch-editor-terminal-tab" }, | ||
React__default['default'].createElement("span", null, "Terminal")), | ||
React__default['default'].createElement("div", { className: "ch-editor-terminal-content" }, | ||
React__default['default'].createElement(miniTerminal.InnerTerminal, { steps: [ | ||
{ text: prev || "" }, | ||
{ text: next || "" }, | ||
], progress: t }), | ||
")"))); | ||
// snapshots | ||
var useLayoutEffect = typeof window !== "undefined" | ||
? React__default['default'].useLayoutEffect | ||
: React__default['default'].useEffect; | ||
function useSnapshots(ref, prev, next) { | ||
var _a = __read(React__default['default'].useState({ | ||
prevSnapshot: null, | ||
nextSnapshot: null, | ||
}), 2), _b = _a[0], prevSnapshot = _b.prevSnapshot, nextSnapshot = _b.nextSnapshot, setState = _a[1]; | ||
useLayoutEffect(function () { | ||
if (prevSnapshot || nextSnapshot) { | ||
setState({ | ||
prevSnapshot: null, | ||
nextSnapshot: null, | ||
}); | ||
} | ||
}, [prev, next]); | ||
useLayoutEffect(function () { | ||
if (!prevSnapshot) { | ||
setState(function (s) { return (__assign(__assign({}, s), { prevSnapshot: __assign(__assign({}, getPanelSnapshot(ref.current, prev)), getTabsSnapshot(ref.current, prev)) })); }); | ||
} | ||
else if (!nextSnapshot) { | ||
setState(function (s) { return (__assign(__assign({}, s), { nextSnapshot: __assign(__assign({}, getPanelSnapshot(ref.current, next)), getTabsSnapshot(ref.current, next)) })); }); | ||
} | ||
}); | ||
return { prevSnapshot: prevSnapshot, nextSnapshot: nextSnapshot }; | ||
} | ||
function getHeight(_a) { | ||
var prev = _a.prev, next = _a.next, t = _a.t; _a.backward; | ||
if (!prev && !next) | ||
return 0; | ||
if (!prev && next) | ||
return MAX_HEIGHT * Math.min(t * 4, 1); | ||
if (prev && !next) | ||
return MAX_HEIGHT * Math.max(1 - t * 4, 0); | ||
return MAX_HEIGHT; | ||
} | ||
var MAX_HEIGHT = 150; | ||
var DEFAULT_STEP = { | ||
files: [{ code: "", lang: "js", name: "" }], | ||
northPanel: { active: "", tabs: [""], heightRatio: 1 }, | ||
}; | ||
function MiniEditorTween(_a) { | ||
var _b = _a.prev, prev = _b === void 0 ? DEFAULT_STEP : _b, _c = _a.next, next = _c === void 0 ? DEFAULT_STEP : _c, t = _a.t, backward = _a.backward, _d = _a.codeProps, codeProps = _d === void 0 ? {} : _d, _e = _a.frameProps, frameProps = _e === void 0 ? {} : _e; | ||
var ref = React__default['default'].createRef(); | ||
var _f = useTransition(ref, prev, next, t, backward, codeProps), northPanel = _f.northPanel, southPanel = _f.southPanel; | ||
var terminalPanel = (React__default['default'].createElement(TerminalPanel, { prev: prev.terminal, next: next.terminal, t: t, backward: backward })); | ||
return (React__default['default'].createElement(EditorFrame, __assign({ ref: ref }, frameProps, { northPanel: northPanel, southPanel: southPanel, terminalPanel: terminalPanel }))); | ||
} | ||
function useTransition(ref, prev, next, t, backward, codeProps) { | ||
var _a = useSnapshots(ref, prev, next), prevSnapshot = _a.prevSnapshot, nextSnapshot = _a.nextSnapshot; | ||
if (!prevSnapshot) { | ||
return startingPosition(prev, next, codeProps); | ||
} | ||
if (!nextSnapshot) { | ||
return endingPosition(prev, next, codeProps); | ||
} | ||
// if (t === 0) { | ||
// return startingPosition(prev, next, codeProps) | ||
// } | ||
if (t === 1) { | ||
return endingPosition(prev, next, codeProps); | ||
} | ||
var inputSouthPanel = prev.southPanel || next.southPanel; | ||
var _b = getStepFiles(prev, next, t == 0 || backward), prevNorthFile = _b.prevNorthFile, prevSouthFile = _b.prevSouthFile, nextNorthFile = _b.nextNorthFile, nextSouthFile = _b.nextSouthFile; | ||
var _c = getPanelStyles(prevSnapshot, nextSnapshot, t), northStyle = _c.northStyle, southStyle = _c.southStyle; | ||
var _d = getTabs(prevSnapshot, nextSnapshot, prevNorthFile.name, prevSouthFile === null || prevSouthFile === void 0 ? void 0 : prevSouthFile.name, t), northTabs = _d.northTabs, southTabs = _d.southTabs; | ||
function getPanelSnapshot(parent, step) { | ||
var _a; | ||
var northElement = parent.querySelector("[data-ch-panel='north']"); | ||
var southElement = parent.querySelector("[data-ch-panel='south']"); | ||
var bar = parent.querySelector(".ch-frame-title-bar"); | ||
return { | ||
northPanel: { | ||
tabs: northTabs, | ||
style: northStyle, | ||
children: (React__default['default'].createElement(CodeTransition, { codeProps: codeProps, prevFile: prevNorthFile, nextFile: nextNorthFile, t: t, parentHeight: northStyle.height })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: southTabs, | ||
style: southStyle, | ||
children: (React__default['default'].createElement(CodeTransition, { codeProps: codeProps, prevFile: prevSouthFile, nextFile: nextSouthFile, t: t, parentHeight: southStyle === null || southStyle === void 0 ? void 0 : southStyle.height })), | ||
}, | ||
titleBarHeight: bar.getBoundingClientRect().height, | ||
northHeight: northElement.getBoundingClientRect() | ||
.height, | ||
northKey: step.northPanel.active, | ||
southHeight: (southElement === null || southElement === void 0 ? void 0 : southElement.getBoundingClientRect().height) || null, | ||
southKey: (_a = step.southPanel) === null || _a === void 0 ? void 0 : _a.active, | ||
}; | ||
} | ||
// Returns the t=0 state of the transition | ||
function startingPosition(prev, next, codeProps) { | ||
var inputNorthPanel = prev.northPanel; | ||
var inputSouthPanel = prev.southPanel; | ||
var _a = getStepFiles(prev, next, true), prevNorthFile = _a.prevNorthFile, prevSouthFile = _a.prevSouthFile, nextNorthFile = _a.nextNorthFile, nextSouthFile = _a.nextSouthFile; | ||
var northHeight = inputSouthPanel | ||
? "calc((100% - var(--ch-title-bar-height)) * " + inputNorthPanel.heightRatio + ")" | ||
: "100%"; | ||
var southHeight = "calc((100% - var(--ch-title-bar-height)) * " + (inputSouthPanel === null || inputSouthPanel === void 0 ? void 0 : inputSouthPanel.heightRatio) + " + var(--ch-title-bar-height))"; | ||
return { | ||
northPanel: { | ||
tabs: inputNorthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputNorthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: northHeight, | ||
}, | ||
children: (React__default['default'].createElement(CodeTransition, { codeProps: codeProps, prevFile: prevNorthFile, nextFile: nextNorthFile, t: 0, parentHeight: northHeight })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: inputSouthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputSouthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: "calc((100% - var(--ch-title-bar-height)) * " + inputSouthPanel.heightRatio + " + var(--ch-title-bar-height))", | ||
}, | ||
children: (React__default['default'].createElement(CodeTransition, { codeProps: codeProps, prevFile: prevSouthFile, nextFile: nextSouthFile, t: 0, parentHeight: southHeight })), | ||
}, | ||
}; | ||
} | ||
// Returns the t=1 state of the transition | ||
function endingPosition(prev, next, codeProps) { | ||
function getTabsSnapshot(parent, step) { | ||
var _a; | ||
var inputNorthPanel = next.northPanel; | ||
var inputSouthPanel = next.southPanel; | ||
var _b = getStepFiles(prev, next, false), prevNorthFile = _b.prevNorthFile, prevSouthFile = _b.prevSouthFile, nextNorthFile = _b.nextNorthFile, nextSouthFile = _b.nextSouthFile; | ||
// getStepFiles return the intermediate files, we need to patch the ending state (2to1south) | ||
var isTwoToOneSouth = !inputSouthPanel && | ||
inputNorthPanel.active === ((_a = prev === null || prev === void 0 ? void 0 : prev.southPanel) === null || _a === void 0 ? void 0 : _a.active); | ||
if (isTwoToOneSouth) { | ||
nextNorthFile = nextSouthFile; | ||
} | ||
var northHeight = inputSouthPanel | ||
? "calc((100% - var(--ch-title-bar-height)) * " + inputNorthPanel.heightRatio + ")" | ||
: "100%"; | ||
var southHeight = "calc((100% - var(--ch-title-bar-height)) * " + (inputSouthPanel === null || inputSouthPanel === void 0 ? void 0 : inputSouthPanel.heightRatio) + " + var(--ch-title-bar-height))"; | ||
var northTabs = Array.from(parent.querySelectorAll("[data-ch-tab='north']")); | ||
var southTabs = Array.from(parent.querySelectorAll("[data-ch-tab='south']")); | ||
return { | ||
northPanel: { | ||
tabs: inputNorthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputNorthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: northHeight, | ||
}, | ||
children: (React__default['default'].createElement(CodeTransition, { codeProps: codeProps, prevFile: prevNorthFile, nextFile: nextNorthFile, t: 1, parentHeight: northHeight })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: inputSouthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputSouthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: southHeight, | ||
}, | ||
children: (React__default['default'].createElement(CodeTransition, { codeProps: codeProps, prevFile: prevSouthFile, nextFile: nextSouthFile, t: 1, parentHeight: southHeight })), | ||
}, | ||
northTabs: getTabsDimensions(northTabs, step.northPanel.active), | ||
southTabs: getTabsDimensions(southTabs, (_a = step.southPanel) === null || _a === void 0 ? void 0 : _a.active), | ||
}; | ||
} | ||
function CodeTransition(_a) { | ||
var prevFile = _a.prevFile, nextFile = _a.nextFile, t = _a.t, codeProps = _a.codeProps, parentHeight = _a.parentHeight; | ||
return (React__default['default'].createElement(smoothCode.Code, __assign({}, codeProps, { code: { prev: prevFile.code, next: nextFile.code }, focus: { prev: prevFile.focus, next: nextFile.focus }, annotations: { | ||
prev: prevFile.annotations, | ||
next: nextFile.annotations, | ||
}, progress: t, language: prevFile.lang, parentHeight: parentHeight }))); | ||
} | ||
/** | ||
* Get the StepFiles for a transition | ||
* in each panel, if the prev and next active files are the same | ||
* we return the prev and next version of that panel | ||
* if the active files are different, we return the same file twice, | ||
* if backward is true we return the prev active file twice, | ||
* or else the next active file twice | ||
*/ | ||
function getStepFiles(prev, next, backward) { | ||
var _a, _b; | ||
// The active file in each panel before and after: | ||
// +----+----+ | ||
// | pn | nn | | ||
// +----+----+ | ||
// | ps | ns | | ||
// +----+----+ | ||
// | ||
var pn = prev.northPanel.active; | ||
var nn = next.northPanel.active; | ||
var ps = (_a = prev.southPanel) === null || _a === void 0 ? void 0 : _a.active; | ||
var ns = (_b = next.southPanel) === null || _b === void 0 ? void 0 : _b.active; | ||
var pnFile = prev.files.find(function (f) { return f.name === pn; }); | ||
var nnFile = next.files.find(function (f) { return f.name === nn; }); | ||
var psFile = ps | ||
? prev.files.find(function (f) { return f.name === ps; }) | ||
: null; | ||
var nsFile = ns | ||
? next.files.find(function (f) { return f.name === ns; }) | ||
: null; | ||
var oneToTwoSouth = !ps && pn === ns; | ||
if (oneToTwoSouth) { | ||
return { | ||
prevNorthFile: nnFile, | ||
nextNorthFile: nnFile, | ||
prevSouthFile: pnFile, | ||
nextSouthFile: nsFile, | ||
}; | ||
function getTabsDimensions(tabElements, active) { | ||
if (!tabElements[0]) { | ||
return null; | ||
} | ||
var twoToOneSouth = !ns && nn === ps; | ||
if (twoToOneSouth) { | ||
return { | ||
prevNorthFile: pnFile, | ||
nextNorthFile: pnFile, | ||
prevSouthFile: psFile, | ||
nextSouthFile: nnFile, | ||
var parent = tabElements[0].parentElement; | ||
var parentLeft = parent.getBoundingClientRect().left; | ||
var dimensions = {}; | ||
tabElements.forEach(function (child) { | ||
var filename = child.getAttribute("title"); | ||
var rect = child.getBoundingClientRect(); | ||
dimensions[filename] = { | ||
left: rect.left - parentLeft, | ||
width: rect.width, | ||
active: filename === active, | ||
}; | ||
} | ||
var prevNorthFile = pn === nn ? pnFile : backward ? pnFile : nnFile; | ||
var nextNorthFile = pn === nn ? nnFile : backward ? pnFile : nnFile; | ||
var prevSouthFile = ps === ns | ||
? psFile | ||
: backward | ||
? psFile || nsFile | ||
: nsFile || psFile; | ||
var nextSouthFile = ps === ns | ||
? nsFile | ||
: backward | ||
? psFile || nsFile | ||
: nsFile || psFile; | ||
return { | ||
prevNorthFile: prevNorthFile, | ||
nextNorthFile: nextNorthFile, | ||
prevSouthFile: prevSouthFile, | ||
nextSouthFile: nextSouthFile, | ||
}; | ||
}); | ||
return dimensions; | ||
} | ||
function MiniEditorHike(_a) { | ||
var _b = _a.steps, steps = _b === void 0 ? [] : _b, _c = _a.progress, progress = _c === void 0 ? 0 : _c, _d = _a.backward, backward = _d === void 0 ? false : _d, frameProps = _a.frameProps, codeProps = _a.codeProps; | ||
var prevIndex = clamp(Math.floor(progress), 0, steps.length - 1); | ||
var nextIndex = clamp(prevIndex + 1, 0, steps.length - 1); | ||
var prev = steps[prevIndex]; | ||
var next = steps[nextIndex]; | ||
var t = clamp(progress - prevIndex, 0, steps.length - 1); | ||
return (React__default['default'].createElement(MiniEditorTween, { frameProps: frameProps, codeProps: codeProps, prev: prev, next: next, backward: backward, t: t })); | ||
var DEFAULT_STEP = { | ||
files: [ | ||
{ | ||
code: { lines: [], lang: "js" }, | ||
focus: "", | ||
name: "", | ||
}, | ||
], | ||
northPanel: { active: "", tabs: [""], heightRatio: 1 }, | ||
}; | ||
function EditorTween(_a) { | ||
var _b = _a.prev, prev = _b === void 0 ? DEFAULT_STEP : _b, next = _a.next, t = _a.t, backward = _a.backward, codeConfig = _a.codeConfig, _c = _a.frameProps, frameProps = _c === void 0 ? {} : _c, divProps = __rest(_a, ["prev", "next", "t", "backward", "codeConfig", "frameProps"]); | ||
var ref = React__default['default'].createRef(); | ||
var _d = useTransition(ref, prev, next || prev, t, backward, codeConfig), northPanel = _d.northPanel, southPanel = _d.southPanel; | ||
var defaultHeight = useDefaultHeight(prev); | ||
var framePropsWithHeight = __assign(__assign(__assign({}, frameProps), divProps), { style: __assign(__assign({ height: defaultHeight }, frameProps === null || frameProps === void 0 ? void 0 : frameProps.style), divProps === null || divProps === void 0 ? void 0 : divProps.style) }); | ||
var terminalPanel = (React__default['default'].createElement(TerminalPanel, { prev: prev.terminal, next: (next || prev).terminal, t: t, backward: backward })); | ||
return (React__default['default'].createElement(EditorFrame, __assign({ ref: ref }, framePropsWithHeight, { northPanel: northPanel, southPanel: southPanel, terminalPanel: terminalPanel, theme: codeConfig.theme }))); | ||
} | ||
function clamp(a, min, max) { | ||
return Math.max(Math.min(a, max), min); | ||
function useDefaultHeight(_a) { | ||
var files = _a.files, northPanel = _a.northPanel, southPanel = _a.southPanel; | ||
return React__default['default'].useMemo(function () { | ||
var northFile = files.find(function (_a) { | ||
var name = _a.name; | ||
return name === northPanel.active; | ||
}); | ||
var southFile = files.find(function (_a) { | ||
var name = _a.name; | ||
return name === (southPanel === null || southPanel === void 0 ? void 0 : southPanel.active); | ||
}); | ||
var focusedLines = getFocusedLineCount(northFile) + 3.9; | ||
if (southFile) { | ||
focusedLines += getFocusedLineCount(southFile) + 3.9; | ||
} | ||
var emHeight = focusedLines * 1.5; | ||
return emHeight + "em"; | ||
}, []); | ||
} | ||
function getFocusedLineCount(_a) { | ||
var code = _a.code; _a.focus; | ||
return code.lines.length; | ||
} | ||
@@ -653,49 +768,3 @@ var defaultSpring = { | ||
}; | ||
function MiniEditor(props) { | ||
if ("northPanel" in props) { | ||
return React__default['default'].createElement(TwoPanelEditor, __assign({}, props)); | ||
} | ||
else if ("active" in props) { | ||
return React__default['default'].createElement(SinglePanelEditor, __assign({}, props)); | ||
} | ||
else { | ||
return React__default['default'].createElement(SingleFileEditor, __assign({}, props)); | ||
} | ||
} | ||
function SingleFileEditor(_a) { | ||
var _b = _a.code, code = _b === void 0 ? "" : _b, _c = _a.lang, lang = _c === void 0 ? "js" : _c, focus = _a.focus, _d = _a.filename, filename = _d === void 0 ? "" : _d, terminal = _a.terminal, springConfig = _a.springConfig, props = __rest(_a, ["code", "lang", "focus", "filename", "terminal", "springConfig"]); | ||
var step = React__default['default'].useMemo(function () { | ||
var step = { | ||
files: [{ name: filename, code: code, lang: lang, focus: focus }], | ||
northPanel: { | ||
active: filename, | ||
tabs: [filename], | ||
heightRatio: 1, | ||
}, | ||
terminal: terminal, | ||
}; | ||
return step; | ||
}, [code, lang, focus, filename, terminal]); | ||
var _e = useStepSpring(step, springConfig), prev = _e.prev, next = _e.next, t = _e.t; | ||
return (React__default['default'].createElement(MiniEditorTween, __assign({ t: t, backward: false, prev: prev, next: next }, props))); | ||
} | ||
function SinglePanelEditor(_a) { | ||
var files = _a.files, active = _a.active, terminal = _a.terminal, springConfig = _a.springConfig, props = __rest(_a, ["files", "active", "terminal", "springConfig"]); | ||
var step = React__default['default'].useMemo(function () { | ||
var tabs = files.map(function (file) { return file.name; }); | ||
var step = { | ||
files: files, | ||
northPanel: { | ||
active: active, | ||
tabs: tabs, | ||
heightRatio: 1, | ||
}, | ||
terminal: terminal, | ||
}; | ||
return step; | ||
}, [files, active, terminal]); | ||
var _b = useStepSpring(step, springConfig), prev = _b.prev, next = _b.next, t = _b.t; | ||
return (React__default['default'].createElement(MiniEditorTween, __assign({ t: t, backward: false, prev: prev, next: next }, props))); | ||
} | ||
function TwoPanelEditor(_a) { | ||
function EditorSpring(_a) { | ||
var northPanel = _a.northPanel, southPanel = _a.southPanel, files = _a.files, terminal = _a.terminal, springConfig = _a.springConfig, props = __rest(_a, ["northPanel", "southPanel", "files", "terminal", "springConfig"]); | ||
@@ -711,3 +780,3 @@ var step = React__default['default'].useMemo(function () { | ||
var _b = useStepSpring(step, springConfig), prev = _b.prev, next = _b.next, t = _b.t; | ||
return (React__default['default'].createElement(MiniEditorTween, __assign({ t: t, backward: false, prev: prev, next: next }, props))); | ||
return (React__default['default'].createElement(EditorTween, __assign({ t: t, backward: false, prev: prev, next: next }, props))); | ||
} | ||
@@ -735,114 +804,3 @@ function useStepSpring(step, springConfig) { | ||
function mdxToSteps(children, settings) { | ||
if (settings === void 0) { settings = {}; } | ||
var steps = []; | ||
children.forEach(function (child, i) { | ||
steps.push(mdxToStep(child, steps[i - 1], settings)); | ||
}); | ||
return steps; | ||
} | ||
var defaultFileName = "index.js"; | ||
function mdxToStep(child, prev, settings) { | ||
var _a; | ||
if (settings === void 0) { settings = {}; } | ||
var stepProps = (child === null || child === void 0 ? void 0 : child.props) || {}; | ||
var stepChildren = React__default['default'].Children.toArray(stepProps.children); | ||
var separatorIndex = stepChildren.findIndex(function (child) { var _a; return ((_a = child === null || child === void 0 ? void 0 : child.props) === null || _a === void 0 ? void 0 : _a.mdxType) === "hr"; }); | ||
var hasTwoPanels = separatorIndex !== -1; | ||
var northChildren = hasTwoPanels | ||
? stepChildren.slice(0, separatorIndex) | ||
: stepChildren; | ||
var southChildren = hasTwoPanels | ||
? stepChildren.slice(separatorIndex + 1) | ||
: null; | ||
var northFiles = northChildren.map(function (pre) { | ||
return preToFile(pre, prev ? prev.files : [], settings); | ||
}); | ||
var southFiles = southChildren === null || southChildren === void 0 ? void 0 : southChildren.map(function (pre) { | ||
return preToFile(pre, prev ? prev.files : [], settings); | ||
}); | ||
var prevFiles = (prev === null || prev === void 0 ? void 0 : prev.files) || []; | ||
var files = __spread(prevFiles.filter(function (f) { | ||
return !northFiles.some(function (nf) { return nf.name === f.name; }) && | ||
!(southFiles === null || southFiles === void 0 ? void 0 : southFiles.some(function (sf) { return sf.name === f.name; })); | ||
}), northFiles, (southFiles || [])); | ||
return { | ||
files: files, | ||
northPanel: { | ||
tabs: chooseNorthTabs(prev, northFiles, southFiles), | ||
active: chooseActiveFile(northFiles, prev === null || prev === void 0 ? void 0 : prev.northPanel.active), | ||
heightRatio: 0.5, | ||
}, | ||
southPanel: southFiles && southFiles.length | ||
? { | ||
tabs: chooseSouthTabs(prev, northFiles, southFiles), | ||
active: chooseActiveFile(southFiles, (_a = prev === null || prev === void 0 ? void 0 : prev.southPanel) === null || _a === void 0 ? void 0 : _a.active), | ||
heightRatio: 0.5, | ||
} | ||
: undefined, | ||
}; | ||
} | ||
function chooseNorthTabs(prev, northFiles, southFiles) { | ||
// old north tabs + new north tabs (except hidden) - new south tabs | ||
var oldNorthTabs = (prev === null || prev === void 0 ? void 0 : prev.northPanel.tabs) || []; | ||
var newSouthTabs = (southFiles || []).map(function (f) { return f.name; }); | ||
var newNorthTabs = northFiles | ||
.filter(function (f) { return !f.hidden && !oldNorthTabs.includes(f.name); }) | ||
.map(function (f) { return f.name; }); | ||
var baseTabs = oldNorthTabs.filter(function (tab) { return !newSouthTabs.includes(tab); }); | ||
return __spread(baseTabs, newNorthTabs); | ||
} | ||
function chooseSouthTabs(prev, northFiles, southFiles) { | ||
var _a; | ||
// old south tabs + new south tabs (except hidden) - new north tabs | ||
var oldSouthTabs = ((_a = prev === null || prev === void 0 ? void 0 : prev.southPanel) === null || _a === void 0 ? void 0 : _a.tabs) || []; | ||
var newSouthTabs = (southFiles || []) | ||
.filter(function (f) { return !f.hidden && !oldSouthTabs.includes(f.name); }) | ||
.map(function (f) { return f.name; }); | ||
var newNorthTabs = northFiles.map(function (f) { return f.name; }); | ||
var baseTabs = oldSouthTabs.filter(function (tab) { return !newNorthTabs.includes(tab); }); | ||
return __spread(baseTabs, newSouthTabs); | ||
} | ||
function chooseActiveFile(panelFiles, prev) { | ||
var _a, _b; | ||
var active = ((_a = panelFiles.find(function (file) { return file.active; })) === null || _a === void 0 ? void 0 : _a.name) || ((_b = panelFiles[0]) === null || _b === void 0 ? void 0 : _b.name) || | ||
prev; | ||
if (!active) { | ||
throw new Error("Something is wrong with Code Hike"); | ||
} | ||
return active; | ||
} | ||
function preToFile(preElement, prevFiles, settings) { | ||
var _a, _b, _c; | ||
var codeElementProps = ((_b = (_a = preElement === null || preElement === void 0 ? void 0 : preElement.props) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b.props) || {}; | ||
var lang = (_c = codeElementProps.className) === null || _c === void 0 ? void 0 : _c.slice(9); | ||
var _d = parseMetastring(codeElementProps.metastring || ""), name = _d.name, options = __rest(_d, ["name"]); | ||
var fileName = name || (settings === null || settings === void 0 ? void 0 : settings.defaultFileName) || defaultFileName; | ||
var code = codeElementProps.children; | ||
var prevFile = prevFiles.find(function (file) { return file.name === fileName; }); | ||
return __assign({ code: code.trim() === "" && prevFile ? prevFile.code : code, lang: lang, name: fileName }, options); | ||
} | ||
function parseMetastring(metastring) { | ||
var params = metastring.split(" "); | ||
var options = {}; | ||
var name = null; | ||
params.forEach(function (param) { | ||
var _a = __read(param.split("="), 2), key = _a[0], value = _a[1]; | ||
if (value != null) { | ||
options[key] = value; | ||
} | ||
else if (name === null) { | ||
name = key; | ||
} | ||
else { | ||
options[key] = true; | ||
} | ||
}); | ||
return __assign({ name: name }, options); | ||
} | ||
exports.MiniEditor = MiniEditor; | ||
exports.MiniEditorHike = MiniEditorHike; | ||
exports.MiniEditorTween = MiniEditorTween; | ||
exports.mdxToStep = mdxToStep; | ||
exports.mdxToSteps = mdxToSteps; | ||
exports.EditorSpring = EditorSpring; | ||
exports.EditorTween = EditorTween; |
import "./index.scss"; | ||
import { MiniEditorTween, MiniEditorTweenProps } from "./mini-editor-tween"; | ||
import { MiniEditorHike, MiniEditorHikeProps, EditorStep } from "./mini-editor-hike"; | ||
import { MiniEditor, MiniEditorProps } from "./mini-editor-spring"; | ||
import { mdxToStep, mdxToSteps } from "./mdx"; | ||
export { mdxToStep, mdxToSteps, MiniEditorTween, MiniEditorTweenProps, MiniEditor, MiniEditorProps, MiniEditorHike, MiniEditorHikeProps, EditorStep, }; | ||
import { EditorTween } from "./editor-tween"; | ||
import { EditorSpring, EditorProps, EditorStep, CodeFile } from "./editor-spring"; | ||
export { EditorTween, EditorSpring, EditorProps, EditorStep, CodeFile, }; |
import React from 'react'; | ||
import { MiniFrame, FrameButtons } from '@code-hike/mini-frame'; | ||
import { useClasser } from '@code-hike/classer'; | ||
import { Code } from '@code-hike/smooth-code'; | ||
import { InnerTerminal } from '@code-hike/mini-terminal'; | ||
import { CodeTween } from '@code-hike/smooth-code'; | ||
import { useSpring } from 'use-spring'; | ||
@@ -69,11 +69,103 @@ | ||
var DEFAULT_HEIGHT = 200; | ||
var ColorName; | ||
(function (ColorName) { | ||
ColorName[ColorName["EditorBackground"] = 0] = "EditorBackground"; | ||
ColorName[ColorName["ActiveTabBackground"] = 1] = "ActiveTabBackground"; | ||
ColorName[ColorName["ActiveTabForeground"] = 2] = "ActiveTabForeground"; | ||
ColorName[ColorName["InactiveTabBackground"] = 3] = "InactiveTabBackground"; | ||
ColorName[ColorName["InactiveTabForeground"] = 4] = "InactiveTabForeground"; | ||
ColorName[ColorName["EditorGroupBorder"] = 5] = "EditorGroupBorder"; | ||
ColorName[ColorName["EditorGroupHeaderBackground"] = 6] = "EditorGroupHeaderBackground"; | ||
ColorName[ColorName["TabBorder"] = 7] = "TabBorder"; | ||
ColorName[ColorName["ActiveTabBottomBorder"] = 8] = "ActiveTabBottomBorder"; | ||
})(ColorName || (ColorName = {})); | ||
var contrastBorder = "#6FC3DF"; | ||
// defaults from: https://github.com/microsoft/vscode/blob/main/src/vs/workbench/common/theme.ts | ||
// keys from : https://code.visualstudio.com/api/references/theme-color#editor-groups-tabs | ||
function getColor(theme, colorName) { | ||
var colors = theme.colors || {}; | ||
switch (colorName) { | ||
case ColorName.EditorBackground: | ||
return (colors["editor.background"] || | ||
getDefault(theme, { | ||
light: "#fffffe", | ||
dark: "#1E1E1E", | ||
hc: "#000000", | ||
})); | ||
case ColorName.ActiveTabBackground: | ||
return (colors["tab.activeBackground"] || | ||
getColor(theme, ColorName.EditorBackground)); | ||
case ColorName.ActiveTabForeground: | ||
return (colors["tab.activeForeground"] || | ||
getDefault(theme, { | ||
dark: "#ffffff", | ||
light: "#333333", | ||
hc: "#ffffff", | ||
})); | ||
case ColorName.InactiveTabBackground: | ||
return (colors["tab.inactiveBackground"] || | ||
getDefault(theme, { | ||
dark: "#2D2D2D", | ||
light: "#ECECEC", | ||
hc: undefined, | ||
})); | ||
case ColorName.InactiveTabForeground: | ||
return (colors["tab.inactiveForeground"] || | ||
getDefault(theme, { | ||
dark: transparent(getColor(theme, ColorName.ActiveTabForeground), 0.5), | ||
light: transparent(getColor(theme, ColorName.ActiveTabForeground), 0.7), | ||
hc: "#ffffff", | ||
})); | ||
case ColorName.TabBorder: | ||
return (colors["tab.border"] || | ||
getDefault(theme, { | ||
dark: "#252526", | ||
light: "#F3F3F3", | ||
hc: contrastBorder, | ||
})); | ||
case ColorName.ActiveTabBottomBorder: | ||
return (colors["tab.activeBorder"] || | ||
getColor(theme, ColorName.ActiveTabBackground)); | ||
case ColorName.EditorGroupBorder: | ||
return (colors["editorGroup.border"] || | ||
getDefault(theme, { | ||
dark: "#444444", | ||
light: "#E7E7E7", | ||
hc: contrastBorder, | ||
})); | ||
case ColorName.EditorGroupHeaderBackground: | ||
return (colors["editorGroupHeader.tabsBackground"] || | ||
getDefault(theme, { | ||
dark: "#252526", | ||
light: "#F3F3F3", | ||
hc: undefined, | ||
})); | ||
default: | ||
return "#f00"; | ||
} | ||
} | ||
function transparent(color, opacity) { | ||
var _opacity = Math.round(Math.min(Math.max(opacity || 1, 0), 1) * 255); | ||
return !color | ||
? color | ||
: color + _opacity.toString(16).toUpperCase(); | ||
} | ||
function getDefault(theme, defaults) { | ||
var _a; | ||
var themeType = (theme.type | ||
? theme.type | ||
: ((_a = theme.name) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes("light")) ? "light" | ||
: "dark"); | ||
return defaults[themeType]; | ||
} | ||
var EditorFrame = React.forwardRef(function InnerEditorFrame(_a, ref) { | ||
var northPanel = _a.northPanel, southPanel = _a.southPanel, terminalPanel = _a.terminalPanel, style = _a.style, height = _a.height, button = _a.button, className = _a.className, rest = __rest(_a, ["northPanel", "southPanel", "terminalPanel", "style", "height", "button", "className"]); | ||
var _b; | ||
var northPanel = _a.northPanel, southPanel = _a.southPanel, terminalPanel = _a.terminalPanel, style = _a.style, height = _a.height, button = _a.button, theme = _a.theme, className = _a.className, rest = __rest(_a, ["northPanel", "southPanel", "terminalPanel", "style", "height", "button", "theme", "className"]); | ||
var c = useClasser("ch-editor"); | ||
return (React.createElement(MiniFrame, __assign({ ref: ref, style: __assign({ height: height !== null && height !== void 0 ? height : DEFAULT_HEIGHT }, style), className: c("frame") + " " + className, overflow: "unset", titleBar: React.createElement(TabsContainer, { tabs: northPanel.tabs, showFrameButtons: true, button: button, panel: "north" }) }, rest), | ||
return (React.createElement(MiniFrame, __assign({ ref: ref, style: __assign((_b = { height: height }, _b["--ch-content-background"] = getColor(theme, ColorName.EditorGroupHeaderBackground), _b), style), className: c("frame") + " " + className, overflow: "unset", titleBar: React.createElement(TabsContainer, { tabs: northPanel.tabs, showFrameButtons: true, button: button, panel: "north", theme: theme }) }, rest), | ||
React.createElement("div", { "data-ch-panel": "north", className: c("body"), style: northPanel.style, children: northPanel.children }), | ||
southPanel && (React.createElement("div", { "data-ch-panel": "south", style: __assign({ display: "flex", flexDirection: "column" }, southPanel.style) }, | ||
React.createElement("div", { className: "ch-frame-title-bar", style: { background: "none" } }, | ||
React.createElement(TabsContainer, { tabs: southPanel.tabs, showFrameButtons: false, topBorder: true, panel: "south" })), | ||
React.createElement(TabsContainer, { tabs: southPanel.tabs, showFrameButtons: false, topBorder: true, panel: "south", theme: theme })), | ||
React.createElement("div", { className: c("body"), children: southPanel.children, style: { | ||
@@ -87,3 +179,3 @@ flexGrow: 1, | ||
function TabsContainer(_a) { | ||
var tabs = _a.tabs, button = _a.button, showFrameButtons = _a.showFrameButtons, topBorder = _a.topBorder, panel = _a.panel; | ||
var tabs = _a.tabs, button = _a.button, showFrameButtons = _a.showFrameButtons, topBorder = _a.topBorder, panel = _a.panel, theme = _a.theme; | ||
var c = useClasser("ch-editor-tab"); | ||
@@ -94,3 +186,3 @@ return (React.createElement(React.Fragment, null, | ||
height: "1px", | ||
background: "#151515", | ||
background: getColor(theme, ColorName.EditorGroupBorder), | ||
width: "100%", | ||
@@ -103,3 +195,9 @@ top: 0, | ||
var title = _a.title, active = _a.active, style = _a.style; | ||
return (React.createElement("div", { key: title, title: title, "data-ch-tab": panel, className: c("", active ? "active" : "inactive"), style: style }, | ||
return (React.createElement("div", { key: title, title: title, "data-ch-tab": panel, className: c("", active ? "active" : "inactive"), style: __assign(__assign({}, style), { background: getColor(theme, active | ||
? ColorName.ActiveTabBackground | ||
: ColorName.InactiveTabBackground), color: getColor(theme, active | ||
? ColorName.ActiveTabForeground | ||
: ColorName.InactiveTabForeground), borderRightColor: getColor(theme, ColorName.TabBorder), borderBottomColor: getColor(theme, active | ||
? ColorName.ActiveTabBottomBorder | ||
: ColorName.InactiveTabBackground) }) }, | ||
React.createElement("div", null, title))); | ||
@@ -110,2 +208,206 @@ }), | ||
} | ||
function TerminalPanel(_a) { | ||
var prev = _a.prev, next = _a.next, t = _a.t, backward = _a.backward; | ||
var height = getHeight({ prev: prev, next: next, t: t, backward: backward }); | ||
return !height ? null : (React.createElement("div", { className: "ch-editor-terminal", style: { height: height } }, | ||
React.createElement("div", { className: "ch-editor-terminal-tab" }, | ||
React.createElement("span", null, "Terminal")), | ||
React.createElement("div", { className: "ch-editor-terminal-content" }, | ||
React.createElement(InnerTerminal, { steps: [ | ||
{ text: prev || "" }, | ||
{ text: next || "" }, | ||
], progress: t }), | ||
")"))); | ||
} | ||
function getHeight(_a) { | ||
var prev = _a.prev, next = _a.next, t = _a.t; _a.backward; | ||
if (!prev && !next) | ||
return 0; | ||
if (!prev && next) | ||
return MAX_HEIGHT * Math.min(t * 4, 1); | ||
if (prev && !next) | ||
return MAX_HEIGHT * Math.max(1 - t * 4, 0); | ||
return MAX_HEIGHT; | ||
} | ||
var MAX_HEIGHT = 150; | ||
function useTransition(ref, prev, next, t, backward, codeConfig) { | ||
var _a = useSnapshots(ref, prev, next), prevSnapshot = _a.prevSnapshot, nextSnapshot = _a.nextSnapshot; | ||
if (!prevSnapshot) { | ||
return startingPosition(prev, next, codeConfig); | ||
} | ||
if (!nextSnapshot) { | ||
return endingPosition(prev, next, codeConfig); | ||
} | ||
// if (t === 0) { | ||
// return startingPosition(prev, next, codeConfig) | ||
// } | ||
if (t === 1) { | ||
return endingPosition(prev, next, codeConfig); | ||
} | ||
var inputSouthPanel = prev.southPanel || next.southPanel; | ||
var _b = getStepFiles(prev, next, t == 0 || backward), prevNorthFile = _b.prevNorthFile, prevSouthFile = _b.prevSouthFile, nextNorthFile = _b.nextNorthFile, nextSouthFile = _b.nextSouthFile; | ||
var _c = getPanelStyles(prevSnapshot, nextSnapshot, t), northStyle = _c.northStyle, southStyle = _c.southStyle; | ||
var _d = getTabs(prevSnapshot, nextSnapshot, prevNorthFile.name, prevSouthFile === null || prevSouthFile === void 0 ? void 0 : prevSouthFile.name, t), northTabs = _d.northTabs, southTabs = _d.southTabs; | ||
return { | ||
northPanel: { | ||
tabs: northTabs, | ||
style: northStyle, | ||
children: (React.createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevNorthFile, nextFile: nextNorthFile, t: t, parentHeight: northStyle.height })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: southTabs, | ||
style: southStyle, | ||
children: (React.createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevSouthFile, nextFile: nextSouthFile, t: t, parentHeight: southStyle === null || southStyle === void 0 ? void 0 : southStyle.height })), | ||
}, | ||
}; | ||
} | ||
// Returns the t=0 state of the transition | ||
function startingPosition(prev, next, codeConfig) { | ||
var inputNorthPanel = prev.northPanel; | ||
var inputSouthPanel = prev.southPanel; | ||
var _a = getStepFiles(prev, next, true), prevNorthFile = _a.prevNorthFile, prevSouthFile = _a.prevSouthFile, nextNorthFile = _a.nextNorthFile, nextSouthFile = _a.nextSouthFile; | ||
var northHeight = inputSouthPanel | ||
? "calc((100% - var(--ch-title-bar-height)) * " + inputNorthPanel.heightRatio + ")" | ||
: "100%"; | ||
var southHeight = "calc((100% - var(--ch-title-bar-height)) * " + (inputSouthPanel === null || inputSouthPanel === void 0 ? void 0 : inputSouthPanel.heightRatio) + " + var(--ch-title-bar-height))"; | ||
return { | ||
northPanel: { | ||
tabs: inputNorthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputNorthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: northHeight, | ||
}, | ||
children: (React.createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevNorthFile, nextFile: nextNorthFile, t: 0, parentHeight: northHeight })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: inputSouthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputSouthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: "calc((100% - var(--ch-title-bar-height)) * " + inputSouthPanel.heightRatio + " + var(--ch-title-bar-height))", | ||
}, | ||
children: (React.createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevSouthFile, nextFile: nextSouthFile, t: 0, parentHeight: southHeight })), | ||
}, | ||
}; | ||
} | ||
// Returns the t=1 state of the transition | ||
function endingPosition(prev, next, codeConfig) { | ||
var _a; | ||
var inputNorthPanel = next.northPanel; | ||
var inputSouthPanel = next.southPanel; | ||
var _b = getStepFiles(prev, next, false), prevNorthFile = _b.prevNorthFile, prevSouthFile = _b.prevSouthFile, nextNorthFile = _b.nextNorthFile, nextSouthFile = _b.nextSouthFile; | ||
// getStepFiles return the intermediate files, we need to patch the ending state (2to1south) | ||
var isTwoToOneSouth = !inputSouthPanel && | ||
inputNorthPanel.active === ((_a = prev === null || prev === void 0 ? void 0 : prev.southPanel) === null || _a === void 0 ? void 0 : _a.active); | ||
if (isTwoToOneSouth) { | ||
nextNorthFile = nextSouthFile; | ||
} | ||
var northHeight = inputSouthPanel | ||
? "calc((100% - var(--ch-title-bar-height)) * " + inputNorthPanel.heightRatio + ")" | ||
: "100%"; | ||
var southHeight = "calc((100% - var(--ch-title-bar-height)) * " + (inputSouthPanel === null || inputSouthPanel === void 0 ? void 0 : inputSouthPanel.heightRatio) + " + var(--ch-title-bar-height))"; | ||
return { | ||
northPanel: { | ||
tabs: inputNorthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputNorthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: northHeight, | ||
}, | ||
children: (React.createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevNorthFile, nextFile: nextNorthFile, t: 1, parentHeight: northHeight })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: inputSouthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputSouthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: southHeight, | ||
}, | ||
children: (React.createElement(CodeTransition, { codeConfig: codeConfig, prevFile: prevSouthFile, nextFile: nextSouthFile, t: 1, parentHeight: southHeight })), | ||
}, | ||
}; | ||
} | ||
function CodeTransition(_a) { | ||
var _b; | ||
var prevFile = _a.prevFile, nextFile = _a.nextFile, t = _a.t, codeConfig = _a.codeConfig, parentHeight = _a.parentHeight; | ||
var htmlProps = __assign(__assign({}, codeConfig === null || codeConfig === void 0 ? void 0 : codeConfig.htmlProps), { style: __assign({ height: "unset" }, (_b = codeConfig === null || codeConfig === void 0 ? void 0 : codeConfig.htmlProps) === null || _b === void 0 ? void 0 : _b.style) }); | ||
return (React.createElement(CodeTween, __assign({ progress: t, tween: { prev: prevFile, next: nextFile }, config: __assign(__assign({}, codeConfig), { parentHeight: parentHeight }) }, htmlProps))); | ||
} | ||
/** | ||
* Get the StepFiles for a transition | ||
* in each panel, if the prev and next active files are the same | ||
* we return the prev and next version of that panel | ||
* if the active files are different, we return the same file twice, | ||
* if backward is true we return the prev active file twice, | ||
* or else the next active file twice | ||
*/ | ||
function getStepFiles(prev, next, backward) { | ||
var _a, _b; | ||
// The active file in each panel before and after: | ||
// +----+----+ | ||
// | pn | nn | | ||
// +----+----+ | ||
// | ps | ns | | ||
// +----+----+ | ||
// | ||
var pn = prev.northPanel.active; | ||
var nn = next.northPanel.active; | ||
var ps = (_a = prev.southPanel) === null || _a === void 0 ? void 0 : _a.active; | ||
var ns = (_b = next.southPanel) === null || _b === void 0 ? void 0 : _b.active; | ||
var pnFile = prev.files.find(function (f) { return f.name === pn; }); | ||
var nnFile = next.files.find(function (f) { return f.name === nn; }); | ||
var psFile = ps | ||
? prev.files.find(function (f) { return f.name === ps; }) | ||
: null; | ||
var nsFile = ns | ||
? next.files.find(function (f) { return f.name === ns; }) | ||
: null; | ||
var oneToTwoSouth = !ps && pn === ns; | ||
if (oneToTwoSouth) { | ||
return { | ||
prevNorthFile: nnFile, | ||
nextNorthFile: nnFile, | ||
prevSouthFile: pnFile, | ||
nextSouthFile: nsFile, | ||
}; | ||
} | ||
var twoToOneSouth = !ns && nn === ps; | ||
if (twoToOneSouth) { | ||
return { | ||
prevNorthFile: pnFile, | ||
nextNorthFile: pnFile, | ||
prevSouthFile: psFile, | ||
nextSouthFile: nnFile, | ||
}; | ||
} | ||
var prevNorthFile = pn === nn ? pnFile : backward ? pnFile : nnFile; | ||
var nextNorthFile = pn === nn ? nnFile : backward ? pnFile : nnFile; | ||
var prevSouthFile = ps === ns | ||
? psFile | ||
: backward | ||
? psFile || nsFile | ||
: nsFile || psFile; | ||
var nextSouthFile = ps === ns | ||
? nsFile | ||
: backward | ||
? psFile || nsFile | ||
: nsFile || psFile; | ||
return { | ||
prevNorthFile: prevNorthFile, | ||
nextNorthFile: nextNorthFile, | ||
prevSouthFile: prevSouthFile, | ||
nextSouthFile: nextSouthFile, | ||
}; | ||
} | ||
function getPanelStyles(prev, next, t) { | ||
@@ -215,71 +517,2 @@ // +---+---+ | ||
} | ||
var useLayoutEffect = typeof window !== "undefined" | ||
? React.useLayoutEffect | ||
: React.useEffect; | ||
function useSnapshots(ref, prev, next) { | ||
var _a = __read(React.useState({ | ||
prevSnapshot: null, | ||
nextSnapshot: null, | ||
}), 2), _b = _a[0], prevSnapshot = _b.prevSnapshot, nextSnapshot = _b.nextSnapshot, setState = _a[1]; | ||
useLayoutEffect(function () { | ||
if (prevSnapshot || nextSnapshot) { | ||
setState({ | ||
prevSnapshot: null, | ||
nextSnapshot: null, | ||
}); | ||
} | ||
}, [prev, next]); | ||
useLayoutEffect(function () { | ||
if (!prevSnapshot) { | ||
setState(function (s) { return (__assign(__assign({}, s), { prevSnapshot: __assign(__assign({}, getPanelSnapshot(ref.current, prev)), getTabsSnapshot(ref.current, prev)) })); }); | ||
} | ||
else if (!nextSnapshot) { | ||
setState(function (s) { return (__assign(__assign({}, s), { nextSnapshot: __assign(__assign({}, getPanelSnapshot(ref.current, next)), getTabsSnapshot(ref.current, next)) })); }); | ||
} | ||
}); | ||
return { prevSnapshot: prevSnapshot, nextSnapshot: nextSnapshot }; | ||
} | ||
function getPanelSnapshot(parent, step) { | ||
var _a; | ||
var northElement = parent.querySelector("[data-ch-panel='north']"); | ||
var southElement = parent.querySelector("[data-ch-panel='south']"); | ||
var bar = parent.querySelector(".ch-frame-title-bar"); | ||
return { | ||
titleBarHeight: bar.getBoundingClientRect().height, | ||
northHeight: northElement.getBoundingClientRect() | ||
.height, | ||
northKey: step.northPanel.active, | ||
southHeight: (southElement === null || southElement === void 0 ? void 0 : southElement.getBoundingClientRect().height) || null, | ||
southKey: (_a = step.southPanel) === null || _a === void 0 ? void 0 : _a.active, | ||
}; | ||
} | ||
function getTabsSnapshot(parent, step) { | ||
var _a; | ||
var northTabs = Array.from(parent.querySelectorAll("[data-ch-tab='north']")); | ||
var southTabs = Array.from(parent.querySelectorAll("[data-ch-tab='south']")); | ||
return { | ||
northTabs: getTabsDimensions(northTabs, step.northPanel.active), | ||
southTabs: getTabsDimensions(southTabs, (_a = step.southPanel) === null || _a === void 0 ? void 0 : _a.active), | ||
}; | ||
} | ||
function getTabsDimensions(tabElements, active) { | ||
if (!tabElements[0]) { | ||
return null; | ||
} | ||
var parent = tabElements[0].parentElement; | ||
var parentLeft = parent.getBoundingClientRect().left; | ||
var dimensions = {}; | ||
tabElements.forEach(function (child) { | ||
var filename = child.getAttribute("title"); | ||
var rect = child.getBoundingClientRect(); | ||
dimensions[filename] = { | ||
left: rect.left - parentLeft, | ||
width: rect.width, | ||
active: filename === active, | ||
}; | ||
}); | ||
return dimensions; | ||
} | ||
function getTabs(prevSnapshot, nextSnapshot, northActive, southActive, t) { | ||
@@ -407,231 +640,113 @@ // TODO simplify | ||
} | ||
function TerminalPanel(_a) { | ||
var prev = _a.prev, next = _a.next, t = _a.t, backward = _a.backward; | ||
var height = getHeight({ prev: prev, next: next, t: t, backward: backward }); | ||
return !height ? null : (React.createElement("div", { className: "ch-editor-terminal", style: { height: height } }, | ||
React.createElement("div", { className: "ch-editor-terminal-tab" }, | ||
React.createElement("span", null, "Terminal")), | ||
React.createElement("div", { className: "ch-editor-terminal-content" }, | ||
React.createElement(InnerTerminal, { steps: [ | ||
{ text: prev || "" }, | ||
{ text: next || "" }, | ||
], progress: t }), | ||
")"))); | ||
// snapshots | ||
var useLayoutEffect = typeof window !== "undefined" | ||
? React.useLayoutEffect | ||
: React.useEffect; | ||
function useSnapshots(ref, prev, next) { | ||
var _a = __read(React.useState({ | ||
prevSnapshot: null, | ||
nextSnapshot: null, | ||
}), 2), _b = _a[0], prevSnapshot = _b.prevSnapshot, nextSnapshot = _b.nextSnapshot, setState = _a[1]; | ||
useLayoutEffect(function () { | ||
if (prevSnapshot || nextSnapshot) { | ||
setState({ | ||
prevSnapshot: null, | ||
nextSnapshot: null, | ||
}); | ||
} | ||
}, [prev, next]); | ||
useLayoutEffect(function () { | ||
if (!prevSnapshot) { | ||
setState(function (s) { return (__assign(__assign({}, s), { prevSnapshot: __assign(__assign({}, getPanelSnapshot(ref.current, prev)), getTabsSnapshot(ref.current, prev)) })); }); | ||
} | ||
else if (!nextSnapshot) { | ||
setState(function (s) { return (__assign(__assign({}, s), { nextSnapshot: __assign(__assign({}, getPanelSnapshot(ref.current, next)), getTabsSnapshot(ref.current, next)) })); }); | ||
} | ||
}); | ||
return { prevSnapshot: prevSnapshot, nextSnapshot: nextSnapshot }; | ||
} | ||
function getHeight(_a) { | ||
var prev = _a.prev, next = _a.next, t = _a.t; _a.backward; | ||
if (!prev && !next) | ||
return 0; | ||
if (!prev && next) | ||
return MAX_HEIGHT * Math.min(t * 4, 1); | ||
if (prev && !next) | ||
return MAX_HEIGHT * Math.max(1 - t * 4, 0); | ||
return MAX_HEIGHT; | ||
} | ||
var MAX_HEIGHT = 150; | ||
var DEFAULT_STEP = { | ||
files: [{ code: "", lang: "js", name: "" }], | ||
northPanel: { active: "", tabs: [""], heightRatio: 1 }, | ||
}; | ||
function MiniEditorTween(_a) { | ||
var _b = _a.prev, prev = _b === void 0 ? DEFAULT_STEP : _b, _c = _a.next, next = _c === void 0 ? DEFAULT_STEP : _c, t = _a.t, backward = _a.backward, _d = _a.codeProps, codeProps = _d === void 0 ? {} : _d, _e = _a.frameProps, frameProps = _e === void 0 ? {} : _e; | ||
var ref = React.createRef(); | ||
var _f = useTransition(ref, prev, next, t, backward, codeProps), northPanel = _f.northPanel, southPanel = _f.southPanel; | ||
var terminalPanel = (React.createElement(TerminalPanel, { prev: prev.terminal, next: next.terminal, t: t, backward: backward })); | ||
return (React.createElement(EditorFrame, __assign({ ref: ref }, frameProps, { northPanel: northPanel, southPanel: southPanel, terminalPanel: terminalPanel }))); | ||
} | ||
function useTransition(ref, prev, next, t, backward, codeProps) { | ||
var _a = useSnapshots(ref, prev, next), prevSnapshot = _a.prevSnapshot, nextSnapshot = _a.nextSnapshot; | ||
if (!prevSnapshot) { | ||
return startingPosition(prev, next, codeProps); | ||
} | ||
if (!nextSnapshot) { | ||
return endingPosition(prev, next, codeProps); | ||
} | ||
// if (t === 0) { | ||
// return startingPosition(prev, next, codeProps) | ||
// } | ||
if (t === 1) { | ||
return endingPosition(prev, next, codeProps); | ||
} | ||
var inputSouthPanel = prev.southPanel || next.southPanel; | ||
var _b = getStepFiles(prev, next, t == 0 || backward), prevNorthFile = _b.prevNorthFile, prevSouthFile = _b.prevSouthFile, nextNorthFile = _b.nextNorthFile, nextSouthFile = _b.nextSouthFile; | ||
var _c = getPanelStyles(prevSnapshot, nextSnapshot, t), northStyle = _c.northStyle, southStyle = _c.southStyle; | ||
var _d = getTabs(prevSnapshot, nextSnapshot, prevNorthFile.name, prevSouthFile === null || prevSouthFile === void 0 ? void 0 : prevSouthFile.name, t), northTabs = _d.northTabs, southTabs = _d.southTabs; | ||
function getPanelSnapshot(parent, step) { | ||
var _a; | ||
var northElement = parent.querySelector("[data-ch-panel='north']"); | ||
var southElement = parent.querySelector("[data-ch-panel='south']"); | ||
var bar = parent.querySelector(".ch-frame-title-bar"); | ||
return { | ||
northPanel: { | ||
tabs: northTabs, | ||
style: northStyle, | ||
children: (React.createElement(CodeTransition, { codeProps: codeProps, prevFile: prevNorthFile, nextFile: nextNorthFile, t: t, parentHeight: northStyle.height })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: southTabs, | ||
style: southStyle, | ||
children: (React.createElement(CodeTransition, { codeProps: codeProps, prevFile: prevSouthFile, nextFile: nextSouthFile, t: t, parentHeight: southStyle === null || southStyle === void 0 ? void 0 : southStyle.height })), | ||
}, | ||
titleBarHeight: bar.getBoundingClientRect().height, | ||
northHeight: northElement.getBoundingClientRect() | ||
.height, | ||
northKey: step.northPanel.active, | ||
southHeight: (southElement === null || southElement === void 0 ? void 0 : southElement.getBoundingClientRect().height) || null, | ||
southKey: (_a = step.southPanel) === null || _a === void 0 ? void 0 : _a.active, | ||
}; | ||
} | ||
// Returns the t=0 state of the transition | ||
function startingPosition(prev, next, codeProps) { | ||
var inputNorthPanel = prev.northPanel; | ||
var inputSouthPanel = prev.southPanel; | ||
var _a = getStepFiles(prev, next, true), prevNorthFile = _a.prevNorthFile, prevSouthFile = _a.prevSouthFile, nextNorthFile = _a.nextNorthFile, nextSouthFile = _a.nextSouthFile; | ||
var northHeight = inputSouthPanel | ||
? "calc((100% - var(--ch-title-bar-height)) * " + inputNorthPanel.heightRatio + ")" | ||
: "100%"; | ||
var southHeight = "calc((100% - var(--ch-title-bar-height)) * " + (inputSouthPanel === null || inputSouthPanel === void 0 ? void 0 : inputSouthPanel.heightRatio) + " + var(--ch-title-bar-height))"; | ||
return { | ||
northPanel: { | ||
tabs: inputNorthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputNorthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: northHeight, | ||
}, | ||
children: (React.createElement(CodeTransition, { codeProps: codeProps, prevFile: prevNorthFile, nextFile: nextNorthFile, t: 0, parentHeight: northHeight })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: inputSouthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputSouthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: "calc((100% - var(--ch-title-bar-height)) * " + inputSouthPanel.heightRatio + " + var(--ch-title-bar-height))", | ||
}, | ||
children: (React.createElement(CodeTransition, { codeProps: codeProps, prevFile: prevSouthFile, nextFile: nextSouthFile, t: 0, parentHeight: southHeight })), | ||
}, | ||
}; | ||
} | ||
// Returns the t=1 state of the transition | ||
function endingPosition(prev, next, codeProps) { | ||
function getTabsSnapshot(parent, step) { | ||
var _a; | ||
var inputNorthPanel = next.northPanel; | ||
var inputSouthPanel = next.southPanel; | ||
var _b = getStepFiles(prev, next, false), prevNorthFile = _b.prevNorthFile, prevSouthFile = _b.prevSouthFile, nextNorthFile = _b.nextNorthFile, nextSouthFile = _b.nextSouthFile; | ||
// getStepFiles return the intermediate files, we need to patch the ending state (2to1south) | ||
var isTwoToOneSouth = !inputSouthPanel && | ||
inputNorthPanel.active === ((_a = prev === null || prev === void 0 ? void 0 : prev.southPanel) === null || _a === void 0 ? void 0 : _a.active); | ||
if (isTwoToOneSouth) { | ||
nextNorthFile = nextSouthFile; | ||
} | ||
var northHeight = inputSouthPanel | ||
? "calc((100% - var(--ch-title-bar-height)) * " + inputNorthPanel.heightRatio + ")" | ||
: "100%"; | ||
var southHeight = "calc((100% - var(--ch-title-bar-height)) * " + (inputSouthPanel === null || inputSouthPanel === void 0 ? void 0 : inputSouthPanel.heightRatio) + " + var(--ch-title-bar-height))"; | ||
var northTabs = Array.from(parent.querySelectorAll("[data-ch-tab='north']")); | ||
var southTabs = Array.from(parent.querySelectorAll("[data-ch-tab='south']")); | ||
return { | ||
northPanel: { | ||
tabs: inputNorthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputNorthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: northHeight, | ||
}, | ||
children: (React.createElement(CodeTransition, { codeProps: codeProps, prevFile: prevNorthFile, nextFile: nextNorthFile, t: 1, parentHeight: northHeight })), | ||
}, | ||
southPanel: inputSouthPanel && { | ||
tabs: inputSouthPanel.tabs.map(function (title) { return ({ | ||
title: title, | ||
active: title === inputSouthPanel.active, | ||
style: {}, | ||
}); }), | ||
style: { | ||
height: southHeight, | ||
}, | ||
children: (React.createElement(CodeTransition, { codeProps: codeProps, prevFile: prevSouthFile, nextFile: nextSouthFile, t: 1, parentHeight: southHeight })), | ||
}, | ||
northTabs: getTabsDimensions(northTabs, step.northPanel.active), | ||
southTabs: getTabsDimensions(southTabs, (_a = step.southPanel) === null || _a === void 0 ? void 0 : _a.active), | ||
}; | ||
} | ||
function CodeTransition(_a) { | ||
var prevFile = _a.prevFile, nextFile = _a.nextFile, t = _a.t, codeProps = _a.codeProps, parentHeight = _a.parentHeight; | ||
return (React.createElement(Code, __assign({}, codeProps, { code: { prev: prevFile.code, next: nextFile.code }, focus: { prev: prevFile.focus, next: nextFile.focus }, annotations: { | ||
prev: prevFile.annotations, | ||
next: nextFile.annotations, | ||
}, progress: t, language: prevFile.lang, parentHeight: parentHeight }))); | ||
} | ||
/** | ||
* Get the StepFiles for a transition | ||
* in each panel, if the prev and next active files are the same | ||
* we return the prev and next version of that panel | ||
* if the active files are different, we return the same file twice, | ||
* if backward is true we return the prev active file twice, | ||
* or else the next active file twice | ||
*/ | ||
function getStepFiles(prev, next, backward) { | ||
var _a, _b; | ||
// The active file in each panel before and after: | ||
// +----+----+ | ||
// | pn | nn | | ||
// +----+----+ | ||
// | ps | ns | | ||
// +----+----+ | ||
// | ||
var pn = prev.northPanel.active; | ||
var nn = next.northPanel.active; | ||
var ps = (_a = prev.southPanel) === null || _a === void 0 ? void 0 : _a.active; | ||
var ns = (_b = next.southPanel) === null || _b === void 0 ? void 0 : _b.active; | ||
var pnFile = prev.files.find(function (f) { return f.name === pn; }); | ||
var nnFile = next.files.find(function (f) { return f.name === nn; }); | ||
var psFile = ps | ||
? prev.files.find(function (f) { return f.name === ps; }) | ||
: null; | ||
var nsFile = ns | ||
? next.files.find(function (f) { return f.name === ns; }) | ||
: null; | ||
var oneToTwoSouth = !ps && pn === ns; | ||
if (oneToTwoSouth) { | ||
return { | ||
prevNorthFile: nnFile, | ||
nextNorthFile: nnFile, | ||
prevSouthFile: pnFile, | ||
nextSouthFile: nsFile, | ||
}; | ||
function getTabsDimensions(tabElements, active) { | ||
if (!tabElements[0]) { | ||
return null; | ||
} | ||
var twoToOneSouth = !ns && nn === ps; | ||
if (twoToOneSouth) { | ||
return { | ||
prevNorthFile: pnFile, | ||
nextNorthFile: pnFile, | ||
prevSouthFile: psFile, | ||
nextSouthFile: nnFile, | ||
var parent = tabElements[0].parentElement; | ||
var parentLeft = parent.getBoundingClientRect().left; | ||
var dimensions = {}; | ||
tabElements.forEach(function (child) { | ||
var filename = child.getAttribute("title"); | ||
var rect = child.getBoundingClientRect(); | ||
dimensions[filename] = { | ||
left: rect.left - parentLeft, | ||
width: rect.width, | ||
active: filename === active, | ||
}; | ||
} | ||
var prevNorthFile = pn === nn ? pnFile : backward ? pnFile : nnFile; | ||
var nextNorthFile = pn === nn ? nnFile : backward ? pnFile : nnFile; | ||
var prevSouthFile = ps === ns | ||
? psFile | ||
: backward | ||
? psFile || nsFile | ||
: nsFile || psFile; | ||
var nextSouthFile = ps === ns | ||
? nsFile | ||
: backward | ||
? psFile || nsFile | ||
: nsFile || psFile; | ||
return { | ||
prevNorthFile: prevNorthFile, | ||
nextNorthFile: nextNorthFile, | ||
prevSouthFile: prevSouthFile, | ||
nextSouthFile: nextSouthFile, | ||
}; | ||
}); | ||
return dimensions; | ||
} | ||
function MiniEditorHike(_a) { | ||
var _b = _a.steps, steps = _b === void 0 ? [] : _b, _c = _a.progress, progress = _c === void 0 ? 0 : _c, _d = _a.backward, backward = _d === void 0 ? false : _d, frameProps = _a.frameProps, codeProps = _a.codeProps; | ||
var prevIndex = clamp(Math.floor(progress), 0, steps.length - 1); | ||
var nextIndex = clamp(prevIndex + 1, 0, steps.length - 1); | ||
var prev = steps[prevIndex]; | ||
var next = steps[nextIndex]; | ||
var t = clamp(progress - prevIndex, 0, steps.length - 1); | ||
return (React.createElement(MiniEditorTween, { frameProps: frameProps, codeProps: codeProps, prev: prev, next: next, backward: backward, t: t })); | ||
var DEFAULT_STEP = { | ||
files: [ | ||
{ | ||
code: { lines: [], lang: "js" }, | ||
focus: "", | ||
name: "", | ||
}, | ||
], | ||
northPanel: { active: "", tabs: [""], heightRatio: 1 }, | ||
}; | ||
function EditorTween(_a) { | ||
var _b = _a.prev, prev = _b === void 0 ? DEFAULT_STEP : _b, next = _a.next, t = _a.t, backward = _a.backward, codeConfig = _a.codeConfig, _c = _a.frameProps, frameProps = _c === void 0 ? {} : _c, divProps = __rest(_a, ["prev", "next", "t", "backward", "codeConfig", "frameProps"]); | ||
var ref = React.createRef(); | ||
var _d = useTransition(ref, prev, next || prev, t, backward, codeConfig), northPanel = _d.northPanel, southPanel = _d.southPanel; | ||
var defaultHeight = useDefaultHeight(prev); | ||
var framePropsWithHeight = __assign(__assign(__assign({}, frameProps), divProps), { style: __assign(__assign({ height: defaultHeight }, frameProps === null || frameProps === void 0 ? void 0 : frameProps.style), divProps === null || divProps === void 0 ? void 0 : divProps.style) }); | ||
var terminalPanel = (React.createElement(TerminalPanel, { prev: prev.terminal, next: (next || prev).terminal, t: t, backward: backward })); | ||
return (React.createElement(EditorFrame, __assign({ ref: ref }, framePropsWithHeight, { northPanel: northPanel, southPanel: southPanel, terminalPanel: terminalPanel, theme: codeConfig.theme }))); | ||
} | ||
function clamp(a, min, max) { | ||
return Math.max(Math.min(a, max), min); | ||
function useDefaultHeight(_a) { | ||
var files = _a.files, northPanel = _a.northPanel, southPanel = _a.southPanel; | ||
return React.useMemo(function () { | ||
var northFile = files.find(function (_a) { | ||
var name = _a.name; | ||
return name === northPanel.active; | ||
}); | ||
var southFile = files.find(function (_a) { | ||
var name = _a.name; | ||
return name === (southPanel === null || southPanel === void 0 ? void 0 : southPanel.active); | ||
}); | ||
var focusedLines = getFocusedLineCount(northFile) + 3.9; | ||
if (southFile) { | ||
focusedLines += getFocusedLineCount(southFile) + 3.9; | ||
} | ||
var emHeight = focusedLines * 1.5; | ||
return emHeight + "em"; | ||
}, []); | ||
} | ||
function getFocusedLineCount(_a) { | ||
var code = _a.code; _a.focus; | ||
return code.lines.length; | ||
} | ||
@@ -644,49 +759,3 @@ var defaultSpring = { | ||
}; | ||
function MiniEditor(props) { | ||
if ("northPanel" in props) { | ||
return React.createElement(TwoPanelEditor, __assign({}, props)); | ||
} | ||
else if ("active" in props) { | ||
return React.createElement(SinglePanelEditor, __assign({}, props)); | ||
} | ||
else { | ||
return React.createElement(SingleFileEditor, __assign({}, props)); | ||
} | ||
} | ||
function SingleFileEditor(_a) { | ||
var _b = _a.code, code = _b === void 0 ? "" : _b, _c = _a.lang, lang = _c === void 0 ? "js" : _c, focus = _a.focus, _d = _a.filename, filename = _d === void 0 ? "" : _d, terminal = _a.terminal, springConfig = _a.springConfig, props = __rest(_a, ["code", "lang", "focus", "filename", "terminal", "springConfig"]); | ||
var step = React.useMemo(function () { | ||
var step = { | ||
files: [{ name: filename, code: code, lang: lang, focus: focus }], | ||
northPanel: { | ||
active: filename, | ||
tabs: [filename], | ||
heightRatio: 1, | ||
}, | ||
terminal: terminal, | ||
}; | ||
return step; | ||
}, [code, lang, focus, filename, terminal]); | ||
var _e = useStepSpring(step, springConfig), prev = _e.prev, next = _e.next, t = _e.t; | ||
return (React.createElement(MiniEditorTween, __assign({ t: t, backward: false, prev: prev, next: next }, props))); | ||
} | ||
function SinglePanelEditor(_a) { | ||
var files = _a.files, active = _a.active, terminal = _a.terminal, springConfig = _a.springConfig, props = __rest(_a, ["files", "active", "terminal", "springConfig"]); | ||
var step = React.useMemo(function () { | ||
var tabs = files.map(function (file) { return file.name; }); | ||
var step = { | ||
files: files, | ||
northPanel: { | ||
active: active, | ||
tabs: tabs, | ||
heightRatio: 1, | ||
}, | ||
terminal: terminal, | ||
}; | ||
return step; | ||
}, [files, active, terminal]); | ||
var _b = useStepSpring(step, springConfig), prev = _b.prev, next = _b.next, t = _b.t; | ||
return (React.createElement(MiniEditorTween, __assign({ t: t, backward: false, prev: prev, next: next }, props))); | ||
} | ||
function TwoPanelEditor(_a) { | ||
function EditorSpring(_a) { | ||
var northPanel = _a.northPanel, southPanel = _a.southPanel, files = _a.files, terminal = _a.terminal, springConfig = _a.springConfig, props = __rest(_a, ["northPanel", "southPanel", "files", "terminal", "springConfig"]); | ||
@@ -702,3 +771,3 @@ var step = React.useMemo(function () { | ||
var _b = useStepSpring(step, springConfig), prev = _b.prev, next = _b.next, t = _b.t; | ||
return (React.createElement(MiniEditorTween, __assign({ t: t, backward: false, prev: prev, next: next }, props))); | ||
return (React.createElement(EditorTween, __assign({ t: t, backward: false, prev: prev, next: next }, props))); | ||
} | ||
@@ -726,110 +795,2 @@ function useStepSpring(step, springConfig) { | ||
function mdxToSteps(children, settings) { | ||
if (settings === void 0) { settings = {}; } | ||
var steps = []; | ||
children.forEach(function (child, i) { | ||
steps.push(mdxToStep(child, steps[i - 1], settings)); | ||
}); | ||
return steps; | ||
} | ||
var defaultFileName = "index.js"; | ||
function mdxToStep(child, prev, settings) { | ||
var _a; | ||
if (settings === void 0) { settings = {}; } | ||
var stepProps = (child === null || child === void 0 ? void 0 : child.props) || {}; | ||
var stepChildren = React.Children.toArray(stepProps.children); | ||
var separatorIndex = stepChildren.findIndex(function (child) { var _a; return ((_a = child === null || child === void 0 ? void 0 : child.props) === null || _a === void 0 ? void 0 : _a.mdxType) === "hr"; }); | ||
var hasTwoPanels = separatorIndex !== -1; | ||
var northChildren = hasTwoPanels | ||
? stepChildren.slice(0, separatorIndex) | ||
: stepChildren; | ||
var southChildren = hasTwoPanels | ||
? stepChildren.slice(separatorIndex + 1) | ||
: null; | ||
var northFiles = northChildren.map(function (pre) { | ||
return preToFile(pre, prev ? prev.files : [], settings); | ||
}); | ||
var southFiles = southChildren === null || southChildren === void 0 ? void 0 : southChildren.map(function (pre) { | ||
return preToFile(pre, prev ? prev.files : [], settings); | ||
}); | ||
var prevFiles = (prev === null || prev === void 0 ? void 0 : prev.files) || []; | ||
var files = __spread(prevFiles.filter(function (f) { | ||
return !northFiles.some(function (nf) { return nf.name === f.name; }) && | ||
!(southFiles === null || southFiles === void 0 ? void 0 : southFiles.some(function (sf) { return sf.name === f.name; })); | ||
}), northFiles, (southFiles || [])); | ||
return { | ||
files: files, | ||
northPanel: { | ||
tabs: chooseNorthTabs(prev, northFiles, southFiles), | ||
active: chooseActiveFile(northFiles, prev === null || prev === void 0 ? void 0 : prev.northPanel.active), | ||
heightRatio: 0.5, | ||
}, | ||
southPanel: southFiles && southFiles.length | ||
? { | ||
tabs: chooseSouthTabs(prev, northFiles, southFiles), | ||
active: chooseActiveFile(southFiles, (_a = prev === null || prev === void 0 ? void 0 : prev.southPanel) === null || _a === void 0 ? void 0 : _a.active), | ||
heightRatio: 0.5, | ||
} | ||
: undefined, | ||
}; | ||
} | ||
function chooseNorthTabs(prev, northFiles, southFiles) { | ||
// old north tabs + new north tabs (except hidden) - new south tabs | ||
var oldNorthTabs = (prev === null || prev === void 0 ? void 0 : prev.northPanel.tabs) || []; | ||
var newSouthTabs = (southFiles || []).map(function (f) { return f.name; }); | ||
var newNorthTabs = northFiles | ||
.filter(function (f) { return !f.hidden && !oldNorthTabs.includes(f.name); }) | ||
.map(function (f) { return f.name; }); | ||
var baseTabs = oldNorthTabs.filter(function (tab) { return !newSouthTabs.includes(tab); }); | ||
return __spread(baseTabs, newNorthTabs); | ||
} | ||
function chooseSouthTabs(prev, northFiles, southFiles) { | ||
var _a; | ||
// old south tabs + new south tabs (except hidden) - new north tabs | ||
var oldSouthTabs = ((_a = prev === null || prev === void 0 ? void 0 : prev.southPanel) === null || _a === void 0 ? void 0 : _a.tabs) || []; | ||
var newSouthTabs = (southFiles || []) | ||
.filter(function (f) { return !f.hidden && !oldSouthTabs.includes(f.name); }) | ||
.map(function (f) { return f.name; }); | ||
var newNorthTabs = northFiles.map(function (f) { return f.name; }); | ||
var baseTabs = oldSouthTabs.filter(function (tab) { return !newNorthTabs.includes(tab); }); | ||
return __spread(baseTabs, newSouthTabs); | ||
} | ||
function chooseActiveFile(panelFiles, prev) { | ||
var _a, _b; | ||
var active = ((_a = panelFiles.find(function (file) { return file.active; })) === null || _a === void 0 ? void 0 : _a.name) || ((_b = panelFiles[0]) === null || _b === void 0 ? void 0 : _b.name) || | ||
prev; | ||
if (!active) { | ||
throw new Error("Something is wrong with Code Hike"); | ||
} | ||
return active; | ||
} | ||
function preToFile(preElement, prevFiles, settings) { | ||
var _a, _b, _c; | ||
var codeElementProps = ((_b = (_a = preElement === null || preElement === void 0 ? void 0 : preElement.props) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b.props) || {}; | ||
var lang = (_c = codeElementProps.className) === null || _c === void 0 ? void 0 : _c.slice(9); | ||
var _d = parseMetastring(codeElementProps.metastring || ""), name = _d.name, options = __rest(_d, ["name"]); | ||
var fileName = name || (settings === null || settings === void 0 ? void 0 : settings.defaultFileName) || defaultFileName; | ||
var code = codeElementProps.children; | ||
var prevFile = prevFiles.find(function (file) { return file.name === fileName; }); | ||
return __assign({ code: code.trim() === "" && prevFile ? prevFile.code : code, lang: lang, name: fileName }, options); | ||
} | ||
function parseMetastring(metastring) { | ||
var params = metastring.split(" "); | ||
var options = {}; | ||
var name = null; | ||
params.forEach(function (param) { | ||
var _a = __read(param.split("="), 2), key = _a[0], value = _a[1]; | ||
if (value != null) { | ||
options[key] = value; | ||
} | ||
else if (name === null) { | ||
name = key; | ||
} | ||
else { | ||
options[key] = true; | ||
} | ||
}); | ||
return __assign({ name: name }, options); | ||
} | ||
export { MiniEditor, MiniEditorHike, MiniEditorTween, mdxToStep, mdxToSteps }; | ||
export { EditorSpring, EditorTween }; |
{ | ||
"name": "@code-hike/mini-editor", | ||
"version": "0.3.0--canary.77.6c844fa.0", | ||
"version": "0.3.0--canary.77.7150a39.0", | ||
"main": "dist/index.cjs.js", | ||
@@ -15,3 +15,3 @@ "typings": "dist/index.d.ts", | ||
"devDependencies": { | ||
"@code-hike/script": "0.3.0--canary.77.6c844fa.0", | ||
"@code-hike/script": "0.3.0--canary.77.7150a39.0", | ||
"@types/react": "^16.9.38", | ||
@@ -21,10 +21,10 @@ "react": "^16.13.1" | ||
"dependencies": { | ||
"@code-hike/classer": "0.3.0--canary.77.6c844fa.0", | ||
"@code-hike/mini-frame": "0.3.0--canary.77.6c844fa.0", | ||
"@code-hike/mini-terminal": "0.3.0--canary.77.6c844fa.0", | ||
"@code-hike/smooth-code": "0.3.0--canary.77.6c844fa.0", | ||
"@code-hike/classer": "0.3.0--canary.77.7150a39.0", | ||
"@code-hike/mini-frame": "0.3.0--canary.77.7150a39.0", | ||
"@code-hike/mini-terminal": "0.3.0--canary.77.7150a39.0", | ||
"@code-hike/smooth-code": "0.3.0--canary.77.7150a39.0", | ||
"use-spring": "^0.2.3" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=16.8" | ||
"react": "^16.8.3 || ^17 || ^18" | ||
}, | ||
@@ -45,3 +45,3 @@ "keywords": [ | ||
}, | ||
"gitHead": "6c844fa2ccfc2fa1368e7b26b2a903f70aa3eee6" | ||
"gitHead": "7150a3912c39850db726e4c1a30c9655b7d14525" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
89269
1765
1
+ Added@code-hike/classer@0.3.0--canary.77.7150a39.0(transitive)
+ Added@code-hike/highlighter@0.3.0--canary.77.7150a39.0(transitive)
+ Added@code-hike/mini-frame@0.3.0--canary.77.7150a39.0(transitive)
+ Added@code-hike/mini-terminal@0.3.0--canary.77.7150a39.0(transitive)
+ Added@code-hike/smooth-code@0.3.0--canary.77.7150a39.0(transitive)
+ Added@code-hike/utils@0.3.0--canary.77.7150a39.0(transitive)
- Removed@code-hike/classer@0.3.0--canary.77.6c844fa.0(transitive)
- Removed@code-hike/code-diff@0.3.0--canary.77.6c844fa.0(transitive)
- Removed@code-hike/mini-frame@0.3.0--canary.77.6c844fa.0(transitive)
- Removed@code-hike/mini-terminal@0.3.0--canary.77.6c844fa.0(transitive)
- Removed@code-hike/smooth-code@0.3.0--canary.77.6c844fa.0(transitive)
- Removed@code-hike/smooth-lines@0.3.0--canary.77.6c844fa.0(transitive)
- Removed@code-hike/utils@0.3.0--canary.77.6c844fa.0(transitive)
- Removedprismjs@1.29.0(transitive)
- Removedreact@19.0.0(transitive)