Text Inputs

Text inputs allow you to enter various forms of text such as usernames, passwords, numbers, and more.

Basic Text Input

Text inputs can be used with or without labels.

Note

Adding the label class to the leading/trailing slots will apply a thin separator between the label and the input.

OR
.flex.flex-col.gap-4
  = daisy_label("Basic Inputs")

  = daisy_text_input(name: "username_input", id: "username_input", placeholder: "Username")

  = daisy_text_input(name: "password_input", id: "password_input", placeholder: "Password")

  = daisy_divider("OR")

  .flex.flex-col.gap-2
    = daisy_label(for: "url_input", title: "URL")
    = daisy_text_input(name: "url_input", id: "url_input", leading: "https://", leading_css: "label")

  .flex.flex-col.gap-2
    = daisy_label(for: "email_input", title: "Email")
    = daisy_text_input(name: "email_input", id: "email_input") do |text|
      - text.with_trailing(css: "label") do
        @gmail.com

Floating Label Inputs

Inputs can also utilize a floating label with or without a placeholder to control animation.

OR
.flex.flex-col.gap-4
  .space-y-4
    = daisy_text_input(name: "first_name_input", id: "first_name_input", floating: "First Name")
    = daisy_text_input(name: "last_name_input", id: "last_name_input", floating: "Last Name")

  = daisy_divider("OR")

  .space-y-4
    = daisy_text_input(name: "phone_floating_input", id: "phone_floating_input", floating: "Phone Number", placeholder: "ph: (123) 456-7890")
    = daisy_text_input(name: "fax_floating_input", id: "fax_floating_input", floating: "Fax", placeholder: "fax: (123) 456-7890")

Sticky Floating Label

By default a floating label collapses back into the field while it is empty and showing a placeholder, only rising on focus. Add the floating-sticky class (a LocoMotion variant) via label_wrapper_css: to pin the label in its raised position, so the label and the placeholder hint show at the same time.

Tip: for an always-raised label with no placeholder, just pass floating: without a placeholder: — DaisyUI keeps that label raised on its own (see the first group of the previous example).

.flex.flex-col.gap-4
  .space-y-4
    = daisy_text_input(name: "email_sticky_input", id: "email_sticky_input", floating: "Email", placeholder: "you@example.com", label_wrapper_css: "floating-sticky")
    = daisy_text_input(name: "company_sticky_input", id: "company_sticky_input", floating: "Company", placeholder: "Acme, Inc.", label_wrapper_css: "floating-sticky")

Different Input Types

Text inputs can have different types such as password, email, number, etc.

See also: Cally Input
.my-2.flex.flex-col.gap-4
  = daisy_label(for: "email", title: "Email", css: "mt-4")
  = daisy_text_input(name: "email", id: "email", type: "email")

  = daisy_label(for: "password", title: "Password")
  = daisy_text_input(name: "password", id: "password", type: "password")

  = daisy_label(for: "number", title: "Number", css: "mt-4")
  = daisy_text_input(name: "number", id: "number", type: "number")

  = daisy_label(for: "date", title: "Date", css: "mt-4")
  = daisy_text_input(name: "date", id: "date", type: "date")
  .text-sm.text-right
    %span{ class: "text-base-content/50" } See also:
    = component_link("Cally Input", "Daisy::DataInput::CallyInputComponent")

  = daisy_label(for: "time", title: "Time", css: "mt-4")
  = daisy_text_input(name: "time", id: "time", type: "time")

  = daisy_label(for: "datetime-local", title: "Datetime Local", css: "mt-4")
  = daisy_text_input(name: "datetime-local", id: "datetime-local", type: "datetime-local")

Text Input Sizes

Text inputs can have different sizes using the input-lg, input-md, input-sm, or input-xs classes.

.my-2.flex.flex-col.gap-4
  = daisy_label(for: "input-lg", title: "Large Input")
  = daisy_text_input(name: "input-lg", id: "input-lg", placeholder: "Large input", css: "input-lg")

  = daisy_label(for: "input-md", title: "Medium Input (default)", css: "mt-4")
  = daisy_text_input(name: "input-md", id: "input-md", placeholder: "Medium input", css: "input-md")

  = daisy_label(for: "input-sm", title: "Small Input", css: "mt-4")
  = daisy_text_input(name: "input-sm", id: "input-sm", placeholder: "Small input", css: "input-sm")

  = daisy_label(for: "input-xs", title: "Extra Small Input", css: "mt-4")
  = daisy_text_input(name: "input-xs", id: "input-xs", placeholder: "Extra small input", css: "input-xs")

Text Input with Different Colors

Text inputs can be styled with additional CSS classes to change their appearance.

.my-2.flex.flex-col.gap-4
  = daisy_label(for: "input_primary", title: "Primary Text Input")
  = daisy_text_input(name: "input_primary", id: "input_primary", css: "input-primary")

  = daisy_label(for: "input_secondary", title: "Secondary Text Input", css: "mt-4")
  = daisy_text_input(name: "input_secondary", id: "input_secondary", css: "input-secondary")

  = daisy_label(for: "input_accent", title: "Accent Text Input", css: "mt-4")
  = daisy_text_input(name: "input_accent", id: "input_accent", css: "input-accent")

Ghost Style Text Input

Text inputs can use the input-ghost class to remove the border. The border will appear on focus.

Ghost style with background container:

.my-2.flex.flex-col.gap-4
  = daisy_label(for: "input_ghost", title: "Ghost Style Text Input")
  = daisy_text_input(name: "input_ghost", id: "input_ghost", css: "input-ghost")

  .mt-4.p-4.border.rounded-lg.bg-secondary.text-secondary-content
    %p.text-sm.mb-2 Ghost style with background container:
    = daisy_label(for: "input_ghost_bg", title: "Search")
    = daisy_text_input(name: "input_ghost_bg", id: "input_ghost_bg", css: "input-ghost", placeholder: "Search the docs...")

Disabled Text Input

Text inputs can be disabled using the disabled attribute.

.my-2.flex.flex-col.gap-4
  = daisy_label(for: "input_disabled", title: "Disabled Text Input", css: "cursor-not-allowed")
  = daisy_text_input(name: "input_disabled", id: "input_disabled", disabled: true)

Required Text Input

Text inputs can be marked as required using the required attribute.

.my-2.flex.flex-col.gap-4
  = daisy_label(for: "input_required", title: "Required Text Input")
  = daisy_text_input(name: "input_required", id: "input_required", required: true)

Text Input with Icons

Text inputs can be combined with icons and other elements using the leading and trailing options or slots, which appear before and after the input field.

.my-2.flex.flex-col.gap-4
  = daisy_label(for: "input_icon_prefix", title: "Search with Icon Prefix")
  = daisy_text_input(name: "input_icon_prefix", id: "input_icon_prefix", placeholder: "Search...") do |text_input|
    - text_input.with_leading(css: "label") do
      = loco_icon("magnifying-glass", css: "text-gray-400")

  = daisy_label(for: "input_icon_suffix", title: "Email with Icon Suffix", css: "mt-4")
  = daisy_text_input(name: "input_icon_suffix", id: "input_icon_suffix", type: "email", placeholder: "Enter your email") do |text_input|
    - text_input.with_trailing do
      = loco_icon("envelope", css: "text-gray-400")

  = daisy_label(for: "input_icon_both", title: "Input with Both Icons", css: "mt-4")
  = daisy_text_input(name: "input_icon_both", id: "input_icon_both", placeholder: "Username") do |text_input|
    - text_input.with_leading do
      = loco_icon("user", css: "text-gray-400")
    - text_input.with_trailing do
      = loco_icon("check", css: "text-success")

Rails Form Example

The built-in Form Builder extension provides an easy way to use text inputs in your forms by extracting the name and ID attributes from the form object and attributes.

= form_with(url: "#", method: :post, scope: :user) do |form|
  .my-2.flex.flex-col.gap-4
    = form.daisy_label(:username)
    = form.daisy_text_input(:username)

    = form.daisy_label(:email, "Email Address", css: "mt-4")
    = form.daisy_text_input(:email, type: "email", placeholder: "example@mail.com")

    = form.daisy_label(:password, css: "mt-4")
    = form.daisy_text_input(:password, type: "password")

Accessibility & ARIA Attributes

Every component accepts an aria: shorthand so you don't have to nest attributes inside html: or hand-dasherize keys. Each key becomes an aria-* attribute, so aria: { describedby: "pw-help" } renders aria-describedby="pw-help". A matching data: shorthand works the same way for data-* attributes.

Tip

Input components automatically add aria-required="true" when you pass required: true, so you only need to set ARIA attributes that can't be derived (like aria-describedby or aria-label on an unlabeled input).

Must be at least 12 characters.
.flex.flex-col.gap-2
  = daisy_label(for: "aria_password", title: "Password")
  = daisy_text_input(name: "aria_password", id: "aria_password",
    type: "password", required: true,
    aria: { describedby: "aria_password_help" })
  %span#aria_password_help.text-sm.opacity-70
    Must be at least 12 characters.
Made with by Profoundry .
Copyright © 2023-2026 Profoundry LLC.
All rights reserved.