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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@pagamio/frontend-commons-lib

v0.8.201

Published

Pagamio library for Frontend reusable components like the form engine and table container

Downloads

2,502

Readme

pagamio-frontend-commons-library

A reusable React component library styled with Tailwind CSS, designed to streamline your frontend development process.

:rocket: Features

  • A Form Engine: A package with all possible input components that can be used to build a form. This helps render forms in your project.
  • Reusable Components: A collection of customizable components like DateInput, TextInput, and more.
  • Tailwind CSS: Utility-first CSS framework for rapid UI development.
  • TypeScript Support: Fully typed components for enhanced developer experience.
  • Flexible Imports: Import components individually or collectively.
  • Peer Dependencies: Ensures compatibility with React and React DOM versions.
  • API Client: Robust API integration with authentication support, SWR data fetching, and mocking capabilities.

:package: Installation

Install the library via Yarn:

yarn add pagamio-frontend-commons-lib

:art: Usage

  • Importing Styles

    Import the compiled Tailwind CSS styles into your application's entry point (e.g., index.js or App.js):

    import 'pagamio-frontend-commons-lib/lib/styles.css';

  • Importing Components

    You can import components individually or collectively.

  • a. Named Imports

    Import multiple components from the main entry point:

    import { DateInput, TextInput } from 'pagamio-frontend-commons-lib';

:gear: Environment Variables

Some utilities (for example the useImageUpload hook and ImageUploader component) require an API endpoint that issues presigned upload URLs. Make sure your host application exposes the following public environment variable before using those helpers:

| Variable | Description | | --- | --- | | NEXT_PUBLIC_UPLOAD_URL_ENDPOINT | HTTP endpoint that returns presigned URLs for file uploads. |

# .env (per app)
NEXT_PUBLIC_UPLOAD_URL_ENDPOINT=https://<your-upload-service>/upload-url

This value is resolved at runtime;

:shield: RBAC Module

The Role-Based Access Control (RBAC) module provides a flexible system for implementing permission-based access control in your applications.

Features

  • Generic TypeScript implementation that works with any permission system
  • Flexible configuration that can be initialized once at application startup
  • Pure utility functions that can be used anywhere in your application
  • React hooks for convenient use in components
  • Support for role-based and permission-based access control
  • Type-safe API with generics for custom user and permission types

Core Components

Initialization

Initialize the RBAC system with your application-specific configuration:

import { initializeRBAC } from 'pagamio-frontend-commons-lib/rbac';
import { Permissions } from './permissions';

// Define your permission enum
enum Permissions {
  ALL = 'ALL',
  VIEW_DASHBOARD = 'VIEW_DASHBOARD',
  MANAGE_USERS = 'MANAGE_USERS',
  // ... other permissions
}

// Define your RBAC configuration
const rbacConfig = {
  'ADMIN': [Permissions.ALL],
  'MANAGER': [Permissions.VIEW_DASHBOARD, Permissions.MANAGE_USERS],
  'USER': [Permissions.VIEW_DASHBOARD],
};

// Initialize RBAC with your configuration
initializeRBAC({
  rbacConfig,
  allPermissionValue: Permissions.ALL,
  allPermissions: Object.values(Permissions),
  roleKey: 'roleName' // The property in your user object that contains the role
});

Utility Functions

Use the RBAC utility functions to check permissions and roles:

import { hasPermission, hasRole, getUserPermissions } from 'pagamio-frontend-commons-lib/rbac';
import { Permissions } from './permissions';

// Check if a user has a specific permission
const canViewDashboard = hasPermission(user, Permissions.VIEW_DASHBOARD);

// Check if a user has a specific role
const isAdmin = hasRole(user, 'ADMIN');

// Get all permissions for a user
const userPermissions = getUserPermissions(user);

React Hooks

Use the RBAC hooks in your React components:

import { useHasPermission, useHasRole } from 'pagamio-frontend-commons-lib/rbac';
import { useAuth } from 'pagamio-frontend-commons-lib/auth';
import { Permissions } from './permissions';

function Dashboard() {
  const { user } = useAuth();
  const canManageUsers = useHasPermission(user, Permissions.MANAGE_USERS);
  
  return (
    <div>
      <h1>Dashboard</h1>
      {canManageUsers && <UserManagement />}
    </div>
  );
}

:globe_with_meridians: API Module

The API module provides a robust system for making API requests with built-in authentication, caching, and error handling capabilities.

Features

  • TypeScript support with generic types for type-safe API operations
  • Authentication integration with token management
  • SWR integration for data fetching, caching, and revalidation
  • Support for RESTful operations (GET, POST, PUT, PATCH, DELETE)
  • Pagination support for large datasets
  • Configurable retry logic and timeout handling
  • Request and response interceptors
  • Error handling and logging
  • Mock API support for testing and development

Core Components

ApiClient

The ApiClient class provides a flexible HTTP client with authentication support, retry logic, and error handling.

import { ApiClient, createApiClient } from 'pagamio-frontend-commons-lib';

// Create a client with your custom auth configuration
const apiClient = createApiClient<MyAuthConfig>({
  baseURL: 'https://api.example.com',
  tokenManager: tokenManager,
  defaultHeaders: {
    'Content-Type': 'application/json',
  },
  timeout: 5000,
  retries: 2,
});

// Making API calls
const data = await apiClient.get<MyResponseType>('/users');
const newUser = await apiClient.post<UserResponse>('/users', { name: 'John', email: '[email protected]' });

SWR Integration

The API module includes SWR hooks for efficient data fetching with caching, revalidation, and focus refetching.

import { useApiSWR, usePaginatedApiSWR } from 'pagamio-frontend-commons-lib';

// Basic data fetching with SWR
function UserProfile({ userId }) {
  const { data, error, isLoading } = useApiSWR<UserData>(`/users/${userId}`);

  if (isLoading) return <div>Loading
...
  </div>;
  if (error) return <div>Error
  loading
  user
  data < /div>;

  return <div>Hello, { data.name }! < /div>;
}

// Paginated data fetching
function UserList() {
  const { data, error, isLoading } = usePaginatedApiSWR<User>('/users', {
    params: { page: 0, size: 10 }
  });

  if (isLoading) return <div>Loading
  users
...
  </div>;

  return (
    <div>
      <h2>Users({ data.totalElements }) < /h2>
    < ul >
    {
      data.content.map(user => <li key = { user.id } > { user.name } < /li>)}
        < /ul>
        < /div>
      );
    }

API Context Provider

The ApiProvider component makes the API client available throughout your application.

import { ApiProvider, createApiClient } from 'pagamio-frontend-commons-lib';

// Create API client
const apiClient = createApiClient<MyAuthConfig>({
  baseURL: 'https://api.example.com',
  tokenManager: tokenManager,
});

// Wrap your application with the provider
function App() {
  return (
    <ApiProvider apiClient = { apiClient } >
      <YourApplication / >
      </ApiProvider>
  );
}

API Mutations

The API module provides hooks for performing mutations (create, update, delete operations).

import { useApiMutation, useApiSWRWithMutation } from 'pagamio-frontend-commons-lib';

// Using the mutation hook
function CreateUserForm() {
  const mutation = useApiMutation<UserResponse>();

  const handleSubmit = async (userData) => {
    try {
      const newUser = await mutation.post('/users', userData);
      alert(`User ${newUser.name} created successfully!`);
    } catch (error) {
      console.error('Failed to create user:', error);
    }
  };

  return <form onSubmit = { handleSubmit } > {/* form fields */ } < /form>;
}

// Combined SWR and mutation hook
function EditUserProfile({ userId }) {
  const { data, error, isLoading, mutate } = useApiSWRWithMutation<UserData>(
    `/users/${userId}`
  );

  const handleUpdate = async (updatedData) => {
    try {
      await mutate.patch(`/users/${userId}`, updatedData);
      alert('Profile updated successfully!');
    } catch (error) {
      console.error('Failed to update profile:', error);
    }
  };

  if (isLoading) return <div>Loading
...
  </div>;

  return <ProfileForm user = { data }
  onSubmit = { handleUpdate }
  />;
}

Mocking API Requests

The API module supports mocking API requests for testing and development.

import { ApiProvider, createApiClient, MockConfig } from 'pagamio-frontend-commons-lib';

// Define mock configurations
const mockConfig: MockConfig[] = [
  {
    path: '/users',
    method: 'GET',
    response: [
      { id: 1, name: 'John Doe', email: '[email protected]' },
      { id: 2, name: 'Jane Smith', email: '[email protected]' }
    ]
  },
  {
    path: '/users',
    method: 'POST',
    params: { name: 'Alice', email: '[email protected]' },
    response: { id: 3, name: 'Alice', email: '[email protected]' }
  }
];

// Enable mocking in the provider
function TestApp() {
  return (
    <ApiProvider
      apiClient = { apiClient }
  mocked = { true }
  mockConfig = { mockConfig } >
    <YourApplication / >
    </ApiProvider>
)
  ;
}

Authentication Integration

The API client integrates with the token manager for authentication.

import { createApiClient, createTokenManager } from 'pagamio-frontend-commons-lib';

// Create a token manager
const tokenManager = createTokenManager<MyAuthConfig>({
  baseUrl: 'https://api.example.com',
  refreshEndpoint: '/auth/refresh',
  cookieOptions: {
    secure: true,
    sameSite: 'strict'
  }
});

// Create API client with authentication
const apiClient = createApiClient<MyAuthConfig>({
  baseURL: 'https://api.example.com',
  tokenManager: tokenManager,
  onUnauthorized: () => {
    // Handle unauthorized access (e.g., redirect to login)
    window.location.href = '/login';
  }
});

Advanced Configuration

Custom Request/Response Handling

const apiClient = createApiClient<MyAuthConfig>({
  baseURL: 'https://api.example.com',
  tokenManager: tokenManager,
  onRequest: async (config) => {
    // Add custom headers or modify request configuration
    config.headers = {
      ...config.headers,
      'X-Custom-Header': 'CustomValue'
    };
    return config;
  },
  onResponse: async (response, data) => {
    // Transform or process response data
    return data.results || data;
  },
  onError: async (error) => {
    // Log or handle errors
    console.error(`API Error (${error.status}):`, error.message);
  }
});

Pagination and Filtering

// Custom pagination params
const { data } = useApiSWR<UserListResponse>('/users', {
  params: {
    page: 0,
    size: 25,
    sortBy: 'createdAt',
    sortDir: 'desc',
    name: 'John'
  }
});

TypeScript Integration

The API module is fully typed with TypeScript, providing type safety and better developer experience.

// Define your auth configuration
interface MyAuthConfig extends CustomAuthConfig {
  UserInfo: {
    id: string;
    username: string;
    email: string;
    roles: string[];
  };
  TokenInfo: {
    token: string;
    expiresIn: number;
  };
  Credentials: {
    username: string;
    password: string;
  };
}

// Use your custom types with the API client
const apiClient = createApiClient<MyAuthConfig>({
  baseURL: 'https://api.example.com',
  tokenManager: tokenManager
});

// Type-safe API calls
interface Product {
  id: string;
  name: string;
  price: number;
}

const { data: products } = useApiSWR<Product[]>('/products');

Best Practices

  1. Centralize API Configuration: Create a central API configuration file that sets up the API client and exports hooks for use throughout your application.

  2. Use TypeScript: Leverage TypeScript definitions for type-safe API calls and better developer experience.

  3. Handle Loading and Error States: Always handle loading and error states in your components when using API hooks.

  4. Implement Proper Error Handling: Configure error handling with the onError callback and handle errors appropriately in your UI.

  5. Use Mocking for Development: Enable mocking during development to work without a backend or to test specific scenarios.

  6. Optimize Cache Invalidation: Use SWR's mutate function to keep your data fresh and update the UI after mutations.

  7. Set Appropriate Timeouts: Configure request timeouts based on the expected response time of your API endpoints.

:globe_with_meridians: Translations

The library provides a complete translation system that supports internationalization for your applications.

Languages Currently Supported

The library comes with built-in support for the following languages:

  • English (en)
  • Spanish (es)
  • French (fr)
  • Portuguese (pt)

Implementation Guide

Follow these steps to implement translations in your project:

1. Setup Translation Provider

Wrap your application with the TranslationProvider:

import { TranslationProvider } from 'pagamio-frontend-commons-lib';

function App() {
  return (
    <TranslationProvider
      defaultLocale="en"
      loadPath="/translations" // Path to your translation files
    >
      <YourApplicationComponents />
    </TranslationProvider>
  );
}

Alternatively, if you're using the AppLayout component:

import { AppLayout } from 'pagamio-frontend-commons-lib';

function App() {
  return (
    <AppLayout
      // other props...
      enableTranslations={true}
      translationConfig={{
        defaultLocale: 'en',
        loadPath: '/translations',
      }}
    >
      {/* Your content */}
    </AppLayout>
  );
}

2. Create Translation Files

Create JSON files for each language in your project:

/public
  /translations
    en.json
    es.json
    fr.json
    pt.json

Example of a translation file (en.json):

{
  "common": {
    "save": "Save",
    "cancel": "Cancel",
    "submit": "Submit"
  },
  "auth": {
    "login": "Login",
    "register": "Register",
    "forgotPassword": "Forgot Password?"
  }
}

3. Add i18next-scanner Config

Create an i18next-scanner.config.js in your project root:

module.exports = {
  input: ['src/**/*.{js,jsx,ts,tsx}', '!src/**/*.test.{js,jsx,ts,tsx}', '!**/node_modules/**'],
  output: './public/translations/',
  options: {
    debug: true,
    func: {
      list: ['t', 'tLib'],
      extensions: ['.js', '.jsx', '.ts', '.tsx'],
    },
    lngs: ['en', 'es', 'fr', 'pt'],
    defaultLng: 'en',
    defaultValue: function(lng, ns, key) {
      return key;
    },
    resource: {
      loadPath: 'public/translations/{{lng}}.json',
      savePath: '{{lng}}.json',
      jsonIndent: 2,
      lineEnding: '\n',
    },
    removeUnusedKeys: false,
    nsSeparator: false,
    keySeparator: '.',
  },
};

4. Add Extraction Script to package.json

"scripts": {
"extract-translations": "i18next-scanner --config i18next-scanner.config.js 'src/**/*.{js,jsx,ts,tsx}'"
}

5. Install Required Dependencies

Install the necessary dev dependencies:

yarn add -D i18next-scanner

Or if you're using npm:

npm install --save-dev i18next-scanner

6. Use Translations in Components

import { useTranslation } from 'pagamio-frontend-commons-lib';

function YourComponent() {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t('common.title', 'Default Title')}</h1>
      <p>{t('common.description', 'This is a default description')}</p>
      <button>{t('common.save', 'Save')}</button>
    </div>
  );
}

7. Use Library Translations

The library provides common translations for frequently used UI elements:

import { useLibTranslations } from 'pagamio-frontend-commons-lib';

function YourComponent() {
  const { tLib } = useLibTranslations();

  return (
    <div>
      <button>{tLib('save')}</button>
      <button>{tLib('cancel')}</button>
      <button>{tLib('submit')}</button>
    </div>
  );
}

8. Add Locale Switcher

Add a language switcher to allow users to change the application language:

import { LocaleSwitcher } from 'pagamio-frontend-commons-lib';

function Header() {
  return (
    <header>
      <nav>
        {/* Your other navigation elements */}
        <LocaleSwitcher />
      </nav>
    </header>
  );
}

You can customize language display names:

<LocaleSwitcher
  localeNames={{
    en: 'English',
    es: 'Español',
    fr: 'Français',
    pt: 'Português'
  }}
/>

9. Run the Extraction Script

Extract all translation keys from your application:

yarn extract-translations

This will scan your code for translation keys and update your translation files.

Advanced Configuration

Custom Locale Detector

You can configure the translation system to detect the browser's locale:

import { TranslationProvider, detectBrowserLocale } from 'pagamio-frontend-commons-lib';

function App() {
  const browserLocale = detectBrowserLocale(); // Returns 'en', 'es', etc.

  return (
    <TranslationProvider
      defaultLocale={browserLocale}
      loadPath="/translations"
    >
      <YourApplicationComponents />
    </TranslationProvider>
  );
}

Direct Loading of Translation Data

Instead of loading translations from files, you can provide them directly:

import { TranslationProvider } from 'pagamio-frontend-commons-lib';

const translations = [
  {
    locale: 'en',
    messages: {
      common: {
        save: 'Save',
        cancel: 'Cancel'
      }
    }
  },
  {
    locale: 'es',
    messages: {
      common: {
        save: 'Guardar',
        cancel: 'Cancelar'
      }
    }
  }
];

function App() {
  return (
    <TranslationProvider
      defaultLocale="en"
      localeData={translations}
    >
      <YourApplicationComponents />
    </TranslationProvider>
  );
}