Skip to content

Commit c6f9161

Browse files
committed
refactor(CSidebar): update mobile behavior
1 parent 5b5bb4e commit c6f9161

File tree

2 files changed

+61
-14
lines changed

2 files changed

+61
-14
lines changed

Diff for: src/components/backdrop/CBackdrop.ts

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ const CBackdrop = defineComponent({
1313
},
1414
},
1515
setup(props) {
16+
const handleBeforeEnter = (el: RendererElement) => {
17+
el.classList.remove('d-none')
18+
}
1619
const handleEnter = (el: RendererElement, done: () => void) => {
1720
el.addEventListener('transitionend', () => {
1821
done()
@@ -28,12 +31,17 @@ const CBackdrop = defineComponent({
2831
})
2932
el.classList.remove('show')
3033
}
34+
const handleAfterLeave = (el: RendererElement) => {
35+
el.classList.add('d-none')
36+
}
3137
return () =>
3238
h(
3339
Transition,
3440
{
41+
onBeforeEnter: (el) => handleBeforeEnter(el),
3542
onEnter: (el, done) => handleEnter(el, done),
3643
onLeave: (el, done) => handleLeave(el, done),
44+
onAfterLeave: (el) => handleAfterLeave(el),
3745
},
3846
() =>
3947
props.visible &&

Diff for: src/components/sidebar/CSidebar.ts

+53-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { defineComponent, h, onBeforeUnmount, onMounted, ref } from 'vue'
1+
import { defineComponent, h, onBeforeUnmount, onMounted, onUpdated, ref, watch } from 'vue'
2+
import { CBackdrop } from '../backdrop'
23

34
const CSidebar = defineComponent({
45
name: 'CSidebar',
@@ -66,16 +67,22 @@ const CSidebar = defineComponent({
6667
/**
6768
* Toggle the visibility of sidebar component.
6869
*/
69-
visible: {
70-
type: Boolean,
71-
default: undefined,
72-
},
70+
visible: Boolean,
7371
},
7472
emits: ['visible-change'],
75-
setup(props, { slots, emit }) {
73+
setup(props, { attrs, slots, emit }) {
74+
const mobile = ref()
75+
const inViewport = ref()
7676
const sidebarRef = ref()
7777
const visible = ref()
7878

79+
const handleClick = (event: Event) => {
80+
const target = event.target as HTMLElement
81+
target.closest('a.nav-link:not(.nav-group-toggle)')
82+
? (visible.value = false)
83+
: (visible.value = true)
84+
}
85+
7986
const options = {
8087
rootMargin: '0px',
8188
threshold: 1.0,
@@ -86,22 +93,44 @@ const CSidebar = defineComponent({
8693
onMounted(() => {
8794
const callback = (entries: IntersectionObserverEntry[]) => {
8895
entries.forEach((entry) => {
89-
if (entry.isIntersecting !== props.visible || typeof visible.value === 'undefined') {
90-
visible.value = entry.isIntersecting
91-
emit('visible-change', visible.value)
92-
}
96+
inViewport.value = entry.isIntersecting
97+
emit('visible-change', entry.isIntersecting)
9398
})
9499
}
95100

96101
observer = new IntersectionObserver(callback, options)
97102
observer.observe(sidebarRef.value)
103+
104+
mobile.value = Boolean(getComputedStyle(sidebarRef.value).getPropertyValue('--cui-is-mobile'))
105+
})
106+
107+
onUpdated(() => {
108+
mobile.value = Boolean(getComputedStyle(sidebarRef.value).getPropertyValue('--cui-is-mobile'))
109+
110+
if (mobile.value) {
111+
window.addEventListener('click', handleClick)
112+
} else {
113+
window.removeEventListener('click', handleClick)
114+
}
98115
})
99116

100117
onBeforeUnmount(() => {
101118
observer.disconnect()
102119
})
103120

104-
return () =>
121+
watch(
122+
() => props.visible,
123+
() => {
124+
if (props.visible === true && inViewport.value === false) {
125+
visible.value = true
126+
}
127+
if (props.visible === false && inViewport.value === true) {
128+
visible.value = false
129+
}
130+
},
131+
)
132+
133+
return () => [
105134
h(
106135
'div',
107136
{
@@ -116,14 +145,24 @@ const CSidebar = defineComponent({
116145
}`]: props.selfHiding,
117146
[`sidebar-${props.size}`]: props.size,
118147
'sidebar-narrow-unfoldable': props.unfoldable,
119-
show: props.visible === true && visible.value === false,
120-
hide: props.visible === false && visible.value === true,
148+
show: visible.value === true,
149+
hide: visible.value === false,
121150
},
151+
attrs.class,
122152
],
123153
ref: sidebarRef,
124154
},
125155
slots.default && slots.default(),
126-
)
156+
),
157+
mobile.value &&
158+
h(CBackdrop, {
159+
class: 'sidebar-backdrop d-none',
160+
visible: props.visible,
161+
onClick: () => {
162+
visible.value = false
163+
},
164+
}),
165+
]
127166
},
128167
})
129168

0 commit comments

Comments
 (0)