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

@whdigitalbuild/react-base-wh

v1.8.9

Published

A comprehensive React UI component library and template designed for Woh Hup applications. This package provides a standardized layout structure and a collection of reusable components built on top of Ant Design...

Readme

@whdigitalbuild/react-base-wh

A comprehensive React UI component library and template designed for Woh Hup applications. This package provides a standardized layout structure and a collection of reusable components built on top of Ant Design...

Installation

Install the package:

npm install @whdigitalbuild/react-base-wh
# or: pnpm add @whdigitalbuild/react-base-wh

The /mf-shared subpath (see Module Federation) is available from v1.8.0 onwards.

Peer Dependencies

Ensure the following are installed in your app so they can be shared as singletons under Module Federation:

"dependencies": {
  "react": "^18.2.0",
  "react-dom": "^18.2.0",
  "antd": "^5.4.6",
  "@ant-design/icons": "^5.0.1",
  "dayjs": "^1.11.0"
}

v1.8.0 breaking-ish change: moment was removed in favour of dayjs (aligned with Ant Design 5, which uses dayjs internally). Nothing to do unless your app relied on moment being pulled in transitively via this package.

Module Federation (shared config)

For apps built with Module Federation (Rsbuild), this package is the single source of truth for shared-library versions. Import the createMfShared factory into your rsbuild.config instead of hand-writing the shared block:

// rsbuild.config.ts — REMOTE
import { pluginModuleFederation } from "@module-federation/rsbuild-plugin";
import { createMfShared } from "@whdigitalbuild/react-base-wh/mf-shared";

pluginModuleFederation({
  name: "my_remote",
  filename: "remoteEntry.js",
  exposes: { "./App": "./src/export-app" },
  shared: createMfShared({ isHost: false }), // remote → lazy
});
// rsbuild.config.ts — HOST (e.g. IddApp_Main)
shared: createMfShared({ isHost: true }); // host → react / react-dom / react-query loaded eager

createMfShared({ isHost }) returns a singleton config for: react, react-dom, @tanstack/react-query + @tanstack/query-core (both required, or the cache duplicates), zustand, dayjs, lodash, ag-grid-community / -enterprise / -react, antd, @ant-design/icons, and @whdigitalbuild/react-base-wh itself. To change a standard version fleet-wide, edit src/mf-shared.ts here and bump the package version.

The clean @whdigitalbuild/react-base-wh/mf-shared import resolves without an exports map (via root mf-shared.js / mf-shared.d.ts re-export stubs), so it works under classic moduleResolution: node as well as bundler resolution.

v1.8.2: react-router-dom is intentionally NOT in the shared list. @module-federation/rspack auto-detects @module-federation/bridge-react (present in most of the fleet's apps) and aliases react-router-dom$ to its own wrapper — it throws a hard build error (React-router-dom cannot be set to shared after react bridge is used) if react-router-dom is also declared in shared. If your app does not use @module-federation/bridge-react and you want react-router-dom shared as a singleton, add it back yourself: { ...createMfShared({ isHost }), 'react-router-dom': { singleton: true, requiredVersion: '^6.3.0' } }.

Usage

Main Template (MainWH)

MainWH is the primary layout component that provides the standard structure for applications, including a top bar and a collapsable left sidebar with project selection, search, and favourites.

import React from "react";
import { MainWH } from "@whdigitalbuild/react-base-wh";

const App = () => {
  const routes = [
    {
      path: "/home",
      name: "Home",
      icon: <HomeOutlined />, // from @ant-design/icons
      component: HomePage,
    },
    // ... define other routes
  ];

  const projects = [
    { id: "All", name: "All", isAllProject: true, isFavorite: true },
    { id: "project-a", name: "Project A", isActive: true, isFavorite: true },
    { id: "project-b", name: "Project B", isFavorite: false },
    { id: "project-c", name: "Project C", isFavorite: false },
  ];

  return (
    <MainWH
      routes={routes}
      projects={projects}
      slidesToShow={5}
      showSearchProject={true}
      onChangeNavigate={(route) => console.log("Navigate to:", route)}
      onChangeProjectSelected={(project) => console.log("Selected:", project)}
      onChangeFavoriteProject={(project) =>
        console.log("Favorite toggled:", project)
      }
      onSearchChange={(e) => console.log(e.target.value)}
    >
      <div>
        {/* Your Page Content Goes Here */}
        <h1>Welcome to the Application</h1>
      </div>
    </MainWH>
  );
};

export default App;

MainWH Props

| Prop | Type | Description | | ------------------------- | --------------------- | ---------------------------------------------------------------------- | | children | ReactNode | The main content to be rendered within the layout body. | | routes | any[] | Array of route objects for the sidebar navigation. | | projects | any[] | List of projects to display in the project selector. | | disableProjects | any | Props to disable project selection if needed. | | searchText | any | Value for the top bar search input. | | searchOptions | any[] | Options for the search input if using a select/autocomplete style. | | leftComponent | ReactNode | Custom component to render on the left side of the top bar. | | rightComponent | ReactNode | Custom component to render on the right side of the top bar. | | slidesToShow | number | Number of project items visible at once in the sidebar carousel. | | showSearchProject | boolean | Whether to show the search button in the left sidebar. | | hiddenSave | boolean | If true, hides the save button in the top bar. Default: false | | onChangeNavigate | (props: any) => any | Callback when a navigation item is clicked. | | onChangeProjectSelected | (props: any) => any | Callback when a project is selected. Returns the selected project object. | | onChangeFavoriteProject | (props: any) => any | Callback when a project's favourite status is toggled. | | onSearchChange | (props: any) => any | Callback when search input changes. | | onClickSearch | (props: any) => any | Callback when the search button is clicked. | | onClickSave | (props: any) => any | Callback when the save button in the top bar is clicked. | | styleForTopBar | CSSProperties | Custom styles for the top bar. | | styleForLeftSideBar | CSSProperties | Custom styles for the left sidebar. | | styleForBody | CSSProperties | Custom styles for the body container. |

Project Object Shape

| Property | Type | Description | | -------------- | --------- | -------------------------------------------------------------------- | | id | string | Unique identifier for the project. | | name | string | Display name (falls back to id if not provided). | | isAllProject | boolean | Marks as the "All" project (always shown first, cannot unfavourite). | | isActive | boolean | If true, this project is selected by default on mount. | | isFavorite | boolean | If true, this project starts as a favourite (shown before others). |

Using showSearchProject with Favourite Toggle

When showSearchProject is enabled, you need to handle the favourite toggle by calling your API and updating the local project list. Here is a complete example:

// API function
export async function UpdateFavoriteProjectForUser(
  projectId: string,
): Promise<unknown> {
  const response = await axiosClientIdd.post(
    `/user-favorite-projects/update-favorite-project-for-user`,
    {
      projectId: projectId,
      appName: "[YOUR APP NAME]",
    },
  );
  return response.data;
}
// Callback in your component
const [projectsFilter, setProjectsFilter] = useState<IProject[]>(projects);

const onChangeFavoriteProject = useCallback(
  async (project: IProject) => {
    try {
      await UpdateFavoriteProjectForUser(project.id);
      setProjectsFilter(
        projectsFilter?.map((p: any) =>
          p.id === project.id ? { ...p, isFavorite: !p.isFavorite } : p,
        ),
      );
    } catch (error) {
      console.error("Update favorite projects failed:", error);
    }
  },
  [projectsFilter, setProjectsFilter],
);

// Usage
<MainWH
  projects={projectsFilter}
  showSearchProject={true}
  onChangeFavoriteProject={onChangeFavoriteProject}
  // ...other props
/>;

Left Sidebar Features

The left sidebar includes:

  • Route Navigation: Clickable items defined via routes prop.
  • Project Carousel: Vertical carousel with slide animation (Up/Down buttons) to browse projects.
  • Search Panel: A Popover panel (toggled via search button) with text search, favourites section, and all projects section.
  • Favourites: Projects with isFavorite: true are shown first. Users can toggle favourites via the star icon in the search panel.
  • Divider: A visual separator between favourite and non-favourite projects in the carousel.

Left Sidebar Component Structure

The left sidebar implementation is split into focused files under src/components/template/left_panel:

| File | Responsibility | | --------------------- | ------------------------------------------------------------------------------------ | | LeftSideBarWH.tsx | Main container. Owns active project/favourite state and wires callbacks. | | RouteItem.tsx | Renders a single route navigation item with tooltip and active styling. | | ProjectSwitcher.tsx | Renders the project area, including search popover, result rows, favourite toggles, and carousel. | | types.ts | Shared TypeScript props and project helper types for the sidebar. |

ProjectSwitcher.tsx keeps its internal project subcomponents in the same file and uses a shared ProjectBaseProps interface for common project props.

TopBar Components

The package exports specialized components for the top bar actions and filters.

import {
  SearchInputWH,
  SearchSelectOption,
  DateRangePickerWH,
  StatusFilterWH
} from '@whdigitalbuild/react-base-wh';

// Example: Using the Search Input
<SearchInputWH
  placeholder="Search..."
  onSearch={(value) => console.log(value)}
/>

// Example: Using the Date Range Picker
<DateRangePickerWH
  onChange={(dates) => console.log(dates)}
/>

Available TopBar Components

  • Inputs & Filters:

    • SearchInputWH: A styled search input field.
    • SearchSelectOption: A search component with dropdown options.
    • DateRangePickerWH: A date range picker based on Ant Design.
    • StatusFilterWH: A dropdown or filter component for status selection.
  • Icons:

    • AddIconWH
    • SaveIconWH
    • UploadIconWH
    • FileExcelIconWH
    • HighlightIconWH
    • GroupExpandedIconWH
    • HansonTableIConWH

External Dependencies

The left sidebar uses Tabler Icons via CDN. Add the following to your index.html:

<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/dist/tabler-icons.min.css"
/>

License

MIT © wohhupwebdeveloper