The Editor component is now implemented! Check it out.
v2.1.16
/
  • Get Started
  • Components
  • Composables
  • Typography
  • GitHub
  • Layout
  • App
  • Container
  • Error
  • SidebarLayout
  • Element
  • Advice
  • Alert
  • Avatar
  • AvatarGroup
  • Badge
  • Banner
  • Button
  • Calendar
  • Card
  • Chip
  • Collapsible
  • Countdown
  • FieldGroup
  • Kbd
  • Progress
  • Separator
  • Skeleton
  • Form
  • Checkbox
  • CheckboxGroup
  • ColorPicker
  • FileUpload
  • Form
  • FormField
  • Input
  • InputDate
  • InputMenu
  • InputNumber
  • InputTags
  • InputTime
  • PinInput
  • RadioGroup
  • Range
  • Select
  • SelectMenu
  • Switch
  • Textarea
  • Data
  • Accordion
  • DescriptionList
  • Empty
  • Table
  • TableWrapper
  • Timeline
  • User
  • Navigation
  • Breadcrumb
  • CommandPalette
  • Link
  • NavigationMenu
  • Pagination
  • Stepper
  • Tabs
  • Overlay
  • ContextMenu
  • DropdownMenu
  • Modal
  • Popover
  • Slideover
  • Toast
  • Tooltip
  • Page
  • PageCard
  • PageColumns
  • PageGrid
  • PageLinks
  • PageList
  • Dashboard
  • DashboardGroup
  • DashboardSearch
  • DashboardSearchButton
  • AI Chat
  • soonChatMessage
  • soonChatMessages
  • soonChatPalette
  • soonChatPrompt
  • soonChatPromptSubmit
  • Editor
  • NewEditor
  • NewEditorDragHandle
  • NewEditorEmojiMenu
  • NewEditorMentionMenu
  • NewEditorSuggestionMenu
  • NewEditorToolbar
  • Content
  • ContentSearch
  • ContentSearchButton
  • ContentSurround
  • ContentToc
  • Color Mode
  • ColorModeAvatar
  • ColorModeButton
  • ColorModeImage
  • ColorModeSelect
  • ColorModeSwitch
  • i18n
  • LocaleSelect
  • b24icons
  • b24jssdk
Use our Nuxt starter
v2.1.16
  • Docs
  • Components
  • Composables
  • Typography

Input

An input box designed for text entry.
GitHub
Demo
Nuxt UI

Usage

Use the v-model directive to control the value of the Input.

<script setup lang="ts">
const value = ref('')
</script>

<template>
  <B24Input v-model="value" />
</template>

Type

Use the type prop to change the input type. Defaults to text.

Some types have been implemented in their own components such as Checkbox, Radio, InputNumber etc. and others have been styled like file for example.

<template>
  <B24Input type="file" />
</template>
You can check all the available types on the MDN Web Docs.

Placeholder

Use the placeholder prop to set a placeholder text.

<template>
  <B24Input placeholder="Search..." />
</template>

Color

Use the color prop to change the ring color when the Input is focused.

<template>
  <B24Input color="air-primary-warning" highlight placeholder="Search..." />
</template>
The highlight prop is used here to show the focus state. It's used internally when a validation error occurs.

Tag

Use the tag property to display a Badge on top of the Input.

note
<template>
  <B24Input tag="note" color="air-primary-warning" highlight placeholder="Search..." />
</template>
The highlight prop is used here to show the focus state. It's used internally when a validation error occurs.

Use the tagColor property to set the color for Badge.

note
<template>
  <B24Input
    tag-color="air-secondary-alert"
    tag="note"
    color="air-primary-warning"
    highlight
    placeholder="Search..."
  />
</template>
The highlight prop is used here to show the focus state. It's used internally when a validation error occurs.

Size

Use the size prop to change the size of the Input.

<template>
  <B24Input size="xl" placeholder="Search..." />
</template>

Icon

Use the icon prop to show an Icon inside the Input.

<script setup lang="ts">
import RocketIcon from '@bitrix24/b24icons-vue/main/RocketIcon'
</script>

<template>
  <B24Input :icon="RocketIcon" size="md" placeholder="Search..." />
</template>

Trailing Icon

Use the trailing-icon prop to set icon for trailing position.

<script setup lang="ts">
import RocketIcon from '@bitrix24/b24icons-vue/main/RocketIcon'
</script>

<template>
  <B24Input :trailing-icon="RocketIcon" placeholder="Enter your email" size="md" />
</template>

Avatar

Use the avatar prop to show an Avatar inside the Input.

<template>
  <B24Input
    :avatar="{
      src: '/b24ui/avatar/employee.png'
    }"
    size="md"
    placeholder="Search..."
  />
</template>

Loading

Use the loading prop to show a loading icon on the Input.

<template>
  <B24Input loading placeholder="Search..." />
</template>

Disabled

Use the disabled prop to disable the Input.

<template>
  <B24Input disabled placeholder="Search..." />
</template>

No padding

Use the noPadding prop to removes padding from the Input.

<template>
  <B24Input no-padding highlight placeholder="Search..." />
</template>
The highlight prop is used here to show the focus state.

No border

Use the noBorder prop to removes all borders (rings) from the Input.

<template>
  <B24Input no-border highlight placeholder="Search..." />
</template>
The highlight prop is used here to indicate that there is no focus state.

Underline

Use the underline prop to removes all borders (rings) except the bottom one from the Input.

<template>
  <B24Input underline highlight placeholder="Search..." />
</template>
The highlight prop is used here to show the focus state.

Rounded

Use the rounded prop to round the Input.

<template>
  <B24Input rounded highlight placeholder="Search..." />
</template>
The highlight prop is used here to show the focus state.

Examples

With clear button

You can put a Button inside the #trailing slot to clear the Input.

<script setup lang="ts">
import CircleCrossIcon from '@bitrix24/b24icons-vue/outline/CircleCrossIcon'

const value = ref('Click to clear')
</script>

<template>
  <B24Input
    v-model="value"
    placeholder="Type something..."
    :b24ui="{ trailing: 'pe-1' }"
  >
    <template v-if="value?.length" #trailing>
      <B24Button
        size="sm"
        color="air-tertiary-no-accent"
        :icon="CircleCrossIcon"
        aria-label="Clear input"
        @click="value = ''"
      />
    </template>
  </B24Input>
</template>

With copy button

You can put a Button inside the #trailing slot to copy the value to the clipboard.

<script setup lang="ts">
import CopyIcon from '@bitrix24/b24icons-vue/outline/CopyIcon'
import CircleCheckIcon from '@bitrix24/b24icons-vue/outline/CircleCheckIcon'

import { useClipboard } from '@vueuse/core'

const value = ref('npx nuxt module add @bitrix24/b24ui-nuxt')

const { copy, copied } = useClipboard()
</script>

<template>
  <B24Input
    v-model="value"
    :b24ui="{ trailing: 'pr-0.5' }"
  >
    <template v-if="value?.length" #trailing>
      <B24Tooltip text="Copy to clipboard" :content="{ side: 'right' }">
        <B24Button
          :b24ui="{
            leadingIcon: [copied ? 'text-(--ui-color-accent-main-success)' : 'text-(--ui-btn-color)']
          }"
          size="sm"
          color="air-tertiary-no-accent"
          :icon="copied ? CircleCheckIcon : CopyIcon"
          aria-label="Copy to clipboard"
          @click="copy(value)"
        />
      </B24Tooltip>
    </template>
  </B24Input>
</template>

With password toggle

You can put a Button inside the #trailing slot to toggle the password visibility.

<script setup lang="ts">
import ObserverIcon from '@bitrix24/b24icons-vue/outline/ObserverIcon'
import CrossedEyeIcon from '@bitrix24/b24icons-vue/outline/CrossedEyeIcon'

const show = ref(false)
const password = ref('')
</script>

<template>
  <B24Input
    v-model="password"
    placeholder="Password"
    :type="show ? 'text' : 'password'"
    :b24ui="{ trailing: 'pe-1' }"
  >
    <template #trailing>
      <B24Button
        size="sm"
        color="air-tertiary-no-accent"
        :icon="show ? CrossedEyeIcon : ObserverIcon"
        :aria-label="show ? 'Hide password' : 'Show password'"
        :aria-pressed="show"
        aria-controls="password"
        @click="show = !show"
      />
    </template>
  </B24Input>
</template>

<style>
/* Hide the password reveal button in Edge */
::-ms-reveal {
    display: none;
}
</style>

With password strength indicator

You can use the Progress component to display the password strength indicator.

Enter a password. Must contain:

  • At least 8 characters - Requirement not met
  • At least 1 number - Requirement not met
  • At least 1 lowercase letter - Requirement not met
  • At least 1 uppercase letter - Requirement not met
<script setup lang="ts">
import ObserverIcon from '@bitrix24/b24icons-vue/outline/ObserverIcon'
import CrossedEyeIcon from '@bitrix24/b24icons-vue/outline/CrossedEyeIcon'
import CircleCheckIcon from '@bitrix24/b24icons-vue/outline/CircleCheckIcon'
import CircleCrossIcon from '@bitrix24/b24icons-vue/outline/CircleCrossIcon'

const show = ref(false)
const password = ref('')

function checkStrength(str: string) {
  const requirements = [
    { regex: /.{8,}/, text: 'At least 8 characters' },
    { regex: /\d/, text: 'At least 1 number' },
    { regex: /[a-z]/, text: 'At least 1 lowercase letter' },
    { regex: /[A-Z]/, text: 'At least 1 uppercase letter' }
  ]

  return requirements.map(req => ({ met: req.regex.test(str), text: req.text }))
}

const strength = computed(() => checkStrength(password.value))
const score = computed(() => strength.value.filter(req => req.met).length)

const color = computed(() => {
  if (score.value === 0) return 'air-primary'
  if (score.value <= 1) return 'air-primary-alert'
  if (score.value <= 2) return 'air-primary-warning'
  if (score.value === 3) return 'air-primary-warning'
  return 'success'
})

const text = computed(() => {
  if (score.value === 0) return 'Enter a password'
  if (score.value <= 2) return 'Weak password'
  if (score.value === 3) return 'Medium password'
  return 'Strong password'
})
</script>

<template>
  <div class="space-y-2">
    <B24FormField label="Password">
      <B24Input
        v-model="password"
        placeholder="Password"
        :color="color"
        :type="show ? 'text' : 'password'"
        :aria-invalid="score < 4"
        aria-describedby="password-strength"
        :b24ui="{ trailing: 'pe-1' }"
        class="w-full"
      >
        <template #trailing>
          <B24Button
            size="sm"
            color="air-tertiary-no-accent"
            :icon="show ? CrossedEyeIcon : ObserverIcon"
            :aria-label="show ? 'Hide password' : 'Show password'"
            :aria-pressed="show"
            aria-controls="password"
            @click="show = !show"
          />
        </template>
      </B24Input>
    </B24FormField>

    <B24Progress
      :color="color"
      :indicator="text"
      :model-value="score"
      :max="4"
      size="sm"
    />

    <p id="password-strength" class="text-(length:--ui-font-size-sm) font-(--ui-font-weight-medium)">
      {{ text }}. Must contain:
    </p>

    <ul class="space-y-1" aria-label="Password requirements">
      <li
        v-for="(req, index) in strength"
        :key="index"
        class="flex items-center gap-0.5"
        :class="req.met ? 'text-(--ui-color-accent-main-success)' : 'text-(--b24ui-typography-label-color)'"
      >
        <CircleCheckIcon v-if="req.met" class="size-4 shrink-0" />
        <CircleCrossIcon v-else class="size-4 shrink-0" />

        <span class="text-(length:--ui-font-size-xs) font-(--ui-font-weight-light)">
          {{ req.text }}
          <span class="sr-only">
            {{ req.met ? ' - Requirement met' : ' - Requirement not met' }}
          </span>
        </span>
      </li>
    </ul>
  </div>
</template>

With character limit

You can use the #trailing slot to add a character limit to the Input.

0/15
<script setup lang="ts">
const value = ref('')
const maxLength = 15
</script>

<template>
  <B24Input
    v-model="value"
    :maxlength="maxLength"
    aria-describedby="character-count"
    :b24ui="{ trailing: 'pointer-events-none' }"
  >
    <template #trailing>
      <div
        id="character-count"
        class="text-(length:--ui-font-size-xs)/(--ui-font-line-height-reset) text-(--b24ui-typography-description-color) tabular-nums"
        aria-live="polite"
        role="status"
      >
        {{ value?.length }}/{{ maxLength }}
      </div>
    </template>
  </B24Input>
</template>

With keyboard shortcut

You can use the Kbd component inside the #trailing slot to add a keyboard shortcut to the Input.

/
<script setup lang="ts">
import CrmSearchIcon from '@bitrix24/b24icons-vue/crm/CrmSearchIcon'

const input = useTemplateRef('input')

defineShortcuts({
  '/': () => {
    input.value?.inputRef?.focus()
  }
})
</script>

<template>
  <B24Input
    ref="input"
    :icon="CrmSearchIcon"
    placeholder="Search..."
  >
    <template #trailing>
      <B24Kbd value="/" />
    </template>
  </B24Input>
</template>
This example uses the defineShortcuts composable to focus the Input when the / key is pressed.

With mask

There's no built-in support for masks, but you can use libraries like maska to mask the Input.

<script setup lang="ts">
import { vMaska } from 'maska/vue'
import CreditDebitCardIcon from '@bitrix24/b24icons-vue/main/CreditDebitCardIcon'
import CalendarIcon from '@bitrix24/b24icons-vue/outline/CalendarIcon'
</script>

<template>
  <div class="flex flex-col gap-2">
    <B24Input v-maska="'#### #### #### ####'" placeholder="4242 4242 4242 4242" :icon="CreditDebitCardIcon" />

    <div class="flex items-center gap-2">
      <B24Input v-maska="'##/##'" placeholder="MM/YY" :icon="CalendarIcon" />
      <B24Input v-maska="'###'" placeholder="CVC" />
    </div>
  </div>
</template>

With floating label

You can use the #default slot to add a floating label to the Input.

<script setup lang="ts">
const value = ref('')
</script>

<template>
  <B24Input v-model="value" placeholder="" :b24ui="{ base: 'peer' }">
    <label class="pointer-events-none absolute left-0 -top-[10px] text-(--b24ui-typography-label-color) text-(length:--ui-font-size-xs)/(--ui-font-line-height-reset) font-(--ui-font-weight-medium) px-1.5 transition-all peer-focus:-top-[10px] peer-focus:text-(--b24ui-typography-label-color) peer-focus:text-(length:--ui-font-size-xs)/(--ui-font-line-height-reset) peer-focus:font-(--ui-font-weight-medium) peer-placeholder-shown:text-(length:--ui-font-size-sm)/(--ui-font-line-height-reset) peer-placeholder-shown:text-(--b24ui-typography-legend-color) peer-placeholder-shown:top-[10px] peer-placeholder-shown:font-(--ui-font-weight-normal)">
      <span class="inline-flex bg-(--ui-color-base-white-fixed) px-1">Email address</span>
    </label>
  </B24Input>
</template>

Within a FormField

You can use the Input within a FormField component to display a label, help text, required indicator, etc.

We won't share your email.
<script setup lang="ts">
import Bitrix24Icon from '@bitrix24/b24icons-vue/common-service/Bitrix24Icon'

const email = ref('')
</script>

<template>
  <B24FormField
    label="Email"
    help="We won't share your email."
    required
  >
    <B24Input
      v-model="email"
      placeholder="Enter your email"
      :icon="Bitrix24Icon"
    />
  </B24FormField>
</template>
It also provides validation and error handling when used within a Form component.

Within a FieldGroup

You can use the Input within a FieldGroup component to group multiple elements together.

https://

<script setup lang="ts">
const value = ref('')
const domains = ['.com', '.dev', '.org']
const domain = ref(domains[0])
</script>

<template>
  <B24FieldGroup>
    <B24Input
      v-model="value"
      placeholder="bitrix24"
      :b24ui="{
        base: 'pl-[48px]',
        leading: 'pointer-events-none'
      }"
    >
      <template #leading>
        <p class="text-(length:--ui-font-size-xs)/(--ui-font-line-height-reset) text-(--b24ui-typography-label-color)">
          https://
        </p>
      </template>
    </B24Input>

    <B24SelectMenu
      v-model="domain"
      :items="domains"
      class="w-[85px]"
      :content="{ align: 'end', side: 'bottom', sideOffset: 4 }"
    />
  </B24FieldGroup>
</template>

API

Props

Prop Default Type
as'div'any

The element or component this component should render as.

id string
name string
type'text' "number" | "image" | "text" | "button" | "search" | "time" | "color" | "checkbox" | "date" | "datetime-local" | "email" | "file" | "hidden" | "month" | "password" | "radio" | "range" | "reset" | "submit" | "tel" | "url" | "week" | string & {}
placeholder string

The placeholder text when the input is empty.

color'air-primary'"air-primary" | "air-primary-success" | "air-primary-alert" | "air-primary-warning" | "air-primary-copilot"
size'md' "xss" | "xs" | "sm" | "md" | "lg" | "xl"
noPaddingfalseboolean

Removes padding from input

noBorderfalseboolean

Removes all borders (rings)

underlinefalseboolean

Removes all borders (rings) except the bottom one

roundedfalseboolean

Rounds the corners of the input

requiredfalseboolean
autocomplete'off' string
autofocusfalseboolean
autofocusDelay0 number
disabledfalseboolean
tag string
tagColor'air-primary'"air-primary" | "air-primary-success" | "air-primary-alert" | "air-primary-warning" | "air-primary-copilot" | "air-secondary" | "air-secondary-alert" | "air-secondary-accent" | "air-secondary-accent-1" | "air-secondary-accent-2" | "air-tertiary" | "air-selection"
highlightboolean

Highlight the ring color like a focus state.

modelValue null | string | number | bigint | false | true
defaultValue null | string | number | bigint | false | true
modelModifiers ModelModifiers<AcceptableValue>
iconIconComponent

Display an icon on the left side.

avatar AvatarProps

Display an avatar on the left side.

  • as?: any

    The element or component this component should render as. Defaults to 'span'.

  • src?: string
  • alt?: string
  • icon?: IconComponent

    Display an icon on the left side.

  • text?: string
  • size?: "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl"

    Defaults to 'md'.

  • chip?: boolean | ChipProps
  • class?: any
  • style?: any
  • b24ui?: { root?: ClassNameValue; image?: ClassNameValue; fallback?: ClassNameValue; icon?: ClassNameValue; }
  • loading?: "eager" | "lazy"
  • crossorigin?: "" | "anonymous" | "use-credentials"
  • decoding?: "async" | "auto" | "sync"
  • height?: Numberish
  • referrerpolicy?: HTMLAttributeReferrerPolicy
  • sizes?: string
  • srcset?: string
  • usemap?: string
  • width?: Numberish
loadingboolean

When true, the loading icon will be displayed.

trailingboolean

When true, the icon will be displayed on the right side.

trailingIconIconComponent

Display an icon on the right side.

list string
max string | number
maxlength string | number
min string | number
minlength string | number
pattern string
readonly false | true | "true" | "false"
step string | number
b24ui { root?: ClassNameValue; base?: ClassNameValue; leading?: ClassNameValue; leadingIcon?: ClassNameValue; leadingAvatar?: ClassNameValue; leadingAvatarSize?: ClassNameValue; trailing?: ClassNameValue; trailingIcon?: ClassNameValue; tag?: ClassNameValue; }
This component also supports all native <input> HTML attributes.

Slots

Slot Type
leading{ b24ui: object; }
default{ b24ui: object; }
trailing{ b24ui: object; }

Emits

Event Type
update:modelValue[value: AcceptableValue]
blur[event: FocusEvent]
change[event: Event]

Expose

When accessing the component via a template ref, you can use the following:

NameType
inputRefRef<HTMLInputElement | null>

Theme

app.config.ts
export default defineAppConfig({
  b24ui: {
    input: {
      slots: {
        root: 'isolate relative inline-flex items-center',
        base: 'px-3 w-full py-0 border-0 focus:outline-none disabled:cursor-not-allowed disabled:pointer-events-none disabled:select-none disabled:opacity-30 disabled:resize-none appearance-none transition duration-300 ease-linear text-(--ui-color-base-1) style-blurred-bg-input placeholder:text-(--ui-color-design-plain-na-content-secondary) hover:text-(--ui-color-base-1) focus:text-(--ui-color-base-1) active:text-(--ui-color-base-1) font-[family-name:var(--ui-font-family-primary)] font-(--ui-font-weight-regular) align-middle text-ellipsis whitespace-nowrap',
        leading: 'absolute inset-y-0 start-0 flex items-center',
        leadingIcon: 'shrink-0 text-(--b24ui-icon-color)',
        leadingAvatar: 'shrink-0',
        leadingAvatarSize: '',
        trailing: 'absolute inset-y-0 end-0 flex items-center',
        trailingIcon: 'shrink-0 text-(--b24ui-icon-color)',
        tag: 'pointer-events-none select-none absolute z-10 -top-[7px] right-[14px] flex flex-col justify-center items-center'
      },
      variants: {
        fieldGroup: {
          horizontal: {
            root: 'group leading-none has-focus-visible:z-[1]',
            base: 'focus-visible:outline-none ring ring-inset ring-1 focus-visible:ring-2 group-not-only:group-first:rounded-e-3xl group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none group-not-only:group-first:rounded-e-none group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none group-not-only:group-first:border-e-0 group-not-only:group-not-first:border-s-0'
          },
          vertical: {
            root: 'group has-focus-visible:z-[1]',
            base: 'focus-visible:outline-none ring ring-inset ring-1 focus-visible:ring-2 group-not-only:group-first:rounded-b-none group-not-only:group-last:rounded-t-none group-not-last:group-not-first:rounded-none'
          }
        },
        noSplit: {
          false: "group-not-only:not-first:after:content-[''] group-not-only:not-first:after:absolute group-not-only:not-first:after:top-[7px] group-not-only:not-first:after:bottom-[6px] group-not-only:not-first:after:left-0 group-not-only:not-first:after:w-px group-not-only:not-first:after:bg-current/30"
        },
        size: {
          xss: {
            base: 'h-[20px] gap-1 text-(length:--ui-font-size-4xs)/[normal]',
            leading: 'px-1',
            trailing: 'px-1',
            leadingIcon: 'size-[12px]',
            leadingAvatarSize: '3xs',
            trailingIcon: 'size-[12px]'
          },
          xs: {
            base: 'h-[24px] gap-1 text-(length:--ui-font-size-xs)/[normal]',
            leading: 'px-1',
            trailing: 'px-1',
            leadingIcon: 'size-[14px]',
            leadingAvatarSize: '3xs',
            trailingIcon: 'size-[14px]'
          },
          sm: {
            base: 'h-[28px] gap-1.5 text-(length:--ui-font-size-sm)/[normal]',
            leading: 'px-1.5',
            trailing: 'px-1.5',
            leadingIcon: 'size-[16px]',
            leadingAvatar: 'size-[16px]',
            leadingAvatarSize: '2xs',
            trailingIcon: 'size-[16px]'
          },
          md: {
            base: 'h-[34px] gap-1.5 text-(length:--ui-font-size-lg)/[normal]',
            leading: 'px-2',
            trailing: 'px-2',
            leadingIcon: 'size-[18px]',
            leadingAvatarSize: '2xs',
            trailingIcon: 'size-[18px]'
          },
          lg: {
            base: 'h-[38px] gap-2 text-(length:--ui-font-size-lg)/[normal]',
            leading: 'px-2',
            trailing: 'px-2',
            leadingIcon: 'size-[22px]',
            leadingAvatarSize: '2xs',
            trailingIcon: 'size-[22px]'
          },
          xl: {
            base: 'h-[46px] gap-2 text-(length:--ui-font-size-2xl)/[normal]',
            leading: 'px-2',
            trailing: 'px-2',
            leadingIcon: 'size-[22px]',
            leadingAvatarSize: '2xs',
            trailingIcon: 'size-[22px]'
          }
        },
        color: {
          'air-primary': {
            base: 'style-filled'
          },
          'air-primary-success': {
            base: 'style-filled-success'
          },
          'air-primary-alert': {
            base: 'style-filled-alert'
          },
          'air-primary-copilot': {
            base: 'style-filled-copilot'
          },
          'air-primary-warning': {
            base: 'style-filled-warning'
          },
          default: {
            base: 'style-old-default'
          },
          danger: {
            base: 'style-old-danger'
          },
          success: {
            base: 'style-old-success'
          },
          warning: {
            base: 'style-old-warning'
          },
          primary: {
            base: 'style-old-primary'
          },
          secondary: {
            base: 'style-old-secondary'
          },
          collab: {
            base: 'style-old-collab'
          },
          ai: {
            base: 'style-old-ai'
          }
        },
        rounded: {
          true: 'rounded-(--ui-border-radius-3xl)',
          false: 'rounded-(--ui-border-radius-sm)'
        },
        noPadding: {
          true: {
            base: 'px-0'
          }
        },
        noBorder: {
          true: 'ring-0 focus-visible:ring-0 style-transparent-bg'
        },
        underline: {
          true: 'rounded-none ring-0 focus-visible:ring-0 style-transparent-bg border-b-1 border-b-(--ui-color-design-outline-stroke)'
        },
        leading: {
          true: ''
        },
        trailing: {
          true: ''
        },
        loading: {
          true: ''
        },
        highlight: {
          true: 'ring ring-inset ring-(--b24ui-border-color)'
        },
        type: {
          file: 'file:me-1.5 file:text-(--ui-color-design-plain-na-content-secondary) file:outline-none'
        }
      },
      compoundVariants: [
        {
          highlight: false,
          noBorder: false,
          underline: false,
          class: {
            base: 'ring ring-inset ring-(--ui-color-design-outline-stroke) focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-(--b24ui-border-color) hover:not-disabled:not-data-disabled:ring-1 hover:not-disabled:not-data-disabled:ring-inset hover:not-disabled:not-data-disabled:ring-(--b24ui-border-color) data-[state=open]:ring-1 data-[state=open]:ring-inset data-[state=open]:ring-(--b24ui-border-color)'
          }
        },
        {
          highlight: true,
          noBorder: false,
          underline: false,
          class: {
            base: 'ring ring-inset ring-(--b24ui-border-color) focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-(--b24ui-border-color) hover:ring-1 hover:ring-inset hover:ring-(--b24ui-border-color) data-[state=open]:ring-1 data-[state=open]:ring-inset data-[state=open]:ring-(--b24ui-border-color)'
          }
        },
        {
          noBorder: false,
          underline: true,
          class: {
            base: 'focus-visible:border-(--b24ui-border-color) hover:border-(--b24ui-border-color) data-[state=open]:border-(--b24ui-border-color)'
          }
        },
        {
          highlight: true,
          noBorder: false,
          underline: true,
          class: {
            base: 'ring-0 border-b-(--b24ui-border-color)'
          }
        },
        {
          highlight: true,
          noBorder: true,
          underline: false,
          class: {
            base: 'ring-0'
          }
        },
        {
          type: 'file',
          size: 'xss',
          class: 'py-[2px]'
        },
        {
          type: 'file',
          size: 'xs',
          class: 'py-[4px]'
        },
        {
          type: 'file',
          size: 'sm',
          class: 'py-[5px]'
        },
        {
          type: 'file',
          size: 'md',
          class: 'py-[7px]'
        },
        {
          type: 'file',
          size: 'lg',
          class: 'py-[9px]'
        },
        {
          type: 'file',
          size: 'xl',
          class: 'py-[11px]'
        },
        {
          leading: true,
          noPadding: false,
          size: 'xss',
          class: 'ps-[20px]'
        },
        {
          leading: true,
          noPadding: false,
          size: 'xs',
          class: 'ps-[22px]'
        },
        {
          leading: true,
          noPadding: false,
          size: 'sm',
          class: 'ps-[28px]'
        },
        {
          leading: true,
          noPadding: false,
          size: 'md',
          class: 'ps-[32px]'
        },
        {
          leading: true,
          noPadding: false,
          size: 'lg',
          class: 'ps-[32px]'
        },
        {
          leading: true,
          noPadding: false,
          size: 'xl',
          class: 'ps-[32px]'
        },
        {
          trailing: true,
          noPadding: false,
          size: 'xss',
          class: 'pe-[20px]'
        },
        {
          trailing: true,
          noPadding: false,
          size: 'xs',
          class: 'pe-[22px]'
        },
        {
          trailing: true,
          noPadding: false,
          size: 'sm',
          class: 'pe-[28px]'
        },
        {
          trailing: true,
          noPadding: false,
          size: 'md',
          class: 'pe-[34px]'
        },
        {
          trailing: true,
          noPadding: false,
          size: 'lg',
          class: 'pe-[38px]'
        },
        {
          trailing: true,
          noPadding: false,
          size: 'xl',
          class: 'pe-[38px]'
        },
        {
          loading: true,
          leading: true,
          class: {
            leadingIcon: 'size-[21px]'
          }
        },
        {
          loading: true,
          leading: false,
          trailing: true,
          class: {
            trailingIcon: 'size-[21px]'
          }
        },
        {
          fieldGroup: [
            'horizontal',
            'vertical'
          ],
          size: [
            'xl',
            'lg',
            'md'
          ],
          rounded: false,
          class: 'rounded-(--ui-border-radius-md)'
        },
        {
          fieldGroup: [
            'horizontal',
            'vertical'
          ],
          size: 'sm',
          rounded: false,
          class: 'rounded-(--ui-border-radius-sm)'
        },
        {
          fieldGroup: [
            'horizontal',
            'vertical'
          ],
          size: 'xs',
          rounded: false,
          class: 'rounded-(--ui-border-radius-xs)'
        },
        {
          fieldGroup: [
            'horizontal',
            'vertical'
          ],
          size: 'xss',
          rounded: false,
          class: 'rounded-[5px]'
        }
      ],
      defaultVariants: {
        color: 'air-primary',
        size: 'md'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import bitrix24UIPluginVite from '@bitrix24/b24ui-nuxt/vite'

export default defineConfig({
  plugins: [
    vue(),
    bitrix24UIPluginVite({
      b24ui: {
        input: {
          slots: {
            root: 'isolate relative inline-flex items-center',
            base: 'px-3 w-full py-0 border-0 focus:outline-none disabled:cursor-not-allowed disabled:pointer-events-none disabled:select-none disabled:opacity-30 disabled:resize-none appearance-none transition duration-300 ease-linear text-(--ui-color-base-1) style-blurred-bg-input placeholder:text-(--ui-color-design-plain-na-content-secondary) hover:text-(--ui-color-base-1) focus:text-(--ui-color-base-1) active:text-(--ui-color-base-1) font-[family-name:var(--ui-font-family-primary)] font-(--ui-font-weight-regular) align-middle text-ellipsis whitespace-nowrap',
            leading: 'absolute inset-y-0 start-0 flex items-center',
            leadingIcon: 'shrink-0 text-(--b24ui-icon-color)',
            leadingAvatar: 'shrink-0',
            leadingAvatarSize: '',
            trailing: 'absolute inset-y-0 end-0 flex items-center',
            trailingIcon: 'shrink-0 text-(--b24ui-icon-color)',
            tag: 'pointer-events-none select-none absolute z-10 -top-[7px] right-[14px] flex flex-col justify-center items-center'
          },
          variants: {
            fieldGroup: {
              horizontal: {
                root: 'group leading-none has-focus-visible:z-[1]',
                base: 'focus-visible:outline-none ring ring-inset ring-1 focus-visible:ring-2 group-not-only:group-first:rounded-e-3xl group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none group-not-only:group-first:rounded-e-none group-not-only:group-last:rounded-s-none group-not-last:group-not-first:rounded-none group-not-only:group-first:border-e-0 group-not-only:group-not-first:border-s-0'
              },
              vertical: {
                root: 'group has-focus-visible:z-[1]',
                base: 'focus-visible:outline-none ring ring-inset ring-1 focus-visible:ring-2 group-not-only:group-first:rounded-b-none group-not-only:group-last:rounded-t-none group-not-last:group-not-first:rounded-none'
              }
            },
            noSplit: {
              false: "group-not-only:not-first:after:content-[''] group-not-only:not-first:after:absolute group-not-only:not-first:after:top-[7px] group-not-only:not-first:after:bottom-[6px] group-not-only:not-first:after:left-0 group-not-only:not-first:after:w-px group-not-only:not-first:after:bg-current/30"
            },
            size: {
              xss: {
                base: 'h-[20px] gap-1 text-(length:--ui-font-size-4xs)/[normal]',
                leading: 'px-1',
                trailing: 'px-1',
                leadingIcon: 'size-[12px]',
                leadingAvatarSize: '3xs',
                trailingIcon: 'size-[12px]'
              },
              xs: {
                base: 'h-[24px] gap-1 text-(length:--ui-font-size-xs)/[normal]',
                leading: 'px-1',
                trailing: 'px-1',
                leadingIcon: 'size-[14px]',
                leadingAvatarSize: '3xs',
                trailingIcon: 'size-[14px]'
              },
              sm: {
                base: 'h-[28px] gap-1.5 text-(length:--ui-font-size-sm)/[normal]',
                leading: 'px-1.5',
                trailing: 'px-1.5',
                leadingIcon: 'size-[16px]',
                leadingAvatar: 'size-[16px]',
                leadingAvatarSize: '2xs',
                trailingIcon: 'size-[16px]'
              },
              md: {
                base: 'h-[34px] gap-1.5 text-(length:--ui-font-size-lg)/[normal]',
                leading: 'px-2',
                trailing: 'px-2',
                leadingIcon: 'size-[18px]',
                leadingAvatarSize: '2xs',
                trailingIcon: 'size-[18px]'
              },
              lg: {
                base: 'h-[38px] gap-2 text-(length:--ui-font-size-lg)/[normal]',
                leading: 'px-2',
                trailing: 'px-2',
                leadingIcon: 'size-[22px]',
                leadingAvatarSize: '2xs',
                trailingIcon: 'size-[22px]'
              },
              xl: {
                base: 'h-[46px] gap-2 text-(length:--ui-font-size-2xl)/[normal]',
                leading: 'px-2',
                trailing: 'px-2',
                leadingIcon: 'size-[22px]',
                leadingAvatarSize: '2xs',
                trailingIcon: 'size-[22px]'
              }
            },
            color: {
              'air-primary': {
                base: 'style-filled'
              },
              'air-primary-success': {
                base: 'style-filled-success'
              },
              'air-primary-alert': {
                base: 'style-filled-alert'
              },
              'air-primary-copilot': {
                base: 'style-filled-copilot'
              },
              'air-primary-warning': {
                base: 'style-filled-warning'
              },
              default: {
                base: 'style-old-default'
              },
              danger: {
                base: 'style-old-danger'
              },
              success: {
                base: 'style-old-success'
              },
              warning: {
                base: 'style-old-warning'
              },
              primary: {
                base: 'style-old-primary'
              },
              secondary: {
                base: 'style-old-secondary'
              },
              collab: {
                base: 'style-old-collab'
              },
              ai: {
                base: 'style-old-ai'
              }
            },
            rounded: {
              true: 'rounded-(--ui-border-radius-3xl)',
              false: 'rounded-(--ui-border-radius-sm)'
            },
            noPadding: {
              true: {
                base: 'px-0'
              }
            },
            noBorder: {
              true: 'ring-0 focus-visible:ring-0 style-transparent-bg'
            },
            underline: {
              true: 'rounded-none ring-0 focus-visible:ring-0 style-transparent-bg border-b-1 border-b-(--ui-color-design-outline-stroke)'
            },
            leading: {
              true: ''
            },
            trailing: {
              true: ''
            },
            loading: {
              true: ''
            },
            highlight: {
              true: 'ring ring-inset ring-(--b24ui-border-color)'
            },
            type: {
              file: 'file:me-1.5 file:text-(--ui-color-design-plain-na-content-secondary) file:outline-none'
            }
          },
          compoundVariants: [
            {
              highlight: false,
              noBorder: false,
              underline: false,
              class: {
                base: 'ring ring-inset ring-(--ui-color-design-outline-stroke) focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-(--b24ui-border-color) hover:not-disabled:not-data-disabled:ring-1 hover:not-disabled:not-data-disabled:ring-inset hover:not-disabled:not-data-disabled:ring-(--b24ui-border-color) data-[state=open]:ring-1 data-[state=open]:ring-inset data-[state=open]:ring-(--b24ui-border-color)'
              }
            },
            {
              highlight: true,
              noBorder: false,
              underline: false,
              class: {
                base: 'ring ring-inset ring-(--b24ui-border-color) focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-(--b24ui-border-color) hover:ring-1 hover:ring-inset hover:ring-(--b24ui-border-color) data-[state=open]:ring-1 data-[state=open]:ring-inset data-[state=open]:ring-(--b24ui-border-color)'
              }
            },
            {
              noBorder: false,
              underline: true,
              class: {
                base: 'focus-visible:border-(--b24ui-border-color) hover:border-(--b24ui-border-color) data-[state=open]:border-(--b24ui-border-color)'
              }
            },
            {
              highlight: true,
              noBorder: false,
              underline: true,
              class: {
                base: 'ring-0 border-b-(--b24ui-border-color)'
              }
            },
            {
              highlight: true,
              noBorder: true,
              underline: false,
              class: {
                base: 'ring-0'
              }
            },
            {
              type: 'file',
              size: 'xss',
              class: 'py-[2px]'
            },
            {
              type: 'file',
              size: 'xs',
              class: 'py-[4px]'
            },
            {
              type: 'file',
              size: 'sm',
              class: 'py-[5px]'
            },
            {
              type: 'file',
              size: 'md',
              class: 'py-[7px]'
            },
            {
              type: 'file',
              size: 'lg',
              class: 'py-[9px]'
            },
            {
              type: 'file',
              size: 'xl',
              class: 'py-[11px]'
            },
            {
              leading: true,
              noPadding: false,
              size: 'xss',
              class: 'ps-[20px]'
            },
            {
              leading: true,
              noPadding: false,
              size: 'xs',
              class: 'ps-[22px]'
            },
            {
              leading: true,
              noPadding: false,
              size: 'sm',
              class: 'ps-[28px]'
            },
            {
              leading: true,
              noPadding: false,
              size: 'md',
              class: 'ps-[32px]'
            },
            {
              leading: true,
              noPadding: false,
              size: 'lg',
              class: 'ps-[32px]'
            },
            {
              leading: true,
              noPadding: false,
              size: 'xl',
              class: 'ps-[32px]'
            },
            {
              trailing: true,
              noPadding: false,
              size: 'xss',
              class: 'pe-[20px]'
            },
            {
              trailing: true,
              noPadding: false,
              size: 'xs',
              class: 'pe-[22px]'
            },
            {
              trailing: true,
              noPadding: false,
              size: 'sm',
              class: 'pe-[28px]'
            },
            {
              trailing: true,
              noPadding: false,
              size: 'md',
              class: 'pe-[34px]'
            },
            {
              trailing: true,
              noPadding: false,
              size: 'lg',
              class: 'pe-[38px]'
            },
            {
              trailing: true,
              noPadding: false,
              size: 'xl',
              class: 'pe-[38px]'
            },
            {
              loading: true,
              leading: true,
              class: {
                leadingIcon: 'size-[21px]'
              }
            },
            {
              loading: true,
              leading: false,
              trailing: true,
              class: {
                trailingIcon: 'size-[21px]'
              }
            },
            {
              fieldGroup: [
                'horizontal',
                'vertical'
              ],
              size: [
                'xl',
                'lg',
                'md'
              ],
              rounded: false,
              class: 'rounded-(--ui-border-radius-md)'
            },
            {
              fieldGroup: [
                'horizontal',
                'vertical'
              ],
              size: 'sm',
              rounded: false,
              class: 'rounded-(--ui-border-radius-sm)'
            },
            {
              fieldGroup: [
                'horizontal',
                'vertical'
              ],
              size: 'xs',
              rounded: false,
              class: 'rounded-(--ui-border-radius-xs)'
            },
            {
              fieldGroup: [
                'horizontal',
                'vertical'
              ],
              size: 'xss',
              rounded: false,
              class: 'rounded-[5px]'
            }
          ],
          defaultVariants: {
            color: 'air-primary',
            size: 'md'
          }
        }
      }
    })
  ]
})

FormField

A container for form elements with built-in validation and error management.

InputDate

A date selection input field.

On this page

  • Usage
    • Type
    • Placeholder
    • Color
    • Tag
    • Size
    • Icon
    • Trailing Icon
    • Avatar
    • Loading
    • Disabled
    • No padding
    • No border
    • Underline
    • Rounded
  • Examples
    • With clear button
    • With copy button
    • With password toggle
    • With password strength indicator
    • With character limit
    • With keyboard shortcut
    • With mask
    • With floating label
    • Within a FormField
    • Within a FieldGroup
  • API
    • Props
    • Slots
    • Emits
    • Expose
  • Theme
Releases
Published under MIT License.

Copyright © 2024-present Bitrix24