npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fiscozen/input

v3.0.3

Published

Design System Input component

Readme

@fiscozen/input

Flexible input component library for Vue 3 applications, featuring icon support, validation states, multiple variants, and specialized currency input with number formatting.

Features

  • Multiple Input Types: text, password, email, number, tel, url
  • Icon Support: Left and right icons (static or clickable buttons)
  • Validation States: Error and valid states with visual feedback
  • Two Variants: Normal and floating-label presentation
  • Two Environments: frontoffice and backoffice (different heights and styling)
  • Currency Input: Specialized component with locale-aware number formatting
  • Full Accessibility: ARIA attributes, keyboard navigation, screen reader support
  • Customizable: Slots for label, icons, help text, and error messages
  • TypeScript: Full type safety with TypeScript definitions

Installation

npm install @fiscozen/input

Components

This package exports two components:

  • FzInput - Standard input with label, icons, and validation states
  • FzCurrencyInput - Specialized currency input with number formatting and validation

Basic Usage

FzInput

<script setup lang="ts">
import { FzInput } from '@fiscozen/input'
import { ref } from 'vue'

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

<template>
  <FzInput label="Email" type="email" v-model="email" />
</template>

FzCurrencyInput

<script setup lang="ts">
import { FzCurrencyInput } from '@fiscozen/input'
import { ref } from 'vue'

const amount = ref<number | undefined>(undefined)
</script>

<template>
  <FzCurrencyInput label="Amount" v-model="amount" />
</template>

Props

FzInput Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | label | string | - | Text label displayed above the input field. Overridden by label slot if provided. | | environment | 'backoffice' \| 'frontoffice' | 'frontoffice' | Environment determining input size and styling | | size | 'sm' \| 'md' \| 'lg' | - | Deprecated: Use environment prop instead. Size values map to environments: sm/md → backoffice, lg → frontoffice | | placeholder | string | - | Placeholder text shown when input is empty. Behavior differs based on variant. | | required | boolean | false | Marks input as required. Adds asterisk to label and sets native required attribute. | | disabled | boolean | false | Disables input interaction and applies disabled styling | | error | boolean | false | Shows error state with red border and enables errorMessage slot display | | valid | boolean | false | Shows success checkmark icon on the right when true. Takes precedence over rightIcon | | variant | 'normal' \| 'floating-label' | 'normal' | Visual presentation style. 'floating-label' moves placeholder above input when focused/filled | | type | 'text' \| 'password' \| 'email' \| 'number' \| 'tel' \| 'url' | 'text' | Native HTML input type. Determines keyboard layout and validation behavior | | leftIcon | string | - | Font Awesome icon name displayed on the left side of input | | leftIconVariant | IconVariant | - | Visual style variant for left icon (solid, regular, light, etc.) | | leftIconButtonVariant | IconButtonVariant | - | Button variant for left icon when rendered as clickable button | | leftIconAriaLabel | string | - | Accessible label for left icon when clickable. Required for screen reader accessibility | | rightIcon | string | - | Font Awesome icon name displayed on the right side of input | | rightIconSize | IconSize | - | Deprecated: Size override for right icon. Icons now have a fixed size of "md". This prop is ignored. | | rightIconVariant | IconVariant | - | Visual style variant for right icon (solid, regular, light, etc.) | | rightIconButton | boolean | false | Renders right icon as clickable button instead of static icon | | rightIconButtonVariant | IconButtonVariant | 'invisible' | Button variant for right icon when rightIconButton is true | | rightIconAriaLabel | string | - | Accessible label for right icon when clickable. Required for screen reader accessibility | | secondRightIcon | string | - | Font Awesome icon name displayed as second icon on the right side of input. Order: secondRightIcon > rightIcon > valid (all can be present simultaneously) | | secondRightIconClass | string | - | Additional CSS classes applied to second right icon container | | secondRightIconVariant | IconVariant | - | Visual style variant for second right icon (solid, regular, light, etc.) | | secondRightIconButton | boolean | false | Renders second right icon as clickable button instead of static icon | | secondRightIconButtonVariant | IconButtonVariant | 'invisible' | Button variant for second right icon when secondRightIconButton is true | | secondRightIconAriaLabel | string | - | Accessible label for second right icon when clickable. Required for screen reader accessibility | | pattern | string | - | HTML5 pattern attribute for native browser validation | | name | string | - | Native name attribute for form submission and identification | | readonly | boolean | false | Native readonly attribute. Prevents user input while keeping field focusable | | maxlength | number | - | Native maxlength attribute. Limits maximum number of characters | | autocomplete | boolean | false | Native autocomplete attribute. Controls browser autocomplete and suggestions. When false, sets autocomplete="off" to disable browser autocomplete | | rightIconClass | string | - | Additional CSS classes applied to right icon container | | leftIconClass | string | - | Additional CSS classes applied to left icon container |

FzCurrencyInput Props

FzCurrencyInput extends FzInput props (except type, modelValue, rightIcon, rightIconSize, rightIconVariant, rightIconButton, rightIconButtonVariant, rightIconAriaLabel, rightIconClass, secondRightIcon, secondRightIconClass, secondRightIconVariant, secondRightIconButton, secondRightIconButtonVariant, secondRightIconAriaLabel) and adds:

| Prop | Type | Default | Description | |------|------|---------|-------------| | modelValue | number \| string \| undefined | - | Type assertion: Accepts number \| string \| undefined as input, but always emits number \| undefined (never string). Strings are deprecated and trigger a console warning. See v-model Type Behavior for details. | | nullOnEmpty | boolean | false | Converts empty input to null instead of 0 | | minimumFractionDigits | number | 2 | Minimum decimal places in formatted output | | maximumFractionDigits | number | 2 | Maximum decimal places in formatted output | | min | number | - | Minimum allowed value. Values below this are clamped to min | | max | number | - | Maximum allowed value. Values above this are clamped to max | | step | number | 1 | Step increment for arrow buttons. When forceStep is true, values are rounded to nearest step multiple | | forceStep | boolean | false | Enforces quantization: values are automatically rounded to nearest step multiple | | stepUpAriaLabel | string | - | Custom accessible label for step up button. If not provided, uses default label | | stepDownAriaLabel | string | - | Custom accessible label for step down button. If not provided, uses default label |

Note: rightIcon and secondRightIcon props are not available in FzCurrencyInput. Only valid checkmark icon can be displayed alongside step controls.

Slots

| Slot | Description | |------|-------------| | label | Custom label content (overrides label prop) | | left-icon | Custom left icon content (overrides leftIcon prop) | | right-icon | Custom right icon content (overrides rightIcon prop and valid checkmark) | | helpText | Help text displayed below input when no error is present | | errorMessage | Error message displayed below input when error is true |

Variants

Normal (Default)

Standard input with label above and placeholder inside the input field.

<FzInput label="Email" type="email" placeholder="Enter your email" v-model="email" />

Floating Label

Floating label variant moves placeholder above input when focused or when input has a value.

<FzInput 
  label="Email" 
  variant="floating-label" 
  placeholder="Enter your email" 
  v-model="email" 
/>

Environments

Inputs support two environments that determine their height and styling:

  • frontoffice (default): larger spacing
  • backoffice: compact spacing
<template>
  <FzInput label="Frontoffice (Default)" environment="frontoffice" v-model="value1" />
  <FzInput label="Backoffice" environment="backoffice" v-model="value2" />
</template>

Note: The size prop is deprecated. Use environment instead.

Input Types

Text

<FzInput label="Name" type="text" v-model="name" />

Password

<FzInput label="Password" type="password" v-model="password" />

Email

<FzInput label="Email" type="email" required v-model="email" />

Number

<FzInput label="Age" type="number" v-model="age" />

Telephone

<FzInput 
  label="Phone" 
  type="tel" 
  pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" 
  v-model="phone" 
/>

URL

<FzInput label="Website" type="url" v-model="website" />

States

Required

Required inputs show an asterisk (*) next to the label and set the native required attribute.

<FzInput label="Email" type="email" required v-model="email" />

Disabled

Disabled inputs prevent user interaction and apply muted styling.

<FzInput label="Disabled Input" disabled v-model="value" />

Error

Error state shows red border and displays error message via errorMessage slot.

<FzInput label="Email" type="email" :error="hasError" v-model="email">
  <template #errorMessage>Please enter a valid email address</template>
</FzInput>

Valid

Valid state shows a green checkmark icon on the right side.

<FzInput label="Email" type="email" :valid="isValid" v-model="email" />

Readonly

Readonly inputs prevent editing but remain focusable and visible.

<FzInput label="Read-only Value" readonly v-model="readonlyValue" />

With Icons

Left Icon

<FzInput 
  label="Date" 
  leftIcon="calendar-lines" 
  v-model="date" 
/>

Right Icon

<FzInput 
  label="Search" 
  rightIcon="magnifying-glass" 
  v-model="search" 
/>

Right Icon as Button

Right icon can be rendered as a clickable button (useful for password visibility toggle, clear button, etc.).

<template>
  <FzInput 
    label="Password" 
    :type="passwordType"
    rightIcon="eye"
    :rightIconButton="true"
    rightIconButtonVariant="secondary"
    rightIconAriaLabel="Toggle password visibility"
    @fzinput:right-icon-click="togglePasswordVisibility"
    v-model="password" 
  />
</template>

<script setup>
import { ref } from 'vue'

const passwordType = ref('password')
const password = ref('')

const togglePasswordVisibility = () => {
  passwordType.value = passwordType.value === 'password' ? 'text' : 'password'
}
</script>

Clickable Icons with Accessibility

When icons are clickable, provide leftIconAriaLabel or rightIconAriaLabel for keyboard accessibility:

<FzInput 
  label="Search" 
  leftIcon="magnifying-glass"
  leftIconAriaLabel="Open search options"
  @fzinput:left-icon-click="openSearchOptions"
  v-model="search" 
/>

Both Icons

<FzInput 
  label="Amount" 
  leftIcon="dollar-sign" 
  rightIcon="credit-card" 
  v-model="amount" 
/>

Help Text and Error Messages

Help Text

Help text is displayed below the input when no error is present.

<FzInput label="Username" v-model="username">
  <template #helpText>
    Username must be between 3 and 20 characters
  </template>
</FzInput>

Error Message

Error message is displayed below the input when error prop is true.

<FzInput label="Email" type="email" :error="hasError" v-model="email">
  <template #errorMessage>
    Please enter a valid email address
  </template>
</FzInput>

Custom Label

You can provide custom label content using the label slot.

<FzInput v-model="value">
  <template #label>
    <strong>Custom Label</strong> with <em>formatting</em>
  </template>
</FzInput>

Examples

Form with Validation

<template>
  <form @submit.prevent="handleSubmit">
    <FzInput 
      label="Email" 
      type="email" 
      required 
      :error="errors.email"
      v-model="form.email"
    >
      <template #errorMessage v-if="errors.email">
        {{ errors.email }}
      </template>
    </FzInput>
    
    <FzInput 
      label="Password" 
      type="password" 
      required 
      :error="errors.password"
      v-model="form.password"
    >
      <template #errorMessage v-if="errors.password">
        {{ errors.password }}
      </template>
    </FzInput>
    
    <button type="submit">Submit</button>
  </form>
</template>

<script setup>
import { ref } from 'vue'

const form = ref({
  email: '',
  password: ''
})

const errors = ref({
  email: null,
  password: null
})

const handleSubmit = () => {
  // Validation logic
}
</script>

Password with Visibility Toggle

<template>
  <FzInput 
    label="Password" 
    :type="showPassword ? 'text' : 'password'"
    rightIcon="eye"
    :rightIconButton="true"
    @fzinput:right-icon-click="togglePassword"
    v-model="password" 
  />
</template>

<script setup>
import { ref } from 'vue'

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

const togglePassword = () => {
  showPassword.value = !showPassword.value
}
</script>

Search Input

<FzInput 
  label="Search" 
  leftIcon="magnifying-glass" 
  rightIcon="xmark"
  :rightIconButton="true"
  @fzinput:right-icon-click="clearSearch"
  v-model="searchQuery" 
/>

Input with Max Length

<FzInput 
  label="PIN" 
  type="text" 
  maxlength="4" 
  pattern="[0-9]{4}"
  v-model="pin" 
/>

FzCurrencyInput

Specialized currency input component built on FzInput with number formatting, validation, and step controls. Formats values using Intl.NumberFormat with locale-aware separators.

Features

  • Locale-aware number formatting (decimal and thousand separators)
  • Min/max value constraints
  • Step quantization with arrow buttons
  • Intelligent paste parsing (detects decimal/thousand separators automatically)
  • Configurable decimal places

Basic Usage

<script setup lang="ts">
import { FzCurrencyInput } from '@fiscozen/input'
import { ref } from 'vue'

const amount = ref<number | undefined>(undefined)
</script>

<template>
  <FzCurrencyInput 
    label="Amount" 
    v-model="amount" 
    :min="0" 
    :max="1000" 
  />
</template>

With Step Controls

Step controls (arrow buttons) are always visible in FzCurrencyInput. Default step is 1, but can be customized.

<FzCurrencyInput 
  label="Quantity" 
  v-model="quantity" 
  :step="5"
/>

With Step Quantization

When forceStep is true, values are automatically rounded to the nearest step multiple.

<FzCurrencyInput 
  label="Quantity" 
  v-model="quantity" 
  :step="4"
  :forceStep="true"
/>

With Min/Max Constraints

<FzCurrencyInput 
  label="Price" 
  v-model="price" 
  :min="0" 
  :max="9999.99"
  :minimumFractionDigits="2"
  :maximumFractionDigits="2"
/>

With Valid State

Valid checkmark icon is displayed alongside step controls.

<FzCurrencyInput 
  label="Amount" 
  v-model="amount" 
  :valid="isValid"
/>

Currency Input Behavior

  • Formatting: Values are formatted using Intl.NumberFormat with locale settings (default: 'it-IT')
  • Paste Handling: Automatically detects and parses various number formats (e.g., "1.234,56", "1,234.56")
  • Step Controls: Arrow buttons are always visible (default step = 1). Support keyboard accessibility (Enter/Space to activate)
  • Step Quantization: When forceStep is true, values are automatically rounded to nearest step multiple
  • Empty Values: When nullOnEmpty is true, empty input converts to null instead of 0
  • Valid State: Valid checkmark icon can be displayed alongside step controls
  • Right Icons: rightIcon and secondRightIcon props are not available. Only valid icon is supported.

v-model Type Behavior

FzCurrencyInput uses a type assertion pattern for its v-model:

  • Accepts: number | string | undefined as input
  • Emits: Always number | undefined (never string)

Type Assertion

The component accepts number | string | undefined as input, but always emits number | undefined. Strings are automatically parsed (Italian format: "1.234,56" → 1234.56) and converted to numbers internally.

Deprecation Warning

String values are deprecated and will be removed in a future version. A console warning is shown when strings are used. Please use number | undefined instead for type safety and future compatibility.

Recommended Usage

<script setup lang="ts">
import { ref } from 'vue'

// ✅ Recommended: number | undefined (future-proof)
const amount = ref<number | undefined>(undefined)
</script>

<template>
  <FzCurrencyInput label="Amount" v-model="amount" />
</template>

Deprecated Usage (Still Works)

<script setup lang="ts">
import { ref } from 'vue'

// ⚠️ Deprecated: string (still works but shows warning)
// Strings are parsed and converted to numbers internally
const amount = ref<string>("1234,56")
</script>

<template>
  <FzCurrencyInput label="Amount" v-model="amount" />
</template>

Note: When using strings, the component will:

  1. Show a console warning about deprecation
  2. Parse the string using Italian format (points = thousands, comma = decimal)
  3. Convert it to a number internally
  4. Always emit a number | undefined value

Migration Guide

If you're currently using strings, migrate to numbers:

<!-- Before (deprecated) -->
<script setup lang="ts">
const amount = ref<string>("1234,56")
</script>

<!-- After (recommended) -->
<script setup lang="ts">
const amount = ref<number | undefined>(1234.56)
// or
const amount = ref<number | undefined>(undefined)
</script>

Accessibility

FzInput and FzCurrencyInput are fully accessible and meet WCAG 2.1 AA standards:

  • ARIA Attributes: Proper aria-required, aria-invalid, aria-disabled, aria-labelledby, aria-describedby
  • Keyboard Navigation: Full keyboard support (Tab, Enter, Space, Arrow keys)
  • Screen Readers: Error messages and help text are properly associated with inputs
  • Focus Management: Visible focus indicators with proper contrast
  • Semantic HTML: Native input elements with proper label associations
  • Error Announcements: Error messages use role="alert" for immediate screen reader announcements

ARIA Attributes

  • aria-required: Set to "true" or "false" (string values for Vue 3 compatibility)
  • aria-invalid: Set to "true" when error prop is true
  • aria-disabled: Set to "true" when disabled prop is true
  • aria-labelledby: Links to label element when label prop is provided
  • aria-describedby: Links to help text or error message when present

Error Message Accessibility

Error messages are rendered with role="alert" to ensure screen readers announce them immediately when displayed.

Behavior & Concepts

Label vs Slot Priority

When both label prop and label slot are provided, the slot takes precedence:

<FzInput label="This won't show">
  <template #label>This will show instead</template>
</FzInput>

Right Icons Display Order

The component supports three types of right-side icons that can all be displayed simultaneously:

  1. valid checkmark (when valid prop is true) - displayed first
  2. secondRightIcon (when provided) - displayed second
  3. rightIcon (when provided) - displayed third

All three icons can be visible at the same time, appearing in this order from left to right.

Floating Label Placeholder Behavior

In floating-label variant:

  • When input is empty and not focused: placeholder shows above input as floating text
  • When input has value or is focused: placeholder moves above input permanently
  • Normal placeholder attribute is hidden in this mode

Icon Button Size Mapping

Right icon buttons use a smaller size scale than inputs to maintain visual balance:

  • Input size sm → Icon button size xs
  • Input size md → Icon button size sm
  • Input size lg → Icon button size md

Notes

Input Type Behavior

Different input types provide different keyboard layouts and validation:

  • email: Triggers email keyboard on mobile devices
  • tel: Triggers numeric keyboard on mobile devices
  • number: Allows numeric input with spinner controls
  • password: Masks input characters
  • url: Validates URL format

Currency Input Formatting

FzCurrencyInput uses Intl.NumberFormat for locale-aware formatting. The formatting respects:

  • Browser locale settings
  • Minimum and maximum fraction digits
  • Decimal and thousand separator conventions

Paste Handling in Currency Input

The currency input uses intelligent heuristics to parse pasted values:

  • Multiple different separators: rightmost is decimal separator
  • Multiple same separators: thousand separator
  • Single separator with <3 digits after: decimal separator
  • Single separator with 3+ digits after: ambiguous, uses default formatting