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

dragon-eye

v2.0.1

Published

A lightweight, accessible React eye icon and password visibility toggle component library.

Readme

dragon-eye 👁️

npm version Downloads TypeScript React License

A lightweight, accessible, and fully typed React eye icon & password visibility toggle library.

dragon-eye provides ready-to-use components for password visibility toggles, authentication forms, and any UI that requires eye / eye-off icons.

Preview

Author


✨ Features

  • TypeScript support included
  • Accessible keyboard interactions (Enter / Space)
  • React 16.8+ compatible
  • Lightweight & tree-shakeable
  • ForwardRef support
  • Memoized components for performance
  • Custom size, color, and stroke width
  • Animated hover interactions
  • Built-in password input component
  • Built-in visibility toggle component
  • usePasswordToggle hook included
  • ✅ Supports both color and colour props

📦 Installation

Install with npm:

npm install dragon-eye

or with yarn:

yarn add dragon-eye

or with pnpm:

pnpm add dragon-eye

📋 Requirements

  • React 16.8 or higher
  • ReactDOM 16.8 or higher

🚀 Quick Start

import { Eye, EyeOff } from "dragon-eye";

function App() {
  return (
    <div style={{ display: "flex", gap: 16 }}>
      <Eye size={32} color="purple" />
      <EyeOff size={32} color="tomato" />
    </div>
  );
}

export default App;

📚 Exports

import {
  Eye,
  EyeOff,
  EyeToggle,
  PasswordInput,
  usePasswordToggle,
} from "dragon-eye";

Components

  • Eye – visible eye icon
  • EyeOff – hidden eye icon
  • EyeToggle – controlled visibility toggle icon
  • PasswordInput – ready-to-use password field with toggle

Hooks

  • usePasswordToggle – state helper for password visibility

👁️ Eye Component

Eye renders an open eye icon that is commonly used for password visibility toggles, visibility indicators, and custom UI controls.

Import

import { Eye } from "dragon-eye";

Basic Usage

<Eye />

Custom Size

<Eye size={32} />

or

<Eye
  width={32}
  height={32}
/>

Custom Color

Preferred:

<Eye color="royalblue" />

Backward compatible:

<Eye colour="royalblue" />

Clickable Icon

<Eye
  color="tomato"
  onClick={() => alert("Clicked!")}
/>

Animated Icon

<Eye
  animated
  size={30}
/>

Disabled Icon

<Eye
  disabled
  color="gray"
/>

Accessibility

<Eye
  ariaLabel="Show password"
  title="Show password"
/>

Eye Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | size | number \| string | 20 | Sets both width and height | | width | number \| string | size | Custom width | | height | number \| string | size | Custom height | | color | string | currentColor | Preferred icon color | | colour | string | — | Backward compatible color prop | | strokeWidth | number | 2 | SVG stroke width | | animated | boolean | false | Enables hover animation | | disabled | boolean | false | Disables interaction | | title | string | "Show password" | SVG title | | ariaLabel | string | "Show password" | Accessibility label | | className | string | — | Custom CSS class | | style | CSSProperties | — | Inline styles | | onClick | (event) => void | — | Click handler |


Example

import { Eye } from "dragon-eye";

export default function Example() {
  return (
    <Eye
      size={36}
      color="#6C63FF"
      strokeWidth={2.5}
      animated
      ariaLabel="Show password"
      onClick={() => console.log("Eye clicked")}
    />
  );
}

🙈 EyeOff Component

EyeOff renders a crossed eye icon, commonly used to indicate hidden content such as concealed passwords or disabled visibility states.

Import

import { EyeOff } from "dragon-eye";

Basic Usage

<EyeOff />

Custom Size

<EyeOff size={32} />

or

<EyeOff
  width={32}
  height={32}
/>

Custom Color

Preferred:

<EyeOff color="crimson" />

Backward compatible:

<EyeOff colour="crimson" />

Clickable Icon

<EyeOff
  color="tomato"
  onClick={() => alert("Clicked!")}
/>

Animated Icon

<EyeOff
  animated
  size={30}
/>

Disabled Icon

<EyeOff
  disabled
  color="gray"
/>

Accessibility

<EyeOff
  ariaLabel="Hide password"
  title="Hide password"
/>

EyeOff Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | size | number \| string | 20 | Sets both width and height | | width | number \| string | size | Custom width | | height | number \| string | size | Custom height | | color | string | currentColor | Preferred icon color | | colour | string | — | Backward compatible color prop | | strokeWidth | number | 2 | SVG stroke width | | animated | boolean | false | Enables hover animation | | disabled | boolean | false | Disables interaction | | title | string | "Hide password" | SVG title | | ariaLabel | string | "Hide password" | Accessibility label | | className | string | — | Custom CSS class | | style | CSSProperties | — | Inline styles | | onClick | (event) => void | — | Click handler |


Example

import { EyeOff } from "dragon-eye";

export default function Example() {
  return (
    <EyeOff
      size={36}
      color="#E63946"
      strokeWidth={2.5}
      animated
      ariaLabel="Hide password"
      onClick={() => console.log("EyeOff clicked")}
    />
  );
}

Common Use Cases

  • Password visibility toggle
  • Hide confidential information
  • Toggle sensitive form fields
  • Authentication interfaces
  • Login and signup forms
  • Custom visibility controls

🔄 EyeToggle Component

EyeToggle is a ready-to-use visibility toggle component that automatically switches between the Eye and EyeOff icons.

It is ideal for password visibility toggles and any UI that needs to switch between visible and hidden states.

Import

import { EyeToggle } from "dragon-eye";

Basic Usage

import { useState } from "react";
import { EyeToggle } from "dragon-eye";

export default function Example() {
  const [visible, setVisible] = useState(false);

  return (
    <EyeToggle
      visible={visible}
      onToggle={setVisible}
    />
  );
}

Password Toggle Example

import { useState } from "react";
import { EyeToggle } from "dragon-eye";

export default function PasswordField() {
  const [visible, setVisible] = useState(false);

  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        gap: 8,
      }}
    >
      <input
        type={visible ? "text" : "password"}
        placeholder="Password"
      />

      <EyeToggle
        visible={visible}
        onToggle={setVisible}
      />
    </div>
  );
}

Controlled Component

EyeToggle is a controlled component.

You manage the visibility state.

const [visible, setVisible] = useState(false);

<EyeToggle
  visible={visible}
  onToggle={setVisible}
/>

Event Handling

The onToggle callback receives the next visibility state.

<EyeToggle
  visible={visible}
  onToggle={(nextVisible) => {
    console.log(nextVisible);

    setVisible(nextVisible);
  }}
/>

Custom Color

Preferred:

<EyeToggle
  visible={visible}
  onToggle={setVisible}
  color="royalblue"
/>

Backward compatible:

<EyeToggle
  visible={visible}
  onToggle={setVisible}
  colour="royalblue"
/>

Custom Size

<EyeToggle
  visible={visible}
  onToggle={setVisible}
  size={30}
/>

or

<EyeToggle
  visible={visible}
  onToggle={setVisible}
  width={30}
  height={30}
/>

Stroke Width

<EyeToggle
  visible={visible}
  onToggle={setVisible}
  strokeWidth={2.5}
/>

Animated Toggle

<EyeToggle
  visible={visible}
  onToggle={setVisible}
  animated
/>

Disabled Toggle

<EyeToggle
  visible={visible}
  onToggle={setVisible}
  disabled
/>

Accessibility

<EyeToggle
  visible={visible}
  onToggle={setVisible}
  ariaLabel="Toggle password visibility"
  title="Toggle password visibility"
/>

EyeToggle Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | visible | boolean | Required | Current visibility state | | onToggle | (visible: boolean) => void | Required | Called with the next visibility state | | size | number \| string | 20 | Sets icon size | | width | number \| string | size | Custom width | | height | number \| string | size | Custom height | | color | string | currentColor | Preferred icon color | | colour | string | — | Backward compatible color prop | | strokeWidth | number | 2 | SVG stroke width | | animated | boolean | false | Enables hover animation | | disabled | boolean | false | Disables interaction | | title | string | Auto generated | SVG title | | ariaLabel | string | Auto generated | Accessibility label | | className | string | — | Custom CSS class | | style | CSSProperties | — | Inline styles |


Default Behaviour

When:

visible={false}

the component renders:

<Eye />

When:

visible={true}

the component renders:

<EyeOff />

Clicking the component automatically calls:

onToggle(!visible)

so you only need to update your state.


Complete Example

import { useState } from "react";
import { EyeToggle } from "dragon-eye";

export default function Example() {
  const [visible, setVisible] = useState(false);

  return (
    <EyeToggle
      visible={visible}
      onToggle={setVisible}
      size={32}
      color="#7C3AED"
      animated
      strokeWidth={2.5}
    />
  );
}

🔐 PasswordInput Component

PasswordInput is a ready-to-use password field with built-in visibility toggle functionality.

It automatically manages password visibility state, renders the appropriate eye icon, and supports customization of the icon appearance.

Import

import { PasswordInput } from "dragon-eye";

Basic Usage

<PasswordInput
  placeholder="Enter password"
/>

Default Behaviour

The component automatically:

  • Starts with the password hidden
  • Switches between password and text
  • Displays the correct icon
  • Supports keyboard accessibility
  • Disables the toggle when the input is disabled

No additional state management is required.


Custom Icon Color

Preferred:

<PasswordInput
  iconColor="royalblue"
/>

Backward compatible:

<PasswordInput
  iconColour="royalblue"
/>

Custom Icon Size

<PasswordInput
  iconSize={28}
/>

Custom Stroke Width

<PasswordInput
  strokeWidth={2.5}
/>

Animated Icon

<PasswordInput
  animated
/>

Disabled Input

<PasswordInput
  disabled
/>

When disabled:

  • Input cannot be edited
  • Eye icon cannot be clicked
  • Visibility cannot be changed

Custom Placeholder

<PasswordInput
  placeholder="Create password"
/>

Default Value

<PasswordInput
  defaultValue="secret123"
/>

Controlled Value

const [password, setPassword] = useState("");

<PasswordInput
  value={password}
  onChange={(e) => setPassword(e.target.value)}
/>

Custom Classes

<PasswordInput
  wrapperClassName="password-wrapper"
  inputClassName="password-input"
/>

Styling Example

.password-wrapper {
  border: 1px solid #ccc;
  border-radius: 8px;
  padding: 6px 10px;
}

.password-input {
  border: none;
  outline: none;
  width: 100%;
}

Using Standard Input Props

Since PasswordInput extends React's native input attributes, you can use all standard input properties.

<PasswordInput
  placeholder="Password"
  autoComplete="current-password"
  required
  maxLength={32}
  autoFocus
/>

PasswordInput Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | iconSize | number \| string | 24 | Toggle icon size | | iconColor | string | currentColor | Preferred icon color | | iconColour | string | — | Backward compatible icon color | | strokeWidth | number | 2 | Icon stroke width | | animated | boolean | true | Enables icon animation | | wrapperClassName | string | — | Wrapper class | | inputClassName | string | — | Input class | | disabled | boolean | false | Disables input and toggle | | placeholder | string | — | Input placeholder | | defaultValue | string | — | Initial value | | value | string | — | Controlled input value | | onChange | (event) => void | — | Input change handler | | ...rest | InputHTMLAttributes | — | All native input props |


Complete Example

import { PasswordInput } from "dragon-eye";

export default function Example() {
  return (
    <PasswordInput
      placeholder="Enter your password"
      iconSize={26}
      iconColor="#7C3AED"
      strokeWidth={2.2}
      animated
    />
  );
}

Why Use PasswordInput?

✅ No state management required

✅ Built-in visibility toggle

✅ Accessible keyboard interaction

✅ Supports all native React input props

✅ Fully customizable icon

✅ TypeScript support

✅ Lightweight

✅ Production ready

Part 6 – usePasswordToggle Hook

usePasswordToggle is a lightweight React hook that manages password visibility state.

It eliminates repetitive useState logic and provides helper functions for showing, hiding, toggling, and manually controlling password visibility.


Import

import { usePasswordToggle } from "dragon-eye";

Basic Example

Instead of writing:

const [visible, setVisible] = useState(false);

you can simply use:

const {
  visible,
  inputType,
  toggle,
} = usePasswordToggle();

Complete example:

import { EyeToggle, usePasswordToggle } from "dragon-eye";

function Login() {
  const {
    visible,
    inputType,
    toggle,
  } = usePasswordToggle();

  return (
    <div>
      <input
        type={inputType}
        placeholder="Password"
      />

      <EyeToggle
        visible={visible}
        onToggle={toggle}
      />
    </div>
  );
}

Start Visible

You may choose the initial visibility state.

const password = usePasswordToggle(true);

or

const password = usePasswordToggle(false);

Returned Values

const {
  visible,
  inputType,
  show,
  hide,
  toggle,
  setVisible,
} = usePasswordToggle();

| Property | Type | Description | |-----------|------|-------------| | visible | boolean | Current visibility state | | inputType | "password" \| "text" | Derived input type | | show() | () => void | Show password | | hide() | () => void | Hide password | | toggle() | () => void | Toggle visibility | | setVisible() | Dispatch<SetStateAction<boolean>> | Manually control visibility |


API

usePasswordToggle(
    initialVisible?: boolean
)

Parameters

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | initialVisible | boolean | false | Initial visibility state |


Example – Toggle Button

import {
  EyeToggle,
  usePasswordToggle,
} from "dragon-eye";

export default function Example() {
  const password =
    usePasswordToggle();

  return (
    <>
      <input
        type={password.inputType}
      />

      <EyeToggle
        visible={password.visible}
        onToggle={password.toggle}
      />
    </>
  );
}

Example – Show Button

const password =
    usePasswordToggle();

<button
    onClick={password.show}
>
    Show Password
</button>

Example – Hide Button

const password =
    usePasswordToggle();

<button
    onClick={password.hide}
>
    Hide Password
</button>

Example – Manual Control

const password =
    usePasswordToggle();

<button
    onClick={() =>
        password.setVisible(true)
    }
>
    Always Show
</button>

<button
    onClick={() =>
        password.setVisible(false)
    }
>
    Always Hide
</button>

Example – Multiple Password Fields

Each hook instance maintains its own independent state.

const loginPassword =
    usePasswordToggle();

const confirmPassword =
    usePasswordToggle();
<input
    type={loginPassword.inputType}
/>

<EyeToggle
    visible={loginPassword.visible}
    onToggle={loginPassword.toggle}
/>

<input
    type={confirmPassword.inputType}
/>

<EyeToggle
    visible={confirmPassword.visible}
    onToggle={confirmPassword.toggle}
/>

Using with PasswordInput

If you're using the built-in PasswordInput component, you usually don't need this hook, because PasswordInput manages visibility internally.

Use the hook when you're building your own password field.


Best Practices

✅ Use one hook instance per password field.

✅ Prefer inputType instead of manually checking visible.

<input
    type={password.inputType}
/>

instead of

<input
    type={
        password.visible
            ? "text"
            : "password"
    }
/>

✅ Use toggle() with EyeToggle.

<EyeToggle
    visible={password.visible}
    onToggle={password.toggle}
/>

✅ Use show() and hide() when explicit actions are required.

password.show();

password.hide();

TypeScript

The hook is fully typed.

import {
    usePasswordToggle,
    UsePasswordToggleReturn,
} from "dragon-eye";

const password:
    UsePasswordToggleReturn =
    usePasswordToggle();

Summary

The usePasswordToggle hook provides a simple, reusable way to manage password visibility in React applications.

It is ideal for custom password inputs and works seamlessly with the Eye and EyeToggle components while remaining fully typed, lightweight, and framework-friendly.

Part 7 – Styling & CSS

dragon-eye ships with a lightweight stylesheet that provides sensible defaults for hover effects, transitions, cursor styles, keyboard focus, and disabled states.

The CSS file is automatically included when using the package with most modern bundlers such as Vite, Rollup, and Webpack.


Default Styling

Icons are rendered as inline-flex elements with smooth transitions.

Features include:

  • Hover animation
  • Keyboard focus support
  • Disabled appearance
  • Pointer cursor for clickable icons
  • Consistent sizing

No additional configuration is required.


CSS Classes

The library uses the following internal CSS classes.

| Class | Description | |---------|-------------| | dragon-eye-icon | Base icon class | | dragon-eye-icon--animated | Enables hover animation | | dragon-eye-icon--clickable | Applied when onClick exists | | dragon-eye-icon--disabled | Applied when disabled |


Animated Icons

Animation is enabled by default on components that support it.

<Eye
    animated
/>

Disable animations if preferred.

<Eye
    animated={false}
/>

The same option is available for:

  • Eye
  • EyeOff
  • EyeToggle
  • PasswordInput

Custom Styling

Every component accepts standard React HTML attributes.

Example:

<Eye
    className="my-icon"
/>
.my-icon {
    color: royalblue;
    transition: transform .2s ease;
}

.my-icon:hover {
    transform: scale(1.15);
}

Inline Styles

Inline styles are also supported.

<Eye
    style={{
        color: "purple",
        marginLeft: 8,
    }}
/>

PasswordInput Styling

Customize wrapper and input independently.

<PasswordInput
    wrapperClassName="password-wrapper"
    inputClassName="password-input"
/>

Example CSS:

.password-wrapper {
    display: flex;
    align-items: center;
    gap: 8px;
}

.password-input {
    width: 100%;
    padding: 10px;
    border-radius: 6px;
}

Disabled State

Disabled icons automatically:

  • ignore clicks
  • remove pointer cursor
  • reduce opacity
  • disable keyboard activation
<EyeToggle
    visible={false}
    disabled
/>

Responsive Sizing

Icons support numbers or CSS values.

<Eye
    size={20}
/>

<Eye
    width="2rem"
    height="2rem"
/>

<Eye
    width="100%"
    height="100%"
/>

Best Practices

✅ Prefer the size prop when width and height are equal.

<Eye size={24} />

✅ Use width and height when different dimensions are required.

<Eye
    width={32}
    height={20}
/>

✅ Customize appearance with your own CSS classes instead of editing library styles.


Summary

dragon-eye includes minimal default styling while remaining fully customizable through CSS classes, inline styles, and component props.


Part 8 – Accessibility

Accessibility is a core feature of dragon-eye.

All interactive components are designed to work with keyboards, assistive technologies, and modern accessibility standards.


Keyboard Support

Clickable icons can be activated using:

  • Tab to focus
  • Enter to activate
  • Space to activate

Example:

<EyeToggle
    visible={visible}
    onToggle={toggle}
/>

No additional keyboard handlers are required.


Focus Management

Interactive icons automatically become keyboard focusable.

<Eye
    onClick={handleClick}
/>

The component receives:

tabIndex=0

automatically.

Non-clickable icons are excluded from keyboard navigation.


Screen Reader Support

Provide meaningful labels using ariaLabel.

<Eye
    ariaLabel="Show password"
/>
<EyeOff
    ariaLabel="Hide password"
/>

SVG Titles

Use the title prop to provide accessible SVG descriptions.

<Eye
    title="Password visible"
/>

This is useful for browser tooltips and assistive technologies.


Disabled Accessibility

Disabled components automatically receive:

aria-disabled="true"

and ignore:

  • mouse clicks
  • keyboard activation

Example:

<EyeToggle
    visible={false}
    disabled
/>

Semantic Roles

Interactive icons use:

role="button"

Static icons use:

role="img"

These roles are managed automatically.


PasswordInput Accessibility

The built-in PasswordInput preserves all native input accessibility features.

Example:

<PasswordInput
    placeholder="Password"
    aria-label="Password"
/>

You may also combine it with labels.

<label htmlFor="password">
    Password
</label>

<PasswordInput
    id="password"
/>

Best Practices

✅ Always provide an ariaLabel for interactive icons.

<EyeToggle
    ariaLabel="Toggle password visibility"
    visible={visible}
    onToggle={toggle}
/>

✅ Use descriptive title values.

<Eye
    title="Show password"
/>

✅ Prefer native <button> elements when wrapping icons inside larger controls.


✅ Pair password inputs with <label> elements whenever possible.


Summary

dragon-eye is built with accessibility in mind, offering keyboard navigation, ARIA support, semantic roles, focus management, and screen reader compatibility out of the box.

Part 9 – TypeScript

dragon-eye is written entirely in TypeScript and ships with built-in type declarations.

No additional typings are required.


Installation

Simply install the package.

npm install dragon-eye

TypeScript definitions are included automatically.


Importing Types

All public types are exported from the package.

import type {
    IconProps,
    IconBaseProps,
    PasswordInputProps,
    UsePasswordToggleReturn,
} from "dragon-eye";

IconProps

Used by:

  • Eye
  • EyeOff
  • EyeToggle

Example:

import type { IconProps } from "dragon-eye";

const props: IconProps = {
    size: 24,
    color: "royalblue",
    animated: true,
};

PasswordInputProps

Useful when creating wrapper components.

import type {
    PasswordInputProps,
} from "dragon-eye";

interface LoginPasswordProps
    extends PasswordInputProps {}

Example:

function LoginPassword(
    props: PasswordInputProps
) {
    return (
        <PasswordInput
            {...props}
        />
    );
}

UsePasswordToggleReturn

The hook exports its return type.

import {
    usePasswordToggle,
    UsePasswordToggleReturn,
} from "dragon-eye";

const password:
    UsePasswordToggleReturn =
    usePasswordToggle();

Component Refs

All components support React refs.

Eye:

const ref =
    useRef<HTMLSpanElement>(null);

<Eye ref={ref} />

EyeToggle:

const ref =
    useRef<HTMLSpanElement>(null);

<EyeToggle
    ref={ref}
    visible={visible}
    onToggle={toggle}
/>

PasswordInput:

const inputRef =
    useRef<HTMLInputElement>(null);

<PasswordInput
    ref={inputRef}
/>

Generic Wrapper Example

import {
    Eye,
    IconProps,
} from "dragon-eye";

function BlueEye(
    props: IconProps
) {
    return (
        <Eye
            color="royalblue"
            {...props}
        />
    );
}

Full Type Exports

The library exports:

| Type | Description | |------|-------------| | IconProps | Shared icon props | | IconBaseProps | Base icon component props | | PasswordInputProps | PasswordInput props | | UsePasswordToggleReturn | Hook return type |


Type Safety

The compiler validates props automatically.

Correct:

<Eye
    size={24}
    color="red"
/>

Incorrect:

<Eye
    size="large"
/>

TypeScript will report an error because size accepts only:

number | string

IntelliSense Support

Modern editors provide:

  • Auto-completion
  • Prop documentation
  • Type checking
  • Hover information
  • Ref types
  • Event types

without any additional configuration.


Summary

dragon-eye is fully typed, providing first-class TypeScript support with exported interfaces, strongly typed hooks, component refs, and editor IntelliSense.


Part 10 – Complete API Reference

This section summarizes every public export available in dragon-eye.


Exports

import {
    Eye,
    EyeOff,
    EyeToggle,
    PasswordInput,
    usePasswordToggle,
} from "dragon-eye";

Eye Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | size | number \| string | 20 | Icon size | | width | number \| string | size | Custom width | | height | number \| string | size | Custom height | | color | string | currentColor | Icon color | | colour | string | currentColor | Backward compatible color | | strokeWidth | number | 2 | SVG stroke width | | animated | boolean | false | Enable hover animation | | disabled | boolean | false | Disable interaction | | title | string | — | SVG title | | ariaLabel | string | — | Accessibility label | | onClick | MouseEventHandler | — | Click handler | | className | string | — | CSS class | | style | CSSProperties | — | Inline styles |


EyeOff Props

Supports exactly the same props as Eye.


EyeToggle Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | visible | boolean | — | Current visibility | | onToggle | (visible:boolean,event?)=>void | — | Toggle callback | | All IconProps | — | — | All icon props are supported |


PasswordInput Props

| Prop | Type | Default | |------|------|---------| | iconSize | number \| string | 20 | | iconColor | string | currentColor | | iconColour | string | currentColor | | strokeWidth | number | 2 | | animated | boolean | true | | wrapperClassName | string | "" | | inputClassName | string | "" | | defaultVisible | boolean | false | | All native input props | ✓ | Supported |


usePasswordToggle

const password =
    usePasswordToggle(
        initialVisible?
    );

Returns:

| Property | Type | |-----------|------| | visible | boolean | | inputType | "password" \| "text" | | show() | () => void | | hide() | () => void | | toggle() | () => void | | setVisible() | Dispatch<SetStateAction<boolean>> |


Browser Support

Compatible with all modern browsers supporting:

  • ES2020
  • SVG
  • React 16.8+
  • React 17
  • React 18
  • React 19

Bundle Formats

The package includes:

  • ES Module (ESM)
  • UMD
  • TypeScript declarations
  • Source maps

Tree Shaking

Only the components you import are included in your bundle.

import { Eye } from "dragon-eye";

This helps keep production bundle sizes small.


Summary

The API is intentionally small, strongly typed, and easy to learn, making dragon-eye suitable for projects ranging from simple forms to large-scale React applications.

Part 11 – Migration Guide

This section explains how to migrate from earlier versions of dragon-eye to the latest release.


Upgrading

Install the latest version:

npm install dragon-eye@latest

or

yarn add dragon-eye@latest

What's New

The latest version introduces:

  • EyeToggle component
  • PasswordInput component
  • usePasswordToggle hook
  • ✅ Better accessibility
  • ✅ Better keyboard support
  • ✅ Improved TypeScript types
  • ✅ React 19 compatibility
  • ✅ Improved tree shaking
  • ✅ Forward ref support

Existing Eye Component

Old usage:

<Eye colour="blue" />

Still works.


New usage:

<Eye color="blue" />

Both are fully supported.


Existing EyeOff Component

No changes are required.

Old code:

<EyeOff
    width={24}
    height={24}
/>

continues to work.


New EyeToggle Component

Instead of manually writing:

{
    visible
        ? <EyeOff />
        : <Eye />
}

You can now write:

<EyeToggle
    visible={visible}
    onToggle={toggle}
/>

This simplifies password visibility logic.


New PasswordInput Component

Previously you had to build your own password field.

Example:

<input
    type={
        visible
            ? "text"
            : "password"
    }
/>

<EyeToggle
    visible={visible}
    onToggle={toggle}
/>

Now you can simply use:

<PasswordInput />

New Hook

Instead of:

const [visible, setVisible] =
    useState(false);

Use:

const password =
    usePasswordToggle();

Deprecated Patterns

Prefer:

color

instead of

colour

The colour prop is still supported for backward compatibility but color is recommended for new projects.


No Breaking Changes

Version 2 maintains compatibility with existing icon usage.

Existing projects using:

  • Eye
  • EyeOff
  • colour

will continue to work without modification.


Summary

Migrating to the latest version is straightforward. Existing applications continue to work while gaining access to new components, improved accessibility, stronger TypeScript support, and simplified password visibility management.


Part 12 – Frequently Asked Questions (FAQ)

Does this library work with React 16?

Yes.

Minimum supported version:

React 16.8+

because Hooks require React 16.8 or newer.


Does it support React 17?

Yes.


Does it support React 18?

Yes.


Does it support React 19?

Yes.

The library is compatible with React 19.


Does it work with TypeScript?

Yes.

TypeScript declarations are included in the package.

No additional typings are required.


Can I use JavaScript instead?

Absolutely.

The package works with both JavaScript and TypeScript projects.


Can I change the icon color?

Yes.

<Eye color="tomato" />

or

<Eye colour="tomato" />

Can I change the size?

Yes.

<Eye size={28} />

or

<Eye
    width={32}
    height={20}
/>

Does it support custom CSS?

Yes.

<Eye
    className="my-icon"
/>

Can I disable animations?

Yes.

<Eye
    animated={false}
/>

Is the library accessible?

Yes.

Features include:

  • Keyboard navigation
  • ARIA labels
  • SVG titles
  • Screen reader support
  • Focus management

Is SSR supported?

Yes.

The package works with server-side rendering frameworks such as:

  • Next.js
  • Remix
  • Gatsby

Does it work with Vite?

Yes.

It is built with Vite and works seamlessly in Vite projects.


Does it work with Create React App?

Yes.


Can I use only one component?

Yes.

Example:

import { Eye } from "dragon-eye";

Only the imported component is bundled.


Does it support tree shaking?

Yes.

Unused components are removed by modern bundlers.


Can I use the icons outside password fields?

Yes.

The icons are generic SVG React components and can be used anywhere.

Example:

<Eye
    color="green"
    size={30}
/>

Is CSS required?

No.

The components work without custom CSS.

The included stylesheet only provides improved hover effects, focus styles, and transitions.


How can I report a bug?

Please open an issue on the GitHub repository.

Include:

  • React version
  • Browser
  • Package version
  • Steps to reproduce

Can I contribute?

Yes.

Contributions are welcome through GitHub pull requests and issue reports.


Summary

If your question isn't covered here, please check the GitHub repository or open an issue. Feedback and contributions are always appreciated.

Part 13 – Contributing

Contributions are welcome and greatly appreciated!

Whether you'd like to fix a bug, improve documentation, add a feature, or optimize performance, your help is always welcome.


Ways to Contribute

You can contribute by:

  • Reporting bugs
  • Suggesting new features
  • Improving documentation
  • Optimizing performance
  • Improving accessibility
  • Fixing TypeScript definitions
  • Writing tests
  • Improving examples

Reporting Issues

If you discover a bug, please create a GitHub issue and include:

  • Package version
  • React version
  • Operating system
  • Browser (if applicable)
  • Expected behavior
  • Actual behavior
  • Steps to reproduce
  • Screenshots (if helpful)

Development Setup

Clone the repository.

git clone https://github.com/iamxerrycan/dragon-eye.git

Enter the project.

cd dragon-eye

Install dependencies.

npm install

Run the build.

npm run build

Run tests.

npm test

Pull Requests

Before submitting a pull request:

  • Keep changes focused
  • Update documentation if needed
  • Ensure the project builds successfully
  • Follow the existing coding style
  • Add tests when introducing new features

Code Style

Please follow the project's conventions:

  • TypeScript
  • Functional React components
  • Hooks over class components
  • Strong typing
  • Meaningful comments
  • Consistent formatting

Feature Requests

Have an idea?

Open a GitHub discussion or issue describing:

  • The problem
  • Your proposed solution
  • Example usage
  • Any alternatives you've considered

Community Guidelines

Please be respectful and constructive.

We aim to maintain a welcoming environment for everyone.


Thank You ❤️

Every contribution—large or small—helps make dragon-eye better for the React community.

Thank you for your support!


Part 14 – License

MIT License

Copyright (c) 2026 iamxerrycan

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to:

  • Use
  • Copy
  • Modify
  • Merge
  • Publish
  • Distribute
  • Sublicense
  • Sell copies of the Software

subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

For the complete license text, see the project's LICENSE file.


Part 15 – Author & Links

Author

Rajshish Singh Rajput (iamxerrycan)

A passionate software developer focused on building modern, reusable, and developer-friendly open-source tools for the React ecosystem.


Connect

GitHub

https://github.com/iamxerrycan


LinkedIn

https://www.linkedin.com/in/iamxerrycan/


Instagram

https://www.instagram.com/rajshishsinghrajput/


Project Links

npm Package

https://www.npmjs.com/package/dragon-eye


GitHub Repository

https://github.com/iamxerrycan/dragon-eye


Issue Tracker

https://github.com/iamxerrycan/dragon-eye/issues


Support

If you find this project useful, consider:

  • ⭐ Starring the GitHub repository
  • 🐛 Reporting bugs
  • 💡 Suggesting new features
  • 📢 Sharing the package with others
  • 🤝 Contributing to the project

Your support helps improve the library and keeps the project growing.


Changelog

For release history and updates, see:

  • GitHub Releases
  • npm Version History

Acknowledgements

Thanks to:

  • The React team
  • The TypeScript team
  • The Vite team
  • Every contributor and user of dragon-eye

Made with ❤️

Built with React, TypeScript, and Vite to provide lightweight, accessible, and customizable eye icons and password visibility components for modern web applications.


⭐ If you like this project...

Please consider giving the repository a Star on GitHub.

It helps others discover the project and motivates continued development.

Thank you for using dragon-eye! 👁️