@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.
- package/NOTICE +2 -2
- package/README.md +1 -1
- package/dist/acknowledgements/inventory.json +5 -5
- package/dist/actions/RowActions.d.ts +2 -2
- package/dist/actions/RowActions.js +2 -2
- package/dist/controls/civilDate.d.ts +1 -1
- package/dist/controls/civilDate.js +1 -1
- package/dist/docs/components/file-importer.md +1 -1
- package/dist/docs/components/paste-button.md +1 -1
- package/dist/docs/components/photos-picker.md +1 -1
- package/dist/docs/components/share-link.md +1 -1
- package/dist/docs/limitations.md +1 -1
- package/dist/docs/push.md +3 -3
- package/dist/docs/reference.md +1870 -0
- package/dist/glass/lens/controlLift.d.ts +1 -1
- package/dist/glass/lens/controlLift.js +1 -1
- package/dist/glass/lens/interactivePress.d.ts +2 -2
- package/dist/glass/lens/interactivePress.js +2 -2
- package/dist/glass/lens/menu-opening-native-fits.json +1 -1
- package/dist/glass/lens/menuContextFit.json +1 -1
- package/dist/glass/lens/menuDropFit.json +1 -1
- package/dist/glass/lens/menuField.d.ts +2 -2
- package/dist/glass/lens/menuField.js +3 -3
- package/dist/glass/lens/menuGlyphDropFit.json +1 -1
- package/dist/glass/lens/menuMorphFit.json +1 -1
- package/dist/glass/lens/menuMorphPhoneFit.json +1 -1
- package/dist/glass/lens/tabAccessoryMotion.d.ts +1 -1
- package/dist/glass/lens/tabSearchMember.d.ts +1 -1
- package/dist/glass/lens/tabSearchMember.js +1 -1
- package/dist/glass/menuPresenter.js +1 -1
- package/dist/glass/regions.d.ts +1 -1
- package/dist/glass/regions.js +1 -1
- package/dist/glass/shapeTrack.d.ts +1 -1
- package/dist/glass/submenuMotion.d.ts +1 -1
- package/dist/glass/submenuMotion.js +1 -1
- package/dist/glass/webgpu/entry.worker.js +3 -6
- package/dist/glass/webgpu/frameClock.d.ts +6 -2
- package/dist/glass/webgpu/frameClock.js +9 -2
- package/dist/glass/webgpu/frameProbe.d.ts +1 -1
- package/dist/glass/webgpu/frameProbe.js +3 -3
- package/dist/glass/webgpu/production.js +4 -0
- package/dist/glass/webgpu/raster.d.ts +18 -0
- package/dist/glass/webgpu/raster.js +105 -15
- package/dist/glass/webgpu/rasterMaterial.d.ts +4 -0
- package/dist/glass/webgpu/rasterMaterial.js +17 -1
- package/dist/glass/webgpu/regionScene.d.ts +4 -1
- package/dist/glass/webgpu/regionScene.js +30 -1
- package/dist/glass/webgpu/renderer.js +23 -7
- package/dist/keyboard/adapter.js +2 -2
- package/dist/keyboard/avoidance.d.ts +1 -1
- package/dist/keyboard/avoidance.js +1 -1
- package/dist/keyboard/motion.d.ts +1 -1
- package/dist/keyboard/motion.js +1 -1
- package/dist/list-form/ListForm.d.ts +2 -2
- package/dist/list-form/ListForm.js +1 -1
- package/dist/list-form/ListItem.js +1 -1
- package/dist/list-form/RowLabel.d.ts +1 -1
- package/dist/list-form/RowLabel.js +1 -1
- package/dist/list-form/Slider.js +1 -1
- package/dist/list-form/editMotion.js +1 -1
- package/dist/list-form/editing.d.ts +5 -5
- package/dist/list-form/editing.js +1 -1
- package/dist/motion/animationValue.d.ts +2 -2
- package/dist/motion/animationValue.js +9 -10
- package/dist/motion/matchedGeometry.d.ts +4 -4
- package/dist/motion/matchedGeometry.js +7 -8
- package/dist/motion/springTrack.d.ts +1 -2
- package/dist/motion/springTrack.js +10 -5
- package/dist/navigation/ScreenContainer.js +1 -1
- package/dist/navigation/chromeCurves.js +1 -1
- package/dist/navigation/types.d.ts +1 -1
- package/dist/navigation/zoomGeometry.js +1 -1
- package/dist/navigation/zoomMotion.d.ts +1 -1
- package/dist/navigation/zoomMotion.js +2 -2
- package/dist/navigation/zoomTransition.js +3 -4
- package/dist/presentation/Presentation.d.ts +2 -2
- package/dist/presentation/Presentation.js +1 -1
- package/dist/presentation/presentationSource.js +1 -1
- package/dist/public/controls.d.ts +4 -4
- package/dist/public/controls.js +7 -7
- package/dist/public/glass.d.ts +3 -4
- package/dist/public/glass.js +1 -2
- package/dist/public/navigationTransition.d.ts +1 -1
- package/dist/public/navigationTransition.js +1 -1
- package/dist/public/scroll.d.ts +1 -1
- package/dist/public/scroll.js +1 -1
- package/dist/public/toolbar.js +1 -1
- package/dist/safe-area/SafeAreaInset.js +3 -3
- package/dist/safe-area/modifiers.js +2 -2
- package/dist/safe-area/useSafeAreaMetrics.js +2 -2
- package/dist/scroll/ScrollSurface.d.ts +5 -5
- package/dist/scroll/ScrollSurface.js +1 -1
- package/dist/scroll/position.js +1 -1
- package/dist/scroll/screenGeometry.d.ts +1 -1
- package/dist/scroll/screenGeometry.js +1 -1
- package/dist/search/SearchDrawer.js +1 -1
- package/dist/search/searchMotion.d.ts +1 -1
- package/dist/search/searchMotion.js +1 -1
- package/dist/search/useSearchPresentation.js +1 -1
- package/dist/shapes/corners.js +1 -1
- package/dist/styles.css +55 -34
- package/dist/text-input/TextEditor.js +7 -3
- package/package.json +4 -4
- 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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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;
|
package/dist/public/controls.js
CHANGED
|
@@ -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
|
-
*
|
|
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
|
|
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
|
-
//
|
|
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
|
|
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
|
-
*
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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' }));
|
package/dist/public/glass.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
17
|
+
/** Effects with one union id draw as one shape. */
|
|
18
18
|
glassEffectUnion?: string;
|
|
19
|
-
/**
|
|
19
|
+
/** Controls how an identified effect enters or leaves its container. */
|
|
20
20
|
glassEffectTransition?: 'matchedGeometry' | 'materialize' | 'identity';
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
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">
|
package/dist/public/glass.js
CHANGED
|
@@ -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
|
-
*
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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' }),
|
package/dist/public/scroll.d.ts
CHANGED
|
@@ -34,5 +34,5 @@ export type ScrollViewProps = Omit<HTMLAttributes<HTMLDivElement>, 'id'> & {
|
|
|
34
34
|
scrollPosition?: never;
|
|
35
35
|
onScrollGeometryChange?: never;
|
|
36
36
|
});
|
|
37
|
-
/**
|
|
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>>;
|
package/dist/public/scroll.js
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
});
|
package/dist/public/toolbar.js
CHANGED
|
@@ -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
|
-
//
|
|
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
|
-
/**
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
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
|
|
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
|
|
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
|
|
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
|
|
31
|
+
* top of the screen's content is primary.
|
|
32
32
|
*/
|
|
33
33
|
primary?: boolean;
|
|
34
|
-
/**
|
|
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
|
-
/**
|
|
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
|
|
55
|
+
* top of the screen's content is primary.
|
|
56
56
|
*/
|
|
57
57
|
primary?: boolean;
|
|
58
|
-
/**
|
|
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
|
-
/**
|
|
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' &&
|
package/dist/scroll/position.js
CHANGED
|
@@ -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,
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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
|
*/
|
package/dist/shapes/corners.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/**
|
|
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;
|