Skip to content

Form spark

The form spark embeds Home Assistant's <ha-form> component in a forged element. Its schema uses the standard Home Assistant form schema: each field has a unique name, optional label and default, and a Home Assistant selector.

Use the optional submit and clear buttons to run Home Assistant actions. The current form values are merged into the action's data; a form value takes precedence when it has the same key as static action data.

Buttons are optional. This allows a form spark inside a UIX Popover action to use the popover footer buttons instead. When a form spark is present in a popover card, its current values are automatically merged into the tap_action, hold_action, or double_tap_action of either footer button.

Basic usage

This blank Forge card needs no placement selector. The form spark automatically inserts itself into the blank card content.

type: custom:uix-forge
forge:
  mold: card
  sparks:
    - type: form
      density: dense
      schema:
        - name: message
          label: Message
          selector:
            text: {}
        - name: priority
          label: Priority
          default: normal
          selector:
            select:
              options:
                - normal
                - urgent
      submit:
        text: Send
        icon: mdi:send
        icon_position: end
        action:
          action: perform-action
          perform_action: script.send_message

Form spark basic example

The action receives data.message and data.priority which will be available in the script as {{ message }} and {{ priority }}. By default, submit clears the form after a valid action is dispatched.

Send values to UIX actions

Form values also flow into UIX actions used through fire-dom-event.

Event action

With action: event, the form values are appended to the custom event's detail. Static data values are retained, except that a form field with the same key wins. This example dispatches uix-form-submitted on window with source, message, and priority in its detail; a form field named source would override contact-form.

submit:
  action:
    action: fire-dom-event
    uix:
      action: event
      name: uix-form-submitted
      data:
        source: contact-form

JavaScript action

With action: javascript, the form values are appended to variables, so the code can use variables.<field-name>. Static variables are retained, except that a form field with the same key wins; a form field named source would override contact-form.

submit:
  action:
    action: fire-dom-event
    uix:
      action: javascript
      data:
        variables:
          source: contact-form
        code: >
          console.info(`Submitted: Message: ${variables.message},
          Priority: ${variables.priority} from ${variables.source}`);

Markdown card placement

For a forged Markdown card, the spark automatically places the form after the Markdown content. The equivalent explicit placement is:

after: hui-markdown-card $ ha-markdown

This is useful when you need to be explicit, or when moving the form before the content:

type: custom:uix-forge
forge:
  mold: card
  sparks:
    - type: form
      before: hui-markdown-card $ ha-markdown
      schema:
        - name: note
          selector:
            text:
              multiline: true
      submit:
        action:
          action: perform-action
          perform_action: script.save_note
element:
  type: markdown
  content: "## Add a note"

Form spark markdown example

Configuration

Key Type Required Default Description
type string ✅ — Must be form.
schema list ✅ — Home Assistant ha-form schema. Each selector field normally provides name, optional label and default, and selector.
after string see placement UIX selector for the reference element. Inserts the form as a sibling after it.
before string — UIX selector for the reference element. Inserts the form as a sibling before it.
for string see placement Alias for after.
density spacious, reduced, or dense spacious Vertical field spacing. See Density.
submit object — Adds a Submit button. See below.
clear object or true — Adds a Clear button. Use true for the default button, or an object to configure it. See below.

When neither after, before, nor for is given, a blank Forge card uses uix-forge-blank-card $ div.content; a Markdown card uses hui-markdown-card $ ha-markdown. Other forged element types need an explicit placement selector.

submit

Key Type Default Description
action action object — Home Assistant action to run with the current form data.
text string Submit Button text.
icon string — Optional MDI icon.
icon_position start or end start Places the icon in the corresponding ha-button slot.
variant string brand Button color variant: brand, neutral, danger, warning, or success.
appearance string accent Button appearance: accent, filled, outlined, or plain.
clear boolean true Clear all form inputs after a valid submit action is dispatched.

clear

Key Type Default Description
action action object — Optional Home Assistant action to run with the current form data before clearing.
text string Clear Button text.
icon string — Optional MDI icon.
icon_position start or end start Places the icon in the corresponding ha-button slot.
variant string neutral Button color variant: brand, neutral, danger, warning, or success.
appearance string filled Button appearance: accent, filled, outlined, or plain.

The Clear button always clears the inputs, whether or not it has an action. Schema defaults provide the initial values on first display; after clearing, fields are always empty. Use clear: true for an unconfigured Clear button.

Density

density controls the vertical gap between fields in Home Assistant's ha-form. It also reduces the vertical margin around radio controls in list selectors; other selector controls keep their usual Home Assistant hit targets.

Value Field gap Use case
spacious 24px Default Home Assistant form layout.
reduced 16px Compact cards with a small number of fields.
dense 8px Popovers or cards where vertical space is limited.
- type: form
  density: dense
  schema:
    - name: note
      selector:
        text: {}

Styling the form and controls

The form uses Home Assistant's normal ha-form and selector controls. CSS custom properties set on the Forge host cascade through the form's open shadow-DOM boundaries, so set them with forge.uix.style and :host.

type: custom:uix-forge
forge:
  mold: card
  uix:
    style: |
      :host {
        /* UIX form layout */
        --uix-form-padding: var(--ha-space-3);
        --uix-form-field-gap: var(--ha-space-2);

        /* Home Assistant ha-input controls used by text selectors */
        --ha-input-padding-bottom: var(--ha-space-1);
        --ha-input-text-align: start;
      }
  sparks:
    - type: form
      density: reduced
      schema:
        - name: note
          selector:
            text: {}

density changes the space between fields and the vertical margin around radio controls in a list selector. reduced uses an 8px top and bottom radio margin; dense uses 4px. The Home Assistant control variables can additionally tune the controls themselves; for example, --ha-input-padding-bottom affects text and number selectors that render an ha-input.

Home Assistant preserves the 56px hit target of text inputs, switches, and standard boolean fields. Those controls do not currently expose a shared public height token, so density deliberately does not shrink their clickable area.

Available tokens

Variable Default Description
--uix-form-padding var(--ha-space-4, 16px) Space around the form.
--uix-form-actions-gap var(--ha-space-2, 8px) Gap between Clear and Submit buttons.
--uix-form-actions-margin-top var(--ha-space-4, 16px) Space above the button row.
--uix-form-field-gap density-specific Overrides the vertical gap between fields.
--uix-form-radio-option-control-margin density-specific Overrides the radio-control margin used by reduced and dense list selectors. Uses the same four-value order as CSS margin.
--ha-radio-option-control-margin Home Assistant default Directly sets the control margin for radio options; useful with spacious or when styling individual radio controls.
--ha-radio-option-toggle-size 20px Diameter of a radio control; does not change the row hit target.
--ha-checkbox-size 20px Size of a checkbox control; does not change the row hit target.
--ha-input-padding-top unset Padding above an ha-input.
--ha-input-padding-bottom var(--ha-space-2) Padding below an ha-input.
--ha-input-text-align start Text alignment in an ha-input.
--ha-input-required-marker "*" Required-field marker used by ha-input.

--ha-space-*, --ha-font-size-*, --primary-color, and --ha-color-* are broader Home Assistant theme tokens that can also be used in the same :host rule. Selector types use different controls, so a token may not apply to every field.

Find selector-specific tokens

Inspect the rendered field in browser DevTools to identify its selector control, then check the component's documented CSS properties and parts. Home Assistant's source is also useful for this:

  • ha-form defines the field layout.
  • ha-selector selects the concrete control for each selector type.
  • ha-input documents properties for text and number selectors, including padding and text alignment.

popover example

This example uses a UIX popover action to host the forged element with form spark. The popover uses its action buttons to call the UIX javascript action. The form fields are automatically placed into variables of the javascript action.

type: button
name: Popover
show_icon: false
tap_action:
  action: fire-dom-event
  uix:
    action: popover
    data:
      buttons:
        primary:
          label: Send
          end_icon: mdi:send
          tap_action:
            action: fire-dom-event
            uix:
              action: javascript
              data:
                variables:
                  source: contact-form
                code: >
                  console.info(`Submitted: Message: ${variables.message},
                  Priority: ${variables.priority} from ${variables.source}`);
      uix:
        style: |
          .uix-popover-card {
            --ha-card-border-width: 0px;
            --ha-card-background: none;
            --uix-form-padding: 0px;
            --ha-radio-option-active-color: red;
          }
      card:
        type: custom:uix-forge
        forge:
          mold: card
          sparks:
            - type: form
              density: dense
              schema:
                - name: message
                  label: Message
                  selector:
                    text: {}
                - name: priority
                  label: Priority
                  default: normal
                  selector:
                    select:
                      options:
                        - normal
                        - urgent

Form spark popover example

When submitted with message Hello Jim and priority urgent:

Submitted: Message: Hello Jim, Priority: urgent from contact-form