Skip to content

Commit

Permalink
tabbed codeblocks
Browse files Browse the repository at this point in the history
  • Loading branch information
velzie committed May 1, 2024
1 parent 2197405 commit a38f6b2
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 24 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"astro-icon": "^1.1.0",
"browserslist": "^4.23.0",
"lightningcss": "^1.24.0",
"linkedom": "^0.16.11",
"rehype-autolink-headings": "^7.1.0",
"typescript": "^5.4.2"
},
Expand Down
93 changes: 93 additions & 0 deletions src/components/Code.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
const { js, jsx, tsx } = Astro.props;
import { parseHTML } from 'linkedom'
import { Icon } from "astro-icon/components";
const html = await Astro.slots.render("default");
const {document} = parseHTML(html);
const children = document.children;
const nameid = ''+Math.random();
---

<div class="codetab">

<div>
{
[...children].map((child) =>{
let lang = child.attributes.getNamedItem("data-language")?.value!;

let uid = Math.random()
return (
<>
<input type="radio" name={"tabset"+nameid} id={lang+uid} checked={lang == "js"}>
<label for={lang+uid}>
<Icon size={30} name="mdi:react" />
{lang?.toUpperCase()}
</label>
</>
)
})
}

<div class="tabs">
{
[...children].map((child) => {
return <>
<div class="tab-panel">
<div class="code-wrapper" set:html={child.outerHTML} />
</div>
</>
})
}
</div>
</div>

<style>
.codetab {
.tab-panel {
display: none;
}

input:first-child:checked ~ .tabs > .tab-panel:first-child,
input:nth-child(3):checked ~ .tabs > .tab-panel:nth-child(2),
input:nth-child(5):checked ~ .tabs > .tab-panel:nth-child(3) {
display: block;
}

input {
position: absolute;
left: -200vw;
}


label {
background-color: #201d20;
user-select: none;
display: inline-flex;
justify-content: center;
align-items: center;
margin: 0;
padding: 0.25em;
font-family: monospace;
}

input:checked + label {
color: var(--acc);
}


label {
border-top-right-radius: 0.5rem;
border-top-left-radius: 0.5rem;
}
}
</style>
<style is:global>
.code-wrapper > .astro-code {
margin: 0;
border-top-left-radius: 0;
}
</style>
</div>
1 change: 1 addition & 0 deletions src/layouts/Document.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Sidebar from "components/Sidebar.astro";
const { headings } = Astro.props;
const title = headings ? headings[0].text + " | dreamland.js" : "404 | dreamland.js";
---

<Base title={title}>
Expand Down
3 changes: 2 additions & 1 deletion src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Code } from "astro:components";
<div id="wrapper">
<div class="split">
<div class="code">

<Code
code={`function Counter(){
this.css = \`
Expand Down Expand Up @@ -64,7 +65,7 @@ document.body.appendChild(root);
>.
</p>
<div class="code">
<Code code={`<script src="https://unpkg.com/dreamland"></script>`} lang="html" />
<Code code={`<script src="https://unpkg.com/dreamland"></script>`} lang="html" theme="min-dark" />
</div>

<p>
Expand Down
43 changes: 20 additions & 23 deletions src/pages/learn/introduction/basic-html.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,23 @@ layout: layouts/Document.astro
order: 1
---

import Code from "../../../components/Code.astro"

# Basic HTML

> ### Note
>
> For the purposes of easy documentation, all examples will be written with JSX syntax, which is not supported in the JavaScript standard and must be used with a preprocessor such as tsc, esbuild, Babel, etc. This is entirely optional, and the `html` tag function is provided to allow for use without a preprocessor:
>
> ```js
> return (
> html`<button on:click=${() => this.counter++}>I have been clicked ${use(this.counter)} times!</button>`;
> )
> ```
>
> Whereas the equivalent JSX would look like
>
> ```jsx
> return (
> <button on:click={() => this.counter++}>I have been clicked {use(this.counter)} times!</button>;
> );
> ```
>
> Which one you choose to use comes down to personal preference, but remember that all examples shown with JSX work in plain JavaScript.
In dreamland, everything is an HTML element. We try to abstract the DOM, but never replace it.
Let's create an HTML element right now.

In dreamland, everything is an HTML element. Unlike other frameworks, we don't abstract away the DOM, only make it easier to use. Let's create an HTML element right now.

<Code>
```js
let button = html`<button class="some-button">content here!</button>`;
document.body.appendChild(button);
```
```jsx
let button = <button class="some-button">content here!</button>;
document.body.appendChild(button);
```
</Code>

We just created a button, with the class "some-button", and added it to the document. This is the simplest possible way of using dreamland, and is why it's so easy to slowly transition to using it from a plain-js codebase.

Expand All @@ -42,10 +29,20 @@ We just created a button, with the class "some-button", and added it to the docu

What if we wanted to do something when the button is clicked? For any DOM event, you can use `on:` handlers.


<Code>
```js
let button = (
html`<button class="some-button" on:click=${() => alert("button clicked!")}>
click me!
</button>`
);
```
```jsx
let button = (
<button class="some-button" on:click={() => alert("button clicked!")}>
click me!
</button>
);
```
</Code>

0 comments on commit a38f6b2

Please sign in to comment.