Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(page-properties): added new custom dynamic page properties #193

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions packages/unconfig-vitepress/src/plugins/nolebase/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,15 @@ const defaultOptions: NolebasePluginPresetOptions = {
dateFnsLocaleName: 'enUS',
},
},
{
key: 'someCustomProperty',
type: 'dynamic',
title: 'Some custom property',
options: {
type: 'custom',
getter: () => 'Custom value',
},
},
],
'zh-CN': [
{
Expand Down Expand Up @@ -184,6 +193,15 @@ const defaultOptions: NolebasePluginPresetOptions = {
dateFnsLocaleName: 'zhCN',
},
},
{
key: 'someCustomProperty',
type: 'dynamic',
title: '自定义属性',
options: {
type: 'custom',
getter: () => 'Custom value',
},
},
],
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { useData } from 'vitepress'
import { NuTag } from '@nolebase/ui'

import { InjectionKey } from '../constants'
import type { Property } from '../types'
import {
isDatetimeProperty,
isDynamicCustomProperty,
isDynamicReadingTimeProperty,
isDynamicWordsCountProperty,
isLinkProperty,
Expand All @@ -22,7 +24,8 @@ import ProgressBar from './ProgressBar.vue'
import Datetime from './Datetime.vue'

const options = inject(InjectionKey, {})
const { lang, frontmatter } = useData()
const vitePressData = useData()
const { lang, frontmatter } = vitePressData
const { t } = useI18n()
const rawPath = useRawPath()
const pagePropertiesData = usePageProperties()
Expand Down Expand Up @@ -148,6 +151,9 @@ const readingTime = computed(() => {
<template v-else-if="isDynamicReadingTimeProperty(property.value, property.pageProperty)">
<div i-icon-park-outline:timer mr-1 />
</template>
<template v-else-if="isDynamicCustomProperty(property.value, property.pageProperty)">
<div i-icon-park-outline:block-nine mr-1 />
</template>
<template v-else-if="typeof property.value === 'object'">
<div i-icon-park-outline:triangle-round-rectangle mr-1 />
</template>
Expand Down Expand Up @@ -245,6 +251,17 @@ const readingTime = computed(() => {
<span>{{ formatDurationFromValue(readingTime, property.pageProperty.options.dateFnsLocaleName || lang) }}</span>
</div>
</template>
<template v-else-if="isDynamicCustomProperty(property.value, property.pageProperty)">
<div
class="vp-nolebase-page-property"
data-page-property="value"
data-page-property-type="dynamic"
data-page-property-dynamic-type="custom"
w-full inline-flex items-center
>
<span>{{ property.pageProperty.options.getter(vitePressData) }}</span>
</div>
</template>
<template v-else-if="typeof property.value === 'object'">
<div
class="vp-nolebase-page-property"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { NuTag } from '@nolebase/ui'
import { InjectionKey } from '../constants'
import {
isDatetimeProperty,
isDynamicCustomProperty,
isDynamicReadingTimeProperty,
isDynamicWordsCountProperty,
isLinkProperty,
Expand All @@ -18,11 +19,13 @@ import { useI18n } from '../composables/i18n'
import { usePageProperties } from '../composables/data'
import { formatDurationFromValue } from '../utils'

import type { Property } from '../types'
import ProgressBar from './ProgressBar.vue'
import Datetime from './Datetime.vue'

const options = inject(InjectionKey, {})
const { lang, frontmatter } = useData()
const vitePressData = useData()
const { lang, frontmatter } = vitePressData
const { t } = useI18n()
const rawPath = useRawPath()
const pagePropertiesData = usePageProperties()
Expand Down Expand Up @@ -172,6 +175,9 @@ const readingTime = computed(() => {
<template v-else-if="isDynamicReadingTimeProperty(property.value, property.pageProperty)">
<div i-icon-park-outline:timer mr-1 />
</template>
<template v-else-if="isDynamicCustomProperty(property.value, property.pageProperty)">
<div i-icon-park-outline:block-nine mr-1 />
</template>
<template v-else-if="typeof property.value === 'object'">
<div i-icon-park-outline:triangle-round-rectangle mr-1 />
</template>
Expand Down Expand Up @@ -269,6 +275,17 @@ const readingTime = computed(() => {
<span>{{ formatDurationFromValue(readingTime, property.pageProperty.options.dateFnsLocaleName || lang) }}</span>
</div>
</template>
<template v-else-if="isDynamicCustomProperty(property.value, property.pageProperty)">
<div
class="vp-nolebase-page-property"
data-page-property="value"
data-page-property-type="dynamic"
data-page-property-dynamic-type="custom"
w-full inline-flex items-center
>
<span>{{ property.pageProperty.options.getter(vitePressData) }}</span>
</div>
</template>
<template v-else-if="typeof property.value === 'object'">
<div
class="vp-nolebase-page-property"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type {
DatetimeProperty,
DynamicCustomProperty,
DynamicProperty,
DynamicReadingTimeProperty,
DynamicWordsCountProperty,
LinkProperty,
PlainProperty,
ProgressProperty,
Expand Down Expand Up @@ -53,16 +56,23 @@ export function isLinkProperty(_?: any, property?: Property<PropertyKey> | null)
return false
}

export function isDynamicWordsCountProperty(_?: any, property?: Property<PropertyKey> | null): property is DynamicProperty<PropertyKey> | null {
export function isDynamicWordsCountProperty(_?: any, property?: Property<PropertyKey> | null): property is DynamicProperty<PropertyKey, DynamicWordsCountProperty> | null {
if (property && property.type && property.type === 'dynamic' && property.options && property.options.type === 'wordsCount')
return true

return false
}

export function isDynamicReadingTimeProperty(_?: any, property?: Property<PropertyKey> | null): property is DynamicProperty<PropertyKey> | null {
export function isDynamicReadingTimeProperty(_?: any, property?: Property<PropertyKey> | null): property is DynamicProperty<PropertyKey, DynamicReadingTimeProperty> | null {
if (property && property.type && property.type === 'dynamic' && property.options && property.options.type === 'readingTime')
return true

return false
}

export function isDynamicCustomProperty(_?: any, property?: Property<PropertyKey> | null): property is DynamicProperty<PropertyKey, DynamicCustomProperty> | null {
if (property && property.type && property.type === 'dynamic' && property.options && property.options.type === 'custom')
return true

return false
}
30 changes: 20 additions & 10 deletions packages/vitepress-plugin-page-properties/src/client/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { VitePressData } from 'vitepress'

export interface TagsProperty<K extends PropertyKey> {
type: 'tags'
key: K
Expand Down Expand Up @@ -36,15 +38,18 @@ export interface LinkProperty<K extends PropertyKey> {
omitEmpty?: boolean
}

export interface DynamicProperty<K extends PropertyKey> {
export interface DynamicProperty<K extends PropertyKey, OP extends DynamicPropertyOptions = DynamicPropertyOptions> {
type: 'dynamic'
key: K | string
title: string
options:
DynamicWordsCountProperty |
DynamicReadingTimeProperty
options: OP
}

export type DynamicPropertyOptions =
| DynamicWordsCountProperty
| DynamicReadingTimeProperty
| DynamicCustomProperty

export interface DynamicWordsCountProperty {
type: 'wordsCount'
}
Expand All @@ -54,13 +59,18 @@ export interface DynamicReadingTimeProperty {
dateFnsLocaleName?: string
}

export interface DynamicCustomProperty {
type: 'custom'
getter: (data: VitePressData) => string | Promise<string>
}

export type Property<K extends PropertyKey> =
TagsProperty<K> |
PlainProperty<K> |
DatetimeProperty<K> |
ProgressProperty<K> |
LinkProperty<K> |
DynamicProperty<K>
| TagsProperty<K>
| PlainProperty<K>
| DatetimeProperty<K>
| ProgressProperty<K>
| LinkProperty<K>
| DynamicProperty<K>

export type PropertyType = Property<PropertyKey>['type']
export type DynamicPropertyType = DynamicProperty<PropertyKey>['options']['type']
Expand Down
67 changes: 0 additions & 67 deletions packages/vitepress-plugin-page-properties/src/client/virtual.d.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,3 @@
interface TagsProperty<K extends PropertyKey> {
type: 'tags'
key: K
title: string
omitEmpty?: boolean
}

interface PlainProperty<K extends PropertyKey> {
type: 'plain'
key: K
title: string
omitEmpty?: boolean
}

interface DatetimeProperty<K extends PropertyKey> {
type: 'datetime'
key: K
title: string
formatAsFrom?: boolean
dateFnsLocaleName?: string
format?: string
omitEmpty?: boolean
}

interface ProgressProperty<K extends PropertyKey> {
type: 'progress'
key: K
title: string
omitEmpty?: boolean
}

interface LinkProperty<K extends PropertyKey> {
type: 'link'
key: K
title: string
omitEmpty?: boolean
}

interface DynamicProperty<K extends PropertyKey> {
type: 'dynamic'
key: K | string
title: string
options:
DynamicWordsCountProperty |
DynamicReadingTimeProperty
}

interface DynamicWordsCountProperty {
type: 'wordsCount'
}

interface DynamicReadingTimeProperty {
type: 'readingTime'
dateFnsLocaleName?: string
}

type Property<K extends PropertyKey> =
TagsProperty<K> |
PlainProperty<K> |
DatetimeProperty<K> |
ProgressProperty<K> |
LinkProperty<K> |
DynamicProperty<K>

type PropertyType = Property<PropertyKey>['type']
type DynamicPropertyType = DynamicProperty<PropertyKey>['options']['type']

declare module 'virtual:nolebase-page-properties' {
const pagePropertiesData: Record<string, {
wordsCount: number
Expand Down
Loading