@butternutbox/pawprint-native 0.17.0 → 0.18.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/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +11 -0
- package/dist/index.cjs +136 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.js +136 -83
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/molecules/Drawer/Drawer.tsx +84 -4
- package/src/components/molecules/Drawer/DrawerBody.tsx +16 -23
- package/src/components/molecules/Drawer/DrawerBodyMaxContext.ts +21 -0
- package/src/components/molecules/Drawer/DrawerContent.tsx +98 -92
- package/src/components/molecules/Drawer/DrawerContext.ts +9 -0
- package/src/components/molecules/Drawer/DrawerFooter.tsx +17 -3
- package/src/components/molecules/Drawer/DrawerHeader.tsx +25 -3
- package/src/components/molecules/Drawer/DrawerMeasureContext.ts +9 -6
- package/src/components/molecules/Drawer/DrawerOverlay.tsx +4 -1
- package/src/components/molecules/Drawer/DrawerOverlayContext.ts +21 -0
- package/src/components/molecules/Drawer/index.ts +2 -1
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import React, { useMemo } from "react"
|
|
2
|
-
import {
|
|
1
|
+
import React, { useCallback, useMemo } from "react"
|
|
2
|
+
import {
|
|
3
|
+
Image,
|
|
4
|
+
ImageSourcePropType,
|
|
5
|
+
View,
|
|
6
|
+
ViewProps,
|
|
7
|
+
type LayoutChangeEvent
|
|
8
|
+
} from "react-native"
|
|
3
9
|
import styled from "@emotion/native"
|
|
4
10
|
import { useTheme } from "@emotion/react"
|
|
5
11
|
import { DrawerClose } from "./DrawerClose"
|
|
@@ -8,6 +14,7 @@ import {
|
|
|
8
14
|
type DrawerHeaderVariant
|
|
9
15
|
} from "./DrawerHeaderContext"
|
|
10
16
|
import { useDrawerDragContext } from "./DrawerDragContext"
|
|
17
|
+
import { useDrawerMeasureContext } from "./DrawerMeasureContext"
|
|
11
18
|
|
|
12
19
|
const parseTokenValue = (value: string): number => parseFloat(value)
|
|
13
20
|
|
|
@@ -139,11 +146,25 @@ function splitChildren(children: React.ReactNode) {
|
|
|
139
146
|
* @param {ImageSourcePropType} [imageSource] - Image source for the `image` variant
|
|
140
147
|
*/
|
|
141
148
|
export const DrawerHeader = React.forwardRef<View, DrawerHeaderProps>(
|
|
142
|
-
(
|
|
149
|
+
(
|
|
150
|
+
{ variant = "titleAndText", imageSource, children, onLayout, ...props },
|
|
151
|
+
ref
|
|
152
|
+
) => {
|
|
143
153
|
const theme = useTheme()
|
|
144
154
|
const { drawer, grabber } = theme.tokens.components
|
|
145
155
|
const { colour, dimensions } = theme.tokens.semantics
|
|
146
156
|
const dragContext = useDrawerDragContext()
|
|
157
|
+
const measureContext = useDrawerMeasureContext()
|
|
158
|
+
|
|
159
|
+
// Report the header's measured height so DrawerContent can reserve it as
|
|
160
|
+
// chrome directly (rather than deriving it from the panel minus the body).
|
|
161
|
+
const handleLayout = useCallback(
|
|
162
|
+
(event: LayoutChangeEvent): void => {
|
|
163
|
+
measureContext?.setHeaderHeight(event.nativeEvent.layout.height)
|
|
164
|
+
onLayout?.(event)
|
|
165
|
+
},
|
|
166
|
+
[measureContext, onLayout]
|
|
167
|
+
)
|
|
147
168
|
|
|
148
169
|
const contextValue = useMemo(() => ({ variant }), [variant])
|
|
149
170
|
const { closeChild, otherChildren } = splitChildren(children)
|
|
@@ -219,6 +240,7 @@ export const DrawerHeader = React.forwardRef<View, DrawerHeaderProps>(
|
|
|
219
240
|
? drawer.drawerHeader.colour.background.fullBleed
|
|
220
241
|
: undefined
|
|
221
242
|
}
|
|
243
|
+
onLayout={handleLayout}
|
|
222
244
|
{...props}
|
|
223
245
|
>
|
|
224
246
|
<StyledGrabberWrapper
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { createContext, useContext } from "react"
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Lets
|
|
5
|
-
* `DrawerContent`, which uses
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* Lets the header and footer report their measured heights up to
|
|
5
|
+
* `DrawerContent`, which uses them to derive the body ScrollView's chrome-aware
|
|
6
|
+
* `maxHeight` (`90%·window − header − footer − border`). Measuring the chrome
|
|
7
|
+
* directly (not by subtraction) keeps that cap correct even when the body grows
|
|
8
|
+
* after the first layout, so tall content scrolls inside the cap and the footer
|
|
9
|
+
* is never clipped. The panel itself wraps its content, so there is no body
|
|
10
|
+
* content-height measurement and no feedback loop.
|
|
9
11
|
*/
|
|
10
12
|
export type DrawerMeasureContextValue = {
|
|
11
|
-
|
|
13
|
+
setHeaderHeight: (height: number) => void
|
|
14
|
+
setFooterHeight: (height: number) => void
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
export const DrawerMeasureContext =
|
|
@@ -19,7 +19,7 @@ export const DrawerOverlay = React.forwardRef<
|
|
|
19
19
|
DrawerOverlayProps
|
|
20
20
|
>(({ accessible = false }, _ref) => {
|
|
21
21
|
const theme = useTheme()
|
|
22
|
-
const { isOpen, closeDrawer } = useDrawerContext()
|
|
22
|
+
const { isOpen, closeDrawer, backdrop } = useDrawerContext()
|
|
23
23
|
const opacity = useRef(new Animated.Value(0)).current
|
|
24
24
|
|
|
25
25
|
useEffect(() => {
|
|
@@ -30,6 +30,9 @@ export const DrawerOverlay = React.forwardRef<
|
|
|
30
30
|
}).start()
|
|
31
31
|
}, [isOpen, opacity])
|
|
32
32
|
|
|
33
|
+
// A backdrop-less drawer omits the dimming/tap-to-dismiss overlay entirely.
|
|
34
|
+
if (!backdrop) return null
|
|
35
|
+
|
|
33
36
|
return (
|
|
34
37
|
<Pressable
|
|
35
38
|
style={StyleSheet.absoluteFillObject}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createContext, useContext, type ComponentType } from "react"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Optional app-provided component rendered on top of *every* modal drawer,
|
|
5
|
+
* inside the drawer's native `Modal` window.
|
|
6
|
+
*
|
|
7
|
+
* A native `Modal` is a separate OS window, so anything mounted at the app root
|
|
8
|
+
* — e.g. a toast/notification stack — is painted *behind* the drawer. Pointing
|
|
9
|
+
* this context at that root overlay lets the app render a second instance inside
|
|
10
|
+
* the drawer's Modal, so it surfaces above the drawer for all modal drawers at
|
|
11
|
+
* once, with no per-drawer wiring. React context flows through RN Modals, so the
|
|
12
|
+
* in-Modal instance reads the same app state as the root one.
|
|
13
|
+
*
|
|
14
|
+
* Defaults to `null` (nothing extra rendered) — fully opt-in and backward
|
|
15
|
+
* compatible. Only applies to modal (backdrop) drawers; backdrop-less drawers
|
|
16
|
+
* render inline, where the app-root overlay already paints on top.
|
|
17
|
+
*/
|
|
18
|
+
export const DrawerOverlayContext = createContext<ComponentType | null>(null)
|
|
19
|
+
|
|
20
|
+
export const useDrawerOverlay = (): ComponentType | null =>
|
|
21
|
+
useContext(DrawerOverlayContext)
|
|
@@ -2,7 +2,8 @@ export { Drawer } from "./Drawer"
|
|
|
2
2
|
export type {
|
|
3
3
|
DrawerProps,
|
|
4
4
|
DrawerTriggerProps,
|
|
5
|
-
DrawerPortalProps
|
|
5
|
+
DrawerPortalProps,
|
|
6
|
+
DrawerOverlayProviderProps
|
|
6
7
|
} from "./Drawer"
|
|
7
8
|
export type { DrawerContentProps } from "./DrawerContent"
|
|
8
9
|
export type { DrawerOverlayProps } from "./DrawerOverlay"
|