Skip to content

Allow use of default SVG Icons (e.g. BootStrap Icons) #31

Open

Description

@slimninja

Allow the option of switching from img to svg icons, maybe define defaults using bootstrap-icons?

        let classes = {
            header: {
                fg: '',
                bg: '',
                icon: ''
            },
            subtitle: 'text-white',
            dismiss: 'text-white'
        };
        switch (type) {
            case 'info':
                classes.header.bg = $.toastDefaults.style.info || 'bg-info';
                classes.header.fg = $.toastDefaults.style.info || 'text-white';
                classes.header.icon = `<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-exclamation-circle-fill mr-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                                          <path fill-rule="evenodd" d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"/>
                                       </svg>`;
                break;
        html += `<div class="toast-header ${classes.header.bg} ${classes.header.fg}">`;

        html += classes.header.icon;
        
        html += `<strong class="mr-auto">${title}</strong>`;

image

Activity

  1. slimninja commented on Nov 25, 2020

    @slimninja
    Author

    Made some very quick edits to work for me, hopefully a little helpful. Added the ability to use opt.img, opt.svg or default svg defined

    toast.js

    /**
     * @author Script47 (https://github.com/Script47/Toast)
     * @description Toast - A Bootstrap 4.2+ jQuery plugin for the toast component
     * @version 1.1.0
     **/
    (function ($) {
        const TOAST_CONTAINER_HTML = `<div id="toast-container" class="toast-container" aria-live="polite" aria-atomic="true"></div>`;
    
        $.toastDefaults = {
            position: 'bottom-right',
            dismissible: true,
            stackable: true,
            pauseDelayOnHover: true,
            style: {
                toast: '',
                info: '',
                success: '',
                warning: '',
                error: '',
            }
        };
    
        $('body').on('hidden.bs.toast', '.toast', function () {
            $(this).remove();
        });
    
        let toastRunningCount = 1;
    
        function render(opts) {
            /** No container, create our own **/
            if (!$('#toast-container').length) {
                const position = ['top-right', 'top-left', 'top-center', 'bottom-right', 'bottom-left', 'bottom-center'].includes($.toastDefaults.position) ? $.toastDefaults.position : 'top-right';
    
                $('body').prepend(TOAST_CONTAINER_HTML);
                $('#toast-container').addClass(position);
            }
    
            let toastContainer = $('#toast-container');
            let html = '';
            let classes = {
                header: {
                    fg: '',
                    bg: '',
                    icon: ''
                },
                subtitle: 'text-white',
                dismiss: 'text-white'
            };
            let id = `toast-${toastRunningCount}`;
            let type = opts.type;
            let title = opts.title;
            let subtitle = opts.subtitle;
            let content = opts.content;
            let img = opts.img;
            let svg = opts.svg;
            let delayOrAutohide = opts.delay ? `data-delay="${opts.delay}"` : `data-autohide="false"`;
            let hideAfter = ``;
            let dismissible = $.toastDefaults.dismissible;
            let globalToastStyles = $.toastDefaults.style.toast;
            let paused = false;
    
            if (typeof opts.dismissible !== 'undefined') {
                dismissible = opts.dismissible;
            }
    
            switch (type) {
                case 'info':
                    classes.header.bg = $.toastDefaults.style.info || 'bg-info';
                    classes.header.fg = $.toastDefaults.style.info || 'text-white';
                    classes.header.icon = `<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-info-circle-fill mr-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                                               <path fill-rule="evenodd" d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM8 5.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
                                           </svg>`;
                    break;
    
                case 'success':
                    classes.header.bg = $.toastDefaults.style.success || 'bg-success';
                    classes.header.fg = $.toastDefaults.style.info || 'text-white';
                    classes.header.icon = `<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-check-circle-fill mr-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                                               <path fill-rule="evenodd" d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
                                           </svg>`;
                    break;
    
                case 'warning':
                    classes.header.bg = $.toastDefaults.style.warning || 'bg-warning';
                    classes.header.fg = $.toastDefaults.style.warning || 'text-white';
                    classes.header.icon = `<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-exclamation-circle-fill mr-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                                              <path fill-rule="evenodd" d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"/>
                                          </svg>`;
                    break;
    
                case 'error':
                    classes.header.bg = $.toastDefaults.style.error || 'bg-danger';
                    classes.header.fg = $.toastDefaults.style.error || 'text-white';
                    classes.header.icon = `<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-exclamation-circle-fill mr-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                                              <path fill-rule="evenodd" d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"/>
                                           </svg>`;
                    break;
            }
    
            if ($.toastDefaults.pauseDelayOnHover && opts.delay) {
                delayOrAutohide = `data-autohide="false"`;
                hideAfter = `data-hide-after="${Math.floor(Date.now() / 1000) + (opts.delay / 1000)}"`;
            }
    
            html = `<div id="${id}" class="toast ${globalToastStyles}" role="alert" aria-live="assertive" aria-atomic="true" ${delayOrAutohide} ${hideAfter}>`;
            html += `<div class="toast-header ${classes.header.bg} ${classes.header.fg}">`;
            
            if (img) {
                html += `<img src="${img.src}" class="mr-2 ${img.class || ''}" alt="${img.alt || 'Image'}">`;
            } else if (svg) {
                html += svg
            } else {
                html += classes.header.icon;
            }
    
            html += `<strong class="mr-auto">${title}</strong>`;
    
            if (subtitle) {
                html += `<small class="${classes.subtitle}">${subtitle}</small>`;
            }
    
            if (dismissible) {
                html += `<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
                            <span aria-hidden="true" class="${classes.dismiss}">&times;</span>
                        </button>`;
            }
    
            html += `</div>`;
    
            if (content) {
                html += `<div class="toast-body">
                            ${content}
                        </div>`;
            }
    
            html += `</div>`;
    
            if (!$.toastDefaults.stackable) {
                toastContainer.find('.toast').each(function () {
                    $(this).remove();
                });
    
                toastContainer.append(html);
                toastContainer.find('.toast:last').toast('show');
            } else {
                toastContainer.append(html);
                toastContainer.find('.toast:last').toast('show');
            }
    
            if ($.toastDefaults.pauseDelayOnHover) {
                setTimeout(function () {
                    if (!paused) {
                        $(`#${id}`).toast('hide');
                    }
                }, opts.delay);
    
                $('body').on('mouseover', `#${id}`, function () {
                    paused = true;
                });
    
                $(document).on('mouseleave', '#' + id, function () {
                    const current = Math.floor(Date.now() / 1000),
                        future = parseInt($(this).data('hideAfter'));
    
                    paused = false;
    
                    if (current >= future) {
                        $(this).toast('hide');
                    }
                });
            }
    
            toastRunningCount++;
        }
    
        /**
         * Show a snack
         * @param type
         * @param title
         * @param delay
         */
        $.snack = function (type, title, delay) {
            return render({
                type,
                title,
                delay
            });
        }
    
        /**
         * Show a toast
         * @param opts
         */
        $.toast = function (opts) {
            return render(opts);
        }
    }(jQuery));
    
    

    and then I updated the toast.css to be a bit more friendly on notify:

    /**
     * @author Script47 (https://github.com/Script47/Toast)
     * @description Toast - A Bootstrap 4.2+ jQuery plugin for the toast component
     * @version 1.1.0
     **/
    
    .toast-container {
        position: fixed;
        z-index: 1055;
        margin: 1em;
    }
    
    .toast-container.top-right {
        top: 0;
        right: 0;
    }
    
    .toast-container.top-left {
        top: 0;
        left: 0;
    }
    
    .toast-container.top-center {
        transform: translateX(-50%);
        top: 0;
        left: 50%;
    }
    
    .toast-container.bottom-right {
        right: 0;
        bottom: 0;
    }
    
    .toast-container.bottom-left {
        left: 0;
        bottom: 0;
    }
    
    .toast-container.bottom-center {
        transform: translateX(-50%);
        bottom: 0;
        left: 50%;
    }
    
    .toast-container > .toast {
        min-width: 150px;
        background: transparent;
        border: none;
    }
    
    .toast-container > .toast > .toast-header {
        border: none;
    }
    
    .toast-container > .toast > .toast-header strong {
        padding-right: 20px;
    }
    
    .toast-container > .toast > .toast-body {
        background: white;
    }
    
    
  2. Script47 commented on Nov 25, 2020

    @Script47
    Owner

    @slimjim91

    Thanks for taking the time out to draft some code.

    I'll look further into your request/changes sometime this week and have a think about how best to implement this.

    I envisage this to be v1.3.0.

  3. self-assigned this
    on Nov 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions