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

@srvzr/cards

v0.1.0

Published

Self-contained SRVZ / SRVZr card components (Events, Services, Rentals, Stints, Menus). Props-only, no external data dependencies, mobile/desktop variants.

Readme

@srvzr/cards

Self-contained React card components ported 1:1 from the SRVZr mobile app. Drop them into any React project — no context, no store, no external dependencies.

v0.1.0 · MIT · ESM + CJS + TypeScript declarations included

npm


Cards

| | Dark | Light | |---|---|---| | EventCard | Event dark | Event light | | ServiceCard | Service dark | Service light | | RentalCard | Rental dark | Rental light | | StintCard | Stint dark | Stint light | | MenuCard | Menu dark | Menu light |


Install

npm install @srvzr/cards
# or
pnpm add @srvzr/cards

Styles are injected automatically (bundled via tsup injectStyle). No CSS import needed.


Quick Start

import { EventCard, ServiceCard, RentalCard, StintCard, MenuCard } from '@srvzr/cards';

function App() {
  return (
    <EventCard
      id="evt-1"
      name="Summer Rooftop Mixer"
      description="Live music, drinks and a skyline view."
      image="https://example.com/event.jpg"
      date={new Date('2026-06-02T19:00:00')}
      tags={['Music', 'Networking']}
    />
  );
}

Components

All cards share these base props:

| Prop | Type | Default | Description | |---|---|---|---| | variant | 'desktop' \| 'mobile' | 'desktop' | Layout variant | | theme | 'dark' \| 'light' | 'dark' | Colour scheme | | className | string | — | Extra class names | | style | React.CSSProperties | — | Inline style / CSS token overrides |


EventCard

Full-bleed image card for events. Shows a live countdown badge, title, date, description, tag chips, and a "View" footer.

<EventCard
  id="evt-1"
  name="Summer Rooftop Mixer"
  description="Live music, drinks and a skyline view to kick off the season."
  image="https://example.com/event.jpg"
  date={new Date('2026-06-02T19:00:00')}
  tags={['Music', 'Networking', 'Drinks']}
  eventColor="#79C1F0"
  variant="desktop"
  theme="dark"
  onClick={() => {}}
/>

| Prop | Type | Description | |---|---|---| | id | string | Unique card id | | name | string | Event name | | description | string | Short description | | image | string | Cover image URL | | date | Date \| string \| number \| { seconds: number } | Event date/time | | tags | string[] | Tag chips | | eventColor | string | Accent hex colour | | onClick | () => void | Click handler |


ServiceCard

Portrait card for a bookable service. Full-bleed icon image with gradient overlay, title, question phrase, bullet description, tags, and CTA buttons.

<ServiceCard
  id="svc-1"
  serviceName="Deep Cleaning"
  questionPhrase="What's your space?"
  bulletDescription="• Kitchen\n• Bathrooms\n• Floors"
  iconImage="https://example.com/cleaning.jpg"
  accentColour="#3B82F6"
  tags={['Home', 'Office']}
  onSaveClick={() => {}}
  onClick={() => {}}
/>

| Prop | Type | Description | |---|---|---| | id | string | Unique card id | | serviceName | string | Service title | | questionPhrase | string | Sub-heading question | | bulletDescription | string | Newline-separated bullet points | | iconImage | string | Cover image URL | | accentColour | string | Accent hex colour | | tags | string[] | Tag chips | | isSaved | boolean | Bookmark state | | onSaveClick | () => void | Bookmark button handler | | onClick | () => void | Click handler |


RentalCard

Full-bleed rental listing card with multiple images and an animated vertical indicator strip. Transparent-mode renders a product PNG with padding instead of a cover crop.

<RentalCard
  id="rnt-1"
  itemName="Downtown Loft"
  subheading="2BR · City center · Sleeps 4"
  images={[
    { url: 'https://example.com/loft.jpg', transparent: false },
    { url: 'https://example.com/camera-kit.png', transparent: true },
  ]}
  pricePerDay={149}
  accentColor="#F59E0B"
  tags={['Apartment', 'City', 'WiFi']}
  onSaveClick={() => {}}
  onClick={() => {}}
/>

| Prop | Type | Description | |---|---|---| | id | string | Unique card id | | itemName | string | Item / listing name | | subheading | string | Sub-heading line | | images | RentalImage[] \| string[] | One or more images | | pricePerDay | number | Price shown as $X/day | | accentColor | string | Accent hex colour | | tags | string[] | Tag chips | | isSaved | boolean | Bookmark state | | onSaveClick | () => void | Bookmark handler | | onClick | () => void | Click handler |

RentalImage{ url: string; transparent: boolean }
Set transparent: true for product PNGs — the card switches to padded object-fit: contain rendering so the transparent background shows cleanly.


StintCard

Compact gig/shift card. Full-bleed image with bottom gradient, title, and question phrase.

<StintCard
  id="stn-1"
  name="Grass Cutting"
  image="https://example.com/lawn.jpg"
  questionPhrase="Can you cut a great lawn?"
  accentColor="#10B981"
  onClick={() => {}}
/>

| Prop | Type | Description | |---|---|---| | id | string | Unique card id | | name | string | Gig / shift name | | image | string | Cover image URL | | questionPhrase | string | Question shown in italic | | accentColor | string | Accent hex colour | | onClick | () => void | Click handler |


MenuCard

Square menu card (260×260 px) with a thumbnail grid of item images, a manage row with animated arrow, and an accent-coloured gradient overlay.

<MenuCard
  id="menu-1"
  name="Brunch Menu"
  statementDescription="Served 9am – 2pm"
  accentColor="#059669"
  items={[
    { image: 'https://example.com/eggs.jpg' },
    { image: 'https://example.com/pancakes.jpg' },
    { image: 'https://example.com/coffee.jpg' },
  ]}
  onClick={() => {}}
  onManageClick={() => {}}
/>

| Prop | Type | Description | |---|---|---| | id | string | Unique card id | | name | string | Menu name | | statementDescription | string | Sub-heading (e.g. hours) | | accentColor | string | Accent hex colour | | items | MenuItemImage[] | Array of { image: string } | | onClick | () => void | Card click handler | | onManageClick | () => void | "Manage" row handler |


CSS Token Overrides

Pass any token via the style prop to re-theme a card without modifying its internals:

<EventCard
  id="x"
  name="Custom themed"
  style={{
    '--background':      '#1a1a2e',
    '--main-background': '#16213e',
    '--text':            '#e0e0e0',
    '--sub-text':        '#a0a0b0',
    '--best-gray':       '#0f3460',
  } as React.CSSProperties}
/>

| Token | Dark default | Light default | |---|---|---| | --background | #101010 | #ffffff | | --main-background | #101010 | #ffffff | | --text | #ffffff | #111827 | | --sub-text | #bababa | #6b7280 | | --gray1 | rgba(255,255,255,0.08) | rgba(0,0,0,0.08) | | --gray2 | #2a2a2a | #e5e7eb | | --best-gray | #252525 | #f3f4f6 | | --shadow | rgba(0,0,0,0.4) | rgba(0,0,0,0.12) |


Development

# Install deps
npm install

# Run the live example dev harness (http://localhost:5180)
npm run dev

# Build the package
npm run build

# Run tests (vitest + @testing-library/react)
npm test

# TypeScript type-check
npm run typecheck

The example dev harness at example/App.tsx renders all 5 cards with live JSON editing, desktop/mobile variant toggle, and dark/light theme toggle.


Exports

// Components
export { EventCard, ServiceCard, RentalCard, StintCard, MenuCard }

// Types
export type { EventCardProps, ServiceCardProps, RentalCardProps }
export type { StintCardProps, MenuCardProps, MenuItemImage }
export type { SrvzBaseCardProps, SrvzVariant, SrvzTheme }

License

MIT © SRVZr