Skip to content

Commit 0d9e92a

Browse files
committed
fix: Enhance AutoExpandTextArea width handling and add minimum width calculation for Firefox
1 parent 2cd619a commit 0d9e92a

File tree

2 files changed

+48
-11
lines changed

2 files changed

+48
-11
lines changed

components/AutoExpandTextArea.vue

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,54 @@ if (!CSS.supports('field-sizing', 'content')) {
4545
const textareaBounding = useElementBounding(textareaRef)
4646
const getSizingStyles = () => {
4747
const width = textareaRef.value?.offsetWidth
48-
const baseStyleCss = `position: absolute; top: 100px; left: 100px; opacity: 1; max-height: 0; overflow-wrap: anywhere; width: ${width}px; scrollbar-width: none`
48+
const widthRule = typeof width === 'number' && width > 0 ? `width: ${width}px;` : ''
49+
const baseStyleCss = `position: absolute; top: 100px; left: 100px; opacity: 1; max-height: 0; overflow-wrap: anywhere; scrollbar-width: none; ${widthRule}`
4950
if (!textareaRef.value) return baseStyleCss
5051
const el = textareaRef.value
5152
const styles = window.getComputedStyle(el)
5253
const sizingStyles = ['width', 'padding-left', 'padding-right', 'border-left', 'border-right', 'box-sizing', 'font-family', 'font-size']
53-
return sizingStyles.filter((prop) => !!styles.getPropertyValue(prop)).map((prop) => `${prop}: ${styles.getPropertyValue(prop)}`).join('; ') + ';' + baseStyleCss
54+
return sizingStyles
55+
.filter((prop) => !!styles.getPropertyValue(prop))
56+
.map((prop) => `${prop}: ${styles.getPropertyValue(prop)}`)
57+
.join('; ') + ';' + baseStyleCss
5458
}
5559
const { element: measureEl } = useTempElement('textarea', { attributes: { style: getSizingStyles(), id: `nm-textarea-measure-${generateRandomId()}` } })
5660
57-
watch(() => [textareaBounding.width.value], ([width]) => {
61+
const syncMeasureStyles = (width?: number) => {
5862
measureEl.style.cssText = getSizingStyles()
59-
measureEl.style.width = `${width}px`
60-
})
63+
if (typeof width === 'number' && width > 0) {
64+
measureEl.style.width = `${width}px`
65+
}
66+
}
6167
62-
watch(inputValue, async (v) => {
63-
measureEl.value = v ?? ''
64-
if (!textareaRef.value) return
68+
const resizeTextarea = () => {
6569
const textarea = textareaRef.value
70+
if (!textarea) return
71+
const width = textareaBounding.width.value
72+
if (width <= 0) return
73+
syncMeasureStyles(width)
74+
measureEl.value = inputValue.value ?? ''
6675
// force a reflow to ensure the height is recalculated
6776
const _ = measureEl.offsetHeight
6877
const scrollHeight = measureEl.scrollHeight
6978
const height = Math.max(props.minHeight || 0, scrollHeight)
70-
textarea.style.height = `${height}px` // Set height to scrollHeight to expand
71-
})
79+
textarea.style.height = `${height}px`
80+
}
81+
82+
watch(
83+
() => textareaBounding.width.value,
84+
() => {
85+
resizeTextarea()
86+
},
87+
{ immediate: true, flush: 'post' },
88+
)
89+
90+
watch(
91+
inputValue,
92+
() => {
93+
resizeTextarea()
94+
},
95+
{ immediate: true, flush: 'post' },
96+
)
7297
}
7398
</script>

entrypoints/sidepanel/components/Chat/Messages/User.vue

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
</div>
1212
<div
1313
v-else
14-
class="flex relative rounded-md border border-border-chat-input bg-bg-chat-input text-text-primary p-2 max-w-full min-w-[220px] focus-within:shadow-[0px_0px_0px_1px_var(--color-border-accent)] max-h-24"
14+
class="flex relative rounded-md border border-border-chat-input bg-bg-chat-input text-text-primary p-2 max-w-full focus-within:shadow-[0px_0px_0px_1px_var(--color-border-accent)] max-h-24"
15+
:style="{width: calcMinWidth}"
1516
>
1617
<ScrollContainer
1718
class="overflow-hidden w-full"
@@ -133,6 +134,8 @@ const emit = defineEmits<{
133134
(e: 'submitEdit', value: string): void
134135
}>()
135136
137+
const isFirefox = import.meta.env.FIREFOX
138+
136139
const { t } = useI18n()
137140
const draft = ref(props.message.displayContent ?? props.message.content)
138141
const editTextareaRef = ref<InstanceType<typeof AutoExpandTextArea>>()
@@ -147,6 +150,15 @@ const ensureDraftFromMessage = () => {
147150
draft.value = props.message.displayContent ?? props.message.content
148151
}
149152
153+
const calcMinWidth = computed(() => {
154+
// For fixing firefox edit textarea cannot full width issue, if browser is firefox, use window width and it will auto clip and fill container
155+
156+
if (isFirefox) {
157+
return `${window.innerWidth}px`
158+
}
159+
return 'auto'
160+
})
161+
150162
watch(() => [props.message.displayContent, props.message.content], () => {
151163
if (!props.isEditing) ensureDraftFromMessage()
152164
})

0 commit comments

Comments
 (0)