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

@fastyshop/ui

v0.13.1

Published

`@fastyshop/ui` contains the shared FastyShop product tokens, React components, and public hooks. The package ships ESM, TypeScript declarations, Tailwind CSS v4 integration, the Inter variable font, the FastyShop Empty and Field patterns, Dialog, AlertDi

Readme

@fastyshop/ui

@fastyshop/ui contains the shared FastyShop product tokens, React components, and public hooks. The package ships ESM, TypeScript declarations, Tailwind CSS v4 integration, the Inter variable font, the FastyShop Empty and Field patterns, Dialog, AlertDialog, Drawer, DrawerMenu, AdaptiveDialog, AdaptiveMenu, Menu, Alert, Accordion, InputGroup, NumberField, OTPField, Tooltip, CheckboxGroup and ButtonLink and Pagination components, BrandMark, BrandWordmark, BrandLockup, Avatar, Badge, Button, Label, Link, Meter, Progress, Select, Separator, Skeleton, Spinner, Tabs, Toast and Typography components and primitives, and the useComboboxFilter, useCopyToClipboard and useMediaQuery hooks.

Install

Install an exact published version from the public npm registry. No npm login or read token is required. This source prepares 0.13.1; the command below applies after its separately approved publication. Until then, 0.12.0 remains the latest published version and does not include Pagination.

pnpm add @fastyshop/[email protected]

React and React DOM are peer dependencies. Supported versions are >=19.2.0 <20. The package requires Node.js >=24.18.0 <25 for build and server-side use.

CSS and themes

Import the runtime stylesheet once near the root of the application:

@import "@fastyshop/ui/styles.css";

Light is the default theme. Set data-fs-theme="dark" on the document root or on a bounded subtree to use the dark semantic values:

<html data-fs-theme="dark"></html>

The runtime stylesheet includes the bundled Inter variable font and the package component styles. If your application already loads Inter, keep one authoritative font declaration and verify that its family and weights match the package contract.

Tailwind CSS v4 consumers can additionally import the semantic utility bridge:

@import "tailwindcss";
@import "@fastyshop/ui/tailwind-theme.css";

The bridge maps fs-prefixed utilities to the runtime CSS variables. It does not copy token values into the consuming application. It deliberately replaces Tailwind's default responsive variants with only md: 48rem and lg: 64rem.

Responsive layout

The page shell remains full-width. Use the responsive semantic grid without a global container or page-level max-width:

<main
  class="grid min-w-0 grid-cols-4 gap-x-fs-grid-column-gap md:grid-cols-8 lg:grid-cols-12"
></main>

Forms and prose opt into local measures with w-full max-w-(--fs-layout-content-form-max) or w-full max-w-(--fs-layout-content-prose-max). Wide tables and timelines own a labelled, keyboard-focusable local scroller; they must not make body scroll horizontally. See the repository's docs/responsive-layout.md for safe-area, overflow, container-query, and localization guidance.

Overlay authors must additionally follow the repository's docs/overlay-viewport-environment.md: free-standing surfaces use the maximum of page gutter and safe area, flush-edge content adds panel padding to the maximum current occlusion, and a form-heavy bottom Drawer delegates software keyboard alignment to Base UI's public Drawer.VirtualKeyboardProvider. The repository's docs/overlay-interaction-boundaries.md also defines semantic topmost ownership, focus entry/return, modality, dismissal, synchronous close prevention and Toast coexistence. Base UI remains the sole mechanics owner; consumers do not add document-level focus or dismissal managers. The repository-only docs/overlay-conformance.md smoke verifies only the shared Foundation boundaries before public overlay families exist; it does not materialize their component behavior and is not part of this package's exports or installed payload.

Brand

import { BrandLockup } from "@fastyshop/ui";

export function ProductIdentity() {
  return <BrandLockup variant="on-light" decorative={false} />;
}

Brand uses the outlined J6.4 artwork, without a runtime font or automatic theme selection. variant and decorative are required. Minimum SVG viewport widths are 16px for BrandMark, 128px for BrandWordmark and 160px for BrandLockup; defaults are 24/128/192px. Use proportional width, not independent height or fill overrides. Leave clear space of 32 × width / viewBoxWidth on every side. Inside a named link, use a decorative Brand and name the link for its destination.

Raw assets resolve through @fastyshop/ui/brand/manifest.json, @fastyshop/ui/brand/assets/mark/fastyshop-mark-on-light.svg, @fastyshop/ui/brand/assets/app-icons/app-icon-192.png and @fastyshop/ui/brand/licenses/Saira-OFL.txt. These are file-resolution/copy subpaths, not a universal JavaScript image loader. All asset and license paths in the manifest resolve within this bundle; upstream proof/evidence references are provenance only and are not distributed. The source-copy registry provides React/TS/CSS only. See the repository's docs/brand.md for the complete contract.

Menu

"use client";

import { Menu, MenuItem, MenuPopup, MenuTrigger } from "@fastyshop/ui";

export function OrderActions({ onArchive }: { onArchive: () => void }) {
  return (
    <Menu>
      <MenuTrigger>Actions</MenuTrigger>
      <MenuPopup>
        <MenuItem onClick={onArchive}>Archive</MenuItem>
      </MenuPopup>
    </Menu>
  );
}

Menu supports controlled and uncontrolled opening, native links, checkbox, switch and radio items, hover opening and submenus. The caller owns routing, permissions, localized labels and asynchronous actions. Base UI owns keyboard, focus and dismissal mechanics. See the Menu contract for all 15 runtime exports, 16 public types and composition recipes.

Pagination

Use a named Pagination with the manual compound parts for caller-owned layouts, or use PaginationControls for a bounded numbered window. Page state, routing, labels and number formatting remain application-owned.

import { Pagination, PaginationControls } from "@fastyshop/ui";

<Pagination aria-label="Order pages">
  <PaginationControls
    mode="link"
    page={10}
    pageCount={20}
    labels={{
      previous: "Previous page",
      next: "Next page",
      page: (page) => `Page ${page}`,
    }}
    getHref={(page) => `/orders?page=${page}`}
  />
</Pagination>;

Use mode="button" with onPageChange for application-controlled transitions. Manual composition exports PaginationList, PaginationItem, PaginationPage, PaginationPrevious, PaginationNext and PaginationEllipsis. Import the shared stylesheet once for both forms.

Dialog and confirmation

"use client";

import {
  Dialog,
  DialogTrigger,
  DialogPopup,
  DialogTitle,
  DialogDescription,
  DialogClose,
} from "@fastyshop/ui";

export function NoteDialog() {
  return (
    <Dialog>
      <DialogTrigger>Open note</DialogTrigger>
      <DialogPopup closeButtonLabel="Close note">
        <DialogTitle>Note</DialogTitle>
        <DialogDescription>Review this message before continuing.</DialogDescription>
        <DialogClose>Done</DialogClose>
      </DialogPopup>
    </Dialog>
  );
}

Dialog includes responsive desktop/mobile presentation, reduced motion, Header/Panel/Footer composition, three modality profiles, synchronous close veto, nested surfaces and typed detached/multiple triggers. Native forms and async state remain caller-owned. See the Dialog contract for public props and Menu-to-Dialog and dirty-draft recipes.

The controlled AlertDialog companion requires a visible Title, Description and text Cancel (AlertDialogClose). Initial focus chooses Cancel; outside interaction never confirms or dismisses. Confirm is a caller-owned Button, separate from Cancel/Escape. See the AlertDialog contract for the complete seven-part composition and pending/error handling.

Form

Form, FormProps and FormErrors are included in 0.9.0. Form renders a native form and composes with named Field/FieldControl and Input, Textarea, Checkbox, RadioGroup, Switch, Select and Combobox. Registered invalid fields block submission and receive first-invalid focus. Pass localized messages through errors keyed by Field name; an empty <FieldError /> displays the active field message.

The caller owns onSubmit, values and payload creation, including FormData. For client validation or requests, call event.preventDefault() synchronously. Zod schemas, React Query mutations, pending, duplicate-submit protection and retry belong to the application; these libraries are not package runtime dependencies. Form provides no intrinsic layout or universal reset-all engine. See the Form contract for native and external validation recipes.

Combobox and native forms

Combobox supports direct Field composition for single or ordered multiple selection, with search in the main control or in the popup. Field labels, descriptions and errors reference the primary Input, ChipsInput or external Trigger. Root name, form and required participate in ordinary HTML forms: FormData contains accepted stable keys, while the search query stays separate. Native validation focuses the primary control, and reset restores mounted uncontrolled keys/query without change callbacks, including inside a ShadowRoot. Controlled axes remain caller-owned.

See the Combobox contract for composition recipes and the accepted input-outside accessibility limitation.

Select

Provide the complete item catalog on the root and render matching items inside the popup:

import {
  Select,
  SelectItem,
  SelectLabel,
  SelectPopup,
  SelectTrigger,
  SelectValue,
} from "@fastyshop/ui";

const countries = [
  { value: "kz", label: "Kazakhstan" },
  { value: "kg", label: "Kyrgyzstan" },
] as const;

<Select items={countries} defaultValue={null} name="country">
  <SelectLabel>Country</SelectLabel>
  <SelectTrigger>
    <SelectValue placeholder="Choose a country" />
  </SelectTrigger>
  <SelectPopup>
    {countries.map((item) => (
      <SelectItem key={item.value} value={item.value}>
        {item.label}
      </SelectItem>
    ))}
  </SelectPopup>
</Select>;

See the repository's docs/select.md for object values, multiple selection, groups, form behavior and the full composition contract.

Toast

Mount one provider near the application shell, then add notifications through the shared manager:

import { ToastProvider, toastManager } from "@fastyshop/ui";

<ToastProvider closeLabel="Close notification" viewportLabel="Notifications">
  {children}
</ToastProvider>;

toastManager.add({ title: "Order created", type: "success" });

See the repository's docs/toast.md for actions, promise notifications, timeouts, portal ownership and the full lifecycle contract.

Button

import { Button } from "@fastyshop/ui";

export function SaveAction() {
  return <Button>Save</Button>;
}

Button is a client component backed by Base UI. The package owns that runtime dependency; consumers do not install Base UI, Radix, or shadcn directly. Use Link or ButtonLink for navigation, keep loading controlled, and provide a non-empty aria-label for icon-only buttons.

Link

import { Link } from "@fastyshop/ui";

export function CatalogLink() {
  return <Link href="/catalog">Catalog</Link>;
}

Link is the server-safe text-navigation primitive. It preserves native anchor semantics and supports a controlled render callback for framework routers without adding a framework dependency to the package.

ButtonLink

import { ButtonLink } from "@fastyshop/ui";

export function CheckoutLink() {
  return <ButtonLink href="/checkout">Continue to checkout</ButtonLink>;
}

ButtonLink is server-safe button-shaped navigation. It shares Button's visual recipe but always materializes an anchor-compatible root and does not expose action-only loading, disabled, press, or form behavior.

Avatar

import { Avatar, AvatarFallback, AvatarImage } from "@fastyshop/ui";

export function MerchantAvatar() {
  return (
    <Avatar>
      <AvatarImage alt="Aruzhan Bek" src="/merchant-avatar.jpg" />
      <AvatarFallback>AB</AvatarFallback>
    </Avatar>
  );
}

Avatar owns image load/failure switching, size and shape. Consumers own the image request, alternative text, fallback content and surrounding interaction.

Badge

import { Badge } from "@fastyshop/ui";

export function PaymentState() {
  return <Badge variant="success">Paid</Badge>;
}

Badge is a compact label for status, category and short metadata. Its native span, a and button roots preserve their distinct semantics.

Label

import { Label } from "@fastyshop/ui";

export function ShopNameLabel() {
  return <Label htmlFor="shop-name">Shop name</Label>;
}

Label is the server-safe native label primitive. Consumers own stable control IDs, field lifecycle, validation and description or error association.

Field

import { Field, FieldControl, FieldDescription, FieldError, FieldLabel } from "@fastyshop/ui";

export function EmailField({ showErrors }: { showErrors: boolean }) {
  return (
    <Field touched={showErrors}>
      <FieldLabel requirement="Required">Email</FieldLabel>
      <FieldControl required type="email" />
      <FieldDescription>Used for order notifications.</FieldDescription>
      <FieldError match={showErrors ? "valueMissing" : false}>Enter your email.</FieldError>
    </Field>
  );
}

Field is the single-control form composition. It owns label, description and error association while consumers own localized copy, validation rules and error timing.

Meter

import { Meter, MeterIndicator, MeterLabel, MeterTrack, MeterValue } from "@fastyshop/ui";

export function PublishedProductsMeter() {
  return (
    <Meter
      getAriaValueText={(_, rawValue) => `Used ${rawValue} of 200 products`}
      max={200}
      tone="success"
      value={69}
    >
      <MeterLabel>Published products</MeterLabel>
      <MeterValue>{(_, rawValue) => `${rawValue} / 200`}</MeterValue>
      <MeterTrack>
        <MeterIndicator />
      </MeterTrack>
    </Meter>
  );
}

Meter is a read-only scalar range primitive backed by Base UI. It normalizes visual and ARIA output to the configured finite range while preserving the raw value for formatter callbacks. Consumers own units, thresholds, localized status copy and announcements; use Progress for an ongoing operation. See the repository guide for the complete composition, accessibility, tone and registry contracts.

Progress

import { Progress } from "@fastyshop/ui";
import { ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue } from "@fastyshop/ui";

export function CatalogUploadProgress() {
  return (
    <Progress
      getAriaValueText={(_, rawValue) => `Uploaded ${rawValue} of 512 MB`}
      max={512}
      value={502}
    >
      <ProgressLabel>Catalog upload</ProgressLabel>
      <ProgressValue>{(_, rawValue) => `${rawValue} / 512 MB`}</ProgressValue>
      <ProgressTrack>
        <ProgressIndicator />
      </ProgressTrack>
    </Progress>
  );
}

Progress is a read-only operation range backed by Base UI. A finite value renders determinate progress; value={null} is the only indeterminate state. Consumers own requests, result state, localized copy and announcements. See the repository guide for the complete composition, accessibility, motion and registry contracts.

Tabs

import { Tabs, TabsList, TabsPanel, TabsTab } from "@fastyshop/ui";

export function ProductSections() {
  return (
    <Tabs defaultValue="overview">
      <TabsList aria-label="Product sections" variant="underline">
        <TabsTab value="overview">Overview</TabsTab>
        <TabsTab value="details">Details</TabsTab>
      </TabsList>
      <TabsPanel value="overview">Overview content</TabsPanel>
      <TabsPanel value="details">Details content</TabsPanel>
    </Tabs>
  );
}

Tabs is a client primitive backed by Base UI. It owns tab semantics, generated Tab/Panel relationships, roving keyboard focus and one private moving indicator. Callers provide an explicit controlled or uncontrolled string selection, one localized tab-list name, visible labels and matching panels. Routing, data loading, overflow treatment and form submission policy stay outside the primitive. See the repository guide for the complete behavior, lifecycle and registry contracts.

Empty

import { Empty, EmptyDescription, EmptyHeader, EmptyTitle } from "@fastyshop/ui";

export function OrdersEmpty() {
  return (
    <Empty aria-labelledby="orders-empty-title">
      <EmptyHeader>
        <EmptyTitle id="orders-empty-title">No orders yet</EmptyTitle>
        <EmptyDescription>New orders will appear here.</EmptyDescription>
      </EmptyHeader>
    </Empty>
  );
}

Empty is a server-safe composition pattern with default and compact density recipes. Consumers choose which subcomponents to render and own all localized copy, state, announcements and actions. The optional media wrapper is decorative; titles remain real h1–h6 headings. See the repository guide for the full composition, media, accessibility and registry contracts.

Typography

import { Typography } from "@fastyshop/ui";

export function PageTitle() {
  return (
    <Typography as="h1" variant="heading-lg">
      Orders
    </Typography>
  );
}

variant is required and selects one of the eleven semantic typography roles; as independently selects span (default), p, div, h1–h6, blockquote, or figcaption. Typography is server-safe, inherits color, neutralizes native margins, and leaves wrapping and document hierarchy to the consumer. Component-owned labels and titles keep their owning component DOM instead of adding a nested Typography wrapper. See the repository guide for the complete API and role guidance.

Spinner

import { Spinner } from "@fastyshop/ui";

export function OrdersStatus() {
  return <Spinner decorative={false} label="Loading orders" />;
}

Spinner is server-safe and decorative by default. Announced use requires a caller-owned localized label. The consumer owns loading lifecycle, aria-busy, completion, errors and retries. Sizes are sm, md and lg; color inherits from context, reduced motion disables rotation, and forced colors follow the system-adjusted foreground. See the repository guide for the full semantic and registry contract.

Separator

import { Separator } from "@fastyshop/ui";

export function OrderSummaryBoundary() {
  return <Separator />;
}

Separator is server-safe and decorative by default. Set decorative={false} only when the divider is a meaningful document boundary; choose horizontal or vertical orientation and keep surrounding spacing and vertical length in the consumer. See the repository guide for the complete semantics and composition contract.

Skeleton

import { Skeleton } from "@fastyshop/ui";

export function OrderCardPlaceholder() {
  return <Skeleton className="order-card-placeholder" />;
}

Skeleton is a decorative, server-safe loading placeholder. The consumer owns its geometry, changing-region aria-busy state and localized status message. Reduced motion disables pulsing, while forced colors preserve a visible static boundary. See the repository guide for sizing and accessibility guidance.

useMediaQuery

"use client";

import { useMediaQuery } from "@fastyshop/ui";

export function ResponsiveBehavior() {
  const isDesktop = useMediaQuery("desktop");
  const reduceMotion = useMediaQuery("(prefers-reduced-motion: reduce)");
  return <span>{isDesktop && !reduceMotion ? "Enhanced motion" : "Standard view"}</span>;
}

FastyShop shorthand maps tablet to 48rem and desktop to 64rem; max-* uses an exclusive upper boundary. Structured input supports min, max, and pointer. Server rendering and initial hydration return false, then React synchronizes the client match. Prefer CSS media/container queries for visual layout. The current browser contract uses modern MediaQueryList events and Media Queries Level 4 range syntax. The full API, browser boundary, and raw-query examples are documented in the repository guide.

useCopyToClipboard

"use client";

import { useCopyToClipboard } from "@fastyshop/ui";

export function CopyOrderId({ orderId }: { orderId: string }) {
  const { copyToClipboard, isCopied } = useCopyToClipboard();

  return (
    <button onClick={() => void copyToClipboard(orderId)} type="button">
      {isCopied ? "Copied" : "Copy order id"}
    </button>
  );
}

copyToClipboard resolves to success, empty, unsupported, or failed. Only an empty string skips the browser API; other strings are passed to navigator.clipboard.writeText unchanged. isCopied is transient presentation state for the latest call. Consumers own localized and accessible feedback, analytics, and recovery behavior. The full result, lifecycle, server, and source-copy contracts are documented in the repository guide.

Package boundary

The public exports are:

  • @fastyshop/ui
  • @fastyshop/ui/styles.css
  • @fastyshop/ui/tailwind-theme.css

Source files, tests, Storybook, registry tooling, and private design evidence are not part of the npm tarball. The package is MIT licensed; bundled Inter files retain the SIL Open Font License 1.1 and adapted Empty material retains its upstream MIT terms as described in THIRD_PARTY_NOTICES.md.