@lingxia/elements 0.17.0 → 0.19.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.
- package/dist/index.d.ts +4 -4
- package/dist/inline-native/structure.js +0 -12
- package/dist/media_swiper.d.ts +28 -18
- package/dist/media_swiper.js +0 -34
- package/dist/native_component_wrapper_shared.d.ts +19 -13
- package/dist/native_component_wrapper_shared.js +12 -0
- package/dist/navigator.d.ts +27 -7
- package/dist/navigator.js +102 -82
- package/dist/picker.d.ts +8 -9
- package/dist/picker.js +0 -47
- package/dist/video.d.ts +2 -8
- package/dist/video.js +0 -16
- package/package.json +2 -2
- package/src/index.ts +14 -0
- package/src/inline-native/structure.ts +0 -11
- package/src/media_swiper.ts +31 -47
- package/src/native_component_wrapper_shared.ts +35 -13
- package/src/navigator.ts +149 -129
- package/src/picker.ts +8 -49
- package/src/video.ts +2 -22
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { registerVideoComponent, LxVideoElement, type LxVideoAttributes, type LxVideoEventPayloads, type LxVideoEventHandlers, } from "./video.js";
|
|
2
|
-
export { registerMediaSwiperComponent, LxMediaSwiperElement, type LxMediaSwiperAttributes, type LxMediaSwiperItem, type LxMediaSwiperChangeEvent, type LxMediaSwiperChangeEventDetail, type LxMediaSwiperTransitionEndEvent, type LxMediaSwiperTransitionEndEventDetail, type LxMediaSwiperItemEvent, type LxMediaSwiperEventDetail, type LxMediaSwiperEndReachedEvent, type LxMediaSwiperEndReachedEventDetail, type LxMediaSwiperErrorEvent, type LxMediaSwiperErrorEventDetail, type LxMediaSwiperChangeSource, type LxMediaSwiperErrorCode, } from "./media_swiper.js";
|
|
3
|
-
export { registerPickerComponent, LxPickerElement, type LxPickerAttributes, type LxPickerColumn, type LxPickerCascadingColumns, type LxPickerEvent, type LxPickerEventDetail, } from "./picker.js";
|
|
4
|
-
export { LxNavigatorElement, type LxNavigatorAttributes, type LxNavigatorEvent, type NavigatorChannel, type NavigatorOpenType, type NavigatorQuery, type NavigatorQueryValue, type NavigatorTarget, } from "./navigator.js";
|
|
1
|
+
export { registerVideoComponent, LxVideoElement, type LxVideoAttributes, type LxVideoEventPayloads, type LxVideoEventHandlers, type LxVideoQuality, } from "./video.js";
|
|
2
|
+
export { registerMediaSwiperComponent, LxMediaSwiperElement, type LxMediaSwiperAttributes, type LxMediaSwiperItem, type LxMediaSwiperEventPayloads, type LxMediaSwiperEventHandlers, type LxMediaSwiperHandle, type LxMediaSwiperChangeEvent, type LxMediaSwiperChangeEventDetail, type LxMediaSwiperTransitionEndEvent, type LxMediaSwiperTransitionEndEventDetail, type LxMediaSwiperItemEvent, type LxMediaSwiperEventDetail, type LxMediaSwiperEndReachedEvent, type LxMediaSwiperEndReachedEventDetail, type LxMediaSwiperErrorEvent, type LxMediaSwiperErrorEventDetail, type LxMediaSwiperChangeSource, type LxMediaSwiperErrorCode, } from "./media_swiper.js";
|
|
3
|
+
export { registerPickerComponent, LxPickerElement, type LxPickerAttributes, type LxPickerColumn, type LxPickerCascadingColumns, type LxPickerColumns, type LxPickerEvent, type LxPickerEventDetail, } from "./picker.js";
|
|
4
|
+
export { LxNavigatorElement, type LxNavigatorAttributes, type LxNavigatorEvent, type NavigatorChannel, type NavigatorEdge, type NavigatorFloatPosition, type NavigatorInteraction, type NavigatorPagePlacement, type NavigatorPlacement, type NavigatorSize, type NavigatorSizeValue, type NavigatorUrlPlacement, type NavigatorWindowChrome, type NavigatorOpenType, type NavigatorQuery, type NavigatorQueryValue, type NavigatorTarget, } from "./navigator.js";
|
|
5
5
|
export { buildVideoNativeAttrs, buildMediaSwiperNativeAttrs, buildNavigatorNativeAttrs, buildPickerNativeAttrs, getPickerDisplayText, getPickerValueFromIndex, VIDEO_DOM_EVENT_MAP, MEDIA_SWIPER_DOM_EVENT_MAP, } from "./native_component_wrapper_shared.js";
|
|
6
6
|
export { isHarmony, isIOS, isAndroid, isMacOS, isDesktop, getOS, } from "./platform.js";
|
|
7
7
|
export { ensureComponentId, rectEquals, NativeComponentUpdateState, type Rect, } from "./component.js";
|
|
@@ -569,7 +569,6 @@ export function isFallbackElement(element) {
|
|
|
569
569
|
}
|
|
570
570
|
function readElementProps(element) {
|
|
571
571
|
const props = {};
|
|
572
|
-
const dataset = {};
|
|
573
572
|
for (const attr of Array.from(element.attributes)) {
|
|
574
573
|
if (attr.name === "data-lx-native-measuring" || attr.name === "data-lx-native-paint-hidden")
|
|
575
574
|
continue;
|
|
@@ -578,11 +577,6 @@ function readElementProps(element) {
|
|
|
578
577
|
continue;
|
|
579
578
|
}
|
|
580
579
|
props[camelize(name)] = attr.value;
|
|
581
|
-
if (name.startsWith("data-") && name !== "data-lx-component-id") {
|
|
582
|
-
const key = camelize(name.slice(5));
|
|
583
|
-
if (key)
|
|
584
|
-
dataset[key] = attr.value;
|
|
585
|
-
}
|
|
586
580
|
if (name.startsWith("aria-")) {
|
|
587
581
|
props[name] = attr.value;
|
|
588
582
|
}
|
|
@@ -614,8 +608,6 @@ function readElementProps(element) {
|
|
|
614
608
|
"muted",
|
|
615
609
|
"volume",
|
|
616
610
|
"progressBar",
|
|
617
|
-
"pageFuncBindings",
|
|
618
|
-
"pageFuncBindingsJson",
|
|
619
611
|
"intent",
|
|
620
612
|
"emphasis",
|
|
621
613
|
"size",
|
|
@@ -638,10 +630,6 @@ function readElementProps(element) {
|
|
|
638
630
|
props[key] = anyEl[key];
|
|
639
631
|
}
|
|
640
632
|
}
|
|
641
|
-
if (Object.keys(dataset).length > 0) {
|
|
642
|
-
props.dataset = dataset;
|
|
643
|
-
props.datasetJson = JSON.stringify(dataset);
|
|
644
|
-
}
|
|
645
633
|
const ariaLabel = element.getAttribute("aria-label");
|
|
646
634
|
if (ariaLabel) {
|
|
647
635
|
props["aria-label"] = ariaLabel;
|
package/dist/media_swiper.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
type LxMediaSwiperEventHandler = (e: Event) => void;
|
|
2
1
|
export type LxMediaSwiperItem = {
|
|
3
2
|
id?: string;
|
|
4
3
|
type: "image";
|
|
@@ -40,6 +39,25 @@ export type LxMediaSwiperTransitionEndEvent = CustomEvent<LxMediaSwiperTransitio
|
|
|
40
39
|
export type LxMediaSwiperItemEvent = CustomEvent<LxMediaSwiperEventDetail>;
|
|
41
40
|
export type LxMediaSwiperEndReachedEvent = CustomEvent<LxMediaSwiperEndReachedEventDetail>;
|
|
42
41
|
export type LxMediaSwiperErrorEvent = CustomEvent<LxMediaSwiperErrorEventDetail>;
|
|
42
|
+
/** What each framework callback receives: the event's `detail`. */
|
|
43
|
+
export interface LxMediaSwiperEventPayloads {
|
|
44
|
+
onChange: LxMediaSwiperChangeEventDetail;
|
|
45
|
+
onTransitionEnd: LxMediaSwiperTransitionEndEventDetail;
|
|
46
|
+
onEndReached: LxMediaSwiperEndReachedEventDetail;
|
|
47
|
+
onTap: LxMediaSwiperEventDetail;
|
|
48
|
+
onVideoEnded: LxMediaSwiperEventDetail;
|
|
49
|
+
onError: LxMediaSwiperErrorEventDetail;
|
|
50
|
+
}
|
|
51
|
+
/** The framework callbacks: each receives its event's payload. */
|
|
52
|
+
export type LxMediaSwiperEventHandlers = {
|
|
53
|
+
[K in keyof LxMediaSwiperEventPayloads]?: (payload: LxMediaSwiperEventPayloads[K]) => void;
|
|
54
|
+
};
|
|
55
|
+
/** Imperative control of a mounted swiper (React ref, Vue template ref). */
|
|
56
|
+
export interface LxMediaSwiperHandle {
|
|
57
|
+
next(): void;
|
|
58
|
+
previous(): void;
|
|
59
|
+
goToIndex(index: number): void;
|
|
60
|
+
}
|
|
43
61
|
/**
|
|
44
62
|
* Peek leaves part of the previous and next pages visible alongside the current
|
|
45
63
|
* page so users get a hint that more content exists. A single `number` applies
|
|
@@ -57,7 +75,7 @@ export type LxMediaSwiperPeek = number | {
|
|
|
57
75
|
};
|
|
58
76
|
export type LxMediaSwiperAttributes = {
|
|
59
77
|
id?: string;
|
|
60
|
-
items?: LxMediaSwiperItem[];
|
|
78
|
+
items?: readonly LxMediaSwiperItem[];
|
|
61
79
|
index?: number;
|
|
62
80
|
initialIndex?: number;
|
|
63
81
|
loop?: boolean;
|
|
@@ -79,13 +97,12 @@ export type LxMediaSwiperAttributes = {
|
|
|
79
97
|
className?: string;
|
|
80
98
|
style?: any;
|
|
81
99
|
ref?: any;
|
|
82
|
-
onChange?:
|
|
83
|
-
onTransitionEnd?:
|
|
84
|
-
onEndReached?:
|
|
85
|
-
onTap?:
|
|
86
|
-
onVideoEnded?:
|
|
87
|
-
onError?:
|
|
88
|
-
pageBindings?: Record<string, string>;
|
|
100
|
+
onChange?: (event: LxMediaSwiperChangeEvent) => void;
|
|
101
|
+
onTransitionEnd?: (event: LxMediaSwiperTransitionEndEvent) => void;
|
|
102
|
+
onEndReached?: (event: LxMediaSwiperEndReachedEvent) => void;
|
|
103
|
+
onTap?: (event: LxMediaSwiperItemEvent) => void;
|
|
104
|
+
onVideoEnded?: (event: LxMediaSwiperItemEvent) => void;
|
|
105
|
+
onError?: (event: LxMediaSwiperErrorEvent) => void;
|
|
89
106
|
};
|
|
90
107
|
declare global {
|
|
91
108
|
namespace JSX {
|
|
@@ -94,7 +111,7 @@ declare global {
|
|
|
94
111
|
}
|
|
95
112
|
}
|
|
96
113
|
}
|
|
97
|
-
export declare class LxMediaSwiperElement extends HTMLElement {
|
|
114
|
+
export declare class LxMediaSwiperElement extends HTMLElement implements LxMediaSwiperHandle {
|
|
98
115
|
static get observedAttributes(): string[];
|
|
99
116
|
private componentId;
|
|
100
117
|
private mounted;
|
|
@@ -107,7 +124,6 @@ export declare class LxMediaSwiperElement extends HTMLElement {
|
|
|
107
124
|
private iOSHelper?;
|
|
108
125
|
private rawHandlers;
|
|
109
126
|
private handlers;
|
|
110
|
-
private _pageBindings;
|
|
111
127
|
private harmonyCommandSeq;
|
|
112
128
|
private harmonyPendingCommand;
|
|
113
129
|
private pendingHarmonyProps?;
|
|
@@ -115,7 +131,7 @@ export declare class LxMediaSwiperElement extends HTMLElement {
|
|
|
115
131
|
private pendingHarmonyRetryCount;
|
|
116
132
|
private harmonyEmbed?;
|
|
117
133
|
private lastHarmonyProps?;
|
|
118
|
-
set items(value: LxMediaSwiperItem[] | string | null | undefined);
|
|
134
|
+
set items(value: readonly LxMediaSwiperItem[] | string | null | undefined);
|
|
119
135
|
get items(): LxMediaSwiperItem[];
|
|
120
136
|
set index(value: number | null | undefined);
|
|
121
137
|
get index(): number | undefined;
|
|
@@ -123,10 +139,6 @@ export declare class LxMediaSwiperElement extends HTMLElement {
|
|
|
123
139
|
get initialIndex(): number | undefined;
|
|
124
140
|
set contentRotate(value: unknown);
|
|
125
141
|
get contentRotate(): 0 | 90 | 180 | 270 | undefined;
|
|
126
|
-
set pageBindings(bindings: Record<string, string>);
|
|
127
|
-
get pageBindings(): Record<string, string>;
|
|
128
|
-
set pageFuncBindings(bindings: Record<string, string>);
|
|
129
|
-
setPageBindings(bindings: Record<string, string>): void;
|
|
130
142
|
next(): void;
|
|
131
143
|
previous(): void;
|
|
132
144
|
goToIndex(index: number): void;
|
|
@@ -176,7 +188,5 @@ export declare class LxMediaSwiperElement extends HTMLElement {
|
|
|
176
188
|
* to the zero-peek (full-width page) layout.
|
|
177
189
|
*/
|
|
178
190
|
private parsePeek;
|
|
179
|
-
private collectDataset;
|
|
180
191
|
}
|
|
181
192
|
export declare function registerMediaSwiperComponent(): void;
|
|
182
|
-
export {};
|
package/dist/media_swiper.js
CHANGED
|
@@ -19,7 +19,6 @@ export class LxMediaSwiperElement extends HTMLElement {
|
|
|
19
19
|
this.boundUpdatePosition = this.updatePosition.bind(this);
|
|
20
20
|
this.rawHandlers = {};
|
|
21
21
|
this.handlers = {};
|
|
22
|
-
this._pageBindings = {};
|
|
23
22
|
// Monotonic command counter used as the Harmony bridge fallback. Harmony's
|
|
24
23
|
// Web.onNativeEmbedDataInfo channel only delivers attribute-derived props,
|
|
25
24
|
// so imperative API calls have to piggyback into a prop the Builder polls.
|
|
@@ -99,20 +98,6 @@ export class LxMediaSwiperElement extends HTMLElement {
|
|
|
99
98
|
get contentRotate() {
|
|
100
99
|
return this.parseRotate(this.getAttribute("content-rotate"));
|
|
101
100
|
}
|
|
102
|
-
set pageBindings(bindings) {
|
|
103
|
-
this.setPageBindings(bindings);
|
|
104
|
-
}
|
|
105
|
-
get pageBindings() {
|
|
106
|
-
return this._pageBindings;
|
|
107
|
-
}
|
|
108
|
-
set pageFuncBindings(bindings) {
|
|
109
|
-
this.setPageBindings(bindings);
|
|
110
|
-
}
|
|
111
|
-
setPageBindings(bindings) {
|
|
112
|
-
this._pageBindings = bindings !== null && bindings !== void 0 ? bindings : {};
|
|
113
|
-
if (this.isConnected)
|
|
114
|
-
this.mountOrUpdate(true);
|
|
115
|
-
}
|
|
116
101
|
next() {
|
|
117
102
|
this.sendCommand("next");
|
|
118
103
|
}
|
|
@@ -129,8 +114,6 @@ export class LxMediaSwiperElement extends HTMLElement {
|
|
|
129
114
|
this.upgradeProperty("index");
|
|
130
115
|
this.upgradeProperty("initialIndex");
|
|
131
116
|
this.upgradeProperty("contentRotate");
|
|
132
|
-
this.upgradeProperty("pageBindings");
|
|
133
|
-
this.upgradeProperty("pageFuncBindings");
|
|
134
117
|
for (const prop of Object.keys(EVENT_MAP))
|
|
135
118
|
this.upgradeProperty(prop);
|
|
136
119
|
this.componentId = ensureComponentId(this, "lx-media-swiper", this.componentId);
|
|
@@ -228,7 +211,6 @@ export class LxMediaSwiperElement extends HTMLElement {
|
|
|
228
211
|
var _a, _b, _c, _d, _e, _f;
|
|
229
212
|
const objectFit = this.parseObjectFit(this.getAttribute("object-fit"));
|
|
230
213
|
const dots = this.parseDots();
|
|
231
|
-
const dataset = this.collectDataset();
|
|
232
214
|
// Always emit a normalised peek object so removing the attribute (or setting it
|
|
233
215
|
// to 0) propagates as an explicit reset. JSON.stringify would drop `undefined`,
|
|
234
216
|
// which makes native think peek hasn't changed and keep the old padding.
|
|
@@ -250,10 +232,6 @@ export class LxMediaSwiperElement extends HTMLElement {
|
|
|
250
232
|
dots,
|
|
251
233
|
swipeEnabled: this.getAttribute("swipe-enabled") !== "false",
|
|
252
234
|
peek,
|
|
253
|
-
pageFuncBindings: this._pageBindings,
|
|
254
|
-
pageFuncBindingsJson: JSON.stringify(this._pageBindings),
|
|
255
|
-
dataset,
|
|
256
|
-
datasetJson: JSON.stringify(dataset),
|
|
257
235
|
};
|
|
258
236
|
return props;
|
|
259
237
|
}
|
|
@@ -675,18 +653,6 @@ export class LxMediaSwiperElement extends HTMLElement {
|
|
|
675
653
|
return undefined;
|
|
676
654
|
}
|
|
677
655
|
}
|
|
678
|
-
collectDataset() {
|
|
679
|
-
const dataset = {};
|
|
680
|
-
for (const attr of this.getAttributeNames()) {
|
|
681
|
-
if (!attr.startsWith("data-"))
|
|
682
|
-
continue;
|
|
683
|
-
const key = attr.slice(5).replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
684
|
-
const value = this.getAttribute(attr);
|
|
685
|
-
if (key && value != null)
|
|
686
|
-
dataset[key] = value;
|
|
687
|
-
}
|
|
688
|
-
return dataset;
|
|
689
|
-
}
|
|
690
656
|
}
|
|
691
657
|
export function registerMediaSwiperComponent() {
|
|
692
658
|
if (!customElements.get("lx-media-swiper")) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LxPickerCascadingColumns, LxPickerColumns } from "./picker.js";
|
|
2
|
+
import type { NavigatorChannel, NavigatorEdge, NavigatorFloatPosition, NavigatorInteraction, NavigatorOpenType, NavigatorPlacement, NavigatorSize, NavigatorTarget, NavigatorWindowChrome } from "./navigator.js";
|
|
2
3
|
import type { NavigatorQuery } from "./navigator.js";
|
|
3
4
|
import type { LxMediaSwiperItem } from "./media_swiper.js";
|
|
4
5
|
import type { LxVideoQuality } from "./video.js";
|
|
@@ -10,6 +11,12 @@ export interface NavigatorNativeAttrOptions {
|
|
|
10
11
|
openType?: NavigatorOpenType;
|
|
11
12
|
target?: NavigatorTarget;
|
|
12
13
|
delta?: number;
|
|
14
|
+
as?: NavigatorPlacement;
|
|
15
|
+
edge?: NavigatorEdge;
|
|
16
|
+
position?: NavigatorFloatPosition;
|
|
17
|
+
chrome?: NavigatorWindowChrome;
|
|
18
|
+
size?: NavigatorSize;
|
|
19
|
+
interaction?: NavigatorInteraction;
|
|
13
20
|
appId?: string;
|
|
14
21
|
query?: NavigatorQuery;
|
|
15
22
|
channel?: NavigatorChannel;
|
|
@@ -21,18 +28,17 @@ export interface NavigatorNativeAttrOptions {
|
|
|
21
28
|
hoverStayTime?: number;
|
|
22
29
|
}
|
|
23
30
|
export declare function buildNavigatorNativeAttrs(options: NavigatorNativeAttrOptions, extraAttrs?: Record<string, unknown>): Record<string, string>;
|
|
24
|
-
export type
|
|
25
|
-
export type PickerValue = string | string[] | undefined;
|
|
31
|
+
export type PickerValue = string | readonly string[] | undefined;
|
|
26
32
|
export type PickerFields = "year" | "month" | "day" | "range";
|
|
27
33
|
export interface PickerNativeAttrOptions {
|
|
28
34
|
id?: string;
|
|
29
|
-
columns?:
|
|
35
|
+
columns?: LxPickerColumns;
|
|
30
36
|
mode?: "date" | "time";
|
|
31
37
|
start?: string;
|
|
32
38
|
end?: string;
|
|
33
39
|
fields?: PickerFields;
|
|
34
|
-
modelValue?: string | string[];
|
|
35
|
-
value?: string | string[];
|
|
40
|
+
modelValue?: string | readonly string[];
|
|
41
|
+
value?: string | readonly string[];
|
|
36
42
|
cancelText?: string;
|
|
37
43
|
cancelTextColor?: string;
|
|
38
44
|
cancelButtonColor?: string;
|
|
@@ -41,10 +47,10 @@ export interface PickerNativeAttrOptions {
|
|
|
41
47
|
confirmButtonColor?: string;
|
|
42
48
|
}
|
|
43
49
|
export declare function isPickerDateMode(mode?: "date" | "time"): boolean;
|
|
44
|
-
export declare function isPickerCascading(columns?:
|
|
45
|
-
export declare function isPickerSingle(columns?:
|
|
46
|
-
export declare function getPickerIndexFromValue(columns:
|
|
47
|
-
export declare function getPickerValueFromIndex(columns:
|
|
50
|
+
export declare function isPickerCascading(columns?: LxPickerColumns): columns is LxPickerCascadingColumns;
|
|
51
|
+
export declare function isPickerSingle(columns?: LxPickerColumns): boolean;
|
|
52
|
+
export declare function getPickerIndexFromValue(columns: LxPickerColumns | undefined, value: PickerValue): number | number[];
|
|
53
|
+
export declare function getPickerValueFromIndex(columns: LxPickerColumns | undefined, index: number | number[]): string | string[];
|
|
48
54
|
export declare function getPickerDisplayText(value: PickerValue, fields?: PickerFields): string;
|
|
49
55
|
export declare function buildPickerNativeAttrs(options: PickerNativeAttrOptions, extraAttrs?: Record<string, unknown>): Record<string, string>;
|
|
50
56
|
export declare const VIDEO_DOM_EVENT_MAP: {
|
|
@@ -74,8 +80,8 @@ export interface VideoNativeAttrOptions {
|
|
|
74
80
|
progressBar?: boolean;
|
|
75
81
|
live?: boolean;
|
|
76
82
|
volume?: string | number;
|
|
77
|
-
qualities?: LxVideoQuality[];
|
|
78
|
-
playbackRates?: number[];
|
|
83
|
+
qualities?: readonly LxVideoQuality[];
|
|
84
|
+
playbackRates?: readonly number[];
|
|
79
85
|
}
|
|
80
86
|
export declare function buildVideoNativeAttrs(options: VideoNativeAttrOptions, extraAttrs?: Record<string, unknown>): Record<string, string | number>;
|
|
81
87
|
export declare const MEDIA_SWIPER_DOM_EVENT_MAP: {
|
|
@@ -88,7 +94,7 @@ export declare const MEDIA_SWIPER_DOM_EVENT_MAP: {
|
|
|
88
94
|
};
|
|
89
95
|
export interface MediaSwiperNativeAttrOptions {
|
|
90
96
|
id?: string;
|
|
91
|
-
items?: LxMediaSwiperItem[];
|
|
97
|
+
items?: readonly LxMediaSwiperItem[];
|
|
92
98
|
index?: number;
|
|
93
99
|
initialIndex?: number;
|
|
94
100
|
loop?: boolean;
|
|
@@ -39,6 +39,18 @@ export function buildNavigatorNativeAttrs(options, extraAttrs = {}) {
|
|
|
39
39
|
result.page = options.page;
|
|
40
40
|
if (options.target)
|
|
41
41
|
result.target = options.target;
|
|
42
|
+
if (options.as)
|
|
43
|
+
result.as = options.as;
|
|
44
|
+
if (options.edge)
|
|
45
|
+
result.edge = options.edge;
|
|
46
|
+
if (options.position)
|
|
47
|
+
result.position = options.position;
|
|
48
|
+
if (options.chrome)
|
|
49
|
+
result.chrome = options.chrome;
|
|
50
|
+
if (options.size)
|
|
51
|
+
result.size = JSON.stringify(options.size);
|
|
52
|
+
if (options.interaction)
|
|
53
|
+
result.interaction = JSON.stringify(options.interaction);
|
|
42
54
|
if (options.appId)
|
|
43
55
|
result["app-id"] = options.appId;
|
|
44
56
|
if (options.query)
|
package/dist/navigator.d.ts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
|
-
export type NavigatorOpenType = 'navigate' | 'redirect' | 'navigateBack' | 'reLaunch' | 'switchTab' | 'exit' | '
|
|
2
|
-
export type NavigatorTarget = '
|
|
1
|
+
export type NavigatorOpenType = 'navigate' | 'redirect' | 'navigateBack' | 'reLaunch' | 'switchTab' | 'exit' | 'tel';
|
|
2
|
+
export type NavigatorTarget = 'page' | 'lxapp' | 'url';
|
|
3
|
+
export type NavigatorUrlPlacement = 'external' | 'tab' | 'aside';
|
|
4
|
+
export type NavigatorPagePlacement = 'float' | 'window';
|
|
5
|
+
export type NavigatorPlacement = NavigatorUrlPlacement | NavigatorPagePlacement;
|
|
6
|
+
export type NavigatorEdge = 'left' | 'right' | 'top' | 'bottom';
|
|
7
|
+
export type NavigatorFloatPosition = 'center' | 'top' | 'bottom' | 'left' | 'right';
|
|
8
|
+
export type NavigatorWindowChrome = 'system' | 'full';
|
|
9
|
+
export type NavigatorSizeValue = number | `${number}%`;
|
|
10
|
+
export type NavigatorSize = {
|
|
11
|
+
width?: NavigatorSizeValue;
|
|
12
|
+
height?: NavigatorSizeValue;
|
|
13
|
+
};
|
|
14
|
+
export type NavigatorInteraction = {
|
|
15
|
+
closeButton?: boolean;
|
|
16
|
+
dismiss?: 'tapOutside' | 'manual';
|
|
17
|
+
modal?: boolean;
|
|
18
|
+
};
|
|
3
19
|
export type NavigatorQueryValue = string | number | boolean | null | undefined;
|
|
4
20
|
export type NavigatorQuery = Record<string, NavigatorQueryValue>;
|
|
5
21
|
export type NavigatorChannel = 'release' | 'draft';
|
|
@@ -17,6 +33,12 @@ export type LxNavigatorAttributes = {
|
|
|
17
33
|
'open-type'?: NavigatorOpenType;
|
|
18
34
|
target?: NavigatorTarget;
|
|
19
35
|
delta?: number;
|
|
36
|
+
as?: NavigatorPlacement;
|
|
37
|
+
edge?: NavigatorEdge;
|
|
38
|
+
position?: NavigatorFloatPosition;
|
|
39
|
+
chrome?: NavigatorWindowChrome;
|
|
40
|
+
size?: string;
|
|
41
|
+
interaction?: string;
|
|
20
42
|
'app-id'?: string;
|
|
21
43
|
channel?: NavigatorChannel;
|
|
22
44
|
'target-version'?: string;
|
|
@@ -75,17 +97,15 @@ export declare class LxNavigatorElement extends HTMLElement {
|
|
|
75
97
|
private removeHoverClass;
|
|
76
98
|
private clearHoverTimer;
|
|
77
99
|
private handleClick;
|
|
78
|
-
/**
|
|
79
|
-
* Auto-infer navigation target based on context
|
|
80
|
-
* Priority: explicit target > appId > HTTPS URL > default (self)
|
|
81
|
-
*/
|
|
82
|
-
private inferTarget;
|
|
83
100
|
private navigate;
|
|
84
101
|
private dispatchSuccess;
|
|
85
102
|
private resolveErrorMessage;
|
|
86
103
|
private dispatchFail;
|
|
104
|
+
private bridge;
|
|
87
105
|
private callHost;
|
|
106
|
+
private callSurface;
|
|
88
107
|
private performNavigation;
|
|
108
|
+
private readJsonObject;
|
|
89
109
|
private readQuery;
|
|
90
110
|
private buildPageTarget;
|
|
91
111
|
private buildLxAppTarget;
|
package/dist/navigator.js
CHANGED
|
@@ -43,6 +43,12 @@ export class LxNavigatorElement extends HTMLElement {
|
|
|
43
43
|
"open-type",
|
|
44
44
|
"target",
|
|
45
45
|
"delta",
|
|
46
|
+
"as",
|
|
47
|
+
"edge",
|
|
48
|
+
"position",
|
|
49
|
+
"chrome",
|
|
50
|
+
"size",
|
|
51
|
+
"interaction",
|
|
46
52
|
"app-id",
|
|
47
53
|
"channel",
|
|
48
54
|
"target-version",
|
|
@@ -158,55 +164,33 @@ export class LxNavigatorElement extends HTMLElement {
|
|
|
158
164
|
}
|
|
159
165
|
}
|
|
160
166
|
handleClick(e) {
|
|
167
|
+
var _a;
|
|
161
168
|
e.preventDefault();
|
|
162
|
-
const
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const path = this.getAttribute('path');
|
|
167
|
-
const query = this.getAttribute('query');
|
|
168
|
-
const openType = (this.getAttribute('open-type') || 'navigate');
|
|
169
|
-
const explicitTarget = this.getAttribute('target');
|
|
170
|
-
const delta = parseInt(this.getAttribute('delta') || '1', 10);
|
|
171
|
-
const appId = this.getAttribute('app-id');
|
|
172
|
-
const channel = this.getAttribute('channel');
|
|
173
|
-
const targetVersion = this.getAttribute('target-version');
|
|
174
|
-
const phoneNumber = this.getAttribute('phone-number');
|
|
175
|
-
// Auto-infer target if not explicitly specified
|
|
176
|
-
const target = this.inferTarget(explicitTarget, url, appId);
|
|
177
|
-
void this.navigate({
|
|
169
|
+
const attr = (name) => this.getAttribute(name);
|
|
170
|
+
const url = attr('url') || '';
|
|
171
|
+
const appId = attr('app-id');
|
|
172
|
+
const options = {
|
|
178
173
|
url,
|
|
179
|
-
page,
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
174
|
+
page: attr('page'),
|
|
175
|
+
// Read the removed attribute only to provide a forward-only runtime error
|
|
176
|
+
// for untyped HTML callers instead of silently ignoring it.
|
|
177
|
+
path: attr('path'),
|
|
178
|
+
query: attr('query'),
|
|
179
|
+
openType: (attr('open-type') || 'navigate'),
|
|
180
|
+
target: (_a = attr('target')) !== null && _a !== void 0 ? _a : (appId ? 'lxapp' : url ? 'url' : 'page'),
|
|
181
|
+
delta: parseInt(attr('delta') || '1', 10),
|
|
182
|
+
placement: attr('as'),
|
|
183
|
+
edge: attr('edge'),
|
|
184
|
+
position: attr('position'),
|
|
185
|
+
chrome: attr('chrome'),
|
|
186
|
+
size: attr('size'),
|
|
187
|
+
interaction: attr('interaction'),
|
|
185
188
|
appId,
|
|
186
|
-
channel,
|
|
187
|
-
targetVersion,
|
|
188
|
-
phoneNumber
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Auto-infer navigation target based on context
|
|
193
|
-
* Priority: explicit target > appId > HTTPS URL > default (self)
|
|
194
|
-
*/
|
|
195
|
-
inferTarget(explicitTarget, url, appId) {
|
|
196
|
-
// 1. Explicit target has highest priority
|
|
197
|
-
if (explicitTarget) {
|
|
198
|
-
return explicitTarget;
|
|
199
|
-
}
|
|
200
|
-
// 2. If appId is specified, target is another lxapp
|
|
201
|
-
if (appId) {
|
|
202
|
-
return 'lxapp';
|
|
203
|
-
}
|
|
204
|
-
// 3. If URL starts with http:// or https://, open in browser
|
|
205
|
-
if (/^https?:\/\//i.test(url)) {
|
|
206
|
-
return 'browser';
|
|
207
|
-
}
|
|
208
|
-
// 4. Default: navigate within current lxapp
|
|
209
|
-
return 'self';
|
|
189
|
+
channel: attr('channel'),
|
|
190
|
+
targetVersion: attr('target-version'),
|
|
191
|
+
phoneNumber: attr('phone-number'),
|
|
192
|
+
};
|
|
193
|
+
void this.navigate(options);
|
|
210
194
|
}
|
|
211
195
|
async navigate(options) {
|
|
212
196
|
try {
|
|
@@ -273,17 +257,24 @@ export class LxNavigatorElement extends HTMLElement {
|
|
|
273
257
|
});
|
|
274
258
|
this.dispatchEvent(completeEvent);
|
|
275
259
|
}
|
|
276
|
-
|
|
260
|
+
bridge() {
|
|
277
261
|
const bridge = window.LingXiaBridge;
|
|
278
262
|
if (!bridge || typeof bridge.invoke !== 'function') {
|
|
279
|
-
|
|
263
|
+
throw new Error('LingXiaBridge is not available');
|
|
280
264
|
}
|
|
281
|
-
return bridge
|
|
265
|
+
return bridge;
|
|
266
|
+
}
|
|
267
|
+
async callHost(route, params) {
|
|
268
|
+
await this.bridge().invoke(route, params);
|
|
269
|
+
}
|
|
270
|
+
// Placements run through Logic's lx.surface, which owns surface handles.
|
|
271
|
+
async callSurface(method, params) {
|
|
272
|
+
await this.bridge().raw.call(`surface.${method}`, params);
|
|
282
273
|
}
|
|
283
274
|
async performNavigation(options) {
|
|
284
|
-
const url = options
|
|
275
|
+
const { url, placement } = options;
|
|
285
276
|
const delta = Number.isFinite(options.delta) && options.delta > 0 ? options.delta : 1;
|
|
286
|
-
if (options.path !== null
|
|
277
|
+
if (options.path !== null) {
|
|
287
278
|
throw new Error('path is not supported; pass the configured page name in page');
|
|
288
279
|
}
|
|
289
280
|
if (options.openType === 'tel') {
|
|
@@ -300,39 +291,71 @@ export class LxNavigatorElement extends HTMLElement {
|
|
|
300
291
|
if (options.openType === 'navigateBack') {
|
|
301
292
|
if (options.target === 'lxapp') {
|
|
302
293
|
await this.callHost('navigator.navigateBackApp');
|
|
303
|
-
return;
|
|
304
294
|
}
|
|
305
|
-
|
|
306
|
-
|
|
295
|
+
else {
|
|
296
|
+
await this.callHost('navigation.navigateBack', { delta });
|
|
307
297
|
}
|
|
308
|
-
await this.callHost('navigation.navigateBack', { delta });
|
|
309
298
|
return;
|
|
310
299
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
300
|
+
switch (options.target) {
|
|
301
|
+
case 'url': {
|
|
302
|
+
if (!url) {
|
|
303
|
+
throw new Error('target url requires url');
|
|
304
|
+
}
|
|
305
|
+
if (!placement || placement === 'external') {
|
|
306
|
+
await this.callHost('device.openUrl', { url, target: 'external' });
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
if (placement !== 'tab' && placement !== 'aside') {
|
|
310
|
+
throw new Error(`a url opens as external, tab, or aside; got ${placement}`);
|
|
311
|
+
}
|
|
312
|
+
const surfaceOptions = { as: placement };
|
|
313
|
+
if (options.edge)
|
|
314
|
+
surfaceOptions.edge = options.edge;
|
|
315
|
+
const size = this.readJsonObject('size', options.size);
|
|
316
|
+
if (size)
|
|
317
|
+
surfaceOptions.size = size;
|
|
318
|
+
await this.callSurface('openUrl', { url, options: surfaceOptions });
|
|
319
|
+
return;
|
|
328
320
|
}
|
|
329
|
-
|
|
330
|
-
|
|
321
|
+
case 'lxapp':
|
|
322
|
+
if (!options.appId) {
|
|
323
|
+
throw new Error('target lxapp requires app-id');
|
|
324
|
+
}
|
|
325
|
+
if (placement) {
|
|
326
|
+
throw new Error('as is not supported for target lxapp');
|
|
327
|
+
}
|
|
328
|
+
await this.callHost('navigator.navigateToApp', this.buildLxAppTarget(options));
|
|
329
|
+
return;
|
|
330
|
+
case 'page':
|
|
331
|
+
break;
|
|
332
|
+
default:
|
|
333
|
+
throw new Error(`Unsupported target: ${options.target}`);
|
|
331
334
|
}
|
|
332
335
|
const target = this.buildPageTarget(options);
|
|
333
336
|
if (!target) {
|
|
334
337
|
throw new Error(`${options.openType} requires page`);
|
|
335
338
|
}
|
|
339
|
+
if (placement) {
|
|
340
|
+
if (placement !== 'float' && placement !== 'window') {
|
|
341
|
+
throw new Error(`a page opens as float or window; got ${placement}`);
|
|
342
|
+
}
|
|
343
|
+
const surfaceOptions = { as: placement };
|
|
344
|
+
if (target.query)
|
|
345
|
+
surfaceOptions.query = target.query;
|
|
346
|
+
if (options.position)
|
|
347
|
+
surfaceOptions.position = options.position;
|
|
348
|
+
if (options.chrome)
|
|
349
|
+
surfaceOptions.chrome = options.chrome;
|
|
350
|
+
const size = this.readJsonObject('size', options.size);
|
|
351
|
+
if (size)
|
|
352
|
+
surfaceOptions.size = size;
|
|
353
|
+
const interaction = this.readJsonObject('interaction', options.interaction);
|
|
354
|
+
if (interaction)
|
|
355
|
+
surfaceOptions.interaction = interaction;
|
|
356
|
+
await this.callSurface('openPage', { page: target.page, options: surfaceOptions });
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
336
359
|
switch (options.openType) {
|
|
337
360
|
case 'navigate':
|
|
338
361
|
await this.callHost('navigation.navigateTo', target);
|
|
@@ -346,25 +369,22 @@ export class LxNavigatorElement extends HTMLElement {
|
|
|
346
369
|
case 'reLaunch':
|
|
347
370
|
await this.callHost('navigation.reLaunch', target);
|
|
348
371
|
break;
|
|
349
|
-
case 'openUrl':
|
|
350
|
-
await this.callHost('device.openUrl', {
|
|
351
|
-
url,
|
|
352
|
-
target: options.target === 'self' ? 'self' : 'external'
|
|
353
|
-
});
|
|
354
|
-
break;
|
|
355
372
|
default:
|
|
356
373
|
throw new Error(`Unsupported openType: ${options.openType}`);
|
|
357
374
|
}
|
|
358
375
|
}
|
|
359
|
-
|
|
376
|
+
readJsonObject(name, raw) {
|
|
360
377
|
if (!raw)
|
|
361
378
|
return undefined;
|
|
362
379
|
const parsed = JSON.parse(raw);
|
|
363
380
|
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
364
|
-
throw new Error(
|
|
381
|
+
throw new Error(`${name} must be an object`);
|
|
365
382
|
}
|
|
366
383
|
return parsed;
|
|
367
384
|
}
|
|
385
|
+
readQuery(raw) {
|
|
386
|
+
return this.readJsonObject('query', raw);
|
|
387
|
+
}
|
|
368
388
|
buildPageTarget(options) {
|
|
369
389
|
var _a;
|
|
370
390
|
const page = (_a = options.page) === null || _a === void 0 ? void 0 : _a.trim();
|