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

@modularize-rbac/admin-react

v0.1.1

Published

React hooks + Storybook-driven admin components for modularize-rbac/laravel.

Readme

@modularize-rbac/admin-react

React hooks + admin components for modularize-rbac/laravel. Pre-built primitives (Roles editor, Modules tree, Audit viewer, Languages admin, AccessGuard) plus the underlying React Query hooks if you want to roll your own UI.

npm i @modularize-rbac/admin-react @modularize-rbac/sdk-ts

What's inside

// API client + types — re-exported from @modularize-rbac/sdk-ts.
import type { paths, components } from '@modularize-rbac/admin-react';

// React provider + hook (wraps the sdk-ts client + React Query).
import { RbacProvider, useRbacApi } from '@modularize-rbac/admin-react';

// React Query hooks
import {
  useAdminModules,
  useUpdateModule,
  useAdminRoles,
  useAdminRole,
  useUpdateRole,
  useSyncRoleModules,
  useAdminLanguages,
  useCreateLanguage,
  useUpdateLanguage,
  useDeleteLanguage,
  useSetDefaultLanguage,
} from '@modularize-rbac/admin-react';

// Reference components (ship pre-built):
import {
  RolesPage,
  ModulesTreeEditor,
  LanguagesAdmin,
  AuditViewer,
  AccessGuard,
  AccessGuardProvider,
  useHasAbility,
} from '@modularize-rbac/admin-react';

Setup

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { RbacProvider } from '@modularize-rbac/admin-react';
import { createClient } from '@modularize-rbac/sdk-ts';

const queryClient = new QueryClient();
const apiClient = createClient({
  baseUrl: 'https://app.test/api/admin',
  headers: { Authorization: `Bearer ${token}` },
});

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <RbacProvider apiClient={apiClient}>
        {/* your routes */}
      </RbacProvider>
    </QueryClientProvider>
  );
}

Reference components

<RolesPage />

Drop-in admin page for managing roles. Lists roles paginated, with create / clone / soft-delete / restore actions wired to the matching hooks.

import { RolesPage } from '@modularize-rbac/admin-react';

export function AdminRolesRoute() {
  return <RolesPage limit={25} />;
}

All visible strings can be overridden for i18n via the labels prop (see RolesPageLabels). Pass onRoleSelect to receive the role id when a row is clicked — wire it up to your own route for the role editor.

<ModulesTreeEditor />

Drag-and-drop tree editor for the module catalog. Built on @dnd-kit/sortable: drag a row to reorder siblings (persists sort_order via PUT /modules/{id}). Per-row Add Child / Edit / Delete + multi-select with bulk-delete bar at the top.

import { ModulesTreeEditor } from '@modularize-rbac/admin-react';

export function AdminModulesRoute() {
  return <ModulesTreeEditor onModuleSelect={(id) => navigate(`/admin/modules/${id}`)} />;
}

Every label is overridable via the labels prop (ModulesTreeEditorLabels). The component issues one PUT /modules/{id} per row when a drag completes (one per affected sort_order), batched by React Query.

<LanguagesAdmin />

CRUD table for the configured languages with a "set as default" action gated by a confirmation modal (changing the default cascades through translation fallbacks). Default-language rows cannot be deleted — the API itself refuses with a 422 anyway.

import { LanguagesAdmin } from '@modularize-rbac/admin-react';

export function AdminLanguagesRoute() {
  return <LanguagesAdmin />;
}

All visible strings (including the default-change warning) override via the labels prop.

<AuditViewer />

Paginated viewer for the audit log with filter controls (event / actor / tenant / time window) and per-row expandable JSON payload. Rows that participate in the v2.7 hash chain get a green "chain ok" badge. [REDACTED] markers in the payload (from the PII redaction layer) are highlighted in amber so reviewers can tell at a glance what was scrubbed.

import { AuditViewer } from '@modularize-rbac/admin-react';

export function AdminAuditRoute() {
  return <AuditViewer limit={50} />;
}

The default event dropdown lists the standard domain events; pass labels.filters.event (or override with a custom select on top) to expose application-specific event names.

<AccessGuard /> + <AccessGuardProvider />

Conditionally render UI based on the current user's abilities. The package does not fetch the ability list — the host already knows what the current user can do (auth response, JWT claims, session). Wrap the relevant subtree in <AccessGuardProvider abilities={...} /> and nested <AccessGuard ability="..."> reads it without prop drilling.

import { AccessGuard, AccessGuardProvider } from '@modularize-rbac/admin-react';

export default function App() {
  const { abilities } = useCurrentUser(); // host's own auth state

  return (
    <AccessGuardProvider abilities={abilities}>
      <Toolbar />
    </AccessGuardProvider>
  );
}

function Toolbar() {
  return (
    <>
      <AccessGuard ability="events.create"><CreateButton /></AccessGuard>
      <AccessGuard ability="events.delete" fallback={<DisabledHint />}>
        <DeleteButton />
      </AccessGuard>
    </>
  );
}

The useHasAbility(ability, abilities?) hook is also exported for ad-hoc imperative checks (e.g. inside a route loader).

Using hooks

import { useAdminModules } from '@modularize-rbac/admin-react';

export function ModulesPage() {
  const { data, isLoading } = useAdminModules();

  if (isLoading) return <p>Loading…</p>;
  return <ul>{data?.map((m) => <li key={m.id}>{m.name}</li>)}</ul>;
}

Peer deps

  • react ^18 || ^19
  • @tanstack/react-query ^5
  • @modularize-rbac/sdk-ts ^0.1
  • @radix-ui/themes ^3 (UI primitives — the reference components render Radix elements)

Don't forget to import the Radix stylesheet once at app entry:

import '@radix-ui/themes/styles.css';

@dnd-kit/core, @dnd-kit/sortable, and @dnd-kit/utilities ship as direct dependencies (ModulesTreeEditor needs them).

Migrating from @casamento/admin-rbac

This package is the renamed continuation of @casamento/admin-rbac v0.1.0. The legacy name is unmaintained.

- import { useAdminModules } from '@casamento/admin-rbac';
+ import { useAdminModules } from '@modularize-rbac/admin-react';

Types changed shape too — hand-rolled AdminModule / AdminRole are gone. Pull the equivalent type out of the spec via @modularize-rbac/sdk-ts instead:

- import type { AdminModule } from '@casamento/admin-rbac';
+ import type { components } from '@modularize-rbac/admin-react';
+ type AdminModule = components['schemas']['Module'];

Build

npm run build    # tsc -p tsconfig.build.json
npm run dev      # watch mode

Outputs dist/index.js + dist/index.d.ts with sourcemaps and declaration maps.

Storybook

Every component ships with a Storybook story documenting its props + at least one usage scenario. Run locally:

npm run storybook        # http://localhost:6006
npm run build-storybook  # static build → storybook-static/

Stories run against msw mock handlers (.storybook/msw-handlers.ts) so they work fully offline. Components are wrapped in:

  • @radix-ui/themes (light, indigo accent, medium radius).
  • A fresh QueryClient per story (no cross-story cache pollution).
  • RbacProvider built on @modularize-rbac/sdk-ts.

Testing

npm test               # vitest run
npm run test:watch     # watch mode
npm run test:coverage  # vitest run --coverage

Tests use Vitest + msw via setupServer in Node. Coverage thresholds: 80% statements / lines, 70% branches, 80% functions.