10up / block-components

A collection of components built to be used in the block editor
https://www.npmjs.com/package/@10up/block-components
262 stars 39 forks source link

Add: Icon Picker Component #57

Closed fabiankaegy closed 2 years ago

fabiankaegy commented 2 years ago

Is your enhancement related to a problem? Please describe.

A common problem we need to solve is projects needing a way to select icons within blocks. The way our theme scaffold does it in PHP is having a helper function that includes the SVG files by a given name.

Describe the solution you'd like

It would be cool to somehow also make this work in React where the Icon picker is self-aware of all the icons in the project and allows editors to pick an icon. The icon itself would be stored as a string which then could be used in a <Icon /> component to actually display that particular icon in react.

Designs

IconPickerControl in InspectorControls area

Icon Picker Component-1

IconPickerToolbarButton in BlockControls area

Icon Picker Component-2

IconPicker inside Content

Icon Picker Component-3

Describe alternatives you've considered

Additional context

fabiankaegy commented 2 years ago

There is an internal project where we build something similar that we can use as an inspiration. The code can be found here:

Icon Component: https://s.10up.com/NThRH JSON Generator: https://s.10up.com/qWQvY

fabiankaegy commented 2 years ago

I just also attached some design ideas to the Description of the Issue. Feel free to provide any other suggestions or share feedback of the Components.

The Figma file can be viewed here: https://www.figma.com/file/Slq60OL1E870V1ghLpzVVi/Icon-Picker-Component?node-id=0%3A1

fabiankaegy commented 2 years ago

Looking back at these designs I wonder whether the name of the icons is even needed. For one the name wouldn't be available in the nice formatting without additional manual work. The idea is right now for the icons to get auto-generated by webpack from SVG files located in a certain folder.

Additionally, I think the Picker looks too much like a block picker right now and has a lot of whitespace. I'm going to spend some more time with the designs but am definitely looking for other opinions and thoughts :)

fabiankaegy commented 2 years ago

Did a quick exploration of a different inserter popover style here:

Screen Shot 2021-11-07 at 23 43 09
fabiankaegy commented 2 years ago

This can also take inspiration from https://github.com/10up/insert-special-characters. But I'd love to refine the visual UI of the popup experience to feel a little more native to Gutenberg.

rdimascio commented 2 years ago

Looking back at these designs I wonder whether the name of the icons is even needed. For one the name wouldn't be available in the nice formatting without additional manual work.

I don't think it would require too much manual work to get a formatted name. I'm thinking we can just capitalize the filenames. And I think having the names next to the icons is necessary if we're going to include a search bar — otherwise, users would not know what to search for.

The idea is right now for the icons to get auto-generated by Webpack from SVG files located in a certain folder.

I also thinks this begs a separate discussion. The functionality of this block is going to rely on changes in both 10up-toolkit as well as wp-scaffold, which means this block would not be "plug-and-play" like every other block in this library. It's functionality is highly dependent on the site/theme/plugin in which it's running. If any existing project would wish to use this block, it would take quite a large effort to get it working.

That being said, I think the path forward for this block at the moment is to function independent of any build processes and theme configuration. In that sense, it would be a pure block, and would just need to get passed an array of icons to work. The method of getting those icons to the block is an implementation detail.

I'd love to refine the visual UI of the popup experience to feel a little more native to Gutenberg.

There's an icon block on the WP plugin repository that we might be able to take a little inspiration from - https://wordpress.org/plugins/icon-block/

image

We obviously would not have to replicate the entire feature set, but if we use a modal like this, we could have separate sections for different icon libraries such as Dashicons, Hero Icons, Feather Icons, and then could give developers the ability to add their own, whether that be through a Webpack build process, file_get_contents + wp_localize_script, etc.

fabiankaegy commented 2 years ago

@rdimascio That is a really nice share and I really appreciate the input. I wonder whether we can get our first MVP to work in a way where we can have some global hook / init call where we can provide a global store our icon set in a certain format. And from that point on this component would use the icons in that global store and display them.

That way we are decoupled from just our theme approach and instead can tap into any icon source.

const icons = [
    {
        source: "...",
        name: "...",
        label: "..."
    }
];

registerIcons( 'namespace/theme-icons', { icons: icons } )

If we make the registerIcons function accept a namespace and an object as the second param we follow the pattern of other registration functions in WordPress and at the same time allow us more flexibility to extend this in the future.


Regarding multiple icon sets, I do think that is a great additional feature that we can support there. But personally speaking, I believe that the main use case for many projects tend to have one set of custom icons that get used throughout the site for a shared common visual language.

As far as the search goes you are probably correct that it would be less obvious without the text there. Even though I think it has become a bit of a common pattern with things like the Systems Emoji picker etc. And I do worry that the icon with text beneath looks too much like a block picker.


One thing I am slightly worried about is Icon Colors. Right now in many projects the svg folder is just full with the same icon with multiple color variants. And that is because we have not yet come up with a nice way of inlining the color value / dynamically generating it based on a query param for example. So the icon library could very quickly look rather ugly when you have 5 colors of each icon next to one another in there.

But that probably is an issue that we can solve in a different way at a different time. Since this component is not aware of the actual icon source and just outputs whatever we provide.

fabiankaegy commented 2 years ago

@rdimascio any I chatted a bit in Slack about this and came up with the following:

Besides the registerIcons function it would also be cool to create the PHP counterpart register_icons. That would allow you as a theme author to directly register the icons via PHP and under the hood, it inlines a script in the editor to call the registerIcons js function. Therefore removing the need of additionally using wp_localize_script to pass the icons to the editor. That would be done in one step in a more readable manner.

fabiankaegy commented 2 years ago

The actual Components that would be exported for this are:

And then the registerIcons and register_icons functions