Skip to content

Commit e9362d3

Browse files
authored
Merge pull request #11 from v-vibe/feat/core-styled
feat(core): [styled] support passing type def for props
2 parents 76c740a + 691be76 commit e9362d3

File tree

18 files changed

+521
-122
lines changed

18 files changed

+521
-122
lines changed

core/helper/css.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { type ExpressionType, insertExpressions } from '@/utils'
22

3-
export function css(strings: TemplateStringsArray, ...interpolations: ExpressionType[]): ExpressionType[] {
4-
return insertExpressions(strings, interpolations)
3+
export function css<T>(strings: TemplateStringsArray, ...interpolations: ExpressionType<T>[]): ExpressionType<T>[] {
4+
return insertExpressions<T>(strings, interpolations)
55
}

core/styled.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,34 @@ type ComponentCustomProps = PublicProps & {
1515

1616
export type StyledComponentType = DefineSetupFnComponent<IProps, any, SlotsType, any, ComponentCustomProps>
1717

18-
type StyledFactory = (styles: TemplateStringsArray, ...expressions: (ExpressionType | ExpressionType[])[]) => StyledComponentType
18+
type StyledFactory = <T = Record<string, any>>(
19+
styles: TemplateStringsArray,
20+
...expressions: (ExpressionType<T> | ExpressionType<T>[])[]
21+
) => StyledComponentType
1922
type StyledComponent = StyledFactory & {
2023
attrs: <T extends Record<string, unknown>>(attrs: T) => StyledFactory
2124
}
22-
type Attrs = Record<string, unknown>
25+
type Attrs = Record<string, any>
2326

2427
function baseStyled(target: string | InstanceType<any>, propsDefinition: Record<string, unknown> = {}): StyledComponent {
2528
if (!isValidElementType(target)) {
2629
throw Error('The element is invalid.')
2730
}
2831
let attributes: Attrs = {}
29-
const styledComponent: StyledComponent = function styledComponent(
32+
function styledComponent<T>(
3033
styles: TemplateStringsArray,
31-
...expressions: (ExpressionType | ExpressionType[])[]
34+
...expressions: (ExpressionType<T> | ExpressionType<T>[])[]
3235
): StyledComponentType {
33-
const cssStringsWithExpression = insertExpressions(styles, expressions)
34-
return createStyledComponent(cssStringsWithExpression)
36+
const cssStringsWithExpression = insertExpressions<T>(styles, expressions)
37+
return createStyledComponent<T>(cssStringsWithExpression)
3538
}
3639

37-
styledComponent.attrs = function <T extends Record<string, unknown>>(attrs: T): StyledComponent {
40+
styledComponent.attrs = function <T extends Record<string, any>>(attrs: T): StyledComponent {
3841
attributes = attrs
3942
return styledComponent
4043
}
4144

42-
function createStyledComponent(cssWithExpression: ExpressionType[]): StyledComponentType {
45+
function createStyledComponent<T>(cssWithExpression: ExpressionType<T>[]): StyledComponentType {
4346
let type: string = target
4447
if (isVueComponent(target)) {
4548
type = 'vue-component'
@@ -70,11 +73,11 @@ function baseStyled(target: string | InstanceType<any>, propsDefinition: Record<
7073
theme,
7174
...props,
7275
}
73-
injectStyle(className, cssWithExpression, context)
76+
injectStyle<T>(className, cssWithExpression, context)
7477
})
7578

7679
onMounted(() => {
77-
injectStyle(className, cssWithExpression, context)
80+
injectStyle<T>(className, cssWithExpression, context)
7881
})
7982

8083
// Return the render function

core/utils/injectStyle.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function insert(className: string, cssString: string) {
3939
insertedRuleMap[className] = cssTextNode
4040
}
4141

42-
export function injectStyle(className: string, cssWithExpression: ExpressionType[], context: Record<string, any>): void {
42+
export function injectStyle<T>(className: string, cssWithExpression: ExpressionType<T>[], context: Record<string, any>): void {
4343
const appliedCss = applyExpressions(cssWithExpression, context).join('')
4444
insert(className, appliedCss)
4545
}

core/utils/insertExpressions.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
export type ExpressionType = ((props: Record<string, any>) => string | number) | string
1+
export type ExpressionType<T = Record<string, any>> = ((props: T) => string | number) | string
22

3-
export function insertExpressions(strings: TemplateStringsArray, expressions: (ExpressionType | ExpressionType[])[]): ExpressionType[] {
3+
export function insertExpressions<T>(
4+
strings: TemplateStringsArray,
5+
expressions: (ExpressionType<T> | ExpressionType<T>[])[],
6+
): ExpressionType<T>[] {
47
return expressions.reduce(
5-
(array: ExpressionType[], expression: ExpressionType[] | ExpressionType | string, index: number) => {
8+
(array: ExpressionType<T>[], expression: ExpressionType<T>[] | ExpressionType<T> | string, index: number) => {
69
return array.concat(expression, strings[index + 1])
710
},
811
[strings[0]],

docs/.vitepress/en.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function nav() {
3030
},
3131
{
3232
text: 'API',
33-
link: '/api/core',
33+
link: '/guide/api/core',
3434
},
3535
]
3636
}
@@ -39,23 +39,31 @@ function sidebarGuide() {
3939
return [
4040
{
4141
text: 'Basic',
42+
base: '/guide/basic/',
4243
items: [
43-
{ text: 'Quick Start', link: '/basic/quick-start' },
44-
{ text: 'Passed Props', link: '/basic/passed-props' },
45-
{ text: 'Extending Styles', link: '/basic/extending-styles' },
46-
{ text: 'Styling Any Component', link: '/basic/styling-any-component' },
47-
{ text: 'Animations', link: '/basic/animations' },
44+
{ text: 'Quick Start', link: 'quick-start' },
45+
{ text: 'Passing Props', link: 'passing-props' },
46+
{ text: 'Extending Styles', link: 'extending-styles' },
47+
{ text: 'Styling Any Component', link: 'styling-any-component' },
48+
{ text: 'Animations', link: 'animations' },
4849
],
4950
},
5051
{
5152
text: 'Advances',
52-
items: [{ text: 'Theming', link: '/advances/theming' }],
53+
base: '/guide/advances/',
54+
items: [
55+
{ text: 'Theming', link: 'theming' },
56+
{ text: 'Global Styles', link: 'global-style' },
57+
{ text: 'CSS Mixin', link: 'css-mixin' }
58+
],
5359
},
5460
{
5561
text: 'API Reference',
62+
base: '/guide/api/',
5663
items: [
57-
{ text: 'Core', link: '/api/core' },
58-
{ text: 'Helper', link: '/api/helper' },
64+
{ text: 'Core', link: 'core' },
65+
{ text: 'Helper', link: 'helper' },
66+
{ text: 'Hook', link: 'hook' },
5967
],
6068
},
6169
]

docs/.vitepress/zh.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,31 @@ function sidebarGuide() {
6363
return [
6464
{
6565
text: '基础',
66+
base: '/zh/guide/basic/',
6667
items: [
67-
{ text: '快速开始', link: '/basic/quick-start' },
68-
{ text: '传递 props', link: '/basic/passed-props' },
69-
{ text: '扩展样式', link: '/basic/extending-styles' },
70-
{ text: '样式化任意组件', link: '/basic/styling-any-component' },
71-
{ text: '动画', link: '/basic/animations' },
68+
{ text: '快速开始', link: 'quick-start' },
69+
{ text: '传递 props', link: 'passing-props' },
70+
{ text: '扩展样式', link: 'extending-styles' },
71+
{ text: '样式化任意组件', link: 'styling-any-component' },
72+
{ text: '动画', link: 'animations' },
7273
],
7374
},
7475
{
7576
text: '进阶',
76-
items: [{ text: '主题', link: '/advances/theming' }],
77+
base: '/zh/guide/advances/',
78+
items: [
79+
{ text: '主题', link: 'theming' },
80+
{ text: '全局样式', link: 'global-style' },
81+
{ text: '样式复用', link: 'css-mixin' }
82+
],
7783
},
7884
{
7985
text: 'API参考',
86+
base: '/zh/guide/api/',
8087
items: [
81-
{ text: '核心', link: '/api/core' },
82-
{ text: '辅助', link: '/api/helper' },
88+
{ text: '核心', link: 'core' },
89+
{ text: '辅助', link: 'helper' },
90+
{ text: 'Hook', link: 'hook' },
8391
],
8492
},
8593
]

docs/guide/advances/css-mixin.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
outline: deep
3+
---
4+
5+
# CSS Mixin
6+
7+
We offer a function named `css` to generate css section and the return value can be used in styled function.
8+
9+
Such as:
10+
11+
:::demo
12+
```vue
13+
<script setup lang="ts">
14+
import { styled, css } from '@vvibe/vue-styled-components'
15+
16+
const commonCSS = css`
17+
padding: 10px 20px;
18+
border-radius: 8px;
19+
background: darkred;
20+
color: #fff;
21+
`
22+
const StyledDiv = styled.div`
23+
${ commonCSS }
24+
`
25+
</script>
26+
27+
<template>
28+
<StyledDiv> Test... </StyledDiv>
29+
</template>
30+
```
31+
:::
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
outline: deep
3+
---
4+
5+
# Global Styles
6+
7+
You can use `createGlobalStyle` to generate global style.
8+
9+
Such as:
10+
11+
:::demo
12+
```vue
13+
<script setup lang="ts">
14+
import { createGlobalStyle } from '@vvibe/vue-styled-components'
15+
16+
const GlobalStyle = createGlobalStyle`
17+
.global-style-test {
18+
padding: 10px 20px;
19+
background: #ccc;
20+
}
21+
`
22+
</script>
23+
24+
<template>
25+
<GlobalStyle />
26+
<div class="global-style-test">
27+
Test...
28+
</div>
29+
</template>
30+
```
31+
:::

docs/guide/api/hook.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
outline: deep
3+
---
4+
5+
# Hook
6+
7+
## `useStyledClassName`
8+
9+
**Return**
10+
11+
- `getStyledClassName`, `styledComponentInstance => string`
12+
- `styledClassNameMap`, `Record<string, string>`, `{[componentName]: className}`
13+
14+
**Usage**
15+
16+
```vue
17+
<script setup lang="ts">
18+
import { styled, useStyledClassName } from '@vvibe/vue-styled-components'
19+
20+
const StyledDiv = styled.div`
21+
background: #ccc;
22+
`
23+
console.log(useStyledClassName(StyledDiv)) // styled-xxx(unique id)
24+
</script>
25+
```
File renamed without changes.

0 commit comments

Comments
 (0)