fix: overlay del buscador de concepto acotado al campo

El AutoComplete se estiraba con las descripciones largas y tapaba el diálogo. La lista queda al ancho del input, con clave + texto envuelto.

Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
This commit is contained in:
Cursor Agent 2026-09-08 20:11:56 +00:00
parent 1e5bc22936
commit 7a31453dfd
No known key found for this signature in database
2 changed files with 89 additions and 8 deletions

View file

@ -1844,7 +1844,8 @@ html.dark .p-tieredmenu,
html.dark .p-popover, html.dark .p-popover,
html.dark .p-datepicker, html.dark .p-datepicker,
html.dark .p-select-overlay, html.dark .p-select-overlay,
html.dark .p-multiselect-overlay { html.dark .p-multiselect-overlay,
html.dark .p-autocomplete-overlay {
--p-content-background: #111b2e; --p-content-background: #111b2e;
} }
@ -2237,6 +2238,41 @@ html.dark .p-dialog .p-dialog-header-icon {
.cost-critical { background: #ffebee !important; color: #b42318 !important; } .cost-critical { background: #ffebee !important; color: #b42318 !important; }
.cost-critical-text { color: #b42318; font-weight: 600; } .cost-critical-text { color: #b42318; font-weight: 600; }
.budget-item-picker-overlay.p-autocomplete-overlay,
.budget-item-picker-overlay {
overflow-x: hidden;
box-sizing: border-box;
}
.budget-item-picker-overlay .p-autocomplete-list,
.budget-item-picker-overlay ul {
width: 100%;
margin: 0;
padding: 4px 0;
list-style: none;
}
.budget-item-picker-overlay .p-autocomplete-option,
.budget-item-picker-overlay li {
white-space: normal;
overflow-wrap: anywhere;
align-items: flex-start;
}
.budget-item-option {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
max-width: 100%;
}
.budget-item-option-desc {
color: #5b6573;
font-size: 12px;
line-height: 1.35;
overflow-wrap: anywhere;
}
html.dark .budget-item-option-desc {
color: #94a3b8;
}
/* Grouped menubar: single row, icons, card-style submenus. */ /* Grouped menubar: single row, icons, card-style submenus. */
.menubar.p-menubar { .menubar.p-menubar {
display: flex; display: flex;

View file

@ -4,11 +4,29 @@
:suggestions="filtered" :suggestions="filtered"
option-label="label" option-label="label"
placeholder="Buscar concepto del presupuesto..." placeholder="Buscar concepto del presupuesto..."
class="w-full" class="budget-item-picker w-full"
input-class="w-full"
overlay-class="budget-item-picker-overlay"
panel-class="budget-item-picker-overlay"
dropdown
fluid
force-selection force-selection
complete-on-focus
scroll-height="16rem"
empty-search-message="Sin conceptos que coincidan"
@complete="onSearch" @complete="onSearch"
@item-select="onSelect" @item-select="onSelect"
/> @option-select="onSelect"
@clear="onClear"
@show="alignOverlay"
>
<template #option="{ option }">
<div class="budget-item-option">
<span class="identifier">{{ option.code || "—" }}</span>
<span class="budget-item-option-desc">{{ option.description }}</span>
</div>
</template>
</AutoComplete>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -56,13 +74,33 @@ async function load() {
} }
function onSearch(event: { query: string }) { function onSearch(event: { query: string }) {
const q = event.query.toLowerCase(); const q = (event.query || "").toLowerCase().trim();
filtered.value = items.value.filter((i) => i.label.toLowerCase().includes(q)).slice(0, 30); filtered.value = items.value
.filter((i) => !q || i.label.toLowerCase().includes(q) || i.code.toLowerCase().includes(q))
.slice(0, 30);
} }
function onSelect(event: { value: BudgetOption }) { function onSelect(event: { value?: BudgetOption; option?: BudgetOption }) {
emit("update:modelValue", event.value?.id ?? null); const option = event.value ?? event.option ?? null;
emit("select", event.value ?? null); emit("update:modelValue", option?.id ?? null);
emit("select", option);
}
function onClear() {
emit("update:modelValue", null);
emit("select", null);
}
function alignOverlay() {
nextTick(() => {
const input = document.querySelector(".budget-item-picker input") as HTMLElement | null;
const overlay = document.querySelector(".budget-item-picker-overlay") as HTMLElement | null;
if (!input || !overlay) return;
const width = Math.round(input.getBoundingClientRect().width);
overlay.style.width = `${width}px`;
overlay.style.minWidth = `${width}px`;
overlay.style.maxWidth = `${width}px`;
});
} }
watch(() => props.projectId, load, { immediate: true }); watch(() => props.projectId, load, { immediate: true });
@ -74,3 +112,10 @@ watch(
}, },
); );
</script> </script>
<style scoped>
.budget-item-picker :deep(.p-autocomplete),
.budget-item-picker :deep(.p-autocomplete-input) {
width: 100%;
}
</style>