Feedback Toast Component Documentation

 Toast Component
   A component for creating toast notifications with Bootstrap 5.
   
   Parameters:
   - title: string - Toast title
   - content: string - Toast content
   - subtitle: string - Optional subtitle/time (optional)
   - variant: string - Toast variant for background (primary, success, etc.) (optional)
   - icon: string - Optional icon (optional)
   - autohide: boolean - Whether to automatically hide the toast (optional)
   - delay: int - Delay before autohiding (in milliseconds) (optional)
   - position: string - Toast position (top-right, top-left, bottom-right, bottom-left) (optional)
   - class: string - Additional CSS classes (optional)
   - attributes: array - Additional HTML attributes (optional)
   - show: boolean - Whether to show the toast immediately (optional)
   

All available options for the Toast component

All available options for the Toast component


    ThemedComponent::make("feedback/toast")
	->content('value') //string - Toast content (always set this first)
	->addAttribute('value') //Add an attribute to the element. This is a string like 'data-foo="bar"' or multiple attributes in a single string like 'data-foo="bar" data-bar="baz"' (optional)
	->addCss('value') //string - Add css styles to the element. This should be '<style> custom-class {...} </style>' (optional)
	->addJavaScript('value') //string - Add a script to the element. This is a string like '<script>console.log('Hello World!')</script>' (optional)
	->autohide('value') //boolean - Whether to automatically hide the toast (optional)
	->canSee('value') //bool - Whether the component should be visible or not (optional)
	->class('value') //string - Additional CSS classes (optional)
	->delay('value') //int - Delay before autohiding (in milliseconds) (optional)
	->icon('value') //string - Optional icon (optional)
	->id('value') //string - The id of the element. If no id is supplied, a random one will be generated (optional)
	->position('value') //string - Toast position (top-right, top-left, bottom-right, bottom-left) (optional)
	->show('value') //boolean - Whether to show the toast immediately (optional)
	->subtitle('value') //string - Optional subtitle/time (optional)
	->title('value') //string - Toast title
	->variant('value') //string - Toast variant for background (primary, success, etc.) (optional)
	->render();

Basic Toasts

Examples of basic toast notifications.

$variants = ['primary', 'secondary', 'success', 'danger', 'warning', 'info'];
foreach ($variants as $variant) {
    $basicToastsContent .= ThemedComponent::make($component)
        ->content('This is a ' . $variant . ' toast message.')
        ->title(ucfirst($variant) . ' Toast')
        ->subtitle('just now')
        ->variant($variant)
        ->autohide(false)
        ->render();
}

Toast Positions

Toasts in different screen positions.

$positions = [
    'top-right' => 'Top Right',
    'top-left' => 'Top Left',
    'bottom-right' => 'Bottom Right',
    'bottom-left' => 'Bottom Left'
];
foreach ($positions as $position => $label) {
    $toastPositionsContent .= ThemedComponent::make('feedback/toast')
        ->content('This toast appears in the ' . strtolower($label) . ' position.')
        ->title($label . ' Toast')
        ->subtitle('2 seconds ago')
        ->position($position)
        ->variant('primary')
        ->autohide(false)
        ->render();
}

Toasts with Icons

Toast notifications with icons.

$iconToasts = [
    [
        'title' => 'Success',
        'content' => 'Operation completed successfully.',
        'icon' => 'check-circle',
        'variant' => 'success'
    ],
    [
        'title' => 'Warning',
        'content' => 'Please review your input.',
        'icon' => 'exclamation-triangle',
        'variant' => 'warning'
    ],
    [
        'title' => 'Error',
        'content' => 'An error occurred during processing.',
        'icon' => 'x-circle',
        'variant' => 'danger'
    ]
];
foreach ($iconToasts as $toast) {
    $toastWithIconsContent .= ThemedComponent::make('feedback/toast')
        ->content($toast['content'])
        ->title($toast['title'])
        ->subtitle('just now')
        ->variant($toast['variant'])
        ->autohide(false)
        ->icon(
            ThemedComponent::make('icons/icon')
                ->name($toast['icon'])
                ->preset_color($toast['variant'])
                ->size("24px")
                ->render()
        )
        ->render();
}

Auto-hide Toasts

Toasts that automatically hide after a delay.

$delays = [3000, 5000, 8000, 15000];
foreach ($delays as $delay) {
    $autohideToastsContent .= ThemedComponent::make('feedback/toast')
        ->content('This toast will hide after ' . ($delay/1000) . ' seconds.')
        ->title('Auto-hide Toast')
        ->subtitle('just now')
        ->variant('info')
        ->autohide(true)
        ->delay($delay)
        ->render();
}

Rich Content Toasts

Toasts with rich HTML content.

// Toast with Action Buttons
$richContentToastsContent .= ThemedComponent::make('feedback/toast')
    ->content('
        <p>A new software update is available.</p>
        <div class="mt-2 pt-2 border-top">
            <button type="button" class="btn btn-primary btn-sm">Update now</button>
            <button type="button" class="btn btn-secondary btn-sm">Later</button>
        </div>
    ')
    ->title('Update Available')
    ->subtitle('just now')
    ->variant('primary')
    ->html(true)
    ->icon(
        ThemedComponent::make('icons/icon')
            ->name('info-circle')
            ->preset_color('primary')
            ->size("24px")
            ->render()
    )
    ->autohide(false)
    ->render();
        
// Toast with List
$richContentToastsContent .= ThemedComponent::make('feedback/toast')
    ->content('
        <ul class="list-unstyled mb-0">
            <li class="mb-1">
                <strong>John Doe</strong>
                <br>
                <small class="text-muted">Hey, are you available for a meeting?</small>
            </li>
            <li>
                <strong>Jane Smith</strong>
                <br>
                <small class="text-muted">The project files have been updated.</small>
            </li>
        </ul>
    ')
    ->title('New Messages')
    ->subtitle('just now')
    ->variant('info')
    ->html(true)
    ->icon(
        ThemedComponent::make('icons/icon')
            ->name('envelope')
            ->preset_color('info')
            ->size("24px")
            ->render()
    )
    ->autohide(false)
    ->render();

Toast component template

The Twig template file for the Toast component

Content of the toast.css file
section {
    border-bottom: 1px solid #dee2e6;
    padding-bottom: 2rem;
}

section:last-child {
    border-bottom: none;
}
Content of the toast.twig file
{# Toast Component
   A component for creating toast notifications with Bootstrap 5.
   
   Parameters:
   - title: string - Toast title
   - content: string - Toast content
   - subtitle: string - Optional subtitle/time (optional)
   - variant: string - Toast variant for background (primary, success, etc.) (optional)
   - icon: string - Optional icon (optional)
   - autohide: boolean - Whether to automatically hide the toast (optional)
   - delay: int - Delay before autohiding (in milliseconds) (optional)
   - position: string - Toast position (top-right, top-left, bottom-right, bottom-left) (optional)
   - class: string - Additional CSS classes (optional)
   - attributes: array - Additional HTML attributes (optional)
   - show: boolean - Whether to show the toast immediately (optional)
   
#}

{# Set default values #}
{% set autohide = content.autohide ?? true %}
{% set delay = content.delay|default(5000) %}
{% set show = content.show ?? true %}

{# Build toast classes #}
{% set toast_classes = ['toast'] %}

{% if content.variant %}
    {% set toast_classes = toast_classes|merge(['text-bg-' ~ content.variant]) %}
{% endif %}

{% if content.class %}
    {% set toast_classes = toast_classes|merge([content.class]) %}
{% endif %}

{# Generate unique ID #}
{% set toast_id = content.id|default('toast-' ~ random(100000)) %}

{# Build container classes for positioning #}
{% set container_classes = ['toast-container', 'position-fixed', 'p-3'] %}

{% if content.position == 'top-right' %}
    {% set container_classes = container_classes|merge(['top-0', 'end-0']) %}
{% elseif content.position == 'top-left' %}
    {% set container_classes = container_classes|merge(['top-0', 'start-0']) %}
{% elseif content.position == 'bottom-right' %}
    {% set container_classes = container_classes|merge(['bottom-0', 'end-0']) %}
{% elseif content.position == 'bottom-left' %}
    {% set container_classes = container_classes|merge(['bottom-0', 'start-0']) %}
{% else %}
    {% set container_classes = container_classes|merge(['top-0', 'end-0']) %}
{% endif %}

{# Render toast #}
{% if content.position %}
<div class="{{ container_classes|join(' ') }}">
{% endif %}

<div 
    id="{{ toast_id }}"
    class="{{ toast_classes|join(' ') }}"
    role="alert" 
    aria-live="assertive" 
    aria-atomic="true"
    data-bs-autohide="{{ autohide ? 'true' : 'false' }}"
    data-bs-delay="{{ delay }}"
    {% if content.attributes %}
        {% for attr, value in content.attributes %}
            {{ attr }}="{{ value }}"
        {% endfor %}
    {% endif %}
>
    <div class="toast-header">
        {% if content.icon %}
            {{ content.icon|raw }}&nbsp;
        {% endif %}
        <strong class="me-auto">{{ content.title }}</strong>
        {% if content.subtitle %}
            <small>{{ content.subtitle }}</small>
        {% endif %}
        <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
    </div>
    <div class="toast-body">
        {{ content.content|raw }}
    </div>
</div>

{% if content.position %}
</div>
{% endif %}

{# Initialize toast #}
<script>
document.addEventListener('DOMContentLoaded', function() {
    var toastElement = document.getElementById('{{ toast_id }}');
    if (toastElement) {
        var toast = new bootstrap.Toast(toastElement);
        {% if show %}
            toast.show();
        {% endif %}
    }
});
</script>