@sigmela/router 0.3.7 → 0.4.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/CHANGELOG.md +23 -0
- package/LICENSE +2 -1
- package/README.md +108 -479
- package/dist/Router.d.ts +190 -0
- package/dist/Router.d.ts.map +1 -0
- package/dist/components/Modal.d.ts +56 -0
- package/dist/components/Modal.d.ts.map +1 -0
- package/dist/components/OverlayContentScope.d.ts +8 -0
- package/dist/components/OverlayContentScope.d.ts.map +1 -0
- package/dist/components/RouterCloseButton.d.ts +9 -0
- package/dist/components/RouterCloseButton.d.ts.map +1 -0
- package/dist/components/Sheet.d.ts +53 -0
- package/dist/components/Sheet.d.ts.map +1 -0
- package/dist/components/SheetSurface.d.ts +27 -0
- package/dist/components/SheetSurface.d.ts.map +1 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/pageScrollLock.d.ts +3 -0
- package/dist/components/pageScrollLock.d.ts.map +1 -0
- package/dist/components/sheetDragEngine.d.ts +27 -0
- package/dist/components/sheetDragEngine.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3649 -0
- package/dist/index.js.map +1 -0
- package/dist/navigationHistory.d.ts +17 -0
- package/dist/navigationHistory.d.ts.map +1 -0
- package/dist/router.css +971 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/package.json +69 -174
- package/lib/module/Drawer/Drawer.js +0 -250
- package/lib/module/Drawer/DrawerContext.js +0 -4
- package/lib/module/Drawer/DrawerIcon.web.js +0 -47
- package/lib/module/Drawer/RenderDrawer.native.js +0 -248
- package/lib/module/Drawer/RenderDrawer.web.js +0 -197
- package/lib/module/Drawer/useDrawer.js +0 -11
- package/lib/module/Navigation.js +0 -80
- package/lib/module/NavigationStack.js +0 -254
- package/lib/module/Router.js +0 -2171
- package/lib/module/RouterContext.js +0 -33
- package/lib/module/ScreenStack/ScreenStack.native.js +0 -3
- package/lib/module/ScreenStack/ScreenStack.web.js +0 -561
- package/lib/module/ScreenStack/ScreenStackContext.js +0 -21
- package/lib/module/ScreenStack/animationHelpers.js +0 -87
- package/lib/module/ScreenStack/index.js +0 -3
- package/lib/module/ScreenStackItem/ScreenStackItem.js +0 -70
- package/lib/module/ScreenStackItem/ScreenStackItem.types.js +0 -3
- package/lib/module/ScreenStackItem/ScreenStackItem.web.js +0 -171
- package/lib/module/ScreenStackItem/index.js +0 -3
- package/lib/module/ScreenStackSheetItem/ScreenStackSheetItem.native.js +0 -70
- package/lib/module/ScreenStackSheetItem/ScreenStackSheetItem.web.js +0 -5
- package/lib/module/ScreenStackSheetItem/index.js +0 -3
- package/lib/module/SplitView/RenderSplitView.native.js +0 -101
- package/lib/module/SplitView/RenderSplitView.web.js +0 -107
- package/lib/module/SplitView/SplitView.js +0 -97
- package/lib/module/SplitView/SplitViewContext.js +0 -4
- package/lib/module/SplitView/index.js +0 -5
- package/lib/module/SplitView/useSplitView.js +0 -11
- package/lib/module/StackRenderer.js +0 -42
- package/lib/module/TabBar/RenderTabBar.native.js +0 -418
- package/lib/module/TabBar/RenderTabBar.web.js +0 -218
- package/lib/module/TabBar/TabBar.js +0 -208
- package/lib/module/TabBar/TabBarContext.js +0 -4
- package/lib/module/TabBar/TabIcon.web.js +0 -47
- package/lib/module/TabBar/index.js +0 -6
- package/lib/module/TabBar/useTabBar.js +0 -11
- package/lib/module/TabBar/useTabBarHeight.js +0 -22
- package/lib/module/createController.js +0 -5
- package/lib/module/index.js +0 -15
- package/lib/module/navigationNode.js +0 -3
- package/lib/module/package.json +0 -1
- package/lib/module/styles.css +0 -1111
- package/lib/module/types.js +0 -13
- package/lib/typescript/package.json +0 -1
- package/lib/typescript/src/Drawer/Drawer.d.ts +0 -100
- package/lib/typescript/src/Drawer/DrawerContext.d.ts +0 -3
- package/lib/typescript/src/Drawer/DrawerIcon.web.d.ts +0 -7
- package/lib/typescript/src/Drawer/RenderDrawer.native.d.ts +0 -8
- package/lib/typescript/src/Drawer/RenderDrawer.web.d.ts +0 -8
- package/lib/typescript/src/Drawer/useDrawer.d.ts +0 -2
- package/lib/typescript/src/Navigation.d.ts +0 -17
- package/lib/typescript/src/NavigationStack.d.ts +0 -46
- package/lib/typescript/src/Router.d.ts +0 -232
- package/lib/typescript/src/RouterContext.d.ts +0 -18
- package/lib/typescript/src/ScreenStack/ScreenStack.native.d.ts +0 -2
- package/lib/typescript/src/ScreenStack/ScreenStack.web.d.ts +0 -9
- package/lib/typescript/src/ScreenStack/ScreenStackContext.d.ts +0 -31
- package/lib/typescript/src/ScreenStack/animationHelpers.d.ts +0 -6
- package/lib/typescript/src/ScreenStack/index.d.ts +0 -2
- package/lib/typescript/src/ScreenStackItem/ScreenStackItem.d.ts +0 -3
- package/lib/typescript/src/ScreenStackItem/ScreenStackItem.types.d.ts +0 -14
- package/lib/typescript/src/ScreenStackItem/ScreenStackItem.web.d.ts +0 -3
- package/lib/typescript/src/ScreenStackItem/index.d.ts +0 -3
- package/lib/typescript/src/ScreenStackSheetItem/ScreenStackSheetItem.native.d.ts +0 -11
- package/lib/typescript/src/ScreenStackSheetItem/ScreenStackSheetItem.web.d.ts +0 -2
- package/lib/typescript/src/ScreenStackSheetItem/index.d.ts +0 -2
- package/lib/typescript/src/SplitView/RenderSplitView.native.d.ts +0 -19
- package/lib/typescript/src/SplitView/RenderSplitView.web.d.ts +0 -8
- package/lib/typescript/src/SplitView/SplitView.d.ts +0 -33
- package/lib/typescript/src/SplitView/SplitViewContext.d.ts +0 -3
- package/lib/typescript/src/SplitView/index.d.ts +0 -5
- package/lib/typescript/src/SplitView/useSplitView.d.ts +0 -2
- package/lib/typescript/src/StackRenderer.d.ts +0 -8
- package/lib/typescript/src/TabBar/RenderTabBar.native.d.ts +0 -8
- package/lib/typescript/src/TabBar/RenderTabBar.web.d.ts +0 -8
- package/lib/typescript/src/TabBar/TabBar.d.ts +0 -112
- package/lib/typescript/src/TabBar/TabBarContext.d.ts +0 -3
- package/lib/typescript/src/TabBar/TabIcon.web.d.ts +0 -7
- package/lib/typescript/src/TabBar/index.d.ts +0 -5
- package/lib/typescript/src/TabBar/useTabBar.d.ts +0 -2
- package/lib/typescript/src/TabBar/useTabBarHeight.d.ts +0 -18
- package/lib/typescript/src/createController.d.ts +0 -15
- package/lib/typescript/src/index.d.ts +0 -21
- package/lib/typescript/src/navigationNode.d.ts +0 -41
- package/lib/typescript/src/types.d.ts +0 -140
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { StackRenderer } from "../StackRenderer.js";
|
|
4
|
-
import { TabBarContext } from "./TabBarContext.js";
|
|
5
|
-
import { useRouter } from "../RouterContext.js";
|
|
6
|
-
import { TabIcon } from './TabIcon';
|
|
7
|
-
import { useCallback, useSyncExternalStore, memo, useMemo } from 'react';
|
|
8
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
-
const isImageSource = value => {
|
|
10
|
-
if (value == null) return false;
|
|
11
|
-
const valueType = typeof value;
|
|
12
|
-
if (valueType === 'number') return true;
|
|
13
|
-
if (Array.isArray(value)) return value.length > 0;
|
|
14
|
-
if (valueType === 'object') {
|
|
15
|
-
const v = value;
|
|
16
|
-
if ('uri' in v || 'width' in v || 'height' in v) return true;
|
|
17
|
-
}
|
|
18
|
-
return false;
|
|
19
|
-
};
|
|
20
|
-
const toColorString = c => typeof c === 'string' ? c : undefined;
|
|
21
|
-
const TabStackRenderer = /*#__PURE__*/memo(({
|
|
22
|
-
stack,
|
|
23
|
-
appearance
|
|
24
|
-
}) => {
|
|
25
|
-
const router = useRouter();
|
|
26
|
-
const stackId = stack.getId();
|
|
27
|
-
const subscribe = useCallback(cb => router.subscribeStack(stackId, cb), [router, stackId]);
|
|
28
|
-
const get = useCallback(() => router.getStackHistory(stackId), [router, stackId]);
|
|
29
|
-
const history = useSyncExternalStore(subscribe, get, get);
|
|
30
|
-
return /*#__PURE__*/_jsx(StackRenderer, {
|
|
31
|
-
appearance: appearance,
|
|
32
|
-
stackId: stackId,
|
|
33
|
-
history: history
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
TabStackRenderer.displayName = 'TabStackRenderer';
|
|
37
|
-
const TabNodeRenderer = /*#__PURE__*/memo(({
|
|
38
|
-
node,
|
|
39
|
-
appearance
|
|
40
|
-
}) => {
|
|
41
|
-
const Renderer = useMemo(() => node.getRenderer(), [node]);
|
|
42
|
-
return /*#__PURE__*/_jsx(Renderer, {
|
|
43
|
-
appearance: appearance
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
TabNodeRenderer.displayName = 'TabNodeRenderer';
|
|
47
|
-
const joinPrefixAndPath = (prefix, path) => {
|
|
48
|
-
const base = (prefix ?? '').trim();
|
|
49
|
-
const child = (path || '/').trim();
|
|
50
|
-
if (!base) return child || '/';
|
|
51
|
-
const baseNorm = base === '/' ? '' : base.endsWith('/') ? base.slice(0, -1) : base;
|
|
52
|
-
if (!child || child === '/') {
|
|
53
|
-
return baseNorm || '/';
|
|
54
|
-
}
|
|
55
|
-
if (child.startsWith('/')) {
|
|
56
|
-
return `${baseNorm}${child}`;
|
|
57
|
-
}
|
|
58
|
-
return `${baseNorm}/${child}`;
|
|
59
|
-
};
|
|
60
|
-
export const RenderTabBar = /*#__PURE__*/memo(({
|
|
61
|
-
tabBar,
|
|
62
|
-
appearance
|
|
63
|
-
}) => {
|
|
64
|
-
const router = useRouter();
|
|
65
|
-
const subscribe = useCallback(cb => tabBar.subscribe(cb), [tabBar]);
|
|
66
|
-
const snapshot = useSyncExternalStore(subscribe, tabBar.getState, tabBar.getState);
|
|
67
|
-
const {
|
|
68
|
-
tabs,
|
|
69
|
-
index,
|
|
70
|
-
config
|
|
71
|
-
} = snapshot;
|
|
72
|
-
const focusedTab = tabs[index];
|
|
73
|
-
const stack = focusedTab ? tabBar.stacks[focusedTab.tabKey] : undefined;
|
|
74
|
-
const node = focusedTab ? tabBar.nodes[focusedTab.tabKey] : undefined;
|
|
75
|
-
const Screen = focusedTab ? tabBar.screens[focusedTab.tabKey] : undefined;
|
|
76
|
-
const onTabClick = useCallback(nextIndex => {
|
|
77
|
-
const targetTab = tabs[nextIndex];
|
|
78
|
-
if (!targetTab) return;
|
|
79
|
-
const targetStack = tabBar.stacks[targetTab.tabKey];
|
|
80
|
-
const targetNode = tabBar.nodes[targetTab.tabKey];
|
|
81
|
-
if (targetStack) {
|
|
82
|
-
// Keep TabBar UI in sync immediately.
|
|
83
|
-
if (nextIndex !== index) {
|
|
84
|
-
tabBar.onIndexChange(nextIndex);
|
|
85
|
-
}
|
|
86
|
-
const firstRoutePath = targetStack.getFirstRoute()?.path;
|
|
87
|
-
if (firstRoutePath) {
|
|
88
|
-
// Web behavior: reset all preserved stacks when switching tabs.
|
|
89
|
-
// This keeps browser URL and Router state always consistent.
|
|
90
|
-
router.reset(firstRoutePath);
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
} else if (targetNode) {
|
|
94
|
-
// Keep TabBar UI in sync immediately.
|
|
95
|
-
if (nextIndex !== index) {
|
|
96
|
-
tabBar.onIndexChange(nextIndex);
|
|
97
|
-
}
|
|
98
|
-
const seedPath = targetNode.seed?.()?.path;
|
|
99
|
-
const fallbackFirstPath = targetNode.getNodeRoutes()?.[0]?.path;
|
|
100
|
-
const path = seedPath ?? fallbackFirstPath ?? '/';
|
|
101
|
-
const fullPath = joinPrefixAndPath(targetTab.tabPrefix, path);
|
|
102
|
-
router.reset(fullPath);
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (nextIndex !== index) {
|
|
106
|
-
tabBar.onIndexChange(nextIndex);
|
|
107
|
-
}
|
|
108
|
-
}, [router, tabBar, tabs, index]);
|
|
109
|
-
const onKeyDown = useCallback((e, currentIndex) => {
|
|
110
|
-
let nextIndex = currentIndex;
|
|
111
|
-
if (e.key === 'ArrowRight') nextIndex = (currentIndex + 1) % tabs.length;else if (e.key === 'ArrowLeft') nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;else return;
|
|
112
|
-
e.preventDefault();
|
|
113
|
-
onTabClick(nextIndex);
|
|
114
|
-
const container = e.currentTarget.parentElement;
|
|
115
|
-
const buttons = container?.querySelectorAll('[role="tab"]');
|
|
116
|
-
buttons?.[nextIndex]?.focus();
|
|
117
|
-
}, [tabs.length, onTabClick]);
|
|
118
|
-
const tabBarStyle = useMemo(() => {
|
|
119
|
-
const tabBarBg = toColorString(appearance?.tabBar?.backgroundColor);
|
|
120
|
-
const style = {
|
|
121
|
-
...(tabBarBg ? {
|
|
122
|
-
['--tabbar-bg']: tabBarBg
|
|
123
|
-
} : null),
|
|
124
|
-
...(tabs.length ? {
|
|
125
|
-
['--tabbar-tabs-count']: String(tabs.length),
|
|
126
|
-
['--tabbar-active-index']: String(index)
|
|
127
|
-
} : null)
|
|
128
|
-
};
|
|
129
|
-
return Object.keys(style).length ? style : undefined;
|
|
130
|
-
}, [appearance?.tabBar?.backgroundColor, tabs.length, index]);
|
|
131
|
-
const titleBaseStyle = useMemo(() => ({
|
|
132
|
-
fontFamily: appearance?.tabBar?.title?.fontFamily,
|
|
133
|
-
fontSize: appearance?.tabBar?.title?.fontSize,
|
|
134
|
-
fontWeight: appearance?.tabBar?.title?.fontWeight,
|
|
135
|
-
fontStyle: appearance?.tabBar?.title?.fontStyle
|
|
136
|
-
}), [appearance?.tabBar?.title?.fontFamily, appearance?.tabBar?.title?.fontSize, appearance?.tabBar?.title?.fontWeight, appearance?.tabBar?.title?.fontStyle]);
|
|
137
|
-
const handleTabClick = useCallback(e => {
|
|
138
|
-
const index = Number(e.currentTarget.dataset.index);
|
|
139
|
-
onTabClick(index);
|
|
140
|
-
}, [onTabClick]);
|
|
141
|
-
const handleKeyDown = useCallback(e => {
|
|
142
|
-
const index = Number(e.currentTarget.dataset.index);
|
|
143
|
-
onKeyDown(e, index);
|
|
144
|
-
}, [onKeyDown]);
|
|
145
|
-
const CustomTabBar = config.component;
|
|
146
|
-
return /*#__PURE__*/_jsx(TabBarContext.Provider, {
|
|
147
|
-
value: tabBar,
|
|
148
|
-
children: /*#__PURE__*/_jsxs("div", {
|
|
149
|
-
className: "tab-stacks-container",
|
|
150
|
-
children: [stack ? /*#__PURE__*/_jsx(TabStackRenderer, {
|
|
151
|
-
appearance: appearance,
|
|
152
|
-
stack: stack
|
|
153
|
-
}) : node ? /*#__PURE__*/_jsx(TabNodeRenderer, {
|
|
154
|
-
appearance: appearance,
|
|
155
|
-
node: node
|
|
156
|
-
}) : Screen ? /*#__PURE__*/_jsx(Screen, {}) : null, CustomTabBar ? /*#__PURE__*/_jsx(CustomTabBar, {
|
|
157
|
-
onTabPress: onTabClick,
|
|
158
|
-
activeIndex: index,
|
|
159
|
-
tabs: tabs
|
|
160
|
-
}) : /*#__PURE__*/_jsx("div", {
|
|
161
|
-
className: "tab-bar",
|
|
162
|
-
style: tabBarStyle,
|
|
163
|
-
"data-tabs-count": tabs.length,
|
|
164
|
-
"data-active-index": index,
|
|
165
|
-
children: /*#__PURE__*/_jsxs("div", {
|
|
166
|
-
className: "tab-bar-inner",
|
|
167
|
-
children: [/*#__PURE__*/_jsx("div", {
|
|
168
|
-
className: "tab-bar-glass",
|
|
169
|
-
"aria-hidden": "true"
|
|
170
|
-
}), /*#__PURE__*/_jsxs("div", {
|
|
171
|
-
className: "tab-bar-content",
|
|
172
|
-
role: "tablist",
|
|
173
|
-
children: [/*#__PURE__*/_jsx("div", {
|
|
174
|
-
className: "tab-bar-active-indicator",
|
|
175
|
-
"aria-hidden": "true"
|
|
176
|
-
}), tabs.map((tab, i) => {
|
|
177
|
-
const isActive = i === index;
|
|
178
|
-
const iconTint = toColorString(isActive ? appearance?.tabBar?.iconColorActive : appearance?.tabBar?.iconColor);
|
|
179
|
-
const title = appearance?.tabBar?.title;
|
|
180
|
-
const labelColor = isActive ? toColorString(title?.activeColor) ?? toColorString(title?.color) : toColorString(title?.color);
|
|
181
|
-
const labelStyle = {
|
|
182
|
-
...titleBaseStyle,
|
|
183
|
-
color: labelColor
|
|
184
|
-
};
|
|
185
|
-
return /*#__PURE__*/_jsxs("button", {
|
|
186
|
-
type: "button",
|
|
187
|
-
role: "tab",
|
|
188
|
-
id: `tab-${tab.tabKey}`,
|
|
189
|
-
"data-index": i,
|
|
190
|
-
"data-active": isActive ? 'true' : 'false',
|
|
191
|
-
"aria-selected": isActive,
|
|
192
|
-
tabIndex: isActive ? 0 : -1,
|
|
193
|
-
className: `tab-item${isActive ? ' active' : ''}`,
|
|
194
|
-
onClick: handleTabClick,
|
|
195
|
-
onKeyDown: handleKeyDown,
|
|
196
|
-
children: [/*#__PURE__*/_jsx("div", {
|
|
197
|
-
className: "tab-item-icon",
|
|
198
|
-
children: isImageSource(tab.icon) ? /*#__PURE__*/_jsx(TabIcon, {
|
|
199
|
-
source: tab.icon,
|
|
200
|
-
tintColor: iconTint
|
|
201
|
-
}) : null
|
|
202
|
-
}), /*#__PURE__*/_jsx("div", {
|
|
203
|
-
className: "tab-item-label",
|
|
204
|
-
style: labelStyle,
|
|
205
|
-
children: tab.title
|
|
206
|
-
}), tab.badgeValue ? /*#__PURE__*/_jsx("span", {
|
|
207
|
-
className: "tab-item-label-badge",
|
|
208
|
-
"aria-label": `${tab.badgeValue} notifications`,
|
|
209
|
-
children: tab.badgeValue
|
|
210
|
-
}) : null]
|
|
211
|
-
}, tab.tabKey);
|
|
212
|
-
})]
|
|
213
|
-
})]
|
|
214
|
-
})
|
|
215
|
-
})]
|
|
216
|
-
})
|
|
217
|
-
});
|
|
218
|
-
});
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { RenderTabBar } from './RenderTabBar';
|
|
5
|
-
|
|
6
|
-
// Legacy icon format for backward compatibility
|
|
7
|
-
|
|
8
|
-
export class TabBar {
|
|
9
|
-
screens = {};
|
|
10
|
-
stacks = {};
|
|
11
|
-
nodes = {};
|
|
12
|
-
listeners = new Set();
|
|
13
|
-
_cachedRenderer = null;
|
|
14
|
-
constructor(options = {}) {
|
|
15
|
-
this.tabBarId = `tabbar-${Math.random().toString(36).slice(2)}`;
|
|
16
|
-
this.state = {
|
|
17
|
-
tabs: [],
|
|
18
|
-
index: options.initialIndex ?? 0,
|
|
19
|
-
config: {
|
|
20
|
-
component: options.component
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
getId() {
|
|
25
|
-
return this.tabBarId;
|
|
26
|
-
}
|
|
27
|
-
addTab(tab) {
|
|
28
|
-
const sourcesCount = (tab.stack ? 1 : 0) + (tab.node ? 1 : 0) + (tab.screen ? 1 : 0);
|
|
29
|
-
if (sourcesCount !== 1) {
|
|
30
|
-
throw new Error(`TabBar.addTab: exactly one of { stack, node, screen } must be provided (got ${sourcesCount})`);
|
|
31
|
-
}
|
|
32
|
-
const {
|
|
33
|
-
key,
|
|
34
|
-
...rest
|
|
35
|
-
} = tab;
|
|
36
|
-
const nextIndex = this.state.tabs.length;
|
|
37
|
-
const tabKey = key ?? `tab-${nextIndex}`;
|
|
38
|
-
const nextTabs = [...this.state.tabs, {
|
|
39
|
-
tabKey,
|
|
40
|
-
tabPrefix: tab.prefix,
|
|
41
|
-
...rest
|
|
42
|
-
}];
|
|
43
|
-
this.setState({
|
|
44
|
-
tabs: nextTabs
|
|
45
|
-
});
|
|
46
|
-
if (tab.stack) {
|
|
47
|
-
this.stacks[tabKey] = tab.stack;
|
|
48
|
-
} else if (tab.node) {
|
|
49
|
-
this.nodes[tabKey] = tab.node;
|
|
50
|
-
} else if (tab.screen) {
|
|
51
|
-
this.screens[tabKey] = tab.screen;
|
|
52
|
-
}
|
|
53
|
-
return this;
|
|
54
|
-
}
|
|
55
|
-
setBadge(tabIndex, badge) {
|
|
56
|
-
this.setState({
|
|
57
|
-
tabs: this.state.tabs.map((route, index) => index === tabIndex ? {
|
|
58
|
-
...route,
|
|
59
|
-
badgeValue: badge ?? undefined
|
|
60
|
-
} : route)
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
setTabBarConfig(config) {
|
|
64
|
-
this.setState({
|
|
65
|
-
config: {
|
|
66
|
-
...this.state.config,
|
|
67
|
-
...config
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
onIndexChange(index) {
|
|
72
|
-
this.setState({
|
|
73
|
-
index
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
getState = () => {
|
|
77
|
-
return this.state;
|
|
78
|
-
};
|
|
79
|
-
setState(state) {
|
|
80
|
-
this.state = {
|
|
81
|
-
...this.state,
|
|
82
|
-
...state
|
|
83
|
-
};
|
|
84
|
-
this.notifyListeners();
|
|
85
|
-
}
|
|
86
|
-
notifyListeners() {
|
|
87
|
-
// Do not allow one listener to break all others.
|
|
88
|
-
for (const listener of Array.from(this.listeners)) {
|
|
89
|
-
try {
|
|
90
|
-
listener();
|
|
91
|
-
} catch (e) {
|
|
92
|
-
// TabBar has no debug flag; keep behavior quiet in production.
|
|
93
|
-
if (__DEV__) {
|
|
94
|
-
console.error('[TabBar] listener error', e);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
subscribe(listener) {
|
|
100
|
-
this.listeners.add(listener);
|
|
101
|
-
return () => {
|
|
102
|
-
this.listeners.delete(listener);
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
getTabs() {
|
|
106
|
-
return this.state.tabs.slice();
|
|
107
|
-
}
|
|
108
|
-
getInitialIndex() {
|
|
109
|
-
return this.state.index ?? 0;
|
|
110
|
-
}
|
|
111
|
-
getActiveChildId() {
|
|
112
|
-
const activeTab = this.state.tabs[this.state.index];
|
|
113
|
-
if (!activeTab) return undefined;
|
|
114
|
-
const node = this.nodes[activeTab.tabKey] ?? this.stacks[activeTab.tabKey];
|
|
115
|
-
return node?.getId();
|
|
116
|
-
}
|
|
117
|
-
switchToRoute(routeId) {
|
|
118
|
-
const idx = this.findTabIndexByRoute(routeId);
|
|
119
|
-
if (idx === -1) return;
|
|
120
|
-
if (idx === this.state.index) return;
|
|
121
|
-
this.setState({
|
|
122
|
-
index: idx
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
hasRoute(routeId) {
|
|
126
|
-
return this.findTabIndexByRoute(routeId) !== -1;
|
|
127
|
-
}
|
|
128
|
-
setActiveChildByRoute(routeId) {
|
|
129
|
-
this.switchToRoute(routeId);
|
|
130
|
-
}
|
|
131
|
-
getNodeRoutes() {
|
|
132
|
-
return [];
|
|
133
|
-
}
|
|
134
|
-
getNodeChildren() {
|
|
135
|
-
const children = [];
|
|
136
|
-
for (let idx = 0; idx < this.state.tabs.length; idx++) {
|
|
137
|
-
const tab = this.state.tabs[idx];
|
|
138
|
-
const node = tab ? this.nodes[tab.tabKey] ?? this.stacks[tab.tabKey] : undefined;
|
|
139
|
-
if (node) {
|
|
140
|
-
children.push({
|
|
141
|
-
prefix: tab?.tabPrefix ?? '',
|
|
142
|
-
node,
|
|
143
|
-
onMatch: () => this.onIndexChange(idx)
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return children;
|
|
148
|
-
}
|
|
149
|
-
getRenderer() {
|
|
150
|
-
if (this._cachedRenderer) {
|
|
151
|
-
return this._cachedRenderer;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// eslint-disable-next-line consistent-this
|
|
155
|
-
const tabBarInstance = this;
|
|
156
|
-
const renderer = function TabBarScreen(props) {
|
|
157
|
-
return /*#__PURE__*/React.createElement(RenderTabBar, {
|
|
158
|
-
tabBar: tabBarInstance,
|
|
159
|
-
appearance: props?.appearance
|
|
160
|
-
});
|
|
161
|
-
};
|
|
162
|
-
this._cachedRenderer = renderer;
|
|
163
|
-
return renderer;
|
|
164
|
-
}
|
|
165
|
-
seed() {
|
|
166
|
-
const activeTab = this.state.tabs[this.state.index];
|
|
167
|
-
if (!activeTab) return null;
|
|
168
|
-
const node = this.nodes[activeTab.tabKey];
|
|
169
|
-
if (node) {
|
|
170
|
-
return node.seed?.() ?? null;
|
|
171
|
-
}
|
|
172
|
-
const stack = this.stacks[activeTab.tabKey];
|
|
173
|
-
if (!stack) return null;
|
|
174
|
-
const firstRoute = stack.getFirstRoute();
|
|
175
|
-
if (!firstRoute) return null;
|
|
176
|
-
return {
|
|
177
|
-
routeId: firstRoute.routeId,
|
|
178
|
-
path: firstRoute.path,
|
|
179
|
-
stackId: stack.getId()
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
findTabIndexByRoute(routeId) {
|
|
183
|
-
for (let i = 0; i < this.state.tabs.length; i++) {
|
|
184
|
-
const tab = this.state.tabs[i];
|
|
185
|
-
const node = tab ? this.nodes[tab.tabKey] ?? this.stacks[tab.tabKey] : undefined;
|
|
186
|
-
if (!node) continue;
|
|
187
|
-
const hasRoute = this.nodeHasRoute(node, routeId);
|
|
188
|
-
if (hasRoute) {
|
|
189
|
-
return i;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return -1;
|
|
193
|
-
}
|
|
194
|
-
nodeHasRoute(node, routeId) {
|
|
195
|
-
const routes = node.getNodeRoutes();
|
|
196
|
-
for (const r of routes) {
|
|
197
|
-
if (r.routeId === routeId) return true;
|
|
198
|
-
if (r.childNode) {
|
|
199
|
-
if (this.nodeHasRoute(r.childNode, routeId)) return true;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
const children = node.getNodeChildren();
|
|
203
|
-
for (const child of children) {
|
|
204
|
-
if (this.nodeHasRoute(child.node, routeId)) return true;
|
|
205
|
-
}
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { memo, useMemo } from 'react';
|
|
4
|
-
import { Image } from 'react-native';
|
|
5
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
-
const resolveImageUri = source => {
|
|
7
|
-
if (!source) return undefined;
|
|
8
|
-
const resolved = typeof Image.resolveAssetSource === 'function' ? Image.resolveAssetSource(source) : undefined;
|
|
9
|
-
if (resolved?.uri) return resolved.uri;
|
|
10
|
-
if (Array.isArray(source)) {
|
|
11
|
-
const first = source[0];
|
|
12
|
-
if (first && typeof first === 'object' && 'uri' in first) return first.uri;
|
|
13
|
-
}
|
|
14
|
-
if (typeof source === 'object' && source && 'uri' in source) return source.uri;
|
|
15
|
-
return undefined;
|
|
16
|
-
};
|
|
17
|
-
export const TabIcon = /*#__PURE__*/memo(({
|
|
18
|
-
source,
|
|
19
|
-
tintColor
|
|
20
|
-
}) => {
|
|
21
|
-
const iconUri = resolveImageUri(source);
|
|
22
|
-
const useMask = Boolean(tintColor && iconUri);
|
|
23
|
-
const maskStyle = useMemo(() => {
|
|
24
|
-
if (!useMask || !iconUri) return undefined;
|
|
25
|
-
return {
|
|
26
|
-
backgroundColor: tintColor,
|
|
27
|
-
WebkitMaskImage: `url(${iconUri})`,
|
|
28
|
-
WebkitMaskSize: 'contain',
|
|
29
|
-
WebkitMaskRepeat: 'no-repeat',
|
|
30
|
-
WebkitMaskPosition: 'center',
|
|
31
|
-
maskImage: `url(${iconUri})`,
|
|
32
|
-
maskSize: 'contain',
|
|
33
|
-
maskRepeat: 'no-repeat',
|
|
34
|
-
maskPosition: 'center',
|
|
35
|
-
width: '100%',
|
|
36
|
-
height: '100%'
|
|
37
|
-
};
|
|
38
|
-
}, [tintColor, iconUri, useMask]);
|
|
39
|
-
if (maskStyle) {
|
|
40
|
-
return /*#__PURE__*/_jsx("div", {
|
|
41
|
-
style: maskStyle
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
return /*#__PURE__*/_jsx(Image, {
|
|
45
|
-
source: source
|
|
46
|
-
});
|
|
47
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { useContext } from 'react';
|
|
4
|
-
import { TabBarContext } from "./TabBarContext.js";
|
|
5
|
-
export const useTabBar = () => {
|
|
6
|
-
const tabBar = useContext(TabBarContext);
|
|
7
|
-
if (!tabBar) {
|
|
8
|
-
throw new Error('useTabBar must be used within a TabBarProvider');
|
|
9
|
-
}
|
|
10
|
-
return tabBar;
|
|
11
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The height of the TabBar in pixels
|
|
5
|
-
*/
|
|
6
|
-
export const TAB_BAR_HEIGHT = 57;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Hook that returns the height of the TabBar
|
|
10
|
-
* @returns {number} The height of the TabBar in pixels
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```tsx
|
|
14
|
-
* const TabBarExample = () => {
|
|
15
|
-
* const tabBarHeight = useTabBarHeight();
|
|
16
|
-
* return <div style={{ paddingBottom: tabBarHeight }}>Content</div>;
|
|
17
|
-
* };
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export const useTabBarHeight = () => {
|
|
21
|
-
return TAB_BAR_HEIGHT;
|
|
22
|
-
};
|
package/lib/module/index.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
export { useTabBar } from "./TabBar/useTabBar.js";
|
|
4
|
-
export { useTabBarHeight, TAB_BAR_HEIGHT } from "./TabBar/useTabBarHeight.js";
|
|
5
|
-
export { TabBar } from "./TabBar/TabBar.js";
|
|
6
|
-
export { Drawer } from "./Drawer/Drawer.js";
|
|
7
|
-
export { useDrawer } from "./Drawer/useDrawer.js";
|
|
8
|
-
export { SplitView } from "./SplitView/SplitView.js";
|
|
9
|
-
export { useSplitView } from "./SplitView/useSplitView.js";
|
|
10
|
-
export { Router } from "./Router.js";
|
|
11
|
-
export { Navigation } from "./Navigation.js";
|
|
12
|
-
export { createController } from "./createController.js";
|
|
13
|
-
export { NavigationStack } from "./NavigationStack.js";
|
|
14
|
-
export { StackRenderer } from "./StackRenderer.js";
|
|
15
|
-
export { useRouter, useCurrentRoute, useParams, useQueryParams, useRoute } from "./RouterContext.js";
|
package/lib/module/package.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"type":"module"}
|