@oxy.so/bloom 4.1.0 → 4.3.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/docs/adoption-matrix.mdx +7 -7
- package/docs/ai-chat.mdx +8 -0
- package/docs/app-shell.mdx +7 -0
- package/docs/bottom-bar.mdx +6 -0
- package/docs/settings-modal.mdx +14 -5
- package/docs/sidebar.mdx +11 -0
- package/lib/commonjs/ai-chat/AiChatContainer.js +8 -8
- package/lib/commonjs/ai-chat/AiChatContainer.js.map +1 -1
- package/lib/commonjs/app-shell/AppShellBars.js +8 -2
- package/lib/commonjs/app-shell/AppShellBars.js.map +1 -1
- package/lib/commonjs/app-shell/AppShellEngine.js +29 -6
- package/lib/commonjs/app-shell/AppShellEngine.js.map +1 -1
- package/lib/commonjs/bottom-bar/BottomBarBase.js +10 -2
- package/lib/commonjs/bottom-bar/BottomBarBase.js.map +1 -1
- package/lib/commonjs/layout/bottom-bar-slot.js +10 -0
- package/lib/commonjs/layout/bottom-bar-slot.js.map +1 -0
- package/lib/commonjs/settings-modal/SettingsModal.js +153 -230
- package/lib/commonjs/settings-modal/SettingsModal.js.map +1 -1
- package/lib/commonjs/sidebar/Sidebar.js +35 -5
- package/lib/commonjs/sidebar/Sidebar.js.map +1 -1
- package/lib/module/ai-chat/AiChatContainer.js +8 -8
- package/lib/module/ai-chat/AiChatContainer.js.map +1 -1
- package/lib/module/app-shell/AppShellBars.js +8 -2
- package/lib/module/app-shell/AppShellBars.js.map +1 -1
- package/lib/module/app-shell/AppShellEngine.js +30 -7
- package/lib/module/app-shell/AppShellEngine.js.map +1 -1
- package/lib/module/bottom-bar/BottomBarBase.js +11 -3
- package/lib/module/bottom-bar/BottomBarBase.js.map +1 -1
- package/lib/module/layout/bottom-bar-slot.js +7 -0
- package/lib/module/layout/bottom-bar-slot.js.map +1 -0
- package/lib/module/settings-modal/SettingsModal.js +150 -227
- package/lib/module/settings-modal/SettingsModal.js.map +1 -1
- package/lib/module/sidebar/Sidebar.js +35 -5
- package/lib/module/sidebar/Sidebar.js.map +1 -1
- package/lib/typescript/commonjs/ai-chat/types.d.ts +2 -2
- package/lib/typescript/commonjs/ai-chat/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/app-shell/AppShellBars.d.ts +1 -0
- package/lib/typescript/commonjs/app-shell/AppShellBars.d.ts.map +1 -1
- package/lib/typescript/commonjs/app-shell/AppShellEngine.d.ts.map +1 -1
- package/lib/typescript/commonjs/bottom-bar/BottomBarBase.d.ts +1 -1
- package/lib/typescript/commonjs/bottom-bar/BottomBarBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/bottom-bar/types.d.ts +4 -0
- package/lib/typescript/commonjs/bottom-bar/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/layout/bottom-bar-slot.d.ts +3 -0
- package/lib/typescript/commonjs/layout/bottom-bar-slot.d.ts.map +1 -0
- package/lib/typescript/commonjs/settings-modal/SettingsModal.d.ts +1 -1
- package/lib/typescript/commonjs/settings-modal/SettingsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/settings-modal/types.d.ts +7 -2
- package/lib/typescript/commonjs/settings-modal/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/sidebar/Sidebar.d.ts.map +1 -1
- package/lib/typescript/commonjs/sidebar/types.d.ts +12 -1
- package/lib/typescript/commonjs/sidebar/types.d.ts.map +1 -1
- package/lib/typescript/module/ai-chat/types.d.ts +2 -2
- package/lib/typescript/module/ai-chat/types.d.ts.map +1 -1
- package/lib/typescript/module/app-shell/AppShellBars.d.ts +1 -0
- package/lib/typescript/module/app-shell/AppShellBars.d.ts.map +1 -1
- package/lib/typescript/module/app-shell/AppShellEngine.d.ts.map +1 -1
- package/lib/typescript/module/bottom-bar/BottomBarBase.d.ts +1 -1
- package/lib/typescript/module/bottom-bar/BottomBarBase.d.ts.map +1 -1
- package/lib/typescript/module/bottom-bar/types.d.ts +4 -0
- package/lib/typescript/module/bottom-bar/types.d.ts.map +1 -1
- package/lib/typescript/module/layout/bottom-bar-slot.d.ts +3 -0
- package/lib/typescript/module/layout/bottom-bar-slot.d.ts.map +1 -0
- package/lib/typescript/module/settings-modal/SettingsModal.d.ts +1 -1
- package/lib/typescript/module/settings-modal/SettingsModal.d.ts.map +1 -1
- package/lib/typescript/module/settings-modal/types.d.ts +7 -2
- package/lib/typescript/module/settings-modal/types.d.ts.map +1 -1
- package/lib/typescript/module/sidebar/Sidebar.d.ts.map +1 -1
- package/lib/typescript/module/sidebar/types.d.ts +12 -1
- package/lib/typescript/module/sidebar/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/support/adoption-matrix.ts +703 -0
- package/src/__tests__/support/collision-fixture-barrel.ts +20 -0
- package/src/__tests__/support/commerce-harness.tsx +97 -0
- package/src/__tests__/support/composite.ts +68 -0
- package/src/__tests__/support/constructed-style-sheets.ts +68 -0
- package/src/__tests__/support/press-host.ts +30 -0
- package/src/__tests__/support/rendered-style.ts +99 -0
- package/src/__tests__/support/unread-hook-fixture.ts +33 -0
- package/src/ai-chat/AiChatContainer.tsx +7 -7
- package/src/ai-chat/types.ts +2 -2
- package/src/app-shell/AppShellBars.tsx +5 -3
- package/src/app-shell/AppShellEngine.tsx +23 -8
- package/src/bottom-bar/BottomBarBase.tsx +7 -4
- package/src/bottom-bar/types.ts +4 -0
- package/src/layout/bottom-bar-slot.ts +4 -0
- package/src/settings-modal/SettingsModal.tsx +180 -250
- package/src/settings-modal/types.ts +7 -2
- package/src/sidebar/Sidebar.tsx +26 -5
- package/src/sidebar/types.ts +12 -1
- package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +9346 -0
- package/src/theme/__tests__/__fixtures__/tonal-glass-primary-failures.json +69 -0
- package/src/theme/__tests__/fixtures/color-engine-golden.json +1 -0
|
@@ -8,14 +8,14 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
|
|
10
10
|
var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
|
|
11
|
-
var _RiArrowLeftSLine = require("../icons/remix/RiArrowLeftSLine.js");
|
|
12
11
|
var _RiArrowRightSLine = require("../icons/remix/RiArrowRightSLine.js");
|
|
13
12
|
var _RiCheckboxCircleFill = require("../icons/remix/RiCheckboxCircleFill.js");
|
|
13
|
+
var _index = require("../page-header/index.js");
|
|
14
|
+
var _index2 = require("../button-group/index.js");
|
|
14
15
|
var _RiCloseLine = require("../icons/remix/RiCloseLine.js");
|
|
15
|
-
var
|
|
16
|
-
var _index = require("../overlay/index.js");
|
|
16
|
+
var _index3 = require("../overlay/index.js");
|
|
17
17
|
var _webData = require("../styles/web-data.js");
|
|
18
|
-
var
|
|
18
|
+
var _index4 = require("../typography/index.js");
|
|
19
19
|
var _context = require("./context.js");
|
|
20
20
|
var _modalPortal = require("./modal-portal");
|
|
21
21
|
var _webCss = require("./web-css.js");
|
|
@@ -33,10 +33,8 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
33
33
|
* 20px icon (icon/secondary) + 8 + body-medium label
|
|
34
34
|
* (selected: background/secondary/hover + text/primary;
|
|
35
35
|
* hover: background/secondary/hover @ 60%)
|
|
36
|
-
* content
|
|
37
|
-
*
|
|
38
|
-
* 16px glyph); the page scrolls under a 40px top fade that eases
|
|
39
|
-
* in (200ms) once it is scrolled; px 32 pb 32
|
|
36
|
+
* content one viewport with a sticky PageHeader and its scroll-linked edge;
|
|
37
|
+
* content insets belong to the page body, never the viewport
|
|
40
38
|
* toast "Saved" pill straddling the panel's bottom edge: 1px
|
|
41
39
|
* border/button, background/primary, py 4 pr 10 pl 6, gap 4,
|
|
42
40
|
* 16px lime check + body-2-medium, shadow-dropdown. Rises 12px in,
|
|
@@ -100,11 +98,13 @@ function SettingsModal({
|
|
|
100
98
|
control,
|
|
101
99
|
open: controlledOpen,
|
|
102
100
|
onClose,
|
|
101
|
+
onBeforeLeave,
|
|
103
102
|
groups,
|
|
104
103
|
pages,
|
|
105
104
|
page: controlledPage,
|
|
106
105
|
defaultPage,
|
|
107
106
|
onPageChange,
|
|
107
|
+
initialView = 'navigation',
|
|
108
108
|
labels,
|
|
109
109
|
testID
|
|
110
110
|
}) {
|
|
@@ -128,7 +128,12 @@ function SettingsModal({
|
|
|
128
128
|
const insets = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
|
|
129
129
|
|
|
130
130
|
// `compact` layout is two levels: the section list, then a page pushed over it.
|
|
131
|
-
const [compactPageOpen, setCompactPageOpen] = (0, _react.useState)(
|
|
131
|
+
const [compactPageOpen, setCompactPageOpen] = (0, _react.useState)(initialView === 'page');
|
|
132
|
+
const initialViewRef = (0, _react.useRef)(initialView);
|
|
133
|
+
initialViewRef.current = initialView;
|
|
134
|
+
const beforeLeaveRef = (0, _react.useRef)(onBeforeLeave);
|
|
135
|
+
beforeLeaveRef.current = onBeforeLeave;
|
|
136
|
+
const mayLeave = (0, _react.useCallback)(reason => beforeLeaveRef.current?.(reason) !== false, []);
|
|
132
137
|
const onCloseRef = (0, _react.useRef)(onClose);
|
|
133
138
|
onCloseRef.current = onClose;
|
|
134
139
|
const isControlledRef = (0, _react.useRef)(isControlled);
|
|
@@ -137,7 +142,7 @@ function SettingsModal({
|
|
|
137
142
|
defaultPageRef.current = defaultPage ?? firstPage(groups);
|
|
138
143
|
const show = (0, _react.useCallback)(() => {
|
|
139
144
|
setInternalPage(defaultPageRef.current);
|
|
140
|
-
setCompactPageOpen(
|
|
145
|
+
setCompactPageOpen(initialViewRef.current === 'page');
|
|
141
146
|
setMounted(true);
|
|
142
147
|
setOpenCount(count => count + 1);
|
|
143
148
|
}, []);
|
|
@@ -174,20 +179,25 @@ function SettingsModal({
|
|
|
174
179
|
if (controlledOpen) show();else hide();
|
|
175
180
|
}, [isControlled, controlledOpen, show, hide]);
|
|
176
181
|
const requestClose = (0, _react.useCallback)(() => {
|
|
182
|
+
if (!mayLeave('close')) return false;
|
|
177
183
|
if (isControlledRef.current) onCloseRef.current?.();else hide();
|
|
178
|
-
|
|
184
|
+
return true;
|
|
185
|
+
}, [hide, mayLeave]);
|
|
179
186
|
(0, _react.useImperativeHandle)(control?.ref, () => ({
|
|
180
187
|
open: show,
|
|
181
188
|
close: cb => {
|
|
182
|
-
|
|
183
|
-
if (cb) setTimeout(cb, UNMOUNT_MS);
|
|
189
|
+
if (requestClose() && cb) setTimeout(cb, UNMOUNT_MS);
|
|
184
190
|
}
|
|
185
|
-
}), [show,
|
|
191
|
+
}), [show, requestClose]);
|
|
186
192
|
const selectPage = (0, _react.useCallback)(next => {
|
|
193
|
+
if (next !== currentPage && !mayLeave('page')) return;
|
|
187
194
|
if (controlledPage === undefined) setInternalPage(next);
|
|
188
195
|
setCompactPageOpen(true);
|
|
189
196
|
onPageChange?.(next);
|
|
190
|
-
}, [controlledPage, onPageChange]);
|
|
197
|
+
}, [controlledPage, currentPage, onPageChange, mayLeave]);
|
|
198
|
+
const requestNavigation = (0, _react.useCallback)(() => {
|
|
199
|
+
if (mayLeave('navigation')) setCompactPageOpen(false);
|
|
200
|
+
}, [mayLeave]);
|
|
191
201
|
|
|
192
202
|
// Escape closes (web). On `window`, not `document`: a menu or popover opened
|
|
193
203
|
// inside the modal handles Escape on `document` and stops propagation there,
|
|
@@ -212,11 +222,11 @@ function SettingsModal({
|
|
|
212
222
|
if (!mounted || _webCss.IS_WEB || typeof _reactNative.BackHandler?.addEventListener !== 'function') return;
|
|
213
223
|
const sub = _reactNative.BackHandler.addEventListener('hardwareBackPress', () => {
|
|
214
224
|
// On a pushed page (compact), back returns to the section list first.
|
|
215
|
-
if (compactPageOpenRef.current)
|
|
225
|
+
if (compactPageOpenRef.current) requestNavigation();else requestClose();
|
|
216
226
|
return true;
|
|
217
227
|
});
|
|
218
228
|
return () => sub.remove();
|
|
219
|
-
}, [mounted, requestClose]);
|
|
229
|
+
}, [mounted, requestClose, requestNavigation]);
|
|
220
230
|
|
|
221
231
|
// ----- saved toast -------------------------------------------------------
|
|
222
232
|
const [savedPhase, setSavedPhase] = (0, _react.useState)('hidden');
|
|
@@ -287,8 +297,8 @@ function SettingsModal({
|
|
|
287
297
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_modalPortal.ModalPortal, {
|
|
288
298
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_context.SettingsModalContext.Provider, {
|
|
289
299
|
value: context,
|
|
290
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
291
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
300
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index3.OverlayRoot, {
|
|
301
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index3.Backdrop, {
|
|
292
302
|
onPress: requestClose,
|
|
293
303
|
progress: progress,
|
|
294
304
|
blurIntensity: 0,
|
|
@@ -326,32 +336,30 @@ function SettingsModal({
|
|
|
326
336
|
backgroundColor: palette.full,
|
|
327
337
|
boxShadow: palette.shadowXs
|
|
328
338
|
}, ringVars(palette)],
|
|
329
|
-
children: layout === 'compact' ? compactPageOpen && pageConfig ? /*#__PURE__*/(0, _jsxRuntime.
|
|
339
|
+
children: layout === 'compact' ? compactPageOpen && pageConfig ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
330
340
|
style: styles.content,
|
|
331
|
-
children:
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(PageScroller, {
|
|
341
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(PageScroller, {
|
|
342
|
+
header: {
|
|
343
|
+
title: pageConfig.title,
|
|
344
|
+
onBack: requestNavigation,
|
|
345
|
+
backLabel: labels?.back ?? 'Back',
|
|
346
|
+
closeLabel,
|
|
347
|
+
onClose: requestClose
|
|
348
|
+
},
|
|
340
349
|
palette: palette,
|
|
341
350
|
inset: CONTENT_INSET.compact,
|
|
342
351
|
insetTop: CONTENT_INSET.compact,
|
|
343
352
|
testID: testID,
|
|
344
353
|
children: pageConfig.content
|
|
345
|
-
}, currentPage)
|
|
346
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.
|
|
354
|
+
}, currentPage)
|
|
355
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
347
356
|
style: styles.content,
|
|
348
|
-
children:
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(SettingsRail, {
|
|
357
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(SettingsRail, {
|
|
358
|
+
header: {
|
|
359
|
+
title: labels?.dialog ?? 'Settings',
|
|
360
|
+
closeLabel,
|
|
361
|
+
onClose: requestClose
|
|
362
|
+
},
|
|
355
363
|
groups: groups,
|
|
356
364
|
page: currentPage,
|
|
357
365
|
onSelect: selectPage,
|
|
@@ -359,7 +367,7 @@ function SettingsModal({
|
|
|
359
367
|
label: labels?.nav ?? 'Settings sections',
|
|
360
368
|
layout: "compact",
|
|
361
369
|
testID: testID
|
|
362
|
-
})
|
|
370
|
+
})
|
|
363
371
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
364
372
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SettingsRail, {
|
|
365
373
|
groups: groups,
|
|
@@ -369,35 +377,20 @@ function SettingsModal({
|
|
|
369
377
|
label: labels?.nav ?? 'Settings sections',
|
|
370
378
|
layout: layout,
|
|
371
379
|
testID: testID
|
|
372
|
-
}), /*#__PURE__*/(0, _jsxRuntime.
|
|
380
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
373
381
|
style: styles.content,
|
|
374
|
-
children:
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
}],
|
|
381
|
-
testID: testID ? `${testID}-title-row` : undefined,
|
|
382
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Text, {
|
|
383
|
-
variant: "title-3-medium",
|
|
384
|
-
role: "heading",
|
|
385
|
-
style: {
|
|
386
|
-
color: palette.text
|
|
387
|
-
},
|
|
388
|
-
children: pageConfig?.title ?? ''
|
|
389
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(SettingsCloseButton, {
|
|
390
|
-
label: closeLabel,
|
|
391
|
-
onPress: requestClose,
|
|
392
|
-
palette: palette,
|
|
393
|
-
testID: testID ? `${testID}-close` : undefined
|
|
394
|
-
})]
|
|
395
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(PageScroller, {
|
|
382
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(PageScroller, {
|
|
383
|
+
header: {
|
|
384
|
+
title: pageConfig?.title ?? '',
|
|
385
|
+
closeLabel,
|
|
386
|
+
onClose: requestClose
|
|
387
|
+
},
|
|
396
388
|
palette: palette,
|
|
397
389
|
inset: CONTENT_INSET[layout],
|
|
390
|
+
insetTop: pageConfig?.compactTitle ? 6 : 12,
|
|
398
391
|
testID: testID,
|
|
399
392
|
children: pageConfig?.content
|
|
400
|
-
}, currentPage)
|
|
393
|
+
}, currentPage)
|
|
401
394
|
})]
|
|
402
395
|
})
|
|
403
396
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(SavedToast, {
|
|
@@ -426,6 +419,7 @@ function ringVars(palette) {
|
|
|
426
419
|
// ---------------------------------------------------------------------------
|
|
427
420
|
|
|
428
421
|
function SettingsRail({
|
|
422
|
+
header,
|
|
429
423
|
groups,
|
|
430
424
|
page,
|
|
431
425
|
onSelect,
|
|
@@ -435,7 +429,11 @@ function SettingsRail({
|
|
|
435
429
|
testID
|
|
436
430
|
}) {
|
|
437
431
|
const compact = layout === 'compact';
|
|
438
|
-
|
|
432
|
+
const scrollY = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
433
|
+
const onScroll = (0, _reactNativeReanimated.useAnimatedScrollHandler)(event => {
|
|
434
|
+
scrollY.value = Math.max(0, event.contentOffset.y);
|
|
435
|
+
}, [scrollY]);
|
|
436
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeReanimated.default.ScrollView, {
|
|
439
437
|
role: "navigation",
|
|
440
438
|
"aria-label": label,
|
|
441
439
|
style: [compact ? styles.railCompact : [styles.rail, {
|
|
@@ -444,31 +442,47 @@ function SettingsRail({
|
|
|
444
442
|
backgroundColor: palette.secondary,
|
|
445
443
|
borderRightColor: palette.separator
|
|
446
444
|
}],
|
|
447
|
-
contentContainerStyle:
|
|
445
|
+
contentContainerStyle: header ? undefined : styles.railContent,
|
|
446
|
+
stickyHeaderIndices: header && !_webCss.IS_WEB ? [0] : undefined,
|
|
447
|
+
onScroll: onScroll,
|
|
448
|
+
scrollEventThrottle: 16,
|
|
449
|
+
contentInsetAdjustmentBehavior: "never",
|
|
450
|
+
automaticallyAdjustContentInsets: false,
|
|
448
451
|
showsVerticalScrollIndicator: false,
|
|
449
452
|
testID: testID ? `${testID}-rail` : undefined,
|
|
450
|
-
children:
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
,
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
453
|
+
children: [header ? /*#__PURE__*/(0, _jsxRuntime.jsx)(SettingsHeader, {
|
|
454
|
+
...header,
|
|
455
|
+
palette: palette,
|
|
456
|
+
scrimColor: palette.secondary,
|
|
457
|
+
scrollY: scrollY,
|
|
458
|
+
testID: testID
|
|
459
|
+
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
460
|
+
style: header ? [styles.railContent, styles.railContentCompact] : {
|
|
461
|
+
gap: 20
|
|
462
|
+
},
|
|
463
|
+
children: groups.map(group => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
464
|
+
style: styles.group,
|
|
465
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index4.Text, {
|
|
466
|
+
variant: "body-medium",
|
|
467
|
+
style: [styles.groupLabel, {
|
|
468
|
+
color: palette.textSecondary
|
|
469
|
+
}],
|
|
470
|
+
children: group.label
|
|
471
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
472
|
+
style: styles.groupRows,
|
|
473
|
+
children: group.items.map(item => /*#__PURE__*/(0, _jsxRuntime.jsx)(RailRow, {
|
|
474
|
+
item: item
|
|
475
|
+
// A list, not a selection, when the rows ARE the navigation.
|
|
476
|
+
,
|
|
477
|
+
selected: !compact && item.page !== undefined && item.page === page,
|
|
478
|
+
showChevron: compact && item.page !== undefined,
|
|
479
|
+
onSelect: onSelect,
|
|
480
|
+
palette: palette,
|
|
481
|
+
testID: testID ? `${testID}-nav-${item.key}` : undefined
|
|
482
|
+
}, item.key))
|
|
483
|
+
})]
|
|
484
|
+
}, group.key ?? group.label))
|
|
485
|
+
})]
|
|
472
486
|
});
|
|
473
487
|
}
|
|
474
488
|
function RailRow({
|
|
@@ -508,7 +522,7 @@ function RailRow({
|
|
|
508
522
|
width: 20,
|
|
509
523
|
height: 20,
|
|
510
524
|
fill: palette.iconSecondary
|
|
511
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
525
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_index4.Text, {
|
|
512
526
|
variant: "body-medium",
|
|
513
527
|
numberOfLines: 1,
|
|
514
528
|
style: [styles.railLabel, {
|
|
@@ -530,124 +544,78 @@ function RailRow({
|
|
|
530
544
|
// Close button, scroller, toast
|
|
531
545
|
// ---------------------------------------------------------------------------
|
|
532
546
|
|
|
533
|
-
|
|
534
|
-
label,
|
|
535
|
-
onPress,
|
|
536
|
-
palette,
|
|
537
|
-
testID
|
|
538
|
-
}) {
|
|
539
|
-
const [hovered, setHovered] = (0, _react.useState)(false);
|
|
540
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
541
|
-
role: "button",
|
|
542
|
-
accessibilityLabel: label,
|
|
543
|
-
...(0, _webData.webDataSet)({
|
|
544
|
-
bloomSettingsPress: ''
|
|
545
|
-
}),
|
|
546
|
-
onPress: onPress,
|
|
547
|
-
onHoverIn: () => setHovered(true),
|
|
548
|
-
onHoverOut: () => setHovered(false),
|
|
549
|
-
testID: testID,
|
|
550
|
-
style: [styles.close, {
|
|
551
|
-
backgroundColor: hovered ? palette.tertiaryHover : palette.tertiary
|
|
552
|
-
}],
|
|
553
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RiCloseLine.RiCloseLine, {
|
|
554
|
-
width: 16,
|
|
555
|
-
height: 16,
|
|
556
|
-
fill: palette.iconSecondary
|
|
557
|
-
})
|
|
558
|
-
});
|
|
559
|
-
}
|
|
547
|
+
/** Shared header on every layout; the modal already owns safe-area insets. */
|
|
560
548
|
|
|
561
|
-
|
|
562
|
-
* The `compact` title bar: optional back chevron, the title, the close button —
|
|
563
|
-
* 56px, the page's 16px inset, hairline under it.
|
|
564
|
-
*/
|
|
565
|
-
function CompactHeader({
|
|
549
|
+
function SettingsHeader({
|
|
566
550
|
title,
|
|
567
551
|
onBack,
|
|
568
552
|
backLabel,
|
|
569
553
|
closeLabel,
|
|
570
554
|
onClose,
|
|
571
555
|
palette,
|
|
556
|
+
scrollY,
|
|
557
|
+
scrimColor = palette.full,
|
|
572
558
|
testID
|
|
573
559
|
}) {
|
|
574
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
560
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.PageHeader, {
|
|
561
|
+
title: title,
|
|
562
|
+
headingLevel: 2,
|
|
563
|
+
onBack: onBack,
|
|
564
|
+
backLabel: backLabel,
|
|
565
|
+
safeArea: false,
|
|
566
|
+
sticky: _webCss.IS_WEB,
|
|
567
|
+
placement: "inline",
|
|
568
|
+
scrim: "auto",
|
|
569
|
+
scrimColor: scrimColor,
|
|
570
|
+
scrollY: scrollY,
|
|
571
|
+
actions: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.ButtonGroup, {
|
|
572
|
+
accessibilityLabel: closeLabel,
|
|
573
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.ButtonGroupItem, {
|
|
574
|
+
iconOnly: true,
|
|
575
|
+
leadingIcon: _RiCloseLine.RiCloseLine,
|
|
576
|
+
accessibilityLabel: closeLabel,
|
|
577
|
+
onPress: onClose,
|
|
578
|
+
testID: testID ? `${testID}-close` : undefined
|
|
593
579
|
})
|
|
594
|
-
})
|
|
595
|
-
|
|
596
|
-
role: "heading",
|
|
597
|
-
numberOfLines: 1,
|
|
598
|
-
style: [styles.compactTitle, {
|
|
599
|
-
color: palette.text
|
|
600
|
-
}],
|
|
601
|
-
children: title
|
|
602
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(SettingsCloseButton, {
|
|
603
|
-
label: closeLabel,
|
|
604
|
-
onPress: onClose,
|
|
605
|
-
palette: palette,
|
|
606
|
-
testID: testID ? `${testID}-close` : undefined
|
|
607
|
-
})]
|
|
580
|
+
}),
|
|
581
|
+
testID: testID ? `${testID}-header` : undefined
|
|
608
582
|
});
|
|
609
583
|
}
|
|
584
|
+
|
|
585
|
+
/** Each page owns one full-height viewport, including its header. */
|
|
610
586
|
function PageScroller({
|
|
611
587
|
children,
|
|
588
|
+
header,
|
|
612
589
|
palette,
|
|
613
590
|
inset,
|
|
614
591
|
insetTop = 0,
|
|
615
592
|
testID
|
|
616
593
|
}) {
|
|
617
|
-
const
|
|
618
|
-
const onScroll = (0,
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
} :
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
594
|
+
const scrollY = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
595
|
+
const onScroll = (0, _reactNativeReanimated.useAnimatedScrollHandler)(event => {
|
|
596
|
+
scrollY.value = Math.max(0, event.contentOffset.y);
|
|
597
|
+
}, [scrollY]);
|
|
598
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeReanimated.default.ScrollView, {
|
|
599
|
+
style: styles.scroll,
|
|
600
|
+
stickyHeaderIndices: _webCss.IS_WEB ? undefined : [0],
|
|
601
|
+
onScroll: onScroll,
|
|
602
|
+
scrollEventThrottle: 16,
|
|
603
|
+
contentInsetAdjustmentBehavior: "never",
|
|
604
|
+
automaticallyAdjustContentInsets: false,
|
|
605
|
+
testID: testID ? `${testID}-page` : undefined,
|
|
606
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SettingsHeader, {
|
|
607
|
+
...header,
|
|
608
|
+
palette: palette,
|
|
609
|
+
scrollY: scrollY,
|
|
610
|
+
testID: testID
|
|
611
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
612
|
+
style: {
|
|
635
613
|
paddingLeft: inset,
|
|
636
614
|
paddingRight: inset,
|
|
637
615
|
paddingBottom: inset,
|
|
638
616
|
paddingTop: insetTop
|
|
639
|
-
}
|
|
640
|
-
onScroll: onScroll,
|
|
641
|
-
scrollEventThrottle: 16,
|
|
642
|
-
testID: testID ? `${testID}-page` : undefined,
|
|
617
|
+
},
|
|
643
618
|
children: children
|
|
644
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
645
|
-
pointerEvents: "none",
|
|
646
|
-
style: [styles.fade, fade],
|
|
647
|
-
testID: testID ? `${testID}-fade` : undefined,
|
|
648
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_SettingsArt.VerticalFade, {
|
|
649
|
-
color: palette.primary
|
|
650
|
-
})
|
|
651
619
|
})]
|
|
652
620
|
});
|
|
653
621
|
}
|
|
@@ -705,7 +673,7 @@ function SavedToast({
|
|
|
705
673
|
width: 16,
|
|
706
674
|
height: 16,
|
|
707
675
|
fill: palette.success[600]
|
|
708
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
676
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_index4.Text, {
|
|
709
677
|
variant: "body-2-medium",
|
|
710
678
|
numberOfLines: 1,
|
|
711
679
|
style: {
|
|
@@ -744,27 +712,6 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
744
712
|
railChevron: {
|
|
745
713
|
marginLeft: 'auto'
|
|
746
714
|
},
|
|
747
|
-
compactHeader: {
|
|
748
|
-
flexDirection: 'row',
|
|
749
|
-
alignItems: 'center',
|
|
750
|
-
gap: 8,
|
|
751
|
-
height: 56,
|
|
752
|
-
paddingLeft: 16,
|
|
753
|
-
paddingRight: 16,
|
|
754
|
-
borderBottomWidth: 1
|
|
755
|
-
},
|
|
756
|
-
compactBack: {
|
|
757
|
-
width: 32,
|
|
758
|
-
height: 32,
|
|
759
|
-
marginLeft: -8,
|
|
760
|
-
alignItems: 'center',
|
|
761
|
-
justifyContent: 'center',
|
|
762
|
-
borderRadius: 9999
|
|
763
|
-
},
|
|
764
|
-
compactTitle: {
|
|
765
|
-
flex: 1,
|
|
766
|
-
minWidth: 0
|
|
767
|
-
},
|
|
768
715
|
panel: {
|
|
769
716
|
flexDirection: 'row',
|
|
770
717
|
borderRadius: 24,
|
|
@@ -803,33 +750,9 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
803
750
|
flex: 1,
|
|
804
751
|
minWidth: 0
|
|
805
752
|
},
|
|
806
|
-
titleRow: {
|
|
807
|
-
flexDirection: 'row',
|
|
808
|
-
alignItems: 'center',
|
|
809
|
-
justifyContent: 'space-between'
|
|
810
|
-
},
|
|
811
|
-
close: {
|
|
812
|
-
width: 24,
|
|
813
|
-
height: 24,
|
|
814
|
-
borderRadius: 9999,
|
|
815
|
-
alignItems: 'center',
|
|
816
|
-
justifyContent: 'center'
|
|
817
|
-
},
|
|
818
|
-
scrollHost: {
|
|
819
|
-
flex: 1,
|
|
820
|
-
minHeight: 0,
|
|
821
|
-
position: 'relative'
|
|
822
|
-
},
|
|
823
753
|
scroll: {
|
|
824
|
-
flex: 1
|
|
825
|
-
|
|
826
|
-
scrollContent: {},
|
|
827
|
-
fade: {
|
|
828
|
-
position: 'absolute',
|
|
829
|
-
left: 0,
|
|
830
|
-
right: 0,
|
|
831
|
-
top: 0,
|
|
832
|
-
height: 40
|
|
754
|
+
flex: 1,
|
|
755
|
+
minHeight: 0
|
|
833
756
|
},
|
|
834
757
|
toast: {
|
|
835
758
|
position: 'absolute',
|