🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@abpjs/theme-shared

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@abpjs/theme-shared

ABP Framework Theme Shared components for React - translated from @abp/ng.theme.shared

latest
Source
npmnpm
Version
4.0.0
Version published
Weekly downloads
50
614.29%
Maintainers
1
Weekly downloads
 
Created
Source

@abpjs/theme-shared

Shared UI components and services for ABP Framework in React

npm version documentation License: LGPL-3.0

Overview

@abpjs/theme-shared provides essential shared UI components and services for ABP-based React applications. It includes toast notifications, confirmation dialogs, modal management, and global error handling - the building blocks that other ABP theme packages depend on.

This package is a React translation of the original @abp/ng.theme.shared Angular package, offering the same powerful UI utilities with modern React patterns.

Features

  • Toast Notifications - Global notification system with multiple types
  • Confirmation Dialogs - Promise-based confirmation modals
  • Modal Management - Centralized modal service
  • Error Handling - Global error handler with user-friendly messages
  • Theme Configuration - Chakra UI v3 theme customization with createSystem
  • Color Mode - Built-in light/dark theme support (opt-in)
  • Utility Functions - Common UI utilities and helpers
  • TypeScript - Full type safety with comprehensive definitions

Installation

# Using npm
npm install @abpjs/theme-shared

# Using yarn
yarn add @abpjs/theme-shared

# Using pnpm
pnpm add @abpjs/theme-shared

Required Dependencies

This package requires the following peer dependencies:

npm install @abpjs/core @chakra-ui/react @emotion/react lucide-react

Note: Chakra UI v3 no longer requires @emotion/styled or framer-motion as peer dependencies.

Quick Start

1. Setup the Theme Provider

Wrap your application with the ThemeSharedProvider:

import { ThemeSharedProvider } from '@abpjs/theme-shared';
import { CoreProvider } from '@abpjs/core';

function App() {
  return (
    <CoreProvider environment={environment}>
      <ThemeSharedProvider>
        <YourApp />
      </ThemeSharedProvider>
    </CoreProvider>
  );
}

Note: ThemeSharedProvider includes Chakra's provider internally, so you don't need to wrap with ChakraProvider separately.

2. Show Toast Notifications

import { useToaster } from '@abpjs/theme-shared';

function MyComponent() {
  const toaster = useToaster();

  const handleSuccess = () => {
    toaster.success('Operation completed successfully!', 'Success');
  };

  const handleError = () => {
    toaster.error('Something went wrong!', 'Error');
  };

  const handleWarning = () => {
    toaster.warn('Please review your input.', 'Warning');
  };

  const handleInfo = () => {
    toaster.info('Did you know? You can customize this.', 'Info');
  };

  return (
    <div>
      <button onClick={handleSuccess}>Success</button>
      <button onClick={handleError}>Error</button>
      <button onClick={handleWarning}>Warning</button>
      <button onClick={handleInfo}>Info</button>
    </div>
  );
}

3. Show Confirmation Dialogs

import { useConfirmation, Toaster } from '@abpjs/theme-shared';

function DeleteButton({ onDelete }) {
  const confirmation = useConfirmation();

  const handleClick = async () => {
    const status = await confirmation.warn(
      'Are you sure you want to delete this item? This action cannot be undone.',
      'Delete Item',
      {
        yesCopy: 'Delete',
        cancelCopy: 'Cancel',
      }
    );

    if (status === Toaster.Status.confirm) {
      onDelete();
    }
  };

  return <button onClick={handleClick}>Delete</button>;
}

Components

Toast / ToastContainer

Toast notification component and container.

import { ToastContainer } from '@abpjs/theme-shared';

// The ToastContainer is usually placed at the root level
// ThemeSharedProvider includes it by default when renderToasts={true}
function App() {
  return (
    <ThemeSharedProvider renderToasts={true}>
      <YourApp />
    </ThemeSharedProvider>
  );
}

ConfirmationDialog

Confirmation dialog component.

import { ConfirmationDialog } from '@abpjs/theme-shared';

// Usually managed by the provider, but can be used directly
// ThemeSharedProvider includes it by default when renderConfirmation={true}

Modal

Generic modal component for custom dialogs. Uses Chakra UI v3 Dialog internally.

import { Modal } from '@abpjs/theme-shared';

function CustomModal({ isOpen, onClose }) {
  return (
    <Modal
      visible={isOpen}
      onVisibleChange={(open) => !open && onClose()}
      header="Custom Modal"
      size="md"
      footer={
        <>
          <Button variant="ghost" onClick={onClose}>Cancel</Button>
          <Button colorPalette="blue">Save</Button>
        </>
      }
    >
      <p>Your modal content here</p>
    </Modal>
  );
}

Props:

PropTypeDefaultDescription
visibleboolean-Controls modal visibility
onVisibleChange(visible: boolean) => void-Callback when visibility changes
headerReactNode-Modal header content
footerReactNode-Modal footer content
size'sm' | 'md' | 'lg' | 'xl' | 'full''md'Modal size
centeredbooleantrueCenter modal vertically
closeOnOverlayClickbooleantrueClose when clicking outside
closeOnEscapebooleantrueClose on Escape key
showCloseButtonbooleantrueShow close button in header
scrollBehavior'inside' | 'outside''inside'Scroll behavior for content
childrenReactNode-Modal content

Hooks

useToaster

Hook for showing toast notifications.

import { useToaster } from '@abpjs/theme-shared';

function MyComponent() {
  const toaster = useToaster();

  // Success toast
  toaster.success('Saved successfully!', 'Success');

  // Error toast
  toaster.error('Failed to save.', 'Error');

  // Warning toast
  toaster.warn('Please check your input.', 'Warning');

  // Info toast
  toaster.info('New updates available.', 'Info');

  // With options
  toaster.success('Custom message', 'Title', {
    life: 5000,      // Duration in ms
    sticky: false,   // If true, won't auto-dismiss
    closable: true,  // Show close button
  });
}

Toaster Methods:

MethodDescription
success(message, title?, options?)Show success notification
error(message, title?, options?)Show error notification
warn(message, title?, options?)Show warning notification
info(message, title?, options?)Show info notification
clear()Clear all notifications
remove(id)Remove specific notification

useConfirmation

Hook for showing confirmation dialogs.

import { useConfirmation, Toaster } from '@abpjs/theme-shared';

function MyComponent() {
  const confirmation = useConfirmation();

  const handleDelete = async () => {
    const status = await confirmation.warn(
      'Are you sure?',
      'Delete',
      {
        yesCopy: 'Yes, Delete',
        cancelCopy: 'No, Keep',
      }
    );

    if (status === Toaster.Status.confirm) {
      // User confirmed
      performDelete();
    }
  };

  // Different severity methods
  const showInfo = () => confirmation.info('Info message', 'Info');
  const showSuccess = () => confirmation.success('Success!', 'Success');
  const showError = () => confirmation.error('Error occurred', 'Error');
}

Confirmation Options:

interface ConfirmationOptions {
  yesCopy?: string;       // Default: 'Yes' (localized)
  cancelCopy?: string;    // Default: 'Cancel' (localized)
  hideYesBtn?: boolean;   // Hide confirm button
  hideCancelBtn?: boolean; // Hide cancel button
}

Theme Configuration

Custom Theme with Chakra v3

Customize the theme using defineConfig:

import { ThemeSharedProvider, defineConfig } from '@abpjs/theme-shared';

const customTheme = defineConfig({
  theme: {
    tokens: {
      colors: {
        brand: {
          50: { value: '#e3f2fd' },
          100: { value: '#bbdefb' },
          500: { value: '#2196f3' },
          600: { value: '#1e88e5' },
          // ... more shades
        },
      },
    },
    semanticTokens: {
      colors: {
        brand: {
          solid: { value: '{colors.brand.500}' },
          contrast: { value: 'white' },
          fg: { value: '{colors.brand.700}' },
        },
      },
    },
  },
});

function App() {
  return (
    <ThemeSharedProvider themeOverrides={customTheme}>
      <YourApp />
    </ThemeSharedProvider>
  );
}

Color Mode (Dark/Light Theme)

Enable color mode support:

import { ThemeSharedProvider } from '@abpjs/theme-shared';

function App() {
  return (
    <ThemeSharedProvider
      enableColorMode={true}
      defaultColorMode="light" // 'light' | 'dark' | 'system'
    >
      <YourApp />
    </ThemeSharedProvider>
  );
}

Use color mode in components:

import { useColorMode, ColorModeButton } from '@abpjs/theme-shared';

function Header() {
  const { colorMode, toggleColorMode } = useColorMode();

  return (
    <header>
      <span>Current mode: {colorMode}</span>
      <ColorModeButton /> {/* Pre-built toggle button */}
    </header>
  );
}

ThemeSharedProvider Props

PropTypeDefaultDescription
childrenReactNode-Child components
renderToastsbooleantrueRender ToastContainer
renderConfirmationbooleantrueRender ConfirmationDialog
themeOverridesThemeOverride-Custom theme configuration
toastPositionstring'bottom-right'Toast position
enableColorModebooleanfalseEnable dark/light mode
defaultColorMode'light' | 'dark' | 'system''light'Default color mode

Data Models

Toaster Types

namespace Toaster {
  interface Toast {
    id: string;
    message: string;
    title?: string;
    severity: 'info' | 'success' | 'warn' | 'error';
    life?: number;
    sticky?: boolean;
    closable?: boolean;
    messageLocalizationParams?: string[];
    titleLocalizationParams?: string[];
  }

  enum Status {
    confirm = 'confirm',
    reject = 'reject',
    dismiss = 'dismiss',
  }
}

Complete Example

Full integration example:

import { BrowserRouter } from 'react-router-dom';
import { CoreProvider } from '@abpjs/core';
import {
  ThemeSharedProvider,
  useToaster,
  useConfirmation,
  Toaster,
  defineConfig,
} from '@abpjs/theme-shared';

const environment = {
  // Your ABP configuration
};

// Optional: Custom theme
const customTheme = defineConfig({
  theme: {
    tokens: {
      colors: {
        brand: {
          500: { value: '#6366f1' }, // Custom primary color
        },
      },
    },
  },
});

// Main App
function App() {
  return (
    <CoreProvider environment={environment}>
      <ThemeSharedProvider
        themeOverrides={customTheme}
        enableColorMode={true}
      >
        <BrowserRouter>
          <AppContent />
        </BrowserRouter>
      </ThemeSharedProvider>
    </CoreProvider>
  );
}

// Example usage in a component
function UserActions({ user }) {
  const toaster = useToaster();
  const confirmation = useConfirmation();

  const handleSave = async () => {
    try {
      await saveUser(user);
      toaster.success('User saved successfully!', 'Success');
    } catch (error) {
      toaster.error(error.message, 'Error');
    }
  };

  const handleDelete = async () => {
    const status = await confirmation.warn(
      `Are you sure you want to delete ${user.name}?`,
      'Delete User',
      { yesCopy: 'Delete' }
    );

    if (status === Toaster.Status.confirm) {
      try {
        await deleteUser(user.id);
        toaster.success('User deleted!', 'Success');
      } catch (error) {
        toaster.error(error.message, 'Error');
      }
    }
  };

  return (
    <div>
      <button onClick={handleSave}>Save</button>
      <button onClick={handleDelete}>Delete</button>
    </div>
  );
}

export default App;

Migration from Chakra UI v2

If you're upgrading from a previous version that used Chakra UI v2:

Key Changes

  • No separate ChakraProvider - ThemeSharedProvider now includes it
  • Theme configuration - Use defineConfig() instead of extendTheme()
  • Modal API - Use visible/onVisibleChange instead of isOpen/onClose
  • Color tokens - Use { value: '#color' } format in theme tokens
  • Boolean props - isDisableddisabled, isLoadingloading
  • Color scheme - colorSchemecolorPalette
  • Icons - Use lucide-react instead of @chakra-ui/icons

Example Migration

// Before (Chakra v2)
<Modal isOpen={isOpen} onClose={onClose} isCentered>
  <ModalOverlay />
  <ModalContent>
    <ModalHeader>Title</ModalHeader>
    <ModalBody>Content</ModalBody>
  </ModalContent>
</Modal>

// After (Chakra v3 via @abpjs/theme-shared)
<Modal
  visible={isOpen}
  onVisibleChange={(open) => !open && onClose()}
  header="Title"
  centered
>
  Content
</Modal>

Documentation

For comprehensive documentation, visit docs.abpjs.io:

Contributing

This package is part of the ABP React monorepo. Contributions are welcome!

License

LGPL-3.0 - See LICENSE for details.

View Full Documentation | Report Issues | View Source

FAQs

Package last updated on 08 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts