@doubao-apps/taro-runtime 0.0.18 → 0.0.19
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/dist/api/base/index.d.ts +12 -0
- package/dist/api/base/index.js +13 -1
- package/dist/api/create-selector-query/index.d.ts +3 -0
- package/dist/api/create-selector-query/index.js +577 -0
- package/dist/api/index.d.ts +7 -3
- package/dist/api/index.js +7 -3
- package/dist/api/location/index.d.ts +10 -0
- package/dist/api/location/index.js +77 -0
- package/dist/api/map/index.js +28 -30
- package/dist/api/request/index.js +8 -18
- package/dist/api/router/index.d.ts +4 -0
- package/dist/api/router/index.js +4 -0
- package/dist/api/router/navigate-back.d.ts +5 -0
- package/dist/api/router/navigate-back.js +20 -0
- package/dist/api/{navigate/index.d.ts → router/navigate-to.d.ts} +2 -2
- package/dist/api/{navigate/index.js → router/navigate-to.js} +7 -7
- package/dist/api/router/redirect-to.d.ts +5 -0
- package/dist/api/router/redirect-to.js +22 -0
- package/dist/api/show-toast/index.d.ts +6 -0
- package/dist/api/show-toast/index.js +39 -0
- package/dist/api/storage/index.d.ts +16 -0
- package/dist/api/storage/index.js +55 -0
- package/dist/api/system/index.d.ts +12 -0
- package/dist/api/system/index.js +40 -10
- package/dist/api/utils.d.ts +21 -0
- package/dist/api/utils.js +65 -0
- package/dist/components/Image/index.d.ts +2 -1
- package/dist/components/Image/index.jsx +3 -2
- package/dist/components/Input/index.d.ts +3 -5
- package/dist/components/Input/index.jsx +50 -3
- package/dist/components/Input/map.d.ts +50 -0
- package/dist/components/Input/map.js +226 -0
- package/dist/components/Map/bridge.d.ts +32 -4
- package/dist/components/Map/bridge.js +224 -13
- package/dist/components/Map/index.jsx +78 -58
- package/dist/components/Map/mapping.d.ts +71 -3
- package/dist/components/Map/mapping.js +0 -15
- package/dist/components/PickerView/index.d.ts +8 -0
- package/dist/components/PickerView/index.jsx +47 -0
- package/dist/components/PickerView/map.d.ts +36 -0
- package/dist/components/PickerView/map.js +29 -0
- package/dist/components/Radio/index.d.ts +5 -0
- package/dist/components/Radio/index.jsx +82 -0
- package/dist/components/Radio/map.d.ts +38 -0
- package/dist/components/Radio/map.js +109 -0
- package/dist/components/Radio/shared.d.ts +7 -0
- package/dist/components/Radio/shared.js +9 -0
- package/dist/components/RadioGroup/context.d.ts +11 -0
- package/dist/components/RadioGroup/context.js +3 -0
- package/dist/components/RadioGroup/index.d.ts +3 -0
- package/dist/components/RadioGroup/index.jsx +80 -0
- package/dist/components/RadioGroup/map.d.ts +44 -0
- package/dist/components/RadioGroup/map.js +109 -0
- package/dist/components/WebView/index.d.ts +3 -0
- package/dist/components/WebView/index.jsx +24 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +4 -0
- package/dist/exports/app-core.d.ts +1 -1
- package/dist/exports/app-core.js +1 -1
- package/dist/exports/view-core.d.ts +1 -1
- package/dist/exports/view-core.js +1 -1
- package/dist/internal/map-context/index.d.ts +7 -1
- package/package.json +1 -1
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import { useEffect, useRef } from '@byted-doubao-apps/framework';
|
|
1
|
+
import { useEffect, useRef, useState } from '@byted-doubao-apps/framework';
|
|
2
2
|
import { registerMapController, unregisterMapController } from '../../internal/map-context/index.js';
|
|
3
3
|
import { Image } from '../Image/index.jsx';
|
|
4
4
|
import { warnUnsupported } from '../base/warn-unsupported.js';
|
|
5
|
-
import { dispatchMarkerTapEvent, mapMarkerToNativeProps, resolvePadding } from './bridge.js';
|
|
5
|
+
import { composeMarkers, createMarkerElementProps, dispatchMarkerTapEvent, getNumericMarkerId, hasByClickCallout, hasTapTitle, mapMarkerToNativeProps, mergeMarkersById, removeMarkersByIds, resolveMarkerIconStyle, resolveMarkerTextContent, shouldAutoSizeMarkerIcon, resolvePadding } from './bridge.js';
|
|
6
6
|
import { collectMapUnsupportedWarnings, createMapElementProps, resolveMapValues, toCommonEvent } from './mapping.js';
|
|
7
7
|
export function Map(props) {
|
|
8
8
|
const { id, className, style, hidden, animation, children, onTouchStart, onTouchMove, onTouchCancel, onTouchEnd, onClick: onBaseClick, onLongPress, onLongClick, onTransitionEnd, onAnimationStart, onAnimationIteration, onAnimationEnd, longitude, latitude, scale, minScale, maxScale, markers, covers, polyline, circles, controls, includePoints, showLocation, polygons, subkey, layerStyle, rotate, skew, showCompass, showScale, enableOverlooking, enableZoom, enableScroll, enableRotate, enableSatellite, enableTraffic, setting, includePadding, groundOverlays, tileOverlay, enablePoi, enableBuilding, polygon, customMapStyle, panels, theme, optimize, enableAutoMaxOverlooking, enable3D, onTap, onMarkerTap, onLabelTap, onControlTap, onCalloutTap, onUpdated, onRegionChange, onPoiTap, onPolylineTap, onAbilitySuccess, onAbilityFailed, onAuthSuccess, onInterpolatePoint, onError, onCallOutTap, onAnchorPointTap, onPanelTap, onInitComplete, ...rest } = props;
|
|
9
9
|
const mapRef = useRef(null);
|
|
10
10
|
const mapControllerRef = useRef(null);
|
|
11
|
+
const [activeCalloutMarkerId, setActiveCalloutMarkerId] = useState(undefined);
|
|
12
|
+
const [imperativeAddedMarkers, setImperativeAddedMarkers] = useState([]);
|
|
13
|
+
const [imperativeRemovedMarkerIds, setImperativeRemovedMarkerIds] = useState([]);
|
|
11
14
|
const { resolvedSetting, resolvedScale, resolvedMinScale, resolvedMaxScale, resolvedRotate, resolvedShowScale, resolvedEnableTilt, resolvedEnableScale, resolvedEnableDrag, resolvedEnableRotate, resolvedMarkers, resolvedPolygons, resolvedMapStyle } = resolveMapValues({
|
|
12
15
|
setting,
|
|
13
16
|
scale,
|
|
@@ -27,7 +30,11 @@ export function Map(props) {
|
|
|
27
30
|
});
|
|
28
31
|
const mapId = id ? String(id) : '';
|
|
29
32
|
if (!mapControllerRef.current) {
|
|
30
|
-
mapControllerRef.current = createMapController(
|
|
33
|
+
mapControllerRef.current = createMapController({
|
|
34
|
+
mapRef,
|
|
35
|
+
setImperativeAddedMarkers,
|
|
36
|
+
setImperativeRemovedMarkerIds
|
|
37
|
+
});
|
|
31
38
|
}
|
|
32
39
|
const unsupported = collectMapUnsupportedWarnings({
|
|
33
40
|
unsupportedValues: {
|
|
@@ -136,79 +143,92 @@ export function Map(props) {
|
|
|
136
143
|
onLabelTap !== undefined ||
|
|
137
144
|
onCalloutTap !== undefined ||
|
|
138
145
|
onCallOutTap !== undefined;
|
|
146
|
+
const renderMarkers = composeMarkers(resolvedMarkers, imperativeAddedMarkers, imperativeRemovedMarkerIds);
|
|
139
147
|
return (<map {...mapElementProps}>
|
|
140
|
-
{
|
|
148
|
+
{renderMarkers.map((marker, index) => {
|
|
141
149
|
const nativeMarker = mapMarkerToNativeProps(marker, index);
|
|
150
|
+
const markerId = nativeMarker.markerId;
|
|
142
151
|
const markerTapEvent = toCommonEvent({
|
|
143
|
-
markerId
|
|
152
|
+
markerId
|
|
144
153
|
}, 'markertap', mapId);
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
draggable: marker.draggable,
|
|
155
|
-
onClick: shouldDispatchMarkerTap
|
|
156
|
-
? () => {
|
|
154
|
+
const shouldActivateByClickCallout = hasByClickCallout(marker);
|
|
155
|
+
const shouldActivateTitle = hasTapTitle(marker);
|
|
156
|
+
const shouldActivateMarkerText = shouldActivateByClickCallout || shouldActivateTitle;
|
|
157
|
+
const handleMarkerClick = shouldDispatchMarkerTap || shouldActivateMarkerText
|
|
158
|
+
? () => {
|
|
159
|
+
if (shouldActivateMarkerText) {
|
|
160
|
+
setActiveCalloutMarkerId(markerId);
|
|
161
|
+
}
|
|
162
|
+
if (shouldDispatchMarkerTap) {
|
|
157
163
|
dispatchMarkerTapEvent(markerTapHandlers, markerTapEvent);
|
|
158
164
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}}/>
|
|
172
|
-
</view>
|
|
173
|
-
</map-marker>);
|
|
165
|
+
}
|
|
166
|
+
: undefined;
|
|
167
|
+
const markerElementProps = createMarkerElementProps({
|
|
168
|
+
nativeMarker,
|
|
169
|
+
onClick: handleMarkerClick
|
|
170
|
+
});
|
|
171
|
+
const markerContent = marker.children !== undefined
|
|
172
|
+
? marker.children
|
|
173
|
+
: renderDefaultMarkerContent(marker, markerId, activeCalloutMarkerId);
|
|
174
|
+
return (
|
|
175
|
+
// biome-ignore lint: key is not sure
|
|
176
|
+
<map-marker {...markerElementProps}>{markerContent}</map-marker>);
|
|
174
177
|
})}
|
|
175
178
|
{children}
|
|
176
179
|
</map>);
|
|
177
180
|
}
|
|
178
|
-
function
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
padding: bubble?.padding ?? 6,
|
|
187
|
-
color: bubble?.color ?? '#222222',
|
|
188
|
-
backgroundColor: bubble?.bgColor ?? '#ffffff',
|
|
189
|
-
borderRadius: bubble?.borderRadius ?? 8,
|
|
190
|
-
borderWidth: bubble?.borderWidth ?? 0,
|
|
191
|
-
borderColor: bubble?.borderColor ?? 'transparent',
|
|
192
|
-
fontSize: bubble?.fontSize ?? 12,
|
|
193
|
-
textAlign: bubble?.textAlign ?? 'center',
|
|
194
|
-
maxWidth: 240
|
|
181
|
+
function renderDefaultMarkerContent(marker, markerId, activeCalloutMarkerId) {
|
|
182
|
+
const textContent = resolveMarkerTextContent(marker, markerId, activeCalloutMarkerId);
|
|
183
|
+
const iconStyle = resolveMarkerIconStyle(marker);
|
|
184
|
+
const shouldAutoSizeIcon = shouldAutoSizeMarkerIcon(marker);
|
|
185
|
+
return (<view style={{
|
|
186
|
+
display: 'flex',
|
|
187
|
+
flexDirection: 'column',
|
|
188
|
+
alignItems: 'center'
|
|
195
189
|
}}>
|
|
196
|
-
{content}
|
|
197
|
-
|
|
190
|
+
{textContent.callout ? (<text style={textContent.callout.style}>{textContent.callout.content}</text>) : null}
|
|
191
|
+
{textContent.label ? <text style={textContent.label.style}>{textContent.label.content}</text> : null}
|
|
192
|
+
{textContent.title ? <text style={textContent.title.style}>{textContent.title.content}</text> : null}
|
|
193
|
+
<Image src={marker.iconPath} style={iconStyle} autoSize={shouldAutoSizeIcon}/>
|
|
194
|
+
</view>);
|
|
198
195
|
}
|
|
199
|
-
function createMapController(
|
|
196
|
+
function createMapController(options) {
|
|
200
197
|
return {
|
|
201
|
-
getCenter: () => getMapInstance(mapRef).getCenter(),
|
|
198
|
+
getCenter: () => getMapInstance(options.mapRef).getCenter(),
|
|
202
199
|
setCenter: (center, scaleValue) => {
|
|
203
|
-
getMapInstance(mapRef).setCenter(center, scaleValue);
|
|
200
|
+
getMapInstance(options.mapRef).setCenter(center, scaleValue);
|
|
204
201
|
},
|
|
205
|
-
getScale: () => getMapInstance(mapRef).getScale(),
|
|
206
|
-
getBound: () => getMapInstance(mapRef).getBound(),
|
|
202
|
+
getScale: () => getMapInstance(options.mapRef).getScale(),
|
|
203
|
+
getBound: () => getMapInstance(options.mapRef).getBound(),
|
|
207
204
|
fitPoints: (points, padding) => {
|
|
208
|
-
getMapInstance(mapRef).fitPoints(points, padding);
|
|
205
|
+
getMapInstance(options.mapRef).fitPoints(points, padding);
|
|
209
206
|
},
|
|
210
207
|
setAnchor: (position) => {
|
|
211
|
-
getMapInstance(mapRef).setAnchor(position);
|
|
208
|
+
getMapInstance(options.mapRef).setAnchor(position);
|
|
209
|
+
},
|
|
210
|
+
addMarkers: (markers, clear) => {
|
|
211
|
+
const runtimeMarkers = markers;
|
|
212
|
+
const shouldClear = clear === true;
|
|
213
|
+
options.setImperativeAddedMarkers((previousAddedMarkers) => mergeMarkersById(shouldClear ? [] : previousAddedMarkers, runtimeMarkers));
|
|
214
|
+
options.setImperativeRemovedMarkerIds((previousRemovedMarkerIds) => {
|
|
215
|
+
const baseRemovedMarkerIds = shouldClear ? [] : previousRemovedMarkerIds;
|
|
216
|
+
const restoredMarkerIds = runtimeMarkers
|
|
217
|
+
.map((marker) => getNumericMarkerId(marker))
|
|
218
|
+
.filter((markerId) => markerId !== undefined);
|
|
219
|
+
if (restoredMarkerIds.length === 0) {
|
|
220
|
+
return baseRemovedMarkerIds;
|
|
221
|
+
}
|
|
222
|
+
const restoredIdSet = new Set(restoredMarkerIds);
|
|
223
|
+
return baseRemovedMarkerIds.filter((markerId) => !restoredIdSet.has(markerId));
|
|
224
|
+
});
|
|
225
|
+
},
|
|
226
|
+
removeMarkers: (markerIds) => {
|
|
227
|
+
options.setImperativeAddedMarkers((previousAddedMarkers) => removeMarkersByIds(previousAddedMarkers, markerIds));
|
|
228
|
+
options.setImperativeRemovedMarkerIds((previousRemovedMarkerIds) => {
|
|
229
|
+
const markerIdSet = new Set([...previousRemovedMarkerIds, ...markerIds]);
|
|
230
|
+
return Array.from(markerIdSet);
|
|
231
|
+
});
|
|
212
232
|
}
|
|
213
233
|
};
|
|
214
234
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { MapRef } from '@byted-doubao-apps/framework/components';
|
|
2
|
+
import type { CSSProperties } from '@lynx-js/types';
|
|
2
3
|
import type { MapProps } from '@tarojs/components';
|
|
3
|
-
import { resolveCustomMapStyle } from './bridge.js';
|
|
4
|
+
import { resolveCustomMapStyle, type NativeRegionChangeLike } from './bridge.js';
|
|
4
5
|
type CommonEvent<T = unknown> = {
|
|
5
6
|
type: string;
|
|
6
7
|
timeStamp: number;
|
|
@@ -18,6 +19,12 @@ type CommonEvent<T = unknown> = {
|
|
|
18
19
|
preventDefault: () => void;
|
|
19
20
|
stopPropagation: () => void;
|
|
20
21
|
};
|
|
22
|
+
type NativeMapClickDetail = {
|
|
23
|
+
point: MapProps.point;
|
|
24
|
+
};
|
|
25
|
+
type NativeMapPolylineClickDetail = {
|
|
26
|
+
id: string;
|
|
27
|
+
};
|
|
21
28
|
type ResolvedMapValues = {
|
|
22
29
|
resolvedSetting: Record<string, unknown>;
|
|
23
30
|
resolvedScale: number;
|
|
@@ -80,7 +87,6 @@ type CreateMapElementPropsOptions = {
|
|
|
80
87
|
declare const MAP_UNSUPPORTED_PROPS: readonly ["animation", "controls", "showLocation", "subkey", "layerStyle", "skew", "showCompass", "enableSatellite", "enableTraffic", "groundOverlays", "tileOverlay", "enablePoi", "enableBuilding", "panels", "theme", "optimize", "enableAutoMaxOverlooking", "enable3D", "onTouchStart", "onTouchMove", "onTouchCancel", "onTouchEnd", "onLongPress", "onLongClick", "onTransitionEnd", "onAnimationStart", "onAnimationIteration", "onAnimationEnd", "onControlTap", "onPoiTap", "onAbilitySuccess", "onAbilityFailed", "onAuthSuccess", "onInterpolatePoint", "onError", "onAnchorPointTap", "onPanelTap"];
|
|
81
88
|
export type RuntimeMarker = MapProps.marker & {
|
|
82
89
|
children?: unknown;
|
|
83
|
-
draggable?: boolean;
|
|
84
90
|
};
|
|
85
91
|
export declare function resolveMapValues(values: {
|
|
86
92
|
setting: MapProps['setting'];
|
|
@@ -100,7 +106,69 @@ export declare function resolveMapValues(values: {
|
|
|
100
106
|
customMapStyle: MapProps['customMapStyle'];
|
|
101
107
|
}): ResolvedMapValues;
|
|
102
108
|
export declare function collectMapUnsupportedWarnings(options: CollectUnsupportedOptions): string[];
|
|
103
|
-
export declare function createMapElementProps(options: CreateMapElementPropsOptions):
|
|
109
|
+
export declare function createMapElementProps(options: CreateMapElementPropsOptions): {
|
|
110
|
+
id: string;
|
|
111
|
+
className: string;
|
|
112
|
+
ref: {
|
|
113
|
+
current: MapRef | null;
|
|
114
|
+
};
|
|
115
|
+
style: CSSProperties;
|
|
116
|
+
mapStyle: "normal-light" | "simple-light" | undefined;
|
|
117
|
+
center: {
|
|
118
|
+
latitude: number;
|
|
119
|
+
longitude: number;
|
|
120
|
+
};
|
|
121
|
+
scale: number;
|
|
122
|
+
minScale: number;
|
|
123
|
+
maxScale: number;
|
|
124
|
+
rotate: number;
|
|
125
|
+
showScale: boolean;
|
|
126
|
+
enableTilt: boolean;
|
|
127
|
+
enableScale: boolean;
|
|
128
|
+
enableDrag: boolean;
|
|
129
|
+
enableRotate: boolean;
|
|
130
|
+
polyline: {
|
|
131
|
+
id: string;
|
|
132
|
+
points: MapProps.point[];
|
|
133
|
+
edgeColor: string[] | undefined;
|
|
134
|
+
edgeTexture: string[] | undefined;
|
|
135
|
+
edgeTextureAssets: {
|
|
136
|
+
id: string;
|
|
137
|
+
url: string;
|
|
138
|
+
}[] | undefined;
|
|
139
|
+
width: number | undefined;
|
|
140
|
+
dottedLine: boolean | undefined;
|
|
141
|
+
}[];
|
|
142
|
+
circles: (Omit<{
|
|
143
|
+
id: string;
|
|
144
|
+
center: {
|
|
145
|
+
latitude: number;
|
|
146
|
+
longitude: number | undefined;
|
|
147
|
+
};
|
|
148
|
+
radius: number;
|
|
149
|
+
strokeWidth: number | undefined;
|
|
150
|
+
strokeColor: string | undefined;
|
|
151
|
+
fillColor: string | undefined;
|
|
152
|
+
}, "center"> & {
|
|
153
|
+
center: {
|
|
154
|
+
latitude: number;
|
|
155
|
+
longitude: number;
|
|
156
|
+
};
|
|
157
|
+
})[];
|
|
158
|
+
polygons: {
|
|
159
|
+
id: string;
|
|
160
|
+
points: MapProps.point[];
|
|
161
|
+
dottedLine: boolean | undefined;
|
|
162
|
+
strokeWidth: number | undefined;
|
|
163
|
+
strokeColor: string | undefined;
|
|
164
|
+
fillColor: string | undefined;
|
|
165
|
+
zIndex: number | undefined;
|
|
166
|
+
}[];
|
|
167
|
+
onClick: (detail: NativeMapClickDetail) => void;
|
|
168
|
+
onMapLoaded: () => void;
|
|
169
|
+
onRegionChange: (detail: NativeRegionChangeLike) => void;
|
|
170
|
+
onPolylineClick: (detail: NativeMapPolylineClickDetail) => void;
|
|
171
|
+
};
|
|
104
172
|
export declare function toCommonEvent<T>(detail: T, type: string, mapId: string): CommonEvent<T>;
|
|
105
173
|
export {};
|
|
106
174
|
//# sourceMappingURL=mapping.d.ts.map
|
|
@@ -140,21 +140,6 @@ function collectShapeWarnings(markers, polylines, circles, polygons) {
|
|
|
140
140
|
if (markers.some((marker) => marker.ariaLabel !== undefined)) {
|
|
141
141
|
unsupported.push('markers[].ariaLabel');
|
|
142
142
|
}
|
|
143
|
-
if (markers.some((marker) => marker.callout?.anchorX !== undefined)) {
|
|
144
|
-
unsupported.push('markers[].callout.anchorX');
|
|
145
|
-
}
|
|
146
|
-
if (markers.some((marker) => marker.callout?.anchorY !== undefined)) {
|
|
147
|
-
unsupported.push('markers[].callout.anchorY');
|
|
148
|
-
}
|
|
149
|
-
if (markers.some((marker) => marker.callout?.display !== undefined)) {
|
|
150
|
-
unsupported.push('markers[].callout.display');
|
|
151
|
-
}
|
|
152
|
-
if (markers.some((marker) => marker.label?.anchorX !== undefined)) {
|
|
153
|
-
unsupported.push('markers[].label.anchorX');
|
|
154
|
-
}
|
|
155
|
-
if (markers.some((marker) => marker.label?.anchorY !== undefined)) {
|
|
156
|
-
unsupported.push('markers[].label.anchorY');
|
|
157
|
-
}
|
|
158
143
|
if ((polylines ?? []).some((item) => item.borderColor !== undefined)) {
|
|
159
144
|
unsupported.push('polyline[].borderColor');
|
|
160
145
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PickerColumnOption } from '@byted-doubao-apps/framework/components';
|
|
2
|
+
import { type TaroPickerViewProps, type TaroPickerViewColumnProps } from './map.js';
|
|
3
|
+
export declare function PickerView(props: TaroPickerViewProps): any;
|
|
4
|
+
export declare function PickerViewColumn(_props: TaroPickerViewColumnProps & {
|
|
5
|
+
__mappedOptions?: PickerColumnOption[];
|
|
6
|
+
__mappedValue?: string | number;
|
|
7
|
+
}): any;
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Children, cloneElement } from 'react';
|
|
2
|
+
import { PickerView as DoubaoPickerView, PickerColumn as DoubaoPickerColumn } from '@byted-doubao-apps/components';
|
|
3
|
+
import { buildOptionsFromRange, mapPickerViewProps, toPickerViewChangeEvent, warnUnsupportedPickerView } from './map.js';
|
|
4
|
+
export function PickerView(props) {
|
|
5
|
+
const { value, onChange, children, ...rest } = props;
|
|
6
|
+
const { mapped, unsupported } = mapPickerViewProps(rest);
|
|
7
|
+
warnUnsupportedPickerView(unsupported);
|
|
8
|
+
// Collect ranges from child columns to compute indices on change
|
|
9
|
+
const ranges = [];
|
|
10
|
+
const childrenWithProps = Children.map(children, (child, index) => {
|
|
11
|
+
if (!child)
|
|
12
|
+
return child;
|
|
13
|
+
// We expect child to be <PickerViewColumn range={...} />
|
|
14
|
+
const range = child?.props?.range;
|
|
15
|
+
const options = buildOptionsFromRange(range);
|
|
16
|
+
ranges[index] = options;
|
|
17
|
+
const selectedIndex = Array.isArray(value) ? value[index] : undefined;
|
|
18
|
+
const selectedValue = selectedIndex != null && options[selectedIndex] ? options[selectedIndex].value : undefined;
|
|
19
|
+
return cloneElement(child, {
|
|
20
|
+
__mappedOptions: options,
|
|
21
|
+
__mappedValue: selectedValue
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
const handleChange = (values, selectedOptions) => {
|
|
25
|
+
// Map selected values back to indices per column
|
|
26
|
+
const indices = values.map((val, idx) => {
|
|
27
|
+
const opts = ranges[idx] ?? [];
|
|
28
|
+
const found = opts.findIndex((opt) => opt.value === val);
|
|
29
|
+
return found >= 0 ? found : 0;
|
|
30
|
+
});
|
|
31
|
+
onChange?.(toPickerViewChangeEvent(indices));
|
|
32
|
+
};
|
|
33
|
+
return (<DoubaoPickerView {...mapped} onChange={onChange ? handleChange : undefined}>
|
|
34
|
+
{Children.map(childrenWithProps, (child) => {
|
|
35
|
+
const options = child?.props?.__mappedOptions;
|
|
36
|
+
const valueForColumn = child?.props?.__mappedValue;
|
|
37
|
+
const columnClassName = child?.props?.className;
|
|
38
|
+
const columnStyle = child?.props?.style;
|
|
39
|
+
return (<DoubaoPickerColumn options={options ?? []} value={valueForColumn} className={columnClassName} style={columnStyle}/>);
|
|
40
|
+
})}
|
|
41
|
+
</DoubaoPickerView>);
|
|
42
|
+
}
|
|
43
|
+
export function PickerViewColumn(_props) {
|
|
44
|
+
// This is a placeholder wrapper. Real rendering is performed by PickerView above after mapping.
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=index.jsx.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { CSSProperties } from '@lynx-js/types';
|
|
2
|
+
import type { PickerViewProps as LynxPickerViewProps, PickerColumnOption } from '@byted-doubao-apps/framework/components';
|
|
3
|
+
export type TaroPickerViewProps = {
|
|
4
|
+
className?: string;
|
|
5
|
+
style?: CSSProperties;
|
|
6
|
+
value?: number[];
|
|
7
|
+
indicatorStyle?: CSSProperties;
|
|
8
|
+
maskStyle?: CSSProperties;
|
|
9
|
+
onChange?: (event: {
|
|
10
|
+
type: string;
|
|
11
|
+
timeStamp: number;
|
|
12
|
+
detail: {
|
|
13
|
+
value: number[];
|
|
14
|
+
};
|
|
15
|
+
}) => void;
|
|
16
|
+
children?: any;
|
|
17
|
+
};
|
|
18
|
+
export type TaroPickerViewColumnProps = {
|
|
19
|
+
range?: Array<string | number>;
|
|
20
|
+
className?: string;
|
|
21
|
+
style?: CSSProperties;
|
|
22
|
+
};
|
|
23
|
+
export declare function toPickerViewChangeEvent(indices: number[]): {
|
|
24
|
+
type: string;
|
|
25
|
+
timeStamp: number;
|
|
26
|
+
detail: {
|
|
27
|
+
value: number[];
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export declare function buildOptionsFromRange(range?: Array<string | number>): PickerColumnOption[];
|
|
31
|
+
export declare function warnUnsupportedPickerView(unsupported: string[]): void;
|
|
32
|
+
export declare function mapPickerViewProps(props: TaroPickerViewProps): {
|
|
33
|
+
mapped: Pick<LynxPickerViewProps, 'className' | 'style'>;
|
|
34
|
+
unsupported: string[];
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=map.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function toPickerViewChangeEvent(indices) {
|
|
2
|
+
return {
|
|
3
|
+
type: 'change',
|
|
4
|
+
timeStamp: Date.now(),
|
|
5
|
+
detail: { value: indices }
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function buildOptionsFromRange(range) {
|
|
9
|
+
return (range ?? []).map((item) => ({ label: String(item), value: item }));
|
|
10
|
+
}
|
|
11
|
+
export function warnUnsupportedPickerView(unsupported) {
|
|
12
|
+
if (unsupported.length > 0) {
|
|
13
|
+
// Centralized warn helper exists for other components; keep inline minimal here
|
|
14
|
+
console.warn(`[PickerView] Unsupported props: ${unsupported.join(', ')}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function mapPickerViewProps(props) {
|
|
18
|
+
const unsupported = [];
|
|
19
|
+
if (props.maskStyle)
|
|
20
|
+
unsupported.push('maskStyle');
|
|
21
|
+
if (props.indicatorStyle)
|
|
22
|
+
unsupported.push('indicatorStyle');
|
|
23
|
+
const mapped = {
|
|
24
|
+
className: props.className,
|
|
25
|
+
style: props.style
|
|
26
|
+
};
|
|
27
|
+
return { mapped, unsupported };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=map.js.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { useCallback, useContext, useEffect, useRef, useState } from '@byted-doubao-apps/framework';
|
|
2
|
+
import { warnUnsupported } from '../base/warn-unsupported.js';
|
|
3
|
+
import { RadioGroupRuntimeContext } from '../RadioGroup/context.js';
|
|
4
|
+
import { mapRadioProps, resolveLynxRadioValue, resolveStandaloneSelectedValue, shouldDispatchStandaloneRadioChange, toRadioChangeEvent } from './map.js';
|
|
5
|
+
import { markRuntimeRadio } from './shared.js';
|
|
6
|
+
function RadioImpl(props) {
|
|
7
|
+
const { children, onChange, ...nonEventProps } = props;
|
|
8
|
+
const { mapped, unsupported, radioId, resolvedValue, resolvedDisabled, resolvedChecked } = mapRadioProps(nonEventProps);
|
|
9
|
+
const groupContext = useContext(RadioGroupRuntimeContext);
|
|
10
|
+
const warnedMissingGroupValueRef = useRef(false);
|
|
11
|
+
const fallbackValueRef = useRef(`__taro_runtime_radio_missing_${nextMissingValueId()}`);
|
|
12
|
+
const [uncontrolledChecked, setUncontrolledChecked] = useState(resolvedChecked ?? false);
|
|
13
|
+
warnUnsupported('Radio', unsupported);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (!groupContext ||
|
|
16
|
+
resolvedValue !== undefined ||
|
|
17
|
+
warnedMissingGroupValueRef.current ||
|
|
18
|
+
isProduction()) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
warnedMissingGroupValueRef.current = true;
|
|
22
|
+
// eslint-disable-next-line no-console
|
|
23
|
+
console.warn('[components-taro] Radio inside RadioGroup requires a string value.');
|
|
24
|
+
}, [groupContext, resolvedValue]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!groupContext || resolvedValue === undefined) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
return groupContext.registerRadioOnChange(resolvedValue, () => {
|
|
30
|
+
onChange?.(toRadioChangeEvent({ value: resolvedValue }, 'change', radioId));
|
|
31
|
+
});
|
|
32
|
+
}, [groupContext, onChange, radioId, resolvedValue]);
|
|
33
|
+
const valueForLynx = resolveLynxRadioValue(resolvedValue, fallbackValueRef.current);
|
|
34
|
+
const handleGroupLabelTap = useCallback(() => {
|
|
35
|
+
if (!groupContext || groupContext.disabled || resolvedDisabled || resolvedValue === undefined) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
groupContext.selectValue(resolvedValue);
|
|
39
|
+
}, [groupContext, resolvedDisabled, resolvedValue]);
|
|
40
|
+
const isStandaloneControlled = resolvedChecked !== undefined;
|
|
41
|
+
const isStandaloneChecked = isStandaloneControlled ? resolvedChecked : uncontrolledChecked;
|
|
42
|
+
const handleStandaloneSelect = useCallback(() => {
|
|
43
|
+
if (resolvedDisabled) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (shouldDispatchStandaloneRadioChange(isStandaloneChecked)) {
|
|
47
|
+
onChange?.(toRadioChangeEvent({ value: resolvedValue }, 'change', radioId));
|
|
48
|
+
}
|
|
49
|
+
if (!isStandaloneControlled && !isStandaloneChecked) {
|
|
50
|
+
setUncontrolledChecked(true);
|
|
51
|
+
}
|
|
52
|
+
}, [isStandaloneChecked, isStandaloneControlled, onChange, radioId, resolvedDisabled, resolvedValue]);
|
|
53
|
+
if (groupContext) {
|
|
54
|
+
return (<view {...mapped}>
|
|
55
|
+
<radio value={valueForLynx} disabled={resolvedDisabled || groupContext.disabled}/>
|
|
56
|
+
{children !== undefined ? <view bindtap={handleGroupLabelTap}>{children}</view> : null}
|
|
57
|
+
</view>);
|
|
58
|
+
}
|
|
59
|
+
const standaloneSelectedValue = resolveStandaloneSelectedValue(isStandaloneChecked ?? false, valueForLynx);
|
|
60
|
+
const lynxStandaloneGroupProps = {
|
|
61
|
+
disabled: resolvedDisabled,
|
|
62
|
+
onValueChange: handleStandaloneSelect,
|
|
63
|
+
...(standaloneSelectedValue !== null ? { value: standaloneSelectedValue } : {})
|
|
64
|
+
};
|
|
65
|
+
return (<view {...mapped}>
|
|
66
|
+
<radio-group {...lynxStandaloneGroupProps}>
|
|
67
|
+
<radio value={valueForLynx} disabled={resolvedDisabled}/>
|
|
68
|
+
</radio-group>
|
|
69
|
+
{children !== undefined ? <view bindtap={handleStandaloneSelect}>{children}</view> : null}
|
|
70
|
+
</view>);
|
|
71
|
+
}
|
|
72
|
+
export const Radio = markRuntimeRadio(RadioImpl);
|
|
73
|
+
let missingValueId = 0;
|
|
74
|
+
function nextMissingValueId() {
|
|
75
|
+
const current = missingValueId;
|
|
76
|
+
missingValueId += 1;
|
|
77
|
+
return current;
|
|
78
|
+
}
|
|
79
|
+
function isProduction() {
|
|
80
|
+
return (globalThis.process?.env?.NODE_ENV === 'production');
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=index.jsx.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { RadioProps as TaroRadioProps } from '@tarojs/components';
|
|
2
|
+
export type MappableTaroRadioProps = Omit<TaroRadioProps, 'children' | 'onChange'>;
|
|
3
|
+
type CommonEvent<T = unknown> = {
|
|
4
|
+
type: string;
|
|
5
|
+
timeStamp: number;
|
|
6
|
+
target: {
|
|
7
|
+
id: string;
|
|
8
|
+
tagName: string;
|
|
9
|
+
dataset: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
currentTarget: {
|
|
12
|
+
id: string;
|
|
13
|
+
tagName: string;
|
|
14
|
+
dataset: Record<string, unknown>;
|
|
15
|
+
};
|
|
16
|
+
detail: T;
|
|
17
|
+
preventDefault: () => void;
|
|
18
|
+
stopPropagation: () => void;
|
|
19
|
+
};
|
|
20
|
+
type MapRadioPropsResult = {
|
|
21
|
+
mapped: Record<string, unknown>;
|
|
22
|
+
unsupported: string[];
|
|
23
|
+
radioId: string;
|
|
24
|
+
resolvedValue: string | undefined;
|
|
25
|
+
resolvedDisabled: boolean;
|
|
26
|
+
resolvedChecked: boolean | undefined;
|
|
27
|
+
};
|
|
28
|
+
export declare function mapRadioProps(props: MappableTaroRadioProps): MapRadioPropsResult;
|
|
29
|
+
export declare function resolveLynxRadioValue(value: string | undefined, fallback: string): string;
|
|
30
|
+
export declare function resolveStandaloneSelectedValue(isChecked: boolean, value: string): string | null;
|
|
31
|
+
export declare function shouldDispatchStandaloneRadioChange(isChecked: boolean): boolean;
|
|
32
|
+
export declare function toRadioChangeEvent(detail: {
|
|
33
|
+
value?: string;
|
|
34
|
+
}, type: string, radioId: string): CommonEvent<{
|
|
35
|
+
value?: string;
|
|
36
|
+
}>;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=map.d.ts.map
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { BASE_PROP_MAP } from '../base/prop-map.js';
|
|
2
|
+
const RADIO_PROP_MAP = {
|
|
3
|
+
name: null,
|
|
4
|
+
nativeProps: null,
|
|
5
|
+
ariaLabel: null
|
|
6
|
+
};
|
|
7
|
+
const RADIO_LAYOUT_STYLE = {
|
|
8
|
+
display: 'flex',
|
|
9
|
+
alignItems: 'center',
|
|
10
|
+
columnGap: '8px'
|
|
11
|
+
};
|
|
12
|
+
export function mapRadioProps(props) {
|
|
13
|
+
const { value, checked, disabled, color, ...rest } = props;
|
|
14
|
+
const mapped = {};
|
|
15
|
+
const unsupported = [];
|
|
16
|
+
Object.entries(rest).forEach(([key, rawValue]) => {
|
|
17
|
+
const target = RADIO_PROP_MAP[key] ?? BASE_PROP_MAP[key];
|
|
18
|
+
if (target) {
|
|
19
|
+
mapped[target] = rawValue;
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
unsupported.push(key);
|
|
23
|
+
});
|
|
24
|
+
const resolvedValue = resolveStringProp(value, 'value', unsupported);
|
|
25
|
+
const resolvedColor = resolveStringProp(color, 'color', unsupported);
|
|
26
|
+
const resolvedChecked = resolveBooleanProp(checked, 'checked', unsupported);
|
|
27
|
+
const resolvedDisabled = resolveBooleanProp(disabled, 'disabled', unsupported) ?? false;
|
|
28
|
+
mapped.style = mergeRadioWrapperStyle(mapped.style, resolvedColor);
|
|
29
|
+
return {
|
|
30
|
+
mapped,
|
|
31
|
+
unsupported: dedupe(unsupported),
|
|
32
|
+
radioId: resolveRadioId(mapped.id),
|
|
33
|
+
resolvedValue,
|
|
34
|
+
resolvedDisabled,
|
|
35
|
+
resolvedChecked
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function resolveLynxRadioValue(value, fallback) {
|
|
39
|
+
return value ?? fallback;
|
|
40
|
+
}
|
|
41
|
+
export function resolveStandaloneSelectedValue(isChecked, value) {
|
|
42
|
+
return isChecked ? value : null;
|
|
43
|
+
}
|
|
44
|
+
export function shouldDispatchStandaloneRadioChange(isChecked) {
|
|
45
|
+
return !isChecked;
|
|
46
|
+
}
|
|
47
|
+
export function toRadioChangeEvent(detail, type, radioId) {
|
|
48
|
+
return {
|
|
49
|
+
type,
|
|
50
|
+
timeStamp: Date.now(),
|
|
51
|
+
target: {
|
|
52
|
+
id: radioId,
|
|
53
|
+
tagName: 'radio',
|
|
54
|
+
dataset: {}
|
|
55
|
+
},
|
|
56
|
+
currentTarget: {
|
|
57
|
+
id: radioId,
|
|
58
|
+
tagName: 'radio',
|
|
59
|
+
dataset: {}
|
|
60
|
+
},
|
|
61
|
+
detail,
|
|
62
|
+
preventDefault: () => { },
|
|
63
|
+
stopPropagation: () => { }
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function mergeRadioWrapperStyle(style, color) {
|
|
67
|
+
const colorStyle = color ? `--doubao-radio-primary-color:${color};` : '';
|
|
68
|
+
const layoutStyle = 'display:flex;align-items:center;column-gap:8px;';
|
|
69
|
+
if (typeof style === 'string') {
|
|
70
|
+
const normalized = style.endsWith(';') ? style : `${style};`;
|
|
71
|
+
return `${normalized}${layoutStyle}${colorStyle}`;
|
|
72
|
+
}
|
|
73
|
+
const styleObject = isObject(style) ? style : {};
|
|
74
|
+
return {
|
|
75
|
+
...RADIO_LAYOUT_STYLE,
|
|
76
|
+
...styleObject,
|
|
77
|
+
...(color ? { '--doubao-radio-primary-color': color } : {})
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function resolveStringProp(value, propName, unsupported) {
|
|
81
|
+
if (value === undefined) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
if (typeof value === 'string') {
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
unsupported.push(propName);
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
function resolveBooleanProp(value, propName, unsupported) {
|
|
91
|
+
if (value === undefined) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
if (typeof value === 'boolean') {
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
97
|
+
unsupported.push(propName);
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
function resolveRadioId(id) {
|
|
101
|
+
return typeof id === 'string' && id.length > 0 ? id : 'radio';
|
|
102
|
+
}
|
|
103
|
+
function isObject(value) {
|
|
104
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
105
|
+
}
|
|
106
|
+
function dedupe(values) {
|
|
107
|
+
return Array.from(new Set(values));
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=map.js.map
|