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

@willphan1712000/frontend

v2.4.1

Published

Frontend Library

Readme

@willphan1712000/frontend

Reusable React UI components and frontend utilities packaged for application development following Will component interface called WUII which stands for Will UI Interface

What this package includes

Components

  • DropdownSelect
  • MultiSelect
  • RangeSlider
  • OptionSlider
  • ColorPickerSlider
  • DynamicList
  • FileDropZone
  • Info
  • Overlay
  • Spinner
  • Button
  • ModernButton
  • Avatar
  • InputGoogle
  • TextArea
  • InputFile
  • UploadImage
  • Image
  • ImageEditor

Utilities

  • Canvas
  • ImageUtilities
  • Transform
  • tools
  • LinearAlgebra
  • useThemeState

Auth helpers

  • useSession
  • SessionProvider
  • useAuthClient
  • AuthInterface
  • StorageInterface

Installation

This package is intended for React applications.

npm install @willphan1712000/frontend

Make sure your app already has React and React DOM installed:

npm install react react-dom

Will UI Interface (WUII)

To ensure ultimate consistency, all interactive UI components in this package implement the WUII<T> interface. The generic type T represents the data type the component operates on.

The WUII<T> Interface

export default interface WUII<T = any> {
    value?: T;
    setValue?: (value?: T) => void;
    options?: Options;
    range?: Range;
    label?: string;
    isReadOnly?: boolean;
    description?: string;
    styling?: {
        primaryColor?: string;
        backgroundColor?: string;
        textColor?: string;
        hoverBackgroundColor?: string;
        focusColor?: string;
        borderColor?: string;
        destructive?: string;
        width?: string;
    };
    config?: {
        default?: string;
        accept?: string;
    };
}

Common Properties

  • value?: T - The current value of the component.
  • setValue?: (value?: T) => void - Callback to update the value.
  • isReadOnly?: boolean - If set to true, disables user interactions and shows a "Locked - Read Only" tooltip instead of the description.
  • description?: string - Custom tooltip text shown on hover of the info icon.
  • styling?: object - Custom styling overrides (e.g., colors, width).
  • config?: object - Component-specific behavior configuration (e.g., accept file extensions or default assets).

Core component usage

DropdownSelect

DropdownSelect is a custom dropdown selection input component that supports filtering options via an integrated search input, as well as read-only states and custom tooltip info guidance.

import { useState } from 'react';
import { DropdownSelect, type Options } from '@willphan1712000/frontend';

const options: Options = [
  { label: 'Apple', value: 'apple' },
  { label: 'Orange', value: 'orange' },
];

export default function Example() {
  const [value, setValue] = useState('');

  return (
    <DropdownSelect
      options={options}
      value={value}
      setValue={setValue}
      isReadOnly={false}
      description="Choose your preferred fruit"
      styling={{
        backgroundColor: '#ffffff',
        textColor: '#000000',
        hoverBackgroundColor: '#f0f0f0',
      }}
    />
  );
}

Props:

  • options: { label: string; value: string }[] - List of select options.
  • value: string - The currently selected value.
  • setValue: (value?: string) => void - Callback function triggered when a new value is selected.
  • isReadOnly?: boolean - If set to true, disables opening the dropdown list and shows a "Locked - Read Only" tooltip message instead of the description (defaults to false).
  • description?: string - Description tooltip text shown on hover of the info icon (defaults to '').
  • styling?: object - Optional custom styling configurations:
    • backgroundColor?: string - Background color of the select box and list elements (defaults to '#fff').
    • textColor?: string - Color of the text inside the input box and dropdown options (defaults to '#000').
    • hoverBackgroundColor?: string - Background color of an option when hovered (defaults to '#f0f0f0').

MultiSelect

MultiSelect is a custom selection input component allowing users to choose multiple options from a search-enabled dropdown list, featuring tag-style selected values, hover help tooltips, and read-only support.

import { useState } from 'react';
import { MultiSelect } from '@willphan1712000/frontend';

const options = [
  { label: 'React', value: 'react' },
  { label: 'TypeScript', value: 'typescript' },
];

export default function Example() {
  const [values, setValues] = useState<string[]>([]);

  return (
    <MultiSelect
      options={options}
      value={values}
      setValue={setValues}
      isReadOnly={false}
      description="Select your tech stack"
      styling={{
        backgroundColor: '#ffffff',
        textColor: '#000000',
        hoverBackgroundColor: '#f0f0f0',
      }}
    />
  );
}

Props:

  • options: { label: string; value: string }[] - List of select options.
  • value: string[] - An array of currently selected values.
  • setValue: (value?: string[]) => void - Callback to update selected values.
  • isReadOnly?: boolean - If set to true, disables opening the dropdown list, clearing all items, or removing individual options, and displays a "Locked - Read Only" tooltip message instead of the description (defaults to false).
  • description?: string - Description tooltip text shown on hover of the info icon (defaults to '').
  • styling?: object - Optional custom styling configurations:
    • backgroundColor?: string - Background color of the select box and list elements (defaults to '#fff').
    • textColor?: string - Color of the text inside the input box and dropdown options (defaults to '#000').
    • hoverBackgroundColor?: string - Background color of an option when hovered (defaults to '#f0f0f0').

RangeSlider

RangeSlider allows users to select a numeric value within a range by dragging a slider track, with custom tooltip info display and read-only support.

import { useState } from 'react';
import { RangeSlider } from '@willphan1712000/frontend';

export default function Example() {
  const [value, setValue] = useState('50');

  return (
    <RangeSlider
      value={value}
      setValue={setValue}
      range={{
        min: '0',
        max: '100',
      }}
      isReadOnly={false}
      description="Select the volume percentage"
      styling={{
        primaryColor: '#2563eb',
        width: '240',
        backgroundColor: '#ffffff',
        textColor: '#000000',
      }}
    />
  );
}

Props:

  • value: string - The current value.
  • setValue: (value?: string) => void - Callback function triggered when the slider value changes.
  • range?: object - Object containing range boundaries:
    • min?: string - Minimum value of the range (defaults to '0').
    • max?: string - Maximum value of the range (defaults to '100').
  • isReadOnly?: boolean - If set to true, disables dragging or changing the slider, and shows a "Locked - Read Only" tooltip message instead of the description (defaults to false).
  • description?: string - Description tooltip text shown on hover of the info icon (defaults to '').
  • styling?: object - Optional custom styling configurations:
    • primaryColor?: string - Custom track/thumb color (defaults to 'purple').
    • width?: string - The width of the slider component in pixels (defaults to '200').
    • backgroundColor?: string - Background color of the tooltip (defaults to '#fff').
    • textColor?: string - Text color of the tooltip (defaults to '#000').

OptionSlider

OptionSlider allows users to select a value by choosing from a set of options represented visually as blocks, with custom tooltip info display and read-only support.

import { useState } from 'react';
import { OptionSlider } from '@willphan1712000/frontend';

const options = [
  { label: 'Low', value: 'low' },
  { label: 'Medium', value: 'medium' },
  { label: 'High', value: 'high' },
];

export default function Example() {
  const [value, setValue] = useState('medium');

  return (
    <OptionSlider
      value={value}
      setValue={setValue}
      options={options}
      isReadOnly={false}
      description="Choose intensity level"
      styling={{
        backgroundColor: '#ffffff',
        textColor: '#000000',
        borderColor: '#2563eb',
      }}
    />
  );
}

Props:

  • value: string - The current value.
  • setValue: (value?: string) => void - Callback function triggered when a new option is selected.
  • options: { label: ReactNode; value: string }[] - List of options. label can be a React Node representing the option.
  • isReadOnly?: boolean - If set to true, disables changing the selected option, and shows a "Locked - Read Only" tooltip message instead of the description (defaults to false).
  • description?: string - Description tooltip text shown on hover of the info icon (defaults to '').
  • styling?: object - Optional custom styling configurations:
    • backgroundColor?: string - Background color of the tooltip (defaults to '#fff').
    • textColor?: string - Text color of the tooltip (defaults to '#000').
    • borderColor?: string - Border color of the options container and selected option (defaults to '#000').

ColorPickerSlider

ColorPickerSlider allows users to select a color by dragging the slider across a spectrum, with custom tooltip info display and read-only support.

import { useState } from 'react';
import { ColorPickerSlider } from '@willphan1712000/frontend';

export default function Example() {
  const [value, setValue] = useState('#2563eb');

  return (
    <ColorPickerSlider
      value={value}
      setValue={setValue}
      isReadOnly={false}
      description="Pick your favorite color"
      styling={{
        width: '240',
        backgroundColor: '#ffffff',
        textColor: '#000000',
      }}
    />
  );
}

Props:

  • value: string - The current color value.
  • setValue: (value: string) => void - Callback function triggered when the slider value changes.
  • isReadOnly?: boolean - If set to true, disables changing the color slider and shows "Locked - Read Only" tooltip message instead of the description (defaults to false).
  • description?: string - Description tooltip text shown on hover of the info icon (defaults to '').
  • styling?: object - Optional custom styling configurations:
    • width?: string - The width of the slider track in pixels (defaults to '200').
    • backgroundColor?: string - Background color of the tooltip (defaults to '#000').
    • textColor?: string - Text color of the tooltip (defaults to '#fff').

Button

import { Button } from '@willphan1712000/frontend';

export default function Example() {
  return (
    <Button
      buttonType="gradient"
      content="Submit"
      type="button"
      onClick={() => console.log('clicked')}
    />
  );
}

Supports:

  • buttonType="normal"
  • buttonType="solid"
  • buttonType="gradient"

Additional styling props:

  • content?: string
  • main?: string
  • text?: string
  • first?: string
  • second?: string
  • isLoading?: boolean

Also accepts normal button props such as onClick, type, disabled, and style.

Avatar

Avatar combines image upload, preview, edit, and remove flows.

import { useState } from 'react';
import { Avatar } from '@willphan1712000/frontend';

const [src, setSrc] = useState<string | undefined>(undefined);

<Avatar
  value={src}
  setValue={setSrc}
  config={{ default: '/images/default-avatar.png' }}
/>;

Props:

  • value?: string - Current base64 string or URL of the avatar image.
  • setValue: (value?: string) => void - Callback function to update the image string.
  • config?: object - Optional component configurations:
    • default?: string - Default fallback image URL.

DynamicList

DynamicList is an interactive list component that allows users to add, remove, edit, and reorder (via drag-and-drop) a list of text inputs. It supports read-only mode, custom labelling, and hover descriptions.

import { useState } from 'react';
import { DynamicList } from '@willphan1712000/frontend';

const [values, setValues] = useState<string[]>(['Option 1', 'Option 2']);

<DynamicList
  value={values}
  setValue={setValues}
  isReadOnly={false}
  label="option"
  description="List of options"
  styling={{
    backgroundColor: '#ffffff',
    borderColor: '#e2e8f0',
    textColor: '#1a202c'
  }}
/>

Props:

  • value: string[] - An array of strings representing the current values in the list.
  • setValue: (value: string[]) => void - Callback triggered when the list values change.
  • isReadOnly?: boolean - If set to true, disables adding, deleting, editing, and dragging items (defaults to false).
  • label?: string - Label used for input placeholders and the "Add" button (defaults to 'value').
  • description?: string - Description tooltip text shown on hover of the info icon (defaults to '').
  • styling?: object - Optional configurations:
    • backgroundColor?: string - Background color for the list container and items (defaults to '#fff').
    • borderColor?: string - Border color for the list container and items (defaults to '#f0f0f0').
    • textColor?: string - Text color for input values and buttons (defaults to '#000').

FileDropZone

FileDropZone provides an interactive drag-and-drop area for uploading files, with custom validation by file extension and support for custom styling.

import { useState } from 'react';
import { FileDropZone } from '@willphan1712000/frontend';

const [file, setFile] = useState<File | undefined>(undefined);

<FileDropZone
  label="Upload configuration"
  value={file}
  setValue={setFile}
  config={{ accept: '.json' }}
  isReadOnly={false}
  description="Drag & drop your JSON configuration file"
  styling={{
    backgroundColor: '#fafafa',
    borderColor: '#1a73e8',
    textColor: '#3c4043',
    destructive: '#d93025'
  }}
/>

Props:

  • label?: string - The text prompt displayed inside the drop zone.
  • value?: File - Optional initial file to display as selected.
  • setValue?: (value?: File) => void - Callback function triggered when a valid file is dropped or selected.
  • config?: object - Optional configuration for component options:
    • accept?: string - Allowed file extension/type suffix (e.g. ".json").
  • isReadOnly?: boolean - If set to true, disables changing the file and shows "Locked - Read Only" tooltip message instead of the description (defaults to false).
  • description?: string - Description tooltip text shown on hover of the info icon (defaults to '').
  • styling?: object - Optional configuration for custom styling:
    • backgroundColor?: string - Custom background color of the drop zone (defaults to '#fff').
    • borderColor?: string - Custom border color of the drop zone (defaults to '#fff').
    • textColor?: string - Custom text and icon color inside the drop zone (defaults to '#000').
    • destructive?: string - Custom color for error messages (defaults to '#df0408').

Info

Info renders a hover-help icon that displays a tooltip-style message when hovered. The tooltip automatically flips to the opposite side when it would overflow the viewport edges.

import { Info } from '@willphan1712000/frontend';

<Info
  message="Helpful guidance for this field."
  options={{
    color: '#1f2937',
    backgroundColor: '#f3f4f6',
  }}
/>

Props:

  • message?: string - Tooltip content shown on hover.
  • options?: { color?: string; backgroundColor?: string } - Optional styling for the tooltip text and background.

Overlay

Overlay renders a full-screen background overlay (with a backdrop blur effect) around a central content container. Clicking outside the content container (on the overlay itself) triggers a close callback.

import { useState } from 'react';
import { Overlay } from '@willphan1712000/frontend';

const [isOpen, setIsOpen] = useState(false);

<Overlay
  open={isOpen}
  close={() => setIsOpen(false)}
  options={{
    backgroundColor: 'rgba(0, 0, 0, 0.5)'
  }}
>
  <div style={{ padding: '20px', background: '#fff', borderRadius: '8px' }}>
    <h3>Overlay Content</h3>
    <p>This is inside the overlay.</p>
  </div>
</Overlay>

Props:

  • open?: boolean - Controls whether the overlay is visible.
  • close?: () => void - Callback function triggered when the overlay is clicked (outside the child element).
  • options?: object - Optional custom configurations:
    • backgroundColor?: string - Custom background color of the overlay (defaults to '#fff').
  • children?: React.ReactNode - Content inside the center container.

Spinner

Spinner renders a full-screen modal loading overlay with an animated spinning circle indicator and customizable text, implementing the WUII<string> interface.

import { Spinner } from '@willphan1712000/frontend';

export default function Example() {
  return (
    <Spinner
      value="WillPhan"
      styling={{
        textColor: '#6f6f6f',
      }}
    />
  );
}

Props:

  • value?: string - Custom text displayed below the circular spinner (defaults to 'WillPhan').
  • styling?: object - Optional custom styling configurations:
    • textColor?: string - Color for the text gradient base and active spinner top border (defaults to '#6f6f6f').

InputGoogle

InputGoogle is a floating label input component designed to mimic Google's sign-in input fields, with built-in tooltip info display and read-only support.

import { useState } from 'react';
import { InputGoogle } from '@willphan1712000/frontend';

export default function Example() {
  const [value, setValue] = useState('');

  return (
    <InputGoogle
      value={value}
      setValue={setValue}
      label="Email or phone"
      description="Enter your registered email address"
      isReadOnly={false}
      styling={{
        focusColor: '#1a73e8',
        backgroundColor: '#ffffff',
        textColor: '#202124',
        borderColor: '#dadce0',
      }}
    />
  );
}

Props:

  • value?: string - The current value of the input field.
  • setValue?: (value?: string) => void - Callback function triggered on input change.
  • label?: string - The text for the floating label (defaults to 'Input Google Component Label').
  • description?: string - Description tooltip text shown on hover of the info icon (defaults to 'Input Google Description'). Displays when the input is not read-only.
  • isReadOnly?: boolean - If set to true, the input becomes read-only and displays a "Locked - Read Only" tooltip message instead of the description (defaults to false).
  • styling?: object - Optional configuration for custom styling:
    • focusColor?: string - Border and label color when the input is focused.
    • backgroundColor?: string - Background color of the input container and label background.
    • textColor?: string - Color of the text input and default label state.
    • borderColor?: string - Default border color when not focused.

TextArea

TextArea is a floating label multi-line text input component with built-in tooltip info display and read-only support.

import { useState } from 'react';
import { TextArea } from '@willphan1712000/frontend';

export default function Example() {
  const [value, setValue] = useState('');

  return (
    <TextArea
      value={value}
      setValue={setValue}
      label="Bio"
      description="Tell us about yourself"
      isReadOnly={false}
      styling={{
        focusColor: '#1a73e8',
        backgroundColor: '#ffffff',
        textColor: '#202124',
        borderColor: '#dadce0',
      }}
    />
  );
}

Props:

  • value?: string - The current value of the textarea.
  • setValue?: (value?: string) => void - Callback function triggered on value change.
  • label?: string - The text for the floating label (defaults to 'Text Area Component Label').
  • isReadOnly?: boolean - If set to true, the textarea becomes read-only and displays a "Locked - Read Only" tooltip message instead of the description (defaults to false).
  • description?: string - Description tooltip text shown on hover of the info icon (defaults to 'Text Area Description'). Displays when the textarea is not read-only.
  • styling?: object - Optional configuration for custom styling:
    • focusColor?: string - Border and label color when the textarea is focused.
    • backgroundColor?: string - Background color of the textarea container and label background.
    • textColor?: string - Color of the text and default label state.
    • borderColor?: string - Default border color when not focused.

Auth usage

The auth helpers are designed around an auth client object that implements AuthInterface.

import {
  SessionProvider,
  useAuthClient,
  type AuthInterface,
} from '@willphan1712000/frontend';

class AuthClient implements AuthInterface {
  getSignInUrl() {
    return '/signin';
  }

  async signin() {}

  async validate() {
    return {
      username: 'will',
      email: '[email protected]',
      role: 'admin',
    };
  }

  async signout() {}
}

const authClient = new AuthClient();

function AppProviders({ children }: { children: React.ReactNode }) {
  const session = useAuthClient(authClient);

  return (
    <SessionProvider value={session}>
      {children}
    </SessionProvider>
  );
}

useAuthClient returns:

  • isLoading
  • session
  • auth

Theme management usage

useThemeState

A custom React hook for managing, persisting, and applying the application's theme state ('light', 'dark', or 'system'). It synchronizes state with browser localStorage and applies/removes the theme class on document.body.

import { useThemeState } from '@willphan1712000/frontend';

const Example = () => {
  const { setThemeState, getThemeState } = useThemeState();

  return (
    <div>
      <p>Current Theme: {getThemeState()}</p>
      <button onClick={() => setThemeState('light')}>Light</button>
      <button onClick={() => setThemeState('dark')}>Dark</button>
      <button onClick={() => setThemeState('system')}>System</button>
    </div>
  );
};

API Reference

  • getThemeState(): 'light' | 'dark' | 'system'
    Retrieves the active theme setting from localStorage. Defaults to 'light'.
  • setThemeState(mode: 'light' | 'dark' | 'system'): void
    Sets the active theme setting.
    • 'light': Stores 'light', removes 'will-dark' class from document.body, and disables OS preference event listeners.
    • 'dark': Stores 'dark', adds 'will-dark' class to document.body, and disables OS preference event listeners.
    • 'system': Stores 'system', automatically toggles 'will-dark' based on OS preferences, and registers a listener to react to future OS preference changes.

Configuration Details

  • Local Storage Key: 'will-theme'
  • CSS Class Applied to <body>: 'will-dark'

Exported utilities

import {
  Canvas,
  ImageUtilities,
  Transform,
  tools,
  LinearAlgebra,
} from '@willphan1712000/frontend';

Included helpers:

  • tools.handleAsync(...)
  • tools.textProcessing(...)
  • tools.getOrCreateUUID(...)
  • tools.copyToClipboard(...)

Development

Install dependencies:

npm install

Build the package:

npm run build

Run in watch mode during development:

npm run dev

Local package testing with npm link

Inside this package:

npm link

Inside the app where you want to test it:

npm link @willphan1712000/frontend

If React reports multiple copies loaded, link the consumer app's React instance:

npm link <path_to_your_testing_project>/node_modules/react

Notes

  • The package is built with tsup.
  • It ships CommonJS, ESM, and TypeScript declaration files.
  • Source code is written in TypeScript and React.

Contributing

If you find a bug or want to improve the package, open an issue or submit a pull request.

Portfolio:

Contact: