Skip to content

Commit

Permalink
feat(theme): support embed theme provider and passing a function to t…
Browse files Browse the repository at this point in the history
…heme prop
  • Loading branch information
akinoccc committed Sep 21, 2024
1 parent 122e854 commit 7ef63d9
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 29 deletions.
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"provenance": true
},
"devDependencies": {
"@types/lodash-es": "^4.17.12",
"@types/stylis": "^4.2.6"
},
"dependencies": {
Expand Down
24 changes: 14 additions & 10 deletions packages/core/src/providers/theme.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import { defineComponent, h, PropType, provide, reactive, ref, watch } from 'vue'
import { defineComponent, h, PropType, provide, reactive, inject, watch } from 'vue'
import { assign, cloneDeep } from 'lodash-es'

export interface DefaultTheme {
[key: string]: any
}

export const ThemeProvider = defineComponent(
(props, { slots }) => {
const theme = ref(props.theme)
provide('$theme', reactive(theme.value as DefaultTheme))
const parentTheme = inject<DefaultTheme>('$theme', reactive({}))
const mergeTheme = (cur: DefaultTheme) => {
return typeof props.theme === 'function' ? props.theme(cloneDeep(cur)) : props.theme
}

const reactiveTheme = reactive(mergeTheme(parentTheme))

provide<DefaultTheme>('$theme', reactive(reactiveTheme))

watch(
() => props.theme,
parentTheme,
(v) => {
theme.value = v
},
{
deep: true,
assign(reactiveTheme, mergeTheme(v))
},
{ deep: true, immediate: true },
)

return () => {
Expand All @@ -27,9 +32,8 @@ export const ThemeProvider = defineComponent(
name: 'ThemeProvider',
props: {
theme: {
type: Object as PropType<DefaultTheme>,
type: [Object, Function] as PropType<DefaultTheme | ((theme: DefaultTheme) => DefaultTheme)>,
required: true,
default: () => {},
},
},
},
Expand Down
44 changes: 32 additions & 12 deletions packages/playground/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
<script setup lang="ts">
import styled from '@vue-styled-components/core'
import styled, { ThemeProvider } from '@vue-styled-components/core'
import { reactive } from 'vue'
const Test = styled('div', { color: String }).attrs<{ disabled: boolean }>({ disabled: false })`
color: ${(props) => props.color};
background: ${(props) => (props.disabled ? 'gray' : 'red')};
`
const Test2 = styled('div', { color: String }).attrs<{ disabled: boolean }>((props) => ({
disabled: props.color === 'orange',
}))`
color: ${(props) => props.color};
background: ${(props) => (props.disabled ? 'gray' : 'red')};
const Button = styled.button`
color: ${(props) => props.theme.fg};
background: ${(props) => props.theme.bg};
`
const theme = reactive({
fg: 'red',
bg: 'blue',
})
const changeTheme = () => {
if (theme.fg === 'red') {
theme.fg = 'blue'
theme.bg = 'red'
} else {
theme.fg = 'red'
theme.bg = 'blue'
}
}
</script>

<template>
<Test color="orange">666</Test>
<Test2 color="orange">666</Test2>
<ThemeProvider :theme="theme">
<Button @click="changeTheme">666</Button>
<ThemeProvider
:theme="
(t) => {
return { fg: t.bg, bg: t.fg, aa: 2111 }
}
"
>
<Button>777</Button>
</ThemeProvider>
</ThemeProvider>
</template>

<style>
Expand Down
22 changes: 15 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7ef63d9

Please sign in to comment.