WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.41k stars 4.16k forks source link

Add an Icons block #16484

Open mtias opened 5 years ago

mtias commented 5 years ago

A common tool that many block libraries are adding is a block to insert icons (usually svgs) with some color and sizing tools. This is appearing repeatedly in libraries to the point that it makes sense to consider a more general solution in core, which ideally handles markup and accessibility consistently. We could make this block easy to extend (register new svg libraries or remove them) and it can be the basis for other more specific / niche tools (like social logos, etc).

richtabor commented 5 years ago

For reference, here's an overview of the Icon block in CoBlocks: icon-block-coblocks

senadir commented 5 years ago

I'm looking at implementing this currently & have some questions of how much features for it is required to consider it ready?

I can see that resizing & Icon search are an essential start this raises other questions like

I can start with a simple implementation of getting both the resizing and a simple search using dashicons

enriquesanchez commented 5 years ago

hey @senadir! 👋

I took an initial stab at exploring how the placeholder state of this block could look like:

icon-block-placeholder

A few things to note:

Before we move on, I think we should figure out what settings and customization we'll offer. Would love to hear what you think.

mapk commented 5 years ago

Looking really good, @enriquesanchez. I like the concept of searching for an icon first before stepping into the actual block, and I think your exploration helps communicate this. I have a bit of feedback.

  1. Often times when adding an icon, it's probably going to be in context to additional text on the page. Maybe a feature content section of 3 columns, or some other area that may not provide a lot of room for a larger placeholder like this. It might be good to explore this placeholder in a more narrow setting too.

Screen Shot 2019-08-02 at 1 00 19 PM

  1. Selecting an icon seems to be a primary function of this block, so I'm hesitant to suggest just pushing it to the block settings sidebar. Maybe the list of icons after search shows them a lot smaller? This might help with space.
enriquesanchez commented 5 years ago

It might be good to explore this placeholder in a more narrow setting too.

That's a great point @mapk!

I think we can definitively go small without sacrificing functionality:

block-icon-placeholder-small

It will all depend on how many results we want to display. Depending on how many libraries we support, I assume that often times we'll have just a couple, but it doesn't hurt to plan for all scenarios.

Thoughts?

mrwweb commented 5 years ago

A few random thoughts to throw out early in the process from my experience using a lot of SVG icons in a few recent projects:

onuro commented 5 years ago

Right now Kioken Blocks does it like the following:

Screen Recording 2019-08-04 at 11 06 PM

Would have always preferred a simpler approach though but I used React FontIconPicker component since plugin hosts around 7500 svg icons.

I also love how CoBlocks and Ghostkit handles it. Like how Ghostkit allow you inline select an icon within a block:

Screen Shot 2019-08-04 at 23 11 14

I use toolbar component for in-context icon changing for a block:

Screen Shot 2019-08-04 at 23 15 06

enriquesanchez commented 5 years ago

Hey @senadir! Are you still interested in working on this block?

I'm looking at implementing this currently & have some questions of how much features for it is required to consider it ready?

I think we should start with the most basic features and go from there. Based on everyone's feedback:

The block's placeholder should take up small space (because of nesting), so we should ask for the minimum:

One thing we need to figure out is where to source the icons from. From the examples shared above, it looks like Ghostkit is using FontAwesome and Kioken Blocks is using React FontIconPicker. @mapk do you have any suggestions?

As for settings/features, I think we can start with:

Anything else I may be missing?

karmatosed commented 5 years ago

One point I wanted to raise from the editor chat would be that I am not convinced supporting yet another icon set is a good idea. My vote would be stick to what Gutenberg already has for now.

mapk commented 5 years ago

@mapk do you have any suggestions?

Yeah, I wonder if would just be easiest to roll out with Dashicons? If we want to include an of the Material icons Gutenberg uses as well, as Tammie mentioned, that's cool too.

enriquesanchez commented 5 years ago

Thanks @karmatosed and @mapk!

onuro commented 5 years ago

@mapk do you have any suggestions?

Yeah, I wonder if would just be easiest to roll out with Dashicons? If we want to include an of the Material icons Gutenberg uses as well, as Tammie mentioned, that's cool too.

Thing is the Material Icons (as components) within GB is relative to the GB plugin version, meaning anything other than Dashicons may not be accessible fully by user based on if they use a WP core GB or the GB plugin (unless a kind of a full set is provided by GB universally just like Dashicons).

A case example is the vertical alignment Material toolbar icons. They're not accessible to WP - 5.2 GB but available with GB plugin active (as icon components).

mrwweb commented 5 years ago

+1 for providing a limited set of icons so long as the block is easily extensible for other sets. Again, it will be super important that the way to register new icons AND file requirements for icon SVGs be clearly documented (and therefore defined and worked out before implementation).

One other note: I can't find a reference, but long ago I recall it being stated somewhere that Dashicons were intended explicitly for the admin and not front-end usage on websites. It seems worth confirming whether that is still the case or not.

melchoyce commented 5 years ago

Yeah, I think something like Font Awesome might be better — open source, actively maintained, and designed for a variety of contexts.

senadir commented 5 years ago

@mrwweb creating an extending standard will not be a priority right now as the same with all other blocks, not until the current implementation is stable enough to allow third party integration to it

hacknug commented 5 years ago

Not sure if this has been discussed elsewhere or not but imho icons could be considered design tokens. As such, theme/plugin developers should be able to add icons using equivalent APIs to the ones used for colors and font-sizes.

Another token that could be introduced is sizing. This would allow developers to define common sizes for things like icons, images…

By default core should only (at least for now) include all Dashicons like @senadir mentioned.

Also, maybe someone from @Automattic should join the convo here? https://github.com/design-tokens/community-group/issues/1

CalumChilds commented 5 years ago

As for the icon frameworks, we should have a drop down below the search text box with "All" to filter the search down to a single framework should the user choose to do so. I think we should offer these icon frameworks to start with:

In the Block Settings area, I think we should have an "icon style" setting, with a drop down for each icon so the user can choose which style to apply the icon.

timhibberd commented 4 years ago

Iconify is an open source react icon framework that might be useful here.

See https://github.com/iconify/iconify-react.

Some useful documentation is available: https://iconify.design/docs/

Just a thought :-)

strarsis commented 4 years ago

What about implementing these icons for unicode characters? E.g. a phone icon is replaced by an inline icon block for the phone icon?

CalumChilds commented 4 years ago

@strarsis Good idea, but not all icon frameworks will support adding unicode characters. Maybe we should add HTML classes instead?

strarsis commented 4 years ago

@Wingo5315: By the way, WordPress core already contains an emoji script that is used to dynamically replace unicode emoji characters, but mainly for compatibility reasons. A JavaScript library like charming could wrap those unicode characters (and yes, one can use unicode characters in CSS selectors). But this isn't as easy in Gutenberg editor - a special icon/emoji inline Gutenberg block would have to be dynamically inserted.

Related issue: https://github.com/yuanqing/charming/issues/19

strarsis commented 4 years ago

Themes should be able to offer their own icon implementations. For example, I would apply a SVG as mask and set the background-color to currentColor. Now the icons can be colored like the text. But this may be different in other themes.

munirkamal commented 4 years ago

Any info when this block would be available? This one is one of the most important design element, and I hope this can make it to the core asap. 😇

CalumChilds commented 4 years ago

Well, I think we need to clarify a few things before we can start building:

  1. How we’re going to insert the icons (I personally think inserting a HTML snippet is the best and easiest way to go as well as having a dedicated block).
  2. What default icon frameworks we’re going to include (Font Awesome/Material Icons and the default WordPress icons).
  3. How the icon directory can be searched. But, I agree with you, @munirkamal, we should implement this as soon as we possibly can (5.5 or 5.6?)
strarsis commented 4 years ago

My 2 cts:

  1. As normal block or inline block (for inserting into text, like an inline image).
  2. IMHO, now SVG icons should be used, no icon fonts.
  3. By existing unicode order/grouping?
munirkamal commented 4 years ago

I think this should be both as a block & Inline blocks.

Regarding the libraries, I would suggest integrating FontAwesome, Dash Icon by default. And have some kind of flexibility for plugin/theme devs to integrate additional libraries easily. Maybe a filter/hook approach?

CalumChilds commented 4 years ago

And have some kind of flexibility for plugin/theme devs to integrate additional libraries easily. Maybe a filter/hook approach?

Absolutely. I don’t know the difference between filters and hooks, so I’m not in a position to say which is best.

Also, something I forgot to add: we should have a list of “styles” for each icon block. This would need to be updated – Font Awesome, for example, is planning to add a few more on.

For the frameworks, we should have the default WordPress icon set, Font Awesome and Material Icons, which should cover 80% of use cases and also provides beginner/novice users a good choice of frameworks. (Although there is no harm in adding more!)

RafaelKr commented 4 years ago

For performance reasons I would suggest to only load a possibility to add custom SVG icons by default but with an option to add additional Icon packs like FontAwesome & Co. Maybe this can be implemented with an Icon Manager where you have a tab to upload (and sort?) your own Icons and a tab where external Icon packs can be enabled and disabled, comparable to the Block Manager.

aristath commented 4 years ago

We could start building this and by default only offer the dashicon SVGs... No need to add icon libraries, there's too many of them and tastes are subjective. However, we could also add a couple of PHP filters to allow extending the block.

add_filter( 'block_icons', function( $icons ) {
    $icons['fish-full'] = [
        'namespace' => 'iconmonstr',
        'category'  => [
            'animals' => __( 'Animals' ),
        ],
        'keywords'  => [ __( 'Animals' ), __( 'Fish' ) ],
        'style'     => [
            'filled' => __( 'Filled' ),
        ],
        'svg'       => '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"><path d="M21 11c0-.552-.448-1-1-1s-1 .448-1 1c0 .551.448 1 1 1s1-.449 1-1m3 .486c-1.184 2.03-3.29 4.081-5.66 5.323-1.336-1.272-2.096-2.957-2.103-4.777-.008-1.92.822-3.704 2.297-5.024 2.262.986 4.258 2.606 5.466 4.478m-6.63 5.774c-.613.255-1.236.447-1.861.573-1.121 1.348-2.796 2.167-5.287 2.167-.387 0-.794-.02-1.222-.061.647-.882.939-1.775 1.02-2.653-2.717-1.004-4.676-2.874-6.02-4.287-1.038 1.175-2.432 2-4 2 1.07-1.891 1.111-4.711 0-6.998 1.353.021 3.001.89 4 1.999 1.381-1.2 3.282-2.661 6.008-3.441-.1-.828-.399-1.668-1.008-2.499.429-.04.837-.06 1.225-.06 2.467 0 4.135.801 5.256 2.128.68.107 1.357.272 2.019.495-1.453 1.469-2.271 3.37-2.263 5.413.008 1.969.773 3.799 2.133 5.224"/></svg>',
    ];
    return $icons;
});

This way, we can start with the basics. If WooCommerce needs to add a custom icon for cart, profile or whatever, then it can just register its own icons. This will also allow plugins like font-awesome or any other icon-library to add their own icons that users can use. If the user later uninstalls one of these plugins, nothing is lost 'cause the actual SVG is what will be saved & rendered anyway in posts. The category and keywords from the icon definition & filter can be used to easier search for icons, while the style can be used to differentiate between solid/filled, outline etc.

strarsis commented 4 years ago

@aristath: Nice idea, also that themes are empowered to add their own icons. Even better, a set of default/unicode icons should be offered so the same icon can be re-used among themes, but with different SVG/image, when the theme wishes to format it. E.g. a phone icon with default image and a theme could show a vintage phone or a futuristic phone or a phone with fitting colors.

strarsis commented 4 years ago

So an icon represents a meaning, which can be visualized as an image. For better decoupling content from theme, unicode characters seem to be ideal. The theme can then either keep the default icon representation (browser or WordPress default icon imagery), or override it with its own SVG/image files / DOM element.

Example: 📞, ✉ and 📌 could be formatted differently by different themes. Skeuomorphisms aside, a theme could show them in golden SVGs, or with some shimmering effect, or Sci-Fi style. The actual meaning of these icons is content and preserved among different themes. And block styles would allow even finer control for the theme how an icon should be visually interpreted. The phone icon may be shown as an old phone and then as tin can telephone, depending on the visual meaning.

coreyworrell commented 3 years ago

Just a note, would be great if these icons were able to integrate with other blocks as well (buttons, media+text, etc).

melchoyce commented 3 years ago

Just a note, would be great if these icons were able to integrate with other blocks as well (buttons, media+text, etc).

Agreed, this would be very useful. For example, in a design like this:

image

Would love to see an icon block in core!

coreyworrell commented 3 years ago

If the user later uninstalls one of these plugins, nothing is lost 'cause the actual SVG is what will be saved & rendered anyway in posts.

This sounds good but the rendering of the block should attempt to use the SVG name first, to allow for icons to be updated, and if an icon no longer exists (plugin deactivated, etc) then it could fallback to the SVG output at the time the page was saved. Kind of like how image blocks work now, the HTML block comment includes the image ID, and the HTML inside the comment includes a fallback that is replaced when the block is successfully rendered (valid ID is found)

paaljoachim commented 3 years ago

Hello everyone

I am helping out with Learn. There are plans for a new Lesson plans landing page. https://github.com/WordPress/learn/issues/153#issuecomment-766526970

https://user-images.githubusercontent.com/2846578/101688755-79264f00-3a3a-11eb-899a-fccedd032de5.png

It would be very helpful to get the Icons block into Gutenberg, as creating the design here would be easier with an Icons block.

Screen Shot 2021-03-30 at 18 45 03

At the moment one would need to upload the icons. Then probably add a Group block which contains an Image block and a Paragraph block.

colorful-tones commented 3 years ago

SVG Icon Block would be so amazing! Inline and block and filters for themes to add their own library would be epic! Perhaps even theme.json integration as well? That would be insane 🤯

iandunn commented 3 years ago

This sounds like a great addition 👍🏻

⚠️ I'd strongly recommend that it doesn't allow users to upload custom SVGs.

That might be possible in the future, but it would be a big project on its own, and should be done with review from the Security team.

#24251-core has a lot of prior discussion on the topic. TL;DR: SVGs aren't images, they're XML documents that execute JavaScript.


Related (non-security) issues: #20284, #21538

paaljoachim commented 3 years ago

Inspiration from ThemeX and their Cornerstone builder. Screenshot 2021-09-30 at 13 50 37

cr0ybot commented 2 years ago

I've built my own icon block using the selection.json output from IcoMoon, which includes SVG paths (but not complete SVG markup). Then the SVG is dynamically built from the paths and rendered/saved—perhaps that would be preferable to a user-uploaded SVG system. It would mean that it might be difficult for users to add their own icons, but plugins could add them in the correct format.

Here's an excerpt from IcoMoon's selection.json with custom icon paths:

{
  "IcoMoonType": "selection",
  "icons": [
    {
      "icon": {
        "paths": [
          "M789.76 457.216c-14.138 0-25.6-11.462-25.6-25.6v0-36.352c0-14.138 11.462-25.6 25.6-25.6s25.6 11.462 25.6 25.6v0 36.352c0 14.138-11.462 25.6-25.6 25.6v0z",
          "M512 721.92c-87.234-0.001-157.95-70.718-157.95-157.952s70.718-157.952 157.952-157.952c86.964 0 157.514 70.28 157.95 157.142l0 0.042c0.001 0.152 0.001 0.332 0.001 0.512 0 87.286-70.687 158.063-157.939 158.208l-0.014 0zM512 457.216c-58.956 0.002-106.749 47.795-106.749 106.752s47.794 106.752 106.752 106.752c58.958 0 106.752-47.794 106.752-106.752 0-0.27-0.001-0.54-0.003-0.809l0 0.041c-0.435-58.626-48.062-105.984-106.749-105.984-0.001 0-0.002 0-0.003 0l0-0z",
          "M512 801.024c-0.076 0-0.166 0-0.255 0-131.064 0-237.312-106.248-237.312-237.312s106.248-237.312 237.312-237.312c130.884 0 237.020 105.956 237.311 236.772l0 0.028c0 0.152 0.001 0.332 0.001 0.512 0 130.974-106.103 237.167-237.043 237.312l-0.014 0zM512 377.856c-0.076-0-0.165-0-0.254-0-102.787 0-186.112 83.325-186.112 186.112s83.325 186.112 186.112 186.112c102.787 0 186.112-83.325 186.112-186.112 0-0.27-0.001-0.54-0.002-0.81l0 0.042c-0.436-102.367-83.449-185.2-185.842-185.344l-0.014-0z",
          "M812.288 867.328h-600.576c-64.785-0.146-117.248-52.698-117.248-117.504 0-0 0-0 0-0l0-0v-371.968c0-64.754 52.494-117.248 117.248-117.248v0h141.824c14.138 0 25.6-11.462 25.6-25.6v0c0-42.415 34.385-76.8 76.8-76.8v0h109.056c42.415 0 76.8 34.385 76.8 76.8v0c0 14.138 11.462 25.6 25.6 25.6v0h141.824c64.754-0 117.248 52.494 117.248 117.248v371.968c0 0.014 0 0.031 0 0.047 0 63.725-50.728 115.603-114.005 117.453l-0.171 0.004zM211.712 311.808c-36.419 0.145-65.903 29.629-66.048 66.034l-0 0.014v371.968c-0 0-0 0-0 0 0 36.529 29.54 66.158 66.034 66.303l0.014 0h600.576c36.508-0.145 66.048-29.775 66.048-66.304 0-0-0-0-0-0l-0-0v-371.968c-0.145-36.419-29.629-65.903-66.034-66.048l-0.014-0h-141.824c-42.415 0-76.8-34.385-76.8-76.8v0c0-14.138-11.462-25.6-25.6-25.6v0h-110.592c-14.138 0-25.6 11.462-25.6 25.6v0c0 42.415-34.385 76.8-76.8 76.8v0z"
        ],
        "attrs": [
          {},
          {},
          {},
          {}
        ],
        "isMulticolor": false,
        "isMulticolor2": false,
        "grid": 0,
        "tags": [
          "camera",
          "picture",
          "photo",
          "photograph",
          "photography",
          "lens"
        ]
      },
      "attrs": [
        {},
        {},
        {},
        {}
      ],
      "properties": {
        "order": 1020,
        "id": 32,
        "name": "camera",
        "prevSize": 32
      },
      "setIdx": 0,
      "setId": 3,
      "iconIdx": 0
    },
    // ...
  ]
}

A few things to note:

  1. Strokes are prohibited, only paths are allowed.
  2. Something that isn't apparent is that I believe IcoMoon normalizes icons to 1024 wide. I think that if it isn't, there is a width property available for the icon, so that the viewbox can be set.
  3. The icon is rendered as HTML and saved directly in the block's save function, so removing icons means the icon is still there until the icon is changed.
  4. I used the tags to make the icons searchable:

Screen Shot 2021-09-15 at 12 07 50 PM(1)

Screen Shot 2021-09-15 at 12 45 07 PM

I've used IcoMoon for a long time for creating custom icon packs. I'm not suggesting this icon block rely on IcoMoon's output but there might be some lessons we can learn from it.

I'd also like to vote NOT in favor of including any icon packs aside from the built-in Dashicons. Perhaps icon packs could be added as collections (again, via plugin or theme), similar to how blocks must have a namespace, so that the user could easily switch between packs if needed. An option to disable the default Dashicons pack, maybe in theme.json, would be nice too.

CalumChilds commented 2 years ago

Using an interface similar to that of IcoMoons' is a great idea.

I do disagree with you on not having any other icon packs included other than Dashicons, since it doesn't include enough variety to be useful on most websites. For this reason, I recommend including one other icon pack into WordPress. I think Font Awesome 5 Free would be best for this since it is open-source and has a wide enough variety of icons to be useful on most websites.

The selection.json format is good, although there are two things that I would add:

  1. A filter where the user could select the weight(s) they want the resulting icons to be, and the ability for plugins/themes to add their own.
  2. A feature allowing duotone icons to be added. I'm not sure how this would be done, but multiple icon frameworks have duotone icons (including IcoMoon and Font Awesome)
cr0ybot commented 2 years ago

I think Font Awesome 5 Free would be best for this since it is open-source and has a wide enough variety of icons to be useful on most websites.

You're probably right. I take back the mention of Dashicons, as I consider them deprecated at this point anyways.

Font Awesome is and has been the default icon set of the web for a while, for better or worse. It makes things a little complicated though when there is a closed, commercial aspect to the project. For example, duotone icons are only available with a Pro license. Another complicating factor is that Font Awesome 6 seems to be close.

I realize it's already been mentioned in this thread, but I think a better option is the Material Design icon set, which is what the @wordpress/icons library (note: separate from Dashicons) is based on (see https://github.com/WordPress/gutenberg/issues/20284#issuecomment-591549017) and has a set of simple guidelines that makes creating additional icons with the same look & feel somewhat simpler than Font Awesome. It also includes different styles, including duotone ("two tone"), and is completely free with no commercial aspect. I can't find a total number of icons at the moment, but I bet the number is at least close to or even surpassing the amount available from FA free.

I suppose another part of the reason I'd advocate pulling in Material over FA is that it could make the much larger icon set more readily available to theme and plugin authors that need to add icons for various reasons in the WordPress admin/editor. I realize that is only tangential to an icon library for a block but it would be useful.

AlecRust commented 2 years ago

Regarding Material Design icons (which sounds good to me) I believe this is the open source effort with a larger set:

https://materialdesignicons.com/

Used by large projects like Home Assistant.

kraftner commented 2 years ago

I think the discussion if/what icon library to include is at best tangentially relevant to this issue. What would be important is the infrastructure to add a custom set of icons as defined by the site/theme. Adding a default set may be nice but is not strictly necessary for an icon block to be useful.

CalumChilds commented 2 years ago

Regarding Material Design icons (which sounds good to me) I believe this is the open source effort with a larger set: https://materialdesignicons.com/

I would support using this icon set if it is from this website and not the official icon set from Google since the one @AlecRust included contains 26,000 icons (more than enough for an average website!) and unlike the official Google set, contains brand icons for non-Google services/products (such as the Facebook icon, which I think would be widely used within blocks.)

cr0ybot commented 2 years ago

I think the discussion if/what icon library to include is at best tangentially relevant to this issue. What would be important is the infrastructure to add a custom set of icons as defined by the site/theme. Adding a default set may be nice but is not strictly necessary for an icon block to be useful.

You're totally right. Regardless of any defaults, the big problem of how to import and store these icon sets is the thing that is most in need of a solution.

The IcoMoon example is just a data format, but it begs the question: regardless of the format, where is it stored, and how is it managed? Can a theme include a JSON file? What happens upon switching themes? Do they get imported into the database?

Jabe64 commented 2 years ago

And what about custom icons? It needs to be considered as well.

thatmikebal commented 2 years ago

Has anyone explored an experience where we use something like the media library experience to let the user browse an icon library and choose what to save to their site so they can use it?

Think about how you can select playlists for offline listening on Spotify or even movies/shows for offline viewing on streaming services.

We wouldn't limit the user's options and we wouldn't have to worry about carrying the weight of a large icon library. Having a site-specific library would also allow the user to upload custom icons.

dugyen commented 2 years ago

Just a note, would be great if these icons were able to integrate with other blocks as well (buttons, media+text, etc).

Agreed, this would be very useful. For example, in a design like this:

image

Would love to see an icon block in core!

I would agree with you.

dugyen commented 2 years ago

It would be great if we could drag and drop icons and move any position ( middle, right, left, up, down) because current option cannot let us to locate the icon where user like to position it or drag icons.

strarsis commented 2 years ago

An icon block would ideally be an inline block that can be placed not only between blocks but also inside text. Related issue: https://github.com/WordPress/gutenberg/issues/10235