@satinhq/kit 0.1.0-beta.3 → 0.1.0-beta.4
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 +1 -1
- package/README.md +1 -2
- package/dist/acknowledgements/inventory.json +1 -1
- package/dist/actions/RowActions.d.ts +2 -2
- package/dist/actions/RowActions.js +91 -25
- package/dist/actions/fullSwipeContact.d.ts +73 -0
- package/dist/actions/fullSwipeContact.js +186 -0
- package/dist/actions/rowScrub.d.ts +7 -4
- package/dist/actions/rowScrub.js +39 -37
- package/dist/actions/types.d.ts +13 -7
- package/dist/app/InstallComponents.d.ts +4 -7
- package/dist/app/InstallComponents.js +7 -7
- package/dist/app/InstallationDiagnostics.d.ts +2 -1
- package/dist/app/InstallationDiagnostics.js +2 -1
- package/dist/app/appearance.d.ts +5 -3
- package/dist/app/appearance.js +5 -3
- package/dist/app/appearanceStore.d.ts +3 -2
- package/dist/app/buildInfo.d.ts +4 -4
- package/dist/app/buildInfo.js +2 -2
- package/dist/app/definition.d.ts +11 -3
- package/dist/app/definition.js +2 -0
- package/dist/app/head.d.ts +2 -1
- package/dist/app/head.js +13 -16
- package/dist/app/inlineCSP.d.ts +6 -0
- package/dist/app/inlineCSP.js +25 -0
- package/dist/app/install.d.ts +1 -0
- package/dist/app/install.js +5 -2
- package/dist/app/installCheck.js +32 -86
- package/dist/app/installContext.d.ts +10 -5
- package/dist/app/installContext.js +2 -0
- package/dist/app/installCustom.js +1 -0
- package/dist/app/installExperience.js +0 -60
- package/dist/app/installationFailure.d.ts +3 -2
- package/dist/app/installationFailure.js +1 -1
- package/dist/app/launchScreen.d.ts +6 -2
- package/dist/app/launchScreen.js +104 -1
- package/dist/app/launchScreenRuntime.d.ts +31 -4
- package/dist/app/launchScreenRuntime.js +150 -22
- package/dist/app/launchWatchdog.js +25 -65
- package/dist/app/platformScripts.js +11 -0
- package/dist/app/styles.d.ts +3 -0
- package/dist/app/styles.js +42 -0
- package/dist/app/viewportValue.d.ts +2 -1
- package/dist/app/vite.d.ts +4 -0
- package/dist/app/vite.js +22 -24
- package/dist/content/content.d.ts +35 -30
- package/dist/content/content.js +19 -16
- package/dist/content/layout.d.ts +10 -2
- package/dist/content/layout.js +4 -2
- package/dist/content/scaledMetric.d.ts +2 -1
- package/dist/content/scaledMetric.js +2 -1
- package/dist/controls/ColorPicker.d.ts +2 -4
- package/dist/controls/ColorPicker.js +2 -4
- package/dist/controls/DatePicker.d.ts +4 -4
- package/dist/controls/DatePicker.js +2 -2
- package/dist/controls/ProgressView.d.ts +4 -4
- package/dist/controls/ProgressView.js +1 -2
- package/dist/data/database.d.ts +9 -8
- package/dist/data/database.js +4 -4
- package/dist/docs/reference.md +982 -964
- package/dist/docs/tailwind.md +76 -0
- package/dist/docs/tokens.md +1 -1
- package/dist/gestures/GestureView.d.ts +3 -1
- package/dist/gestures/GestureView.js +2 -1
- package/dist/gestures/gesture.d.ts +22 -2
- package/dist/gestures/gesture.js +7 -2
- package/dist/glass/GlassEffect.d.ts +2 -1
- package/dist/glass/GlassEffect.js +2 -1
- package/dist/glass/GlassPresentation.d.ts +1 -0
- package/dist/glass/GlassPresentation.js +21 -4
- package/dist/glass/TabBar.js +23 -1
- package/dist/glass/errorAlert.js +2 -1
- package/dist/glass/errors.d.ts +3 -1
- package/dist/glass/fallback/runtime.d.ts +1 -0
- package/dist/glass/fallback/runtime.js +8 -1
- package/dist/glass/liquidContext.d.ts +2 -0
- package/dist/glass/menuPresenter.d.ts +2 -0
- package/dist/glass/regions.d.ts +2 -1
- package/dist/glass/renderSpecs.d.ts +1 -0
- package/dist/glass/renderSpecs.js +1 -0
- package/dist/glass/webgpu/controlRim.d.ts +29 -0
- package/dist/glass/webgpu/controlRim.js +68 -0
- package/dist/glass/webgpu/passes.d.ts +2 -2
- package/dist/glass/webgpu/production.d.ts +1 -0
- package/dist/glass/webgpu/production.js +27 -1
- package/dist/glass/webgpu/rasterUniforms.js +9 -0
- package/dist/glass/webgpu/shaders.d.ts +2 -2
- package/dist/glass/webgpu/shaders.js +5 -1
- package/dist/haptics/SensoryButton.d.ts +4 -4
- package/dist/haptics/SensoryButton.js +3 -3
- package/dist/image/Image.d.ts +6 -3
- package/dist/image/Image.js +4 -3
- package/dist/image/asset.d.ts +2 -1
- package/dist/keyboard/adapter.d.ts +3 -4
- package/dist/keyboard/geometry.d.ts +1 -1
- package/dist/list-form/ListForm.d.ts +8 -7
- package/dist/list-form/ListForm.js +2 -2
- package/dist/list-form/editing.d.ts +5 -6
- package/dist/list-form/editing.js +4 -5
- package/dist/list-form/offsets.d.ts +2 -2
- package/dist/list-form/offsets.js +2 -2
- package/dist/media/react.d.ts +2 -1
- package/dist/media/react.js +2 -1
- package/dist/media/types.d.ts +6 -3
- package/dist/motion/TransitionView.d.ts +4 -2
- package/dist/motion/TransitionView.js +3 -2
- package/dist/motion/animationValue.d.ts +1 -1
- package/dist/motion/matchedGeometry.d.ts +6 -5
- package/dist/motion/matchedGeometry.js +2 -1
- package/dist/motion/transition.d.ts +4 -1
- package/dist/motion/transition.js +2 -0
- package/dist/navigation/DetailList.d.ts +1 -1
- package/dist/navigation/DetailList.js +1 -1
- package/dist/navigation/Sidebar.d.ts +3 -1
- package/dist/navigation/Sidebar.js +1 -1
- package/dist/navigation/SidebarSymbol.d.ts +2 -1
- package/dist/navigation/SidebarSymbol.js +2 -1
- package/dist/navigation/navigationContext.d.ts +2 -1
- package/dist/navigation/navigationContext.js +2 -1
- package/dist/navigation/splitContext.d.ts +2 -1
- package/dist/navigation/splitContext.js +2 -1
- package/dist/navigation/toolbarMinimization.d.ts +4 -3
- package/dist/navigation/types.d.ts +7 -5
- package/dist/presentation/Presentation.d.ts +8 -7
- package/dist/presentation/Presentation.js +3 -2
- package/dist/presentation/model.d.ts +2 -1
- package/dist/press/Pressable.d.ts +5 -1
- package/dist/press/Pressable.js +2 -0
- package/dist/press/stateMachine.d.ts +1 -1
- package/dist/public/Label.d.ts +2 -1
- package/dist/public/Label.js +2 -1
- package/dist/public/Screen.d.ts +4 -6
- package/dist/public/actions.d.ts +2 -1
- package/dist/public/actions.js +2 -1
- package/dist/public/buttonBorderShape.d.ts +2 -1
- package/dist/public/colors.d.ts +7 -4
- package/dist/public/colors.js +3 -2
- package/dist/public/controlStyle.d.ts +17 -14
- package/dist/public/controls.d.ts +27 -26
- package/dist/public/controls.js +20 -19
- package/dist/public/deviceActions.d.ts +6 -4
- package/dist/public/deviceActions.js +4 -2
- package/dist/public/environment.d.ts +16 -13
- package/dist/public/environment.js +11 -9
- package/dist/public/filePickers.d.ts +6 -4
- package/dist/public/filePickers.js +3 -2
- package/dist/public/glass.d.ts +6 -3
- package/dist/public/glass.js +2 -1
- package/dist/public/glassValue.d.ts +3 -4
- package/dist/public/glassValue.js +3 -4
- package/dist/public/keyboard.d.ts +4 -1
- package/dist/public/keyboard.js +2 -1
- package/dist/public/navigationTransition.d.ts +5 -5
- package/dist/public/navigationTransition.js +2 -2
- package/dist/public/presentation.d.ts +8 -7
- package/dist/public/presentation.js +5 -5
- package/dist/public/runtime.d.ts +9 -8
- package/dist/public/runtime.js +7 -7
- package/dist/public/scroll.d.ts +6 -3
- package/dist/public/scroll.js +3 -1
- package/dist/public/structure.d.ts +2 -2
- package/dist/public/toolbar.d.ts +15 -11
- package/dist/public/toolbar.js +12 -7
- package/dist/reachability/model.d.ts +4 -3
- package/dist/reachability/react.d.ts +4 -1
- package/dist/reachability/react.js +2 -1
- package/dist/root/SatinRoot.d.ts +3 -3
- package/dist/root/SatinRoot.js +12 -36
- package/dist/root/mountSatin.d.ts +1 -1
- package/dist/root/mountSatin.js +26 -35
- package/dist/root/runtimeContext.d.ts +2 -1
- package/dist/root/runtimeContext.js +2 -1
- package/dist/safe-area/Overlay.d.ts +3 -2
- package/dist/safe-area/Overlay.js +2 -1
- package/dist/safe-area/SafeAreaInset.d.ts +11 -7
- package/dist/safe-area/SafeAreaInset.js +7 -6
- package/dist/safe-area/context.d.ts +3 -3
- package/dist/safe-area/context.js +1 -1
- package/dist/safe-area/displayCorners.d.ts +4 -2
- package/dist/safe-area/displayCorners.js +4 -2
- package/dist/safe-area/modifiers.d.ts +14 -10
- package/dist/safe-area/modifiers.js +8 -4
- package/dist/scroll/ScrollSurface.js +5 -1
- package/dist/scroll/ScrollTarget.d.ts +1 -1
- package/dist/scroll/ScrollTarget.js +1 -1
- package/dist/scroll/edgePolicy.d.ts +2 -2
- package/dist/scroll/position.d.ts +5 -3
- package/dist/scroll/types.d.ts +1 -1
- package/dist/search/PadSearchDrawer.d.ts +7 -0
- package/dist/search/PadSearchDrawer.js +8 -0
- package/dist/search/PadSearchPresentationContext.d.ts +6 -0
- package/dist/search/PadSearchPresentationContext.js +4 -0
- package/dist/search/SearchDrawer.d.ts +1 -1
- package/dist/search/SearchDrawer.js +6 -1
- package/dist/search/SearchSuggestionsPopover.d.ts +6 -0
- package/dist/search/SearchSuggestionsPopover.js +42 -0
- package/dist/search/SearchToolbarField.d.ts +2 -1
- package/dist/search/SearchToolbarField.js +28 -7
- package/dist/search/padSearchBarMotion.d.ts +69 -0
- package/dist/search/padSearchBarMotion.js +73 -0
- package/dist/search/padSearchFieldSamples.json +491 -0
- package/dist/search/searchPlacement.d.ts +3 -0
- package/dist/search/searchPlacement.js +7 -0
- package/dist/search/searchable.d.ts +14 -12
- package/dist/search/usePadSearchFieldMotion.d.ts +4 -0
- package/dist/search/usePadSearchFieldMotion.js +100 -0
- package/dist/search/useSearchPresentation.d.ts +2 -1
- package/dist/search/useSearchPresentation.js +23 -5
- package/dist/server.d.ts +4 -4
- package/dist/server.js +4 -4
- package/dist/shapes/corners.d.ts +3 -3
- package/dist/shapes/corners.js +1 -2
- package/dist/styles.css +8289 -8244
- package/dist/sw/vite.d.ts +4 -0
- package/dist/sw/vite.js +2 -0
- package/dist/symbols/Symbol.d.ts +7 -5
- package/dist/symbols/Symbol.js +5 -3
- package/dist/symbols/catalogue.d.ts +1 -1
- package/dist/symbols/types.d.ts +6 -4
- package/dist/tabs/TabSection.d.ts +3 -2
- package/dist/tabs/TabSection.js +2 -1
- package/dist/tabs/TabView.js +54 -51
- package/dist/tasks/useTask.d.ts +5 -4
- package/dist/tasks/useTask.js +4 -3
- package/dist/testing.d.ts +3 -2
- package/dist/testing.js +3 -2
- package/dist/text-input/focusChain.d.ts +4 -3
- package/dist/text-input/focusChain.js +3 -2
- package/dist/text-input/kinds.d.ts +1 -1
- package/dist/web/WebView.d.ts +10 -3
- package/dist/web/WebView.js +3 -2
- package/dist/web/authentication.d.ts +12 -1
- package/dist/web/authentication.js +2 -1
- package/dist/web/openURL.d.ts +10 -4
- package/dist/web/openURL.js +4 -2
- package/dist/web/useWebAuthentication.d.ts +2 -1
- package/dist/web/useWebAuthentication.js +2 -1
- package/dist/zoom/Zoomable.d.ts +3 -3
- package/dist/zoom/Zoomable.js +2 -2
- package/package.json +1 -1
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { usePadSearchFieldMotion } from './usePadSearchFieldMotion.js';
|
|
3
|
+
import { PadSearchPresentationContext, PadSearchTabContext, } from './PadSearchPresentationContext.js';
|
|
2
4
|
import { useContext, useLayoutEffect, useRef, useSyncExternalStore } from 'react';
|
|
5
|
+
import { readDeviceIdiom } from '../layout/deviceIdiom.js';
|
|
3
6
|
import { createPortal } from 'react-dom';
|
|
4
7
|
import { GlassBackground } from '../glass/GlassEffect.js';
|
|
5
8
|
import { MaterialEffectContext } from '../glass/liquidContext.js';
|
|
@@ -9,6 +12,7 @@ import { contactTarget, MENU_CONTACT_CLICK_WINDOW_MS, ownPhysicalContact, } from
|
|
|
9
12
|
import { focusFromFramework } from '../focus/programmaticFocus.js';
|
|
10
13
|
import { SymbolImage } from '../symbols/Symbol.js';
|
|
11
14
|
import { TextField } from '../text-input/TextField.js';
|
|
15
|
+
import { SearchSuggestionsPopover } from './SearchSuggestionsPopover.js';
|
|
12
16
|
import { SearchScopesBar } from './SearchScopesBar.js';
|
|
13
17
|
import { navigationChromeOf, ownBarParts, stackedOver, subscribeNever } from './searchChrome.js';
|
|
14
18
|
import { useSearchPresentation } from './useSearchPresentation.js';
|
|
@@ -24,20 +28,31 @@ import { useSearchPresentation } from './useSearchPresentation.js';
|
|
|
24
28
|
* placed among the bottom items. Suggestions stand in for the scroll view's content, as in the
|
|
25
29
|
* drawer. Presentation is not animated yet: native's motion is not measured (spec notes, reference).
|
|
26
30
|
*/
|
|
27
|
-
export function SearchToolbarField({ configuration, scroller, host, navigation = false, }) {
|
|
31
|
+
export function SearchToolbarField({ configuration, scroller, host, navigation = false, drawer = false, }) {
|
|
32
|
+
const tabSearch = useContext(PadSearchPresentationContext);
|
|
33
|
+
const searchTab = useContext(PadSearchTabContext);
|
|
34
|
+
const setSearchOwner = tabSearch?.setOwner;
|
|
28
35
|
const liquid = useContext(MaterialEffectContext);
|
|
29
36
|
const navigator = useContext(NavigatorContext);
|
|
30
37
|
const screenKey = useContext(ScreenContext)?.key;
|
|
31
38
|
const stacked = useSyncExternalStore(navigator?.subscribe ?? subscribeNever, () => stackedOver(navigator, screenKey, scroller.current));
|
|
32
39
|
const inputRef = useRef(null);
|
|
33
40
|
const rowRef = useRef(null);
|
|
34
|
-
const
|
|
41
|
+
const pad = navigation && readDeviceIdiom() === 'pad';
|
|
42
|
+
const search = useSearchPresentation(configuration, inputRef, pad);
|
|
35
43
|
const { presented } = search;
|
|
44
|
+
usePadSearchFieldMotion(rowRef, pad && !drawer, presented, searchTab !== null, liquid?.regions);
|
|
45
|
+
useLayoutEffect(() => {
|
|
46
|
+
if (!pad || !searchTab || !setSearchOwner || !presented || stacked)
|
|
47
|
+
return;
|
|
48
|
+
setSearchOwner(searchTab);
|
|
49
|
+
return () => setSearchOwner(null);
|
|
50
|
+
}, [pad, searchTab, setSearchOwner, presented, stacked]);
|
|
36
51
|
// The bar's title and items give way while search is presented; its back control too, unless a
|
|
37
52
|
// screen is stacked over this one (as the drawer, SearchDrawer.tsx).
|
|
38
53
|
useLayoutEffect(() => {
|
|
39
54
|
const element = scroller.current;
|
|
40
|
-
if (!element || navigation)
|
|
55
|
+
if (!element || (navigation && !drawer))
|
|
41
56
|
return;
|
|
42
57
|
element.toggleAttribute('data-satin-search-presented', presented);
|
|
43
58
|
const { header } = navigationChromeOf(element);
|
|
@@ -57,7 +72,7 @@ export function SearchToolbarField({ configuration, scroller, host, navigation =
|
|
|
57
72
|
part.removeAttribute('data-satin-search-presented');
|
|
58
73
|
header?.removeAttribute('data-satin-search-presented');
|
|
59
74
|
};
|
|
60
|
-
}, [presented, scroller, screenKey, stacked, navigation]);
|
|
75
|
+
}, [presented, scroller, screenKey, stacked, navigation, drawer]);
|
|
61
76
|
// The field moves with the keyboard on the keyboard's own curve (styles.css). Glass regions
|
|
62
77
|
// follow a moving element only when told: refresh them while it moves.
|
|
63
78
|
useLayoutEffect(() => {
|
|
@@ -93,16 +108,20 @@ export function SearchToolbarField({ configuration, scroller, host, navigation =
|
|
|
93
108
|
}, [liquid?.regions, presented]);
|
|
94
109
|
const prompt = configuration.prompt ?? 'Search';
|
|
95
110
|
const ownsItem = !host.hasAttribute('data-satin-search-toolbar-host');
|
|
96
|
-
const row = (_jsxs("div", { ref: rowRef, role: "search", "data-satin-search-toolbar": "", "data-satin-search-navigation": navigation || undefined, "data-satin-search-toolbar-presented": presented || undefined, children: [_jsxs("div", { "data-satin-search-toolbar-field": "", children: [_jsx(GlassBackground, { shape: "capsule" }), _jsx(SymbolImage, { name: "magnifyingglass", weight: "medium", "data-satin-search-toolbar-magnifier": "" }), _jsx(TextField, { ref: inputRef, label: prompt, labelVisibility: "hidden", variant: "plain", placeholder: prompt, kind: "search", submitLabel: "search", value: configuration.text, onChange: search.change, onFocus: search.present, onSubmit: search.submit, onKeyDown: event => {
|
|
111
|
+
const row = (_jsxs("div", { ref: rowRef, role: "search", "data-satin-search-toolbar": "", "data-satin-search-navigation": navigation || undefined, "data-satin-search-pad": pad || undefined, "data-satin-search-toolbar-presented": presented || undefined, children: [_jsxs("div", { "data-satin-search-toolbar-field": "", children: [_jsx(GlassBackground, { shape: "capsule" }), _jsx(SymbolImage, { name: "magnifyingglass", weight: "medium", "data-satin-search-toolbar-magnifier": "" }), _jsx(TextField, { ref: inputRef, label: prompt, labelVisibility: "hidden", variant: "plain", placeholder: prompt, kind: "search", submitLabel: "search", value: configuration.text, onChange: search.change, onFocus: search.present, onBlur: pad ? search.resign : undefined, onSubmit: search.submit, onKeyDown: event => {
|
|
97
112
|
if (event.key !== 'Escape' || event.nativeEvent.isComposing)
|
|
98
113
|
return;
|
|
99
114
|
event.preventDefault();
|
|
100
115
|
search.dismiss();
|
|
101
116
|
} }), configuration.text && (_jsx(Pressable, { iconOnly: true, "aria-label": "Clear text", "data-satin-search-toolbar-clear": "", onPress: () => {
|
|
117
|
+
if (pad && searchTab) {
|
|
118
|
+
search.dismiss();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
102
121
|
search.change('');
|
|
103
122
|
if (inputRef.current)
|
|
104
123
|
focusFromFramework(inputRef.current);
|
|
105
|
-
}, children: _jsx(SymbolImage, { name: "xmark.circle.fill" }) }))] }), presented && (_jsxs(Pressable, { iconOnly: true, "aria-label": "Close", "data-satin-search-toolbar-close": "", "data-satin-glass-press": "true", onPress: () => {
|
|
124
|
+
}, children: _jsx(SymbolImage, { name: "xmark.circle.fill" }) }))] }), presented && !pad && (_jsxs(Pressable, { iconOnly: true, "aria-label": "Close", "data-satin-search-toolbar-close": "", "data-satin-glass-press": "true", onPress: () => {
|
|
106
125
|
// The touch ends here: WebKit's synthesized mouse events must not refocus the field
|
|
107
126
|
// that moves under the finger (as the drawer's close button).
|
|
108
127
|
ownPhysicalContact(contactTarget(), closeContactOwner, MENU_CONTACT_CLICK_WINDOW_MS, {
|
|
@@ -110,6 +129,8 @@ export function SearchToolbarField({ configuration, scroller, host, navigation =
|
|
|
110
129
|
});
|
|
111
130
|
search.dismiss();
|
|
112
131
|
}, children: [_jsx(GlassBackground, { shape: "circle", interactive: true }), _jsx(SymbolImage, { name: "xmark", weight: "medium" })] }))] }));
|
|
113
|
-
|
|
132
|
+
const suggestions = search.suggestions.map(suggestion => (_jsx(Pressable, { role: "listitem", feedback: "row", "data-satin-search-suggestion": "", onPress: () => search.complete(suggestion), children: suggestion.label ?? suggestion.text }, suggestion.id)));
|
|
133
|
+
return (_jsxs(_Fragment, { children: [createPortal(ownsItem ? (_jsx("div", { "data-satin-toolbar-item": "search", "data-satin-search-pad-item": pad || undefined, "data-satin-search-expanded": (pad && presented) || undefined, children: row })) : (row), host), navigation && (!pad || drawer) && configuration.scopes && presented && (_jsx("div", { "data-satin-search-navigation-scopes": "", "data-satin-search-presented": "", children: _jsx(SearchScopesBar, { scopes: configuration.scopes, presented: presented }) })), search.suggestions.length > 0 &&
|
|
134
|
+
(pad ? (_jsx(SearchSuggestionsPopover, { anchor: rowRef, children: suggestions })) : (_jsx("div", { "data-satin-search-suggestions": "", role: "list", "aria-label": "Suggestions", children: suggestions })))] }));
|
|
114
135
|
}
|
|
115
136
|
const closeContactOwner = {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { SurfaceRenderSpec } from '../glass/renderSpecs.js';
|
|
2
|
+
/** iPad, iPadOS 27.0 (24A437), reference. Activation fit from original video
|
|
3
|
+
* F742–751: omega 17.8734, critical damping, RMS 0.104 pt. Dismissal
|
|
4
|
+
* presentation-layer fit: omega 17.9118, zeta .9982, RMS .038 pt.
|
|
5
|
+
* Translation and effective opacity are one group track; scale remains 1. */
|
|
6
|
+
export declare const PAD_SEARCH_BAR_OMEGA = 17.9;
|
|
7
|
+
export declare const PAD_SEARCH_BAR_TRAVEL = 64;
|
|
8
|
+
export declare class PadSearchBarMotion {
|
|
9
|
+
private run?;
|
|
10
|
+
private animation?;
|
|
11
|
+
get active(): boolean;
|
|
12
|
+
sample(at: number): {
|
|
13
|
+
value: number;
|
|
14
|
+
velocity: number;
|
|
15
|
+
};
|
|
16
|
+
retarget(target: number, at: number): void;
|
|
17
|
+
start(element: HTMLElement, target: number, finalSpec: SurfaceRenderSpec | undefined, at?: number): {
|
|
18
|
+
at: number;
|
|
19
|
+
duration: number;
|
|
20
|
+
specs: {
|
|
21
|
+
touchLight?: import("../internal.js").GlassTouchLight;
|
|
22
|
+
excludeRegionIds?: readonly string[];
|
|
23
|
+
restHidden?: boolean;
|
|
24
|
+
occluder?: import("../internal.js").CapsuleShape;
|
|
25
|
+
prewarmTransparent?: boolean;
|
|
26
|
+
recipeMix?: number;
|
|
27
|
+
sheetOpaqueMix?: number;
|
|
28
|
+
popoverArrow?: import("../glass/regions.js").PopoverArrow;
|
|
29
|
+
variant?: import("../glass/lens/referenceProfiles.js").ReferenceVariant;
|
|
30
|
+
treatment?: 'sheet' | 'expandedSheet' | 'alert' | 'confirmation' | 'contextBackdrop' | 'contextPreview' | 'contextMenu';
|
|
31
|
+
tint?: import("../index.js").GlassTint;
|
|
32
|
+
memberHighlight?: Readonly<{
|
|
33
|
+
member: number;
|
|
34
|
+
amount: number;
|
|
35
|
+
light?: import("../internal.js").GlassTouchLight;
|
|
36
|
+
}>;
|
|
37
|
+
backdropExclusions?: readonly string[];
|
|
38
|
+
backdropMenuOverlay?: boolean;
|
|
39
|
+
blurSigmaCssPx?: number;
|
|
40
|
+
frameHeight: number;
|
|
41
|
+
frameWidth: number;
|
|
42
|
+
frameX: number;
|
|
43
|
+
id: import("../internal.js").SurfaceId;
|
|
44
|
+
materialMix: number;
|
|
45
|
+
materialProfile: 'chrome' | 'searchField' | 'menu';
|
|
46
|
+
menuTintMix?: number;
|
|
47
|
+
returningTrigger?: import("../internal.js").ReturningMenuTrigger;
|
|
48
|
+
radius: number;
|
|
49
|
+
sampleHeight: number;
|
|
50
|
+
sampleInsetX: number;
|
|
51
|
+
sampleInsetY: number;
|
|
52
|
+
sampleWidth: number;
|
|
53
|
+
shaderAperture: boolean;
|
|
54
|
+
shape: import("../internal.js").SurfaceShape;
|
|
55
|
+
tabSelection?: import("../internal.js").TabSelectionShape;
|
|
56
|
+
ink?: Readonly<{
|
|
57
|
+
atlas: Readonly<{
|
|
58
|
+
width: number;
|
|
59
|
+
height: number;
|
|
60
|
+
}>;
|
|
61
|
+
layers: readonly import("../glass/lens/menuField.js").MenuInkLayer[];
|
|
62
|
+
}>;
|
|
63
|
+
frameY: number;
|
|
64
|
+
opacity: number;
|
|
65
|
+
}[];
|
|
66
|
+
finished: Promise<void | Animation>;
|
|
67
|
+
};
|
|
68
|
+
dispose(): void;
|
|
69
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { animateElement, timelineStart } from '../motion/animate.js';
|
|
2
|
+
/** iPad, iPadOS 27.0 (24A437), reference. Activation fit from original video
|
|
3
|
+
* F742–751: omega 17.8734, critical damping, RMS 0.104 pt. Dismissal
|
|
4
|
+
* presentation-layer fit: omega 17.9118, zeta .9982, RMS .038 pt.
|
|
5
|
+
* Translation and effective opacity are one group track; scale remains 1. */
|
|
6
|
+
export const PAD_SEARCH_BAR_OMEGA = 17.9;
|
|
7
|
+
export const PAD_SEARCH_BAR_TRAVEL = 64;
|
|
8
|
+
export class PadSearchBarMotion {
|
|
9
|
+
run;
|
|
10
|
+
animation;
|
|
11
|
+
get active() {
|
|
12
|
+
return this.animation?.playState === 'running';
|
|
13
|
+
}
|
|
14
|
+
sample(at) {
|
|
15
|
+
const run = this.run;
|
|
16
|
+
if (!run)
|
|
17
|
+
return { value: 0, velocity: 0 };
|
|
18
|
+
const t = Math.max(0, at - run.at) / 1000;
|
|
19
|
+
const displacement = run.from - run.target;
|
|
20
|
+
const slope = run.velocity + PAD_SEARCH_BAR_OMEGA * displacement;
|
|
21
|
+
const decay = Math.exp(-PAD_SEARCH_BAR_OMEGA * t);
|
|
22
|
+
return {
|
|
23
|
+
value: run.target + (displacement + slope * t) * decay,
|
|
24
|
+
velocity: (slope - PAD_SEARCH_BAR_OMEGA * (displacement + slope * t)) * decay,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
retarget(target, at) {
|
|
28
|
+
const current = this.sample(at);
|
|
29
|
+
this.run = { at, from: current.value, target, velocity: current.velocity };
|
|
30
|
+
}
|
|
31
|
+
start(element, target, finalSpec, at = performance.now()) {
|
|
32
|
+
this.retarget(target, at);
|
|
33
|
+
this.animation?.cancel();
|
|
34
|
+
this.animation = undefined;
|
|
35
|
+
const reduced = matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
36
|
+
let duration = 0;
|
|
37
|
+
if (!reduced) {
|
|
38
|
+
do {
|
|
39
|
+
duration += 1000 / 60;
|
|
40
|
+
} while (duration < 2000 &&
|
|
41
|
+
(Math.abs(this.sample(at + duration).value - target) > 0.0015 ||
|
|
42
|
+
Math.abs(this.sample(at + duration).velocity) > 0.02));
|
|
43
|
+
}
|
|
44
|
+
const count = Math.max(1, Math.round(duration / (1000 / 60)));
|
|
45
|
+
const values = Array.from({ length: count + 1 }, (_, index) => reduced || index === count ? target : this.sample(at + (duration * index) / count).value);
|
|
46
|
+
const specs = finalSpec
|
|
47
|
+
? values.map(value => ({
|
|
48
|
+
...finalSpec,
|
|
49
|
+
frameY: finalSpec.frameY - PAD_SEARCH_BAR_TRAVEL * (value - target),
|
|
50
|
+
opacity: Math.max(0, Math.min(1, 1 - value)),
|
|
51
|
+
}))
|
|
52
|
+
: [];
|
|
53
|
+
const frames = values.map(value => ({
|
|
54
|
+
transform: `translateY(${-PAD_SEARCH_BAR_TRAVEL * (value - target)}px)`,
|
|
55
|
+
opacity: Math.max(0, Math.min(1, 1 - value)),
|
|
56
|
+
}));
|
|
57
|
+
if (duration) {
|
|
58
|
+
this.animation = animateElement(element, frames, { duration, easing: 'linear' });
|
|
59
|
+
this.animation.startTime = timelineStart(at);
|
|
60
|
+
}
|
|
61
|
+
else
|
|
62
|
+
this.run = { at, from: target, target, velocity: 0 };
|
|
63
|
+
return {
|
|
64
|
+
at,
|
|
65
|
+
duration,
|
|
66
|
+
specs,
|
|
67
|
+
finished: this.animation?.finished.catch(() => { }) ?? Promise.resolve(),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
dispose() {
|
|
71
|
+
this.animation?.cancel();
|
|
72
|
+
}
|
|
73
|
+
}
|