@hzblj/kara-components 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +2 -3
- package/lib/module/atoms/h-stack/h-stack.android.js +2 -5
- package/lib/module/atoms/h-stack/h-stack.android.js.map +1 -1
- package/lib/module/atoms/v-stack/v-stack.android.js +2 -5
- package/lib/module/atoms/v-stack/v-stack.android.js.map +1 -1
- package/lib/module/atoms/z-stack/z-stack.android.js +2 -5
- package/lib/module/atoms/z-stack/z-stack.android.js.map +1 -1
- package/lib/module/molecules/index.js +1 -0
- package/lib/module/molecules/index.js.map +1 -1
- package/lib/module/molecules/labeled-content/labeled-content.js +2 -0
- package/lib/module/molecules/labeled-content/labeled-content.js.map +1 -1
- package/lib/module/molecules/list-item/list-item.js +12 -1
- package/lib/module/molecules/list-item/list-item.js.map +1 -1
- 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/molecules/rn-list-item/index.js +5 -0
- package/lib/module/molecules/rn-list-item/index.js.map +1 -0
- package/lib/module/molecules/rn-list-item/rn-list-item.js +71 -0
- package/lib/module/molecules/rn-list-item/rn-list-item.js.map +1 -0
- package/lib/module/molecules/rn-list-item/rn-list-item.types.js +4 -0
- package/lib/module/molecules/rn-list-item/rn-list-item.types.js.map +1 -0
- package/lib/module/organisms/context-menu/context-menu.android.js +83 -38
- package/lib/module/organisms/context-menu/context-menu.android.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/module/ripple-clip.js +36 -0
- package/lib/module/ripple-clip.js.map +1 -0
- package/lib/module/use-stack-modifiers.js +35 -0
- package/lib/module/use-stack-modifiers.js.map +1 -0
- package/lib/typescript/molecules/index.d.ts +1 -0
- package/lib/typescript/molecules/labeled-content/labeled-content.types.d.ts +3 -0
- package/lib/typescript/molecules/list-item/list-item.types.d.ts +6 -0
- package/lib/typescript/molecules/navigation-bar/navigation-bar.types.d.ts +56 -17
- package/lib/typescript/molecules/rn-list-item/index.d.ts +2 -0
- package/lib/typescript/molecules/rn-list-item/rn-list-item.d.ts +2 -0
- package/lib/typescript/molecules/rn-list-item/rn-list-item.types.d.ts +10 -0
- package/lib/typescript/organisms/context-menu/context-menu.types.d.ts +2 -1
- 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/lib/typescript/ripple-clip.d.ts +12 -0
- package/lib/typescript/use-stack-modifiers.d.ts +8 -0
- package/package.json +6 -4
- package/src/atoms/h-stack/h-stack.android.tsx +2 -8
- package/src/atoms/v-stack/v-stack.android.tsx +2 -8
- package/src/atoms/z-stack/z-stack.android.tsx +2 -8
- package/src/molecules/index.ts +1 -0
- package/src/molecules/labeled-content/labeled-content.tsx +2 -1
- package/src/molecules/labeled-content/labeled-content.types.ts +3 -0
- package/src/molecules/list-item/list-item.tsx +12 -4
- package/src/molecules/list-item/list-item.types.ts +6 -0
- 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/molecules/rn-list-item/index.ts +2 -0
- package/src/molecules/rn-list-item/rn-list-item.tsx +48 -0
- package/src/molecules/rn-list-item/rn-list-item.types.ts +13 -0
- package/src/organisms/context-menu/context-menu.android.tsx +63 -38
- package/src/organisms/context-menu/context-menu.types.ts +2 -1
- 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/src/ripple-clip.ts +47 -0
- package/src/use-stack-modifiers.ts +24 -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
|
@@ -3,18 +3,17 @@
|
|
|
3
3
|
import { Text as ComposeText, DropdownMenu, DropdownMenuItem, Host } from '@expo/ui/jetpack-compose';
|
|
4
4
|
import { useSx } from '@hzblj/kara-sx';
|
|
5
5
|
import { useAppTheme } from '@hzblj/kara-theme';
|
|
6
|
-
import
|
|
6
|
+
import * as Haptics from 'expo-haptics';
|
|
7
|
+
import { useCallback, useMemo, useRef, useState } from 'react';
|
|
7
8
|
import { Pressable, StyleSheet, View } from 'react-native';
|
|
9
|
+
import { Icon } from "../../atoms/icon/index.js";
|
|
10
|
+
import { HostBoundary } from "../../host-context.js";
|
|
11
|
+
import { splitForRipple } from "../../ripple-clip.js";
|
|
8
12
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
-
/**
|
|
10
|
-
* The menu's anchor: a point at the trigger's bottom start, so the dropdown opens just under it. The host lies outside
|
|
11
|
-
* the touch path — the dropdown is a popup window of its own, which takes its touches regardless.
|
|
12
|
-
*/
|
|
13
13
|
const styles = StyleSheet.create({
|
|
14
|
+
/** A point under the finger: the dropdown opens from it. The menu is a popup window, so nothing clips it. */
|
|
14
15
|
anchor: {
|
|
15
|
-
bottom: 0,
|
|
16
16
|
height: 1,
|
|
17
|
-
left: 0,
|
|
18
17
|
position: 'absolute',
|
|
19
18
|
width: 1
|
|
20
19
|
}
|
|
@@ -25,26 +24,34 @@ const MenuRow = ({
|
|
|
25
24
|
onDismiss
|
|
26
25
|
}) => {
|
|
27
26
|
const theme = useAppTheme();
|
|
27
|
+
const color = action.destructive ? 'content.destructive' : 'content.primary';
|
|
28
28
|
const onClick = useCallback(() => {
|
|
29
29
|
onDismiss();
|
|
30
30
|
action.onPress();
|
|
31
31
|
}, [action, onDismiss]);
|
|
32
|
-
return /*#__PURE__*/
|
|
32
|
+
return /*#__PURE__*/_jsxs(DropdownMenuItem, {
|
|
33
33
|
onClick: onClick,
|
|
34
|
-
children: /*#__PURE__*/_jsx(DropdownMenuItem.Text, {
|
|
34
|
+
children: [/*#__PURE__*/_jsx(DropdownMenuItem.Text, {
|
|
35
35
|
children: /*#__PURE__*/_jsx(ComposeText, {
|
|
36
|
-
color: theme.colorString(
|
|
36
|
+
color: theme.colorString(color),
|
|
37
37
|
style: theme.typography.body,
|
|
38
38
|
children: action.label
|
|
39
39
|
})
|
|
40
|
-
})
|
|
40
|
+
}), action.icon ? /*#__PURE__*/_jsx(DropdownMenuItem.LeadingIcon, {
|
|
41
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
42
|
+
color: color,
|
|
43
|
+
name: action.icon,
|
|
44
|
+
size: "s20"
|
|
45
|
+
})
|
|
46
|
+
}) : null]
|
|
41
47
|
});
|
|
42
48
|
};
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
51
|
+
* Android's own take on a context menu, since Material has no lifted preview: a long press ripples the trigger, ticks
|
|
52
|
+
* the long-press haptic, and opens a Material dropdown where the finger is — the trigger stays highlighted while the
|
|
53
|
+
* menu is up. The host behind the menu mounts on the first long press and stays, so a list of triggers that are only
|
|
54
|
+
* scrolled past never builds one. `preview` and `onPreviewPress` are iOS-only.
|
|
48
55
|
*/
|
|
49
56
|
const ContextMenuRoot = ({
|
|
50
57
|
actions,
|
|
@@ -58,34 +65,72 @@ const ContextMenuRoot = ({
|
|
|
58
65
|
...sx
|
|
59
66
|
} = props;
|
|
60
67
|
const theme = useAppTheme();
|
|
61
|
-
const
|
|
62
|
-
const
|
|
68
|
+
const resolved = useSx(sx);
|
|
69
|
+
const trigger = useRef(null);
|
|
70
|
+
const [anchor, setAnchor] = useState(null);
|
|
63
71
|
const [expanded, setExpanded] = useState(false);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
|
|
73
|
+
// The shape clips on an outer view, so the ripple and the highlight follow the trigger's rounded corners.
|
|
74
|
+
const {
|
|
75
|
+
inner,
|
|
76
|
+
outer
|
|
77
|
+
} = useMemo(() => splitForRipple(resolved), [resolved]);
|
|
78
|
+
const ripple = useMemo(() => ({
|
|
79
|
+
color: theme.color('fill.tertiary')
|
|
80
|
+
}), [theme]);
|
|
81
|
+
const highlight = useMemo(() => ({
|
|
82
|
+
backgroundColor: theme.color('fill.tertiary')
|
|
83
|
+
}), [theme]);
|
|
84
|
+
const open = useCallback(event => {
|
|
85
|
+
const {
|
|
86
|
+
pageX,
|
|
87
|
+
pageY
|
|
88
|
+
} = event.nativeEvent;
|
|
89
|
+
Haptics.performAndroidHapticsAsync(Haptics.AndroidHaptics.Long_Press).catch(() => undefined);
|
|
90
|
+
// The touch in the trigger's own coordinates: `locationX/Y` are relative to whichever child was touched.
|
|
91
|
+
trigger.current?.measure((_x, _y, _width, _height, left, top) => {
|
|
92
|
+
setAnchor({
|
|
93
|
+
x: pageX - left,
|
|
94
|
+
y: pageY - top
|
|
95
|
+
});
|
|
96
|
+
setExpanded(true);
|
|
97
|
+
});
|
|
67
98
|
}, []);
|
|
68
99
|
const dismiss = useCallback(() => setExpanded(false), []);
|
|
69
|
-
return /*#__PURE__*/
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
100
|
+
return /*#__PURE__*/_jsx(View, {
|
|
101
|
+
style: outer,
|
|
102
|
+
children: /*#__PURE__*/_jsxs(Pressable, {
|
|
103
|
+
android_ripple: ripple,
|
|
104
|
+
onLongPress: open,
|
|
105
|
+
ref: trigger,
|
|
106
|
+
style: inner,
|
|
107
|
+
testID: testID,
|
|
108
|
+
children: [expanded ? /*#__PURE__*/_jsx(View, {
|
|
109
|
+
pointerEvents: "none",
|
|
110
|
+
style: [StyleSheet.absoluteFill, highlight]
|
|
111
|
+
}) : null, children, anchor ? /*#__PURE__*/_jsx(Host, {
|
|
112
|
+
colorScheme: theme.dark ? 'dark' : 'light',
|
|
113
|
+
pointerEvents: "none",
|
|
114
|
+
seedColor: theme.materialSeed,
|
|
115
|
+
style: [styles.anchor, {
|
|
116
|
+
left: anchor.x,
|
|
117
|
+
top: anchor.y
|
|
118
|
+
}],
|
|
119
|
+
children: /*#__PURE__*/_jsx(HostBoundary, {
|
|
120
|
+
children: /*#__PURE__*/_jsx(DropdownMenu, {
|
|
121
|
+
color: theme.color('surface.primary'),
|
|
122
|
+
expanded: expanded,
|
|
123
|
+
onDismissRequest: dismiss,
|
|
124
|
+
children: /*#__PURE__*/_jsx(DropdownMenu.Items, {
|
|
125
|
+
children: actions.map(action => /*#__PURE__*/_jsx(MenuRow, {
|
|
126
|
+
action: action,
|
|
127
|
+
onDismiss: dismiss
|
|
128
|
+
}, action.label))
|
|
129
|
+
})
|
|
130
|
+
})
|
|
86
131
|
})
|
|
87
|
-
})
|
|
88
|
-
})
|
|
132
|
+
}) : null]
|
|
133
|
+
})
|
|
89
134
|
});
|
|
90
135
|
};
|
|
91
136
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Text","ComposeText","DropdownMenu","DropdownMenuItem","Host","useSx","useAppTheme","useCallback","useState","Pressable","StyleSheet","View","jsx","_jsx","jsxs","_jsxs","styles","create","anchor","
|
|
1
|
+
{"version":3,"names":["Text","ComposeText","DropdownMenu","DropdownMenuItem","Host","useSx","useAppTheme","Haptics","useCallback","useMemo","useRef","useState","Pressable","StyleSheet","View","Icon","HostBoundary","splitForRipple","jsx","_jsx","jsxs","_jsxs","styles","create","anchor","height","position","width","MenuRow","action","onDismiss","theme","color","destructive","onClick","onPress","children","colorString","style","typography","body","label","icon","LeadingIcon","name","size","ContextMenuRoot","actions","testID","props","onPreviewPress","_onPreviewPress","preview","_preview","sx","resolved","trigger","setAnchor","expanded","setExpanded","inner","outer","ripple","highlight","backgroundColor","open","event","pageX","pageY","nativeEvent","performAndroidHapticsAsync","AndroidHaptics","Long_Press","catch","undefined","current","measure","_x","_y","_width","_height","left","top","x","y","dismiss","android_ripple","onLongPress","ref","pointerEvents","absoluteFill","colorScheme","dark","seedColor","materialSeed","onDismissRequest","Items","map","Exclusion","ContextMenu","Object","assign"],"sourceRoot":"../../../../src","sources":["organisms/context-menu/context-menu.android.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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["isScrollEdgeEffectAvailable","spacing","useCallback","useMemo","useRef","useState","Platform","Box","RnText","NavigationBar","jsx","_jsx","jsxs","_jsxs","ESTIMATED_HEADER_HEIGHT","OS","s16","COLLAPSED_TITLE_ALIGNMENT","OVERLAY_HEADER_STYLE","left","position","right","top","zIndex","SOFT_EDGE_EFFECTS","bottomScrollEdgeEffect","topScrollEdgeEffect","SheetLargeTitle","onLayout","title","pb","pt","px","children","accessibilityRole","variant","useSheetHeader","header","headerProps","scrollable","titleStyle","leadingItems","trailingItems","inverted","search","accessory","hasBar","undefined","length","hasHeader","isOverlay","isLargeTitle","headerHeight","setHeaderHeight","largeTitleScrolledAway","setLargeTitleScrolledAway","largeTitleHeight","handleHeaderLayout","event","nativeEvent","layout","height","handleLargeTitleLayout","current","handleScroll","contentOffset","y","titleAlignment","titleVisible","headerElement","largeTitle","scrollContext","onScroll","topInset","headerStyle","scrollableOptions","staticLargeTitle"],"sourceRoot":"../../../../src","sources":["organisms/sheet/use-sheet-header.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { StyleSheet } from 'react-native';
|
|
4
|
+
|
|
5
|
+
/** What lays out a view's children — it goes on the pressable inside, so the content sits where the caller put it. */
|
|
6
|
+
const CONTENT_KEYS = new Set(['alignContent', 'alignItems', 'columnGap', 'flexDirection', 'flexWrap', 'gap', 'justifyContent', 'padding', 'paddingBottom', 'paddingEnd', 'paddingHorizontal', 'paddingLeft', 'paddingRight', 'paddingStart', 'paddingTop', 'paddingVertical', 'rowGap']);
|
|
7
|
+
const FILL = {
|
|
8
|
+
flexGrow: 1
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Splits a resolved style for a pressable with an Android ripple. The ripple is drawn as the pressable's foreground,
|
|
13
|
+
* which its own `overflow: hidden` does not clip — so it would spill past rounded corners. A parent clips its
|
|
14
|
+
* children's foregrounds, though: the outer view takes the shape, background, border and outer layout and clips; the
|
|
15
|
+
* pressable inside takes the padding and the content layout and fills it, so the ripple covers the whole card and
|
|
16
|
+
* stops at its corners.
|
|
17
|
+
*/
|
|
18
|
+
export const splitForRipple = style => {
|
|
19
|
+
const flat = StyleSheet.flatten(style) ?? {};
|
|
20
|
+
const outer = {
|
|
21
|
+
overflow: 'hidden'
|
|
22
|
+
};
|
|
23
|
+
const inner = {};
|
|
24
|
+
for (const [key, value] of Object.entries(flat)) {
|
|
25
|
+
if (CONTENT_KEYS.has(key)) {
|
|
26
|
+
inner[key] = value;
|
|
27
|
+
} else if (key !== 'overflow') {
|
|
28
|
+
outer[key] = value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
inner: [FILL, inner],
|
|
33
|
+
outer: outer
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=ripple-clip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["StyleSheet","CONTENT_KEYS","Set","FILL","flexGrow","splitForRipple","style","flat","flatten","outer","overflow","inner","key","value","Object","entries","has"],"sourceRoot":"../../src","sources":["ripple-clip.ts"],"mappings":";;AAAA,SAAQA,UAAU,QAAuB,cAAc;;AAEvD;AACA,MAAMC,YAAY,GAAG,IAAIC,GAAG,CAAS,CACnC,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,UAAU,EACV,KAAK,EACL,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,QAAQ,CACT,CAAC;AAEF,MAAMC,IAAe,GAAG;EAACC,QAAQ,EAAE;AAAC,CAAC;;AAErC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,cAAc,GAAIC,KAA4B,IAA6C;EACtG,MAAMC,IAAI,GAAGP,UAAU,CAACQ,OAAO,CAACF,KAAK,CAAC,IAAI,CAAC,CAAC;EAC5C,MAAMG,KAA8B,GAAG;IAACC,QAAQ,EAAE;EAAQ,CAAC;EAC3D,MAAMC,KAA8B,GAAG,CAAC,CAAC;EAEzC,KAAK,MAAM,CAACC,GAAG,EAAEC,KAAK,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACR,IAAI,CAAC,EAAE;IAC/C,IAAIN,YAAY,CAACe,GAAG,CAACJ,GAAG,CAAC,EAAE;MACzBD,KAAK,CAACC,GAAG,CAAC,GAAGC,KAAK;IACpB,CAAC,MAAM,IAAID,GAAG,KAAK,UAAU,EAAE;MAC7BH,KAAK,CAACG,GAAG,CAAC,GAAGC,KAAK;IACpB;EACF;EAEA,OAAO;IAACF,KAAK,EAAE,CAACR,IAAI,EAAEQ,KAAK,CAAc;IAAEF,KAAK,EAAEA;EAAkB,CAAC;AACvE,CAAC","ignoreList":[]}
|