@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/picker.d.ts CHANGED
@@ -1,5 +1,10 @@
1
- export type LxPickerColumn = string[];
2
- export type LxPickerCascadingColumns = [string[], Record<string, string[]>];
1
+ export type LxPickerColumn = readonly string[];
2
+ export type LxPickerCascadingColumns = readonly [
3
+ readonly string[],
4
+ Readonly<Record<string, readonly string[]>>
5
+ ];
6
+ /** Selector or multi-column columns, or cascading keys and their options. */
7
+ export type LxPickerColumns = readonly LxPickerColumn[] | LxPickerCascadingColumns;
3
8
  type LxPickerViewEventHandler = (e: LxPickerEvent) => void;
4
9
  export interface LxPickerEventDetail {
5
10
  index?: number | number[];
@@ -13,7 +18,7 @@ export interface LxPickerEvent extends CustomEvent<LxPickerEventDetail> {
13
18
  export type LxPickerAttributes = {
14
19
  id?: string;
15
20
  mode?: 'selector' | 'multiSelector' | 'cascading' | 'date' | 'time';
16
- columns?: LxPickerColumn[] | LxPickerCascadingColumns;
21
+ columns?: LxPickerColumns;
17
22
  defaultIndex?: number | number[];
18
23
  value?: string;
19
24
  start?: string;
@@ -30,7 +35,6 @@ export type LxPickerAttributes = {
30
35
  ref?: any;
31
36
  onChange?: LxPickerViewEventHandler;
32
37
  onScroll?: LxPickerViewEventHandler;
33
- pageBindings?: Record<string, string>;
34
38
  };
35
39
  declare global {
36
40
  namespace JSX {
@@ -46,7 +50,6 @@ export declare class LxPickerElement extends HTMLElement {
46
50
  private unregister?;
47
51
  private _handlers;
48
52
  private rawHandlers;
49
- private _pageBindings;
50
53
  private harmonyEmbed?;
51
54
  private lastHarmonyProps?;
52
55
  private webCleanup?;
@@ -54,8 +57,6 @@ export declare class LxPickerElement extends HTMLElement {
54
57
  private removeLayoutInvalidationListener?;
55
58
  private readonly layoutInvalidationListener;
56
59
  private upgradeProperty;
57
- set pageBindings(bindings: Record<string, string>);
58
- get pageBindings(): Record<string, string>;
59
60
  connectedCallback(): void;
60
61
  disconnectedCallback(): void;
61
62
  attributeChangedCallback(name: string): void;
@@ -65,8 +66,6 @@ export declare class LxPickerElement extends HTMLElement {
65
66
  private shouldRefreshForAttribute;
66
67
  private startAttrObserver;
67
68
  private stopAttrObserver;
68
- private dataAttrToDatasetKey;
69
- private collectDataset;
70
69
  private mountPicker;
71
70
  set onchange(cb: EventListener | null);
72
71
  get onchange(): EventListener | null;
package/dist/picker.js CHANGED
@@ -19,7 +19,6 @@ export class LxPickerElement extends HTMLElement {
19
19
  this.mounted = false;
20
20
  this._handlers = {};
21
21
  this.rawHandlers = {};
22
- this._pageBindings = {};
23
22
  this.layoutInvalidationListener = {
24
23
  handleEvent: () => {
25
24
  if (!this.isConnected || isHarmony() || !hasNativePicker())
@@ -54,17 +53,7 @@ export class LxPickerElement extends HTMLElement {
54
53
  delete self[propName];
55
54
  self[propName] = value;
56
55
  }
57
- set pageBindings(bindings) {
58
- this._pageBindings = bindings !== null && bindings !== void 0 ? bindings : {};
59
- if (this.isConnected) {
60
- this.mountPicker();
61
- }
62
- }
63
- get pageBindings() {
64
- return this._pageBindings;
65
- }
66
56
  connectedCallback() {
67
- this.upgradeProperty("pageBindings");
68
57
  this.upgradeProperty("onchange");
69
58
  this.componentId = ensureComponentId(this, "lx-picker", this.componentId);
70
59
  if (!this.componentId)
@@ -203,46 +192,10 @@ export class LxPickerElement extends HTMLElement {
203
192
  this.attrObserver.disconnect();
204
193
  this.attrObserver = undefined;
205
194
  }
206
- dataAttrToDatasetKey(attr) {
207
- const raw = attr.slice(5).trim();
208
- if (!raw)
209
- return "";
210
- const parts = raw.split("-").filter(Boolean);
211
- if (parts.length === 0)
212
- return "";
213
- return parts
214
- .map((segment, index) => {
215
- if (index === 0)
216
- return segment.toLowerCase();
217
- return segment.charAt(0).toUpperCase() + segment.slice(1);
218
- })
219
- .join("");
220
- }
221
- collectDataset() {
222
- const dataset = {};
223
- const attrs = this.getAttributeNames();
224
- for (const attr of attrs) {
225
- if (!attr.startsWith("data-"))
226
- continue;
227
- const key = this.dataAttrToDatasetKey(attr);
228
- if (!key)
229
- continue;
230
- const value = this.getAttribute(attr);
231
- if (value == null)
232
- continue;
233
- dataset[key] = value;
234
- }
235
- return dataset;
236
- }
237
195
  async mountPicker() {
238
196
  if (!this.componentId)
239
197
  return;
240
198
  const props = this.collectProps();
241
- const dataset = this.collectDataset();
242
- props.dataset = dataset;
243
- props.datasetJson = JSON.stringify(dataset);
244
- props.pageFuncBindings = this._pageBindings;
245
- props.pageFuncBindingsJson = JSON.stringify(this._pageBindings);
246
199
  const { rect, cornerRadius } = measureElement(this);
247
200
  if (isHarmony()) {
248
201
  this.ensureHarmonyEmbed(rect, props, cornerRadius);
package/dist/video.d.ts CHANGED
@@ -69,8 +69,8 @@ export type LxVideoAttributes = {
69
69
  progressBar?: boolean;
70
70
  live?: boolean;
71
71
  volume?: string | number;
72
- qualities?: LxVideoQuality[];
73
- playbackRates?: number[];
72
+ qualities?: readonly LxVideoQuality[];
73
+ playbackRates?: readonly number[];
74
74
  className?: string;
75
75
  style?: unknown;
76
76
  ref?: unknown;
@@ -88,7 +88,6 @@ export type LxVideoAttributes = {
88
88
  onQualityChange?: (event: CustomEvent<LxVideoEventPayloads["onQualityChange"]>) => void;
89
89
  onRateChange?: (event: CustomEvent<LxVideoEventPayloads["onRateChange"]>) => void;
90
90
  onVolumeChange?: (event: CustomEvent<LxVideoEventPayloads["onVolumeChange"]>) => void;
91
- pageBindings?: Record<string, string>;
92
91
  };
93
92
  declare global {
94
93
  namespace JSX {
@@ -110,11 +109,6 @@ export declare class LxVideoElement extends HTMLElement {
110
109
  private unregister?;
111
110
  private handlers;
112
111
  private rawHandlers;
113
- private bindings;
114
- set pageBindings(bindings: Record<string, string>);
115
- get pageBindings(): Record<string, string>;
116
- get pageFuncBindings(): Record<string, string>;
117
- get pageFuncBindingsJson(): string;
118
112
  set src(value: string | null | undefined);
119
113
  get src(): string | null;
120
114
  set contentRotate(value: unknown);
package/dist/video.js CHANGED
@@ -15,7 +15,6 @@ export class LxVideoElement extends HTMLElement {
15
15
  this.islandPlaybackIdle = false;
16
16
  this.handlers = {};
17
17
  this.rawHandlers = {};
18
- this.bindings = {};
19
18
  }
20
19
  static get observedAttributes() {
21
20
  return [
@@ -35,20 +34,6 @@ export class LxVideoElement extends HTMLElement {
35
34
  "playback-rates",
36
35
  ];
37
36
  }
38
- set pageBindings(bindings) {
39
- this.bindings = bindings !== null && bindings !== void 0 ? bindings : {};
40
- if (this.isConnected)
41
- this.requestRootCompile();
42
- }
43
- get pageBindings() {
44
- return this.bindings;
45
- }
46
- get pageFuncBindings() {
47
- return this.bindings;
48
- }
49
- get pageFuncBindingsJson() {
50
- return JSON.stringify(this.bindings);
51
- }
52
37
  set src(value) {
53
38
  if (value == null) {
54
39
  this.removeAttribute("src");
@@ -74,7 +59,6 @@ export class LxVideoElement extends HTMLElement {
74
59
  }
75
60
  connectedCallback() {
76
61
  for (const property of [
77
- "pageBindings",
78
62
  "contentRotate",
79
63
  "src",
80
64
  "onplayrequest",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingxia/elements",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "private": false,
5
5
  "description": "LingXia custom elements — native-backed web components for LxApp pages",
6
6
  "type": "module",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "scripts": {
17
17
  "build": "npm --prefix ../lingxia-bridge run build:types && tsc -p tsconfig.json",
18
- "test:inline-native": "npm run build && node tests/inline-native-structure.mjs && node tests/inline-native-unwrap.mjs && node tests/inline-native-runtime.mjs && node tests/inline-native-events.mjs && node tests/inline-native-style.mjs && node tests/video-events.mjs && node tests/inline-native-identity.mjs && node tests/inline-native-contract.mjs",
18
+ "test:inline-native": "npm run build && node tests/inline-native-structure.mjs && node tests/inline-native-unwrap.mjs && node tests/inline-native-runtime.mjs && node tests/inline-native-events.mjs && node tests/inline-native-style.mjs && node tests/video-events.mjs && node tests/navigator-routing.mjs && node tests/inline-native-identity.mjs && node tests/inline-native-contract.mjs",
19
19
  "clean": "rm -rf dist",
20
20
  "prepublishOnly": "npm run build"
21
21
  },
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@ export {
4
4
  type LxVideoAttributes,
5
5
  type LxVideoEventPayloads,
6
6
  type LxVideoEventHandlers,
7
+ type LxVideoQuality,
7
8
  } from "./video.js";
8
9
 
9
10
  export {
@@ -11,6 +12,9 @@ export {
11
12
  LxMediaSwiperElement,
12
13
  type LxMediaSwiperAttributes,
13
14
  type LxMediaSwiperItem,
15
+ type LxMediaSwiperEventPayloads,
16
+ type LxMediaSwiperEventHandlers,
17
+ type LxMediaSwiperHandle,
14
18
  type LxMediaSwiperChangeEvent,
15
19
  type LxMediaSwiperChangeEventDetail,
16
20
  type LxMediaSwiperTransitionEndEvent,
@@ -31,6 +35,7 @@ export {
31
35
  type LxPickerAttributes,
32
36
  type LxPickerColumn,
33
37
  type LxPickerCascadingColumns,
38
+ type LxPickerColumns,
34
39
  type LxPickerEvent,
35
40
  type LxPickerEventDetail,
36
41
  } from "./picker.js";
@@ -41,6 +46,15 @@ export {
41
46
  type LxNavigatorAttributes,
42
47
  type LxNavigatorEvent,
43
48
  type NavigatorChannel,
49
+ type NavigatorEdge,
50
+ type NavigatorFloatPosition,
51
+ type NavigatorInteraction,
52
+ type NavigatorPagePlacement,
53
+ type NavigatorPlacement,
54
+ type NavigatorSize,
55
+ type NavigatorSizeValue,
56
+ type NavigatorUrlPlacement,
57
+ type NavigatorWindowChrome,
44
58
  type NavigatorOpenType,
45
59
  type NavigatorQuery,
46
60
  type NavigatorQueryValue,
@@ -687,7 +687,6 @@ export function isFallbackElement(element: Element): boolean {
687
687
 
688
688
  function readElementProps(element: Element): Record<string, unknown> {
689
689
  const props: Record<string, unknown> = {};
690
- const dataset: Record<string, string> = {};
691
690
  for (const attr of Array.from(element.attributes)) {
692
691
  if (attr.name === "data-lx-native-measuring" || attr.name === "data-lx-native-paint-hidden") continue;
693
692
  const name = attr.name;
@@ -695,10 +694,6 @@ function readElementProps(element: Element): Record<string, unknown> {
695
694
  continue;
696
695
  }
697
696
  props[camelize(name)] = attr.value;
698
- if (name.startsWith("data-") && name !== "data-lx-component-id") {
699
- const key = camelize(name.slice(5));
700
- if (key) dataset[key] = attr.value;
701
- }
702
697
  if (name.startsWith("aria-")) {
703
698
  props[name] = attr.value;
704
699
  }
@@ -730,8 +725,6 @@ function readElementProps(element: Element): Record<string, unknown> {
730
725
  "muted",
731
726
  "volume",
732
727
  "progressBar",
733
- "pageFuncBindings",
734
- "pageFuncBindingsJson",
735
728
  "intent",
736
729
  "emphasis",
737
730
  "size",
@@ -754,10 +747,6 @@ function readElementProps(element: Element): Record<string, unknown> {
754
747
  props[key] = anyEl[key];
755
748
  }
756
749
  }
757
- if (Object.keys(dataset).length > 0) {
758
- props.dataset = dataset;
759
- props.datasetJson = JSON.stringify(dataset);
760
- }
761
750
  const ariaLabel = element.getAttribute("aria-label");
762
751
  if (ariaLabel) {
763
752
  props["aria-label"] = ariaLabel;
@@ -7,8 +7,6 @@ import { ensureComponentId, NativeComponentUpdateState, iOSNativeComponentHelper
7
7
  import { measureElement } from "./dom.js";
8
8
  import { isAndroid, isHarmony, isIOS } from "./platform.js";
9
9
 
10
- type LxMediaSwiperEventHandler = (e: Event) => void;
11
-
12
10
  export type LxMediaSwiperItem =
13
11
  | {
14
12
  id?: string;
@@ -66,6 +64,28 @@ export type LxMediaSwiperItemEvent = CustomEvent<LxMediaSwiperEventDetail>;
66
64
  export type LxMediaSwiperEndReachedEvent = CustomEvent<LxMediaSwiperEndReachedEventDetail>;
67
65
  export type LxMediaSwiperErrorEvent = CustomEvent<LxMediaSwiperErrorEventDetail>;
68
66
 
67
+ /** What each framework callback receives: the event's `detail`. */
68
+ export interface LxMediaSwiperEventPayloads {
69
+ onChange: LxMediaSwiperChangeEventDetail;
70
+ onTransitionEnd: LxMediaSwiperTransitionEndEventDetail;
71
+ onEndReached: LxMediaSwiperEndReachedEventDetail;
72
+ onTap: LxMediaSwiperEventDetail;
73
+ onVideoEnded: LxMediaSwiperEventDetail;
74
+ onError: LxMediaSwiperErrorEventDetail;
75
+ }
76
+
77
+ /** The framework callbacks: each receives its event's payload. */
78
+ export type LxMediaSwiperEventHandlers = {
79
+ [K in keyof LxMediaSwiperEventPayloads]?: (payload: LxMediaSwiperEventPayloads[K]) => void;
80
+ };
81
+
82
+ /** Imperative control of a mounted swiper (React ref, Vue template ref). */
83
+ export interface LxMediaSwiperHandle {
84
+ next(): void;
85
+ previous(): void;
86
+ goToIndex(index: number): void;
87
+ }
88
+
69
89
  /**
70
90
  * Peek leaves part of the previous and next pages visible alongside the current
71
91
  * page so users get a hint that more content exists. A single `number` applies
@@ -81,7 +101,7 @@ export type LxMediaSwiperPeek = number | { previous?: number; next?: number };
81
101
 
82
102
  export type LxMediaSwiperAttributes = {
83
103
  id?: string;
84
- items?: LxMediaSwiperItem[];
104
+ items?: readonly LxMediaSwiperItem[];
85
105
  index?: number;
86
106
  initialIndex?: number;
87
107
  loop?: boolean;
@@ -100,13 +120,12 @@ export type LxMediaSwiperAttributes = {
100
120
  className?: string;
101
121
  style?: any;
102
122
  ref?: any;
103
- onChange?: LxMediaSwiperEventHandler;
104
- onTransitionEnd?: LxMediaSwiperEventHandler;
105
- onEndReached?: LxMediaSwiperEventHandler;
106
- onTap?: LxMediaSwiperEventHandler;
107
- onVideoEnded?: LxMediaSwiperEventHandler;
108
- onError?: LxMediaSwiperEventHandler;
109
- pageBindings?: Record<string, string>;
123
+ onChange?: (event: LxMediaSwiperChangeEvent) => void;
124
+ onTransitionEnd?: (event: LxMediaSwiperTransitionEndEvent) => void;
125
+ onEndReached?: (event: LxMediaSwiperEndReachedEvent) => void;
126
+ onTap?: (event: LxMediaSwiperItemEvent) => void;
127
+ onVideoEnded?: (event: LxMediaSwiperItemEvent) => void;
128
+ onError?: (event: LxMediaSwiperErrorEvent) => void;
110
129
  };
111
130
 
112
131
  type ObjectFit = "cover" | "contain" | "fill" | "fit";
@@ -129,7 +148,7 @@ declare global {
129
148
  }
130
149
  }
131
150
 
132
- export class LxMediaSwiperElement extends HTMLElement {
151
+ export class LxMediaSwiperElement extends HTMLElement implements LxMediaSwiperHandle {
133
152
  static get observedAttributes() {
134
153
  return [
135
154
  "id",
@@ -163,7 +182,6 @@ export class LxMediaSwiperElement extends HTMLElement {
163
182
  private iOSHelper?: iOSNativeComponentHelper;
164
183
  private rawHandlers: Record<string, EventListenerOrEventListenerObject> = {};
165
184
  private handlers: Record<string, EventListenerOrEventListenerObject> = {};
166
- private _pageBindings: Record<string, string> = {};
167
185
  // Monotonic command counter used as the Harmony bridge fallback. Harmony's
168
186
  // Web.onNativeEmbedDataInfo channel only delivers attribute-derived props,
169
187
  // so imperative API calls have to piggyback into a prop the Builder polls.
@@ -179,7 +197,7 @@ export class LxMediaSwiperElement extends HTMLElement {
179
197
  private harmonyEmbed?: HTMLEmbedElement;
180
198
  private lastHarmonyProps?: string;
181
199
 
182
- set items(value: LxMediaSwiperItem[] | string | null | undefined) {
200
+ set items(value: readonly LxMediaSwiperItem[] | string | null | undefined) {
183
201
  if (typeof value === "string") {
184
202
  const trimmed = value.trim();
185
203
  if (trimmed.length === 0) {
@@ -237,23 +255,6 @@ export class LxMediaSwiperElement extends HTMLElement {
237
255
  return this.parseRotate(this.getAttribute("content-rotate"));
238
256
  }
239
257
 
240
- set pageBindings(bindings: Record<string, string>) {
241
- this.setPageBindings(bindings);
242
- }
243
-
244
- get pageBindings(): Record<string, string> {
245
- return this._pageBindings;
246
- }
247
-
248
- set pageFuncBindings(bindings: Record<string, string>) {
249
- this.setPageBindings(bindings);
250
- }
251
-
252
- setPageBindings(bindings: Record<string, string>) {
253
- this._pageBindings = bindings ?? {};
254
- if (this.isConnected) this.mountOrUpdate(true);
255
- }
256
-
257
258
  next(): void {
258
259
  this.sendCommand("next");
259
260
  }
@@ -272,8 +273,6 @@ export class LxMediaSwiperElement extends HTMLElement {
272
273
  this.upgradeProperty("index");
273
274
  this.upgradeProperty("initialIndex");
274
275
  this.upgradeProperty("contentRotate");
275
- this.upgradeProperty("pageBindings");
276
- this.upgradeProperty("pageFuncBindings");
277
276
  for (const prop of Object.keys(EVENT_MAP)) this.upgradeProperty(prop);
278
277
 
279
278
  this.componentId = ensureComponentId(this, "lx-media-swiper", this.componentId);
@@ -377,7 +376,6 @@ export class LxMediaSwiperElement extends HTMLElement {
377
376
  private collectProps(): Record<string, unknown> {
378
377
  const objectFit = this.parseObjectFit(this.getAttribute("object-fit"));
379
378
  const dots = this.parseDots();
380
- const dataset = this.collectDataset();
381
379
  // Always emit a normalised peek object so removing the attribute (or setting it
382
380
  // to 0) propagates as an explicit reset. JSON.stringify would drop `undefined`,
383
381
  // which makes native think peek hasn't changed and keep the old padding.
@@ -399,10 +397,6 @@ export class LxMediaSwiperElement extends HTMLElement {
399
397
  dots,
400
398
  swipeEnabled: this.getAttribute("swipe-enabled") !== "false",
401
399
  peek,
402
- pageFuncBindings: this._pageBindings,
403
- pageFuncBindingsJson: JSON.stringify(this._pageBindings),
404
- dataset,
405
- datasetJson: JSON.stringify(dataset),
406
400
  };
407
401
  return props;
408
402
  }
@@ -809,16 +803,6 @@ export class LxMediaSwiperElement extends HTMLElement {
809
803
  }
810
804
  }
811
805
 
812
- private collectDataset(): Record<string, string> {
813
- const dataset: Record<string, string> = {};
814
- for (const attr of this.getAttributeNames()) {
815
- if (!attr.startsWith("data-")) continue;
816
- const key = attr.slice(5).replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());
817
- const value = this.getAttribute(attr);
818
- if (key && value != null) dataset[key] = value;
819
- }
820
- return dataset;
821
- }
822
806
  }
823
807
 
824
808
  export function registerMediaSwiperComponent() {
@@ -1,4 +1,15 @@
1
- import type { NavigatorChannel, NavigatorOpenType, NavigatorTarget } from "./navigator.js";
1
+ import type { LxPickerCascadingColumns, LxPickerColumns } from "./picker.js";
2
+ import type {
3
+ NavigatorChannel,
4
+ NavigatorEdge,
5
+ NavigatorFloatPosition,
6
+ NavigatorInteraction,
7
+ NavigatorOpenType,
8
+ NavigatorPlacement,
9
+ NavigatorSize,
10
+ NavigatorTarget,
11
+ NavigatorWindowChrome,
12
+ } from "./navigator.js";
2
13
  import type { NavigatorQuery } from "./navigator.js";
3
14
  import type { LxMediaSwiperItem } from "./media_swiper.js";
4
15
  import type { LxVideoQuality, LxVideoEventPayloads } from "./video.js";
@@ -37,6 +48,12 @@ export interface NavigatorNativeAttrOptions {
37
48
  openType?: NavigatorOpenType;
38
49
  target?: NavigatorTarget;
39
50
  delta?: number;
51
+ as?: NavigatorPlacement;
52
+ edge?: NavigatorEdge;
53
+ position?: NavigatorFloatPosition;
54
+ chrome?: NavigatorWindowChrome;
55
+ size?: NavigatorSize;
56
+ interaction?: NavigatorInteraction;
40
57
  appId?: string;
41
58
  query?: NavigatorQuery;
42
59
  channel?: NavigatorChannel;
@@ -64,6 +81,12 @@ export function buildNavigatorNativeAttrs(
64
81
  if (options.url) result.url = options.url;
65
82
  if (options.page) result.page = options.page;
66
83
  if (options.target) result.target = options.target;
84
+ if (options.as) result.as = options.as;
85
+ if (options.edge) result.edge = options.edge;
86
+ if (options.position) result.position = options.position;
87
+ if (options.chrome) result.chrome = options.chrome;
88
+ if (options.size) result.size = JSON.stringify(options.size);
89
+ if (options.interaction) result.interaction = JSON.stringify(options.interaction);
67
90
  if (options.appId) result["app-id"] = options.appId;
68
91
  if (options.query) result.query = JSON.stringify(options.query);
69
92
  if (options.channel) result.channel = options.channel;
@@ -74,19 +97,18 @@ export function buildNavigatorNativeAttrs(
74
97
  return result;
75
98
  }
76
99
 
77
- export type PickerColumns = string[][] | [string[], Record<string, string[]>];
78
- export type PickerValue = string | string[] | undefined;
100
+ export type PickerValue = string | readonly string[] | undefined;
79
101
  export type PickerFields = "year" | "month" | "day" | "range";
80
102
 
81
103
  export interface PickerNativeAttrOptions {
82
104
  id?: string;
83
- columns?: PickerColumns;
105
+ columns?: LxPickerColumns;
84
106
  mode?: "date" | "time";
85
107
  start?: string;
86
108
  end?: string;
87
109
  fields?: PickerFields;
88
- modelValue?: string | string[];
89
- value?: string | string[];
110
+ modelValue?: string | readonly string[];
111
+ value?: string | readonly string[];
90
112
  cancelText?: string;
91
113
  cancelTextColor?: string;
92
114
  cancelButtonColor?: string;
@@ -99,16 +121,16 @@ export function isPickerDateMode(mode?: "date" | "time"): boolean {
99
121
  return mode === "date" || mode === "time";
100
122
  }
101
123
 
102
- export function isPickerCascading(columns?: PickerColumns): columns is [string[], Record<string, string[]>] {
124
+ export function isPickerCascading(columns?: LxPickerColumns): columns is LxPickerCascadingColumns {
103
125
  return !!columns && columns.length === 2 && typeof columns[1] === "object" && !Array.isArray(columns[1]);
104
126
  }
105
127
 
106
- export function isPickerSingle(columns?: PickerColumns): boolean {
128
+ export function isPickerSingle(columns?: LxPickerColumns): boolean {
107
129
  return !!columns && columns.length === 1;
108
130
  }
109
131
 
110
132
  export function getPickerIndexFromValue(
111
- columns: PickerColumns | undefined,
133
+ columns: LxPickerColumns | undefined,
112
134
  value: PickerValue
113
135
  ): number | number[] {
114
136
  if (!columns) return 0;
@@ -132,7 +154,7 @@ export function getPickerIndexFromValue(
132
154
  }
133
155
 
134
156
  export function getPickerValueFromIndex(
135
- columns: PickerColumns | undefined,
157
+ columns: LxPickerColumns | undefined,
136
158
  index: number | number[]
137
159
  ): string | string[] {
138
160
  if (!columns) return "";
@@ -222,8 +244,8 @@ export interface VideoNativeAttrOptions {
222
244
  progressBar?: boolean;
223
245
  live?: boolean;
224
246
  volume?: string | number;
225
- qualities?: LxVideoQuality[];
226
- playbackRates?: number[];
247
+ qualities?: readonly LxVideoQuality[];
248
+ playbackRates?: readonly number[];
227
249
  }
228
250
 
229
251
  export function buildVideoNativeAttrs(
@@ -263,7 +285,7 @@ export const MEDIA_SWIPER_DOM_EVENT_MAP = {
263
285
 
264
286
  export interface MediaSwiperNativeAttrOptions {
265
287
  id?: string;
266
- items?: LxMediaSwiperItem[];
288
+ items?: readonly LxMediaSwiperItem[];
267
289
  index?: number;
268
290
  initialIndex?: number;
269
291
  loop?: boolean;