updated plugin Menu Icons version 0.12.8

This commit is contained in:
2021-07-25 23:25:06 +00:00
committed by Gitium
parent 3ef36355e9
commit a2480e23b7
63 changed files with 1153 additions and 1499 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 557 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

View File

@ -337,4 +337,6 @@ final class Icon_Picker {
$this->is_admin_loaded = true;
}
}
add_action( 'plugins_loaded', array( 'Icon_Picker', 'instance' ), 7 );
if ( function_exists( 'add_action' ) ) {
add_action( 'plugins_loaded', array( 'Icon_Picker', 'instance' ), 7 );
}

View File

@ -1,101 +0,0 @@
require( './media/manifest' );
( function( $ ) {
var l10n = wp.media.view.l10n.iconPicker,
templates = {},
frame, selectIcon, removeIcon, getFrame, updateField, updatePreview, $field;
getFrame = function() {
if ( ! frame ) {
frame = new wp.media.view.MediaFrame.IconPicker();
frame.target.on( 'change', updateField );
}
return frame;
};
updateField = function( model ) {
_.each( model.get( 'inputs' ), function( $input, key ) {
$input.val( model.get( key ) );
});
model.clear({ silent: true });
$field.trigger( 'ipf:update' );
};
updatePreview = function( e ) {
var $el = $( e.currentTarget ),
$select = $el.find( 'a.ipf-select' ),
$remove = $el.find( 'a.ipf-remove' ),
type = $el.find( 'input.ipf-type' ).val(),
icon = $el.find( 'input.ipf-icon' ).val(),
url = $el.find( 'input.url' ).val(),
template;
if ( type === '' || icon === '' || ! _.has( iconPicker.types, type ) ) {
$remove.addClass( 'hidden' );
$select
.removeClass( 'has-icon' )
.addClass( 'button' )
.text( l10n.selectIcon )
.attr( 'title', '' );
return;
}
if ( templates[ type ]) {
template = templates[ type ];
} else {
template = templates[ type ] = wp.template( 'iconpicker-' + iconPicker.types[ type ].templateId + '-icon' );
}
$remove.removeClass( 'hidden' );
$select
.attr( 'title', l10n.selectIcon )
.addClass( 'has-icon' )
.removeClass( 'button' )
.html( template({
type: type,
icon: icon,
url: url
}) );
};
selectIcon = function( e ) {
var frame = getFrame(),
model = { inputs: {} };
e.preventDefault();
$field = $( e.currentTarget ).closest( '.ipf' );
model.id = $field.attr( 'id' );
// Collect input fields and use them as the model's attributes.
$field.find( 'input' ).each( function() {
var $input = $( this ),
key = $input.attr( 'class' ).replace( 'ipf-', '' ),
value = $input.val();
model[ key ] = value;
model.inputs[ key ] = $input;
});
frame.target.set( model, { silent: true });
frame.open();
};
removeIcon = function( e ) {
var $el = $( e.currentTarget ).closest( 'div.ipf' );
$el.find( 'input' ).val( '' );
$el.trigger( 'ipf:update' );
};
$( document )
.on( 'click', 'a.ipf-select', selectIcon )
.on( 'click', 'a.ipf-remove', removeIcon )
.on( 'ipf:update', 'div.ipf', updatePreview );
$( 'div.ipf' ).trigger( 'ipf:update' );
}( jQuery ) );

View File

@ -1,69 +0,0 @@
/**
* wp.media.controller.IconPickerFont
*
* @class
* @augments wp.media.controller.State
* @augments Backbone.Model
* @mixes wp.media.controller.iconPickerMixin
*/
var IconPickerFont = wp.media.controller.State.extend( _.extend({}, wp.media.controller.iconPickerMixin, {
defaults: {
multiple: false,
menu: 'default',
toolbar: 'select',
baseType: 'font'
},
initialize: function() {
var data = this.get( 'data' );
this.set( 'groups', new Backbone.Collection( data.groups ) );
this.set( 'library', new wp.media.model.IconPickerFonts( data.items ) );
this.set( 'selection', new wp.media.model.Selection( null, {
multiple: this.get( 'multiple' )
}) );
},
activate: function() {
this.frame.on( 'open', this.updateSelection, this );
this.resetFilter();
this.updateSelection();
},
deactivate: function() {
this.frame.off( 'open', this.updateSelection, this );
},
resetFilter: function() {
this.get( 'library' ).props.set( 'group', 'all' );
},
updateSelection: function() {
var selection = this.get( 'selection' ),
library = this.get( 'library' ),
target = this.frame.target,
icon = target.get( 'icon' ),
type = target.get( 'type' ),
selected;
if ( this.id === type ) {
selected = library.findWhere({ id: icon });
}
selection.reset( selected ? selected : null );
},
getContentView: function() {
return new wp.media.view.IconPickerFontBrowser( _.extend({
controller: this.frame,
model: this,
groups: this.get( 'groups' ),
collection: this.get( 'library' ),
selection: this.get( 'selection' ),
baseType: this.get( 'baseType' ),
type: this.get( 'id' )
}, this.ipGetSidebarOptions() ) );
}
}) );
module.exports = IconPickerFont;

View File

@ -1,148 +0,0 @@
var Library = wp.media.controller.Library,
l10n = wp.media.view.l10n,
models = wp.media.model,
views = wp.media.view,
IconPickerImg;
/**
* wp.media.controller.IconPickerImg
*
* @augments wp.media.controller.Library
* @augments wp.media.controller.State
* @augments Backbone.Model
* @mixes media.selectionSync
* @mixes wp.media.controller.iconPickerMixin
*/
IconPickerImg = Library.extend( _.extend({}, wp.media.controller.iconPickerMixin, {
defaults: _.defaults({
id: 'image',
baseType: 'image',
syncSelection: false
}, Library.prototype.defaults ),
initialize: function( options ) {
var selection = this.get( 'selection' );
this.options = options;
this.set( 'library', wp.media.query({ type: options.data.mimeTypes }) );
this.routers = {
upload: {
text: l10n.uploadFilesTitle,
priority: 20
},
browse: {
text: l10n.mediaLibraryTitle,
priority: 40
}
};
if ( ! ( selection instanceof models.Selection ) ) {
this.set( 'selection', new models.Selection( selection, {
multiple: false
}) );
}
Library.prototype.initialize.apply( this, arguments );
},
activate: function() {
Library.prototype.activate.apply( this, arguments );
this.get( 'library' ).observe( wp.Uploader.queue );
this.frame.on( 'open', this.updateSelection, this );
this.updateSelection();
},
deactivate: function() {
Library.prototype.deactivate.apply( this, arguments );
this.get( 'library' ).unobserve( wp.Uploader.queue );
this.frame.off( 'open', this.updateSelection, this );
},
getContentView: function( mode ) {
var content = ( mode === 'upload' ) ? this.uploadContent() : this.browseContent();
this.frame.$el.removeClass( 'hide-toolbar' );
return content;
},
/**
* Media library content
*
* @returns {wp.media.view.IconPickerImgBrowser} "Browse" content view.
*/
browseContent: function() {
var options = _.extend({
model: this,
controller: this.frame,
collection: this.get( 'library' ),
selection: this.get( 'selection' ),
sortable: this.get( 'sortable' ),
search: this.get( 'searchable' ),
filters: this.get( 'filterable' ),
dragInfo: this.get( 'dragInfo' ),
idealColumnWidth: this.get( 'idealColumnWidth' ),
suggestedWidth: this.get( 'suggestedWidth' ),
suggestedHeight: this.get( 'suggestedHeight' )
}, this.ipGetSidebarOptions() );
if ( this.id === 'svg' ) {
options.AttachmentView = views.IconPickerSvgItem;
}
return new views.IconPickerImgBrowser( options );
},
/**
* Render callback for the content region in the `upload` mode.
*
* @returns {wp.media.view.UploaderInline} "Upload" content view.
*/
uploadContent: function() {
return new wp.media.view.UploaderInline({
controller: this.frame
});
},
updateSelection: function() {
var selection = this.get( 'selection' ),
target = this.frame.target,
icon = target.get( 'icon' ),
type = target.get( 'type' ),
selected;
if ( this.id === type ) {
selected = models.Attachment.get( icon );
this.dfd = selected.fetch();
}
selection.reset( selected ? selected : null );
},
/**
* Get image icon URL
*
* @param {object} model - Selected icon model.
* @param {string} size - Image size.
*
* @returns {string} Icon URL.
*/
ipGetIconUrl: function( model, size ) {
var url = model.get( 'url' ),
sizes = model.get( 'sizes' );
if ( undefined === size ) {
size = 'thumbnail';
}
if ( sizes && sizes[ size ]) {
url = sizes[ size ].url;
}
return url;
}
}) );
module.exports = IconPickerImg;

View File

@ -1,35 +0,0 @@
/**
* Methods for the state
*
* @mixin
*/
var iconPickerMixin = {
/**
* @returns {object}
*/
ipGetSidebarOptions: function() {
var frameOptions = this.frame.options,
options = {};
if ( frameOptions.SidebarView && frameOptions.SidebarView.prototype instanceof wp.media.view.IconPickerSidebar ) {
options.sidebar = true;
options.SidebarView = frameOptions.SidebarView;
} else {
options.sidebar = false;
}
return options;
},
/**
* Get image icon URL
*
* @returns {string}
*/
ipGetIconUrl: function() {
return '';
}
};
module.exports = iconPickerMixin;

View File

@ -1,16 +0,0 @@
wp.media.model.IconPickerTarget = require( './models/target.js' );
wp.media.model.IconPickerFonts = require( './models/fonts.js' );
wp.media.controller.iconPickerMixin = require( './controllers/mixin.js' );
wp.media.controller.IconPickerFont = require( './controllers/font.js' );
wp.media.controller.IconPickerImg = require( './controllers/img.js' );
wp.media.view.IconPickerBrowser = require( './views/browser.js' );
wp.media.view.IconPickerSidebar = require( './views/sidebar.js' );
wp.media.view.IconPickerFontItem = require( './views/font-item.js' );
wp.media.view.IconPickerFontLibrary = require( './views/font-library.js' );
wp.media.view.IconPickerFontFilter = require( './views/font-filter.js' );
wp.media.view.IconPickerFontBrowser = require( './views/font-browser.js' );
wp.media.view.IconPickerImgBrowser = require( './views/img-browser.js' );
wp.media.view.IconPickerSvgItem = require( './views/svg-item.js' );
wp.media.view.MediaFrame.IconPicker = require( './views/frame.js' );

View File

@ -1,77 +0,0 @@
/**
* wp.media.model.IconPickerFonts
*/
var IconPickerFonts = Backbone.Collection.extend({
constructor: function() {
Backbone.Collection.prototype.constructor.apply( this, arguments );
this.items = new Backbone.Collection( this.models );
this.props = new Backbone.Model({
group: 'all',
search: ''
});
this.props.on( 'change', this.refresh, this );
},
/**
* Refresh library when props is changed
*
* @param {Backbone.Model} props
*/
refresh: function( props ) {
let items = _.clone( this.items.models );
_.each( props.toJSON(), ( value, filter ) => {
const method = this.filters[ filter ];
if ( method ) {
items = items.filter( item => {
return method( item, value );
});
}
});
this.reset( items );
},
filters: {
/**
* @static
*
* @param {Backbone.Model} item Item model.
* @param {string} group Group ID.
*
* @returns {Boolean}
*/
group: function( item, group ) {
return ( group === 'all' || item.get( 'group' ) === group || item.get( 'group' ) === '' );
},
/**
* @static
*
* @param {Backbone.Model} item Item model.
* @param {string} term Search term.
*
* @returns {Boolean}
*/
search: function( item, term ) {
let result;
if ( term === '' ) {
result = true;
} else {
result = _.any([ 'id', 'name' ], attribute => {
const value = item.get( attribute );
return value && value.search( term ) >= 0;
}, term );
}
return result;
}
}
});
module.exports = IconPickerFonts;

View File

@ -1,18 +0,0 @@
/**
* wp.media.model.IconPickerTarget
*
* A target where the picked icon should be sent to
*
* @augments Backbone.Model
*/
var IconPickerTarget = Backbone.Model.extend({
defaults: {
type: '',
group: 'all',
icon: '',
url: '',
sizes: []
}
});
module.exports = IconPickerTarget;

View File

@ -1,15 +0,0 @@
/**
* Methods for the browser views
*/
var IconPickerBrowser = {
createSidebar: function() {
this.sidebar = new this.options.SidebarView({
controller: this.controller,
selection: this.options.selection
});
this.views.add( this.sidebar );
}
};
module.exports = IconPickerBrowser;

View File

@ -1,63 +0,0 @@
/**
* wp.media.view.IconPickerFontBrowser
*/
var IconPickerFontBrowser = wp.media.View.extend( _.extend({
className: function() {
var className = 'attachments-browser iconpicker-fonts-browser';
if ( ! this.options.sidebar ) {
className += ' hide-sidebar';
}
return className;
},
initialize: function() {
this.groups = this.options.groups;
this.createToolbar();
this.createLibrary();
if ( this.options.sidebar ) {
this.createSidebar();
}
},
createLibrary: function() {
this.items = new wp.media.view.IconPickerFontLibrary({
controller: this.controller,
collection: this.collection,
selection: this.options.selection,
baseType: this.options.baseType,
type: this.options.type
});
// Add keydown listener to the instance of the library view
this.views.add( this.items );
},
createToolbar: function() {
this.toolbar = new wp.media.view.Toolbar({
controller: this.controller
});
this.views.add( this.toolbar );
// Dropdown filter
this.toolbar.set( 'filters', new wp.media.view.IconPickerFontFilter({
controller: this.controller,
model: this.collection.props,
priority: - 80
}).render() );
// Search field
this.toolbar.set( 'search', new wp.media.view.Search({
controller: this.controller,
model: this.collection.props,
priority: 60
}).render() );
}
}, wp.media.view.IconPickerBrowser ) );
module.exports = IconPickerFontBrowser;

View File

@ -1,33 +0,0 @@
/**
* wp.media.view.IconPickerFontFilter
*/
var IconPickerFontFilter = wp.media.view.AttachmentFilters.extend({
createFilters: function() {
var groups = this.controller.state().get( 'groups' ),
filters = {};
filters.all = {
text: wp.media.view.l10n.iconPicker.allFilter,
props: { group: 'all' }
};
groups.each( function( group ) {
filters[ group.id ] = {
text: group.get( 'name' ),
props: { group: group.id }
};
});
this.filters = filters;
},
change: function() {
var filter = this.filters[ this.el.value ];
if ( filter ) {
this.model.set( 'group', filter.props.group );
}
}
});
module.exports = IconPickerFontFilter;

View File

@ -1,30 +0,0 @@
var Attachment = wp.media.view.Attachment.Library,
IconPickerFontItem;
/**
* wp.media.view.IconPickerFontItem
*/
IconPickerFontItem = Attachment.extend({
className: 'attachment iconpicker-item',
initialize: function() {
this.template = wp.media.template( 'iconpicker-' + this.options.baseType + '-item' );
Attachment.prototype.initialize.apply( this, arguments );
},
render: function() {
var options = _.defaults( this.model.toJSON(), {
baseType: this.options.baseType,
type: this.options.type
});
this.views.detach();
this.$el.html( this.template( options ) );
this.updateSelect();
this.views.render();
return this;
}
});
module.exports = IconPickerFontItem;

View File

@ -1,100 +0,0 @@
var $ = jQuery,
Attachments = wp.media.view.Attachments,
IconPickerFontLibrary;
/**
* wp.media.view.IconPickerFontLibrary
*/
IconPickerFontLibrary = Attachments.extend({
className: 'attachments iconpicker-items clearfix',
initialize: function() {
Attachments.prototype.initialize.apply( this, arguments );
_.bindAll( this, 'scrollToSelected' );
_.defer( this.scrollToSelected, this );
this.controller.on( 'open', this.scrollToSelected, this );
$( this.options.scrollElement ).off( 'scroll', this.scroll );
},
_addItem: function( model ) {
this.views.add( this.createAttachmentView( model ), {
at: this.collection.indexOf( model )
});
},
_removeItem: function( model ) {
var view = this._viewsByCid[ model.cid ];
delete this._viewsByCid[ model.cid ];
if ( view ) {
view.remove();
}
},
render: function() {
_.each( this._viewsByCid, this._removeItem, this );
this.collection.each( this._addItem, this );
return this;
},
createAttachmentView: function( model ) {
var view = new wp.media.view.IconPickerFontItem({
controller: this.controller,
model: model,
collection: this.collection,
selection: this.options.selection,
baseType: this.options.baseType,
type: this.options.type
});
return this._viewsByCid[ view.cid ] = view;
},
/**
* Scroll to selected item
*/
scrollToSelected: function() {
var selected = this.options.selection.single(),
singleView, distance;
if ( ! selected ) {
return;
}
singleView = this.getView( selected );
if ( singleView && ! this.isInView( singleView.$el ) ) {
distance = (
singleView.$el.offset().top -
parseInt( singleView.$el.css( 'paddingTop' ), 10 ) -
this.$el.offset().top +
this.$el.scrollTop() -
parseInt( this.$el.css( 'paddingTop' ), 10 )
);
this.$el.scrollTop( distance );
}
},
getView: function( model ) {
return _.findWhere( this._viewsByCid, { model: model });
},
isInView: function( $elem ) {
var docViewTop = this.$window.scrollTop(),
docViewBottom = docViewTop + this.$window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
return ( ( elemBottom <= docViewBottom ) && ( elemTop >= docViewTop ) );
},
prepare: function() {},
ready: function() {},
initSortable: function() {},
scroll: function() {}
});
module.exports = IconPickerFontLibrary;

View File

@ -1,118 +0,0 @@
/**
* wp.media.view.MediaFrame.IconPicker
*
* A frame for selecting an icon.
*
* @class
* @augments wp.media.view.MediaFrame.Select
* @augments wp.media.view.MediaFrame
* @augments wp.media.view.Frame
* @augments wp.media.View
* @augments wp.Backbone.View
* @augments Backbone.View
* @mixes wp.media.controller.StateMachine
*/
var l10n = wp.media.view.l10n,
Select = wp.media.view.MediaFrame.Select,
IconPicker;
IconPicker = Select.extend({
initialize: function() {
_.defaults( this.options, {
title: l10n.iconPicker.frameTitle,
multiple: false,
ipTypes: iconPicker.types,
target: null,
SidebarView: null
});
if ( this.options.target instanceof wp.media.model.IconPickerTarget ) {
this.target = this.options.target;
} else {
this.target = new wp.media.model.IconPickerTarget();
}
Select.prototype.initialize.apply( this, arguments );
},
createStates: function() {
var Controller;
_.each( this.options.ipTypes, function( props ) {
if ( ! wp.media.controller.hasOwnProperty( 'IconPicker' + props.controller ) ) {
return;
}
Controller = wp.media.controller[ 'IconPicker' + props.controller ];
this.states.add( new Controller({
id: props.id,
content: props.id,
title: props.name,
data: props.data
}) );
}, this );
},
/**
* Bind region mode event callbacks.
*/
bindHandlers: function() {
this.on( 'router:create:browse', this.createRouter, this );
this.on( 'router:render:browse', this.browseRouter, this );
this.on( 'content:render', this.ipRenderContent, this );
this.on( 'toolbar:create:select', this.createSelectToolbar, this );
this.on( 'open', this._ipSetState, this );
this.on( 'select', this._ipUpdateTarget, this );
},
/**
* Set state based on the target's icon type
*/
_ipSetState: function() {
var stateId = this.target.get( 'type' );
if ( ! stateId || ! this.states.findWhere({ id: stateId }) ) {
stateId = this.states.at( 0 ).id;
}
this.setState( stateId );
},
/**
* Update target's attributes after selecting an icon
*/
_ipUpdateTarget: function() {
var state = this.state(),
selected = state.get( 'selection' ).single(),
props;
props = {
type: state.id,
icon: selected.get( 'id' ),
sizes: selected.get( 'sizes' ),
url: state.ipGetIconUrl( selected )
};
this.target.set( props );
},
browseRouter: function( routerView ) {
var routers = this.state().routers;
if ( routers ) {
routerView.set( routers );
}
},
ipRenderContent: function() {
var state = this.state(),
mode = this.content.mode(),
content = state.getContentView( mode );
this.content.set( content );
}
});
module.exports = IconPicker;

View File

@ -1,6 +0,0 @@
/**
* wp.media.view.IconPickerImgBrowser
*/
var IconPickerImgBrowser = wp.media.view.AttachmentsBrowser.extend( wp.media.view.IconPickerBrowser );
module.exports = IconPickerImgBrowser;

View File

@ -1,29 +0,0 @@
/**
* wp.media.view.IconPickerSidebar
*/
var IconPickerSidebar = wp.media.view.Sidebar.extend({
initialize: function() {
var selection = this.options.selection;
wp.media.view.Sidebar.prototype.initialize.apply( this, arguments );
selection.on( 'selection:single', this.createSingle, this );
selection.on( 'selection:unsingle', this.disposeSingle, this );
if ( selection.single() ) {
this.createSingle();
}
},
/**
* @abstract
*/
createSingle: function() {},
/**
* @abstract
*/
disposeSingle: function() {}
});
module.exports = IconPickerSidebar;

View File

@ -1,8 +0,0 @@
/**
* wp.media.view.IconPickerSvgItem
*/
var IconPickerSvgItem = wp.media.view.Attachment.Library.extend({
template: wp.template( 'iconpicker-svg-item' )
});
module.exports = IconPickerSvgItem;

View File

@ -1,17 +0,0 @@
<?xml version="1.0"?>
<ruleset name="Icon Picker Coding Standards">
<config name="installed_paths" value="vendor/wp-coding-standards/wpcs" />
<exclude-pattern>*/node_modules/*</exclude-pattern>
<exclude-pattern>*/vendor/*</exclude-pattern>
<rule ref="WordPress-VIP">
<!-- ...Except for VIP-specific things -->
<exclude name="WordPress.VIP.FileSystemWritesDisallow" />
<exclude name="WordPress.VIP.RestrictedFunctions" />
<exclude name="WordPress.VIP.RestrictedVariables" />
<exclude name="WordPress.VIP.SuperGlobalInputUsage" />
<exclude name="WordPress.VIP.ValidatedSanitizedInput" />
<exclude name="WordPress.VIP.DirectDatabaseQuery" />
</rule>
</ruleset>

View File

@ -1,85 +0,0 @@
<!-- DO NOT EDIT THIS FILE; it is auto-generated from readme.txt -->
# Icon Picker
Pick an icon of your choice.
**Contributors:** [kucrut](https://profiles.wordpress.org/kucrut)
**Tags:** [icons](https://wordpress.org/plugins/tags/icons), [image](https://wordpress.org/plugins/tags/image), [svg](https://wordpress.org/plugins/tags/svg)
**Requires at least:** 4.3
**Tested up to:** 4.7.2
**Stable tag:** 0.5.0
**License:** [GPLv2](http://www.gnu.org/licenses/gpl-2.0.html)
**Donate Link:** http://kucrut.org/#coffee
[![Build Status](https://travis-ci.org/kucrut/wp-icon-picker.svg?branch=master)](https://travis-ci.org/kucrut/wp-icon-picker) [![Built with Grunt](https://cdn.gruntjs.com/builtwith.svg)](http://gruntjs.com)
## Description ##
An icon picker library plugin.
## Screenshots ##
### Icon selector
![Icon selector](assets/screenshot-1.png)
### Icon fields in a post meta box using [CMB](https://github.com/humanmade/Custom-Meta-Boxes/)
![Icon fields in a post meta box using [CMB](https://github.com/humanmade/Custom-Meta-Boxes/)](assets/screenshot-2.png)
## Frequently Asked Questions ##
### How do I use css file from CDN? ###
You can use the `icon_picker_icon_type_stylesheet_uri` filter, eg:
```php
/**
* Load Font Awesome's CSS from CDN
*
* @param string $stylesheet_uri Icon type's stylesheet URI.
* @param string $icon_type_id Icon type's ID.
* @param Icon_Picker_Type_Font $icon_type Icon type's instance.
*
* @return string
*/
function myprefix_font_awesome_css_from_cdn( $stylesheet_uri, $icon_type_id, $icon_type ) {
if ( 'fa' === $icon_type_id ) {
$stylesheet_uri = sprintf(
'https://maxcdn.bootstrapcdn.com/font-awesome/%s/css/font-awesome.min.css',
$icon_type->version
);
}
return $stylesheet_uri;
}
add_filter( 'icon_picker_icon_type_stylesheet_uri', 'myprefix_font_awesome_css_from_cdn', 10, 3 );
```
## Changelog ##
### 0.5.0 ###
* Update Font Awesome to 4.7.0.
* Switch to Webpack.
* Various [bug fixes and enhancements](https://github.com/kucrut/wp-icon-picker/issues?q=is%3Aissue+milestone%3A0.5.0+is%3Aclosed).
### 0.4.1 ###
* Improve support for CMB: Make the field usable in a repeatable field.
### 0.4.0 ###
* Introduce `icon_picker_icon_type_stylesheet_uri` filter hook.
* Font Awesome 4.6.1
### 0.3.0 ###
* Fix CSS classname conflicts.
### 0.2.0 ###
* Introduce `icon_picker_field()`.
* Add support for [CMB](https://github.com/humanmade/Custom-Meta-Boxes/).
### 0.1.1 ###
* Load translation, props [Eduardo Larequi](https://wordpress.org/support/profile/elarequi).
### 0.1.0 ###
* Initial