To implement this consistently I added the SVG files folder from this repository: https://github.com/material-icons/material-icons directly to our kolibri-components
package in Kolibri. This gives the kolibri-components
package a reliable place from which to read the SVGs when used across products.
The other primary change is to use the file-svg
directive provided by the svg-icon-inline-loader
package here.
The folders are named and laid out differently than before. No longer are there "categories" - there is just one huge directory with folders named after the icons themselves. Inside are various styles such as baseline.svg
or outline.svg
.
See this commit on my fork to see the changes made to KIcon
. This is a change to using file-svg
rather than mat-svg
and adds all of those SVGs to the package.
By installing this new version of the kolibri-components
in Studio, we are able to use KIcon
the same as we do in Kolibri.
Additionally, we need to install the svg-icon-inline-loader
and update the webpack.config.js
file as it is here. There is a branch with this committed I'll share later in the 'how to test' section.
Now you may use KIcon
in the frontend/shared/Sandbox.vue
(or anywhere in Studio) by importing import KIcon from 'kolibri-components/src/KIcon.vue';
.
The mat-svg
directive is used extensively throughout Kolibri code (~240x). It would be an easy enough task to change them to use KIcon
instead if that doesn't cause issues with styling.
The reason why file-svg
works in KIcon is because the folder of SVG files actually live in the same directory.
For this reason, file-svg
will not work elsewhere in Studio code unless the targeted SVG is in the same directory as the component in which it is used OR the directory is explicitly given (relative paths work but are hideous... src="../../../../../node_modules/kolibri-components/src/svg/ICON/STYLE.svg
).
Is KIcon
not used in Kolibri where mat-svg
is used due to the svg-icon-inline-loader
coming before KIcon
did? Or is it because KIcon
doesn't meet certain design requirements? Or is it some other reason?
If Studio needs file-svg
for instances where KIcon
isn't sufficient, then we may need to take another approach.
What is the other approach?
We could add the SVGs directly to the svg-icon-inline-loader
and rewrite the file-svg
directive to specifically load those files.
Why wasn't that the first approach?
I felt like having the dependency of the SVG files in the kolibri-components
package made more sense for the purposes of the goal of "Making KIcon work regardless of where kolibri-components
is installed".
I also didn't think of it until after implementing the current solution. Pending feedback it shouldn't be a heavy lift to make the necessary changes.
svg-icon-inline-loader
ought to probably be a dependency of kolibri-components
. It is currently included in Kolibri because it is a dependency of kolibri-tools
but if we want these packages to be self-contained, having it defined in both packages makes sense.
Additionally, doing this would remove the need to yarn add svg-icon-inline-loader
in Studio
NOTE: JACOB
refers to whatever name you gave to my remote fork of the repo. If you haven't already:
cd /path/to/studio
git add remote JACOB git@github.com:nucleogenesis/studio.git
cd ../path/to/kolibri
git add remote JACOB git@github.com:nucleogenesis/kolibri.git
git checkout JACOB/svg-inline-file
git fetch JACOB
git checkout JACOB/inline-svgs
yarn add svg-inline-file
yarn add ../path/to/kolibri/packages/kolibri-components
Update the frontend/shared/Sandbox.vue
file with something like:
<template>
<div>
<KIcon icon="correct" color="blue" />
<file-svg src="../../../../../node_modules/kolibri-components/src/svg/warning/baseline.svg" />
</div>
</template>
<script>
import TemplateComponent from '../../channelEdit/views/template/Template';
import KIcon from 'kolibri-components/src/KIcon.vue';
export default {
name: 'Sandbox',
components: {
TemplateComponent,
KIcon,
},
};
</script>
<style lang="sass" scoped>
svg {
position: relative;
top: 0.125em;
width: 1.125em;
height: 1.125em;
}
</style>
Run that devserver and go to http://localhost:8080/sandbox and if that doesn't work, make sure you're logged in by going to the root path on the server then back to the sandbox. Right click the icon you see and inspect element and BOOM... inline svgs.