feat: code-block component & sample code

This commit is contained in:
Ayo 2023-10-19 15:57:39 +02:00
parent d12f6a5aa6
commit 9225fa662e
7 changed files with 80 additions and 9 deletions

3
public/prism.css Normal file
View file

@ -0,0 +1,3 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism&languages=clike+javascript */
code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}

5
public/prism.js Normal file

File diff suppressed because one or more lines are too long

View file

@ -62,6 +62,8 @@ async function insertRegistry(
key.replace(`.${type}`, "")
);
console.log(">>> availableComponents", availableComponents);
const usedCustomElements = [];
walkSync(ast, (node) => {
@ -74,6 +76,7 @@ async function insertRegistry(
// insert registry script to head
if (usedCustomElements.length > 0) {
console.log(">>> usedCustomElements", usedCustomElements);
const registryScript = await buildRegistry(usedCustomElements, type);
walkSync(ast, (node) => {
if (node.type === ELEMENT_NODE && node.name === "head") {
@ -95,7 +98,9 @@ import { WebComponent } from "https://unpkg.com/web-component-base@1.6.15/WebCom
`assets:components:${name}.${type}`
);
registryScript += content;
const evalStore = eval(`class WebComponent {};(${content.toString()})`);
const evalStore = eval(
`class WebComponent {}; class HTMLElement {}; (${content.toString()})`
);
const className = new evalStore().constructor.name;
registryScript += `customElements.define("${name}", ${className});`;
@ -224,13 +229,31 @@ async function useFragments(html: string) {
);
if (node.type === ELEMENT_NODE && !!usedFragment) {
node.children.push(parse(usedFragment.text));
const value = replaceSlots(usedFragment.text, node);
node.children.push(parse(value));
}
});
return render(ast);
}
function replaceSlots(text: string, sourceNode: UltraNode) {
const regex = /<slot \/>/g;
var match;
while ((match = regex.exec(text))) {
let [key, _value] = match;
const slotName = sourceNode.attributes.slot;
const h = sourceNode.children.find((node) => node.name === slotName);
if (h) {
text = text?.replace(key, h.value);
sourceNode.children.splice(sourceNode.children.indexOf(h), 1);
}
}
return text;
}
async function getFiles(type: string) {
return (await useStorage().getKeys("assets:components"))
.map((key) => key.replace("assets:components:", ""))

View file

@ -0,0 +1,20 @@
class CodeBlockComponent extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
let lang = this.classList.value;
lang = lang.replace("language-", "");
const trimmed = this.innerHTML.trim();
const template = `
<div>
<pre class="${this.classList}" id="pre"><code id="code">${trimmed}</code></pre>
</div>
`;
this.innerHTML = template;
}
}

View file

@ -1,5 +1,4 @@
class HelloWorld extends WebComponent {
name = "";
static properties = ["name"];
onInit() {

View file

@ -1,6 +1,9 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>McFly: Back to the Basics. Into the Future.</title>
<link rel="stylesheet" href="./reset.css"></style>
</head>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>McFly: Back to the Basics. Into the Future.</title>
<link rel="stylesheet" href="./reset.css" />
<link rel="stylesheet" href="./prism.css" />
<script src="./prism.js"></script>
<slot />
</head>

View file

@ -12,6 +12,24 @@
Here's a sample interactive custom element:
<hello-world name="McFly"></hello-world>
</p>
<code-block class="language-js line-numbers" data-line="2">
<pre>
class HelloWorld extends WebComponent {
static properties = ["name"];
onInit() {
let count = 0;
this.onclick = () => {
this.setAttribute("name", `Clicked ${++count}x`);
};
}
get template() {
return `<button style="cursor:pointer">Hello ${this.name}!</button>`;
}
}
</pre>
</code-block>
<p>
Start at the very basic of writing HTML files and enhance with standard
web technologies or go advanced as you like, at your own pace.