on master help sign in
Sync playground default with updated demo showcase
commitf851c721ae93512f9162120b25df3209fd101da8 authoriko <mail@iko.soy> dateThu 16 Apr 2026, 12:00 (6 months ago) parent70ddab0
1 file changed+313−151
src/playground_default.hl+313−151
src/playground_default.hl+313−151
@@ -1,168 +1,330 @@
1−@page htmlang Showcase
1+-- A comprehensive tour of htmlang: layout, style, components, and control flow.
2+@page htmlang Demo
23@lang en
4+@meta description A one-page tour of htmlang.
5+@og title htmlang
6+@og type website
37
4−-- Design tokens
5−@let primary #3b82f6
6−@let accent #ec4899
7−@let ink #0f172a
8−@let muted #64748b
9−@let surface white
10−@let bg #f8fafc
11−@let radius 10
8+-- Design tokens become both $vars and CSS custom properties
9+@theme
10+ primary #3b82f6
11+ ink #0f172a
12+ muted #64748b
13+ subtle #f8fafc
14+
15+-- Computed @let with arithmetic
1216@let base 8
1317@let gap = $base * 2
18+@let gutter = $gap + $base
1419
15−-- Style presets
20+-- Reusable attribute bundle
1621@define card [
17− padding 24, background $surface, rounded $radius,
18− border 1 #e2e8f0,
19− dark:background #1e293b, dark:border 1 #334155
22+ padding $gap,
23+ background white,
24+ rounded $base,
25+ border 1 #e5e7eb,
26+ shadow 0 1px 3px rgba(0,0,0,0.05)
2027]
2128
22−@mixin lift [
23− transition all 0.2s ease,
24− hover:shadow 0 12px 24px rgba(0,0,0,0.08)
29+-- Composable style group (used with spread)
30+@mixin interactive [
31+ cursor pointer,
32+ hover:shadow 0 4px 12px rgba(0,0,0,0.08),
33+ transition all 0.2s ease
2534]
2635
27−-- Components (functions with parameters, defaults, and slots)
28−@fn button $label $variant=primary
29− @el [
30− padding 10 20, rounded 8, cursor pointer, bold,
31− background if($variant == primary, $primary, transparent),
32− color if($variant == primary, white, $primary),
33− border 1 $primary, transition all 0.15s ease,
34− hover:opacity 0.9, active:opacity 0.8
35− ]
36+-- Keyframes using attribute syntax
37+@keyframes fade-up
38+ from [opacity 0, transform translateY(8px)]
39+ to [opacity 1, transform translateY(0)]
40+
41+-- Raw HTML escape hatch
42+@raw """
43+<noscript><style>.needs-js{display:none}</style></noscript>
44+"""
45+
46+-- Component with default parameter + @children slot
47+@fn card $title $icon=◆
48+ @article [$card, ...$interactive, animate fade-up 0.3s ease]
49+ @row [spacing 10, align-items center]
50+ @text [size 20, color $primary] $icon
51+ @text [bold, size 16, color $ink] $title
52+ @children
53+
54+-- Component that wraps children in a titled section (function + slot)
55+@fn titled $title
56+ @section [spacing 12, padding-y $base]
57+ @text [bold, size 22, color $ink] $title
58+ @children
59+
60+-- Top-level layout
61+@column [
62+ max-width 960,
63+ center-x,
64+ padding 32,
65+ spacing $gutter,
66+ background white,
67+ dark:background #0b1220,
68+ dark:color #e2e8f0
69+]
70+
71+ -- Header: nav + hero
72+ @header [spacing $base]
73+ @nav [spacing 6, color $muted, size 13]
74+ @row [spacing 6, align-items center]
75+ @link [color $muted] / Home
76+ @text /
77+ @link [color $muted] /demos Demos
78+ @text /
79+ @text [color $ink] htmlang
80+
81+ @row [spacing $gap, align-items center]
82+ @column [width fill, spacing 6]
83+ @text [bold, size 40, color $ink, dark:color white] Welcome to htmlang
84+ @paragraph [line-height 1.6, color $muted]
85+ A minimalist layout language that compiles to
86+ {@text [bold, color $primary] static HTML} — no JS, no build step.
87+ Visit the {@link [color $primary, underline] https://github.com repo} for more.
88+ @image [width 72, height 72, rounded 36, alt "Avatar"] https://picsum.photos/72
89+
90+ @hr [border-top 1 #e5e7eb]
91+
92+ -- Feature grid using @card + @titled components
93+ @titled [title Features]
94+ @row [wrap, gap $base]
95+ @card [title Simple, icon ✦]
96+ Write layouts without CSS classes.
97+ @card [title Fast, icon ⚡]
98+ Compiles to a single self-contained HTML file.
99+ @card [title Minimal, icon ○]
100+ Zero runtime JavaScript by default.
101+ @card [title Typed]
102+ LSP with diagnostics and go-to-definition.
103+
104+ -- Typography showcase: inline elements, blockquote, code
105+ @titled [title Typography]
106+ @paragraph [line-height 1.7]
107+ A quick brown fox jumps over {@text [bold] the lazy} {@text [italic] dog}.
108+ Press {@kbd [
109+ padding 2 6, background #f1f5f9, rounded 4,
110+ font monospace, size 13
111+ ] Ctrl+K} to search. {@mark [background #fef08a] Highlighted} uses mark.
112+ {@abbr [title HyperText Markup Language + language] htmlang} is an abbreviation.
113+
114+ @blockquote [
115+ padding-inline-start $gap, border-left 3 $primary,
116+ color $muted, italic
117+ ]
118+ Layout is code. Style is code. Everything should compose.
119+ @cite — Anonymous
120+
121+ @pre [
122+ background #0f172a, color #e2e8f0,
123+ padding 16, rounded 8, font monospace, size 13,
124+ overflow-x auto
125+ ]
126+ @raw """
127+@fn button $label
128+ @el [padding 12, background blue]
36129 @text $label
130+"""
37131
38−@fn feature $title $emoji
39− @el [$card, ...$lift, spacing 10]
40− @text [size 32] $emoji
41− @text [bold, size 18, color $ink, dark:color #f1f5f9] $title
42− @paragraph [color $muted, line-height 1.6]
43− @children
44−
45−@fn stat $value $label
46− @column [spacing 4, text-align center, padding 12]
47− @text [bold, size 40, color $primary] $value
48− @text [color $muted, size 12, text-transform uppercase, letter-spacing 2] $label
49−
50−-- Page
51−@column [background $bg, dark:background #0f172a, min-height 100vh]
52−
53− -- Header
54− @header [
55− padding 16 32, background $surface, dark:background #1e293b,
56− border-bottom 1 #e2e8f0, dark:border-bottom 1 #334155
57− ]
58− @row [center-y, max-width 1100, center-x, width 100%]
59− @text [bold, size 18, color $ink, dark:color #f1f5f9] htmlang
60− @el [width fill]
61− @row [spacing 24]
62− @link [color $muted, hover:color $primary] #docs Docs
63− @link [color $muted, hover:color $primary] #blog Blog
64− @link [color $muted, hover:color $primary] #github GitHub
132+ -- Control flow: @each, @else, @repeat, @for, @match, if()
133+ @titled [title Control flow]
134+ @column [spacing 6]
135+ @each $name, $role in Alice Engineer, Bob Designer, Carol PM
136+ @row [spacing 10, align-items baseline]
137+ @text [bold, min-width 80] $name
138+ @text [color $muted] $role
139+
140+ -- @each ... @else fallback for empty list
141+ @let nothing ""
142+ @each $x in $nothing
143+ @text $x
144+ @else
145+ @text [color $muted, italic, data-state $nothing] (Nothing — @each ... @else fallback)
146+
147+ -- @repeat
148+ @row [spacing 6]
149+ @repeat 6
150+ @el [width 18, height 18, rounded 9, background $primary, opacity 0.4]
151+
152+ -- @for range
153+ @row [spacing 4]
154+ @for $i in 1..6
155+ @el [
156+ width 24, height 24, rounded 4,
157+ background $primary, color white,
158+ text-align center, size 12, bold, line-height 24
159+ ]
160+ $i
65161
66− -- Hero
67− @section [padding 80 32, max-width 900, center-x, text-align center, spacing 20]
162+ -- @if / @else if / @else (with @assert to verify at compile time)
163+ @let count 3
164+ @assert $count == 3
165+ @row [spacing 6, align-items center]
166+ @text [bold, min-width 64] Count:
167+ @if $count == 0
168+ @text [color $muted] Empty
169+ @else if $count == 1
170+ @text [color $primary] Exactly one
171+ @else
172+ @text [color $primary, bold] $count items
173+
174+ -- @match
175+ @let status ready
176+ @match $status
177+ @case pending
178+ @text [color #f59e0b] Pending…
179+ @case ready
180+ @text [color #10b981, bold] ✓ Ready
181+ @case error
182+ @text [color #ef4444] Error
183+ @default
184+ @text Unknown
185+
186+ -- Conditional attribute value + before: pseudo-element
187+ @let emphasized true
68188 @el [
69− padding 6 14, rounded 999,
70− background $primary|alpha:0.12, color $primary,
71− bold, size 12, text-transform uppercase, letter-spacing 2,
72− before:content "* "
189+ padding 12, rounded 6,
190+ background if($emphasized, $primary, #e5e7eb),
191+ color if($emphasized, white, $ink),
192+ before:content "→ ", before:bold
73193 ]
74− Built with htmlang
75− @text [bold, size 56, color $ink, dark:color #f1f5f9, line-height 1.1]
76− Layouts that just {@text [italic, color $primary] make sense}.
77− @paragraph [max-width 600, center-x, color $muted, line-height 1.7, size 18]
78− A minimalist DSL that compiles to a single static HTML file.
79− No cascade, no JavaScript, no build chain.
80− @row [center-x, spacing 12, wrap]
81− @button [label Get Started]
82− @button [label Star on GitHub, variant ghost]
83−
84− -- Stats (each iteration could go here too)
85− @section [padding 24 32, max-width 800, center-x]
86− @row [wrap, center-x, spacing 20]
87− @stat [value 0kb, label JavaScript]
88− @stat [value 1, label HTML File]
89− @stat [value 100%, label Static]
90−
91− -- Features (grid layout)
92− @section [padding 64 32, max-width 1100, center-x, spacing 24]
93− @column [spacing 8, text-align center]
94− @text [bold, size 32, color $ink, dark:color #f1f5f9] Why htmlang?
95− @text [color $muted] Primitives over CSS quirks.
96−
97− @el [grid, grid-cols 3, gap $gap]
98− @feature [title Composable, emoji X]
99− Functions, mixins, and slots make components first-class.
100− @feature [title Predictable, emoji Y]
101− Flex-based layout - no cascade, no surprises.
102− @feature [title Static, emoji Z]
103− One file out. Deploy anywhere. Loads instantly.
104−
105− -- Quote (semantic blockquote + cite)
106− @section [padding 32, max-width 720, center-x]
107− @blockquote [
108− padding 24 32, background $surface, dark:background #1e293b,
109− border-left 4 $primary, rounded $radius, italic,
110− color $ink, dark:color #f1f5f9, line-height 1.7, size 18
194+ Conditional styling via {@code if(cond, a, b)}.
195+
196+ -- Forms + pseudo-states
197+ @titled [title Forms]
198+ @form [spacing 10, max-width 420] /subscribe
199+ @label [bold, size 13, for email] Email
200+ @input [
201+ id email, type email, name email,
202+ placeholder you@example.com, required,
203+ padding 10, border 1 #e5e7eb, rounded 6,
204+ focus:border 1 $primary,
205+ valid:border 1 #10b981,
206+ invalid:border 1 #ef4444,
207+ transition border 0.15s ease
208+ ]
209+ @label [bold, size 13, for role] Role
210+ @select [id role, name role, padding 10, border 1 #e5e7eb, rounded 6]
211+ @option [value dev] Developer
212+ @option [value designer] Designer
213+ @option [value other] Other
214+ @label [bold, size 13, for msg] Message
215+ @textarea [
216+ id msg, name msg, rows 3,
217+ padding 10, border 1 #e5e7eb, rounded 6
218+ ]
219+ @row [spacing 8]
220+ @button [
221+ type submit,
222+ padding 10 16, background $primary, color white, bold,
223+ rounded 6, border 0,
224+ hover:background $primary|darken:10,
225+ active:background $primary|darken:20,
226+ transition background 0.15s ease,
227+ cursor pointer
228+ ] Subscribe
229+ @button [
230+ type reset,
231+ padding 10 16, background white,
232+ border 1 #e5e7eb, rounded 6, cursor pointer
233+ ] Reset
234+ @progress [value 60, max 100]
235+
236+ -- Lists and tables
237+ @titled [title Data]
238+ @row [gap $gap, wrap]
239+ @column [width fill, spacing $base, min-width 240]
240+ @text [bold] Unordered
241+ @list [spacing 4, list-style disc, padding-inline-start 20]
242+ @item [display list-item] Composable with @each
243+ @item [display list-item] Indent to nest children
244+ @item [display list-item] Bold list items work too
245+ @text [bold] Ordered
246+ @list [ordered, list-style decimal, padding-inline-start 20]
247+ @item [display list-item] First
248+ @item [display list-item] Second
249+ @item [display list-item] Third
250+
251+ @column [width fill, spacing $base, min-width 240]
252+ @text [bold] Table
253+ @table
254+ @thead
255+ @tr
256+ @th [text-align left, padding 8] Item
257+ @th [text-align right, padding 8] Qty
258+ @tbody
259+ @tr
260+ @td [padding 8, border-top 1 #e5e7eb] Widgets
261+ @td [padding 8, border-top 1 #e5e7eb, text-align right] 12
262+ @tr
263+ @td [padding 8, border-top 1 #e5e7eb] Gadgets
264+ @td [padding 8, border-top 1 #e5e7eb, text-align right] 7
265+
266+ @figure [spacing 6]
267+ @image [alt "A random placeholder", rounded 8] https://picsum.photos/640/200
268+ @figcaption [color $muted, size 13, text-align center]
269+ A placeholder image.
270+
271+ -- Disclosure + named grid areas
272+ @titled [title Disclosure + grid areas]
273+ @details [padding 12, border 1 #e5e7eb, rounded 6, background $subtle]
274+ @summary [bold, cursor pointer] What is htmlang?
275+ @paragraph [color $muted, line-height 1.6, padding-block-start 6]
276+ htmlang is a layout-first language that compiles to a single,
277+ self-contained HTML file with embedded CSS.
278+
279+ -- Implicit @el via bare [attrs] line
280+ [
281+ grid,
282+ grid-template-columns 1fr 2fr,
283+ grid-template-areas "h h" "s m" "f f",
284+ gap $base,
285+ padding $base, background $subtle, rounded 8
111286 ]
112− "I want to lay out an interface, not argue with the cascade."
113− @cite [color $muted, size 13, italic]
114− - every frontend dev, eventually
115−
116− -- Team (each + destructuring)
117− @section [padding 48 32, max-width 1100, center-x, spacing 16]
118− @text [bold, size 24, color $ink, dark:color #f1f5f9] The team
119−
120− @row [wrap, spacing 12]
121− @each $name, $role in Ada Engineer, Grace Architect, Linus Maintainer, Ken Researcher
122− @column [$card, ...$lift, spacing 6, width 200, text-align center]
123− @text [bold, color $ink, dark:color #f1f5f9] $name
124− @text [color $muted, size 13] $role
125−
126− -- FAQ (native disclosure widget + inline elements)
127− @section [padding 48 32, max-width 720, center-x, spacing 12]
128− @text [bold, size 24, color $ink, dark:color #f1f5f9] FAQ
129−
130− @details [$card]
131− @summary [bold, color $ink, dark:color #f1f5f9, cursor pointer]
132− Does it support dark mode?
133− @paragraph [color $muted, line-height 1.7]
134− Yes - prefix any style with {@code [background $bg, padding 2 6, rounded 4, color $accent] dark:} and it generates a media query.
135−
136− @details [$card]
137− @summary [bold, color $ink, dark:color #f1f5f9, cursor pointer]
138− How do reusable components work?
139− @paragraph [color $muted, line-height 1.7]
140− Use {@code [background $bg, padding 2 6, rounded 4, color $accent] @fn} for parameters and {@code [background $bg, padding 2 6, rounded 4, color $accent] @children} as a slot.
141−
142− -- Native widgets (progress + meter)
143− @section [padding 48 32, max-width 720, center-x, spacing 16]
144− @text [bold, size 24, color $ink, dark:color #f1f5f9] Native widgets
145−
146− @column [$card, spacing 16]
147− @column [spacing 6]
148− @row [center-y, spacing 12]
149− @text [color $ink, dark:color #f1f5f9] Coverage
150− @el [width fill]
151− @text [color $muted, size 13] 70%
152− @progress [value 70, max 100, width 100%]
153−
154− @column [spacing 6]
155− @text [color $ink, dark:color #f1f5f9] Battery
156− @meter [value 6, min 0, max 10, low 3, high 8, width 100%]
157−
158− -- Footer (hr divider + breadcrumb)
159− @hr [border-top 1 #e2e8f0, dark:border-top 1 #334155]
160− @footer [padding 32, max-width 1100, center-x]
161− @row [center-y, wrap, spacing 16, width 100%]
162− @text [color $muted, size 13]
163− Made with htmlang.
287+ @el [grid-area h, padding 10, background $primary, color white, rounded 6, text-align center]
288+ Header
289+ @el [grid-area s, padding 10, background white, rounded 6, border 1 #e5e7eb]
290+ Sidebar
291+ @el [grid-area m, padding 10, background white, rounded 6, border 1 #e5e7eb]
292+ Main
293+ @el [grid-area f, padding 10, background $ink, color white, rounded 6, text-align center]
294+ Footer
295+
296+ -- Misc: address, time, meter
297+ @titled [title Misc]
298+ @address [spacing 4, font-style normal]
299+ @text [bold] htmlang HQ
300+ @text 123 Flexbox Avenue
301+ @link [color $primary] mailto:hi@htmlang.dev hi@htmlang.dev
302+ @row [spacing 10, align-items center]
303+ @text [size 13, color $muted] Published
304+ @time [datetime 2026-04-16, size 13] April 16 2026
305+ @row [spacing 10, align-items center]
306+ @text [size 13, color $muted] Confidence
307+ @meter [value 8, min 0, max 10, low 3, high 7] 8/10
308+
309+ -- Footer: hover/active button, visited link, print-hidden
310+ @footer [
311+ padding-block-start $gutter, margin-block-start $gutter,
312+ border-top 1 #e5e7eb, spacing $base,
313+ print:display none
314+ ]
315+ @row [spacing $base, align-items center]
316+ @el [
317+ padding 12 20, background $primary, color white, bold, rounded 8,
318+ hover:background $primary|darken:10,
319+ active:background $primary|darken:20,
320+ transition all 0.15s ease,
321+ cursor pointer
322+ ] > @link https://github.com
323+ Get Started
324+ @link [
325+ color $primary,
326+ visited:color #8b5cf6,
327+ hover:underline
328+ ] https://github.com Browse source
164329 @el [width fill]
165− @breadcrumb [spacing 8]
166− @link [color $muted, hover:color $primary] / Home
167− @link [color $muted, hover:color $primary] /docs Docs
168− @text [color $muted, size 13] v1.0
330+ @text [color $muted, size 13] © 2026 htmlang