|
1 | 1 | <template> |
2 | | - <div v-click-away="{ handler: handleClose, enabled: enableClickAway }"> |
| 2 | + <div |
| 3 | + :style="interactiveStyle" |
| 4 | + @mouseleave="hover && handleClose()" |
| 5 | + v-click-away="{ handler: handleClose, enabled: enableClickAway }" |
| 6 | + > |
3 | 7 | <div |
4 | 8 | ref="triggerNode" |
5 | 9 | @mouseover="hover && handleOpen()" |
6 | | - @mouseleave="hover && handleClose()" |
7 | 10 | @click="handleToggle" |
8 | 11 | @focus="handleOpen" |
9 | 12 | @blur="handleClose" |
|
15 | 18 | </div> |
16 | 19 | <Transition name="fade"> |
17 | 20 | <div |
| 21 | + @click="!interactive && handleToggle()" |
18 | 22 | v-show="shouldShowPopper" |
19 | 23 | :class="['popper', shouldShowPopper ? 'inline-block' : null]" |
20 | 24 | ref="popperNode" |
|
80 | 84 | default: false, |
81 | 85 | }, |
82 | 86 | /** |
83 | | - * Distance in pixels along the trigger element |
| 87 | + * Offset in pixels along the trigger element |
84 | 88 | */ |
85 | | - offsetX: { |
| 89 | + offsetSkid: { |
86 | 90 | type: String, |
87 | 91 | default: "0", |
88 | 92 | }, |
89 | 93 | /** |
90 | | - * Distance in pixels away from the trigger element |
| 94 | + * Offset in pixels away from the trigger element |
91 | 95 | */ |
92 | | - offsetY: { |
| 96 | + offsetDistance: { |
93 | 97 | type: String, |
94 | 98 | default: "12", |
95 | 99 | }, |
|
135 | 139 | type: String, |
136 | 140 | default: "0", |
137 | 141 | }, |
| 142 | + interactive: { |
| 143 | + type: Boolean, |
| 144 | + default: true, |
| 145 | + }, |
138 | 146 | }, |
139 | 147 | setup(props, { slots, emit }) { |
140 | 148 | const children = slots.default(); |
|
150 | 158 | const modifiedIsOpen = ref(false); |
151 | 159 |
|
152 | 160 | const { |
153 | | - offsetX, |
154 | | - offsetY, |
| 161 | + offsetSkid, |
| 162 | + offsetDistance, |
155 | 163 | arrowPadding, |
156 | 164 | placement, |
157 | 165 | disabled, |
158 | 166 | disableClickAway, |
159 | 167 | openDelay, |
160 | 168 | closeDelay, |
| 169 | + interactive, |
161 | 170 | } = toRefs(props); |
162 | 171 |
|
163 | 172 | const { isOpen, open, close } = usePopper({ |
164 | 173 | popperNode, |
165 | 174 | triggerNode, |
166 | | - offsetX, |
167 | | - offsetY, |
| 175 | + offsetSkid, |
| 176 | + offsetDistance, |
168 | 177 | arrowPadding, |
169 | 178 | placement, |
170 | 179 | emit, |
|
218 | 227 | const invalid = computed(() => disabled.value || !hasContent.value); |
219 | 228 | const shouldShowPopper = computed(() => isOpen.value && !invalid.value); |
220 | 229 | const enableClickAway = computed(() => !disableClickAway.value); |
| 230 | + // Add an invisible border to keep the Popper open when hovering from the trigger into it |
| 231 | + const interactiveStyle = computed(() => |
| 232 | + interactive.value |
| 233 | + ? `border: ${offsetDistance.value}px solid transparent; margin: -${offsetDistance.value}px;` |
| 234 | + : null, |
| 235 | + ); |
221 | 236 |
|
222 | 237 | return { |
223 | 238 | popperNode, |
|
230 | 245 | shouldShowPopper, |
231 | 246 | enableClickAway, |
232 | 247 | modifiedIsOpen, |
| 248 | + interactive, |
| 249 | + interactiveStyle, |
233 | 250 | }; |
234 | 251 | }, |
235 | 252 | }); |
|
0 commit comments