mirror of
https://github.com/Steffo99/bluelib.git
synced 2024-12-22 19:44:21 +00:00
First commit (0.8.1)
This commit is contained in:
commit
f034bf23ba
34 changed files with 13171 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
node_modules
|
||||||
|
/*.log
|
||||||
|
.idea/
|
||||||
|
size-plugin.json
|
12354
package-lock.json
generated
Normal file
12354
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
32
package.json
Normal file
32
package.json
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"private": false,
|
||||||
|
"name": "bluelib",
|
||||||
|
"version": "0.8.1",
|
||||||
|
"license": "AGPL-3.0-or-later",
|
||||||
|
"main": "src/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "preact watch",
|
||||||
|
"build": "preact build --no-prerender --dest docs && git add docs",
|
||||||
|
"ghpages": "npm run -s build && git add . && cross-env-shell git commit -m \"$npm_package_version\" && git push && cross-env-shell hub release create -m \"$npm_package_version\" \"$npm_package_version\" && cross-env-shell sentry-cli releases set-commits \"$npm_package_version\" --auto && cross-env-shell sentry-cli releases deploys \"$npm_package_version\" new --env production -n \"gh-pages\""
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"cross-env": "^7.0.2",
|
||||||
|
"preact-cli": "^3.0.0-rc.14"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fortawesome/fontawesome-svg-core": "^1.2.28",
|
||||||
|
"@fortawesome/free-brands-svg-icons": "^5.13.0",
|
||||||
|
"@fortawesome/free-regular-svg-icons": "^5.13.0",
|
||||||
|
"@fortawesome/free-solid-svg-icons": "^5.13.0",
|
||||||
|
"@fortawesome/react-fontawesome": "^0.1.9",
|
||||||
|
"css-loader": "^3.5.3",
|
||||||
|
"file-loader": "^5.0.2",
|
||||||
|
"less": "^3.11.1",
|
||||||
|
"less-loader": "^5.0.0",
|
||||||
|
"preact": "^10.4.4",
|
||||||
|
"preact-render-to-string": "^5.1.8",
|
||||||
|
"react-syntax-highlighter": "^12.2.1",
|
||||||
|
"showdown": "^1.9.1",
|
||||||
|
"style-loader": "^1.2.1"
|
||||||
|
}
|
||||||
|
}
|
9
preact.config.js
Normal file
9
preact.config.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
const DefinePlugin = require("webpack/lib/DefinePlugin");
|
||||||
|
|
||||||
|
|
||||||
|
export default function (config, env, helpers) {
|
||||||
|
// noinspection JSUnresolvedVariable
|
||||||
|
config.resolve.alias["react"] = "preact/compat";
|
||||||
|
// noinspection JSUnresolvedVariable
|
||||||
|
config.resolve.alias["react-dom"] = "preact/compat";
|
||||||
|
};
|
25
src/components/Elements/Box.js
Normal file
25
src/components/Elements/Box.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import style from "./Box.less";
|
||||||
|
|
||||||
|
export const BoxColors = Object.freeze({
|
||||||
|
RED: style.red,
|
||||||
|
ORANGE: style.orange,
|
||||||
|
YELLOW: style.yellow,
|
||||||
|
LIME: style.lime,
|
||||||
|
CYAN: style.cyan,
|
||||||
|
BLUE: style.blue,
|
||||||
|
MAGENTA: style.magenta,
|
||||||
|
DEFAULT: style.default
|
||||||
|
})
|
||||||
|
|
||||||
|
export default function (props) {
|
||||||
|
let color = BoxColors.DEFAULT;
|
||||||
|
if(props.color) {
|
||||||
|
color = props.color;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={style.box + " " + color}>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
49
src/components/Elements/Box.less
Normal file
49
src/components/Elements/Box.less
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
@import "../../styles/constants.less";
|
||||||
|
|
||||||
|
.box {
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 4px;
|
||||||
|
height: calc(100% - 8px);
|
||||||
|
min-width: 256px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.default {
|
||||||
|
background-color: fade(@fg, 5%);
|
||||||
|
color: @fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
background-color: fade(@red, 5%);
|
||||||
|
color: @red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orange {
|
||||||
|
background-color: fade(@orange, 5%);
|
||||||
|
color: @orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yellow {
|
||||||
|
background-color: fade(@yellow, 5%);
|
||||||
|
color: @yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lime {
|
||||||
|
background-color: fade(@lime, 5%);
|
||||||
|
color: @lime;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cyan {
|
||||||
|
background-color: fade(@cyan, 5%);
|
||||||
|
color: @cyan;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blue {
|
||||||
|
background-color: fade(@blue, 5%);
|
||||||
|
color: @blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.magenta {
|
||||||
|
background-color: fade(@magenta, 5%);
|
||||||
|
color: @magenta;
|
||||||
|
}
|
5
src/components/Elements/Image.js
Normal file
5
src/components/Elements/Image.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export default function(props) {
|
||||||
|
return (
|
||||||
|
<a href={props.src} title={props.alt} target={"_blank"}><img src={props.src} alt={props.alt}/></a>
|
||||||
|
)
|
||||||
|
}
|
15
src/components/Elements/Panel.js
Normal file
15
src/components/Elements/Panel.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import style from "./Panel.less";
|
||||||
|
import Box from "./Box";
|
||||||
|
|
||||||
|
export default function(props) {
|
||||||
|
return (
|
||||||
|
<Box color={props.color}>
|
||||||
|
<h3 class={style.title}>
|
||||||
|
{props.title}
|
||||||
|
</h3>
|
||||||
|
<div class={style.contents}>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
10
src/components/Elements/Panel.less
Normal file
10
src/components/Elements/Panel.less
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
@import "../../styles/constants.less";
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-family: @title;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents {
|
||||||
|
font-family: @text;
|
||||||
|
}
|
15
src/components/Elements/Section.js
Normal file
15
src/components/Elements/Section.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import Split from "../Layout/Split";
|
||||||
|
import {Fragment} from "preact";
|
||||||
|
|
||||||
|
export default function (props) {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<h2>
|
||||||
|
{props.title}
|
||||||
|
</h2>
|
||||||
|
<Split>
|
||||||
|
{props.children}
|
||||||
|
</Split>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
9
src/components/Elements/TablePanel.js
Normal file
9
src/components/Elements/TablePanel.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import style from "./TablePanel.less";
|
||||||
|
|
||||||
|
export default function (props) {
|
||||||
|
return (
|
||||||
|
<table class={style.tablepanel}>
|
||||||
|
{props.children}
|
||||||
|
</table>
|
||||||
|
);
|
||||||
|
}
|
6
src/components/Elements/TablePanel.less
Normal file
6
src/components/Elements/TablePanel.less
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
@import "../../styles/constants.less";
|
||||||
|
|
||||||
|
.tablepanel {
|
||||||
|
margin: 4px;
|
||||||
|
width: calc(100% - 8px);
|
||||||
|
}
|
97
src/components/Elements/Timer.js
Normal file
97
src/components/Elements/Timer.js
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
import {Component} from 'preact'
|
||||||
|
import style from "./Timer.less"
|
||||||
|
|
||||||
|
|
||||||
|
export default class Timer extends Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.state = {
|
||||||
|
"now": Date.now()
|
||||||
|
};
|
||||||
|
this.timer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
this.setState({"now": Date.now()})
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
if(this.timer !== null) {
|
||||||
|
clearInterval(this.timer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let dateTo = "Unknown date";
|
||||||
|
let className = style.timer;
|
||||||
|
|
||||||
|
let parts = {
|
||||||
|
milliseconds: "?",
|
||||||
|
seconds: "?",
|
||||||
|
minutes: "?",
|
||||||
|
hours: "?",
|
||||||
|
days: "?",
|
||||||
|
};
|
||||||
|
|
||||||
|
if(this.props.to) {
|
||||||
|
dateTo = new Date(this.props.to);
|
||||||
|
let timeLeft = dateTo - this.state.now;
|
||||||
|
|
||||||
|
if(timeLeft > 0) {
|
||||||
|
parts = {
|
||||||
|
milliseconds: timeLeft % 1000,
|
||||||
|
seconds: Math.floor(timeLeft / 1000) % 60,
|
||||||
|
minutes: Math.floor(timeLeft / 60000) % 60,
|
||||||
|
hours: Math.floor(timeLeft / 3600000) % 24,
|
||||||
|
days: Math.floor(timeLeft / 86400000),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
parts = {
|
||||||
|
milliseconds: 0,
|
||||||
|
seconds: 0,
|
||||||
|
minutes: 0,
|
||||||
|
hours: 0,
|
||||||
|
days: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
className += " " + style.expired;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
className += " " + style.unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={className} title={dateTo}>
|
||||||
|
<div class={style.days + " " + style.count}>
|
||||||
|
{parts.days}
|
||||||
|
</div>
|
||||||
|
<div className={style.days + " " + style.text}>
|
||||||
|
giorni
|
||||||
|
</div>
|
||||||
|
<div class={style.hours + " " + style.count}>
|
||||||
|
{parts.hours}
|
||||||
|
</div>
|
||||||
|
<div className={style.hours + " " + style.text}>
|
||||||
|
ore
|
||||||
|
</div>
|
||||||
|
<div class={style.minutes + " " + style.count}>
|
||||||
|
{parts.minutes}
|
||||||
|
</div>
|
||||||
|
<div className={style.minutes + " " + style.text}>
|
||||||
|
minuti
|
||||||
|
</div>
|
||||||
|
<div class={style.seconds + " " + style.count}>
|
||||||
|
{parts.seconds}
|
||||||
|
</div>
|
||||||
|
<div class={style.seconds + " " + style.text}>
|
||||||
|
secondi
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
57
src/components/Elements/Timer.less
Normal file
57
src/components/Elements/Timer.less
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
@import "../../styles/constants";
|
||||||
|
|
||||||
|
.timer {
|
||||||
|
display: grid;
|
||||||
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
grid-template-columns: 80px 80px 80px 80px;
|
||||||
|
border: 2px solid @plusplus;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.days {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hours {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minutes {
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.seconds {
|
||||||
|
grid-column: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.count {
|
||||||
|
grid-row: 1;
|
||||||
|
font-size: xx-large;
|
||||||
|
color: @accent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
grid-row: 2;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unknown {
|
||||||
|
color: @magenta;
|
||||||
|
|
||||||
|
.count {
|
||||||
|
color: @magenta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.expired {
|
||||||
|
color: @red;
|
||||||
|
|
||||||
|
.count {
|
||||||
|
color: @red;
|
||||||
|
}
|
||||||
|
}
|
10
src/components/Elements/Todo.js
Normal file
10
src/components/Elements/Todo.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import style from "./Todo.less";
|
||||||
|
|
||||||
|
export default function (props) {
|
||||||
|
if(process.env.NODE_ENV === "development") {
|
||||||
|
return <span class={style.todo}>{props.children}</span>;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
9
src/components/Elements/Todo.less
Normal file
9
src/components/Elements/Todo.less
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
@import "../../styles/constants.less";
|
||||||
|
|
||||||
|
.todo {
|
||||||
|
border: 1px yellow solid;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 1px;
|
||||||
|
background-color: black;
|
||||||
|
color: yellow;
|
||||||
|
}
|
18
src/components/Layout/Footer.js
Normal file
18
src/components/Layout/Footer.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import style from './Footer.less';
|
||||||
|
import { Component } from 'preact';
|
||||||
|
|
||||||
|
export default function(props) {
|
||||||
|
return (
|
||||||
|
<div class={style.footer}>
|
||||||
|
© {new Date().getFullYear()}
|
||||||
|
-
|
||||||
|
<a href={"https://steffo.eu/"}>Stefano Pigozzi</a>
|
||||||
|
-
|
||||||
|
<a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>
|
||||||
|
-
|
||||||
|
<a href="https://github.com/Steffo99/appuntiweb">uni.steffo.eu {process.env.RELEASE}</a>
|
||||||
|
-
|
||||||
|
<a href={"https://ko-fi.com/steffo"}>Supportami</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
8
src/components/Layout/Footer.less
Normal file
8
src/components/Layout/Footer.less
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
@import "../../styles/constants.less";
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
margin-top: 8px;
|
||||||
|
color: @accent;
|
||||||
|
text-align: center;
|
||||||
|
font-size: x-small;
|
||||||
|
}
|
28
src/components/Layout/Split.js
Normal file
28
src/components/Layout/Split.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import style from "./Split.less";
|
||||||
|
|
||||||
|
export default function (props) {
|
||||||
|
let children;
|
||||||
|
|
||||||
|
if(Array.isArray(props.children)) {
|
||||||
|
children = props.children.map(element => {
|
||||||
|
return (
|
||||||
|
<div class={style.splitchild}>
|
||||||
|
{element}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
children = (
|
||||||
|
<div class={style.splitchild}>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div class={style.split}>
|
||||||
|
<div class={style.splitparent}>{children}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
16
src/components/Layout/Split.less
Normal file
16
src/components/Layout/Split.less
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
@import "../../styles/constants.less";
|
||||||
|
|
||||||
|
.split {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.splitparent {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.splitchild {
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-basis: 0;
|
||||||
|
}
|
7
src/components/Rendering/BLatex.js
Normal file
7
src/components/Rendering/BLatex.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Latex from "./Latex";
|
||||||
|
|
||||||
|
export default function (props) {
|
||||||
|
return (
|
||||||
|
<Latex inline={false}>{props.children}</Latex>
|
||||||
|
);
|
||||||
|
}
|
11
src/components/Rendering/Code.js
Normal file
11
src/components/Rendering/Code.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import SyntaxHighlighter from 'react-syntax-highlighter'
|
||||||
|
import {monokai} from "react-syntax-highlighter/dist/cjs/styles/hljs";
|
||||||
|
import stripTabs from "../../utils/stripTabs";
|
||||||
|
|
||||||
|
export default function(props) {
|
||||||
|
return (
|
||||||
|
<SyntaxHighlighter language={props.language ? props.language : "plaintext"} style={monokai}>
|
||||||
|
{stripTabs(String(props.children))}
|
||||||
|
</SyntaxHighlighter>
|
||||||
|
)
|
||||||
|
}
|
7
src/components/Rendering/ILatex.js
Normal file
7
src/components/Rendering/ILatex.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Latex from "./Latex";
|
||||||
|
|
||||||
|
export default function (props) {
|
||||||
|
return (
|
||||||
|
<Latex inline={true}>{props.children}</Latex>
|
||||||
|
);
|
||||||
|
}
|
39
src/components/Rendering/Latex.js
Normal file
39
src/components/Rendering/Latex.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import style from './Latex.less';
|
||||||
|
import {useContext} from "preact/hooks";
|
||||||
|
import LatexRenderColor from "../../contexts/LatexRenderColor";
|
||||||
|
import LatexDefaultInline from "../../contexts/LatexDefaultInline";
|
||||||
|
|
||||||
|
export default function(props) {
|
||||||
|
// black, blue, brown, cyan, darkgray, gray, green, lightgray, lime, magenta, olive, orange, pink, purple, red, teal, violet, white, yellow
|
||||||
|
let renderColor = useContext(LatexRenderColor);
|
||||||
|
let defaultInline = useContext(LatexDefaultInline);
|
||||||
|
|
||||||
|
let is_inline;
|
||||||
|
if(props.inline === undefined) {
|
||||||
|
is_inline = defaultInline;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
is_inline = props.inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_inline) {
|
||||||
|
let equation = `\\inline {\\color{${renderColor}} ${props.children} }`;
|
||||||
|
return (
|
||||||
|
<img src={`https://latex.codecogs.com/svg.latex?${equation}`}
|
||||||
|
alt={props.children}
|
||||||
|
title={props.children}
|
||||||
|
class={style.latex + " " + style.inline}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let equation = `{\\color{${renderColor}} ${props.children} }`;
|
||||||
|
return (
|
||||||
|
<img src={`https://latex.codecogs.com/svg.latex?${equation}`}
|
||||||
|
alt={props.children}
|
||||||
|
title={props.children}
|
||||||
|
class={style.latex + " " + style.block}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
14
src/components/Rendering/Latex.less
Normal file
14
src/components/Rendering/Latex.less
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
@import "../../styles/constants.less";
|
||||||
|
|
||||||
|
.latex {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block {
|
||||||
|
display: block;
|
||||||
|
}
|
14
src/components/Rendering/Markdown.js
Normal file
14
src/components/Rendering/Markdown.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import showdown from "showdown";
|
||||||
|
import stripTabs from "../../utils/stripTabs";
|
||||||
|
import style from "./Markdown.less";
|
||||||
|
|
||||||
|
export default function(props) {
|
||||||
|
let converter = new showdown.Converter({
|
||||||
|
"tables": true,
|
||||||
|
});
|
||||||
|
converter.setFlavor("github");
|
||||||
|
|
||||||
|
let html = converter.makeHtml(stripTabs(String(props.children)));
|
||||||
|
|
||||||
|
return <div class={style.markdown} dangerouslySetInnerHTML={{__html: html}}/>;
|
||||||
|
}
|
12
src/components/Rendering/Markdown.less
Normal file
12
src/components/Rendering/Markdown.less
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
@import "../../styles/constants.less";
|
||||||
|
|
||||||
|
.markdown {
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
padding-bottom: 2px;
|
||||||
|
border-bottom: 1px solid @plusplusplus;
|
||||||
|
}
|
||||||
|
}
|
9
src/components/Rendering/PLatex.js
Normal file
9
src/components/Rendering/PLatex.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import BLatex from "./BLatex";
|
||||||
|
|
||||||
|
export default function (props) {
|
||||||
|
return (
|
||||||
|
<p>
|
||||||
|
<BLatex>{props.children}</BLatex>
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
3
src/contexts/LatexDefaultInline.js
Normal file
3
src/contexts/LatexDefaultInline.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import {createContext} from "preact";
|
||||||
|
|
||||||
|
export default createContext(true);
|
3
src/contexts/LatexRenderColor.js
Normal file
3
src/contexts/LatexRenderColor.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import {createContext} from "preact";
|
||||||
|
|
||||||
|
export default createContext("White");
|
64
src/index.js
Normal file
64
src/index.js
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
import Box from "./components/Elements/Box"
|
||||||
|
import {BoxColors} from "./components/Elements/Box";
|
||||||
|
import Image from "./components/Elements/Image"
|
||||||
|
import Panel from "./components/Elements/Panel";
|
||||||
|
import Section from "./components/Elements/Section";
|
||||||
|
import TablePanel from "./components/Elements/TablePanel";
|
||||||
|
import Timer from "./components/Elements/Timer";
|
||||||
|
import Todo from "./components/Elements/Todo";
|
||||||
|
import Footer from "./components/Layout/Footer";
|
||||||
|
import Split from "./components/Layout/Split";
|
||||||
|
import Code from "./components/Rendering/Code";
|
||||||
|
import Latex from "./components/Rendering/Latex";
|
||||||
|
import BLatex from "./components/Rendering/BLatex";
|
||||||
|
import ILatex from "./components/Rendering/ILatex";
|
||||||
|
import PLatex from "./components/Rendering/PLatex";
|
||||||
|
import LatexDefaultInline from "./contexts/LatexDefaultInline";
|
||||||
|
import LatexRenderColor from "./contexts/LatexRenderColor";
|
||||||
|
import Markdown from "./components/Rendering/Markdown";
|
||||||
|
|
||||||
|
export {
|
||||||
|
Box,
|
||||||
|
BoxColors,
|
||||||
|
Image,
|
||||||
|
Panel,
|
||||||
|
Section,
|
||||||
|
TablePanel,
|
||||||
|
Timer,
|
||||||
|
Todo,
|
||||||
|
Footer,
|
||||||
|
Split,
|
||||||
|
Code,
|
||||||
|
Latex,
|
||||||
|
BLatex,
|
||||||
|
ILatex,
|
||||||
|
PLatex,
|
||||||
|
LatexDefaultInline,
|
||||||
|
LatexRenderColor,
|
||||||
|
Markdown,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
import {Fragment} from "preact";
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
|
export default function() {
|
||||||
|
require("./styles/theme.less");
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<h1>
|
||||||
|
bluelib
|
||||||
|
</h1>
|
||||||
|
<Split>
|
||||||
|
<Box>
|
||||||
|
Hi. I'm a box!
|
||||||
|
</Box>
|
||||||
|
<Box color={BoxColors.RED}>
|
||||||
|
Hi. I'm a box, but I'm red!
|
||||||
|
</Box>
|
||||||
|
<Box color={BoxColors.LIME}>
|
||||||
|
Hi. I was here third!
|
||||||
|
</Box>
|
||||||
|
</Split>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}
|
33
src/styles/constants.less
Normal file
33
src/styles/constants.less
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
@bg: #0d193b;
|
||||||
|
@bg-light: #142245;
|
||||||
|
@bg-lighter: #1c2b4f;
|
||||||
|
@bg-lightest: #233358;
|
||||||
|
@fg: #a0ccff;
|
||||||
|
@accent: #ffffff;
|
||||||
|
|
||||||
|
@link: #00caca;
|
||||||
|
@linkhover: #00ffff;
|
||||||
|
@linkactive: #a0ffff;
|
||||||
|
|
||||||
|
@plus: fade(@fg, 5%);
|
||||||
|
@plusplus: fade(@fg, 10%);
|
||||||
|
@plusplusplus: fade(@fg, 15%);
|
||||||
|
@plusplusplusplus: fade(@fg, 20%);
|
||||||
|
|
||||||
|
@red: #ff7d7d;
|
||||||
|
@orange: #ffbb7d;
|
||||||
|
@yellow: #ffff7d;
|
||||||
|
@lime: #7dff7d;
|
||||||
|
@cyan: #7dffff;
|
||||||
|
@blue: #7d7dff;
|
||||||
|
@magenta: #ff7dff;
|
||||||
|
|
||||||
|
@disabledfg: #808080;
|
||||||
|
@disabledbg: #1f1f1f;
|
||||||
|
|
||||||
|
@sans: "Arial", sans-serif;
|
||||||
|
@text: "Calibri", sans-serif;
|
||||||
|
@title: "Verdana", sans-serif;
|
||||||
|
@mono: "Consolas", "SFMono-Regular", "Liberation Mono", "Menlo", monospace;
|
||||||
|
|
||||||
|
@example: #d3a1ff;
|
154
src/styles/theme.less
Normal file
154
src/styles/theme.less
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
@import "constants.less";
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: @bg;
|
||||||
|
color: @fg;
|
||||||
|
font-family: @sans;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
margin-top: 4px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
color: @accent;
|
||||||
|
font-family: @title;
|
||||||
|
font-weight: normal;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
// By default h1 are as large as h2
|
||||||
|
h1 {
|
||||||
|
font-size: xx-large;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: @link;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: @linkhover;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: @linkactive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img, iframe {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 300px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre, code {
|
||||||
|
font-family: @mono;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
color: @fg;
|
||||||
|
border-left: 3px solid @plusplusplusplus;
|
||||||
|
background-color: @plus;
|
||||||
|
padding: 4px 4px 4px 8px;
|
||||||
|
margin: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"], input[type="password"] {
|
||||||
|
color: @fg;
|
||||||
|
background-color: @bg;
|
||||||
|
border: 1px solid @plusplus;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 4px;
|
||||||
|
font-size: medium;
|
||||||
|
|
||||||
|
&:disabled, &.disabled {
|
||||||
|
color: @disabledfg;
|
||||||
|
background-color: @disabledbg;
|
||||||
|
border-style: dotted;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
color: @fg;
|
||||||
|
background-color: @bg;
|
||||||
|
border: 1px solid @plusplus;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 4px;
|
||||||
|
font-size: medium;
|
||||||
|
|
||||||
|
&:hover, &.hover {
|
||||||
|
background-color: @plusplus;
|
||||||
|
border: 1px solid @fg;
|
||||||
|
color: @fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active, &.active {
|
||||||
|
background-color: fade(@accent, 20%);
|
||||||
|
border: 1px solid @accent;
|
||||||
|
color: @accent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled, &.disabled {
|
||||||
|
color: @disabledfg;
|
||||||
|
background-color: @disabledbg;
|
||||||
|
border-style: dotted;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border: 1px solid @plusplusplusplus;
|
||||||
|
margin-top: 24px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-spacing: 0;
|
||||||
|
border: 2px solid @plusplus;
|
||||||
|
background-color: @plus;
|
||||||
|
border-collapse: collapse;
|
||||||
|
|
||||||
|
thead, tbody {
|
||||||
|
th, td {
|
||||||
|
padding: 4px;
|
||||||
|
border: 1px solid @plusplus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thead {
|
||||||
|
background-color: @plusplus;
|
||||||
|
color: @accent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
b {
|
||||||
|
color: @accent;
|
||||||
|
}
|
||||||
|
|
||||||
|
abbr {
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
margin: 4px 0;
|
||||||
|
padding: 4px;
|
||||||
|
font-size: smaller;
|
||||||
|
background-color: @plus;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
25
src/utils/stripTabs.js
Normal file
25
src/utils/stripTabs.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
export default function(input) {
|
||||||
|
let indent_regex = /^[ \t]+/;
|
||||||
|
|
||||||
|
let lines = input.split("\n").filter((line) => {
|
||||||
|
return line !== "";
|
||||||
|
});
|
||||||
|
let match = null;
|
||||||
|
|
||||||
|
for(let i = 0; i < lines.length; i++) {
|
||||||
|
match = indent_regex.exec(lines[i]);
|
||||||
|
if(match !== null) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let start;
|
||||||
|
if(match === null) {
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
start = match[0].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.map((line) => {
|
||||||
|
return line.substr(start);
|
||||||
|
}).join("\n");
|
||||||
|
}
|
Loading…
Reference in a new issue