jsbox-cview 1.0.0 → 1.1.0

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.
Files changed (47) hide show
  1. package/dist/components/alert/input-alert.js +39 -0
  2. package/dist/components/alert/login-alert.js +45 -0
  3. package/dist/components/alert/plain-alert.js +25 -0
  4. package/dist/components/alert/uialert.js +89 -0
  5. package/dist/components/artificial-flowlayout.js +258 -0
  6. package/dist/components/base.js +43 -0
  7. package/dist/components/custom-navigation-bar.js +519 -0
  8. package/dist/components/dialogs/dialog-sheet.js +67 -0
  9. package/dist/components/dialogs/form-dialog.js +24 -0
  10. package/dist/components/dialogs/list-dialog.js +87 -0
  11. package/dist/components/dialogs/text-dialog.js +31 -0
  12. package/dist/components/dynamic-itemsize-matrix.js +129 -0
  13. package/dist/components/dynamic-preference-listview.js +557 -0
  14. package/dist/components/dynamic-rowheight-list.js +44 -0
  15. package/dist/components/enhanced-imageview.js +114 -0
  16. package/dist/components/image-pager.js +157 -0
  17. package/dist/components/page-control.js +76 -0
  18. package/dist/components/pageviewer-titlebar.js +143 -0
  19. package/dist/components/pageviewer.js +96 -0
  20. package/dist/components/rotating-view.js +102 -0
  21. package/dist/components/searchbar.js +322 -0
  22. package/dist/components/sheet.js +82 -0
  23. package/dist/components/single-views.js +429 -0
  24. package/dist/components/spinners/loading-double-rings.js +104 -0
  25. package/dist/components/spinners/loading-dual-ring.js +82 -0
  26. package/dist/components/spinners/loading-wedges.js +104 -0
  27. package/dist/components/spinners/spinner-androidstyle.js +248 -0
  28. package/dist/components/static-preference-listview.js +798 -0
  29. package/dist/components/symbol-button.js +79 -0
  30. package/dist/components/tabbar.js +357 -0
  31. package/dist/controller/base-controller.js +178 -0
  32. package/dist/controller/controller-router.js +68 -0
  33. package/dist/controller/pageviewer-controller.js +63 -0
  34. package/dist/controller/presented-page-controller.js +48 -0
  35. package/dist/controller/splitview-controller.js +252 -0
  36. package/dist/controller/tabbar-controller.js +74 -0
  37. package/dist/index.js +58 -0
  38. package/dist/test.js +1 -0
  39. package/dist/utils/colors.js +15 -0
  40. package/dist/utils/cvid.js +28 -0
  41. package/dist/utils/l10n.js +44 -0
  42. package/dist/utils/path.js +107 -0
  43. package/dist/utils/rect.js +72 -0
  44. package/dist/utils/uitools.js +95 -0
  45. package/index.ts +42 -0
  46. package/package.json +4 -3
  47. package/tsconfig.json +5 -3
@@ -0,0 +1,557 @@
1
+ "use strict";
2
+ /**
3
+ * # cview PreferenceListView_dynamic
4
+ *
5
+ * 便捷的设置列表实现. 样式以及功能均以 PreferenceListView_static 为准.
6
+ *
7
+ * 优势在于:
8
+ *
9
+ * - 可以实现 sections 重新写入.
10
+ *
11
+ * 劣势在于:
12
+ *
13
+ * - 由于每个 cell 不能单独布局, 因此标题和内容的长度无法动态调整, 在两者都比较短的情况下没有问题, 长了布局可能会重叠.
14
+ * - 不能真正实现 selectable 为 false, 分割线仍然会闪动
15
+ *
16
+ * 为了缓解上面的问题, 让修改布局无需调整源代码, 增加下列 props:
17
+ *
18
+ * - stringLeftInset?: number = 120 将同时作用于 string, number, integer, list, 但是由于后三者内容可控, 可视为只作用于 string
19
+ * - infoAndLinkLeftInset?: number = 120 作用于 info, link
20
+ * - sliderWidth?: number = 200 作用于 slider
21
+ * - tabWidth?: number = 200 作用于 tab
22
+ * 注意以上的修改是应用于 template, 而不是应用于单个 cell 的
23
+ *
24
+ * 独特方法:
25
+ *
26
+ * - cview.sections = sections 可以写入新的 sections
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.DynamicPreferenceListView = void 0;
30
+ const base_1 = require("./base");
31
+ const selectableTypes = [
32
+ "string",
33
+ "number",
34
+ "integer",
35
+ "stepper",
36
+ "list",
37
+ "link",
38
+ "action"
39
+ ];
40
+ class DynamicPreferenceListView extends base_1.Base {
41
+ constructor({ sections, props, layout, events = {} }) {
42
+ super();
43
+ this._sections = sections.map(n => ({
44
+ title: n.title,
45
+ rows: n.rows.map(r => (Object.assign({}, r)))
46
+ }));
47
+ this._props = Object.assign({ stringLeftInset: 120, infoAndLinkLeftInset: 120, sliderWidth: 200, tabWidth: 200 }, props);
48
+ this._layout = layout;
49
+ this._defineView = () => {
50
+ return {
51
+ type: "list",
52
+ props: Object.assign(Object.assign({ style: 2 }, this._props), { id: this.id, template: {
53
+ views: [
54
+ {
55
+ type: "view",
56
+ props: {
57
+ id: "bgview",
58
+ bgcolor: $color("secondarySurface")
59
+ },
60
+ layout: $layout.fill
61
+ },
62
+ {
63
+ type: "label",
64
+ props: {
65
+ id: "title",
66
+ font: $font(17)
67
+ },
68
+ layout: (make, view) => {
69
+ make.top.bottom.inset(0);
70
+ make.left.right.inset(15);
71
+ }
72
+ },
73
+ {
74
+ type: "view",
75
+ props: {},
76
+ layout: (make, view) => {
77
+ make.top.bottom.inset(0);
78
+ make.left.right.inset(15);
79
+ },
80
+ views: [
81
+ {
82
+ type: "view",
83
+ props: {
84
+ id: "label_and_chevron"
85
+ },
86
+ layout: $layout.fill,
87
+ views: [
88
+ {
89
+ type: "image",
90
+ props: {
91
+ symbol: "chevron.right",
92
+ tintColor: $color("lightGray", "darkGray"),
93
+ contentMode: 1
94
+ },
95
+ layout: (make, view) => {
96
+ make.centerY.equalTo(view.super);
97
+ make.size.equalTo($size(17, 17));
98
+ make.right.inset(0);
99
+ }
100
+ },
101
+ {
102
+ type: "label",
103
+ props: {
104
+ id: "label_before_chevron",
105
+ align: $align.right,
106
+ font: $font(17)
107
+ },
108
+ layout: (make, view) => {
109
+ make.centerY.equalTo(view.super);
110
+ make.left.inset(this._props.stringLeftInset - 15);
111
+ make.right.equalTo(view.prev.left).inset(5);
112
+ }
113
+ }
114
+ ]
115
+ },
116
+ {
117
+ type: "view",
118
+ props: {
119
+ id: "number_and_stepper"
120
+ },
121
+ layout: $layout.fill,
122
+ views: [
123
+ {
124
+ type: "stepper",
125
+ props: {
126
+ id: "stepper"
127
+ },
128
+ layout: (make, view) => {
129
+ make.centerY.equalTo(view.super);
130
+ make.right.inset(0);
131
+ },
132
+ events: {
133
+ changed: sender => {
134
+ const { section, row } = sender.info;
135
+ this._sections[section].rows[row].value =
136
+ sender.value;
137
+ this.view.data = this._map(this._sections);
138
+ if (events.changed)
139
+ events.changed(this.values);
140
+ }
141
+ }
142
+ },
143
+ {
144
+ type: "label",
145
+ props: {
146
+ id: "label_stepper",
147
+ align: $align.right
148
+ },
149
+ layout: (make, view) => {
150
+ make.top.bottom.inset(0);
151
+ make.right.equalTo(view.prev.left).inset(10);
152
+ make.width.equalTo(100);
153
+ }
154
+ }
155
+ ]
156
+ },
157
+ {
158
+ type: "view",
159
+ props: {
160
+ id: "slider_and_number"
161
+ },
162
+ layout: $layout.fill,
163
+ views: [
164
+ {
165
+ type: "slider",
166
+ props: {
167
+ id: "slider"
168
+ },
169
+ layout: (make, view) => {
170
+ make.centerY.equalTo(view.super);
171
+ make.right.inset(40);
172
+ make.width.equalTo(this._props.sliderWidth - 40);
173
+ },
174
+ events: {
175
+ changed: sender => {
176
+ const { section, row } = sender.info;
177
+ const options = this._sections[section].rows[row];
178
+ const label = sender.next;
179
+ label.text = this._handleSliderValue(sender.value, options.decimal, options.min, options.max).toString();
180
+ },
181
+ touchesEnded: sender => {
182
+ const { section, row } = sender.info;
183
+ const options = this._sections[section].rows[row];
184
+ this._sections[section].rows[row].value = this._handleSliderValue(sender.value, options.decimal, options.min, options.max);
185
+ this.view.data = this._map(this._sections);
186
+ if (events.changed)
187
+ events.changed(this.values);
188
+ }
189
+ }
190
+ },
191
+ {
192
+ type: "label",
193
+ props: {
194
+ id: "label_slider",
195
+ align: $align.center
196
+ },
197
+ layout: (make, view) => {
198
+ make.top.bottom.inset(0);
199
+ make.right.inset(0);
200
+ make.width.equalTo(44);
201
+ }
202
+ }
203
+ ]
204
+ },
205
+ {
206
+ type: "switch",
207
+ props: {
208
+ id: "switch"
209
+ },
210
+ layout: (make, view) => {
211
+ make.centerY.equalTo(view.super);
212
+ make.right.inset(0);
213
+ },
214
+ events: {
215
+ changed: sender => {
216
+ const { section, row } = sender.info;
217
+ this._sections[section].rows[row].value = sender.on;
218
+ $delay(0.2, () => {
219
+ this.view.data = this._map(this._sections);
220
+ if (events.changed)
221
+ events.changed(this.values);
222
+ });
223
+ }
224
+ }
225
+ },
226
+ {
227
+ type: "tab",
228
+ props: {
229
+ id: "tab"
230
+ },
231
+ layout: (make, view) => {
232
+ make.centerY.equalTo(view.super);
233
+ make.height.equalTo(32);
234
+ make.width.equalTo(this._props.tabWidth);
235
+ make.right.inset(0);
236
+ },
237
+ events: {
238
+ changed: sender => {
239
+ const { section, row } = sender.info;
240
+ this._sections[section].rows[row].value = sender.index;
241
+ $delay(0.3, () => {
242
+ this.view.data = this._map(this._sections);
243
+ if (events.changed)
244
+ events.changed(this.values);
245
+ });
246
+ }
247
+ }
248
+ },
249
+ {
250
+ type: "label",
251
+ props: {
252
+ id: "label_info_link",
253
+ align: $align.right
254
+ },
255
+ layout: (make, view) => {
256
+ make.top.bottom.inset(0);
257
+ make.left.inset(this._props.infoAndLinkLeftInset);
258
+ make.right.inset(0);
259
+ }
260
+ }
261
+ ]
262
+ }
263
+ ]
264
+ }, data: this._map(this._sections) }),
265
+ layout: this._layout,
266
+ events: {
267
+ didSelect: (sender, indexPath, data) => {
268
+ const row = this._sections[indexPath.section].rows[indexPath.row];
269
+ if (!selectableTypes.includes(row.type))
270
+ return;
271
+ switch (row.type) {
272
+ case "string": {
273
+ $input.text({
274
+ type: $kbType.default,
275
+ placeholder: row.placeholder,
276
+ handler: text => {
277
+ row.value = text;
278
+ sender.data = this._map(this._sections);
279
+ if (events.changed)
280
+ events.changed(this.values);
281
+ }
282
+ });
283
+ break;
284
+ }
285
+ case "number": {
286
+ $input.text({
287
+ type: $kbType.decimal,
288
+ placeholder: row.placeholder,
289
+ handler: text => {
290
+ let num = this._handleText(text, row.type);
291
+ if (num === undefined)
292
+ return;
293
+ if (row.min !== undefined && num < row.min)
294
+ num = row.min;
295
+ if (row.max !== undefined && num > row.max)
296
+ num = row.max;
297
+ row.value = num;
298
+ sender.data = this._map(this._sections);
299
+ if (events.changed)
300
+ events.changed(this.values);
301
+ }
302
+ });
303
+ break;
304
+ }
305
+ case "integer": {
306
+ $input.text({
307
+ type: $kbType.number,
308
+ placeholder: row.placeholder,
309
+ handler: text => {
310
+ let num = this._handleText(text, row.type);
311
+ if (num === undefined)
312
+ return;
313
+ if (row.min !== undefined && num < row.min)
314
+ num = row.min;
315
+ if (row.max !== undefined && num > row.max)
316
+ num = row.max;
317
+ row.value = num;
318
+ sender.data = this._map(this._sections);
319
+ if (events.changed)
320
+ events.changed(this.values);
321
+ }
322
+ });
323
+ break;
324
+ }
325
+ case "list": {
326
+ $ui.menu({
327
+ items: row.items,
328
+ handler: (title, index) => {
329
+ row.value = index;
330
+ sender.data = this._map(this._sections);
331
+ if (events.changed)
332
+ events.changed(this.values);
333
+ }
334
+ });
335
+ break;
336
+ }
337
+ case "link": {
338
+ if (row.value)
339
+ $safari.open({ url: row.value });
340
+ break;
341
+ }
342
+ case "action": {
343
+ if (row.value)
344
+ row.value();
345
+ break;
346
+ }
347
+ default:
348
+ break;
349
+ }
350
+ }
351
+ }
352
+ };
353
+ };
354
+ }
355
+ _handleText(text, type) {
356
+ switch (type) {
357
+ case "number": {
358
+ const number = parseFloat(text);
359
+ if (isNaN(number))
360
+ return;
361
+ return number;
362
+ }
363
+ case "integer": {
364
+ const number = parseInt(text);
365
+ if (isNaN(number))
366
+ return;
367
+ return number;
368
+ }
369
+ case "stepper": {
370
+ const number = parseInt(text);
371
+ if (isNaN(number))
372
+ return;
373
+ return number;
374
+ }
375
+ default:
376
+ throw new Error("Invalid type");
377
+ }
378
+ }
379
+ _handleSliderValue(num, decimal, min, max) {
380
+ if (num === undefined)
381
+ return min || 0;
382
+ if (decimal === undefined)
383
+ decimal = 1;
384
+ if (isNaN(num))
385
+ num = min || 0;
386
+ if (min !== undefined && num < min)
387
+ num = min;
388
+ if (max !== undefined && num > max)
389
+ num = max;
390
+ const adjustedValue = parseFloat(num.toFixed(decimal));
391
+ return adjustedValue;
392
+ }
393
+ _map(sections) {
394
+ function generateDefaultRow(options) {
395
+ return {
396
+ bgview: { hidden: selectableTypes.includes(options.type) }, // bgview其实是用于调整selectable, 显示此视图就没有highlight效果
397
+ title: {
398
+ text: options.title,
399
+ textColor: options.titleColor || $color("primaryText")
400
+ }, // 标题, 同时用于action
401
+ label_and_chevron: { hidden: true }, // 用于string, number, integer, list
402
+ number_and_stepper: { hidden: true }, // 用于stepper
403
+ slider_and_number: { hidden: true }, // 用于slider
404
+ switch: { hidden: true }, // 用于boolean
405
+ tab: { hidden: true }, // 用于tab
406
+ label_info_link: { hidden: true } // 用于info, link
407
+ };
408
+ }
409
+ return sections.map((section, sectionIndex) => ({
410
+ title: section.title,
411
+ rows: section.rows.map((n, rowIndex) => {
412
+ const data = generateDefaultRow(n);
413
+ switch (n.type) {
414
+ case "string": {
415
+ data.label_and_chevron.hidden = false;
416
+ data.label_before_chevron = {
417
+ textColor: n.textColor || $color("primaryText"),
418
+ text: n.value === undefined ? "" : n.value
419
+ };
420
+ break;
421
+ }
422
+ case "number": {
423
+ data.label_and_chevron.hidden = false;
424
+ data.label_before_chevron = {
425
+ textColor: n.textColor || $color("primaryText"),
426
+ text: n.value === undefined ? "" : n.value
427
+ };
428
+ break;
429
+ }
430
+ case "integer": {
431
+ data.label_and_chevron.hidden = false;
432
+ data.label_before_chevron = {
433
+ textColor: n.textColor || $color("primaryText"),
434
+ text: n.value === undefined ? "" : n.value
435
+ };
436
+ break;
437
+ }
438
+ case "stepper": {
439
+ data.number_and_stepper.hidden = false;
440
+ data.label_stepper = {
441
+ textColor: $color("primaryText"),
442
+ text: n.value === undefined ? "" : n.value
443
+ };
444
+ data.stepper = {
445
+ min: n.min,
446
+ max: n.max,
447
+ value: n.value,
448
+ info: { section: sectionIndex, row: rowIndex, key: n.key }
449
+ };
450
+ break;
451
+ }
452
+ case "boolean": {
453
+ data.switch = {
454
+ hidden: false,
455
+ on: n.value,
456
+ onColor: n.onColor || $color("#34C85A"),
457
+ thumbColor: n.thumbColor,
458
+ info: { section: sectionIndex, row: rowIndex, key: n.key }
459
+ };
460
+ break;
461
+ }
462
+ case "slider": {
463
+ data.slider_and_number.hidden = false;
464
+ const adjustedValue = this._handleSliderValue(n.value, n.decimal, n.min, n.max);
465
+ data.label_slider = {
466
+ textColor: $color("primaryText"),
467
+ text: adjustedValue
468
+ };
469
+ data.slider = {
470
+ value: adjustedValue,
471
+ info: { section: sectionIndex, row: rowIndex, key: n.key },
472
+ min: n.min,
473
+ max: n.max,
474
+ minColor: n.minColor || $color("systemLink"),
475
+ maxColor: n.maxColor,
476
+ thumbColor: n.thumbColor
477
+ };
478
+ break;
479
+ }
480
+ case "list": {
481
+ data.label_and_chevron.hidden = false;
482
+ data.label_before_chevron = {
483
+ textColor: $color("secondaryText"),
484
+ text: n.items[n.value || 0]
485
+ };
486
+ break;
487
+ }
488
+ case "tab": {
489
+ data.tab = {
490
+ hidden: false,
491
+ items: n.items,
492
+ index: n.value,
493
+ info: { section: sectionIndex, row: rowIndex, key: n.key }
494
+ };
495
+ break;
496
+ }
497
+ case "info": {
498
+ data.label_info_link = {
499
+ hidden: false,
500
+ textColor: $color("secondaryText"),
501
+ text: n.value
502
+ };
503
+ break;
504
+ }
505
+ case "link": {
506
+ data.label_info_link = {
507
+ hidden: false,
508
+ styledText: `[${n.value}]()`
509
+ };
510
+ break;
511
+ }
512
+ case "action": {
513
+ data.title.textColor = n.destructive
514
+ ? $color("red")
515
+ : $color("systemLink");
516
+ break;
517
+ }
518
+ default:
519
+ break;
520
+ }
521
+ return data;
522
+ })
523
+ }));
524
+ }
525
+ get sections() {
526
+ return this._sections;
527
+ }
528
+ set sections(sections) {
529
+ this._sections = sections.map(n => ({
530
+ title: n.title,
531
+ rows: n.rows.map(r => (Object.assign({}, r)))
532
+ }));
533
+ this.view.data = this._map(this._sections);
534
+ }
535
+ get values() {
536
+ const values = {};
537
+ const excludedTypes = ["action", "info", "link"];
538
+ this._sections.forEach(section => {
539
+ section.rows.forEach(row => {
540
+ if (row.key && !excludedTypes.includes(row.type)) {
541
+ values[row.key] = row.value;
542
+ }
543
+ });
544
+ });
545
+ return values;
546
+ }
547
+ set(key, value) {
548
+ this._sections.forEach(section => {
549
+ section.rows.forEach(row => {
550
+ if (row.key === key)
551
+ row.value = value;
552
+ });
553
+ });
554
+ this.view.data = this._map(this._sections);
555
+ }
556
+ }
557
+ exports.DynamicPreferenceListView = DynamicPreferenceListView;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /**
3
+ * # cview Dynamic RowHeight List
4
+ *
5
+ * 可以自动更新 rowHeight 的 list
6
+ *
7
+ * 核心策略为 list 的所有行均为 cview,且每一个 cview 需要实现一个方法:heightToWidth(width: number) => number
8
+ * 通过这个方法汇报自己在某个宽度的时候所需要的高度,这必须任何时候均立即可用;
9
+ * 如果这个方法不可用,那么行高设为 44
10
+ *
11
+ * 特别参数
12
+ * sections: {title: string, rows: cview[]}[]
13
+ *
14
+ * 除了 props.data, props.template 和 events.rowHeight 不可用,其他均和 list 一致
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.DynamicRowHeightList = void 0;
18
+ const base_1 = require("./base");
19
+ class DynamicRowHeightList extends base_1.Base {
20
+ constructor({ sections, props, layout, events }) {
21
+ super();
22
+ this._sections = sections;
23
+ this._defineView = () => {
24
+ const data = this._sections.map(n => ({
25
+ title: n.title,
26
+ rows: n.rows.map(r => r.definition)
27
+ }));
28
+ return {
29
+ type: "list",
30
+ props: Object.assign({ data }, props),
31
+ layout,
32
+ events: Object.assign({ rowHeight: (sender, indexPath) => {
33
+ const cview = this._sections[indexPath.section].rows[indexPath.row];
34
+ if (cview.heightToWidth &&
35
+ typeof cview.heightToWidth === "function")
36
+ return cview.heightToWidth(sender.frame.width);
37
+ else
38
+ return 44;
39
+ } }, events)
40
+ };
41
+ };
42
+ }
43
+ }
44
+ exports.DynamicRowHeightList = DynamicRowHeightList;