123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- import $ from 'jquery';
- /* Icon Picker by QueryLoop
- * Author: @eliorivero
- * URL: http://queryloop.com/
- * License: GPLv2
- */
- var defaults = {
- 'mode': 'dialog', // show overlay 'dialog' panel or slide down 'inline' panel
- 'closeOnPick': true, // whether to close panel after picking or 'no'
- 'save': 'class', // save icon 'class' or 'code'
- 'size': '',
- 'classes': {
- 'launcher': '', // extra classes for launcher buttons
- 'clear': 'remove-times', // extra classes for button that removes preview and clears field
- 'highlight': '', // extra classes when highlighting an icon
- 'close': '' // extra classes for close button
- },
- 'iconSets': { // example data structure. Used to specify which launchers will be created
- 'genericon': 'Genericon', // create a launcher to pick genericon icons
- 'fa': 'FontAwesome' // create a launcher to pick fontawesome icons
- }
- };
- class QL_Icon_Picker {
- constructor(element, options) {
- this.iconSet = '';
- this.iconSetName = '';
- this.$field = '';
- this.element = element;
- this.settings = $.extend({}, defaults, options);
- this._defaults = defaults;
- this.init();
- }
- init() {
- var $brick = $(this.element);
- var pickerId = $brick.data('pickerid');
- var $preview = $('<div class="icon-preview icon-preview-' + pickerId + '" />');
- this.$field = $brick.find('input');
- // Add preview area
- this.makePreview($brick, pickerId, $preview);
- // Make button to clear field and remove preview
- this.makeClear(pickerId, $preview);
- // Make buttons that open the panel of icons
- this.makeLaunchers($brick, pickerId);
- // Prepare display styles, inline and dialog
- this.makeDisplay($brick);
- }
- makePreview($brick, pickerId, $preview) {
- var $icon = $('<i />');
- var iconValue = this.$field.val();
- $preview.prependTo($brick);
- $icon.prependTo($preview);
- if (iconValue !== '') {
- $preview.addClass('icon-preview-on');
- $icon.addClass(iconValue);
- }
- }
- makeClear(pickerId, $preview) {
- var base = this;
- var $clear = $('<a class="remove-icon ' + base.settings.classes.clear + '" />');
- // Hide button to remove icon and preview and append it to preview area
- $clear.hide().prependTo($preview);
- // If there's a icon saved in the field, show remove icon button
- if (base.$field.val() !== '') {
- $clear.show();
- }
- $preview.on('click', '.remove-icon', function(e) {
- e.preventDefault();
- base.$field.val('');
- $preview.removeClass('icon-preview-on').find('i').removeClass();
- $(this).hide();
- });
- }
- makeDisplay($brick) {
- var base = this;
- var close = base.settings.classes.close;
- var $body = $('body');
- var $close = $('<a href="#" class="icon-picker-close"/>');
- if (base.settings.mode === 'inline') {
- $brick.find('.icon-set').append($close).removeClass('dialog').addClass('ip-inline ' + base.settings.size).parent().addClass('icon-set-wrap');
- } else if (base.settings.mode === 'dialog') {
- $('.icon-set').addClass('dialog ' + base.settings.size);
- if ($('.icon-picker-overlay').length <= 0) {
- $body.append('<div class="icon-picker-overlay"/>').append($close);
- }
- }
- $body
- .on('click', '.icon-picker-close, .icon-picker-overlay', function(e) {
- e.preventDefault();
- base.closePicker($brick, $(base.iconSet), base.settings.mode);
- })
- .on('mouseenter mouseleave', '.icon-picker-close', function(e) {
- if (e.type === 'mouseenter') {
- $(this).addClass(close);
- } else {
- $(this).removeClass(close);
- }
- });
- }
- makeLaunchers($brick) {
- var base = this;
- var dataIconSets = $brick.data('iconsets');
- var iconSet;
- if (typeof dataIconSets === 'undefined') {
- dataIconSets = base.settings.iconSets;
- }
- for (iconSet in dataIconSets) {
- if (dataIconSets.hasOwnProperty(iconSet)) {
- $brick.append('<a class="launch-icons button ' + base.settings.classes.launcher + '" data-icons="' + iconSet + '">' + dataIconSets[iconSet] + '</a>');
- }
- }
- $brick.find('.launch-icons').on('click', function(e) {
- e.preventDefault();
- var $self = $(this);
- var theseIcons = $self.data('icons');
- base.iconSetName = theseIcons;
- base.iconSet = '.' + theseIcons + '-set';
- // Initialize picker
- base.iconPick($brick);
- // Show icon picker
- base.showPicker($brick, $(base.iconSet), base.settings.mode);
- });
- }
- iconPick($brick) {
- var base = this;
- var highlight = 'icon-highlight ' + base.settings.classes.highlight;
- $(base.iconSet).on('click', 'li', function(e) {
- e.preventDefault();
- var $icon = $(this);
- var icon = $icon.data(base.settings.save);
- // Mark as selected
- $('.icon-selected').removeClass('icon-selected');
- $icon.addClass('icon-selected');
- if (base.$field.data('format') === 'short') {
- icon = icon.slice(6);
- }
- // Save icon value to field
- base.$field.val(icon);
- // Close icon picker
- if (base.settings.closeOnPick) {
- base.closePicker($brick, $icon.closest(base.iconSet), base.settings.mode);
- }
- // Set preview
- base.setPreview($icon.data('class'));
- // Broadcast event passing the selected icon.
- $('body').trigger('iconselected.queryloop', icon);
- });
- $(base.iconSet).on('mouseenter mouseleave', 'li', function(e) {
- if (e.type === 'mouseenter') {
- $(this).addClass(highlight);
- } else {
- $(this).removeClass(highlight);
- }
- });
- }
- showPicker($brick, $icons, mode) {
- if (mode === 'inline') {
- $('.icon-set').removeClass('ip-inline-open');
- $brick.find($icons).toggleClass('ip-inline-open');
- } else if (mode === 'dialog') {
- $brick.find('.icon-picker-close').addClass('make-visible');
- $brick.find('.icon-picker-overlay').addClass('make-visible');
- $icons.addClass('dialog-open');
- }
- $icons.find('.icon-selected').removeClass('icon-selected');
- var selectedIcon = this.$field.val().replace(' ', '.');
- if (selectedIcon !== '') {
- if (this.settings.save === 'class') {
- $icons.find('.' + selectedIcon).addClass('icon-selected');
- } else {
- $icons.find('[data-code="' + selectedIcon + '"]').addClass('icon-selected');
- }
- }
- // Broadcast event when the picker is shown passing the picker mode.
- $('body').trigger('iconpickershow.queryloop', mode);
- }
- closePicker($brick, $icons, mode) {
- // Remove event so they don't fire from a different picker
- $(this.iconSet).off('click', 'li');
- if (mode === 'inline') {
- $brick.find($icons).removeClass('ip-inline-open');
- } else if (mode === 'dialog') {
- $('.icon-picker-close, .icon-picker-overlay').removeClass('make-visible');
- }
- // Broadcast event when the picker is closed passing the picker mode.
- $('body').trigger('iconpickerclose.queryloop', mode);
- $('.icon-set').removeClass('dialog-open');
- }
- setPreview(preview) {
- var $preview = $(this.element).find('.icon-preview');
- $preview.addClass('icon-preview-on').find('i').removeClass()
- .addClass(this.iconSetName)
- .addClass(preview);
- $preview.find('a').show();
- }
- }
- /* Grav */
- // extend $ with 3rd party QL Icon Picker
- $.fn.qlIconPicker = function(options) {
- this.each(function() {
- if (!$.data(this, 'plugin_qlIconPicker')) {
- $.data(this, 'plugin_qlIconPicker', new QL_Icon_Picker(this, options));
- }
- });
- return this;
- };
- export default class IconpickerField {
- constructor(options) {
- this.items = $();
- this.options = Object.assign({}, this.defaults, options);
- $('[data-grav-iconpicker]').each((index, element) => this.addItem(element));
- $('body').on('mutation._grav', this._onAddedNodes.bind(this));
- }
- _onAddedNodes(event, target/* , record, instance */) {
- let fields = $(target).find('[data-grav-iconpicker]');
- if (!fields.length) { return; }
- fields.each((index, field) => {
- field = $(field);
- if (!~this.items.index(field)) {
- this.addItem(field);
- }
- });
- }
- addItem(element) {
- element = $(element);
- this.items = this.items.add(element);
- element.find('.icon-picker').qlIconPicker({
- 'save': 'class'
- });
- // hack to remove extra icon sets that are just copies
- $('.icon-set:not(:first)').remove();
- }
- }
- export let Instance = new IconpickerField();
- // Fix to close the dialog when clicking outside
- $(document).on('click', (event) => {
- const target = $(event.target);
- const match = '.icon-set.dialog-open, .launch-icons[data-icons]';
- if (!target.is(match) && !target.closest(match).length) {
- const dialogs = $('.icon-set.dialog-open');
- // skip if there's no dialog open
- if (dialogs.length) {
- dialogs.each((index, dialog) => {
- const picker = $(dialog).siblings('.icon-picker');
- const data = picker.data('plugin_qlIconPicker');
- data.closePicker(picker, $(data.iconSet), data.settings.mode);
- });
- }
- }
- });
|