@open-wxa/wxa-runner-core 0.8.0 → 0.8.1
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.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +22 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -5
- package/dist/index.mjs.map +1 -1
- package/dist/runtime/host.js +86 -14
- package/dist/runtime/host.js.map +1 -1
- package/package.json +3 -3
package/dist/runtime/host.js
CHANGED
|
@@ -1642,7 +1642,8 @@ ${frames}` : "");
|
|
|
1642
1642
|
}
|
|
1643
1643
|
|
|
1644
1644
|
// src/runtime/host/api/ui.ts
|
|
1645
|
-
function createUiApis({ shell, updateNavigation }) {
|
|
1645
|
+
function createUiApis({ shell, updateNavigation, setTabBarHidden }) {
|
|
1646
|
+
const updateTabBarItem = (api, index, item) => shell.updateTabBarItem(Number(index), item) ? void 0 : fail(api, "tabbar item not found");
|
|
1646
1647
|
return {
|
|
1647
1648
|
showToast: (args) => shell.showToast(args),
|
|
1648
1649
|
hideToast: () => shell.hideToast(),
|
|
@@ -1660,6 +1661,22 @@ ${frames}` : "");
|
|
|
1660
1661
|
}),
|
|
1661
1662
|
showNavigationBarLoading: () => shell.setNavigationLoading(true),
|
|
1662
1663
|
hideNavigationBarLoading: () => shell.setNavigationLoading(false),
|
|
1664
|
+
hideTabBar: () => setTabBarHidden(true),
|
|
1665
|
+
showTabBar: () => setTabBarHidden(false),
|
|
1666
|
+
// 基础库把 removeTabBarBadge、showTabBarRedDot、hideTabBarRedDot 都转成 setTabBarBadge,用 type 区分;
|
|
1667
|
+
// 徽标文字超长时基础库已经换成 ...
|
|
1668
|
+
setTabBarBadge: (args, { api }) => updateTabBarItem(api, args.index, { mark: tabBarMark(args) }),
|
|
1669
|
+
setTabBarItem: (args, { api }) => updateTabBarItem(api, args.index, {
|
|
1670
|
+
text: args.text,
|
|
1671
|
+
iconPath: args.iconPath,
|
|
1672
|
+
selectedIconPath: args.selectedIconPath
|
|
1673
|
+
}),
|
|
1674
|
+
setTabBarStyle: (args) => shell.updateTabBarStyle({
|
|
1675
|
+
color: args.color,
|
|
1676
|
+
selectedColor: args.selectedColor,
|
|
1677
|
+
backgroundColor: args.backgroundColor,
|
|
1678
|
+
borderStyle: args.borderStyle
|
|
1679
|
+
}),
|
|
1663
1680
|
hideHomeButton: () => void 0,
|
|
1664
1681
|
setBackgroundColor: () => void 0,
|
|
1665
1682
|
setBackgroundTextStyle: () => void 0,
|
|
@@ -1667,6 +1684,11 @@ ${frames}` : "");
|
|
|
1667
1684
|
stopPullDownRefresh: () => void 0
|
|
1668
1685
|
};
|
|
1669
1686
|
}
|
|
1687
|
+
function tabBarMark(args) {
|
|
1688
|
+
if (args.type === "text") return { type: "text", text: String(args.badgeValue ?? "") };
|
|
1689
|
+
if (args.type === "redDot") return { type: "redDot" };
|
|
1690
|
+
return null;
|
|
1691
|
+
}
|
|
1670
1692
|
|
|
1671
1693
|
// src/runtime/host/api/webView.ts
|
|
1672
1694
|
function createWebViewApis({ documentOf, emitToWebview }) {
|
|
@@ -1975,7 +1997,12 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
1975
1997
|
.wxa-tabbar { flex: none; height: calc(50px + var(--wxa-safe-bottom, 0px)); padding-bottom: var(--wxa-safe-bottom, 0px); display: flex; border-top: .5px solid rgba(0,0,0,.1); box-sizing: border-box; }
|
|
1976
1998
|
.wxa-tabbar.is-hidden { display: none; }
|
|
1977
1999
|
.wxa-tabbar-item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 10px; cursor: pointer; user-select: none; gap: 2px; }
|
|
1978
|
-
.wxa-tabbar-item img { width: 24px; height: 24px; }
|
|
2000
|
+
.wxa-tabbar-item img { width: 24px; height: 24px; display: block; }
|
|
2001
|
+
.wxa-tabbar-icon, .wxa-tabbar-text { position: relative; }
|
|
2002
|
+
.wxa-tabbar-badge { position: absolute; top: -4px; left: calc(100% - 6px); min-width: 16px; height: 16px; padding: 0 5px; box-sizing: border-box; border-radius: 8px; background: #fa5151; color: #fff; font-size: 11px; line-height: 16px; text-align: center; white-space: nowrap; }
|
|
2003
|
+
.wxa-tabbar-dot { position: absolute; top: -2px; left: calc(100% - 2px); width: 8px; height: 8px; border-radius: 50%; background: #fa5151; }
|
|
2004
|
+
.wxa-tabbar-text > .wxa-tabbar-badge { top: -10px; left: calc(100% + 1px); }
|
|
2005
|
+
.wxa-tabbar-text > .wxa-tabbar-dot { top: -3px; left: calc(100% + 1px); }
|
|
1979
2006
|
.wxa-overlay { position: absolute; inset: 0; pointer-events: none; z-index: 10; }
|
|
1980
2007
|
.wxa-mask { position: absolute; inset: 0; pointer-events: auto; }
|
|
1981
2008
|
.wxa-mask.is-dim { background: rgba(0,0,0,.5); }
|
|
@@ -2140,7 +2167,10 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2140
2167
|
this.tabBarConfig = null;
|
|
2141
2168
|
this.onTabTap = () => void 0;
|
|
2142
2169
|
this.navigation = { title: "", backgroundColor: "#000", textStyle: "white", showBack: false, custom: false };
|
|
2143
|
-
|
|
2170
|
+
/** 当前页面是 tabBar 页面时为它的路径 */
|
|
2171
|
+
this.tabBarPath = null;
|
|
2172
|
+
/** wx.hideTabBar 设置,对所有 tab 页生效,直到 wx.showTabBar */
|
|
2173
|
+
this.tabBarHidden = false;
|
|
2144
2174
|
const style = document.createElement("style");
|
|
2145
2175
|
style.textContent = SHELL_CSS;
|
|
2146
2176
|
document.head.appendChild(style);
|
|
@@ -2252,9 +2282,28 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2252
2282
|
setNavigationLoading(loading) {
|
|
2253
2283
|
this.navBar.classList.toggle("is-loading", loading);
|
|
2254
2284
|
}
|
|
2255
|
-
/** 该页面是否显示原生 tabBar(自定义 tabBar
|
|
2285
|
+
/** 该页面是否显示原生 tabBar(自定义 tabBar、被 wx.hideTabBar 隐藏的都不算) */
|
|
2256
2286
|
hasTabBar(pagePath) {
|
|
2257
|
-
return !!this.tabBarConfig?.list.some((item) => item.pagePath === pagePath);
|
|
2287
|
+
return !this.tabBarHidden && !!this.tabBarConfig?.list.some((item) => item.pagePath === pagePath);
|
|
2288
|
+
}
|
|
2289
|
+
setTabBarHidden(hidden) {
|
|
2290
|
+
this.tabBarHidden = hidden;
|
|
2291
|
+
this.renderTabBar(this.tabBarPath);
|
|
2292
|
+
}
|
|
2293
|
+
/** 没有原生 tabBar(未配置或自定义 tabBar)时什么都不做 */
|
|
2294
|
+
updateTabBarStyle(style) {
|
|
2295
|
+
if (!this.tabBarConfig) return;
|
|
2296
|
+
Object.assign(this.tabBarConfig, definedOnly(style));
|
|
2297
|
+
this.renderTabBar(this.tabBarPath);
|
|
2298
|
+
}
|
|
2299
|
+
/** 返回 false 表示 index 越界;没有原生 tabBar 时什么都不做 */
|
|
2300
|
+
updateTabBarItem(index, item) {
|
|
2301
|
+
if (!this.tabBarConfig) return true;
|
|
2302
|
+
const target = this.tabBarConfig.list[index];
|
|
2303
|
+
if (!target) return false;
|
|
2304
|
+
Object.assign(target, definedOnly(item));
|
|
2305
|
+
this.renderTabBar(this.tabBarPath);
|
|
2306
|
+
return true;
|
|
2258
2307
|
}
|
|
2259
2308
|
/**
|
|
2260
2309
|
* 页面窗口里 env(safe-area-inset-*) 的取值:窗口贴着屏幕边缘的一侧才有安全区。
|
|
@@ -2271,9 +2320,10 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2271
2320
|
/** 当前页面是 tabBar 页面时传入它的路径,否则传 null */
|
|
2272
2321
|
renderTabBar(selectedPath) {
|
|
2273
2322
|
const config = this.tabBarConfig;
|
|
2274
|
-
this.
|
|
2275
|
-
|
|
2276
|
-
|
|
2323
|
+
this.tabBarPath = selectedPath;
|
|
2324
|
+
const visible = this.tabBarVisible();
|
|
2325
|
+
this.tabBar.classList.toggle("is-hidden", !visible);
|
|
2326
|
+
if (!config || !visible) return;
|
|
2277
2327
|
this.tabBar.style.background = config.backgroundColor || "#f7f7f7";
|
|
2278
2328
|
this.tabBar.style.borderTopColor = config.borderStyle === "white" ? "rgba(255,255,255,.3)" : "rgba(0,0,0,.1)";
|
|
2279
2329
|
this.tabBar.innerHTML = "";
|
|
@@ -2284,21 +2334,26 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2284
2334
|
el.dataset.pagePath = item.pagePath;
|
|
2285
2335
|
el.style.color = selected ? config.selectedColor || "#07c160" : config.color || "#7a7e83";
|
|
2286
2336
|
const icon = selected ? item.selectedIconPath || item.iconPath : item.iconPath;
|
|
2337
|
+
const iconBox = element("span", "wxa-tabbar-icon");
|
|
2287
2338
|
if (icon) {
|
|
2288
2339
|
const img = document.createElement("img");
|
|
2289
|
-
img.src = "/" + icon.replace(/^\//, "");
|
|
2290
|
-
|
|
2340
|
+
img.src = /^https?:\/\//.test(icon) ? icon : "/" + icon.replace(/^\//, "");
|
|
2341
|
+
iconBox.appendChild(img);
|
|
2342
|
+
el.appendChild(iconBox);
|
|
2291
2343
|
}
|
|
2292
|
-
const text =
|
|
2293
|
-
text.textContent = item.text || "";
|
|
2344
|
+
const text = element("span", "wxa-tabbar-text", item.text || "");
|
|
2294
2345
|
el.appendChild(text);
|
|
2346
|
+
if (item.mark) (icon ? iconBox : text).appendChild(markElement(item.mark));
|
|
2295
2347
|
el.addEventListener("click", () => this.onTabTap(item.pagePath, index));
|
|
2296
2348
|
this.tabBar.appendChild(el);
|
|
2297
2349
|
});
|
|
2298
2350
|
}
|
|
2351
|
+
tabBarVisible() {
|
|
2352
|
+
return this.tabBarPath !== null && this.hasTabBar(this.tabBarPath);
|
|
2353
|
+
}
|
|
2299
2354
|
/** 页面可用高度,与 getSystemInfo().windowHeight 对应;tabBar 会连同底部安全区一起占掉 */
|
|
2300
2355
|
windowHeight() {
|
|
2301
|
-
return this.profile.screenHeight - this.screenTop() - (this.tabBarVisible ? TAB_BAR_HEIGHT + this.profile.safeAreaBottom : 0);
|
|
2356
|
+
return this.profile.screenHeight - this.screenTop() - (this.tabBarVisible() ? TAB_BAR_HEIGHT + this.profile.safeAreaBottom : 0);
|
|
2302
2357
|
}
|
|
2303
2358
|
/** 页面窗口顶部到屏幕顶部的距离,与 getWindowInfo().screenTop 对应 */
|
|
2304
2359
|
screenTop() {
|
|
@@ -2435,6 +2490,12 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2435
2490
|
this.device.querySelector(".wxa-error")?.remove();
|
|
2436
2491
|
}
|
|
2437
2492
|
};
|
|
2493
|
+
function markElement(mark) {
|
|
2494
|
+
return mark.type === "redDot" ? element("span", "wxa-tabbar-dot") : element("span", "wxa-tabbar-badge", mark.text);
|
|
2495
|
+
}
|
|
2496
|
+
function definedOnly(value) {
|
|
2497
|
+
return Object.fromEntries(Object.entries(value).filter(([, v]) => v !== void 0));
|
|
2498
|
+
}
|
|
2438
2499
|
function maskElement(dim) {
|
|
2439
2500
|
return element("div", "wxa-mask" + (dim ? " is-dim" : ""));
|
|
2440
2501
|
}
|
|
@@ -2843,6 +2904,13 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2843
2904
|
page.navigation = { ...page.navigation, ...Object.fromEntries(Object.entries(state).filter(([, v]) => v !== void 0)) };
|
|
2844
2905
|
this.shell.setNavigation(page.navigation);
|
|
2845
2906
|
}
|
|
2907
|
+
/** tabBar 显隐改变 tab 页窗口是否贴着屏幕底边,已打开的 tab 页要同步底部安全区 */
|
|
2908
|
+
setTabBarHidden(hidden) {
|
|
2909
|
+
this.shell.setTabBarHidden(hidden);
|
|
2910
|
+
for (const page of this.tabPages.values()) {
|
|
2911
|
+
page.setSafeAreaInsets(this.shell.safeAreaInsetsFor(page.path, page.navigation));
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2846
2914
|
registerApis() {
|
|
2847
2915
|
const routeApi = (handler) => (args) => this.enqueueRoute(() => handler(args));
|
|
2848
2916
|
this.api.register({
|
|
@@ -2875,7 +2943,11 @@ html, body { margin: 0; height: 100%; background: radial-gradient(120% 80% at 50
|
|
|
2875
2943
|
...createAudioApis({ emit: (event, data) => this.emitToService(event, data) }),
|
|
2876
2944
|
...createMapApis({ registry: this.api, operations: this.mapOperations }),
|
|
2877
2945
|
...createLibFileApis({ windowOf: (webviewId) => this.pages.get(webviewId)?.win }),
|
|
2878
|
-
...createUiApis({
|
|
2946
|
+
...createUiApis({
|
|
2947
|
+
shell: this.shell,
|
|
2948
|
+
updateNavigation: (state) => this.updateNavigation(state),
|
|
2949
|
+
setTabBarHidden: (hidden) => this.setTabBarHidden(hidden)
|
|
2950
|
+
}),
|
|
2879
2951
|
...createMediaApis({
|
|
2880
2952
|
showActionSheet: (options) => this.shell.showActionSheet(options),
|
|
2881
2953
|
chooseFiles,
|