feat: code-block component & sample code
This commit is contained in:
parent
d12f6a5aa6
commit
9225fa662e
7 changed files with 80 additions and 9 deletions
3
public/prism.css
Normal file
3
public/prism.css
Normal 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
5
public/prism.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -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:", ""))
|
||||
|
|
20
src/components/code-block.js
Normal file
20
src/components/code-block.js
Normal 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;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
class HelloWorld extends WebComponent {
|
||||
name = "";
|
||||
static properties = ["name"];
|
||||
|
||||
onInit() {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue