diff --git a/src/desktop-main.ts b/src/desktop-main.ts index 0d0351d6..b9d41957 100644 --- a/src/desktop-main.ts +++ b/src/desktop-main.ts @@ -108,6 +108,8 @@ import AccountBalanceTrendsChart from '@/components/desktop/AccountBalanceTrends import AccountAndCategorySankeyChart from '@/components/desktop/AccountAndCategorySankeyChart.vue'; import SwitchToMobileDialog from '@/components/desktop/SwitchToMobileDialog.vue'; +import TextFieldAutoWidth from '@/directives/desktop/textfieldAutoWidth.ts'; + import '@/styles/desktop/template/vuetify/index.scss'; import '@/styles/desktop/template/template/index.scss'; import '@/styles/desktop/template/layout/index.scss'; @@ -550,4 +552,6 @@ app.component('AccountBalanceTrendsChart', AccountBalanceTrendsChart); app.component('AccountAndCategorySankeyChart', AccountAndCategorySankeyChart); app.component('SwitchToMobileDialog', SwitchToMobileDialog); +app.directive('TextFieldAutoWidth', TextFieldAutoWidth); + app.mount('#app'); diff --git a/src/directives/desktop/textfieldAutoWidth.ts b/src/directives/desktop/textfieldAutoWidth.ts new file mode 100644 index 00000000..30552c55 --- /dev/null +++ b/src/directives/desktop/textfieldAutoWidth.ts @@ -0,0 +1,57 @@ +import type { DirectiveBinding } from 'vue'; + +interface AutoWidthOptions { + auxSpanId: string; + minWidth?: number; + maxWidth?: number; +} + +function updateWidth(el: HTMLElement, options: AutoWidthOptions, initStyle: boolean): void { + const input = el.querySelector('input'); + + if (!input) { + return; + } + + const auxEl = el.parentElement?.querySelector(`span#${options.auxSpanId}`); + + if (!auxEl) { + return; + } + + const span = auxEl as HTMLSpanElement; + + if (initStyle) { + const inputStyle = window.getComputedStyle(input); + span.style.position = 'absolute'; + span.style.visibility = 'hidden'; + span.style.whiteSpace = 'pre'; + span.style.font = inputStyle.font; + span.style.letterSpacing = inputStyle.letterSpacing; + span.style.padding = '0'; + span.style.margin = '0'; + } + + span.textContent = input.value || input.placeholder || ''; + + let width: number = span.offsetWidth; + + if (options.minWidth) { + width = Math.max(width, options.minWidth); + } + + if (options.maxWidth) { + width = Math.min(width, options.maxWidth); + } + + el.style.width = `${width}px`; +} + +export default { + mounted(el: HTMLElement, binding: DirectiveBinding): void { + updateWidth(el, binding.value, true); + }, + updated(el: HTMLElement, binding: DirectiveBinding): void { + updateWidth(el, binding.value, false); + } +} diff --git a/src/views/desktop/insights/tabs/ExploreQueryTab.vue b/src/views/desktop/insights/tabs/ExploreQueryTab.vue index e285f690..6617c6b1 100644 --- a/src/views/desktop/insights/tabs/ExploreQueryTab.vue +++ b/src/views/desktop/insights/tabs/ExploreQueryTab.vue @@ -15,13 +15,16 @@ - {{ query.name || `${tt('Query')} #${queryIndex + 1}` }} + {{ query.name || `${tt('Query')} #${queryIndex + 1}` }}
- +