@hzblj/kara-components 0.2.1 → 0.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/CHANGELOG.md +15 -0
- package/README.md +2 -3
- package/lib/module/molecules/navigation-bar/navigation-bar.android.js +65 -35
- package/lib/module/molecules/navigation-bar/navigation-bar.android.js.map +1 -1
- package/lib/module/molecules/navigation-bar/navigation-bar.ios.js +48 -13
- package/lib/module/molecules/navigation-bar/navigation-bar.ios.js.map +1 -1
- package/lib/module/organisms/sheet/index.js +2 -1
- package/lib/module/organisms/sheet/index.js.map +1 -1
- package/lib/module/organisms/sheet/sheet-header.js +7 -0
- package/lib/module/organisms/sheet/sheet-header.js.map +1 -0
- package/lib/module/organisms/sheet/sheet-scroll.js +62 -0
- package/lib/module/organisms/sheet/sheet-scroll.js.map +1 -0
- package/lib/module/organisms/sheet/sheet.js +136 -0
- package/lib/module/organisms/sheet/sheet.js.map +1 -0
- package/lib/module/organisms/sheet/split-sheet-children.js +21 -0
- package/lib/module/organisms/sheet/split-sheet-children.js.map +1 -0
- package/lib/module/organisms/sheet/use-sheet-header.js +118 -0
- package/lib/module/organisms/sheet/use-sheet-header.js.map +1 -0
- package/lib/typescript/molecules/navigation-bar/navigation-bar.types.d.ts +56 -17
- package/lib/typescript/organisms/sheet/index.d.ts +1 -0
- package/lib/typescript/organisms/sheet/sheet-header.d.ts +3 -0
- package/lib/typescript/organisms/sheet/sheet-scroll.d.ts +9 -0
- package/lib/typescript/organisms/sheet/sheet.d.ts +7 -1
- package/lib/typescript/organisms/sheet/sheet.types.d.ts +86 -3
- package/lib/typescript/organisms/sheet/split-sheet-children.d.ts +9 -0
- package/lib/typescript/organisms/sheet/use-sheet-header.d.ts +24 -0
- package/package.json +6 -4
- package/src/molecules/navigation-bar/navigation-bar.android.tsx +50 -23
- package/src/molecules/navigation-bar/navigation-bar.ios.tsx +54 -15
- package/src/molecules/navigation-bar/navigation-bar.types.ts +56 -17
- package/src/organisms/sheet/index.ts +1 -0
- package/src/organisms/sheet/sheet-header.tsx +6 -0
- package/src/organisms/sheet/sheet-scroll.tsx +69 -0
- package/src/organisms/sheet/sheet.tsx +140 -0
- package/src/organisms/sheet/sheet.types.ts +93 -3
- package/src/organisms/sheet/split-sheet-children.ts +23 -0
- package/src/organisms/sheet/use-sheet-header.tsx +135 -0
- package/lib/module/organisms/sheet/sheet.android.js +0 -26
- package/lib/module/organisms/sheet/sheet.android.js.map +0 -1
- package/lib/module/organisms/sheet/sheet.ios.js +0 -25
- package/lib/module/organisms/sheet/sheet.ios.js.map +0 -1
- package/lib/typescript/organisms/sheet/sheet.ios.d.ts +0 -2
- package/src/organisms/sheet/sheet.android.tsx +0 -25
- package/src/organisms/sheet/sheet.ios.tsx +0 -23
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @hzblj/kara-components
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`f84ffd5`](https://github.com/hzblj/kara-ui/commit/f84ffd52954a5e7052541c8682787137de205a28) Thanks [@hzblj](https://github.com/hzblj)! - Native sheets with a native header. `Sheet` is now a TrueSheet (`@lodev09/react-native-true-sheet`, a new peer dependency) with `<Sheet.Header>` — a real navigation bar with a centred, leading or large title that hands over to the bar as it scrolls away, items on either side, and on iOS 26 the content scrolls under it with the soft edge effect — plus `<Sheet.ScrollView>`, `useSheetScroll`, detents, a footer and a ref (`present`/`dismiss`/`resize`). It is React Native tier now: no host, native atoms inside go in an `Island`. `fitToContents` is replaced by `detents` (`['auto']` by default).
|
|
8
|
+
|
|
9
|
+
`NavigationBar` takes `leadingItems` / `trailingItems` instead of `onBack` / `onClose`: `back`, `close` or an app `icon`, on either side and in any order; on iOS 26 neighbours share a glass capsule unless an item is `separated`. Also `titleAlignment`, `titleVisible`, `inverted` and an iOS `search` field. On Android it is now Material's native top app bar.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [[`f84ffd5`](https://github.com/hzblj/kara-ui/commit/f84ffd52954a5e7052541c8682787137de205a28)]:
|
|
14
|
+
- @hzblj/kara-native@0.3.0
|
|
15
|
+
- @hzblj/kara-theme@0.3.0
|
|
16
|
+
- @hzblj/kara-sx@0.3.0
|
|
17
|
+
|
|
3
18
|
## 0.2.1
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# @hzblj/kara-components
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The components of kara-ui.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
blocks, published so the umbrella can depend on it; it is versioned together with it and has no standalone docs.
|
|
5
|
+
Install [`@hzblj/kara-ui`](https://www.npmjs.com/package/@hzblj/kara-ui) instead — this is one of its building blocks.
|
|
7
6
|
|
|
8
7
|
MIT
|
|
@@ -1,41 +1,71 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { iconResourceName } from '@hzblj/kara-native';
|
|
4
|
+
import { TopAppBar } from '@hzblj/kara-native/jetpack-compose';
|
|
5
|
+
import { useAppTheme } from '@hzblj/kara-theme';
|
|
6
|
+
import { useMemo } from 'react';
|
|
7
|
+
import { StyleSheet } from 'react-native';
|
|
4
8
|
import { Island } from "../../atoms/island/index.js";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
/** Material's small top app bar. */
|
|
11
|
+
const BAR_HEIGHT = 64;
|
|
12
|
+
const styles = StyleSheet.create({
|
|
13
|
+
bar: {
|
|
14
|
+
height: BAR_HEIGHT,
|
|
15
|
+
width: '100%'
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
const DEFAULT_LABELS = {
|
|
19
|
+
back: 'Back',
|
|
20
|
+
close: 'Close'
|
|
21
|
+
};
|
|
22
|
+
const toNativeItem = ({
|
|
23
|
+
onPress,
|
|
24
|
+
testID,
|
|
25
|
+
...item
|
|
26
|
+
}) => item.type === 'icon' ? {
|
|
27
|
+
iconName: iconResourceName(item.icon),
|
|
28
|
+
label: item.label,
|
|
29
|
+
onPress,
|
|
30
|
+
testID,
|
|
31
|
+
type: 'icon'
|
|
32
|
+
} : {
|
|
33
|
+
label: item.label ?? DEFAULT_LABELS[item.type],
|
|
34
|
+
onPress,
|
|
35
|
+
testID,
|
|
36
|
+
type: item.type
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/** Material's top app bar in its own host. `search` is iOS-only for now, and `separated` has no Material counterpart. */
|
|
13
40
|
export const NavigationBar = ({
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
onBack,
|
|
17
|
-
onClose,
|
|
41
|
+
inverted = false,
|
|
42
|
+
leadingItems,
|
|
18
43
|
testID,
|
|
19
|
-
title
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
title,
|
|
45
|
+
titleAlignment = 'center',
|
|
46
|
+
titleVisible = true,
|
|
47
|
+
trailingItems
|
|
48
|
+
}) => {
|
|
49
|
+
const theme = useAppTheme();
|
|
50
|
+
const font = theme.typography.headline;
|
|
51
|
+
const color = theme.color(inverted ? 'content.on.bg' : 'content.primary');
|
|
52
|
+
const nativeLeadingItems = useMemo(() => leadingItems?.map(toNativeItem), [leadingItems]);
|
|
53
|
+
const nativeTrailingItems = useMemo(() => trailingItems?.map(toNativeItem), [trailingItems]);
|
|
54
|
+
return /*#__PURE__*/_jsx(Island, {
|
|
55
|
+
matchContents: false,
|
|
56
|
+
style: styles.bar,
|
|
57
|
+
testID: testID,
|
|
58
|
+
children: /*#__PURE__*/_jsx(TopAppBar, {
|
|
59
|
+
fontFamily: font.fontFamily,
|
|
60
|
+
fontSize: font.fontSize,
|
|
61
|
+
itemColor: color,
|
|
62
|
+
leadingItems: nativeLeadingItems,
|
|
63
|
+
title: title,
|
|
64
|
+
titleAlignment: titleAlignment,
|
|
65
|
+
titleColor: color,
|
|
66
|
+
titleVisible: titleVisible,
|
|
67
|
+
trailingItems: nativeTrailingItems
|
|
68
|
+
})
|
|
69
|
+
});
|
|
70
|
+
};
|
|
41
71
|
//# sourceMappingURL=navigation-bar.android.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["iconResourceName","TopAppBar","useAppTheme","useMemo","StyleSheet","Island","jsx","_jsx","BAR_HEIGHT","styles","create","bar","height","width","DEFAULT_LABELS","back","close","toNativeItem","onPress","testID","item","type","iconName","icon","label","NavigationBar","inverted","leadingItems","title","titleAlignment","titleVisible","trailingItems","theme","font","typography","headline","color","nativeLeadingItems","map","nativeTrailingItems","matchContents","style","children","fontFamily","fontSize","itemColor","titleColor"],"sourceRoot":"../../../../src","sources":["molecules/navigation-bar/navigation-bar.android.tsx"],"mappings":";;AAAA,SAAQA,gBAAgB,QAAO,oBAAoB;AACnD,SAAQC,SAAS,QAA2B,oCAAoC;AAChF,SAAQC,WAAW,QAAO,mBAAmB;AAC7C,SAAQC,OAAO,QAAO,OAAO;AAC7B,SAAQC,UAAU,QAAO,cAAc;AACvC,SAAQC,MAAM,QAAO,6BAAoB;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAGzC;AACA,MAAMC,UAAU,GAAG,EAAE;AAErB,MAAMC,MAAM,GAAGL,UAAU,CAACM,MAAM,CAAC;EAC/BC,GAAG,EAAE;IAACC,MAAM,EAAEJ,UAAU;IAAEK,KAAK,EAAE;EAAM;AACzC,CAAC,CAAC;AAEF,MAAMC,cAAc,GAAG;EAACC,IAAI,EAAE,MAAM;EAAEC,KAAK,EAAE;AAAO,CAAU;AAE9D,MAAMC,YAAY,GAAGA,CAAC;EAACC,OAAO;EAAEC,MAAM;EAAE,GAAGC;AAAuB,CAAC,KACjEA,IAAI,CAACC,IAAI,KAAK,MAAM,GAChB;EAACC,QAAQ,EAAEtB,gBAAgB,CAACoB,IAAI,CAACG,IAAI,CAAC;EAAEC,KAAK,EAAEJ,IAAI,CAACI,KAAK;EAAEN,OAAO;EAAEC,MAAM;EAAEE,IAAI,EAAE;AAAM,CAAC,GACzF;EAACG,KAAK,EAAEJ,IAAI,CAACI,KAAK,IAAIV,cAAc,CAACM,IAAI,CAACC,IAAI,CAAC;EAAEH,OAAO;EAAEC,MAAM;EAAEE,IAAI,EAAED,IAAI,CAACC;AAAI,CAAC;;AAExF;AACA,OAAO,MAAMI,aAAqC,GAAGA,CAAC;EACpDC,QAAQ,GAAG,KAAK;EAChBC,YAAY;EACZR,MAAM;EACNS,KAAK;EACLC,cAAc,GAAG,QAAQ;EACzBC,YAAY,GAAG,IAAI;EACnBC;AACkB,CAAC,KAAK;EACxB,MAAMC,KAAK,GAAG9B,WAAW,CAAC,CAAC;EAC3B,MAAM+B,IAAI,GAAGD,KAAK,CAACE,UAAU,CAACC,QAAQ;EACtC,MAAMC,KAAK,GAAGJ,KAAK,CAACI,KAAK,CAACV,QAAQ,GAAG,eAAe,GAAG,iBAAiB,CAAC;EAEzE,MAAMW,kBAAkB,GAAGlC,OAAO,CAAC,MAAMwB,YAAY,EAAEW,GAAG,CAACrB,YAAY,CAAC,EAAE,CAACU,YAAY,CAAC,CAAC;EACzF,MAAMY,mBAAmB,GAAGpC,OAAO,CAAC,MAAM4B,aAAa,EAAEO,GAAG,CAACrB,YAAY,CAAC,EAAE,CAACc,aAAa,CAAC,CAAC;EAE5F,oBACExB,IAAA,CAACF,MAAM;IAACmC,aAAa,EAAE,KAAM;IAACC,KAAK,EAAEhC,MAAM,CAACE,GAAI;IAACQ,MAAM,EAAEA,MAAO;IAAAuB,QAAA,eAC9DnC,IAAA,CAACN,SAAS;MACR0C,UAAU,EAAEV,IAAI,CAACU,UAAW;MAC5BC,QAAQ,EAAEX,IAAI,CAACW,QAAS;MACxBC,SAAS,EAAET,KAAM;MACjBT,YAAY,EAAEU,kBAAmB;MACjCT,KAAK,EAAEA,KAAM;MACbC,cAAc,EAAEA,cAAe;MAC/BiB,UAAU,EAAEV,KAAM;MAClBN,YAAY,EAAEA,YAAa;MAC3BC,aAAa,EAAEQ;IAAoB,CACpC;EAAC,CACI,CAAC;AAEb,CAAC","ignoreList":[]}
|
|
@@ -1,33 +1,68 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
import { iconResourceName } from '@hzblj/kara-native';
|
|
3
4
|
import { NavigationBar as NativeNavigationBar } from '@hzblj/kara-native/swift-ui';
|
|
4
5
|
import { useAppTheme } from '@hzblj/kara-theme';
|
|
6
|
+
import { useImperativeHandle, useMemo, useRef } from 'react';
|
|
5
7
|
import { StyleSheet } from 'react-native';
|
|
6
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
-
/**
|
|
8
|
-
const BAR_HEIGHT =
|
|
9
|
+
/** Fits iOS 26's 44 pt glass items with the bar's own margin; the bar centres itself vertically in it. */
|
|
10
|
+
const BAR_HEIGHT = 56;
|
|
9
11
|
const styles = StyleSheet.create({
|
|
10
12
|
bar: {
|
|
11
13
|
height: BAR_HEIGHT,
|
|
12
14
|
width: '100%'
|
|
13
15
|
}
|
|
14
16
|
});
|
|
17
|
+
const DEFAULT_LABELS = {
|
|
18
|
+
back: 'Back',
|
|
19
|
+
close: 'Close'
|
|
20
|
+
};
|
|
21
|
+
const toNativeItem = item => item.type === 'icon' ? {
|
|
22
|
+
...item,
|
|
23
|
+
imageName: iconResourceName(item.icon),
|
|
24
|
+
type: 'icon'
|
|
25
|
+
} : {
|
|
26
|
+
...item,
|
|
27
|
+
label: item.label ?? DEFAULT_LABELS[item.type]
|
|
28
|
+
};
|
|
29
|
+
const ignoreDetachedView = () => undefined;
|
|
15
30
|
export const NavigationBar = ({
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
31
|
+
inverted = false,
|
|
32
|
+
leadingItems,
|
|
33
|
+
search,
|
|
34
|
+
testID,
|
|
35
|
+
title,
|
|
36
|
+
titleAlignment = 'center',
|
|
37
|
+
titleVisible = true,
|
|
38
|
+
trailingItems
|
|
19
39
|
}) => {
|
|
20
40
|
const theme = useAppTheme();
|
|
21
|
-
const
|
|
41
|
+
const barRef = useRef(null);
|
|
42
|
+
const font = theme.typography.headline;
|
|
43
|
+
const color = theme.color(inverted ? 'content.on.bg' : 'content.primary');
|
|
44
|
+
useImperativeHandle(search?.ref, () => ({
|
|
45
|
+
clear: () => barRef.current?.clearSearchText().catch(ignoreDetachedView)
|
|
46
|
+
}), []);
|
|
47
|
+
const nativeLeadingItems = useMemo(() => leadingItems?.map(toNativeItem), [leadingItems]);
|
|
48
|
+
const nativeTrailingItems = useMemo(() => trailingItems?.map(toNativeItem), [trailingItems]);
|
|
22
49
|
return /*#__PURE__*/_jsx(NativeNavigationBar, {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
50
|
+
fontFamily: font.fontFamily,
|
|
51
|
+
fontSize: font.fontSize,
|
|
52
|
+
itemColor: color,
|
|
53
|
+
leadingItems: nativeLeadingItems,
|
|
54
|
+
onSearchFocusChange: search?.onFocusChange,
|
|
55
|
+
onSearchTextChange: search?.onChangeText,
|
|
56
|
+
ref: barRef,
|
|
57
|
+
searchPlaceholder: search?.placeholder,
|
|
58
|
+
searchTestID: search?.testID,
|
|
29
59
|
style: styles.bar,
|
|
30
|
-
|
|
60
|
+
testID: testID,
|
|
61
|
+
title: title,
|
|
62
|
+
titleAlignment: titleAlignment,
|
|
63
|
+
titleColor: color,
|
|
64
|
+
titleVisible: titleVisible,
|
|
65
|
+
trailingItems: nativeTrailingItems
|
|
31
66
|
});
|
|
32
67
|
};
|
|
33
68
|
//# sourceMappingURL=navigation-bar.ios.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NavigationBar","NativeNavigationBar","useAppTheme","StyleSheet","jsx","_jsx","BAR_HEIGHT","styles","create","bar","height","width","
|
|
1
|
+
{"version":3,"names":["iconResourceName","NavigationBar","NativeNavigationBar","useAppTheme","useImperativeHandle","useMemo","useRef","StyleSheet","jsx","_jsx","BAR_HEIGHT","styles","create","bar","height","width","DEFAULT_LABELS","back","close","toNativeItem","item","type","imageName","icon","label","ignoreDetachedView","undefined","inverted","leadingItems","search","testID","title","titleAlignment","titleVisible","trailingItems","theme","barRef","font","typography","headline","color","ref","clear","current","clearSearchText","catch","nativeLeadingItems","map","nativeTrailingItems","fontFamily","fontSize","itemColor","onSearchFocusChange","onFocusChange","onSearchTextChange","onChangeText","searchPlaceholder","placeholder","searchTestID","style","titleColor"],"sourceRoot":"../../../../src","sources":["molecules/navigation-bar/navigation-bar.ios.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sourceRoot":"../../../../src","sources":["organisms/sheet/index.ts"],"mappings":";;AAAA,cAAc,
|
|
1
|
+
{"version":3,"names":["useSheetScroll"],"sourceRoot":"../../../../src","sources":["organisms/sheet/index.ts"],"mappings":";;AAAA,cAAc,YAAS;AACvB,cAAc,kBAAe;AAC7B,SAAQA,cAAc,QAAO,mBAAgB","ignoreList":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/** A slot, never rendered: `Sheet` reads its props and builds the header into the native sheet's own header area. */
|
|
4
|
+
export const SheetHeader = _props => {
|
|
5
|
+
throw new Error('[kara-ui] <Sheet.Header> must be a direct child of <Sheet>.');
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=sheet-header.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["SheetHeader","_props","Error"],"sourceRoot":"../../../../src","sources":["organisms/sheet/sheet-header.tsx"],"mappings":";;AAEA;AACA,OAAO,MAAMA,WAAW,GAAIC,MAAwB,IAAY;EAC9D,MAAM,IAAIC,KAAK,CAAC,6DAA6D,CAAC;AAChF,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useSx } from '@hzblj/kara-sx';
|
|
4
|
+
import { createContext, useCallback, useContext, useMemo } from 'react';
|
|
5
|
+
import { ScrollView } from 'react-native';
|
|
6
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
export const SheetScrollContext = /*#__PURE__*/createContext(null);
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* For a scroll view of your own inside a sheet (a `RnFlatList`, say): pad its content by `topInset`, render
|
|
11
|
+
* `largeTitle` first, and forward `onScroll` — which is what `<Sheet.ScrollView>` does.
|
|
12
|
+
*/
|
|
13
|
+
export const useSheetScroll = () => {
|
|
14
|
+
const context = useContext(SheetScrollContext);
|
|
15
|
+
if (context === null) {
|
|
16
|
+
throw new Error('[kara-ui] useSheetScroll and <Sheet.ScrollView> must be used inside <Sheet>.');
|
|
17
|
+
}
|
|
18
|
+
return context;
|
|
19
|
+
};
|
|
20
|
+
const NO_SX = {};
|
|
21
|
+
|
|
22
|
+
/** The sheet's scrolling body: starts below the header on iOS 26, carries a large title, and reports its scroll. */
|
|
23
|
+
export const SheetScrollView = ({
|
|
24
|
+
children,
|
|
25
|
+
content,
|
|
26
|
+
keyboardShouldPersistTaps,
|
|
27
|
+
onScroll,
|
|
28
|
+
testID
|
|
29
|
+
}) => {
|
|
30
|
+
const {
|
|
31
|
+
largeTitle,
|
|
32
|
+
onScroll: onSheetScroll,
|
|
33
|
+
topInset
|
|
34
|
+
} = useSheetScroll();
|
|
35
|
+
const contentStyle = useSx(content ?? NO_SX);
|
|
36
|
+
// The header's room goes on top of the content's own top padding, not in place of it.
|
|
37
|
+
const containerStyle = useMemo(() => {
|
|
38
|
+
if (topInset === 0) {
|
|
39
|
+
return contentStyle;
|
|
40
|
+
}
|
|
41
|
+
const ownTop = typeof contentStyle.paddingTop === 'number' ? contentStyle.paddingTop : 0;
|
|
42
|
+
return [contentStyle, {
|
|
43
|
+
paddingTop: topInset + ownTop
|
|
44
|
+
}];
|
|
45
|
+
}, [contentStyle, topInset]);
|
|
46
|
+
const handleScroll = useCallback(event => {
|
|
47
|
+
onSheetScroll?.(event);
|
|
48
|
+
onScroll?.(event);
|
|
49
|
+
}, [onScroll, onSheetScroll]);
|
|
50
|
+
return /*#__PURE__*/_jsxs(ScrollView, {
|
|
51
|
+
contentContainerStyle: containerStyle,
|
|
52
|
+
contentInsetAdjustmentBehavior: "never",
|
|
53
|
+
keyboardShouldPersistTaps: keyboardShouldPersistTaps,
|
|
54
|
+
nestedScrollEnabled: true,
|
|
55
|
+
onScroll: onSheetScroll || onScroll ? handleScroll : undefined,
|
|
56
|
+
overScrollMode: "always",
|
|
57
|
+
scrollEventThrottle: 16,
|
|
58
|
+
testID: testID,
|
|
59
|
+
children: [largeTitle, children]
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=sheet-scroll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useSx","createContext","useCallback","useContext","useMemo","ScrollView","jsxs","_jsxs","SheetScrollContext","useSheetScroll","context","Error","NO_SX","SheetScrollView","children","content","keyboardShouldPersistTaps","onScroll","testID","largeTitle","onSheetScroll","topInset","contentStyle","containerStyle","ownTop","paddingTop","handleScroll","event","contentContainerStyle","contentInsetAdjustmentBehavior","nestedScrollEnabled","undefined","overScrollMode","scrollEventThrottle"],"sourceRoot":"../../../../src","sources":["organisms/sheet/sheet-scroll.tsx"],"mappings":";;AAAA,SAAQA,KAAK,QAAO,gBAAgB;AACpC,SAAQC,aAAa,EAAEC,WAAW,EAAEC,UAAU,EAAEC,OAAO,QAAO,OAAO;AACrE,SAAQC,UAAU,QAAO,cAAc;AAAA,SAAAC,IAAA,IAAAC,KAAA;AAIvC,OAAO,MAAMC,kBAAkB,gBAAGP,aAAa,CAAiC,IAAI,CAAC;;AAErF;AACA;AACA;AACA;AACA,OAAO,MAAMQ,cAAc,GAAGA,CAAA,KAA+B;EAC3D,MAAMC,OAAO,GAAGP,UAAU,CAACK,kBAAkB,CAAC;EAE9C,IAAIE,OAAO,KAAK,IAAI,EAAE;IACpB,MAAM,IAAIC,KAAK,CAAC,8EAA8E,CAAC;EACjG;EAEA,OAAOD,OAAO;AAChB,CAAC;AAED,MAAME,KAAK,GAAG,CAAC,CAAC;;AAEhB;AACA,OAAO,MAAMC,eAAe,GAAGA,CAAC;EAC9BC,QAAQ;EACRC,OAAO;EACPC,yBAAyB;EACzBC,QAAQ;EACRC;AACoB,CAAC,KAAK;EAC1B,MAAM;IAACC,UAAU;IAAEF,QAAQ,EAAEG,aAAa;IAAEC;EAAQ,CAAC,GAAGZ,cAAc,CAAC,CAAC;EACxE,MAAMa,YAAY,GAAGtB,KAAK,CAACe,OAAO,IAAIH,KAAK,CAAC;EAC5C;EACA,MAAMW,cAAc,GAAGnB,OAAO,CAAC,MAAM;IACnC,IAAIiB,QAAQ,KAAK,CAAC,EAAE;MAClB,OAAOC,YAAY;IACrB;IAEA,MAAME,MAAM,GAAG,OAAOF,YAAY,CAACG,UAAU,KAAK,QAAQ,GAAGH,YAAY,CAACG,UAAU,GAAG,CAAC;IAExF,OAAO,CAACH,YAAY,EAAE;MAACG,UAAU,EAAEJ,QAAQ,GAAGG;IAAM,CAAC,CAAC;EACxD,CAAC,EAAE,CAACF,YAAY,EAAED,QAAQ,CAAC,CAAC;EAE5B,MAAMK,YAAY,GAAGxB,WAAW,CAC9ByB,KAAK,IAAI;IACPP,aAAa,GAAGO,KAAK,CAAC;IACtBV,QAAQ,GAAGU,KAAK,CAAC;EACnB,CAAC,EACD,CAACV,QAAQ,EAAEG,aAAa,CAC1B,CAAC;EAED,oBACEb,KAAA,CAACF,UAAU;IACTuB,qBAAqB,EAAEL,cAAe;IACtCM,8BAA8B,EAAC,OAAO;IACtCb,yBAAyB,EAAEA,yBAA0B;IACrDc,mBAAmB;IACnBb,QAAQ,EAAEG,aAAa,IAAIH,QAAQ,GAAGS,YAAY,GAAGK,SAAU;IAC/DC,cAAc,EAAC,QAAQ;IACvBC,mBAAmB,EAAE,EAAG;IACxBf,MAAM,EAAEA,MAAO;IAAAJ,QAAA,GAEdK,UAAU,EACVL,QAAQ;EAAA,CACC,CAAC;AAEjB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useAppTheme } from '@hzblj/kara-theme';
|
|
4
|
+
import { TrueSheet } from '@lodev09/react-native-true-sheet';
|
|
5
|
+
import { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef } from 'react';
|
|
6
|
+
import { Platform, StyleSheet, View } from 'react-native';
|
|
7
|
+
import { SheetHeader } from "./sheet-header.js";
|
|
8
|
+
import { SheetScrollContext, SheetScrollView } from "./sheet-scroll.js";
|
|
9
|
+
import { splitSheetChildren } from "./split-sheet-children.js";
|
|
10
|
+
import { useSheetHeader } from "./use-sheet-header.js";
|
|
11
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
const FIT_CONTENT = ['auto'];
|
|
13
|
+
|
|
14
|
+
/** Material's extra-large shape for a bottom sheet; iOS keeps the system's own, which follows the device's corners. */
|
|
15
|
+
const CORNER_RADIUS = Platform.OS === 'android' ? 28 : undefined;
|
|
16
|
+
|
|
17
|
+
/** Keeps the sheet's own native view out of the layout it is declared in. */
|
|
18
|
+
const styles = StyleSheet.create({
|
|
19
|
+
host: {
|
|
20
|
+
position: 'absolute'
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const SheetRoot = ({
|
|
24
|
+
bg = 'surface.primary',
|
|
25
|
+
children,
|
|
26
|
+
detents = FIT_CONTENT,
|
|
27
|
+
dimmed = true,
|
|
28
|
+
dismissible = true,
|
|
29
|
+
draggable = true,
|
|
30
|
+
footer,
|
|
31
|
+
grabber = true,
|
|
32
|
+
onDetentChange,
|
|
33
|
+
onDismiss,
|
|
34
|
+
onPresent,
|
|
35
|
+
ref,
|
|
36
|
+
scrollable = false,
|
|
37
|
+
testID,
|
|
38
|
+
visible
|
|
39
|
+
}) => {
|
|
40
|
+
const theme = useAppTheme();
|
|
41
|
+
const {
|
|
42
|
+
content,
|
|
43
|
+
header: headerProps
|
|
44
|
+
} = useMemo(() => splitSheetChildren(children), [children]);
|
|
45
|
+
const sheetHeader = useSheetHeader({
|
|
46
|
+
header: headerProps,
|
|
47
|
+
scrollable
|
|
48
|
+
});
|
|
49
|
+
const sheetRef = useRef(null);
|
|
50
|
+
const presented = useRef(false);
|
|
51
|
+
/** A dismissal we asked for: `onDismiss` reports the user's, never ours. */
|
|
52
|
+
const programmaticDismiss = useRef(false);
|
|
53
|
+
useImperativeHandle(ref, () => ({
|
|
54
|
+
dismiss: () => {
|
|
55
|
+
presented.current = false;
|
|
56
|
+
programmaticDismiss.current = true;
|
|
57
|
+
return sheetRef.current?.dismiss() ?? Promise.resolve();
|
|
58
|
+
},
|
|
59
|
+
present: detentIndex => {
|
|
60
|
+
presented.current = true;
|
|
61
|
+
return sheetRef.current?.present(detentIndex) ?? Promise.resolve();
|
|
62
|
+
},
|
|
63
|
+
resize: detentIndex => sheetRef.current?.resize(detentIndex) ?? Promise.resolve()
|
|
64
|
+
}), []);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (visible && !presented.current) {
|
|
67
|
+
presented.current = true;
|
|
68
|
+
void sheetRef.current?.present();
|
|
69
|
+
} else if (!visible && presented.current) {
|
|
70
|
+
presented.current = false;
|
|
71
|
+
programmaticDismiss.current = true;
|
|
72
|
+
void sheetRef.current?.dismiss();
|
|
73
|
+
}
|
|
74
|
+
}, [visible]);
|
|
75
|
+
|
|
76
|
+
// A sheet unmounted while presented would otherwise stay on screen, blocking everything under it.
|
|
77
|
+
useLayoutEffect(() => {
|
|
78
|
+
const sheet = sheetRef.current;
|
|
79
|
+
return () => {
|
|
80
|
+
if (!presented.current) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
presented.current = false;
|
|
84
|
+
programmaticDismiss.current = true;
|
|
85
|
+
void sheet?.dismiss();
|
|
86
|
+
};
|
|
87
|
+
}, []);
|
|
88
|
+
const handleDidDismiss = useCallback(() => {
|
|
89
|
+
presented.current = false;
|
|
90
|
+
if (programmaticDismiss.current) {
|
|
91
|
+
programmaticDismiss.current = false;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
onDismiss();
|
|
95
|
+
}, [onDismiss]);
|
|
96
|
+
const handleDetentChange = useCallback(event => onDetentChange?.(event.nativeEvent.index), [onDetentChange]);
|
|
97
|
+
return /*#__PURE__*/_jsx(View, {
|
|
98
|
+
collapsable: false,
|
|
99
|
+
pointerEvents: "box-none",
|
|
100
|
+
style: styles.host,
|
|
101
|
+
children: /*#__PURE__*/_jsx(TrueSheet, {
|
|
102
|
+
backgroundColor: theme.color(bg),
|
|
103
|
+
cornerRadius: CORNER_RADIUS,
|
|
104
|
+
detents: detents,
|
|
105
|
+
dimmed: dimmed,
|
|
106
|
+
dismissible: dismissible,
|
|
107
|
+
draggable: draggable,
|
|
108
|
+
footer: footer,
|
|
109
|
+
grabber: grabber,
|
|
110
|
+
header: sheetHeader.header,
|
|
111
|
+
headerStyle: sheetHeader.headerStyle,
|
|
112
|
+
onDetentChange: handleDetentChange,
|
|
113
|
+
onDidDismiss: handleDidDismiss,
|
|
114
|
+
onDidPresent: onPresent,
|
|
115
|
+
ref: sheetRef,
|
|
116
|
+
scrollable: scrollable,
|
|
117
|
+
scrollableOptions: sheetHeader.scrollableOptions,
|
|
118
|
+
testID: testID,
|
|
119
|
+
children: /*#__PURE__*/_jsxs(SheetScrollContext.Provider, {
|
|
120
|
+
value: sheetHeader.scrollContext,
|
|
121
|
+
children: [sheetHeader.staticLargeTitle, content]
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* A native sheet with an optional native header. `visible` presents and dismisses it; a swipe or a tap outside calls
|
|
129
|
+
* `onDismiss`, which should set `visible` back. `<Sheet.Header>` (a direct child) gives it a bar with a title and
|
|
130
|
+
* items; `<Sheet.ScrollView>` is the body of a `scrollable` sheet.
|
|
131
|
+
*/
|
|
132
|
+
export const Sheet = Object.assign(SheetRoot, {
|
|
133
|
+
Header: SheetHeader,
|
|
134
|
+
ScrollView: SheetScrollView
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=sheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useAppTheme","TrueSheet","useCallback","useEffect","useImperativeHandle","useLayoutEffect","useMemo","useRef","Platform","StyleSheet","View","SheetHeader","SheetScrollContext","SheetScrollView","splitSheetChildren","useSheetHeader","jsxs","_jsxs","jsx","_jsx","FIT_CONTENT","CORNER_RADIUS","OS","undefined","styles","create","host","position","SheetRoot","bg","children","detents","dimmed","dismissible","draggable","footer","grabber","onDetentChange","onDismiss","onPresent","ref","scrollable","testID","visible","theme","content","header","headerProps","sheetHeader","sheetRef","presented","programmaticDismiss","dismiss","current","Promise","resolve","present","detentIndex","resize","sheet","handleDidDismiss","handleDetentChange","event","nativeEvent","index","collapsable","pointerEvents","style","backgroundColor","color","cornerRadius","headerStyle","onDidDismiss","onDidPresent","scrollableOptions","Provider","value","scrollContext","staticLargeTitle","Sheet","Object","assign","Header","ScrollView"],"sourceRoot":"../../../../src","sources":["organisms/sheet/sheet.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Children, isValidElement } from 'react';
|
|
4
|
+
import { SheetHeader } from "./sheet-header.js";
|
|
5
|
+
const isSheetHeader = child => /*#__PURE__*/isValidElement(child) && child.type === SheetHeader;
|
|
6
|
+
|
|
7
|
+
/** Takes `<Sheet.Header>` out of the children: its props become the native header, the rest is the content. */
|
|
8
|
+
export const splitSheetChildren = children => {
|
|
9
|
+
const nodes = Children.toArray(children);
|
|
10
|
+
const header = nodes.find(isSheetHeader);
|
|
11
|
+
if (!header) {
|
|
12
|
+
return {
|
|
13
|
+
content: children
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
content: nodes.filter(node => node !== header),
|
|
18
|
+
header: header.props
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=split-sheet-children.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Children","isValidElement","SheetHeader","isSheetHeader","child","type","splitSheetChildren","children","nodes","toArray","header","find","content","filter","node","props"],"sourceRoot":"../../../../src","sources":["organisms/sheet/split-sheet-children.ts"],"mappings":";;AAAA,SAAQA,QAAQ,EAAEC,cAAc,QAA0C,OAAO;AAEjF,SAAQC,WAAW,QAAO,mBAAgB;AAO1C,MAAMC,aAAa,GAAIC,KAAgB,IACrC,aAAAH,cAAc,CAACG,KAAK,CAAC,IAAIA,KAAK,CAACC,IAAI,KAAKH,WAAW;;AAErD;AACA,OAAO,MAAMI,kBAAkB,GAAIC,QAAmB,IAAoB;EACxE,MAAMC,KAAK,GAAGR,QAAQ,CAACS,OAAO,CAACF,QAAQ,CAAC;EACxC,MAAMG,MAAM,GAAGF,KAAK,CAACG,IAAI,CAACR,aAAa,CAAC;EAExC,IAAI,CAACO,MAAM,EAAE;IACX,OAAO;MAACE,OAAO,EAAEL;IAAQ,CAAC;EAC5B;EAEA,OAAO;IAACK,OAAO,EAAEJ,KAAK,CAACK,MAAM,CAACC,IAAI,IAAIA,IAAI,KAAKJ,MAAM,CAAC;IAAEA,MAAM,EAAEA,MAAM,CAACK;EAAK,CAAC;AAC/E,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { isScrollEdgeEffectAvailable } from '@hzblj/kara-native';
|
|
4
|
+
import { spacing } from '@hzblj/kara-theme';
|
|
5
|
+
import { useCallback, useMemo, useRef, useState } from 'react';
|
|
6
|
+
import { Platform } from 'react-native';
|
|
7
|
+
import { Box } from "../../atoms/box/index.js";
|
|
8
|
+
import { RnText } from "../../atoms/rn-text/index.js";
|
|
9
|
+
import { NavigationBar } from "../../molecules/navigation-bar/index.js";
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
/** The bar's own height (`NavigationBar`) plus the room above it, before the header has been measured. */
|
|
12
|
+
const ESTIMATED_HEADER_HEIGHT = (Platform.OS === 'ios' ? 56 : 64) + spacing.s16;
|
|
13
|
+
|
|
14
|
+
/** Where a large title's bar title appears once it has scrolled away: the platform's own place for it. */
|
|
15
|
+
const COLLAPSED_TITLE_ALIGNMENT = Platform.OS === 'ios' ? 'center' : 'leading';
|
|
16
|
+
|
|
17
|
+
/** Lays the header over the content so the content can scroll under it — the edge effect needs it there. */
|
|
18
|
+
const OVERLAY_HEADER_STYLE = {
|
|
19
|
+
left: 0,
|
|
20
|
+
position: 'absolute',
|
|
21
|
+
right: 0,
|
|
22
|
+
top: 0,
|
|
23
|
+
zIndex: 1
|
|
24
|
+
};
|
|
25
|
+
const SOFT_EDGE_EFFECTS = {
|
|
26
|
+
bottomScrollEdgeEffect: 'soft',
|
|
27
|
+
topScrollEdgeEffect: 'soft'
|
|
28
|
+
};
|
|
29
|
+
const SheetLargeTitle = ({
|
|
30
|
+
onLayout,
|
|
31
|
+
title
|
|
32
|
+
}) => /*#__PURE__*/_jsx(Box, {
|
|
33
|
+
onLayout: onLayout,
|
|
34
|
+
pb: "s8",
|
|
35
|
+
pt: "s8",
|
|
36
|
+
px: "s16",
|
|
37
|
+
children: /*#__PURE__*/_jsx(RnText, {
|
|
38
|
+
accessibilityRole: "header",
|
|
39
|
+
variant: "headingM",
|
|
40
|
+
children: title
|
|
41
|
+
})
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Turns `<Sheet.Header>`'s props into what the native sheet takes: its header element, how that is laid out, the scroll
|
|
46
|
+
* edge effects, and the context a `<Sheet.ScrollView>` reads. On iOS 26 a scrollable sheet's header is laid over the
|
|
47
|
+
* content (which is then inset by the header's measured height) so the system's soft edge blurs what scrolls under it;
|
|
48
|
+
* everywhere else the header simply sits above the content.
|
|
49
|
+
*/
|
|
50
|
+
export const useSheetHeader = ({
|
|
51
|
+
header: headerProps,
|
|
52
|
+
scrollable
|
|
53
|
+
}) => {
|
|
54
|
+
const title = headerProps?.title;
|
|
55
|
+
const titleStyle = headerProps?.titleStyle ?? 'center';
|
|
56
|
+
const leadingItems = headerProps?.leadingItems;
|
|
57
|
+
const trailingItems = headerProps?.trailingItems;
|
|
58
|
+
const inverted = headerProps?.inverted;
|
|
59
|
+
const search = headerProps?.search;
|
|
60
|
+
const accessory = headerProps?.children;
|
|
61
|
+
const hasBar = title !== undefined || !!leadingItems?.length || !!trailingItems?.length || !!search;
|
|
62
|
+
const hasHeader = hasBar || !!accessory;
|
|
63
|
+
const isOverlay = isScrollEdgeEffectAvailable() && hasHeader && scrollable;
|
|
64
|
+
const isLargeTitle = titleStyle === 'large' && !!title;
|
|
65
|
+
const [headerHeight, setHeaderHeight] = useState(hasBar ? ESTIMATED_HEADER_HEIGHT : 0);
|
|
66
|
+
const [largeTitleScrolledAway, setLargeTitleScrolledAway] = useState(false);
|
|
67
|
+
const largeTitleHeight = useRef(0);
|
|
68
|
+
const handleHeaderLayout = useCallback(event => {
|
|
69
|
+
setHeaderHeight(event.nativeEvent.layout.height);
|
|
70
|
+
}, []);
|
|
71
|
+
const handleLargeTitleLayout = useCallback(event => {
|
|
72
|
+
largeTitleHeight.current = event.nativeEvent.layout.height;
|
|
73
|
+
}, []);
|
|
74
|
+
const handleScroll = useCallback(event => {
|
|
75
|
+
if (largeTitleHeight.current === 0) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
setLargeTitleScrolledAway(event.nativeEvent.contentOffset.y >= largeTitleHeight.current);
|
|
79
|
+
}, []);
|
|
80
|
+
const titleAlignment = titleStyle === 'large' ? COLLAPSED_TITLE_ALIGNMENT : titleStyle;
|
|
81
|
+
const titleVisible = !isLargeTitle || scrollable && largeTitleScrolledAway;
|
|
82
|
+
const headerElement = useMemo(() => {
|
|
83
|
+
if (!hasHeader) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
return /*#__PURE__*/_jsxs(Box, {
|
|
87
|
+
onLayout: isOverlay ? handleHeaderLayout : undefined,
|
|
88
|
+
pt: "s16",
|
|
89
|
+
children: [hasBar ? /*#__PURE__*/_jsx(NavigationBar, {
|
|
90
|
+
inverted: inverted,
|
|
91
|
+
leadingItems: leadingItems,
|
|
92
|
+
search: search,
|
|
93
|
+
title: title,
|
|
94
|
+
titleAlignment: titleAlignment,
|
|
95
|
+
titleVisible: titleVisible,
|
|
96
|
+
trailingItems: trailingItems
|
|
97
|
+
}) : null, accessory]
|
|
98
|
+
});
|
|
99
|
+
}, [accessory, handleHeaderLayout, hasBar, hasHeader, inverted, isOverlay, leadingItems, search, title, titleAlignment, titleVisible, trailingItems]);
|
|
100
|
+
const largeTitle = useMemo(() => title && isLargeTitle ? /*#__PURE__*/_jsx(SheetLargeTitle, {
|
|
101
|
+
onLayout: handleLargeTitleLayout,
|
|
102
|
+
title: title
|
|
103
|
+
}) : null, [handleLargeTitleLayout, isLargeTitle, title]);
|
|
104
|
+
const scrollContext = useMemo(() => ({
|
|
105
|
+
largeTitle: scrollable ? largeTitle : null,
|
|
106
|
+
onScroll: scrollable && isLargeTitle ? handleScroll : undefined,
|
|
107
|
+
topInset: isOverlay ? headerHeight : 0
|
|
108
|
+
}), [handleScroll, headerHeight, isLargeTitle, isOverlay, largeTitle, scrollable]);
|
|
109
|
+
return {
|
|
110
|
+
header: headerElement,
|
|
111
|
+
headerStyle: isOverlay ? OVERLAY_HEADER_STYLE : undefined,
|
|
112
|
+
scrollableOptions: isOverlay ? SOFT_EDGE_EFFECTS : undefined,
|
|
113
|
+
scrollContext,
|
|
114
|
+
/** Without a scroll view to carry it, a large title simply leads the content. */
|
|
115
|
+
staticLargeTitle: scrollable ? null : largeTitle
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
//# sourceMappingURL=use-sheet-header.js.map
|