---
title: Input
desc: Form element that allows users to input and edit text or data into a website page.
ico: mdi:form-textbox
keywords:
  - color
  - date
  - datetime-local
  - email
  - file
  - form
  - hidden
  - image
  - month
  - number
  - password
  - range
  - search
  - tel
  - text
  - textarea
  - time
  - url
  - week

after: |
  ## Note:

  <div class="not-prose alert mb-6 border-base-300 shadow-lg md:mb-12 [&_a]:text-(--color-primary) [&_a]:font-semibold [&_a]:underline [&_a]:hover:no-underline [&>p_br~strong]:mx-1 [&>p_br~strong]:text-(--color-secondary) [&>p_br~strong]:font-mono" role="alert">
    <iconify-icon icon="mdi:warning" class="iconify text-xl block" noobserver></iconify-icon>
    <p><strong>Use as a container:</strong><br />
    <strong class="kbd kbd-sm mx-1 font-mono">.prs-input</strong> can also be used as a container to "weld" inputs + non-input elements together when used with the <a href="../form-control/">Form Control</a> component structure. Please make sure that if you use this, your container can shrink down below 320px for smaller screens. See example below:</p>
  </div>

  <fieldset class="fieldset mx-auto mb-6 border border-base-300 px-4 pb-4 max-w-xs rounded-box">
    <legend class="fieldset-legend">Input as a container</legend>
    <div class="not-prose prs-form-control">
      <div class="prs-label">
        <label for="faux-contained-input" class="prs-label-text">Example:</label>
      </div>
      <label class="prs-input">
        <span class="prs-label-text">$</span>
        <input type="number" id="faux-contained-input" min="0" max="999" step="1" pattern="[0-9]{1,3}" oninput="if(parseInt(this.value)>999){ this.value = 999; return false; }" placeholder="123" />
        <span class="prs-label-text">.00</span>
      </label>
    </div>
  </fieldset>

  ```html
  <div class="prs-form-control">
    <div class="prs-label">
      <label for="contained-input" class="prs-label-text">Example:</label>
    </div>
    <label class="prs-input">
      <span class="prs-label-text">$</span>
      <input type="number" id="contained-input" placeholder="123" />
      <span class="prs-label-text">.00</span>
    </label>
  </div>
  ```

props:
  - class: .prs-input
    type: component
    desc: For <input> or <label>
  - class: .prs-input-ghost
    type: modifier
    desc: Remove border
  - class: .prs-input_focus
    type: state
    desc: Manually apply visual focus
  - class: .prs-input_invalid
    type: state
    desc: Manually apply visual invalid
  - class: .prs-input_disabled
    type: state
    desc: Manually apply visual disabled

controls:
  - name: value
    type: text
    label: Value
    desc: Value text.
    default: ''
  - name: placeholder
    type: text
    label: Placeholder
    desc: Placeholder text.
    default: ''
  - name: type
    type: select
    label: Input Type
    desc: There are quite a few input types that share styles. Select requires a supplementary class.
    default: text
    options:
      - text
      - number
      - date
      - textarea
      - select
      - file
  - name: invalid
    type: toggle
    label: Invalid
    desc: Invalid state automatically shows if you use native HTML required/pattern attributes OR if you manually apply the .prs-input_invalid class. An optional error message can also automatically display without any extra coding logic (pure CSS).
    default: false
  - name: variant
    type: radio
    label: Variant
    desc: Ghost is a border-less & background-less alternate display for extreme cases.
    default: default
    options:
      - default
      - ghost
  - name: state
    type: radio
    label: State
    desc: These states will happen automatically when using valid sematic markup.
    default: default
    options:
      - default
      - focus
      - disabled

preview: |
  <label class="prs-form-control w-screen max-w-xs">
    <input
      x-model="value"
      x-show="type !== 'select' && type !== 'textarea'"
      @focus="$el.showPicker()"
      :type="type"
      :class="{
        'prs-input-ghost': variant === 'ghost',
        'prs-input_focus': state === 'focus',
        'prs-input_invalid': invalid,
        'prs-select': type === 'select',
        'prs-textarea': type === 'textarea',
        'prs-file': type === 'file',
      }"
      :placeholder="placeholder ? placeholder : 'Text Placeholder'"
      :disabled="state === 'disabled'"
      class="prs-input"
    />
    <textarea
      x-show="type === 'textarea'"
      x-model="value"
      :class="{
        'prs-input-ghost': variant === 'ghost',
        'prs-input_focus': state === 'focus',
        'prs-input_invalid': invalid,
      }"
      :placeholder="placeholder ? placeholder : 'Textarea Placeholder'"
      :disabled="state === 'disabled'"
      class="prs-input"
    ></textarea>
    <select
      x-show="type === 'select'"
      :disabled="state === 'disabled'"
      :class="{
        'prs-input-ghost': variant === 'ghost',
        'prs-input_focus': state === 'focus',
        'prs-input_invalid': invalid,
      }"
      class="prs-input prs-select"
    >
      <option selected disabled>Choose:</option>
      <option>Option 1</option>
      <option>Option 2</option>
      <option>Option 3</option>
    </select>
    <span class="prs-label-text prs-label-error">Error message</span>
  </div>

code:
  html: |
    <label class="prs-form-control" aria-label="Accessible description">
      {text}{number}{date}{textarea}{select}{file}{validated}
    </label>
  logic:
    text: "this.type === 'text' ? '<input type=\"text\" class=\"prs-input{ghost}{invalid}\"{value}{placeholder}{required}{disabled} />' : ''"
    number: "this.type === 'number' ? '<input type=\"number\" class=\"prs-input{ghost}{invalid}\" min=\"0\" max=\"999\" step=\"1\" pattern=\"[0-9]{1,3}\"{value}{placeholder}{required}{disabled} />' : ''"
    date: "this.type === 'date' ? '<input type=\"date\" class=\"prs-input{ghost}{invalid}\" onfocus=\"this.showPicker()\"{required}{disabled} />' : ''"
    textarea: "this.type === 'textarea' ? '<textarea class=\"prs-input{ghost}{invalid}\"{value}{placeholder}{required}{disabled} /></textarea>' : ''"
    select: "this.type === 'select' ? '<select class=\"prs-input prs-select{ghost}{invalid}\"{required}{disabled} />\\n    <option{value}></option>\\n  </select>' : ''"
    file: "this.type === 'file' ? '<input type=\"file\" class=\"prs-input{ghost}{invalid}\" accept=\"image/*\"{required}{disabled} />' : ''"
    value: "this.value !== '' ? (' value=\"'+ this.value +'\"') : ''"
    placeholder: "this.placeholder !== '' ? (' placeholder=\"'+ this.placeholder +'\"') : ''"
    ghost: "this.variant === 'ghost' ? ' prs-input-ghost' : ''"
    invalid: "this.invalid ? ' prs-input_invalid' : ''"
    required: "this.invalid ? ' required' : ''"
    disabled: "this.state === 'disabled' ? ' disabled' : ''"
    validated: "this.invalid ? '\\n  <span class=\"prs-label-text prs-label-error\">Shows based on native invalid or `.prs-input_invalid`</span>' : ''"
---
