Icons

Vueless supports three popular SVG icon libraries: @material-symbols, bootstrap-icons, heroicons.

if you going to use bootstrap-icons or heroicons or other weight of @material-symbols you should install needed package first.

# weight from 100 to 700 is available
npm install @material-symbols/svg-500
# or
npm install bootstrap-icons
# or
npm install heroicons

And after set the library in the config:

vueless.config.js
export default {
  component: {
    UIcon: {
      defaults: {
        library: "@material-symbols/svg-500",
        style: "outlined", // sharp | rounded | outlined
      }
    }
  }
};

Custom icons

UIcon component supports custom icons as well. To use it:

  • Import the SVG icon, with suffix ?component .

  • Pass the imported component in the :src prop.

<UIcon :src="EqualIcon" color="gray" />

<script setup>
import EqualIcon from "./images/equal.svg?component";
</script>

Dynamic import

Before the build Vueless automatically scan the project files and collects all the icons. If Vueless can't recognise the icon it may be skipped, what mean's it will be lost after build.

To avoid this behavior and include all the icons into the build, please follow rules below or add needed icons into the safelist.

<!-- ✅ this will work (string) -->
<UIcon name="close" />

<!-- ✅ this will work too (ternary operator with strings) -->
<UIcon name="isOpened ? 'arrow_up' : 'arrow_down'" />

<!-- 🛑 this won't work (variable) -->
<UIcon :name="stateIcon" />

If you need to use icon names in JS you should declare the icon names in any of JS object. If the key in the object includes icon word it will be automatically recognised by Vueless and icon will be added to the build.

<UIcon :name="stateIcon" />

<script setup>
import { computed } from "vue";

/* here is the trick */
const icons = {
  iconArrowUp: "arrow_up",
  iconArrowDown: "arrow_down",
}

const stateIcon = computed(() => isOpened ? icons.iconArrowUp : icons.iconArrowDown);
</script>

Icons safelist

if you don't want to use object approach you can simply add needed icons into the safelist.

vueless.config.js
export default {
  component: {
    UIcon: {
      safelistIcons: ["1k", "2d", "close"],
    }
  }
};

In this case regular and filled icon variants will be safelisted and added into the build.

Replace all icons at once

If you going to use bootstrap-icons or heroicons you need to replace icon names in all needed Vueless components. You can easily do that by using the config below:

vueless.config.js
export default {
  component: {
    UAccordion: {
      defaults: {
        expandIcon: "add",
        collapseIcon: "remove",
      },
    },
    UModal: {
      defaults: {
        backIcon: "arrow_back",
        closeIcon: "close",
      },
    },
    UPage: {
      defaults: {
        backIcon: "arrow_back",
      },
    },
    UDataList: {
      defaults: {
        dragIcon: "drag_indicator",
        deleteIcon: "delete",
        editIcon: "edit_note",
      },
    },
    UTable: {
      defaults: {
        expandIcon: "add",
        collapseIcon: "remove",
      },
    },
    UDropdownBadge: {
      defaults: {
        dropdownIcon: "keyboard_arrow_down",
      },
    },
    UDropdownButton: {
      defaults: {
        dropdownIcon: "keyboard_arrow_down",
      },
    },
    UDropdownLink: {
      defaults: {
        dropdownIcon: "keyboard_arrow_down",
      },
    },
    UDropdownList: {
      defaults: {
        addOptionIcon: "add",
      },
    },
    UCalendar: {
      defaults: {
        viewSwitchIcon: "keyboard_arrow_down",
        nextIcon: "keyboard_arrow_right",
        prevIcon: "keyboard_arrow_left",
      },
    },
    UCheckbox: {
      defaults: {
        partiallyCheckedIcon: "remove",
        checkedIcon: "check",
      },
    },
    UColorPicker: {
      defaults: {
        unselectedIcon: "close",
      },
    },
    UDatePickerRange: {
      defaults: {
        nextIcon: "keyboard_arrow_right",
        prevIcon: "keyboard_arrow_left",
        ownRangeIcon: "apps",
      },
    },
    UInput: {
      defaults: {
        passwordVisibleIcon: "visibility-fill",
        passwordHiddenIcon: "visibility_off-fill",
      },
    },
    UInputFile: {
      defaults: {
        chooseFileIcon: "attach_file",
        clearIcon: "close",
        removeIcon: "close",
      },
    },
    UInputNumber: {
      defaults: {
        removeIcon: "remove",
        addIcon: "add",
      },
    },
    UInputRating: {
      defaults: {
        selectedIcon: "star-fill",
        unselectedIcon: "star",
      },
    },
    UInputSearch: {
      defaults: {
        clearIcon: "close",
        searchIcon: "search",
       },
    },
    USelect: {
      defaults: {
        dropdownIcon: "expand_more",
        clearIcon: "close_small",
        clearMultipleIcon: "close_small",
      },
    },
    USwitch: {
      defaults: {
        onIcon: "check",
        offIcon: "close",
      },
    },
    UAlert: {
      defaults: {
        closeIcon: "close",
      },
    },
    UEmpty: {
      defaults: {
        emptyIcon: "emoji_food_beverage",
      },
    },
    UFile: {
      defaults: {
        fileIcon: "description",
      },
    },
    UNotify: {
      defaults: {
        successIcon: "check_circle",
        warningIcon: "warning",
        errorIcon: "error",
        closeIcon: "close",
      },
    },
  },
};

Deep tuning

Loding SVG icons provided by @vueless/plugin-vite which in turn was be inspired by vite-svg-loader .

For loading SVG @vueless/plugin-vite use SVGO by default. We created and already included optimal config to cover most of the cases, but if you will face with some issues with SVG rendering feel free to change it by passing you own config under the svgoConfig key, (see SVGO plugin docs).

vite.config.js
import { Vueless } from "@vueless/plugin-vite";

export default defineConfig({
  plugins: [
    ...
    Vueless({
      svgoConfig: {
        plugins: [
          {
            name: "preset-default",
            params: {
              overrides: {
                removeViewBox: false,
                convertColors: {
                  currentColor: true,
                },
              },
            },
          },
        ],
      },
    }),
  ],
  ...
});

Or you can disable SVGO globally as well.

vite.config.js
import { Vueless } from "@vueless/plugin-vite";

export default defineConfig({
  plugins: [
    ...
    Vueless({ svgo: false }),
  ],
  ...
});

SVGO also can be explicitly disabled for one file by adding the ?skipsvgo suffix.

<UIcon :src="IconWithoutOptimizer" />

<script setup>
import IconWithoutOptimizer from "./my-icon.svg?skipsvgo"
</script>

Last updated