Skip to content

Commit d6c4db1

Browse files
committed
feat(attrs): support passing a function to generate attrs
1 parent 5e32b20 commit d6c4db1

File tree

2 files changed

+27
-20
lines changed

2 files changed

+27
-20
lines changed

packages/core/src/styled.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
ref,
1212
watch,
1313
HTMLAttributes,
14+
computed,
1415
} from 'vue'
1516
import domElements, { type SupportedHTMLElements } from '@/src/constants/domElements'
1617
import { type ExpressionType, generateClassName, generateComponentName, insertExpressions, injectStyle, removeStyle } from '@/src/utils'
@@ -33,14 +34,16 @@ interface StyledComponent<T extends object> {
3334
)[]
3435
): DefineSetupFnComponent<{ as?: string; props?: P } & ExtractPropTypes<PropsDefinition<T>> & HTMLAttributes>
3536

36-
attrs<A extends object>(attrs: A): StyledComponent<A & T>
37+
attrs<A = object>(
38+
attrs: A | ((props: ExtractPropTypes<PropsDefinition<T>>) => A),
39+
): StyledComponent<A & ExtractPropTypes<PropsDefinition<T>>>
3740
}
3841

3942
function baseStyled<T extends object>(target: string | InstanceType<any>, propsDefinition?: PropsDefinition<T>): StyledComponent<T> {
4043
if (!isValidElementType(target)) {
4144
throw Error('The element is invalid.')
4245
}
43-
let attributes = {}
46+
let defaultAttrs: unknown
4447
function styledComponent<P>(
4548
styles: TemplateStringsArray,
4649
...expressions: (
@@ -53,7 +56,7 @@ function baseStyled<T extends object>(target: string | InstanceType<any>, propsD
5356
}
5457

5558
styledComponent.attrs = function <A extends object>(attrs: A) {
56-
attributes = attrs
59+
defaultAttrs = attrs
5760
return styledComponent
5861
}
5962

@@ -69,14 +72,25 @@ function baseStyled<T extends object>(target: string | InstanceType<any>, propsD
6972
const componentName = generateComponentName(type)
7073
return defineComponent(
7174
(props, { slots }) => {
75+
const internalAttrs = computed<Record<string, any>>(() => {
76+
if (typeof defaultAttrs === 'function') {
77+
return defaultAttrs(props)
78+
}
79+
if (typeof defaultAttrs === 'object') {
80+
return defaultAttrs
81+
}
82+
return {}
83+
})
84+
7285
const tailwindClasses = ref<string[]>([])
73-
const internalProps = ref({ class: '', ...attributes })
86+
const internalProps = ref({ class: '', ...internalAttrs.value })
7487
const theme = inject<Record<string, string | number>>('$theme', reactive({}))
88+
7589
let context = {
7690
theme,
7791
...props,
7892
...props.props,
79-
...attributes,
93+
...internalAttrs.value,
8094
}
8195

8296
const defaultClassName = generateClassName()
@@ -109,7 +123,6 @@ function baseStyled<T extends object>(target: string | InstanceType<any>, propsD
109123
)
110124

111125
onMounted(() => {
112-
console.log(internalProps.value)
113126
tailwindClasses.value = injectStyle(defaultClassName, cssWithExpression, context)
114127
})
115128

packages/playground/src/App.vue

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,21 @@
11
<script setup lang="ts">
2-
import { styled } from '@vue-styled-components/core'
2+
import styled from '@vue-styled-components/core'
33
4-
const TestProps = styled.div<{
5-
color: string
6-
}>`
4+
const Test = styled('div', { color: String }).attrs<{ disabled: boolean }>({ disabled: false })`
75
color: ${(props) => props.color};
6+
background: ${(props) => (props.disabled ? 'gray' : 'red')};
87
`
9-
10-
const Test = styled('div', { color: String })`
8+
const Test2 = styled('div', { color: String }).attrs<{ disabled: boolean }>((props) => ({
9+
disabled: props.color === 'orange',
10+
}))`
1111
color: ${(props) => props.color};
12+
background: ${(props) => (props.disabled ? 'gray' : 'red')};
1213
`
1314
</script>
1415

1516
<template>
1617
<Test color="orange">666</Test>
17-
18-
<TestProps
19-
:props="{
20-
color: 'red',
21-
}"
22-
>
23-
tttttttt
24-
</TestProps>
18+
<Test2 color="orange">666</Test2>
2519
</template>
2620

2721
<style>

0 commit comments

Comments
 (0)