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

Why so explicit (the :icon="['far', 'coffee']" syntax)? #347

Closed
rentalhost opened this issue Feb 12, 2022 · 22 comments
Closed

Why so explicit (the :icon="['far', 'coffee']" syntax)? #347

rentalhost opened this issue Feb 12, 2022 · 22 comments

Comments

@rentalhost
Copy link

I would like to suggest an improvement over the icon style (or understand why not). The way it currently works is very complicated (and ugly, visually).

The documentation explains some reasons why we can't use some style with some syntaxes, but I believe the way below can solve the problem:

<font-awesome-icon icon="fas user" />

This syntax, when used, will throw an error:

- Could not find one or more icon(s) {prefix: 'fas', iconName: 'far user'} {}

If it's for performance reasons (eg having to break the string into spaces, similar to using :icon="[ 'fas', 'user' ]"), I believe that the string break could only occur a moment before this error is thrown, as a fallback. Even so, if that's really the case, breaking a string for space wouldn't actually generate any kind of performance problem, I believe.

In my vision, some could be done at this part:

if (typeof icon === 'string') {
return { prefix: 'fas', iconName: icon }
}

Something like:

  if (typeof icon === 'string') {
    const [ prefix, iconName ] = icon.split(/\s+/); 

    return iconName ? { prefix, iconName } : { prefix: 'fas', iconName: prefix }
  }
@angelhdzdev
Copy link

angelhdzdev commented Feb 15, 2022

Isn't it icon="fas fa-user" or simply icon="user"???

For me it's working with icon="eye" (I'm using faEye).

@christhofer
Copy link

christhofer commented Feb 15, 2022

@angelhdzmultimedia

icon="eye" use solid icons by default
but for other icons, you need to use :icon=['far', 'icon-name']

See documentation
image

I've created pull request #243 to allow us change the default, but unfortunately it gets closed.

@angelhdzdev
Copy link

@angelhdzmultimedia

icon="eye" use solid icons by default but for other icons, you need to use :icon=['far', 'icon-name']

See documentation image

I've created pull request #243 to allow us change the default, but unfortunately it gets closed.

I'm a bit lost. Are you trying to use reactive :icon? Or you can just use a normal icon attribute with a string?
Because it that's the case, you can just use icon="fas fa-user-secret" and not the ugly syntax you mentioned...

@angelhdzdev
Copy link

I think what you need is mask: <font-awesome-icon icon="coffee" :mask="['far', 'circle']" />

@christhofer
Copy link

christhofer commented Feb 15, 2022

@angelhdzmultimedia Just read the documentation. I'm not the one that create this "ugly" syntax.

I'm using pro license, so I can't just use icon="user-secret", I have to use :icon="['far', 'user-secret']"

I haven't tried your way icon="fas fa-user-secret", but If what you said is correct that we can use icon="far fa-user-secret", then they must have updated it, because it didn't work like that.

My pull request was to allow us change the default.
so we can just call
FontAwesomeIcon.setPrefix('far')
and then icon="user-secret" use regular icon by default instead of solid.

@angelhdzdev
Copy link

Also, you can made a custom component that wraps FontAwesomeIcon, then you can pass icon="fas fa-user-secret", and then you split that string inside your component, to an array, and pass that array to .

@angelhdzdev
Copy link

FaIcon.vue:

<template>
<FontAwesomeIcon :icon="_icon"></FontAwesomeIcon>
</template>

<script lang="ts">


  export default {
    name: 'FaIcon',
    inheritAttrs: false,
    customOptions: {},
  }
</script>

<script setup lang="ts">
import { toRefs, useAttrs, ref } from 'vue'
const {icon} = useAttrs()
const _icon = ref(String(icon).split(' '))
</script>

<style>
</style>

App.vue:

<template>
<FaIcon icon="fas eye"></FaIcon>
</template>

<script setup lang="ts">
import FaIcon from './components/FaIcon.vue'
</script>

You can use this solution while they add icon="far fa-user-secret" syntax.

I read that version 6 releases this month...

@angelhdzdev
Copy link

It's strange. The docs mention this:
image

But it causes error.

@rentalhost
Copy link
Author

Sorry for the late reply.

The @next version only uses the icon name -- at least when using library mode. So basically <font-awesome-icon icon="user" /> loads the icon fas fa-user.

import { library } from '@fortawesome/fontawesome-svg-core';

library.add(
    require('@fortawesome/pro-solid-svg-icons/faUser').definition,
    require('@fortawesome/pro-regular-svg-icons/faUser').definition
);

If I have two different styles for the same icon, I need to use an "ugly" syntax, even if the icon is not reactive -- like most cases I intend to use. Like: <font-awesome-icon :icon="[ 'far', 'user' ]" /> loads the icon far fa-user.

Thus, my suggestion is to allow that instead of an array, allow passing a string containing a space that will be broken internally as an array and proceed normally. Then <font-awesome-icon icon="far user" /> would be a direct equivalent to <font-awesome-icon :icon="[ 'far', 'user' ]" />.

I'm not the best person to do a PR with this change, but from what I've been investigating the change should occur in this file or deeper, in @fortawesome/fontawesome-svg-core.

@angelhdzdev
Copy link

Hello, no worries for the delay.

I finally understood your issue, and confirmed it. The documentation says explicitly that we can easily use icon="far fa-user-secret", but then we get an error.

This should be submitted as a BUG and not as a FEATURE REQUEST I think.

@rentalhost
Copy link
Author

@angelhdzmultimedia In fact, the vue-fontawesome documentation says to explicitly defined using array. However, the site itself shows an incompatible Vue.js code in every way:

image

<font-awesome-icon icon="fa-regular fa-file-chart-pie" />

The style is wrong (must be far, not fa-regular) and the icon name is wrong (must be file-chart-pie, not fa-file-chart-pie).

But regardless of the site's error (which would be nice to fix, in fact), the most important thing would be to make vue-fontawesome compatible with string containing the style. So the site could look like this:

<font-awesome-icon icon="far file-chart-pie" />

And not like (the confusing...):

<font-awesome-icon :icon="[ 'far', 'file-chart-pie' ]" />

@angelhdzdev
Copy link

@angelhdzmultimedia In fact, the vue-fontawesome documentation says to explicitly defined using array. However, the site itself shows an incompatible Vue.js code in every way:

image

<font-awesome-icon icon="fa-regular fa-file-chart-pie" />

The style is wrong (must be far, not fa-regular) and the icon name is wrong (must be file-chart-pie, not fa-file-chart-pie).

But regardless of the site's error (which would be nice to fix, in fact), the most important thing would be to make vue-fontawesome compatible with string containing the style. So the site could look like this:

<font-awesome-icon icon="far file-chart-pie" />

And not like (the confusing...):

<font-awesome-icon :icon="[ 'far', 'file-chart-pie' ]" />

Yeah. Completely agree. Don't know how they could miss something important like this. Not everyone want to pass the icons names dynamically...

In the meantime, you can put those in a reactive object as part of the component's state:

<button :style="styles.openDialogButton.style">
<font-awesome-icon :style="styles.openDialogButton.icon.style" :icon="styles.openDialogButton.icon.name" />
<span>{{ styles.openDialogButton.text }}</span>
</button>

const styles= reactive({
      openDialogButton: {
          icon: {
            style: {
             color: 'white'
            },
            name: [ 'far', 'file-chart-pie' ]
          },
          text: 'Open Chart',
          style: {
             background: 'primary'
          }
       }
    
});

Or even store it in a state management store like Pinia, instead of hardcoding everything.

Wish you success and health!

@robmadole
Copy link
Member

Being able to specify an icon using <font-awesome-icon icon="far file-chart-pie" /> is a new feature in @fortwesome/[email protected].

This component (vue-fontawesome) uses the new parse.icon() function found here:

https://github.com/FortAwesome/vue-fontawesome/blob/2.x/src/components/FontAwesomeIcon.js#L14

First up, @rentalhost can you tell me what version of @fortwesome/fontawesome-svg-core you are using? And have you added the icons you are trying to use to the library?

@rentalhost
Copy link
Author

@robmadole yes, that is my packages.json:

"devDependencies": {
    "@fortawesome/fontawesome-svg-core": "^1.3.0",
    "@fortawesome/vue-fontawesome": "^3.0.0-5",
    // [...]
}

I am using library.add() as well:

import { library } from '@fortawesome/fontawesome-svg-core';

library.add(
    require('@fortawesome/pro-solid-svg-icons/faUser').definition,
    require('@fortawesome/pro-regular-svg-icons/faUser').definition,
);

As for the ability to use far file-chart-pie directly (which is what I would like), I haven't been able to make it work and I haven't been able to find the source code that creates this possibility either.

I've been looking at two pieces of code:

So what I can see is that the vue-fontawesome normalization process is causing the problem, as it prevents parse.icon() from doing the complete (and possibly correct) job.

@robmadole
Copy link
Member

Ok, we'll need to get the Vue 3 version of this library updated to support v6. Thanks for the clarification.

@jasonlundien
Copy link
Member

Just wanted to give an update:

Using Vue 2.x
$ npm i --save @fortawesome/vue-fontawesome@latest

you can add icons using the string format and/or the array format:
<font-awesome-icon icon="fa-duotone fa-alien" />
<font-awesome-icon :icon="['fad', 'coffee']" />

Using Vue 3.x
$ npm i --save @fortawesome/vue-fontawesome@prerelease

currently you can only add icons using the array syntax:
<font-awesome-icon :icon="['fad', 'coffee']" />

Our next release will allow you to use either (or both) in our Vue 3.x package.

@taroy1
Copy link

taroy1 commented May 13, 2022

Thank you for that update. And when is that next release expected to be available?

@christhofer
Copy link

@jasonlundien I'd like to be able to set the default icon style.
Currently if we use <font-awesome-icon icon="coffee" />, it always defaults to solid.
I want to be able to specify the style to always default to regular.
See my pull request #243

Or even better if we can just write
<font-awesome-icon icon="fad-coffee" />

@jasonlundien
Copy link
Member

Update:

We have released updated components for both Vue 2 and Vue 3. You can now use the array and/or the string format for either component.

String
<font-awesome-icon icon="fa-solid fa-user-secret" />

Array
<font-awesome-icon :icon="['fas', 'user-secret']" />

To get our official Vue 3.x component: $ npm i --save @fortawesome/vue-fontawesome@latest-3
** the prerelease has been deprecated.

@christhofer
Copy link

@jasonlundien Is there a reason why we need to type the whole string "fa-solid fa-user-secret"? Why not shorten it to just "fas user-secret" or "fas-user-secret" like all of us here asked?

@jasonlundien
Copy link
Member

jasonlundien commented Jun 18, 2022

@christhofer

We added the string format ("fa-solid fa-user-secret") to the Vue 3 component mainly because our Vue 2 component allowed us to call icons that way, so seemed only natural and quite frankly not a huge fix.

Currently, the other ways in which you can add icons using a shortened syntax would be:
<font-awesome-icon icon="fas fa-alien" size="5x"/>
<font-awesome-icon :icon="['fas', 'alien']" size="3x"/>

We do not have the "fas user-secret" option at this time. Once the the Sharp family style has been released we can explore alternatives to calling the icons.

@jasonlundien
Copy link
Member

jasonlundien commented Jan 4, 2023

I wanted to follow up by suggesting another option we have with setting the default style.

In your main.js file, you could set the default to "duotones" by importing config:

So your main.js file would look similar to this:

/* import the fontawesome core */
import { library } from '@fortawesome/fontawesome-svg-core'

/* import font awesome icon component */
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

/* import specific icons */
import { faCoffee as fadCoffee } from '@fortawesome/pro-duotone-svg-icons'
import { faDog as fadDog } from '@fortawesome/pro-duotone-svg-icons'
import { faCoffee as fatCoffee } from '@fortawesome/pro-thin-svg-icons'

library.add(fadCoffee, fadDog, fatCoffee)

// import config so we can set a default style
import { config } from '@fortawesome/fontawesome-svg-core'

// set the default style.  I set it to "duotones" below, but it could be any one of our styles.
config.styleDefault = 'duotone'

You could then call the "duotone" icons, in this example, by:
<font-awesome-icon icon="coffee" size="3x" />
<font-awesome-icon icon="dog" size="3x" />

You would still need to call the other icons (that are NOT the default style) by using either the string or array syntax:

  • string syntax: <font-awesome-icon icon="fa-thin fa-coffee" />
  • array syntax: <font-awesome-icon :icon="['fat', 'coffee']" />

So we have a few options in which icons can be called . With that said, I am going to go ahead and close this issue "Why so explicit".

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

No branches or pull requests

6 participants