Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip
ARC UI ARC Radiant Components
v4.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip

Password Input

Password entry field with a built-in visibility toggle and an optional four-segment strength meter. Shares its styling and form behavior with Input, so mixed forms stay visually uniform.

Components Password Input
input interactive beta
<arc-password-input>

Overview

PasswordInput is the sibling of Input specialized for secret entry. It wraps a native `<input type="password">` with the same label, placeholder, validation, and size treatment as Input, and adds two password-specific affordances: an inline eye button that toggles the field between masked and plain text, and an optional strength meter driven by a self-contained heuristic. The visibility toggle persists the user's choice — revealing the password does not silently revert on blur, which matches platform conventions and avoids surprising users mid-edit. The toggle is a real button with `aria-pressed` state and an accessible name, so screen-reader users get the same control. When `show-strength` is set, a four-segment meter and text label ("Weak" through "Strong") render under the field. The score considers length thresholds, character-class variety, and penalises repeated characters, sequential runs like "abcd" or "1234", and the most common leaked passwords. The heuristic runs entirely client-side with no network calls. The meter exposes `role="meter"` semantics and announces changes politely for assistive technology. PasswordInput participates in native forms through ElementInternals just like Input: it submits its value under `name`, supports `required` constraint validation, and resets with `form.reset()`. Use `autocomplete="new-password"` on registration and change-password forms so password managers offer to generate a credential.

Guidelines

When to use

  • Always provide a `label` so the field is accessible to screen readers
  • Set `autocomplete="new-password"` on sign-up and change-password forms so password managers can generate credentials
  • Enable `show-strength` on password-creation flows to give users live feedback
  • Listen to `arc-strength-change` if you gate submission on a minimum score
  • Pair with Form for coordinated validation and an error summary
  • Keep the `error` prop for server-side or policy failures (e.g. "Password was found in a breach")

When not to use

  • Do not show the strength meter on login forms — it only makes sense when creating a password
  • Do not treat the heuristic score as a security guarantee; enforce real policy on the server
  • Do not force the field back to masked while the user is typing — the toggle state is theirs
  • Do not use placeholder text as the only label
  • Do not block paste into the field — pasting from a password manager is a best practice

Features

  • Visibility toggle button with `aria-pressed` state and eye / eye-off iconography
  • User choice persists — the field does not re-mask on blur
  • Optional four-segment strength meter with Weak / Fair / Good / Strong label
  • Self-contained strength heuristic: length, character variety, common-password and pattern penalties
  • `arc-strength-change` event exposes the 0-4 score for custom policy UI
  • Native form participation via `ElementInternals`: submission, reset, and required validation
  • `autocomplete` pass-through (defaults to `current-password`) for password-manager integration
  • Identical field styling to Input — labels, sizes, error state, and focus rings match
  • Meter uses `role="meter"` with aria value semantics and polite live announcements

Preview

Usage

This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.

<!-- Login: masked field with visibility toggle -->
<arc-password-input label="Password" name="password" required></arc-password-input>

<!-- Sign-up: strength meter + password-manager generation -->
<arc-password-input
  label="New password"
  name="new-password"
  autocomplete="new-password"
  show-strength
  required
></arc-password-input>

<script>
  document.querySelector('[show-strength]').addEventListener('arc-strength-change', (e) => {
    console.log('strength score:', e.detail.score); // 0-4
  });
</script>
import { PasswordInput } from '@arclux/arc-ui-react';

{/* Login */}
<PasswordInput label="Password" name="password" required />

{/* Sign-up with strength meter */}
<PasswordInput
  label="New password"
  name="new-password"
  autocomplete="new-password"
  showStrength
  required
  onArcStrengthChange={(e) => setScore(e.detail.score)}
/>
<script setup>
import { PasswordInput } from '@arclux/arc-ui-vue';
</script>

<template>
  <!-- Login -->
  <PasswordInput label="Password" name="password" required />

  <!-- Sign-up with strength meter -->
  <PasswordInput
    label="New password"
    name="new-password"
    autocomplete="new-password"
    show-strength
    required
    @arc-strength-change="(e) => console.log('strength score:', e.detail.score)"
  />
</template>
<script>
  import { PasswordInput } from '@arclux/arc-ui-svelte';
</script>

<!-- Login -->
<PasswordInput label="Password" name="password" required />

<!-- Sign-up with strength meter -->
<PasswordInput
  label="New password"
  name="new-password"
  autocomplete="new-password"
  showStrength
  required
  on:arc-strength-change={(e) => console.log('strength score:', e.detail.score)}
/>
import { Component } from '@angular/core';
import { PasswordInput } from '@arclux/arc-ui-angular';

@Component({
  imports: [PasswordInput],
  template: `
    <!-- Login -->
    <arc-password-input label="Password" name="password" required></arc-password-input>

    <!-- Sign-up with strength meter -->
    <arc-password-input
      label="New password"
      name="new-password"
      autocomplete="new-password"
      showStrength
      required
      (arcStrengthChange)="onStrength($event)"
    ></arc-password-input>
  `,
})
export class PasswordFormComponent {
  onStrength(e: CustomEvent) {
    console.log('strength score:', e.detail.score);
  }
}
<div style="display:flex; flex-direction:column; width:100%; max-width:400px; gap:16px;">
  <arc-password-input label="Password" name="password" required></arc-password-input>
  <arc-password-input label="New password" name="new-password" autocomplete="new-password" show-strength required></arc-password-input>
</div>

API

autoValidates boolean false
Runs its own constraint logic — owns the whole validity flag set.
name string ''
The name attribute sent with form data on submission. Also used by the Form component to track field state.
label string ''
Visible label rendered above the field. Automatically associated with the input via a generated id.
placeholder string ''
Hint text displayed when the field is empty. Use it for guidance, never as a substitute for the label.
value string ''
The current value of the field. Can be set programmatically; updated internally on each keystroke.
disabled boolean false
Prevents interaction (including the visibility toggle) and applies a muted visual treatment.
error string ''
Error message displayed below the field. When set, the border turns red and the message is announced.
autocomplete string 'current-password'
Passed through to the inner input. Use new-password on registration or change-password forms so password managers offer generation.
required boolean false
Marks the field as required and enables native constraint validation on form submission.
size 'sm' | 'md' | 'lg' 'md'
Controls the field size. Options: 'sm', 'md', 'lg'.
showStrength boolean false
Renders a four-segment strength meter with a Weak / Fair / Good / Strong label under the field, scored by a built-in heuristic (length, character variety, common-pattern penalties).
formAssociated boolean true
properties object { // flag(), unlike `disabled`. The exclusion in props.js is specifically // about form-associated *platform* semantics: a `disabled` content // attribute that is merely present makes the element actually disabled // per the HTML spec, and formDisabledCallback assigns the property back, // so no converter can win. Neither of these is platform-mapped — // `required` is enforced by _computeValidity() below and `readonly` by // each component's own interaction handlers — so the stock converter buys // nothing here and costs the usual bug: `required="false"` read as true, // blocking submission of a form the author meant to leave optional. // Finding #48's shape, across all 26 form controls at once. required: flag(false), readonly: flag(false), }
Lit merges static properties up the prototype chain, so every consumer gets these without declaring them. required participates in constraint validation below; readonly reflects for styling and is enforced by each component's interaction handlers (the mixin can't know which gestures mutate state).
form
validity
validationMessage
readonly boolean false

Methods

checkValidity() boolean
Whether the control currently satisfies its constraints, per the native constraint-validation API. Fires invalid on the element when it does not, and reports nothing to the user.
reportValidity() boolean
As checkValidity(), but also shows the browser's validation message against the control when it fails.

Events

arc-strength-change
Fired when the strength score changes (only while show-strength is set), with { score } detail (0-4)
arc-input detail: { value: string }
Fired on each keystroke with { value } detail
arc-change detail: { value: string }
Fired on blur when value has changed, with { value } detail

See Also