All skills

Practical playbook for React teams to choose and apply reactuse hooks across state, async flows, browser APIs, and UI interactions. Use it when replacing custom hook logic with production-ready patterns that stay compatible with SSR and Next.js.

Use this Skill: https://skilld.dev/gh/siberiacancode/agent-skills/reactuse

This session only. Nothing lands on disk.

rulesuseMask.md

≈1.4k tokens on demand. Your agent reads this file only when SKILL.md points to it.

useMask

Keeps the DOM input value, raw value, display mask, cursor behavior, and validation callbacks aligned for masked text fields.

Usage

import { useMask } from "@siberiacancode/reactuse";

const phone = useMask("+9 (999) 999-99-99");

Example

import { useMask } from "@siberiacancode/reactuse";

export const PhoneField = () => {
  const phone = useMask("+9 (999) 999-99-99", {
    showMask: "focus",
  });

  return (
    <label>
      Phone
      <input {...phone.register()} />
      <span>{phone.watch().rawValue}</span>
    </label>
  );
};

tokens:

const serial = useMask("AA-999", { tokens: { A: /[A-Z]/ } });

autoClear:

const phone = useMask("+9 (999) 999-99-99", { autoClear: true });

beforeMaskedChange:

const phone = useMask("+9 (999) 999-99-99", {
  beforeMaskedChange: ({ nextState }) => nextState,
});

initialValue:

const phone = useMask("+9 (999) 999-99-99", { initialValue: "79990000000" });

mask as array:

const code = useMask(["#", /\d/, /\d/, "-", /\d/]);

modify:

const card = useMask("9999 9999 9999 9999", {
  modify: (value) => (value.startsWith("34") ? { mask: "9999 999999 99999" } : {}),
});

onChangeRaw:

const phone = useMask("+9 (999) 999-99-99", {
  onChangeRaw: (rawValue) => console.log(rawValue),
});

onFilled:

const phone = useMask("+9 (999) 999-99-99", {
  onFilled: (maskedValue) => console.log(maskedValue),
});

showMask:

const phone = useMask("+9 (999) 999-99-99", { showMask: "focus" });

slot:

const date = useMask("99/99/9999", { slot: "_" });

transform:

const serial = useMask("AA-999", {
  transform: (char) => char.toUpperCase(),
});

register(params):

<input {...phone.register({ onBlur: () => console.log(phone.getValue()) })} />;

getValue(type):

const raw = phone.getValue();
const masked = phone.getValue("masked");
const display = phone.getValue("display");

sanitize(value, options):

import { sanitize } from "@siberiacancode/reactuse";

const raw = sanitize("+7 (999) 123-45-67", {
  mask: "+9 (999) 999-99-99",
});

Notes

  • Default tokens: 9 digit, a letter, A uppercase letter, * alphanumeric, # signed digit.
  • By default the hook stores the input value in refs and does not re-render on every edit. To render live masked state in JSX, subscribe via watch(): call it once per render, for example const value = mask.watch(), then the component will re-render when the masked value changes. Use getValue() for one-off reads.

Type Declarations

import type {
  ChangeEventHandler,
  ClipboardEventHandler,
  FocusEventHandler,
  KeyboardEventHandler,
  MouseEventHandler,
  RefObject,
} from "react";

export type UseMaskPattern = string | Array<string | RegExp>;
export type UseMaskShow = "always" | "filled" | "focus" | "never";
export type UseMaskGetValueType = "display" | "masked" | "raw";
export interface UseMaskOptions {
  autoClear?: boolean;
  initialValue?: string;
  mask: UseMaskPattern;
  showMask?: UseMaskShow;
  slot?: string;
  tokens?: Record<string, RegExp>;
  beforeMaskedChange?: (states: {
    previousState: MaskState;
    currentState: MaskState;
    nextState: MaskState;
  }) => MaskState;
  modify?: (
    value: string
  ) => Partial<Pick<UseMaskOptions, "mask" | "showMask" | "slot" | "tokens">>;
  onChangeRaw?: (rawValue: string, maskedValue: string) => void;
  onFilled?: (maskedValue: string, rawValue: string) => void;
  transform?: (char: string) => string;
}
export interface MaskState {
  selection: { start: number; end: number } | null;
  value: string;
}
export interface UseMaskRegisterParams {
  onBlur?: FocusEventHandler<HTMLInputElement>;
  onChange?: ChangeEventHandler<HTMLInputElement>;
  onFocus?: FocusEventHandler<HTMLInputElement>;
  onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
  onMouseDown?: MouseEventHandler<HTMLInputElement>;
  onMouseUp?: MouseEventHandler<HTMLInputElement>;
  onPaste?: ClipboardEventHandler<HTMLInputElement>;
}
export interface UseMaskGetValueMap {
  display: string;
  masked: string;
  raw: string;
}
export interface UseMaskValue {
  displayValue: string;
  filled: boolean;
  maskedValue: string;
  rawValue: string;
  value: string;
}
export interface UseMaskReturn {
  ref: RefObject<HTMLInputElement | null>;
  getValue: <Type extends UseMaskGetValueType = "raw">(type?: Type) => UseMaskGetValueMap[Type];
  register: (params?: UseMaskRegisterParams) => {
    onBlur?: FocusEventHandler<HTMLInputElement>;
    onChange?: ChangeEventHandler<HTMLInputElement>;
    onFocus?: FocusEventHandler<HTMLInputElement>;
    onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
    onMouseDown?: MouseEventHandler<HTMLInputElement>;
    onMouseUp?: MouseEventHandler<HTMLInputElement>;
    onPaste?: ClipboardEventHandler<HTMLInputElement>;
    ref: (node: HTMLInputElement | null | undefined) => void;
  };
  reset: () => void;
  setValue: (value: string) => void;
  watch: () => UseMaskValue;
}
export type UseMaskReturnValue = UseMaskReturn;
export declare const sanitize: (value: string, options: UseMaskOptions) => string;
export declare const formatMask: (rawValue: string, options: UseMaskOptions) => string;
export declare const unformatMask: (maskedValue: string, options: UseMaskOptions) => string;
export declare const isMaskComplete: (maskedValue: string, options: UseMaskOptions) => boolean;
export declare const generatePattern: (
  mode: "full-inexact" | "full",
  options: UseMaskOptions
) => string;
export declare const useMask: (
  mask: UseMaskPattern,
  options?: Omit<UseMaskOptions, "mask">
) => UseMaskReturn;

Source: SKILL.md on GitHub

No alerts16d4 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill is a comprehensive documentation and implementation guide for the Reactuse hook library, designed for React and Next.js projects. It provides clear rules, usage examples, and type declarations for a wide range of hooks, including those interacting with browser APIs. No malicious patterns, obfuscation, or security risks were detected.

  • Socket5mo

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    1/166 files flagged

Signed by skilld at a090849. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated last month
metadata
{
  "author": "siberiacancode",
  "version": "1.0.16"
}

README badge

README badge for siberiacancode/agent-skills/reactuse