No description
Find a file
2025-08-06 22:10:16 -04:00
_new Changes 2025-08-06 22:10:16 -04:00
src Changes 2025-08-06 22:10:16 -04:00
.gitignore Added State Management 2025-07-07 12:52:52 -04:00
README.md Update README.md 2025-06-16 21:18:43 -04:00
web.nimble Changes 2025-08-06 22:10:16 -04:00

web

Macro-based HTML & CSS generation system for Nim — powering the Thing framework.


Overview

web provides a macro-driven approach to building full web UIs directly in Nim using declarative, type-safe HTML and CSS generation. It integrates directly into the Thing framework.


Key Principles

  • Component-driven architecture
  • Inline styles preferred — automatically compiled to isolated CSS classes at build time
  • Avoids decoupled global CSS — style remains directly tied to component state
  • Class-based styling supported but discouraged
  • Designed to integrate directly into Things reactive full-stack system

Reactive Engine

For full reactive state management, diffing, and lifecycle control, see: Thing framework.

  • React-style useState, useEffect, useMemo, etc.
  • Deterministic DOM diffing and reconciliation
  • Fully compile-time validated state and props
  • Deep integration with Thing's declarative dataflow system

Dependencies

  • css: Compile-time and runtime CSS validation
  • html: MDN-typed HTML elements

Core Usage

HTML Generation

import web

let someText = "Dynamic content"

let html = web:
  p "Simple text"
  
  p:
    "Multiple lines"
    someText
    
  p:
    "With attributes"
    id "main-paragraph"
    class "highlight"

Styling

By default, inline styles are compiled into generated CSS classes automatically:

web:
  p "Validated styling":
    style:
      color: red
      fontSize: 16.px
      margin: {8.px, 16.px}

Dynamic values

var textDecorationValue = "underline"

web:
  p "Dynamic style":
    style:
      textDecoration: `textDecorationValue`

External style objects

var styles = newStyles()
styles.color = "red"
styles.marginBlock = {1.px, 2.px}

web:
  box:
    style styles

Selectors

web:
  p "Interactive element":
    class textElement
    style:
      !textElement:
        color: blue
      !textElement[hover]:
        color: darkBlue
      [root]:
        backgroundColor: white
  • ! = class selector
  • [state] = pseudo-classes

Components

Basic Components

proc Card(title: string, content: string): HTML =
  return web:
    box:
      class "card"
      h2: title
      p: content

web:
  Card:
    title "Hello"
    content "This is a card"

Components with Children

proc Container(children: HTML): HTML =
  return web:
    box:
      class "container"
      children

web:
  Container:
    children:
      h1 "Title"
      p "Body"

Attribute & Style Passthrough

web:
  Card:
    title "Hello"
    `id` "custom-card"
    `style`:
      backgroundColor: blue

Component Name Conflicts

proc p(content: string): HTML =
  return web:
    box: content

web:
  `p`:
    content "Custom paragraph"

Types

type HTMLNodeKind* = enum
  htmlnkElement
  htmlnkText

type HTMLNode* = object
  elementId*: string
  case kind*: HTMLNodeKind
  of htmlnkElement:
    tag*: string
    attributes*: Table[string, string]
    children*: seq[HTMLNode]
  of htmlnkText:
    text*: string

type HTML* = seq[HTMLNode]

Framework Integration

The web package is built specifically for use inside the Thing framework.

  • Style and component state remain tightly coupled.
  • Inline styles automatically generate scoped CSS classes — no manual class management required.
  • Global class usage is supported for external libraries but generally discouraged inside Thing projects.
  • Fully reactive state layer, lifecycle management, and DOM diffing handled by Thing core.

web is a first-class HTML/CSS generation layer fully integrated into Things self-hosted full-stack system.