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

@mysios-labs-inc/whatsapp-mockup

v2.0.1

Published

Reusable iPhone + WhatsApp chat mockup components for React (Tailwind v4)

Readme

@mysios-labs-inc/whatsapp-mockup

npm version license

Reusable iPhone device frame + WhatsApp chat mockup components for React (Tailwind v4). Drop a scripted WhatsApp conversation into a realistic iPhone frame for landing pages, demos, and pitch decks — no screenshots to keep up to date. Extracted from fudi-web.

Chat mockups inside the iPhone frame

Screenshots

Captured from the example app's component showcase — every screenshot below reflects real rendered output, not mockups of mockups.

| | | | --- | --- | | Chat list (home) screen | Calls tab | | Chat list screen | Calls tab | | Media bubbles (photo/video/grid/document) | Rich bubbles (link/contact/poll previews) | | Media bubbles | Rich bubbles | | Settings & Contact Info | WhatsAppButton variants | | Settings and contact info | WhatsAppButton variants |

A note on language

Chrome/UI labels — headers, tab bar text, button labels — are authored in English to match the components' exported defaults. Demo/example content — contact names, message text, and aria-labels on internal interactive elements like back/attach buttons — uses Spanish, reflecting the original Fudis restaurant-bot use case this library was extracted from. Contributors should preserve this split rather than "fixing" one language to match the other.

Table of contents

Install

npm install @mysios-labs-inc/whatsapp-mockup

Peer dependencies: react and react-dom (>=18).

Setup (Tailwind v4)

Components use Tailwind utility classes, including a coral-* color scale. Import the bundled theme before your own styles:

@import "tailwindcss";
@import "@mysios-labs-inc/whatsapp-mockup/theme.css";

If your app already defines coral-300..coral-600, import your theme after this one to override.

Quick start

import { Iphone17Pro, WhatsAppMockup } from '@mysios-labs-inc/whatsapp-mockup'

function Demo() {
  return (
    <Iphone17Pro width={370} height={740}>
      <WhatsAppMockup contactName="Fudis" contactSubtitle="en línea" />
    </Iphone17Pro>
  )
}

For a full working app with every component, see examples/basic.

Components

Iphone17Pro

Device frame rendered as inline SVG. Pass src for a static image, or children for arbitrary React/HTML content (rendered inside the screen via <foreignObject>). children takes precedence over src if both are given. Any extra prop is forwarded to the underlying <svg> element (e.g. className, style).

| Prop | Type | Default | Description | | --- | --- | --- | --- | | width | number | 200 | Rendered SVG width. | | height | number | 400 | Rendered SVG height. | | src | string | — | Image URL rendered inside the screen. Ignored if children is set. | | children | ReactNode | — | Arbitrary content rendered inside the screen. |

<Iphone17Pro width={400} height={800} src="/screenshot.png" />

WhatsAppMockup

Scripted restaurant-discovery-and-booking conversation demo. Render inside <Iphone17Pro> to get the full device frame.

| Prop | Type | Default | Description | | --- | --- | --- | --- | | contactName | string | 'Fudis' | Name shown in the chat header. | | contactSubtitle | string | 'en línea' | Subtitle shown under the contact name. | | restaurants | RestaurantCard[] | 3 sample restaurants | Cards rendered in the restaurant-recommendation bubble. |

RestaurantCard shape:

type RestaurantCard = {
  name: string
  rating: number
  location: string
  priceRange: string
  highlights: string[]
}

WhatsAppChatMockup / WhatsAppChatScrollable

Static reference chat demo with no props — useful as a lightweight placeholder or design reference. WhatsAppChatMockup renders a fixed, non-scrolling message list; WhatsAppChatScrollable renders the same content in a scrollable container, auto-scrolled to the latest message on mount.

<Iphone17Pro width={400} height={800}>
  <WhatsAppChatScrollable />
</Iphone17Pro>

WhatsAppButton

Inline "message on WhatsApp" button — same wa.me link logic as WhatsAppStickyCTA, but rendered in normal document flow instead of fixed to the viewport. Use this for hero CTAs, cards, or anywhere a regular button belongs; use WhatsAppStickyCTA for a floating button.

| Prop | Type | Default | Description | | --- | --- | --- | --- | | contactName | string | — | Required. Used in the aria-label and default message templates. | | phone | string \| null | — | Required. Direct phone number for this contact, if known. Any format — non-digits are stripped. Pass null to fall back to fallbackPhoneNumber. | | fallbackPhoneNumber | string | — | Required. Used when phone is null/empty. | | ctaLabel | string | 'Reservar' | Button label. Ignored for variant="icon-only". | | variant | 'solid' \| 'outline' \| 'icon-only' | 'solid' | Visual style. | | size | 'sm' \| 'md' \| 'lg' | 'md' | Button size. | | buildMessageWithPhone | (contactName: string) => string | Spanish order message | Message template used when phone is provided. | | buildFallbackMessage | (contactName: string) => string | Spanish order message + "Vi su menú en Fudis." | Message template used when falling back to fallbackPhoneNumber. | | onClick | (info: { hasDirectPhone: boolean }) => void | — | Fired on click, before the WhatsApp link opens. Wire up your own analytics here. | | className | string | — | Extra classes merged onto the button. |

<WhatsAppButton
  contactName="Punto Azul"
  phone={restaurant.phone}
  fallbackPhoneNumber="51999999999"
  variant="outline"
  size="sm"
/>

WhatsAppStickyCTA

Floating "message on WhatsApp" CTA button, fixed to the bottom of the viewport and fading in after the user scrolls. Client-only component ('use client').

| Prop | Type | Default | Description | | --- | --- | --- | --- | | contactName | string | — | Required. Used in the aria-label and default message templates. | | phone | string \| null | — | Required. Direct phone number for this contact, if known. Any format — non-digits are stripped. Pass null to fall back to fallbackPhoneNumber. | | fallbackPhoneNumber | string | — | Required. Used when phone is null/empty. | | ctaLabel | string | 'Reservar' | Button label. | | buildMessageWithPhone | (contactName: string) => string | Spanish order message | Message template used when phone is provided. | | buildFallbackMessage | (contactName: string) => string | Spanish order message + "Vi su menú en Fudis." | Message template used when falling back to fallbackPhoneNumber. | | showAfterScrollPx | number | 200 | Scroll offset (px) after which the CTA becomes visible. | | onClick | (info: { hasDirectPhone: boolean }) => void | — | Fired on click, before the WhatsApp link opens. Wire up your own analytics here. | | className | string | — | Extra classes merged onto the wrapper. |

<WhatsAppStickyCTA
  contactName="Punto Azul"
  phone={restaurant.phone}
  fallbackPhoneNumber="51999999999"
  onClick={({ hasDirectPhone }) => track('whatsapp_clicked', { hasDirectPhone })}
/>

WhatsAppIcon

Standalone WhatsApp brand icon SVG (24x24 viewBox, defaults to h-5 w-5).

| Prop | Type | Default | Description | | --- | --- | --- | --- | | className | string | 'h-5 w-5' | Fully replaces the default size when provided — include your own sizing classes. |

Chat primitives

Lower-level building blocks exported from parts.tsx, useful for composing custom conversations instead of using WhatsAppMockup as-is:

  • BubbleMe / BubbleFriend — chat bubbles for each side of the conversation.
  • DateChip — centered date separator (e.g. "Hoy").
  • LocationBubble — WhatsApp-style shared-location bubble.
  • RestaurantCardsBubble — carousel of RestaurantCard items inside a bubble.
  • StatusBar — iOS status bar (time/signal/battery).
  • ChatHeader — WhatsApp conversation header (avatar, name, subtitle).
  • InputBar — the message composer bar at the bottom of the screen.
  • ChatMessages — the fixed message list used by WhatsAppChatMockup/WhatsAppChatScrollable.
  • DESIGN_WIDTH / DESIGN_HEIGHT — the design canvas size (393 x 852) all mockups are laid out against.

Example app

A runnable Vite + React + Tailwind v4 app lives in examples/basic — a component showcase covering every export: the three chat mockups, WhatsAppIcon, WhatsAppButton (all variants/sizes), and a live WhatsAppStickyCTA. It consumes this package via a local file:../.. dependency, so no publish is required to try it:

npm run build          # build the package itself first (dist/ output)
cd examples/basic
npm install
npm run dev             # or: npm run build && npm run preview

Publishing

Published to the public npm registry. Push a v* tag to trigger the GitHub Actions publish workflow (requires an NPM_TOKEN repo secret with publish rights on the @mysios-labs-inc npm org):

npm version patch
git push --follow-tags

License

MIT © Mysios Labs — see LICENSE.