@@ -182,20 +182,73 @@ const renderContent = (h, ctx) => {
182
182
}
183
183
184
184
const renderBackdrop = ( h , ctx ) => {
185
- if ( ! ctx . backdrop ) {
186
- return h ( )
185
+ let $backdrop = h ( )
186
+ if ( ctx . backdrop ) {
187
+ const { backdropVariant } = ctx
188
+
189
+ $backdrop = h ( 'div' , {
190
+ directives : [ { name : 'show' , value : ctx . localShow } ] ,
191
+ staticClass : 'b-sidebar-backdrop' ,
192
+ class : { [ `bg-${ backdropVariant } ` ] : backdropVariant } ,
193
+ on : { click : ctx . onBackdropClick }
194
+ } )
187
195
}
188
196
189
- const { backdropVariant } = ctx
197
+ return h ( BVTransition , { props : { noFade : ctx . noSlide } } , [ $backdrop ] )
198
+ }
199
+
200
+ const renderTabTrap = ( h , ctx , focusHandler ) => {
201
+ if ( ctx . noEnforceFocus ) {
202
+ return h ( )
203
+ }
190
204
191
- return h ( 'div' , {
192
- directives : [ { name : 'show' , value : ctx . localShow } ] ,
193
- staticClass : 'b-sidebar-backdrop' ,
194
- class : { [ `bg-${ backdropVariant } ` ] : backdropVariant } ,
195
- on : { click : ctx . onBackdropClick }
205
+ return h ( 'span' , {
206
+ class : { 'd-none' : ! ctx . localShow } ,
207
+ attrs : { tabindex : '0' } ,
208
+ on : { focus : focusHandler }
196
209
} )
197
210
}
198
211
212
+ const renderSidebar = ( h , ctx ) => {
213
+ const { bgVariant, width, textVariant } = ctx
214
+ const shadow = ctx . shadow === '' ? true : ctx . shadow
215
+
216
+ return h (
217
+ 'transition' ,
218
+ {
219
+ props : ctx . transitionProps ,
220
+ on : {
221
+ beforeEnter : ctx . onBeforeEnter ,
222
+ afterEnter : ctx . onAfterEnter ,
223
+ afterLeave : ctx . onAfterLeave
224
+ }
225
+ } ,
226
+ [
227
+ h (
228
+ ctx . tag ,
229
+ {
230
+ staticClass : CLASS_NAME ,
231
+ class : [
232
+ {
233
+ shadow : shadow === true ,
234
+ [ `shadow-${ shadow } ` ] : shadow && shadow !== true ,
235
+ [ `${ CLASS_NAME } -right` ] : ctx . right ,
236
+ [ `bg-${ bgVariant } ` ] : bgVariant ,
237
+ [ `text-${ textVariant } ` ] : textVariant
238
+ } ,
239
+ ctx . sidebarClass
240
+ ] ,
241
+ style : { width } ,
242
+ attrs : ctx . computedAttrs ,
243
+ directives : [ { name : 'show' , value : ctx . localShow } ] ,
244
+ ref : 'content'
245
+ } ,
246
+ [ renderContent ( h , ctx ) ]
247
+ )
248
+ ]
249
+ )
250
+ }
251
+
199
252
// --- Main component ---
200
253
201
254
// @vue /component
@@ -214,6 +267,9 @@ export const BSidebar = /*#__PURE__*/ Vue.extend({
214
267
}
215
268
} ,
216
269
computed : {
270
+ sidebarId ( ) {
271
+ return this . safeId ( )
272
+ } ,
217
273
transitionProps ( ) {
218
274
return this . noSlide
219
275
? /* istanbul ignore next */ { css : true }
@@ -245,7 +301,7 @@ export const BSidebar = /*#__PURE__*/ Vue.extend({
245
301
computedAttrs ( ) {
246
302
return {
247
303
...this . bvAttrs ,
248
- id : this . safeId ( ) ,
304
+ id : this . sidebarId ,
249
305
tabindex : '-1' ,
250
306
role : 'dialog' ,
251
307
'aria-modal' : this . backdrop ? 'true' : 'false' ,
@@ -256,8 +312,8 @@ export const BSidebar = /*#__PURE__*/ Vue.extend({
256
312
}
257
313
} ,
258
314
watch : {
259
- [ MODEL_PROP_NAME ] ( newValue , oldValue ) {
260
- if ( newValue !== oldValue ) {
315
+ [ MODEL_PROP_NAME ] ( newValue ) {
316
+ if ( newValue !== this . localShow ) {
261
317
this . localShow = newValue
262
318
}
263
319
} ,
@@ -284,7 +340,7 @@ export const BSidebar = /*#__PURE__*/ Vue.extend({
284
340
this . listenOnRoot ( ROOT_ACTION_EVENT_NAME_REQUEST_STATE , this . handleSync )
285
341
// Send out a gratuitous state event to ensure toggle button is synced
286
342
this . $nextTick ( ( ) => {
287
- this . emitState ( this . localShow )
343
+ this . emitState ( )
288
344
} )
289
345
} ,
290
346
/* istanbul ignore next */
@@ -300,22 +356,22 @@ export const BSidebar = /*#__PURE__*/ Vue.extend({
300
356
this . localShow = false
301
357
} ,
302
358
emitState ( state = this . localShow ) {
303
- this . emitOnRoot ( ROOT_EVENT_NAME_STATE , this . safeId ( ) , state )
359
+ this . emitOnRoot ( ROOT_EVENT_NAME_STATE , this . sidebarId , state )
304
360
} ,
305
361
emitSync ( state = this . localShow ) {
306
- this . emitOnRoot ( ROOT_EVENT_NAME_SYNC_STATE , this . safeId ( ) , state )
362
+ this . emitOnRoot ( ROOT_EVENT_NAME_SYNC_STATE , this . sidebarId , state )
307
363
} ,
308
364
handleToggle ( id ) {
309
- // Note `safeId() ` can be null until after mount
310
- if ( id && id === this . safeId ( ) ) {
365
+ // Note `sidebarId ` can be ` null` until after mount
366
+ if ( id && id === this . sidebarId ) {
311
367
this . localShow = ! this . localShow
312
368
}
313
369
} ,
314
370
handleSync ( id ) {
315
- // Note `safeId() ` can be null until after mount
316
- if ( id && id === this . safeId ( ) ) {
371
+ // Note `sidebarId ` can be ` null` until after mount
372
+ if ( id && id === this . sidebarId ) {
317
373
this . $nextTick ( ( ) => {
318
- this . emitSync ( this . localShow )
374
+ this . emitSync ( )
319
375
} )
320
376
}
321
377
} ,
@@ -332,13 +388,11 @@ export const BSidebar = /*#__PURE__*/ Vue.extend({
332
388
} ,
333
389
/* istanbul ignore next */
334
390
onTopTrapFocus ( ) {
335
- const tabables = getTabables ( this . $refs . content )
336
- this . enforceFocus ( tabables . reverse ( ) [ 0 ] )
391
+ this . enforceFocus ( getTabables ( this . $refs . content ) . reverse ( ) [ 0 ] )
337
392
} ,
338
393
/* istanbul ignore next */
339
394
onBottomTrapFocus ( ) {
340
- const tabables = getTabables ( this . $refs . content )
341
- this . enforceFocus ( tabables [ 0 ] )
395
+ this . enforceFocus ( getTabables ( this . $refs . content ) [ 0 ] )
342
396
} ,
343
397
onBeforeEnter ( ) {
344
398
// Returning focus to `document.body` may cause unwanted scrolls,
@@ -367,61 +421,6 @@ export const BSidebar = /*#__PURE__*/ Vue.extend({
367
421
}
368
422
} ,
369
423
render ( h ) {
370
- const { bgVariant, width, textVariant, localShow } = this
371
- const shadow = this . shadow === '' ? true : this . shadow
372
-
373
- let $sidebar = h (
374
- this . tag ,
375
- {
376
- staticClass : CLASS_NAME ,
377
- class : [
378
- {
379
- shadow : shadow === true ,
380
- [ `shadow-${ shadow } ` ] : shadow && shadow !== true ,
381
- [ `${ CLASS_NAME } -right` ] : this . right ,
382
- [ `bg-${ bgVariant } ` ] : bgVariant ,
383
- [ `text-${ textVariant } ` ] : textVariant
384
- } ,
385
- this . sidebarClass
386
- ] ,
387
- style : { width } ,
388
- attrs : this . computedAttrs ,
389
- directives : [ { name : 'show' , value : localShow } ] ,
390
- ref : 'content'
391
- } ,
392
- [ renderContent ( h , this ) ]
393
- )
394
-
395
- $sidebar = h (
396
- 'transition' ,
397
- {
398
- props : this . transitionProps ,
399
- on : {
400
- beforeEnter : this . onBeforeEnter ,
401
- afterEnter : this . onAfterEnter ,
402
- afterLeave : this . onAfterLeave
403
- }
404
- } ,
405
- [ $sidebar ]
406
- )
407
-
408
- const $backdrop = h ( BVTransition , { props : { noFade : this . noSlide } } , [
409
- renderBackdrop ( h , this )
410
- ] )
411
-
412
- let $tabTrapTop = h ( )
413
- let $tabTrapBottom = h ( )
414
- if ( this . backdrop && localShow ) {
415
- $tabTrapTop = h ( 'div' , {
416
- attrs : { tabindex : '0' } ,
417
- on : { focus : this . onTopTrapFocus }
418
- } )
419
- $tabTrapBottom = h ( 'div' , {
420
- attrs : { tabindex : '0' } ,
421
- on : { focus : this . onBottomTrapFocus }
422
- } )
423
- }
424
-
425
424
return h (
426
425
'div' ,
427
426
{
@@ -430,7 +429,12 @@ export const BSidebar = /*#__PURE__*/ Vue.extend({
430
429
attrs : { tabindex : '-1' } ,
431
430
on : { keydown : this . onKeydown }
432
431
} ,
433
- [ $tabTrapTop , $sidebar , $tabTrapBottom , $backdrop ]
432
+ [
433
+ renderTabTrap ( h , this , this . onTopTrapFocus ) ,
434
+ renderSidebar ( h , this ) ,
435
+ renderTabTrap ( h , this , this . onBottomTrapFocus ) ,
436
+ renderBackdrop ( h , this )
437
+ ]
434
438
)
435
439
}
436
440
} )
0 commit comments