@tuya-miniapp/smart-ui 2.13.4-canary.fix-picker.2cc7b5d → 2.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -225,6 +225,8 @@ category: 展示
225
225
  | --cell-label-line-height | _18px_ | 单元格标签行高 |
226
226
  | --cell-label-margin-top | _3px_ | 单元格标签上边距 |
227
227
  | --cell-value-color | _var(--app-B6-N3, rgba(0, 0, 0, 0.5))_ | 单元格值文字颜色 |
228
+ | --cell-value-max-width `v2.13.4` | _none_ | 单元格值区域最大宽度,超出部分隐藏;默认不限制 |
229
+ | --cell-value-margin-left `v2.13.4` | _8px_ | 单元格值区域与标题的间距 |
228
230
  | --cell-icon-size | _24px_ | 单元格图标大小 |
229
231
  | --cell-right-icon-color | _var(--app-B6-N6, rgba(0, 0, 0, 0.2))_ | 单元格右侧图标颜色 |
230
232
  | --cell-border-color `v2.1.4` | _var(--app-B6-N7, rgba(0, 0, 0, 0.1))_ | 单元格边框颜色 |
@@ -1 +1 @@
1
- @import '../common/index.css';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:var(--app-B4,#fff);--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff;--smart-ui-toast-background:#5c5c5c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 4px 12px rgba(0,0,0,.1),0 16px 32px rgba(0,0,0,.12);--smart-ui-overlay-blur-background:rgba(40,44,53,.22)}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--smart-ui-dialog-background:linear-gradient(0deg,var(--app-B4-N6),var(--app-B4-N6)),var(--app-B1);--smart-ui-border-image:linear-gradient(90deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.3),hsla(0,0%,100%,0));--smart-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000;--smart-ui-toast-background:#3c3c3c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 8px 24px 0 rgba(0,0,0,.15);--smart-ui-overlay-blur-background:rgba(0,0,0,.6)}.smart-manrope{font-family:Manrope,sans-serif}.smart-cell{align-items:center;background-color:var(--cell-background-color,var(--app-B6,#fff));box-sizing:border-box;color:var(--cell-text-color,var(--app-B6-N1,#000));display:flex;font-size:var(--cell-font-size,16px);line-height:var(--cell-line-height,24px);padding:var(--cell-vertical-padding,16px) var(--cell-horizontal-padding,16px);position:relative;width:100%}.smart-cell:after{border-bottom:1px solid var(--cell-border-color,var(--app-B6-N7,rgba(0,0,0,.1)));bottom:0;box-sizing:border-box;content:" ";left:var(--cell-border-left-position,16px);pointer-events:none;position:absolute;right:var(--cell-border-right-position,16px);transform:scaleY(.5);transform-origin:center}.smart-cell--borderless:after{display:none}.smart-cell-group{background-color:var(--cell-background-color,var(--app-B6,#fff))}.smart-cell__label{color:var(--cell-label-color,var(--app-B6-N3,rgba(0,0,0,.5)));font-size:var(--cell-label-font-size,14px);line-height:var(--cell-label-line-height,18px);margin-top:var(--cell-label-margin-top,3px)}.smart-cell__title{align-items:flex-start;display:flex;flex-direction:column;justify-content:center}.smart-cell__value{align-items:center;color:var(--cell-value-color,var(--app-B6-N3,rgba(0,0,0,.5)));display:flex;justify-content:flex-end;overflow:hidden;text-align:right;vertical-align:middle}.smart-cell__title,.smart-cell__value{flex:1}.smart-cell__title:empty,.smart-cell__value:empty{display:none}.smart-cell__left-icon-wrap,.smart-cell__right-icon-wrap{align-items:center;display:flex;font-size:var(--cell-icon-size,24px);height:var(--cell-line-height,24px)}.smart-cell__left-icon-wrap{margin-right:var(--padding-base,4px)}.smart-cell__right-icon-wrap{color:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)));margin-left:var(--padding-base,4px)}.smart-cell__left-icon{vertical-align:middle}.smart-cell__left-icon,.smart-cell__right-icon{line-height:var(--cell-line-height,24px)}.smart-cell__right-icon>view{background:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)))}.smart-cell--clickable.smart-cell--hover{background-color:var(--cell-active-color,var(--app-B1,#f6f7fb))}.smart-cell--required{overflow:visible}.smart-cell--required:before{color:var(--cell-required-color,var(--app-M2,#f04c4c));content:"*";font-size:var(--cell-font-size,16px);left:var(--padding-xs,8px);position:absolute}
1
+ @import '../common/index.css';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:var(--app-B4,#fff);--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff;--smart-ui-toast-background:#5c5c5c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 4px 12px rgba(0,0,0,.1),0 16px 32px rgba(0,0,0,.12);--smart-ui-overlay-blur-background:rgba(40,44,53,.22)}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--smart-ui-dialog-background:linear-gradient(0deg,var(--app-B4-N6),var(--app-B4-N6)),var(--app-B1);--smart-ui-border-image:linear-gradient(90deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.3),hsla(0,0%,100%,0));--smart-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000;--smart-ui-toast-background:#3c3c3c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 8px 24px 0 rgba(0,0,0,.15);--smart-ui-overlay-blur-background:rgba(0,0,0,.6)}.smart-manrope{font-family:Manrope,sans-serif}.smart-cell{align-items:center;background-color:var(--cell-background-color,var(--app-B6,#fff));box-sizing:border-box;color:var(--cell-text-color,var(--app-B6-N1,#000));display:flex;font-size:var(--cell-font-size,16px);line-height:var(--cell-line-height,24px);padding:var(--cell-vertical-padding,16px) var(--cell-horizontal-padding,16px);position:relative;width:100%}.smart-cell:after{border-bottom:1px solid var(--cell-border-color,var(--app-B6-N7,rgba(0,0,0,.1)));bottom:0;box-sizing:border-box;content:" ";left:var(--cell-border-left-position,16px);pointer-events:none;position:absolute;right:var(--cell-border-right-position,16px);transform:scaleY(.5);transform-origin:center}.smart-cell--borderless:after{display:none}.smart-cell-group{background-color:var(--cell-background-color,var(--app-B6,#fff))}.smart-cell__label{color:var(--cell-label-color,var(--app-B6-N3,rgba(0,0,0,.5)));font-size:var(--cell-label-font-size,14px);line-height:var(--cell-label-line-height,18px);margin-top:var(--cell-label-margin-top,3px)}.smart-cell__title{align-items:flex-start;display:flex;flex:1;flex-direction:column;justify-content:center}.smart-cell__title:empty{display:none}.smart-cell__value{align-items:center;color:var(--cell-value-color,var(--app-B6-N3,rgba(0,0,0,.5)));display:flex;flex:none;justify-content:flex-end;margin-left:var(--cell-value-margin-left,8px);max-width:var(--cell-value-max-width,none);overflow:hidden;text-align:right;vertical-align:middle}.smart-cell__value:empty{display:none}.smart-cell__left-icon-wrap,.smart-cell__right-icon-wrap{align-items:center;display:flex;font-size:var(--cell-icon-size,24px);height:var(--cell-line-height,24px)}.smart-cell__left-icon-wrap{margin-right:var(--padding-base,4px)}.smart-cell__right-icon-wrap{color:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)));margin-left:var(--padding-base,4px)}.smart-cell__left-icon{vertical-align:middle}.smart-cell__left-icon,.smart-cell__right-icon{line-height:var(--cell-line-height,24px)}.smart-cell__right-icon>view{background:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)))}.smart-cell--clickable.smart-cell--hover{background-color:var(--cell-active-color,var(--app-B1,#f6f7fb))}.smart-cell--required{overflow:visible}.smart-cell--required:before{color:var(--cell-required-color,var(--app-M2,#f04c4c));content:"*";font-size:var(--cell-font-size,16px);left:var(--padding-xs,8px);position:absolute}
@@ -1 +1 @@
1
- @import '../common/index.wxss';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:var(--app-B4,#fff);--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff;--smart-ui-toast-background:#5c5c5c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 4px 12px rgba(0,0,0,.1),0 16px 32px rgba(0,0,0,.12);--smart-ui-overlay-blur-background:rgba(40,44,53,.22)}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--smart-ui-dialog-background:linear-gradient(0deg,var(--app-B4-N6),var(--app-B4-N6)),var(--app-B1);--smart-ui-border-image:linear-gradient(90deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.3),hsla(0,0%,100%,0));--smart-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000;--smart-ui-toast-background:#3c3c3c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 8px 24px 0 rgba(0,0,0,.15);--smart-ui-overlay-blur-background:rgba(0,0,0,.6)}.smart-manrope{font-family:Manrope,sans-serif}.smart-cell{align-items:center;background-color:var(--cell-background-color,var(--app-B6,#fff));box-sizing:border-box;color:var(--cell-text-color,var(--app-B6-N1,#000));display:flex;font-size:var(--cell-font-size,16px);line-height:var(--cell-line-height,24px);padding:var(--cell-vertical-padding,16px) var(--cell-horizontal-padding,16px);position:relative;width:100%}.smart-cell:after{border-bottom:1px solid var(--cell-border-color,var(--app-B6-N7,rgba(0,0,0,.1)));bottom:0;box-sizing:border-box;content:" ";left:var(--cell-border-left-position,16px);pointer-events:none;position:absolute;right:var(--cell-border-right-position,16px);transform:scaleY(.5);transform-origin:center}.smart-cell--borderless:after{display:none}.smart-cell-group{background-color:var(--cell-background-color,var(--app-B6,#fff))}.smart-cell__label{color:var(--cell-label-color,var(--app-B6-N3,rgba(0,0,0,.5)));font-size:var(--cell-label-font-size,14px);line-height:var(--cell-label-line-height,18px);margin-top:var(--cell-label-margin-top,3px)}.smart-cell__title{align-items:flex-start;display:flex;flex-direction:column;justify-content:center}.smart-cell__value{align-items:center;color:var(--cell-value-color,var(--app-B6-N3,rgba(0,0,0,.5)));display:flex;justify-content:flex-end;overflow:hidden;text-align:right;vertical-align:middle}.smart-cell__title,.smart-cell__value{flex:1}.smart-cell__title:empty,.smart-cell__value:empty{display:none}.smart-cell__left-icon-wrap,.smart-cell__right-icon-wrap{align-items:center;display:flex;font-size:var(--cell-icon-size,24px);height:var(--cell-line-height,24px)}.smart-cell__left-icon-wrap{margin-right:var(--padding-base,4px)}.smart-cell__right-icon-wrap{color:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)));margin-left:var(--padding-base,4px)}.smart-cell__left-icon{vertical-align:middle}.smart-cell__left-icon,.smart-cell__right-icon{line-height:var(--cell-line-height,24px)}.smart-cell__right-icon>view{background:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)))}.smart-cell--clickable.smart-cell--hover{background-color:var(--cell-active-color,var(--app-B1,#f6f7fb))}.smart-cell--required{overflow:visible}.smart-cell--required:before{color:var(--cell-required-color,var(--app-M2,#f04c4c));content:"*";font-size:var(--cell-font-size,16px);left:var(--padding-xs,8px);position:absolute}
1
+ @import '../common/index.wxss';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:var(--app-B4,#fff);--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff;--smart-ui-toast-background:#5c5c5c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 4px 12px rgba(0,0,0,.1),0 16px 32px rgba(0,0,0,.12);--smart-ui-overlay-blur-background:rgba(40,44,53,.22)}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--smart-ui-dialog-background:linear-gradient(0deg,var(--app-B4-N6),var(--app-B4-N6)),var(--app-B1);--smart-ui-border-image:linear-gradient(90deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.3),hsla(0,0%,100%,0));--smart-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000;--smart-ui-toast-background:#3c3c3c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 8px 24px 0 rgba(0,0,0,.15);--smart-ui-overlay-blur-background:rgba(0,0,0,.6)}.smart-manrope{font-family:Manrope,sans-serif}.smart-cell{align-items:center;background-color:var(--cell-background-color,var(--app-B6,#fff));box-sizing:border-box;color:var(--cell-text-color,var(--app-B6-N1,#000));display:flex;font-size:var(--cell-font-size,16px);line-height:var(--cell-line-height,24px);padding:var(--cell-vertical-padding,16px) var(--cell-horizontal-padding,16px);position:relative;width:100%}.smart-cell:after{border-bottom:1px solid var(--cell-border-color,var(--app-B6-N7,rgba(0,0,0,.1)));bottom:0;box-sizing:border-box;content:" ";left:var(--cell-border-left-position,16px);pointer-events:none;position:absolute;right:var(--cell-border-right-position,16px);transform:scaleY(.5);transform-origin:center}.smart-cell--borderless:after{display:none}.smart-cell-group{background-color:var(--cell-background-color,var(--app-B6,#fff))}.smart-cell__label{color:var(--cell-label-color,var(--app-B6-N3,rgba(0,0,0,.5)));font-size:var(--cell-label-font-size,14px);line-height:var(--cell-label-line-height,18px);margin-top:var(--cell-label-margin-top,3px)}.smart-cell__title{align-items:flex-start;display:flex;flex:1;flex-direction:column;justify-content:center}.smart-cell__title:empty{display:none}.smart-cell__value{align-items:center;color:var(--cell-value-color,var(--app-B6-N3,rgba(0,0,0,.5)));display:flex;flex:none;justify-content:flex-end;margin-left:var(--cell-value-margin-left,8px);max-width:var(--cell-value-max-width,none);overflow:hidden;text-align:right;vertical-align:middle}.smart-cell__value:empty{display:none}.smart-cell__left-icon-wrap,.smart-cell__right-icon-wrap{align-items:center;display:flex;font-size:var(--cell-icon-size,24px);height:var(--cell-line-height,24px)}.smart-cell__left-icon-wrap{margin-right:var(--padding-base,4px)}.smart-cell__right-icon-wrap{color:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)));margin-left:var(--padding-base,4px)}.smart-cell__left-icon{vertical-align:middle}.smart-cell__left-icon,.smart-cell__right-icon{line-height:var(--cell-line-height,24px)}.smart-cell__right-icon>view{background:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)))}.smart-cell--clickable.smart-cell--hover{background-color:var(--cell-active-color,var(--app-B1,#f6f7fb))}.smart-cell--required{overflow:visible}.smart-cell--required:before{color:var(--cell-required-color,var(--app-M2,#f04c4c));content:"*";font-size:var(--cell-font-size,16px);left:var(--padding-xs,8px);position:absolute}
@@ -47,7 +47,7 @@ export function getRect(context, selector) {
47
47
  .in(context)
48
48
  .select(selector)
49
49
  .boundingClientRect()
50
- .exec((rect = []) => resolve(rect[0]));
50
+ .exec((rect = []) => resolve((rect || [])[0]));
51
51
  });
52
52
  }
53
53
  export function getAllRect(context, selector) {
@@ -56,7 +56,7 @@ export function getAllRect(context, selector) {
56
56
  .in(context)
57
57
  .selectAll(selector)
58
58
  .boundingClientRect()
59
- .exec((rect = []) => resolve(rect[0]));
59
+ .exec((rect = []) => resolve((rect || [])[0] || []));
60
60
  });
61
61
  }
62
62
  export function groupSetData(context, cb) {
@@ -1,10 +1,5 @@
1
1
  import { SmartComponent } from '../common/component';
2
2
  import { pickerProps } from './shared';
3
- // 超过该数量且非 loop 的列启用「窗口化」:只把当前位置附近的一段数据交给子 picker-column,
4
- // 其余保存在逻辑层实例属性中,滚动停稳后再回中,避免把超长数组整份 setData 到渲染层 / 子组件。
5
- const WINDOW_THRESHOLD = 2000;
6
- const WINDOW_SIZE = 1000;
7
- const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
8
3
  SmartComponent({
9
4
  classes: ['hairline-class', 'active-class', 'toolbar-class', 'column-class'],
10
5
  props: Object.assign(Object.assign({}, pickerProps), { valueKey: {
@@ -21,12 +16,6 @@ SmartComponent({
21
16
  value: 0,
22
17
  }, activeIndex: {
23
18
  type: null,
24
- observer() {
25
- // 受控模式下 activeIndex(全局)变化时,若存在窗口化列需以新位置重建窗口
26
- if (this._hasWindow) {
27
- this.buildRenderColumns();
28
- }
29
- },
30
19
  }, unit: {
31
20
  type: String,
32
21
  value: '',
@@ -35,7 +24,6 @@ SmartComponent({
35
24
  value: [],
36
25
  observer(columns = []) {
37
26
  this.simple = columns.length && !columns[0].values;
38
- this.buildRenderColumns();
39
27
  if (Array.isArray(this.children) && this.children.length) {
40
28
  this.setColumns().catch(() => { });
41
29
  }
@@ -43,14 +31,8 @@ SmartComponent({
43
31
  } }),
44
32
  data: {
45
33
  animating: false,
46
- // 交给渲染层 / 子组件的列数据(窗口化列在此仅为切片,非窗口化列为完整数据)
47
- renderColumns: [],
48
34
  },
49
35
  beforeCreate() {
50
- // 每列的窗口状态:{ windowed, start, size, full },保存在逻辑层,不进入 data
51
- this._windows = [];
52
- this._hasWindow = false;
53
- this._repositioning = false;
54
36
  Object.defineProperty(this, 'children', {
55
37
  get: () => this.selectAllComponents('.smart-picker__column') || [],
56
38
  });
@@ -62,103 +44,10 @@ SmartComponent({
62
44
  },
63
45
  methods: {
64
46
  noop() { },
65
- // 归一化列数据:simple 模式(columns 为一维数组)包一层
66
- normalizedColumns() {
67
- const { columns } = this.data;
68
- if (this.simple) {
69
- return [{ values: columns }];
70
- }
71
- return Array.isArray(columns) ? columns : [];
72
- },
73
- // 解析某列的初始全局下标(优先 activeIndex,其次 defaultIndex)
74
- resolveInitialIndex(column) {
75
- const { defaultIndex, activeIndex } = this.data;
76
- const columnActive = column.activeIndex === null || column.activeIndex === undefined
77
- ? activeIndex
78
- : column.activeIndex;
79
- let index;
80
- if (columnActive !== null && columnActive !== undefined) {
81
- index = columnActive;
82
- }
83
- else if (column.defaultIndex !== undefined) {
84
- index = column.defaultIndex;
85
- }
86
- else {
87
- index = defaultIndex;
88
- }
89
- const { length } = column.values || [];
90
- return clamp(index || 0, 0, Math.max(0, length - 1));
91
- },
92
- // 判断某列是否需要窗口化
93
- shouldWindow(column) {
94
- return (!this.data.loop &&
95
- !column.loop &&
96
- Array.isArray(column.values) &&
97
- column.values.length > WINDOW_THRESHOLD);
98
- },
99
- // 基于当前 columns 计算 renderColumns 与每列窗口状态
100
- buildRenderColumns() {
101
- const columns = this.normalizedColumns();
102
- const windows = [];
103
- let hasWindow = false;
104
- const renderColumns = columns.map((column) => {
105
- const values = column.values || [];
106
- if (!this.shouldWindow(column)) {
107
- windows.push({ windowed: false, start: 0, size: values.length, full: values });
108
- return column;
109
- }
110
- hasWindow = true;
111
- const globalIndex = this.resolveInitialIndex(column);
112
- const size = WINDOW_SIZE;
113
- const start = clamp(globalIndex - Math.floor(size / 2), 0, Math.max(0, values.length - size));
114
- const localIndex = globalIndex - start;
115
- windows.push({ windowed: true, start, size, full: values });
116
- return Object.assign(Object.assign({}, column), { values: values.slice(start, start + size), defaultIndex: localIndex, activeIndex: localIndex, _windowed: true });
117
- });
118
- this._windows = windows;
119
- this._hasWindow = hasWindow;
120
- this.setData({ renderColumns });
121
- },
122
- // 将窗口化列停稳后回中:使当前项回到窗口中心,纯坐标平移,静止态无感
123
- recenterColumn(columnIndex) {
124
- const win = this._windows[columnIndex];
125
- if (!win || !win.windowed || this._repositioning)
126
- return;
127
- const column = this.getColumn(columnIndex);
128
- if (!column)
129
- return;
130
- const localIndex = column.data.currentIndex;
131
- const globalIndex = win.start + localIndex;
132
- const { size } = win;
133
- const newStart = clamp(globalIndex - Math.floor(size / 2), 0, Math.max(0, win.full.length - size));
134
- if (newStart === win.start)
135
- return;
136
- this._repositioning = true;
137
- win.start = newStart;
138
- const newLocal = globalIndex - newStart;
139
- // 同一次 setData 内同时更新切片与 active-index(局部),子组件原子接收,
140
- // 配合 wxs 对大跳变强制 transition:none,实现无动画的静默回中
141
- this.setData({
142
- [`renderColumns[${columnIndex}].values`]: win.full.slice(newStart, newStart + size),
143
- [`renderColumns[${columnIndex}].activeIndex`]: newLocal,
144
- }, () => {
145
- this._repositioning = false;
146
- });
147
- },
148
- // 局部下标 -> 全局下标
149
- toGlobalIndex(columnIndex, localIndex) {
150
- const win = this._windows[columnIndex];
151
- return win && win.windowed ? win.start + localIndex : localIndex;
152
- },
153
47
  setColumns() {
154
- const columns = this.normalizedColumns();
155
- const stack = columns.map((column, index) => {
156
- // 窗口化列由 renderColumns(wxml)响应式驱动,不走命令式全量下发
157
- if (this._windows[index] && this._windows[index].windowed) {
158
- return Promise.resolve();
159
- }
160
- return this.setColumnValues(index, column.values);
161
- });
48
+ const { data } = this;
49
+ const columns = this.simple ? [{ values: data.columns }] : data.columns;
50
+ const stack = columns.map((column, index) => this.setColumnValues(index, column.values));
162
51
  return Promise.all(stack);
163
52
  },
164
53
  emit(event) {
@@ -177,7 +66,6 @@ SmartComponent({
177
66
  }
178
67
  },
179
68
  onChange(event) {
180
- const columnIndex = this.simple ? 0 : event.currentTarget.dataset.index;
181
69
  if (this.simple) {
182
70
  this.$emit('change', {
183
71
  picker: this,
@@ -192,8 +80,6 @@ SmartComponent({
192
80
  index: event.currentTarget.dataset.index,
193
81
  });
194
82
  }
195
- // 停稳后再回中,保证切换发生在静止态
196
- this.recenterColumn(columnIndex);
197
83
  },
198
84
  // get column instance by index
199
85
  getColumn(index) {
@@ -206,19 +92,6 @@ SmartComponent({
206
92
  },
207
93
  // set column value by index
208
94
  setColumnValue(index, value) {
209
- const win = this._windows[index];
210
- if (win && win.windowed) {
211
- // 窗口化列:在完整数据中按 valueKey 查找全局下标后跳转
212
- const { valueKey } = this.data;
213
- for (let i = 0; i < win.full.length; i++) {
214
- const option = win.full[i];
215
- const text = option && typeof option === 'object' && valueKey in option ? option[valueKey] : option;
216
- if (text === value) {
217
- return this.setColumnIndex(index, i);
218
- }
219
- }
220
- return Promise.resolve();
221
- }
222
95
  const column = this.getColumn(index);
223
96
  if (column == null) {
224
97
  return Promise.reject(new Error('setColumnValue: The corresponding column does not exist'));
@@ -227,27 +100,10 @@ SmartComponent({
227
100
  },
228
101
  // get column option index by column index
229
102
  getColumnIndex(columnIndex) {
230
- var _a, _b;
231
- const local = (_b = (_a = (this.getColumn(columnIndex) || {}).data) === null || _a === void 0 ? void 0 : _a.currentIndex) !== null && _b !== void 0 ? _b : 0;
232
- return this.toGlobalIndex(columnIndex, local);
103
+ return (this.getColumn(columnIndex) || {}).data.currentIndex;
233
104
  },
234
105
  // set column option index by column index
235
106
  setColumnIndex(columnIndex, optionIndex) {
236
- const win = this._windows[columnIndex];
237
- if (win && win.windowed) {
238
- // 以目标全局下标为中心重建窗口,子组件通过 active-index 定位
239
- const { size } = win;
240
- const globalIndex = clamp(optionIndex, 0, Math.max(0, win.full.length - 1));
241
- const newStart = clamp(globalIndex - Math.floor(size / 2), 0, Math.max(0, win.full.length - size));
242
- win.start = newStart;
243
- this._repositioning = true;
244
- return this.set({
245
- [`renderColumns[${columnIndex}].values`]: win.full.slice(newStart, newStart + size),
246
- [`renderColumns[${columnIndex}].activeIndex`]: globalIndex - newStart,
247
- }).then(() => {
248
- this._repositioning = false;
249
- });
250
- }
251
107
  const column = this.getColumn(columnIndex);
252
108
  if (column == null) {
253
109
  return Promise.reject(new Error('setColumnIndex: The corresponding column does not exist'));
@@ -256,37 +112,15 @@ SmartComponent({
256
112
  },
257
113
  // get options of column by index
258
114
  getColumnValues(index) {
259
- const win = this._windows[index];
260
- if (win && win.windowed) {
261
- return win.full;
262
- }
263
115
  return (this.children[index] || {}).data.options;
264
116
  },
265
117
  // set options of column by index
266
118
  setColumnValues(index, options, needReset = true) {
267
- const win = this._windows[index];
268
- if (win && win.windowed) {
269
- // 替换完整数据并以头部为中心重建窗口
270
- win.full = options || [];
271
- const { size } = win;
272
- const start = needReset ? 0 : clamp(win.start, 0, Math.max(0, win.full.length - size));
273
- win.start = start;
274
- this._repositioning = true;
275
- return this.set({
276
- [`renderColumns[${index}].values`]: win.full.slice(start, start + size),
277
- [`renderColumns[${index}].activeIndex`]: 0,
278
- }).then(() => {
279
- this._repositioning = false;
280
- });
281
- }
282
119
  const column = this.children[index];
283
120
  if (column == null) {
284
121
  return Promise.reject(new Error('setColumnValues: The corresponding column does not exist'));
285
122
  }
286
- const prevOptions = column.data.options || [];
287
- // 先比长度(O(1))短路:长度不同必然不同,避免对超长数组做两次 JSON.stringify
288
- const isSame = prevOptions.length === options.length &&
289
- JSON.stringify(prevOptions) === JSON.stringify(options);
123
+ const isSame = JSON.stringify(column.data.options) === JSON.stringify(options);
290
124
  if (isSame) {
291
125
  return Promise.resolve();
292
126
  }
@@ -307,7 +141,7 @@ SmartComponent({
307
141
  },
308
142
  // get indexes of all columns
309
143
  getIndexes() {
310
- return this.children.map((child, index) => this.toGlobalIndex(index, child.data.currentIndex));
144
+ return this.children.map(child => child.data.currentIndex);
311
145
  },
312
146
  // set indexes of all columns
313
147
  setIndexes(indexes) {
@@ -14,7 +14,7 @@
14
14
  >
15
15
  <picker-column
16
16
  class="smart-picker__column"
17
- wx:for="{{ renderColumns }}"
17
+ wx:for="{{ computed.columns(columns) }}"
18
18
  wx:key="index"
19
19
  data-index="{{ index }}"
20
20
  animation-time="{{ animationTime }}"
@@ -24,7 +24,6 @@
24
24
  active-style="{{ activeStyle }}"
25
25
  font-style="{{fontStyle ? fontStyle + ';' + computed.style(item.fontStyle): computed.style(item.fontStyle)}}"
26
26
  options="{{ item.values }}"
27
- windowed="{{ item._windowed || false }}"
28
27
  disabled="{{ item.disabled || false }}"
29
28
  unit="{{ item.unit || unit }}"
30
29
  unit-gap="{{ item.unitGap }}"
@@ -16,11 +16,6 @@ SmartComponent({
16
16
  className: String,
17
17
  itemHeight: Number,
18
18
  disabled: Boolean,
19
- // 是否为父级窗口化列:为 true 时对大幅度的 active-index 跳变强制关闭过渡(用于停稳回中的静默重定位)
20
- windowed: {
21
- type: Boolean,
22
- value: false,
23
- },
24
19
  visibleItemCount: Number,
25
20
  activeStyle: {
26
21
  type: String,
@@ -33,12 +28,7 @@ SmartComponent({
33
28
  if (!this.data.isInit)
34
29
  return;
35
30
  this.updateUint(value);
36
- // 窗口化列:切片与 activeIndex(局部)在同一批 setData 到达,
37
- // 此处直接采用新的 activeIndex,使「新切片 + 新下标」原子落地,避免差一帧的错位闪烁
38
- const nextIndex = this.data.windowed && this.data.activeIndex !== null && this.data.activeIndex !== undefined
39
- ? this.data.activeIndex
40
- : this.data.currentIndex;
41
- this.updateCurrentIndex(nextIndex);
31
+ this.updateCurrentIndex(this.data.currentIndex);
42
32
  this.updateVisibleOptions();
43
33
  },
44
34
  },
@@ -8,15 +8,15 @@
8
8
  id="{{instanceId}}"
9
9
  data-isdestroy="{{isDestroy}}"
10
10
  data-changeanimation="{{changeAnimation}}"
11
+ data-options="{{options}}"
11
12
  data-valuekey="{{valueKey}}"
12
13
  data-itemheight="{{itemHeight}}"
13
14
  data-visibleitemcount="{{visibleItemCount}}"
14
15
  data-activeindex="{{currentIndex}}"
15
16
  data-loop="{{loop && options.length > 1}}"
16
17
  data-animationtime="{{animationTime}}"
17
- data-windowed="{{windowed}}"
18
18
  isdestroy="{{isDestroy}}"
19
- options="{{options}}"
19
+ options="{{options}}"
20
20
  activeindex="{{currentIndex}}"
21
21
  changeanimation="{{changeAnimation}}"
22
22
  loop="{{loop && options.length > 1}}"
@@ -24,17 +24,15 @@
24
24
  itemheight="{{itemHeight}}"
25
25
  visibleitemcount="{{visibleItemCount}}"
26
26
  animationtime="{{animationTime}}"
27
- windowed="{{windowed}}"
28
27
  change:isdestroy="{{computed.updateValue(instanceId, 'isDestroy')}}"
29
- change:options="{{computed.updateValue(instanceId, 'options')}}"
30
- change:valuekey="{{computed.updateValue(instanceId,'valueKey')}}"
31
- change:itemheight="{{computed.updateValue(instanceId,'itemHeight')}}"
32
- change:visibleitemcount="{{computed.updateValue(instanceId, 'visibleItemCount')}}"
33
- change:activeindex="{{computed.updateValue(instanceId,'activeIndex')}}"
34
- change:loop="{{computed.updateValue(instanceId,'loop')}}"
35
- change:animationtime="{{computed.updateValue(instanceId,'animationTime')}}"
36
- change:windowed="{{computed.updateValue(instanceId,'windowed')}}"
37
- change:instanceid="{{computed.updateValue(instanceId,'instanceId')}}"
28
+ change:options="{{computed.updateValue(instanceId, 'options')}}"
29
+ change:valuekey="{{computed.updateValue(instanceId,'valueKey')}}"
30
+ change:itemheight="{{computed.updateValue(instanceId,'itemHeight')}}"
31
+ change:visibleitemcount="{{computed.updateValue(instanceId, 'visibleItemCount')}}"
32
+ change:activeindex="{{computed.updateValue(instanceId,'activeIndex')}}"
33
+ change:loop="{{computed.updateValue(instanceId,'loop')}}"
34
+ change:animationtime="{{computed.updateValue(instanceId,'animationTime')}}"
35
+ change:instanceid="{{computed.updateValue(instanceId,'instanceId')}}"
38
36
  bind:touchstart="{{computed.touchStart(instanceId)}}"
39
37
  catch:touchmove="{{computed.touchMove(instanceId)}}"
40
38
  bind:touchend="{{computed.touchEnd(instanceId)}}"
@@ -226,8 +226,7 @@ function getDomState(ownerInstance) {
226
226
 
227
227
  function initDomState(instanceId, ownerInstance) {
228
228
  var state = getDomState(ownerInstance);
229
- // options 不再通过 data-options 传入(避免把全量数组塞进 dataset / getDataset),
230
- // 由 change:options -> updateValue('options', ...) 单独维护 state.options
229
+ updateState(instanceId, 'options', state.options)
231
230
  updateState(instanceId, 'valueKey', state.valuekey)
232
231
  updateState(instanceId, 'itemHeight', state.itemheight)
233
232
  updateState(instanceId, 'visibleItemCount', state.visibleitemcount)
@@ -235,7 +234,6 @@ function initDomState(instanceId, ownerInstance) {
235
234
  updateState(instanceId, 'loop', state.loop)
236
235
  updateState(instanceId, 'animationTime', state.animationtime)
237
236
  updateState(instanceId, 'changeAnimation', state.changeanimation)
238
- updateState(instanceId, 'windowed', state.windowed)
239
237
  }
240
238
 
241
239
 
@@ -264,14 +262,10 @@ function updateListView(instanceId, ownerInstance) {
264
262
  var animationIndex = state.animationIndex || 0;
265
263
  var newAnimationIndex = getNewAnimationIndex(animationIndex, activeIndex, length, state.loop);
266
264
  var isSame = newAnimationIndex === animationIndex;
267
- // 窗口化列的「停稳回中/重定位」会产生大幅度的 activeIndex 跳变,此时强制关闭过渡:
268
- // 因为切片内容与位置是同步平移的,直接吸附即像素级一致,避免整轮旋转动画造成抖动。
269
- var vOptionLength = state.visibleItemCount * 4 - 2;
270
- var isWindowReposition = state.windowed && Math.abs(newAnimationIndex - animationIndex) > vOptionLength;
271
265
  updateState(instanceId, 'animationIndex', newAnimationIndex)
272
266
  updateVisibleOptions(state.animationIndex, instanceId);
273
267
  updateWrapperStyle(instanceId, ownerInstance, {
274
- transition: (!state.changeAnimation || isSame || isWindowReposition) ? 'none' : 'transform ' + state.animationTime + 'ms cubic-bezier(0.2, 0.9, 0.25, 1)'
268
+ transition: (!state.changeAnimation || isSame) ? 'none' : 'transform ' + state.animationTime + 'ms cubic-bezier(0.2, 0.9, 0.25, 1)'
275
269
  });
276
270
  }
277
271
 
@@ -379,8 +373,7 @@ function touchEnd(instanceId) {
379
373
 
380
374
  // 惯性滚动参数配置
381
375
  var minVelocity = 0.1; // 最小速度阈值,低于此值停止滚动
382
- // 最大惯性滚动距离:下限 6 项,上限 100 项,避免超长列表单次快滑滚动上万项
383
- var maxInertiaDistance = state.itemHeight * Math.min(Math.max(Math.floor(state.options.length/4), 6), 100);
376
+ var maxInertiaDistance = state.itemHeight * Math.max(Math.floor(state.options.length/4), 6); // 最大惯性滚动距离
384
377
  // 计算惯性滚动距离
385
378
  var inertiaDistance = 0;
386
379
  if (recentVelocity > minVelocity) {
@@ -76,8 +76,8 @@ SmartComponent({
76
76
  if (!touchable)
77
77
  return;
78
78
  const { clientX } = event.touches[0];
79
- getAllRect(this, '.smart-rate__icon').then(list => {
80
- const target = list
79
+ getAllRect(this, '.smart-rate__icon').then((list = []) => {
80
+ const target = (list || [])
81
81
  .sort((cur, next) => cur.dataset.score - next.dataset.score)
82
82
  .find(item => clientX >= item.left && clientX <= item.right);
83
83
  if (target != null) {
@@ -227,7 +227,12 @@ SmartComponent({
227
227
  return;
228
228
  }
229
229
  Promise.all([getAllRect(this, '.smart-tab'), getRect(this, '.smart-tabs__nav')]).then(([tabRects, navRect]) => {
230
- const tabRect = tabRects[currentIndex];
230
+ const tabRect = tabRects === null || tabRects === void 0 ? void 0 : tabRects[currentIndex];
231
+ // On Android the layout query can resolve before the tabs are laid out,
232
+ // in which case there is nothing to scroll to yet.
233
+ if (tabRect == null || navRect == null) {
234
+ return;
235
+ }
231
236
  const offsetLeft = tabRects
232
237
  .slice(0, currentIndex)
233
238
  .reduce((prev, curr) => prev + curr.width, 0);
@@ -225,6 +225,8 @@ category: 展示
225
225
  | --cell-label-line-height | _18px_ | 单元格标签行高 |
226
226
  | --cell-label-margin-top | _3px_ | 单元格标签上边距 |
227
227
  | --cell-value-color | _var(--app-B6-N3, rgba(0, 0, 0, 0.5))_ | 单元格值文字颜色 |
228
+ | --cell-value-max-width `v2.13.4` | _none_ | 单元格值区域最大宽度,超出部分隐藏;默认不限制 |
229
+ | --cell-value-margin-left `v2.13.4` | _8px_ | 单元格值区域与标题的间距 |
228
230
  | --cell-icon-size | _24px_ | 单元格图标大小 |
229
231
  | --cell-right-icon-color | _var(--app-B6-N6, rgba(0, 0, 0, 0.2))_ | 单元格右侧图标颜色 |
230
232
  | --cell-border-color `v2.1.4` | _var(--app-B6-N7, rgba(0, 0, 0, 0.1))_ | 单元格边框颜色 |
@@ -1 +1 @@
1
- @import '../common/index.css';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:var(--app-B4,#fff);--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff;--smart-ui-toast-background:#5c5c5c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 4px 12px rgba(0,0,0,.1),0 16px 32px rgba(0,0,0,.12);--smart-ui-overlay-blur-background:rgba(40,44,53,.22)}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--smart-ui-dialog-background:linear-gradient(0deg,var(--app-B4-N6),var(--app-B4-N6)),var(--app-B1);--smart-ui-border-image:linear-gradient(90deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.3),hsla(0,0%,100%,0));--smart-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000;--smart-ui-toast-background:#3c3c3c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 8px 24px 0 rgba(0,0,0,.15);--smart-ui-overlay-blur-background:rgba(0,0,0,.6)}.smart-manrope{font-family:Manrope,sans-serif}.smart-cell{align-items:center;background-color:var(--cell-background-color,var(--app-B6,#fff));box-sizing:border-box;color:var(--cell-text-color,var(--app-B6-N1,#000));display:flex;font-size:var(--cell-font-size,16px);line-height:var(--cell-line-height,24px);padding:var(--cell-vertical-padding,16px) var(--cell-horizontal-padding,16px);position:relative;width:100%}.smart-cell:after{border-bottom:1px solid var(--cell-border-color,var(--app-B6-N7,rgba(0,0,0,.1)));bottom:0;box-sizing:border-box;content:" ";left:var(--cell-border-left-position,16px);pointer-events:none;position:absolute;right:var(--cell-border-right-position,16px);transform:scaleY(.5);transform-origin:center}.smart-cell--borderless:after{display:none}.smart-cell-group{background-color:var(--cell-background-color,var(--app-B6,#fff))}.smart-cell__label{color:var(--cell-label-color,var(--app-B6-N3,rgba(0,0,0,.5)));font-size:var(--cell-label-font-size,14px);line-height:var(--cell-label-line-height,18px);margin-top:var(--cell-label-margin-top,3px)}.smart-cell__title{align-items:flex-start;display:flex;flex-direction:column;justify-content:center}.smart-cell__value{align-items:center;color:var(--cell-value-color,var(--app-B6-N3,rgba(0,0,0,.5)));display:flex;justify-content:flex-end;overflow:hidden;text-align:right;vertical-align:middle}.smart-cell__title,.smart-cell__value{flex:1}.smart-cell__title:empty,.smart-cell__value:empty{display:none}.smart-cell__left-icon-wrap,.smart-cell__right-icon-wrap{align-items:center;display:flex;font-size:var(--cell-icon-size,24px);height:var(--cell-line-height,24px)}.smart-cell__left-icon-wrap{margin-right:var(--padding-base,4px)}.smart-cell__right-icon-wrap{color:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)));margin-left:var(--padding-base,4px)}.smart-cell__left-icon{vertical-align:middle}.smart-cell__left-icon,.smart-cell__right-icon{line-height:var(--cell-line-height,24px)}.smart-cell__right-icon>view{background:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)))}.smart-cell--clickable.smart-cell--hover{background-color:var(--cell-active-color,var(--app-B1,#f6f7fb))}.smart-cell--required{overflow:visible}.smart-cell--required:before{color:var(--cell-required-color,var(--app-M2,#f04c4c));content:"*";font-size:var(--cell-font-size,16px);left:var(--padding-xs,8px);position:absolute}
1
+ @import '../common/index.css';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:var(--app-B4,#fff);--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff;--smart-ui-toast-background:#5c5c5c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 4px 12px rgba(0,0,0,.1),0 16px 32px rgba(0,0,0,.12);--smart-ui-overlay-blur-background:rgba(40,44,53,.22)}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--smart-ui-dialog-background:linear-gradient(0deg,var(--app-B4-N6),var(--app-B4-N6)),var(--app-B1);--smart-ui-border-image:linear-gradient(90deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.3),hsla(0,0%,100%,0));--smart-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000;--smart-ui-toast-background:#3c3c3c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 8px 24px 0 rgba(0,0,0,.15);--smart-ui-overlay-blur-background:rgba(0,0,0,.6)}.smart-manrope{font-family:Manrope,sans-serif}.smart-cell{align-items:center;background-color:var(--cell-background-color,var(--app-B6,#fff));box-sizing:border-box;color:var(--cell-text-color,var(--app-B6-N1,#000));display:flex;font-size:var(--cell-font-size,16px);line-height:var(--cell-line-height,24px);padding:var(--cell-vertical-padding,16px) var(--cell-horizontal-padding,16px);position:relative;width:100%}.smart-cell:after{border-bottom:1px solid var(--cell-border-color,var(--app-B6-N7,rgba(0,0,0,.1)));bottom:0;box-sizing:border-box;content:" ";left:var(--cell-border-left-position,16px);pointer-events:none;position:absolute;right:var(--cell-border-right-position,16px);transform:scaleY(.5);transform-origin:center}.smart-cell--borderless:after{display:none}.smart-cell-group{background-color:var(--cell-background-color,var(--app-B6,#fff))}.smart-cell__label{color:var(--cell-label-color,var(--app-B6-N3,rgba(0,0,0,.5)));font-size:var(--cell-label-font-size,14px);line-height:var(--cell-label-line-height,18px);margin-top:var(--cell-label-margin-top,3px)}.smart-cell__title{align-items:flex-start;display:flex;flex:1;flex-direction:column;justify-content:center}.smart-cell__title:empty{display:none}.smart-cell__value{align-items:center;color:var(--cell-value-color,var(--app-B6-N3,rgba(0,0,0,.5)));display:flex;flex:none;justify-content:flex-end;margin-left:var(--cell-value-margin-left,8px);max-width:var(--cell-value-max-width,none);overflow:hidden;text-align:right;vertical-align:middle}.smart-cell__value:empty{display:none}.smart-cell__left-icon-wrap,.smart-cell__right-icon-wrap{align-items:center;display:flex;font-size:var(--cell-icon-size,24px);height:var(--cell-line-height,24px)}.smart-cell__left-icon-wrap{margin-right:var(--padding-base,4px)}.smart-cell__right-icon-wrap{color:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)));margin-left:var(--padding-base,4px)}.smart-cell__left-icon{vertical-align:middle}.smart-cell__left-icon,.smart-cell__right-icon{line-height:var(--cell-line-height,24px)}.smart-cell__right-icon>view{background:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)))}.smart-cell--clickable.smart-cell--hover{background-color:var(--cell-active-color,var(--app-B1,#f6f7fb))}.smart-cell--required{overflow:visible}.smart-cell--required:before{color:var(--cell-required-color,var(--app-M2,#f04c4c));content:"*";font-size:var(--cell-font-size,16px);left:var(--padding-xs,8px);position:absolute}
@@ -1 +1 @@
1
- @import '../common/index.wxss';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:var(--app-B4,#fff);--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff;--smart-ui-toast-background:#5c5c5c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 4px 12px rgba(0,0,0,.1),0 16px 32px rgba(0,0,0,.12);--smart-ui-overlay-blur-background:rgba(40,44,53,.22)}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--smart-ui-dialog-background:linear-gradient(0deg,var(--app-B4-N6),var(--app-B4-N6)),var(--app-B1);--smart-ui-border-image:linear-gradient(90deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.3),hsla(0,0%,100%,0));--smart-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000;--smart-ui-toast-background:#3c3c3c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 8px 24px 0 rgba(0,0,0,.15);--smart-ui-overlay-blur-background:rgba(0,0,0,.6)}.smart-manrope{font-family:Manrope,sans-serif}.smart-cell{align-items:center;background-color:var(--cell-background-color,var(--app-B6,#fff));box-sizing:border-box;color:var(--cell-text-color,var(--app-B6-N1,#000));display:flex;font-size:var(--cell-font-size,16px);line-height:var(--cell-line-height,24px);padding:var(--cell-vertical-padding,16px) var(--cell-horizontal-padding,16px);position:relative;width:100%}.smart-cell:after{border-bottom:1px solid var(--cell-border-color,var(--app-B6-N7,rgba(0,0,0,.1)));bottom:0;box-sizing:border-box;content:" ";left:var(--cell-border-left-position,16px);pointer-events:none;position:absolute;right:var(--cell-border-right-position,16px);transform:scaleY(.5);transform-origin:center}.smart-cell--borderless:after{display:none}.smart-cell-group{background-color:var(--cell-background-color,var(--app-B6,#fff))}.smart-cell__label{color:var(--cell-label-color,var(--app-B6-N3,rgba(0,0,0,.5)));font-size:var(--cell-label-font-size,14px);line-height:var(--cell-label-line-height,18px);margin-top:var(--cell-label-margin-top,3px)}.smart-cell__title{align-items:flex-start;display:flex;flex-direction:column;justify-content:center}.smart-cell__value{align-items:center;color:var(--cell-value-color,var(--app-B6-N3,rgba(0,0,0,.5)));display:flex;justify-content:flex-end;overflow:hidden;text-align:right;vertical-align:middle}.smart-cell__title,.smart-cell__value{flex:1}.smart-cell__title:empty,.smart-cell__value:empty{display:none}.smart-cell__left-icon-wrap,.smart-cell__right-icon-wrap{align-items:center;display:flex;font-size:var(--cell-icon-size,24px);height:var(--cell-line-height,24px)}.smart-cell__left-icon-wrap{margin-right:var(--padding-base,4px)}.smart-cell__right-icon-wrap{color:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)));margin-left:var(--padding-base,4px)}.smart-cell__left-icon{vertical-align:middle}.smart-cell__left-icon,.smart-cell__right-icon{line-height:var(--cell-line-height,24px)}.smart-cell__right-icon>view{background:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)))}.smart-cell--clickable.smart-cell--hover{background-color:var(--cell-active-color,var(--app-B1,#f6f7fb))}.smart-cell--required{overflow:visible}.smart-cell--required:before{color:var(--cell-required-color,var(--app-M2,#f04c4c));content:"*";font-size:var(--cell-font-size,16px);left:var(--padding-xs,8px);position:absolute}
1
+ @import '../common/index.wxss';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:var(--app-B4,#fff);--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff;--smart-ui-toast-background:#5c5c5c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 4px 12px rgba(0,0,0,.1),0 16px 32px rgba(0,0,0,.12);--smart-ui-overlay-blur-background:rgba(40,44,53,.22)}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--smart-ui-dialog-background:linear-gradient(0deg,var(--app-B4-N6),var(--app-B4-N6)),var(--app-B1);--smart-ui-border-image:linear-gradient(90deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.3),hsla(0,0%,100%,0));--smart-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000;--smart-ui-toast-background:#3c3c3c;--smart-ui-toast-border:1px solid hsla(0,0%,100%,.05);--smart-ui-toast-box-shadow:0 8px 24px 0 rgba(0,0,0,.15);--smart-ui-overlay-blur-background:rgba(0,0,0,.6)}.smart-manrope{font-family:Manrope,sans-serif}.smart-cell{align-items:center;background-color:var(--cell-background-color,var(--app-B6,#fff));box-sizing:border-box;color:var(--cell-text-color,var(--app-B6-N1,#000));display:flex;font-size:var(--cell-font-size,16px);line-height:var(--cell-line-height,24px);padding:var(--cell-vertical-padding,16px) var(--cell-horizontal-padding,16px);position:relative;width:100%}.smart-cell:after{border-bottom:1px solid var(--cell-border-color,var(--app-B6-N7,rgba(0,0,0,.1)));bottom:0;box-sizing:border-box;content:" ";left:var(--cell-border-left-position,16px);pointer-events:none;position:absolute;right:var(--cell-border-right-position,16px);transform:scaleY(.5);transform-origin:center}.smart-cell--borderless:after{display:none}.smart-cell-group{background-color:var(--cell-background-color,var(--app-B6,#fff))}.smart-cell__label{color:var(--cell-label-color,var(--app-B6-N3,rgba(0,0,0,.5)));font-size:var(--cell-label-font-size,14px);line-height:var(--cell-label-line-height,18px);margin-top:var(--cell-label-margin-top,3px)}.smart-cell__title{align-items:flex-start;display:flex;flex:1;flex-direction:column;justify-content:center}.smart-cell__title:empty{display:none}.smart-cell__value{align-items:center;color:var(--cell-value-color,var(--app-B6-N3,rgba(0,0,0,.5)));display:flex;flex:none;justify-content:flex-end;margin-left:var(--cell-value-margin-left,8px);max-width:var(--cell-value-max-width,none);overflow:hidden;text-align:right;vertical-align:middle}.smart-cell__value:empty{display:none}.smart-cell__left-icon-wrap,.smart-cell__right-icon-wrap{align-items:center;display:flex;font-size:var(--cell-icon-size,24px);height:var(--cell-line-height,24px)}.smart-cell__left-icon-wrap{margin-right:var(--padding-base,4px)}.smart-cell__right-icon-wrap{color:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)));margin-left:var(--padding-base,4px)}.smart-cell__left-icon{vertical-align:middle}.smart-cell__left-icon,.smart-cell__right-icon{line-height:var(--cell-line-height,24px)}.smart-cell__right-icon>view{background:var(--cell-right-icon-color,var(--app-B6-N6,rgba(0,0,0,.2)))}.smart-cell--clickable.smart-cell--hover{background-color:var(--cell-active-color,var(--app-B1,#f6f7fb))}.smart-cell--required{overflow:visible}.smart-cell--required:before{color:var(--cell-required-color,var(--app-M2,#f04c4c));content:"*";font-size:var(--cell-font-size,16px);left:var(--padding-xs,8px);position:absolute}
@@ -59,7 +59,7 @@ function getRect(context, selector) {
59
59
  .boundingClientRect()
60
60
  .exec(function (rect) {
61
61
  if (rect === void 0) { rect = []; }
62
- return resolve(rect[0]);
62
+ return resolve((rect || [])[0]);
63
63
  });
64
64
  });
65
65
  }
@@ -72,7 +72,7 @@ function getAllRect(context, selector) {
72
72
  .boundingClientRect()
73
73
  .exec(function (rect) {
74
74
  if (rect === void 0) { rect = []; }
75
- return resolve(rect[0]);
75
+ return resolve((rect || [])[0] || []);
76
76
  });
77
77
  });
78
78
  }
@@ -13,11 +13,6 @@ var __assign = (this && this.__assign) || function () {
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  var component_1 = require("../common/component");
15
15
  var shared_1 = require("./shared");
16
- // 超过该数量且非 loop 的列启用「窗口化」:只把当前位置附近的一段数据交给子 picker-column,
17
- // 其余保存在逻辑层实例属性中,滚动停稳后再回中,避免把超长数组整份 setData 到渲染层 / 子组件。
18
- var WINDOW_THRESHOLD = 2000;
19
- var WINDOW_SIZE = 1000;
20
- var clamp = function (value, min, max) { return Math.min(Math.max(value, min), max); };
21
16
  (0, component_1.SmartComponent)({
22
17
  classes: ['hairline-class', 'active-class', 'toolbar-class', 'column-class'],
23
18
  props: __assign(__assign({}, shared_1.pickerProps), { valueKey: {
@@ -34,12 +29,6 @@ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), m
34
29
  value: 0,
35
30
  }, activeIndex: {
36
31
  type: null,
37
- observer: function () {
38
- // 受控模式下 activeIndex(全局)变化时,若存在窗口化列需以新位置重建窗口
39
- if (this._hasWindow) {
40
- this.buildRenderColumns();
41
- }
42
- },
43
32
  }, unit: {
44
33
  type: String,
45
34
  value: '',
@@ -49,7 +38,6 @@ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), m
49
38
  observer: function (columns) {
50
39
  if (columns === void 0) { columns = []; }
51
40
  this.simple = columns.length && !columns[0].values;
52
- this.buildRenderColumns();
53
41
  if (Array.isArray(this.children) && this.children.length) {
54
42
  this.setColumns().catch(function () { });
55
43
  }
@@ -57,15 +45,9 @@ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), m
57
45
  } }),
58
46
  data: {
59
47
  animating: false,
60
- // 交给渲染层 / 子组件的列数据(窗口化列在此仅为切片,非窗口化列为完整数据)
61
- renderColumns: [],
62
48
  },
63
49
  beforeCreate: function () {
64
50
  var _this = this;
65
- // 每列的窗口状态:{ windowed, start, size, full },保存在逻辑层,不进入 data
66
- this._windows = [];
67
- this._hasWindow = false;
68
- this._repositioning = false;
69
51
  Object.defineProperty(this, 'children', {
70
52
  get: function () { return _this.selectAllComponents('.smart-picker__column') || []; },
71
53
  });
@@ -77,105 +59,11 @@ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), m
77
59
  },
78
60
  methods: {
79
61
  noop: function () { },
80
- // 归一化列数据:simple 模式(columns 为一维数组)包一层
81
- normalizedColumns: function () {
82
- var columns = this.data.columns;
83
- if (this.simple) {
84
- return [{ values: columns }];
85
- }
86
- return Array.isArray(columns) ? columns : [];
87
- },
88
- // 解析某列的初始全局下标(优先 activeIndex,其次 defaultIndex)
89
- resolveInitialIndex: function (column) {
90
- var _a = this.data, defaultIndex = _a.defaultIndex, activeIndex = _a.activeIndex;
91
- var columnActive = column.activeIndex === null || column.activeIndex === undefined
92
- ? activeIndex
93
- : column.activeIndex;
94
- var index;
95
- if (columnActive !== null && columnActive !== undefined) {
96
- index = columnActive;
97
- }
98
- else if (column.defaultIndex !== undefined) {
99
- index = column.defaultIndex;
100
- }
101
- else {
102
- index = defaultIndex;
103
- }
104
- var length = (column.values || []).length;
105
- return clamp(index || 0, 0, Math.max(0, length - 1));
106
- },
107
- // 判断某列是否需要窗口化
108
- shouldWindow: function (column) {
109
- return (!this.data.loop &&
110
- !column.loop &&
111
- Array.isArray(column.values) &&
112
- column.values.length > WINDOW_THRESHOLD);
113
- },
114
- // 基于当前 columns 计算 renderColumns 与每列窗口状态
115
- buildRenderColumns: function () {
116
- var _this = this;
117
- var columns = this.normalizedColumns();
118
- var windows = [];
119
- var hasWindow = false;
120
- var renderColumns = columns.map(function (column) {
121
- var values = column.values || [];
122
- if (!_this.shouldWindow(column)) {
123
- windows.push({ windowed: false, start: 0, size: values.length, full: values });
124
- return column;
125
- }
126
- hasWindow = true;
127
- var globalIndex = _this.resolveInitialIndex(column);
128
- var size = WINDOW_SIZE;
129
- var start = clamp(globalIndex - Math.floor(size / 2), 0, Math.max(0, values.length - size));
130
- var localIndex = globalIndex - start;
131
- windows.push({ windowed: true, start: start, size: size, full: values });
132
- return __assign(__assign({}, column), { values: values.slice(start, start + size), defaultIndex: localIndex, activeIndex: localIndex, _windowed: true });
133
- });
134
- this._windows = windows;
135
- this._hasWindow = hasWindow;
136
- this.setData({ renderColumns: renderColumns });
137
- },
138
- // 将窗口化列停稳后回中:使当前项回到窗口中心,纯坐标平移,静止态无感
139
- recenterColumn: function (columnIndex) {
140
- var _a;
141
- var _this = this;
142
- var win = this._windows[columnIndex];
143
- if (!win || !win.windowed || this._repositioning)
144
- return;
145
- var column = this.getColumn(columnIndex);
146
- if (!column)
147
- return;
148
- var localIndex = column.data.currentIndex;
149
- var globalIndex = win.start + localIndex;
150
- var size = win.size;
151
- var newStart = clamp(globalIndex - Math.floor(size / 2), 0, Math.max(0, win.full.length - size));
152
- if (newStart === win.start)
153
- return;
154
- this._repositioning = true;
155
- win.start = newStart;
156
- var newLocal = globalIndex - newStart;
157
- // 同一次 setData 内同时更新切片与 active-index(局部),子组件原子接收,
158
- // 配合 wxs 对大跳变强制 transition:none,实现无动画的静默回中
159
- this.setData((_a = {},
160
- _a["renderColumns[".concat(columnIndex, "].values")] = win.full.slice(newStart, newStart + size),
161
- _a["renderColumns[".concat(columnIndex, "].activeIndex")] = newLocal,
162
- _a), function () {
163
- _this._repositioning = false;
164
- });
165
- },
166
- // 局部下标 -> 全局下标
167
- toGlobalIndex: function (columnIndex, localIndex) {
168
- var win = this._windows[columnIndex];
169
- return win && win.windowed ? win.start + localIndex : localIndex;
170
- },
171
62
  setColumns: function () {
172
63
  var _this = this;
173
- var columns = this.normalizedColumns();
64
+ var data = this.data;
65
+ var columns = this.simple ? [{ values: data.columns }] : data.columns;
174
66
  var stack = columns.map(function (column, index) {
175
- // 窗口化列由 renderColumns(wxml)响应式驱动,不走命令式全量下发
176
- if (_this._windows[index] && _this._windows[index].windowed) {
177
- return Promise.resolve();
178
- }
179
67
  return _this.setColumnValues(index, column.values);
180
68
  });
181
69
  return Promise.all(stack);
@@ -196,7 +84,6 @@ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), m
196
84
  }
197
85
  },
198
86
  onChange: function (event) {
199
- var columnIndex = this.simple ? 0 : event.currentTarget.dataset.index;
200
87
  if (this.simple) {
201
88
  this.$emit('change', {
202
89
  picker: this,
@@ -211,8 +98,6 @@ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), m
211
98
  index: event.currentTarget.dataset.index,
212
99
  });
213
100
  }
214
- // 停稳后再回中,保证切换发生在静止态
215
- this.recenterColumn(columnIndex);
216
101
  },
217
102
  // get column instance by index
218
103
  getColumn: function (index) {
@@ -225,19 +110,6 @@ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), m
225
110
  },
226
111
  // set column value by index
227
112
  setColumnValue: function (index, value) {
228
- var win = this._windows[index];
229
- if (win && win.windowed) {
230
- // 窗口化列:在完整数据中按 valueKey 查找全局下标后跳转
231
- var valueKey = this.data.valueKey;
232
- for (var i = 0; i < win.full.length; i++) {
233
- var option = win.full[i];
234
- var text = option && typeof option === 'object' && valueKey in option ? option[valueKey] : option;
235
- if (text === value) {
236
- return this.setColumnIndex(index, i);
237
- }
238
- }
239
- return Promise.resolve();
240
- }
241
113
  var column = this.getColumn(index);
242
114
  if (column == null) {
243
115
  return Promise.reject(new Error('setColumnValue: The corresponding column does not exist'));
@@ -246,29 +118,10 @@ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), m
246
118
  },
247
119
  // get column option index by column index
248
120
  getColumnIndex: function (columnIndex) {
249
- var _a, _b;
250
- var local = (_b = (_a = (this.getColumn(columnIndex) || {}).data) === null || _a === void 0 ? void 0 : _a.currentIndex) !== null && _b !== void 0 ? _b : 0;
251
- return this.toGlobalIndex(columnIndex, local);
121
+ return (this.getColumn(columnIndex) || {}).data.currentIndex;
252
122
  },
253
123
  // set column option index by column index
254
124
  setColumnIndex: function (columnIndex, optionIndex) {
255
- var _a;
256
- var _this = this;
257
- var win = this._windows[columnIndex];
258
- if (win && win.windowed) {
259
- // 以目标全局下标为中心重建窗口,子组件通过 active-index 定位
260
- var size = win.size;
261
- var globalIndex = clamp(optionIndex, 0, Math.max(0, win.full.length - 1));
262
- var newStart = clamp(globalIndex - Math.floor(size / 2), 0, Math.max(0, win.full.length - size));
263
- win.start = newStart;
264
- this._repositioning = true;
265
- return this.set((_a = {},
266
- _a["renderColumns[".concat(columnIndex, "].values")] = win.full.slice(newStart, newStart + size),
267
- _a["renderColumns[".concat(columnIndex, "].activeIndex")] = globalIndex - newStart,
268
- _a)).then(function () {
269
- _this._repositioning = false;
270
- });
271
- }
272
125
  var column = this.getColumn(columnIndex);
273
126
  if (column == null) {
274
127
  return Promise.reject(new Error('setColumnIndex: The corresponding column does not exist'));
@@ -277,40 +130,16 @@ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), m
277
130
  },
278
131
  // get options of column by index
279
132
  getColumnValues: function (index) {
280
- var win = this._windows[index];
281
- if (win && win.windowed) {
282
- return win.full;
283
- }
284
133
  return (this.children[index] || {}).data.options;
285
134
  },
286
135
  // set options of column by index
287
136
  setColumnValues: function (index, options, needReset) {
288
- var _a;
289
- var _this = this;
290
137
  if (needReset === void 0) { needReset = true; }
291
- var win = this._windows[index];
292
- if (win && win.windowed) {
293
- // 替换完整数据并以头部为中心重建窗口
294
- win.full = options || [];
295
- var size = win.size;
296
- var start = needReset ? 0 : clamp(win.start, 0, Math.max(0, win.full.length - size));
297
- win.start = start;
298
- this._repositioning = true;
299
- return this.set((_a = {},
300
- _a["renderColumns[".concat(index, "].values")] = win.full.slice(start, start + size),
301
- _a["renderColumns[".concat(index, "].activeIndex")] = 0,
302
- _a)).then(function () {
303
- _this._repositioning = false;
304
- });
305
- }
306
138
  var column = this.children[index];
307
139
  if (column == null) {
308
140
  return Promise.reject(new Error('setColumnValues: The corresponding column does not exist'));
309
141
  }
310
- var prevOptions = column.data.options || [];
311
- // 先比长度(O(1))短路:长度不同必然不同,避免对超长数组做两次 JSON.stringify
312
- var isSame = prevOptions.length === options.length &&
313
- JSON.stringify(prevOptions) === JSON.stringify(options);
142
+ var isSame = JSON.stringify(column.data.options) === JSON.stringify(options);
314
143
  if (isSame) {
315
144
  return Promise.resolve();
316
145
  }
@@ -332,10 +161,7 @@ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), m
332
161
  },
333
162
  // get indexes of all columns
334
163
  getIndexes: function () {
335
- var _this = this;
336
- return this.children.map(function (child, index) {
337
- return _this.toGlobalIndex(index, child.data.currentIndex);
338
- });
164
+ return this.children.map(function (child) { return child.data.currentIndex; });
339
165
  },
340
166
  // set indexes of all columns
341
167
  setIndexes: function (indexes) {
@@ -14,7 +14,7 @@
14
14
  >
15
15
  <picker-column
16
16
  class="smart-picker__column"
17
- wx:for="{{ renderColumns }}"
17
+ wx:for="{{ computed.columns(columns) }}"
18
18
  wx:key="index"
19
19
  data-index="{{ index }}"
20
20
  animation-time="{{ animationTime }}"
@@ -24,7 +24,6 @@
24
24
  active-style="{{ activeStyle }}"
25
25
  font-style="{{fontStyle ? fontStyle + ';' + computed.style(item.fontStyle): computed.style(item.fontStyle)}}"
26
26
  options="{{ item.values }}"
27
- windowed="{{ item._windowed || false }}"
28
27
  disabled="{{ item.disabled || false }}"
29
28
  unit="{{ item.unit || unit }}"
30
29
  unit-gap="{{ item.unitGap }}"
@@ -21,11 +21,6 @@ var getId = function () {
21
21
  className: String,
22
22
  itemHeight: Number,
23
23
  disabled: Boolean,
24
- // 是否为父级窗口化列:为 true 时对大幅度的 active-index 跳变强制关闭过渡(用于停稳回中的静默重定位)
25
- windowed: {
26
- type: Boolean,
27
- value: false,
28
- },
29
24
  visibleItemCount: Number,
30
25
  activeStyle: {
31
26
  type: String,
@@ -38,12 +33,7 @@ var getId = function () {
38
33
  if (!this.data.isInit)
39
34
  return;
40
35
  this.updateUint(value);
41
- // 窗口化列:切片与 activeIndex(局部)在同一批 setData 到达,
42
- // 此处直接采用新的 activeIndex,使「新切片 + 新下标」原子落地,避免差一帧的错位闪烁
43
- var nextIndex = this.data.windowed && this.data.activeIndex !== null && this.data.activeIndex !== undefined
44
- ? this.data.activeIndex
45
- : this.data.currentIndex;
46
- this.updateCurrentIndex(nextIndex);
36
+ this.updateCurrentIndex(this.data.currentIndex);
47
37
  this.updateVisibleOptions();
48
38
  },
49
39
  },
@@ -8,15 +8,15 @@
8
8
  id="{{instanceId}}"
9
9
  data-isdestroy="{{isDestroy}}"
10
10
  data-changeanimation="{{changeAnimation}}"
11
+ data-options="{{options}}"
11
12
  data-valuekey="{{valueKey}}"
12
13
  data-itemheight="{{itemHeight}}"
13
14
  data-visibleitemcount="{{visibleItemCount}}"
14
15
  data-activeindex="{{currentIndex}}"
15
16
  data-loop="{{loop && options.length > 1}}"
16
17
  data-animationtime="{{animationTime}}"
17
- data-windowed="{{windowed}}"
18
18
  isdestroy="{{isDestroy}}"
19
- options="{{options}}"
19
+ options="{{options}}"
20
20
  activeindex="{{currentIndex}}"
21
21
  changeanimation="{{changeAnimation}}"
22
22
  loop="{{loop && options.length > 1}}"
@@ -24,17 +24,15 @@
24
24
  itemheight="{{itemHeight}}"
25
25
  visibleitemcount="{{visibleItemCount}}"
26
26
  animationtime="{{animationTime}}"
27
- windowed="{{windowed}}"
28
27
  change:isdestroy="{{computed.updateValue(instanceId, 'isDestroy')}}"
29
- change:options="{{computed.updateValue(instanceId, 'options')}}"
30
- change:valuekey="{{computed.updateValue(instanceId,'valueKey')}}"
31
- change:itemheight="{{computed.updateValue(instanceId,'itemHeight')}}"
32
- change:visibleitemcount="{{computed.updateValue(instanceId, 'visibleItemCount')}}"
33
- change:activeindex="{{computed.updateValue(instanceId,'activeIndex')}}"
34
- change:loop="{{computed.updateValue(instanceId,'loop')}}"
35
- change:animationtime="{{computed.updateValue(instanceId,'animationTime')}}"
36
- change:windowed="{{computed.updateValue(instanceId,'windowed')}}"
37
- change:instanceid="{{computed.updateValue(instanceId,'instanceId')}}"
28
+ change:options="{{computed.updateValue(instanceId, 'options')}}"
29
+ change:valuekey="{{computed.updateValue(instanceId,'valueKey')}}"
30
+ change:itemheight="{{computed.updateValue(instanceId,'itemHeight')}}"
31
+ change:visibleitemcount="{{computed.updateValue(instanceId, 'visibleItemCount')}}"
32
+ change:activeindex="{{computed.updateValue(instanceId,'activeIndex')}}"
33
+ change:loop="{{computed.updateValue(instanceId,'loop')}}"
34
+ change:animationtime="{{computed.updateValue(instanceId,'animationTime')}}"
35
+ change:instanceid="{{computed.updateValue(instanceId,'instanceId')}}"
38
36
  bind:touchstart="{{computed.touchStart(instanceId)}}"
39
37
  catch:touchmove="{{computed.touchMove(instanceId)}}"
40
38
  bind:touchend="{{computed.touchEnd(instanceId)}}"
@@ -226,8 +226,7 @@ function getDomState(ownerInstance) {
226
226
 
227
227
  function initDomState(instanceId, ownerInstance) {
228
228
  var state = getDomState(ownerInstance);
229
- // options 不再通过 data-options 传入(避免把全量数组塞进 dataset / getDataset),
230
- // 由 change:options -> updateValue('options', ...) 单独维护 state.options
229
+ updateState(instanceId, 'options', state.options)
231
230
  updateState(instanceId, 'valueKey', state.valuekey)
232
231
  updateState(instanceId, 'itemHeight', state.itemheight)
233
232
  updateState(instanceId, 'visibleItemCount', state.visibleitemcount)
@@ -235,7 +234,6 @@ function initDomState(instanceId, ownerInstance) {
235
234
  updateState(instanceId, 'loop', state.loop)
236
235
  updateState(instanceId, 'animationTime', state.animationtime)
237
236
  updateState(instanceId, 'changeAnimation', state.changeanimation)
238
- updateState(instanceId, 'windowed', state.windowed)
239
237
  }
240
238
 
241
239
 
@@ -264,14 +262,10 @@ function updateListView(instanceId, ownerInstance) {
264
262
  var animationIndex = state.animationIndex || 0;
265
263
  var newAnimationIndex = getNewAnimationIndex(animationIndex, activeIndex, length, state.loop);
266
264
  var isSame = newAnimationIndex === animationIndex;
267
- // 窗口化列的「停稳回中/重定位」会产生大幅度的 activeIndex 跳变,此时强制关闭过渡:
268
- // 因为切片内容与位置是同步平移的,直接吸附即像素级一致,避免整轮旋转动画造成抖动。
269
- var vOptionLength = state.visibleItemCount * 4 - 2;
270
- var isWindowReposition = state.windowed && Math.abs(newAnimationIndex - animationIndex) > vOptionLength;
271
265
  updateState(instanceId, 'animationIndex', newAnimationIndex)
272
266
  updateVisibleOptions(state.animationIndex, instanceId);
273
267
  updateWrapperStyle(instanceId, ownerInstance, {
274
- transition: (!state.changeAnimation || isSame || isWindowReposition) ? 'none' : 'transform ' + state.animationTime + 'ms cubic-bezier(0.2, 0.9, 0.25, 1)'
268
+ transition: (!state.changeAnimation || isSame) ? 'none' : 'transform ' + state.animationTime + 'ms cubic-bezier(0.2, 0.9, 0.25, 1)'
275
269
  });
276
270
  }
277
271
 
@@ -379,8 +373,7 @@ function touchEnd(instanceId) {
379
373
 
380
374
  // 惯性滚动参数配置
381
375
  var minVelocity = 0.1; // 最小速度阈值,低于此值停止滚动
382
- // 最大惯性滚动距离:下限 6 项,上限 100 项,避免超长列表单次快滑滚动上万项
383
- var maxInertiaDistance = state.itemHeight * Math.min(Math.max(Math.floor(state.options.length/4), 6), 100);
376
+ var maxInertiaDistance = state.itemHeight * Math.max(Math.floor(state.options.length/4), 6); // 最大惯性滚动距离
384
377
  // 计算惯性滚动距离
385
378
  var inertiaDistance = 0;
386
379
  if (recentVelocity > minVelocity) {
package/lib/rate/index.js CHANGED
@@ -95,7 +95,8 @@ var version_1 = require("../common/version");
95
95
  return;
96
96
  var clientX = event.touches[0].clientX;
97
97
  (0, utils_1.getAllRect)(this, '.smart-rate__icon').then(function (list) {
98
- var target = list
98
+ if (list === void 0) { list = []; }
99
+ var target = (list || [])
99
100
  .sort(function (cur, next) { return cur.dataset.score - next.dataset.score; })
100
101
  .find(function (item) { return clientX >= item.left && clientX <= item.right; });
101
102
  if (target != null) {
package/lib/tabs/index.js CHANGED
@@ -253,7 +253,12 @@ var ty_1 = __importDefault(require("../common/ty"));
253
253
  }
254
254
  Promise.all([(0, utils_1.getAllRect)(this, '.smart-tab'), (0, utils_1.getRect)(this, '.smart-tabs__nav')]).then(function (_a) {
255
255
  var tabRects = _a[0], navRect = _a[1];
256
- var tabRect = tabRects[currentIndex];
256
+ var tabRect = tabRects === null || tabRects === void 0 ? void 0 : tabRects[currentIndex];
257
+ // On Android the layout query can resolve before the tabs are laid out,
258
+ // in which case there is nothing to scroll to yet.
259
+ if (tabRect == null || navRect == null) {
260
+ return;
261
+ }
257
262
  var offsetLeft = tabRects
258
263
  .slice(0, currentIndex)
259
264
  .reduce(function (prev, curr) { return prev + curr.width; }, 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuya-miniapp/smart-ui",
3
- "version": "2.13.4-canary.fix-picker.2cc7b5d",
3
+ "version": "2.13.4",
4
4
  "author": "MiniApp Team",
5
5
  "license": "MIT",
6
6
  "miniprogram": "lib",