Skip to content
GitHub

UI (lexigram-ui)

HTMX/htpy component library for Lexigram web applications.


lexigram-ui provides server-rendered UI primitives — components, layouts, HTMX helpers, and rendering utilities — built on htpy for plain Python templates. It ships with atoms (Button, TextInput, Badge), molecules (Card, Modal, Tabs), organisms (Form, SlideOver), and layouts, all integrated via UIModule for DI wiring and config-driven defaults.

The library ships with ShadCN-compatible CSS variable design tokens in oklch color space, a polymorphic asChild pattern for slot-based composition, and a component CLI (lexigram-ui add) for scaffolding components into your project.


Terminal window
uv add lexigram-ui
from lexigram.di.module import Module, module
from lexigram.ui.module import UIModule
from lexigram.ui.config import UIConfig
from lexigram.ui.atoms import Button
from lexigram.ui.core.base import Component, el, render_to_string
@module(imports=[UIModule.configure(UIConfig(default_theme="default"))])
class AppModule(Module):
pass
class SavePanel(Component):
def render(self) -> object:
return el(
"section",
el("h2", "Profile"),
Button("Save", hx_post="/profile/save"),
class_="bg-card text-card-foreground p-6 rounded-lg shadow-sm",
)
html = render_to_string(SavePanel())

Zero-config usage: Call UIModule.configure() with no arguments to use all defaults.

flowchart LR
    subgraph Input[Configuration Sources]
        Y[application.yaml<br/>ui: section]
        E[Environment vars<br/>LEX_UI__*]
        P[Python API<br/>UIConfig(...)]
    end
    UC[UIConfig<br/>merged + validated]
    UM[UIModule.configure]
    App[Application]

    Y --> UC
    E --> UC
    P --> UC
    UC --> UM
    UM --> App
application.yaml
ui:
default_theme: "default"
auto_escape: true
htmx_version: "2.0.4"
debug_components: false
theme: light
enable_sse: false
enable_realtime: false
Section titled “Option 2 — Profiles + Environment Variables (recommended)”
Terminal window
export LEX_UI__DEFAULT_THEME=default
export LEX_UI__DEBUG_COMPONENTS=false
export LEX_UI__THEME=dark
from lexigram.ui.module import UIModule
from lexigram.ui.config import UIConfig
UIModule.configure(
UIConfig(
default_theme="default",
theme="dark",
enable_sse=True,
)
)
FieldDefaultEnv varDescription
default_theme"default"LEX_UI__DEFAULT_THEMECSS theme name passed to shadcn_css()
auto_escapetrueLEX_UI__AUTO_ESCAPEHTML-escape user-supplied strings by default
htmx_version"2.0.4"LEX_UI__HTMX_VERSIONHTMX asset version referenced in layout helpers
debug_componentsfalseLEX_UI__DEBUG_COMPONENTSRender data-component debug attributes (dev only)
theme"light"LEX_UI__THEMEActive theme (light, dark, system)
enable_ssefalseLEX_UI__ENABLE_SSEEnable server-sent event support
enable_realtimefalseLEX_UI__ENABLE_REALTIMEEnable realtime-oriented UI features
MethodDescription
UIModule.configure(config, **kwargs)Register UIProvider with explicit UIConfig values
UIModule.stub()Default no-op module for tests
  • Core rendering primitivesComponent, Element, RawHTML, el, raw, render_to_string
  • Polymorphic asChild pattern — slot-based composition via as_child parameter on Component, Button, Link, Card
  • ShadCN design tokens — CSS variable system in oklch color space: SHADCN_DEFAULT_COLORS, SHADCN_DARK_COLORS, shadcn_css() generator, SEMANTIC_UTILITY_CLASSES
  • Theme systemshadcn_css() generates complete :root / .dark CSS blocks with overridable primary, background, foreground, radius, status colors
  • Component CLIlexigram-ui add <component> scaffolds components into your project (12 components in registry: button, card, modal, input, select, tabs, toast, tooltip, skeleton, form, badge, pagination)
  • HTMX helpershx_get, hx_post, hx_target, hx_swap, and higher-level helpers
  • Server-Sent EventsSSEMessage and SSEStream for realtime UI
  • Component library — atoms, molecules, organisms, and layouts organized by usage layer
  • Context and swap zonesUIContext, Zone, Zones, SwapMode
  • Error and response helpersvalidation_error, render_validation_errors, htmx_error_response
  • AccessibilityAriaAttrs, SkipLink, announce, ARIA role helpers
  • PerformanceRenderCache, ResponseOptimizer, MetricsCollector
  • CSP requirementsUI_CSP_REQUIREMENTS for Content Security Policy configuration
FileWhat it contains
src/lexigram/ui/module.pyUIModule.configure(), .stub()
src/lexigram/ui/config.pyUIConfig, DebounceConfig, HTMLDocumentConfig, BaseLayoutConfig, HeadConfig, FooterConfig, ToastConfig
src/lexigram/ui/core/base.pyComponent, Element, el, render_to_string
src/lexigram/ui/core/slot.pySlot — pass-through renderer for asChild pattern
src/lexigram/ui/protocols.pyRenderableProtocol
src/lexigram/ui/styles/design_tokens.pySHADCN_DEFAULT_COLORS, SHADCN_DARK_COLORS, render_css_variables(), render_utility_classes()
src/lexigram/ui/styles/theme.pyshadcn_css() — complete CSS variable generation
src/lexigram/ui/styles/tokens.pySemantic class maps (button, alert, toast, icon colors)
src/lexigram/ui/atoms/__init__.pyButton, TextInput, Badge, Icon
src/lexigram/ui/molecules/__init__.pyCard, Modal, Tabs, Toast
src/lexigram/ui/organisms/__init__.pyForm, SlideOver, Chart
src/lexigram/ui/htmx/htmx.pyhx_get, hx_post, hx_target, hx_swap
src/lexigram/ui/htmx/sse.pySSEMessage, SSEStream
src/lexigram/ui/cli/registry.pyCOMPONENT_REGISTRY, ComponentEntry — 12 registerable components
src/lexigram/ui/cli/add.pylexigram-ui add CLI command (typer)
src/lexigram/ui/constants.pyUITheme, Breakpoint, UI_CSP_REQUIREMENTS