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

@xsolla/xui-input-copy

v0.187.3

Published

A cross-platform React input component that includes a copy-to-clipboard button. Supports visibility toggle for sensitive data like API keys or tokens. <!-- BEGIN:xui-mcp-instructions:input-copy --> An input field that displays a value and provides a one-

Readme

Input Copy

A cross-platform React input component that includes a copy-to-clipboard button. Supports visibility toggle for sensitive data like API keys or tokens.

An input field that displays a value and provides a one-click copy-to-clipboard action. The copy button is built into the right side of the field — clicking it copies the displayed text and transitions the component to State=Copied to confirm the action. Supports five sizes, an optional leading icon, a visibility toggle for sensitive values, and an error state.

When to use

When a value must be both readable and copyable — API keys, access tokens, referral links, invite codes, wallet addresses, webhook URLs, promo codes

When the user may occasionally need to edit the value in addition to copying it — for example, adjusting a URL before sharing

When copy confirmation matters — the Copied state makes it clear the action succeeded without requiring a Toast notification

In developer portals, settings panels, sharing flows, and payment confirmation screens

When not to use

When the value is purely display-only and never needs to be copied — use a plain text element

When the user should copy but never edit — consider making the field read-only at the product level (not the component level), but InputCopy itself supports editing by default

When multiple copy fields appear in a dense list — consider grouping them under a single copy-all action instead

Behaviour guidelines

Editable value — the field is a standard editable input. The user can click into it, select text, and type. The copy button copies the current value at the time of clicking, including any edits the user has made.

Copy on click — clicking the copy button copies the full Input text value to the clipboard using the Clipboard API. Immediately transition to State=Copied.

Copy on field click — optionally, clicking anywhere on the field (not just the button) can also trigger the copy action, especially on mobile where small buttons are hard to tap accurately. If implemented, the entire field becomes the tap target for copying.

Revert timer — after entering State=Copied, start a timer of 1.5–2 seconds. When the timer expires, revert to State=Default. If the user clicks the copy button again during the Copied state, restart the timer.

Clipboard API fallback — if the Clipboard API is unavailable (e.g. non-HTTPS context, older browser), fall back to document.execCommand('copy') or show a tooltip instructing the user to copy manually (e.g. "Press Ctrl+C to copy"). Do not silently fail.

Truncation — the value text is always single-line and truncated with an ellipsis (text-overflow: ellipsis) when it exceeds the field width. The full value is always available via the copy action, regardless of what is visible. Show the full value in a tooltip on hover when truncation is visible.

Visibility=False + copy — always copy the full unmasked value to the clipboard, even when Visibility=False. Masking is a visual-only feature.

Error state — use State=Error when the value is invalid, expired, or unavailable (e.g. an expired API token, a revoked access key). Show a descriptive error message below the field. The copy button may be disabled or hidden in this state depending on context.

Disable state — use State=Disable when the value cannot be interacted with in the current context (e.g. a feature is not enabled for this account). Show the value in muted style. Do not disable the field when the only difference is that copying is blocked — the field should still be readable.

Mobile — on touch devices, use Visibility=True by default unless the value is genuinely sensitive. Truncation without a hover tooltip is a problem on mobile — consider showing a narrower, more concise value or using a different layout.

Content guidelines

Value text — display the exact value the user needs. Do not add labels or prefixes inside the field (e.g. do not show "key: sk-prod-…" — show only sk-prod-…). The field label above the component communicates what the value is.

Field label — always provide a visible label above the component: "API key", "Referral link", "Access token", "Promo code". Do not rely on the icon or placeholder alone. Error messages — be specific:

  • "This token has expired. Generate a new one below."
  • "API key is unavailable. Contact your administrator."
  • "Link has been revoked."
  • Tooltip on copy button — add a tooltip to the copy button with aria-label text: "Copy API key", "Copy link", "Copy code". The tooltip disappears when the state transitions to Copied and the checkmark is shown.
  • Copied confirmation text — if additional text confirmation is needed (e.g. a tooltip or an aria-live announcement), use "Copied!" or "Copied to clipboard". Keep it brief.

Accessibility

The field must be a standard element — keyboard-focusable, editable, and selectable. Do not use readonly or disabled at the component level; handle those constraints at the product level if needed.

The copy button must be a element with aria-label identifying what is being copied — e.g. aria-label="Copy API key".

When State=Copied, update the button's aria-label to "Copied" and add aria-pressed="true" or update aria-live so screen readers announce the confirmation.

Use aria-live="polite" on a visually hidden region to announce "Copied to clipboard" when the state transitions to Copied. This ensures screen reader users receive the same confirmation that sighted users see via the checkmark.

When State=Error, the error message must be linked via aria-describedby and placed in an aria-live="polite" region.

When State=Disable, the copy button must have aria-disabled="true" and must not receive focus.

The leading icon must have aria-hidden="true".

When Visibility=False and the value is masked, add a tooltip or aria-description on the copy button clarifying that the full value will be copied despite the masking: e.g. aria-label="Copy secret key (hidden)".

Ensure the copy button meets the minimum touch target of 44 × 44 px on mobile. For XS [32] and S [40] sizes, add layout padding as needed.

Installation

npm install @xsolla/xui-input-copy

Demo

Basic Input Copy

import * as React from "react";
import { InputCopy } from "@xsolla/xui-input-copy";

export default function BasicInputCopy() {
  return (
    <InputCopy
      value="sk_live_abc123xyz"
      onCopy={(val) => console.log("Copied:", val)}
    />
  );
}

With Label

import * as React from "react";
import { InputCopy } from "@xsolla/xui-input-copy";

export default function LabeledInputCopy() {
  return (
    <InputCopy
      label="API Key"
      value="sk_live_abc123xyz789"
      onCopy={(val) => console.log("Copied:", val)}
    />
  );
}

Secure Text Entry

import * as React from "react";
import { InputCopy } from "@xsolla/xui-input-copy";

export default function SecureInputCopy() {
  return (
    <InputCopy
      label="Secret Token"
      value="super_secret_token_12345"
      secureTextEntry={true}
      onCopy={(val) => console.log("Copied:", val)}
    />
  );
}

Editable Input Copy

import * as React from "react";
import { InputCopy } from "@xsolla/xui-input-copy";

export default function EditableInputCopy() {
  const [value, setValue] = React.useState("editable-value");

  return (
    <InputCopy
      label="Editable Field"
      value={value}
      onChange={(e) => setValue(e.target.value)}
      onCopy={(val) => console.log("Copied:", val)}
    />
  );
}

Anatomy

import { InputCopy } from "@xsolla/xui-input-copy";

<InputCopy
  value="text to copy" // Value to display and copy
  onChange={handleChange} // Change event handler
  onCopy={handleCopy} // Callback after copying
  secureTextEntry={false} // Hide text like password
  initialVisible={false} // Initial visibility (when secure)
  size="md" // Size variant
  label="Label" // Label above input
  disabled={false} // Disabled state
  error={false} // Error state
  errorMessage="Error" // Error message text
/>;

Examples

Input Copy Sizes

import * as React from "react";
import { InputCopy } from "@xsolla/xui-input-copy";

export default function InputCopySizes() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      <InputCopy size="xs" value="Extra Small" />
      <InputCopy size="sm" value="Small" />
      <InputCopy size="md" value="Medium" />
      <InputCopy size="lg" value="Large" />
      <InputCopy size="xl" value="Extra Large" />
    </div>
  );
}

Error State

import * as React from "react";
import { InputCopy } from "@xsolla/xui-input-copy";

export default function ErrorInputCopy() {
  return (
    <InputCopy
      label="API Key"
      value="invalid-key"
      error={true}
      errorMessage="Invalid API key format"
    />
  );
}

API Reference

InputCopy

InputCopy Props:

| Prop | Type | Default | Description | | :-------------- | :------------------------------------- | :------ | :------------------------------------------------------------------------------------------------------------ | | testID | string | — | Test ID for testing frameworks. On web this renders as data-testid; on React Native it renders as testID. | | value | string | "" | Value to display and copy. | | onChange | (e: ChangeEvent) => void | - | Change event handler. | | onChangeText | (text: string) => void | - | Text change handler. | | onCopy | (value: string) => void | - | Callback when value is copied. | | secureTextEntry | boolean | false | Hide text like a password field. | | initialVisible | boolean | false | Initial visibility when secureTextEntry is true. | | size | "xl" \| "lg" \| "md" \| "sm" \| "xs" | "md" | Component size. | | label | string | - | Label above input. | | disabled | boolean | false | Disabled state. | | error | boolean | false | Error state. | | errorMessage | string | - | Error message text. | | placeholder | string | - | Placeholder text. | | testID | string | - | Test identifier. |

Behavior

  • Copy Button: Shows checkmark icon briefly (2 seconds) after successful copy
  • Visibility Toggle: When secureTextEntry is enabled, the eye icon reflects the current state:
    • Open eye = Text is currently visible (type="text")
    • Closed eye = Text is currently hidden (type="password")
    • This follows modern design system conventions (Material, Apple, Atlassian, Polaris)
  • Uses browser Clipboard API for copying
  • Error state shows red border and error message

Accessibility

  • Copy button has aria-label that changes from "Copy to clipboard" to "Copied" after action
  • Visibility toggle button has appropriate aria-label:
    • "Show text" when text is hidden
    • "Hide text" when text is visible
  • Toggle button uses aria-pressed to indicate current visibility state
  • Error messages linked via aria-describedby for screen reader context
  • Labels properly linked via aria-labelledby when provided
  • Input has aria-invalid when in error state
  • Error messages use role="alert" for immediate announcement