Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow use of different icons via the config.yml file #1040

Open
binaryben opened this issue Jan 23, 2018 · 12 comments
Open

Allow use of different icons via the config.yml file #1040

binaryben opened this issue Jan 23, 2018 · 12 comments

Comments

@binaryben
Copy link

binaryben commented Jan 23, 2018

UPDATE: See below for a temporary workaround. Ideally someone can still make this happen via the config.yml file instead though.

 


Original Request

- Do you want to request a feature or report a bug?

Feature request

- What is the current behavior?

All icons for collections are the same. It is hard to quickly differentiate if there is a large number of collection types.

- What is the expected behavior?

Possibly through using something like font awesome instead of SVG's, allow developers to change the look of the icon next to each category in the side bar.

- Please link or paste your config.yml below if applicable.

See the addition of the icon attribute below as an example:

collections:
  - name: settings
    label: Settings
    icon: fa-cog
    files: 
      - label: Global Settings
        name: global
        file: global-settings.yml

Many users probably have font awesome cached in their browser as well if that helps.


 

Temporary Solution & Example of Output

For reference, I have added font awesome css to my site and used the web inspector to manually change the icons to see if it works. SPOILER: IT DOES! (as you would expect..)

So far all I had to do was replace the relevant SVG elements with the following:

<i class="fa fa-<<icon name>> fa-fw" aria-hidden="true"></i>

I did this by using the following javascript code placed after the react app:

<script>
    icons = [
      {"name": "cal","fa": "calendar"},
      // ...
      {"name": "settings","fa": "cogs"}
    ]

  function iconify() {
      icons.forEach(function(item) {
          var selector = "a[href$='" + item.name + "'] .nc-icon span";
          var loc = document.querySelector(selector);
          var i = document.createElement("i");
          i.classList.add("fa", "fa-fw", "fa-" + item.fa);
          i.setAttribute("aria-hidden", "true");
          if (loc) {
              while (loc.firstChild) loc.removeChild(loc.firstChild);
              loc.appendChild(i);
          }
      })
  }

  var observer = new MutationObserver(function(changes) {
      iconify();
  });

  var init = new MutationObserver(function(changes) {
      var exists = !!document.querySelector(".nc-app-main div");

      if (exists) {
          iconify();
          observer.observe(document.querySelector('.nc-app-main div'), {
              childList: true
          });
          init.disconnect();
      }
  });

  init.observe(document.querySelector('body'), {
      childList: true
  });
</script>

...and put the following in my HTML header:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<link href="https://unpkg.com/netlify-cms/dist/cms.css" rel="stylesheet" />
<style>
    .nc-collectionPage-sidebarLink i {
        font-size: 19px;
        line-height: 24px;
        margin-left: -1px;
    }
</style>

... which results in this:

screen shot 2018-01-24 at 9 36 42 pm

This is exactly the type of output I am hoping for from this feature request. Unfortunately I don't have any time for a little while to try and integrate these better myself, but this might help someone else in the mean time?

P.S. This workaround only works in modern browsers due to use of MutationObserver. I'm also not sure how efficient it is.. feedback appreciated!

@erquhart
Copy link
Contributor

erquhart commented Jan 23, 2018

At a minimum we could accept an icon name from the CMS' built in collection (we have a cog). Makes sense to me, just need to document those icons.

Thoughts, anyone?

@binaryben
Copy link
Author

The cog was just given as an obvious example, but glad it is there. Also noticed a bunch of other icons that cover 50% of my needs, which is promising - but I think there is still value in adding other sources for icons as options?

Maybe we could use the existing icons to get something up faster, but it shouldn't be too hard to add a pattern check to allow alternatives after that. Documentation is arguably as simple as adding it to the list of collection objects available to every collection at this link:

  • icon: use a different icon to identify the collection in the editor UI; use the name of any existing icon (don't add the .svg extension; defaults to icon: write), any Font Awesome icon (e.g. icon: fa-cog) if you have FA installed on your admin page, or any publicly available square SVG (e.g. icon: /admin/link-to-file.svg)

 

Knowing where to load the relevant sprite from:

  • fa-*: load a font awesome placeholder
  • *.svg: it's an externally referenced SVG file
  • fallback: assume a built in icon

Honestly, if someone mistypes (not that I know anything about that.. haha) and no icon shows up, it's on the developer. So not much checking beyond that should be needed.

 

Example documentation for installing Font Awesome:

Can add the following to this page for showing users how to "install" font-awesome if they want to use it.

Make sure to include <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" /> before your own styles if you want to use custom icons in the Netlify CMS user interface

 

Bonus points if Netlify CMS can instead dynamically load Font Awesome if it detects it is needed (so no user installation on the admin page; also good for use in custom widgets potentially?) or if the team decide to use Font Awesome for their fonts!

@binaryben
Copy link
Author

binaryben commented Jan 24, 2018

I have updated OP with a temp. solution.

@erquhart
Copy link
Contributor

Your workaround is pretty cool, nice work :)

I definitely see the value of allowing other icons to be used, but I'd rather not favor one lib (e.g. font awesome) over others. I think we're on the same page with the outcome, but more consideration is needed to figure out the right abstraction. Should be maximally compatible with icon libraries without making things too messy.

@cdeath
Copy link

cdeath commented Oct 6, 2018

CSS-only workaround with icon font:

Choose your favorite icon font or generate your own (FortAwesome, IcoMoon, etc...) and include it the cms page:

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">

This example uses Font Awesome:

aside a span {
  display: inline-flex !important;
  justify-content: center;
  align-items: center
}

aside a span svg {
  display: none !important;
}

aside a span::before {
  font-family: "Font Awesome 5 Free";
  font-size: 1rem;
}

aside a[href="#/collections/posts"] span::before {
  content: "\f5a1";
}

aside a[href="#/collections/pages"] span::before {
  content: "\f15c";
}

aside a[href="#/collections/sections"] span::before {
  content: "\f550";
}

aside a[href="#/collections/menus"] span::before {
  content: "\f0e8";
}

aside a[href="#/collections/people"] span::before {
  content: "\f2b9";
}

aside a[href="#/collections/settings"] span::before {
  content: "\f085";
}

You have to pick which character is assigned to the icon you want in your font and use it as the content of the pseudo-element.

Use more or less specific selectors as you see fit.

Result:

screen shot 2018-10-06 at 02 00 56

If you don't want to use an icon font, you can use an SVG sprite or individual SVG files, you just have to set them as a background of the pseudo-elements.

@m2creates
Copy link

If you are using the free version of Font Awesome 5 double check your font weight! I fixed my custom icons following cdeath's guide with a minor addition (after much head-desking).

aside a span::before {
  font-family: "Font Awesome 5 Free";
  font-size: 1rem;
  /* Regular (400) only includes some icons. Solid (900) has the rest of the free ones */
  font-weight: 900;
}

@stale
Copy link

stale bot commented Oct 29, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@hacknug
Copy link

hacknug commented Nov 4, 2019

Please, be a good bot and don't close this. @erquhart promised us changes soon. Let him close it when it's time 🙂

@stale stale bot removed the status: stale label Nov 4, 2019
@hanneskuettner
Copy link
Contributor

Is it worth checking out how to integrate react-icons since they seem to support all of the most common icon libraries out there?

We could possible build a icon library registry that we use internally and expose to the user to register their own icon libraries if they really wanted to.

Something like

const myIconLibrary {
  prefix: "mi",
  get: (name) => <MyIcon name={name} />
}

CMS.registerIconLibrary(myIconLibrary)

and in the configuration icons could be referenced like mi/cog or in the case of all supported react-icons icon libraries, eg. fa/FaAccessibleIcon.

@austincondiff
Copy link
Collaborator

austincondiff commented May 15, 2020

Regarding #2557, I am using the open source Feather icon set with a few additions of my own. In this redesign I planned to allow to specify the icon used for each collection by specifying the name in config.yml like this.

collections:
  - name: posts
    label: Posts
    icon: pin

We could default to this set and allow for custom icons or entire icon sets to be used.

@hanneskuettner
Copy link
Contributor

I love feather icons. They would make a great default. Also they come with the react-icons package as well.

I just don't know how we would incorporate your additions. Are they intended to be used internally or with user defined collections as well?

I think then we should add something like a default icon library so the user can drop the fi prefix (or any other for that matter) and just use the icon names.

@austincondiff
Copy link
Collaborator

@hanneskuettner Check out our Icon story in storybook here. Also look at the ui-default package in the v3-ui-redesign branch.

As you can see right now they are all react components but maybe we could be handling that better. I am not including the Feather icons package because I wanted to do my own and include them. But now that I think about it, we might just use our icon as a proxy and only include custom icons. Maybe not though. I think I did it this way to allow for more flexibility. If you have any input here I’m all ears!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants