feat: Update conversation side panel layout and styling (#12983)
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { computed } from 'vue';
|
||||
import { useElementBounding, useWindowSize } from '@vueuse/core';
|
||||
|
||||
/**
|
||||
* Auto-position dropdown based on available space
|
||||
* @param {Ref} triggerRef - Trigger element ref
|
||||
* @param {Ref} dropdownRef - Dropdown element ref
|
||||
* @param {Ref} enabled - Whether to calculate position
|
||||
* @returns {Object} { positionClasses, updatePosition }
|
||||
*/
|
||||
export function useDropdownPosition(triggerRef, dropdownRef, enabled) {
|
||||
const SAFE_MARGIN = 16;
|
||||
const RTL = 'rtl';
|
||||
|
||||
const triggerBounds = useElementBounding(triggerRef);
|
||||
const dropdownBounds = useElementBounding(dropdownRef);
|
||||
const { height: windowHeight, width: windowWidth } = useWindowSize();
|
||||
|
||||
const positionClasses = computed(() => {
|
||||
// Don't calculate if not enabled
|
||||
if (!enabled?.value) {
|
||||
return 'top-full mt-2 ltr:left-0 rtl:right-0';
|
||||
}
|
||||
|
||||
if (!triggerRef.value || !dropdownRef.value) {
|
||||
return 'top-full mt-2 ltr:left-0 rtl:right-0';
|
||||
}
|
||||
|
||||
const spaceBelow = windowHeight.value - triggerBounds.bottom.value;
|
||||
const dropdownHeight = dropdownBounds.height.value || 200;
|
||||
const dropdownWidth = dropdownBounds.width.value || 200;
|
||||
|
||||
// Check if RTL by checking app div with dir attribute
|
||||
const appDiv = document.querySelector('#app[dir]');
|
||||
const isRTL = appDiv?.getAttribute('dir') === RTL;
|
||||
|
||||
// Use appropriate edge based on text direction
|
||||
const triggerEdge = isRTL
|
||||
? triggerBounds.right.value
|
||||
: triggerBounds.left.value;
|
||||
const wouldOverflow = isRTL
|
||||
? triggerEdge - dropdownWidth - SAFE_MARGIN < 0
|
||||
: triggerEdge + dropdownWidth + SAFE_MARGIN > windowWidth.value;
|
||||
|
||||
const vertical =
|
||||
spaceBelow >= dropdownHeight + SAFE_MARGIN
|
||||
? 'top-full mt-2'
|
||||
: 'bottom-full mb-2';
|
||||
|
||||
const horizontal = wouldOverflow
|
||||
? 'ltr:right-0 rtl:left-0'
|
||||
: 'ltr:left-0 rtl:right-0';
|
||||
|
||||
return `${vertical} ${horizontal}`;
|
||||
});
|
||||
|
||||
const updatePosition = () => {
|
||||
triggerBounds.update();
|
||||
dropdownBounds.update();
|
||||
};
|
||||
|
||||
return { positionClasses, updatePosition };
|
||||
}
|
||||
Reference in New Issue
Block a user