Skip to content

Commit 0777d09

Browse files
authoredMay 16, 2024··
feat(client): improve AutoLinkProps (#1554)
1 parent 60478fe commit 0777d09

File tree

2 files changed

+36
-73
lines changed

2 files changed

+36
-73
lines changed
 

‎e2e/docs/components/auto-link.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
# AutoLink
22

33
<div id="route-link">
4-
<AutoLink v-for="item in routeLinksConfig" v-bind="item" />
4+
<AutoLink v-for="item in routeLinksConfig" :config="item" />
55
</div>
66

77
<div id="external-link">
8-
<AutoLink v-for="item in externalLinksConfig" v-bind="item" />
8+
<AutoLink v-for="item in externalLinksConfig" :config="item" />
99
</div>
1010

1111
<div id="config">
12-
<AutoLink v-bind="{ text: 'text1', link: '/', ariaLabel: 'label' }" />
13-
<AutoLink v-bind="{ text: 'text2', link: 'https://example.com/test/' }" />
12+
<AutoLink :config="{ text: 'text1', link: '/', ariaLabel: 'label' }" />
13+
<AutoLink :config="{ text: 'text2', link: 'https://example.com/test/' }" />
1414
</div>
1515

1616
<script setup lang="ts">

‎packages/client/src/components/AutoLink.ts

+32-69
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { isLinkWithProtocol } from '@vuepress/shared'
2-
import type { SlotsType, VNode } from 'vue'
3-
import { computed, defineComponent, h } from 'vue'
2+
import type { PropType, SlotsType, VNode } from 'vue'
3+
import { computed, defineComponent, h, toRef } from 'vue'
44
import { useRoute } from 'vue-router'
55
import { useSiteData } from '../composables/index.js'
66
import { RouteLink } from './RouteLink.js'
77

8-
export interface AutoLinkProps {
8+
export interface AutoLinkConfig {
99
/**
1010
* Pattern to determine if the link should be active, which has higher priority than `exact`
1111
*/
@@ -51,57 +51,11 @@ export interface AutoLinkProps {
5151
export const AutoLink = defineComponent({
5252
name: 'AutoLink',
5353

54-
props: {
55-
/**
56-
* Pattern to determine if the link should be active, which has higher priority than `exact`
57-
*/
58-
activeMatch: {
59-
type: [String, RegExp],
60-
default: '',
61-
},
62-
63-
/**
64-
* The `aria-label` attribute
65-
*/
66-
ariaLabel: {
67-
type: String,
68-
default: '',
69-
},
70-
71-
/**
72-
* Whether the link should be active only if the url is an exact match
73-
*/
74-
exact: Boolean,
75-
76-
/**
77-
* URL of the auto link
78-
*/
79-
link: {
80-
type: String,
81-
required: true,
82-
},
83-
84-
/**
85-
* The `rel` attribute
86-
*/
87-
rel: {
88-
type: String,
89-
default: '',
90-
},
54+
inheritAttrs: false,
9155

92-
/**
93-
* The `target` attribute
94-
*/
95-
target: {
96-
type: String,
97-
default: '',
98-
},
99-
100-
/**
101-
* Text of the auto link
102-
*/
103-
text: {
104-
type: String,
56+
props: {
57+
config: {
58+
type: Object as PropType<AutoLinkConfig>,
10559
required: true,
10660
},
10761
},
@@ -113,15 +67,16 @@ export const AutoLink = defineComponent({
11367
}>,
11468

11569
setup(props, { slots }) {
70+
const config = toRef(props, 'config')
11671
const route = useRoute()
11772
const siteData = useSiteData()
11873

11974
// If the link has non-http protocol
120-
const withProtocol = computed(() => isLinkWithProtocol(props.link))
75+
const withProtocol = computed(() => isLinkWithProtocol(config.value.link))
12176

12277
// Resolve the `target` attr
12378
const linkTarget = computed(
124-
() => props.target || (withProtocol.value ? '_blank' : undefined),
79+
() => config.value.target || (withProtocol.value ? '_blank' : undefined),
12580
)
12681

12782
// If the `target` attr is "_blank"
@@ -134,57 +89,65 @@ export const AutoLink = defineComponent({
13489

13590
// Resolve the `rel` attr
13691
const linkRel = computed(
137-
() => props.rel || (isBlankTarget.value ? 'noopener noreferrer' : null),
92+
() =>
93+
config.value.rel ||
94+
(isBlankTarget.value ? 'noopener noreferrer' : null),
13895
)
13996

14097
// Resolve the `aria-label` attr
141-
const linkAriaLabel = computed(() => props.ariaLabel ?? props.text)
98+
const linkAriaLabel = computed(
99+
() => config.value.ariaLabel ?? config.value.text,
100+
)
142101

143102
// Should be active when current route is a subpath of this link
144103
const shouldBeActiveInSubpath = computed(() => {
145104
// Should not be active in `exact` mode
146-
if (props.exact) return false
105+
if (config.value.exact) return false
147106

148107
const localePaths = Object.keys(siteData.value.locales)
149108

150109
return localePaths.length
151110
? // Check all the locales
152-
localePaths.every((key) => key !== props.link)
111+
localePaths.every((key) => key !== config.value.link)
153112
: // Check root
154-
props.link !== '/'
113+
config.value.link !== '/'
155114
})
156115

157116
// If this link is active
158117
const isActive = computed(() => {
159118
if (!isInternal.value) return false
160119

161-
if (props.activeMatch) {
120+
if (config.value.activeMatch) {
162121
return (
163-
props.activeMatch instanceof RegExp
164-
? props.activeMatch
165-
: new RegExp(props.activeMatch, 'u')
122+
config.value.activeMatch instanceof RegExp
123+
? config.value.activeMatch
124+
: new RegExp(config.value.activeMatch, 'u')
166125
).test(route.path)
167126
}
168127

169128
// If this link is active in subpath
170129
if (shouldBeActiveInSubpath.value) {
171-
return route.path.startsWith(props.link)
130+
return route.path.startsWith(config.value.link)
172131
}
173132

174-
return route.path === props.link
133+
return route.path === config.value.link
175134
})
176135

177136
return () => {
178137
const { before, after, default: defaultSlot } = slots
179138

180-
const content = defaultSlot?.() || [before?.(), props.text, after?.()]
139+
const content = defaultSlot?.() || [
140+
before?.(),
141+
config.value.text,
142+
after?.(),
143+
]
181144

182145
return isInternal.value
183146
? h(
184147
RouteLink,
185148
{
186149
'class': 'auto-link',
187-
'to': props.link,
150+
'to': config.value.link,
188151
'active': isActive.value,
189152
'aria-label': linkAriaLabel.value,
190153
},
@@ -194,7 +157,7 @@ export const AutoLink = defineComponent({
194157
'a',
195158
{
196159
'class': 'auto-link external-link',
197-
'href': props.link,
160+
'href': config.value.link,
198161
'aria-label': linkAriaLabel.value,
199162
'rel': linkRel.value,
200163
'target': linkTarget.value,

0 commit comments

Comments
 (0)
Please sign in to comment.