@satinhq/kit 0.1.0-beta.2 → 0.1.0-beta.3

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 (104) hide show
  1. package/NOTICE +2 -2
  2. package/README.md +1 -1
  3. package/dist/acknowledgements/inventory.json +5 -5
  4. package/dist/actions/RowActions.d.ts +2 -2
  5. package/dist/actions/RowActions.js +2 -2
  6. package/dist/controls/civilDate.d.ts +1 -1
  7. package/dist/controls/civilDate.js +1 -1
  8. package/dist/docs/components/file-importer.md +1 -1
  9. package/dist/docs/components/paste-button.md +1 -1
  10. package/dist/docs/components/photos-picker.md +1 -1
  11. package/dist/docs/components/share-link.md +1 -1
  12. package/dist/docs/limitations.md +1 -1
  13. package/dist/docs/push.md +3 -3
  14. package/dist/docs/reference.md +1870 -0
  15. package/dist/glass/lens/controlLift.d.ts +1 -1
  16. package/dist/glass/lens/controlLift.js +1 -1
  17. package/dist/glass/lens/interactivePress.d.ts +2 -2
  18. package/dist/glass/lens/interactivePress.js +2 -2
  19. package/dist/glass/lens/menu-opening-native-fits.json +1 -1
  20. package/dist/glass/lens/menuContextFit.json +1 -1
  21. package/dist/glass/lens/menuDropFit.json +1 -1
  22. package/dist/glass/lens/menuField.d.ts +2 -2
  23. package/dist/glass/lens/menuField.js +3 -3
  24. package/dist/glass/lens/menuGlyphDropFit.json +1 -1
  25. package/dist/glass/lens/menuMorphFit.json +1 -1
  26. package/dist/glass/lens/menuMorphPhoneFit.json +1 -1
  27. package/dist/glass/lens/tabAccessoryMotion.d.ts +1 -1
  28. package/dist/glass/lens/tabSearchMember.d.ts +1 -1
  29. package/dist/glass/lens/tabSearchMember.js +1 -1
  30. package/dist/glass/menuPresenter.js +1 -1
  31. package/dist/glass/regions.d.ts +1 -1
  32. package/dist/glass/regions.js +1 -1
  33. package/dist/glass/shapeTrack.d.ts +1 -1
  34. package/dist/glass/submenuMotion.d.ts +1 -1
  35. package/dist/glass/submenuMotion.js +1 -1
  36. package/dist/glass/webgpu/entry.worker.js +3 -6
  37. package/dist/glass/webgpu/frameClock.d.ts +6 -2
  38. package/dist/glass/webgpu/frameClock.js +9 -2
  39. package/dist/glass/webgpu/frameProbe.d.ts +1 -1
  40. package/dist/glass/webgpu/frameProbe.js +3 -3
  41. package/dist/glass/webgpu/production.js +4 -0
  42. package/dist/glass/webgpu/raster.d.ts +18 -0
  43. package/dist/glass/webgpu/raster.js +105 -15
  44. package/dist/glass/webgpu/rasterMaterial.d.ts +4 -0
  45. package/dist/glass/webgpu/rasterMaterial.js +17 -1
  46. package/dist/glass/webgpu/regionScene.d.ts +4 -1
  47. package/dist/glass/webgpu/regionScene.js +30 -1
  48. package/dist/glass/webgpu/renderer.js +23 -7
  49. package/dist/keyboard/adapter.js +2 -2
  50. package/dist/keyboard/avoidance.d.ts +1 -1
  51. package/dist/keyboard/avoidance.js +1 -1
  52. package/dist/keyboard/motion.d.ts +1 -1
  53. package/dist/keyboard/motion.js +1 -1
  54. package/dist/list-form/ListForm.d.ts +2 -2
  55. package/dist/list-form/ListForm.js +1 -1
  56. package/dist/list-form/ListItem.js +1 -1
  57. package/dist/list-form/RowLabel.d.ts +1 -1
  58. package/dist/list-form/RowLabel.js +1 -1
  59. package/dist/list-form/Slider.js +1 -1
  60. package/dist/list-form/editMotion.js +1 -1
  61. package/dist/list-form/editing.d.ts +5 -5
  62. package/dist/list-form/editing.js +1 -1
  63. package/dist/motion/animationValue.d.ts +2 -2
  64. package/dist/motion/animationValue.js +9 -10
  65. package/dist/motion/matchedGeometry.d.ts +4 -4
  66. package/dist/motion/matchedGeometry.js +7 -8
  67. package/dist/motion/springTrack.d.ts +1 -2
  68. package/dist/motion/springTrack.js +10 -5
  69. package/dist/navigation/ScreenContainer.js +1 -1
  70. package/dist/navigation/chromeCurves.js +1 -1
  71. package/dist/navigation/types.d.ts +1 -1
  72. package/dist/navigation/zoomGeometry.js +1 -1
  73. package/dist/navigation/zoomMotion.d.ts +1 -1
  74. package/dist/navigation/zoomMotion.js +2 -2
  75. package/dist/navigation/zoomTransition.js +3 -4
  76. package/dist/presentation/Presentation.d.ts +2 -2
  77. package/dist/presentation/Presentation.js +1 -1
  78. package/dist/presentation/presentationSource.js +1 -1
  79. package/dist/public/controls.d.ts +4 -4
  80. package/dist/public/controls.js +7 -7
  81. package/dist/public/glass.d.ts +3 -4
  82. package/dist/public/glass.js +1 -2
  83. package/dist/public/navigationTransition.d.ts +1 -1
  84. package/dist/public/navigationTransition.js +1 -1
  85. package/dist/public/scroll.d.ts +1 -1
  86. package/dist/public/scroll.js +1 -1
  87. package/dist/public/toolbar.js +1 -1
  88. package/dist/safe-area/SafeAreaInset.js +3 -3
  89. package/dist/safe-area/modifiers.js +2 -2
  90. package/dist/safe-area/useSafeAreaMetrics.js +2 -2
  91. package/dist/scroll/ScrollSurface.d.ts +5 -5
  92. package/dist/scroll/ScrollSurface.js +1 -1
  93. package/dist/scroll/position.js +1 -1
  94. package/dist/scroll/screenGeometry.d.ts +1 -1
  95. package/dist/scroll/screenGeometry.js +1 -1
  96. package/dist/search/SearchDrawer.js +1 -1
  97. package/dist/search/searchMotion.d.ts +1 -1
  98. package/dist/search/searchMotion.js +1 -1
  99. package/dist/search/useSearchPresentation.js +1 -1
  100. package/dist/shapes/corners.js +1 -1
  101. package/dist/styles.css +55 -34
  102. package/dist/text-input/TextEditor.js +7 -3
  103. package/package.json +4 -4
  104. package/dist/docs/swiftui-reference.md +0 -1895
@@ -19,7 +19,7 @@ export type SheetProps = PresentationProps & {
19
19
  * content that fills the card (Now Playing). A modal NavigationStack root's title is drawn by
20
20
  * its navigation bar either way. */
21
21
  titleVisibility?: 'visible' | 'hidden';
22
- /** SwiftUI's `presentationDragIndicator`. `automatic` shows it only when there is more than one
22
+ /** Control the sheet drag indicator. `automatic` shows it only when there is more than one
23
23
  * detent to drag between, as native does. */
24
24
  dragIndicator?: 'automatic' | 'visible' | 'hidden';
25
25
  };
@@ -27,7 +27,7 @@ export declare function Sheet(props: SheetProps): import("react").JSX.Element |
27
27
  export type FullScreenCoverProps = PresentationProps & {
28
28
  children: ReactNode;
29
29
  };
30
- /** SwiftUI's `fullScreenCover`: an opaque presentation over the whole screen that slides up from
30
+ /** An opaque presentation over the whole screen that slides up from
31
31
  * the bottom edge. It has no grabber and no interactive dismissal; close it with its binding or
32
32
  * `useDismiss()`. Its title labels the dialog for assistive technology and is not drawn. */
33
33
  export declare function FullScreenCover({ children, ...props }: FullScreenCoverProps): import("react").JSX.Element | null;
@@ -23,7 +23,7 @@ export function Sheet(props) {
23
23
  props.onDismiss?.();
24
24
  } })) : null;
25
25
  }
26
- /** SwiftUI's `fullScreenCover`: an opaque presentation over the whole screen that slides up from
26
+ /** An opaque presentation over the whole screen that slides up from
27
27
  * the bottom edge. It has no grabber and no interactive dismissal; close it with its binding or
28
28
  * `useDismiss()`. Its title labels the dialog for assistive technology and is not drawn. */
29
29
  export function FullScreenCover({ children, ...props }) {
@@ -1,7 +1,7 @@
1
1
  /** The control a presentation grows from when the app names no anchor. Native iOS 27 presents
2
2
  * `confirmationDialog` as a popover from the view that asked for it: a swipe action's dialog points
3
3
  * at its row, a toolbar button's dialog grows out of the button. Satin's natural structure attaches
4
- * the dialog at screen level, so the pressed control stands in for SwiftUI's attachment point. */
4
+ * the dialog at screen level, so the pressed control supplies the attachment point. */
5
5
  const lastPress = new WeakMap();
6
6
  const tracked = new WeakSet();
7
7
  // A press older than this did not open the dialog (a timer or a data change did).
@@ -112,7 +112,7 @@ export type ButtonProps = AriaAttributes & RowInteractionProps & {
112
112
  iconOnly?: false;
113
113
  });
114
114
  /**
115
- * SwiftUI `Button`. It adapts to where it is: a tinted row in a `List`, a glass button in a
115
+ * A pressable control that adapts to where it is: a tinted row in a `List`, a glass button in a
116
116
  * toolbar, otherwise the `buttonStyle` you choose. `role="destructive"` carries into every context.
117
117
  *
118
118
  * @example
@@ -291,7 +291,7 @@ export type VerticalTextFieldProps = Omit<TextareaHTMLAttributes<HTMLTextAreaEle
291
291
  /** A single-line field, or with `axis="vertical"` a field that grows to its `lineLimit`. */
292
292
  export type TextFieldProps = HorizontalTextFieldProps | VerticalTextFieldProps;
293
293
  /**
294
- * SwiftUI `TextField`: controlled text with a label, an optional `prompt` and keyboard intent from
294
+ * Single-line controlled text with a label, an optional `prompt` and keyboard intent from
295
295
  * `kind`. In a `List` or `Form` it becomes the row; elsewhere it draws a standalone field.
296
296
  * `axis="vertical"` grows with its content.
297
297
  *
@@ -314,7 +314,7 @@ export type SecureFieldProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type
314
314
  prompt?: string;
315
315
  textFieldStyle?: TextFieldStyle;
316
316
  };
317
- /** SwiftUI `SecureField`: password entry with secure system input, adapting to a row in a form. */
317
+ /** Password entry with secure system input, adapting to a row in a form. */
318
318
  export declare const SecureField: import("react").ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "defaultValue" | "onChange" | "onSubmit" | "placeholder" | "size" | "type" | "value"> & {
319
319
  label: string;
320
320
  value: string;
@@ -336,7 +336,7 @@ export type TextEditorProps = Omit<TextareaHTMLAttributes<HTMLTextAreaElement>,
336
336
  prompt?: string;
337
337
  textFieldStyle?: TextFieldStyle;
338
338
  };
339
- /** SwiftUI `TextEditor`: multiline text, adapting to a row in a form. */
339
+ /** Multiline text entry, adapting to a row in a form. */
340
340
  export declare const TextEditor: import("react").ForwardRefExoticComponent<Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "defaultValue" | "onChange" | "placeholder" | "rows" | "value"> & {
341
341
  value: string;
342
342
  onChange(value: string): void;
@@ -52,7 +52,7 @@ export function Form(props) {
52
52
  return (_jsx(List, { ...props, listStyle: "insetGrouped", scrollDismissesKeyboard: props.scrollDismissesKeyboard ?? 'immediately' }));
53
53
  }
54
54
  /**
55
- * SwiftUI `Button`. It adapts to where it is: a tinted row in a `List`, a glass button in a
55
+ * A pressable control that adapts to where it is: a tinted row in a `List`, a glass button in a
56
56
  * toolbar, otherwise the `buttonStyle` you choose. `role="destructive"` carries into every context.
57
57
  *
58
58
  * @example
@@ -72,9 +72,9 @@ export const Button = forwardRef(function Button({ children, symbol, role, butto
72
72
  const resolvedBorderShape = resolveButtonBorderShape(buttonBorderShape);
73
73
  const [isPressed, setPressed] = useState(false);
74
74
  // A toolbar button labelled with an icon-only Label or a SymbolImage is a glass circle, and so is a
75
- // titled button with a symbol: SwiftUI's `Button("New Reminder", systemImage: "plus")` in a toolbar
75
+ // A titled toolbar button with a symbol uses a circular control.
76
76
  // draws only its symbol (iOS 27.0 native reference), the title becoming its accessible name. A bare symbol
77
- // with no title is the same circle (SwiftUI's `Button { } label: { Image(systemName:) }`).
77
+ // An icon-only toolbar button uses the same circle.
78
78
  const symbolTitle = toolbar && symbol && typeof children === 'string' && !rest.iconOnly ? children : undefined;
79
79
  const bareSymbolName = toolbar && symbol && (children == null || typeof children === 'boolean') && !rest.iconOnly
80
80
  ? rest['aria-label']?.trim() || symbol
@@ -236,7 +236,7 @@ function toggleLabel(props, descriptionId) {
236
236
  * options={[{ id: 'home', label: 'Home', symbol: 'house', color: systemColor('red') }]} />
237
237
  */
238
238
  export function Picker({ pickerStyle = 'menu', selection, onSelectionChange, disabled, ...rest }) {
239
- // `ControlStyleProvider disabled` disables a Picker as SwiftUI's `.disabled` does a subtree.
239
+ // `ControlStyleProvider disabled` disables a Picker throughout its subtree.
240
240
  const configuration = useControlStyle({ disabled });
241
241
  const props = {
242
242
  ...rest,
@@ -276,7 +276,7 @@ const Field = forwardRef(function TextField({ prompt, textFieldStyle, style, ...
276
276
  return (_jsx(Fields.TextField, { ...fieldProps, style: style, ref: ref, placeholder: prompt ?? (hidden ? props.label : undefined), variant: variant, labelVisibility: hidden ? 'hidden' : 'visible' }));
277
277
  });
278
278
  /**
279
- * SwiftUI `TextField`: controlled text with a label, an optional `prompt` and keyboard intent from
279
+ * Single-line controlled text with a label, an optional `prompt` and keyboard intent from
280
280
  * `kind`. In a `List` or `Form` it becomes the row; elsewhere it draws a standalone field.
281
281
  * `axis="vertical"` grows with its content.
282
282
  *
@@ -285,12 +285,12 @@ const Field = forwardRef(function TextField({ prompt, textFieldStyle, style, ...
285
285
  */
286
286
  // The cast keeps single-line refs and events precisely typed when axis is omitted.
287
287
  export const TextField = Field;
288
- /** SwiftUI `SecureField`: password entry with secure system input, adapting to a row in a form. */
288
+ /** Password entry with secure system input, adapting to a row in a form. */
289
289
  export const SecureField = forwardRef(function SecureField({ prompt, textFieldStyle, style, ...props }, ref) {
290
290
  const variant = useFieldVariant(textFieldStyle);
291
291
  return (_jsx(Fields.SecureField, { ...props, style: style, ref: ref, placeholder: prompt ?? (variant !== 'standalone' ? props.label : undefined), variant: variant, labelVisibility: prompt !== undefined || variant !== 'standalone' ? 'hidden' : 'visible' }));
292
292
  });
293
- /** SwiftUI `TextEditor`: multiline text, adapting to a row in a form. */
293
+ /** Multiline text entry, adapting to a row in a form. */
294
294
  export const TextEditor = forwardRef(function TextEditor({ prompt, textFieldStyle, style, ...props }, ref) {
295
295
  const variant = useFieldVariant(textFieldStyle);
296
296
  return (_jsx(Editor, { ...props, minLines: props.minLines ?? (variant === 'row' ? 1 : 3), style: style, ref: ref, placeholder: prompt ?? (variant === 'plain' ? props.label : undefined), variant: variant, labelVisibility: prompt !== undefined || variant !== 'standalone' ? 'hidden' : 'visible' }));
@@ -14,14 +14,13 @@ export type GlassEffectProps = HTMLAttributes<HTMLDivElement> & {
14
14
  in?: NamespaceID;
15
15
  /** Morph identity within namespace; independent of the DOM id. */
16
16
  glassEffectID?: string;
17
- /** `glassEffectUnion(id:namespace:)`: effects with one union id draw as one shape. */
17
+ /** Effects with one union id draw as one shape. */
18
18
  glassEffectUnion?: string;
19
- /** `glassEffectTransition`. */
19
+ /** Controls how an identified effect enters or leaves its container. */
20
20
  glassEffectTransition?: 'matchedGeometry' | 'materialize' | 'identity';
21
21
  };
22
22
  /**
23
- * `glassEffect(_:in:)`: draws Liquid Glass behind its content in the given shape (a
24
- * capsule by default). Inside a `GlassEffectContainer`, effects with ids morph into one another.
23
+ * Draws glass behind its content in the given shape, using a capsule by default. Inside a `GlassEffectContainer`, effects with ids morph into one another.
25
24
  *
26
25
  * @example
27
26
  * <GlassEffect glass={Glass.regular.interactive()} shape="circle">
@@ -3,8 +3,7 @@ import { Glass, resolveGlass } from './glassValue.js';
3
3
  import { GlassFieldContext } from './fieldContext.js';
4
4
  import { GlassEffect as Effect } from '../glass/GlassEffect.js';
5
5
  /**
6
- * `glassEffect(_:in:)`: draws Liquid Glass behind its content in the given shape (a
7
- * capsule by default). Inside a `GlassEffectContainer`, effects with ids morph into one another.
6
+ * Draws glass behind its content in the given shape, using a capsule by default. Inside a `GlassEffectContainer`, effects with ids morph into one another.
8
7
  *
9
8
  * @example
10
9
  * <GlassEffect glass={Glass.regular.interactive()} shape="circle">
@@ -17,7 +17,7 @@ export type ZoomTransitionOptions = Readonly<{
17
17
  sourceID: string;
18
18
  in: NamespaceID;
19
19
  }>;
20
- /** SwiftUI's navigation transitions. */
20
+ /** Transitions between retained navigation entries. */
21
21
  export declare const NavigationTransition: Readonly<{
22
22
  automatic: NavigationTransition;
23
23
  zoom: (options: ZoomTransitionOptions) => NavigationTransition;
@@ -4,7 +4,7 @@ import { NavigatorContext } from '../navigation/navigationContext.js';
4
4
  import { installZoomDismissDrag } from '../navigation/zoomDrag.js';
5
5
  import { registerTransitionSource, registerZoomRequest } from '../navigation/zoomTransition.js';
6
6
  const brand = Symbol('satin.navigationTransition');
7
- /** SwiftUI's navigation transitions. */
7
+ /** Transitions between retained navigation entries. */
8
8
  export const NavigationTransition = Object.freeze({
9
9
  /** The platform's push: the screen slides in from the trailing edge. */
10
10
  automatic: Object.freeze({ [brand]: true, kind: 'automatic' }),
@@ -34,5 +34,5 @@ export type ScrollViewProps = Omit<HTMLAttributes<HTMLDivElement>, 'id'> & {
34
34
  scrollPosition?: never;
35
35
  onScrollGeometryChange?: never;
36
36
  });
37
- /** SwiftUI ScrollView with framework-owned restoration and native scrolling. */
37
+ /** A scroll surface with framework-owned restoration and native scrolling. */
38
38
  export declare const ScrollView: import("react").ForwardRefExoticComponent<ScrollViewProps & import("react").RefAttributes<ScrollViewHandle>>;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { forwardRef } from 'react';
3
3
  import { ScrollSurface } from '../scroll/ScrollSurface.js';
4
- /** SwiftUI ScrollView with framework-owned restoration and native scrolling. */
4
+ /** A scroll surface with framework-owned restoration and native scrolling. */
5
5
  export const ScrollView = forwardRef(function ScrollView(props, ref) {
6
6
  return _jsx(ScrollSurface, { ...props, ref: ref });
7
7
  });
@@ -69,7 +69,7 @@ export function ToolbarSpacer({ sizing = 'flexible', placement = 'automatic', })
69
69
  /** `ToolbarItemGroup`: its items render as consecutive `ToolbarItem`s of the placement,
70
70
  * which share one glass capsule (iOS 26+ draws a group and adjacent items identically). */
71
71
  export function ToolbarItemGroup({ children, placement }) {
72
- // SwiftUI gives confirmation actions separate capsules, even inside a group.
72
+ // gives confirmation actions separate capsules, even inside a group.
73
73
  if (placement === 'confirmationAction')
74
74
  return (_jsx(ToolbarItem, { placement: placement, children: _jsx("div", { "data-satin-toolbar-confirmation-group": "true", children: children }) }));
75
75
  return (_jsx(_Fragment, { children: Children.toArray(children).map((child, index) => (_jsx(ToolbarItem, { placement: placement, children: child }, isValidElement(child) && child.key !== null ? child.key : index))) }));
@@ -6,7 +6,7 @@ import { IgnoresSafeAreaContext } from './context.js';
6
6
  import { createContext, useContext, useLayoutEffect, useRef, useMemo, useCallback, } from 'react';
7
7
  /** Whether an enclosing SafeAreaInset already owns the bottom boundary (keyboard, home indicator). */
8
8
  export const BottomInsetContext = createContext({ consumed: false });
9
- /** SwiftUI's system spacing between content and a safe-area inset (`spacing: nil`). */
9
+ /** Default spacing between content and a safe-area inset. */
10
10
  const SYSTEM_INSET_SPACING_PX = 8;
11
11
  const ACCESSORY_INSET_SCOPE = { consumed: true };
12
12
  /**
@@ -41,7 +41,7 @@ function BottomInset({ content, spacing, children, ...props }) {
41
41
  geometry.publish((parent.geometry?.value ?? 0) + measuredHeight.current + spacing + extension);
42
42
  }, [geometry, parent.geometry, spacing]);
43
43
  // `IgnoresSafeArea regions="keyboard"` around the inset: the boundary stays above the home
44
- // indicator while the keyboard is up, as SwiftUI's `ignoresSafeArea(.keyboard)`.
44
+ // indicator while the keyboard is up `ignoresSafeArea(.keyboard)`.
45
45
  const keyboardIgnored = useContext(IgnoresSafeAreaContext).keyboard;
46
46
  const inset = useRef(null);
47
47
  const accessory = useRef(null);
@@ -112,7 +112,7 @@ function BottomInset({ content, spacing, children, ...props }) {
112
112
  * native adds it to the scroll view's adjusted inset (iOS 27 native reference `inset-top`: 116 + 44.33 + 8);
113
113
  * - leading/trailing: the accessory is a column of the safe area's height and the content's frame
114
114
  * gives up its width plus `spacing` (`inset-leading`: strip 0–60, cards from 68).
115
- * A background drawn by the accessory's root view reaches the screen's top edge, as a SwiftUI
115
+ * A background drawn by the accessory's root view reaches the screen's top edge. An accessory
116
116
  * `background` ignores the safe area by default (`inset-top`: the yellow fills 0–160.33).
117
117
  */
118
118
  function EdgeInset({ edge, content, spacing, children, ...props }) {
@@ -3,7 +3,7 @@ import { startsScreenContent } from '../scroll/screenGeometry.js';
3
3
  import { SafeAreaInset } from './SafeAreaInset.js';
4
4
  import { ContentMarginsContext, IgnoresSafeAreaContext, NO_LENGTHS, SafeAreaPaddingContext, } from './context.js';
5
5
  import { useContext, useLayoutEffect, useRef } from 'react';
6
- /** SwiftUI's default padding amount (`padding()` and `safeAreaPadding()` with no length). */
6
+ /** Default padding used when no length is supplied. */
7
7
  const SYSTEM_PADDING_PX = 16;
8
8
  function edgesOf(set) {
9
9
  const edges = new Set();
@@ -68,7 +68,7 @@ export function IgnoresSafeArea({ regions = 'all', edges = 'all', children, ...p
68
68
  const container = regions === 'keyboard' ? new Set() : set;
69
69
  const keyboard = regions !== 'container' && set.has('bottom');
70
70
  const element = useRef(null);
71
- // Only a view that reaches the safe edge extends past it, as SwiftUI's does.
71
+ // Only a view that reaches the safe edge extends past it.
72
72
  useLayoutEffect(() => {
73
73
  const node = element.current;
74
74
  if (!node)
@@ -60,7 +60,7 @@ function readInsets(element) {
60
60
  };
61
61
  }
62
62
  // Native home-indicator boundaries, in points. Phone: Foundation 00, iPhone 17 Pro Max,
63
- // iOS 27 portrait. Pad: a SwiftUI .safeAreaInset(edge: .bottom) composer on iPad Pro
63
+ // iOS 27 portrait. Pad: a .safeAreaInset(edge: .bottom) composer on iPad Pro
64
64
  // 12.9-inch, iPadOS 27, which keeps 25 pt in portrait and in landscape.
65
65
  const PHONE_HOME_INDICATOR_INSET = 34;
66
66
  const PAD_HOME_INDICATOR_INSET = 25;
@@ -72,7 +72,7 @@ const PAD_FITTED_STATUS_BAND = 32;
72
72
  * With viewport-fit auto/contain, the system takes the status band outside the viewport,
73
73
  * but content still reaches the screen bottom and every env() inset reads zero. Without
74
74
  * this boundary, bottom bars and composers sit in the home-indicator band: on iPad a
75
- * composer sat 25 pt lower than the same SwiftUI layout, its trailing edge in the corner
75
+ * composer sat 25 pt lower than the same layout, its trailing edge in the corner
76
76
  * that carries the window-resize grabber. Device identity comes from the shared
77
77
  * resolver, never from screen dimensions.
78
78
  */
@@ -28,15 +28,15 @@ export type ScrollSurfaceProps = Omit<HTMLAttributes<HTMLDivElement>, 'id'> & Sc
28
28
  /**
29
29
  * Whether this is the screen's primary scroll view, which gets the large title, the bar's
30
30
  * content inset and the scroll edge effect. By default the outermost vertical scroll view at the
31
- * top of the screen's content is primary, as in SwiftUI.
31
+ * top of the screen's content is primary.
32
32
  */
33
33
  primary?: boolean;
34
- /** SwiftUI `scrollEdgeEffectHidden(_:for: .top)`: no scroll edge effect under the bar. */
34
+ /** Hide the scroll edge effect under the top bar. */
35
35
  scrollEdgeEffectHidden?: ScrollEdgeEffectHidden;
36
36
  /** Soft/automatic select the existing top treatment. Hard is explicitly unsupported. */
37
37
  scrollEdgeEffectStyle?: ScrollEdgeEffectStyleSelection;
38
38
  }>;
39
- /** SwiftUI `ScrollView`: a named scroll surface whose position is retained by the framework. */
39
+ /** A named scroll surface whose position is retained by the framework. */
40
40
  export declare const ScrollSurface: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLDivElement>, "id"> & Readonly<{
41
41
  defaultScrollAnchor?: 'top' | 'bottom';
42
42
  maintainVisibleContentPosition?: boolean;
@@ -52,10 +52,10 @@ export declare const ScrollSurface: import("react").ForwardRefExoticComponent<Om
52
52
  /**
53
53
  * Whether this is the screen's primary scroll view, which gets the large title, the bar's
54
54
  * content inset and the scroll edge effect. By default the outermost vertical scroll view at the
55
- * top of the screen's content is primary, as in SwiftUI.
55
+ * top of the screen's content is primary.
56
56
  */
57
57
  primary?: boolean;
58
- /** SwiftUI `scrollEdgeEffectHidden(_:for: .top)`: no scroll edge effect under the bar. */
58
+ /** Hide the scroll edge effect under the top bar. */
59
59
  scrollEdgeEffectHidden?: ScrollEdgeEffectHidden;
60
60
  /** Soft/automatic select the existing top treatment. Hard is explicitly unsupported. */
61
61
  scrollEdgeEffectStyle?: ScrollEdgeEffectStyleSelection;
@@ -27,7 +27,7 @@ export const ListNavigationContext = createContext(undefined);
27
27
  /** A scroll view's content is inside its safe area: modifiers above it stop at its frame. */
28
28
  const NO_IGNORED = { container: new Set(), keyboard: false };
29
29
  const cssLength = (value) => typeof value === 'number' ? `${value}px` : (value ?? '0px');
30
- /** SwiftUI `ScrollView`: a named scroll surface whose position is retained by the framework. */
30
+ /** A named scroll surface whose position is retained by the framework. */
31
31
  export const ScrollSurface = forwardRef(function ScrollSurface({ axis = 'vertical', chain = false, children, primary, scrollEdgeEffectHidden, scrollEdgeEffectStyle, refreshable, scrollDismissesKeyboard = 'never', id, defaultScrollAnchor, maintainVisibleContentPosition, scrollPosition, onScrollGeometryChange, ...props }, forwardedRef) {
32
32
  const refresh = refreshable;
33
33
  if (axis !== 'vertical' &&
@@ -84,7 +84,7 @@ export function createScrollPositionController(surface, content, targets, option
84
84
  pending = undefined;
85
85
  const targetTop = top(target);
86
86
  const height = target.getBoundingClientRect().height;
87
- // Targets align within the content insets, as SwiftUI's do: a screen's primary scroll view
87
+ // Targets align within the content insets, within the owned scroll region: a screen's primary scroll view
88
88
  // reaches under the bar and the bottom bars, and its padding is the bar's and the bottom inset
89
89
  // chain's content inset. Other scroll views only clear the enclosing bottom insets' accessories.
90
90
  const style = getComputedStyle(surface);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Whether a scroll view starts its screen's content, as a SwiftUI scroll view that reaches the
2
+ * Whether a scroll view starts its screen's content, as a scroll view that reaches the
3
3
  * top safe-area edge does. Only such a scroll view extends under the navigation bar and takes the
4
4
  * bar's content inset; one placed below other content keeps its own frame, like a Form under a
5
5
  * header in a VStack.
@@ -11,7 +11,7 @@ function occupiesFlow(element) {
11
11
  return position !== 'absolute' && position !== 'fixed';
12
12
  }
13
13
  /**
14
- * Whether a scroll view starts its screen's content, as a SwiftUI scroll view that reaches the
14
+ * Whether a scroll view starts its screen's content, as a scroll view that reaches the
15
15
  * top safe-area edge does. Only such a scroll view extends under the navigation bar and takes the
16
16
  * bar's content inset; one placed below other content keeps its own frame, like a Form under a
17
17
  * header in a VStack.
@@ -258,7 +258,7 @@ function pinProgress(drawer) {
258
258
  }
259
259
  /* How far the resting field has turned from its grey fill to glass. The field is glass from
260
260
  * scroll 0 only when the drawer is fixed in the bar: an explicit `navigationBarDrawer` placement
261
- * (SwiftUI's `displayMode: .always`) under an inline or inlineLarge title (native reference reference and reference
261
+ * with persistent visibility under an inline or inlineLarge title (native reference reference and reference
262
262
  * B/H, iOS 27.0: light 251 with a darker rim, dark 32 with a light rim). Under a large title the
263
263
  * field belongs to the content header, and an automatic placement's drawer scrolls away with the
264
264
  * content; both are a grey fill until content scrolls under the field (reference A/C/D/G: light 228-239,
@@ -3,7 +3,7 @@ import { sampledKeyframes, springTrack, type SpringParameters, type SpringTrack
3
3
  export { sampledKeyframes, springTrack, type SpringTrack };
4
4
  /**
5
5
  * Native `.searchable` presentation and dismissal, measured from the presentation layer of a
6
- * stock SwiftUI drawer (iOS 27.0, 15 focus/close trials in light and dark,
6
+ * native search drawer (iOS 27.0, 15 focus/close trials in light and dark,
7
7
  * every frame).
8
8
  *
9
9
  * - The field's position and width, the list content, the close button and the field's grey fill
@@ -3,7 +3,7 @@ import { sampledKeyframes, springMotion, springTrack, } from '../motion/springTr
3
3
  export { sampledKeyframes, springTrack };
4
4
  /**
5
5
  * Native `.searchable` presentation and dismissal, measured from the presentation layer of a
6
- * stock SwiftUI drawer (iOS 27.0, 15 focus/close trials in light and dark,
6
+ * native search drawer (iOS 27.0, 15 focus/close trials in light and dark,
7
7
  * every frame).
8
8
  *
9
9
  * - The field's position and width, the list content, the close button and the field's grey fill
@@ -3,7 +3,7 @@ import { focusFromFramework } from '../focus/programmaticFocus.js';
3
3
  import { validateSearchPresentation } from './searchable.js';
4
4
  /*
5
5
  * The state of one `searchable` field, whatever draws it: presentation (owned or controlled by
6
- * `isPresented:`), text changes, submission and suggestion completion, as SwiftUI's search
6
+ * `isPresented:`), text changes, submission and suggestion completion search
7
7
  * controller. The bottom toolbar field uses it (SearchToolbarField.tsx); the navigation bar drawer
8
8
  * keeps its own copy until reference adopts this hook (spec notes, reference construction update).
9
9
  */
@@ -1,4 +1,4 @@
1
- /** Measured from public SwiftUI RoundedRectangle paths on iOS 27.0. The
1
+ /** Continuous rounded corners measured on iOS 27.0. The
2
2
  * straight-edge approach contracts independently on each axis for short boxes;
3
3
  * clamping the entire continuous corner to half-height changes its curvature. */
4
4
  const extent = 1.5286649466;