From 0178c35de92dedfcbbefd41796482057b13f901d Mon Sep 17 00:00:00 2001
From: tangjinzhou <415800467@qq.com>
Date: Thu, 3 Jan 2019 20:51:56 +0800
Subject: [PATCH] perf: input icon grid
---
components/grid/Row.jsx | 2 +-
components/icon/index.js | 2 +-
components/input/Input.jsx | 2 +
components/input/TextArea.jsx | 44 ++++++++++++---
components/input/calculateNodeHeight.js | 68 +++++++++++-------------
components/input/demo/textarea-resize.md | 28 ++++++++++
package.json | 2 +-
types/badge.d.ts | 7 +--
types/cascader.d.ts | 6 +++
9 files changed, 112 insertions(+), 49 deletions(-)
create mode 100644 components/input/demo/textarea-resize.md
diff --git a/components/grid/Row.jsx b/components/grid/Row.jsx
index 09e77bb1d..a89546212 100644
--- a/components/grid/Row.jsx
+++ b/components/grid/Row.jsx
@@ -105,7 +105,7 @@ export default {
getGutter () {
const { gutter } = this
if (typeof gutter === 'object') {
- for (let i = 0; i <= responsiveArray.length; i++) {
+ for (let i = 0; i < responsiveArray.length; i++) {
const breakpoint = responsiveArray[i]
if (this.screens[breakpoint] && gutter[breakpoint] !== undefined) {
return gutter[breakpoint]
diff --git a/components/icon/index.js b/components/icon/index.js
index 31e4ec37a..d6c2cd9d1 100644
--- a/components/icon/index.js
+++ b/components/icon/index.js
@@ -112,7 +112,7 @@ const Icon = {
` the 'theme' prop '${theme}' will be ignored.`)
}
computedType = withThemeSuffix(
- removeTypeTheme(alias(type)),
+ removeTypeTheme(alias(computedType)),
dangerousTheme || theme || defaultTheme,
)
innerNode = (
diff --git a/components/input/Input.jsx b/components/input/Input.jsx
index 5f050b285..8863328c8 100644
--- a/components/input/Input.jsx
+++ b/components/input/Input.jsx
@@ -171,6 +171,8 @@ export default {
'addonAfter',
'prefix',
'suffix',
+ 'value',
+ 'defaultValue',
])
const { stateValue, getInputClassName, handleKeyDown, handleChange, $listeners } = this
const inputProps = {
diff --git a/components/input/TextArea.jsx b/components/input/TextArea.jsx
index 1ff5a6cde..a488be4a4 100644
--- a/components/input/TextArea.jsx
+++ b/components/input/TextArea.jsx
@@ -1,5 +1,6 @@
import omit from 'omit.js'
+import ResizeObserver from 'resize-observer-polyfill'
import inputProps from './inputProps'
import calculateNodeHeight from './calculateNodeHeight'
import hasProp from '../_util/props-util'
@@ -47,22 +48,53 @@ export default {
},
watch: {
value (val) {
+ this.$nextTick(() => {
+ this.resizeOnNextFrame()
+ })
this.stateValue = fixControlledValue(val)
- if (this.nextFrameActionId) {
- clearNextFrameAction(this.nextFrameActionId)
+ },
+ autosize (val) {
+ if (!val && this.$refs.textArea) {
+ this.textareaStyles = omit(this.textareaStyles, ['overflowY'])
}
- this.nextFrameActionId = onNextFrame(this.resizeTextarea)
},
},
mounted () {
this.$nextTick(() => {
this.resizeTextarea()
+ this.updateResizeObserverHook()
if (this.autoFocus) {
this.focus()
}
})
},
+ updated () {
+ this.updateResizeObserverHook()
+ },
+ beforeDestroy () {
+ if (this.resizeObserver) {
+ this.resizeObserver.disconnect()
+ }
+ },
methods: {
+ resizeOnNextFrame () {
+ if (this.nextFrameActionId) {
+ clearNextFrameAction(this.nextFrameActionId)
+ }
+ this.nextFrameActionId = onNextFrame(this.resizeTextarea)
+ },
+ // We will update hooks if `autosize` prop change
+ updateResizeObserverHook () {
+ if (!this.resizeObserver && this.$props.autosize) {
+ // Add resize observer
+ this.resizeObserver = new ResizeObserver(this.resizeOnNextFrame)
+ this.resizeObserver.observe(this.$refs.textArea)
+ } else if (this.resizeObserver && !this.$props.autosize) {
+ // Remove resize observer
+ this.resizeObserver.disconnect()
+ this.resizeObserver = null
+ }
+ },
handleKeyDown (e) {
if (e.keyCode === 13) {
this.$emit('pressEnter', e)
@@ -91,9 +123,7 @@ export default {
handleTextareaChange (e) {
if (!hasProp(this, 'value')) {
this.stateValue = e.target.value
- this.$nextTick(() => {
- this.resizeTextarea()
- })
+ this.resizeTextarea()
} else {
this.$forceUpdate()
}
@@ -126,6 +156,8 @@ export default {
'prefixCls',
'autosize',
'type',
+ 'value',
+ 'defaultValue',
])
const textareaProps = {
attrs: { ...otherProps, ...$attrs },
diff --git a/components/input/calculateNodeHeight.js b/components/input/calculateNodeHeight.js
index c1dcf48ab..12c194e23 100644
--- a/components/input/calculateNodeHeight.js
+++ b/components/input/calculateNodeHeight.js
@@ -5,15 +5,15 @@
*/
const HIDDEN_TEXTAREA_STYLE = `
-min-height:0 !important;
-max-height:none !important;
-height:0 !important;
-visibility:hidden !important;
-overflow:hidden !important;
-position:absolute !important;
-z-index:-1000 !important;
-top:0 !important;
-right:0 !important
+ min-height:0 !important;
+ max-height:none !important;
+ height:0 !important;
+ visibility:hidden !important;
+ overflow:hidden !important;
+ position:absolute !important;
+ z-index:-1000 !important;
+ top:0 !important;
+ right:0 !important
`
const SIZING_STYLE = [
@@ -38,11 +38,9 @@ const computedStyleCache = {}
let hiddenTextarea
function calculateNodeStyling (node, useCache = false) {
- const nodeRef = (
- node.getAttribute('id') ||
- node.getAttribute('data-reactid') ||
- node.getAttribute('name')
- )
+ const nodeRef = (node.getAttribute('id') ||
+ node.getAttribute('data-reactid') ||
+ node.getAttribute('name'))
if (useCache && computedStyleCache[nodeRef]) {
return computedStyleCache[nodeRef]
@@ -50,25 +48,20 @@ function calculateNodeStyling (node, useCache = false) {
const style = window.getComputedStyle(node)
- const boxSizing = (
+ const boxSizing =
style.getPropertyValue('box-sizing') ||
- style.getPropertyValue('-moz-box-sizing') ||
- style.getPropertyValue('-webkit-box-sizing')
- )
+ style.getPropertyValue('-moz-box-sizing') ||
+ style.getPropertyValue('-webkit-box-sizing')
- const paddingSize = (
+ const paddingSize =
parseFloat(style.getPropertyValue('padding-bottom')) +
- parseFloat(style.getPropertyValue('padding-top'))
- )
+ parseFloat(style.getPropertyValue('padding-top'))
- const borderSize = (
+ const borderSize =
parseFloat(style.getPropertyValue('border-bottom-width')) +
- parseFloat(style.getPropertyValue('border-top-width'))
- )
+ parseFloat(style.getPropertyValue('border-top-width'))
- const sizingStyle = SIZING_STYLE
- .map(name => `${name}:${style.getPropertyValue(name)}`)
- .join(';')
+ const sizingStyle = SIZING_STYLE.map(name => `${name}:${style.getPropertyValue(name)}`).join(';')
const nodeInfo = {
sizingStyle,
@@ -105,10 +98,10 @@ export default function calculateNodeHeight (
// Copy all CSS properties that have an impact on the height of the content in
// the textbox
- const {
- paddingSize, borderSize,
- boxSizing, sizingStyle,
- } = calculateNodeStyling(uiTextNode, useCache)
+ const { paddingSize, borderSize, boxSizing, sizingStyle } = calculateNodeStyling(
+ uiTextNode,
+ useCache,
+ )
// Need to have the overflow attribute to hide the scrollbar otherwise
// text-lines will not calculated properly as the shadow will technically be
@@ -116,22 +109,22 @@ export default function calculateNodeHeight (
hiddenTextarea.setAttribute('style', `${sizingStyle};${HIDDEN_TEXTAREA_STYLE}`)
hiddenTextarea.value = uiTextNode.value || uiTextNode.placeholder || ''
- let minHeight = -Infinity
- let maxHeight = Infinity
+ let minHeight = Number.MIN_SAFE_INTEGER
+ let maxHeight = Number.MAX_SAFE_INTEGER
let height = hiddenTextarea.scrollHeight
let overflowY
if (boxSizing === 'border-box') {
- // border-box: add border, since height = content + padding + border
+ // border-box: add border, since height = content + padding + border
height = height + borderSize
} else if (boxSizing === 'content-box') {
- // remove padding, since height = content
+ // remove padding, since height = content
height = height - paddingSize
}
if (minRows !== null || maxRows !== null) {
- // measure height of a textarea with a single row
- hiddenTextarea.value = ''
+ // measure height of a textarea with a single row
+ hiddenTextarea.value = ' '
const singleRowHeight = hiddenTextarea.scrollHeight - paddingSize
if (minRows !== null) {
minHeight = singleRowHeight * minRows
@@ -150,6 +143,7 @@ export default function calculateNodeHeight (
}
}
// Remove scroll bar flash when autosize without maxRows
+ // donot remove in vue
if (!maxRows) {
overflowY = 'hidden'
}
diff --git a/components/input/demo/textarea-resize.md b/components/input/demo/textarea-resize.md
new file mode 100644
index 000000000..b853cd8e7
--- /dev/null
+++ b/components/input/demo/textarea-resize.md
@@ -0,0 +1,28 @@
+
+#### 文本域
+用于多行输入。
+
+
+
+#### TextArea
+For multi-line input.
+
+
+```html
+
+
+
this.autoResize = !autoResize">
+ Auto Resize: {String(autoResize)}
+
+
+
+
+
+```
diff --git a/package.json b/package.json
index a000f2d0a..f8cb084ca 100644
--- a/package.json
+++ b/package.json
@@ -178,7 +178,7 @@
"mutationobserver-shim": "^0.3.2",
"omit.js": "^1.0.0",
"raf": "^3.4.0",
- "resize-observer-polyfill": "^1.5.0",
+ "resize-observer-polyfill": "^1.5.1",
"shallow-equal": "^1.0.0",
"shallowequal": "^1.0.2",
"vue-ref": "^1.0.3",
diff --git a/types/badge.d.ts b/types/badge.d.ts
index 7d5ff850b..0da61af02 100644
--- a/types/badge.d.ts
+++ b/types/badge.d.ts
@@ -3,13 +3,14 @@
// Definitions: https://github.com/vueComponent/ant-design-vue/types
import { AntdComponent } from './component';
+import { VNode } from 'vue';
export declare class Badge extends AntdComponent {
/**
- * Number to show in badge
- * @type number | string
+ * Number to show in badge, support slot
+ * @type number | string | VNode
*/
- count: number | string;
+ count: number | string | VNode;
/**
* to display a red dot instead of count
diff --git a/types/cascader.d.ts b/types/cascader.d.ts
index f239d95fe..30e8e6f04 100644
--- a/types/cascader.d.ts
+++ b/types/cascader.d.ts
@@ -38,6 +38,12 @@ export interface ShowSearchType {
* @type boolean
*/
matchInputWidth?: boolean;
+
+ /**
+ * Set the count of filtered items
+ * @type number | false
+ */
+ limit?: number | false;
}
export declare class Cascader extends AntdComponent {