@ray-js/ray-ipc-half-horizontal-drag 0.0.6 → 0.0.7-beta.1
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.
- package/README.md +10 -0
- package/lib/index.js +11 -124
- package/lib/lynx/android-bounce.d.ts +55 -0
- package/lib/lynx/android-bounce.js +171 -0
- package/lib/lynx/index.d.ts +4 -0
- package/lib/lynx/index.js +102 -0
- package/lib/lynx/index.module.less +207 -0
- package/lib/props.d.ts +6 -1
- package/lib/webview.d.ts +5 -0
- package/lib/webview.js +129 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -16,6 +16,16 @@ $ yarn add @ray-js/ray-ipc-half-horizontal-drag
|
|
|
16
16
|
|
|
17
17
|
## Develop
|
|
18
18
|
|
|
19
|
+
### Lynx Android background images
|
|
20
|
+
|
|
21
|
+
With `renderMode="lynx"`, Android URL backgrounds use a real `Image` layer (`aspectFill`) to match the CSS cover layout. iOS and the default WebView implementation keep their existing CSS path. Card/tag/close behavior and the public props are unchanged. The local background fix was verified on Android on 2026-11-02 and is pending publication.
|
|
22
|
+
|
|
23
|
+
### Lynx Android edge feedback (local integration)
|
|
24
|
+
|
|
25
|
+
The local Lynx Android branch adds bounded edge drag feedback around the existing native ScrollView. Normal scrolling stays native; out-of-range horizontal drags offset the track with resistance and return it on release/cancel. Vertical gestures remain native, dragged cards cannot fire click/close handlers, and page hide clears the offset. Bounds are measured in logical px for phone/tablet layouts. iOS and WebView keep the existing path and public props.
|
|
26
|
+
|
|
27
|
+
This is a local source integration, not a published beta update. It does not implement a replacement momentum scroller or promise identical iOS fling-at-edge physics. The Android local integration was accepted on 2026-11-02: the user confirmed edge return and vertical scrolling are normal.
|
|
28
|
+
|
|
19
29
|
```sh
|
|
20
30
|
# install deps
|
|
21
31
|
yarn
|
package/lib/index.js
CHANGED
|
@@ -1,128 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
2
|
+
const _excluded = ["renderMode"];
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
showCloseBtn,
|
|
14
|
-
onCloseClick = NILL,
|
|
15
|
-
closeBtnTitle = 'Close',
|
|
16
|
-
closeBtnIcon
|
|
17
|
-
} = props;
|
|
18
|
-
const renderCloseBtn = () => {
|
|
19
|
-
if (!showCloseBtn) return null;
|
|
20
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
21
|
-
className: styles.closeBtn,
|
|
22
|
-
onClick: onCloseClick
|
|
23
|
-
}, closeBtnIcon, closeBtnTitle);
|
|
24
|
-
};
|
|
25
|
-
if (!data || !data.length) return null;
|
|
26
|
-
if (data.length === 1) {
|
|
27
|
-
const item = data[0];
|
|
28
|
-
const {
|
|
29
|
-
tag,
|
|
30
|
-
tagStyle,
|
|
31
|
-
tagClassName,
|
|
32
|
-
title,
|
|
33
|
-
onClick = NILL
|
|
34
|
-
} = item || {};
|
|
35
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
36
|
-
className: clsx(styles.content, className, {
|
|
37
|
-
[styles.moreContent]: showCloseBtn
|
|
38
|
-
}),
|
|
39
|
-
style: _objectSpread({}, style)
|
|
40
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
41
|
-
style: _objectSpread(_objectSpread({}, item.style), {}, {
|
|
42
|
-
backgroundImage: item.backgroundImage ? `url(${item.backgroundImage})` : undefined,
|
|
43
|
-
background: item.background || undefined
|
|
44
|
-
}),
|
|
45
|
-
className: clsx(styles.one_data_item, styles.item, item.className, {
|
|
46
|
-
[styles.one_data_item_width]: showCloseBtn
|
|
47
|
-
}),
|
|
48
|
-
onClick: onClick
|
|
49
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
50
|
-
className: styles.icon
|
|
51
|
-
}, item.icon), /*#__PURE__*/React.createElement(View, {
|
|
52
|
-
className: styles.title
|
|
53
|
-
}, title), !!tag && /*#__PURE__*/React.createElement(View, {
|
|
54
|
-
style: _objectSpread({}, tagStyle),
|
|
55
|
-
className: clsx(styles.tag, tagClassName)
|
|
56
|
-
}, tag)), renderCloseBtn());
|
|
57
|
-
}
|
|
58
|
-
if (data.length === 2) {
|
|
59
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
60
|
-
className: clsx(styles.content, styles.towContent, className, {
|
|
61
|
-
[styles.moreContent]: showCloseBtn
|
|
62
|
-
}),
|
|
63
|
-
style: _objectSpread({}, style)
|
|
64
|
-
}, data.map((item, idx) => {
|
|
65
|
-
const {
|
|
66
|
-
title,
|
|
67
|
-
tag,
|
|
68
|
-
tagStyle,
|
|
69
|
-
tagClassName,
|
|
70
|
-
onClick = NILL
|
|
71
|
-
} = item;
|
|
72
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
73
|
-
key: idx // eslint-disable-line
|
|
74
|
-
,
|
|
75
|
-
style: _objectSpread(_objectSpread({}, item.style), {}, {
|
|
76
|
-
backgroundImage: item.backgroundImage ? `url(${item.backgroundImage})` : undefined,
|
|
77
|
-
background: item.background || undefined
|
|
78
|
-
}),
|
|
79
|
-
onClick: onClick,
|
|
80
|
-
className: clsx(styles.two_data_item, styles.item, item.className, {
|
|
81
|
-
[styles.two_data_item_width]: showCloseBtn
|
|
82
|
-
})
|
|
83
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
84
|
-
className: styles.icon
|
|
85
|
-
}, item.icon), /*#__PURE__*/React.createElement(View, {
|
|
86
|
-
className: styles.title
|
|
87
|
-
}, title), !!tag && /*#__PURE__*/React.createElement(View, {
|
|
88
|
-
style: _objectSpread({}, tagStyle),
|
|
89
|
-
className: clsx(styles.tag, tagClassName)
|
|
90
|
-
}, tag));
|
|
91
|
-
}), renderCloseBtn());
|
|
92
|
-
}
|
|
93
|
-
if (data.length >= 3) {
|
|
94
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
95
|
-
className: clsx(styles.content, styles.moreContent, className),
|
|
96
|
-
style: _objectSpread({}, style)
|
|
97
|
-
}, data.map((item, idx) => {
|
|
98
|
-
const {
|
|
99
|
-
title,
|
|
100
|
-
tag,
|
|
101
|
-
tagStyle,
|
|
102
|
-
tagClassName,
|
|
103
|
-
onClick = NILL
|
|
104
|
-
} = item;
|
|
105
|
-
return /*#__PURE__*/React.createElement(View
|
|
106
|
-
// eslint-disable-next-line react/no-array-index-key
|
|
107
|
-
, {
|
|
108
|
-
key: idx,
|
|
109
|
-
style: _objectSpread(_objectSpread({}, item.style), {}, {
|
|
110
|
-
backgroundImage: item.backgroundImage ? `url(${item.backgroundImage})` : undefined,
|
|
111
|
-
background: item.background || undefined
|
|
112
|
-
}),
|
|
113
|
-
className: clsx(styles.item, styles.more_data_item, item.className),
|
|
114
|
-
onClick: onClick
|
|
115
|
-
}, /*#__PURE__*/React.createElement(View, {
|
|
116
|
-
className: styles.icon
|
|
117
|
-
}, item.icon), /*#__PURE__*/React.createElement(View, {
|
|
118
|
-
className: styles.title
|
|
119
|
-
}, title), !!tag && /*#__PURE__*/React.createElement(View, {
|
|
120
|
-
style: _objectSpread({}, tagStyle),
|
|
121
|
-
className: clsx(styles.tag, tagClassName)
|
|
122
|
-
}, tag));
|
|
123
|
-
}), renderCloseBtn());
|
|
124
|
-
}
|
|
125
|
-
return null;
|
|
4
|
+
import WebViewHalfHorizontalDrag from './webview';
|
|
5
|
+
import LynxHalfHorizontalDrag from './lynx';
|
|
6
|
+
const HalfHorizontalDrag = _ref => {
|
|
7
|
+
let {
|
|
8
|
+
renderMode = 'webview'
|
|
9
|
+
} = _ref,
|
|
10
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
11
|
+
if (renderMode === 'lynx') return /*#__PURE__*/React.createElement(LynxHalfHorizontalDrag, props);
|
|
12
|
+
return /*#__PURE__*/React.createElement(WebViewHalfHorizontalDrag, props);
|
|
126
13
|
};
|
|
127
14
|
HalfHorizontalDrag.displayName = 'HalfHorizontalDrag';
|
|
128
15
|
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ScrollView } from '@ray-js/ray';
|
|
3
|
+
type ScrollProps = React.ComponentProps<typeof ScrollView> & {
|
|
4
|
+
hideScrollbar?: boolean;
|
|
5
|
+
};
|
|
6
|
+
type Touch = {
|
|
7
|
+
identifier?: number | string;
|
|
8
|
+
clientX?: number;
|
|
9
|
+
clientY?: number;
|
|
10
|
+
pageX?: number;
|
|
11
|
+
pageY?: number;
|
|
12
|
+
};
|
|
13
|
+
type TouchEvent = {
|
|
14
|
+
touches?: Touch[];
|
|
15
|
+
origin?: {
|
|
16
|
+
touches?: Touch[];
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export type ClickGuard = (callback: ((event?: any) => void) | undefined, event: any) => void;
|
|
20
|
+
type Props = Omit<ScrollProps, 'children'> & {
|
|
21
|
+
children: (track: {
|
|
22
|
+
id: string;
|
|
23
|
+
style: React.CSSProperties;
|
|
24
|
+
}, guard: ClickGuard) => React.ReactElement;
|
|
25
|
+
};
|
|
26
|
+
export declare function rubberBand(distance: number, width: number): number;
|
|
27
|
+
/** Android-only visual compensation; native scrolling and vertical gesture arbitration stay native. */
|
|
28
|
+
export declare class AndroidBounceScrollImpl extends React.Component<Props, {
|
|
29
|
+
offset: number;
|
|
30
|
+
returning: boolean;
|
|
31
|
+
}> {
|
|
32
|
+
constructor(props: Props);
|
|
33
|
+
componentDidMount(): void;
|
|
34
|
+
componentDidUpdate(previous: Props): void;
|
|
35
|
+
componentWillUnmount(): void;
|
|
36
|
+
onHide: () => void;
|
|
37
|
+
private id;
|
|
38
|
+
private alive;
|
|
39
|
+
private measureId;
|
|
40
|
+
private width;
|
|
41
|
+
private range;
|
|
42
|
+
private scrollLeft;
|
|
43
|
+
private moved;
|
|
44
|
+
private press?;
|
|
45
|
+
private measure;
|
|
46
|
+
start: (event: TouchEvent) => void;
|
|
47
|
+
move: (event: TouchEvent) => void;
|
|
48
|
+
end: () => void;
|
|
49
|
+
cancel: () => void;
|
|
50
|
+
private guard;
|
|
51
|
+
private scroll;
|
|
52
|
+
render(): React.JSX.Element;
|
|
53
|
+
}
|
|
54
|
+
export declare const AndroidBounceScroll: React.ComponentType<Props>;
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
3
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
4
|
+
const _excluded = ["children"];
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { createSelectorQuery, ScrollView, withPageLifecycle } from '@ray-js/ray';
|
|
7
|
+
let sequence = 0;
|
|
8
|
+
|
|
9
|
+
// Limit the displacement in logical px, independent of rpx conversion and screen size.
|
|
10
|
+
export function rubberBand(distance, width) {
|
|
11
|
+
if (!(width > 0) || !Number.isFinite(distance)) return 0;
|
|
12
|
+
const limit = Math.min(56, width * 0.16);
|
|
13
|
+
return Math.sign(distance) * Math.min(limit, Math.abs(distance) * 0.36 / (1 + Math.abs(distance) / width));
|
|
14
|
+
}
|
|
15
|
+
function point(event) {
|
|
16
|
+
var _event$origin, _event$touches;
|
|
17
|
+
const touches = (event === null || event === void 0 || (_event$origin = event.origin) === null || _event$origin === void 0 ? void 0 : _event$origin.touches) || (event === null || event === void 0 ? void 0 : event.touches);
|
|
18
|
+
if ((touches === null || touches === void 0 ? void 0 : touches.length) !== 1) return undefined;
|
|
19
|
+
return _objectSpread(_objectSpread({}, event === null || event === void 0 || (_event$touches = event.touches) === null || _event$touches === void 0 ? void 0 : _event$touches[0]), touches[0]);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Android-only visual compensation; native scrolling and vertical gesture arbitration stay native. */
|
|
23
|
+
export class AndroidBounceScrollImpl extends React.Component {
|
|
24
|
+
constructor(props) {
|
|
25
|
+
super(props);
|
|
26
|
+
this.state = {
|
|
27
|
+
offset: 0,
|
|
28
|
+
returning: false
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
componentDidMount() {
|
|
32
|
+
this.alive = true;
|
|
33
|
+
this.measure();
|
|
34
|
+
}
|
|
35
|
+
componentDidUpdate(previous) {
|
|
36
|
+
if (previous.children !== this.props.children) {
|
|
37
|
+
this.cancel();
|
|
38
|
+
this.measure();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
componentWillUnmount() {
|
|
42
|
+
this.alive = false;
|
|
43
|
+
this.measureId++;
|
|
44
|
+
this.press = undefined;
|
|
45
|
+
}
|
|
46
|
+
onHide = () => this.cancel();
|
|
47
|
+
id = (() => `half-drag-bounce-${++sequence}`)();
|
|
48
|
+
alive = false;
|
|
49
|
+
measureId = 0;
|
|
50
|
+
width = 0;
|
|
51
|
+
range = 0;
|
|
52
|
+
scrollLeft = 0;
|
|
53
|
+
moved = false;
|
|
54
|
+
measure = () => {
|
|
55
|
+
const request = ++this.measureId;
|
|
56
|
+
const query = createSelectorQuery();
|
|
57
|
+
let viewport = 0;
|
|
58
|
+
let content = 0;
|
|
59
|
+
query.select(`#${this.id}`).boundingClientRect(rect => {
|
|
60
|
+
viewport = (rect === null || rect === void 0 ? void 0 : rect.width) || 0;
|
|
61
|
+
});
|
|
62
|
+
query.select(`#${this.id}-track`).boundingClientRect(rect => {
|
|
63
|
+
content = (rect === null || rect === void 0 ? void 0 : rect.width) || 0;
|
|
64
|
+
});
|
|
65
|
+
query.exec(() => {
|
|
66
|
+
if (!this.alive || request !== this.measureId || viewport <= 0 || content <= 0) return;
|
|
67
|
+
this.width = viewport;
|
|
68
|
+
this.range = Math.max(0, content - viewport);
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
start = event => {
|
|
72
|
+
var _touch$clientX, _touch$clientY, _touch$identifier;
|
|
73
|
+
const touch = point(event);
|
|
74
|
+
if (!touch) {
|
|
75
|
+
this.cancel();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const x = (_touch$clientX = touch.clientX) !== null && _touch$clientX !== void 0 ? _touch$clientX : touch.pageX;
|
|
79
|
+
const y = (_touch$clientY = touch.clientY) !== null && _touch$clientY !== void 0 ? _touch$clientY : touch.pageY;
|
|
80
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) return;
|
|
81
|
+
this.moved = false;
|
|
82
|
+
this.press = {
|
|
83
|
+
identifier: (_touch$identifier = touch.identifier) !== null && _touch$identifier !== void 0 ? _touch$identifier : 0,
|
|
84
|
+
x,
|
|
85
|
+
y,
|
|
86
|
+
scrollLeft: this.scrollLeft
|
|
87
|
+
};
|
|
88
|
+
this.setState({
|
|
89
|
+
offset: 0,
|
|
90
|
+
returning: false
|
|
91
|
+
});
|
|
92
|
+
this.measure();
|
|
93
|
+
};
|
|
94
|
+
move = event => {
|
|
95
|
+
var _touch$identifier2, _touch$clientX2, _touch$clientY2;
|
|
96
|
+
const touch = point(event);
|
|
97
|
+
const {
|
|
98
|
+
press
|
|
99
|
+
} = this;
|
|
100
|
+
if (!touch || !press || ((_touch$identifier2 = touch.identifier) !== null && _touch$identifier2 !== void 0 ? _touch$identifier2 : 0) !== press.identifier) {
|
|
101
|
+
this.cancel();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const x = (_touch$clientX2 = touch.clientX) !== null && _touch$clientX2 !== void 0 ? _touch$clientX2 : touch.pageX;
|
|
105
|
+
const y = (_touch$clientY2 = touch.clientY) !== null && _touch$clientY2 !== void 0 ? _touch$clientY2 : touch.pageY;
|
|
106
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) return;
|
|
107
|
+
const dx = x - press.x;
|
|
108
|
+
const dy = y - press.y;
|
|
109
|
+
if (!press.axis) {
|
|
110
|
+
if (Math.max(Math.abs(dx), Math.abs(dy)) < 6) return;
|
|
111
|
+
this.moved = true;
|
|
112
|
+
press.axis = Math.abs(dx) > Math.abs(dy) * 1.2 ? 'x' : 'y';
|
|
113
|
+
}
|
|
114
|
+
if (press.axis !== 'x' || this.range <= 0) return;
|
|
115
|
+
const requested = press.scrollLeft - dx;
|
|
116
|
+
const overflow = requested < 0 ? -requested : requested > this.range ? this.range - requested : 0;
|
|
117
|
+
const offset = rubberBand(overflow, this.width);
|
|
118
|
+
if (offset !== this.state.offset || this.state.returning) {
|
|
119
|
+
this.setState({
|
|
120
|
+
offset,
|
|
121
|
+
returning: false
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
end = () => {
|
|
126
|
+
this.press = undefined;
|
|
127
|
+
if (this.alive) this.setState({
|
|
128
|
+
offset: 0,
|
|
129
|
+
returning: true
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
cancel = () => {
|
|
133
|
+
this.moved = true;
|
|
134
|
+
this.end();
|
|
135
|
+
};
|
|
136
|
+
guard = (callback, event) => {
|
|
137
|
+
// Reset on the next touchstart, rather than a timer that might reject a later intentional tap.
|
|
138
|
+
if (this.alive && !this.moved) callback === null || callback === void 0 || callback(event);
|
|
139
|
+
};
|
|
140
|
+
scroll = event => {
|
|
141
|
+
var _this$props$onScroll, _this$props;
|
|
142
|
+
this.scrollLeft = Math.max(0, event.detail.scrollLeft || 0);
|
|
143
|
+
(_this$props$onScroll = (_this$props = this.props).onScroll) === null || _this$props$onScroll === void 0 || _this$props$onScroll.call(_this$props, event);
|
|
144
|
+
};
|
|
145
|
+
render() {
|
|
146
|
+
const _this$props2 = this.props,
|
|
147
|
+
{
|
|
148
|
+
children
|
|
149
|
+
} = _this$props2,
|
|
150
|
+
props = _objectWithoutProperties(_this$props2, _excluded);
|
|
151
|
+
return /*#__PURE__*/React.createElement(ScrollView, _extends({}, props, {
|
|
152
|
+
id: this.id,
|
|
153
|
+
onScroll: this.scroll,
|
|
154
|
+
onTouchStart: this.start,
|
|
155
|
+
onTouchMove: this.move,
|
|
156
|
+
onTouchEnd: this.end,
|
|
157
|
+
onTouchCancel: this.cancel
|
|
158
|
+
}), children({
|
|
159
|
+
id: `${this.id}-track`,
|
|
160
|
+
style: {
|
|
161
|
+
transform: `translateX(${this.state.offset}px)`,
|
|
162
|
+
transitionProperty: 'transform',
|
|
163
|
+
transitionDuration: this.state.returning ? '260ms' : '0ms',
|
|
164
|
+
transitionTimingFunction: 'cubic-bezier(0.2, 0.75, 0.3, 1)'
|
|
165
|
+
}
|
|
166
|
+
}, this.guard));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Ray's older HOC declaration drops the wrapped component's props; runtime forwards them unchanged.
|
|
171
|
+
export const AndroidBounceScroll = withPageLifecycle(AndroidBounceScrollImpl);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
3
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
4
|
+
const _excluded = ["background"];
|
|
5
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { getSystemInfoSync, Image, ScrollView, Text, View } from '@ray-js/ray';
|
|
8
|
+
import clsx from 'clsx';
|
|
9
|
+
import styles from './index.module.less';
|
|
10
|
+
import { AndroidBounceScroll } from './android-bounce';
|
|
11
|
+
|
|
12
|
+
// Ray's newer host supports hideScrollbar; older supported Ray declarations omit it.
|
|
13
|
+
// Keep this native-only prop local rather than changing installed dependency types.
|
|
14
|
+
|
|
15
|
+
const LynxScrollView = ScrollView;
|
|
16
|
+
const isText = value => typeof value === 'string' || typeof value === 'number';
|
|
17
|
+
|
|
18
|
+
// Keep gradients on the explicit property: this build chain drops background shorthand gradients.
|
|
19
|
+
const getBackgroundStyle = function () {
|
|
20
|
+
let style = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
21
|
+
const {
|
|
22
|
+
background
|
|
23
|
+
} = style,
|
|
24
|
+
rest = _objectWithoutProperties(style, _excluded);
|
|
25
|
+
if (typeof background === 'string' && background.includes('gradient(')) {
|
|
26
|
+
return _objectSpread(_objectSpread({}, rest), {}, {
|
|
27
|
+
backgroundImage: background.trim().replace(/;$/, '')
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return style;
|
|
31
|
+
};
|
|
32
|
+
const LynxHalfHorizontalDrag = _ref => {
|
|
33
|
+
let {
|
|
34
|
+
data,
|
|
35
|
+
className,
|
|
36
|
+
style,
|
|
37
|
+
showCloseBtn = false,
|
|
38
|
+
closeBtnTitle = 'Close',
|
|
39
|
+
closeBtnIcon,
|
|
40
|
+
onCloseClick,
|
|
41
|
+
onScroll
|
|
42
|
+
} = _ref;
|
|
43
|
+
if (!data || data.length === 0) return null;
|
|
44
|
+
// Keep iOS on its existing CSS path; Android hosts may not draw CSS URL backgrounds.
|
|
45
|
+
const useImageBackground = getSystemInfoSync().platform === 'android';
|
|
46
|
+
const scrollable = data.length >= 3 || showCloseBtn;
|
|
47
|
+
const renderTrack = (trackProps, guard) => /*#__PURE__*/React.createElement(View, _extends({}, trackProps, {
|
|
48
|
+
className: clsx(styles.track, !scrollable && styles.staticTrack)
|
|
49
|
+
}), data.map((item, index) => {
|
|
50
|
+
var _item$style;
|
|
51
|
+
const hasImageBackground = useImageBackground && !!item.backgroundImage;
|
|
52
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
53
|
+
key: index // eslint-disable-line react/no-array-index-key
|
|
54
|
+
,
|
|
55
|
+
className: clsx(styles.item, scrollable ? styles.scrollingItem : styles.staticItem, data.length === 1 && scrollable && styles.singleScrollingItem, index === 0 && styles.firstItem, index === data.length - 1 && !showCloseBtn && styles.lastItem, item.className),
|
|
56
|
+
style: getBackgroundStyle(_objectSpread(_objectSpread({}, item.style), {}, {
|
|
57
|
+
backgroundImage: item.backgroundImage && !hasImageBackground ? `url(${item.backgroundImage})` : undefined,
|
|
58
|
+
background: item.background || undefined
|
|
59
|
+
}, hasImageBackground ? {
|
|
60
|
+
zIndex: 0
|
|
61
|
+
} : {})),
|
|
62
|
+
onClick: guard ? event => guard(item.onClick, event) : item.onClick
|
|
63
|
+
}, hasImageBackground && /*#__PURE__*/React.createElement(Image, {
|
|
64
|
+
src: item.backgroundImage,
|
|
65
|
+
mode: "aspectFill",
|
|
66
|
+
className: styles.backgroundImage,
|
|
67
|
+
style: ((_item$style = item.style) === null || _item$style === void 0 ? void 0 : _item$style.borderRadius) !== undefined ? {
|
|
68
|
+
borderRadius: item.style.borderRadius
|
|
69
|
+
} : undefined
|
|
70
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
71
|
+
className: styles.icon
|
|
72
|
+
}, item.icon), /*#__PURE__*/React.createElement(View, {
|
|
73
|
+
className: styles.title
|
|
74
|
+
}, isText(item.title) ? /*#__PURE__*/React.createElement(Text, {
|
|
75
|
+
className: styles.titleText,
|
|
76
|
+
"text-maxline": 2
|
|
77
|
+
}, item.title) : item.title), !!item.tag && /*#__PURE__*/React.createElement(View, {
|
|
78
|
+
className: clsx(styles.tag, item.tagClassName),
|
|
79
|
+
style: getBackgroundStyle(item.tagStyle)
|
|
80
|
+
}, isText(item.tag) ? /*#__PURE__*/React.createElement(Text, {
|
|
81
|
+
className: styles.tagText,
|
|
82
|
+
"text-maxline": 1
|
|
83
|
+
}, item.tag) : item.tag));
|
|
84
|
+
}), showCloseBtn && /*#__PURE__*/React.createElement(View, {
|
|
85
|
+
className: styles.closeBtn,
|
|
86
|
+
onClick: guard ? event => guard(onCloseClick, event) : onCloseClick
|
|
87
|
+
}, closeBtnIcon, isText(closeBtnTitle) ? /*#__PURE__*/React.createElement(Text, {
|
|
88
|
+
className: styles.closeText
|
|
89
|
+
}, closeBtnTitle) : closeBtnTitle));
|
|
90
|
+
const scrollProps = {
|
|
91
|
+
className: styles.viewport,
|
|
92
|
+
scrollX: scrollable,
|
|
93
|
+
scrollY: false,
|
|
94
|
+
hideScrollbar: true,
|
|
95
|
+
onScroll
|
|
96
|
+
};
|
|
97
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
98
|
+
className: clsx(styles.root, className),
|
|
99
|
+
style: style
|
|
100
|
+
}, useImageBackground && scrollable ? /*#__PURE__*/React.createElement(AndroidBounceScroll, scrollProps, renderTrack) : /*#__PURE__*/React.createElement(LynxScrollView, scrollProps, renderTrack()));
|
|
101
|
+
};
|
|
102
|
+
export default LynxHalfHorizontalDrag;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// Only used by the explicit Lynx renderer. Legacy CSS is kept byte-for-byte.
|
|
2
|
+
.root {
|
|
3
|
+
--half-drag-height: 110rpx;
|
|
4
|
+
--half-drag-tag-inset: 20rpx;
|
|
5
|
+
--half-drag-item-width: 336rpx;
|
|
6
|
+
--half-drag-single-width: 686rpx;
|
|
7
|
+
--half-drag-side: 32rpx;
|
|
8
|
+
--half-drag-gap: 12rpx;
|
|
9
|
+
--half-drag-close-gap: 14rpx;
|
|
10
|
+
--half-drag-radius: 32rpx;
|
|
11
|
+
--half-drag-icon-size: 48rpx;
|
|
12
|
+
--half-drag-title-gap: 24rpx;
|
|
13
|
+
--half-drag-font-size: 28rpx;
|
|
14
|
+
--half-drag-line-height: 40rpx;
|
|
15
|
+
width: 100%;
|
|
16
|
+
min-width: 0;
|
|
17
|
+
height: var(--half-drag-height);
|
|
18
|
+
box-sizing: content-box;
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
padding-top: 48rpx;
|
|
22
|
+
}
|
|
23
|
+
.viewport {
|
|
24
|
+
width: 100%;
|
|
25
|
+
height: calc(var(--half-drag-height) + var(--half-drag-tag-inset));
|
|
26
|
+
margin-top: calc(0px - var(--half-drag-tag-inset));
|
|
27
|
+
flex-shrink: 0;
|
|
28
|
+
}
|
|
29
|
+
.track {
|
|
30
|
+
overflow: visible;
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: row;
|
|
33
|
+
align-items: center;
|
|
34
|
+
align-self: flex-start;
|
|
35
|
+
flex-shrink: 0;
|
|
36
|
+
height: calc(var(--half-drag-height) + var(--half-drag-tag-inset));
|
|
37
|
+
padding-top: var(--half-drag-tag-inset);
|
|
38
|
+
box-sizing: border-box;
|
|
39
|
+
}
|
|
40
|
+
.staticTrack {
|
|
41
|
+
width: 100%;
|
|
42
|
+
}
|
|
43
|
+
.item {
|
|
44
|
+
overflow: visible;
|
|
45
|
+
position: relative;
|
|
46
|
+
flex-shrink: 0;
|
|
47
|
+
height: var(--half-drag-height);
|
|
48
|
+
border-radius: var(--half-drag-radius);
|
|
49
|
+
display: flex;
|
|
50
|
+
flex-direction: row;
|
|
51
|
+
align-items: center;
|
|
52
|
+
padding: 0 40rpx;
|
|
53
|
+
box-sizing: border-box;
|
|
54
|
+
color: #000;
|
|
55
|
+
background-color: #fff;
|
|
56
|
+
background-size: cover;
|
|
57
|
+
background-repeat: no-repeat;
|
|
58
|
+
background-position: center;
|
|
59
|
+
}
|
|
60
|
+
.scrollingItem {
|
|
61
|
+
width: var(--half-drag-item-width);
|
|
62
|
+
margin-left: var(--half-drag-gap);
|
|
63
|
+
}
|
|
64
|
+
.backgroundImage {
|
|
65
|
+
position: absolute;
|
|
66
|
+
top: 0;
|
|
67
|
+
left: 0;
|
|
68
|
+
width: 100%;
|
|
69
|
+
height: 100%;
|
|
70
|
+
border-radius: var(--half-drag-radius);
|
|
71
|
+
z-index: -1;
|
|
72
|
+
pointer-events: none;
|
|
73
|
+
}
|
|
74
|
+
.singleScrollingItem {
|
|
75
|
+
width: var(--half-drag-single-width);
|
|
76
|
+
}
|
|
77
|
+
.staticItem {
|
|
78
|
+
flex: 1;
|
|
79
|
+
min-width: 0;
|
|
80
|
+
margin-left: var(--half-drag-side);
|
|
81
|
+
}
|
|
82
|
+
.firstItem {
|
|
83
|
+
margin-left: var(--half-drag-side);
|
|
84
|
+
}
|
|
85
|
+
.lastItem {
|
|
86
|
+
margin-right: var(--half-drag-side);
|
|
87
|
+
}
|
|
88
|
+
.icon {
|
|
89
|
+
width: var(--half-drag-icon-size);
|
|
90
|
+
height: var(--half-drag-icon-size);
|
|
91
|
+
flex-shrink: 0;
|
|
92
|
+
display: flex;
|
|
93
|
+
align-items: center;
|
|
94
|
+
justify-content: center;
|
|
95
|
+
}
|
|
96
|
+
.title {
|
|
97
|
+
flex: 1;
|
|
98
|
+
min-width: 0;
|
|
99
|
+
margin-left: var(--half-drag-title-gap);
|
|
100
|
+
overflow: hidden;
|
|
101
|
+
font-size: var(--half-drag-font-size);
|
|
102
|
+
line-height: var(--half-drag-line-height);
|
|
103
|
+
}
|
|
104
|
+
.titleText {
|
|
105
|
+
width: 100%;
|
|
106
|
+
max-height: calc(var(--half-drag-line-height) + var(--half-drag-line-height));
|
|
107
|
+
font-size: var(--half-drag-font-size);
|
|
108
|
+
line-height: var(--half-drag-line-height);
|
|
109
|
+
white-space: normal;
|
|
110
|
+
overflow: hidden;
|
|
111
|
+
text-overflow: ellipsis;
|
|
112
|
+
}
|
|
113
|
+
.tag {
|
|
114
|
+
position: absolute;
|
|
115
|
+
right: -6rpx;
|
|
116
|
+
top: calc(0px - var(--half-drag-tag-inset));
|
|
117
|
+
height: 40rpx;
|
|
118
|
+
line-height: 40rpx;
|
|
119
|
+
border-radius: 40rpx;
|
|
120
|
+
border-bottom-right-radius: 0;
|
|
121
|
+
padding: 0 20rpx;
|
|
122
|
+
font-size: 24rpx;
|
|
123
|
+
font-weight: 600;
|
|
124
|
+
background-color: #ebebeb;
|
|
125
|
+
background-image: linear-gradient(345deg, #b2b0b0 1%, #ebebeb 100%);
|
|
126
|
+
color: rgba(0, 0, 0, 0.4);
|
|
127
|
+
max-width: 128rpx;
|
|
128
|
+
white-space: nowrap;
|
|
129
|
+
overflow: hidden;
|
|
130
|
+
}
|
|
131
|
+
.tagText {
|
|
132
|
+
max-width: 128rpx;
|
|
133
|
+
height: 40rpx;
|
|
134
|
+
line-height: 40rpx;
|
|
135
|
+
font-size: 24rpx;
|
|
136
|
+
white-space: nowrap;
|
|
137
|
+
overflow: hidden;
|
|
138
|
+
text-overflow: ellipsis;
|
|
139
|
+
}
|
|
140
|
+
.closeText {
|
|
141
|
+
font-size: var(--half-drag-font-size);
|
|
142
|
+
white-space: nowrap;
|
|
143
|
+
}
|
|
144
|
+
.closeBtn {
|
|
145
|
+
height: var(--half-drag-height);
|
|
146
|
+
flex-shrink: 0;
|
|
147
|
+
display: flex;
|
|
148
|
+
flex-direction: row;
|
|
149
|
+
align-items: center;
|
|
150
|
+
justify-content: center;
|
|
151
|
+
margin-left: var(--half-drag-close-gap);
|
|
152
|
+
margin-right: var(--half-drag-side);
|
|
153
|
+
border-radius: var(--half-drag-radius);
|
|
154
|
+
color: #f04c4c;
|
|
155
|
+
background-color: rgba(240, 76, 76, 0.2);
|
|
156
|
+
padding: 0 32rpx;
|
|
157
|
+
font-size: var(--half-drag-font-size);
|
|
158
|
+
font-weight: 500;
|
|
159
|
+
}
|
|
160
|
+
@media (min-width: 600px) {
|
|
161
|
+
.root {
|
|
162
|
+
--half-drag-height: 55px;
|
|
163
|
+
--half-drag-tag-inset: 10px;
|
|
164
|
+
--half-drag-item-width: 168px;
|
|
165
|
+
--half-drag-single-width: 343px;
|
|
166
|
+
--half-drag-side: 16px;
|
|
167
|
+
--half-drag-gap: 6px;
|
|
168
|
+
--half-drag-close-gap: 7px;
|
|
169
|
+
--half-drag-radius: 16px;
|
|
170
|
+
--half-drag-icon-size: 24px;
|
|
171
|
+
--half-drag-title-gap: 12px;
|
|
172
|
+
--half-drag-font-size: 16px;
|
|
173
|
+
--half-drag-line-height: 20px;
|
|
174
|
+
padding-top: 24px;
|
|
175
|
+
}
|
|
176
|
+
.item {
|
|
177
|
+
padding: 0 20px;
|
|
178
|
+
}
|
|
179
|
+
.tag {
|
|
180
|
+
right: -3px;
|
|
181
|
+
height: 20px;
|
|
182
|
+
line-height: 20px;
|
|
183
|
+
padding: 0 10px;
|
|
184
|
+
font-size: 14px;
|
|
185
|
+
max-width: 64px;
|
|
186
|
+
}
|
|
187
|
+
.tagText {
|
|
188
|
+
max-width: 64px;
|
|
189
|
+
height: 20px;
|
|
190
|
+
line-height: 20px;
|
|
191
|
+
font-size: 14px;
|
|
192
|
+
}
|
|
193
|
+
.closeBtn {
|
|
194
|
+
padding: 0 16px;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
@media (min-width: 920px) {
|
|
198
|
+
.root {
|
|
199
|
+
--half-drag-font-size: 18px;
|
|
200
|
+
}
|
|
201
|
+
.tag {
|
|
202
|
+
font-size: 16px;
|
|
203
|
+
}
|
|
204
|
+
.tagText {
|
|
205
|
+
font-size: 16px;
|
|
206
|
+
}
|
|
207
|
+
}
|
package/lib/props.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { ScrollView } from '@ray-js/ray';
|
|
2
3
|
export type Data = {
|
|
3
|
-
title:
|
|
4
|
+
title: React.ReactNode;
|
|
4
5
|
backgroundImage?: string;
|
|
5
6
|
background?: string;
|
|
6
7
|
icon?: React.ReactNode;
|
|
@@ -12,6 +13,10 @@ export type Data = {
|
|
|
12
13
|
onClick?: () => void;
|
|
13
14
|
};
|
|
14
15
|
export interface IProps {
|
|
16
|
+
/** Explicit page renderer; defaults to the unchanged WebView implementation. */
|
|
17
|
+
renderMode?: 'webview' | 'lynx';
|
|
18
|
+
/** Lynx horizontal ScrollView event, used for integration diagnostics. */
|
|
19
|
+
onScroll?: React.ComponentProps<typeof ScrollView>['onScroll'];
|
|
15
20
|
/**
|
|
16
21
|
* @description.zh 数据
|
|
17
22
|
* @description.en datas
|
package/lib/webview.d.ts
ADDED
package/lib/webview.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { View } from '@ray-js/ray';
|
|
5
|
+
import clsx from 'clsx';
|
|
6
|
+
import styles from './index.module.less';
|
|
7
|
+
const NILL = () => null;
|
|
8
|
+
const HalfHorizontalDrag = props => {
|
|
9
|
+
const {
|
|
10
|
+
className,
|
|
11
|
+
style,
|
|
12
|
+
data,
|
|
13
|
+
showCloseBtn,
|
|
14
|
+
onCloseClick = NILL,
|
|
15
|
+
closeBtnTitle = 'Close',
|
|
16
|
+
closeBtnIcon
|
|
17
|
+
} = props;
|
|
18
|
+
const renderCloseBtn = () => {
|
|
19
|
+
if (!showCloseBtn) return null;
|
|
20
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
21
|
+
className: styles.closeBtn,
|
|
22
|
+
onClick: onCloseClick
|
|
23
|
+
}, closeBtnIcon, closeBtnTitle);
|
|
24
|
+
};
|
|
25
|
+
if (!data || !data.length) return null;
|
|
26
|
+
if (data.length === 1) {
|
|
27
|
+
const item = data[0];
|
|
28
|
+
const {
|
|
29
|
+
tag,
|
|
30
|
+
tagStyle,
|
|
31
|
+
tagClassName,
|
|
32
|
+
title,
|
|
33
|
+
onClick = NILL
|
|
34
|
+
} = item || {};
|
|
35
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
36
|
+
className: clsx(styles.content, className, {
|
|
37
|
+
[styles.moreContent]: showCloseBtn
|
|
38
|
+
}),
|
|
39
|
+
style: _objectSpread({}, style)
|
|
40
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
41
|
+
style: _objectSpread(_objectSpread({}, item.style), {}, {
|
|
42
|
+
backgroundImage: item.backgroundImage ? `url(${item.backgroundImage})` : undefined,
|
|
43
|
+
background: item.background || undefined
|
|
44
|
+
}),
|
|
45
|
+
className: clsx(styles.one_data_item, styles.item, item.className, {
|
|
46
|
+
[styles.one_data_item_width]: showCloseBtn
|
|
47
|
+
}),
|
|
48
|
+
onClick: onClick
|
|
49
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
50
|
+
className: styles.icon
|
|
51
|
+
}, item.icon), /*#__PURE__*/React.createElement(View, {
|
|
52
|
+
className: styles.title
|
|
53
|
+
}, title), !!tag && /*#__PURE__*/React.createElement(View, {
|
|
54
|
+
style: _objectSpread({}, tagStyle),
|
|
55
|
+
className: clsx(styles.tag, tagClassName)
|
|
56
|
+
}, tag)), renderCloseBtn());
|
|
57
|
+
}
|
|
58
|
+
if (data.length === 2) {
|
|
59
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
60
|
+
className: clsx(styles.content, styles.towContent, className, {
|
|
61
|
+
[styles.moreContent]: showCloseBtn
|
|
62
|
+
}),
|
|
63
|
+
style: _objectSpread({}, style)
|
|
64
|
+
}, data.map((item, idx) => {
|
|
65
|
+
const {
|
|
66
|
+
title,
|
|
67
|
+
tag,
|
|
68
|
+
tagStyle,
|
|
69
|
+
tagClassName,
|
|
70
|
+
onClick = NILL
|
|
71
|
+
} = item;
|
|
72
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
73
|
+
key: idx // eslint-disable-line
|
|
74
|
+
,
|
|
75
|
+
style: _objectSpread(_objectSpread({}, item.style), {}, {
|
|
76
|
+
backgroundImage: item.backgroundImage ? `url(${item.backgroundImage})` : undefined,
|
|
77
|
+
background: item.background || undefined
|
|
78
|
+
}),
|
|
79
|
+
onClick: onClick,
|
|
80
|
+
className: clsx(styles.two_data_item, styles.item, item.className, {
|
|
81
|
+
[styles.two_data_item_width]: showCloseBtn
|
|
82
|
+
})
|
|
83
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
84
|
+
className: styles.icon
|
|
85
|
+
}, item.icon), /*#__PURE__*/React.createElement(View, {
|
|
86
|
+
className: styles.title
|
|
87
|
+
}, title), !!tag && /*#__PURE__*/React.createElement(View, {
|
|
88
|
+
style: _objectSpread({}, tagStyle),
|
|
89
|
+
className: clsx(styles.tag, tagClassName)
|
|
90
|
+
}, tag));
|
|
91
|
+
}), renderCloseBtn());
|
|
92
|
+
}
|
|
93
|
+
if (data.length >= 3) {
|
|
94
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
95
|
+
className: clsx(styles.content, styles.moreContent, className),
|
|
96
|
+
style: _objectSpread({}, style)
|
|
97
|
+
}, data.map((item, idx) => {
|
|
98
|
+
const {
|
|
99
|
+
title,
|
|
100
|
+
tag,
|
|
101
|
+
tagStyle,
|
|
102
|
+
tagClassName,
|
|
103
|
+
onClick = NILL
|
|
104
|
+
} = item;
|
|
105
|
+
return /*#__PURE__*/React.createElement(View
|
|
106
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
107
|
+
, {
|
|
108
|
+
key: idx,
|
|
109
|
+
style: _objectSpread(_objectSpread({}, item.style), {}, {
|
|
110
|
+
backgroundImage: item.backgroundImage ? `url(${item.backgroundImage})` : undefined,
|
|
111
|
+
background: item.background || undefined
|
|
112
|
+
}),
|
|
113
|
+
className: clsx(styles.item, styles.more_data_item, item.className),
|
|
114
|
+
onClick: onClick
|
|
115
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
116
|
+
className: styles.icon
|
|
117
|
+
}, item.icon), /*#__PURE__*/React.createElement(View, {
|
|
118
|
+
className: styles.title
|
|
119
|
+
}, title), !!tag && /*#__PURE__*/React.createElement(View, {
|
|
120
|
+
style: _objectSpread({}, tagStyle),
|
|
121
|
+
className: clsx(styles.tag, tagClassName)
|
|
122
|
+
}, tag));
|
|
123
|
+
}), renderCloseBtn());
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
};
|
|
127
|
+
HalfHorizontalDrag.displayName = 'HalfHorizontalDrag';
|
|
128
|
+
export {};
|
|
129
|
+
export default HalfHorizontalDrag;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ray-js/ray-ipc-half-horizontal-drag",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7-beta.1",
|
|
4
4
|
"description": "水平方向可拖动,显示出下一个组件的小部分内容",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"files": [
|
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
"start:wechat": "ray start ./example -t wechat --verbose",
|
|
29
29
|
"start:web": "ray start ./example -t web",
|
|
30
30
|
"prepublishOnly": "yarn build",
|
|
31
|
-
"release-it": "standard-version"
|
|
31
|
+
"release-it": "standard-version",
|
|
32
|
+
"test": "node --test tests/render-mode.test.cjs",
|
|
33
|
+
"typecheck": "tsc --noEmit"
|
|
32
34
|
},
|
|
33
35
|
"peerDependencies": {
|
|
34
36
|
"@ray-js/ray": "^1.4.9"
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
"@commitlint/cli": "^7.2.1",
|
|
42
44
|
"@commitlint/config-conventional": "^9.0.1",
|
|
43
45
|
"@ray-js/cli": "^1.4.9",
|
|
44
|
-
"@ray-js/panel-sdk": "^1.
|
|
46
|
+
"@ray-js/panel-sdk": "^1.16.1",
|
|
45
47
|
"@ray-js/ray": "^1.4.9",
|
|
46
48
|
"core-js": "^3.19.1",
|
|
47
49
|
"eslint-config-tuya-panel": "^0.4.2",
|