@expo/ui 55.0.5 → 55.0.6

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.
Files changed (92) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/AlertDialogView.kt +56 -28
  4. package/android/src/main/java/expo/modules/ui/BasicAlertDialogView.kt +9 -1
  5. package/android/src/main/java/expo/modules/ui/DividerView.kt +21 -2
  6. package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +15 -15
  7. package/android/src/main/java/expo/modules/ui/ModifierRegistry.kt +6 -0
  8. package/android/src/main/java/expo/modules/ui/PullToRefreshBoxView.kt +20 -3
  9. package/android/src/main/java/expo/modules/ui/SlotView.kt +8 -0
  10. package/android/src/main/java/expo/modules/ui/SurfaceView.kt +88 -11
  11. package/android/src/main/java/expo/modules/ui/TextInputView.kt +15 -3
  12. package/android/src/main/java/expo/modules/ui/TextView.kt +145 -12
  13. package/build/jetpack-compose/AlertDialog/index.d.ts +72 -36
  14. package/build/jetpack-compose/AlertDialog/index.d.ts.map +1 -1
  15. package/build/jetpack-compose/BasicAlertDialog/index.d.ts +7 -2
  16. package/build/jetpack-compose/BasicAlertDialog/index.d.ts.map +1 -1
  17. package/build/jetpack-compose/Card/index.d.ts.map +1 -1
  18. package/build/jetpack-compose/Divider/index.d.ts +20 -5
  19. package/build/jetpack-compose/Divider/index.d.ts.map +1 -1
  20. package/build/jetpack-compose/Progress/index.d.ts.map +1 -1
  21. package/build/jetpack-compose/PullToRefreshBox/index.d.ts +34 -9
  22. package/build/jetpack-compose/PullToRefreshBox/index.d.ts.map +1 -1
  23. package/build/jetpack-compose/Surface/index.d.ts +52 -2
  24. package/build/jetpack-compose/Surface/index.d.ts.map +1 -1
  25. package/build/jetpack-compose/Text/index.d.ts +77 -89
  26. package/build/jetpack-compose/Text/index.d.ts.map +1 -1
  27. package/build/jetpack-compose/TextInput/index.d.ts +18 -3
  28. package/build/jetpack-compose/TextInput/index.d.ts.map +1 -1
  29. package/build/jetpack-compose/index.d.ts +2 -2
  30. package/build/jetpack-compose/index.d.ts.map +1 -1
  31. package/build/jetpack-compose/modifiers/index.d.ts +5 -0
  32. package/build/jetpack-compose/modifiers/index.d.ts.map +1 -1
  33. package/build/swift-ui/modifiers/index.d.ts +1 -1
  34. package/build/types.d.ts +26 -0
  35. package/build/types.d.ts.map +1 -1
  36. package/expo-module.config.json +1 -1
  37. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.5/expo.modules.ui-55.0.5-sources.jar → 55.0.6/expo.modules.ui-55.0.6-sources.jar} +0 -0
  38. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6-sources.jar.md5 +1 -0
  39. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6-sources.jar.sha1 +1 -0
  40. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6-sources.jar.sha256 +1 -0
  41. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6-sources.jar.sha512 +1 -0
  42. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.aar +0 -0
  43. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.aar.md5 +1 -0
  44. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.aar.sha1 +1 -0
  45. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.aar.sha256 +1 -0
  46. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.aar.sha512 +1 -0
  47. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.5/expo.modules.ui-55.0.5.module → 55.0.6/expo.modules.ui-55.0.6.module} +22 -22
  48. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.module.md5 +1 -0
  49. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.module.sha1 +1 -0
  50. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.module.sha256 +1 -0
  51. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.module.sha512 +1 -0
  52. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.5/expo.modules.ui-55.0.5.pom → 55.0.6/expo.modules.ui-55.0.6.pom} +1 -1
  53. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.pom.md5 +1 -0
  54. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.pom.sha1 +1 -0
  55. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.pom.sha256 +1 -0
  56. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.6/expo.modules.ui-55.0.6.pom.sha512 +1 -0
  57. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  58. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  59. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  60. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  61. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  62. package/package.json +2 -2
  63. package/src/jetpack-compose/AlertDialog/index.tsx +94 -41
  64. package/src/jetpack-compose/BasicAlertDialog/index.tsx +9 -2
  65. package/src/jetpack-compose/Card/index.tsx +4 -2
  66. package/src/jetpack-compose/Divider/index.tsx +34 -14
  67. package/src/jetpack-compose/Progress/index.tsx +4 -2
  68. package/src/jetpack-compose/PullToRefreshBox/index.tsx +35 -18
  69. package/src/jetpack-compose/Surface/index.tsx +75 -4
  70. package/src/jetpack-compose/Text/index.tsx +171 -101
  71. package/src/jetpack-compose/TextInput/index.tsx +38 -8
  72. package/src/jetpack-compose/index.ts +2 -2
  73. package/src/jetpack-compose/modifiers/index.ts +10 -0
  74. package/src/swift-ui/modifiers/index.ts +1 -1
  75. package/src/types.ts +27 -0
  76. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.md5 +0 -1
  77. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.sha1 +0 -1
  78. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.sha256 +0 -1
  79. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5-sources.jar.sha512 +0 -1
  80. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar +0 -0
  81. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.md5 +0 -1
  82. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.sha1 +0 -1
  83. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.sha256 +0 -1
  84. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.aar.sha512 +0 -1
  85. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.md5 +0 -1
  86. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.sha1 +0 -1
  87. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.sha256 +0 -1
  88. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.module.sha512 +0 -1
  89. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.md5 +0 -1
  90. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.sha1 +0 -1
  91. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.sha256 +0 -1
  92. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.5/expo.modules.ui-55.0.5.pom.sha512 +0 -1
@@ -1,85 +1,138 @@
1
1
  import { requireNativeView } from 'expo';
2
2
  import { type ColorValue } from 'react-native';
3
3
 
4
- import { ExpoModifier } from '../../types';
4
+ import { type ViewEvent, type ModifierConfig, type DialogProperties } from '../../types';
5
5
  import { createViewModifierEventListener } from '../modifiers/utils';
6
6
 
7
- export type AlertDialogButtonColors = {
7
+ /**
8
+ * Colors for the alert dialog, matching `AlertDialogDefaults` in Compose.
9
+ */
10
+ export type AlertDialogColors = {
8
11
  /**
9
- * The background color of the button.
12
+ * The background color of the dialog.
10
13
  */
11
14
  containerColor?: ColorValue;
12
15
  /**
13
- * The text color of the button.
14
- */
15
- contentColor?: ColorValue;
16
- };
17
-
18
- export type AlertDialogProps = {
19
- /**
20
- * The title of the alert dialog.
16
+ * The color of the icon.
21
17
  */
22
- title?: string;
18
+ iconContentColor?: ColorValue;
23
19
  /**
24
- * The text of the alert dialog.
20
+ * The color of the title text.
25
21
  */
26
- text?: string;
22
+ titleContentColor?: ColorValue;
27
23
  /**
28
- * The text of the confirm button of the alert dialog.
24
+ * The color of the body text.
29
25
  */
30
- confirmButtonText?: string;
31
- /**
32
- * The text of the dismiss button of the alert dialog.
33
- */
34
- dismissButtonText?: string;
26
+ textContentColor?: ColorValue;
27
+ };
28
+
29
+ export type AlertDialogProps = {
35
30
  /**
36
- * The colors for the confirm button.
31
+ * Colors for the alert dialog.
37
32
  */
38
- confirmButtonColors?: AlertDialogButtonColors;
33
+ colors?: AlertDialogColors;
39
34
  /**
40
- * The colors for the dismiss button.
35
+ * The tonal elevation of the dialog in dp, which affects its background color
36
+ * based on the color scheme.
41
37
  */
42
- dismissButtonColors?: AlertDialogButtonColors;
38
+ tonalElevation?: number;
43
39
  /**
44
- * Whether the alert dialog is visible.
45
- *
46
- * @default false
40
+ * Properties for the dialog window.
47
41
  */
48
- visible?: boolean;
42
+ properties?: DialogProperties;
49
43
  /**
50
- * Callback that is called when the user tries to confirm the dialog.
44
+ * Callback that is called when the user tries to dismiss the dialog
45
+ * (for example, by tapping outside of it or pressing the back button).
51
46
  */
52
- onConfirmPressed?: () => void;
47
+ onDismissRequest?: () => void;
53
48
  /**
54
- * Callback that is called when the user tries to dismiss the dialog.
49
+ * Modifiers for the component.
55
50
  */
56
- onDismissPressed?: () => void;
57
-
51
+ modifiers?: ModifierConfig[];
58
52
  /**
59
- * Modifiers for the component.
53
+ * Children containing slot sub-components (`AlertDialog.Title`, `AlertDialog.Text`,
54
+ * `AlertDialog.ConfirmButton`, `AlertDialog.DismissButton`, `AlertDialog.Icon`).
60
55
  */
61
- modifiers?: ExpoModifier[];
56
+ children?: React.ReactNode;
62
57
  };
63
58
 
64
- export type NativeAlertDialogProps = AlertDialogProps;
59
+ type NativeAlertDialogProps = Omit<AlertDialogProps, 'onDismissRequest'> &
60
+ ViewEvent<'onDismissRequest', { onDismissRequest?: () => void }>;
65
61
 
66
62
  const AlertDialogNativeView: React.ComponentType<NativeAlertDialogProps> = requireNativeView(
67
63
  'ExpoUI',
68
64
  'AlertDialogView'
69
65
  );
70
66
 
71
- function transformProps(props: AlertDialogProps): NativeAlertDialogProps {
72
- const { modifiers, ...restProps } = props;
67
+ const SlotNativeView: React.ComponentType<{ slotName: string; children: React.ReactNode }> =
68
+ requireNativeView('ExpoUI', 'SlotView');
69
+
70
+ function transformProps(
71
+ props: Omit<AlertDialogProps, 'children'>
72
+ ): Omit<NativeAlertDialogProps, 'children'> {
73
+ const { modifiers, onDismissRequest, ...restProps } = props;
73
74
  return {
74
75
  modifiers,
75
76
  ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
76
77
  ...restProps,
78
+ onDismissRequest: () => {
79
+ onDismissRequest?.();
80
+ },
77
81
  };
78
82
  }
79
83
 
80
84
  /**
81
- * Renders an `AlertDialog` component.
85
+ * The title slot of the `AlertDialog`.
86
+ */
87
+ function AlertDialogTitle(props: { children: React.ReactNode }) {
88
+ return <SlotNativeView slotName="title">{props.children}</SlotNativeView>;
89
+ }
90
+
91
+ /**
92
+ * The text (body) slot of the `AlertDialog`.
82
93
  */
83
- export function AlertDialog(props: AlertDialogProps) {
84
- return <AlertDialogNativeView {...transformProps(props)} />;
94
+ function AlertDialogText(props: { children: React.ReactNode }) {
95
+ return <SlotNativeView slotName="text">{props.children}</SlotNativeView>;
85
96
  }
97
+
98
+ /**
99
+ * The confirm button slot of the `AlertDialog`.
100
+ */
101
+ function AlertDialogConfirmButton(props: { children: React.ReactNode }) {
102
+ return <SlotNativeView slotName="confirmButton">{props.children}</SlotNativeView>;
103
+ }
104
+
105
+ /**
106
+ * The dismiss button slot of the `AlertDialog`.
107
+ */
108
+ function AlertDialogDismissButton(props: { children: React.ReactNode }) {
109
+ return <SlotNativeView slotName="dismissButton">{props.children}</SlotNativeView>;
110
+ }
111
+
112
+ /**
113
+ * The icon slot of the `AlertDialog`.
114
+ */
115
+ function AlertDialogIcon(props: { children: React.ReactNode }) {
116
+ return <SlotNativeView slotName="icon">{props.children}</SlotNativeView>;
117
+ }
118
+
119
+ /**
120
+ * Renders an `AlertDialog` component with slot-based content matching the Compose API.
121
+ * Content is provided via slot sub-components: `AlertDialog.Title`, `AlertDialog.Text`,
122
+ * `AlertDialog.ConfirmButton`, `AlertDialog.DismissButton`, and `AlertDialog.Icon`.
123
+ */
124
+ function AlertDialogComponent(props: AlertDialogProps) {
125
+ const { children, ...restProps } = props;
126
+ return <AlertDialogNativeView {...transformProps(restProps)}>{children}</AlertDialogNativeView>;
127
+ }
128
+
129
+ AlertDialogComponent.Title = AlertDialogTitle;
130
+ AlertDialogComponent.Text = AlertDialogText;
131
+ AlertDialogComponent.ConfirmButton = AlertDialogConfirmButton;
132
+ AlertDialogComponent.DismissButton = AlertDialogDismissButton;
133
+ AlertDialogComponent.Icon = AlertDialogIcon;
134
+
135
+ export { AlertDialogComponent as AlertDialog };
136
+
137
+ // Re-exported so the docs generator includes DialogProperties on the AlertDialog API page.
138
+ export type { DialogProperties };
@@ -1,6 +1,6 @@
1
1
  import { requireNativeView } from 'expo';
2
2
 
3
- import { type ViewEvent, type ExpoModifier } from '../../types';
3
+ import { type ViewEvent, type ModifierConfig, type DialogProperties } from '../../types';
4
4
  import { createViewModifierEventListener } from '../modifiers/utils';
5
5
 
6
6
  export type BasicAlertDialogProps = {
@@ -13,10 +13,14 @@ export type BasicAlertDialogProps = {
13
13
  * (e.g. by tapping outside of it or pressing the back button).
14
14
  */
15
15
  onDismissRequest?: () => void;
16
+ /**
17
+ * Properties for the dialog window.
18
+ */
19
+ properties?: DialogProperties;
16
20
  /**
17
21
  * Modifiers for the component.
18
22
  */
19
- modifiers?: ExpoModifier[];
23
+ modifiers?: ModifierConfig[];
20
24
  };
21
25
 
22
26
  type NativeBasicAlertDialogProps = Omit<BasicAlertDialogProps, 'onDismissRequest'> &
@@ -49,3 +53,6 @@ function transformProps(props: BasicAlertDialogProps): NativeBasicAlertDialogPro
49
53
  export function BasicAlertDialog(props: BasicAlertDialogProps) {
50
54
  return <BasicAlertDialogNativeView {...transformProps(props)} />;
51
55
  }
56
+
57
+ // Re-exported so the docs generator includes DialogProperties on the BasicAlertDialog API page.
58
+ export type { DialogProperties };
@@ -40,9 +40,11 @@ function createCardComponent<P extends { modifiers?: ModifierConfig[] }>(
40
40
  viewName: string
41
41
  ): React.ComponentType<P> {
42
42
  const NativeView: React.ComponentType<P> = requireNativeView('ExpoUI', viewName);
43
- return function CardComponent(props: P) {
43
+ function Component(props: P) {
44
44
  return <NativeView {...transformProps(props)} />;
45
- };
45
+ }
46
+ Component.displayName = viewName;
47
+ return Component;
46
48
  }
47
49
 
48
50
  // region Card
@@ -1,22 +1,25 @@
1
1
  import { requireNativeView } from 'expo';
2
+ import { type ColorValue } from 'react-native';
2
3
 
3
- import { ExpoModifier } from '../../types';
4
+ import { type ModifierConfig } from '../../types';
4
5
  import { createViewModifierEventListener } from '../modifiers/utils';
5
6
 
6
- export type DividerProps = {
7
+ export type DividerCommonConfig = {
8
+ /**
9
+ * Thickness of the divider line. Accepts dp values; use `StyleSheet.hairlineWidth` for a single-pixel line.
10
+ */
11
+ thickness?: number;
12
+ /**
13
+ * Color of the divider line.
14
+ */
15
+ color?: ColorValue;
7
16
  /**
8
17
  * Modifiers for the component.
9
18
  */
10
- modifiers?: ExpoModifier[];
19
+ modifiers?: ModifierConfig[];
11
20
  };
12
21
 
13
- type NativeDividerProps = DividerProps;
14
- const DividerNativeView: React.ComponentType<NativeDividerProps> = requireNativeView(
15
- 'ExpoUI',
16
- 'DividerView'
17
- );
18
-
19
- function transformProps(props: DividerProps): NativeDividerProps {
22
+ function transformProps(props: DividerCommonConfig): DividerCommonConfig {
20
23
  const { modifiers, ...restProps } = props;
21
24
  return {
22
25
  modifiers,
@@ -25,9 +28,26 @@ function transformProps(props: DividerProps): NativeDividerProps {
25
28
  };
26
29
  }
27
30
 
31
+ function createDividerComponent(viewName: string): React.ComponentType<DividerCommonConfig> {
32
+ const NativeView: React.ComponentType<DividerCommonConfig> = requireNativeView(
33
+ 'ExpoUI',
34
+ viewName
35
+ );
36
+ function Component(props: DividerCommonConfig) {
37
+ return <NativeView {...transformProps(props)} />;
38
+ }
39
+ Component.displayName = viewName;
40
+ return Component;
41
+ }
42
+
28
43
  /**
29
- * A visual element that can be used to separate other content.
44
+ * A horizontal divider line that groups content in lists and layouts,
45
+ * matching Compose's `HorizontalDivider`.
30
46
  */
31
- export function Divider(props: DividerProps) {
32
- return <DividerNativeView {...transformProps(props)} />;
33
- }
47
+ export const HorizontalDivider = createDividerComponent('HorizontalDividerView');
48
+
49
+ /**
50
+ * A vertical divider line that groups content in layouts,
51
+ * matching Compose's `VerticalDivider`.
52
+ */
53
+ export const VerticalDivider = createDividerComponent('VerticalDividerView');
@@ -44,9 +44,11 @@ function createProgressComponent<P extends ProgressCommonConfig>(
44
44
  viewName: string
45
45
  ): React.ComponentType<P> {
46
46
  const NativeView: React.ComponentType<P> = requireNativeView('ExpoUI', viewName);
47
- return function ProgressComponent(props: P) {
47
+ function Component(props: P) {
48
48
  return <NativeView {...transformProps(props)} />;
49
- };
49
+ }
50
+ Component.displayName = viewName;
51
+ return Component;
50
52
  }
51
53
 
52
54
  // region LinearProgressIndicator
@@ -1,9 +1,30 @@
1
1
  import { requireNativeView } from 'expo';
2
+ import { type ColorValue } from 'react-native';
2
3
 
3
- import { type ViewEvent, type ExpoModifier } from '../../types';
4
- import { align } from '../modifiers';
4
+ import { type ViewEvent, type ModifierConfig } from '../../types';
5
+ import { type ContentAlignment } from '../layout-types';
5
6
  import { createViewModifierEventListener } from '../modifiers/utils';
6
7
 
8
+ /**
9
+ * Configuration for the loading indicator shown during pull-to-refresh.
10
+ */
11
+ export type PullToRefreshIndicatorProps = {
12
+ /**
13
+ * Color of the loading indicator spinner.
14
+ * @default MaterialTheme.colorScheme.primary
15
+ */
16
+ color?: ColorValue;
17
+ /**
18
+ * Background color of the loading indicator container.
19
+ * @default MaterialTheme.colorScheme.surfaceContainerHigh
20
+ */
21
+ containerColor?: ColorValue;
22
+ /**
23
+ * Modifiers for the loading indicator.
24
+ */
25
+ modifiers?: ModifierConfig[];
26
+ };
27
+
7
28
  export type PullToRefreshBoxProps = {
8
29
  /**
9
30
  * Whether the content is refreshing.
@@ -11,20 +32,22 @@ export type PullToRefreshBoxProps = {
11
32
  */
12
33
  isRefreshing?: boolean;
13
34
  /**
14
- * Callback to call when the content is refreshed.
35
+ * Callback that is called when the user pulls to refresh.
15
36
  */
16
37
  onRefresh?: () => void;
17
38
  /**
18
- * Modifiers for the component.
39
+ * Alignment of children within the box.
40
+ * @default 'topStart'
19
41
  */
20
- modifiers?: ExpoModifier[];
21
-
42
+ contentAlignment?: ContentAlignment;
22
43
  /**
23
- * Modifiers for the loading indicator.
24
- * @default [align('topCenter'), padding(0, 10, 0, 0)]
44
+ * Configuration for the loading indicator shown during pull-to-refresh.
25
45
  */
26
- loadingIndicatorModifiers?: ExpoModifier[];
27
-
46
+ indicator?: PullToRefreshIndicatorProps;
47
+ /**
48
+ * Modifiers for the component.
49
+ */
50
+ modifiers?: ModifierConfig[];
28
51
  /**
29
52
  * The content to refresh.
30
53
  */
@@ -40,11 +63,6 @@ const NativePullToRefreshBoxView: React.ComponentType<NativePullToRefreshBoxProp
40
63
  function transformProps(props: PullToRefreshBoxProps): NativePullToRefreshBoxProps {
41
64
  const { isRefreshing, modifiers, onRefresh, ...restProps } = props;
42
65
 
43
- const loadingIndicatorModifiers = props.loadingIndicatorModifiers ?? [
44
- align('topCenter'),
45
- // padding(0, 10, 0, 0),
46
- ];
47
-
48
66
  return {
49
67
  modifiers,
50
68
  ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
@@ -53,13 +71,12 @@ function transformProps(props: PullToRefreshBoxProps): NativePullToRefreshBoxPro
53
71
  onRefresh: () => {
54
72
  onRefresh?.();
55
73
  },
56
- loadingIndicatorModifiers,
57
74
  };
58
75
  }
59
76
 
60
77
  /**
61
- * Renders a `PullToRefreshBox` component.
62
- * A box that allows the user to pull down to refresh the content.
78
+ * A pull-to-refresh container that wraps scrollable content and shows a refresh indicator when pulled,
79
+ * matching Compose's `PullToRefreshBox`.
63
80
  */
64
81
  export function PullToRefreshBox(props: PullToRefreshBoxProps) {
65
82
  return <NativePullToRefreshBoxView {...transformProps(props)} />;
@@ -2,9 +2,26 @@ import { requireNativeView } from 'expo';
2
2
  import React from 'react';
3
3
  import { type ColorValue } from 'react-native';
4
4
 
5
- import { type ExpoModifier } from '../../types';
5
+ import { type ViewEvent, type ModifierConfig } from '../../types';
6
+ import { parseJSXShape, ShapeJSXElement, type ShapeRecordProps } from '../Shape';
6
7
  import { createViewModifierEventListener } from '../modifiers/utils';
7
8
 
9
+ /**
10
+ * Border stroke configuration.
11
+ */
12
+ export type SurfaceBorder = {
13
+ /**
14
+ * Border width in dp.
15
+ * @default 1
16
+ */
17
+ width?: number;
18
+ /**
19
+ * Border color.
20
+ * @default MaterialTheme.colorScheme.outline
21
+ */
22
+ color?: ColorValue;
23
+ };
24
+
8
25
  export type SurfaceProps = {
9
26
  /**
10
27
  * The content to display inside the surface.
@@ -33,13 +50,58 @@ export type SurfaceProps = {
33
50
  * @default 0
34
51
  */
35
52
  shadowElevation?: number;
53
+ /**
54
+ * Shape configuration for clipping the surface.
55
+ */
56
+ shape?: ShapeJSXElement;
57
+ /**
58
+ * Border stroke drawn around the surface.
59
+ */
60
+ border?: SurfaceBorder;
61
+
62
+ /**
63
+ * Whether the surface is enabled and responds to user interaction.
64
+ *
65
+ * @default true
66
+ */
67
+ enabled?: boolean;
68
+
69
+ /**
70
+ * Whether the surface is in a selected state. When provided together with `onClick`,
71
+ * the surface becomes a selectable surface that visually reflects its selection state.
72
+ */
73
+ selected?: boolean;
74
+
75
+ /**
76
+ * Whether the surface is in a checked (toggled on) state. When provided together with
77
+ * `onCheckedChange`, the surface becomes a toggleable surface.
78
+ */
79
+ checked?: boolean;
80
+
81
+ /**
82
+ * Called when the surface is clicked. Providing this callback makes the surface clickable.
83
+ * When combined with `selected`, the surface becomes a selectable variant.
84
+ */
85
+ onClick?: () => void;
86
+
87
+ /**
88
+ * Called when the checked state of a toggleable surface changes.
89
+ * Providing this callback together with `checked` enables the toggleable variant.
90
+ */
91
+ onCheckedChange?: (checked: boolean) => void;
92
+
36
93
  /**
37
94
  * Modifiers for the component.
38
95
  */
39
- modifiers?: ExpoModifier[];
96
+ modifiers?: ModifierConfig[];
40
97
  };
41
98
 
42
- type NativeSurfaceProps = SurfaceProps;
99
+ type NativeSurfaceProps = Omit<SurfaceProps, 'onClick' | 'onCheckedChange' | 'shape'> &
100
+ ViewEvent<'onSurfaceClick', void> &
101
+ ViewEvent<'onCheckedChange', { value: boolean }> & {
102
+ clickable?: boolean;
103
+ shape?: ShapeRecordProps;
104
+ };
43
105
 
44
106
  const SurfaceNativeView: React.ComponentType<NativeSurfaceProps> = requireNativeView(
45
107
  'ExpoUI',
@@ -47,11 +109,20 @@ const SurfaceNativeView: React.ComponentType<NativeSurfaceProps> = requireNative
47
109
  );
48
110
 
49
111
  function transformProps(props: SurfaceProps): NativeSurfaceProps {
50
- const { modifiers, ...restProps } = props;
112
+ const { modifiers, onClick, onCheckedChange, shape, ...restProps } = props;
113
+
51
114
  return {
52
115
  modifiers,
53
116
  ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
54
117
  ...restProps,
118
+ clickable: !!onClick,
119
+ shape: parseJSXShape(shape),
120
+ onSurfaceClick: onClick ? () => onClick() : undefined,
121
+ onCheckedChange: onCheckedChange
122
+ ? (e: { nativeEvent: { value: boolean } }) => {
123
+ onCheckedChange(e.nativeEvent.value);
124
+ }
125
+ : undefined,
55
126
  };
56
127
  }
57
128