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

Alias for icons #28

Open
ange007 opened this issue Dec 26, 2022 · 2 comments
Open

Alias for icons #28

ange007 opened this issue Dec 26, 2022 · 2 comments

Comments

@ange007
Copy link

ange007 commented Dec 26, 2022

Hi.
Is it possible to somehow implement an icon alias to be able to use a set of icons with the same name from different sources?

Example:

import { FaQrcode, FaWifi, FaBluetoothB, FcNfcSign, RiGpsLine } from "oh-vue-icons/icons";

addIcons({
  'qr': FaQrcode, 
  'wifi': FaWifi, 
  'nfc': FcNfcSign, 
  'gps': RiGpsLine
});
<v-icon name="qr" />
<v-icon name="nfc" />
<v-icon name="gps" />
@Ryomasao
Copy link

Ryomasao commented Dec 28, 2022

I accomplished that by wrapping v-icon.

import { addIcons } from "oh-vue-icons";
import { FaFlag, MdDaterangeOutlined } from "oh-vue-icons/icons";

export const ICONS_ALIASES = {
  flag: ["fa-flag", FaFlag],
  date: ["md-daterange-outlined", MdDaterangeOutlined],
} as const;

export const ICON_NAMES = Object.keys(ICONS_ALIASES);

export const registerIcons = () => {
  const vueIcons = Object.entries(ICONS_ALIASES).map(([_, v]) => v[1]);
  addIcons(...vueIcons);
};

Icon.vue

<script setup lang="ts">
import { computed } from "vue";
import { OhVueIcon } from "oh-vue-icons";
import { ICONS_ALIASES } from "./registerIcons";

const props = 
  defineProps<{
    name: keyof typeof ICONS_ALIASES;
  }>();

// resolve actual name
const vueIconName = computed(() => ICONS_ALIASES[props.name][0]);
</script>

<template>
  <OhVueIcon :name="vueIconName" />
</template>

@ange007
Copy link
Author

ange007 commented Apr 7, 2023

Hi, @Ryomasao.
I try, but for some reason it doesn't work ...
Although I started doing it at the moment of moving from Webpack to Vite, maybe that is also a matter.

But for any variants always one error (even if the icon is added directly):
image
image

index.js

import Vue from 'vue';
import { OhVueIcon } from "oh-vue-icons";

import IconTemplate from './Template.vue';
import { registerIcons } from "@/components/oh-vue-icons/icons.ts";

registerIcons();
Vue.component('v-icon', OhVueIcon);
Vue.component('oh-icon', IconTemplate);

icons.ts

import { addIcons } from "oh-vue-icons";
import { IconType } from "oh-vue-icons/types/icons";

import { MdQrcode, MdWifi, MdBluetooth, MdNfc, MdGpsfixed } from "oh-vue-icons/icons/md";

export const ICON_SETS = {
    tags: {
        qr: MdQrcode,
        wifi: MdWifi,
        bluetooth: MdBluetooth,
        nfc: MdNfc,
        gps: MdGpsfixed,
    }
};

export const getIcon = (collection, name): IconType => {
    const collectionList = ICON_SETS[collection] ?? {};
    return collectionList[name] ?? {};
}

export const getIconName = (collection, name): string => {
    const icon = getIcon(collection, name);
    return icon?.name ?? '';
}

export const registerIcons = () => {
    let icons = [];

    for (const iconCollectionKey in ICON_SETS) {
        const iconCollection = ICON_SETS[iconCollectionKey];

        for (const iconKey in iconCollection) {
            const iconComponent = iconCollection[iconKey];

            icons.push(iconComponent);
        }
    }

    addIcons(...icons);
};

Template.vue

<template>
    <span>
        <!-- 
        <svg
            aria-hidden="true"
            :width="icon.width"
            :height="icon.height"
            :viewBox="icon.box"
            effect="true"
            fill="currentColor"
            :x="icon.minX"
            :y="icon.minY"
            class="value effect"
            v-html="icon.raw"
        /> 
        -->
        {{ iconName }}
        <v-icon name="md-qrcode" />
        <v-icon :name="iconName" />
        <!--
        <OhVueIcon name="fa-flag" />
        <OhVueIcon
            :name="iconName"
            :title="title"
            :label="label"
            :hover="hover"
            :inverse="inverse"
        />
        -->
    </span>
</template>

<script lang="ts">
    import Vue from 'vue';
    import { OhVueIcon } from "oh-vue-icons";
    import { IconType } from "oh-vue-icons/types/icons";

    import { getIcon, getIconName } from "./icons";

    export default Vue.extend({
        name: 'oh-icon',

        components: {
            OhVueIcon
        },

        props: {
            collection: String,
            name: String,

            title: String,
            label: String,
            hover: Boolean,
            inverse: Boolean,
        },

        computed: {
            icon(): IconType {
                if (!this.collection || !this.name) {
                    return null;
                }

                let icon = this.getIcon(this.collection, this.name);
                console.log(icon);

                return icon;
            },

            iconName(): string {
                if (!this.collection || !this.name) {
                    return '';
                }

                let icon = this.getIconName(this.collection, this.name);
                console.log(icon);

                return icon;
            }
        },

        setup() {
            return {
                getIcon,
                getIconName,
            }
        }
    })
</script>

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

2 participants