Skip to content

Commit 0d0922c

Browse files
author
Kurt Medley
committed
Emitting aria message. Refactoring prop names
1 parent f5d1889 commit 0d0922c

5 files changed

Lines changed: 164 additions & 8 deletions

File tree

src/components/filmstrip/CdrFilmstrip.vue

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010
:id="filmstripId"
1111
:description="description"
1212
:frames="frames"
13-
:framesGap="framesGap"
14-
:framesToShow="framesToShow"
15-
:framesToScroll="framesToScroll"
13+
:frames-gap="framesGap"
14+
:frames-to-show="framesToShow"
15+
:frames-to-scroll="framesToScroll"
1616
:focus-selector="focusSelector"
17-
@arrow-click="onArrowClick"
17+
@ariaMessage="$emit('ariaMessage', $event)"
18+
@arrowClick="onArrowClick"
1819
>
1920
<template #frame="{ ...frameProps }: Record<string, unknown>">
2021
<component

src/components/filmstrip/CdrFilmstripEngine.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ const props = withDefaults(defineProps<CdrFilmstripEngine>(), {
107107
108108
const emit = defineEmits<{
109109
(e: 'arrowClick', payload: CdrFilmstripArrowClickPayload): void;
110+
(e: 'ariaMessage', message: string): void;
110111
}>();
111112
112113
const ariaMessage = ref(''); // Live region message for screen readers
@@ -220,6 +221,7 @@ const announceFrames = useDebounceFn(() => {
220221
props.framesToShow === 1
221222
? `Now showing frame ${start}`
222223
: `Now showing frames ${start} through ${end}`;
224+
emit('ariaMessage', ariaMessage.value);
223225
}, 1000);
224226
225227
/**
@@ -232,6 +234,7 @@ const handleFocusIn = (e: FocusEvent) => {
232234
ariaMessage.value = `Showing ${props.frames.length} items. Currently on item ${
233235
currentIndex.value + 1
234236
}. Use left and right arrow keys to navigate.`;
237+
emit('ariaMessage', ariaMessage.value);
235238
}
236239
};
237240
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import { mount, VueWrapper } from '@vue/test-utils';
2+
import { describe, it, expect, vi, beforeEach } from 'vitest';
3+
import CdrFilmstripEngine from '../CdrFilmstripEngine.vue';
4+
import { nextTick, ref } from 'vue';
5+
6+
vi.mock('@vueuse/core', async () => {
7+
const actual = await vi.importActual('@vueuse/core');
8+
return {
9+
...actual,
10+
useElementHover: () => ref(true), // Force hover state to be true
11+
};
12+
});
13+
14+
describe('CdrFilmstripEngine', () => {
15+
const sampleFrames = [
16+
{ key: 'frame-1', props: { text: 'Frame 1' } },
17+
{ key: 'frame-2', props: { text: 'Frame 2' } },
18+
{ key: 'frame-3', props: { text: 'Frame 3' } },
19+
{ key: 'frame-4', props: { text: 'Frame 4' } },
20+
{ key: 'frame-5', props: { text: 'Frame 5' } },
21+
];
22+
23+
let wrapper: VueWrapper<any>;
24+
25+
beforeEach(() => {
26+
wrapper = mount(CdrFilmstripEngine, {
27+
props: { frames: sampleFrames, framesToShow: 2, framesToScroll: 1, isShowingArrows: true },
28+
});
29+
30+
// **Mock `scrollBy()` on viewport element**
31+
const mockViewport = wrapper.vm.framesRef?.viewportElement;
32+
if (mockViewport) {
33+
mockViewport.scrollBy = vi.fn(); // Mock as a no-op function
34+
}
35+
});
36+
37+
it('renders correctly with provided frames', async () => {
38+
await nextTick();
39+
expect(wrapper.find('.cdr-filmstrip__viewport').exists()).toBe(true);
40+
expect(wrapper.findAll('.cdr-filmstrip__frame')).toHaveLength(sampleFrames.length);
41+
});
42+
43+
it('shows arrows when isShowingArrows is true', async () => {
44+
await wrapper.setProps({ isShowingArrows: true });
45+
await nextTick();
46+
47+
expect(wrapper.find('[data-ui="cdr-filmstrip__arrow--left"]').exists()).toBe(true);
48+
expect(wrapper.find('[data-ui="cdr-filmstrip__arrow--right"]').exists()).toBe(true);
49+
});
50+
51+
it('disables left arrow at the start and right arrow at the end', async () => {
52+
await wrapper.setProps({ isShowingArrows: true });
53+
await nextTick();
54+
55+
const leftArrow = wrapper.find('[data-ui="cdr-filmstrip__arrow--left"]');
56+
const rightArrow = wrapper.find('[data-ui="cdr-filmstrip__arrow--right"]');
57+
58+
expect(leftArrow.attributes('disabled')).toBeDefined();
59+
expect(rightArrow.attributes('disabled')).toBeUndefined();
60+
61+
// Move to the last frame
62+
await wrapper.vm.onArrowClick(new Event('click'), 'right');
63+
await wrapper.vm.onArrowClick(new Event('click'), 'right');
64+
await wrapper.vm.onArrowClick(new Event('click'), 'right');
65+
66+
await nextTick();
67+
68+
expect(leftArrow.attributes('disabled')).toBeUndefined();
69+
expect(rightArrow.attributes('disabled')).toBeDefined();
70+
});
71+
72+
// it('emits arrowClick event with correct payload', async () => {
73+
// const emitSpy = vi.spyOn(wrapper.vm, '$emit');
74+
75+
// await wrapper.vm.onArrowClick(new Event('click'), 'right');
76+
// await nextTick();
77+
78+
// expect(emitSpy).toHaveBeenCalledWith(
79+
// 'arrowClick',
80+
// expect.objectContaining({ direction: 'right' }),
81+
// );
82+
83+
// await wrapper.vm.onArrowClick(new Event('click'), 'left');
84+
// await nextTick();
85+
86+
// expect(emitSpy).toHaveBeenCalledWith(
87+
// 'arrowClick',
88+
// expect.objectContaining({ direction: 'left' }),
89+
// );
90+
// });
91+
92+
// it('updates correctly when frames prop changes', async () => {
93+
// await wrapper.setProps({
94+
// frames: [
95+
// { key: 'frame-6', props: { text: 'Frame 6' } },
96+
// { key: 'frame-7', props: { text: 'Frame 7' } },
97+
// ],
98+
// });
99+
100+
// await nextTick();
101+
// expect(wrapper.findAll('.cdr-filmstrip__frame')).toHaveLength(2);
102+
// });
103+
104+
// it('handles keyboard navigation correctly', async () => {
105+
// const viewport = wrapper.find('.cdr-filmstrip__viewport');
106+
// await viewport.trigger('keydown', { key: 'ArrowRight' });
107+
108+
// await nextTick();
109+
// expect(wrapper.vm.currentIndex).toBe(1);
110+
111+
// await viewport.trigger('keydown', { key: 'ArrowLeft' });
112+
// await nextTick();
113+
// expect(wrapper.vm.currentIndex).toBe(0);
114+
// });
115+
116+
// it('resizes correctly when container width changes', async () => {
117+
// const container = wrapper.vm.containerRef;
118+
// expect(container).not.toBeNull();
119+
120+
// const mockResizeObserverCallback = vi.fn();
121+
// const resizeObserver = new ResizeObserver((entries) => {
122+
// entries.forEach(() => mockResizeObserverCallback());
123+
// });
124+
125+
// resizeObserver.observe(container);
126+
// await nextTick();
127+
128+
// expect(mockResizeObserverCallback).toHaveBeenCalled();
129+
// });
130+
131+
// it('manages focus correctly', async () => {
132+
// const frames = wrapper.findAll('.cdr-filmstrip__frame');
133+
// await frames[1].trigger('focusin');
134+
135+
// await nextTick();
136+
// expect(wrapper.vm.focusIndex).toBe(1);
137+
138+
// await frames[0].trigger('focusin');
139+
// await nextTick();
140+
// expect(wrapper.vm.focusIndex).toBe(0);
141+
// });
142+
143+
// it('announces frames to screen readers when scrolling', async () => {
144+
// const mockAnnounceFrames = vi.fn();
145+
// wrapper.vm.announceFrames = mockAnnounceFrames;
146+
147+
// await wrapper.vm.onArrowClick(new Event('click'), 'right');
148+
// await nextTick();
149+
150+
// expect(mockAnnounceFrames).toHaveBeenCalled();
151+
// });
152+
});

src/components/filmstrip/examples/Lifestyle/Example.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
class="lifestyle-filmstrip"
44
:model="lifestyleModelData"
55
:adapter="LifestyleAdapter"
6-
@frame-click="onFrameClick"
7-
@arrow-click="onArrowClick"
6+
@frameClick="onFrameClick"
7+
@arrowClick="onArrowClick"
88
@resize="onResize"
99
/>
1010
</template>

src/components/filmstrip/examples/ProductRecommendation/Example.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
class="product-recommendation-filmstrip"
44
:model="ProductRecommendationModelData"
55
:adapter="ProductRecommendationAdapter"
6-
@frame-click="onFrameClick"
7-
@arrow-click="onArrowClick"
6+
@frameClick="onFrameClick"
7+
@arrowClick="onArrowClick"
88
/>
99
</template>
1010

0 commit comments

Comments
 (0)