@expo/ui 57.0.16 → 57.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/ui/DatePickerView.kt +31 -20
- package/android/src/main/java/expo/modules/ui/DateRangePickerView.kt +191 -0
- package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +17 -0
- package/android/src/main/java/expo/modules/ui/RadioButtonView.kt +23 -1
- package/android/src/main/java/expo/modules/ui/menu/DropdownMenu.kt +2 -0
- package/android/src/main/java/expo/modules/ui/menu/DropdownMenuRecords.kt +2 -1
- package/build/community/bottom-sheet/BottomSheet.android.d.ts.map +1 -1
- package/build/community/bottom-sheet/BottomSheet.ios.d.ts.map +1 -1
- package/build/jetpack-compose/DatePicker/index.d.ts +88 -0
- package/build/jetpack-compose/DatePicker/index.d.ts.map +1 -1
- package/build/jetpack-compose/DropdownMenu/index.d.ts +7 -0
- package/build/jetpack-compose/DropdownMenu/index.d.ts.map +1 -1
- package/build/jetpack-compose/RadioButton/index.d.ts +19 -0
- package/build/jetpack-compose/RadioButton/index.d.ts.map +1 -1
- package/build/swift-ui/Button/index.d.ts +3 -1
- package/build/swift-ui/Button/index.d.ts.map +1 -1
- package/build/swift-ui/NavigationDestination/index.d.ts +30 -0
- package/build/swift-ui/NavigationDestination/index.d.ts.map +1 -0
- package/build/swift-ui/NavigationLink/index.d.ts +32 -0
- package/build/swift-ui/NavigationLink/index.d.ts.map +1 -0
- package/build/swift-ui/NavigationStack/index.d.ts +45 -0
- package/build/swift-ui/NavigationStack/index.d.ts.map +1 -0
- package/build/swift-ui/Toolbar/index.d.ts +40 -0
- package/build/swift-ui/Toolbar/index.d.ts.map +1 -0
- package/build/swift-ui/index.d.ts +4 -0
- package/build/swift-ui/index.d.ts.map +1 -1
- package/build/swift-ui/modifiers/containerBackground.d.ts +9 -4
- package/build/swift-ui/modifiers/containerBackground.d.ts.map +1 -1
- package/build/swift-ui/modifiers/index.d.ts +47 -10
- package/build/swift-ui/modifiers/index.d.ts.map +1 -1
- package/build/swift-ui/modifiers/presentationModifiers.d.ts +6 -3
- package/build/swift-ui/modifiers/presentationModifiers.d.ts.map +1 -1
- package/expo-module.config.json +1 -1
- package/ios/Button/Button.swift +13 -0
- package/ios/Button/ButtonProps.swift +6 -0
- package/ios/ExpoUIModule.swift +4 -0
- package/ios/Modifiers/ContainerBackgroundModifier.swift +4 -4
- package/ios/Modifiers/PresentationModifiers.swift +3 -3
- package/ios/Modifiers/ScrollClipDisabledModifier.swift +16 -0
- package/ios/Modifiers/ViewModifierRegistry.swift +35 -8
- package/ios/NavigationLinkView.swift +22 -0
- package/ios/NavigationStackView.swift +63 -0
- package/ios/SlotView.swift +5 -0
- package/ios/ToolbarView.swift +33 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.16/expo.modules.ui-57.0.16-sources.jar → 57.0.18/expo.modules.ui-57.0.18-sources.jar} +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18-sources.jar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18-sources.jar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18-sources.jar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18-sources.jar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.aar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.aar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.aar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.aar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.16/expo.modules.ui-57.0.16.module → 57.0.18/expo.modules.ui-57.0.18.module} +22 -22
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.module.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.module.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.16/expo.modules.ui-57.0.16.pom → 57.0.18/expo.modules.ui-57.0.18.pom} +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.18/expo.modules.ui-57.0.18.pom.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
- package/package.json +3 -3
- package/spm.config.json +1 -1
- package/src/community/bottom-sheet/BottomSheet.android.tsx +5 -3
- package/src/community/bottom-sheet/BottomSheet.ios.tsx +4 -3
- package/src/jetpack-compose/DatePicker/index.tsx +156 -0
- package/src/jetpack-compose/DropdownMenu/index.tsx +9 -0
- package/src/jetpack-compose/RadioButton/index.tsx +20 -0
- package/src/swift-ui/Button/index.tsx +3 -1
- package/src/swift-ui/NavigationDestination/index.tsx +39 -0
- package/src/swift-ui/NavigationLink/index.tsx +51 -0
- package/src/swift-ui/NavigationStack/index.tsx +75 -0
- package/src/swift-ui/Toolbar/index.tsx +64 -0
- package/src/swift-ui/index.tsx +4 -0
- package/src/swift-ui/modifiers/containerBackground.ts +10 -5
- package/src/swift-ui/modifiers/index.ts +67 -9
- package/src/swift-ui/modifiers/presentationModifiers.ts +7 -4
- package/src/universal/transformStyle.ios.ts +2 -2
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16-sources.jar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16-sources.jar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16-sources.jar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16-sources.jar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.aar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.aar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.aar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.aar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.module.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.pom.sha512 +0 -1
|
@@ -8,6 +8,20 @@ export type AndroidVariant = 'picker' | 'input';
|
|
|
8
8
|
|
|
9
9
|
export type DisplayedComponents = 'date' | 'hourAndMinute' | 'dateAndTime';
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* The date range reported by `DateRangePicker` and `DateRangePickerDialog`.
|
|
13
|
+
*/
|
|
14
|
+
export type DateRangeSelection = {
|
|
15
|
+
/**
|
|
16
|
+
* The selected start date, or `null` when no start date is selected.
|
|
17
|
+
*/
|
|
18
|
+
start: Date | null;
|
|
19
|
+
/**
|
|
20
|
+
* The selected end date, or `null` until the user selects the second date of the range.
|
|
21
|
+
*/
|
|
22
|
+
end: Date | null;
|
|
23
|
+
};
|
|
24
|
+
|
|
11
25
|
/**
|
|
12
26
|
* Color overrides for the Material 3 DatePicker component.
|
|
13
27
|
* All properties are optional — unset values use Material 3 theme defaults.
|
|
@@ -177,6 +191,10 @@ function convertSelectableDates(selectableDates?: {
|
|
|
177
191
|
};
|
|
178
192
|
}
|
|
179
193
|
|
|
194
|
+
function convertTimestampToDate(timestamp: number | null): Date | null {
|
|
195
|
+
return timestamp == null ? null : new Date(timestamp);
|
|
196
|
+
}
|
|
197
|
+
|
|
180
198
|
function transformDateTimePickerProps(props: DateTimePickerProps): NativeDatePickerProps {
|
|
181
199
|
const { modifiers, variant, initialDate, selectableDates, elementColors, color, ...rest } = props;
|
|
182
200
|
|
|
@@ -210,9 +228,107 @@ export function DateTimePicker(props: DateTimePickerProps) {
|
|
|
210
228
|
return <DatePickerNativeView {...transformDateTimePickerProps(props)} />;
|
|
211
229
|
}
|
|
212
230
|
|
|
231
|
+
export interface DateRangePickerProps {
|
|
232
|
+
/**
|
|
233
|
+
* The initially selected start date, as an ISO 8601 string.
|
|
234
|
+
*/
|
|
235
|
+
initialStartDate?: string | null;
|
|
236
|
+
/**
|
|
237
|
+
* The initially selected end date, as an ISO 8601 string. It must be on or after `initialStartDate`.
|
|
238
|
+
*/
|
|
239
|
+
initialEndDate?: string | null;
|
|
240
|
+
/**
|
|
241
|
+
* Called once when the component mounts with the initial range, and again whenever the selected date range changes.
|
|
242
|
+
* The end date is `null` while the user is selecting a range.
|
|
243
|
+
*/
|
|
244
|
+
onDateRangeSelected?: (range: DateRangeSelection) => void;
|
|
245
|
+
/**
|
|
246
|
+
* The variant of the picker, which determines its appearance and behavior.
|
|
247
|
+
* @default 'picker'
|
|
248
|
+
*/
|
|
249
|
+
variant?: AndroidVariant;
|
|
250
|
+
/**
|
|
251
|
+
* Show a button to toggle between variants on Android.
|
|
252
|
+
* @default true
|
|
253
|
+
*/
|
|
254
|
+
showVariantToggle?: boolean;
|
|
255
|
+
/**
|
|
256
|
+
* The tint color to use on the picker elements.
|
|
257
|
+
*/
|
|
258
|
+
color?: ColorValue;
|
|
259
|
+
/**
|
|
260
|
+
* Fine-grained color overrides for individual picker elements.
|
|
261
|
+
*/
|
|
262
|
+
elementColors?: DatePickerElementColors;
|
|
263
|
+
/**
|
|
264
|
+
* Constrains which dates can be selected. `start` is the earliest selectable date and `end` is
|
|
265
|
+
* the latest.
|
|
266
|
+
*/
|
|
267
|
+
selectableDates?: { start?: Date; end?: Date };
|
|
268
|
+
/**
|
|
269
|
+
* Modifiers for the component.
|
|
270
|
+
*/
|
|
271
|
+
modifiers?: ModifierConfig[];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
type NativeDateRangePickerProps = Omit<
|
|
275
|
+
DateRangePickerProps,
|
|
276
|
+
'onDateRangeSelected' | 'initialStartDate' | 'initialEndDate' | 'selectableDates'
|
|
277
|
+
> & {
|
|
278
|
+
initialStartDate?: number | null;
|
|
279
|
+
initialEndDate?: number | null;
|
|
280
|
+
selectableDates?: { start?: number | null; end?: number | null } | null;
|
|
281
|
+
} & ViewEvent<'onDateRangeSelected', { start: number | null; end: number | null }>;
|
|
282
|
+
|
|
283
|
+
function transformDateRangePickerProps(
|
|
284
|
+
props: Omit<DateRangePickerProps, 'modifiers'>
|
|
285
|
+
): Omit<NativeDateRangePickerProps, 'modifiers'> {
|
|
286
|
+
const {
|
|
287
|
+
initialStartDate,
|
|
288
|
+
initialEndDate,
|
|
289
|
+
selectableDates,
|
|
290
|
+
elementColors,
|
|
291
|
+
onDateRangeSelected,
|
|
292
|
+
...rest
|
|
293
|
+
} = props;
|
|
294
|
+
return {
|
|
295
|
+
...rest,
|
|
296
|
+
initialStartDate: initialStartDate ? new Date(initialStartDate).getTime() : null,
|
|
297
|
+
initialEndDate: initialEndDate ? new Date(initialEndDate).getTime() : null,
|
|
298
|
+
selectableDates: convertSelectableDates(selectableDates),
|
|
299
|
+
onDateRangeSelected: ({ nativeEvent: { start, end } }) => {
|
|
300
|
+
onDateRangeSelected?.({
|
|
301
|
+
start: convertTimestampToDate(start),
|
|
302
|
+
end: convertTimestampToDate(end),
|
|
303
|
+
});
|
|
304
|
+
},
|
|
305
|
+
...(elementColors != null ? { elementColors } : undefined),
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const DateRangePickerNativeView: React.ComponentType<NativeDateRangePickerProps> =
|
|
310
|
+
requireNativeView('ExpoUI', 'DateRangePickerView');
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Renders an inline Material 3 date range picker.
|
|
314
|
+
*/
|
|
315
|
+
export function DateRangePicker(props: DateRangePickerProps) {
|
|
316
|
+
const { modifiers, ...rest } = props;
|
|
317
|
+
const nativeProps: NativeDateRangePickerProps = {
|
|
318
|
+
modifiers,
|
|
319
|
+
...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
|
|
320
|
+
...transformDateRangePickerProps(rest),
|
|
321
|
+
};
|
|
322
|
+
return <DateRangePickerNativeView {...nativeProps} />;
|
|
323
|
+
}
|
|
324
|
+
|
|
213
325
|
// -- Dialog views (used internally by the compat layer) ---------------------
|
|
214
326
|
|
|
215
327
|
export interface DatePickerDialogProps {
|
|
328
|
+
/**
|
|
329
|
+
* The initially selected date. When omitted, the dialog opens on the current month with no
|
|
330
|
+
* selection and the confirm button stays disabled until a date is picked.
|
|
331
|
+
*/
|
|
216
332
|
initialDate?: string | null;
|
|
217
333
|
variant?: AndroidVariant;
|
|
218
334
|
showVariantToggle?: boolean;
|
|
@@ -260,6 +376,46 @@ export function DatePickerDialog(props: DatePickerDialogProps) {
|
|
|
260
376
|
return <DatePickerDialogNativeView {...nativeProps} />;
|
|
261
377
|
}
|
|
262
378
|
|
|
379
|
+
export interface DateRangePickerDialogProps extends Omit<DateRangePickerProps, 'modifiers'> {
|
|
380
|
+
/**
|
|
381
|
+
* The label for the button that confirms the selected range.
|
|
382
|
+
* Defaults to the system "Ok" string.
|
|
383
|
+
*/
|
|
384
|
+
confirmButtonLabel?: string;
|
|
385
|
+
/**
|
|
386
|
+
* The label for the button that dismisses the dialog.
|
|
387
|
+
* Defaults to the system "Cancel" string.
|
|
388
|
+
*/
|
|
389
|
+
dismissButtonLabel?: string;
|
|
390
|
+
/** The tint color to use on the picker elements and dialog buttons. */
|
|
391
|
+
color?: ColorValue;
|
|
392
|
+
/** Callback function that is called when the user confirms a complete date range. */
|
|
393
|
+
onDateRangeSelected?: (range: DateRangeSelection) => void;
|
|
394
|
+
/** Callback function that is called when the dialog is dismissed. */
|
|
395
|
+
onDismissRequest: () => void;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
type NativeDateRangePickerDialogProps = Omit<NativeDateRangePickerProps, 'modifiers'> &
|
|
399
|
+
Pick<DateRangePickerDialogProps, 'confirmButtonLabel' | 'dismissButtonLabel'> &
|
|
400
|
+
ViewEvent<'onDismissRequest', void>;
|
|
401
|
+
|
|
402
|
+
const DateRangePickerDialogNativeView: React.ComponentType<NativeDateRangePickerDialogProps> =
|
|
403
|
+
requireNativeView('ExpoUI', 'DateRangePickerDialogView');
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Renders a modal Material 3 date range picker.
|
|
407
|
+
*/
|
|
408
|
+
export function DateRangePickerDialog(props: DateRangePickerDialogProps) {
|
|
409
|
+
const { confirmButtonLabel, dismissButtonLabel, onDismissRequest, ...rest } = props;
|
|
410
|
+
const nativeProps: NativeDateRangePickerDialogProps = {
|
|
411
|
+
...transformDateRangePickerProps(rest),
|
|
412
|
+
confirmButtonLabel,
|
|
413
|
+
dismissButtonLabel,
|
|
414
|
+
onDismissRequest,
|
|
415
|
+
};
|
|
416
|
+
return <DateRangePickerDialogNativeView {...nativeProps} />;
|
|
417
|
+
}
|
|
418
|
+
|
|
263
419
|
export interface TimePickerDialogProps {
|
|
264
420
|
initialDate?: string | null;
|
|
265
421
|
is24Hour?: boolean;
|
|
@@ -43,6 +43,14 @@ export interface DropdownMenuProps {
|
|
|
43
43
|
*/
|
|
44
44
|
color?: ColorValue;
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Shadow elevation of the dropdown menu popup in dp. Set to `0` to remove the shadow.
|
|
48
|
+
* Defaults to Material3's `MenuDefaults.ShadowElevation`.
|
|
49
|
+
*
|
|
50
|
+
* @platform android
|
|
51
|
+
*/
|
|
52
|
+
shadowElevation?: number;
|
|
53
|
+
|
|
46
54
|
/**
|
|
47
55
|
* Optional styles to apply to the `DropdownMenu`.
|
|
48
56
|
*/
|
|
@@ -58,6 +66,7 @@ type NativeMenuProps = {
|
|
|
58
66
|
expanded?: boolean;
|
|
59
67
|
onDismissRequest?: () => void;
|
|
60
68
|
color?: ColorValue;
|
|
69
|
+
shadowElevation?: number;
|
|
61
70
|
style?: StyleProp<ViewStyle>;
|
|
62
71
|
modifiers?: ModifierConfig[];
|
|
63
72
|
children?: ReactNode;
|
|
@@ -1,17 +1,37 @@
|
|
|
1
1
|
import { requireNativeView } from 'expo';
|
|
2
|
+
import type { ColorValue } from 'react-native';
|
|
2
3
|
|
|
3
4
|
import { type ModifierConfig, type ViewEvent } from '../../types';
|
|
4
5
|
import { createViewModifierEventListener } from '../modifiers/utils';
|
|
5
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Colors for the radio button in different states.
|
|
9
|
+
*/
|
|
10
|
+
export type RadioButtonColors = {
|
|
11
|
+
selectedColor?: ColorValue;
|
|
12
|
+
unselectedColor?: ColorValue;
|
|
13
|
+
disabledSelectedColor?: ColorValue;
|
|
14
|
+
disabledUnselectedColor?: ColorValue;
|
|
15
|
+
};
|
|
16
|
+
|
|
6
17
|
export interface RadioButtonProps {
|
|
7
18
|
/**
|
|
8
19
|
* Whether the radio button is selected.
|
|
9
20
|
*/
|
|
10
21
|
selected: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the radio button is enabled.
|
|
24
|
+
* @default true
|
|
25
|
+
*/
|
|
26
|
+
enabled?: boolean;
|
|
11
27
|
/**
|
|
12
28
|
* Callback that is called when the radio button is clicked.
|
|
13
29
|
*/
|
|
14
30
|
onClick?: () => void;
|
|
31
|
+
/**
|
|
32
|
+
* Colors for the radio button in different states.
|
|
33
|
+
*/
|
|
34
|
+
colors?: RadioButtonColors;
|
|
15
35
|
/**
|
|
16
36
|
* Modifiers for the component.
|
|
17
37
|
*/
|
|
@@ -10,8 +10,10 @@ import { type CommonViewModifierProps } from '../types';
|
|
|
10
10
|
* - `default` - The default button role.
|
|
11
11
|
* - `cancel` - A button that cancels the current operation.
|
|
12
12
|
* - `destructive` - A button that deletes data or performs a destructive action.
|
|
13
|
+
* - `close` - A button that closes the view it is presented in. Given no `label` and no children,
|
|
14
|
+
* the system draws it as an xmark.
|
|
13
15
|
*/
|
|
14
|
-
export type ButtonRole = 'default' | 'cancel' | 'destructive';
|
|
16
|
+
export type ButtonRole = 'default' | 'cancel' | 'destructive' | 'close';
|
|
15
17
|
|
|
16
18
|
export interface ButtonProps extends CommonViewModifierProps {
|
|
17
19
|
/**
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
import { Slot } from '../SlotView';
|
|
4
|
+
|
|
5
|
+
export interface NavigationDestinationProps {
|
|
6
|
+
/**
|
|
7
|
+
* The `NavigationLink` value this destination is presented for.
|
|
8
|
+
*/
|
|
9
|
+
value: string;
|
|
10
|
+
/**
|
|
11
|
+
* The view pushed onto the stack for `value`.
|
|
12
|
+
*/
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Associates a destination view with a `NavigationLink` value, matching SwiftUI's
|
|
18
|
+
* `navigationDestination(for:destination:)`. It must be a direct child of the `NavigationStack`,
|
|
19
|
+
* however deeply the link that pushes it is nested inside that stack.
|
|
20
|
+
*
|
|
21
|
+
* Keep it mounted so the pushed screen already carries its `navigationTitle` when the slide
|
|
22
|
+
* starts, or render one for each value on the stack's `path` to build screens on demand.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <NavigationDestination value="settings">
|
|
27
|
+
* <SettingsScreen />
|
|
28
|
+
* </NavigationDestination>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @platform ios
|
|
32
|
+
*/
|
|
33
|
+
export function NavigationDestination(props: NavigationDestinationProps) {
|
|
34
|
+
return (
|
|
35
|
+
<Slot name="destination" extraProps={{ value: props.value }}>
|
|
36
|
+
{props.children}
|
|
37
|
+
</Slot>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { requireNativeView } from 'expo';
|
|
2
|
+
import { type ComponentType, type ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
import { createViewModifierEventListener } from '../modifiers/utils';
|
|
5
|
+
import { type CommonViewModifierProps } from '../types';
|
|
6
|
+
|
|
7
|
+
export interface NavigationLinkProps extends CommonViewModifierProps {
|
|
8
|
+
/**
|
|
9
|
+
* The value to append to the enclosing `NavigationStack`'s path when the link is tapped. The
|
|
10
|
+
* stack presents the `NavigationDestination` whose `value` matches.
|
|
11
|
+
*/
|
|
12
|
+
value: string;
|
|
13
|
+
/**
|
|
14
|
+
* A view that describes the link.
|
|
15
|
+
*/
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const NavigationLinkNativeView: ComponentType<NavigationLinkProps> = requireNativeView(
|
|
20
|
+
'ExpoUI',
|
|
21
|
+
'NavigationLinkView'
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A view that controls a navigation presentation. In a `List` it renders as a row with a
|
|
26
|
+
* disclosure chevron, and tapping it pushes the matching `NavigationDestination`.
|
|
27
|
+
*
|
|
28
|
+
* The link has to be inside the `NavigationStack` itself. Content presented from the stack, such
|
|
29
|
+
* as a `BottomSheet` or a `Popover`, is its own presentation context and does not reach the
|
|
30
|
+
* stack's destinations, so give that content its own `NavigationStack`.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* <NavigationLink value="settings">
|
|
35
|
+
* <Text>Settings</Text>
|
|
36
|
+
* </NavigationLink>
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @platform ios
|
|
40
|
+
*/
|
|
41
|
+
export function NavigationLink(props: NavigationLinkProps) {
|
|
42
|
+
const { modifiers, children, ...restProps } = props;
|
|
43
|
+
return (
|
|
44
|
+
<NavigationLinkNativeView
|
|
45
|
+
modifiers={modifiers}
|
|
46
|
+
{...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
|
|
47
|
+
{...restProps}>
|
|
48
|
+
{children}
|
|
49
|
+
</NavigationLinkNativeView>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { requireNativeView } from 'expo';
|
|
2
|
+
import { type ComponentType, type ReactNode } from 'react';
|
|
3
|
+
import { type NativeSyntheticEvent } from 'react-native';
|
|
4
|
+
|
|
5
|
+
import { createViewModifierEventListener } from '../modifiers/utils';
|
|
6
|
+
import { type CommonViewModifierProps } from '../types';
|
|
7
|
+
|
|
8
|
+
export interface NavigationStackProps extends CommonViewModifierProps {
|
|
9
|
+
/**
|
|
10
|
+
* The root view of the stack, and the `NavigationDestination` views the stack can push. It is
|
|
11
|
+
* displayed inside a navigation bar.
|
|
12
|
+
*/
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* The values of the views pushed on top of the root view, in the order they were pushed.
|
|
16
|
+
* Leave it undefined to let the stack manage its own path.
|
|
17
|
+
*/
|
|
18
|
+
path?: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Callback function that is called when the stack pushes or pops a view, for example when a
|
|
21
|
+
* `NavigationLink` is tapped or the user swipes back. Gets called with the new path.
|
|
22
|
+
*
|
|
23
|
+
* When `path` is set, the stack is controlled: a push takes effect once the new path comes back
|
|
24
|
+
* through this prop.
|
|
25
|
+
*/
|
|
26
|
+
onPathChange?: (path: string[]) => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type NativeNavigationStackProps = Omit<NavigationStackProps, 'onPathChange'> & {
|
|
30
|
+
onPathChange?: (event: NativeSyntheticEvent<{ path: string[] }>) => void;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const NavigationStackNativeView: ComponentType<NativeNavigationStackProps> = requireNativeView(
|
|
34
|
+
'ExpoUI',
|
|
35
|
+
'NavigationStackView'
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A view that displays a root view and enables you to present additional views over the root view.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```tsx
|
|
43
|
+
* const [path, setPath] = useState<string[]>([]);
|
|
44
|
+
*
|
|
45
|
+
* <NavigationStack path={path} onPathChange={setPath}>
|
|
46
|
+
* <List>
|
|
47
|
+
* <NavigationLink value="settings">
|
|
48
|
+
* <Text>Settings</Text>
|
|
49
|
+
* </NavigationLink>
|
|
50
|
+
* </List>
|
|
51
|
+
* <NavigationDestination value="settings">
|
|
52
|
+
* <SettingsScreen />
|
|
53
|
+
* </NavigationDestination>
|
|
54
|
+
* </NavigationStack>
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @platform ios
|
|
58
|
+
*/
|
|
59
|
+
export function NavigationStack(props: NavigationStackProps) {
|
|
60
|
+
const { modifiers, onPathChange, ...restProps } = props;
|
|
61
|
+
return (
|
|
62
|
+
<NavigationStackNativeView
|
|
63
|
+
modifiers={modifiers}
|
|
64
|
+
{...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
|
|
65
|
+
{...restProps}
|
|
66
|
+
onPathChange={
|
|
67
|
+
onPathChange
|
|
68
|
+
? ({ nativeEvent: { path } }) => {
|
|
69
|
+
onPathChange(path);
|
|
70
|
+
}
|
|
71
|
+
: undefined
|
|
72
|
+
}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { requireNativeView } from 'expo';
|
|
2
|
+
|
|
3
|
+
import { Slot } from '../SlotView';
|
|
4
|
+
import { createViewModifierEventListener } from '../modifiers/utils';
|
|
5
|
+
import { type CommonViewModifierProps } from '../types';
|
|
6
|
+
|
|
7
|
+
export interface ToolbarProps extends CommonViewModifierProps {
|
|
8
|
+
/**
|
|
9
|
+
* The view the toolbar belongs to, together with the `Toolbar.Content` that fills it.
|
|
10
|
+
*/
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ToolbarContentProps {
|
|
15
|
+
/**
|
|
16
|
+
* The items to place in the toolbar.
|
|
17
|
+
*/
|
|
18
|
+
children: React.ReactNode;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const ToolbarNativeView: React.ComponentType<ToolbarProps> = requireNativeView(
|
|
22
|
+
'ExpoUI',
|
|
23
|
+
'ToolbarView'
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The items placed in the toolbar of the view `Toolbar` wraps.
|
|
28
|
+
*/
|
|
29
|
+
function ToolbarContent(props: ToolbarContentProps) {
|
|
30
|
+
return <Slot name="content">{props.children}</Slot>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Adds a toolbar to the view it wraps, matching SwiftUI's `toolbar(content:)`.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* <NavigationStack>
|
|
39
|
+
* <Toolbar>
|
|
40
|
+
* <Text>Bird description</Text>
|
|
41
|
+
* <Toolbar.Content>
|
|
42
|
+
* <Button role="close" onPress={() => setIsPresented(false)} />
|
|
43
|
+
* </Toolbar.Content>
|
|
44
|
+
* </Toolbar>
|
|
45
|
+
* </NavigationStack>
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @platform ios
|
|
49
|
+
*/
|
|
50
|
+
function ToolbarComponent(props: ToolbarProps) {
|
|
51
|
+
const { modifiers, children, ...restProps } = props;
|
|
52
|
+
return (
|
|
53
|
+
<ToolbarNativeView
|
|
54
|
+
modifiers={modifiers}
|
|
55
|
+
{...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
|
|
56
|
+
{...restProps}>
|
|
57
|
+
{children}
|
|
58
|
+
</ToolbarNativeView>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const Toolbar = Object.assign(ToolbarComponent, { Content: ToolbarContent });
|
|
63
|
+
|
|
64
|
+
export { Toolbar };
|
package/src/swift-ui/index.tsx
CHANGED
|
@@ -25,6 +25,9 @@ export * from './ZStack';
|
|
|
25
25
|
export * from './Group';
|
|
26
26
|
export * from './List';
|
|
27
27
|
export * from './Menu';
|
|
28
|
+
export * from './NavigationDestination';
|
|
29
|
+
export * from './NavigationLink';
|
|
30
|
+
export * from './NavigationStack';
|
|
28
31
|
export * from './Picker';
|
|
29
32
|
export * from './ProgressView';
|
|
30
33
|
export * from './Section';
|
|
@@ -38,6 +41,7 @@ export { useNativeState } from '../State';
|
|
|
38
41
|
export { withAnimation, type WithAnimationCompletionCriteria } from './withAnimation';
|
|
39
42
|
export * from './SyncToggle';
|
|
40
43
|
export * from './TabView';
|
|
44
|
+
export * from './Toolbar';
|
|
41
45
|
export * from './Toggle';
|
|
42
46
|
export {
|
|
43
47
|
TextField,
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { createModifier } from './createModifier';
|
|
2
|
-
import type
|
|
2
|
+
import { resolveShapeStyle, type ShapeStyle } from './shapeStyle';
|
|
3
3
|
|
|
4
4
|
export type ContainerBackgroundPlacement = 'widget' | 'navigation' | 'navigationSplitView';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Sets the container background of the enclosing container
|
|
8
|
-
*
|
|
7
|
+
* Sets the container background of the enclosing container.
|
|
8
|
+
*
|
|
9
|
+
* > **Note:** `navigation` and `navigationSplitView` require iOS 18. On iOS 17 they fall back to
|
|
10
|
+
* > the `widget` placement.
|
|
11
|
+
*
|
|
12
|
+
* @param style - Any [`ShapeStyle`](#shapestyle): a color, a hierarchical style, a material, or a gradient.
|
|
9
13
|
* @param container - The type of container to apply the background to.
|
|
14
|
+
* @platform ios 17.0+
|
|
10
15
|
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/containerbackground(_:for:)).
|
|
11
16
|
*/
|
|
12
|
-
export const containerBackground = (
|
|
13
|
-
createModifier('containerBackground', {
|
|
17
|
+
export const containerBackground = (style: ShapeStyle, container: ContainerBackgroundPlacement) =>
|
|
18
|
+
createModifier('containerBackground', { style: resolveShapeStyle(style), container });
|
|
@@ -287,13 +287,38 @@ export const clipShape = (
|
|
|
287
287
|
cornerRadius?: number
|
|
288
288
|
) => createModifier('clipShape', { shape, cornerRadius });
|
|
289
289
|
|
|
290
|
+
/**
|
|
291
|
+
* The parameters of the `border` modifier.
|
|
292
|
+
*/
|
|
293
|
+
export type BorderParams =
|
|
294
|
+
| {
|
|
295
|
+
/**
|
|
296
|
+
* The style painted along the border. No border is drawn when the style is not available on
|
|
297
|
+
* the running platform, unlike `strokeBorder`, which falls back to the foreground style.
|
|
298
|
+
*/
|
|
299
|
+
content: ShapeStyle;
|
|
300
|
+
/** The border width. @default 1 */
|
|
301
|
+
width?: number;
|
|
302
|
+
}
|
|
303
|
+
| {
|
|
304
|
+
/**
|
|
305
|
+
* @deprecated Use `content`, which takes any `ShapeStyle` and not only a color.
|
|
306
|
+
*/
|
|
307
|
+
color: Color;
|
|
308
|
+
/** The border width. @default 1 */
|
|
309
|
+
width?: number;
|
|
310
|
+
};
|
|
311
|
+
|
|
290
312
|
/**
|
|
291
313
|
* Adds a border to a view.
|
|
292
|
-
* @param params - The border parameters.
|
|
314
|
+
* @param params - The border parameters. The style painted along the border, and its width.
|
|
293
315
|
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/border(_:width:)).
|
|
294
316
|
*/
|
|
295
|
-
export const border = (params:
|
|
296
|
-
createModifier('border',
|
|
317
|
+
export const border = (params: BorderParams) =>
|
|
318
|
+
createModifier('border', {
|
|
319
|
+
content: resolveShapeStyle('content' in params ? params.content : params.color),
|
|
320
|
+
width: params.width,
|
|
321
|
+
});
|
|
297
322
|
|
|
298
323
|
/**
|
|
299
324
|
* The characteristics of a stroke that traces a path.
|
|
@@ -316,10 +341,15 @@ export type StrokeStyle = {
|
|
|
316
341
|
|
|
317
342
|
/**
|
|
318
343
|
* Strokes an inset border along the view's shape.
|
|
319
|
-
* @param params - The stroke parameters.
|
|
344
|
+
* @param params - The stroke parameters. The style painted along the stroke (omit for the foreground style), the stroke style, antialiased, shape and cornerRadius.
|
|
320
345
|
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/insettableshape/strokeborder(_:style:antialiased:)).
|
|
321
346
|
*/
|
|
322
347
|
export const strokeBorder = (params: {
|
|
348
|
+
/** The style painted along the stroke. Omit to use the foreground style. */
|
|
349
|
+
content?: ShapeStyle;
|
|
350
|
+
/**
|
|
351
|
+
* @deprecated Use `content`, which takes any `ShapeStyle` and not only a color.
|
|
352
|
+
*/
|
|
323
353
|
color?: Color;
|
|
324
354
|
style?: StrokeStyle;
|
|
325
355
|
antialiased?: boolean;
|
|
@@ -331,7 +361,14 @@ export const strokeBorder = (params: {
|
|
|
331
361
|
| 'roundedRectangle'
|
|
332
362
|
| 'containerRelativeShape';
|
|
333
363
|
cornerRadius?: number;
|
|
334
|
-
}) =>
|
|
364
|
+
}) => {
|
|
365
|
+
const { content, color, ...rest } = params;
|
|
366
|
+
const shapeStyle = content ?? color;
|
|
367
|
+
return createModifier('strokeBorder', {
|
|
368
|
+
...rest,
|
|
369
|
+
content: shapeStyle === undefined ? undefined : resolveShapeStyle(shapeStyle),
|
|
370
|
+
});
|
|
371
|
+
};
|
|
335
372
|
|
|
336
373
|
/**
|
|
337
374
|
* Applies scaling transformation.
|
|
@@ -495,11 +532,11 @@ export const italic = () => createModifier('italic', {});
|
|
|
495
532
|
export const monospacedDigit = () => createModifier('monospacedDigit', {});
|
|
496
533
|
|
|
497
534
|
/**
|
|
498
|
-
* Sets the tint
|
|
499
|
-
* @param
|
|
535
|
+
* Sets the tint of a view.
|
|
536
|
+
* @param tint - Any [`ShapeStyle`](#shapestyle): a color, a hierarchical style, a material, or a gradient.
|
|
500
537
|
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/tint(_:)).
|
|
501
538
|
*/
|
|
502
|
-
export const tint = (
|
|
539
|
+
export const tint = (tint: ShapeStyle) => createModifier('tint', { tint: resolveShapeStyle(tint) });
|
|
503
540
|
|
|
504
541
|
/**
|
|
505
542
|
* Hides or shows a view.
|
|
@@ -749,6 +786,18 @@ export const scrollDismissesKeyboard = (
|
|
|
749
786
|
export const scrollDisabled = (disabled: boolean = true) =>
|
|
750
787
|
createModifier('scrollDisabled', { disabled });
|
|
751
788
|
|
|
789
|
+
/**
|
|
790
|
+
* Disables or enables clipping of a scrollable view's content to its bounds.
|
|
791
|
+
* Content drawn outside those bounds, such as a shadow or a view scaled up past the edge, is
|
|
792
|
+
* cut off by default and stays visible once clipping is disabled.
|
|
793
|
+
* @param disabled - Whether clipping should be disabled (default: true).
|
|
794
|
+
* @platform ios 17.0+
|
|
795
|
+
* @platform tvos 17.0+
|
|
796
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/scrollclipdisabled(_:)).
|
|
797
|
+
*/
|
|
798
|
+
export const scrollClipDisabled = (disabled: boolean = true) =>
|
|
799
|
+
createModifier('scrollClipDisabled', { disabled });
|
|
800
|
+
|
|
752
801
|
/**
|
|
753
802
|
* Controls the visibility of scroll indicators for scrollable views.
|
|
754
803
|
* Mirrors SwiftUI's `scrollIndicators(_:axes:)` modifier.
|
|
@@ -1638,6 +1687,13 @@ export const resizable = (
|
|
|
1638
1687
|
resizingMode?: 'stretch' | 'tile'
|
|
1639
1688
|
) => createModifier('resizable', { ...capInsets, resizingMode });
|
|
1640
1689
|
|
|
1690
|
+
/**
|
|
1691
|
+
* Configures the view's title for purposes of navigation, using a string.
|
|
1692
|
+
* @param title - The title to display.
|
|
1693
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/navigationtitle(_:)).
|
|
1694
|
+
*/
|
|
1695
|
+
export const navigationTitle = (title: string) => createModifier('navigationTitle', { title });
|
|
1696
|
+
|
|
1641
1697
|
// =============================================================================
|
|
1642
1698
|
// Type Definitions
|
|
1643
1699
|
// =============================================================================
|
|
@@ -1725,6 +1781,7 @@ export type BuiltInModifier =
|
|
|
1725
1781
|
| ReturnType<typeof containerRelativeFrame>
|
|
1726
1782
|
| ReturnType<typeof scrollContentBackground>
|
|
1727
1783
|
| ReturnType<typeof scrollDisabled>
|
|
1784
|
+
| ReturnType<typeof scrollClipDisabled>
|
|
1728
1785
|
| ReturnType<typeof scrollIndicators>
|
|
1729
1786
|
| ReturnType<typeof defaultScrollAnchor>
|
|
1730
1787
|
| ReturnType<typeof defaultScrollAnchorForRole>
|
|
@@ -1780,7 +1837,8 @@ export type BuiltInModifier =
|
|
|
1780
1837
|
| ReturnType<typeof widgetAccentedRenderingMode>
|
|
1781
1838
|
| ReturnType<typeof widgetURL>
|
|
1782
1839
|
| ReturnType<typeof activityBackgroundTint>
|
|
1783
|
-
| ReturnType<typeof containerBackground
|
|
1840
|
+
| ReturnType<typeof containerBackground>
|
|
1841
|
+
| ReturnType<typeof navigationTitle>;
|
|
1784
1842
|
|
|
1785
1843
|
/**
|
|
1786
1844
|
* Main ViewModifier type that supports both built-in and 3rd party modifiers.
|