@lingxia/vue 0.18.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.
@@ -4,6 +4,9 @@ import {
4
4
  buildMediaSwiperNativeAttrs,
5
5
  MEDIA_SWIPER_DOM_EVENT_MAP,
6
6
  registerMediaSwiperComponent,
7
+ unwrapNativeEventPayload,
8
+ type LxMediaSwiperEventPayloads as Payloads,
9
+ type LxMediaSwiperHandle,
7
10
  } from '@lingxia/elements';
8
11
  import { bindElementEvents, unbindElementEvents } from './text_component_shared.js';
9
12
  import type { LxMediaSwiperProps } from './types.js';
@@ -23,31 +26,31 @@ const props = withDefaults(defineProps<LxMediaSwiperProps>(), {
23
26
  const attrs = useAttrs();
24
27
 
25
28
  const emit = defineEmits<{
26
- change: [e: Event];
27
- transitionEnd: [e: Event];
28
- endReached: [e: Event];
29
- tap: [e: Event];
30
- videoEnded: [e: Event];
31
- error: [e: Event];
29
+ change: [payload: Payloads['onChange']];
30
+ transitionEnd: [payload: Payloads['onTransitionEnd']];
31
+ endReached: [payload: Payloads['onEndReached']];
32
+ tap: [payload: Payloads['onTap']];
33
+ videoEnded: [payload: Payloads['onVideoEnded']];
34
+ error: [payload: Payloads['onError']];
32
35
  }>();
33
36
 
34
37
  if (typeof window !== 'undefined') {
35
38
  registerMediaSwiperComponent();
36
39
  }
37
40
 
38
- const elementRef = ref<HTMLElement | null>(null);
41
+ const elementRef = ref<(HTMLElement & LxMediaSwiperHandle) | null>(null);
39
42
  const vueId = useId();
40
43
  let boundElement: HTMLElement | null = null;
41
44
 
42
45
  const resolvedId = computed(() => props.id || `lx-media-swiper-${vueId.replace(/[:]/g, '')}`);
43
46
 
44
47
  const eventListeners: Record<string, EventListenerObject> = {
45
- [MEDIA_SWIPER_DOM_EVENT_MAP.onChange]: { handleEvent: (event: Event) => emit('change', event) },
46
- [MEDIA_SWIPER_DOM_EVENT_MAP.onTransitionEnd]: { handleEvent: (event: Event) => emit('transitionEnd', event) },
47
- [MEDIA_SWIPER_DOM_EVENT_MAP.onEndReached]: { handleEvent: (event: Event) => emit('endReached', event) },
48
- [MEDIA_SWIPER_DOM_EVENT_MAP.onTap]: { handleEvent: (event: Event) => emit('tap', event) },
49
- [MEDIA_SWIPER_DOM_EVENT_MAP.onVideoEnded]: { handleEvent: (event: Event) => emit('videoEnded', event) },
50
- [MEDIA_SWIPER_DOM_EVENT_MAP.onError]: { handleEvent: (event: Event) => emit('error', event) },
48
+ [MEDIA_SWIPER_DOM_EVENT_MAP.onChange]: { handleEvent: (event: Event) => emit('change', unwrapNativeEventPayload(event)) },
49
+ [MEDIA_SWIPER_DOM_EVENT_MAP.onTransitionEnd]: { handleEvent: (event: Event) => emit('transitionEnd', unwrapNativeEventPayload(event)) },
50
+ [MEDIA_SWIPER_DOM_EVENT_MAP.onEndReached]: { handleEvent: (event: Event) => emit('endReached', unwrapNativeEventPayload(event)) },
51
+ [MEDIA_SWIPER_DOM_EVENT_MAP.onTap]: { handleEvent: (event: Event) => emit('tap', unwrapNativeEventPayload(event)) },
52
+ [MEDIA_SWIPER_DOM_EVENT_MAP.onVideoEnded]: { handleEvent: (event: Event) => emit('videoEnded', unwrapNativeEventPayload(event)) },
53
+ [MEDIA_SWIPER_DOM_EVENT_MAP.onError]: { handleEvent: (event: Event) => emit('error', unwrapNativeEventPayload(event)) },
51
54
  };
52
55
 
53
56
  watch(elementRef, (element) => {
@@ -58,16 +61,6 @@ onBeforeUnmount(() => {
58
61
  unbindElementEvents(boundElement, eventListeners);
59
62
  });
60
63
 
61
- watch(
62
- [elementRef, () => props.pageBindings],
63
- () => {
64
- const el = elementRef.value as any;
65
- if (el) {
66
- el.pageBindings = props.pageBindings ?? {};
67
- }
68
- },
69
- { immediate: true }
70
- );
71
64
 
72
65
  const domProps = computed(() => {
73
66
  const result = buildMediaSwiperNativeAttrs({
@@ -81,12 +74,13 @@ const domProps = computed(() => {
81
74
  };
82
75
  });
83
76
 
84
- defineExpose({
77
+ const handle: LxMediaSwiperHandle & { el: typeof elementRef } = {
85
78
  el: elementRef,
86
- next: () => (elementRef.value as any)?.next?.(),
87
- previous: () => (elementRef.value as any)?.previous?.(),
88
- goToIndex: (index: number) => (elementRef.value as any)?.goToIndex?.(index),
89
- });
79
+ next: () => elementRef.value?.next(),
80
+ previous: () => elementRef.value?.previous(),
81
+ goToIndex: (index: number) => elementRef.value?.goToIndex(index),
82
+ };
83
+ defineExpose(handle);
90
84
 
91
85
  const render = () => h('lx-media-swiper', { ref: elementRef, ...domProps.value });
92
86
  </script>
package/dist/LxPicker.vue CHANGED
@@ -131,7 +131,16 @@ const renderPicker = () => visible.value ? h('lx-picker', { ref: pickerRef, ...p
131
131
 
132
132
  <template>
133
133
  <slot :open="handleClick" :disabled="props.disabled">
134
- <div :class="props.class ?? attrs.class" :style="[triggerStyle, props.style ?? attrs.style]" @click="handleClick">
134
+ <div
135
+ :class="props.class ?? attrs.class"
136
+ :style="[triggerStyle, props.style ?? attrs.style]"
137
+ role="button"
138
+ :tabindex="props.disabled ? -1 : 0"
139
+ :aria-disabled="props.disabled || undefined"
140
+ @click="handleClick"
141
+ @keydown.enter.prevent="handleClick"
142
+ @keydown.space.prevent="handleClick"
143
+ >
135
144
  <span :style="{ color: modelValue ? '#111' : '#9ca3af' }">{{ displayText || placeholder }}</span>
136
145
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="2">
137
146
  <path d="M6 9l6 6 6-6" />
@@ -0,0 +1,13 @@
1
+ import { type Component } from "vue";
2
+ /**
3
+ * Mount a page's View. The CLI's generated entry calls this; pages never do.
4
+ *
5
+ * With `waitForState` — the page has Logic — the View mounts only once the
6
+ * page's first state has arrived, so `useLxPage().data` is whole from the first
7
+ * render. If that takes longer than 10 seconds, a panel names the page
8
+ * instead of a blank screen — and if the state arrives after all (a slow cold
9
+ * start, a paused debugger), the panel goes and the page mounts.
10
+ */
11
+ export declare function mountPage(App: Component, options: {
12
+ waitForState: boolean;
13
+ }): Promise<void>;
package/dist/entry.js ADDED
@@ -0,0 +1,16 @@
1
+ import { createApp } from "vue";
2
+ import { waitForPageState } from "@lingxia/page-runtime";
3
+ /**
4
+ * Mount a page's View. The CLI's generated entry calls this; pages never do.
5
+ *
6
+ * With `waitForState` — the page has Logic — the View mounts only once the
7
+ * page's first state has arrived, so `useLxPage().data` is whole from the first
8
+ * render. If that takes longer than 10 seconds, a panel names the page
9
+ * instead of a blank screen — and if the state arrives after all (a slow cold
10
+ * start, a paused debugger), the panel goes and the page mounts.
11
+ */
12
+ export async function mountPage(App, options) {
13
+ if (options.waitForState)
14
+ await waitForPageState();
15
+ createApp(App).mount("#app");
16
+ }
package/dist/hook.d.ts CHANGED
@@ -1,20 +1,39 @@
1
1
  import { type Ref } from "vue";
2
2
  import type { LxChannel, LxBridgeError, LxStream } from "@lingxia/bridge";
3
- import { type ChannelIn, type ChannelOut, type MethodParams, type ParamsSource, type StreamData, type StreamResult } from "@lingxia/bridge/invocation";
4
- import { type ActionMap, type PageChromeLayoutSnapshot, type Snapshot } from "@lingxia/page-runtime";
3
+ import { type LxHost } from "@lingxia/bridge";
4
+ import { type ChannelIn, type ChannelOut, type MethodParams, type OptionsArg, type ParamsOption, type ParamsSource, type StreamData, type StreamResult } from "@lingxia/bridge/invocation";
5
+ import { type ActionMap, type PageActions, type DeepReadonly, type Snapshot } from "@lingxia/page-runtime";
5
6
  type MethodSource<T> = T | Ref<T>;
7
+ /**
8
+ * This page's Logic state and actions — `this.data` and the page's methods.
9
+ * The page mounts once its first state has arrived, so `data` is whole from
10
+ * the first render. `data` is deep-reactive, readonly and updated in place, so
11
+ * it may be destructured; keep editable state in a `ref` and send it with an
12
+ * action. Call during component setup; pass actions into shared helpers
13
+ * instead of reading at module load.
14
+ */
6
15
  export declare function useLxPage<TData = Snapshot, TActions extends ActionMap = ActionMap>(): {
7
- data: TData;
8
- actions: TActions;
16
+ data: DeepReadonly<TData>;
17
+ actions: PageActions<TActions>;
9
18
  };
10
- /** Reactive native page-chrome geometry for View layout. */
11
- export declare function useLxPageChrome(): Readonly<Ref<PageChromeLayoutSnapshot>>;
12
- export interface LxStreamOptions<TData, TReduced> {
13
- params?: unknown | (() => unknown);
19
+ /**
20
+ * What the host decided for this page: `sizeClass`, `aside`,
21
+ * `displayLanguage`, `formFactor`, `os`, `runner` — a readonly reactive object
22
+ * that changes only when one of them does, never while a window is dragged.
23
+ * Read `host.sizeClass`; destructuring takes a snapshot. Geometry is CSS:
24
+ * `--lx-page-chrome-*` and container queries. Callable anywhere.
25
+ */
26
+ export declare function useLxHost(): Readonly<LxHost>;
27
+ type StreamMethod = (...args: any[]) => LxStream<any, any>;
28
+ type ChannelMethod = (...args: any[]) => Promise<LxChannel<any, any>>;
29
+ export type LxStreamOptions<TMethod> = ParamsOption<TMethod, ParamsSource<MethodParams<TMethod>>> & {
14
30
  manual?: boolean;
15
- reduce?: (accumulated: TReduced, chunk: TData) => TReduced;
16
- initial?: TReduced;
17
- }
31
+ };
32
+ /** A reducer folds chunks into `data`, starting from `initial`. */
33
+ export type LxReducedStreamOptions<TMethod, TReduced> = LxStreamOptions<TMethod> & {
34
+ reduce: (accumulated: TReduced, chunk: StreamData<TMethod>) => TReduced;
35
+ initial: TReduced;
36
+ };
18
37
  export interface LxStreamState<TData, TResult = unknown> {
19
38
  data: Ref<TData | undefined>;
20
39
  result: Ref<TResult | undefined>;
@@ -23,43 +42,20 @@ export interface LxStreamState<TData, TResult = unknown> {
23
42
  cancel: () => void;
24
43
  start: () => void;
25
44
  }
26
- export declare function useLxStream<TMethod extends (...args: any[]) => LxStream<any, any>, TReduced = StreamData<TMethod>>(method: MethodSource<TMethod>, options?: LxStreamOptions<StreamData<TMethod>, TReduced> & {
27
- params?: ParamsSource<MethodParams<TMethod>>;
28
- }): LxStreamState<TReduced extends StreamData<TMethod> ? StreamData<TMethod> : TReduced, StreamResult<TMethod>>;
29
- export interface LxChannelOptions {
30
- params?: unknown | (() => unknown);
45
+ export declare function useLxStream<TMethod extends StreamMethod, TReduced>(method: MethodSource<TMethod>, options: LxReducedStreamOptions<TMethod, TReduced>): LxStreamState<TReduced, StreamResult<TMethod>>;
46
+ export declare function useLxStream<TMethod extends StreamMethod>(method: MethodSource<TMethod>, ...options: OptionsArg<TMethod, LxStreamOptions<TMethod>>): LxStreamState<StreamData<TMethod>, StreamResult<TMethod>>;
47
+ export type LxChannelOptions<TMethod> = ParamsOption<TMethod, ParamsSource<MethodParams<TMethod>>> & {
31
48
  manual?: boolean;
32
- }
49
+ };
33
50
  export interface LxChannelState<TData, TOut = TData> {
34
51
  last: Ref<TData | undefined>;
35
52
  error: Ref<LxBridgeError | undefined>;
36
53
  connecting: Ref<boolean>;
37
54
  connected: Ref<boolean>;
38
- send: (payload: TOut) => void;
55
+ /** Sends when connected; `false` when there is no open channel to send on. */
56
+ send: (payload: TOut) => boolean;
39
57
  close: (code?: string, reason?: string) => void;
40
58
  reopen: () => void;
41
59
  }
42
- export declare function useLxChannel<TMethod extends (...args: any[]) => Promise<LxChannel<any, any>>>(method: MethodSource<TMethod>, options?: LxChannelOptions & {
43
- params?: ParamsSource<MethodParams<TMethod>>;
44
- }): LxChannelState<ChannelIn<TMethod>, ChannelOut<TMethod>>;
45
- export interface LxPlatform {
46
- os: string;
47
- isIOS: boolean;
48
- isMacOS: boolean;
49
- isApple: boolean;
50
- isAndroid: boolean;
51
- isHarmony: boolean;
52
- isWindows: boolean;
53
- /**
54
- * Form factor, not OS. This, not `isMacOS`/`isWindows`, is what a layout
55
- * decision is usually about: the Runner reports macOS while simulating a
56
- * phone, and a narrowed desktop window is still a desktop.
57
- */
58
- isDesktop: boolean;
59
- isMobile: boolean;
60
- isRunner: boolean;
61
- }
62
- export declare function usePlatform(): LxPlatform;
63
- /** Effective product language selected by the host; follows a change. */
64
- export declare function useDisplayLanguage(): Readonly<Ref<string>>;
60
+ export declare function useLxChannel<TMethod extends ChannelMethod>(method: MethodSource<TMethod>, ...args: OptionsArg<TMethod, LxChannelOptions<TMethod>>): LxChannelState<ChannelIn<TMethod>, ChannelOut<TMethod>>;
65
61
  export {};
package/dist/hook.js CHANGED
@@ -1,43 +1,62 @@
1
- import { onUnmounted, getCurrentInstance, reactive, ref, shallowRef, unref, watch, } from "vue";
2
- import { getDisplayLanguage, subscribeDisplayLanguage } from "@lingxia/bridge";
1
+ import { onUnmounted, reactive, readonly, ref, unref, watch, } from "vue";
2
+ import { getHost, subscribeHost } from "@lingxia/bridge";
3
3
  import { getMethodKey, invokeMethod, resolveParams, stableParamKey, toBridgeError, } from "@lingxia/bridge/invocation";
4
- import { ensurePageBridgeSubscription, getPageActions, getPageChromeLayout, subscribePageChromeLayout, subscribePageData, } from "@lingxia/page-runtime";
4
+ import { getPageActions, getPageSnapshot, subscribePageSnapshot, } from "@lingxia/page-runtime";
5
5
  function resolveMethod(source) {
6
6
  return unref(source);
7
7
  }
8
+ // One reactive copy of the page's data for the document, updated in place so
9
+ // a destructured `data` stays live.
8
10
  const reactiveSnapshot = reactive({});
9
11
  let snapshotSubscribed = false;
10
- function ensureReactiveSnapshot() {
11
- if (snapshotSubscribed)
12
- return;
13
- snapshotSubscribed = true;
14
- subscribePageData((next) => {
15
- const normalized = next && typeof next === "object" ? next : {};
16
- for (const key of Object.keys(reactiveSnapshot)) {
17
- if (!Object.prototype.hasOwnProperty.call(normalized, key)) {
18
- delete reactiveSnapshot[key];
19
- }
12
+ function syncSnapshot() {
13
+ const next = getPageSnapshot();
14
+ const normalized = next && typeof next === "object" ? next : {};
15
+ for (const key of Object.keys(reactiveSnapshot)) {
16
+ if (!Object.prototype.hasOwnProperty.call(normalized, key)) {
17
+ delete reactiveSnapshot[key];
20
18
  }
21
- Object.assign(reactiveSnapshot, normalized);
22
- });
19
+ }
20
+ Object.assign(reactiveSnapshot, normalized);
23
21
  }
22
+ // What pages get: Logic owns the data, so a View write is refused (Vue warns
23
+ // in development) while the sync above keeps updating the same object.
24
+ const readonlySnapshot = readonly(reactiveSnapshot);
25
+ /**
26
+ * This page's Logic state and actions — `this.data` and the page's methods.
27
+ * The page mounts once its first state has arrived, so `data` is whole from
28
+ * the first render. `data` is deep-reactive, readonly and updated in place, so
29
+ * it may be destructured; keep editable state in a `ref` and send it with an
30
+ * action. Call during component setup; pass actions into shared helpers
31
+ * instead of reading at module load.
32
+ */
24
33
  export function useLxPage() {
25
- ensurePageBridgeSubscription();
26
- ensureReactiveSnapshot();
27
- return { data: reactiveSnapshot, actions: getPageActions() };
34
+ if (!snapshotSubscribed) {
35
+ snapshotSubscribed = true;
36
+ syncSnapshot();
37
+ subscribePageSnapshot(syncSnapshot);
38
+ }
39
+ return {
40
+ data: readonlySnapshot,
41
+ actions: getPageActions(),
42
+ };
28
43
  }
29
- /** Reactive native page-chrome geometry for View layout. */
30
- export function useLxPageChrome() {
31
- const layout = shallowRef(getPageChromeLayout());
32
- if (!getCurrentInstance()) {
33
- console.warn("useLxPageChrome() must be called during component setup");
34
- return layout;
44
+ const hostState = reactive({ ...getHost() });
45
+ let hostSubscribed = false;
46
+ /**
47
+ * What the host decided for this page: `sizeClass`, `aside`,
48
+ * `displayLanguage`, `formFactor`, `os`, `runner` — a readonly reactive object
49
+ * that changes only when one of them does, never while a window is dragged.
50
+ * Read `host.sizeClass`; destructuring takes a snapshot. Geometry is CSS:
51
+ * `--lx-page-chrome-*` and container queries. Callable anywhere.
52
+ */
53
+ export function useLxHost() {
54
+ if (!hostSubscribed) {
55
+ hostSubscribed = true;
56
+ Object.assign(hostState, getHost());
57
+ subscribeHost(() => Object.assign(hostState, getHost()));
35
58
  }
36
- const unsubscribe = subscribePageChromeLayout((next) => {
37
- layout.value = next;
38
- });
39
- onUnmounted(unsubscribe);
40
- return layout;
59
+ return readonly(hostState);
41
60
  }
42
61
  export function useLxStream(method, options) {
43
62
  const data = ref((options?.reduce ? options.initial : undefined));
@@ -122,7 +141,8 @@ export function useLxStream(method, options) {
122
141
  });
123
142
  return { data, result, error, streaming, cancel, start };
124
143
  }
125
- export function useLxChannel(method, options) {
144
+ export function useLxChannel(method, ...args) {
145
+ const options = args[0];
126
146
  const last = ref(undefined);
127
147
  const error = ref(undefined);
128
148
  const connecting = ref(false);
@@ -130,7 +150,10 @@ export function useLxChannel(method, options) {
130
150
  let ch = null;
131
151
  let runId = 0;
132
152
  function send(payload) {
133
- ch?.send(payload);
153
+ if (!ch)
154
+ return false;
155
+ ch.send(payload);
156
+ return true;
134
157
  }
135
158
  function close(code, reason) {
136
159
  runId += 1;
@@ -147,7 +170,11 @@ export function useLxChannel(method, options) {
147
170
  error.value = undefined;
148
171
  connecting.value = true;
149
172
  connected.value = false;
150
- Promise.resolve(invokeMethod(resolveMethod(method), resolveParams(options?.params)))
173
+ // In the executor: a method or params getter that throws synchronously
174
+ // lands in `.catch`.
175
+ new Promise((resolve) => {
176
+ resolve(invokeMethod(resolveMethod(method), resolveParams(options?.params)));
177
+ })
151
178
  .then((nextChannel) => {
152
179
  if (runId !== thisRunId) {
153
180
  nextChannel.close();
@@ -205,40 +232,3 @@ export function useLxChannel(method, options) {
205
232
  });
206
233
  return { last, error, connecting, connected, send, close, reopen };
207
234
  }
208
- function readPlatform() {
209
- const p = window.LingXiaBridge?.platform;
210
- const desktop = p?.isDesktop() ?? false;
211
- return {
212
- os: p?.getOS() ?? "unknown",
213
- isIOS: p?.isIOS() ?? false,
214
- isMacOS: p?.isMacOS() ?? false,
215
- isApple: p?.isApple() ?? false,
216
- isAndroid: p?.isAndroid() ?? false,
217
- isHarmony: p?.isHarmony() ?? false,
218
- isWindows: p?.isWindows() ?? false,
219
- isDesktop: desktop,
220
- // Derived, not read, so that a host too old to answer `isMobile` reports
221
- // one of the two rather than neither.
222
- isMobile: p?.isMobile?.() ?? !desktop,
223
- isRunner: p?.isRunner() ?? false,
224
- };
225
- }
226
- // Typed platform detection for pages, so they never reach for the window global
227
- // or hand-roll an OS check. Fixed for the session, so it resolves once — the
228
- // Runner re-serves the page when its simulated device changes form factor.
229
- export function usePlatform() {
230
- return readPlatform();
231
- }
232
- /** Effective product language selected by the host; follows a change. */
233
- export function useDisplayLanguage() {
234
- const language = shallowRef(getDisplayLanguage());
235
- if (!getCurrentInstance()) {
236
- console.warn("useDisplayLanguage() must be called during component setup");
237
- return language;
238
- }
239
- const unsubscribe = subscribeDisplayLanguage(() => {
240
- language.value = getDisplayLanguage();
241
- });
242
- onUnmounted(unsubscribe);
243
- return language;
244
- }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- export { useLxPage, useLxPageChrome, useLxStream, useLxChannel, usePlatform, useDisplayLanguage, type LxStreamOptions, type LxStreamState, type LxChannelOptions, type LxChannelState, type LxPlatform, } from "./hook.js";
1
+ export { useLxPage, useLxHost, useLxStream, useLxChannel, type LxStreamOptions, type LxReducedStreamOptions, type LxStreamState, type LxChannelOptions, type LxChannelState, } from "./hook.js";
2
+ export type { LxHost } from "@lingxia/bridge";
3
+ export type { DeepReadonly } from "@lingxia/page-runtime";
2
4
  export { default as LxVideo } from "./LxVideo.vue";
3
5
  export { default as LxNativeRoot } from "./LxNativeRoot.vue";
4
6
  export { default as LxNativeView } from "./LxNativeView.vue";
@@ -9,6 +11,5 @@ export { default as LxMediaSwiper } from "./LxMediaSwiper.vue";
9
11
  export { default as LxPicker } from "./LxPicker.vue";
10
12
  export { default as LxNavigator } from "./LxNavigator.vue";
11
13
  export type { LxVideoProps, LxNativeRootProps, LxNativeViewProps, LxNativeCoverProps, LxNativeTextProps, LxNativeButtonProps, LxMediaSwiperProps, LxPickerProps, LxNavigatorProps, LxNavigatorEvent, } from "./types.js";
12
- export type { LxPageChrome, PageChromeLayoutListener, PageChromeLayoutSnapshot, PageChromeRect, } from "@lingxia/page-runtime";
13
- export type { LxVideoEventPayloads, LxVideoEventHandlers, NativeActionIcon } from "@lingxia/elements";
14
+ export type { LxVideoEventPayloads, LxVideoEventHandlers, LxMediaSwiperEventPayloads, LxMediaSwiperEventHandlers, LxMediaSwiperHandle, LxMediaSwiperItem, NativeActionIcon, } from "@lingxia/elements";
14
15
  export type { NativeStyle } from "./types.js";
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { useLxPage, useLxPageChrome, useLxStream, useLxChannel, usePlatform, useDisplayLanguage, } from "./hook.js";
1
+ export { useLxPage, useLxHost, useLxStream, useLxChannel, } from "./hook.js";
2
2
  export { default as LxVideo } from "./LxVideo.vue";
3
3
  export { default as LxNativeRoot } from "./LxNativeRoot.vue";
4
4
  export { default as LxNativeView } from "./LxNativeView.vue";
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { CSSProperties } from 'vue';
2
- import type { LxNavigatorEvent, LxVideoEventPayloads, NativeActionIcon, NativeStyleProperty, NavigatorChannel, NavigatorOpenType, NavigatorQuery, NavigatorTarget, NavigatorEdge, NavigatorFloatPosition, NavigatorInteraction, NavigatorPlacement, NavigatorSize, NavigatorWindowChrome } from '@lingxia/elements';
2
+ import type { LxMediaSwiperEventPayloads, LxMediaSwiperItem, LxPickerColumns, LxVideoQuality, LxNavigatorEvent, LxVideoEventPayloads, NativeActionIcon, NativeStyleProperty, NavigatorChannel, NavigatorOpenType, NavigatorQuery, NavigatorTarget, NavigatorEdge, NavigatorFloatPosition, NavigatorInteraction, NavigatorPlacement, NavigatorSize, NavigatorWindowChrome } from '@lingxia/elements';
3
3
  export type NativeStyle = Omit<Pick<CSSProperties, NativeStyleProperty>, "borderStyle"> & {
4
4
  borderStyle?: "solid" | "none";
5
5
  };
@@ -16,11 +16,8 @@ export interface LxVideoProps {
16
16
  progressBar?: boolean;
17
17
  live?: boolean;
18
18
  volume?: string | number;
19
- qualities?: Array<{
20
- label: string;
21
- url?: string;
22
- }>;
23
- playbackRates?: number[];
19
+ qualities?: readonly LxVideoQuality[];
20
+ playbackRates?: readonly number[];
24
21
  class?: string;
25
22
  style?: NativeStyle;
26
23
  onPlayRequest?: (payload: LxVideoEventPayloads["onPlayRequest"]) => void;
@@ -37,7 +34,6 @@ export interface LxVideoProps {
37
34
  onQualityChange?: (payload: LxVideoEventPayloads["onQualityChange"]) => void;
38
35
  onRateChange?: (payload: LxVideoEventPayloads["onRateChange"]) => void;
39
36
  onVolumeChange?: (payload: LxVideoEventPayloads["onVolumeChange"]) => void;
40
- pageBindings?: Record<string, string>;
41
37
  }
42
38
  export interface LxNativeNodeProps {
43
39
  id?: string;
@@ -82,21 +78,9 @@ export interface LxNativeButtonProps extends LxNativeNodeProps {
82
78
  loading?: boolean;
83
79
  tabIndex?: 0 | -1;
84
80
  }
85
- type LxMediaSwiperItem = {
86
- id?: string;
87
- type: 'image';
88
- src: string;
89
- } | {
90
- id?: string;
91
- type: 'video';
92
- src: string;
93
- poster?: string;
94
- controls?: boolean;
95
- muted?: boolean;
96
- };
97
81
  export interface LxMediaSwiperProps {
98
82
  id?: string;
99
- items?: LxMediaSwiperItem[];
83
+ items?: readonly LxMediaSwiperItem[];
100
84
  index?: number;
101
85
  initialIndex?: number;
102
86
  loop?: boolean;
@@ -120,21 +104,20 @@ export interface LxMediaSwiperProps {
120
104
  };
121
105
  class?: string;
122
106
  style?: CSSProperties;
123
- onChange?: (event: Event) => void;
124
- onTransitionEnd?: (event: Event) => void;
125
- onEndReached?: (event: Event) => void;
126
- onTap?: (event: Event) => void;
127
- onVideoEnded?: (event: Event) => void;
128
- onError?: (event: Event) => void;
129
- pageBindings?: Record<string, string>;
107
+ onChange?: (payload: LxMediaSwiperEventPayloads["onChange"]) => void;
108
+ onTransitionEnd?: (payload: LxMediaSwiperEventPayloads["onTransitionEnd"]) => void;
109
+ onEndReached?: (payload: LxMediaSwiperEventPayloads["onEndReached"]) => void;
110
+ onTap?: (payload: LxMediaSwiperEventPayloads["onTap"]) => void;
111
+ onVideoEnded?: (payload: LxMediaSwiperEventPayloads["onVideoEnded"]) => void;
112
+ onError?: (payload: LxMediaSwiperEventPayloads["onError"]) => void;
130
113
  }
131
114
  export interface LxPickerProps {
132
- columns?: string[][] | [string[], Record<string, string[]>];
115
+ columns?: LxPickerColumns;
133
116
  mode?: 'date' | 'time';
134
117
  start?: string;
135
118
  end?: string;
136
119
  fields?: 'year' | 'month' | 'day' | 'range';
137
- modelValue?: string | string[];
120
+ modelValue?: string | readonly string[];
138
121
  placeholder?: string;
139
122
  class?: string;
140
123
  style?: CSSProperties;
@@ -145,7 +128,6 @@ export interface LxPickerProps {
145
128
  confirmText?: string;
146
129
  confirmTextColor?: string;
147
130
  confirmButtonColor?: string;
148
- pageBindings?: Record<string, string>;
149
131
  }
150
132
  export interface LxNavigatorProps {
151
133
  url?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingxia/vue",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "private": false,
5
5
  "description": "LingXia Vue runtime and components for lxapp pages",
6
6
  "type": "module",
@@ -11,18 +11,23 @@
11
11
  "types": "./dist/index.d.ts",
12
12
  "default": "./dist/index.js"
13
13
  },
14
+ "./entry": {
15
+ "types": "./dist/entry.d.ts",
16
+ "default": "./dist/entry.js"
17
+ },
14
18
  "./package.json": "./package.json"
15
19
  },
16
20
  "scripts": {
17
21
  "build": "npm run clean && npm --prefix ../lingxia-elements run build && npm --prefix ../lingxia-page-runtime run build && tsc -p tsconfig.json && node scripts/copy-sfc-assets.mjs",
18
22
  "clean": "rm -rf dist",
19
23
  "prepublishOnly": "npm run build",
20
- "test:components": "npm run build && node tests/native-components.mjs && node tests/native-aria-attributes.mjs"
24
+ "test:components": "npm run build && node tests/native-components.mjs && node tests/native-aria-attributes.mjs",
25
+ "test:hooks": "rolldown -c tests/rolldown.hooks.config.mjs && node tests/page-hooks.mjs"
21
26
  },
22
27
  "dependencies": {
23
- "@lingxia/bridge": "~0.18.0",
24
- "@lingxia/elements": "~0.18.0",
25
- "@lingxia/page-runtime": "~0.18.0"
28
+ "@lingxia/bridge": "~0.19.0",
29
+ "@lingxia/elements": "~0.19.0",
30
+ "@lingxia/page-runtime": "~0.19.0"
26
31
  },
27
32
  "peerDependencies": {
28
33
  "vue": ">=3.5.0"