Skip to content
This repository was archived by the owner on Jan 8, 2025. It is now read-only.

Commit d88c2ad

Browse files
wangKBwebdavion
andauthored
feat(ui/picker): add textFormatter in picker (#58)
* test: steps test * test: swipe test * test: list test * test: dialog test * test: pagination test * feat(ui/picker): add textFormatter in picker Co-authored-by: davion <[email protected]>
1 parent edec891 commit d88c2ad

File tree

12 files changed

+1276
-7
lines changed

12 files changed

+1276
-7
lines changed

packages/varlet-vue2-ui/src/picker/Picker.vue

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
v-for="t in c.column.texts"
6969
:key="t"
7070
>
71-
<div class="var-picker__text">{{ t }}</div>
71+
<div class="var-picker__text">{{ textFormatter(t, c.columnIndex) }}</div>
7272
</div>
7373
</div>
7474
</div>
@@ -140,7 +140,7 @@
140140
v-for="t in c.column.texts"
141141
:key="t"
142142
>
143-
<div class="var-picker__text">{{ t }}</div>
143+
<div class="var-picker__text">{{ textFormatter(t, c.columnIndex) }}</div>
144144
</div>
145145
</div>
146146
</div>
@@ -369,7 +369,7 @@ export default defineComponent({
369369
},
370370
371371
normalizeNormalColumns(normalColumns) {
372-
return normalColumns.map((column) => {
372+
return normalColumns.map((column, columnIndex) => {
373373
const normalColumn = isArray(column) ? { texts: column } : column
374374
const scrollColumn = {
375375
id: sid++,
@@ -378,6 +378,7 @@ export default defineComponent({
378378
touching: false,
379379
translate: this.center,
380380
index: normalColumn.initialIndex ?? 0,
381+
columnIndex,
381382
duration: 0,
382383
momentumTime: 0,
383384
column: normalColumn,
@@ -392,12 +393,12 @@ export default defineComponent({
392393
normalizeCascadeColumns(cascadeColumns) {
393394
const scrollColumns = []
394395
395-
this.createChildren(scrollColumns, cascadeColumns)
396+
this.createChildren(scrollColumns, cascadeColumns, 0)
396397
397398
return scrollColumns
398399
},
399400
400-
createChildren(scrollColumns, children) {
401+
createChildren(scrollColumns, children, columnIndex) {
401402
if (isArray(children) && children.length) {
402403
const scrollColumn = {
403404
id: sid++,
@@ -406,6 +407,7 @@ export default defineComponent({
406407
touching: false,
407408
translate: this.center,
408409
index: 0,
410+
columnIndex,
409411
duration: 0,
410412
momentumTime: 0,
411413
column: {
@@ -417,13 +419,17 @@ export default defineComponent({
417419
}
418420
419421
scrollColumns.push(scrollColumn)
420-
this.createChildren(scrollColumns, scrollColumn.columns[scrollColumn.index].children)
422+
this.createChildren(scrollColumns, scrollColumn.columns[scrollColumn.index].children, columnIndex + 1)
421423
}
422424
},
423425
424426
rebuildChildren(scrollColumn) {
425427
this.scrollColumns.splice(this.scrollColumns.indexOf(scrollColumn) + 1)
426-
this.createChildren(this.scrollColumns, scrollColumn.columns[scrollColumn.index].children)
428+
this.createChildren(
429+
this.scrollColumns,
430+
scrollColumn.columns[scrollColumn.index].children,
431+
scrollColumn.columnIndex + 1
432+
)
427433
},
428434
429435
change(scrollColumn) {

packages/varlet-vue2-ui/src/picker/__tests__/__snapshots__/component.spec.js.snap

Lines changed: 627 additions & 0 deletions
Large diffs are not rendered by default.

packages/varlet-vue2-ui/src/picker/__tests__/component.spec.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,21 @@ test('test cascade mode', async () => {
159159
mockRestore()
160160
wrapper.destroy()
161161
})
162+
163+
test('test picker component textFormatter', async () => {
164+
const textFormatter = jest.fn().mockReturnValue('text')
165+
const columns = [['A']]
166+
167+
const wrapper = mount(VarPicker, {
168+
propsData: {
169+
columns,
170+
textFormatter,
171+
},
172+
})
173+
174+
const pickerText = wrapper.find('.var-picker__text')
175+
176+
expect(pickerText.text()).toBe('text')
177+
178+
wrapper.destroy()
179+
})

packages/varlet-vue2-ui/src/picker/__tests__/index.spec.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,27 @@ test('test picker functional cancel', async () => {
7373
await delay(16)
7474
await delay(300)
7575
})
76+
77+
test('test picker functional textFormatter', async () => {
78+
const textFormatter = jest.fn().mockReturnValue('text')
79+
const onCancel = jest.fn()
80+
81+
const columns = [['A']]
82+
83+
Picker({
84+
columns,
85+
textFormatter,
86+
onCancel,
87+
})
88+
89+
await delay(16)
90+
await delay(300)
91+
92+
await trigger(document.querySelector('.var-picker__cancel-button'), 'click')
93+
94+
expect(textFormatter).toHaveBeenLastCalledWith('A', 0)
95+
expect(document.querySelector('.var-picker__text').innerHTML).toBe('text')
96+
97+
await delay(16)
98+
await delay(300)
99+
})

packages/varlet-vue2-ui/src/picker/docs/en-US.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,117 @@ const { state, texts, indexes } = await Picker({
5454
})
5555
```
5656

57+
### Text Formatter
58+
59+
Picker passes in a `textFormatter` attribute to customize the text.
60+
`textFormatter` accepts two parameters. The first parameter `text` is the current text, and the second parameter
61+
`columnIndex` is the subscript of the column where the current text is located.
62+
The following is the case of year month day selection
63+
64+
```js
65+
import { Picker } from '@varlet-vue2/ui'
66+
67+
const genCounts = length => Array.from({ length }, (_, index) => index + 1)
68+
69+
const months = genCounts(12)
70+
const leapYearFebruaryDates = genCounts(29)
71+
const februaryDates = genCounts(28)
72+
const oddMonthDates = genCounts(31)
73+
const evenMonthDates = genCounts(30)
74+
75+
const isOddMonth = month => [1, 3, 5, 7, 8, 10, 12].includes(month)
76+
77+
const isLeapYear = year => (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
78+
79+
const genDates = (year, month) => {
80+
if (isLeapYear(year) && month === 2) {
81+
return leapYearFebruaryDates
82+
}
83+
84+
if (!isLeapYear(year) && month === 2) {
85+
return februaryDates
86+
}
87+
88+
if (isOddMonth(month)) {
89+
return oddMonthDates
90+
}
91+
92+
return evenMonthDates
93+
}
94+
95+
const genColumns = (startYear, endYear) => {
96+
const columns = []
97+
98+
for (let year = startYear; year < endYear; year++) {
99+
columns.push({
100+
text: year,
101+
children: months.map((month) => {
102+
return {
103+
text: month,
104+
children: genDates(year, month).map(date => ({ text: date }))
105+
}
106+
})
107+
})
108+
}
109+
110+
return columns
111+
}
112+
113+
const columns = genColumns(1970, 2100)
114+
115+
const textFormatter = (text, columnIndex) => {
116+
if (columnIndex === 0) return `${text} YEAR`
117+
else if (columnIndex === 1) return `${text} MONTH`
118+
else if (columnIndex === 2) return `${text} DATE`
119+
}
120+
121+
const { state, texts, indexes } = await Picker({
122+
cascade: true,
123+
columns,
124+
textFormatter,
125+
})
126+
```
127+
128+
### Mapping of values
129+
130+
```js
131+
import { Picker, Snackbar } from '@varlet-vue2/ui'
132+
133+
const rawColumns = [
134+
[
135+
{ label: 'Ember Spirit', id: 1 },
136+
{ label: 'Storm Spirit', id: 2 },
137+
{ label: 'Earth Spirit', id: 3 },
138+
{ label: 'Void Spirit', id: 4 },
139+
],
140+
[
141+
{ label: 'Ember Spirit', id: 1 },
142+
{ label: 'Storm Spirit', id: 2 },
143+
{ label: 'Earth Spirit', id: 3 },
144+
{ label: 'Void Spirit', id: 4 },
145+
],
146+
[
147+
{ label: 'Ember Spirit', id: 1 },
148+
{ label: 'Storm Spirit', id: 2 },
149+
{ label: 'Earth Spirit', id: 3 },
150+
{ label: 'Void Spirit', id: 4 },
151+
],
152+
]
153+
154+
const normalizedColumns = rawColumns.map((column) => column.map(option => option.label))
155+
156+
const handleChange = (_, [i1, i2, i3]) => {
157+
const [c1, c2, c3] = rawColumns
158+
const ids = [c1[i1].id, c2[i2].id, c3[i3].id]
159+
Snackbar(ids.toString())
160+
}
161+
162+
const { state, texts, indexes } = await Picker({
163+
columns: normalizedColumns,
164+
onChange: handleChange
165+
})
166+
```
167+
57168
## Component Call
58169

59170
### Multi-column Picker
@@ -118,6 +229,123 @@ export default {
118229
}
119230
```
120231

232+
### Text Formatter
233+
234+
```html
235+
<template>
236+
<var-picker cascade :columns="columns" :text-formatter="textFormatter" />
237+
</template>
238+
```
239+
240+
```js
241+
const genCounts = length => Array.from({ length }, (_, index) => index + 1)
242+
243+
const months = genCounts(12)
244+
const leapYearFebruaryDates = genCounts(29)
245+
const februaryDates = genCounts(28)
246+
const oddMonthDates = genCounts(31)
247+
const evenMonthDates = genCounts(30)
248+
249+
const isOddMonth = month => [1, 3, 5, 7, 8, 10, 12].includes(month)
250+
251+
const isLeapYear = year => (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
252+
253+
const genDates = (year, month) => {
254+
if (isLeapYear(year) && month === 2) {
255+
return leapYearFebruaryDates
256+
}
257+
258+
if (!isLeapYear(year) && month === 2) {
259+
return februaryDates
260+
}
261+
262+
if (isOddMonth(month)) {
263+
return oddMonthDates
264+
}
265+
266+
return evenMonthDates
267+
}
268+
269+
const genColumns = (startYear, endYear) => {
270+
const columns = []
271+
272+
for (let year = startYear; year < endYear; year++) {
273+
columns.push({
274+
text: year,
275+
children: months.map((month) => {
276+
return {
277+
text: month,
278+
children: genDates(year, month).map(date => ({ text: date }))
279+
}
280+
})
281+
})
282+
}
283+
284+
return columns
285+
}
286+
287+
export default {
288+
data: () => ({
289+
columns: genColumns(1970, 2100)
290+
}),
291+
methods: {
292+
textFormatter() {
293+
if (columnIndex === 0) return `${text} YEAR`
294+
else if (columnIndex === 1) return `${text} MONTH`
295+
else if (columnIndex === 2) return `${text} DATE`
296+
}
297+
}
298+
}
299+
```
300+
301+
### Mapping of values
302+
303+
```html
304+
<template>
305+
<var-picker :columns="columns" @change="handleChange" />
306+
</template>
307+
```
308+
309+
```js
310+
import { Snackbar } from '@varlet-vue2/ui'
311+
312+
const rawColumns = [
313+
[
314+
{ label: 'Ember Spirit', id: 1 },
315+
{ label: 'Storm Spirit', id: 2 },
316+
{ label: 'Earth Spirit', id: 3 },
317+
{ label: 'Void Spirit', id: 4 },
318+
],
319+
[
320+
{ label: 'Ember Spirit', id: 1 },
321+
{ label: 'Storm Spirit', id: 2 },
322+
{ label: 'Earth Spirit', id: 3 },
323+
{ label: 'Void Spirit', id: 4 },
324+
],
325+
[
326+
{ label: 'Ember Spirit', id: 1 },
327+
{ label: 'Storm Spirit', id: 2 },
328+
{ label: 'Earth Spirit', id: 3 },
329+
{ label: 'Void Spirit', id: 4 },
330+
]
331+
]
332+
333+
const normalizedColumns = rawColumns.map(column => column.map(option => option.label))
334+
335+
export default {
336+
data: () => ({
337+
columns: normalizedColumns
338+
}),
339+
methods: {
340+
handleChange(_, [i1, i2, i3]) {
341+
const [c1, c2, c3] = rawColumns
342+
const ids = [c1[i1].id, c2[i2].id, c3[i3].id]
343+
Snackbar(ids.toString())
344+
}
345+
}
346+
}
347+
```
348+
121349
## API
122350

123351
### Props
@@ -129,6 +357,7 @@ export default {
129357
| `text-key` | The attribute key of the text | _string_ | `text` |
130358
| `toolbar` | Whether to display the top toolbar | _string_ | `true` |
131359
| `cascade` | Whether to enable cascading mode | _boolean_ | `true` |
360+
| `text-formatter` | Text formatter | _(text: any, columnIndex: number) => any_ | `text => text` |
132361
| `option-height` | Option height(px rem) | _string \| number_ | `44` |
133362
| `option-count` | Number of options visible | _string \| number_ | `6` |
134363
| `confirm-button-text` | Confirm button text | _string_ | `Confirm` |
@@ -145,6 +374,7 @@ export default {
145374
| `textKey` | The attribute key of the text | _string_ | `text` |
146375
| `toolbar` | Whether to display the top toolbar | _string_ | `true` |
147376
| `cascade` | Whether to enable cascading mode | _boolean_ | `true` |
377+
| `textFormatter` | Text formatter | _(text: any, columnIndex: number) => any_ | `text => text` |
148378
| `optionHeight` | Option height | _string \| number_ | `44` |
149379
| `optionCount` | Number of options visible | _string \| number_ | `6` |
150380
| `confirmButtonText` | Confirm button text | _string_ | `Confirm` |

0 commit comments

Comments
 (0)