react-floatui
v0.1.0
Published
Floating UI kit for elements like modals, toasts for React Web Application
Readme
react-floatui
A flexible UI Kit for React applications, providing modal dialogs and toast notifications with rich animations and customization options.
Features
Modals
- Promise-based API - Handle modal results with promises
- Rich animations - Fade, float, and scale animations with customizable options
- Flexible configurations - Background blur, overlay customization, click-outside behavior
- TypeScript support - Full type safety for modal parameters and return values
- Error boundaries - Built-in error handling for modal components
- Accessibility - ESC key support and focus management
Toasts
- Multiple positions - 7 different positioning options (center, corners, edges)
- Animation variety - Fly-in, fade, and scale animations from multiple directions
- Auto-dismiss - Configurable auto-dismiss timers
- Queue management - Queue multiple toasts or replace existing ones
- Manual control - Programmatic closing and close-all functionality
- Configurable defaults - Set default options per hook instance
Installation
npm install react-floatuiQuick Start
1. Setup Provider
Wrap your app with the FloatUI Provider:
import React from 'react';
import { FloatUI } from 'react-floatui';
function App() {
return (
<FloatUI.Provider>
{/* Your app content */}
</FloatUI.Provider>
);
}2. Using Modals
The modal API allows you to show modals directly without registration, similar to the toast API:
import React from 'react';
import { useModal, useModalInstance } from 'react-floatui';
// Define your modal component
function ConfirmModal({ message }: { message: string }) {
const modal = useModalInstance();
return (
<div style={{ padding: '2rem', backgroundColor: 'white', borderRadius: '8px' }}>
<h2>Confirm</h2>
<p>{message}</p>
<button onClick={() => modal.resolve(true)}>Yes</button>
<button onClick={() => modal.reject(false)}>No</button>
</div>
);
}
// Use the modal in your component
function MyComponent() {
const modal = useModal(); // No registration needed
const handleClick = async () => {
try {
const result = await modal.show(ConfirmModal,
{ message: 'Are you sure?' },
{ animation: { type: 'scale', duration: 300 } }
);
console.log('User confirmed:', result);
} catch (error) {
console.log('User cancelled');
}
};
return <button onClick={handleClick}>Show Modal</button>;
}Default Configuration
You can configure default modal options that apply to all modals from a specific hook instance:
function MyComponent() {
// Create a modal hook with default options
const modal = useModal({
animation: { type: 'scale', duration: 300 },
overlay: { opacity: 0.8 },
closeOnEsc: true
});
const showConfirm = () => {
// Uses default animation and overlay settings
modal.show(ConfirmModal, { message: 'Are you sure?' });
};
const showInfo = () => {
// Override specific options while keeping other defaults
modal.show(InfoModal,
{ message: 'Information' },
{ animation: { type: 'fade' } } // Override animation, keep other defaults
);
};
return (
<div>
<button onClick={showConfirm}>Show Confirm</button>
<button onClick={showInfo}>Show Info</button>
</div>
);
}3. Using Toasts
import React from 'react';
import { useToast } from 'react-floatui';
// Define your toast component
function SuccessToast({ message, onClose, closable }) {
return (
<div style={{
padding: '1rem',
backgroundColor: '#28a745',
color: 'white',
borderRadius: '4px'
}}>
{message}
{closable && <button onClick={onClose}>×</button>}
</div>
);
}
function MyComponent() {
const toast = useToast();
const showSuccess = () => {
toast.show(SuccessToast,
{ message: 'Operation successful!' },
{
position: 'topright',
duration: 3000,
animation: {
entry: { type: 'flyin', direction: 'right' },
exit: { type: 'fade' }
}
}
);
};
return <button onClick={showSuccess}>Show Toast</button>;
}API Reference
Modal API
useModal(): ConfigurableModalAPI
Hook for showing modals directly without registration, with optional default configuration.
Parameters:
defaultConfig(optional) - Default modal options applied to all modals from this hook
Returns: Configurable Modal API with show method
modal.show(component, params?, options?): Promise<TResult>
Shows a modal with the specified component.
Parameters:
component- React component to render as modal contentparams- Props to pass to the modal componentoptions- Modal configuration options (merged with defaults)
Modal Options:
interface ModalOptions {
blurBackground?: number; // Background blur in pixels
overlay?: boolean | ModalOverlayConfig; // Overlay configuration
preventScroll?: boolean; // Prevent body scroll
closeOnClickOutside?: boolean; // Close on outside click
closeOnEsc?: boolean; // Close on ESC key (default: true)
animation?: AnimationConfig; // Animation configuration
}Animation Types:
fade- Simple fade in/outfloat- Float up or down movementscale- Scale in/out effect
useModalInstance(): ModalHandle
Hook used within modal components to control their lifecycle.
Returns:
resolve(value?)- Close modal with success resultreject(reason?)- Close modal with error/cancellation
Toast API
useToast(defaultConfig?: ToastOptions): ConfigurableToastAPI
Hook for showing toast notifications with optional default configuration.
Parameters:
defaultConfig- Default options applied to all toasts from this hook
Toast Options:
interface ToastOptions {
position?: ToastPosition; // Toast position on screen
duration?: number; // Auto-dismiss duration (0 = no auto-dismiss)
closable?: boolean; // Show close button
queue?: boolean; // Queue multiple toasts
animation?: ToastAnimationOptions; // Animation configuration
}Toast Positions:
center,topcenter,topleft,toprightbottomcenter,bottomleft,bottomright
Animation Types:
flyin- Slide in from specified directionfade- Simple fade in/outscale- Scale in/out effect
Toast Component Props
All toast components receive these props:
interface ToastComponentProps {
onClose: () => void; // Function to close the toast
closable: boolean; // Whether the toast can be manually closed
}Advanced Usage
Modal Instance Isolation
Each useModal() call creates an isolated instance with its own default configuration:
function MyApp() {
// Each hook has its own configuration that doesn't interfere with others
const confirmModal = useModal({
animation: { type: 'scale', duration: 300 },
closeOnEsc: false
});
const infoModal = useModal({
animation: { type: 'fade', duration: 200 },
overlay: { opacity: 0.5 }
});
const alertModal = useModal(); // No defaults
// These all work independently with their own settings
const showConfirm = () => confirmModal.show(ConfirmModal, { message: 'Confirm?' });
const showInfo = () => infoModal.show(InfoModal, { message: 'Info' });
const showAlert = () => alertModal.show(AlertModal, { message: 'Alert!' });
return (
<div>
<button onClick={showConfirm}>Confirm</button>
<button onClick={showInfo}>Info</button>
<button onClick={showAlert}>Alert</button>
</div>
);
}Default Toast Configuration
Create a toast hook with default settings:
const topRightToast = useToast({
position: 'topright',
duration: 3000,
animation: { entry: { type: 'flyin', direction: 'right' } }
});
// All toasts will use these defaults unless overridden
topRightToast.show(SuccessToast, { message: 'Success!' });Complex Modal Animations
const result = await modal.show(ConfirmModal, params, {
animation: {
type: 'float',
direction: 'up',
duration: 400
},
overlay: {
color: '#000000',
opacity: 0.7
},
blurBackground: 5
});Toast Queue Management
// Queue multiple toasts
toast.show(InfoToast, { message: 'First' }, { queue: true });
toast.show(InfoToast, { message: 'Second' }, { queue: true });
// Replace existing toasts
toast.show(ErrorToast, { message: 'Important!' }, { queue: false });
// Close all toasts
toast.closeAll();Error Handling
The library provides error boundaries for robust error handling:
import { UIKit } from 'react-floatui';
// Wrap specific sections
<UIKit.ModalErrorBoundary>
<ComponentWithModals />
</UIKit.ModalErrorBoundary>
// Or use the general error boundary
<UIKit.ErrorBoundary>
<App />
</UIKit.ErrorBoundary>TypeScript Support
The library is written in TypeScript and provides full type support:
// Typed modal parameters and results
interface UserFormData {
name: string;
email: string;
}
const result = await modal.show<UserFormData>(
UserFormComponent,
{ userId: '123' }
);
// result is typed as UserFormDataDevelopment
# Install dependencies
npm install
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Build the library
npm run build
# Run example app
npm run dev
# Lint code
npm run lintLicense
MIT © Duong Nguyen (duongtdn)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
