NodeBB/NodeBB

View on GitHub
public/src/modules/iconSelect.js

Summary

Maintainability
A
2 hrs
Test Coverage
'use strict';


define('iconSelect', ['benchpress', 'bootbox'], function (Benchpress, bootbox) {
    const fontawesome_license = config.fontawesome.pro ? 'pro' : 'free';
    const iconSelect = {};
    const initialIcons = [
        { id: 'nbb-none', label: 'None (NodeBB)', style: 'nodebb' },
        { id: 'youtube', label: 'YouTube (brands)', style: 'brands' },
        { id: 'window-restore', label: 'Window Restore (solid)', style: 'solid' },
        { id: 'window-maximize', label: 'Window Maximize (solid)', style: 'solid' },
        { id: 'rectangle-xmark', label: 'Rectangle X Mark (solid)', style: 'solid' },
        { id: 'triangle-exclamation', label: 'Triangle exclamation (solid)', style: 'solid' },
        { id: 'phone-volume', label: 'Phone Volume (solid)', style: 'solid' },
        { id: 'video', label: 'Video (solid)', style: 'solid' },
        { id: 'address-card', label: 'Address Card (solid)', style: 'solid' },
        { id: 'user', label: 'User (solid)', style: 'solid' },
        { id: 'circle-user', label: 'Circle user (solid)', style: 'solid' },
        { id: 'usb', label: 'USB (brands)', style: 'brands' },
        { id: 'sort', label: 'Sort (solid)', style: 'solid' },
        { id: 'unlock', label: 'unlock (solid)', style: 'solid' },
        { id: 'link-slash', label: 'Link Slash (solid)', style: 'solid' },
        { id: 'trash-can', label: 'Trash can (solid)', style: 'solid' },
        { id: 'transgender', label: 'Transgender (solid)', style: 'solid' },
        { id: 'mars-and-venus', label: 'Mars and Venus (solid)', style: 'solid' },
        { id: 'square-caret-up', label: 'Square caret up (solid)', style: 'solid' },
        { id: 'square-caret-right', label: 'Square caret right (solid)', style: 'solid' },
        { id: 'square-caret-left', label: 'Square caret left (solid)', style: 'solid' },
        { id: 'square-caret-down', label: 'Square caret down (solid)', style: 'solid' },
        { id: 'circle-xmark', label: 'Circle X Mark (solid)', style: 'solid' },
        { id: 'thumbs-up', label: 'thumbs-up (solid)', style: 'solid' },
        { id: 'thumbs-down', label: 'thumbs-down (solid)', style: 'solid' },
        { id: 'thumbtack', label: 'Thumbtack (solid)', style: 'solid' },
        { id: 'temperature-full', label: 'Temperature full (solid)', style: 'solid' },
        { id: 'temperature-three-quarters', label: 'Temperature three quarters (solid)', style: 'solid' },
        { id: 'temperature-half', label: 'Temperature half (solid)', style: 'solid' },
        { id: 'temperature-quarter', label: 'Temperature quarter (solid)', style: 'solid' },
        { id: 'temperature-empty', label: 'Temperature empty (solid)', style: 'solid' },
        { id: 'tv', label: 'Television (solid)', style: 'solid' },
        { id: 'bars-progress', label: 'Bars progress (solid)', style: 'solid' },
        { id: 'gauge-high', label: 'Gauge (solid)', style: 'solid' },
        { id: 'tablet-screen-button', label: 'Tablet screen button (solid)', style: 'solid' },
        { id: 'life-ring', label: 'Life Ring (solid)', style: 'solid' },
        { id: 'sun', label: 'Sun (solid)', style: 'solid' },
        { id: 'circle-stop', label: 'Circle stop (solid)', style: 'solid' },
        { id: 'note-sticky', label: 'Note sticky (solid)', style: 'solid' },
        { id: 'star', label: 'Star (solid)', style: 'solid' },
        { id: 'star-half-stroke', label: 'Star half stroke (solid)', style: 'solid' },
        { id: 'square', label: 'Square (solid)', style: 'solid' },
        { id: 'arrow-down-9-1', label: 'Arrow down 9 1 (solid)', style: 'solid' },
        { id: 'arrow-down-1-9', label: 'Arrow down 1 9 (solid)', style: 'solid' },
        { id: 'sort-down', label: 'Sort Down (Descending) (solid)', style: 'solid' },
        { id: 'sort-up', label: 'Sort Up (Ascending) (solid)', style: 'solid' },
        { id: 'arrow-down-wide-short', label: 'Arrow down wide short (solid)', style: 'solid' },
        { id: 'arrow-down-short-wide', label: 'Arrow down short wide (solid)', style: 'solid' },
        { id: 'arrow-down-z-a', label: 'Arrow down z a (solid)', style: 'solid' },
        { id: 'arrow-down-a-z', label: 'Arrow down a z (solid)', style: 'solid' },
        { id: 'futbol', label: 'Futbol ball (solid)', style: 'solid' },
        { id: 'snowflake', label: 'Snowflake (solid)', style: 'solid' },
        { id: 'face-smile', label: 'Face Smile (solid)', style: 'solid' },
        { id: 'hands', label: 'Hands (solid)', style: 'solid' },
        { id: 'right-from-bracket', label: 'Right from bracket (solid)', style: 'solid' },
        { id: 'right-to-bracket', label: 'Right to bracket (solid)', style: 'solid' },
        { id: 'share-from-square', label: 'Share from square (solid)', style: 'solid' },
        { id: 'paper-plane', label: 'Paper Plane (solid)', style: 'solid' },
        { id: 'floppy-disk', label: 'Floppy Disk (solid)', style: 'solid' },
        { id: 'safari', label: 'Safari (brands)', style: 'brands' },
        { id: 'bath', label: 'Bath (solid)', style: 'solid' },
        { id: 'arrow-rotate-right', label: 'Arrow Rotate Right (solid)', style: 'solid' },
        { id: 'arrow-rotate-left', label: 'Arrow Rotate Left (solid)', style: 'solid' },
        { id: 'bars', label: 'Bars (solid)', style: 'solid' },
        { id: 'xmark', label: 'X Mark (solid)', style: 'solid' },
        { id: 'registered', label: 'Registered Trademark (solid)', style: 'solid' },
        { id: 'arrows-rotate', label: 'Arrows rotate (solid)', style: 'solid' },
        { id: 'circle-question', label: 'Circle question (solid)', style: 'solid' },
        { id: 'square-plus', label: 'Square plus (solid)', style: 'solid' },
        { id: 'circle-play', label: 'Circle play (solid)', style: 'solid' },
        { id: 'chart-pie', label: 'Pie Chart (solid)', style: 'solid' },
        { id: 'image', label: 'Image (solid)', style: 'solid' },
        { id: 'pen-to-square', label: 'Pen to square (solid)', style: 'solid' },
        { id: 'square-pen', label: 'Square pen (solid)', style: 'solid' },
        { id: 'circle-pause', label: 'Circle pause (solid)', style: 'solid' },
        { id: 'opera', label: 'Opera (brands)', style: 'brands' },
        { id: 'openid', label: 'OpenID (brands)', style: 'brands' },
        { id: 'object-ungroup', label: 'Object Ungroup (solid)', style: 'solid' },
        { id: 'object-group', label: 'Object Group (solid)', style: 'solid' },
        { id: 'newspaper', label: 'Newspaper (solid)', style: 'solid' },
        { id: 'graduation-cap', label: 'Graduation Cap (solid)', style: 'solid' },
        { id: 'moon', label: 'Moon (solid)', style: 'solid' },
        { id: 'money-bill-1', label: 'Money bill 1 (solid)', style: 'solid' },
        { id: 'mobile-screen-button', label: 'Mobile screen button (solid)', style: 'solid' },
        { id: 'square-minus', label: 'Square minus (solid)', style: 'solid' },
        { id: 'face-meh', label: 'Face meh (solid)', style: 'solid' },
        { id: 'map', label: 'Map (solid)', style: 'solid' },
        { id: 'location-dot', label: 'Location dot (solid)', style: 'solid' },
        { id: 'reply-all', label: 'reply-all (solid)', style: 'solid' },
        { id: 'reply', label: 'Reply (solid)', style: 'solid' },
        { id: 'share', label: 'Share (solid)', style: 'solid' },
        { id: 'wand-magic-sparkles', label: 'Wand magic sparkles (solid)', style: 'solid' },
        { id: 'up-long', label: 'Up long (solid)', style: 'solid' },
        { id: 'right-long', label: 'Right long (solid)', style: 'solid' },
        { id: 'left-long', label: 'Left long (solid)', style: 'solid' },
        { id: 'down-long', label: 'Down long (solid)', style: 'solid' },
        { id: 'rectangle-list', label: 'Rectangle list (solid)', style: 'solid' },
        { id: 'chart-line', label: 'Line Chart (solid)', style: 'solid' },
        { id: 'lightbulb', label: 'Lightbulb (solid)', style: 'solid' },
        { id: 'turn-up', label: 'Turn up (solid)', style: 'solid' },
        { id: 'turn-down', label: 'Turn down (solid)', style: 'solid' },
        { id: 'lemon', label: 'Lemon (solid)', style: 'solid' },
        { id: 'gavel', label: 'Gavel (solid)', style: 'solid' },
        { id: 'keyboard', label: 'Keyboard (solid)', style: 'solid' },
        { id: 'building-columns', label: 'Building with Columns (solid)', style: 'solid' },
        { id: 'id-card', label: 'Identification Card (solid)', style: 'solid' },
        { id: 'id-badge', label: 'Identification Badge (solid)', style: 'solid' },
        { id: 'hourglass', label: 'Hourglass (solid)', style: 'solid' },
        { id: 'hourglass-end', label: 'Hourglass End (solid)', style: 'solid' },
        { id: 'hourglass-half', label: 'Hourglass Half (solid)', style: 'solid' },
        { id: 'hourglass-start', label: 'Hourglass Start (solid)', style: 'solid' },
        { id: 'bed', label: 'Bed (solid)', style: 'solid' },
        { id: 'hospital', label: 'hospital (solid)', style: 'solid' },
        { id: 'house', label: 'House (solid)', style: 'solid' },
        { id: 'heart', label: 'Heart (solid)', style: 'solid' },
        { id: 'heading', label: 'heading (solid)', style: 'solid' },
        { id: 'hard-drive', label: 'Hard drive (solid)', style: 'solid' },
        { id: 'ear-deaf', label: 'Ear deaf (solid)', style: 'solid' },
        { id: 'handshake', label: 'Handshake (solid)', style: 'solid' },
        { id: 'hand', label: 'Paper (Hand) (solid)', style: 'solid' },
        { id: 'hand-spock', label: 'Spock (Hand) (solid)', style: 'solid' },
        { id: 'hand-scissors', label: 'Scissors (Hand) (solid)', style: 'solid' },
        { id: 'hand-back-fist', label: 'Rock (Hand) (solid)', style: 'solid' },
        { id: 'hand-pointer', label: 'Pointer (Hand) (solid)', style: 'solid' },
        { id: 'hand-peace', label: 'Peace (Hand) (solid)', style: 'solid' },
        { id: 'hand-point-up', label: 'Hand Pointing Up (solid)', style: 'solid' },
        { id: 'hand-point-right', label: 'Hand Pointing Right (solid)', style: 'solid' },
        { id: 'hand-point-left', label: 'Hand Pointing Left (solid)', style: 'solid' },
        { id: 'hand-point-down', label: 'Hand Pointing Down (solid)', style: 'solid' },
        { id: 'hand-lizard', label: 'Lizard (Hand) (solid)', style: 'solid' },
        { id: 'users', label: 'Users (solid)', style: 'solid' },
        { id: 'gears', label: 'Gears (solid)', style: 'solid' },
        { id: 'gear', label: 'Gear (solid)', style: 'solid' },
        { id: 'face-frown', label: 'Face frown (solid)', style: 'solid' },
        { id: 'font-awesome', label: 'Font Awesome (brands)', style: 'brands' },
        { id: 'folder-open', label: 'Folder Open (solid)', style: 'solid' },
        { id: 'folder', label: 'Folder (solid)', style: 'solid' },
        { id: 'bolt', label: 'Bolt (solid)', style: 'solid' },
        { id: 'flag', label: 'flag (solid)', style: 'solid' },
        { id: 'firefox', label: 'Firefox (brands)', style: 'brands' },
        { id: 'copy', label: 'Copy (solid)', style: 'solid' },
        { id: 'file-zipper', label: 'File zipper (solid)', style: 'solid' },
        { id: 'file-video', label: 'Video File (solid)', style: 'solid' },
        { id: 'file-lines', label: 'File lines (solid)', style: 'solid' },
        { id: 'file-audio', label: 'Audio File (solid)', style: 'solid' },
        { id: 'file-image', label: 'Image File (solid)', style: 'solid' },
        { id: 'file', label: 'File (solid)', style: 'solid' },
        { id: 'file-code', label: 'Code File (solid)', style: 'solid' },
        { id: 'eye-dropper', label: 'Eye Dropper (solid)', style: 'solid' },
        { id: 'eye-slash', label: 'Eye Slash (solid)', style: 'solid' },
        { id: 'eye', label: 'Eye (solid)', style: 'solid' },
        { id: 'square-up-right', label: 'Square up right (solid)', style: 'solid' },
        { id: 'up-right-from-square', label: 'Up right from square (solid)', style: 'solid' },
        { id: 'up-right-and-down-left-from-center', label: 'Up right and down left from center (solid)', style: 'solid' },
        { id: 'right-left', label: 'Right left (solid)', style: 'solid' },
        { id: 'envelope-open', label: 'Envelope Open (solid)', style: 'solid' },
        { id: 'envelope', label: 'Envelope (solid)', style: 'solid' },
        { id: 'edge', label: 'Edge Browser (brands)', style: 'brands' },
        { id: 'circle-dot', label: 'Circle dot (solid)', style: 'solid' },
        { id: 'gem', label: 'Gem (solid)', style: 'solid' },
        { id: 'outdent', label: 'Outdent (solid)', style: 'solid' },
        { id: 'utensils', label: 'Utensils (solid)', style: 'solid' },
        { id: 'scissors', label: 'Scissors (solid)', style: 'solid' },
        { id: 'credit-card', label: 'Credit Card (solid)', style: 'solid' },
        { id: 'creative-commons', label: 'Creative Commons (brands)', style: 'brands' },
        { id: 'copyright', label: 'Copyright (solid)', style: 'solid' },
        { id: 'down-left-and-up-right-to-center', label: 'Down left and up right to center (solid)', style: 'solid' },
        { id: 'compass', label: 'Compass (solid)', style: 'solid' },
        { id: 'comments', label: 'comments (solid)', style: 'solid' },
        { id: 'comment-dots', label: 'Comment Dots (solid)', style: 'solid' },
        { id: 'comment', label: 'comment (solid)', style: 'solid' },
        { id: 'code-branch', label: 'Code Branch (solid)', style: 'solid' },
        { id: 'cloud-arrow-up', label: 'Cloud arrow up (solid)', style: 'solid' },
        { id: 'cloud-arrow-down', label: 'Cloud arrow down (solid)', style: 'solid' },
        { id: 'clone', label: 'Clone (solid)', style: 'solid' },
        { id: 'clock', label: 'Clock (solid)', style: 'solid' },
        { id: 'paste', label: 'Paste (solid)', style: 'solid' },
        { id: 'circle', label: 'Circle (solid)', style: 'solid' },
        { id: 'circle-notch', label: 'Circle Notched (solid)', style: 'solid' },
        { id: 'chrome', label: 'Chrome (brands)', style: 'brands' },
        { id: 'square-check', label: 'Square check (solid)', style: 'solid' },
        { id: 'circle-check', label: 'Circle check (solid)', style: 'solid' },
        { id: 'link', label: 'Link (solid)', style: 'solid' },
        { id: 'closed-captioning', label: 'Closed Captioning (solid)', style: 'solid' },
        { id: 'calendar-xmark', label: 'Calendar X Mark (solid)', style: 'solid' },
        { id: 'calendar-plus', label: 'Calendar Plus (solid)', style: 'solid' },
        { id: 'calendar', label: 'Calendar (solid)', style: 'solid' },
        { id: 'calendar-minus', label: 'Calendar Minus (solid)', style: 'solid' },
        { id: 'calendar-check', label: 'Calendar Check (solid)', style: 'solid' },
        { id: 'calendar-days', label: 'Calendar Days (solid)', style: 'solid' },
        { id: 'taxi', label: 'Taxi (solid)', style: 'solid' },
        { id: 'building', label: 'Building (solid)', style: 'solid' },
        { id: 'bookmark', label: 'bookmark (solid)', style: 'solid' },
        { id: 'bluetooth', label: 'Bluetooth (brands)', style: 'brands' },
        { id: 'bell-slash', label: 'Bell Slash (solid)', style: 'solid' },
        { id: 'bell', label: 'bell (solid)', style: 'solid' },
        { id: 'battery-full', label: 'Battery Full (solid)', style: 'solid' },
        { id: 'battery-three-quarters', label: 'Battery 3/4 Full (solid)', style: 'solid' },
        { id: 'battery-half', label: 'Battery 1/2 Full (solid)', style: 'solid' },
        { id: 'battery-quarter', label: 'Battery 1/4 Full (solid)', style: 'solid' },
        { id: 'battery-empty', label: 'Battery Empty (solid)', style: 'solid' },
        { id: 'chart-column', label: 'Chart Column (solid)', style: 'solid' },
        { id: 'car', label: 'Car (solid)', style: 'solid' },
        { id: 'hands-asl-interpreting', label: 'Hands american sign language interpreting (solid)', style: 'solid' },
        { id: 'up-down', label: 'Up down (solid)', style: 'solid' },
        { id: 'left-right', label: 'Left right (solid)', style: 'solid' },
        { id: 'maximize', label: 'Maximize (solid)', style: 'solid' },
        { id: 'up-down-left-right', label: 'Up down left right (solid)', style: 'solid' },
        { id: 'circle-up', label: 'Circle up (solid)', style: 'solid' },
        { id: 'circle-right', label: 'Circle right (solid)', style: 'solid' },
        { id: 'circle-left', label: 'Circle left (solid)', style: 'solid' },
        { id: 'circle-down', label: 'Circle down (solid)', style: 'solid' },
        { id: 'chart-area', label: 'Area Chart (solid)', style: 'solid' },
        { id: 'apple', label: 'Apple (brands)', style: 'brands' },
        { id: 'android', label: 'Android (brands)', style: 'brands' },
        { id: 'address-book', label: 'Address Book (solid)', style: 'solid' },
    ];
    iconSelect.init = function (el, onModified) {
        onModified = onModified || function () { };
        let selected = cleanFAClass(el[0].classList);
        $('#icons .selected').removeClass('selected');
        if (selected.icon) {
            try {
                $(`#icons .nbb-fa-icons ${selected.styles.length ? '.' + selected.styles.join('.') : ''}.${selected.icon}`).addClass('selected');
            } catch (err) {
                selected = {
                    icon: '',
                    style: '',
                };
            }
        }

        Benchpress.render('partials/fontawesome', { icons: initialIcons }).then(function (html) {
            html = $(html);

            const picker = bootbox.dialog({
                onEscape: true,
                backdrop: true,
                show: false,
                message: html,
                size: 'large',
                title: 'Select an Icon',
                buttons: {
                    noIcon: {
                        label: 'No Icon',
                        className: 'btn-default',
                        callback: function () {
                            el.removeClass(selected.icon);
                            // eslint-disable-next-line no-restricted-syntax
                            for (const style of selected.styles) {
                                el.removeClass(style);
                            }
                            el.val('');
                            el.attr('value', '');
                            onModified(el, '', []);
                        },
                    },
                    success: {
                        label: 'Select',
                        className: 'btn-primary',
                        callback: function () {
                            const iconClass = $('.bootbox .selected')[0]?.classList || [`fa-${$('.bootbox #fa-filter').val()}`];
                            const newIcon = cleanFAClass(iconClass);
                            if (newIcon.icon) {
                                el.removeClass(selected.icon).addClass(newIcon.icon);
                                // eslint-disable-next-line no-restricted-syntax
                                for (const style of selected.styles || []) {
                                    el.removeClass(style);
                                }
                                // eslint-disable-next-line no-restricted-syntax
                                for (const style of newIcon.styles || []) {
                                    el.addClass(style);
                                }
                                // Simple workaround for lack of style information in icons by just adding the style class to the value
                                const newValue = newIcon.icon + (newIcon.styles.length ? ' ' + newIcon.styles.join(' ') : '');
                                el.val(newValue);
                                el.attr('value', newValue);
                            }

                            onModified(el, newIcon.icon, newIcon.styles);
                        },
                    },
                },
            });

            picker.on('show.bs.modal', function () {
                const modalEl = $(this);
                const searchEl = modalEl.find('input');

                if (selected.icon) {
                    modalEl.find('.' + selected.icon).addClass('selected');
                    searchEl.val(selected.icon.replace('fa-', ''));
                }
            }).modal('show');

            picker.on('shown.bs.modal', function () {
                const modalEl = $(this);
                const searchEl = modalEl.find('input');
                const iconContainer = modalEl.find('.nbb-fa-icons');
                let icons = modalEl.find('.nbb-fa-icons i');
                const submitEl = modalEl.find('button.btn-primary');
                let lastSearch = '';

                function changeSelection(newSelection) {
                    modalEl.find('i.selected').removeClass('selected');
                    if (newSelection) {
                        newSelection.addClass('selected');
                    } else if (searchEl.val().length === 0) {
                        if (selected.icon) {
                            modalEl.find('.' + selected.icon).addClass('selected');
                        }
                    } else {
                        modalEl.find('i:visible').first().addClass('selected');
                    }
                }

                // Focus on the input box
                searchEl.selectRange(0, searchEl.val().length);

                modalEl.find('.icon-container').on('click', 'i', function () {
                    searchEl.val(cleanFAClass($(this)[0].classList).icon.replace('fa-', ''));
                    changeSelection($(this));
                });
                const debouncedSearch = utils.debounce(async () => {
                    // Search
                    let iconData;
                    if (lastSearch.length) {
                        iconData = await iconSelect.findIcons(lastSearch);
                    } else {
                        iconData = initialIcons;
                    }
                    icons.remove();
                    iconData.forEach((iconData) => {
                        iconContainer.append($(`<i class="fa fa-xl fa-${iconData.style}${iconData.family !== 'classic' ? ` fa-${iconData.family}` : ''} fa-${iconData.id} rounded-1" data-label="${iconData.label}"></i>`));
                    });
                    icons = modalEl.find('.nbb-fa-icons i');
                    changeSelection();
                }, 200);
                searchEl.on('keyup', function (e) {
                    if (e.code !== 'Enter' && searchEl.val() !== lastSearch) {
                        lastSearch = searchEl.val();
                        debouncedSearch();
                    } else if (e.code === 'Enter') {
                        submitEl.trigger('click');
                    }
                });
            });
        });
    };

    const excludedClassList = [
        'nodebb',
        'fw',
        '\\d{1,2}?[xsl][smgl]',
        'rotate-(\\d+|horizontal|vertical|both|by)',
        'flip-(\\d+|horizontal|vertical|both)',
        'beat',
        'fade',
        'beat-fade',
        'bounce',
        'flip',
        'shake',
        'spin',
        'spin-pulse',
        'spin-reverse',
        'border',
        'pull-(left|right)',
        'stack(-\\dx)?',
        'inverse',
        'layers(-text)?(-counter)?',
        'ul',
        'li',
        'border',
        'swap-opacity',
        'sr-only(-focusable)?',
    ];

    const excludedClassRegex = RegExp(`\\bfa-(${excludedClassList.join('|')})\\b`, 'i');

    const styleRegex = /fa-(solid|regular|brands|light|thin|duotone|sharp)/;
    // turns 'fa fa-2x fa-solid fa-heart' into 'fa-heart'
    function cleanFAClass(classList) {
        const styles = [];
        let icon;
        // eslint-disable-next-line no-restricted-syntax
        for (const className of classList) {
            if (className.startsWith('fa-') && !excludedClassRegex.test(className)) {
                if (styleRegex.test(className)) {
                    styles.push(className);
                } else {
                    icon = className;
                }
            }
        }
        return {
            icon,
            styles,
        };
    }

    iconSelect.findIcons = async function (searchString) {
        const request = await fetch('https://api.fontawesome.com', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                query: `query {
                    search(version: "${config.fontawesome.version}", query: "${searchString}", first: 200) {
                        id,
                        label,
                        familyStylesByLicense {
                            ${fontawesome_license} {
                                style,
                                family
                            }
                        }
                    }
                }`.replace(/(\n| {2,}|\t{2,})/g, ''), // very simple minification
            }),
        });
        const response = await request.json();
        const icons = response.data.search.filter(icon => icon.familyStylesByLicense.free.length > 0).flatMap((icon) => {
            const result = [];
            icon.familyStylesByLicense[fontawesome_license].forEach((style) => {
                let familyStyle = style.style;
                if (style.family !== 'classic') {
                    familyStyle = `${style.family}-${familyStyle}`;
                }
                if (!config.fontawesome.styles.includes(familyStyle)) {
                    return;
                }
                result.push({
                    id: icon.id,
                    label: `${icon.label} (${style.style})`,
                    style: style.style,
                    family: style.family,
                });
            });
            return result;
        });
        return icons;
    };

    return iconSelect;
});