@xsolla/xui-b2b-drawer 0.147.1
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/native/index.d.mts +64 -0
- package/native/index.d.ts +64 -0
- package/native/index.js +586 -0
- package/native/index.js.map +1 -0
- package/native/index.mjs +552 -0
- package/native/index.mjs.map +1 -0
- package/package.json +62 -0
- package/web/index.d.mts +64 -0
- package/web/index.d.ts +64 -0
- package/web/index.js +746 -0
- package/web/index.js.map +1 -0
- package/web/index.mjs +708 -0
- package/web/index.mjs.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/index.tsx","../../src/Drawer.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../src/DrawerRoot.native.tsx","../../src/DrawerHeader.tsx","../../src/DrawerFooter.tsx","../../src/useDrawer.ts"],"sourcesContent":["export { Drawer } from \"./Drawer\";\nexport { useDrawer } from \"./useDrawer\";\nexport type {\n DrawerProps,\n DrawerSize,\n DrawerFooterAlign,\n LegacyDrawerHeader,\n} from \"./types\";\nexport type { UseDrawerOptions, UseDrawerReturn } from \"./useDrawer\";\n","import { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type { DrawerProps } from \"./types\";\nimport { DrawerRoot } from \"./DrawerRoot\";\nimport { DrawerHeader } from \"./DrawerHeader\";\nimport { DrawerFooter } from \"./DrawerFooter\";\n\nconst FOCUSABLE_SELECTORS =\n 'button:not([disabled]), [href], input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nconst isElementVisible = (el: HTMLElement): boolean => {\n if (el.offsetParent === null && getComputedStyle(el).position !== \"fixed\")\n return false;\n const style = getComputedStyle(el);\n return style.visibility !== \"hidden\" && style.display !== \"none\";\n};\n\nconst getFocusableElements = (container: HTMLElement): HTMLElement[] =>\n Array.from(\n container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTORS)\n ).filter(isElementVisible);\n\nconst DRAWER_WIDTHS: Record<string, number> = {\n sm: 480,\n md: 620,\n lg: 1056,\n};\n\nexport const Drawer = forwardRef<HTMLDivElement, DrawerProps>(\n (\n {\n open: openProp,\n isOpen,\n onClose,\n size = \"md\",\n title: titleProp,\n header: headerProp,\n onBack: onBackProp,\n headerAction,\n closeOnOverlayClick = true,\n closeOnEscape = true,\n footer: footerProp,\n bottom,\n footerAlign = \"right\",\n footerShadow = false,\n footerFullWidth = true,\n stepper,\n children,\n initialFocusRef,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n // Resolve legacy aliases — new props take precedence\n const open = openProp ?? isOpen ?? false;\n const title = titleProp ?? headerProp?.title;\n const onBack = onBackProp ?? headerProp?.onBack;\n const footer = footerProp ?? bottom;\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.drawer();\n\n const [mounted, setMounted] = useState(open);\n\n useEffect(() => {\n if (open) setMounted(true);\n }, [open]);\n\n const drawerRef = useRef<HTMLDivElement>(null);\n const closeButtonRef = useRef<HTMLDivElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n\n // Focus management on open/close\n useEffect(() => {\n if (!open) return;\n if (typeof document === \"undefined\") return;\n\n previousActiveElement.current = document.activeElement as HTMLElement;\n\n const focusTarget =\n initialFocusRef?.current ||\n closeButtonRef.current ||\n (drawerRef.current && getFocusableElements(drawerRef.current)[0]);\n\n if (focusTarget) {\n (focusTarget as HTMLElement).focus();\n } else {\n drawerRef.current?.focus();\n }\n\n // Focus is restored inside onExited (after the exit animation) so that\n // keyboard focus does not escape back to the page while the drawer is\n // still visible on screen.\n }, [open, initialFocusRef]);\n\n // Escape key handler\n useEffect(() => {\n if (!open || !closeOnEscape || !onClose) return;\n if (typeof document === \"undefined\") return;\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [open, closeOnEscape, onClose]);\n\n // Focus trap\n const handleKeyDown = useCallback((event: React.KeyboardEvent) => {\n if (event.key !== \"Tab\" || !drawerRef.current) return;\n if (typeof document === \"undefined\") return;\n\n const focusableElements = getFocusableElements(drawerRef.current);\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (!firstElement) {\n event.preventDefault();\n return;\n }\n\n if (event.shiftKey && document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n } else if (!event.shiftKey && document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }, []);\n\n if (!mounted) return null;\n\n const contentWidth = DRAWER_WIDTHS[size];\n\n return (\n <DrawerRoot\n open={open}\n onExited={() => {\n setMounted(false);\n previousActiveElement.current?.focus();\n }}\n onBackdropClick={closeOnOverlayClick ? onClose : undefined}\n scrimColor={sizing.scrimColor}\n outerPadding={sizing.outerPadding}\n animationDuration={sizing.animationDuration}\n zIndex={sizing.zIndex}\n >\n {/* Outer panel — white background + container radius clips the inner content corners */}\n <div\n style={{\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"stretch\",\n backgroundColor: theme.colors.background.primary,\n borderRadius: sizing.containerRadius,\n overflow: \"hidden\",\n gap: stepper ? sizing.stepperContentGap : 0,\n }}\n >\n {/* Optional stepper sidebar */}\n {stepper && (\n <div\n style={{\n flexShrink: 0,\n alignSelf: \"stretch\",\n backgroundColor: theme.colors.background.secondary,\n borderRadius: sizing.contentRadius,\n padding: sizing.stepperPadding,\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n {stepper}\n </div>\n )}\n\n {/* Content panel */}\n <Box\n ref={(node: HTMLDivElement | null) => {\n (\n drawerRef as React.MutableRefObject<HTMLDivElement | null>\n ).current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref)\n (ref as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={typeof title === \"string\" ? title : undefined}\n tabIndex={-1}\n onKeyDown={handleKeyDown}\n style={{\n width: contentWidth,\n height: \"100%\",\n flexShrink: 0,\n display: \"flex\",\n flexDirection: \"column\",\n outline: \"none\",\n color: theme.colors.content.primary,\n }}\n >\n {/* Header */}\n <DrawerHeader\n title={title}\n onBack={onBack}\n onClose={onClose}\n headerAction={headerAction}\n paddingX={sizing.headerPaddingX}\n paddingY={sizing.headerPaddingY}\n gap={sizing.headerGap}\n />\n\n {/* Body */}\n <Box\n style={{\n flex: 1,\n minHeight: 0,\n overflowY: \"auto\",\n paddingLeft: sizing.contentPaddingX,\n paddingRight: sizing.contentPaddingX,\n }}\n >\n {children}\n </Box>\n\n {/* Footer */}\n {footer ? (\n <DrawerFooter\n align={footerAlign}\n shadow={footerShadow}\n fullWidth={footerFullWidth}\n >\n {footer}\n </DrawerFooter>\n ) : (\n <div style={{ flexShrink: 0, height: 32 }} />\n )}\n </Box>\n </div>\n </DrawerRoot>\n );\n }\n);\n\nDrawer.displayName = \"Drawer\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import { memo } from \"react\";\nimport type { DrawerRootProps } from \"./types\";\n\n// Web portal not available on React Native.\n// Native drawer implementation would use RN-specific approach (e.g. Animated.View).\nexport const DrawerRoot = memo((_props: DrawerRootProps) => {\n return null;\n});\n\nDrawerRoot.displayName = \"DrawerRoot\";\n","import { memo } from \"react\";\nimport { IconButton } from \"@xsolla/xui-button\";\nimport { ArrowLeft, Remove } from \"@xsolla/xui-icons-base\";\nimport { Typography } from \"@xsolla/xui-typography\";\nimport type { DrawerHeaderProps } from \"./types\";\n\nexport const DrawerHeader = memo(\n ({\n title,\n onBack,\n onClose,\n headerAction,\n paddingX,\n paddingY,\n gap,\n }: DrawerHeaderProps) => {\n return (\n <div\n style={{\n flexShrink: 0,\n height: 80,\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n paddingLeft: paddingX,\n paddingRight: paddingX,\n paddingTop: paddingY,\n paddingBottom: paddingY,\n gap,\n boxSizing: \"border-box\",\n }}\n >\n {/* Left content: back button + title */}\n <div\n style={{\n flex: 1,\n minWidth: 0,\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: 16,\n }}\n >\n {/* Back button */}\n {onBack && (\n <IconButton\n variant=\"secondary\"\n tone=\"mono\"\n size=\"xs\"\n icon={<ArrowLeft />}\n onPress={onBack}\n aria-label=\"Go back\"\n />\n )}\n\n {/* Title */}\n {title && (\n <div style={{ flex: 1, minWidth: 0, overflow: \"hidden\" }}>\n <Typography variant=\"bodyLgAccent\" noWrap>\n {title}\n </Typography>\n </div>\n )}\n </div>\n\n {/* Optional header action */}\n {headerAction && <div style={{ flexShrink: 0 }}>{headerAction}</div>}\n\n {/* Close button */}\n {onClose && (\n <IconButton\n variant=\"secondary\"\n tone=\"mono\"\n size=\"xs\"\n icon={<Remove />}\n onPress={onClose}\n aria-label=\"Close drawer\"\n />\n )}\n </div>\n );\n }\n);\n\nDrawerHeader.displayName = \"DrawerHeader\";\n","import React, { memo } from \"react\";\nimport type { DrawerFooterProps } from \"./types\";\n\nconst flattenChildren = (children: React.ReactNode): React.ReactNode[] => {\n const result: React.ReactNode[] = [];\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child) && child.type === React.Fragment) {\n result.push(\n ...flattenChildren(\n (child.props as { children: React.ReactNode }).children\n )\n );\n } else if (child !== null && child !== undefined) {\n result.push(child);\n }\n });\n return result;\n};\n\nexport const DrawerFooter = memo(\n ({ children, align, shadow, fullWidth }: DrawerFooterProps) => {\n const justifyContent = align === \"center\" ? \"center\" : \"flex-end\";\n\n const renderedChildren = fullWidth\n ? flattenChildren(children).map((child, i) =>\n React.isValidElement(child)\n ? React.cloneElement(\n child as React.ReactElement<Record<string, unknown>>,\n {\n key: (child as React.ReactElement).key ?? i,\n fullWidth: true,\n }\n )\n : child\n )\n : children;\n\n return (\n <div\n style={{\n flexShrink: 0,\n width: \"100%\",\n boxShadow: shadow ? \"0px 2px 25px 0px rgba(7, 7, 8, 0.15)\" : \"none\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n justifyContent: fullWidth ? \"stretch\" : justifyContent,\n padding: 16,\n gap: 8,\n }}\n >\n {renderedChildren}\n </div>\n </div>\n );\n }\n);\n\nDrawerFooter.displayName = \"DrawerFooter\";\n","import { useCallback, useState } from \"react\";\n\nexport interface UseDrawerOptions {\n onOpen?: () => void;\n onClose?: () => void;\n}\n\nexport interface UseDrawerReturn {\n isOpen: boolean;\n open: () => void;\n close: () => void;\n}\n\nexport function useDrawer(options?: UseDrawerOptions): UseDrawerReturn {\n const [isOpen, setIsOpen] = useState(false);\n\n const open = useCallback(() => {\n setIsOpen(true);\n options?.onOpen?.();\n }, [options]);\n\n const close = useCallback(() => {\n setIsOpen(false);\n options?.onClose?.();\n }, [options]);\n\n return { isOpen, open, close };\n}\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","React","import_jsx_runtime","handleKeyDown","import_react"]}
|
package/native/index.mjs
ADDED
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
// src/Drawer.tsx
|
|
2
|
+
import { forwardRef, useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
|
|
4
|
+
// ../../foundation/primitives-native/src/Box.tsx
|
|
5
|
+
import {
|
|
6
|
+
View,
|
|
7
|
+
Pressable,
|
|
8
|
+
Image
|
|
9
|
+
} from "react-native";
|
|
10
|
+
import { jsx } from "react/jsx-runtime";
|
|
11
|
+
var Box = ({
|
|
12
|
+
children,
|
|
13
|
+
onPress,
|
|
14
|
+
onLayout,
|
|
15
|
+
onMoveShouldSetResponder,
|
|
16
|
+
onResponderGrant,
|
|
17
|
+
onResponderMove,
|
|
18
|
+
onResponderRelease,
|
|
19
|
+
onResponderTerminate,
|
|
20
|
+
backgroundColor,
|
|
21
|
+
borderColor,
|
|
22
|
+
borderWidth,
|
|
23
|
+
borderBottomWidth,
|
|
24
|
+
borderBottomColor,
|
|
25
|
+
borderTopWidth,
|
|
26
|
+
borderTopColor,
|
|
27
|
+
borderLeftWidth,
|
|
28
|
+
borderLeftColor,
|
|
29
|
+
borderRightWidth,
|
|
30
|
+
borderRightColor,
|
|
31
|
+
borderRadius,
|
|
32
|
+
borderStyle,
|
|
33
|
+
height,
|
|
34
|
+
padding,
|
|
35
|
+
paddingHorizontal,
|
|
36
|
+
paddingVertical,
|
|
37
|
+
margin,
|
|
38
|
+
marginTop,
|
|
39
|
+
marginBottom,
|
|
40
|
+
marginLeft,
|
|
41
|
+
marginRight,
|
|
42
|
+
flexDirection,
|
|
43
|
+
alignItems,
|
|
44
|
+
justifyContent,
|
|
45
|
+
position,
|
|
46
|
+
top,
|
|
47
|
+
bottom,
|
|
48
|
+
left,
|
|
49
|
+
right,
|
|
50
|
+
width,
|
|
51
|
+
minWidth,
|
|
52
|
+
minHeight,
|
|
53
|
+
maxWidth,
|
|
54
|
+
maxHeight,
|
|
55
|
+
flex,
|
|
56
|
+
overflow,
|
|
57
|
+
zIndex,
|
|
58
|
+
hoverStyle,
|
|
59
|
+
pressStyle,
|
|
60
|
+
style,
|
|
61
|
+
"data-testid": dataTestId,
|
|
62
|
+
testID,
|
|
63
|
+
as,
|
|
64
|
+
src,
|
|
65
|
+
alt,
|
|
66
|
+
...rest
|
|
67
|
+
}) => {
|
|
68
|
+
const getContainerStyle = (pressed) => ({
|
|
69
|
+
backgroundColor: pressed && pressStyle?.backgroundColor ? pressStyle.backgroundColor : backgroundColor,
|
|
70
|
+
borderColor,
|
|
71
|
+
borderWidth,
|
|
72
|
+
borderBottomWidth,
|
|
73
|
+
borderBottomColor,
|
|
74
|
+
borderTopWidth,
|
|
75
|
+
borderTopColor,
|
|
76
|
+
borderLeftWidth,
|
|
77
|
+
borderLeftColor,
|
|
78
|
+
borderRightWidth,
|
|
79
|
+
borderRightColor,
|
|
80
|
+
borderRadius,
|
|
81
|
+
borderStyle,
|
|
82
|
+
overflow,
|
|
83
|
+
zIndex,
|
|
84
|
+
height,
|
|
85
|
+
width,
|
|
86
|
+
minWidth,
|
|
87
|
+
minHeight,
|
|
88
|
+
maxWidth,
|
|
89
|
+
maxHeight,
|
|
90
|
+
padding,
|
|
91
|
+
paddingHorizontal,
|
|
92
|
+
paddingVertical,
|
|
93
|
+
margin,
|
|
94
|
+
marginTop,
|
|
95
|
+
marginBottom,
|
|
96
|
+
marginLeft,
|
|
97
|
+
marginRight,
|
|
98
|
+
flexDirection,
|
|
99
|
+
alignItems,
|
|
100
|
+
justifyContent,
|
|
101
|
+
position,
|
|
102
|
+
top,
|
|
103
|
+
bottom,
|
|
104
|
+
left,
|
|
105
|
+
right,
|
|
106
|
+
flex,
|
|
107
|
+
...style
|
|
108
|
+
});
|
|
109
|
+
const finalTestID = dataTestId || testID;
|
|
110
|
+
const {
|
|
111
|
+
role,
|
|
112
|
+
tabIndex,
|
|
113
|
+
onKeyDown,
|
|
114
|
+
onKeyUp,
|
|
115
|
+
"aria-label": _ariaLabel,
|
|
116
|
+
"aria-labelledby": _ariaLabelledBy,
|
|
117
|
+
"aria-current": _ariaCurrent,
|
|
118
|
+
"aria-disabled": _ariaDisabled,
|
|
119
|
+
"aria-live": _ariaLive,
|
|
120
|
+
className,
|
|
121
|
+
"data-testid": _dataTestId,
|
|
122
|
+
...nativeRest
|
|
123
|
+
} = rest;
|
|
124
|
+
if (as === "img" && src) {
|
|
125
|
+
const imageStyle = {
|
|
126
|
+
width,
|
|
127
|
+
height,
|
|
128
|
+
borderRadius,
|
|
129
|
+
position,
|
|
130
|
+
top,
|
|
131
|
+
bottom,
|
|
132
|
+
left,
|
|
133
|
+
right,
|
|
134
|
+
...style
|
|
135
|
+
};
|
|
136
|
+
return /* @__PURE__ */ jsx(
|
|
137
|
+
Image,
|
|
138
|
+
{
|
|
139
|
+
source: { uri: src },
|
|
140
|
+
style: imageStyle,
|
|
141
|
+
testID: finalTestID,
|
|
142
|
+
resizeMode: "cover",
|
|
143
|
+
...nativeRest
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
if (onPress) {
|
|
148
|
+
return /* @__PURE__ */ jsx(
|
|
149
|
+
Pressable,
|
|
150
|
+
{
|
|
151
|
+
onPress,
|
|
152
|
+
onLayout,
|
|
153
|
+
onMoveShouldSetResponder,
|
|
154
|
+
onResponderGrant,
|
|
155
|
+
onResponderMove,
|
|
156
|
+
onResponderRelease,
|
|
157
|
+
onResponderTerminate,
|
|
158
|
+
style: ({ pressed }) => getContainerStyle(pressed),
|
|
159
|
+
testID: finalTestID,
|
|
160
|
+
...nativeRest,
|
|
161
|
+
children
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
return /* @__PURE__ */ jsx(
|
|
166
|
+
View,
|
|
167
|
+
{
|
|
168
|
+
style: getContainerStyle(),
|
|
169
|
+
testID: finalTestID,
|
|
170
|
+
onLayout,
|
|
171
|
+
onMoveShouldSetResponder,
|
|
172
|
+
onResponderGrant,
|
|
173
|
+
onResponderMove,
|
|
174
|
+
onResponderRelease,
|
|
175
|
+
onResponderTerminate,
|
|
176
|
+
...nativeRest,
|
|
177
|
+
children
|
|
178
|
+
}
|
|
179
|
+
);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// src/Drawer.tsx
|
|
183
|
+
import { useResolvedTheme } from "@xsolla/xui-core";
|
|
184
|
+
|
|
185
|
+
// src/DrawerRoot.native.tsx
|
|
186
|
+
import { memo } from "react";
|
|
187
|
+
var DrawerRoot = memo((_props) => {
|
|
188
|
+
return null;
|
|
189
|
+
});
|
|
190
|
+
DrawerRoot.displayName = "DrawerRoot";
|
|
191
|
+
|
|
192
|
+
// src/DrawerHeader.tsx
|
|
193
|
+
import { memo as memo2 } from "react";
|
|
194
|
+
import { IconButton } from "@xsolla/xui-button";
|
|
195
|
+
import { ArrowLeft, Remove } from "@xsolla/xui-icons-base";
|
|
196
|
+
import { Typography } from "@xsolla/xui-typography";
|
|
197
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
198
|
+
var DrawerHeader = memo2(
|
|
199
|
+
({
|
|
200
|
+
title,
|
|
201
|
+
onBack,
|
|
202
|
+
onClose,
|
|
203
|
+
headerAction,
|
|
204
|
+
paddingX,
|
|
205
|
+
paddingY,
|
|
206
|
+
gap
|
|
207
|
+
}) => {
|
|
208
|
+
return /* @__PURE__ */ jsxs(
|
|
209
|
+
"div",
|
|
210
|
+
{
|
|
211
|
+
style: {
|
|
212
|
+
flexShrink: 0,
|
|
213
|
+
height: 80,
|
|
214
|
+
width: "100%",
|
|
215
|
+
display: "flex",
|
|
216
|
+
flexDirection: "row",
|
|
217
|
+
alignItems: "center",
|
|
218
|
+
paddingLeft: paddingX,
|
|
219
|
+
paddingRight: paddingX,
|
|
220
|
+
paddingTop: paddingY,
|
|
221
|
+
paddingBottom: paddingY,
|
|
222
|
+
gap,
|
|
223
|
+
boxSizing: "border-box"
|
|
224
|
+
},
|
|
225
|
+
children: [
|
|
226
|
+
/* @__PURE__ */ jsxs(
|
|
227
|
+
"div",
|
|
228
|
+
{
|
|
229
|
+
style: {
|
|
230
|
+
flex: 1,
|
|
231
|
+
minWidth: 0,
|
|
232
|
+
display: "flex",
|
|
233
|
+
flexDirection: "row",
|
|
234
|
+
alignItems: "center",
|
|
235
|
+
gap: 16
|
|
236
|
+
},
|
|
237
|
+
children: [
|
|
238
|
+
onBack && /* @__PURE__ */ jsx2(
|
|
239
|
+
IconButton,
|
|
240
|
+
{
|
|
241
|
+
variant: "secondary",
|
|
242
|
+
tone: "mono",
|
|
243
|
+
size: "xs",
|
|
244
|
+
icon: /* @__PURE__ */ jsx2(ArrowLeft, {}),
|
|
245
|
+
onPress: onBack,
|
|
246
|
+
"aria-label": "Go back"
|
|
247
|
+
}
|
|
248
|
+
),
|
|
249
|
+
title && /* @__PURE__ */ jsx2("div", { style: { flex: 1, minWidth: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx2(Typography, { variant: "bodyLgAccent", noWrap: true, children: title }) })
|
|
250
|
+
]
|
|
251
|
+
}
|
|
252
|
+
),
|
|
253
|
+
headerAction && /* @__PURE__ */ jsx2("div", { style: { flexShrink: 0 }, children: headerAction }),
|
|
254
|
+
onClose && /* @__PURE__ */ jsx2(
|
|
255
|
+
IconButton,
|
|
256
|
+
{
|
|
257
|
+
variant: "secondary",
|
|
258
|
+
tone: "mono",
|
|
259
|
+
size: "xs",
|
|
260
|
+
icon: /* @__PURE__ */ jsx2(Remove, {}),
|
|
261
|
+
onPress: onClose,
|
|
262
|
+
"aria-label": "Close drawer"
|
|
263
|
+
}
|
|
264
|
+
)
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
);
|
|
270
|
+
DrawerHeader.displayName = "DrawerHeader";
|
|
271
|
+
|
|
272
|
+
// src/DrawerFooter.tsx
|
|
273
|
+
import React, { memo as memo3 } from "react";
|
|
274
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
275
|
+
var flattenChildren = (children) => {
|
|
276
|
+
const result = [];
|
|
277
|
+
React.Children.forEach(children, (child) => {
|
|
278
|
+
if (React.isValidElement(child) && child.type === React.Fragment) {
|
|
279
|
+
result.push(
|
|
280
|
+
...flattenChildren(
|
|
281
|
+
child.props.children
|
|
282
|
+
)
|
|
283
|
+
);
|
|
284
|
+
} else if (child !== null && child !== void 0) {
|
|
285
|
+
result.push(child);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
return result;
|
|
289
|
+
};
|
|
290
|
+
var DrawerFooter = memo3(
|
|
291
|
+
({ children, align, shadow, fullWidth }) => {
|
|
292
|
+
const justifyContent = align === "center" ? "center" : "flex-end";
|
|
293
|
+
const renderedChildren = fullWidth ? flattenChildren(children).map(
|
|
294
|
+
(child, i) => React.isValidElement(child) ? React.cloneElement(
|
|
295
|
+
child,
|
|
296
|
+
{
|
|
297
|
+
key: child.key ?? i,
|
|
298
|
+
fullWidth: true
|
|
299
|
+
}
|
|
300
|
+
) : child
|
|
301
|
+
) : children;
|
|
302
|
+
return /* @__PURE__ */ jsx3(
|
|
303
|
+
"div",
|
|
304
|
+
{
|
|
305
|
+
style: {
|
|
306
|
+
flexShrink: 0,
|
|
307
|
+
width: "100%",
|
|
308
|
+
boxShadow: shadow ? "0px 2px 25px 0px rgba(7, 7, 8, 0.15)" : "none"
|
|
309
|
+
},
|
|
310
|
+
children: /* @__PURE__ */ jsx3(
|
|
311
|
+
"div",
|
|
312
|
+
{
|
|
313
|
+
style: {
|
|
314
|
+
display: "flex",
|
|
315
|
+
flexDirection: "row",
|
|
316
|
+
justifyContent: fullWidth ? "stretch" : justifyContent,
|
|
317
|
+
padding: 16,
|
|
318
|
+
gap: 8
|
|
319
|
+
},
|
|
320
|
+
children: renderedChildren
|
|
321
|
+
}
|
|
322
|
+
)
|
|
323
|
+
}
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
);
|
|
327
|
+
DrawerFooter.displayName = "DrawerFooter";
|
|
328
|
+
|
|
329
|
+
// src/Drawer.tsx
|
|
330
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
331
|
+
var FOCUSABLE_SELECTORS = 'button:not([disabled]), [href], input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
332
|
+
var isElementVisible = (el) => {
|
|
333
|
+
if (el.offsetParent === null && getComputedStyle(el).position !== "fixed")
|
|
334
|
+
return false;
|
|
335
|
+
const style = getComputedStyle(el);
|
|
336
|
+
return style.visibility !== "hidden" && style.display !== "none";
|
|
337
|
+
};
|
|
338
|
+
var getFocusableElements = (container) => Array.from(
|
|
339
|
+
container.querySelectorAll(FOCUSABLE_SELECTORS)
|
|
340
|
+
).filter(isElementVisible);
|
|
341
|
+
var DRAWER_WIDTHS = {
|
|
342
|
+
sm: 480,
|
|
343
|
+
md: 620,
|
|
344
|
+
lg: 1056
|
|
345
|
+
};
|
|
346
|
+
var Drawer = forwardRef(
|
|
347
|
+
({
|
|
348
|
+
open: openProp,
|
|
349
|
+
isOpen,
|
|
350
|
+
onClose,
|
|
351
|
+
size = "md",
|
|
352
|
+
title: titleProp,
|
|
353
|
+
header: headerProp,
|
|
354
|
+
onBack: onBackProp,
|
|
355
|
+
headerAction,
|
|
356
|
+
closeOnOverlayClick = true,
|
|
357
|
+
closeOnEscape = true,
|
|
358
|
+
footer: footerProp,
|
|
359
|
+
bottom,
|
|
360
|
+
footerAlign = "right",
|
|
361
|
+
footerShadow = false,
|
|
362
|
+
footerFullWidth = true,
|
|
363
|
+
stepper,
|
|
364
|
+
children,
|
|
365
|
+
initialFocusRef,
|
|
366
|
+
themeMode,
|
|
367
|
+
themeProductContext
|
|
368
|
+
}, ref) => {
|
|
369
|
+
const open = openProp ?? isOpen ?? false;
|
|
370
|
+
const title = titleProp ?? headerProp?.title;
|
|
371
|
+
const onBack = onBackProp ?? headerProp?.onBack;
|
|
372
|
+
const footer = footerProp ?? bottom;
|
|
373
|
+
const { theme } = useResolvedTheme({ themeMode, themeProductContext });
|
|
374
|
+
const sizing = theme.sizing.drawer();
|
|
375
|
+
const [mounted, setMounted] = useState(open);
|
|
376
|
+
useEffect(() => {
|
|
377
|
+
if (open) setMounted(true);
|
|
378
|
+
}, [open]);
|
|
379
|
+
const drawerRef = useRef(null);
|
|
380
|
+
const closeButtonRef = useRef(null);
|
|
381
|
+
const previousActiveElement = useRef(null);
|
|
382
|
+
useEffect(() => {
|
|
383
|
+
if (!open) return;
|
|
384
|
+
if (typeof document === "undefined") return;
|
|
385
|
+
previousActiveElement.current = document.activeElement;
|
|
386
|
+
const focusTarget = initialFocusRef?.current || closeButtonRef.current || drawerRef.current && getFocusableElements(drawerRef.current)[0];
|
|
387
|
+
if (focusTarget) {
|
|
388
|
+
focusTarget.focus();
|
|
389
|
+
} else {
|
|
390
|
+
drawerRef.current?.focus();
|
|
391
|
+
}
|
|
392
|
+
}, [open, initialFocusRef]);
|
|
393
|
+
useEffect(() => {
|
|
394
|
+
if (!open || !closeOnEscape || !onClose) return;
|
|
395
|
+
if (typeof document === "undefined") return;
|
|
396
|
+
const handleKeyDown2 = (event) => {
|
|
397
|
+
if (event.key === "Escape") onClose();
|
|
398
|
+
};
|
|
399
|
+
document.addEventListener("keydown", handleKeyDown2);
|
|
400
|
+
return () => document.removeEventListener("keydown", handleKeyDown2);
|
|
401
|
+
}, [open, closeOnEscape, onClose]);
|
|
402
|
+
const handleKeyDown = useCallback((event) => {
|
|
403
|
+
if (event.key !== "Tab" || !drawerRef.current) return;
|
|
404
|
+
if (typeof document === "undefined") return;
|
|
405
|
+
const focusableElements = getFocusableElements(drawerRef.current);
|
|
406
|
+
const firstElement = focusableElements[0];
|
|
407
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
408
|
+
if (!firstElement) {
|
|
409
|
+
event.preventDefault();
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
if (event.shiftKey && document.activeElement === firstElement) {
|
|
413
|
+
event.preventDefault();
|
|
414
|
+
lastElement.focus();
|
|
415
|
+
} else if (!event.shiftKey && document.activeElement === lastElement) {
|
|
416
|
+
event.preventDefault();
|
|
417
|
+
firstElement.focus();
|
|
418
|
+
}
|
|
419
|
+
}, []);
|
|
420
|
+
if (!mounted) return null;
|
|
421
|
+
const contentWidth = DRAWER_WIDTHS[size];
|
|
422
|
+
return /* @__PURE__ */ jsx4(
|
|
423
|
+
DrawerRoot,
|
|
424
|
+
{
|
|
425
|
+
open,
|
|
426
|
+
onExited: () => {
|
|
427
|
+
setMounted(false);
|
|
428
|
+
previousActiveElement.current?.focus();
|
|
429
|
+
},
|
|
430
|
+
onBackdropClick: closeOnOverlayClick ? onClose : void 0,
|
|
431
|
+
scrimColor: sizing.scrimColor,
|
|
432
|
+
outerPadding: sizing.outerPadding,
|
|
433
|
+
animationDuration: sizing.animationDuration,
|
|
434
|
+
zIndex: sizing.zIndex,
|
|
435
|
+
children: /* @__PURE__ */ jsxs2(
|
|
436
|
+
"div",
|
|
437
|
+
{
|
|
438
|
+
style: {
|
|
439
|
+
height: "100%",
|
|
440
|
+
display: "flex",
|
|
441
|
+
flexDirection: "row",
|
|
442
|
+
alignItems: "stretch",
|
|
443
|
+
backgroundColor: theme.colors.background.primary,
|
|
444
|
+
borderRadius: sizing.containerRadius,
|
|
445
|
+
overflow: "hidden",
|
|
446
|
+
gap: stepper ? sizing.stepperContentGap : 0
|
|
447
|
+
},
|
|
448
|
+
children: [
|
|
449
|
+
stepper && /* @__PURE__ */ jsx4(
|
|
450
|
+
"div",
|
|
451
|
+
{
|
|
452
|
+
style: {
|
|
453
|
+
flexShrink: 0,
|
|
454
|
+
alignSelf: "stretch",
|
|
455
|
+
backgroundColor: theme.colors.background.secondary,
|
|
456
|
+
borderRadius: sizing.contentRadius,
|
|
457
|
+
padding: sizing.stepperPadding,
|
|
458
|
+
display: "flex",
|
|
459
|
+
flexDirection: "column"
|
|
460
|
+
},
|
|
461
|
+
children: stepper
|
|
462
|
+
}
|
|
463
|
+
),
|
|
464
|
+
/* @__PURE__ */ jsxs2(
|
|
465
|
+
Box,
|
|
466
|
+
{
|
|
467
|
+
ref: (node) => {
|
|
468
|
+
drawerRef.current = node;
|
|
469
|
+
if (typeof ref === "function") ref(node);
|
|
470
|
+
else if (ref)
|
|
471
|
+
ref.current = node;
|
|
472
|
+
},
|
|
473
|
+
role: "dialog",
|
|
474
|
+
"aria-modal": "true",
|
|
475
|
+
"aria-label": typeof title === "string" ? title : void 0,
|
|
476
|
+
tabIndex: -1,
|
|
477
|
+
onKeyDown: handleKeyDown,
|
|
478
|
+
style: {
|
|
479
|
+
width: contentWidth,
|
|
480
|
+
height: "100%",
|
|
481
|
+
flexShrink: 0,
|
|
482
|
+
display: "flex",
|
|
483
|
+
flexDirection: "column",
|
|
484
|
+
outline: "none",
|
|
485
|
+
color: theme.colors.content.primary
|
|
486
|
+
},
|
|
487
|
+
children: [
|
|
488
|
+
/* @__PURE__ */ jsx4(
|
|
489
|
+
DrawerHeader,
|
|
490
|
+
{
|
|
491
|
+
title,
|
|
492
|
+
onBack,
|
|
493
|
+
onClose,
|
|
494
|
+
headerAction,
|
|
495
|
+
paddingX: sizing.headerPaddingX,
|
|
496
|
+
paddingY: sizing.headerPaddingY,
|
|
497
|
+
gap: sizing.headerGap
|
|
498
|
+
}
|
|
499
|
+
),
|
|
500
|
+
/* @__PURE__ */ jsx4(
|
|
501
|
+
Box,
|
|
502
|
+
{
|
|
503
|
+
style: {
|
|
504
|
+
flex: 1,
|
|
505
|
+
minHeight: 0,
|
|
506
|
+
overflowY: "auto",
|
|
507
|
+
paddingLeft: sizing.contentPaddingX,
|
|
508
|
+
paddingRight: sizing.contentPaddingX
|
|
509
|
+
},
|
|
510
|
+
children
|
|
511
|
+
}
|
|
512
|
+
),
|
|
513
|
+
footer ? /* @__PURE__ */ jsx4(
|
|
514
|
+
DrawerFooter,
|
|
515
|
+
{
|
|
516
|
+
align: footerAlign,
|
|
517
|
+
shadow: footerShadow,
|
|
518
|
+
fullWidth: footerFullWidth,
|
|
519
|
+
children: footer
|
|
520
|
+
}
|
|
521
|
+
) : /* @__PURE__ */ jsx4("div", { style: { flexShrink: 0, height: 32 } })
|
|
522
|
+
]
|
|
523
|
+
}
|
|
524
|
+
)
|
|
525
|
+
]
|
|
526
|
+
}
|
|
527
|
+
)
|
|
528
|
+
}
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
);
|
|
532
|
+
Drawer.displayName = "Drawer";
|
|
533
|
+
|
|
534
|
+
// src/useDrawer.ts
|
|
535
|
+
import { useCallback as useCallback2, useState as useState2 } from "react";
|
|
536
|
+
function useDrawer(options) {
|
|
537
|
+
const [isOpen, setIsOpen] = useState2(false);
|
|
538
|
+
const open = useCallback2(() => {
|
|
539
|
+
setIsOpen(true);
|
|
540
|
+
options?.onOpen?.();
|
|
541
|
+
}, [options]);
|
|
542
|
+
const close = useCallback2(() => {
|
|
543
|
+
setIsOpen(false);
|
|
544
|
+
options?.onClose?.();
|
|
545
|
+
}, [options]);
|
|
546
|
+
return { isOpen, open, close };
|
|
547
|
+
}
|
|
548
|
+
export {
|
|
549
|
+
Drawer,
|
|
550
|
+
useDrawer
|
|
551
|
+
};
|
|
552
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/Drawer.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../src/DrawerRoot.native.tsx","../../src/DrawerHeader.tsx","../../src/DrawerFooter.tsx","../../src/useDrawer.ts"],"sourcesContent":["import { forwardRef, useCallback, useEffect, useRef, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport type { DrawerProps } from \"./types\";\nimport { DrawerRoot } from \"./DrawerRoot\";\nimport { DrawerHeader } from \"./DrawerHeader\";\nimport { DrawerFooter } from \"./DrawerFooter\";\n\nconst FOCUSABLE_SELECTORS =\n 'button:not([disabled]), [href], input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nconst isElementVisible = (el: HTMLElement): boolean => {\n if (el.offsetParent === null && getComputedStyle(el).position !== \"fixed\")\n return false;\n const style = getComputedStyle(el);\n return style.visibility !== \"hidden\" && style.display !== \"none\";\n};\n\nconst getFocusableElements = (container: HTMLElement): HTMLElement[] =>\n Array.from(\n container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTORS)\n ).filter(isElementVisible);\n\nconst DRAWER_WIDTHS: Record<string, number> = {\n sm: 480,\n md: 620,\n lg: 1056,\n};\n\nexport const Drawer = forwardRef<HTMLDivElement, DrawerProps>(\n (\n {\n open: openProp,\n isOpen,\n onClose,\n size = \"md\",\n title: titleProp,\n header: headerProp,\n onBack: onBackProp,\n headerAction,\n closeOnOverlayClick = true,\n closeOnEscape = true,\n footer: footerProp,\n bottom,\n footerAlign = \"right\",\n footerShadow = false,\n footerFullWidth = true,\n stepper,\n children,\n initialFocusRef,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n // Resolve legacy aliases — new props take precedence\n const open = openProp ?? isOpen ?? false;\n const title = titleProp ?? headerProp?.title;\n const onBack = onBackProp ?? headerProp?.onBack;\n const footer = footerProp ?? bottom;\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.drawer();\n\n const [mounted, setMounted] = useState(open);\n\n useEffect(() => {\n if (open) setMounted(true);\n }, [open]);\n\n const drawerRef = useRef<HTMLDivElement>(null);\n const closeButtonRef = useRef<HTMLDivElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n\n // Focus management on open/close\n useEffect(() => {\n if (!open) return;\n if (typeof document === \"undefined\") return;\n\n previousActiveElement.current = document.activeElement as HTMLElement;\n\n const focusTarget =\n initialFocusRef?.current ||\n closeButtonRef.current ||\n (drawerRef.current && getFocusableElements(drawerRef.current)[0]);\n\n if (focusTarget) {\n (focusTarget as HTMLElement).focus();\n } else {\n drawerRef.current?.focus();\n }\n\n // Focus is restored inside onExited (after the exit animation) so that\n // keyboard focus does not escape back to the page while the drawer is\n // still visible on screen.\n }, [open, initialFocusRef]);\n\n // Escape key handler\n useEffect(() => {\n if (!open || !closeOnEscape || !onClose) return;\n if (typeof document === \"undefined\") return;\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [open, closeOnEscape, onClose]);\n\n // Focus trap\n const handleKeyDown = useCallback((event: React.KeyboardEvent) => {\n if (event.key !== \"Tab\" || !drawerRef.current) return;\n if (typeof document === \"undefined\") return;\n\n const focusableElements = getFocusableElements(drawerRef.current);\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (!firstElement) {\n event.preventDefault();\n return;\n }\n\n if (event.shiftKey && document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n } else if (!event.shiftKey && document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }, []);\n\n if (!mounted) return null;\n\n const contentWidth = DRAWER_WIDTHS[size];\n\n return (\n <DrawerRoot\n open={open}\n onExited={() => {\n setMounted(false);\n previousActiveElement.current?.focus();\n }}\n onBackdropClick={closeOnOverlayClick ? onClose : undefined}\n scrimColor={sizing.scrimColor}\n outerPadding={sizing.outerPadding}\n animationDuration={sizing.animationDuration}\n zIndex={sizing.zIndex}\n >\n {/* Outer panel — white background + container radius clips the inner content corners */}\n <div\n style={{\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"stretch\",\n backgroundColor: theme.colors.background.primary,\n borderRadius: sizing.containerRadius,\n overflow: \"hidden\",\n gap: stepper ? sizing.stepperContentGap : 0,\n }}\n >\n {/* Optional stepper sidebar */}\n {stepper && (\n <div\n style={{\n flexShrink: 0,\n alignSelf: \"stretch\",\n backgroundColor: theme.colors.background.secondary,\n borderRadius: sizing.contentRadius,\n padding: sizing.stepperPadding,\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n {stepper}\n </div>\n )}\n\n {/* Content panel */}\n <Box\n ref={(node: HTMLDivElement | null) => {\n (\n drawerRef as React.MutableRefObject<HTMLDivElement | null>\n ).current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref)\n (ref as React.MutableRefObject<HTMLDivElement | null>).current =\n node;\n }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={typeof title === \"string\" ? title : undefined}\n tabIndex={-1}\n onKeyDown={handleKeyDown}\n style={{\n width: contentWidth,\n height: \"100%\",\n flexShrink: 0,\n display: \"flex\",\n flexDirection: \"column\",\n outline: \"none\",\n color: theme.colors.content.primary,\n }}\n >\n {/* Header */}\n <DrawerHeader\n title={title}\n onBack={onBack}\n onClose={onClose}\n headerAction={headerAction}\n paddingX={sizing.headerPaddingX}\n paddingY={sizing.headerPaddingY}\n gap={sizing.headerGap}\n />\n\n {/* Body */}\n <Box\n style={{\n flex: 1,\n minHeight: 0,\n overflowY: \"auto\",\n paddingLeft: sizing.contentPaddingX,\n paddingRight: sizing.contentPaddingX,\n }}\n >\n {children}\n </Box>\n\n {/* Footer */}\n {footer ? (\n <DrawerFooter\n align={footerAlign}\n shadow={footerShadow}\n fullWidth={footerFullWidth}\n >\n {footer}\n </DrawerFooter>\n ) : (\n <div style={{ flexShrink: 0, height: 32 }} />\n )}\n </Box>\n </div>\n </DrawerRoot>\n );\n }\n);\n\nDrawer.displayName = \"Drawer\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import { memo } from \"react\";\nimport type { DrawerRootProps } from \"./types\";\n\n// Web portal not available on React Native.\n// Native drawer implementation would use RN-specific approach (e.g. Animated.View).\nexport const DrawerRoot = memo((_props: DrawerRootProps) => {\n return null;\n});\n\nDrawerRoot.displayName = \"DrawerRoot\";\n","import { memo } from \"react\";\nimport { IconButton } from \"@xsolla/xui-button\";\nimport { ArrowLeft, Remove } from \"@xsolla/xui-icons-base\";\nimport { Typography } from \"@xsolla/xui-typography\";\nimport type { DrawerHeaderProps } from \"./types\";\n\nexport const DrawerHeader = memo(\n ({\n title,\n onBack,\n onClose,\n headerAction,\n paddingX,\n paddingY,\n gap,\n }: DrawerHeaderProps) => {\n return (\n <div\n style={{\n flexShrink: 0,\n height: 80,\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n paddingLeft: paddingX,\n paddingRight: paddingX,\n paddingTop: paddingY,\n paddingBottom: paddingY,\n gap,\n boxSizing: \"border-box\",\n }}\n >\n {/* Left content: back button + title */}\n <div\n style={{\n flex: 1,\n minWidth: 0,\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: 16,\n }}\n >\n {/* Back button */}\n {onBack && (\n <IconButton\n variant=\"secondary\"\n tone=\"mono\"\n size=\"xs\"\n icon={<ArrowLeft />}\n onPress={onBack}\n aria-label=\"Go back\"\n />\n )}\n\n {/* Title */}\n {title && (\n <div style={{ flex: 1, minWidth: 0, overflow: \"hidden\" }}>\n <Typography variant=\"bodyLgAccent\" noWrap>\n {title}\n </Typography>\n </div>\n )}\n </div>\n\n {/* Optional header action */}\n {headerAction && <div style={{ flexShrink: 0 }}>{headerAction}</div>}\n\n {/* Close button */}\n {onClose && (\n <IconButton\n variant=\"secondary\"\n tone=\"mono\"\n size=\"xs\"\n icon={<Remove />}\n onPress={onClose}\n aria-label=\"Close drawer\"\n />\n )}\n </div>\n );\n }\n);\n\nDrawerHeader.displayName = \"DrawerHeader\";\n","import React, { memo } from \"react\";\nimport type { DrawerFooterProps } from \"./types\";\n\nconst flattenChildren = (children: React.ReactNode): React.ReactNode[] => {\n const result: React.ReactNode[] = [];\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child) && child.type === React.Fragment) {\n result.push(\n ...flattenChildren(\n (child.props as { children: React.ReactNode }).children\n )\n );\n } else if (child !== null && child !== undefined) {\n result.push(child);\n }\n });\n return result;\n};\n\nexport const DrawerFooter = memo(\n ({ children, align, shadow, fullWidth }: DrawerFooterProps) => {\n const justifyContent = align === \"center\" ? \"center\" : \"flex-end\";\n\n const renderedChildren = fullWidth\n ? flattenChildren(children).map((child, i) =>\n React.isValidElement(child)\n ? React.cloneElement(\n child as React.ReactElement<Record<string, unknown>>,\n {\n key: (child as React.ReactElement).key ?? i,\n fullWidth: true,\n }\n )\n : child\n )\n : children;\n\n return (\n <div\n style={{\n flexShrink: 0,\n width: \"100%\",\n boxShadow: shadow ? \"0px 2px 25px 0px rgba(7, 7, 8, 0.15)\" : \"none\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n justifyContent: fullWidth ? \"stretch\" : justifyContent,\n padding: 16,\n gap: 8,\n }}\n >\n {renderedChildren}\n </div>\n </div>\n );\n }\n);\n\nDrawerFooter.displayName = \"DrawerFooter\";\n","import { useCallback, useState } from \"react\";\n\nexport interface UseDrawerOptions {\n onOpen?: () => void;\n onClose?: () => void;\n}\n\nexport interface UseDrawerReturn {\n isOpen: boolean;\n open: () => void;\n close: () => void;\n}\n\nexport function useDrawer(options?: UseDrawerOptions): UseDrawerReturn {\n const [isOpen, setIsOpen] = useState(false);\n\n const open = useCallback(() => {\n setIsOpen(true);\n options?.onOpen?.();\n }, [options]);\n\n const close = useCallback(() => {\n setIsOpen(false);\n options?.onClose?.();\n }, [options]);\n\n return { isOpen, open, close };\n}\n"],"mappings":"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","names":["memo","jsx","memo","jsx","jsx","jsxs","handleKeyDown","useCallback","useState"]}
|