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

@mofei-dev/ui

v1.0.3

Published

Shared React UI components for Mofei projects. The package focuses on the Mofei Life visual system: dark glass surfaces, bilingual navigation, blog listing and article layouts, comment/message primitives, admin workspace screens, and reusable form/status

Readme

@mofei-dev/ui

Shared React UI components for Mofei projects. The package focuses on the Mofei Life visual system: dark glass surfaces, bilingual navigation, blog listing and article layouts, comment/message primitives, admin workspace screens, and reusable form/status controls.

The package ships compiled JavaScript and type declarations in dist. React and Next are peer dependencies, so each consuming app owns its runtime versions.

Installation

pnpm add @mofei-dev/ui

Import from the package root:

import { AppBackground, StickyTopNav, BlogArticleLayout } from "@mofei-dev/ui";
import type { StickyTopNavProps } from "@mofei-dev/ui";

For the complete root export list, see docs/API.md.

Tailwind CSS

Components use Tailwind utility classes in the distributed files. Tailwind CSS v4 consumers must include this package's dist directory as a source so responsive, state, and arbitrary-value classes are generated.

@import "tailwindcss";
@source "../node_modules/@mofei-dev/ui/dist";

Adjust the relative path from your stylesheet location. A Next app with src/app/globals.css commonly needs:

@source "../../node_modules/@mofei-dev/ui/dist";

Without this source entry, components such as StickyTopNav can render mobile states on desktop because classes like lg:hidden and lg:flex are not emitted.

The same rule applies to admin/workspace components. If a consuming app shows mostly unstyled borders, table outlines, or "wireframe" surfaces after a production build, first check that its global Tailwind stylesheet includes the package source path and that the path is correct relative to that stylesheet. For example:

/* apps/admin/src/app/globals.css */
@import "tailwindcss";
@source "../../node_modules/@mofei-dev/ui/dist";

After adding or changing the source entry, rebuild the consuming app before deploying. Deploy-only commands that reuse an old .open-next directory can publish stale CSS and make the production site appear to roll back.

App Shell

Use AppBackground inside a positioned isolated shell. The component renders fixed layers with negative z-index, so the host shell must create the stacking context.

import Link from "next/link";
import {
  AppBackground,
  FooterPreview,
  LogoMark,
  StickyTopNav,
} from "@mofei-dev/ui";

export function AppShell({ children }: { children: React.ReactNode }) {
  return (
    <div className="relative isolate min-h-screen overflow-x-clip bg-[#0b1120] text-white">
      <AppBackground />
      <StickyTopNav
        lang="en"
        LinkComponent={Link}
        brand={<LogoMark alt="Mofei" />}
        items={[
          { id: "blog", zh: "博客", en: "Blog", href: "/blog" },
          { id: "about", zh: "关于", en: "About", href: "/about" },
        ]}
        activeId="blog"
        languageLinks={{ zh: "/zh/blog", en: "/en/blog" }}
        className="fixed left-0 right-0 top-0"
        innerClassName="border-b border-white/[0.08] bg-white/[0.02] backdrop-blur-xl"
      />
      <main className="pt-24">{children}</main>
      <FooterPreview lang="en" />
    </div>
  );
}

Keep the document or body background close to #0b1120 so the page does not flash a different color before the app shell paints.

Blog Listing

Use the blog/listing components together for index pages, filtered archives, and collection pages.

import {
  BlogListHero,
  CategoryFilterNav,
  BlogListContentSection,
  BlogListEmptyState,
  ResponsivePagination,
} from "@mofei-dev/ui";

export function BlogIndex({ posts, activeCategory, setCategory }) {
  return (
    <>
      <BlogListHero
        lang="en"
        title="Mofei Life"
        description="Notes on family, migration, engineering, and AI workflows."
      />

      <CategoryFilterNav
        lang="en"
        activeId={activeCategory}
        onChange={setCategory}
        items={[
          { id: "all", label: { zh: "全部", en: "All" }, count: posts.length },
          { id: "tech", label: { zh: "技术", en: "Tech" } },
        ]}
      />

      <BlogListContentSection
        lang="en"
        cards={posts}
        emptyState={<BlogListEmptyState lang="en" kind="empty" />}
      />

      <ResponsivePagination
        lang="en"
        currentPage={1}
        totalPages={5}
        getPageHref={(page) => `/blog/page/${page}`}
      />
    </>
  );
}

For simpler lists, BlogCardList wraps BlogListContentSection. Use BlogCollectionList for grouped collections, ActivityFeedList for timelines, FriendLinkCardList for friend links, and LinkList or LinkGroup for compact link groups.

Article Page

BlogArticleLayout composes the article title, metadata, summary, table of contents, action area, and reading column. The smaller article components can also be used independently.

import {
  ArticleCodeBlock,
  ArticleMetaBar,
  ArticleProse,
  ArticleShareBar,
  ArticleSummaryCard,
  ArticleTocCard,
  BlogArticleLayout,
  PrevNextNav,
} from "@mofei-dev/ui";

const code = `pnpm add @mofei-dev/ui`;

export function ArticlePage() {
  const toc = (
    <ArticleTocCard
      eyebrow="Contents"
      title="On this page"
      items={[
        { id: "setup", label: "Setup", href: "#setup" },
        { id: "usage", label: "Usage", href: "#usage" },
      ]}
    />
  );

  return (
    <BlogArticleLayout
      lang="en"
      title="Building with the Mofei UI package"
      metaBar={<ArticleMetaBar label="Published" trailing="2026-04-26" />}
      summary={<ArticleSummaryCard label="Summary">Reusable UI for Mofei apps.</ArticleSummaryCard>}
      toc={toc}
      actions={
        <ArticleShareBar
          mode="inline"
          preset={{
            lang: "en",
            canonicalUrl: "https://www.mofei.life/blog/ui",
            shareTitle: "Building with the Mofei UI package",
          }}
        />
      }
    >
      <ArticleProse>
        <h2 id="setup">Setup</h2>
        <p>Install the package and include its Tailwind source.</p>
        <ArticleCodeBlock code={code} language="bash">
          <pre><code>{code}</code></pre>
        </ArticleCodeBlock>
      </ArticleProse>

      <PrevNextNav
        lang="en"
        prev={{ title: "Previous article", href: "/blog/previous" }}
        next={{ title: "Next article", href: "/blog/next" }}
      />
    </BlogArticleLayout>
  );
}

Forms And Messaging

Form controls are styled but mostly unopinionated. MessageComposer and AiChatDockPanel are higher-level pieces for comment and AI assistant experiences.

import {
  AiChatDockPanel,
  AiChatDockTrigger,
  ColorInput,
  FormPanel,
  FormPanelHeader,
  MessageComposer,
  SelectInput,
  TextInput,
  UploadDropzone,
  UploadQueueList,
} from "@mofei-dev/ui";

export function EditorTools({ open, setOpen }) {
  return (
    <>
      <FormPanel>
        <FormPanelHeader title="Asset settings" description="Prepare upload metadata." />
        <TextInput placeholder="Title" />
        <SelectInput defaultValue="cover">
          <option value="cover">Cover</option>
          <option value="gallery">Gallery</option>
        </SelectInput>
        <ColorInput value="#67e8f9" onChange={() => {}} />
        <UploadDropzone
          title="Drop files here"
          description="Release to upload assets."
          isDragging={false}
          onDrop={() => {}}
          onDragOver={(event) => event.preventDefault()}
          onDragLeave={() => {}}
        />
        <UploadQueueList items={[]} emptyState="No uploads yet" />
      </FormPanel>

      <AiChatDockTrigger isOpen={open} onToggle={() => setOpen(!open)} unreadCount={2} />
      {open ? (
        <AiChatDockPanel title="AI assistant" subtitle="Draft support" onClose={() => setOpen(false)}>
          <MessageComposer
            copy={{
              title: "Leave a message",
              submitLabel: "Send",
              secondaryLabel: "Clear",
              messagePlaceholder: "Write here...",
            }}
            onSubmit={(payload) => console.log(payload)}
          />
        </AiChatDockPanel>
      ) : null}
    </>
  );
}

Comments, Status, And Workspace UI

import {
  AITransparencyBadge,
  CommentList,
  LoadingPanel,
  MetricGrid,
  NoticeBanner,
  SectionHeader,
  StatusToastStack,
  ThreadedCommentList,
  WorkspaceTabs,
} from "@mofei-dev/ui";

export function FeedbackPanel() {
  return (
    <section>
      <SectionHeader title="Comments" meta={<AITransparencyBadge context="comment" mode="assisted" lang="en" />} />
      <NoticeBanner tone="info">Replies may include AI-assisted summaries.</NoticeBanner>
      <WorkspaceTabs
        activeKey="comments"
        onChange={() => {}}
        items={[
          { key: "comments", label: "Comments" },
          { key: "metrics", label: "Metrics" },
        ]}
      />
      <MetricGrid>
        <LoadingPanel label="Loading metrics..." />
      </MetricGrid>
      <CommentList lang="en" comments={[]} />
      <ThreadedCommentList lang="en" comments={[]} />
      <StatusToastStack items={[]} />
    </section>
  );
}

Admin UI

Admin components are for dense workspace screens with shared dark surfaces.

import {
  AdminShell,
  DataTable,
  FeatureCard,
  FilterBar,
  FilterField,
  Modal,
  PageHeader,
  PrimaryButton,
  StatusBadge,
} from "@mofei-dev/ui";

type Row = { id: string; title: string; status: "draft" | "published" };

export function AdminPage({ rows }: { rows: Row[] }) {
  return (
    <AdminShell
      title="Blog Admin"
      activeNavKey="posts"
      navItems={[{ key: "posts", label: "Posts", href: "/admin/posts" }]}
    >
      <PageHeader
        title="Posts"
        description="Review drafts and published articles."
        actions={<PrimaryButton>New post</PrimaryButton>}
      />
      <FilterBar onSubmit={(event) => event.preventDefault()}>
        <FilterField label="Search"><input name="q" /></FilterField>
      </FilterBar>
      <FeatureCard title="Publishing queue" description="Items waiting for review." href="/admin/posts" />
      <DataTable
        rows={rows}
        rowKey={(row) => row.id}
        columns={[
          { key: "title", header: "Title", render: (row) => row.title },
          { key: "status", header: "Status", render: (row) => <StatusBadge label={row.status} tone="info" /> },
        ]}
      />
      <Modal open={false} title="Confirm" onClose={() => {}}>Modal content</Modal>
    </AdminShell>
  );
}

Component Catalog

Navigation And Pagination

| Export | Use | | --- | --- | | StickyTopNav | Sticky responsive top nav with desktop links, mobile drawer, brand slot, active state, and language links. | | SiteGlobalNav | Desktop global nav used by StickyTopNav; useful when the shell owns its own header. | | PageSectionNav | Section anchor navigation for long pages. | | CategoryFilterNav | Horizontal category chips with counts, active state, and scroll fades. | | PrevNextNav | Previous/next article cards. | | HeaderNavBar | Compact header navigation bar. | | BlogEntryTabs | Blog entry tab switcher. | | ResponsivePagination | Pagination links with responsive page ranges. |

Buttons

| Export | Use | | --- | --- | | PrimaryButton | Main command button. | | SecondaryButton | Secondary command button. | | TextButton | Low-emphasis text command. | | PrimaryPillButton | Pill-shaped button for compact actions. | | PrimaryPillLink | Pill-shaped anchor link. |

Content Shells And Heroes

| Export | Use | | --- | --- | | AppBackground | Fixed or absolute Mofei background layers. | | ContentBackground / BlogListBackground | Content-page background layer alias. | | ContentPageShell / BlogListPageShell | Page shell with background-aware layout. | | SecondaryHero | Secondary page hero with bilingual/text slots. | | SecondaryHeroPageShell | Shell that combines secondary hero and page content. | | BlogListHero | Blog index hero. | | MessageHeroVisual | Visual element for message/contact pages. |

Blog Lists

| Export | Use | | --- | --- | | BlogListContentSection | Full featured blog listing section with filters, cards, empty states, and layout controls. | | BlogCardList | Compatibility wrapper around BlogListContentSection. | | BlogCard | Individual blog card renderer. | | BlogCollectionList | Grouped blog collections. | | BlogListEmptyState | Empty-state copy for blog filters/searches. | | LinkList | Simple list of links. | | LinkGroup | Titled grouped links. | | ActivityFeedList | Timeline/feed list. | | FriendLinkCardList | Friend link cards. |

Article

| Export | Use | | --- | --- | | BlogArticleLayout | Article title, metadata, TOC rail, reading column, summary, and actions layout. | | ArticleMetaBar | Small metadata row. | | ArticleActionBar | Action panel/row for article-level commands. | | ArticleTocCard | Table-of-contents card. | | ArticleSummaryCard | Summary callout. | | ArticleProse | Prose wrapper for article body content. | | ArticleCodeBlock | Copyable code block shell. | | ArticleShareBar | Share buttons, inline/panel/collapsed modes. | | buildArticleShareItems | Helper that builds localized share item URLs from a canonical URL and title. |

Forms, Uploads, And Messaging

| Export | Use | | --- | --- | | TextInput | Styled text input. | | SelectInput | Styled select with custom adornment. | | TextAreaInput | Styled textarea. | | CheckboxInput | Styled checkbox with optional label. | | ReadonlyField | Read-only field display. | | CheckboxFieldRow | Label/description checkbox row. | | ColorInput | Color value input with swatch treatment. | | FormPanel | Surface for grouped controls. | | FormPanelHeader | Title/description/action header for FormPanel. | | InlineSearchBar | Compact inline search input. | | UploadDropzone | Drag/drop upload target. | | UploadQueueList | Upload progress/list display. | | AssetList | Uploaded asset list. | | SubscribeForm | Email subscription form. | | MessageComposer | Identity-aware message/comment composer with optional chat messages and status toasts. | | AiChatDockPanel | Fixed or embedded chat panel. | | AiChatDockTrigger | Floating trigger button with unread badge. |

Comments And Message Threads

| Export | Use | | --- | --- | | CommentList | Flat comment list. | | ThreadedCommentList | Nested/threaded comment list. | | MessageThreadList | Rich message thread renderer. | | MessageThreadRichText | Sanitized/rich text block used in message threads. | | MessageThreadReplyQuote | Reply quote block. | | MessageThreadAiReply | AI reply block. | | MessageThreadActionBar | Action row for message threads. | | CommentSectionTitle | Comment section heading primitive. | | CommentAvatar | Comment avatar primitive. | | CommentAuthor | Comment author link/text primitive. | | CommentMetaCluster | Metadata group primitive. | | CommentActionButton | Comment action button primitive. | | CommentReplyQuote | Comment quote primitive. | | CommentAiReply | Comment AI-reply primitive. |

Status And Feedback

| Export | Use | | --- | --- | | StatusToast | Single toast item renderer. | | StatusToastStack | Toast stack. | | NoticeBanner | Inline info/success/warning/danger banner. | | LoadingPanel | Loading state panel. | | AITransparencyBadge | Localized AI disclosure badge for articles, comments, search, translation, ranking, and generated/assisted content. |

Layout, Surfaces, And Text

| Export | Use | | --- | --- | | GlassPanel | Glass surface wrapper. | | SectionFrame | Framed section wrapper. | | SectionHeading | Section heading block. | | PreviewBody | Preview-page body wrapper. | | PreviewGroupDivider | Divider for preview groups. | | PreviewIntroShell | Intro shell for preview pages. | | PreviewSectionShell | Section shell for preview pages. | | LogoMark | Mofei logo image helper. | | InlineNote | Inline note/callout. | | InfoMetricCard | Small metric card. | | FooterPreview | Site footer preview with localized content. | | ProgressBar | Determinate or loading progress bar. | | CopyToken | Monospace copy/value token. | | Eyebrow | Small eyebrow label. | | SectionLabel | Section label text primitive. | | MetaLabel | Metadata label text primitive. |

Workspace

| Export | Use | | --- | --- | | MetricCard | Single workspace metric. | | MetricGrid | Responsive metric grid. | | SectionHeader | Workspace section header with meta/actions. | | WorkspaceTabs | Controlled workspace tabs. |

Admin

| Export | Use | | --- | --- | | AdminShell | Full admin shell with background, nav, title, logout action, and content area. | | PageHeader | Admin page title, description, actions, and metrics. | | FilterBar | Filter form wrapper. | | FilterField | Labeled filter field. | | Modal | Admin modal shell. | | StatusBadge | Admin status badge. | | DataTable | Generic typed data table. | | FeatureCard | Admin feature/summary card. |

Design Tokens And Helpers

The package also exports class-name tokens for consumers that need to build custom surfaces while staying visually aligned:

  • Typography: typeDisplay, typeHeadline, typeTitleLarge, typeTitleMedium, typeTitleSmall, typeBodyLarge, typeBodyMedium, typeBodySmall, typeCaption, typeLabel, typeEyebrow, typeSystemLabel, typeScale
  • Surface colors and borders: contentPageBg, appBackgroundBg, surfaceTextPrimary, surfaceTextStrong, surfaceTextSecondary, surfaceTextBody, surfaceTextSupport, surfaceTextMeta, surfaceTextFaint, surfaceTextGhost, surfaceBgShell, surfaceBgShellSoft, surfaceBgShellMuted, surfaceBgShellLifted, surfaceBgShellSubtle, accentTextPrimary, accentTextSecondary, accentBorderSubtle, accentBorderStrong, accentBgSoft, accentBgMuted, accentGradientBar, borderDefault, borderStrong, borderCyanSubtle, borderCyanStrong
  • Shape and motion: radiusXl, radiusCard, radiusPanel, radiusComponent, radiusToast, radiusStandard, radiusSmall, radiusInput, radiusPill, shadowNav, shadowGlassPanel, shadowSectionShell, shadowModal, shadowInputInset, blurNavHover, blurGlassPanel, blurDrawer, spacingScaleTokens, radiusTokens, shadowTokens, blurTokens

Types

Every exported component with custom props also exports its prop type from the package root. The most frequently used types are grouped below.

Navigation and pagination: StickyTopNavProps, CategoryFilterNavProps, CategoryFilterNavItem, PrevNextNavItem, HeaderNavBarProps, BlogEntryTabsProps

Blog lists: BlogCardItem, BlogCardLayout, BlogCardLinkComponent, BlogCardTag, BlogCardTagVariant, BlogCardBrand, BlogCardImageMeta, BlogCardImageTransform, BlogFilterItem, BlogRealCard, BlogPreviewCard, BlogCollectionListItem, BlogCollectionListProps, BlogCardImageComponent, BlogCardActionsRenderProps, BlogCardActionsRenderer, LinkListItem, LinkGroupItem, LinkGroupProps, ActivityFeedItem, ActivityFeedListProps, FriendLinkListItem

Article: BlogArticleLayoutProps, ArticleMetaBarProps, ArticleActionBarProps, ArticleTocCardProps, ArticleTocCardItem, ArticleSummaryCardProps, ArticleProseProps, ArticleCodeBlockProps, ArticleShareBarProps, ArticleShareBarPreset, ArticleShareItem, ArticleSharePlatform

Forms and messaging: MessageComposerProps, MessageComposerCopy, MessageComposerMessage, MessageComposerMessageAction, MessageComposerIdentity, AiChatDockPanelProps, AiChatDockTriggerProps, TextInputProps, SelectInputProps, TextAreaInputProps, CheckboxInputProps, ReadonlyFieldProps, CheckboxFieldRowProps, ColorInputProps, FormPanelProps, FormPanelHeaderProps, UploadDropzoneProps, UploadQueueItem, UploadQueueListProps, AssetListItem, AssetListProps, SubscribeFormProps, InlineSearchBarProps

Comments and threads: CommentItem, ThreadedCommentItem, ThreadedCommentAction, MessageThreadItem, MessageThreadAction, MessageThreadListProps, MessageThreadRichTextProps, MessageThreadReplyQuoteProps, MessageThreadAiReplyProps, MessageThreadActionBarProps

Status and workspace: StatusToastItem, StatusToastStackProps, NoticeBannerProps, NoticeBannerTone, LoadingPanelProps, AITransparencyBadgeProps, AITransparencyContext, AITransparencyMode, AITransparencyLanguage, MetricCardProps, MetricGridProps, SectionHeaderProps, WorkspaceTabsProps, WorkspaceTabItem

Layout and text: ContentBackgroundProps, BlogListBackgroundProps, BlogListHeroProps, SecondaryHeroProps, SecondaryHeroPageShellProps, ContentPageShellProps, BlogListPageShellProps, PreviewBodyProps, PreviewGroupDividerProps, PreviewIntroShellProps, PreviewSectionShellProps, LogoMarkProps, InlineNoteProps, InfoMetricCardProps, AppBackgroundProps, ProgressBarProps, CopyTokenProps, EyebrowProps, SectionLabelProps, MetaLabelProps

Admin: ShellProps, ShellNavItem, AdminNavItem, PageHeaderProps, FilterBarProps, FilterFieldProps, ModalProps, StatusBadgeProps, StatusTone, DataTableProps, DataTableColumn, FeatureCardProps

Development

pnpm install
pnpm typecheck
pnpm test

Before publishing, run the consumer fallback guard:

pnpm typecheck
pnpm test:consumer-fallback
pnpm build:lib

Releases

This repository publishes to the public npm registry through GitHub Actions and npm Trusted Publishing. It does not require a long-lived NPM_TOKEN.

Release workflow:

  • Workflow file: .github/workflows/npm-release.yml
  • npm Trusted Publisher workflow filename: npm-release.yml
  • GitHub Actions environment: npm-publish
  • Package: @mofei-dev/ui
  • Registry: https://registry.npmjs.org

Configure npm Trusted Publishing for zmofei/mofei-life-ui before using the workflow:

  • Workflow filename: npm-release.yml
  • GitHub Actions environment: npm-publish

Release Dev

Use a dev release when another project needs to test the current main branch without moving the stable latest tag.

From GitHub:

  1. Open Actions.
  2. Select NPM Release.
  3. Click Run workflow.
  4. Choose channel: dev.
  5. Run from main.

From the CLI:

gh workflow run npm-release.yml --ref main -f channel=dev

The workflow creates a temporary prerelease version without committing it back to the repo:

<package.json version>-dev.<github run number>.<short sha>

Example:

0.1.2-dev.2.a85355f

Install the latest dev build in a consumer app:

pnpm add @mofei-dev/ui@dev

Install an exact dev build:

pnpm add @mofei-dev/[email protected]

Release Production

Use a production release when the package is ready to become the npm latest version.

  1. Start from a clean main branch.
  2. Bump package.json to a stable semver version. Do not include a prerelease suffix such as -dev or -beta.
  3. Run the publish guard locally:
pnpm typecheck
pnpm test:consumer-fallback
pnpm build:lib
  1. Commit and push the version bump:
git add package.json
git commit -m "Release v0.1.3"
git push origin main
  1. Create and push a matching tag:
git tag v0.1.3
git push origin v0.1.3

The production workflow verifies that v0.1.3 matches package.json version 0.1.3, runs the same publish guard, publishes to npm with the latest dist-tag, and creates a GitHub Release for the tag.

Manual production dispatch is available from Actions with channel: production, but tag-based release is preferred because it gives the published package a durable GitHub Release and an auditable version ref.