Skip to content

skavan/super-text-input

Repository files navigation

Super Text Input Card for Home Assistant

I hate the default text_input card. It's huge, ugly and the onblur update (i.e. only triggers update when you leave the field) is annoying. Especially on mobile. I wanted a replacement that was compact, flexible, could easily be styled and had icon(s)/button(s).

So, I made one. A highly customizable text input card that provides real-time updates (as well as old fashioned onblur), buttons (and actions), advanced styling options and more. It also supports firing events after text updates, to save on creating automations. It supports text entities as well as text_input entities.



See credits below. This was my first attempt at a custom card. My first public repository.

Features

  • Real-time or on-blur text updates (no more focus blink in real-time mode — the input keeps focus across re-renders)
  • Configurable buttons with icons, custom shapes, and tap actions
  • Card- and editor-level styling: background, border, padding, height, fonts, colors, underline color
  • Floated, compact label (or hide it entirely for a slim single-row look)
  • Vertical alignment of the value text (top / center / bottom)
  • Optional compact buttons mode that strips Material Design's 48 px touch target
  • Per-button border-radius that also reshapes the hover/ripple overlay
  • Underscore (margin_left) and hyphen (margin-left) YAML keys both accepted
  • Supports text entities and text_input entities
  • Debounced updates to prevent excessive service calls
  • Compatible with HA 2026.4+ (Web Awesome wa-input) and older HA (MDC ha-textfield)

What's new in v0.3

v0.3 is a big update. The card has been rewritten for Home Assistant 2026.4+, which replaced the MDC ha-textfield internals with Web Awesome's wa-input. The old version stopped rendering on 2026.4 — v0.3 detects which input element your HA exposes and styles it accordingly, so the same YAML works on both old and new HA.

Along the way the card picked up a much larger style vocabulary, slim-mode rendering, and per-button hover-shape customization. See the Style reference for the full list of keys.

The two original GitHub issues (real-time mode keyboard close on iPhone, space key not registering) are also fixed — both were symptoms of the same render-time DOM replacement, now solved by switching render() to a real Lit template.

⚠️ Breaking changes

Most existing YAML continues to work. A few defaults shifted:

  • Default card height is now 56 px when a label is shown, 44 px when hide_label: true. If you set style.card.height, that wins.
  • Default editor height is now 100% of the card's inner area (was a fixed 36 px). Set style.editor.height to override.
  • Default editor padding-bottom is 2 px. The legacy negative-margin trick (margin-bottom: -3 px) is no longer the default — you can still set it explicitly.
  • Label rendering is now a compact floated label by default (font-size: 10 px, tight padding). Set style.editor.label-font-size and label-padding-* to customize.
  • compact_buttons is a new card-level flag that tightens the spacing around buttons. By default every Material Design button reserves a 48×48 px touch-target, which makes shrunken icon buttons sit in much more empty space than you'd expect. compact_buttons: true strips that empty padding so the button hit area matches the visible icon — useful for slim pills and tight rows. It defaults to false so existing layouts and touch accessibility are preserved.
  • Hover overlay shape now follows the button. Independent of compact_buttons, any button under 48 px now has its hover/ripple overlay scoped to the visible button (was always a 48 px circle before), and the overlay's corners follow the button's border-radius — set border-radius: 12 px and the hover becomes a rounded square instead of a circle.

If you were on v0.1 or v0.2 and your card looked exactly the way you wanted, double-check it after upgrading — small pixel shifts are possible. Everything is overridable.

Installation

Via HACS (recommended)

This repo isn't in the HACS default list yet, but you can install it as a custom repository in one click:

  1. Open HACS in Home Assistant.
  2. Click the ⋮ menu (top-right) → Custom repositories.
  3. Repository: https://github.com/skavan/super-text-input
  4. Type: Dashboard
  5. Click Add.
  6. Find Super Text Input in the HACS list and click Download.
  7. Add the resource — HACS may do this for you automatically. If not, see the manual install step 2 below.
  8. Hard-refresh your browser (Ctrl/Cmd+Shift+R).

When a new release ships, HACS will surface an update notification.

Manual install

  1. Download the files (super-text-input.js, card-utils.js, editor.js, base-editor.js, preview.png) to your config/www/community/super-text-input/ directory.
  2. Add the resource in your dashboard configuration. Two ways:
    • Using the UI: SettingsDashboardsMore Options iconResourcesAdd Resource → Set Url to /local/community/super-text-input/super-text-input.js → Set Resource type to JavaScript Module. Note: If you don't see the Resources menu, enable Advanced Mode in your User Profile.
    • Using YAML: add this to your lovelace section.
      resources:
        - url: /local/community/super-text-input/super-text-input.js
          type: module

Quick start

All props are optional except type and entity.

type: custom:super-text-input
entity: text.some_entity   # supports input_text and text entities
name: my name              # optional friendly name
label: enter text          # floated label above the input
placeholder: text here...
update_mode: realtime      # 'realtime' or 'blur' (blur is default)
debounce_time: 1000        # ms to wait in realtime mode before pushing the value

A truly minimal one-liner search field:

type: custom:super-text-input
entity: input_text.search
placeholder: search...
hide_label: true           # slim mode — collapses to a single row, no label area

Usage

Top-level config

Key Type Default Description
entity string required input_text.* or text.* entity
name string entity friendly name Used as label fallback
label string name Floated label above the value
placeholder string "" Shown when the value is empty
update_mode "blur" | "realtime" "blur" When to push the value to HA
debounce_time number (ms) 1000 Debounce delay in realtime mode
hide_label bool false Slim mode — collapses to a single-row input
compact_buttons bool false Force all buttons to skip the 48 px MD touch target
change_action action Fires whenever the value changes (see Actions)
style object See Style reference
buttons array See Icons and buttons

Card and editor styling

- type: custom:super-text-input
  entity: input_text.sti_test
  label: Bubble Card
  placeholder: transparent background...
  buttons:
    - id: toast                          # id is yours — useful for card_mod & the `clear` template
      icon: mdi:text-box-edit            # any mdi icon
      position: start                    # start = left of input; end = right
      size: 38px                         # outer button (default 36px)
      icon_size: 26px                    # icon inside the button (default 24px)
      style:
        border_radius: 50%               # button shape; also reshapes the hover overlay
        background: mintcream            # button fill
        color: limegreen                 # icon color
      tap_action:                        # any HA action; supports {{ value }}
        action: fire-dom-event
        browser_mod:
          service: browser_mod.notification
          data:
            message: 'Your toast: {{value}}'
  style:
    card:                                # outer card chrome (around buttons + input)
      height: 56px
      padding: 8px                       # space between card edge and inner content
      margin: 0px
      background: white
      border-radius: 28px                # pill shape
      border: 1px solid rgba(0,0,0,0.1)
    editor:                              # the input/text area itself
      height: 100%                       # fill card minus card padding
      background: transparent            # let the card's white show through
      padding-left: 8px                  # where the value text starts horizontally
      label-font-size: 12px              # default is 10px; bump for a louder label
      label-font-weight: 600
      margin-left: 6px                   # nudge the whole input rightward
      margin-right: 24px                 # leave room on the right

BubbleCard-esque:

Style reference

All keys accept either hyphenated CSS form (padding-left) or underscored (padding_left) — they are normalized at config-load time.

style.card

Key Default Notes
height 56px (or 44px when hide_label: true) Outer card height
padding 8px Inset around the editor + buttons
background Card background
border-radius Card corner radius
border Full CSS border shorthand
width Optional fixed card width — applied to the host
max-width Optional cap on card growth in 1fr tracks
min-width 0 Floors the card's shrinkability — leave 0 so the card participates in grid 1fr tracks

style.editor

Key Default Notes
height 100% Height of the input area inside the card
background Editor area background
color Value text color
font-size Value text size
font-weight Value text weight
placeholder-color Placeholder color
padding-left 8px Where the value text starts horizontally
padding-right mirror of padding-left if only L set Right inset
padding-top 20px if label shown, none otherwise Vertical inset above the value
padding-bottom 2px Gap above the underline
line-gap Alias for padding-bottom (visual intent)
padding Shorthand. Long-hand keys override per-side.
vertical-align bottom top / center(middle) / bottom. Use center in slim/hide_label cards
margin-left, margin-right, margin-top, margin-bottom Offset the input element
line-color Color of the bottom underline
border-color, border-radius, border-width border-radius: 4px Border around the editor area
label-color Label color
label-font-size 10px (when label shown) Label font size
label-font-weight Label font weight
label-line-height 1.2 (when label shown) Label line height
label-padding-top 4px (when label shown) Label top inset
label-padding-bottom 0 (when label shown) Label bottom inset
label-padding-left 8px (when label shown) Label left inset (align with value)
label-padding-right Label right inset

buttons[]

Key Type Notes
id string Useful for card_mod and for the prebuilt clear template
icon string mdi:... icon name
position "start" | "end" Side of the input the button sits on
size css length Default 36px. Sub-48 sizes auto-trigger ripple-shape correction
icon_size css length Default 24px
entity string If set, used as the target for template: more-info
template "clear" | "toast" | "more-info" Built-in actions (see Actions)
tap_action action Custom action. Overrides template.
style object Per-button styling (below)

buttons[].style

Key Default Notes
color var(--blue-color) Icon color
background rgb(from <color> r g b / 0.2) Button background
border none CSS border shorthand
border-radius 50% Button shape. Also propagates to the hover/ripple overlay.
margin-left, margin-right auto-computed from size Fine-tune positioning

Actions

change_action

Fires whenever the entity's value changes. Takes a standard HA action and supports a {{ value }} template — useful for kicking off searches or media queries without writing a separate automation.

change_action:
  action: call-service
  service: script.mass_media_search
  data:
    search_param: "{{ value }}"           # current input value gets substituted in
    media_type: playlist
    sensor_id: ma_mqtt_sensor
    media_player: MA Connect Basement

Per-button tap_action

Any standard HA action works. For example, a button that fires a browser_mod toast with the current value:

buttons:
  - id: toast
    icon: mdi:bell
    tap_action:
      action: fire-dom-event              # browser_mod's required action type
      browser_mod:
        service: browser_mod.notification
        data:
          message: "You said: {{ value }}"

Built-in button templates

Three actions are common enough that the card ships them as named templates. Set template: on the button instead of tap_action:

Template What it does
clear Sets the entity's value back to ""
toast Fires a browser_mod notification with the current {{ value }}
more-info Opens the more-info dialog for the card's entity (or the button's own entity if set)

tap_action overrides template if both are set. If neither is set, the button has no action (decorative).

Icons and buttons

Buttons live at start (left of the input) or end (right). You can mix sizes, shapes and actions freely.

  compact_buttons: false                  # leave the MD touch-target padding (default)
  buttons:
    - id: edit
      icon: mdi:text-box-edit
      position: start
      size: 28px
      icon_size: 20px

    - id: clear
      icon: mdi:close
      position: end
      size: 22px
      icon_size: 16px
      template: clear                     # built-in: blanks the entity's value
      style:
        background: transparent           # no fill — just a bare icon
        color: grey
        margin_left: 2px                  # underscore form is fine — normalized to margin-left
        margin_right: 4px
    - id: info
      icon: mdi:information-outline
      position: end
      size: 28px
      icon_size: 18px
      template: more-info                 # built-in: opens the entity's more-info dialog
      style:
        background: transparent
        color: green
        border: 1.5px solid green         # a decorative outline ring
        margin_left: 4px
        margin_right: 0px

Hover/ripple shape

The MD hover overlay used to always be a circle, even when the button was a rounded rectangle. v0.3 fixes this:

  • Any button with size: < 48 px automatically gets its inner hover overlay shrunk to match
  • The hover overlay's border-radius follows the button's style.border-radius — set border-radius: 12 px and the hover becomes a rounded square instead of a circle
  • Card-level compact_buttons: true forces all buttons (regardless of size) to behave this way

Recipes

Five common looks. The full set lives in sample-yaml.yaml.

1. Icons + green-bordered info button

Normal MD-sized buttons, with a decorative bordered info button on the right.

type: custom:super-text-input
entity: input_text.sti_test
label: icons and buttons
buttons:
  - id: edit
    icon: mdi:text-box-edit
    position: start
    size: 28px
    icon_size: 20px
  - id: clear
    icon: mdi:close
    position: end
    size: 22px
    icon_size: 16px
    template: clear
    style:
      background: transparent
      color: grey
      margin-left: 2px                    # tight against the input
      margin-right: 4px                   # small gap before the next button
  - id: info
    icon: mdi:information-outline
    position: end
    size: 28px
    icon_size: 18px
    template: more-info
    style:
      background: transparent
      color: green
      border: 1.5px solid green           # the distinctive ringed look
      margin-left: 4px
      margin-right: 0px                   # flush with the card edge

2. Google-style slim search pill (vertically centered)

hide_label: true collapses to a single row, vertical-align: center puts the value text in the visual middle of the pill, and a transparent line-color hides the underline.

type: custom:super-text-input
entity: input_text.sti_test
placeholder: Search…
hide_label: true
compact_buttons: true                     # strip the 48px MD touch-target around every button
buttons:
  - id: l
    icon: mdi:magnify
    position: start
    size: 28px
    icon_size: 18px
    style:
      background: transparent
      color: '#5f6368'
      padding-right: 0px
  - id: x
    icon: mdi:close
    position: end
    size: 28px
    icon_size: 16px
    template: clear
    style:
      background: transparent
      color: '#5f6368'
style:
  card:
    height: 44px                          # short pill height
    padding: 6px
    border-radius: 22px                   # half of height = perfect pill
    border: '1px solid #dadce0'
  editor:
    vertical-align: center                # value text sits in the visual middle of the pill
    height: 32px
    background: transparent
    padding-left: 0px                     # flush against the magnify icon
    padding-right: 4px
    line-color: transparent               # hide the underline — pills don't have one
    margin-left: 0px

3. WhatsApp-style chat pill

Trailing send button only. Slim, rounded, no visible underline.

type: custom:super-text-input
entity: input_text.sti_test
placeholder: Ask anything…
hide_label: true
compact_buttons: true
buttons:
  - id: s
    icon: mdi:send
    position: end
    size: 32px
    icon_size: 20px
    style:
      background: transparent
      color: '#1a73e8'
style:
  card:
    height: 48px
    padding: 4px
    background: '#f8fafc'
    border-radius: 24px                   # half of height = pill
    border: '1px solid #e2e8f0'
  editor:
    height: 100%
    background: transparent
    padding-left: 14px                    # room for the placeholder text
    padding-right: 4px
    padding-bottom: 11px                  # bump text up so it centers without using vertical-align
    line-color: transparent

4. Dark notes

Dark card, blue label and underline, light value text.

type: custom:super-text-input
entity: input_text.sti_test
label: Dark Notes
placeholder: jot something…
style:
  card:
    height: 80px                          # taller card for a notes-style block
    padding: 12px
    background: '#1e293b'                 # dark navy
    border-radius: 14px
  editor:
    background: transparent
    label-color: '#60a5fa'                # blue label
    label-font-size: 16px                 # larger than default 10px — louder header
    font-size: 16px                       # value text size
    color: '#f1f5f9'                      # near-white value text on dark bg
    placeholder-color: '#64748b'          # muted placeholder
    line-color: '#60a5fa'                 # blue underline matches the label

5. Fixed / capped card width (v0.3.24)

Pin a card to a fixed width, or cap it with max-width so it can still shrink in a 1fr grid track. Both are applied to the host element so they participate correctly with whatever flex/grid container the card sits in.

# Fixed 220px footprint — never grows, never shrinks
type: custom:super-text-input
entity: input_text.sti_test
placeholder: fixed 220 px
hide_label: true
style:
  card:
    width: 220px
    background: '#fef3c7'
    border-radius: 16px
    padding: 6px
  editor:
    vertical-align: center
    color: '#78350f'
    placeholder-color: '#92400e'
    line-color: transparent
    padding-left: 10px

# Capped at 300px — full width up to 300, shrinks below in narrow tracks
type: custom:super-text-input
entity: input_text.sti_test
placeholder: max 300 px, shrinks below
hide_label: true
style:
  card:
    max-width: 300px
    background: '#dbeafe'
    border-radius: 16px
    padding: 6px
  editor:
    vertical-align: center
    color: '#1e3a8a'
    placeholder-color: '#3b82f6'
    line-color: transparent
    padding-left: 10px

Forward-compatibility notes

The card reaches into Home Assistant's shadow DOM in a few places. These should be stable across point releases but could break if HA refactors the underlying elements:

  • The label-styling rule targets label.label inside wa-input's shadow — a CSS class, not an exposed part. If Web Awesome renames the class, all label styling silently no-ops until this card is updated.
  • The underline (line-color) is drawn via [part="base"]::after. If wa-input switches to a border-bottom or a real DOM node, line-color becomes a no-op.
  • The hover-shape correction styles ha-button::after, ha-button::before. If HA swaps to mwc-ripple / md-ripple or renames the pseudo, hover reverts to its default 50% circle.

In each case the card itself keeps working — only the affected style key loses effect.

Credits

The core card was inspired by gadgetchnnel/lovelace-text-input-row and the config options were inspired by delphiki../base-editor.js.

The HA 2026.4+ compatibility work draws on PR #4 by @DavidCeliis.

About

A highly customizable text input card for Home Assistant Lovelace dashboards — slim/pill modes, action buttons, real-time updates, styling controls.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors