@expo/ui 57.0.16 → 57.0.17

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 (75) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/DatePickerView.kt +29 -18
  4. package/android/src/main/java/expo/modules/ui/DateRangePickerView.kt +191 -0
  5. package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +17 -0
  6. package/android/src/main/java/expo/modules/ui/RadioButtonView.kt +23 -1
  7. package/build/community/bottom-sheet/BottomSheet.android.d.ts.map +1 -1
  8. package/build/community/bottom-sheet/BottomSheet.ios.d.ts.map +1 -1
  9. package/build/jetpack-compose/DatePicker/index.d.ts +84 -0
  10. package/build/jetpack-compose/DatePicker/index.d.ts.map +1 -1
  11. package/build/jetpack-compose/RadioButton/index.d.ts +19 -0
  12. package/build/jetpack-compose/RadioButton/index.d.ts.map +1 -1
  13. package/build/swift-ui/modifiers/containerBackground.d.ts +9 -4
  14. package/build/swift-ui/modifiers/containerBackground.d.ts.map +1 -1
  15. package/build/swift-ui/modifiers/index.d.ts +41 -10
  16. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  17. package/build/swift-ui/modifiers/presentationModifiers.d.ts +6 -3
  18. package/build/swift-ui/modifiers/presentationModifiers.d.ts.map +1 -1
  19. package/expo-module.config.json +1 -1
  20. package/ios/Modifiers/ContainerBackgroundModifier.swift +4 -4
  21. package/ios/Modifiers/PresentationModifiers.swift +3 -3
  22. package/ios/Modifiers/ScrollClipDisabledModifier.swift +16 -0
  23. package/ios/Modifiers/ViewModifierRegistry.swift +18 -8
  24. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.16/expo.modules.ui-57.0.16-sources.jar → 57.0.17/expo.modules.ui-57.0.17-sources.jar} +0 -0
  25. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17-sources.jar.md5 +1 -0
  26. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17-sources.jar.sha1 +1 -0
  27. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17-sources.jar.sha256 +1 -0
  28. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17-sources.jar.sha512 +1 -0
  29. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.aar +0 -0
  30. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.aar.md5 +1 -0
  31. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.aar.sha1 +1 -0
  32. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.aar.sha256 +1 -0
  33. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.aar.sha512 +1 -0
  34. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.16/expo.modules.ui-57.0.16.module → 57.0.17/expo.modules.ui-57.0.17.module} +22 -22
  35. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.module.md5 +1 -0
  36. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.module.sha1 +1 -0
  37. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.module.sha256 +1 -0
  38. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.module.sha512 +1 -0
  39. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{57.0.16/expo.modules.ui-57.0.16.pom → 57.0.17/expo.modules.ui-57.0.17.pom} +1 -1
  40. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.pom.md5 +1 -0
  41. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.pom.sha1 +1 -0
  42. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.pom.sha256 +1 -0
  43. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.17/expo.modules.ui-57.0.17.pom.sha512 +1 -0
  44. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  45. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  46. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  47. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  48. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  49. package/package.json +3 -3
  50. package/spm.config.json +1 -1
  51. package/src/community/bottom-sheet/BottomSheet.android.tsx +5 -3
  52. package/src/community/bottom-sheet/BottomSheet.ios.tsx +4 -3
  53. package/src/jetpack-compose/DatePicker/index.tsx +152 -0
  54. package/src/jetpack-compose/RadioButton/index.tsx +20 -0
  55. package/src/swift-ui/modifiers/containerBackground.ts +10 -5
  56. package/src/swift-ui/modifiers/index.ts +58 -8
  57. package/src/swift-ui/modifiers/presentationModifiers.ts +7 -4
  58. package/src/universal/transformStyle.ios.ts +2 -2
  59. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16-sources.jar.md5 +0 -1
  60. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16-sources.jar.sha1 +0 -1
  61. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16-sources.jar.sha256 +0 -1
  62. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16-sources.jar.sha512 +0 -1
  63. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.aar +0 -0
  64. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.aar.md5 +0 -1
  65. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.aar.sha1 +0 -1
  66. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.aar.sha256 +0 -1
  67. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.aar.sha512 +0 -1
  68. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.module.md5 +0 -1
  69. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.module.sha1 +0 -1
  70. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.module.sha256 +0 -1
  71. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.module.sha512 +0 -1
  72. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.pom.md5 +0 -1
  73. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.pom.sha1 +0 -1
  74. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.pom.sha256 +0 -1
  75. package/local-maven-repo/expo/modules/ui/expo.modules.ui/57.0.16/expo.modules.ui-57.0.16.pom.sha512 +0 -1
@@ -234,12 +234,13 @@ export function BottomSheet(props: BottomSheetProps) {
234
234
  <RNHostView matchContents={fitToContents}>
235
235
  {/* paddingTop compensates for tighter spacing between native drag indicator and content
236
236
  compared to gorhom's handle. flexGrow:1 + height:0 (flex-basis 0) fills the snap-point
237
- height without inheriting the scrollable child's intrinsic content height. Omitted for fitToContents
238
- so RNHostView can measure natural content height. */}
237
+ height without inheriting the scrollable child's intrinsic content height. With matchContents,
238
+ RNHostView lays the hosted view out at its own size, so `width` gives it the sheet width
239
+ while its height stays content-sized. */}
239
240
  <View
240
241
  style={
241
242
  fitToContents
242
- ? { paddingTop: handleComponent !== null ? 16 : 0 }
243
+ ? { width, paddingTop: handleComponent !== null ? 16 : 0 }
243
244
  : { flexGrow: 1, height: 0, paddingTop: handleComponent !== null ? 16 : 0 }
244
245
  }>
245
246
  <SheetScrollContextReset>{children}</SheetScrollContextReset>
@@ -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,6 +228,100 @@ 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 {
@@ -260,6 +372,46 @@ export function DatePickerDialog(props: DatePickerDialogProps) {
260
372
  return <DatePickerDialogNativeView {...nativeProps} />;
261
373
  }
262
374
 
375
+ export interface DateRangePickerDialogProps extends Omit<DateRangePickerProps, 'modifiers'> {
376
+ /**
377
+ * The label for the button that confirms the selected range.
378
+ * Defaults to the system "Ok" string.
379
+ */
380
+ confirmButtonLabel?: string;
381
+ /**
382
+ * The label for the button that dismisses the dialog.
383
+ * Defaults to the system "Cancel" string.
384
+ */
385
+ dismissButtonLabel?: string;
386
+ /** The tint color to use on the picker elements and dialog buttons. */
387
+ color?: ColorValue;
388
+ /** Callback function that is called when the user confirms a complete date range. */
389
+ onDateRangeSelected?: (range: DateRangeSelection) => void;
390
+ /** Callback function that is called when the dialog is dismissed. */
391
+ onDismissRequest: () => void;
392
+ }
393
+
394
+ type NativeDateRangePickerDialogProps = Omit<NativeDateRangePickerProps, 'modifiers'> &
395
+ Pick<DateRangePickerDialogProps, 'confirmButtonLabel' | 'dismissButtonLabel'> &
396
+ ViewEvent<'onDismissRequest', void>;
397
+
398
+ const DateRangePickerDialogNativeView: React.ComponentType<NativeDateRangePickerDialogProps> =
399
+ requireNativeView('ExpoUI', 'DateRangePickerDialogView');
400
+
401
+ /**
402
+ * Renders a modal Material 3 date range picker.
403
+ */
404
+ export function DateRangePickerDialog(props: DateRangePickerDialogProps) {
405
+ const { confirmButtonLabel, dismissButtonLabel, onDismissRequest, ...rest } = props;
406
+ const nativeProps: NativeDateRangePickerDialogProps = {
407
+ ...transformDateRangePickerProps(rest),
408
+ confirmButtonLabel,
409
+ dismissButtonLabel,
410
+ onDismissRequest,
411
+ };
412
+ return <DateRangePickerDialogNativeView {...nativeProps} />;
413
+ }
414
+
263
415
  export interface TimePickerDialogProps {
264
416
  initialDate?: string | null;
265
417
  is24Hour?: boolean;
@@ -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
  */
@@ -1,13 +1,18 @@
1
1
  import { createModifier } from './createModifier';
2
- import type { Color } from './types';
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 using a view.
8
- * @param color - The color to set as the background of the container.
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 = (color: Color, container: ContainerBackgroundPlacement) =>
13
- createModifier('containerBackground', { color, container });
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. Color and width.
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: { color: Color; width?: number }) =>
296
- createModifier('border', params);
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. Color (omit for the foreground style), style, antialiased, shape and cornerRadius.
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
- }) => createModifier('strokeBorder', params);
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 color of a view.
499
- * @param color - The tint color (hex string). For example, `#FF0000`.
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 = (color: Color) => createModifier('tint', { color });
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.
@@ -1725,6 +1774,7 @@ export type BuiltInModifier =
1725
1774
  | ReturnType<typeof containerRelativeFrame>
1726
1775
  | ReturnType<typeof scrollContentBackground>
1727
1776
  | ReturnType<typeof scrollDisabled>
1777
+ | ReturnType<typeof scrollClipDisabled>
1728
1778
  | ReturnType<typeof scrollIndicators>
1729
1779
  | ReturnType<typeof defaultScrollAnchor>
1730
1780
  | ReturnType<typeof defaultScrollAnchorForRole>
@@ -3,7 +3,7 @@ import {
3
3
  createModifierWithEventListener,
4
4
  type ModifierConfig,
5
5
  } from './createModifier';
6
- import type { Color } from './types';
6
+ import { resolveShapeStyle, type ShapeStyle } from './shapeStyle';
7
7
 
8
8
  /**
9
9
  * Presentation detent type for controlling sheet heights.
@@ -89,13 +89,16 @@ export const presentationBackgroundInteraction = (
89
89
  * Sets the background of a sheet presentation. Paints the entire sheet chrome
90
90
  * including the drag-indicator zone and home-indicator safe-area inset, which
91
91
  * a regular `background()` modifier cannot reach.
92
- * @param color - The background color.
92
+ *
93
+ * > **Note:** iOS 26 renders a material as a flat color rather than a translucent blur.
94
+ * @param style - Any [`ShapeStyle`](#shapestyle): a color, a hierarchical style, a material, or a gradient.
93
95
  * @platform ios 16.4+
96
+ * @platform tvos 16.4+
94
97
  * @see Official [SwiftUI
95
98
  documentation](https://developer.apple.com/documentation/swiftui/view/presentationbackground(_:)).
96
99
  */
97
- export const presentationBackground = (color: Color) =>
98
- createModifier('presentationBackground', { color });
100
+ export const presentationBackground = (style: ShapeStyle) =>
101
+ createModifier('presentationBackground', { style: resolveShapeStyle(style) });
99
102
 
100
103
  /**
101
104
  * Disables interactive dismissal of a sheet.
@@ -131,12 +131,12 @@ export function transformToModifiers(
131
131
 
132
132
  // Background (fills the frame area including padding)
133
133
  if (style.backgroundColor) {
134
- mods.push(background(String(style.backgroundColor)));
134
+ mods.push(background(style.backgroundColor));
135
135
  }
136
136
 
137
137
  // Border (before clip so the clip rounds the border corners too)
138
138
  if (style.borderWidth != null && style.borderColor != null) {
139
- mods.push(border({ color: String(style.borderColor), width: style.borderWidth }));
139
+ mods.push(border({ content: style.borderColor, width: style.borderWidth }));
140
140
  }
141
141
 
142
142
  // Clip (border radius — rounds both background and border)
@@ -1 +0,0 @@
1
- 6b28263e7e0227478fe261eeffb9f640dced8ca0
@@ -1 +0,0 @@
1
- 36bbbdb98934c3b0ecf275049cb2012dcb65ad2d329fee1f7e42428dcb49da04
@@ -1 +0,0 @@
1
- 99fa1b7ecf29945c1331833c23ab82c3717bea6a43f8056dacf7179a8eb86b18b7d1511838585debdaa6df79b9ea528e8af0babce933a03bd606838ef8747b7a
@@ -1 +0,0 @@
1
- a14f54eee92691240a7cd6a83f944b0ba11733a0
@@ -1 +0,0 @@
1
- 478029e9cf52a0e86909c248a99329f7e3488a65fc3ac06bce0fbf614f5553f1
@@ -1 +0,0 @@
1
- 5e177e8e0e7abb84c61422d42bd006f13589886297c6835028fd8df1be8a86bac8415dff355cd4d29abe28b209eca4171c32b5ef5552f46d71c2fc39a8f2a9fd
@@ -1 +0,0 @@
1
- e8be172ae1de0c69a4721b510ad4b2a57f38d0d7
@@ -1 +0,0 @@
1
- 606fea92fbb5bee94b622a8c8c181f4c7a092d8b495fbc69a5b78efe602667fd
@@ -1 +0,0 @@
1
- 29813d4039bcdd201463695c4dc7c25cd2a542a3e3b18d8a5dc483cd9ee8e654edcf8e87f896a44c31548e845e3f0b562440200ec50c23dcba4faf29e7918436
@@ -1 +0,0 @@
1
- ba7bbd6ac7336e57e6f2bff3bbf73cb50e280e27
@@ -1 +0,0 @@
1
- 7a5ff13f5a7f7b543453f3ca4d75fc04c726c75bd6ab837043af8100f6154adb
@@ -1 +0,0 @@
1
- 63a8a73c453fe98411f22786180631b84d8299418a6eded64c4a4b9df88017f60e8812a4d658d050ac0e9f4e79434cbb486799d5840b7a552978e24692160173