Skip to content

HTML-First ui.* Template Tags #123

Description

@davecoates

HTML-First ui.* Template Tags (Alongside React Tags)

Summary

Introduce a HTML-first template tag namespace for Alliance UI components: ui.* (for example {% ui.button %}), while keeping existing React-backed tags ({% Button %}) unchanged.

Background

Old template used Antd and we manually applied classes to HTML to mirror Antd styles so was consistent with React components. Was fragile to changes in Antd and also required knowledge of internals (e.g. what classes to apply), and broke when styling was rewritten in v5.

We introduced @allianceplatform/ui which focused first on React components, with the idea being we could then roll out Django HTML template versions in a library to avoid the issues described above. In the meantime we introduced template tags like {% Button %} that just rendered the React version under the hood.

Why

  • Avoid unnecessary React/hydration for simple UI primitives.
  • Keep visual parity with existing Alliance UI styles.
  • Make things like HTMX integration easier
  • Better UX; no flash of content when component first renders (avoided by SSR, but SSR has it's own cost)

Proposed Public Interface

  1. Naming

    • HTML-first tags: {% ui.button %}, {% ui.button_group %}, etc.
    • Existing React tags remain as-is: {% Button %}, {% ButtonGroup %} etc.
    • Alternatives: {% ui 'button' %}, {% button %} or switch out implementation on {% Button %} (breaking change)
  2. API Compatibility

    • ui.* tags should mirror React component props/defaults where practical.
    • Invalid enum props should warn and fall back (not hard-fail templates).
  3. Runtime Behavior

    • Default is static HTML output.
    • For components needing JS behavior, use a small attach runtime pattern:
      • render data-djid or similar on container
      • inject <script type="module"> and call attach(element)
  4. Assets

    • CSS and runtime resources are discoverable through existing bundler/resource mechanisms. Shipped bundle only includes styles used.
  5. Exstensible

    • Provide necessary primitives to make it easy for projects to provide own component tags

Scope

Initial scope would be those that lend themselves to no/low JS: buttons, tables, tabs etc. menubar has slightly higher JS requirement but a bigger payoff given it's used on every page for navigation, so would be part of initial scope.

HTMX

No immediate plans to adopt this, but this change would also enable server-rendered components to work naturally in HTMX flows without React boundaries.

e.g.: ui.table can support pagination/filter updates via hx-get/hx-swap while preserving Alliance UI styling

(this is me assuming a few things based on my understanding without having used HTMX)

Examples

{% load alliance_platform.ui %}

{% ui.button type="submit" variant="solid" color="primary" %}
    Save changes
{% endui.button %}
{% load alliance_platform.ui %}

{% ui.button_group variant="outlined" size="sm" density="compact" %}
    {% ui.button %}Day{% endui.button %}
    {% ui.button %}Week{% endui.button %}
    {% ui.button %}Month{% endui.button %}
{% endui.button_group %}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions