jsbox-cview 1.0.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/LICENSE +21 -0
  2. package/README.md +19 -0
  3. package/components/alert/input-alert.ts +73 -0
  4. package/components/alert/login-alert.ts +75 -0
  5. package/components/alert/plain-alert.ts +49 -0
  6. package/components/alert/uialert.ts +110 -0
  7. package/components/artificial-flowlayout.ts +321 -0
  8. package/components/base.ts +47 -0
  9. package/components/custom-navigation-bar.ts +570 -0
  10. package/components/dialogs/dialog-sheet.ts +87 -0
  11. package/components/dialogs/form-dialog.ts +23 -0
  12. package/components/dialogs/list-dialog.ts +87 -0
  13. package/components/dialogs/text-dialog.ts +34 -0
  14. package/components/dynamic-itemsize-matrix.ts +190 -0
  15. package/components/dynamic-preference-listview.ts +691 -0
  16. package/components/dynamic-rowheight-list.ts +62 -0
  17. package/components/enhanced-imageview.ts +128 -0
  18. package/components/image-pager.ts +177 -0
  19. package/components/page-control.ts +91 -0
  20. package/components/pageviewer-titlebar.ts +170 -0
  21. package/components/pageviewer.ts +124 -0
  22. package/components/rotating-view.ts +126 -0
  23. package/components/searchbar.ts +373 -0
  24. package/components/sheet.ts +113 -0
  25. package/components/single-views.ts +828 -0
  26. package/components/spinners/loading-double-rings.ts +121 -0
  27. package/components/spinners/loading-dual-ring.ts +90 -0
  28. package/components/spinners/loading-wedges.ts +112 -0
  29. package/components/spinners/spinner-androidstyle.ts +264 -0
  30. package/components/static-preference-listview.ts +991 -0
  31. package/components/symbol-button.ts +105 -0
  32. package/components/tabbar.ts +451 -0
  33. package/controller/base-controller.ts +216 -0
  34. package/controller/controller-router.ts +74 -0
  35. package/controller/pageviewer-controller.ts +86 -0
  36. package/controller/presented-page-controller.ts +57 -0
  37. package/controller/splitview-controller.ts +323 -0
  38. package/controller/tabbar-controller.ts +99 -0
  39. package/package.json +23 -0
  40. package/test.ts +0 -0
  41. package/tsconfig.json +121 -0
  42. package/utils/colors.ts +13 -0
  43. package/utils/cvid.ts +34 -0
  44. package/utils/l10n.ts +42 -0
  45. package/utils/path.ts +100 -0
  46. package/utils/rect.ts +67 -0
  47. package/utils/uitools.ts +117 -0
@@ -0,0 +1,62 @@
1
+ /**
2
+ * # cview Dynamic RowHeight List
3
+ *
4
+ * 可以自动更新 rowHeight 的 list
5
+ *
6
+ * 核心策略为 list 的所有行均为 cview,且每一个 cview 需要实现一个方法:heightToWidth(width: number) => number
7
+ * 通过这个方法汇报自己在某个宽度的时候所需要的高度,这必须任何时候均立即可用;
8
+ * 如果这个方法不可用,那么行高设为 44
9
+ *
10
+ * 特别参数
11
+ * sections: {title: string, rows: cview[]}[]
12
+ *
13
+ * 除了 props.data, props.template 和 events.rowHeight 不可用,其他均和 list 一致
14
+ */
15
+
16
+ import { Base } from './base';
17
+
18
+ interface DynamicRowHeightListProps extends Omit<UiTypes.ListProps, "data" | "template"> {}
19
+ interface DynamicRowHeightListEvents extends Omit<UiTypes.ListEvents, "rowHeight"> {}
20
+ interface DynamicRowHeightListCView extends Base<any, any> {
21
+ heightToWidth: (width: number) => number;
22
+ }
23
+
24
+ export class DynamicRowHeightList extends Base<UIListView, UiTypes.ListOptions>{
25
+ _sections: {title: string, rows: DynamicRowHeightListCView[]}[];
26
+ _defineView: () => UiTypes.ListOptions;
27
+ constructor({ sections, props, layout, events }: {
28
+ sections: {title: string, rows: DynamicRowHeightListCView[]}[];
29
+ props: DynamicRowHeightListProps;
30
+ layout: (make: MASConstraintMaker, view: UIListView) => void;
31
+ events: DynamicRowHeightListEvents;
32
+ }) {
33
+ super();
34
+ this._sections = sections;
35
+ this._defineView = () => {
36
+ const data = this._sections.map(n => ({
37
+ title: n.title,
38
+ rows: n.rows.map(r => r.definition)
39
+ }));
40
+ return {
41
+ type: "list",
42
+ props: {
43
+ data,
44
+ ...props
45
+ },
46
+ layout,
47
+ events: {
48
+ rowHeight: (sender, indexPath) => {
49
+ const cview = this._sections[indexPath.section].rows[indexPath.row];
50
+ if (
51
+ cview.heightToWidth &&
52
+ typeof cview.heightToWidth === "function"
53
+ )
54
+ return cview.heightToWidth(sender.frame.width);
55
+ else return 44;
56
+ },
57
+ ...events
58
+ }
59
+ };
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * 此组件是为了加强 imageView,实现以下目的:
3
+ * 1. 点击实现上下翻页
4
+ * 2. 双指放大缩小(但不可以双击放大缩小)
5
+ *
6
+ * 请注意:此组件使用了Runtime代码重新设置了Tapped事件。
7
+ * 与以前使用touchesEnded事件来实现相比,可以避免在滑动手指时误触发。
8
+ * 但因此带来了副作用:必须在关闭前通过releaseGestureObject释放掉此视图中自定义的NSObject,否则再次启动可能会有问题。
9
+ *
10
+ * Props:
11
+ * src: string, 图片地址
12
+ * maxZoomScale: number, 最大缩放倍数,默认为2
13
+ *
14
+ * Events:
15
+ * upperLocationTouched: (sender: EnhancedImageView) => void, 上半部分被点击
16
+ * lowerLocationTouched: (sender: EnhancedImageView) => void, 下半部分被点击
17
+ */
18
+ import { Base } from "./base";
19
+ import { Scroll } from "./single-views";
20
+ import { cvid } from "../utils/cvid";
21
+
22
+ export class EnhancedImageView extends Base<UIView, UiTypes.ViewOptions> {
23
+ private _props: { src: string; maxZoomScale: number };
24
+ private _scroll: Scroll;
25
+ private _gestureObject: any;
26
+ _defineView: () => UiTypes.ViewOptions;
27
+
28
+ constructor({ props, layout, events = {} }: {
29
+ props: { src: string; maxZoomScale?: number };
30
+ layout: (make: MASConstraintMaker, view: UIView) => void;
31
+ events?: {
32
+ upperLocationTouched?: (sender: EnhancedImageView) => void;
33
+ lowerLocationTouched?: (sender: EnhancedImageView) => void;
34
+ }
35
+ }) {
36
+ super();
37
+ this._props = { maxZoomScale: 2, ...props };
38
+ this._scroll = new Scroll({
39
+ props: {
40
+ zoomEnabled: true,
41
+ doubleTapToZoom: false,
42
+ maxZoomScale: this._props.maxZoomScale
43
+ },
44
+ layout: $layout.fill,
45
+ views: [
46
+ {
47
+ type: "image",
48
+ props: {
49
+ id: "image",
50
+ src: this._props.src,
51
+ contentMode: 1
52
+ },
53
+ layout: $layout.fill
54
+ }
55
+ ],
56
+ events: {
57
+ ready: view => {
58
+ $delay(0.1, () =>
59
+ this._addGesture(view, (gesture: any) => {
60
+ const location = gesture.$locationInView(view.ocValue());
61
+ const realLocation = $point(location.x - view.bounds.x, location.y - view.bounds.y)
62
+ const frame = this.view.frame
63
+ if (realLocation.y <= frame.height / 2) {
64
+ if (events.upperLocationTouched) events.upperLocationTouched(this)
65
+ } else {
66
+ if (events.lowerLocationTouched) events.lowerLocationTouched(this)
67
+ }
68
+ })
69
+ );
70
+ }
71
+ }
72
+ });
73
+ this._defineView = () => {
74
+ return {
75
+ type: "view",
76
+ props: {
77
+ id: this.id
78
+ },
79
+ views: [this._scroll.definition],
80
+ layout,
81
+ events: {
82
+ layoutSubviews: sender => {
83
+ $delay(0.1, () => (this.src = this.src));
84
+ $delay(0.3, () => (this.src = this.src));
85
+ }
86
+ }
87
+ };
88
+ }
89
+ }
90
+
91
+
92
+ private _addGesture(view: AllUIView, event: (gesture: any) => void) {
93
+ const objectId = cvid.newId;
94
+ $define({
95
+ type: objectId + ": NSObject",
96
+ events: {
97
+ tapped: event
98
+ }
99
+ });
100
+ const object = $objc(objectId).$new();
101
+ $objc_retain(object); // 此步骤是必须的,否则将很快被系统释放掉,但是必须在关闭时手动释放掉,否则再次启动可能会有问题
102
+ this._gestureObject = object;
103
+ const tapGestureRecognizer = $objc("UITapGestureRecognizer")
104
+ .$alloc()
105
+ .$initWithTarget_action(this._gestureObject, "tapped:");
106
+ view.ocValue().$addGestureRecognizer(tapGestureRecognizer);
107
+ }
108
+
109
+ releaseGestureObject() {
110
+ if (this._gestureObject) $objc_release(this._gestureObject);
111
+ }
112
+
113
+ get src() {
114
+ return this._props.src;
115
+ }
116
+
117
+ set src(src) {
118
+ this._props.src = src;
119
+ const view = this._scroll.view.get("image") as UIImageView;
120
+ view.src = src;
121
+ }
122
+
123
+ get image() {
124
+ const view = this._scroll.view.get("image") as UIImageView;
125
+ return view.image;
126
+ }
127
+ }
128
+
@@ -0,0 +1,177 @@
1
+ /**
2
+ * 与内置的Gallery组件相比,ImagePager组件可以动态刷新,适用于图片数量较多的场景,以及需要动态加载图片列表的场景
3
+ *
4
+ * # Props
5
+ * srcs: string[] - 图片地址列表
6
+ * page: number - 当前页码
7
+ *
8
+ * # Events
9
+ * changed: (page: number) => void - 页码变化时触发
10
+ * tapped: (sender: ImagePager) => void - 点击图片时触发
11
+ */
12
+ import { Base } from "./base";
13
+ import { Matrix } from "./single-views";
14
+
15
+ export class ImagePager extends Base<UIView, UiTypes.ViewOptions> {
16
+ _props: {
17
+ srcs: string[];
18
+ page: number;
19
+ };
20
+ _matrix: Matrix;
21
+ _pageLoadRecorder: { [key: number]: boolean };
22
+ _defineView: () => UiTypes.ViewOptions;
23
+ constructor({ props, layout, events = {} }: {
24
+ props: {
25
+ srcs?: string[];
26
+ page?: number;
27
+ };
28
+ layout: (make: MASConstraintMaker, view: UIView) => void;
29
+ events: {
30
+ changed?: (page: number) => void;
31
+ tapped?: (sender: ImagePager) => void;
32
+ };
33
+
34
+ }) {
35
+ super();
36
+ this._props = {
37
+ srcs: [],
38
+ page: 0,
39
+ ...props
40
+ };
41
+ this._pageLoadRecorder = {};
42
+ this._matrix = new Matrix({
43
+ props: {
44
+ direction: $scrollDirection.horizontal,
45
+ pagingEnabled: true,
46
+ alwaysBounceVertical: false,
47
+ showsVerticalIndicator: false,
48
+ showsHorizontalIndicator: false,
49
+ template: {
50
+ views: [
51
+ {
52
+ type: "scroll",
53
+ props: {
54
+ id: "scroll",
55
+ zoomEnabled: true,
56
+ maxZoomScale: 3,
57
+ doubleTapToZoom: true
58
+ },
59
+ layout: $layout.fill,
60
+ views: [
61
+ {
62
+ type: "image",
63
+ props: {
64
+ id: "image",
65
+ contentMode: $contentMode.scaleAspectFit
66
+ }
67
+ }
68
+ ]
69
+ }
70
+ ]
71
+ },
72
+ data: this._props.srcs.map(n => {
73
+ return { image: { src: n } };
74
+ })
75
+ },
76
+ layout: $layout.fill,
77
+ events: {
78
+ ready: sender => {
79
+ // 如果没有此处的relayout,则会出现莫名其妙的bug
80
+ sender.relayout();
81
+ this.page = this.page;
82
+ this.loadsrc(this.page);
83
+ },
84
+ itemSize: (sender, indexPath) => {
85
+ return $size(sender.frame.width, sender.frame.height);
86
+ },
87
+ forEachItem: (view, indexPath) => {
88
+ const scroll = view.get("scroll") as UIScrollView;
89
+ scroll.zoomScale = 0;
90
+ //$delay(0.01, () => {});
91
+ },
92
+ willEndDragging: (sender, velocity, target) => {
93
+ const oldPage = this.page;
94
+ this._props.page = Math.round(target.x / sender.frame.width);
95
+ //this.loadsrc(this.page, true);
96
+ if (oldPage !== this.page && events.changed)
97
+ events.changed(this.page);
98
+ },
99
+ didScroll: sender => {
100
+ this.loadsrc(this.page + 1, true);
101
+ this.loadsrc(this.page - 1, true);
102
+ }
103
+ }
104
+ });
105
+ this._defineView = () => {
106
+ return {
107
+ type: "view",
108
+ props: {
109
+ id: this.id,
110
+ userInteractionEnabled: true
111
+ },
112
+ layout,
113
+ views: [this._matrix.definition],
114
+ events: {
115
+ layoutSubviews: sender => {
116
+ this._pageLoadRecorder = {};
117
+ sender.relayout();
118
+ this._matrix.view.reload();
119
+ this.page = this.page;
120
+ $delay(0.1, () => this.loadsrc(this.page, true));
121
+ $delay(0.3, () => this.loadsrc(this.page, true));
122
+ },
123
+ tapped: sender => {
124
+ const cell = this._matrix.view.cell($indexPath(0, this.page));
125
+ if (!cell) return;
126
+ const scroll = cell.get("scroll") as UIScrollView;
127
+ const zoomScale = scroll.zoomScale;
128
+ $delay(0.3, () => {
129
+ const zoomScale1 = scroll.zoomScale;
130
+ if (zoomScale === zoomScale1 && events.tapped)
131
+ events.tapped(this);
132
+ });
133
+ }
134
+ }
135
+ };
136
+ }
137
+ }
138
+
139
+ loadsrc(page: number, forced = false) {
140
+ if (page < 0 || page >= this._props.srcs.length) return;
141
+ const cell = this._matrix.view.cell($indexPath(0, page));
142
+ if (!cell) return;
143
+ const image = cell.get("image") as UIImageView;
144
+ if (forced || !image.image || !this._pageLoadRecorder[page]) {
145
+ const scroll = cell.get("scroll") as UIScrollView;
146
+ scroll.zoomScale = 0;
147
+ this._pageLoadRecorder[page] = true;
148
+ }
149
+ }
150
+
151
+ get page() {
152
+ return this._props.page;
153
+ }
154
+
155
+ get currentImage() {
156
+ const cell = this._matrix.view.cell($indexPath(0, this.page));
157
+ if (!cell) return;
158
+ const image = cell.get("image") as UIImageView;
159
+ return image.image;
160
+ }
161
+
162
+ set page(page) {
163
+ this._matrix.view.scrollTo({
164
+ indexPath: $indexPath(0, page),
165
+ animated: false
166
+ });
167
+ this._props.page = page;
168
+ }
169
+
170
+ scrollToPage(page: number) {
171
+ this._matrix.view.scrollTo({
172
+ indexPath: $indexPath(0, page),
173
+ animated: true
174
+ });
175
+ this._props.page = page;
176
+ }
177
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * # CView PageControl
3
+ *
4
+ * 基于 Runtime 构建 PageControl
5
+ *
6
+ * 请注意本视图如果没有足够的横向宽度,会显示不全
7
+ * ## Props
8
+ *
9
+ * - 只写 numberOfPages: numnber
10
+ * - 读写 currentPage: number
11
+ * - 只写 pageIndicatorTintColor?: JSBoxColor
12
+ * - 只写 currentPageIndicatorTintColor?: JSBoxColor
13
+ * - 其他通用属性
14
+ *
15
+ * ## Events
16
+ *
17
+ * changed: (cview: Cview, currentPage: number) => void
18
+ */
19
+
20
+ import { Runtime } from "./single-views";
21
+
22
+ export class PageControl extends Runtime {
23
+ private _numberOfPages: number;
24
+ private _currentPage: number;
25
+ private _pageIndicatorTintColor?: UIColor;
26
+ private _currentPageIndicatorTintColor?: UIColor;
27
+ private _changed?: (sender: PageControl, currentPage: number) => void;
28
+ private _pageControl: any;
29
+ constructor({ props, layout, events = {} }: {
30
+ props: {
31
+ numberOfPages?: number;
32
+ currentPage?: number;
33
+ pageIndicatorTintColor?: UIColor;
34
+ currentPageIndicatorTintColor?: UIColor;
35
+ };
36
+ layout: (make: MASConstraintMaker, view: UIView) => void;
37
+ events?: {
38
+ changed?: (sender: PageControl, currentPage: number) => void;
39
+ }
40
+ }) {
41
+ const {
42
+ numberOfPages = 3,
43
+ currentPage = 0,
44
+ pageIndicatorTintColor,
45
+ currentPageIndicatorTintColor,
46
+ ...restProps
47
+ } = props;
48
+ const { changed, ...restEvents } = events;
49
+ super({ props: restProps, layout, events: restEvents });
50
+ this._numberOfPages = numberOfPages;
51
+ this._currentPage = currentPage;
52
+ this._pageIndicatorTintColor = pageIndicatorTintColor;
53
+ this._currentPageIndicatorTintColor = currentPageIndicatorTintColor;
54
+ this._changed = changed;
55
+ this._pageControl = this._createPageControl();
56
+ if (this._props) this._props.view = this._pageControl;
57
+ }
58
+
59
+ _createPageControl() {
60
+ const pageControl = $objc("UIPageControl").$new();
61
+ pageControl.$setNumberOfPages(this._numberOfPages);
62
+ pageControl.$setCurrentPage(this._currentPage);
63
+ if (this._pageIndicatorTintColor)
64
+ pageControl.$setPageIndicatorTintColor(
65
+ this._pageIndicatorTintColor.ocValue()
66
+ );
67
+ if (this._currentPageIndicatorTintColor)
68
+ pageControl.$setCurrentPageIndicatorTintColor(
69
+ this._currentPageIndicatorTintColor.ocValue()
70
+ );
71
+
72
+ pageControl.$addEventHandler({
73
+ events: $UIEvent.valueChanged,
74
+ handler: $block("void", () => {
75
+ const currentPage = pageControl.$currentPage();
76
+ this._currentPage = currentPage
77
+ if (this._changed) this._changed(this, currentPage);
78
+ })
79
+ });
80
+ return pageControl;
81
+ }
82
+
83
+ get currentPage() {
84
+ return this._currentPage;
85
+ }
86
+
87
+ set currentPage(num) {
88
+ this._currentPage = num
89
+ if (this._pageControl) this._pageControl.$setCurrentPage(num);
90
+ }
91
+ }
@@ -0,0 +1,170 @@
1
+ /**
2
+ * # CView PageViewer TitleBar
3
+ *
4
+ * props:
5
+ *
6
+ * - 只写 items: string[]
7
+ * - 读写 index: number
8
+ * - 只写 selectedItemColor
9
+ * - 只写 defaultItemColor
10
+ *
11
+ * events:
12
+ *
13
+ * - changed: (cview, index) => void 在点击变更 index 的时候回调
14
+ */
15
+
16
+ import { Base } from './base';
17
+ import { ContentView, Label, Stack } from "./single-views";
18
+ //const { getTextWidth } = require("cview-util-ui");
19
+
20
+ function weightedAverageColors(c0: UIColor, c1: UIColor, w: number) {
21
+ const red = c0.components.red * w + c1.components.red * (1 - w);
22
+ const green = c0.components.green * w + c1.components.green * (1 - w);
23
+ const blue = c0.components.blue * w + c1.components.blue * (1 - w);
24
+ return $rgb(red, green, blue);
25
+ }
26
+
27
+ interface PageViewerTitleBarProps {
28
+ items: string[];
29
+ index?: number;
30
+ selectedItemColor?: UIColor;
31
+ defaultItemColor?: UIColor;
32
+ }
33
+
34
+ interface PageViewerTitleBarEvents extends UiTypes.BaseViewEvents {
35
+ changed?: (cview: PageViewerTitleBar, index: number) => void;
36
+ }
37
+
38
+ export class PageViewerTitleBar extends Base<UIView, UiTypes.ViewOptions> {
39
+ private _props: Required<PageViewerTitleBarProps>;
40
+ private _floatedIndex: number;
41
+ private _lineStartLocationPercentage: number;
42
+ labels: Label[];
43
+ stack: Stack;
44
+ placeholderView: ContentView;
45
+ line: ContentView;
46
+
47
+ _defineView: () => UiTypes.ViewOptions;
48
+
49
+ constructor({ props, layout, events = {} }: {
50
+ props: PageViewerTitleBarProps;
51
+ layout: (make: MASConstraintMaker, view: UIView) => void;
52
+ events: PageViewerTitleBarEvents;
53
+ }) {
54
+ super();
55
+ this._props = {
56
+ index: 0,
57
+ selectedItemColor: $color("systemLink"),
58
+ defaultItemColor: $color("secondaryText"),
59
+ ...props
60
+ };
61
+ const { changed, ...restEvents } = events;
62
+ this._floatedIndex = this._props.index;
63
+ this._lineStartLocationPercentage = this._floatedIndex / this._props.items.length;
64
+ this.labels = this._props.items.map((n, i) => {
65
+ return new Label({
66
+ props: {
67
+ text: n,
68
+ font: $font("bold", 17),
69
+ textColor:
70
+ i === this.index
71
+ ? this._props.selectedItemColor
72
+ : this._props.defaultItemColor,
73
+ align: $align.center,
74
+ userInteractionEnabled: true
75
+ },
76
+ events: {
77
+ tapped: sender => {
78
+ this.index = i;
79
+ if (changed) changed(this, i);
80
+ }
81
+ }
82
+ });
83
+ });
84
+ this.stack = new Stack({
85
+ props: {
86
+ axis: $stackViewAxis.horizontal,
87
+ distribution: $stackViewDistribution.fillEqually,
88
+ stack: {
89
+ views: this.labels.map(n => n.definition)
90
+ }
91
+ },
92
+ layout: $layout.fill
93
+ });
94
+ this.placeholderView = new ContentView({
95
+ props: {
96
+ bgcolor: $color("clear")
97
+ },
98
+ layout: (make, view) => {
99
+ make.left.bottom.inset(0);
100
+ make.width.equalTo(view.super).multipliedBy(this._floatedIndex / this._props.items.length);
101
+ }
102
+ });
103
+ this.line = new ContentView({
104
+ props: {
105
+ bgcolor: this._props.selectedItemColor
106
+ },
107
+ layout: (make, view) => {
108
+ make.height.equalTo(4);
109
+ make.width.equalTo(view.super).dividedBy(this._props.items.length);
110
+ make.bottom.inset(0);
111
+ make.left.equalTo(view.prev.right);
112
+ }
113
+ });
114
+ this._defineView = () => {
115
+ return {
116
+ type: "view",
117
+ props: {
118
+ id: this.id
119
+ },
120
+ layout,
121
+ events: restEvents,
122
+ views: [
123
+ this.stack.definition,
124
+ this.placeholderView.definition,
125
+ this.line.definition
126
+ ]
127
+ };
128
+ }
129
+ }
130
+
131
+ get lineStartLocationPercentage() {
132
+ return this._lineStartLocationPercentage;
133
+ }
134
+
135
+ set lineStartLocationPercentage(percent) {
136
+ this._lineStartLocationPercentage = percent;
137
+ this.placeholderView.view.remakeLayout((make, view) => {
138
+ make.left.bottom.inset(0);
139
+ make.width.equalTo(view.super).multipliedBy(percent);
140
+ });
141
+ }
142
+
143
+ get floatedIndex() {
144
+ return this._floatedIndex;
145
+ }
146
+
147
+ set floatedIndex(floatedIndex) {
148
+ this._floatedIndex = floatedIndex;
149
+ this.lineStartLocationPercentage = floatedIndex / this._props.items.length;
150
+ this.labels.forEach((n, i) => {
151
+ if (Math.abs(floatedIndex - i) < 1) {
152
+ n.view.textColor = weightedAverageColors(
153
+ this._props.selectedItemColor,
154
+ this._props.defaultItemColor,
155
+ floatedIndex - i > 0 ? 1 - (floatedIndex - i) : 1 - (i - floatedIndex)
156
+ );
157
+ } else {
158
+ n.view.textColor = this._props.defaultItemColor;
159
+ }
160
+ });
161
+ }
162
+
163
+ get index() {
164
+ return this._props.index;
165
+ }
166
+
167
+ set index(index) {
168
+ this._props.index = index;
169
+ }
170
+ }