@lingxia/elements 0.6.3 → 0.7.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 +2 -1
- package/dist/index.js +2 -1
- package/dist/media_swiper.d.ts +182 -0
- package/dist/media_swiper.js +695 -0
- package/dist/native_component_wrapper_shared.d.ts +35 -0
- package/dist/native_component_wrapper_shared.js +61 -0
- package/dist/video.d.ts +5 -3
- package/dist/video.js +25 -14
- package/package.json +1 -1
- package/src/index.ts +21 -0
- package/src/media_swiper.ts +828 -0
- package/src/native_component_wrapper_shared.ts +70 -0
- package/src/video.ts +28 -15
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { NavigatorEnvVersion, NavigatorOpenType, NavigatorTarget } from "./navigator.js";
|
|
2
2
|
import type { NavigatorQuery } from "./navigator.js";
|
|
3
|
+
import type { LxMediaSwiperItem } from "./media_swiper.js";
|
|
3
4
|
import type { LxVideoQuality } from "./video.js";
|
|
4
5
|
|
|
5
6
|
export function appendDataAttrs(
|
|
@@ -250,3 +251,72 @@ export function buildVideoNativeAttrs(
|
|
|
250
251
|
appendPassthroughAttrs(extraAttrs, extraNativeAttrs);
|
|
251
252
|
return { ...result, ...extraNativeAttrs };
|
|
252
253
|
}
|
|
254
|
+
|
|
255
|
+
export const MEDIA_SWIPER_DOM_EVENT_MAP = {
|
|
256
|
+
onChange: "change",
|
|
257
|
+
onTransitionEnd: "transitionend",
|
|
258
|
+
onEndReached: "endreached",
|
|
259
|
+
onTap: "tap",
|
|
260
|
+
onVideoEnded: "videoended",
|
|
261
|
+
onError: "error",
|
|
262
|
+
} as const;
|
|
263
|
+
|
|
264
|
+
export interface MediaSwiperNativeAttrOptions {
|
|
265
|
+
id?: string;
|
|
266
|
+
items?: LxMediaSwiperItem[];
|
|
267
|
+
index?: number;
|
|
268
|
+
initialIndex?: number;
|
|
269
|
+
loop?: boolean;
|
|
270
|
+
autoplay?: boolean;
|
|
271
|
+
interval?: number;
|
|
272
|
+
animation?: "slide" | "none";
|
|
273
|
+
animationDuration?: number;
|
|
274
|
+
direction?: "horizontal" | "vertical";
|
|
275
|
+
contentRotate?: 0 | 90 | 180 | 270;
|
|
276
|
+
objectFit?: "cover" | "contain" | "fill" | "fit";
|
|
277
|
+
controls?: boolean;
|
|
278
|
+
muted?: boolean;
|
|
279
|
+
dots?: boolean | { color?: string; activeColor?: string };
|
|
280
|
+
swipeEnabled?: boolean;
|
|
281
|
+
peek?: number | { previous?: number; next?: number };
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export function buildMediaSwiperNativeAttrs(
|
|
285
|
+
options: MediaSwiperNativeAttrOptions,
|
|
286
|
+
extraAttrs: Record<string, unknown> = {}
|
|
287
|
+
): Record<string, string | number> {
|
|
288
|
+
const result: Record<string, string | number> = {};
|
|
289
|
+
const explicitId = typeof options.id === "string" ? options.id.trim() : "";
|
|
290
|
+
|
|
291
|
+
if (explicitId.length > 0) result.id = explicitId;
|
|
292
|
+
if (Array.isArray(options.items)) result.items = JSON.stringify(options.items);
|
|
293
|
+
if (typeof options.index === "number") result.index = options.index;
|
|
294
|
+
if (typeof options.initialIndex === "number") result["initial-index"] = options.initialIndex;
|
|
295
|
+
if (options.loop) result.loop = "";
|
|
296
|
+
if (options.autoplay) result.autoplay = "";
|
|
297
|
+
if (typeof options.interval === "number") result.interval = options.interval;
|
|
298
|
+
if (options.animation) result.animation = options.animation;
|
|
299
|
+
if (typeof options.animationDuration === "number") result["animation-duration"] = options.animationDuration;
|
|
300
|
+
if (options.direction) result.direction = options.direction;
|
|
301
|
+
if (typeof options.contentRotate === "number") result["content-rotate"] = options.contentRotate;
|
|
302
|
+
if (options.objectFit) result["object-fit"] = options.objectFit;
|
|
303
|
+
if (options.controls) result.controls = "";
|
|
304
|
+
if (options.muted === false) result.muted = "false";
|
|
305
|
+
if (options.muted === true) result.muted = "";
|
|
306
|
+
if (options.dots === true) result.dots = "";
|
|
307
|
+
if (options.dots && typeof options.dots === "object") result.dots = JSON.stringify(options.dots);
|
|
308
|
+
if (options.swipeEnabled === false) result["swipe-enabled"] = "false";
|
|
309
|
+
if (typeof options.peek === "number" && options.peek > 0) {
|
|
310
|
+
result.peek = options.peek;
|
|
311
|
+
} else if (options.peek && typeof options.peek === "object") {
|
|
312
|
+
const previous = Math.max(0, Number(options.peek.previous) || 0);
|
|
313
|
+
const next = Math.max(0, Number(options.peek.next) || 0);
|
|
314
|
+
if (previous > 0 || next > 0) {
|
|
315
|
+
result.peek = JSON.stringify({ previous, next });
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const extraNativeAttrs: Record<string, string> = {};
|
|
320
|
+
appendPassthroughAttrs(extraAttrs, extraNativeAttrs);
|
|
321
|
+
return { ...result, ...extraNativeAttrs };
|
|
322
|
+
}
|
package/src/video.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type LxVideoAttributes = {
|
|
|
18
18
|
src?: string;
|
|
19
19
|
poster?: string;
|
|
20
20
|
objectFit?: "cover" | "contain" | "fill" | "fit";
|
|
21
|
-
|
|
21
|
+
contentRotate?: 0 | 90 | 180 | 270;
|
|
22
22
|
autoplay?: boolean;
|
|
23
23
|
loop?: boolean;
|
|
24
24
|
muted?: boolean;
|
|
@@ -67,7 +67,7 @@ export class LxVideoElement extends HTMLElement {
|
|
|
67
67
|
"src",
|
|
68
68
|
"poster",
|
|
69
69
|
"object-fit",
|
|
70
|
-
"rotate",
|
|
70
|
+
"content-rotate",
|
|
71
71
|
"autoplay",
|
|
72
72
|
"loop",
|
|
73
73
|
"muted",
|
|
@@ -151,6 +151,18 @@ export class LxVideoElement extends HTMLElement {
|
|
|
151
151
|
return this._pageBindings;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
set src(value: string | null | undefined) {
|
|
155
|
+
if (value == null) {
|
|
156
|
+
this.removeAttribute("src");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
this.setAttribute("src", String(value));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
get src(): string | null {
|
|
163
|
+
return this.getAttribute("src");
|
|
164
|
+
}
|
|
165
|
+
|
|
154
166
|
private dataAttrToDatasetKey(attr: string): string {
|
|
155
167
|
const raw = attr.slice(5).trim();
|
|
156
168
|
if (!raw) return "";
|
|
@@ -186,23 +198,24 @@ export class LxVideoElement extends HTMLElement {
|
|
|
186
198
|
self[propName] = value;
|
|
187
199
|
}
|
|
188
200
|
|
|
189
|
-
set
|
|
201
|
+
set contentRotate(value: unknown) {
|
|
190
202
|
const normalized = this.parseRotateValue(value);
|
|
191
203
|
if (normalized === undefined) {
|
|
192
|
-
this.removeAttribute("rotate");
|
|
204
|
+
this.removeAttribute("content-rotate");
|
|
193
205
|
return;
|
|
194
206
|
}
|
|
195
|
-
this.setAttribute("rotate", String(normalized));
|
|
207
|
+
this.setAttribute("content-rotate", String(normalized));
|
|
196
208
|
}
|
|
197
209
|
|
|
198
|
-
get
|
|
199
|
-
return this.parseRotateValue(this.getAttribute("rotate"));
|
|
210
|
+
get contentRotate(): 0 | 90 | 180 | 270 | undefined {
|
|
211
|
+
return this.parseRotateValue(this.getAttribute("content-rotate"));
|
|
200
212
|
}
|
|
201
213
|
|
|
202
214
|
connectedCallback() {
|
|
203
215
|
// React may set custom-element properties before upgrade; replay through setters.
|
|
204
216
|
this.upgradeProperty("pageBindings");
|
|
205
|
-
this.upgradeProperty("
|
|
217
|
+
this.upgradeProperty("contentRotate");
|
|
218
|
+
this.upgradeProperty("src");
|
|
206
219
|
this.upgradeProperty("onplayrequest");
|
|
207
220
|
this.upgradeProperty("onplay");
|
|
208
221
|
this.upgradeProperty("onplaying");
|
|
@@ -301,8 +314,8 @@ export class LxVideoElement extends HTMLElement {
|
|
|
301
314
|
}
|
|
302
315
|
}
|
|
303
316
|
if (!this.isConnected) return;
|
|
304
|
-
// Keep rotate/object-fit updates immediate across all native platforms.
|
|
305
|
-
const forcePropsUpdate = name === "rotate" || name === "object-fit" || name === "objectfit";
|
|
317
|
+
// Keep content-rotate/object-fit updates immediate across all native platforms.
|
|
318
|
+
const forcePropsUpdate = name === "content-rotate" || name === "object-fit" || name === "objectfit";
|
|
306
319
|
if (isHarmony() && forcePropsUpdate) {
|
|
307
320
|
// Bridge callbacks can race on Harmony; force a deterministic embed recreate for visual props.
|
|
308
321
|
this.forceHarmonyEmbedRecreate = true;
|
|
@@ -430,13 +443,13 @@ export class LxVideoElement extends HTMLElement {
|
|
|
430
443
|
? (progressBarAttr !== null && progressBarAttr !== "false")
|
|
431
444
|
: (progressBarAttr !== "false");
|
|
432
445
|
|
|
433
|
-
const
|
|
434
|
-
const
|
|
446
|
+
const rawContentRotate = this.getAttribute("content-rotate");
|
|
447
|
+
const validContentRotate = this.parseRotateValue(rawContentRotate);
|
|
435
448
|
const pageFuncBindings = this._pageBindings;
|
|
436
449
|
const dataset = this.collectDataset();
|
|
437
450
|
const clearProps: string[] = [];
|
|
438
|
-
if (
|
|
439
|
-
clearProps.push("
|
|
451
|
+
if (rawContentRotate === null || validContentRotate === undefined) {
|
|
452
|
+
clearProps.push("contentRotate");
|
|
440
453
|
}
|
|
441
454
|
if (rawObjectFit == null || objectFit === undefined) {
|
|
442
455
|
clearProps.push("objectFit");
|
|
@@ -453,7 +466,7 @@ export class LxVideoElement extends HTMLElement {
|
|
|
453
466
|
live: isLive,
|
|
454
467
|
volume: !Number.isNaN(volume ?? NaN) ? volume : undefined,
|
|
455
468
|
objectFit,
|
|
456
|
-
|
|
469
|
+
contentRotate: validContentRotate,
|
|
457
470
|
...(clearProps.length > 0 ? { __clearProps: clearProps } : {}),
|
|
458
471
|
qualities,
|
|
459
472
|
playbackRates,
|