1+ import type { ComputedRef } from 'vue' ;
12import { describe , expect , it , vi } from 'vitest' ;
2- import { ref } from 'vue' ;
3+ import { computed , ref } from 'vue' ;
34import { useKeyboard } from './use-keyboard' ;
45
56describe ( 'useKeyboard' , ( ) => {
@@ -9,15 +10,27 @@ describe('useKeyboard', () => {
910 return event ;
1011 } ;
1112
13+ // Helper to build options with defaults and optional overrides
14+ const createOptions = ( override : Partial < {
15+ disabled : boolean ;
16+ collapsible : boolean ;
17+ primary : 'start' | 'end' ;
18+ orientation : 'horizontal' | 'vertical' ;
19+ minSizePercentage : ComputedRef < number > ;
20+ maxSizePercentage : ComputedRef < number | undefined > ;
21+ } > = { } ) => ( {
22+ disabled : override . disabled ?? false ,
23+ collapsible : override . collapsible ?? true ,
24+ primary : override . primary ?? 'start' ,
25+ orientation : override . orientation ?? 'horizontal' ,
26+ minSizePercentage : override . minSizePercentage ?? computed ( ( ) => 0 ) ,
27+ maxSizePercentage : override . maxSizePercentage ?? computed ( ( ) => void 0 ) ,
28+ } ) ;
29+
1230 it ( 'should return handleKeydown function' , ( ) => {
1331 const sizePercentage = ref ( 50 ) ;
1432 const collapsed = ref ( false ) ;
15- const options = {
16- disabled : false ,
17- collapsible : true ,
18- primary : 'start' as const ,
19- orientation : 'horizontal' as const ,
20- } ;
33+ const options = createOptions ( ) ;
2134
2235 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
2336
@@ -27,12 +40,7 @@ describe('useKeyboard', () => {
2740 it ( 'should do nothing when disabled' , ( ) => {
2841 const sizePercentage = ref ( 50 ) ;
2942 const collapsed = ref ( false ) ;
30- const options = {
31- disabled : true ,
32- collapsible : true ,
33- primary : 'start' as const ,
34- orientation : 'horizontal' as const ,
35- } ;
43+ const options = createOptions ( { disabled : true } ) ;
3644
3745 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
3846 const event = createMockKeyboardEvent ( 'ArrowRight' ) ;
@@ -47,12 +55,7 @@ describe('useKeyboard', () => {
4755 it ( 'should decrease size on ArrowLeft when primary is start' , ( ) => {
4856 const sizePercentage = ref ( 50 ) ;
4957 const collapsed = ref ( false ) ;
50- const options = {
51- disabled : false ,
52- collapsible : true ,
53- primary : 'start' as const ,
54- orientation : 'horizontal' as const ,
55- } ;
58+ const options = createOptions ( ) ;
5659
5760 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
5861 const event = createMockKeyboardEvent ( 'ArrowLeft' ) ;
@@ -66,12 +69,7 @@ describe('useKeyboard', () => {
6669 it ( 'should increase size on ArrowRight when primary is start' , ( ) => {
6770 const sizePercentage = ref ( 50 ) ;
6871 const collapsed = ref ( false ) ;
69- const options = {
70- disabled : false ,
71- collapsible : true ,
72- primary : 'start' as const ,
73- orientation : 'horizontal' as const ,
74- } ;
72+ const options = createOptions ( ) ;
7573
7674 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
7775 const event = createMockKeyboardEvent ( 'ArrowRight' ) ;
@@ -85,12 +83,7 @@ describe('useKeyboard', () => {
8583 it ( 'should increase size on ArrowLeft when primary is end' , ( ) => {
8684 const sizePercentage = ref ( 50 ) ;
8785 const collapsed = ref ( false ) ;
88- const options = {
89- disabled : false ,
90- collapsible : true ,
91- primary : 'end' as const ,
92- orientation : 'horizontal' as const ,
93- } ;
86+ const options = createOptions ( { primary : 'end' } ) ;
9487
9588 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
9689 const event = createMockKeyboardEvent ( 'ArrowLeft' ) ;
@@ -105,12 +98,7 @@ describe('useKeyboard', () => {
10598 it ( 'should decrease size on ArrowUp when primary is start' , ( ) => {
10699 const sizePercentage = ref ( 50 ) ;
107100 const collapsed = ref ( false ) ;
108- const options = {
109- disabled : false ,
110- collapsible : true ,
111- primary : 'start' as const ,
112- orientation : 'vertical' as const ,
113- } ;
101+ const options = createOptions ( { orientation : 'vertical' } ) ;
114102
115103 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
116104 const event = createMockKeyboardEvent ( 'ArrowUp' ) ;
@@ -123,12 +111,7 @@ describe('useKeyboard', () => {
123111 it ( 'should increase size on ArrowDown when primary is start' , ( ) => {
124112 const sizePercentage = ref ( 50 ) ;
125113 const collapsed = ref ( false ) ;
126- const options = {
127- disabled : false ,
128- collapsible : true ,
129- primary : 'start' as const ,
130- orientation : 'vertical' as const ,
131- } ;
114+ const options = createOptions ( { orientation : 'vertical' } ) ;
132115
133116 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
134117 const event = createMockKeyboardEvent ( 'ArrowDown' ) ;
@@ -143,12 +126,7 @@ describe('useKeyboard', () => {
143126 it ( 'should change by 10 when shift key is pressed' , ( ) => {
144127 const sizePercentage = ref ( 50 ) ;
145128 const collapsed = ref ( false ) ;
146- const options = {
147- disabled : false ,
148- collapsible : true ,
149- primary : 'start' as const ,
150- orientation : 'horizontal' as const ,
151- } ;
129+ const options = createOptions ( ) ;
152130
153131 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
154132 const event = createMockKeyboardEvent ( 'ArrowRight' , true ) ;
@@ -163,12 +141,7 @@ describe('useKeyboard', () => {
163141 it ( 'should set to 0 on Home when primary is start' , ( ) => {
164142 const sizePercentage = ref ( 50 ) ;
165143 const collapsed = ref ( false ) ;
166- const options = {
167- disabled : false ,
168- collapsible : true ,
169- primary : 'start' as const ,
170- orientation : 'horizontal' as const ,
171- } ;
144+ const options = createOptions ( ) ;
172145
173146 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
174147 const event = createMockKeyboardEvent ( 'Home' ) ;
@@ -181,12 +154,7 @@ describe('useKeyboard', () => {
181154 it ( 'should set to 100 on End when primary is start' , ( ) => {
182155 const sizePercentage = ref ( 50 ) ;
183156 const collapsed = ref ( false ) ;
184- const options = {
185- disabled : false ,
186- collapsible : true ,
187- primary : 'start' as const ,
188- orientation : 'horizontal' as const ,
189- } ;
157+ const options = createOptions ( ) ;
190158
191159 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
192160 const event = createMockKeyboardEvent ( 'End' ) ;
@@ -199,12 +167,7 @@ describe('useKeyboard', () => {
199167 it ( 'should set to 100 on Home when primary is end' , ( ) => {
200168 const sizePercentage = ref ( 50 ) ;
201169 const collapsed = ref ( false ) ;
202- const options = {
203- disabled : false ,
204- collapsible : true ,
205- primary : 'end' as const ,
206- orientation : 'horizontal' as const ,
207- } ;
170+ const options = createOptions ( { primary : 'end' } ) ;
208171
209172 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
210173 const event = createMockKeyboardEvent ( 'Home' ) ;
@@ -219,12 +182,7 @@ describe('useKeyboard', () => {
219182 it ( 'should toggle collapsed state on Enter when collapsible is true' , ( ) => {
220183 const sizePercentage = ref ( 50 ) ;
221184 const collapsed = ref ( false ) ;
222- const options = {
223- disabled : false ,
224- collapsible : true ,
225- primary : 'start' as const ,
226- orientation : 'horizontal' as const ,
227- } ;
185+ const options = createOptions ( ) ;
228186
229187 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
230188 const event = createMockKeyboardEvent ( 'Enter' ) ;
@@ -237,12 +195,7 @@ describe('useKeyboard', () => {
237195 it ( 'should not toggle collapsed state on Enter when collapsible is false' , ( ) => {
238196 const sizePercentage = ref ( 50 ) ;
239197 const collapsed = ref ( false ) ;
240- const options = {
241- disabled : false ,
242- collapsible : false ,
243- primary : 'start' as const ,
244- orientation : 'horizontal' as const ,
245- } ;
198+ const options = createOptions ( { collapsible : false } ) ;
246199
247200 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
248201 const event = createMockKeyboardEvent ( 'Enter' ) ;
@@ -257,12 +210,7 @@ describe('useKeyboard', () => {
257210 it ( 'should clamp size to 0 minimum' , ( ) => {
258211 const sizePercentage = ref ( 2 ) ;
259212 const collapsed = ref ( false ) ;
260- const options = {
261- disabled : false ,
262- collapsible : true ,
263- primary : 'start' as const ,
264- orientation : 'horizontal' as const ,
265- } ;
213+ const options = createOptions ( ) ;
266214
267215 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
268216 const event = createMockKeyboardEvent ( 'ArrowLeft' , true ) ;
@@ -275,12 +223,7 @@ describe('useKeyboard', () => {
275223 it ( 'should clamp size to 100 maximum' , ( ) => {
276224 const sizePercentage = ref ( 98 ) ;
277225 const collapsed = ref ( false ) ;
278- const options = {
279- disabled : false ,
280- collapsible : true ,
281- primary : 'start' as const ,
282- orientation : 'horizontal' as const ,
283- } ;
226+ const options = createOptions ( ) ;
284227
285228 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
286229 const event = createMockKeyboardEvent ( 'ArrowRight' , true ) ;
@@ -294,12 +237,7 @@ describe('useKeyboard', () => {
294237 it ( 'should ignore non-handled keys' , ( ) => {
295238 const sizePercentage = ref ( 50 ) ;
296239 const collapsed = ref ( false ) ;
297- const options = {
298- disabled : false ,
299- collapsible : true ,
300- primary : 'start' as const ,
301- orientation : 'horizontal' as const ,
302- } ;
240+ const options = createOptions ( ) ;
303241
304242 const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
305243 const event = createMockKeyboardEvent ( 'KeyA' ) ;
@@ -309,4 +247,65 @@ describe('useKeyboard', () => {
309247 expect ( sizePercentage . value ) . toBe ( 50 ) ;
310248 expect ( event . preventDefault ) . not . toHaveBeenCalled ( ) ;
311249 } ) ;
250+
251+ describe ( 'custom min/max size percentages' , ( ) => {
252+ it ( 'respects a custom minimum size percentage' , ( ) => {
253+ const sizePercentage = ref ( 25 ) ;
254+ const collapsed = ref ( false ) ;
255+ const options = createOptions ( { minSizePercentage : computed ( ( ) => 20 ) } ) ;
256+
257+ const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
258+
259+ const event = new KeyboardEvent ( 'keydown' , { key : 'ArrowLeft' } ) ;
260+ handleKeydown ( event ) ;
261+
262+ expect ( sizePercentage . value ) . toBe ( 24 ) ; // still above min -> decremented
263+
264+ for ( let i = 0 ; i < 10 ; i ++ ) handleKeydown ( new KeyboardEvent ( 'keydown' , { key : 'ArrowLeft' } ) ) ;
265+
266+ expect ( sizePercentage . value ) . toBe ( 20 ) ; // clamped to min
267+ } ) ;
268+
269+ it ( 'respects a custom maximum size percentage' , ( ) => {
270+ const sizePercentage = ref ( 75 ) ;
271+ const collapsed = ref ( false ) ;
272+ const options = createOptions ( { maxSizePercentage : computed ( ( ) => 80 ) } ) ;
273+
274+ const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
275+
276+ const event = new KeyboardEvent ( 'keydown' , { key : 'ArrowRight' } ) ;
277+ handleKeydown ( event ) ;
278+
279+ expect ( sizePercentage . value ) . toBe ( 76 ) ;
280+
281+ for ( let i = 0 ; i < 10 ; i ++ ) handleKeydown ( new KeyboardEvent ( 'keydown' , { key : 'ArrowRight' } ) ) ;
282+
283+ expect ( sizePercentage . value ) . toBe ( 80 ) ; // clamped to max
284+ } ) ;
285+
286+ it ( 'clamps both min and max simultaneously' , ( ) => {
287+ const sizePercentage = ref ( 40 ) ;
288+ const collapsed = ref ( false ) ;
289+ const options = createOptions ( { minSizePercentage : computed ( ( ) => 30 ) , maxSizePercentage : computed ( ( ) => 60 ) } ) ;
290+
291+ const { handleKeydown } = useKeyboard ( sizePercentage , collapsed , options ) ;
292+
293+ // Grow past max with shift
294+ handleKeydown ( new KeyboardEvent ( 'keydown' , { key : 'ArrowRight' , shiftKey : true } ) ) ; // +10 => 50
295+ expect ( sizePercentage . value ) . toBe ( 50 ) ;
296+
297+ handleKeydown ( new KeyboardEvent ( 'keydown' , { key : 'ArrowRight' , shiftKey : true } ) ) ; // +10 => 60
298+ expect ( sizePercentage . value ) . toBe ( 60 ) ;
299+
300+ handleKeydown ( new KeyboardEvent ( 'keydown' , { key : 'ArrowRight' , shiftKey : true } ) ) ; // attempt +10 => 70 -> clamp 60
301+ expect ( sizePercentage . value ) . toBe ( 60 ) ;
302+
303+ // Shrink past min with shift
304+ handleKeydown ( new KeyboardEvent ( 'keydown' , { key : 'ArrowLeft' , shiftKey : true } ) ) ; // -10 => 50
305+ expect ( sizePercentage . value ) . toBe ( 50 ) ;
306+
307+ for ( let i = 0 ; i < 10 ; i ++ ) handleKeydown ( new KeyboardEvent ( 'keydown' , { key : 'ArrowLeft' , shiftKey : true } ) ) ;
308+ expect ( sizePercentage . value ) . toBe ( 30 ) ;
309+ } ) ;
310+ } ) ;
312311} ) ;
0 commit comments