First, thanks for this awesome Vue plugin.
I drew some glyph icons (.ttf; surely for those which cannot found in FontAwesome or MaterialDesign) for my project. So I'm trying to write a Vue component to wrap my icon, which can aware currently activated theme (dark
/light
) and change color for it.
Basically, for consistence, I wish it can works just like
v-icon
, with same API, maybe...
However, after hours of research, I didn't find any reliable way/API/mechanism to get the activated theme of a specific level of a HTML/Component hierarchy, for coloring the glyph icons I made.
I guess the possible way can be (may be silly, I'm not familiar the internal implementation of Vuetify):
v-app
?) to notify all children (oops, this.$broadcast
seems only available in Vue1.x; not available in Vue2.x)this.$vuetify
?.theme--dark
to the HTML element, then user can decide the color in CSS (e.g. .my-glyphicon.theme--dark { color: #fff; }
)?VIcon uses this: https://github.com/vuetifyjs/vuetify/blob/dev/src/mixins/themeable.ts#L70
If you just want to consume the current theme, simply use inject: ['theme']
and this.theme.isDark
. We could probably expose a renderless component to make this easier though.
Thanks a lot, currently inject: ['theme']
seems to work as same as what I've expected. I will keep paying attention on its behaviors on some edge cases.
A little question: when using inject: ['theme']
, how to satisfy the type checking of TypeScript without vue-class-component
?
interface Themeable extends Vue {
theme: {
isDark: boolean
}
}
export default Vue.extend<Themeable>().extend({
...
I just tried, but it broken:
BTW, currently I use a terrible workaround this['theme']['isDark']
to escape from the type checking of TypeScript
@kuanyui I think you need this.props.dark
and this.props.light
I was just trying to understand how to programmatically manipulate the theme, and themeable components, first as an exercise to make a theme switcher for the user...
Old habits die hard, and so first crack at it was this ah, rather jquery-esque (walk the dom, manipulate/toggle classes) and not so vue-esque (or reactive) approach:
<template>
<v-switch @change="switchTheme"
hint="switch theme"
append-icon="palette"
></v-switch>
</template>
<script>
export default {
inject: ['theme'],
/**
* use either this.theme.isDark or this.$vuetify.dark
*/
methods: {
switchTheme() {
const switchOff = this.$vuetify.dark ? 'theme--dark' : 'theme--light'
, switchOn = this.$vuetify.dark ? 'theme--light' : 'theme--dark'
, themed = document.getElementsByClassName( switchOff )
Array.from(themed).forEach( (el) => {
el.classList.remove( switchOff )
el.classList.add( switchOn )
})
this.$vuetify.dark = ! this.$vuetify.dark
this.theme.isDark = ! this.theme.isDark
}
}
}
</script>
Aaaand right about when I got that working, I found this theme-switching codepen, maybe shed a tear, and went to bed. 馃槀
馃憤 Point stands tho, that I had trouble finding documentation or examples of how to work with the active and available themes programmatically... at runtime.
Most helpful comment
VIcon uses this: https://github.com/vuetifyjs/vuetify/blob/dev/src/mixins/themeable.ts#L70
If you just want to consume the current theme, simply use
inject: ['theme']
andthis.theme.isDark
. We could probably expose a renderless component to make this easier though.