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

fancy-ui-ts

v1.3.3

Published

A library to easily create cool and customizable webcomponents.

Readme

Fancy UI

A lightweight, cool, customizable Web Component library built with TypeScript. Works with React, Vue, Angular, Svelte, or plain HTML/JS.

Installation

npm install fancy-ui-ts

1. Quick Start

Registration

Before using a component, you must register it with the browser.

import { defineInput } from './index';

defineInput(); 

You can also register every component at once:

import { defineAll } from './index';

defineAll(); 

Basic HTML Usage

<form>
  <fc-input 
    name="username" 
    placeholder="Enter username" 
    required 
    minlength="3"
  >
  </fc-input>

  <fc-input 
    type="password" 
    name="password" 
    required
  >
  </fc-input>
</form>

2. Setting Properties & Attributes

Most fc-components have properties that can be set as custom attributes, they also accepts default attributes. You can configure the component using HTML Attributes or JavaScript Properties.

Via HTML Attributes

Use this for static configuration or simple strings.

<fc-input 
  label="Email" 
  type="email" 
  disabled
  placeholder="[email protected]"
></fc-input>

Via JavaScript Properties

In some cases, you'll need to pass dynamic data, complex objects, arrays or event listeners. You can't do that as attributes, you must pass them with Javascript:

const input = document.querySelector('fc-input');

input.value = "New Value";
input.disabled = true;
input.required = false;

// The setProps() helper: useful for setting multiple properties at once using a configuration object.
input.setProps({
  value: "Dynamic Value",
  placeholder: "Updated Placeholder",
  readOnly: true
});

3. Styling & Theming

The component uses Shadow DOM, which means internal elements (like the actual <input> tag) are isolated from global CSS. You cannot style internal classes like .fc-input-field directly. Instead, you use CSS Variables or style the Host Component.

Strategy A: CSS Variables (Theming)

Variables pierce the Shadow DOM and are the primary way to theme the component.

/* Apply globally to all inputs */
:root {
  --fc-input-bg: #ffffff;
  --fc-input-border: #ccc;
  --fc-input-focus-ring: 0 0 0 3px rgba(0, 123, 255, 0.25);
  --fc-input-radius: 4px;
}

/* Apply only on a theme */
:root[fc-theme="dark"] {
    --fc-input-bg: #333;
    --fc-input-fg: #fff;
}

/* Apply to a specific class */
.username-input {
  --fc-input-border: #555;
}

Strategy B: Host Styling

You can style the element tag itself (dimensions, margins, display).

/* Target by tag name */
fc-input {
  display: block;
  margin-bottom: 1rem;
  width: 100%;
  max-width: 400px;
}

/* Target by class */
.my-custom-input {
  width: 50%;
}

/* Target specific states provided by the component */
fc-input[disabled] {
  opacity: 0.7;
}

fc-input[touched]:invalid {
  /* You can style the host wrapper when error exists */
  animation: shake 0.2s ease-in-out;
}

4. Events

Each element has its own unique events that are emitted from it. Even though the elements still standart events like input, click, blur, because of the nature of the Shadow DOM, it is highly recommended to listen to only custom Events.

const el = document.querySelector('fc-input');

el.addEventListener('fc-input', (e) => {
  console.log('Typing:', e.detail.value);
});

el.addEventListener('fc-change', (e) => {
  console.log('Committed:', e.detail.value);
});

5. Validation Logic

Some elements has validation logic, most are form field elements, link inputs, select, combobox, etc. Visual errors (red borders) are suppressed until the user interacts with the field (blur) or submits the form. Validation works in two layers:

Layer 1: Native Attributes

Standard HTML5 attributes work automatically.

  • required, min, max, step
  • minlength, maxlength, pattern
  • type="email", type="url"

Layer 2: Custom Validator Function

You can inject custom business logic using the .validator property.

const usernameInput = document.getElementById('user-field');

// Function receives value -> returns Error String or Null
usernameInput.validator = (value) => {
  if (value.toLowerCase() === 'admin') {
    return 'This username is reserved.'; // Error message
  }
  return null; // Valid
};

On both ways, you can also use our custom <fc-error> component to display the error message as a paragraph:

<fc-input 
  id="email-field"
  label="Email" 
  type="email" 
  disabled
  placeholder="[email protected]"
>
</fc-input>
<fc-error 
  for="email-field"
>
</fc-error>

6. Accessibility (A11y)

  • Delegates Focus: Most elements has delegate focus, which means clicking anywhere on the component focuses the internal input.
  • ARIA Labels: aria-label, aria-labelledby, aria-describedby and others aria's can be set directly to the fc-element. The browser automatically maps them to the respective internal element.
  • Auto-States: aria-disabled, aria-required, and aria-invalid are automatically managed by ElementInternals. Do not set these manually.
  • Other: Other aria properties are added directly to the element template because they do not need to be custom and does not change. Example: <fc-combobox> has keyboard mapping arias added to its template, <fc-input> has 'aria-live' on its internal input element, etc.

7. Attribute Reflection

For all properties (disabled, placeholder, min, etc.), the component uses Reflection.

  • JS to HTML: Setting el.disabled = true adds the disabled attribute to the HTML tag.
  • HTML to JS: Changing the HTML attribute triggers attributeChangedCallback, which updates the internal logic.