code-surfer
Advanced tools
Comparing version 0.0.2 to 0.1.2
import { configure } from "@storybook/react"; | ||
function loadStories() { | ||
require("./story.js"); | ||
require("./code-surfer.story.js"); | ||
require("./scroller.story.js"); | ||
} | ||
configure(loadStories, module); |
@@ -7,2 +7,4 @@ "use strict"; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _react = require("react"); | ||
@@ -12,10 +14,14 @@ | ||
var _highlighter = require("./highlighter"); | ||
var _prismReactRenderer = require("prism-react-renderer"); | ||
var _highlighter2 = _interopRequireDefault(_highlighter); | ||
var _prismReactRenderer2 = _interopRequireDefault(_prismReactRenderer); | ||
var _stepParser = require("./step-parser"); | ||
var _duotoneDark = require("prism-react-renderer/themes/duotoneDark"); | ||
var _stepParser2 = _interopRequireDefault(_stepParser); | ||
var _duotoneDark2 = _interopRequireDefault(_duotoneDark); | ||
var _duotoneLight = require("prism-react-renderer/themes/duotoneLight"); | ||
var _duotoneLight2 = _interopRequireDefault(_duotoneLight); | ||
var _scroller = require("./scroller"); | ||
@@ -27,5 +33,5 @@ | ||
var _theme = require("./theme"); | ||
var _stepParser = require("./step-parser"); | ||
var _theme2 = _interopRequireDefault(_theme); | ||
var _stepParser2 = _interopRequireDefault(_stepParser); | ||
@@ -36,80 +42,73 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } | ||
var selectedRules = (0, _glamor.css)({ | ||
opacity: 1, | ||
transition: "opacity 300ms" | ||
}); | ||
var unselectedRules = (0, _glamor.css)({ | ||
opacity: 0.3, | ||
transition: "opacity 300ms" | ||
}); | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
var CodeSurfer = function CodeSurfer(_ref) { | ||
var code = _ref.code, | ||
step = _ref.step, | ||
lang = _ref.lang, | ||
showNumbers = _ref.showNumbers, | ||
dark = _ref.dark; | ||
//TODO configure theme | ||
//TODO don't import css | ||
// import "prismjs/themes/prism.css"; | ||
(0, _theme2.default)(); | ||
function getFullLineHtml(showNumber, number, line) { | ||
var numberHtml = '<span class="token comment token-leaf line-number" style="user-select: none">' + String(number).padStart(3) + ".</span> "; | ||
return showNumber ? numberHtml + line : line || " "; | ||
} | ||
var getLineClassName = function getLineClassName(tokens, lineNumber) { | ||
if (Object.keys(tokens).length === 0) { | ||
return (0, _glamor.css)(_defineProperty({}, "& .token-leaf", { | ||
opacity: "1 !important" | ||
})); | ||
} else if (!(lineNumber in tokens)) { | ||
return ""; | ||
} else if (tokens[lineNumber] == null) { | ||
return (0, _glamor.css)(_defineProperty({}, "& .token-leaf", { | ||
opacity: "1 !important" | ||
})); | ||
} else { | ||
return _glamor.css.apply(undefined, [_defineProperty({}, "& .token-leaf.line-number", { | ||
opacity: "1 !important" | ||
})].concat(_toConsumableArray(tokens[lineNumber].map(function (n) { | ||
return _defineProperty({}, "& .token-leaf.token-" + n, { | ||
opacity: "1 !important" | ||
}); | ||
})))); | ||
} | ||
}; | ||
var LineOfCode = function LineOfCode(_ref3) { | ||
var number = _ref3.number, | ||
tokensPerLine = _ref3.tokensPerLine, | ||
html = _ref3.html; | ||
var isSelected = number in tokensPerLine; | ||
var className = getLineClassName(tokensPerLine, number); | ||
return _react2.default.createElement(Scroller.Element, { | ||
dangerouslySetInnerHTML: { __html: html } | ||
// style={{ opacity: isSelected ? 1 : 0.3 }} | ||
, className: className, | ||
selected: isSelected | ||
}); | ||
}; | ||
var CodeSurfer = function CodeSurfer(_ref4) { | ||
var code = _ref4.code, | ||
step = _ref4.step, | ||
showNumbers = _ref4.showNumbers; | ||
var tokensPerLine = (0, _stepParser2.default)(step); | ||
var tokenOpacity = (0, _glamor.css)(_defineProperty({}, "& .token-leaf", { | ||
opacity: "0.35", | ||
transition: "opacity 300ms" | ||
})); | ||
var isSelected = function isSelected(lineIndex, tokenIndex) { | ||
return tokensPerLine[lineIndex + 1] !== undefined && (tokensPerLine[lineIndex + 1] === null || tokensPerLine[lineIndex + 1].includes(tokenIndex)); | ||
}; | ||
return _react2.default.createElement( | ||
Scroller.Container, | ||
{ type: "pre", height: 500 }, | ||
_react2.default.createElement( | ||
Scroller.Content, | ||
{ type: "code", className: tokenOpacity }, | ||
(0, _highlighter2.default)(code).map(function (line, index) { | ||
return _react2.default.createElement(LineOfCode, { | ||
key: index, | ||
html: getFullLineHtml(showNumbers, index + 1, line), | ||
number: index + 1, | ||
tokensPerLine: tokensPerLine | ||
}); | ||
}) | ||
) | ||
_prismReactRenderer2.default, | ||
_extends({}, _prismReactRenderer.defaultProps, { | ||
code: code, | ||
language: lang || "jsx", | ||
theme: dark ? _duotoneDark2.default : _duotoneLight2.default | ||
}), | ||
function (_ref2) { | ||
var className = _ref2.className, | ||
style = _ref2.style, | ||
tokens = _ref2.tokens, | ||
getLineProps = _ref2.getLineProps, | ||
getTokenProps = _ref2.getTokenProps; | ||
return _react2.default.createElement( | ||
Scroller.Container, | ||
{ | ||
type: "pre", | ||
className: className, | ||
style: Object.assign({}, style, { background: null }) | ||
}, | ||
_react2.default.createElement( | ||
Scroller.Content, | ||
{ type: "code" }, | ||
tokens.map(function (line, i) { | ||
return _react2.default.createElement( | ||
"div", | ||
getLineProps({ line: line, key: i }), | ||
showNumbers && _react2.default.createElement( | ||
"span", | ||
{ | ||
className: "token comment " + (tokensPerLine[i + 1] !== undefined ? selectedRules : unselectedRules), | ||
style: { userSelect: "none" } | ||
}, | ||
(i + 1 + ".").padStart(3), | ||
" " | ||
), | ||
line.map(function (token, key) { | ||
return _react2.default.createElement(Scroller.Element, _extends({ | ||
type: "span" | ||
}, getTokenProps({ | ||
token: token, | ||
key: key, | ||
selected: isSelected(i, key), | ||
className: isSelected(i, key) ? selectedRules : unselectedRules | ||
}))); | ||
}) | ||
); | ||
}) | ||
) | ||
); | ||
} | ||
); | ||
@@ -116,0 +115,0 @@ }; |
@@ -16,10 +16,6 @@ "use strict"; | ||
var _componentTween = require("component-tween"); | ||
var _tween = require("./tween"); | ||
var _componentTween2 = _interopRequireDefault(_componentTween); | ||
var _tween2 = _interopRequireDefault(_tween); | ||
var _componentRaf = require("component-raf"); | ||
var _componentRaf2 = _interopRequireDefault(_componentRaf); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -71,9 +67,9 @@ | ||
console.log("top", top); | ||
console.log("bottom", bottom); | ||
console.log("containerHeight", containerHeight); | ||
console.log("selectedHeight", selectedHeight); | ||
console.log("scaledSelectedHeight", scaledSelectedHeight); | ||
console.log("contentHeight", contentHeight); | ||
console.log("scaledContentHeight", scaledContentHeight); | ||
// console.log("top", top); | ||
// console.log("bottom", bottom); | ||
// console.log("containerHeight", containerHeight); | ||
// console.log("selectedHeight", selectedHeight); | ||
// console.log("scaledSelectedHeight", scaledSelectedHeight); | ||
// console.log("contentHeight", contentHeight); | ||
// console.log("scaledContentHeight", scaledContentHeight); | ||
@@ -89,7 +85,7 @@ if (containerHeight >= scaledContentHeight) { | ||
} else { | ||
console.log("Bigger selected than container"); | ||
// console.log("Bigger selected than container"); | ||
center = (top - halfContent) * scale + halfContent + containerHeight / 2; | ||
} | ||
console.log(center); | ||
// console.log(center); | ||
return { center: center, scale: scale }; | ||
@@ -108,17 +104,14 @@ }; | ||
var tween = (0, _componentTween2.default)({ top: startY, scale: startScale }).ease("out-circ").to({ top: endY, scale: scale }).duration(duration); | ||
var step = { top: startY, scale: startScale }; | ||
tween.update(function (o) { | ||
container.scrollTop = o.top | 0; | ||
content.style.transform = "scale(" + o.scale + ")"; | ||
}); | ||
tween.on("end", function () { | ||
animate = function animate() {}; | ||
}); | ||
var tween = new _tween2.default.Tween(step).to({ top: endY, scale: scale }, duration).easing(_tween2.default.Easing.Circular.Out).onUpdate(function () { | ||
container.scrollTop = step.top | 0; | ||
content.style.transform = "scale(" + step.scale + ")"; | ||
}).start(); | ||
function animate() { | ||
(0, _componentRaf2.default)(animate); | ||
tween.update(); | ||
function animate(time) { | ||
requestAnimationFrame(animate); | ||
_tween2.default.update(time); | ||
} | ||
animate(); | ||
requestAnimationFrame(animate); | ||
}; | ||
@@ -164,3 +157,3 @@ | ||
value: function componentDidUpdate() { | ||
this.animate(700); | ||
this.animate(400); | ||
} | ||
@@ -174,16 +167,14 @@ }, { | ||
children = _props.children, | ||
rest = _objectWithoutProperties(_props, ["type", "height", "children"]); | ||
style = _props.style, | ||
rest = _objectWithoutProperties(_props, ["type", "height", "children", "style"]); | ||
return _react2.default.createElement(type || "div", _extends({ | ||
ref: this.containerRef, | ||
style: { | ||
style: Object.assign({}, { | ||
height: 0, | ||
margin: 0, | ||
// background: "#222", | ||
// padding: this.props.height / 2 + "px 0", | ||
overflow: "hidden", | ||
textAlign: "center", | ||
position: "relative" | ||
// color: "#fafafa" | ||
} | ||
}, style) | ||
}, rest), _react2.default.createElement( | ||
@@ -215,8 +206,9 @@ "div", | ||
children = _props2.children, | ||
style = _props2.style, | ||
className = _props2.className, | ||
rest = _objectWithoutProperties(_props2, ["type", "children", "className"]); | ||
rest = _objectWithoutProperties(_props2, ["type", "children", "style", "className"]); | ||
return _react2.default.createElement(type || "div", _extends({ | ||
className: contentClassName + " " + className, | ||
style: { display: "inline-block", textAlign: "left", width: "100%" } | ||
style: Object.assign({}, { display: "inline-block", textAlign: "left", width: "100%" }, style) | ||
}, rest), children); | ||
@@ -223,0 +215,0 @@ } |
{ | ||
"name": "code-surfer", | ||
"version": "0.0.2", | ||
"description": "React component for scrolling, zooming and highlighting code.", | ||
"keywords": [ | ||
"mdx", | ||
"mdx-deck", | ||
"slides", | ||
"react", | ||
"code", | ||
"highlight", | ||
"token", | ||
"prism" | ||
], | ||
"version": "0.1.2", | ||
"main": "dist/code-surfer.js", | ||
"author": "pomber", | ||
"license": "MIT", | ||
"repository": "pomber/code-surfer", | ||
"repository": "https://github.com/pomber/code-surfer", | ||
"private": false, | ||
@@ -13,13 +24,11 @@ "scripts": { | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"release": "np" | ||
"test:watch": "jest --watchAll" | ||
}, | ||
"dependencies": { | ||
"component-raf": "^1.2.0", | ||
"component-tween": "^1.2.0", | ||
"glamor": "^2.20.40", | ||
"lodash.memoize": "^4.1.2", | ||
"prismjs": "^1.15.0", | ||
"react": "^16.4.2" | ||
"prism-react-renderer": "^0.1.2" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=15.0.0" | ||
}, | ||
"devDependencies": { | ||
@@ -34,5 +43,5 @@ "@storybook/react": "^3.4.10", | ||
"jest": "^23.5.0", | ||
"np": "^3.0.4", | ||
"raw-loader": "^0.5.1", | ||
"react-dom": "^16.4.2" | ||
} | ||
} |
import React from "react"; | ||
import hightlightLines from "./highlighter"; | ||
import getTokensPerLine from "./step-parser"; | ||
import Highlight, { defaultProps } from "prism-react-renderer"; | ||
import darkTheme from "prism-react-renderer/themes/duotoneDark"; | ||
import lightTheme from "prism-react-renderer/themes/duotoneLight"; | ||
import * as Scroller from "./scroller"; | ||
import { css } from "glamor"; | ||
import getTokensPerLine from "./step-parser"; | ||
//TODO configure theme | ||
//TODO don't import css | ||
// import "prismjs/themes/prism.css"; | ||
import loadTheme from "./theme"; | ||
loadTheme(); | ||
const selectedRules = css({ | ||
opacity: 1, | ||
transition: "opacity 300ms" | ||
}); | ||
const unselectedRules = css({ | ||
opacity: 0.3, | ||
transition: "opacity 300ms" | ||
}); | ||
function getFullLineHtml(showNumber, number, line) { | ||
const numberHtml = | ||
'<span class="token comment token-leaf line-number" style="user-select: none">' + | ||
String(number).padStart(3) + | ||
".</span> "; | ||
return showNumber ? numberHtml + line : line || " "; | ||
} | ||
const getLineClassName = (tokens, lineNumber) => { | ||
if (Object.keys(tokens).length === 0) { | ||
return css({ | ||
[`& .token-leaf`]: { | ||
opacity: "1 !important" | ||
} | ||
}); | ||
} else if (!(lineNumber in tokens)) { | ||
return ""; | ||
} else if (tokens[lineNumber] == null) { | ||
return css({ | ||
[`& .token-leaf`]: { | ||
opacity: "1 !important" | ||
} | ||
}); | ||
} else { | ||
return css( | ||
{ | ||
[`& .token-leaf.line-number`]: { | ||
opacity: "1 !important" | ||
} | ||
}, | ||
...tokens[lineNumber].map(n => ({ | ||
[`& .token-leaf.token-${n}`]: { | ||
opacity: "1 !important" | ||
} | ||
})) | ||
); | ||
} | ||
}; | ||
const LineOfCode = ({ number, tokensPerLine, html }) => { | ||
const isSelected = number in tokensPerLine; | ||
const className = getLineClassName(tokensPerLine, number); | ||
return ( | ||
<Scroller.Element | ||
dangerouslySetInnerHTML={{ __html: html }} | ||
// style={{ opacity: isSelected ? 1 : 0.3 }} | ||
className={className} | ||
selected={isSelected} | ||
/> | ||
); | ||
}; | ||
const CodeSurfer = ({ code, step, showNumbers }) => { | ||
const CodeSurfer = ({ code, step, lang, showNumbers, dark }) => { | ||
const tokensPerLine = getTokensPerLine(step); | ||
const tokenOpacity = css({ | ||
["& .token-leaf"]: { | ||
opacity: "0.35", | ||
transition: "opacity 300ms" | ||
} | ||
}); | ||
const isSelected = (lineIndex, tokenIndex) => | ||
tokensPerLine[lineIndex + 1] !== undefined && | ||
(tokensPerLine[lineIndex + 1] === null || | ||
tokensPerLine[lineIndex + 1].includes(tokenIndex)); | ||
return ( | ||
<Scroller.Container type="pre" height={500}> | ||
<Scroller.Content type="code" className={tokenOpacity}> | ||
{hightlightLines(code).map((line, index) => ( | ||
<LineOfCode | ||
key={index} | ||
html={getFullLineHtml(showNumbers, index + 1, line)} | ||
number={index + 1} | ||
tokensPerLine={tokensPerLine} | ||
/> | ||
))} | ||
</Scroller.Content> | ||
</Scroller.Container> | ||
<Highlight | ||
{...defaultProps} | ||
code={code} | ||
language={lang || "jsx"} | ||
theme={dark ? darkTheme : lightTheme} | ||
> | ||
{({ className, style, tokens, getLineProps, getTokenProps }) => ( | ||
<Scroller.Container | ||
type="pre" | ||
className={className} | ||
style={Object.assign({}, style, { background: null })} | ||
> | ||
<Scroller.Content type="code"> | ||
{tokens.map((line, i) => ( | ||
<div {...getLineProps({ line, key: i })}> | ||
{showNumbers && ( | ||
<span | ||
className={ | ||
"token comment " + | ||
(tokensPerLine[i + 1] !== undefined | ||
? selectedRules | ||
: unselectedRules) | ||
} | ||
style={{ userSelect: "none" }} | ||
> | ||
{(i + 1 + ".").padStart(3)}{" "} | ||
</span> | ||
)} | ||
{line.map((token, key) => ( | ||
<Scroller.Element | ||
type="span" | ||
{...getTokenProps({ | ||
token, | ||
key, | ||
selected: isSelected(i, key), | ||
className: isSelected(i, key) | ||
? selectedRules | ||
: unselectedRules | ||
})} | ||
/> | ||
))} | ||
</div> | ||
))} | ||
</Scroller.Content> | ||
</Scroller.Container> | ||
)} | ||
</Highlight> | ||
); | ||
@@ -87,0 +73,0 @@ }; |
import React from "react"; | ||
import Tween from "component-tween"; | ||
import raf from "component-raf"; | ||
import TWEEN from "./tween"; | ||
@@ -41,9 +40,9 @@ const getNewCenter = (container, content, firstSelected, lastSelected) => { | ||
console.log("top", top); | ||
console.log("bottom", bottom); | ||
console.log("containerHeight", containerHeight); | ||
console.log("selectedHeight", selectedHeight); | ||
console.log("scaledSelectedHeight", scaledSelectedHeight); | ||
console.log("contentHeight", contentHeight); | ||
console.log("scaledContentHeight", scaledContentHeight); | ||
// console.log("top", top); | ||
// console.log("bottom", bottom); | ||
// console.log("containerHeight", containerHeight); | ||
// console.log("selectedHeight", selectedHeight); | ||
// console.log("scaledSelectedHeight", scaledSelectedHeight); | ||
// console.log("contentHeight", contentHeight); | ||
// console.log("scaledContentHeight", scaledContentHeight); | ||
@@ -59,7 +58,7 @@ if (containerHeight >= scaledContentHeight) { | ||
} else { | ||
console.log("Bigger selected than container"); | ||
// console.log("Bigger selected than container"); | ||
center = (top - halfContent) * scale + halfContent + containerHeight / 2; | ||
} | ||
console.log(center); | ||
// console.log(center); | ||
return { center, scale }; | ||
@@ -82,20 +81,18 @@ }; | ||
const tween = Tween({ top: startY, scale: startScale }) | ||
.ease("out-circ") | ||
.to({ top: endY, scale }) | ||
.duration(duration); | ||
let step = { top: startY, scale: startScale }; | ||
tween.update(o => { | ||
container.scrollTop = o.top | 0; | ||
content.style.transform = "scale(" + o.scale + ")"; | ||
}); | ||
tween.on("end", function() { | ||
animate = function() {}; | ||
}); | ||
const tween = new TWEEN.Tween(step) | ||
.to({ top: endY, scale }, duration) | ||
.easing(TWEEN.Easing.Circular.Out) | ||
.onUpdate(() => { | ||
container.scrollTop = step.top | 0; | ||
content.style.transform = "scale(" + step.scale + ")"; | ||
}) | ||
.start(); | ||
function animate() { | ||
raf(animate); | ||
tween.update(); | ||
function animate(time) { | ||
requestAnimationFrame(animate); | ||
TWEEN.update(time); | ||
} | ||
animate(); | ||
requestAnimationFrame(animate); | ||
}; | ||
@@ -134,6 +131,6 @@ | ||
componentDidUpdate() { | ||
this.animate(700); | ||
this.animate(400); | ||
} | ||
render() { | ||
const { type, height, children, ...rest } = this.props; | ||
const { type, height, children, style, ...rest } = this.props; | ||
return React.createElement( | ||
@@ -143,12 +140,13 @@ type || "div", | ||
ref: this.containerRef, | ||
style: { | ||
height: 0, | ||
margin: 0, | ||
// background: "#222", | ||
// padding: this.props.height / 2 + "px 0", | ||
overflow: "hidden", | ||
textAlign: "center", | ||
position: "relative" | ||
// color: "#fafafa" | ||
}, | ||
style: Object.assign( | ||
{}, | ||
{ | ||
height: 0, | ||
margin: 0, | ||
overflow: "hidden", | ||
textAlign: "center", | ||
position: "relative" | ||
}, | ||
style | ||
), | ||
...rest | ||
@@ -163,3 +161,3 @@ }, | ||
render() { | ||
const { type, children, className, ...rest } = this.props; | ||
const { type, children, style, className, ...rest } = this.props; | ||
return React.createElement( | ||
@@ -169,3 +167,7 @@ type || "div", | ||
className: contentClassName + " " + className, | ||
style: { display: "inline-block", textAlign: "left", width: "100%" }, | ||
style: Object.assign( | ||
{}, | ||
{ display: "inline-block", textAlign: "left", width: "100%" }, | ||
style | ||
), | ||
...rest | ||
@@ -172,0 +174,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
62724
3
16
1886
1
1
+ Addedprism-react-renderer@^0.1.2
+ Addedprism-react-renderer@0.1.7(transitive)
+ Addedreact@18.3.1(transitive)
- Removedcomponent-raf@^1.2.0
- Removedcomponent-tween@^1.2.0
- Removedlodash.memoize@^4.1.2
- Removedprismjs@^1.15.0
- Removedreact@^16.4.2
- Removedcomponent-clone@0.2.2(transitive)
- Removedcomponent-emitter@1.2.0(transitive)
- Removedcomponent-raf@1.2.0(transitive)
- Removedcomponent-tween@1.2.0(transitive)
- Removedcomponent-type@1.1.0(transitive)
- Removedease-component@1.0.0(transitive)
- Removedlodash.memoize@4.1.2(transitive)
- Removedprismjs@1.29.0(transitive)
- Removedreact@16.14.0(transitive)