From 2f2760aba669ef92b18df8bf8c87dce7c8e85770 Mon Sep 17 00:00:00 2001 From: neverland Date: Fri, 5 Jun 2020 09:25:19 +0800 Subject: [PATCH] feat(Picker): item-height support rem unit (#6462) --- src/area/README.md | 2 +- src/area/README.zh-CN.md | 2 +- src/datetime-picker/README.md | 2 +- src/datetime-picker/README.zh-CN.md | 2 +- src/picker/PickerColumn.js | 2 +- src/picker/README.md | 2 +- src/picker/README.zh-CN.md | 4 +- src/picker/index.js | 61 ++++++++++--------- .../test/__snapshots__/index.spec.js.snap | 21 +++++++ src/picker/test/index.spec.js | 18 ++++++ src/utils/format/unit.ts | 21 +++++++ src/utils/test/index.spec.js | 25 ++++++++ 12 files changed, 126 insertions(+), 36 deletions(-) diff --git a/src/area/README.md b/src/area/README.md index 72c54c68a..9c10fdb57 100644 --- a/src/area/README.md +++ b/src/area/README.md @@ -64,7 +64,7 @@ To have a selected value,simply pass the `code` of target area to `value` prop | area-list | Area list data | _object_ | - | | columns-placeholder `v2.2.5` | Placeholder of columns | _string[]_ | `[]` | | loading | Whether to show loading prompt | _boolean_ | `false` | -| item-height | Option height | _number \| string_ | `44` | +| item-height `v2.8.6` | Option height, supports `px` ans `rem` unit, default `px` | _number \| string_ | `44` | | columns-num | Level of picker | _number \| string_ | `3` | | visible-item-count | Count of visible columns | _number \| string_ | `5` | | swipe-duration `v2.2.13` | Duration of the momentum animation,unit `ms` | _number \| string_ | `1000` | diff --git a/src/area/README.zh-CN.md b/src/area/README.zh-CN.md index 60ec2a1a7..71f8367e5 100644 --- a/src/area/README.zh-CN.md +++ b/src/area/README.zh-CN.md @@ -64,7 +64,7 @@ Vue.use(Area); | area-list | 省市区数据,格式见下方 | _object_ | - | | columns-placeholder `v2.2.5` | 列占位提示文字 | _string[]_ | `[]` | | loading | 是否显示加载状态 | _boolean_ | `false` | -| item-height | 选项高度 | _number \| string_ | `44` | +| item-height `v2.8.6` | 选项高度,支持 `px` 和 `rem` 单位,默认 `px` | _number \| string_ | `44` | | columns-num | 显示列数,3-省市区,2-省市,1-省 | _number \| string_ | `3` | | visible-item-count | 可见的选项个数 | _number \| string_ | `5` | | swipe-duration `v2.2.13` | 快速滑动时惯性滚动的时长,单位`ms` | _number \| string_ | `1000` | diff --git a/src/datetime-picker/README.md b/src/datetime-picker/README.md index 93de87b90..fa884c5fe 100644 --- a/src/datetime-picker/README.md +++ b/src/datetime-picker/README.md @@ -198,7 +198,7 @@ export default { | loading | Whether to show loading prompt | _boolean_ | `false` | | filter | Option filter | _(type, vals) => vals_ | - | | formatter | Option text formatter | _(type, val) => val_ | - | -| item-height | Option height | _number \| string_ | `44` | +| item-height `v2.8.6` | Option height, supports `px` ans `rem` unit, default `px` | _number \| string_ | `44` | | visible-item-count | Count of visible columns | _number \| string_ | `5` | | swipe-duration `v2.2.13` | Duration of the momentum animation,unit `ms` | _number \| string_ | `1000` | diff --git a/src/datetime-picker/README.zh-CN.md b/src/datetime-picker/README.zh-CN.md index e9db92cbe..15e5155b5 100644 --- a/src/datetime-picker/README.zh-CN.md +++ b/src/datetime-picker/README.zh-CN.md @@ -205,7 +205,7 @@ export default { | loading | 是否显示加载状态 | _boolean_ | `false` | | filter | 选项过滤函数 | _(type, vals) => vals_ | - | | formatter | 选项格式化函数 | _(type, val) => val_ | - | -| item-height | 选项高度 | _number \| string_ | `44` | +| item-height `v2.8.6` | 选项高度,支持 `px` 和 `rem` 单位,默认 `px` | _number \| string_ | `44` | | visible-item-count | 可见的选项个数 | _number \| string_ | `5` | | swipe-duration `v2.2.13` | 快速滑动时惯性滚动的时长,单位`ms` | _number \| string_ | `1000` | diff --git a/src/picker/PickerColumn.js b/src/picker/PickerColumn.js index 60aad747e..bc3ee03df 100644 --- a/src/picker/PickerColumn.js +++ b/src/picker/PickerColumn.js @@ -33,7 +33,7 @@ export default createComponent({ valueKey: String, allowHtml: Boolean, className: String, - itemHeight: [Number, String], + itemHeight: Number, defaultIndex: Number, swipeDuration: [Number, String], visibleItemCount: [Number, String], diff --git a/src/picker/README.md b/src/picker/README.md index 2d40ac899..a2654b023 100644 --- a/src/picker/README.md +++ b/src/picker/README.md @@ -252,7 +252,7 @@ export default { | show-toolbar | Whether to show toolbar | _boolean_ | `false` | | allow-html `v2.1.8` | Whether to allow HTML in option text | _boolean_ | `true` | | default-index | Default value index of single column picker | _number \| string_ | `0` | -| item-height | Option height | _number \| string_ | `44` | +| item-height `v2.8.6` | Option height, supports `px` ans `rem` unit, default `px` | _number \| string_ | `44` | | visible-item-count | Count of visible columns | _number \| string_ | `5` | | swipe-duration `v2.2.10` | Duration of the momentum animation,unit `ms` | _number \| string_ | `1000` | diff --git a/src/picker/README.zh-CN.md b/src/picker/README.zh-CN.md index f3f8c0a95..9d0fdad33 100644 --- a/src/picker/README.zh-CN.md +++ b/src/picker/README.zh-CN.md @@ -275,9 +275,9 @@ export default { | show-toolbar | 是否显示顶部栏 | _boolean_ | `false` | | allow-html `v2.1.8` | 是否允许选项内容中渲染 HTML | _boolean_ | `true` | | default-index | 单列选择时,默认选中项的索引 | _number \| string_ | `0` | -| item-height | 选项高度 | _number \| string_ | `44` | +| item-height `v2.8.6` | 选项高度,支持 `px` 和 `rem` 单位,默认 `px` | _number \| string_ | `44` | | visible-item-count | 可见的选项个数 | _number \| string_ | `5` | -| swipe-duration `v2.2.10` | 快速滑动时惯性滚动的时长,单位`ms` | _number \| string_ | `1000` | +| swipe-duration `v2.2.10` | 快速滑动时惯性滚动的时长,单位 `ms` | _number \| string_ | `1000` | ### Events diff --git a/src/picker/index.js b/src/picker/index.js index cdbb136a4..927f4faf2 100644 --- a/src/picker/index.js +++ b/src/picker/index.js @@ -3,6 +3,7 @@ import { createNamespace, isObject } from '../utils'; import { preventDefault } from '../utils/dom/event'; import { BORDER_UNSET_TOP_BOTTOM } from '../utils/constant'; import { pickerProps } from './shared'; +import { unitToPx } from '../utils/format/unit'; // Components import Loading from '../loading'; @@ -39,6 +40,10 @@ export default createComponent({ }, computed: { + itemPxHeight() { + return unitToPx(this.itemHeight); + }, + dataType() { const { columns } = this; const firstColumn = columns[0] || {}; @@ -277,12 +282,38 @@ export default createComponent({ }, genColumns() { + const { itemPxHeight } = this; + const wrapHeight = itemPxHeight * this.visibleItemCount; + + const frameStyle = { height: `${itemPxHeight}px` }; + const columnsStyle = { height: `${wrapHeight}px` }; + const maskStyle = { + backgroundSize: `100% ${(wrapHeight - itemPxHeight) / 2}px`, + }; + + return ( +
+ {this.genColumnItems()} +
+
+
+ ); + }, + + genColumnItems() { return this.formattedColumns.map((item, columnIndex) => ( {this.toolbarPosition === 'top' ? this.genToolbar() : h()} {this.loading ? : h()} {this.slots('columns-top')} -
- {this.genColumns()} -
-
-
+ {this.genColumns()} {this.slots('columns-bottom')} {this.toolbarPosition === 'bottom' ? this.genToolbar() : h()}
diff --git a/src/picker/test/__snapshots__/index.spec.js.snap b/src/picker/test/__snapshots__/index.spec.js.snap index 016a64223..2a6f8bb0d 100644 --- a/src/picker/test/__snapshots__/index.spec.js.snap +++ b/src/picker/test/__snapshots__/index.spec.js.snap @@ -103,6 +103,27 @@ exports[`render title slot 1`] = `
`; +exports[`set rem item-height 1`] = ` +
+ +
+
+
    +
  • +
    1990
    +
  • +
  • +
    1991
    +
  • +
+
+
+
+
+ +
+`; + exports[`toolbar-position prop 1`] = `
diff --git a/src/picker/test/index.spec.js b/src/picker/test/index.spec.js index bb959ea9f..f528f8017 100644 --- a/src/picker/test/index.spec.js +++ b/src/picker/test/index.spec.js @@ -261,3 +261,21 @@ test('should not reset index when columns unchanged', () => { wrapper.find('.van-picker__confirm').trigger('click'); expect(wrapper.emitted('confirm')[0]).toEqual(['2', 1]); }); + +test('set rem item-height', async () => { + const originGetComputedStyle = window.getComputedStyle; + + window.getComputedStyle = () => ({ fontSize: '16px' }); + + const wrapper = mount(Picker, { + propsData: { + columns: simpleColumn.slice(0, 2), + itemHeight: '10rem', + }, + }); + + await later(); + expect(wrapper).toMatchSnapshot(); + + window.getComputedStyle = originGetComputedStyle; +}); diff --git a/src/utils/format/unit.ts b/src/utils/format/unit.ts index 613882285..7f422c6af 100644 --- a/src/utils/format/unit.ts +++ b/src/utils/format/unit.ts @@ -9,3 +9,24 @@ export function addUnit(value?: string | number): string | undefined { value = String(value); return isNumeric(value) ? `${value}px` : value; } + +function convertRem(value: string) { + const rootStyle = window.getComputedStyle(document.documentElement); + const rootFontSize = parseFloat(rootStyle.fontSize); + + value = value.replace(/rem/g, ''); + + return +value * rootFontSize; +} + +export function unitToPx(value: string | number): number { + if (typeof value === 'number') { + return value; + } + + if (value.indexOf('rem') !== -1) { + return convertRem(value); + } + + return parseFloat(value); +} diff --git a/src/utils/test/index.spec.js b/src/utils/test/index.spec.js index 281c07dc9..a9d6bea10 100644 --- a/src/utils/test/index.spec.js +++ b/src/utils/test/index.spec.js @@ -9,6 +9,7 @@ import { isNumeric } from '../validate/number'; import { isAndroid } from '../validate/system'; import { camelize } from '../format/string'; import { formatNumber } from '../format/number'; +import { addUnit, unitToPx } from '../format/unit'; test('deepClone', () => { const a = { foo: 0 }; @@ -115,3 +116,27 @@ test('formatNumber', () => { expect(formatNumber('-1.2-', true)).toEqual('-1.2'); expect(formatNumber('123-')).toEqual('123'); }); + +test('addUnit', () => { + expect(addUnit(0)).toEqual('0px'); + expect(addUnit(10)).toEqual('10px'); + expect(addUnit('1%')).toEqual('1%'); + expect(addUnit('1px')).toEqual('1px'); + expect(addUnit('1vw')).toEqual('1vw'); + expect(addUnit('1vh')).toEqual('1vh'); + expect(addUnit('1rem')).toEqual('1rem'); +}); + +test('unitToPx', () => { + const originGetComputedStyle = window.getComputedStyle; + + window.getComputedStyle = () => ({ fontSize: '16px' }); + + expect(unitToPx(0)).toEqual(0); + expect(unitToPx(10)).toEqual(10); + expect(unitToPx('10px')).toEqual(10); + expect(unitToPx('0rem')).toEqual(0); + expect(unitToPx('10rem')).toEqual(160); + + window.getComputedStyle = originGetComputedStyle; +});