@idealyst/components 1.2.39 → 1.2.41
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/package.json +4 -3
- package/src/Dialog/Dialog.native.tsx +62 -27
- package/src/Dialog/Dialog.web.tsx +68 -2
- package/src/Dialog/types.ts +18 -1
- package/src/Screen/Screen.native.tsx +5 -1
- package/src/Screen/Screen.styles.tsx +10 -18
- package/src/Screen/Screen.web.tsx +5 -1
- package/src/Select/Select.styles.tsx +2 -1
- package/src/View/View.native.tsx +5 -1
- package/src/View/View.styles.tsx +6 -8
- package/src/View/View.web.tsx +5 -1
- package/src/examples/DialogExamples.tsx +61 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idealyst/components",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.41",
|
|
4
4
|
"description": "Shared component library for React and React Native",
|
|
5
5
|
"documentation": "https://github.com/IdealystIO/idealyst-framework/tree/main/packages/components#readme",
|
|
6
6
|
"readme": "README.md",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"publish:npm": "npm publish"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@idealyst/theme": "^1.2.
|
|
59
|
+
"@idealyst/theme": "^1.2.41",
|
|
60
60
|
"@mdi/js": ">=7.0.0",
|
|
61
61
|
"@mdi/react": ">=1.0.0",
|
|
62
62
|
"@react-native-vector-icons/common": ">=12.0.0",
|
|
@@ -106,7 +106,8 @@
|
|
|
106
106
|
}
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
|
-
"@idealyst/
|
|
109
|
+
"@idealyst/blur": "^1.2.40",
|
|
110
|
+
"@idealyst/theme": "^1.2.41",
|
|
110
111
|
"@idealyst/tooling": "^1.2.30",
|
|
111
112
|
"@mdi/react": "^1.6.1",
|
|
112
113
|
"@types/react": "^19.1.0",
|
|
@@ -18,6 +18,7 @@ const Dialog = forwardRef<View, DialogProps>(({
|
|
|
18
18
|
style,
|
|
19
19
|
testID,
|
|
20
20
|
id,
|
|
21
|
+
BackdropComponent,
|
|
21
22
|
// Accessibility props
|
|
22
23
|
accessibilityLabel,
|
|
23
24
|
accessibilityHint,
|
|
@@ -124,6 +125,56 @@ const Dialog = forwardRef<View, DialogProps>(({
|
|
|
124
125
|
const closeButtonTextStyle = (dialogStyles.closeButtonText as any)({});
|
|
125
126
|
const contentStyle = (dialogStyles.content as any)({});
|
|
126
127
|
|
|
128
|
+
// Style for custom backdrop wrapper (no default backdrop styling)
|
|
129
|
+
const customBackdropWrapperStyle = {
|
|
130
|
+
position: 'absolute' as const,
|
|
131
|
+
top: 0,
|
|
132
|
+
left: 0,
|
|
133
|
+
right: 0,
|
|
134
|
+
bottom: 0,
|
|
135
|
+
display: 'flex' as const,
|
|
136
|
+
alignItems: 'center' as const,
|
|
137
|
+
justifyContent: 'center' as const,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// Style for custom backdrop component container (fills entire backdrop area)
|
|
141
|
+
const customBackdropContainerStyle = {
|
|
142
|
+
position: 'absolute' as const,
|
|
143
|
+
top: 0,
|
|
144
|
+
left: 0,
|
|
145
|
+
right: 0,
|
|
146
|
+
bottom: 0,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const dialogContainer = (
|
|
150
|
+
<TouchableWithoutFeedback onPress={(e: GestureResponderEvent) => e.stopPropagation()}>
|
|
151
|
+
<Animated.View ref={ref as any} style={[containerStyle, style, containerAnimatedStyle]} nativeID={id} {...nativeA11yProps}>
|
|
152
|
+
{(title || showCloseButton) && (
|
|
153
|
+
<View style={headerStyle}>
|
|
154
|
+
{title && (
|
|
155
|
+
<Text style={titleStyle}>
|
|
156
|
+
{title}
|
|
157
|
+
</Text>
|
|
158
|
+
)}
|
|
159
|
+
{showCloseButton && (
|
|
160
|
+
<TouchableOpacity
|
|
161
|
+
style={closeButtonStyle}
|
|
162
|
+
onPress={handleClosePress}
|
|
163
|
+
accessibilityLabel="Close dialog"
|
|
164
|
+
accessibilityRole="button"
|
|
165
|
+
>
|
|
166
|
+
<Text style={closeButtonTextStyle}>×</Text>
|
|
167
|
+
</TouchableOpacity>
|
|
168
|
+
)}
|
|
169
|
+
</View>
|
|
170
|
+
)}
|
|
171
|
+
<View style={contentStyle}>
|
|
172
|
+
{children}
|
|
173
|
+
</View>
|
|
174
|
+
</Animated.View>
|
|
175
|
+
</TouchableWithoutFeedback>
|
|
176
|
+
);
|
|
177
|
+
|
|
127
178
|
return (
|
|
128
179
|
<Modal
|
|
129
180
|
visible={open}
|
|
@@ -134,34 +185,18 @@ const Dialog = forwardRef<View, DialogProps>(({
|
|
|
134
185
|
testID={testID}
|
|
135
186
|
>
|
|
136
187
|
<TouchableWithoutFeedback onPress={handleBackdropPress}>
|
|
137
|
-
|
|
138
|
-
<
|
|
139
|
-
<Animated.View
|
|
140
|
-
{
|
|
141
|
-
<View style={headerStyle}>
|
|
142
|
-
{title && (
|
|
143
|
-
<Text style={titleStyle}>
|
|
144
|
-
{title}
|
|
145
|
-
</Text>
|
|
146
|
-
)}
|
|
147
|
-
{showCloseButton && (
|
|
148
|
-
<TouchableOpacity
|
|
149
|
-
style={closeButtonStyle}
|
|
150
|
-
onPress={handleClosePress}
|
|
151
|
-
accessibilityLabel="Close dialog"
|
|
152
|
-
accessibilityRole="button"
|
|
153
|
-
>
|
|
154
|
-
<Text style={closeButtonTextStyle}>×</Text>
|
|
155
|
-
</TouchableOpacity>
|
|
156
|
-
)}
|
|
157
|
-
</View>
|
|
158
|
-
)}
|
|
159
|
-
<View style={contentStyle}>
|
|
160
|
-
{children}
|
|
161
|
-
</View>
|
|
188
|
+
{BackdropComponent ? (
|
|
189
|
+
<View style={customBackdropWrapperStyle}>
|
|
190
|
+
<Animated.View style={[customBackdropContainerStyle, backdropAnimatedStyle]}>
|
|
191
|
+
<BackdropComponent isVisible={open} />
|
|
162
192
|
</Animated.View>
|
|
163
|
-
|
|
164
|
-
|
|
193
|
+
{dialogContainer}
|
|
194
|
+
</View>
|
|
195
|
+
) : (
|
|
196
|
+
<Animated.View style={[backdropStyle, backdropAnimatedStyle]}>
|
|
197
|
+
{dialogContainer}
|
|
198
|
+
</Animated.View>
|
|
199
|
+
)}
|
|
165
200
|
</TouchableWithoutFeedback>
|
|
166
201
|
</Modal>
|
|
167
202
|
);
|
|
@@ -24,6 +24,7 @@ const Dialog = forwardRef<HTMLDivElement, DialogProps>(({
|
|
|
24
24
|
style,
|
|
25
25
|
testID,
|
|
26
26
|
id,
|
|
27
|
+
BackdropComponent,
|
|
27
28
|
// Accessibility props
|
|
28
29
|
accessibilityLabel,
|
|
29
30
|
accessibilityHint,
|
|
@@ -154,7 +155,73 @@ const Dialog = forwardRef<HTMLDivElement, DialogProps>(({
|
|
|
154
155
|
|
|
155
156
|
const mergedBackdropRef = useMergeRefs(ref, backdropProps.ref);
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
// Styles for the custom backdrop wrapper (no default backdrop styling)
|
|
159
|
+
const customBackdropWrapperStyle: React.CSSProperties = {
|
|
160
|
+
position: 'fixed',
|
|
161
|
+
top: 0,
|
|
162
|
+
left: 0,
|
|
163
|
+
right: 0,
|
|
164
|
+
bottom: 0,
|
|
165
|
+
display: 'flex',
|
|
166
|
+
alignItems: 'center',
|
|
167
|
+
justifyContent: 'center',
|
|
168
|
+
zIndex: 1000,
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
// Styles for the custom backdrop component container (fills the entire backdrop area)
|
|
172
|
+
const customBackdropStyle: React.CSSProperties = {
|
|
173
|
+
position: 'absolute',
|
|
174
|
+
top: 0,
|
|
175
|
+
left: 0,
|
|
176
|
+
right: 0,
|
|
177
|
+
bottom: 0,
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const dialogContent = BackdropComponent ? (
|
|
181
|
+
<div
|
|
182
|
+
ref={mergedBackdropRef}
|
|
183
|
+
style={customBackdropWrapperStyle}
|
|
184
|
+
onClick={handleBackdropClick}
|
|
185
|
+
data-testid={testID}
|
|
186
|
+
>
|
|
187
|
+
<div style={customBackdropStyle}>
|
|
188
|
+
<BackdropComponent isVisible={isVisible} />
|
|
189
|
+
</div>
|
|
190
|
+
<div
|
|
191
|
+
{...containerProps}
|
|
192
|
+
{...ariaProps}
|
|
193
|
+
ref={dialogRef}
|
|
194
|
+
id={dialogId}
|
|
195
|
+
role="dialog"
|
|
196
|
+
aria-modal="true"
|
|
197
|
+
aria-labelledby={title ? titleId : undefined}
|
|
198
|
+
onClick={(e) => e.stopPropagation()}
|
|
199
|
+
>
|
|
200
|
+
{(title || showCloseButton) && (
|
|
201
|
+
<div {...headerProps}>
|
|
202
|
+
{title && (
|
|
203
|
+
<h2 {...titleProps} id={titleId}>
|
|
204
|
+
{title}
|
|
205
|
+
</h2>
|
|
206
|
+
)}
|
|
207
|
+
{showCloseButton && (
|
|
208
|
+
<button
|
|
209
|
+
{...closeButtonProps}
|
|
210
|
+
onClick={handleCloseClick}
|
|
211
|
+
aria-label="Close dialog"
|
|
212
|
+
type="button"
|
|
213
|
+
>
|
|
214
|
+
<Icon name="close" />
|
|
215
|
+
</button>
|
|
216
|
+
)}
|
|
217
|
+
</div>
|
|
218
|
+
)}
|
|
219
|
+
<div {...contentProps}>
|
|
220
|
+
{children}
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
) : (
|
|
158
225
|
<div
|
|
159
226
|
{...backdropProps}
|
|
160
227
|
ref={mergedBackdropRef}
|
|
@@ -169,7 +236,6 @@ const Dialog = forwardRef<HTMLDivElement, DialogProps>(({
|
|
|
169
236
|
role="dialog"
|
|
170
237
|
aria-modal="true"
|
|
171
238
|
aria-labelledby={title ? titleId : undefined}
|
|
172
|
-
tabIndex={-1}
|
|
173
239
|
onClick={(e) => e.stopPropagation()}
|
|
174
240
|
>
|
|
175
241
|
{(title || showCloseButton) && (
|
package/src/Dialog/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
1
|
+
import type { ReactNode, ComponentType } from 'react';
|
|
2
2
|
import type { StyleProp, ViewStyle } from 'react-native';
|
|
3
3
|
import { BaseProps } from '../utils/viewStyleProps';
|
|
4
4
|
import { InteractiveAccessibilityProps } from '../utils/accessibility';
|
|
@@ -8,6 +8,16 @@ export type DialogSizeVariant = 'sm' | 'md' | 'lg' | 'fullscreen';
|
|
|
8
8
|
export type DialogType = 'default' | 'alert' | 'confirmation';
|
|
9
9
|
export type DialogAnimationType = 'slide' | 'fade' | 'none';
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Props passed to custom backdrop components
|
|
13
|
+
*/
|
|
14
|
+
export interface BackdropComponentProps {
|
|
15
|
+
/**
|
|
16
|
+
* Whether the dialog is visible (for animation purposes)
|
|
17
|
+
*/
|
|
18
|
+
isVisible: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
11
21
|
/**
|
|
12
22
|
* Modal dialog component for focused interactions requiring user attention.
|
|
13
23
|
* Supports multiple sizes, animation types, and configurable close behaviors.
|
|
@@ -72,4 +82,11 @@ export interface DialogProps extends BaseProps, InteractiveAccessibilityProps {
|
|
|
72
82
|
* Test ID for testing
|
|
73
83
|
*/
|
|
74
84
|
testID?: string;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Custom backdrop component that replaces the default backdrop.
|
|
88
|
+
* The component will be rendered as a full-screen overlay behind the dialog.
|
|
89
|
+
* It receives isVisible for animation coordination.
|
|
90
|
+
*/
|
|
91
|
+
BackdropComponent?: ComponentType<BackdropComponentProps>;
|
|
75
92
|
}
|
|
@@ -26,9 +26,13 @@ const Screen = forwardRef<IdealystElement, ScreenProps>(({
|
|
|
26
26
|
}, ref) => {
|
|
27
27
|
const insets = useSafeAreaInsets();
|
|
28
28
|
|
|
29
|
+
// Handle 'transparent' background separately since it's not a surface color key
|
|
30
|
+
// The $surface iterator only expands to actual surface color keys
|
|
31
|
+
const backgroundVariant = background === 'transparent' ? undefined : background;
|
|
32
|
+
|
|
29
33
|
// Set active variants for this render
|
|
30
34
|
screenStyles.useVariants({
|
|
31
|
-
background,
|
|
35
|
+
background: backgroundVariant,
|
|
32
36
|
safeArea,
|
|
33
37
|
gap,
|
|
34
38
|
padding,
|
|
@@ -5,6 +5,7 @@ import { StyleSheet } from 'react-native-unistyles';
|
|
|
5
5
|
import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
|
|
6
6
|
import type { Theme as BaseTheme } from '@idealyst/theme';
|
|
7
7
|
import { ViewStyleSize } from '../utils/viewStyleProps';
|
|
8
|
+
import type { Surface } from '@idealyst/theme';
|
|
8
9
|
|
|
9
10
|
// Required: Unistyles must see StyleSheet usage in original source to process this file
|
|
10
11
|
void StyleSheet;
|
|
@@ -12,7 +13,8 @@ void StyleSheet;
|
|
|
12
13
|
// Wrap theme for $iterator support
|
|
13
14
|
type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
// Background type is derived from Surface color keys plus 'transparent'
|
|
17
|
+
type ScreenBackground = Surface | 'transparent';
|
|
16
18
|
|
|
17
19
|
export type ScreenDynamicProps = {
|
|
18
20
|
background?: ScreenBackground;
|
|
@@ -27,23 +29,19 @@ export type ScreenDynamicProps = {
|
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
/**
|
|
30
|
-
* Screen styles with $iterator expansion for spacing variants.
|
|
32
|
+
* Screen styles with $iterator expansion for spacing and background variants.
|
|
31
33
|
*
|
|
32
34
|
* NOTE: Top-level theme access required for Unistyles reactivity.
|
|
35
|
+
* The background variant uses $surface iterator to expand to all surface color keys.
|
|
33
36
|
*/
|
|
34
37
|
export const screenStyles = defineStyle('Screen', (theme: Theme) => ({
|
|
35
38
|
screen: (_props: ScreenDynamicProps) => ({
|
|
36
39
|
flex: 1,
|
|
37
40
|
variants: {
|
|
41
|
+
// $iterator expands for each surface color key
|
|
38
42
|
background: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
secondary: { backgroundColor: theme.colors.surface.secondary },
|
|
42
|
-
tertiary: { backgroundColor: theme.colors.surface.tertiary },
|
|
43
|
-
inverse: { backgroundColor: theme.colors.surface.inverse },
|
|
44
|
-
'inverse-secondary': { backgroundColor: theme.colors.surface['inverse-secondary'] },
|
|
45
|
-
'inverse-tertiary': { backgroundColor: theme.colors.surface['inverse-tertiary'] },
|
|
46
|
-
transparent: { backgroundColor: 'transparent' },
|
|
43
|
+
backgroundColor: theme.colors.$surface,
|
|
44
|
+
// 'transparent' is handled separately via compound variant or default
|
|
47
45
|
},
|
|
48
46
|
safeArea: {
|
|
49
47
|
true: {},
|
|
@@ -81,15 +79,9 @@ export const screenStyles = defineStyle('Screen', (theme: Theme) => ({
|
|
|
81
79
|
|
|
82
80
|
screenContent: (_props: ScreenDynamicProps) => ({
|
|
83
81
|
variants: {
|
|
82
|
+
// $iterator expands for each surface color key
|
|
84
83
|
background: {
|
|
85
|
-
|
|
86
|
-
primary: { backgroundColor: theme.colors.surface.primary },
|
|
87
|
-
secondary: { backgroundColor: theme.colors.surface.secondary },
|
|
88
|
-
tertiary: { backgroundColor: theme.colors.surface.tertiary },
|
|
89
|
-
inverse: { backgroundColor: theme.colors.surface.inverse },
|
|
90
|
-
'inverse-secondary': { backgroundColor: theme.colors.surface['inverse-secondary'] },
|
|
91
|
-
'inverse-tertiary': { backgroundColor: theme.colors.surface['inverse-tertiary'] },
|
|
92
|
-
transparent: { backgroundColor: 'transparent' },
|
|
84
|
+
backgroundColor: theme.colors.$surface,
|
|
93
85
|
},
|
|
94
86
|
safeArea: {
|
|
95
87
|
true: {},
|
|
@@ -29,8 +29,12 @@ const Screen = forwardRef<IdealystElement, ScreenProps>(({
|
|
|
29
29
|
}, ref) => {
|
|
30
30
|
const layoutRef = useWebLayout<HTMLDivElement>(onLayout);
|
|
31
31
|
|
|
32
|
+
// Handle 'transparent' background separately since it's not a surface color key
|
|
33
|
+
// The $surface iterator only expands to actual surface color keys
|
|
34
|
+
const backgroundVariant = background === 'transparent' ? undefined : background;
|
|
35
|
+
|
|
32
36
|
screenStyles.useVariants({
|
|
33
|
-
background,
|
|
37
|
+
background: backgroundVariant,
|
|
34
38
|
safeArea,
|
|
35
39
|
gap,
|
|
36
40
|
padding,
|
|
@@ -33,7 +33,7 @@ export const selectStyles = defineStyle('Select', (theme: Theme) => ({
|
|
|
33
33
|
container: (_props: SelectDynamicProps) => ({
|
|
34
34
|
position: 'relative' as const,
|
|
35
35
|
_web: {
|
|
36
|
-
display: '
|
|
36
|
+
display: 'flex',
|
|
37
37
|
flexDirection: 'column',
|
|
38
38
|
},
|
|
39
39
|
variants: {
|
|
@@ -82,6 +82,7 @@ export const selectStyles = defineStyle('Select', (theme: Theme) => ({
|
|
|
82
82
|
},
|
|
83
83
|
_web: {
|
|
84
84
|
display: 'flex',
|
|
85
|
+
width: '100%',
|
|
85
86
|
boxSizing: 'border-box',
|
|
86
87
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
87
88
|
border: `1px solid ${borderColor}`,
|
package/src/View/View.native.tsx
CHANGED
|
@@ -47,9 +47,13 @@ const View = forwardRef<IdealystElement, ViewProps>(({
|
|
|
47
47
|
id,
|
|
48
48
|
onLayout,
|
|
49
49
|
}, ref) => {
|
|
50
|
+
// Handle 'transparent' background separately since it's not a surface color key
|
|
51
|
+
// The $surface iterator only expands to actual surface color keys
|
|
52
|
+
const backgroundVariant = background === 'transparent' ? undefined : background;
|
|
53
|
+
|
|
50
54
|
// Set active variants for this render
|
|
51
55
|
viewStyles.useVariants({
|
|
52
|
-
background,
|
|
56
|
+
background: backgroundVariant,
|
|
53
57
|
radius,
|
|
54
58
|
border,
|
|
55
59
|
gap,
|
package/src/View/View.styles.tsx
CHANGED
|
@@ -29,10 +29,12 @@ export type ViewVariants = {
|
|
|
29
29
|
export type ViewDynamicProps = Partial<ViewVariants>;
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* View styles with $iterator expansion for spacing variants.
|
|
32
|
+
* View styles with $iterator expansion for spacing and background variants.
|
|
33
33
|
*
|
|
34
34
|
* NOTE: At least one top-level theme access is required for Unistyles to trace
|
|
35
35
|
* theme dependencies. We use a transparent borderColor as a marker.
|
|
36
|
+
*
|
|
37
|
+
* The background variant uses $surface iterator to expand to all surface color keys.
|
|
36
38
|
*/
|
|
37
39
|
export const viewStyles = defineStyle('View', (theme: Theme) => ({
|
|
38
40
|
view: (_props: ViewDynamicProps) => ({
|
|
@@ -41,14 +43,10 @@ export const viewStyles = defineStyle('View', (theme: Theme) => ({
|
|
|
41
43
|
borderColor: theme.colors.border.primary,
|
|
42
44
|
borderWidth: 0,
|
|
43
45
|
variants: {
|
|
46
|
+
// $iterator expands for each surface color key
|
|
44
47
|
background: {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
secondary: { backgroundColor: theme.colors.surface.secondary },
|
|
48
|
-
tertiary: { backgroundColor: theme.colors.surface.tertiary },
|
|
49
|
-
inverse: { backgroundColor: theme.colors.surface.inverse },
|
|
50
|
-
'inverse-secondary': { backgroundColor: theme.colors.surface['inverse-secondary'] },
|
|
51
|
-
'inverse-tertiary': { backgroundColor: theme.colors.surface['inverse-tertiary'] },
|
|
48
|
+
backgroundColor: theme.colors.$surface,
|
|
49
|
+
// 'transparent' is handled as a special case
|
|
52
50
|
},
|
|
53
51
|
radius: {
|
|
54
52
|
none: { borderRadius: 0 },
|
package/src/View/View.web.tsx
CHANGED
|
@@ -36,8 +36,12 @@ const View = forwardRef<IdealystElement, ViewProps>(({
|
|
|
36
36
|
}, ref) => {
|
|
37
37
|
const layoutRef = useWebLayout<HTMLDivElement>(onLayout);
|
|
38
38
|
|
|
39
|
+
// Handle 'transparent' background separately since it's not a surface color key
|
|
40
|
+
// The $surface iterator only expands to actual surface color keys
|
|
41
|
+
const backgroundVariant = background === 'transparent' ? undefined : background;
|
|
42
|
+
|
|
39
43
|
viewStyles.useVariants({
|
|
40
|
-
background,
|
|
44
|
+
background: backgroundVariant,
|
|
41
45
|
radius,
|
|
42
46
|
border,
|
|
43
47
|
gap,
|
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { Screen, View, Button, Text, Dialog } from '../index';
|
|
3
|
+
import { BlurView } from '@idealyst/blur';
|
|
4
|
+
import type { BackdropComponentProps } from '../Dialog/types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Custom blur backdrop component for dialogs.
|
|
8
|
+
* Uses @idealyst/blur to create a frosted glass effect over the content.
|
|
9
|
+
*/
|
|
10
|
+
const BlurBackdrop = ({ isVisible }: BackdropComponentProps) => (
|
|
11
|
+
<BlurView
|
|
12
|
+
intensity={isVisible ? 80 : 0}
|
|
13
|
+
blurType="dark"
|
|
14
|
+
style={{
|
|
15
|
+
flex: 1,
|
|
16
|
+
width: '100%',
|
|
17
|
+
height: '100%',
|
|
18
|
+
}}
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
3
21
|
|
|
4
22
|
export const DialogExamples = () => {
|
|
5
23
|
const [basicOpen, setBasicOpen] = useState(false);
|
|
6
24
|
const [alertOpen, setAlertOpen] = useState(false);
|
|
7
25
|
const [confirmationOpen, setConfirmationOpen] = useState(false);
|
|
8
26
|
const [sizesOpen, setSizesOpen] = useState<string | null>(null);
|
|
27
|
+
const [blurBackdropOpen, setBlurBackdropOpen] = useState(false);
|
|
9
28
|
|
|
10
29
|
return (
|
|
11
30
|
<Screen background="primary" padding="lg">
|
|
@@ -22,7 +41,7 @@ export const DialogExamples = () => {
|
|
|
22
41
|
</Button>
|
|
23
42
|
<Dialog
|
|
24
43
|
open={basicOpen}
|
|
25
|
-
|
|
44
|
+
onClose={() => setBasicOpen(false)}
|
|
26
45
|
title="Basic Dialog"
|
|
27
46
|
>
|
|
28
47
|
<Text>This is a basic dialog with a title and some content.</Text>
|
|
@@ -53,7 +72,7 @@ export const DialogExamples = () => {
|
|
|
53
72
|
{/* Alert Dialog */}
|
|
54
73
|
<Dialog
|
|
55
74
|
open={alertOpen}
|
|
56
|
-
|
|
75
|
+
onClose={() => setAlertOpen(false)}
|
|
57
76
|
title="Important Alert"
|
|
58
77
|
type="alert"
|
|
59
78
|
>
|
|
@@ -72,7 +91,7 @@ export const DialogExamples = () => {
|
|
|
72
91
|
{/* Confirmation Dialog */}
|
|
73
92
|
<Dialog
|
|
74
93
|
open={confirmationOpen}
|
|
75
|
-
|
|
94
|
+
onClose={() => setConfirmationOpen(false)}
|
|
76
95
|
title="Confirm Action"
|
|
77
96
|
type="confirmation"
|
|
78
97
|
closeOnBackdropClick={false}
|
|
@@ -114,7 +133,7 @@ export const DialogExamples = () => {
|
|
|
114
133
|
{sizesOpen && (
|
|
115
134
|
<Dialog
|
|
116
135
|
open={!!sizesOpen}
|
|
117
|
-
|
|
136
|
+
onClose={() => setSizesOpen(null)}
|
|
118
137
|
title={`${sizesOpen === 'sm' ? 'Small' : sizesOpen === 'md' ? 'Medium' : 'Large'} Dialog`}
|
|
119
138
|
size={sizesOpen as 'sm' | 'md' | 'lg'}
|
|
120
139
|
>
|
|
@@ -135,6 +154,41 @@ export const DialogExamples = () => {
|
|
|
135
154
|
</View>
|
|
136
155
|
|
|
137
156
|
|
|
157
|
+
{/* Custom Blur Backdrop */}
|
|
158
|
+
<View gap="md">
|
|
159
|
+
<Text typography="subtitle1">Custom Blur Backdrop</Text>
|
|
160
|
+
<Text typography="caption" color="secondary">
|
|
161
|
+
Use the BackdropComponent prop to create a custom blur backdrop using @idealyst/blur.
|
|
162
|
+
</Text>
|
|
163
|
+
<Button onPress={() => setBlurBackdropOpen(true)}>
|
|
164
|
+
Open Dialog with Blur Backdrop
|
|
165
|
+
</Button>
|
|
166
|
+
<Dialog
|
|
167
|
+
open={blurBackdropOpen}
|
|
168
|
+
onClose={() => setBlurBackdropOpen(false)}
|
|
169
|
+
title="Blur Backdrop Dialog"
|
|
170
|
+
BackdropComponent={BlurBackdrop}
|
|
171
|
+
>
|
|
172
|
+
<Text>
|
|
173
|
+
This dialog uses a custom backdrop component with @idealyst/blur to create
|
|
174
|
+
a frosted glass effect over the background content.
|
|
175
|
+
</Text>
|
|
176
|
+
<View gap="md" style={{ marginTop: 16 }}>
|
|
177
|
+
<Text typography="caption" color="secondary">
|
|
178
|
+
The blur intensity animates based on the isVisible prop passed to the
|
|
179
|
+
BackdropComponent.
|
|
180
|
+
</Text>
|
|
181
|
+
<Button
|
|
182
|
+
type="contained"
|
|
183
|
+
intent="primary"
|
|
184
|
+
onPress={() => setBlurBackdropOpen(false)}
|
|
185
|
+
>
|
|
186
|
+
Close
|
|
187
|
+
</Button>
|
|
188
|
+
</View>
|
|
189
|
+
</Dialog>
|
|
190
|
+
</View>
|
|
191
|
+
|
|
138
192
|
{/* Dialog Options */}
|
|
139
193
|
<View gap="md">
|
|
140
194
|
<Text typography="subtitle1">Dialog Options</Text>
|
|
@@ -150,6 +204,9 @@ export const DialogExamples = () => {
|
|
|
150
204
|
<Text typography="caption" color="secondary">
|
|
151
205
|
• Focus management: Automatic focus trapping and restoration (web only)
|
|
152
206
|
</Text>
|
|
207
|
+
<Text typography="caption" color="secondary">
|
|
208
|
+
• Custom backdrop: Use BackdropComponent prop for custom effects like blur
|
|
209
|
+
</Text>
|
|
153
210
|
</View>
|
|
154
211
|
</View>
|
|
155
212
|
</Screen>
|