1
1
import {
2
+ ComponentObjectPropsOptions ,
3
+ ExtractPropTypes ,
2
4
defineComponent ,
3
- DefineSetupFnComponent ,
4
5
h ,
5
6
inject ,
6
7
onMounted ,
7
8
onUnmounted ,
8
- PropType ,
9
- PublicProps ,
10
9
reactive ,
11
10
ref ,
12
- SlotsType ,
13
11
watch ,
14
12
} from 'vue'
15
13
import domElements , { type SupportedHTMLElements } from '@/src/constants/domElements'
16
14
import { type ExpressionType , generateClassName , generateComponentName , insertExpressions , injectStyle , removeStyle } from '@/src/utils'
17
15
import { isStyledComponent , isValidElementType , isVueComponent } from '@/src/helper'
18
16
import { DefaultTheme } from './providers/theme'
19
17
20
- interface IProps {
21
- as ?: PropType < SupportedHTMLElements >
22
- }
23
-
24
- type ComponentCustomProps = PublicProps & {
25
- styled : boolean
26
- }
27
-
28
- export type StyledComponentType < P = any > = DefineSetupFnComponent < IProps & P , any , SlotsType , IProps & P , ComponentCustomProps >
29
-
30
- type StyledFactory = < T = Record < string , any > > (
31
- styles : TemplateStringsArray ,
32
- ...expressions : ( ExpressionType < T & { theme : DefaultTheme } > | ExpressionType < T & { theme : DefaultTheme } > [ ] ) [ ]
33
- ) => StyledComponentType
34
- type StyledComponent = StyledFactory & {
35
- attrs : < T extends Record < string , unknown > > ( attrs : T ) => StyledFactory
36
- }
37
18
type Attrs = Record < string , any >
38
19
39
- function baseStyled < P extends Record < string , any > > ( target : string | InstanceType < any > , propsDefinition ?: P & IProps ) : StyledComponent {
20
+ type BaseContext < T > = T & { theme : DefaultTheme }
21
+ type PropsDefinition < T > = {
22
+ [ K in keyof T ] : T [ K ]
23
+ }
24
+ function baseStyled < T extends object > ( target : string | InstanceType < any > , propsDefinition ?: PropsDefinition < T > ) {
40
25
if ( ! isValidElementType ( target ) ) {
41
26
throw Error ( 'The element is invalid.' )
42
27
}
43
28
let attributes : Attrs = { }
44
- function styledComponent < T > (
29
+ function styledComponent < P > (
45
30
styles : TemplateStringsArray ,
46
- ...expressions : ( ExpressionType < T > | ExpressionType < T > [ ] ) [ ]
47
- ) : StyledComponentType {
48
- const cssStringsWithExpression = insertExpressions < T > ( styles , expressions )
49
- return createStyledComponent < T > ( cssStringsWithExpression )
31
+ ...expressions : (
32
+ | ExpressionType < BaseContext < P & ExtractPropTypes < PropsDefinition < T > > > >
33
+ | ExpressionType < BaseContext < P & ExtractPropTypes < PropsDefinition < T > > > > [ ]
34
+ ) [ ]
35
+ ) {
36
+ const cssStringsWithExpression = insertExpressions ( styles , expressions )
37
+ return createStyledComponent < P > ( cssStringsWithExpression )
50
38
}
51
39
52
- styledComponent . attrs = function < T extends Record < string , any > > ( attrs : T ) : StyledComponent {
40
+ styledComponent . attrs = function < A extends Attrs = Record < string , any > > ( attrs : A ) {
53
41
attributes = attrs
54
42
return styledComponent
55
43
}
56
44
57
- function createStyledComponent < T > ( cssWithExpression : ExpressionType < T & { theme : DefaultTheme } > [ ] ) : StyledComponentType {
45
+ function createStyledComponent < P > ( cssWithExpression : ExpressionType < any > [ ] ) {
58
46
let type : string = target
59
47
if ( isVueComponent ( target ) ) {
60
48
type = 'vue-component'
@@ -96,15 +84,15 @@ function baseStyled<P extends Record<string, any>>(target: string | InstanceType
96
84
...props ,
97
85
...props . props ,
98
86
}
99
- tailwindClasses . value = injectStyle < T & { theme : DefaultTheme } > ( defaultClassName , cssWithExpression , context )
87
+ tailwindClasses . value = injectStyle ( defaultClassName , cssWithExpression , context )
100
88
} ,
101
89
{
102
90
deep : true ,
103
91
} ,
104
92
)
105
93
106
94
onMounted ( ( ) => {
107
- tailwindClasses . value = injectStyle < T & { theme : DefaultTheme } > ( defaultClassName , cssWithExpression , context )
95
+ tailwindClasses . value = injectStyle ( defaultClassName , cssWithExpression , context )
108
96
} )
109
97
110
98
onUnmounted ( ( ) => {
@@ -127,13 +115,15 @@ function baseStyled<P extends Record<string, any>>(target: string | InstanceType
127
115
name : componentName ,
128
116
props : {
129
117
as : {
130
- type : String as PropType < SupportedHTMLElements > ,
118
+ type : String ,
119
+ required : false ,
131
120
} ,
132
121
props : {
133
- type : Object as PropType < P > ,
122
+ type : Object ,
123
+ required : false ,
134
124
} ,
135
125
...propsDefinition ,
136
- } ,
126
+ } as ComponentObjectPropsOptions < { as ?: string ; props ?: P } & ExtractPropTypes < PropsDefinition < T > > > ,
137
127
inheritAttrs : true ,
138
128
} ,
139
129
)
@@ -144,7 +134,7 @@ function baseStyled<P extends Record<string, any>>(target: string | InstanceType
144
134
145
135
/** Append all the supported HTML elements to the styled properties */
146
136
const styled = baseStyled as typeof baseStyled & {
147
- [ E in SupportedHTMLElements ] : StyledComponent
137
+ [ E in SupportedHTMLElements ] : ReturnType < typeof baseStyled >
148
138
}
149
139
150
140
domElements . forEach ( ( domElement : SupportedHTMLElements ) => {
0 commit comments