feat: Update conversation side panel layout and styling (#12983)

This commit is contained in:
Sivin Varghese
2025-12-04 13:55:07 +05:30
committed by GitHub
parent 832d61c004
commit 604d4a9c30
68 changed files with 2336 additions and 2553 deletions
@@ -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 };
}