Alt text for second image (code listings) is here due to arbitrary character limit on alt text in Mastodon:
Source code for the only two files in the project that created the example:
index.page.md:
---
title: An interactive markdown page
imports:
- import Reaction from './Reaction.fragment.js'
script: |
// Initialise database if necessary.
if (kitten.db.reactions === undefined) { kitten.db.reactions = {} }
if (kitten.db.reactions.Heart === undefined) { kitten.db.reactions.Heart = 0 }
if (kitten.db.reactions.Confetti === undefined) { kitten.db.reactions.Confetti = 0 }
if (kitten.db.reactions.Smiley === undefined) { kitten.db.reactions.Smiley = 0 }
let page
export function onConnect (data) {
page = data.page
}
export function onReaction (data) {
kitten.db.reactions[data.type]++
page.send(kitten.html`<${Reaction} />`)
}
---
<page css>
# Hello!
While this is a __markdown__ page, I can easily layer interactivity by adding a simple component in a script block.
## Reactions{id=your-reactions}
<${Reaction} />
Reaction.fragment.js:
/**
Simple Reactions control.
Broadcasts «reaction» event.
*/
function Button ({ Icon }) {
const iconName = Icon.name
return kitten.html`
<div class='reaction'>
<button
name='reaction'
data='type:"${iconName}"'
connect
>
<${Icon} weight=duotone alt=${Icon.name} colour=deeppink><title>${Icon.name}</title></>
</button>
${kitten.db.reactions[iconName]}
</div>
`
}
export default function Reactions () {
return kitten.html`
<div id='reactions' morph>
<${Button} Icon=${kitten.icons.h.Heart} />
<${Button} Icon=${kitten.icons.c.Confetti} />
<${Button} Icon=${kitten.icons.s.Smiley} />
<style>
button { background: var(--background-alt); }
button:hover { background: var(--background); }
#reactions { display: flex; }
.reaction { display: flex; flex-direction: column; align-items: center; font-size: 2em;}
</style>
</div>
`
}