Skip to content

Commit 6f3c9ec

Browse files
committed
update readme
1 parent 8a1e6a0 commit 6f3c9ec

File tree

6 files changed

+81
-39
lines changed

6 files changed

+81
-39
lines changed

README.md

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ But it may not be the one-size-fits-all solution for highlighting menu/sidebar l
1717
- On page load, active target doesn't match the one in the URL hash.
1818
- Is tricky to customize behavior according to different interactions
1919

20-
> Vue Use Active Scroll implements a custom scroll observer that automatically deals with all these drabacks and simply returns the correct active target.
20+
<br />
21+
22+
**Vue Use Active Scroll** implements a custom scroll observer that automatically deals with all these drabacks and simply returns the correct active target.
2123

2224
### Features
2325

@@ -30,7 +32,7 @@ But it may not be the one-size-fits-all solution for highlighting menu/sidebar l
3032

3133
### What it doesn't do?
3234

33-
- Mutate your elements and styles
35+
- Mutate elements and inject styles
3436
- Scroll to targets
3537

3638
<br />
@@ -237,10 +239,10 @@ const { isActive, setActive } = useActive(targets)
237239
<template>
238240
<nav>
239241
<a
240-
v-for="(link, index) in links"
241242
@click="setActive(link.targetId) /* 👈🏻 */"
242-
:href="`#${link.targetId}`"
243+
v-for="(link, index) in links"
243244
:key="link.targetId"
245+
:to="`#${link.targetId}`"
244246
>
245247
{{ link.label }}
246248
</a>
@@ -257,16 +259,6 @@ html {
257259

258260
You are totally free to create your own click handler and choose the scrolling strategy: CSS (smooth or auto), [scrollIntoView](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) or even a scroll library like [animated-scroll-to](https://github.com/Stanko/animated-scroll-to) with custom easings will work. Just remember to include `setActive` in your handler.
259261

260-
<details><summary><strong>RouterLink / NuxtLink</strong></summary>
261-
262-
<br />
263-
264-
Since those links don't navigate to another page, you can safely use an `a` tag with a `href` attribute and avoid to use `RouterLink` or `NuxtLink`.
265-
266-
<br />
267-
268-
</details>
269-
270262
<details><summary><strong>Custom Scroll Callback</strong></summary>
271263

272264
<br />
@@ -296,9 +288,8 @@ function scrollTo(event, targetId) {
296288
<a
297289
v-for="(link, index) in links"
298290
@click="scrollTo($event, link.targetId)"
299-
:href="`#${link.targetId}`"
300291
:key="link.targetId"
301-
:class="{ active: isActive(link.targetId) }"
292+
:to="`#${link.targetId}`"
302293
>
303294
{{ link.label }}
304295
</a>
@@ -310,20 +301,24 @@ function scrollTo(event, targetId) {
310301

311302
### **2.** Use `isActive` to style the active link:
312303

304+
> :bulb: If you're playing with transitions or advanced styling rules simply leverage _activeIndex_ and _activeId_.
305+
313306
```vue
314307
<script setup>
315308
// ...
316-
const { isActive } = useActive(targets)
309+
const { isActive, setActive } = useActive(targets)
317310
</script>
318311
319312
<template>
320313
<nav>
321314
<a
322-
v-for="(link, index) in links"
323315
@click="setActive(link.targetId)"
324-
:href="`#${link.targetId}`"
316+
v-for="(link, index) in links"
325317
:key="link.targetId"
326-
:class="{ active: isActive(link.targetId) /* 👈🏻 */ }"
318+
:to="`#${link.targetId}`"
319+
:class="{
320+
active: isActive(link.targetId) /* 👈🏻 or link.targetId === activeId */
321+
}"
327322
>
328323
{{ link.label }}
329324
</a>
@@ -342,7 +337,44 @@ html {
342337
</style>
343338
```
344339

345-
> :bulb: If you're playing with transitions or advanced styling rules simply leverage _activeIndex_ and _activeId_.
340+
<details><summary><strong>RouterLink</strong></summary>
341+
342+
<br />
343+
344+
```vue
345+
<RouterLink
346+
@click.native="setActive(link.targetId)"
347+
:to="{ hash: `#${link.targetId}` }"
348+
:class="{
349+
active: isActive(link.targetId)
350+
}"
351+
:ariaCurrentValue="`${isActive(link.targetId)}`"
352+
activeClass=""
353+
exactActiveClass=""
354+
>
355+
{{ link.label }}
356+
</RouterLink>
357+
```
358+
359+
</details>
360+
361+
<details><summary><strong>NuxtLink</strong></summary>
362+
363+
<br />
364+
365+
```vue
366+
<NuxtLink
367+
@click="setActive(link.targetId)"
368+
:href="`#${link.targetId}`"
369+
:class="{
370+
active: isActive(link.targetId)
371+
}"
372+
>
373+
{{ link.label }}
374+
</NuxtLink>
375+
```
376+
377+
</details>
346378

347379
<br />
348380

demo/App.vue

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ provide('DemoRadios', {
5555
5656
* {
5757
box-sizing: border-box;
58-
}
59-
60-
html {
6158
scroll-behavior: var(--ScrollBehavior);
6259
}
6360

demo/components/Sidebar/DemoControls.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,20 @@ button {
122122
transition: border 100ms ease-in-out, background-color 100ms ease-in-out;
123123
}
124124
125+
input {
126+
margin: 0;
127+
}
128+
125129
button:hover {
126130
border: 1px solid white;
127131
background-color: #4a5463;
128132
}
129133
130134
label {
131135
cursor: pointer;
136+
display: flex;
137+
align-items: center;
138+
gap: 5px;
132139
padding: 0;
133140
}
134141
</style>

demo/components/Sidebar/TOC.vue

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { computed, ComputedRef, inject } from 'vue';
33
import { useActive } from '../../../src/useActive';
44
import animateScrollTo from 'animated-scroll-to';
5+
import { routerKey, useRoute } from 'vue-router';
56
67
type TOCData = {
78
menuItems: { label: string; href: string }[];
@@ -25,8 +26,10 @@ const { activeIndex, activeId, setActive, isActive } = useActive(targets, {
2526
}, */
2627
});
2728
29+
const route = useRoute();
30+
2831
const activeItemHeight = computed(
29-
() => document.querySelector(`a[href="#${activeId.value}"]`)?.scrollHeight || 0
32+
() => document.querySelector(`a[href="${route.path}#${activeId.value}"]`)?.scrollHeight || 0
3033
);
3134
3235
function customScroll(id: string) {
@@ -50,15 +53,18 @@ const onClick = computed(() => (clickType.value === 'native' ? setActive : custo
5053
<span v-if="activeIndex >= 0" class="Tracker" />
5154

5255
<li v-for="item in menuItems" :key="item.href">
53-
<a
54-
@click="onClick(item.href)"
55-
:href="`#${item.href}`"
56+
<RouterLink
57+
@click.native="onClick(item.href)"
58+
:ariaCurrentValue="`${isActive(item.href)}`"
59+
:to="{ hash: `#${item.href}` }"
5660
:class="{
5761
Active: isActive(item.href),
5862
}"
63+
activeClass=""
64+
exactActiveClass=""
5965
>
6066
{{ item.label }}
61-
</a>
67+
</RouterLink>
6268
</li>
6369
</ul>
6470
</nav>
@@ -101,8 +107,10 @@ a {
101107
--webkit-tap-highlight-color: rgba(0, 0, 0, 0);
102108
}
103109
104-
a:hover {
105-
color: white;
110+
@media (hover: hover) {
111+
a:hover {
112+
color: white;
113+
}
106114
}
107115
108116
.Active {

demo/useFakeData.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@ export function useFakeData() {
1111
const maxText = isMobile ? 100 : 320;
1212

1313
const sections = reactive(
14-
Array.from({ length: parsedLength <= 1 ? 10 : parsedLength }, (_, index) => {
15-
return {
16-
id: `title_${parsedStart + index}`,
17-
title: `${parsedStart + index} `.repeat(6).toUpperCase(),
18-
text: 'Text '.repeat(getInt(minText, maxText)),
19-
};
20-
})
14+
Array.from({ length: parsedLength <= 1 ? 10 : parsedLength }, (_, index) => ({
15+
id: `title_${parsedStart + index}`,
16+
title: `${parsedStart + index} `.repeat(6).toUpperCase(),
17+
text: 'Text '.repeat(getInt(minText, maxText)),
18+
}))
2119
);
2220

2321
const lastNum = computed(() => parseInt(sections[sections.length - 1].title));

src/useScroll.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export function useScroll({ isHTML, root, _setActive, matchMedia }: UseListeners
8383
}
8484

8585
onMounted(() => {
86-
if (matchMedia.value && window.location.hash) {
86+
if (matchMedia.value && location.hash) {
8787
// Wait for any eventual scroll to hash triggered by browser to end
8888
setReady(10);
8989
} else {

0 commit comments

Comments
 (0)