From 128979a35430a2d062d07b094ed0eed8921805d0 Mon Sep 17 00:00:00 2001 From: YUCLing Date: Fri, 25 Oct 2024 12:08:46 +0800 Subject: [PATCH 1/2] fix(tags): wrong tag input width for cjk --- .../common/components/TagSelectionModal.tsx | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/extensions/tags/js/src/common/components/TagSelectionModal.tsx b/extensions/tags/js/src/common/components/TagSelectionModal.tsx index 7b9366f7b8..4aa3468f3c 100644 --- a/extensions/tags/js/src/common/components/TagSelectionModal.tsx +++ b/extensions/tags/js/src/common/components/TagSelectionModal.tsx @@ -75,6 +75,10 @@ export default class TagSelectionModal< protected navigator = new KeyboardNavigatable(); protected indexTag?: Tag; + protected textMeasurementCanvas: HTMLCanvasElement | undefined; + protected textMeasurementCanvasCtx: CanvasRenderingContext2D | undefined; + protected textMeasurementFont: string = ""; + static initAttrs(attrs: ITagSelectionModalAttrs) { super.initAttrs(attrs); @@ -102,6 +106,9 @@ export default class TagSelectionModal< oninit(vnode: Mithril.Vnode) { super.oninit(vnode); + this.textMeasurementCanvas = document.createElement('canvas'); + this.textMeasurementCanvasCtx = this.textMeasurementCanvas.getContext('2d') ?? undefined; + this.navigator .onUp(() => this.setIndex(this.getCurrentNumericIndex() - 1, true)) .onDown(() => this.setIndex(this.getCurrentNumericIndex() + 1, true)) @@ -127,6 +134,26 @@ export default class TagSelectionModal< }); } + onupdate(vnode: Mithril.VnodeDOM): void { + super.onupdate(vnode); + + if (!this.textMeasurementCanvasCtx) return; + const inputEl = vnode.dom.querySelector('.TagsInput > input.FormControl') as HTMLInputElement; + if (!inputEl) return; + const style = getComputedStyle(inputEl); + const font = `${style.getPropertyValue('font-weight')} ${style.getPropertyValue('font-size')} ${style.getPropertyValue('font-family')}`; + if (this.textMeasurementFont != font) { + this.textMeasurementCanvasCtx.font = this.textMeasurementFont = font; + m.redraw(); + } + } + + onremove(vnode: Mithril.VnodeDOM): void { + super.onremove(vnode); + + this.textMeasurementCanvas?.remove(); + } + className() { return classList('TagSelectionModal Modal--simple', this.attrs.className); } @@ -140,12 +167,16 @@ export default class TagSelectionModal< return ; } - const filter = this.filter().toLowerCase(); + const filterText = this.filter(); + const filter = filterText.toLowerCase(); const primaryCount = this.primaryCount(); const secondaryCount = this.secondaryCount(); const tags = this.getFilteredTags(); - const inputWidth = Math.max(extractText(this.getInstruction(primaryCount, secondaryCount)).length, this.filter().length); + const instructionText = extractText(this.getInstruction(primaryCount, secondaryCount)); + const inputChars = Math.max(instructionText.length, filterText.length); + const textWidth = filterText ? this.measureText(filterText)?.width : this.measureText(instructionText)?.width; + const inputWidth = textWidth ? `${textWidth}px` : `${inputChars}ch`; return [
@@ -169,7 +200,7 @@ export default class TagSelectionModal< className="FormControl" placeholder={extractText(this.getInstruction(primaryCount, secondaryCount))} bidi={this.filter} - style={{ width: inputWidth + 'ch' }} + style={{ width: inputWidth }} onkeydown={this.navigator.navigate.bind(this.navigator)} onfocus={() => (this.focused = true)} onblur={() => (this.focused = false)} @@ -385,6 +416,13 @@ export default class TagSelectionModal< return ''; } + /** + * Measures the metrics of the given text for tag input control and returns it in pixels. + */ + protected measureText(text: string) { + return this.textMeasurementCanvasCtx?.measureText(text); + } + /** * Submit tag selection. */ From dc4a04c8133213e5bc9219e576708fdd630aa58f Mon Sep 17 00:00:00 2001 From: YUCLing Date: Fri, 25 Oct 2024 12:20:33 +0800 Subject: [PATCH 2/2] fix: quote styles --- extensions/tags/js/src/common/components/TagSelectionModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/tags/js/src/common/components/TagSelectionModal.tsx b/extensions/tags/js/src/common/components/TagSelectionModal.tsx index 4aa3468f3c..70b9d75d90 100644 --- a/extensions/tags/js/src/common/components/TagSelectionModal.tsx +++ b/extensions/tags/js/src/common/components/TagSelectionModal.tsx @@ -77,7 +77,7 @@ export default class TagSelectionModal< protected textMeasurementCanvas: HTMLCanvasElement | undefined; protected textMeasurementCanvasCtx: CanvasRenderingContext2D | undefined; - protected textMeasurementFont: string = ""; + protected textMeasurementFont: string = ''; static initAttrs(attrs: ITagSelectionModalAttrs) { super.initAttrs(attrs);