Skip to content

Commit

Permalink
Merge pull request #409 from sronveaux/vuetify-custom-icons
Browse files Browse the repository at this point in the history
Allow Vuetify custom icons
  • Loading branch information
sronveaux authored Jul 23, 2024
2 parents 41e4892 + 6c163cf commit 3a33aae
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 8 deletions.
3 changes: 2 additions & 1 deletion docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
- [Map Layers](map-layer-configuration.md)
- [Module Configuration](module-configuration.md)
- [Reusable Components](reusable-components.md)
- [Language packs](language-packs.md)
- [Language Packs](language-packs.md)
- [Custom Icons](custom-icons.md)
- [QGIS2Wegue](qgis_plugin.md)


Expand Down
34 changes: 34 additions & 0 deletions docs/custom-icons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Custom icons

Wegue allows to inject custom icons inside Vuetify. Each icon to be injected must be defined in a separate file in the `app/custom-icons` folder.

Those files should be standard `.js` files containing a default export of an `SVG` path definition. The name of the file, without the `.js` extension will be used to reference the icon afterwards.
To use a custom icon inside a component or a configuration file, you have to name it as `$vuetify.icons.myIconName`.

To integrate nicely inside Vuetify and keep the visual coherence of the whole framework, path coordinates should stay in the [0, 24] range in both horizontal and vertical directions.

## Example

Below is an example of an icon file which defines a W letter:


```js
export default 'M 23.16738,3.1894921 18.478314,20.810508 H 16.232499 L 12.802077,9.2605987 Q 12.579963,8.5695784 12.382529,7.8538789 12.209775,7.1134999 12.061699,6.5705557 11.938302,6.002932 11.913624,5.780818 11.888911,6.1016475 11.64215,7.1628586 11.395358,8.1993891 11.074526,9.3346366 L 7.7428218,20.810508 H 5.497006 L 0.83261985,3.1894921 H 3.1524731 L 5.8918748,13.949664 q 0.2961515,1.135248 0.4935859,2.196457 0.2221136,1.06121 0.3455113,1.999023 0.1233977,-0.962492 0.3701893,-2.09774 0.2467916,-1.135247 0.5676237,-2.221136 l 3.10959,-10.6367759 h 2.295174 l 3.232988,10.7108139 q 0.345511,1.135247 0.592302,2.270495 0.246792,1.135247 0.37019,1.974343 0.09872,-0.913134 0.320829,-1.974343 0.246792,-1.085889 0.542945,-2.245816 L 20.847525,3.1894921 Z'
```

If this icon file is named `app/custom-icons/WLetter.js`, it can used inside a configuration file like this:

```json
"sample-module": {
"target": "toolbar",
"win": "floating",
"icon": "$vuetify.icons.WLetter"
}
```

And to use the same icon inside of a Vue component:


```vue
<v-icon color="teal darken-2">$vuetify.icons.WLetter</v-icon>
```
16 changes: 9 additions & 7 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
// (runtime-only or standalone) has been set in vue.config.js with runtimeCompiler.
import Vue from 'vue';
import Vuetify from 'vuetify/lib/framework';
import PortalVue from 'portal-vue'
import 'roboto-fontface/css/roboto/roboto-fontface.css'
import '@mdi/font/css/materialdesignicons.css'
import 'material-icons/iconfont/material-icons.css'
import '../node_modules/ol/ol.css';
import PortalVue from 'portal-vue';
import 'roboto-fontface/css/roboto/roboto-fontface.css';
import '@mdi/font/css/materialdesignicons.css';
import 'material-icons/iconfont/material-icons.css';
import 'ol/ol.css';
import WguApp from '../app/WguApp';
import UrlUtil from './util/Url';
import IconUtil from './util/Icon';
import LocaleUtil from './util/Locale';
import ObjectUtil from './util/Object';
import ColorThemeUtil from './util/ColorTheme'
import ColorThemeUtil from './util/ColorTheme';
import axios from 'axios';

Vue.use(Vuetify);
Expand Down Expand Up @@ -50,7 +51,8 @@ const createVuetify = function (appConfig) {
const preset = {
theme: ColorThemeUtil.buildTheme(appConfig.colorTheme),
icons: {
iconfont: 'mdiSvg'
iconfont: 'mdiSvg',
values: IconUtil.importIcons()
},
lang: {
current: LocaleUtil.getPreferredLanguage(appConfig),
Expand Down
58 changes: 58 additions & 0 deletions src/util/Icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import ObjectUtil from './Object.js';

/**
* Icon related utility methods.
*/
const IconUtil = {

/**
* Import custom icons from 'app/custom-icons'. Those icons will be included
* in an object ready to be injected inside Vuetify configuration options
* object under the icons['values'] property.
*
* @returns {Object} An object containing the imported icons.
* Key is the icon name, value contains the icon.
*/
importIcons () {
const icons = {};

try {
const pathIcons = IconUtil.importPathIcons();
ObjectUtil.mergeDeep(icons, pathIcons);
} catch (e) {
console.warn('An error occured while importing the custom icons, ' +
'they will not be registered inside Vuetify. The error was: ', e);
}

return icons;
},

/**
* Import custom icons from 'app/custom-icons/*.js'. Those icons will be included
* in an object ready to be injected inside Vuetify configuration options object
* under the icons['values'] property.
* The icons must be .js files with a default export which contains an SVG path.
*
* @returns {Object} An object containing icon SVG paths.
* Key is the icon name, value contains the path.
*/
importPathIcons () {
const moduleDefaultExtractor = (i) => i.default;
const testExp = /custom-icons\/(?:.+\/)*([a-z0-9_-]+).js$/i;

const context = require.context(
'../../app',
true,
/custom-icons\/(?:.+\/)*([a-z0-9_-]+).js$/i
);
const pathIcons = {};
for (const key of context.keys()) {
const iconName = key.match(testExp)[1];
pathIcons[iconName] = moduleDefaultExtractor(context(key));
}

return pathIcons;
}
}

export default IconUtil;

0 comments on commit 3a33aae

Please sign in to comment.