sinho 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +24 -0
- package/.github/workflows/deploy-docs.yml +47 -0
- package/.prettierrc +3 -0
- package/LICENSE.md +21 -0
- package/README.md +33 -0
- package/ci/check-size.js +8 -0
- package/dist/array_mutation.d.ts +16 -0
- package/dist/array_mutation.js +75 -0
- package/dist/array_mutation.js.map +1 -0
- package/dist/bundle.d.ts +1126 -0
- package/dist/bundle.js +1074 -0
- package/dist/bundle.min.js +1 -0
- package/dist/component.d.ts +253 -0
- package/dist/component.js +256 -0
- package/dist/component.js.map +1 -0
- package/dist/context.d.ts +21 -0
- package/dist/context.js +34 -0
- package/dist/context.js.map +1 -0
- package/dist/create_element.d.ts +43 -0
- package/dist/create_element.js +43 -0
- package/dist/create_element.js.map +1 -0
- package/dist/dom.d.ts +602 -0
- package/dist/dom.js +97 -0
- package/dist/dom.js.map +1 -0
- package/dist/intrinsic/ClassComponent.d.ts +2 -0
- package/dist/intrinsic/ClassComponent.js +10 -0
- package/dist/intrinsic/ClassComponent.js.map +1 -0
- package/dist/intrinsic/Dynamic.d.ts +33 -0
- package/dist/intrinsic/Dynamic.js +53 -0
- package/dist/intrinsic/Dynamic.js.map +1 -0
- package/dist/intrinsic/ErrorBoundary.d.ts +14 -0
- package/dist/intrinsic/ErrorBoundary.js +36 -0
- package/dist/intrinsic/ErrorBoundary.js.map +1 -0
- package/dist/intrinsic/For.d.ts +10 -0
- package/dist/intrinsic/For.js +81 -0
- package/dist/intrinsic/For.js.map +1 -0
- package/dist/intrinsic/Fragment.d.ts +23 -0
- package/dist/intrinsic/Fragment.js +28 -0
- package/dist/intrinsic/Fragment.js.map +1 -0
- package/dist/intrinsic/If.d.ts +24 -0
- package/dist/intrinsic/If.js +47 -0
- package/dist/intrinsic/If.js.map +1 -0
- package/dist/intrinsic/Portal.d.ts +6 -0
- package/dist/intrinsic/Portal.js +15 -0
- package/dist/intrinsic/Portal.js.map +1 -0
- package/dist/intrinsic/Style.d.ts +7 -0
- package/dist/intrinsic/Style.js +70 -0
- package/dist/intrinsic/Style.js.map +1 -0
- package/dist/intrinsic/TagComponent.d.ts +4 -0
- package/dist/intrinsic/TagComponent.js +67 -0
- package/dist/intrinsic/TagComponent.js.map +1 -0
- package/dist/intrinsic/Text.d.ts +6 -0
- package/dist/intrinsic/Text.js +16 -0
- package/dist/intrinsic/Text.js.map +1 -0
- package/dist/intrinsic/mod.d.ts +5 -0
- package/dist/intrinsic/mod.js +6 -0
- package/dist/intrinsic/mod.js.map +1 -0
- package/dist/jsx-runtime/mod.d.ts +23 -0
- package/dist/jsx-runtime/mod.js +11 -0
- package/dist/jsx-runtime/mod.js.map +1 -0
- package/dist/mod.d.ts +8 -0
- package/dist/mod.js +7 -0
- package/dist/mod.js.map +1 -0
- package/dist/renderer.d.ts +13 -0
- package/dist/renderer.js +25 -0
- package/dist/renderer.js.map +1 -0
- package/dist/scope.d.ts +138 -0
- package/dist/scope.js +228 -0
- package/dist/scope.js.map +1 -0
- package/dist/template.d.ts +10 -0
- package/dist/template.js +7 -0
- package/dist/template.js.map +1 -0
- package/dist/utils.d.ts +6 -0
- package/dist/utils.js +13 -0
- package/dist/utils.js.map +1 -0
- package/package.json +71 -0
- package/src/array_mutation.ts +118 -0
- package/src/component.ts +624 -0
- package/src/context.ts +70 -0
- package/src/create_element.ts +89 -0
- package/src/dom.ts +819 -0
- package/src/intrinsic/ClassComponent.ts +17 -0
- package/src/intrinsic/For.ts +122 -0
- package/src/intrinsic/Fragment.ts +38 -0
- package/src/intrinsic/If.ts +73 -0
- package/src/intrinsic/Portal.ts +25 -0
- package/src/intrinsic/Style.ts +120 -0
- package/src/intrinsic/TagComponent.ts +102 -0
- package/src/intrinsic/Text.ts +24 -0
- package/src/intrinsic/mod.ts +5 -0
- package/src/jsx-runtime/mod.ts +41 -0
- package/src/mod.ts +37 -0
- package/src/renderer.ts +45 -0
- package/src/scope.ts +404 -0
- package/src/template.ts +16 -0
- package/src/utils.ts +29 -0
- package/terser.config.json +16 -0
- package/tsconfig.json +18 -0
- package/web/README.md +41 -0
- package/web/babel.config.js +3 -0
- package/web/dist/shingo.min.d.ts +1131 -0
- package/web/dist/shingo.min.js +1 -0
- package/web/docusaurus.config.ts +151 -0
- package/web/package-lock.json +14850 -0
- package/web/package.json +54 -0
- package/web/sidebars.ts +31 -0
- package/web/src/components/monacoEditor.tsx +72 -0
- package/web/src/components/playground.tsx +89 -0
- package/web/src/components/playgroundComponent.tsx +168 -0
- package/web/src/css/custom.css +37 -0
- package/web/src/pages/index.module.css +31 -0
- package/web/src/pages/index.tsx +73 -0
- package/web/src/pages/playground.tsx +64 -0
- package/web/static/.nojekyll +0 -0
- package/web/static/dist/bundle.d.ts +1126 -0
- package/web/static/dist/bundle.min.js +1 -0
- package/web/tsconfig.json +8 -0
package/web/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "site",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"docusaurus": "docusaurus",
|
|
7
|
+
"prepare-static": "copyfiles --flat ../dist/bundle.min.js ../dist/bundle.d.ts ./static/dist",
|
|
8
|
+
"start": "npm run prepare-static && docusaurus start",
|
|
9
|
+
"build": "npm run prepare-static && docusaurus build",
|
|
10
|
+
"swizzle": "docusaurus swizzle",
|
|
11
|
+
"deploy": "docusaurus deploy",
|
|
12
|
+
"clear": "docusaurus clear",
|
|
13
|
+
"serve": "docusaurus serve",
|
|
14
|
+
"write-translations": "docusaurus write-translations",
|
|
15
|
+
"write-heading-ids": "docusaurus write-heading-ids",
|
|
16
|
+
"typecheck": "tsc"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@docusaurus/core": "3.2.1",
|
|
20
|
+
"@docusaurus/preset-classic": "3.2.1",
|
|
21
|
+
"@mdx-js/react": "^3.0.0",
|
|
22
|
+
"@swc/wasm-web": "^1.4.17",
|
|
23
|
+
"clsx": "^2.0.0",
|
|
24
|
+
"monaco-editor": "^0.48.0",
|
|
25
|
+
"monaco-editor-webpack-plugin": "^7.1.0",
|
|
26
|
+
"prism-react-renderer": "^2.3.0",
|
|
27
|
+
"react": "^18.0.0",
|
|
28
|
+
"react-dom": "^18.0.0",
|
|
29
|
+
"sinho": "file:.."
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@docusaurus/module-type-aliases": "3.2.1",
|
|
33
|
+
"@docusaurus/tsconfig": "3.2.1",
|
|
34
|
+
"@docusaurus/types": "3.2.1",
|
|
35
|
+
"docusaurus-plugin-typedoc-api": "^4.2.0",
|
|
36
|
+
"typedoc": "^0.25.13",
|
|
37
|
+
"typescript": "^5.4.3"
|
|
38
|
+
},
|
|
39
|
+
"browserslist": {
|
|
40
|
+
"production": [
|
|
41
|
+
">0.5%",
|
|
42
|
+
"not dead",
|
|
43
|
+
"not op_mini all"
|
|
44
|
+
],
|
|
45
|
+
"development": [
|
|
46
|
+
"last 3 chrome version",
|
|
47
|
+
"last 3 firefox version",
|
|
48
|
+
"last 5 safari version"
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=18.0"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/web/sidebars.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type {SidebarsConfig} from '@docusaurus/plugin-content-docs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creating a sidebar enables you to:
|
|
5
|
+
- create an ordered group of docs
|
|
6
|
+
- render a sidebar for each doc of that group
|
|
7
|
+
- provide next/previous navigation
|
|
8
|
+
|
|
9
|
+
The sidebars can be generated from the filesystem, or explicitly defined here.
|
|
10
|
+
|
|
11
|
+
Create as many sidebars as you want.
|
|
12
|
+
*/
|
|
13
|
+
const sidebars: SidebarsConfig = {
|
|
14
|
+
// By default, Docusaurus generates a sidebar from the docs folder structure
|
|
15
|
+
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
|
|
16
|
+
|
|
17
|
+
// But you can create a sidebar manually
|
|
18
|
+
/*
|
|
19
|
+
tutorialSidebar: [
|
|
20
|
+
'intro',
|
|
21
|
+
'hello',
|
|
22
|
+
{
|
|
23
|
+
type: 'category',
|
|
24
|
+
label: 'Tutorial',
|
|
25
|
+
items: ['tutorial-basics/create-a-document'],
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
*/
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default sidebars;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { useColorMode } from "@docusaurus/theme-common";
|
|
2
|
+
import useBaseUrl from "@docusaurus/useBaseUrl";
|
|
3
|
+
import * as monaco from "monaco-editor";
|
|
4
|
+
import { CSSProperties, FC, useEffect, useRef } from "react";
|
|
5
|
+
|
|
6
|
+
export const MonacoEditor: FC<{
|
|
7
|
+
style?: CSSProperties;
|
|
8
|
+
text?: string;
|
|
9
|
+
onChange?: (text: string) => void;
|
|
10
|
+
}> = (props) => {
|
|
11
|
+
const divRef = useRef<HTMLDivElement>(null);
|
|
12
|
+
const typesPath = useBaseUrl("/dist/bundle.d.ts");
|
|
13
|
+
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
|
|
14
|
+
const { colorMode } = useColorMode();
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
(async () => {
|
|
18
|
+
editorRef.current = monaco.editor.create(divRef.current!, {
|
|
19
|
+
model: monaco.editor.createModel(
|
|
20
|
+
props.text!,
|
|
21
|
+
"typescript",
|
|
22
|
+
monaco.Uri.file("/main.tsx"),
|
|
23
|
+
),
|
|
24
|
+
language: "typescript",
|
|
25
|
+
minimap: {
|
|
26
|
+
enabled: false,
|
|
27
|
+
},
|
|
28
|
+
smoothScrolling: true,
|
|
29
|
+
automaticLayout: true,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
editorRef.current.onDidChangeModelContent(() => {
|
|
33
|
+
props.onChange?.(editorRef.current!.getValue());
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
|
|
37
|
+
strict: true,
|
|
38
|
+
jsx: monaco.languages.typescript.JsxEmit.ReactJSX,
|
|
39
|
+
jsxImportSource: "sinho",
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const types = await fetch(typesPath).then((res) => res.text());
|
|
43
|
+
|
|
44
|
+
monaco.languages.typescript.typescriptDefaults.addExtraLib(
|
|
45
|
+
`declare module "sinho" {\n${types}\n}`,
|
|
46
|
+
"ts:sinho.d.ts",
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
monaco.languages.typescript.typescriptDefaults.addExtraLib(
|
|
50
|
+
`declare module "sinho/jsx-runtime" {\n${types}\n}`,
|
|
51
|
+
"ts:sinho-jsx-runtime.d.ts",
|
|
52
|
+
);
|
|
53
|
+
})();
|
|
54
|
+
|
|
55
|
+
return () => {
|
|
56
|
+
editorRef.current?.getModel()!.dispose();
|
|
57
|
+
editorRef.current?.dispose();
|
|
58
|
+
};
|
|
59
|
+
}, []);
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
monaco.editor.setTheme(colorMode == "light" ? "vs" : "vs-dark");
|
|
63
|
+
}, [colorMode]);
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (editorRef.current?.getValue() != props.text) {
|
|
67
|
+
editorRef.current?.setValue(props.text!);
|
|
68
|
+
}
|
|
69
|
+
}, [props.text]);
|
|
70
|
+
|
|
71
|
+
return <div ref={divRef} style={props.style} />;
|
|
72
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { useColorMode } from "@docusaurus/theme-common";
|
|
2
|
+
import useBaseUrl from "@docusaurus/useBaseUrl";
|
|
3
|
+
import {
|
|
4
|
+
CSSProperties,
|
|
5
|
+
FC,
|
|
6
|
+
RefObject,
|
|
7
|
+
useEffect,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
} from "react";
|
|
11
|
+
|
|
12
|
+
export const Playground: FC<{
|
|
13
|
+
innerRef?: RefObject<HTMLElement>;
|
|
14
|
+
style?: CSSProperties;
|
|
15
|
+
headerText?: string;
|
|
16
|
+
customCode?: string;
|
|
17
|
+
autosize?: boolean;
|
|
18
|
+
}> = (props) => {
|
|
19
|
+
const { colorMode } = useColorMode();
|
|
20
|
+
const sinhoPath = useBaseUrl("/dist/bundle.min.js");
|
|
21
|
+
const importMap = {
|
|
22
|
+
imports: {
|
|
23
|
+
sinho: sinhoPath,
|
|
24
|
+
"sinho/jsx-runtime": sinhoPath,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
import("./playgroundComponent");
|
|
30
|
+
}, []);
|
|
31
|
+
|
|
32
|
+
const Playground: any = "x-playground";
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<Playground
|
|
36
|
+
ref={props.innerRef}
|
|
37
|
+
style={props.style}
|
|
38
|
+
color-mode={colorMode}
|
|
39
|
+
header-text={props.headerText}
|
|
40
|
+
autosize={props.autosize}
|
|
41
|
+
import-map={JSON.stringify(importMap)}
|
|
42
|
+
custom-code={props.customCode}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const CodeSnippetPlayground: FC<{
|
|
48
|
+
headerText?: string;
|
|
49
|
+
customCode?: (code: string) => string;
|
|
50
|
+
}> = (props) => {
|
|
51
|
+
const [customCode, setCustomCode] = useState("");
|
|
52
|
+
const playgroundRef = useRef<HTMLElement>(null);
|
|
53
|
+
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (playgroundRef.current == null) return;
|
|
56
|
+
|
|
57
|
+
const codeElement = playgroundRef.current
|
|
58
|
+
.previousElementSibling as HTMLElement | null;
|
|
59
|
+
const detectedCode = codeElement?.innerText ?? "";
|
|
60
|
+
|
|
61
|
+
setCustomCode(props.customCode?.(detectedCode) ?? detectedCode);
|
|
62
|
+
}, [props.customCode]);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Playground
|
|
66
|
+
innerRef={playgroundRef}
|
|
67
|
+
autosize
|
|
68
|
+
headerText={props.headerText}
|
|
69
|
+
customCode={customCode}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const CodeSnippetComponentPlayground: FC<{
|
|
75
|
+
headerText?: string;
|
|
76
|
+
componentName: string;
|
|
77
|
+
}> = (props) => {
|
|
78
|
+
return (
|
|
79
|
+
<CodeSnippetPlayground
|
|
80
|
+
headerText={props.headerText}
|
|
81
|
+
customCode={(code) =>
|
|
82
|
+
`${code}
|
|
83
|
+
import { defineComponents } from "sinho";
|
|
84
|
+
defineComponents(${props.componentName});
|
|
85
|
+
document.body.append(new ${props.componentName}());`
|
|
86
|
+
}
|
|
87
|
+
/>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/** @jsxImportSource sinho */
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Component,
|
|
5
|
+
prop,
|
|
6
|
+
Style,
|
|
7
|
+
css,
|
|
8
|
+
defineComponents,
|
|
9
|
+
useSignal,
|
|
10
|
+
useEffect,
|
|
11
|
+
MaybeSignal,
|
|
12
|
+
} from "sinho";
|
|
13
|
+
|
|
14
|
+
export class Playground extends Component("x-playground", {
|
|
15
|
+
colorMode: prop<"light" | "dark">("light", {
|
|
16
|
+
attribute: (value) => (value === "dark" ? value : "light"),
|
|
17
|
+
}),
|
|
18
|
+
headerText: prop<string>("Preview", {
|
|
19
|
+
attribute: String,
|
|
20
|
+
}),
|
|
21
|
+
importMap: prop<{ imports: Record<string, string> }>(
|
|
22
|
+
{ imports: {} },
|
|
23
|
+
{ attribute: JSON.parse },
|
|
24
|
+
),
|
|
25
|
+
customCode: prop<string>("", {
|
|
26
|
+
attribute: String,
|
|
27
|
+
}),
|
|
28
|
+
autosize: prop<boolean>(false, {
|
|
29
|
+
attribute: () => true,
|
|
30
|
+
}),
|
|
31
|
+
}) {
|
|
32
|
+
render() {
|
|
33
|
+
const [src, setSrc] = useSignal(
|
|
34
|
+
"document.body.innerHTML = '<p>LoadingâĻ</p>';",
|
|
35
|
+
);
|
|
36
|
+
const [error, setError] = useSignal<Error>();
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
setError(undefined);
|
|
40
|
+
const customCode = this.props.customCode();
|
|
41
|
+
|
|
42
|
+
(async () => {
|
|
43
|
+
try {
|
|
44
|
+
const swc = await import("@swc/wasm-web");
|
|
45
|
+
await swc.default();
|
|
46
|
+
|
|
47
|
+
const { code } = swc.transformSync(customCode, {
|
|
48
|
+
jsc: {
|
|
49
|
+
target: "es2022",
|
|
50
|
+
parser: {
|
|
51
|
+
syntax: "typescript",
|
|
52
|
+
tsx: true,
|
|
53
|
+
},
|
|
54
|
+
transform: {
|
|
55
|
+
react: {
|
|
56
|
+
runtime: "automatic",
|
|
57
|
+
importSource: "sinho",
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
setSrc(code);
|
|
64
|
+
} catch (err) {
|
|
65
|
+
setError(new Error((err as string).replace(/\x1B\[.*?m/g, "")));
|
|
66
|
+
}
|
|
67
|
+
})();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const iframeCss = css`
|
|
71
|
+
@import url("https://rsms.me/inter/inter.css");
|
|
72
|
+
|
|
73
|
+
body {
|
|
74
|
+
background: ${() =>
|
|
75
|
+
this.props.colorMode() == "light" ? "#f6f8fa" : "#282a36"};
|
|
76
|
+
color: ${() =>
|
|
77
|
+
this.props.colorMode() == "light" ? "#1c1e21" : "#e3e3e3"};
|
|
78
|
+
font-family: "Inter", sans-serif;
|
|
79
|
+
margin: 0;
|
|
80
|
+
padding: 0.5em 1em;
|
|
81
|
+
overflow: ${() => (this.props.autosize() ? "hidden" : "auto")};
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
const jsBlob = () =>
|
|
86
|
+
new Blob(
|
|
87
|
+
[
|
|
88
|
+
error() == null
|
|
89
|
+
? src()
|
|
90
|
+
: `\
|
|
91
|
+
document.body.innerHTML = '<p>Error loading preview:</p><pre id="error"></pre>';
|
|
92
|
+
document.getElementById("error").innerText = ${JSON.stringify(
|
|
93
|
+
error()!.message,
|
|
94
|
+
)};`,
|
|
95
|
+
],
|
|
96
|
+
{ type: "application/javascript" },
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const htmlBlob = () =>
|
|
100
|
+
new Blob(
|
|
101
|
+
[
|
|
102
|
+
`<!DOCTYPE html>
|
|
103
|
+
<html>
|
|
104
|
+
<head>
|
|
105
|
+
<base href="${location.href}" />
|
|
106
|
+
<script type="importmap">${JSON.stringify(this.props.importMap())}</script>
|
|
107
|
+
<style>${MaybeSignal.get(iframeCss)}</style>
|
|
108
|
+
<script type="module" src="${URL.createObjectURL(jsBlob())}"></script>
|
|
109
|
+
</head>
|
|
110
|
+
<body>
|
|
111
|
+
</body>
|
|
112
|
+
</html>`,
|
|
113
|
+
],
|
|
114
|
+
{ type: "text/html" },
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<>
|
|
119
|
+
<div class="header">{this.props.headerText}</div>
|
|
120
|
+
|
|
121
|
+
<iframe
|
|
122
|
+
src={() => URL.createObjectURL(htmlBlob())}
|
|
123
|
+
onload={(evt) => {
|
|
124
|
+
if (!this.props.autosize()) return;
|
|
125
|
+
|
|
126
|
+
const bodySize =
|
|
127
|
+
evt.currentTarget.contentWindow!.document.body.getBoundingClientRect();
|
|
128
|
+
|
|
129
|
+
evt.currentTarget.height = bodySize.height.toString();
|
|
130
|
+
}}
|
|
131
|
+
/>
|
|
132
|
+
|
|
133
|
+
<Style>{css`
|
|
134
|
+
:host {
|
|
135
|
+
display: flex;
|
|
136
|
+
flex-direction: column;
|
|
137
|
+
position: relative;
|
|
138
|
+
margin-bottom: var(--ifm-leading);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.header {
|
|
142
|
+
border-bottom: 1px solid var(--ifm-color-emphasis-300);
|
|
143
|
+
font-size: var(--ifm-code-font-size);
|
|
144
|
+
font-weight: 500;
|
|
145
|
+
padding: 0.75rem var(--ifm-pre-padding);
|
|
146
|
+
border-top-left-radius: var(--ifm-code-border-radius);
|
|
147
|
+
border-top-right-radius: var(--ifm-code-border-radius);
|
|
148
|
+
background: ${() =>
|
|
149
|
+
this.props.colorMode() == "light" ? "#f6f8fa" : "#282a36"};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
iframe {
|
|
153
|
+
flex: ${this.props.autosize() ? "auto" : "1"};
|
|
154
|
+
display: block;
|
|
155
|
+
border: none;
|
|
156
|
+
width: 100%;
|
|
157
|
+
}
|
|
158
|
+
`}</Style>
|
|
159
|
+
</>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
defineComponents(Playground);
|
|
166
|
+
} catch (err) {
|
|
167
|
+
console.error(err);
|
|
168
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Any CSS included here will be global. The classic template
|
|
3
|
+
* bundles Infima by default. Infima is a CSS framework designed to
|
|
4
|
+
* work well for content-centric websites.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/* You can override the default Infima variables here. */
|
|
8
|
+
:root {
|
|
9
|
+
--ifm-font-family-base: Inter, sans-serif;
|
|
10
|
+
font-feature-settings:
|
|
11
|
+
"liga" 1,
|
|
12
|
+
"calt" 1; /* fix for Chrome */
|
|
13
|
+
|
|
14
|
+
--ifm-color-primary-darkest: #93160f;
|
|
15
|
+
--ifm-color-primary-darker: #c2221a;
|
|
16
|
+
--ifm-color-primary-dark: #e24627;
|
|
17
|
+
--ifm-color-primary: #f06533;
|
|
18
|
+
--ifm-color-primary-light: #ef9540;
|
|
19
|
+
--ifm-color-primary-lighter: #ffb655;
|
|
20
|
+
--ifm-color-primary-lightest: #ffcf6f;
|
|
21
|
+
--ifm-code-font-size: 90%;
|
|
22
|
+
--docusaurus-highlighted-code-line-bg: rgba(255, 207, 111, 0.2);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* For readability concerns, you should choose a lighter palette in dark mode. */
|
|
26
|
+
[data-theme="dark"] {
|
|
27
|
+
--docusaurus-highlighted-code-line-bg: rgba(255, 207, 111, 0.1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
h1,
|
|
31
|
+
h2,
|
|
32
|
+
h3,
|
|
33
|
+
h4,
|
|
34
|
+
h5,
|
|
35
|
+
h6 {
|
|
36
|
+
letter-spacing: -0.02em;
|
|
37
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS files with the .module.css suffix will be treated as CSS modules
|
|
3
|
+
* and scoped locally.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
.heroBanner {
|
|
7
|
+
padding: 4rem 0;
|
|
8
|
+
text-align: center;
|
|
9
|
+
position: relative;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@media screen and (max-width: 996px) {
|
|
14
|
+
.heroBanner {
|
|
15
|
+
padding: 2rem;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.buttons {
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
gap: .7em;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
main {
|
|
27
|
+
margin: 1.5em auto;
|
|
28
|
+
display: inline-block;
|
|
29
|
+
max-width: 100%;
|
|
30
|
+
padding: 0 var(--ifm-spacing-horizontal);
|
|
31
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import clsx from "clsx";
|
|
2
|
+
import Link from "@docusaurus/Link";
|
|
3
|
+
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
|
4
|
+
import Layout from "@theme/Layout";
|
|
5
|
+
import Heading from "@theme/Heading";
|
|
6
|
+
|
|
7
|
+
import { CodeSnippetComponentPlayground } from "../components/playground";
|
|
8
|
+
import styles from "./index.module.css";
|
|
9
|
+
import CodeBlock from "@theme/CodeBlock";
|
|
10
|
+
|
|
11
|
+
function HomepageHeader() {
|
|
12
|
+
const { siteConfig } = useDocusaurusContext();
|
|
13
|
+
return (
|
|
14
|
+
<header className={clsx("hero", styles.heroBanner)}>
|
|
15
|
+
<div className="container">
|
|
16
|
+
<Heading as="h1" className="hero__title">
|
|
17
|
+
{siteConfig.title}
|
|
18
|
+
</Heading>
|
|
19
|
+
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
|
20
|
+
<div className={styles.buttons}>
|
|
21
|
+
<Link
|
|
22
|
+
className="button button--primary button--lg"
|
|
23
|
+
to="/docs/installation"
|
|
24
|
+
>
|
|
25
|
+
Documentation
|
|
26
|
+
</Link>
|
|
27
|
+
<Link className="button button--secondary button--lg" to="/api">
|
|
28
|
+
API
|
|
29
|
+
</Link>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</header>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default function Home(): JSX.Element {
|
|
37
|
+
return (
|
|
38
|
+
<Layout description="A lightweight signal-based library for building web components with a React-like API.">
|
|
39
|
+
<HomepageHeader />
|
|
40
|
+
<main>
|
|
41
|
+
<ul>
|
|
42
|
+
<li>đ Web standards with custom HTML elements</li>
|
|
43
|
+
<li>âī¸ React-like API</li>
|
|
44
|
+
<li>âī¸ Declarative templating with JSX (no additional parsing)</li>
|
|
45
|
+
<li>đĨ Fine-grained reactivity with signals</li>
|
|
46
|
+
<li>đ Type-safe components out of the box with TypeScript</li>
|
|
47
|
+
<li>đĒļ Lightweight (~4KB minified and compressed)</li>
|
|
48
|
+
</ul>
|
|
49
|
+
|
|
50
|
+
<CodeBlock language="tsx">{`\
|
|
51
|
+
import { Component, useSignal } from "sinho";
|
|
52
|
+
|
|
53
|
+
class Counter extends Component("x-counter") {
|
|
54
|
+
render() {
|
|
55
|
+
const [value, setValue] = useSignal(0);
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<>
|
|
59
|
+
<p>Counter: {value}</p>
|
|
60
|
+
<p>
|
|
61
|
+
<button onclick={() => setValue((n) => n + 1)}>Increment</button>{" "}
|
|
62
|
+
<button onclick={() => setValue((n) => n - 1)}>Decrement</button>
|
|
63
|
+
</p>
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}`}</CodeBlock>
|
|
68
|
+
|
|
69
|
+
<CodeSnippetComponentPlayground componentName="Counter" />
|
|
70
|
+
</main>
|
|
71
|
+
</Layout>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import Layout from "@theme/Layout";
|
|
2
|
+
import { Playground } from "../components/playground";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import BrowserOnly from "@docusaurus/BrowserOnly";
|
|
5
|
+
|
|
6
|
+
export default function PlaygroundPage() {
|
|
7
|
+
const [src, setSrc] = useState(`\
|
|
8
|
+
import { Component, useSignal, defineComponents } from "sinho";
|
|
9
|
+
|
|
10
|
+
class Counter extends Component("x-counter") {
|
|
11
|
+
render() {
|
|
12
|
+
const [value, setValue] = useSignal(0);
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
<p>Counter: {value}</p>
|
|
17
|
+
<p>
|
|
18
|
+
<button onclick={() => setValue((n) => n + 1)}>Increment</button>{" "}
|
|
19
|
+
<button onclick={() => setValue((n) => n - 1)}>Decrement</button>
|
|
20
|
+
</p>
|
|
21
|
+
</>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
defineComponents(Counter);
|
|
27
|
+
document.body.append(new Counter());`);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<Layout
|
|
31
|
+
title="Playground"
|
|
32
|
+
description="A lightweight signal-based library for building web components with a React-like API."
|
|
33
|
+
noFooter
|
|
34
|
+
>
|
|
35
|
+
<div
|
|
36
|
+
style={{
|
|
37
|
+
alignSelf: "stretch",
|
|
38
|
+
flex: 1,
|
|
39
|
+
display: "flex",
|
|
40
|
+
alignItems: "stretch",
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
<BrowserOnly>
|
|
44
|
+
{() => {
|
|
45
|
+
const { MonacoEditor } =
|
|
46
|
+
require("../components/monacoEditor") as typeof import("../components/monacoEditor");
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<MonacoEditor
|
|
50
|
+
style={{ flex: 1, overflow: "hidden" }}
|
|
51
|
+
text={src}
|
|
52
|
+
onChange={(src) => setSrc(src)}
|
|
53
|
+
/>
|
|
54
|
+
);
|
|
55
|
+
}}
|
|
56
|
+
</BrowserOnly>
|
|
57
|
+
<Playground
|
|
58
|
+
style={{ flex: 1, marginBottom: 0, overflow: "hidden" }}
|
|
59
|
+
customCode={src}
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
</Layout>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
File without changes
|