From d3483f795df10d85bff1da4e0032f48fffc34a12 Mon Sep 17 00:00:00 2001 From: Dongming Huang Date: Tue, 10 Mar 2026 16:45:19 +0800 Subject: [PATCH] Auto refresh select width when the attribute is auto --- .../templates/custom-dropdown-width.html | 25 ++++++++++++-- src/MultipleSelect.js | 34 +++++++++++++++++-- src/constants/index.js | 3 ++ vue-examples/src/assets/MS.json | 2 +- .../src/examples/CustomDropdownWidth.vue | 23 +++++++++++++ 5 files changed, 80 insertions(+), 7 deletions(-) diff --git a/site/website/static/templates/custom-dropdown-width.html b/site/website/static/templates/custom-dropdown-width.html index 5a5fe2c0..02adde3d 100644 --- a/site/website/static/templates/custom-dropdown-width.html +++ b/site/website/static/templates/custom-dropdown-width.html @@ -1,7 +1,7 @@ diff --git a/src/MultipleSelect.js b/src/MultipleSelect.js index 775180a5..353655f0 100644 --- a/src/MultipleSelect.js +++ b/src/MultipleSelect.js @@ -733,13 +733,15 @@ class MultipleSelect { computedWidth = window.getComputedStyle(this.$el[0]).width if (computedWidth === 'auto') { - computedWidth = this.$drop.outerWidth() + 20 + computedWidth = this.$drop.outerWidth() + Constants.ICON_WIDTH_OFFSET } } else { - computedWidth = this.$el.outerWidth() + 20 + computedWidth = this.$el.outerWidth() + Constants.ICON_WIDTH_OFFSET } - this.$parent.css('width', this.options.width || computedWidth) + if (this.options.width !== 'auto') { + this.$parent.css('width', this.options.width || computedWidth) + } this.$el.show().addClass('ms-offscreen') } @@ -861,6 +863,32 @@ class MultipleSelect { $span.prop('title', this.getSelects('text')) } + if (this.options.width === 'auto') { + if (!this._autoWidthCanvas) { + this._autoWidthCanvas = document.createElement('canvas') + this._autoWidthContext = this._autoWidthCanvas.getContext('2d') + } + + const context = this._autoWidthContext + + if (context) { + const styles = window.getComputedStyle ? window.getComputedStyle($span[0]) : $span[0].style + const computedFont = styles.font && styles.font.trim() + + context.font = computedFont || + `${styles.fontWeight || 'normal'} ${styles.fontSize || '16px'} ${styles.fontFamily || 'sans-serif'}` + + const textWidth = context.measureText($span.text()).width + const iconWidth = Constants.ICON_WIDTH_OFFSET + (this.$close.width() || 0) + const spanPadding = parseFloat($span.css('paddingLeft')) + parseFloat($span.css('paddingRight')) + const totalWidth = textWidth + iconWidth + spanPadding + 10 + + this.$parent.css('width', totalWidth) + } else { + this.$parent.css('width', 200) + } + } + // set selects to select this.$el.val(this.getSelects()) diff --git a/src/constants/index.js b/src/constants/index.js index cfb2b575..8679038b 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -1,6 +1,7 @@ const VERSION = '2.3.1' const BLOCK_ROWS = 500 const CLUSTER_BLOCKS = 4 +const ICON_WIDTH_OFFSET = 20 const DEFAULTS = { name: '', @@ -146,6 +147,8 @@ const Constants = { DEFAULTS, + ICON_WIDTH_OFFSET, + METHODS, LOCALES: { diff --git a/vue-examples/src/assets/MS.json b/vue-examples/src/assets/MS.json index 09fd5688..0cdcaccf 100644 --- a/vue-examples/src/assets/MS.json +++ b/vue-examples/src/assets/MS.json @@ -100,7 +100,7 @@ { "title": "Custom Dropdown Width", "url": "custom-dropdown-width.html", - "description": "Use dropWidth: 580 option to custom the dropdown width." + "description": "Use dropWidth: 580 option to custom the dropdown width, or use width: 'auto' option to auto adjust the width based on the selected text." }, { "title": "Max Height", diff --git a/vue-examples/src/examples/CustomDropdownWidth.vue b/vue-examples/src/examples/CustomDropdownWidth.vue index dc0363e3..03921351 100644 --- a/vue-examples/src/examples/CustomDropdownWidth.vue +++ b/vue-examples/src/examples/CustomDropdownWidth.vue @@ -104,6 +104,29 @@ + +
+ + +
+ + + + + + +
+