@dloizides/ui-nav 1.26.2 → 1.28.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 +8 -0
- package/dist/index.d.mts +48 -2
- package/dist/index.d.ts +48 -2
- package/dist/index.js +418 -59
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +418 -62
- 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';
|
|
@@ -897,7 +897,8 @@ var APP_SHELL_SUFFIX = {
|
|
|
897
897
|
pending: "-pending",
|
|
898
898
|
loading: "-loading",
|
|
899
899
|
error: "-error",
|
|
900
|
-
forbidden: "-forbidden"
|
|
900
|
+
forbidden: "-forbidden",
|
|
901
|
+
band: "-backdrop-band"
|
|
901
902
|
};
|
|
902
903
|
var FocusableTouchable = ({
|
|
903
904
|
onPress,
|
|
@@ -1051,10 +1052,88 @@ var Topbar = ({
|
|
|
1051
1052
|
}
|
|
1052
1053
|
);
|
|
1053
1054
|
};
|
|
1055
|
+
|
|
1056
|
+
// src/NavHoverFeedback.ts
|
|
1057
|
+
var NavHoverFeedback = /* @__PURE__ */ ((NavHoverFeedback2) => {
|
|
1058
|
+
NavHoverFeedback2["Default"] = "default";
|
|
1059
|
+
NavHoverFeedback2["TintPill"] = "tint-pill";
|
|
1060
|
+
NavHoverFeedback2["Underline"] = "underline";
|
|
1061
|
+
NavHoverFeedback2["Lift"] = "lift";
|
|
1062
|
+
NavHoverFeedback2["SlidingHighlight"] = "sliding-highlight";
|
|
1063
|
+
return NavHoverFeedback2;
|
|
1064
|
+
})(NavHoverFeedback || {});
|
|
1065
|
+
|
|
1066
|
+
// src/feedback/navLinkFeedback.ts
|
|
1067
|
+
var DEFAULT_FADE_MS = 150;
|
|
1068
|
+
var PRESS_SCALE = 0.97;
|
|
1069
|
+
var PRESS_NUDGE_PX = 1;
|
|
1070
|
+
var LIFT_PX = -2;
|
|
1071
|
+
var PILL_KINDS = /* @__PURE__ */ new Set([
|
|
1072
|
+
"default" /* Default */,
|
|
1073
|
+
"tint-pill" /* TintPill */,
|
|
1074
|
+
"lift" /* Lift */
|
|
1075
|
+
]);
|
|
1076
|
+
function pillBackground(kind, isHovered, active, colors) {
|
|
1077
|
+
if (!PILL_KINDS.has(kind)) return void 0;
|
|
1078
|
+
if (active) return colors.activeBg;
|
|
1079
|
+
return isHovered ? colors.hoverBg : void 0;
|
|
1080
|
+
}
|
|
1081
|
+
function linkTextColor(kind, isHovered, active, colors) {
|
|
1082
|
+
if (active) return PILL_KINDS.has(kind) ? colors.onPrimary : colors.activeBg;
|
|
1083
|
+
return isHovered ? colors.hoverText : colors.rest;
|
|
1084
|
+
}
|
|
1085
|
+
function pressTransform(kind, pressed, isHovered) {
|
|
1086
|
+
if (kind === "tint-pill" /* TintPill */) return pressed ? [{ scale: PRESS_SCALE }] : void 0;
|
|
1087
|
+
if (kind === "underline" /* Underline */) return pressed ? [{ translateY: PRESS_NUDGE_PX }] : void 0;
|
|
1088
|
+
if (kind !== "lift" /* Lift */) return void 0;
|
|
1089
|
+
if (pressed) return [{ translateY: 0 }];
|
|
1090
|
+
return isHovered ? [{ translateY: LIFT_PX }] : void 0;
|
|
1091
|
+
}
|
|
1092
|
+
function feedbackDuration(kind) {
|
|
1093
|
+
if (kind === "default" /* Default */) return DEFAULT_FADE_MS;
|
|
1094
|
+
return kind === "tint-pill" /* TintPill */ ? motionDurations.fast : motionDurations.base;
|
|
1095
|
+
}
|
|
1096
|
+
function resolveLinkFeedback(kind, state, colors, reducedMotion) {
|
|
1097
|
+
const isHovered = state.hovered && !state.active;
|
|
1098
|
+
const underlined = state.active || isHovered;
|
|
1099
|
+
return {
|
|
1100
|
+
background: pillBackground(kind, isHovered, state.active, colors),
|
|
1101
|
+
textColor: linkTextColor(kind, isHovered, state.active, colors),
|
|
1102
|
+
transform: reducedMotion ? void 0 : pressTransform(kind, state.pressed, isHovered),
|
|
1103
|
+
shadow: kind === "lift" /* Lift */ && isHovered,
|
|
1104
|
+
underline: kind === "underline" /* Underline */ ? { color: colors.activeBg, scale: underlined ? 1 : 0 } : null,
|
|
1105
|
+
durationMs: reducedMotion ? motionDurations.instant : feedbackDuration(kind)
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1054
1108
|
var TEXT_ON_PRIMARY2 = "#ffffff";
|
|
1055
1109
|
function ariaCurrentProps2(isActive) {
|
|
1056
1110
|
return isActive ? { "aria-current": "page" } : {};
|
|
1057
1111
|
}
|
|
1112
|
+
var FEEDBACK_PROPERTIES = "color, background-color, transform, box-shadow";
|
|
1113
|
+
var UNDERLINE_INSET = 14;
|
|
1114
|
+
var UNDERLINE_HEIGHT = 2;
|
|
1115
|
+
var SHADOW_OPACITY = 0.18;
|
|
1116
|
+
var SHADOW_RADIUS = 6;
|
|
1117
|
+
var SHADOW_OFFSET = { width: 0, height: 2 };
|
|
1118
|
+
function feedbackStyle(kind, feedback, shadowColor, reducedMotion) {
|
|
1119
|
+
const background = feedback.background === void 0 ? {} : { backgroundColor: feedback.background };
|
|
1120
|
+
const shadow = feedback.shadow ? { shadowColor, shadowOpacity: SHADOW_OPACITY, shadowRadius: SHADOW_RADIUS, shadowOffset: SHADOW_OFFSET } : {};
|
|
1121
|
+
const transition = kind === "default" /* Default */ ? hoverTransitionStyle(reducedMotion) : webTransition(FEEDBACK_PROPERTIES, feedback.durationMs, reducedMotion);
|
|
1122
|
+
return [background, shadow, { transform: feedback.transform }, transition ?? {}];
|
|
1123
|
+
}
|
|
1124
|
+
function underlineStyle(feedback, reducedMotion) {
|
|
1125
|
+
if (feedback.underline === null) return null;
|
|
1126
|
+
const line = {
|
|
1127
|
+
position: "absolute",
|
|
1128
|
+
left: UNDERLINE_INSET,
|
|
1129
|
+
right: UNDERLINE_INSET,
|
|
1130
|
+
bottom: 0,
|
|
1131
|
+
height: UNDERLINE_HEIGHT,
|
|
1132
|
+
backgroundColor: feedback.underline.color,
|
|
1133
|
+
transform: [{ scaleX: feedback.underline.scale }]
|
|
1134
|
+
};
|
|
1135
|
+
return [line, webTransition("transform", feedback.durationMs, reducedMotion) ?? {}];
|
|
1136
|
+
}
|
|
1058
1137
|
var NavBarLink = ({
|
|
1059
1138
|
item,
|
|
1060
1139
|
isActive,
|
|
@@ -1063,13 +1142,20 @@ var NavBarLink = ({
|
|
|
1063
1142
|
reducedMotion,
|
|
1064
1143
|
colors,
|
|
1065
1144
|
navigateHint,
|
|
1066
|
-
onPress
|
|
1145
|
+
onPress,
|
|
1146
|
+
hoverFeedback = "default" /* Default */,
|
|
1147
|
+
onHoverChange
|
|
1067
1148
|
}) => {
|
|
1068
1149
|
const [hovered, setHovered] = useState(false);
|
|
1069
1150
|
const [focused, setFocused] = useState(false);
|
|
1070
|
-
const
|
|
1071
|
-
const
|
|
1072
|
-
const
|
|
1151
|
+
const linkColors = { ...colors, onPrimary: TEXT_ON_PRIMARY2 };
|
|
1152
|
+
const resolve = (pressed) => resolveLinkFeedback(hoverFeedback, { hovered, pressed, active: isActive }, linkColors, reducedMotion);
|
|
1153
|
+
const textColor = resolve(false).textColor;
|
|
1154
|
+
const underline = underlineStyle(resolve(false), reducedMotion);
|
|
1155
|
+
const setHover = (next) => {
|
|
1156
|
+
setHovered(next);
|
|
1157
|
+
onHoverChange?.(item.key, next);
|
|
1158
|
+
};
|
|
1073
1159
|
return /* @__PURE__ */ jsxs(
|
|
1074
1160
|
Pressable,
|
|
1075
1161
|
{
|
|
@@ -1077,27 +1163,61 @@ var NavBarLink = ({
|
|
|
1077
1163
|
accessibilityLabel: item.label,
|
|
1078
1164
|
accessibilityRole: "link",
|
|
1079
1165
|
accessibilityState: { selected: isActive },
|
|
1080
|
-
style: [
|
|
1166
|
+
style: ({ pressed }) => [
|
|
1081
1167
|
navBarStyles.link,
|
|
1082
1168
|
collapsed ? navBarStyles.linkStacked : void 0,
|
|
1083
|
-
|
|
1084
|
-
hoverTransitionStyle(reducedMotion),
|
|
1169
|
+
...feedbackStyle(hoverFeedback, resolve(pressed), colors.rest, reducedMotion),
|
|
1085
1170
|
focusRingStyle(focused, colors.ring)
|
|
1086
1171
|
],
|
|
1087
1172
|
testID: item.testID ?? item.key,
|
|
1088
1173
|
onBlur: () => setFocused(false),
|
|
1089
1174
|
onFocus: () => setFocused(true),
|
|
1090
|
-
onHoverIn: () =>
|
|
1091
|
-
onHoverOut: () =>
|
|
1175
|
+
onHoverIn: () => setHover(true),
|
|
1176
|
+
onHoverOut: () => setHover(false),
|
|
1092
1177
|
onPress: () => onPress(item.route),
|
|
1093
1178
|
...ariaCurrentProps2(isActive),
|
|
1094
1179
|
children: [
|
|
1095
1180
|
typeof item.renderIcon === "function" ? /* @__PURE__ */ jsx(View, { style: navBarStyles.linkIcon, children: item.renderIcon(textColor, iconSize) }) : null,
|
|
1181
|
+
underline === null ? null : /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: underline }),
|
|
1096
1182
|
/* @__PURE__ */ jsx(Text, { style: [navBarStyles.linkText, { color: textColor }], children: item.label })
|
|
1097
1183
|
]
|
|
1098
1184
|
}
|
|
1099
1185
|
);
|
|
1100
1186
|
};
|
|
1187
|
+
var HIGHLIGHT_RADIUS = 8;
|
|
1188
|
+
var SLIDE_PROPERTIES = "left, top, width, height";
|
|
1189
|
+
function slideHighlightRect(layouts, activeKey, hoveredKey) {
|
|
1190
|
+
const hoveredRect = hoveredKey === null ? void 0 : layouts[hoveredKey];
|
|
1191
|
+
const activeRect = activeKey === void 0 ? void 0 : layouts[activeKey];
|
|
1192
|
+
return hoveredRect ?? activeRect ?? null;
|
|
1193
|
+
}
|
|
1194
|
+
function useSlidingHighlight(enabled, activeKey, color, reducedMotion) {
|
|
1195
|
+
const [layouts, setLayouts] = useState({});
|
|
1196
|
+
const [hoveredKey, setHoveredKey] = useState(null);
|
|
1197
|
+
const measure = useCallback(
|
|
1198
|
+
(key, layout) => {
|
|
1199
|
+
if (enabled) setLayouts((prev) => ({ ...prev, [key]: layout }));
|
|
1200
|
+
},
|
|
1201
|
+
[enabled]
|
|
1202
|
+
);
|
|
1203
|
+
const hover = useCallback((key, hovered) => {
|
|
1204
|
+
setHoveredKey((prev) => hovered ? key : prev === key ? null : prev);
|
|
1205
|
+
}, []);
|
|
1206
|
+
const rect = enabled ? slideHighlightRect(layouts, activeKey, hoveredKey) : null;
|
|
1207
|
+
const style = rect === null ? null : [
|
|
1208
|
+
{
|
|
1209
|
+
position: "absolute",
|
|
1210
|
+
left: rect.x,
|
|
1211
|
+
top: rect.y,
|
|
1212
|
+
width: rect.width,
|
|
1213
|
+
height: rect.height,
|
|
1214
|
+
borderRadius: HIGHLIGHT_RADIUS,
|
|
1215
|
+
backgroundColor: color
|
|
1216
|
+
},
|
|
1217
|
+
webTransition(SLIDE_PROPERTIES, motionDurations.base, reducedMotion)
|
|
1218
|
+
];
|
|
1219
|
+
return { style, measure, hover };
|
|
1220
|
+
}
|
|
1101
1221
|
var TEXT_ON_PRIMARY3 = "#ffffff";
|
|
1102
1222
|
var NO_ACTIVE_ROUTE = "";
|
|
1103
1223
|
var OVERFLOW_MENU_MIN_WIDTH = 200;
|
|
@@ -1238,7 +1358,8 @@ var NavBarInner = ({
|
|
|
1238
1358
|
overflowLabel = "More",
|
|
1239
1359
|
overflowHint = "",
|
|
1240
1360
|
containerStyle,
|
|
1241
|
-
contentMaxWidth
|
|
1361
|
+
contentMaxWidth,
|
|
1362
|
+
hoverFeedback = "default" /* Default */
|
|
1242
1363
|
}) => {
|
|
1243
1364
|
const { theme } = useUi();
|
|
1244
1365
|
const colors = theme.colors;
|
|
@@ -1272,6 +1393,12 @@ var NavBarInner = ({
|
|
|
1272
1393
|
[onNavigate]
|
|
1273
1394
|
);
|
|
1274
1395
|
const activeRoute = resolveActiveRoute(items, pathname);
|
|
1396
|
+
const slide = useSlidingHighlight(
|
|
1397
|
+
hoverFeedback === "sliding-highlight" /* SlidingHighlight */,
|
|
1398
|
+
items.find((item) => item.route === activeRoute)?.key,
|
|
1399
|
+
colors.surfaceElevated,
|
|
1400
|
+
reducedMotion
|
|
1401
|
+
);
|
|
1275
1402
|
const linkColors = useMemo(
|
|
1276
1403
|
() => ({
|
|
1277
1404
|
rest: colors.textSecondary,
|
|
@@ -1321,9 +1448,11 @@ var NavBarInner = ({
|
|
|
1321
1448
|
colors: linkColors,
|
|
1322
1449
|
iconSize: NAV_ICON_SIZE,
|
|
1323
1450
|
isActive: item.route === activeRoute,
|
|
1451
|
+
hoverFeedback,
|
|
1324
1452
|
item,
|
|
1325
1453
|
navigateHint,
|
|
1326
1454
|
reducedMotion,
|
|
1455
|
+
onHoverChange: slide.hover,
|
|
1327
1456
|
onPress: handlePress
|
|
1328
1457
|
}
|
|
1329
1458
|
);
|
|
@@ -1349,11 +1478,15 @@ var NavBarInner = ({
|
|
|
1349
1478
|
testID: NAV_TEST_IDS.navBarLinks,
|
|
1350
1479
|
onLayout: (event) => setAvailableWidth(event.nativeEvent.layout.width),
|
|
1351
1480
|
children: [
|
|
1481
|
+
slide.style === null ? null : /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: slide.style }),
|
|
1352
1482
|
visibleItems.map((item, index) => /* @__PURE__ */ jsx(
|
|
1353
1483
|
View,
|
|
1354
1484
|
{
|
|
1355
1485
|
style: navBarStyles.linkCell,
|
|
1356
|
-
onLayout: (event) =>
|
|
1486
|
+
onLayout: (event) => {
|
|
1487
|
+
setItemWidth(index, event.nativeEvent.layout.width);
|
|
1488
|
+
slide.measure(item.key, event.nativeEvent.layout);
|
|
1489
|
+
},
|
|
1357
1490
|
children: renderLink(item)
|
|
1358
1491
|
},
|
|
1359
1492
|
item.key
|
|
@@ -1404,13 +1537,53 @@ var Nav = (props) => {
|
|
|
1404
1537
|
}
|
|
1405
1538
|
return /* @__PURE__ */ jsx(NavBar, { ...props });
|
|
1406
1539
|
};
|
|
1540
|
+
var RAIL_FULL_BREAKPOINT = LAYOUT_COLLAPSE_BREAKPOINT;
|
|
1541
|
+
var DEFAULT_COLLAPSED_RAIL_MAX = 1024;
|
|
1542
|
+
function resolveRailMode({ viewport, hasSidebar, hasCollapsed, range }) {
|
|
1543
|
+
if (!hasSidebar) return "none";
|
|
1544
|
+
if (hasCollapsed) {
|
|
1545
|
+
if (viewport >= range.max) return "full";
|
|
1546
|
+
if (viewport >= range.min) return "collapsed";
|
|
1547
|
+
return "drawer";
|
|
1548
|
+
}
|
|
1549
|
+
return viewport >= RAIL_FULL_BREAKPOINT ? "full" : "drawer";
|
|
1550
|
+
}
|
|
1551
|
+
var styles3 = StyleSheet.create({
|
|
1552
|
+
band: { left: 0, position: "absolute", right: 0, top: 0 }
|
|
1553
|
+
});
|
|
1554
|
+
function readBackdrop(theme) {
|
|
1555
|
+
return theme.backdrop;
|
|
1556
|
+
}
|
|
1557
|
+
function rootStyle(backdrop, fallback) {
|
|
1558
|
+
if (backdrop === void 0) return { backgroundColor: fallback };
|
|
1559
|
+
const base = { backgroundColor: backdrop.color };
|
|
1560
|
+
if (!IS_WEB || backdrop.image === null) return base;
|
|
1561
|
+
const web = { backgroundImage: backdrop.image, backgroundSize: backdrop.imageSize ?? "auto" };
|
|
1562
|
+
return { ...base, ...web };
|
|
1563
|
+
}
|
|
1564
|
+
function resolveShellBackdrop(theme, viewport, contentPadding, testID) {
|
|
1565
|
+
const backdrop = readBackdrop(theme);
|
|
1566
|
+
const band = backdrop?.band ?? null;
|
|
1567
|
+
const root = rootStyle(backdrop, theme.colors.background);
|
|
1568
|
+
if (band === null) return { root, chrome: void 0, chromeText: theme.colors.text, band: null };
|
|
1569
|
+
const overlap = viewport < RAIL_FULL_BREAKPOINT ? band.overlap.compact : band.overlap.wide;
|
|
1570
|
+
const element = /* @__PURE__ */ jsx(
|
|
1571
|
+
View,
|
|
1572
|
+
{
|
|
1573
|
+
pointerEvents: "none",
|
|
1574
|
+
style: [styles3.band, { backgroundColor: band.color, height: contentPadding + overlap }],
|
|
1575
|
+
testID: `${testID}${APP_SHELL_SUFFIX.band}`
|
|
1576
|
+
}
|
|
1577
|
+
);
|
|
1578
|
+
return { root, chrome: { backgroundColor: band.color }, chromeText: band.text, band: element };
|
|
1579
|
+
}
|
|
1407
1580
|
var CARD_PADDING = 20;
|
|
1408
1581
|
var CARD_BORDER_RADIUS = 12;
|
|
1409
1582
|
var CARD_BORDER_WIDTH = 1;
|
|
1410
1583
|
var CARD_TITLE_FONT_SIZE = 16;
|
|
1411
1584
|
var CARD_MESSAGE_FONT_SIZE = 14;
|
|
1412
1585
|
var CARD_TITLE_MARGIN_BOTTOM = 8;
|
|
1413
|
-
var
|
|
1586
|
+
var styles4 = StyleSheet.create({
|
|
1414
1587
|
// Loading is a TRANSITIONAL state: the spinner is an absolute overlay ON TOP of
|
|
1415
1588
|
// stably-mounted children, never a replacement for them. Replacing children here
|
|
1416
1589
|
// would unmount whatever they host (e.g. a navigator), and on remount React
|
|
@@ -1442,9 +1615,9 @@ function MessageCard({
|
|
|
1442
1615
|
}) {
|
|
1443
1616
|
const { theme } = useUi();
|
|
1444
1617
|
const colors = theme.colors;
|
|
1445
|
-
return /* @__PURE__ */ jsxs(View, { style: [
|
|
1446
|
-
/* @__PURE__ */ jsx(Text, { style: [
|
|
1447
|
-
/* @__PURE__ */ jsx(Text, { style: [
|
|
1618
|
+
return /* @__PURE__ */ jsxs(View, { style: [styles4.card, { backgroundColor: colors.surface, borderColor: accentColor }], testID, children: [
|
|
1619
|
+
/* @__PURE__ */ jsx(Text, { style: [styles4.cardTitle, { color: accentColor }], children: message.titleText }),
|
|
1620
|
+
/* @__PURE__ */ jsx(Text, { style: [styles4.cardMessage, { color: colors.textSecondary }], children: message.messageText })
|
|
1448
1621
|
] });
|
|
1449
1622
|
}
|
|
1450
1623
|
function useContentBody(state, children, testID) {
|
|
@@ -1456,12 +1629,12 @@ function useContentBody(state, children, testID) {
|
|
|
1456
1629
|
return /* @__PURE__ */ jsx(MessageCard, { accentColor: errorColor, message: state.forbidden, testID: `${testID}${APP_SHELL_SUFFIX.forbidden}` });
|
|
1457
1630
|
if (state.error)
|
|
1458
1631
|
return /* @__PURE__ */ jsx(MessageCard, { accentColor: errorColor, message: state.error, testID: `${testID}${APP_SHELL_SUFFIX.error}` });
|
|
1459
|
-
return /* @__PURE__ */ jsxs(View, { style:
|
|
1632
|
+
return /* @__PURE__ */ jsxs(View, { style: styles4.loadingHost, children: [
|
|
1460
1633
|
children,
|
|
1461
1634
|
state.loading === true ? /* @__PURE__ */ jsx(
|
|
1462
1635
|
View,
|
|
1463
1636
|
{
|
|
1464
|
-
style: [
|
|
1637
|
+
style: [styles4.loadingOverlay, { backgroundColor: theme.colors.background }],
|
|
1465
1638
|
testID: `${testID}${APP_SHELL_SUFFIX.loading}`,
|
|
1466
1639
|
children: /* @__PURE__ */ jsx(ActivityIndicator, { color: primary, size: "large" })
|
|
1467
1640
|
}
|
|
@@ -1488,7 +1661,7 @@ var DEFAULT_DRAWER_LABELS = {
|
|
|
1488
1661
|
closeLabel: "Close menu",
|
|
1489
1662
|
closeHint: "Close the navigation menu"
|
|
1490
1663
|
};
|
|
1491
|
-
var
|
|
1664
|
+
var styles5 = StyleSheet.create({
|
|
1492
1665
|
overlay: { ...StyleSheet.absoluteFillObject, zIndex: DRAWER_Z_INDEX },
|
|
1493
1666
|
// The scrim's tap-to-close hit area is anchored to the RIGHT of the panel
|
|
1494
1667
|
// (`left: DRAWER_WIDTH`), so it NEVER overlaps the panel: nav-item taps always
|
|
@@ -1523,10 +1696,10 @@ var MenuToggle = ({ label, hint, onOpen, testID }) => {
|
|
|
1523
1696
|
accessibilityHint: hint,
|
|
1524
1697
|
accessibilityLabel: label,
|
|
1525
1698
|
ringColor: theme.palette.primary["500"],
|
|
1526
|
-
style:
|
|
1699
|
+
style: styles5.menuToggle,
|
|
1527
1700
|
testID,
|
|
1528
1701
|
onPress: onOpen,
|
|
1529
|
-
children: /* @__PURE__ */ jsx(Text, { style: [
|
|
1702
|
+
children: /* @__PURE__ */ jsx(Text, { style: [styles5.menuToggleGlyph, { color: theme.colors.text }], children: MENU_GLYPH2 })
|
|
1530
1703
|
}
|
|
1531
1704
|
);
|
|
1532
1705
|
};
|
|
@@ -1552,14 +1725,14 @@ var MobileDrawer = ({
|
|
|
1552
1725
|
node.addEventListener("click", handleClick);
|
|
1553
1726
|
return () => node.removeEventListener("click", handleClick);
|
|
1554
1727
|
}, [onClose]);
|
|
1555
|
-
return /* @__PURE__ */ jsxs(View, { style:
|
|
1728
|
+
return /* @__PURE__ */ jsxs(View, { style: styles5.overlay, children: [
|
|
1556
1729
|
/* @__PURE__ */ jsx(
|
|
1557
1730
|
Pressable,
|
|
1558
1731
|
{
|
|
1559
1732
|
accessibilityHint: labels.closeHint,
|
|
1560
1733
|
accessibilityLabel: labels.closeLabel,
|
|
1561
1734
|
accessibilityRole: "button",
|
|
1562
|
-
style:
|
|
1735
|
+
style: styles5.scrim,
|
|
1563
1736
|
testID: scrimTestID,
|
|
1564
1737
|
onPress: onClose
|
|
1565
1738
|
}
|
|
@@ -1570,24 +1743,13 @@ var MobileDrawer = ({
|
|
|
1570
1743
|
ref: panelRef,
|
|
1571
1744
|
"aria-modal": true,
|
|
1572
1745
|
role: "dialog",
|
|
1573
|
-
style: [
|
|
1746
|
+
style: [styles5.panel, { backgroundColor: theme.colors.surface }],
|
|
1574
1747
|
testID: drawerTestID,
|
|
1575
1748
|
children: renderTextSlot(sidebar, { color: theme.colors.text })
|
|
1576
1749
|
}
|
|
1577
1750
|
)
|
|
1578
1751
|
] });
|
|
1579
1752
|
};
|
|
1580
|
-
var RAIL_FULL_BREAKPOINT = LAYOUT_COLLAPSE_BREAKPOINT;
|
|
1581
|
-
var DEFAULT_COLLAPSED_RAIL_MAX = 1024;
|
|
1582
|
-
function resolveRailMode({ viewport, hasSidebar, hasCollapsed, range }) {
|
|
1583
|
-
if (!hasSidebar) return "none";
|
|
1584
|
-
if (hasCollapsed) {
|
|
1585
|
-
if (viewport >= range.max) return "full";
|
|
1586
|
-
if (viewport >= range.min) return "collapsed";
|
|
1587
|
-
return "drawer";
|
|
1588
|
-
}
|
|
1589
|
-
return viewport >= RAIL_FULL_BREAKPOINT ? "full" : "drawer";
|
|
1590
|
-
}
|
|
1591
1753
|
function resolveContentMaxWidth(width, viewport) {
|
|
1592
1754
|
if (width === "full") return "full";
|
|
1593
1755
|
const wideMinViewport = width.wideMinViewport ?? Number.POSITIVE_INFINITY;
|
|
@@ -1599,7 +1761,7 @@ function useContentMaxWidth(width) {
|
|
|
1599
1761
|
return resolveContentMaxWidth(width, viewport);
|
|
1600
1762
|
}
|
|
1601
1763
|
var DEFAULT_CONTENT_PADDING = 24;
|
|
1602
|
-
var
|
|
1764
|
+
var styles6 = StyleSheet.create({
|
|
1603
1765
|
root: { flex: 1 },
|
|
1604
1766
|
// Auth-pending spinner: an opaque absolute overlay over the mounted shell, so
|
|
1605
1767
|
// `children` (and any navigator they host) are never unmounted while the gate
|
|
@@ -1639,6 +1801,7 @@ var AppShell = ({
|
|
|
1639
1801
|
const maxWidth = useContentMaxWidth(width);
|
|
1640
1802
|
const body = useContentBody(state, children, testID);
|
|
1641
1803
|
const { width: viewportWidth } = useWindowDimensions();
|
|
1804
|
+
const look = resolveShellBackdrop(theme, viewportWidth, contentPadding, testID);
|
|
1642
1805
|
const railRange = collapsedRailRange ?? { min: RAIL_FULL_BREAKPOINT, max: DEFAULT_COLLAPSED_RAIL_MAX };
|
|
1643
1806
|
const railMode = resolveRailMode({
|
|
1644
1807
|
viewport: viewportWidth,
|
|
@@ -1660,18 +1823,21 @@ var AppShell = ({
|
|
|
1660
1823
|
}, [isUnauthenticated, gate]);
|
|
1661
1824
|
const gatePending = gate?.pending === true;
|
|
1662
1825
|
if (isUnauthenticated) return null;
|
|
1663
|
-
const columnStyle = maxWidth === "full" ?
|
|
1664
|
-
const navInnerStyle = chromeAlignment === "content" && maxWidth !== "full" ? [
|
|
1665
|
-
const scroller = /* @__PURE__ */
|
|
1826
|
+
const columnStyle = maxWidth === "full" ? styles6.columnFull : [styles6.columnCapped, { maxWidth }];
|
|
1827
|
+
const navInnerStyle = chromeAlignment === "content" && maxWidth !== "full" ? [styles6.chromeCapped, { maxWidth, paddingHorizontal: contentPadding }] : void 0;
|
|
1828
|
+
const scroller = /* @__PURE__ */ jsxs(
|
|
1666
1829
|
ScrollView,
|
|
1667
1830
|
{
|
|
1668
|
-
contentContainerStyle: [
|
|
1669
|
-
style:
|
|
1831
|
+
contentContainerStyle: [styles6.scrollContent, { padding: contentPadding }],
|
|
1832
|
+
style: styles6.scroll,
|
|
1670
1833
|
testID: `${testID}${APP_SHELL_SUFFIX.content}`,
|
|
1671
|
-
children:
|
|
1834
|
+
children: [
|
|
1835
|
+
look.band,
|
|
1836
|
+
/* @__PURE__ */ jsx(View, { style: columnStyle, children: body })
|
|
1837
|
+
]
|
|
1672
1838
|
}
|
|
1673
1839
|
);
|
|
1674
|
-
const headerRegion = useDrawer ? /* @__PURE__ */ jsxs(View, { style:
|
|
1840
|
+
const headerRegion = useDrawer ? /* @__PURE__ */ jsxs(View, { style: [styles6.headerRow, look.chrome], testID: `${testID}${APP_SHELL_SUFFIX.header}`, children: [
|
|
1675
1841
|
/* @__PURE__ */ jsx(
|
|
1676
1842
|
MenuToggle,
|
|
1677
1843
|
{
|
|
@@ -1681,14 +1847,14 @@ var AppShell = ({
|
|
|
1681
1847
|
onOpen: openDrawer
|
|
1682
1848
|
}
|
|
1683
1849
|
),
|
|
1684
|
-
/* @__PURE__ */ jsx(View, { style:
|
|
1685
|
-
] }) : /* @__PURE__ */ jsx(View, { testID: `${testID}${APP_SHELL_SUFFIX.header}`, children: renderTextSlot(header, { color:
|
|
1850
|
+
/* @__PURE__ */ jsx(View, { style: styles6.headerFill, children: renderTextSlot(header, { color: look.chromeText }) })
|
|
1851
|
+
] }) : /* @__PURE__ */ jsx(View, { style: look.chrome, testID: `${testID}${APP_SHELL_SUFFIX.header}`, children: renderTextSlot(header, { color: look.chromeText }) });
|
|
1686
1852
|
const railRegion = railMode === "full" ? /* @__PURE__ */ jsx(View, { testID: `${testID}${APP_SHELL_SUFFIX.sidebar}`, children: renderTextSlot(sidebar, { color: theme.colors.text }) }) : railMode === "collapsed" ? /* @__PURE__ */ jsx(View, { testID: `${testID}${APP_SHELL_SUFFIX.collapsedSidebar}`, children: renderTextSlot(collapsedSidebar, { color: theme.colors.text }) }) : null;
|
|
1687
|
-
return /* @__PURE__ */ jsxs(View, { style: [
|
|
1853
|
+
return /* @__PURE__ */ jsxs(View, { style: [styles6.root, look.root], testID, children: [
|
|
1688
1854
|
headerRegion,
|
|
1689
|
-
nav !== void 0 ? /* @__PURE__ */ jsx(View, { testID: `${testID}${APP_SHELL_SUFFIX.nav}`, children: navInnerStyle !== void 0 ? /* @__PURE__ */ jsx(View, { style: navInnerStyle, children: renderTextSlot(nav, { color:
|
|
1855
|
+
nav !== void 0 ? /* @__PURE__ */ jsx(View, { style: look.chrome, testID: `${testID}${APP_SHELL_SUFFIX.nav}`, children: navInnerStyle !== void 0 ? /* @__PURE__ */ jsx(View, { style: navInnerStyle, children: renderTextSlot(nav, { color: look.chromeText }) }) : renderTextSlot(nav, { color: look.chromeText }) }) : null,
|
|
1690
1856
|
banner !== void 0 ? /* @__PURE__ */ jsx(View, { testID: `${testID}${APP_SHELL_SUFFIX.banner}`, children: renderTextSlot(banner, { color: theme.colors.text }) }) : null,
|
|
1691
|
-
railRegion !== null ? /* @__PURE__ */ jsxs(View, { style:
|
|
1857
|
+
railRegion !== null ? /* @__PURE__ */ jsxs(View, { style: styles6.bodyRow, children: [
|
|
1692
1858
|
railRegion,
|
|
1693
1859
|
scroller
|
|
1694
1860
|
] }) : scroller,
|
|
@@ -1705,7 +1871,7 @@ var AppShell = ({
|
|
|
1705
1871
|
gatePending ? /* @__PURE__ */ jsx(
|
|
1706
1872
|
View,
|
|
1707
1873
|
{
|
|
1708
|
-
style: [
|
|
1874
|
+
style: [styles6.pendingOverlay, { backgroundColor: theme.colors.background }],
|
|
1709
1875
|
testID: `${testID}${APP_SHELL_SUFFIX.pending}`,
|
|
1710
1876
|
children: /* @__PURE__ */ jsx(ActivityIndicator, { color: primary, size: "large" })
|
|
1711
1877
|
}
|
|
@@ -2072,7 +2238,7 @@ var KEY_DOWN = "ArrowDown";
|
|
|
2072
2238
|
var KEY_UP = "ArrowUp";
|
|
2073
2239
|
var KEY_ENTER = "Enter";
|
|
2074
2240
|
var KEY_ESCAPE = "Escape";
|
|
2075
|
-
var
|
|
2241
|
+
var styles7 = StyleSheet.create({
|
|
2076
2242
|
overlay: { ...StyleSheet.absoluteFillObject, zIndex: OVERLAY_Z_INDEX, alignItems: "center" },
|
|
2077
2243
|
scrim: { ...StyleSheet.absoluteFillObject, backgroundColor: SCRIM_COLOR2 },
|
|
2078
2244
|
panel: {
|
|
@@ -2101,14 +2267,14 @@ var PaletteRow = ({ item, selected, onChoose }) => {
|
|
|
2101
2267
|
accessibilityLabel: item.label,
|
|
2102
2268
|
accessibilityRole: "button",
|
|
2103
2269
|
accessibilityState: { selected },
|
|
2104
|
-
style: [
|
|
2270
|
+
style: [styles7.row, selected ? { backgroundColor: colors.border } : void 0],
|
|
2105
2271
|
testID: item.testID ?? item.key,
|
|
2106
2272
|
onPress: () => onChoose(item),
|
|
2107
2273
|
children: [
|
|
2108
2274
|
typeof item.renderIcon === "function" ? item.renderIcon(colors.textSecondary, NAV_ICON_SIZE) : null,
|
|
2109
|
-
/* @__PURE__ */ jsxs(View, { style:
|
|
2110
|
-
/* @__PURE__ */ jsx(Text, { style: [
|
|
2111
|
-
item.hint ? /* @__PURE__ */ jsx(Text, { style: [
|
|
2275
|
+
/* @__PURE__ */ jsxs(View, { style: styles7.rowText, children: [
|
|
2276
|
+
/* @__PURE__ */ jsx(Text, { style: [styles7.rowLabel, { color: colors.text }], children: item.label }),
|
|
2277
|
+
item.hint ? /* @__PURE__ */ jsx(Text, { style: [styles7.rowHint, { color: colors.textSecondary }], children: item.hint }) : null
|
|
2112
2278
|
] })
|
|
2113
2279
|
]
|
|
2114
2280
|
}
|
|
@@ -2148,14 +2314,14 @@ var CommandPalette = ({ open, items, onClose, labels, testID }) => {
|
|
|
2148
2314
|
[results, selected, choose, onClose]
|
|
2149
2315
|
);
|
|
2150
2316
|
if (!open) return null;
|
|
2151
|
-
return /* @__PURE__ */ jsxs(View, { style:
|
|
2317
|
+
return /* @__PURE__ */ jsxs(View, { style: styles7.overlay, children: [
|
|
2152
2318
|
/* @__PURE__ */ jsx(
|
|
2153
2319
|
Pressable,
|
|
2154
2320
|
{
|
|
2155
2321
|
accessibilityHint: labels.closeHint,
|
|
2156
2322
|
accessibilityLabel: labels.closeLabel,
|
|
2157
2323
|
accessibilityRole: "button",
|
|
2158
|
-
style:
|
|
2324
|
+
style: styles7.scrim,
|
|
2159
2325
|
testID: `${testID ?? "command-palette"}-scrim`,
|
|
2160
2326
|
onPress: onClose
|
|
2161
2327
|
}
|
|
@@ -2166,7 +2332,7 @@ var CommandPalette = ({ open, items, onClose, labels, testID }) => {
|
|
|
2166
2332
|
"aria-modal": true,
|
|
2167
2333
|
"aria-label": labels.regionLabel,
|
|
2168
2334
|
role: "dialog",
|
|
2169
|
-
style: [
|
|
2335
|
+
style: [styles7.panel, { backgroundColor: colors.surface, borderColor: colors.border }],
|
|
2170
2336
|
testID: testID ?? "command-palette",
|
|
2171
2337
|
children: [
|
|
2172
2338
|
/* @__PURE__ */ jsx(
|
|
@@ -2176,14 +2342,14 @@ var CommandPalette = ({ open, items, onClose, labels, testID }) => {
|
|
|
2176
2342
|
accessibilityLabel: labels.placeholder,
|
|
2177
2343
|
placeholder: labels.placeholder,
|
|
2178
2344
|
placeholderTextColor: colors.textSecondary,
|
|
2179
|
-
style: [
|
|
2345
|
+
style: [styles7.input, { color: colors.text, borderBottomColor: colors.border }],
|
|
2180
2346
|
testID: `${testID ?? "command-palette"}-input`,
|
|
2181
2347
|
value: query,
|
|
2182
2348
|
onChangeText: setQuery,
|
|
2183
2349
|
onKeyPress
|
|
2184
2350
|
}
|
|
2185
2351
|
),
|
|
2186
|
-
results.length === 0 ? /* @__PURE__ */ jsx(Text, { style: [
|
|
2352
|
+
results.length === 0 ? /* @__PURE__ */ jsx(Text, { style: [styles7.empty, { color: colors.textSecondary }], children: labels.emptyText }) : /* @__PURE__ */ jsx(ScrollView, { keyboardShouldPersistTaps: "handled", style: styles7.list, children: results.map((item, index) => /* @__PURE__ */ jsx(PaletteRow, { item, selected: index === selected, onChoose: choose }, item.key)) })
|
|
2187
2353
|
]
|
|
2188
2354
|
}
|
|
2189
2355
|
)
|
|
@@ -2214,6 +2380,196 @@ function accessibleNavItems(user, table, translate) {
|
|
|
2214
2380
|
return roleRoutesToNavItems(resolveAccessibleRoutes(user, table), translate);
|
|
2215
2381
|
}
|
|
2216
2382
|
|
|
2217
|
-
|
|
2383
|
+
// src/TabFeedback.ts
|
|
2384
|
+
var TabFeedback = /* @__PURE__ */ ((TabFeedback2) => {
|
|
2385
|
+
TabFeedback2["Default"] = "default";
|
|
2386
|
+
TabFeedback2["IndicatorPill"] = "indicator-pill";
|
|
2387
|
+
TabFeedback2["DimSpring"] = "dim-spring";
|
|
2388
|
+
TabFeedback2["SlidingBar"] = "sliding-bar";
|
|
2389
|
+
TabFeedback2["IconLift"] = "icon-lift";
|
|
2390
|
+
return TabFeedback2;
|
|
2391
|
+
})(TabFeedback || {});
|
|
2392
|
+
|
|
2393
|
+
// src/feedback/tabPressFeedback.ts
|
|
2394
|
+
var FULL = 1;
|
|
2395
|
+
var PERCENT = 100;
|
|
2396
|
+
var PRESS_ICON_SCALE = 0.92;
|
|
2397
|
+
var DIM_OPACITY = 0.6;
|
|
2398
|
+
var ICON_LIFT_PX = -3;
|
|
2399
|
+
var SPRING_OVERSHOOT = 1.06;
|
|
2400
|
+
function tabIconTransform(kind, state) {
|
|
2401
|
+
if (kind === "indicator-pill" /* IndicatorPill */ && state.pressed) return [{ scale: PRESS_ICON_SCALE }];
|
|
2402
|
+
const lifted = state.active || state.pressed;
|
|
2403
|
+
return kind === "icon-lift" /* IconLift */ && lifted ? [{ translateY: ICON_LIFT_PX }] : void 0;
|
|
2404
|
+
}
|
|
2405
|
+
function tabDuration(kind) {
|
|
2406
|
+
if (kind === "default" /* Default */) return motionDurations.instant;
|
|
2407
|
+
const slow = kind === "dim-spring" /* DimSpring */ || kind === "sliding-bar" /* SlidingBar */;
|
|
2408
|
+
return slow ? motionDurations.slow : motionDurations.base;
|
|
2409
|
+
}
|
|
2410
|
+
function resolveTabFeedback(kind, state, reducedMotion) {
|
|
2411
|
+
const pillScale = state.active ? FULL : 0;
|
|
2412
|
+
return {
|
|
2413
|
+
opacity: kind === "dim-spring" /* DimSpring */ && state.pressed ? DIM_OPACITY : FULL,
|
|
2414
|
+
iconTransform: reducedMotion ? void 0 : tabIconTransform(kind, state),
|
|
2415
|
+
pillScale: kind === "indicator-pill" /* IndicatorPill */ ? pillScale : null,
|
|
2416
|
+
spring: kind === "dim-spring" /* DimSpring */ && !reducedMotion,
|
|
2417
|
+
durationMs: reducedMotion ? motionDurations.instant : tabDuration(kind)
|
|
2418
|
+
};
|
|
2419
|
+
}
|
|
2420
|
+
function slidingBarPosition(activeIndex, count) {
|
|
2421
|
+
if (activeIndex < 0 || count <= 0) return null;
|
|
2422
|
+
const share = PERCENT / count;
|
|
2423
|
+
return { left: `${activeIndex * share}%`, width: `${share}%` };
|
|
2424
|
+
}
|
|
2425
|
+
function springSteps() {
|
|
2426
|
+
return [
|
|
2427
|
+
{ toValue: SPRING_OVERSHOOT, durationMs: motionDurations.fast },
|
|
2428
|
+
{ toValue: FULL, durationMs: motionDurations.slow - motionDurations.fast }
|
|
2429
|
+
];
|
|
2430
|
+
}
|
|
2431
|
+
function useSettleSpring(active, enabled) {
|
|
2432
|
+
const scale = useRef(new Animated.Value(FULL)).current;
|
|
2433
|
+
useEffect(() => {
|
|
2434
|
+
if (!enabled || !active) return void 0;
|
|
2435
|
+
const steps = springSteps().map(
|
|
2436
|
+
(step) => Animated.timing(scale, {
|
|
2437
|
+
toValue: step.toValue,
|
|
2438
|
+
duration: step.durationMs,
|
|
2439
|
+
easing: motionEasings.standard,
|
|
2440
|
+
useNativeDriver: false
|
|
2441
|
+
})
|
|
2442
|
+
);
|
|
2443
|
+
const animation = Animated.sequence(steps);
|
|
2444
|
+
animation.start();
|
|
2445
|
+
return () => animation.stop();
|
|
2446
|
+
}, [active, enabled, scale]);
|
|
2447
|
+
return scale;
|
|
2448
|
+
}
|
|
2449
|
+
var ICON_SIZE = 24;
|
|
2450
|
+
var PILL_WIDTH = 56;
|
|
2451
|
+
var PILL_HEIGHT = 32;
|
|
2452
|
+
var PILL_RADIUS = 16;
|
|
2453
|
+
var TAB_MIN_HEIGHT = 56;
|
|
2454
|
+
var LABEL_SIZE = 12;
|
|
2455
|
+
var LABEL_GAP = 2;
|
|
2456
|
+
var TAB_PADDING = 4;
|
|
2457
|
+
var styles8 = StyleSheet.create({
|
|
2458
|
+
tab: {
|
|
2459
|
+
flex: 1,
|
|
2460
|
+
minHeight: TAB_MIN_HEIGHT,
|
|
2461
|
+
alignItems: "center",
|
|
2462
|
+
justifyContent: "center",
|
|
2463
|
+
paddingVertical: TAB_PADDING,
|
|
2464
|
+
rowGap: LABEL_GAP
|
|
2465
|
+
},
|
|
2466
|
+
iconWrap: { width: PILL_WIDTH, height: PILL_HEIGHT, alignItems: "center", justifyContent: "center" },
|
|
2467
|
+
pill: { ...StyleSheet.absoluteFillObject, borderRadius: PILL_RADIUS },
|
|
2468
|
+
label: { fontSize: LABEL_SIZE, textAlign: "center" }
|
|
2469
|
+
});
|
|
2470
|
+
function ariaCurrentProps3(isActive) {
|
|
2471
|
+
return isActive ? { "aria-current": "page" } : {};
|
|
2472
|
+
}
|
|
2473
|
+
var BottomTab = ({
|
|
2474
|
+
item,
|
|
2475
|
+
isActive,
|
|
2476
|
+
kind,
|
|
2477
|
+
colors,
|
|
2478
|
+
reducedMotion,
|
|
2479
|
+
navigateHint,
|
|
2480
|
+
onPress
|
|
2481
|
+
}) => {
|
|
2482
|
+
const [pressed, setPressed] = useState(false);
|
|
2483
|
+
const feedback = resolveTabFeedback(kind, { active: isActive, pressed }, reducedMotion);
|
|
2484
|
+
const scale = useSettleSpring(isActive, feedback.spring);
|
|
2485
|
+
const color = isActive ? colors.active : colors.rest;
|
|
2486
|
+
const motion = webTransition("transform", feedback.durationMs, reducedMotion);
|
|
2487
|
+
return /* @__PURE__ */ jsxs(
|
|
2488
|
+
Pressable,
|
|
2489
|
+
{
|
|
2490
|
+
accessibilityHint: navigateHint(item.label),
|
|
2491
|
+
accessibilityLabel: item.label,
|
|
2492
|
+
accessibilityRole: "link",
|
|
2493
|
+
accessibilityState: { selected: isActive },
|
|
2494
|
+
style: [styles8.tab, { opacity: feedback.opacity }],
|
|
2495
|
+
testID: item.testID ?? item.key,
|
|
2496
|
+
onPress: () => onPress(item.route),
|
|
2497
|
+
onPressIn: () => setPressed(true),
|
|
2498
|
+
onPressOut: () => setPressed(false),
|
|
2499
|
+
...ariaCurrentProps3(isActive),
|
|
2500
|
+
children: [
|
|
2501
|
+
/* @__PURE__ */ jsxs(Animated.View, { style: [styles8.iconWrap, { transform: [{ scale }] }], children: [
|
|
2502
|
+
feedback.pillScale === null ? null : /* @__PURE__ */ jsx(
|
|
2503
|
+
View,
|
|
2504
|
+
{
|
|
2505
|
+
pointerEvents: "none",
|
|
2506
|
+
style: [styles8.pill, { backgroundColor: colors.pill, transform: [{ scale: feedback.pillScale }] }, motion]
|
|
2507
|
+
}
|
|
2508
|
+
),
|
|
2509
|
+
/* @__PURE__ */ jsx(View, { style: [{ transform: feedback.iconTransform }, motion], children: item.renderIcon?.(color, ICON_SIZE) })
|
|
2510
|
+
] }),
|
|
2511
|
+
/* @__PURE__ */ jsx(Text, { style: [styles8.label, { color }], children: item.label })
|
|
2512
|
+
]
|
|
2513
|
+
}
|
|
2514
|
+
);
|
|
2515
|
+
};
|
|
2516
|
+
var DEFAULT_TEST_ID = "bottom-tab-bar";
|
|
2517
|
+
var SLIDER_HEIGHT = 3;
|
|
2518
|
+
var styles9 = StyleSheet.create({
|
|
2519
|
+
bar: { flexDirection: "row", borderTopWidth: StyleSheet.hairlineWidth },
|
|
2520
|
+
slider: { position: "absolute", top: 0, height: SLIDER_HEIGHT }
|
|
2521
|
+
});
|
|
2522
|
+
var BottomTabBar = ({
|
|
2523
|
+
items,
|
|
2524
|
+
pathname,
|
|
2525
|
+
onNavigate,
|
|
2526
|
+
tabFeedback = "default" /* Default */,
|
|
2527
|
+
navigateHint = (label) => label,
|
|
2528
|
+
regionLabel = "",
|
|
2529
|
+
containerStyle,
|
|
2530
|
+
testID = DEFAULT_TEST_ID
|
|
2531
|
+
}) => {
|
|
2532
|
+
const { theme } = useUi();
|
|
2533
|
+
const reducedMotion = useReducedMotion();
|
|
2534
|
+
const primary = theme.palette.primary["500"];
|
|
2535
|
+
const activeRoute = resolveActiveRoute(items, pathname);
|
|
2536
|
+
const activeIndex = items.findIndex((item) => item.route === activeRoute);
|
|
2537
|
+
const bar = tabFeedback === "sliding-bar" /* SlidingBar */ ? slidingBarPosition(activeIndex, items.length) : null;
|
|
2538
|
+
const barMs = resolveTabFeedback(tabFeedback, { active: true, pressed: false }, reducedMotion).durationMs;
|
|
2539
|
+
const colors = { active: primary, rest: theme.colors.textSecondary, pill: theme.colors.surfaceElevated };
|
|
2540
|
+
return /* @__PURE__ */ jsxs(
|
|
2541
|
+
View,
|
|
2542
|
+
{
|
|
2543
|
+
"aria-label": regionLabel,
|
|
2544
|
+
role: "navigation",
|
|
2545
|
+
style: [styles9.bar, { backgroundColor: theme.colors.surface, borderTopColor: theme.colors.border }, containerStyle],
|
|
2546
|
+
testID,
|
|
2547
|
+
children: [
|
|
2548
|
+
bar === null ? null : /* @__PURE__ */ jsx(
|
|
2549
|
+
View,
|
|
2550
|
+
{
|
|
2551
|
+
pointerEvents: "none",
|
|
2552
|
+
style: [styles9.slider, { left: bar.left, width: bar.width, backgroundColor: primary }, webTransition("left", barMs, reducedMotion)]
|
|
2553
|
+
}
|
|
2554
|
+
),
|
|
2555
|
+
items.map((item) => /* @__PURE__ */ jsx(
|
|
2556
|
+
BottomTab,
|
|
2557
|
+
{
|
|
2558
|
+
colors,
|
|
2559
|
+
isActive: item.route === activeRoute,
|
|
2560
|
+
item,
|
|
2561
|
+
kind: tabFeedback,
|
|
2562
|
+
navigateHint,
|
|
2563
|
+
reducedMotion,
|
|
2564
|
+
onPress: onNavigate
|
|
2565
|
+
},
|
|
2566
|
+
item.key
|
|
2567
|
+
))
|
|
2568
|
+
]
|
|
2569
|
+
}
|
|
2570
|
+
);
|
|
2571
|
+
};
|
|
2572
|
+
|
|
2573
|
+
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
2574
|
//# sourceMappingURL=index.mjs.map
|
|
2219
2575
|
//# sourceMappingURL=index.mjs.map
|