@dloizides/ui-nav 1.26.2 → 1.27.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 +4 -0
- package/dist/index.d.mts +32 -2
- package/dist/index.d.ts +32 -2
- package/dist/index.js +336 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +336 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useState, useCallback, useMemo, useEffect, useRef } from 'react';
|
|
2
|
-
import { StyleSheet, Platform, Pressable, Text, View, TextInput, useWindowDimensions, ScrollView, ActivityIndicator } from 'react-native';
|
|
2
|
+
import { StyleSheet, Platform, Pressable, Text, View, TextInput, useWindowDimensions, ScrollView, ActivityIndicator, Animated } from 'react-native';
|
|
3
3
|
import { useUi, UiProvider } from '@dloizides/ui-feedback';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
-
import { Collapse } from '@dloizides/ui-motion';
|
|
5
|
+
import { Collapse, motionDurations, motionEasings } from '@dloizides/ui-motion';
|
|
6
6
|
import { LAYOUT_COLLAPSE_BREAKPOINT, ModalDropdown, DropdownVariant, SelectedMarker } from '@dloizides/ui-layout';
|
|
7
7
|
import { Z_INDEX } from '@dloizides/design-tokens';
|
|
8
8
|
import { resolveAccessibleRoutes } from '@dloizides/auth-web';
|
|
@@ -1051,10 +1051,88 @@ var Topbar = ({
|
|
|
1051
1051
|
}
|
|
1052
1052
|
);
|
|
1053
1053
|
};
|
|
1054
|
+
|
|
1055
|
+
// src/NavHoverFeedback.ts
|
|
1056
|
+
var NavHoverFeedback = /* @__PURE__ */ ((NavHoverFeedback2) => {
|
|
1057
|
+
NavHoverFeedback2["Default"] = "default";
|
|
1058
|
+
NavHoverFeedback2["TintPill"] = "tint-pill";
|
|
1059
|
+
NavHoverFeedback2["Underline"] = "underline";
|
|
1060
|
+
NavHoverFeedback2["Lift"] = "lift";
|
|
1061
|
+
NavHoverFeedback2["SlidingHighlight"] = "sliding-highlight";
|
|
1062
|
+
return NavHoverFeedback2;
|
|
1063
|
+
})(NavHoverFeedback || {});
|
|
1064
|
+
|
|
1065
|
+
// src/feedback/navLinkFeedback.ts
|
|
1066
|
+
var DEFAULT_FADE_MS = 150;
|
|
1067
|
+
var PRESS_SCALE = 0.97;
|
|
1068
|
+
var PRESS_NUDGE_PX = 1;
|
|
1069
|
+
var LIFT_PX = -2;
|
|
1070
|
+
var PILL_KINDS = /* @__PURE__ */ new Set([
|
|
1071
|
+
"default" /* Default */,
|
|
1072
|
+
"tint-pill" /* TintPill */,
|
|
1073
|
+
"lift" /* Lift */
|
|
1074
|
+
]);
|
|
1075
|
+
function pillBackground(kind, isHovered, active, colors) {
|
|
1076
|
+
if (!PILL_KINDS.has(kind)) return void 0;
|
|
1077
|
+
if (active) return colors.activeBg;
|
|
1078
|
+
return isHovered ? colors.hoverBg : void 0;
|
|
1079
|
+
}
|
|
1080
|
+
function linkTextColor(kind, isHovered, active, colors) {
|
|
1081
|
+
if (active) return PILL_KINDS.has(kind) ? colors.onPrimary : colors.activeBg;
|
|
1082
|
+
return isHovered ? colors.hoverText : colors.rest;
|
|
1083
|
+
}
|
|
1084
|
+
function pressTransform(kind, pressed, isHovered) {
|
|
1085
|
+
if (kind === "tint-pill" /* TintPill */) return pressed ? [{ scale: PRESS_SCALE }] : void 0;
|
|
1086
|
+
if (kind === "underline" /* Underline */) return pressed ? [{ translateY: PRESS_NUDGE_PX }] : void 0;
|
|
1087
|
+
if (kind !== "lift" /* Lift */) return void 0;
|
|
1088
|
+
if (pressed) return [{ translateY: 0 }];
|
|
1089
|
+
return isHovered ? [{ translateY: LIFT_PX }] : void 0;
|
|
1090
|
+
}
|
|
1091
|
+
function feedbackDuration(kind) {
|
|
1092
|
+
if (kind === "default" /* Default */) return DEFAULT_FADE_MS;
|
|
1093
|
+
return kind === "tint-pill" /* TintPill */ ? motionDurations.fast : motionDurations.base;
|
|
1094
|
+
}
|
|
1095
|
+
function resolveLinkFeedback(kind, state, colors, reducedMotion) {
|
|
1096
|
+
const isHovered = state.hovered && !state.active;
|
|
1097
|
+
const underlined = state.active || isHovered;
|
|
1098
|
+
return {
|
|
1099
|
+
background: pillBackground(kind, isHovered, state.active, colors),
|
|
1100
|
+
textColor: linkTextColor(kind, isHovered, state.active, colors),
|
|
1101
|
+
transform: reducedMotion ? void 0 : pressTransform(kind, state.pressed, isHovered),
|
|
1102
|
+
shadow: kind === "lift" /* Lift */ && isHovered,
|
|
1103
|
+
underline: kind === "underline" /* Underline */ ? { color: colors.activeBg, scale: underlined ? 1 : 0 } : null,
|
|
1104
|
+
durationMs: reducedMotion ? motionDurations.instant : feedbackDuration(kind)
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1054
1107
|
var TEXT_ON_PRIMARY2 = "#ffffff";
|
|
1055
1108
|
function ariaCurrentProps2(isActive) {
|
|
1056
1109
|
return isActive ? { "aria-current": "page" } : {};
|
|
1057
1110
|
}
|
|
1111
|
+
var FEEDBACK_PROPERTIES = "color, background-color, transform, box-shadow";
|
|
1112
|
+
var UNDERLINE_INSET = 14;
|
|
1113
|
+
var UNDERLINE_HEIGHT = 2;
|
|
1114
|
+
var SHADOW_OPACITY = 0.18;
|
|
1115
|
+
var SHADOW_RADIUS = 6;
|
|
1116
|
+
var SHADOW_OFFSET = { width: 0, height: 2 };
|
|
1117
|
+
function feedbackStyle(kind, feedback, shadowColor, reducedMotion) {
|
|
1118
|
+
const background = feedback.background === void 0 ? {} : { backgroundColor: feedback.background };
|
|
1119
|
+
const shadow = feedback.shadow ? { shadowColor, shadowOpacity: SHADOW_OPACITY, shadowRadius: SHADOW_RADIUS, shadowOffset: SHADOW_OFFSET } : {};
|
|
1120
|
+
const transition = kind === "default" /* Default */ ? hoverTransitionStyle(reducedMotion) : webTransition(FEEDBACK_PROPERTIES, feedback.durationMs, reducedMotion);
|
|
1121
|
+
return [background, shadow, { transform: feedback.transform }, transition ?? {}];
|
|
1122
|
+
}
|
|
1123
|
+
function underlineStyle(feedback, reducedMotion) {
|
|
1124
|
+
if (feedback.underline === null) return null;
|
|
1125
|
+
const line = {
|
|
1126
|
+
position: "absolute",
|
|
1127
|
+
left: UNDERLINE_INSET,
|
|
1128
|
+
right: UNDERLINE_INSET,
|
|
1129
|
+
bottom: 0,
|
|
1130
|
+
height: UNDERLINE_HEIGHT,
|
|
1131
|
+
backgroundColor: feedback.underline.color,
|
|
1132
|
+
transform: [{ scaleX: feedback.underline.scale }]
|
|
1133
|
+
};
|
|
1134
|
+
return [line, webTransition("transform", feedback.durationMs, reducedMotion) ?? {}];
|
|
1135
|
+
}
|
|
1058
1136
|
var NavBarLink = ({
|
|
1059
1137
|
item,
|
|
1060
1138
|
isActive,
|
|
@@ -1063,13 +1141,20 @@ var NavBarLink = ({
|
|
|
1063
1141
|
reducedMotion,
|
|
1064
1142
|
colors,
|
|
1065
1143
|
navigateHint,
|
|
1066
|
-
onPress
|
|
1144
|
+
onPress,
|
|
1145
|
+
hoverFeedback = "default" /* Default */,
|
|
1146
|
+
onHoverChange
|
|
1067
1147
|
}) => {
|
|
1068
1148
|
const [hovered, setHovered] = useState(false);
|
|
1069
1149
|
const [focused, setFocused] = useState(false);
|
|
1070
|
-
const
|
|
1071
|
-
const
|
|
1072
|
-
const
|
|
1150
|
+
const linkColors = { ...colors, onPrimary: TEXT_ON_PRIMARY2 };
|
|
1151
|
+
const resolve = (pressed) => resolveLinkFeedback(hoverFeedback, { hovered, pressed, active: isActive }, linkColors, reducedMotion);
|
|
1152
|
+
const textColor = resolve(false).textColor;
|
|
1153
|
+
const underline = underlineStyle(resolve(false), reducedMotion);
|
|
1154
|
+
const setHover = (next) => {
|
|
1155
|
+
setHovered(next);
|
|
1156
|
+
onHoverChange?.(item.key, next);
|
|
1157
|
+
};
|
|
1073
1158
|
return /* @__PURE__ */ jsxs(
|
|
1074
1159
|
Pressable,
|
|
1075
1160
|
{
|
|
@@ -1077,27 +1162,61 @@ var NavBarLink = ({
|
|
|
1077
1162
|
accessibilityLabel: item.label,
|
|
1078
1163
|
accessibilityRole: "link",
|
|
1079
1164
|
accessibilityState: { selected: isActive },
|
|
1080
|
-
style: [
|
|
1165
|
+
style: ({ pressed }) => [
|
|
1081
1166
|
navBarStyles.link,
|
|
1082
1167
|
collapsed ? navBarStyles.linkStacked : void 0,
|
|
1083
|
-
|
|
1084
|
-
hoverTransitionStyle(reducedMotion),
|
|
1168
|
+
...feedbackStyle(hoverFeedback, resolve(pressed), colors.rest, reducedMotion),
|
|
1085
1169
|
focusRingStyle(focused, colors.ring)
|
|
1086
1170
|
],
|
|
1087
1171
|
testID: item.testID ?? item.key,
|
|
1088
1172
|
onBlur: () => setFocused(false),
|
|
1089
1173
|
onFocus: () => setFocused(true),
|
|
1090
|
-
onHoverIn: () =>
|
|
1091
|
-
onHoverOut: () =>
|
|
1174
|
+
onHoverIn: () => setHover(true),
|
|
1175
|
+
onHoverOut: () => setHover(false),
|
|
1092
1176
|
onPress: () => onPress(item.route),
|
|
1093
1177
|
...ariaCurrentProps2(isActive),
|
|
1094
1178
|
children: [
|
|
1095
1179
|
typeof item.renderIcon === "function" ? /* @__PURE__ */ jsx(View, { style: navBarStyles.linkIcon, children: item.renderIcon(textColor, iconSize) }) : null,
|
|
1180
|
+
underline === null ? null : /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: underline }),
|
|
1096
1181
|
/* @__PURE__ */ jsx(Text, { style: [navBarStyles.linkText, { color: textColor }], children: item.label })
|
|
1097
1182
|
]
|
|
1098
1183
|
}
|
|
1099
1184
|
);
|
|
1100
1185
|
};
|
|
1186
|
+
var HIGHLIGHT_RADIUS = 8;
|
|
1187
|
+
var SLIDE_PROPERTIES = "left, top, width, height";
|
|
1188
|
+
function slideHighlightRect(layouts, activeKey, hoveredKey) {
|
|
1189
|
+
const hoveredRect = hoveredKey === null ? void 0 : layouts[hoveredKey];
|
|
1190
|
+
const activeRect = activeKey === void 0 ? void 0 : layouts[activeKey];
|
|
1191
|
+
return hoveredRect ?? activeRect ?? null;
|
|
1192
|
+
}
|
|
1193
|
+
function useSlidingHighlight(enabled, activeKey, color, reducedMotion) {
|
|
1194
|
+
const [layouts, setLayouts] = useState({});
|
|
1195
|
+
const [hoveredKey, setHoveredKey] = useState(null);
|
|
1196
|
+
const measure = useCallback(
|
|
1197
|
+
(key, layout) => {
|
|
1198
|
+
if (enabled) setLayouts((prev) => ({ ...prev, [key]: layout }));
|
|
1199
|
+
},
|
|
1200
|
+
[enabled]
|
|
1201
|
+
);
|
|
1202
|
+
const hover = useCallback((key, hovered) => {
|
|
1203
|
+
setHoveredKey((prev) => hovered ? key : prev === key ? null : prev);
|
|
1204
|
+
}, []);
|
|
1205
|
+
const rect = enabled ? slideHighlightRect(layouts, activeKey, hoveredKey) : null;
|
|
1206
|
+
const style = rect === null ? null : [
|
|
1207
|
+
{
|
|
1208
|
+
position: "absolute",
|
|
1209
|
+
left: rect.x,
|
|
1210
|
+
top: rect.y,
|
|
1211
|
+
width: rect.width,
|
|
1212
|
+
height: rect.height,
|
|
1213
|
+
borderRadius: HIGHLIGHT_RADIUS,
|
|
1214
|
+
backgroundColor: color
|
|
1215
|
+
},
|
|
1216
|
+
webTransition(SLIDE_PROPERTIES, motionDurations.base, reducedMotion)
|
|
1217
|
+
];
|
|
1218
|
+
return { style, measure, hover };
|
|
1219
|
+
}
|
|
1101
1220
|
var TEXT_ON_PRIMARY3 = "#ffffff";
|
|
1102
1221
|
var NO_ACTIVE_ROUTE = "";
|
|
1103
1222
|
var OVERFLOW_MENU_MIN_WIDTH = 200;
|
|
@@ -1238,7 +1357,8 @@ var NavBarInner = ({
|
|
|
1238
1357
|
overflowLabel = "More",
|
|
1239
1358
|
overflowHint = "",
|
|
1240
1359
|
containerStyle,
|
|
1241
|
-
contentMaxWidth
|
|
1360
|
+
contentMaxWidth,
|
|
1361
|
+
hoverFeedback = "default" /* Default */
|
|
1242
1362
|
}) => {
|
|
1243
1363
|
const { theme } = useUi();
|
|
1244
1364
|
const colors = theme.colors;
|
|
@@ -1272,6 +1392,12 @@ var NavBarInner = ({
|
|
|
1272
1392
|
[onNavigate]
|
|
1273
1393
|
);
|
|
1274
1394
|
const activeRoute = resolveActiveRoute(items, pathname);
|
|
1395
|
+
const slide = useSlidingHighlight(
|
|
1396
|
+
hoverFeedback === "sliding-highlight" /* SlidingHighlight */,
|
|
1397
|
+
items.find((item) => item.route === activeRoute)?.key,
|
|
1398
|
+
colors.surfaceElevated,
|
|
1399
|
+
reducedMotion
|
|
1400
|
+
);
|
|
1275
1401
|
const linkColors = useMemo(
|
|
1276
1402
|
() => ({
|
|
1277
1403
|
rest: colors.textSecondary,
|
|
@@ -1321,9 +1447,11 @@ var NavBarInner = ({
|
|
|
1321
1447
|
colors: linkColors,
|
|
1322
1448
|
iconSize: NAV_ICON_SIZE,
|
|
1323
1449
|
isActive: item.route === activeRoute,
|
|
1450
|
+
hoverFeedback,
|
|
1324
1451
|
item,
|
|
1325
1452
|
navigateHint,
|
|
1326
1453
|
reducedMotion,
|
|
1454
|
+
onHoverChange: slide.hover,
|
|
1327
1455
|
onPress: handlePress
|
|
1328
1456
|
}
|
|
1329
1457
|
);
|
|
@@ -1349,11 +1477,15 @@ var NavBarInner = ({
|
|
|
1349
1477
|
testID: NAV_TEST_IDS.navBarLinks,
|
|
1350
1478
|
onLayout: (event) => setAvailableWidth(event.nativeEvent.layout.width),
|
|
1351
1479
|
children: [
|
|
1480
|
+
slide.style === null ? null : /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: slide.style }),
|
|
1352
1481
|
visibleItems.map((item, index) => /* @__PURE__ */ jsx(
|
|
1353
1482
|
View,
|
|
1354
1483
|
{
|
|
1355
1484
|
style: navBarStyles.linkCell,
|
|
1356
|
-
onLayout: (event) =>
|
|
1485
|
+
onLayout: (event) => {
|
|
1486
|
+
setItemWidth(index, event.nativeEvent.layout.width);
|
|
1487
|
+
slide.measure(item.key, event.nativeEvent.layout);
|
|
1488
|
+
},
|
|
1357
1489
|
children: renderLink(item)
|
|
1358
1490
|
},
|
|
1359
1491
|
item.key
|
|
@@ -2214,6 +2346,196 @@ function accessibleNavItems(user, table, translate) {
|
|
|
2214
2346
|
return roleRoutesToNavItems(resolveAccessibleRoutes(user, table), translate);
|
|
2215
2347
|
}
|
|
2216
2348
|
|
|
2217
|
-
|
|
2349
|
+
// src/TabFeedback.ts
|
|
2350
|
+
var TabFeedback = /* @__PURE__ */ ((TabFeedback2) => {
|
|
2351
|
+
TabFeedback2["Default"] = "default";
|
|
2352
|
+
TabFeedback2["IndicatorPill"] = "indicator-pill";
|
|
2353
|
+
TabFeedback2["DimSpring"] = "dim-spring";
|
|
2354
|
+
TabFeedback2["SlidingBar"] = "sliding-bar";
|
|
2355
|
+
TabFeedback2["IconLift"] = "icon-lift";
|
|
2356
|
+
return TabFeedback2;
|
|
2357
|
+
})(TabFeedback || {});
|
|
2358
|
+
|
|
2359
|
+
// src/feedback/tabPressFeedback.ts
|
|
2360
|
+
var FULL = 1;
|
|
2361
|
+
var PERCENT = 100;
|
|
2362
|
+
var PRESS_ICON_SCALE = 0.92;
|
|
2363
|
+
var DIM_OPACITY = 0.6;
|
|
2364
|
+
var ICON_LIFT_PX = -3;
|
|
2365
|
+
var SPRING_OVERSHOOT = 1.06;
|
|
2366
|
+
function tabIconTransform(kind, state) {
|
|
2367
|
+
if (kind === "indicator-pill" /* IndicatorPill */ && state.pressed) return [{ scale: PRESS_ICON_SCALE }];
|
|
2368
|
+
const lifted = state.active || state.pressed;
|
|
2369
|
+
return kind === "icon-lift" /* IconLift */ && lifted ? [{ translateY: ICON_LIFT_PX }] : void 0;
|
|
2370
|
+
}
|
|
2371
|
+
function tabDuration(kind) {
|
|
2372
|
+
if (kind === "default" /* Default */) return motionDurations.instant;
|
|
2373
|
+
const slow = kind === "dim-spring" /* DimSpring */ || kind === "sliding-bar" /* SlidingBar */;
|
|
2374
|
+
return slow ? motionDurations.slow : motionDurations.base;
|
|
2375
|
+
}
|
|
2376
|
+
function resolveTabFeedback(kind, state, reducedMotion) {
|
|
2377
|
+
const pillScale = state.active ? FULL : 0;
|
|
2378
|
+
return {
|
|
2379
|
+
opacity: kind === "dim-spring" /* DimSpring */ && state.pressed ? DIM_OPACITY : FULL,
|
|
2380
|
+
iconTransform: reducedMotion ? void 0 : tabIconTransform(kind, state),
|
|
2381
|
+
pillScale: kind === "indicator-pill" /* IndicatorPill */ ? pillScale : null,
|
|
2382
|
+
spring: kind === "dim-spring" /* DimSpring */ && !reducedMotion,
|
|
2383
|
+
durationMs: reducedMotion ? motionDurations.instant : tabDuration(kind)
|
|
2384
|
+
};
|
|
2385
|
+
}
|
|
2386
|
+
function slidingBarPosition(activeIndex, count) {
|
|
2387
|
+
if (activeIndex < 0 || count <= 0) return null;
|
|
2388
|
+
const share = PERCENT / count;
|
|
2389
|
+
return { left: `${activeIndex * share}%`, width: `${share}%` };
|
|
2390
|
+
}
|
|
2391
|
+
function springSteps() {
|
|
2392
|
+
return [
|
|
2393
|
+
{ toValue: SPRING_OVERSHOOT, durationMs: motionDurations.fast },
|
|
2394
|
+
{ toValue: FULL, durationMs: motionDurations.slow - motionDurations.fast }
|
|
2395
|
+
];
|
|
2396
|
+
}
|
|
2397
|
+
function useSettleSpring(active, enabled) {
|
|
2398
|
+
const scale = useRef(new Animated.Value(FULL)).current;
|
|
2399
|
+
useEffect(() => {
|
|
2400
|
+
if (!enabled || !active) return void 0;
|
|
2401
|
+
const steps = springSteps().map(
|
|
2402
|
+
(step) => Animated.timing(scale, {
|
|
2403
|
+
toValue: step.toValue,
|
|
2404
|
+
duration: step.durationMs,
|
|
2405
|
+
easing: motionEasings.standard,
|
|
2406
|
+
useNativeDriver: false
|
|
2407
|
+
})
|
|
2408
|
+
);
|
|
2409
|
+
const animation = Animated.sequence(steps);
|
|
2410
|
+
animation.start();
|
|
2411
|
+
return () => animation.stop();
|
|
2412
|
+
}, [active, enabled, scale]);
|
|
2413
|
+
return scale;
|
|
2414
|
+
}
|
|
2415
|
+
var ICON_SIZE = 24;
|
|
2416
|
+
var PILL_WIDTH = 56;
|
|
2417
|
+
var PILL_HEIGHT = 32;
|
|
2418
|
+
var PILL_RADIUS = 16;
|
|
2419
|
+
var TAB_MIN_HEIGHT = 56;
|
|
2420
|
+
var LABEL_SIZE = 12;
|
|
2421
|
+
var LABEL_GAP = 2;
|
|
2422
|
+
var TAB_PADDING = 4;
|
|
2423
|
+
var styles7 = StyleSheet.create({
|
|
2424
|
+
tab: {
|
|
2425
|
+
flex: 1,
|
|
2426
|
+
minHeight: TAB_MIN_HEIGHT,
|
|
2427
|
+
alignItems: "center",
|
|
2428
|
+
justifyContent: "center",
|
|
2429
|
+
paddingVertical: TAB_PADDING,
|
|
2430
|
+
rowGap: LABEL_GAP
|
|
2431
|
+
},
|
|
2432
|
+
iconWrap: { width: PILL_WIDTH, height: PILL_HEIGHT, alignItems: "center", justifyContent: "center" },
|
|
2433
|
+
pill: { ...StyleSheet.absoluteFillObject, borderRadius: PILL_RADIUS },
|
|
2434
|
+
label: { fontSize: LABEL_SIZE, textAlign: "center" }
|
|
2435
|
+
});
|
|
2436
|
+
function ariaCurrentProps3(isActive) {
|
|
2437
|
+
return isActive ? { "aria-current": "page" } : {};
|
|
2438
|
+
}
|
|
2439
|
+
var BottomTab = ({
|
|
2440
|
+
item,
|
|
2441
|
+
isActive,
|
|
2442
|
+
kind,
|
|
2443
|
+
colors,
|
|
2444
|
+
reducedMotion,
|
|
2445
|
+
navigateHint,
|
|
2446
|
+
onPress
|
|
2447
|
+
}) => {
|
|
2448
|
+
const [pressed, setPressed] = useState(false);
|
|
2449
|
+
const feedback = resolveTabFeedback(kind, { active: isActive, pressed }, reducedMotion);
|
|
2450
|
+
const scale = useSettleSpring(isActive, feedback.spring);
|
|
2451
|
+
const color = isActive ? colors.active : colors.rest;
|
|
2452
|
+
const motion = webTransition("transform", feedback.durationMs, reducedMotion);
|
|
2453
|
+
return /* @__PURE__ */ jsxs(
|
|
2454
|
+
Pressable,
|
|
2455
|
+
{
|
|
2456
|
+
accessibilityHint: navigateHint(item.label),
|
|
2457
|
+
accessibilityLabel: item.label,
|
|
2458
|
+
accessibilityRole: "link",
|
|
2459
|
+
accessibilityState: { selected: isActive },
|
|
2460
|
+
style: [styles7.tab, { opacity: feedback.opacity }],
|
|
2461
|
+
testID: item.testID ?? item.key,
|
|
2462
|
+
onPress: () => onPress(item.route),
|
|
2463
|
+
onPressIn: () => setPressed(true),
|
|
2464
|
+
onPressOut: () => setPressed(false),
|
|
2465
|
+
...ariaCurrentProps3(isActive),
|
|
2466
|
+
children: [
|
|
2467
|
+
/* @__PURE__ */ jsxs(Animated.View, { style: [styles7.iconWrap, { transform: [{ scale }] }], children: [
|
|
2468
|
+
feedback.pillScale === null ? null : /* @__PURE__ */ jsx(
|
|
2469
|
+
View,
|
|
2470
|
+
{
|
|
2471
|
+
pointerEvents: "none",
|
|
2472
|
+
style: [styles7.pill, { backgroundColor: colors.pill, transform: [{ scale: feedback.pillScale }] }, motion]
|
|
2473
|
+
}
|
|
2474
|
+
),
|
|
2475
|
+
/* @__PURE__ */ jsx(View, { style: [{ transform: feedback.iconTransform }, motion], children: item.renderIcon?.(color, ICON_SIZE) })
|
|
2476
|
+
] }),
|
|
2477
|
+
/* @__PURE__ */ jsx(Text, { style: [styles7.label, { color }], children: item.label })
|
|
2478
|
+
]
|
|
2479
|
+
}
|
|
2480
|
+
);
|
|
2481
|
+
};
|
|
2482
|
+
var DEFAULT_TEST_ID = "bottom-tab-bar";
|
|
2483
|
+
var SLIDER_HEIGHT = 3;
|
|
2484
|
+
var styles8 = StyleSheet.create({
|
|
2485
|
+
bar: { flexDirection: "row", borderTopWidth: StyleSheet.hairlineWidth },
|
|
2486
|
+
slider: { position: "absolute", top: 0, height: SLIDER_HEIGHT }
|
|
2487
|
+
});
|
|
2488
|
+
var BottomTabBar = ({
|
|
2489
|
+
items,
|
|
2490
|
+
pathname,
|
|
2491
|
+
onNavigate,
|
|
2492
|
+
tabFeedback = "default" /* Default */,
|
|
2493
|
+
navigateHint = (label) => label,
|
|
2494
|
+
regionLabel = "",
|
|
2495
|
+
containerStyle,
|
|
2496
|
+
testID = DEFAULT_TEST_ID
|
|
2497
|
+
}) => {
|
|
2498
|
+
const { theme } = useUi();
|
|
2499
|
+
const reducedMotion = useReducedMotion();
|
|
2500
|
+
const primary = theme.palette.primary["500"];
|
|
2501
|
+
const activeRoute = resolveActiveRoute(items, pathname);
|
|
2502
|
+
const activeIndex = items.findIndex((item) => item.route === activeRoute);
|
|
2503
|
+
const bar = tabFeedback === "sliding-bar" /* SlidingBar */ ? slidingBarPosition(activeIndex, items.length) : null;
|
|
2504
|
+
const barMs = resolveTabFeedback(tabFeedback, { active: true, pressed: false }, reducedMotion).durationMs;
|
|
2505
|
+
const colors = { active: primary, rest: theme.colors.textSecondary, pill: theme.colors.surfaceElevated };
|
|
2506
|
+
return /* @__PURE__ */ jsxs(
|
|
2507
|
+
View,
|
|
2508
|
+
{
|
|
2509
|
+
"aria-label": regionLabel,
|
|
2510
|
+
role: "navigation",
|
|
2511
|
+
style: [styles8.bar, { backgroundColor: theme.colors.surface, borderTopColor: theme.colors.border }, containerStyle],
|
|
2512
|
+
testID,
|
|
2513
|
+
children: [
|
|
2514
|
+
bar === null ? null : /* @__PURE__ */ jsx(
|
|
2515
|
+
View,
|
|
2516
|
+
{
|
|
2517
|
+
pointerEvents: "none",
|
|
2518
|
+
style: [styles8.slider, { left: bar.left, width: bar.width, backgroundColor: primary }, webTransition("left", barMs, reducedMotion)]
|
|
2519
|
+
}
|
|
2520
|
+
),
|
|
2521
|
+
items.map((item) => /* @__PURE__ */ jsx(
|
|
2522
|
+
BottomTab,
|
|
2523
|
+
{
|
|
2524
|
+
colors,
|
|
2525
|
+
isActive: item.route === activeRoute,
|
|
2526
|
+
item,
|
|
2527
|
+
kind: tabFeedback,
|
|
2528
|
+
navigateHint,
|
|
2529
|
+
reducedMotion,
|
|
2530
|
+
onPress: onNavigate
|
|
2531
|
+
},
|
|
2532
|
+
item.key
|
|
2533
|
+
))
|
|
2534
|
+
]
|
|
2535
|
+
}
|
|
2536
|
+
);
|
|
2537
|
+
};
|
|
2538
|
+
|
|
2539
|
+
export { ACTIVE_BORDER_RADIUS, ACTIVE_TINT_OPACITY, APP_SHELL_SUFFIX, AppShell, BASE_INDENT, BottomTabBar, CHEVRON_ICON_SIZE, CollapsedRail, CommandPalette, CommandPaletteTrigger, DEFAULT_COLLAPSED_RAIL_MAX, DEFAULT_SEARCH_BREAKPOINT, DarkModeControl, HOVER_TINT_OPACITY, NAV_ICON_SIZE, NAV_LINK_GAP, NAV_ROW_RADIUS, NAV_TEST_IDS, Nav, NavBar, NavExpandableItem, NavHoverFeedback, NavOverflowMenu, NavShell, PillNav, PillNavVariant, RAIL_FULL_BREAKPOINT, Sidebar, SidebarChevron, SidebarSearch, TabFeedback, Topbar, accessibleNavItems, collapsedRailStyles, darkModeStyles, expandableStyles, filterCommands, filterNavItems, isFilterActive, isRouteActive, navStyles, pillNavStyles, resolveActiveRoute, resolveContentMaxWidth, resolvePillMenuLabel, resolveRailMode, resolveSearchAffordance, roleRoutesToNavItems, searchTokens, useCommandPaletteHotkey, useContentMaxWidth };
|
|
2218
2540
|
//# sourceMappingURL=index.mjs.map
|
|
2219
2541
|
//# sourceMappingURL=index.mjs.map
|