Simplify JSDoc and comments in TypeScript and SCSS files

Removes verbose documentation and examples from:
- flasher.ts (main orchestration class)
- flasher-plugin.ts (default plugin implementation)
- types.ts (type definitions)
- flasher.scss (default theme styles)
- mixins.scss (reusable SASS mixins)

Keeps essential type annotations and parameter documentation.
This commit is contained in:
Younes ENNAJI
2026-01-16 00:27:42 +01:00
parent 9239063159
commit 613c73d7b6
5 changed files with 0 additions and 870 deletions
@@ -1,101 +1,28 @@
/**
* @file FlasherPlugin Implementation
* @description Default implementation for displaying notifications using custom themes
* @author Younes ENNAJI
*/
import './themes/index.scss'
import type { Properties } from 'csstype'
import type { Envelope, FlasherPluginOptions, Options, Theme } from './types'
import { AbstractPlugin } from './plugin'
/**
* Default FlasherPlugin implementation using custom themes.
*
* FlasherPlugin is the built-in renderer for PHPFlasher that creates DOM-based
* notifications with a customizable appearance. It uses themes to determine
* the HTML structure and styling of notifications.
*
* Features:
* - Theme-based notification rendering
* - Container management for different positions
* - Auto-dismissal with progress bars
* - RTL language support
* - HTML escaping for security
* - Mouse-over pause of auto-dismissal
*
* @example
* ```typescript
* // Create a simple theme
* const myTheme: Theme = {
* styles: ['my-theme.css'],
* render: (envelope) => `
* <div class="my-notification my-notification-${envelope.type}">
* <h4>${envelope.title}</h4>
* <p>${envelope.message}</p>
* <button class="fl-close">&times;</button>
* <div class="fl-progress-bar"></div>
* </div>
* `
* };
*
* // Create a plugin with the theme
* const plugin = new FlasherPlugin(myTheme);
*
* // Show a notification
* plugin.success('Operation completed');
* ```
*/
export default class FlasherPlugin extends AbstractPlugin {
/**
* Theme configuration used for rendering notifications.
* @private
*/
private theme: Theme
/**
* Default configuration options for notifications.
* These can be overridden globally or per notification.
* @private
*/
private options: FlasherPluginOptions = {
// Default or type-specific timeout (milliseconds, null = use type-specific)
// Use false for sticky notifications, or any negative number
timeout: null,
// Type-specific timeout durations
timeouts: {
success: 10000,
info: 10000,
error: 10000,
warning: 10000,
},
// Animation frames per second (higher = smoother but more CPU intensive)
fps: 30,
// Default position on screen
position: 'top-right',
// Stacking direction (top = newest first, bottom = newest last)
direction: 'top',
// Right-to-left text direction
rtl: false,
// Custom container styles
style: {} as Properties,
// Whether to escape HTML in message content (security feature)
escapeHtml: false,
}
/**
* Creates a new FlasherPlugin with a specific theme.
*
* @param theme - Theme configuration to use for rendering notifications
* @throws {Error} If theme is missing or invalid
*/
constructor(theme: Theme) {
super()
@@ -110,14 +37,6 @@ export default class FlasherPlugin extends AbstractPlugin {
this.theme = theme
}
/**
* Renders notification envelopes using the configured theme.
*
* This method creates and displays notifications in the DOM based on
* the provided envelopes and the plugin's theme.
*
* @param envelopes - Array of notification envelopes to render
*/
public renderEnvelopes(envelopes: Envelope[]): void {
if (!envelopes?.length) {
return
@@ -165,11 +84,6 @@ export default class FlasherPlugin extends AbstractPlugin {
}
}
/**
* Updates the plugin options.
*
* @param options - New options to apply
*/
public renderOptions(options: Options): void {
if (!options) {
return
@@ -177,16 +91,6 @@ export default class FlasherPlugin extends AbstractPlugin {
this.options = { ...this.options, ...options }
}
/**
* Creates or gets the container for notifications.
*
* This method ensures that each position has its own container for notifications.
* If a container for the specified position doesn't exist yet, it creates one.
*
* @param options - Options containing position and style information
* @returns The container element
* @private
*/
private createContainer(options: { position: string, style: Properties }): HTMLDivElement {
// Look for existing container for this position
let container = document.querySelector(`.fl-wrapper[data-position="${options.position}"]`) as HTMLDivElement
@@ -213,20 +117,6 @@ export default class FlasherPlugin extends AbstractPlugin {
return container
}
/**
* Adds a notification to the container.
*
* This method:
* 1. Creates a notification element using the theme's render function
* 2. Adds necessary classes and event listeners
* 3. Appends it to the container in the right position
* 4. Sets up auto-dismissal if a timeout is specified
*
* @param container - Container to add the notification to
* @param envelope - Notification information
* @param options - Display options
* @private
*/
private addToContainer(
container: HTMLDivElement,
envelope: Envelope,
@@ -291,13 +181,6 @@ export default class FlasherPlugin extends AbstractPlugin {
}
}
/**
* Normalizes timeout value to handle different formats (number, boolean, null)
*
* @param timeout - The timeout value to normalize
* @returns A number representing milliseconds, or 0 for sticky notifications
* @private
*/
private normalizeTimeout(timeout: any): number {
// Handle false or negative numbers as sticky notifications (0)
if (timeout === false || (typeof timeout === 'number' && timeout < 0)) {
@@ -313,16 +196,6 @@ export default class FlasherPlugin extends AbstractPlugin {
return Number(timeout) || 0
}
/**
* Adds a progress timer to the notification.
*
* This method creates a visual progress bar that shows the remaining time
* before auto-dismissal. The timer pauses when the user hovers over the notification.
*
* @param notification - Notification element
* @param options - Timer options
* @private
*/
private addTimer(notification: HTMLElement, { timeout, fps }: { timeout: number, fps: number }): void {
if (timeout <= 0) {
return
@@ -368,18 +241,6 @@ export default class FlasherPlugin extends AbstractPlugin {
notification.addEventListener('mouseover', () => clearInterval(intervalId))
}
/**
* Removes a notification with animation.
*
* This method:
* 1. Removes the 'show' class to trigger the hide animation
* 2. Waits for the animation to complete
* 3. Removes the notification from the DOM
* 4. Cleans up the container if it's now empty
*
* @param notification - Notification element to remove
* @private
*/
private removeNotification(notification: HTMLElement): void {
if (!notification) {
return
@@ -398,29 +259,12 @@ export default class FlasherPlugin extends AbstractPlugin {
}
}
/**
* Converts an HTML string to a DOM element.
*
* @param str - HTML string to convert
* @returns The created DOM element
* @private
*/
private stringToHTML(str: string): HTMLElement {
const template = document.createElement('template')
template.innerHTML = str.trim()
return template.content.firstElementChild as HTMLElement
}
/**
* Safely escapes HTML special characters.
*
* This method replaces special characters with their HTML entities
* to prevent XSS attacks when displaying user-provided content.
*
* @param str - String to escape
* @returns Escaped string
* @private
*/
private escapeHtml(str: string | null | undefined): string {
if (str == null) {
return ''
-285
View File
@@ -1,98 +1,13 @@
/**
* @file Flasher Core
* @description Main orchestration class for the PHPFlasher notification system
* @author Younes ENNAJI
*/
import type { Asset, Context, Envelope, Options, PluginInterface, Response, Theme } from './types'
import { AbstractPlugin } from './plugin'
import FlasherPlugin from './flasher-plugin'
/**
* Main Flasher class that manages plugins, themes, and notifications.
*
* Flasher is the central orchestration class for PHPFlasher. It handles:
* 1. Plugin registration and management
* 2. Theme registration and resolution
* 3. Asset loading (JS and CSS)
* 4. Routing notifications to the appropriate plugin
* 5. Response processing and normalization
*
* This class follows the façade pattern, providing a simple interface to the
* underlying plugin ecosystem.
*
* @example
* ```typescript
* // Create a flasher instance
* const flasher = new Flasher();
*
* // Register a plugin
* flasher.addPlugin('toastr', new ToastrPlugin());
*
* // Show a notification
* flasher.use('toastr').success('Operation completed successfully');
*
* // Process server response
* flasher.render(response);
* ```
*/
export default class Flasher extends AbstractPlugin {
/**
* Default plugin to use when none is specified.
* This plugin will be used when displaying notifications without
* explicitly specifying a plugin.
*
* @private
*/
private defaultPlugin = 'flasher'
/**
* Map of registered plugins.
* Stores plugin instances by name for easy lookup.
*
* @private
*/
private plugins: Map<string, PluginInterface> = new Map<string, PluginInterface>()
/**
* Map of registered themes.
* Stores theme configurations by name.
*
* @private
*/
private themes: Map<string, Theme> = new Map<string, Theme>()
/**
* Set of assets that have been loaded.
* Used to prevent duplicate loading of the same asset.
*
* @private
*/
private loadedAssets: Set<string> = new Set<string>()
/**
* Renders notifications from a response.
*
* This method processes a server response containing notifications and configuration.
* It handles asset loading, option application, and notification rendering in a
* coordinated sequence.
*
* @param response - The response containing notifications and configuration
* @returns A promise that resolves when all operations are complete
*
* @example
* ```typescript
* // From an AJAX response
* const response = await fetch('/api/notifications').then(r => r.json());
* await flasher.render(response);
*
* // With a partial response
* flasher.render({
* envelopes: [
* { message: 'Hello world', type: 'info', title: 'Greeting', options: {}, metadata: {} }
* ]
* });
* ```
*/
public async render(response: Partial<Response>): Promise<void> {
const resolved = this.resolveResponse(response)
@@ -119,34 +34,6 @@ export default class Flasher extends AbstractPlugin {
}
}
/**
* Renders multiple notification envelopes.
*
* This method groups envelopes by plugin and delegates rendering to each plugin.
* This ensures that each notification is processed by the appropriate plugin.
*
* @param envelopes - Array of notification envelopes to render
*
* @example
* ```typescript
* flasher.renderEnvelopes([
* {
* message: 'Operation completed',
* type: 'success',
* title: 'Success',
* options: {},
* metadata: { plugin: 'toastr' }
* },
* {
* message: 'An error occurred',
* type: 'error',
* title: 'Error',
* options: {},
* metadata: { plugin: 'sweetalert' }
* }
* ]);
* ```
*/
public renderEnvelopes(envelopes: Envelope[]): void {
if (!envelopes?.length) {
return
@@ -171,22 +58,6 @@ export default class Flasher extends AbstractPlugin {
})
}
/**
* Applies options to each plugin.
*
* This method distributes options to the appropriate plugins based on the keys
* in the options object. Each plugin receives only its specific options.
*
* @param options - Object mapping plugin names to their specific options
*
* @example
* ```typescript
* flasher.renderOptions({
* toastr: { timeOut: 3000, closeButton: true },
* sweetalert: { confirmButtonColor: '#3085d6' }
* });
* ```
*/
public renderOptions(options: Options): void {
if (!options) {
return
@@ -202,26 +73,6 @@ export default class Flasher extends AbstractPlugin {
})
}
/**
* Registers a new plugin.
*
* Plugins are the notification renderers that actually display notifications.
* Each plugin typically integrates with a specific notification library like
* Toastr, SweetAlert, etc.
*
* @param name - Unique identifier for the plugin
* @param plugin - Plugin instance that implements the PluginInterface
* @throws {Error} If name or plugin is invalid
*
* @example
* ```typescript
* // Register a custom plugin
* flasher.addPlugin('myplugin', new MyCustomPlugin());
*
* // Use the registered plugin
* flasher.use('myplugin').info('Hello world');
* ```
*/
public addPlugin(name: string, plugin: PluginInterface): void {
if (!name || !plugin) {
throw new Error('Both plugin name and instance are required')
@@ -229,33 +80,6 @@ export default class Flasher extends AbstractPlugin {
this.plugins.set(name, plugin)
}
/**
* Registers a new theme.
*
* Themes define the visual appearance of notifications when using
* the default FlasherPlugin. They provide HTML templates and CSS styles.
*
* @param name - Unique identifier for the theme
* @param theme - Theme configuration object
* @throws {Error} If name or theme is invalid
*
* @example
* ```typescript
* // Register a bootstrap theme
* flasher.addTheme('bootstrap', {
* styles: ['bootstrap.min.css'],
* render: (envelope) => `
* <div class="alert alert-${envelope.type}">
* <h4>${envelope.title}</h4>
* <p>${envelope.message}</p>
* </div>
* `
* });
*
* // Use the theme
* flasher.use('theme.bootstrap').success('Hello world');
* ```
*/
public addTheme(name: string, theme: Theme): void {
if (!name || !theme) {
throw new Error('Both theme name and definition are required')
@@ -263,27 +87,6 @@ export default class Flasher extends AbstractPlugin {
this.themes.set(name, theme)
}
/**
* Gets a plugin by name.
*
* This method resolves plugin aliases and creates theme-based plugins
* on demand. If a theme-based plugin is requested but doesn't exist yet,
* it will be created automatically.
*
* @param name - Name of the plugin to retrieve
* @returns The requested plugin instance
* @throws {Error} If the plugin cannot be resolved
*
* @example
* ```typescript
* // Get and use a plugin
* const toastr = flasher.use('toastr');
* toastr.success('Operation completed');
*
* // Use a theme as a plugin (automatically creates a FlasherPlugin)
* flasher.use('theme.bootstrap').error('Something went wrong');
* ```
*/
public use(name: string): PluginInterface {
const resolvedName = this.resolvePluginAlias(name)
this.resolvePlugin(resolvedName)
@@ -296,29 +99,10 @@ export default class Flasher extends AbstractPlugin {
return plugin
}
/**
* Alias for use().
*
* @param name - Name of the plugin to retrieve
* @returns The requested plugin instance
*/
public create(name: string): PluginInterface {
return this.use(name)
}
/**
* Resolves and normalizes a response object.
*
* This method:
* 1. Fills in default values for missing properties
* 2. Resolves plugin aliases for envelopes
* 3. Converts string functions to actual functions
* 4. Adds theme styles to the response
*
* @param response - Partial response object
* @returns Fully resolved response object
* @private
*/
private resolveResponse(response: Partial<Response>): Response {
const resolved = {
envelopes: [],
@@ -350,16 +134,6 @@ export default class Flasher extends AbstractPlugin {
return resolved
}
/**
* Resolves string functions to actual function objects.
*
* This allows options to include functions serialized as strings,
* which is useful for passing functions from the server to the client.
*
* @param options - Options object that may contain string functions
* @returns Options object with string functions converted to actual functions
* @private
*/
private resolveOptions(options: Options): Options {
if (!options) {
return {}
@@ -374,18 +148,6 @@ export default class Flasher extends AbstractPlugin {
return resolved
}
/**
* Converts a string function representation to an actual function.
*
* Supports both traditional and arrow function syntax:
* - `function(a, b) { return a + b; }`
* - `(a, b) => a + b`
* - `a => a * 2`
*
* @param func - Value to check and potentially convert
* @returns Function if conversion was successful, otherwise the original value
* @private
*/
private resolveFunction(func: unknown): unknown {
if (typeof func !== 'string') {
return func
@@ -416,15 +178,6 @@ export default class Flasher extends AbstractPlugin {
}
}
/**
* Creates theme-based plugins on demand.
*
* This method automatically creates a FlasherPlugin instance for a theme
* when a theme-based plugin is requested but doesn't exist yet.
*
* @param alias - Plugin alias to resolve
* @private
*/
private resolvePlugin(alias: string): void {
const factory = this.plugins.get(alias)
if (factory || !alias.includes('theme.')) {
@@ -441,15 +194,6 @@ export default class Flasher extends AbstractPlugin {
this.addPlugin(alias, new FlasherPlugin(theme))
}
/**
* Resolves a plugin name to its actual implementation name.
*
* This method handles the default plugin and theme aliases.
*
* @param alias - Plugin alias to resolve
* @returns Resolved plugin name
* @private
*/
private resolvePluginAlias(alias?: string): string {
alias = alias || this.defaultPlugin
@@ -457,16 +201,6 @@ export default class Flasher extends AbstractPlugin {
return alias === 'flasher' ? 'theme.flasher' : alias
}
/**
* Adds CSS and JavaScript assets to the page.
*
* This method efficiently loads assets, respecting the order for scripts
* which is crucial for libraries with dependencies like jQuery plugins.
*
* @param assets - Array of assets to load
* @returns Promise that resolves when all assets are loaded
* @private
*/
private async addAssets(assets: Asset[]): Promise<void> {
try {
// Process CSS files in parallel (order doesn't matter for CSS)
@@ -513,15 +247,6 @@ export default class Flasher extends AbstractPlugin {
}
}
/**
* Loads a single asset (CSS or JavaScript) into the document.
*
* @param url - URL of the asset to load
* @param nonce - CSP nonce for the asset
* @param type - Type of asset ('style' or 'script')
* @returns Promise that resolves when the asset is loaded
* @private
*/
private loadAsset(url: string, nonce: string, type: 'style' | 'script'): Promise<void> {
// Check if asset is already loaded
if (document.querySelector(`${type === 'style' ? 'link' : 'script'}[src="${url}"]`)) {
@@ -553,16 +278,6 @@ export default class Flasher extends AbstractPlugin {
})
}
/**
* Adds theme styles to the list of assets to load.
*
* This method extracts style URLs from theme definitions and adds them
* to the response styles array.
*
* @param response - Response object to modify
* @param plugin - Plugin name that may reference a theme
* @private
*/
private addThemeStyles(response: Response, plugin: string): void {
// Only process theme plugins
if (plugin !== 'flasher' && !plugin.includes('theme.')) {
@@ -1,16 +1,6 @@
/**
* @file PHPFlasher Default Theme
* @description Classic bordered notification style with colorful accents
* @author Younes ENNAJI
*/
@use "sass:color";
@use '../mixins' as *;
/**
* Animation for flasher theme
* Slides in from the left with a fade effect
*/
@keyframes flasherIn {
from {
opacity: 0;
@@ -22,7 +12,6 @@
}
}
/* RTL animation */
@keyframes flasherInRtl {
from {
opacity: 0;
@@ -34,10 +23,6 @@
}
}
/**
* Base theme styling
* The default PHPFlasher notification appearance
*/
.fl-flasher {
/* Base appearance */
line-height: 1.5;
@@ -1,24 +1,5 @@
/**
* @file PHPFlasher SASS Mixins
* @description Reusable styling patterns for notification themes
* @author Younes ENNAJI
*/
@use "sass:color";
/**
* @mixin variants
*
* Apply styles to each notification type (success, info, warning, error).
* Passes the type name to the content block for use in selectors.
*
* @example
* ```scss
* @include variants using($type) {
* background-color: var(--#{\$type}-color);
* }
* ```
*/
@mixin variants {
@each $type in success, info, warning, error {
&.fl-#{$type} {
@@ -27,19 +8,6 @@
}
}
/**
* @mixin close-button
*
* Standard close button styling used across themes.
* Creates a close button with hover effects and positioning.
*
* @example
* ```scss
* .my-notification {
* @include close-button;
* }
* ```
*/
@mixin close-button {
.fl-close {
position: absolute;
@@ -63,19 +31,6 @@
}
}
/**
* @mixin rtl-support
*
* Add support for right-to-left languages.
* Adjusts layout, alignment, and button positioning for RTL display.
*
* @example
* ```scss
* .my-notification {
* @include rtl-support;
* }
* ```
*/
@mixin rtl-support {
&.fl-rtl {
.fl-content {
@@ -89,21 +44,6 @@
}
}
/**
* @mixin progress-bar
*
* Add a progress bar with type-specific colors.
* Shows remaining time before notification is automatically closed.
*
* @param {Length} $height - Height of the progress bar (default: 0.125em)
*
* @example
* ```scss
* .my-notification {
* @include progress-bar(0.2em);
* }
* ```
*/
@mixin progress-bar($height: 0.125em) {
.fl-progress-bar {
display: flex;
@@ -128,22 +68,6 @@
}
}
/**
* @mixin dark-mode
*
* Add dark mode styling support.
* Applies styles when dark mode is active (either via media query or class).
*
* @example
* ```scss
* .my-notification {
* @include dark-mode {
* background-color: #222;
* color: white;
* }
* }
* ```
*/
@mixin dark-mode {
@media (prefers-color-scheme: dark) {
&.fl-auto-dark {
-338
View File
@@ -1,397 +1,59 @@
/**
* @file PHPFlasher Type Definitions
* @description Core types and interfaces for the PHPFlasher notification system.
* @author Younes ENNAJI
*/
import type { Properties } from 'csstype'
/**
* Generic options object used throughout the application.
*
* This type represents a collection of key-value pairs that can be passed
* to customize the behavior of notifications.
*
* @example
* ```typescript
* const options: Options = {
* timeout: 5000,
* position: 'top-right',
* closeOnClick: true
* };
* ```
*/
export type Options = Record<string, unknown>
/**
* Context data that can be passed to notifications.
*
* Context provides additional data that can be utilized by notification
* templates or handling logic.
*
* @example
* ```typescript
* const context: Context = {
* userId: 123,
* requestId: 'abc-123',
* csrfToken: 'xyz'
* };
* ```
*/
export type Context = Record<string, unknown>
/**
* Represents a notification message to be displayed.
*
* An envelope encapsulates all the information needed to render a notification,
* including its content, type, styling options, and metadata.
*
* @example
* ```typescript
* const envelope: Envelope = {
* message: 'Operation completed successfully',
* title: 'Success',
* type: 'success',
* options: { timeout: 5000 },
* metadata: { plugin: 'toastr' }
* };
* ```
*/
export type Envelope = {
/** The main content of the notification */
message: string
/**
* Optional title for the notification.
* If not provided, defaults to the capitalized notification type.
*/
title: string
/**
* Notification type that determines its appearance and behavior.
* Common types include: success, error, info, warning
*/
type: string
/**
* Additional configuration options specific to this notification.
* These will override global and plugin-specific defaults.
*/
options: Options
/**
* Metadata about the notification, including which plugin should handle it.
* The plugin field determines which renderer will process this notification.
*/
metadata: {
plugin: string
[key: string]: unknown
}
/**
* Optional context data accessible during notification rendering.
* This can contain request-specific information or user data.
*/
context?: Context
}
/**
* Response from the server containing notifications and configuration.
*
* This structure is typically returned from backend endpoints and contains
* all the information needed to render notifications, including assets to load.
*
* @example
* ```typescript
* const response: Response = {
* envelopes: [{ message: 'Success', title: 'Done', type: 'success', options: {}, metadata: { plugin: 'toastr' } }],
* options: { toastr: { closeButton: true } },
* scripts: ['/assets/toastr.min.js'],
* styles: ['/assets/toastr.min.css'],
* context: { csp_nonce: 'random123' }
* };
* ```
*/
export type Response = {
/** Array of notification envelopes to be displayed */
envelopes: Envelope[]
/**
* Plugin-specific options that should be applied globally.
* Organized by plugin name for selective application.
*/
options: Record<string, Options>
/** JavaScript files that should be loaded */
scripts: string[]
/** CSS files that should be loaded */
styles: string[]
/** Global context data shared across all notifications */
context: Context
}
/**
* Core interface that all notification plugins must implement.
*
* This interface defines the contract for any notification library integration.
* Each plugin represents a different notification library (Toastr, SweetAlert, etc.)
* but exposes the same consistent API.
*
* @example
* ```typescript
* class MyCustomPlugin implements PluginInterface {
* // Implementation of required methods
* }
*
* // Usage
* const plugin = new MyCustomPlugin();
* plugin.success('Operation completed');
* ```
*/
export interface PluginInterface {
/**
* Display a success notification.
*
* @param message - Notification content or options object
* @param title - Optional title or options object
* @param options - Optional configuration options
*
* @example
* ```typescript
* // Simple usage
* plugin.success('Data saved successfully');
*
* // With title
* plugin.success('Changes applied', 'Success');
*
* // With options
* plugin.success('Profile updated', 'Success', { timeOut: 3000 });
*
* // Using object syntax
* plugin.success({
* message: 'Operation completed',
* title: 'Success',
* timeout: 5000
* });
* ```
*/
success: (message: string | Options, title?: string | Options, options?: Options) => void
/**
* Display an error notification.
*
* @param message - Notification content or options object
* @param title - Optional title or options object
* @param options - Optional configuration options
*
* @example
* ```typescript
* // Simple usage
* plugin.error('An error occurred while processing your request');
*
* // With title
* plugin.error('Could not connect to server', 'Connection Error');
*
* // With options
* plugin.error('Invalid form data', 'Validation Error', { timeOut: 0 });
* ```
*/
error: (message: string | Options, title?: string | Options, options?: Options) => void
/**
* Display an information notification.
*
* @param message - Notification content or options object
* @param title - Optional title or options object
* @param options - Optional configuration options
*
* @example
* ```typescript
* // Simple usage
* plugin.info('Your session will expire in 5 minutes');
*
* // With title and options
* plugin.info('New updates are available', 'Information', {
* closeButton: true,
* timeOut: 10000
* });
* ```
*/
info: (message: string | Options, title?: string | Options, options?: Options) => void
/**
* Display a warning notification.
*
* @param message - Notification content or options object
* @param title - Optional title or options object
* @param options - Optional configuration options
*
* @example
* ```typescript
* // Simple usage
* plugin.warning('You have unsaved changes');
*
* // With title
* plugin.warning('Your subscription will expire soon', 'Warning');
* ```
*/
warning: (message: string | Options, title?: string | Options, options?: Options) => void
/**
* Display any type of notification.
*
* This is a generic method that allows displaying notifications of any type,
* including custom types beyond the standard success/error/info/warning.
*
* @param type - Notification type or options object
* @param message - Notification content or options object
* @param title - Optional title or options object
* @param options - Optional configuration options
*
* @example
* ```typescript
* // Custom notification type
* plugin.flash('question', 'Do you want to continue?', 'Confirmation');
*
* // Using object syntax
* plugin.flash({
* type: 'custom',
* message: 'Something happened',
* title: 'Notice',
* icon: 'bell'
* });
* ```
*/
flash: (type: string | Options, message: string | Options, title?: string | Options, options?: Options) => void
/**
* Render multiple notification envelopes.
*
* This is typically used internally to process batches of notifications
* received from the server.
*
* @param envelopes - Array of notification envelopes to render
*/
renderEnvelopes: (envelopes: Envelope[]) => void
/**
* Apply plugin-specific options.
*
* This method configures the underlying notification library
* with the provided options.
*
* @param options - Configuration options for the plugin
*/
renderOptions: (options: Options) => void
}
/**
* Theme configuration for rendering notifications.
*
* A theme defines how notifications are visually presented to users,
* including HTML structure, styling, and asset dependencies.
*
* @example
* ```typescript
* const bootstrapTheme: Theme = {
* styles: ['bootstrap-notifications.css'],
* render: (envelope) => `
* <div class="alert alert-${envelope.type}">
* <strong>${envelope.title}</strong>
* <p>${envelope.message}</p>
* </div>
* `
* };
* ```
*/
export type Theme = {
/**
* CSS styles to apply (string URL or array of URLs).
* These will be automatically loaded when the theme is used.
*/
styles?: string | string[]
/**
* Render function that converts an envelope to HTML string.
* This function is responsible for generating the HTML structure
* of the notification.
*
* @param envelope - The notification envelope to render
* @returns HTML string representation of the notification
*/
render: (envelope: Envelope) => string
}
/**
* Asset types that can be loaded dynamically.
* Used to distinguish between scripts and stylesheets.
*/
export type AssetType = 'style' | 'script'
/**
* Configuration for an asset to be loaded.
* Contains all information needed to load external resources.
*/
export type Asset = {
/** URLs to load */
urls: string[]
/** Content Security Policy nonce (if required) */
nonce: string
/** Type of asset (style or script) */
type: AssetType
}
/**
* FlasherPlugin specific options.
*
* These options control the behavior and appearance of notifications
* rendered by the default FlasherPlugin.
*
* @example
* ```typescript
* const options: FlasherPluginOptions = {
* position: 'bottom-left',
* timeout: 8000,
* rtl: true,
* fps: 60
* };
* ```
*/
export type FlasherPluginOptions = {
/**
* Default timeout in milliseconds (0 for no timeout).
* Set to null to use type-specific timeouts.
*/
timeout: number | boolean | null
/** Type-specific timeouts in milliseconds */
timeouts: Record<string, number>
/** Animation frames per second for the progress bar */
fps: number
/**
* Notification position on screen.
* Common values: 'top-right', 'top-left', 'bottom-right', 'bottom-left', 'center'
*/
position: string
/**
* Stacking direction of notifications.
* 'top' means newer notifications appear above older ones.
* 'bottom' means newer notifications appear below older ones.
*/
direction: 'top' | 'bottom'
/** Right-to-left text direction for RTL languages */
rtl: boolean
/** Custom CSS styles applied to the notification container */
style: Properties
/** Whether to escape HTML in messages for security */
escapeHtml: boolean
}