Skip to content

feat: add vue icons - #294

Merged
sammarks merged 4 commits into
iconoir-icons:mainfrom
Scalamando:main
May 3, 2023
Merged

feat: add vue icons#294
sammarks merged 4 commits into
iconoir-icons:mainfrom
Scalamando:main

Conversation

@Scalamando

Copy link
Copy Markdown
Contributor

Closes #124

Adds Vue components for each icon and a <IconoirProvider :icon-props="{...}" /> to match the features of the React package.

It also adds support for both Vue 2 and Vue 3, thanks to the vue-demi package.

I've still got a couple of issues:

IconoirProvider prop names

The iconProps prop uses the SVGAttributes type, which doesn't use camelCase. This leads to the following code:

<IconoirProvider
  :icon-props="{
    'stroke-width': 1.5,
    ...
  }"
>...</IconoirProvider>

Is this okay or would you prefer camelCase props?

Build file structure

Currently, the buildVue.js file is located in /bin, which may not be the most optimal location. Any suggestions on how to structure this?

Package.json exports

I added the "./*" exports field to the package.json file to allow for individual exports of icons. However, it seems that Typescript doesn't work well with this format, as mentioned in issue #243. Should we still keep this field?

This is my first feature PR so any feedback is greatly appreciated!

@sammarks sammarks left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thank you for getting the ball rolling on this!

I am fine with the props being kebab-case instead of camelCase, as long as it's consistent with what Vue users are expecting. So if Vue users expect them to be kebab-case, let's leave them that way. If they're expecting camelCase, let's update them to be camel case.

On the exports field, I'm of the opinion that the best approach for now would be to preserve support for TS, and then we can address the exports issue at the same time we re-approach it for the React packages (once TS decides to be a little friendlier).

So I would setup the exports to mirror the React packages for now (with support for ESM packages, etc), and then we can address the individual package export issues later, as part of the issue you mentioned. It's also important to make sure we still support both ESM + CommonJS, just like the React packages do.

I've reviewed the build script, and that all looks great as well.

Comment thread README.md Outdated

## Vue

A Vue library is available to install under the name `iconoir-vue`. For more details, see the package [README](./packages/iconoir-vue).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lucaburgio / @paescuj should confirm but I believe we decided whenever any new packages are to be released, we'll have them named with an organization prefix.

Can you rename any mention of iconoir-vue with @iconoir/vue instead?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, please 😍

@Scalamando

Copy link
Copy Markdown
Contributor Author

All issues except the prop casing should be fixed now.

While I'd guess that camelCase is a bit more idiomatic, SVG has a mix of camelCase and kebab-case attributes. Therefore, we'd need to manually transform the kebab-case attributes from camelCase back to kebab-case, which feels a little cumbersome:

interface Props {
    iconProps: CamelCaseSVGAttributes;
}
const props = defineProps<Props>();

const kebabCaseProps = { 
    "accentHeight": "accent-height",
    "alignmentBaseline": "alignment-baseline",
    "arabicForm": "arabic-form",
    ...
};

const transformedProps = computed(() => {
    const kebabCaseKeys = Object.keys(kebabCaseProps);
    const result = {};

    for(const key of Object.keys(props.iconProps)) {
        if (kebabCaseKeys.includes(key)) {
            result[kebabCaseProps[key]] = props.iconProps[key];
        } else {
            result[key] = props.iconProps[key];
        }
    }

    return result;
});

provide(providerKey, transformedProps);

Do you have any better ideas?

@sammarks sammarks left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say we just leave the props as-is, that way it's similar to what you would be expecting if you're using SVG inside Vue.

It all looks good to me! I will merge this at some point this week and get this automatically publishing to NPM, and then will post back here when it's done!

Thank you for the help on this one!

@sammarks
sammarks merged commit fb28018 into iconoir-icons:main May 3, 2023
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

Successfully merging this pull request may close these issues.

[FEAT] Vue Library

3 participants