Skip to content

Commit 5e692aa

Browse files
authored
Merge pull request #103 from AdamDrewsTR/major-fix-and-more
feat+FIX: enhance VTour component with default tooltip placement and mult…
2 parents c61c59c + ba4c32d commit 5e692aa

21 files changed

Lines changed: 2691 additions & 404 deletions

README.md

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,35 +33,6 @@
3333
> Looking for a nuxt version?
3434
> [Nuxt version (Special thanks to BayBreezy)](https://github.com/BayBreezy/nuxt-tour)
3535
36-
> [!CAUTION]
37-
> As of version 2.0.1, VueJS Tour has been rewritten in TypeScript. The `VTour` component is now a named export and must be imported as such.
38-
> Please refer to the [Documentation](https://globalhive.github.io/vuejs-tour/) for more information on how to use VueJS Tour.
39-
40-
<br><br><br><br>
41-
<ins>If you still want to use the old version, then this is the correct way to install it:</ins>
42-
43-
* Step 1: Go to your project directory and install VueJS Tour using npm:
44-
45-
```bash
46-
cd my-project
47-
npm install @globalhive/vuejs-tour
48-
```
49-
50-
* Step 2: Import the plugin in your application entry point (typically `main.js`):
51-
52-
```javascript
53-
import { createApp } from "vue";
54-
import App from "./App.vue";
55-
import VueJsTour from '@globalhive/vuejs-tour';
56-
import '@globalhive/vuejs-tour/dist/style.css';
57-
58-
const app = createApp(App)
59-
.use(VueJsTour)
60-
.mount("#app");
61-
```
62-
Everything is ready! Now you can use VueJS Tour in your application.<br>
63-
Make sure to check out the [documentation](https://globalhive.github.io/vuejs-tour/) for more information.
64-
6536
## Create a tour
6637

6738
Add the VueJS Tour component anywhere in your app. It is recommended to add it to `App.vue`

docs/.vitepress/config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default defineConfig({
1919
nav: [
2020
{ text: 'Guide', link: '/guide/what-is-vuejs-tour' },
2121
{
22-
text: '2.4.3',
22+
text: '2.5.0',
2323
items: [
2424
{
2525
text: 'Changelog',
@@ -98,6 +98,8 @@ export default defineConfig({
9898
{ text: 'Skipping a Tour', link: '/guide/skipping-a-tour' },
9999
{ text: 'Button Labels', link: '/guide/button-labels' },
100100
{ text: 'Multiple Tours', link: '/guide/multiple-tours' },
101+
{ text: 'Jump Options', link: '/guide/jump-options' },
102+
{ text: 'Accessibility', link: '/guide/accessibility' },
101103
{
102104
text: 'Styling',
103105
items: [

docs/guide/accessibility.md

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
# Accessibility Guide for VueJS Tour
2+
3+
## Current State
4+
5+
VueJS Tour now includes comprehensive WCAG 2.1 AA accessibility features, including keyboard navigation, ARIA attributes, focus management, and screen reader support.
6+
7+
**⚠️ Note:** Accessibility features are **disabled by default** (as of v2.5.0) pending further testing and validation. Enable them by setting `enableA11y: true` on the component.
8+
9+
## Implemented Accessibility Features
10+
11+
### 1. **ARIA Attributes**
12+
13+
Implemented:
14+
15+
-`aria-label` on tooltip (configurable via `ariaLabel` prop or per-step `ariaLabel`)
16+
-`aria-describedby` for step content
17+
-`aria-live="polite"` region for step announcements
18+
-`aria-modal="true"` when `enableA11y` is enabled
19+
-`role="dialog"` for proper semantic structure
20+
- ✅ Enhanced `aria-label` attributes on all buttons
21+
22+
### 2. **Keyboard Navigation**
23+
24+
Implemented:
25+
26+
-`Escape` key to close tour
27+
-`ArrowRight` or `Enter` to go to next step
28+
-`ArrowLeft` to go to previous step
29+
- ✅ Keyboard navigation can be disabled via `keyboardNav: false`
30+
- ⚠️ Focus trap not yet implemented (planned for future release)
31+
32+
### 3. **Focus Management**
33+
34+
Implemented:
35+
36+
- ✅ Tooltip receives focus when opened (when `enableA11y` is true)
37+
- ✅ Previous focus restored when tour ends
38+
-`tabindex="0"` on tooltip for keyboard accessibility
39+
40+
### 4. **Screen Reader Support**
41+
42+
Implemented:
43+
44+
- ✅ Step progress announced ("Step 2 of 5")
45+
- ✅ Descriptive button labels with step context
46+
- ✅ Content changes announced via aria-live region
47+
- ✅ Screen reader only content via `.vjt-sr-only` CSS class
48+
49+
### 5. **Semantic Structure**
50+
51+
Implemented:
52+
53+
-`role="dialog"` on tooltip (changed from `role="tooltip"` for better modal semantics)
54+
- ✅ Step counter announced to screen readers
55+
- ✅ Proper ARIA attributes on all interactive elements
56+
57+
## Usage
58+
59+
### Enabling Accessibility Features
60+
61+
Accessibility features are disabled by default. To enable them:
62+
63+
```vue
64+
<VTour
65+
:steps="steps"
66+
:enableA11y="true"
67+
:keyboardNav="true"
68+
ariaLabel="Product tour"
69+
/>
70+
```
71+
72+
### Available Props
73+
74+
```typescript
75+
interface VTourProps {
76+
// ... other props
77+
78+
/** Enable accessibility features (default: false) */
79+
readonly enableA11y?: boolean;
80+
81+
/** Enable keyboard navigation (default: true, only active when enableA11y is true) */
82+
readonly keyboardNav?: boolean;
83+
84+
/** Custom aria-label for the tour (default: "Guided tour") */
85+
readonly ariaLabel?: string;
86+
}
87+
88+
interface ITourStep {
89+
// ... other props
90+
91+
/** Descriptive label for screen readers */
92+
readonly ariaLabel?: string;
93+
}
94+
```
95+
96+
### Example: Per-Step Accessibility Labels
97+
98+
```vue
99+
<script setup>
100+
const steps = [
101+
{
102+
target: '#welcome',
103+
content: 'Welcome to our app!',
104+
ariaLabel: 'Welcome step: Introduction to the application',
105+
},
106+
{
107+
target: '#profile',
108+
content: 'View your profile here',
109+
ariaLabel: 'Profile step: Learn about your user profile',
110+
},
111+
];
112+
</script>
113+
114+
<template>
115+
<VTour :steps="steps" :enableA11y="true" />
116+
</template>
117+
```
118+
119+
## Implementation Details
120+
121+
### Features Already Implemented ✅
122+
123+
1. **ARIA Live Region** - Announces step changes to screen readers
124+
125+
```vue
126+
<div
127+
v-if="enableA11y"
128+
role="status"
129+
aria-live="polite"
130+
aria-atomic="true"
131+
class="vjt-sr-only"
132+
>
133+
Step {{ currentStepIndex + 1 }} of {{ props.steps.length }}
134+
</div>
135+
```
136+
137+
2. **Enhanced Tooltip Semantics** - Proper dialog role and ARIA attributes
138+
139+
```vue
140+
<div
141+
:id="tooltipId"
142+
role="dialog"
143+
:aria-modal="enableA11y ? 'true' : undefined"
144+
:aria-label="getCurrentStep?.ariaLabel || ariaLabel"
145+
:aria-describedby="`${tooltipId}-content`"
146+
:tabindex="enableA11y ? '0' : undefined"
147+
/>
148+
```
149+
150+
3. **Keyboard Navigation** - Arrow keys, Enter, and Escape support
151+
152+
```typescript
153+
const onKeydown = (event: KeyboardEvent): void => {
154+
if (!tourVisible.value || !props.enableA11y || !props.keyboardNav) return;
155+
156+
switch (event.key) {
157+
case 'Escape':
158+
endTour();
159+
event.preventDefault();
160+
break;
161+
case 'ArrowRight':
162+
case 'Enter':
163+
nextStep();
164+
event.preventDefault();
165+
break;
166+
case 'ArrowLeft':
167+
if (currentStepIndex.value > 0) {
168+
lastStep();
169+
event.preventDefault();
170+
}
171+
break;
172+
}
173+
};
174+
```
175+
176+
4. **Focus Management** - Stores and restores focus
177+
178+
```typescript
179+
let previousFocus: HTMLElement | null = null;
180+
181+
const startTour = async () => {
182+
if (props.enableA11y && typeof document !== 'undefined') {
183+
previousFocus = document.activeElement as HTMLElement;
184+
}
185+
// ... tour starts
186+
if (props.enableA11y) {
187+
await nextTick();
188+
_Tooltip.value?.focus();
189+
}
190+
};
191+
192+
const stopTour = () => {
193+
if (props.enableA11y && previousFocus) {
194+
previousFocus.focus();
195+
previousFocus = null;
196+
}
197+
};
198+
```
199+
200+
5. **Enhanced Button Labels** - Descriptive aria-labels for all actions
201+
202+
```vue
203+
<button
204+
type="button"
205+
@click.prevent="nextStep"
206+
:aria-label="
207+
enableA11y
208+
? isLastStep
209+
? 'Finish tour'
210+
: `Go to next step, step ${nextStepIndex + 1} of ${props.steps.length}`
211+
: undefined
212+
"
213+
>
214+
{{ getNextLabel }}
215+
</button>
216+
```
217+
218+
### Future Enhancements ⚠️
219+
220+
These features are planned for future releases:
221+
222+
1. **Focus Trap** - Trap focus within modal when backdrop is active
223+
2. **Customizable Keyboard Shortcuts** - Allow users to configure key bindings
224+
3. **Visual Progress Indicators** - Show step progress visually
225+
4. **Skip to Content** - Quick navigation option
226+
227+
## Backward Compatibility
228+
229+
All accessibility features:
230+
231+
- ⚠️ Default to **disabled** (`enableA11y: false`) as of v2.4.3 pending further testing
232+
- Are opt-in via `enableA11y: true` prop
233+
- Do not break existing implementations when disabled
234+
- Add ~3KB to bundle size (minimal impact)
235+
236+
## Testing Requirements
237+
238+
1. **Keyboard-only navigation**
239+
- Can navigate all steps without mouse
240+
- Can dismiss tour with Escape
241+
- Focus visible at all times
242+
243+
2. **Screen reader testing**
244+
- NVDA (Windows)
245+
- JAWS (Windows)
246+
- VoiceOver (macOS/iOS)
247+
- TalkBack (Android)
248+
249+
3. **Automated testing**
250+
- axe-core integration
251+
- ARIA validity checks
252+
- Keyboard interaction tests
253+
254+
## Resources
255+
256+
- [WAI-ARIA Authoring Practices Guide - Dialog](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)
257+
- [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
258+
- [focus-trap library](https://github.com/focus-trap/focus-trap)
259+
- [Vue A11y Best Practices](https://vue-a11y.com/)
260+
261+
## Testing Status
262+
263+
**Implemented (v2.4.3):**
264+
265+
- ✅ Keyboard navigation tests (28 test cases)
266+
- ✅ ARIA attributes validation
267+
- ✅ Focus management tests
268+
- ✅ Screen reader announcement tests
269+
270+
**Pending:**
271+
272+
1. **Manual testing with screen readers**
273+
- NVDA (Windows)
274+
- JAWS (Windows)
275+
- VoiceOver (macOS/iOS)
276+
- TalkBack (Android)
277+
278+
2. **Real-world validation**
279+
- User testing with keyboard-only users
280+
- Screen reader user feedback
281+
- Production environment testing
282+
283+
3. **Automated accessibility testing**
284+
- axe-core integration
285+
- Lighthouse accessibility audits
286+
- pa11y or similar tools
287+
288+
## Status
289+
290+
**Phase 1 (Critical) features implemented** - All essential WCAG AA compliance features are in place and tested. Features are disabled by default pending further validation.
291+
292+
**Next steps:**
293+
294+
1. Community testing and feedback
295+
2. Screen reader validation
296+
3. Enable by default once vetted
297+
4. Implement Phase 2 features (focus trap, custom shortcuts)

0 commit comments

Comments
 (0)