a reactive (signals based) hypermedia web framework (wip)
stormlightlabs.github.io/volt/
hypermedia
frontend
signals
1/**
2 * Interactivity Section
3 * Demonstrates dialogs and event-based interactions
4 */
5
6import * as dom from "../utils";
7
8export function createInteractivitySection(): HTMLElement {
9 return dom.article(
10 { id: "interactivity" },
11 dom.h2(null, "Dialogs & Interactivity"),
12 dom.section(
13 null,
14 dom.h3(null, "Native Dialog Element"),
15 dom.p(
16 null,
17 "The HTML ",
18 dom.code(null, "<dialog>"),
19 " element provides semantic modal functionality.",
20 dom.small(
21 null,
22 "Modern browsers support the dialog element natively, providing built-in accessibility features and keyboard handling (ESC to close, focus trapping, etc.).",
23 ),
24 " VoltX CSS styles it elegantly, and VoltX.js handles the interaction.",
25 ),
26 dom.button({
27 "data-volt-on-click": "$helpers.openDialog('demo-dialog'); dialogMessage.set(''); dialogInput.set('')",
28 }, "Open Dialog"),
29 dom.p({ "data-volt-if": "dialogMessage", "data-volt-text": "dialogMessage" }),
30 dom.dialog(
31 { id: "demo-dialog" },
32 dom.article(
33 null,
34 dom.header(
35 null,
36 dom.h3(null, "Dialog Demo"),
37 dom.button({ "data-volt-on-click": "$helpers.closeDialog('demo-dialog')", "aria-label": "Close" }, "×"),
38 ),
39 dom.form(
40 {
41 id: "demo-dialog-form",
42 "data-volt-on-submit":
43 "$event.preventDefault(); dialogMessage.set('You entered: ' + dialogInput); setTimeout(() => $helpers.closeDialog('demo-dialog'), 2000)",
44 },
45 ...dom.labelFor("Enter something:", {
46 type: "text",
47 id: "dialog-input",
48 "data-volt-model": "dialogInput",
49 placeholder: "Type here...",
50 required: true,
51 }),
52 ),
53 dom.footer(
54 null,
55 dom.button({ type: "button", "data-volt-on-click": "$helpers.closeDialog('demo-dialog')" }, "Cancel"),
56 dom.button({ type: "submit", form: "demo-dialog-form" }, "Submit"),
57 ),
58 ),
59 ),
60 ),
61 dom.section(
62 null,
63 dom.h3(null, "Button Interactions"),
64 dom.p(
65 null,
66 "Count: ",
67 dom.strong({ "data-volt-text": "count" }, "0"),
68 " | Doubled: ",
69 dom.strong({ "data-volt-text": "doubled" }, "0"),
70 ),
71 dom.div(
72 { style: "display: flex; gap: 0.5rem; flex-wrap: wrap;" },
73 ...dom.buttons([["Increment", "count.set(count + 1)"], ["Decrement", "count.set(count - 1)"], [
74 "Reset",
75 "count.set(0)",
76 ], ["Update Header", "message.set('Count is now ' + count)"]]),
77 ),
78 ),
79 );
80}