@astryxdesign/core 0.7.6 → 0.7.7-canary.240e8c5
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/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +23 -3
- package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetPanel.js +16 -9
- package/dist/Chat/ChatComposerInput.d.ts +9 -0
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +2 -0
- package/dist/Chat/ChatMessage.js +2 -2
- package/dist/Chat/chatMessage.vars.stylex.d.ts +8 -8
- package/dist/Chat/chatMessage.vars.stylex.js +8 -8
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +8 -1
- package/dist/Drawer/Drawer.d.ts.map +1 -1
- package/dist/Drawer/Drawer.js +6 -0
- package/dist/DropdownMenu/useMenuOverflow.d.ts +13 -3
- package/dist/DropdownMenu/useMenuOverflow.d.ts.map +1 -1
- package/dist/DropdownMenu/useMenuOverflow.js +31 -8
- package/dist/Field/PanelSearchInput.d.ts.map +1 -1
- package/dist/Field/PanelSearchInput.js +8 -1
- package/dist/Field/textEntryTraits.d.ts +6 -6
- package/dist/Field/textEntryTraits.js +6 -6
- package/dist/Link/Link.d.ts.map +1 -1
- package/dist/Link/Link.js +1 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +25 -13
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +404 -131
- package/dist/Slider/sliderTouchController.d.ts +189 -0
- package/dist/Slider/sliderTouchController.d.ts.map +1 -0
- package/dist/Slider/sliderTouchController.js +1017 -0
- package/dist/Slider/useSliderTouch.d.ts +22 -0
- package/dist/Slider/useSliderTouch.d.ts.map +1 -0
- package/dist/Slider/useSliderTouch.js +56 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +19 -9
- package/dist/astryx.css +33 -6
- package/dist/gestures/GestureArena.d.ts.map +1 -1
- package/dist/gestures/GestureArena.js +4 -1
- package/dist/gestures/GestureHost.d.ts +72 -2
- package/dist/gestures/GestureHost.d.ts.map +1 -1
- package/dist/gestures/GestureHost.js +643 -5
- package/dist/gestures/GestureRecognizer.d.ts +15 -1
- package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/GestureRecognizer.js +12 -0
- package/dist/gestures/PanGestureRecognizer.d.ts +8 -0
- package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/PinchGestureRecognizer.d.ts +5 -1
- package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/PinchGestureRecognizer.js +10 -0
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +3 -3
- package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -1
- package/dist/gestures/ScreenEdgePanGestureRecognizer.js +7 -5
- package/dist/gestures/nativeScroll.d.ts +16 -2
- package/dist/gestures/nativeScroll.d.ts.map +1 -1
- package/dist/gestures/nativeScroll.js +39 -8
- package/dist/gestures/recognizerInternals.d.ts +4 -2
- package/dist/gestures/recognizerInternals.d.ts.map +1 -1
- package/dist/gestures/types.d.ts +11 -0
- package/dist/gestures/types.d.ts.map +1 -1
- package/dist/gestures/types.js +7 -0
- package/dist/gestures/wheelSegmenter.d.ts +45 -0
- package/dist/gestures/wheelSegmenter.d.ts.map +1 -0
- package/dist/gestures/wheelSegmenter.js +98 -0
- package/dist/motion/animator.d.ts.map +1 -1
- package/dist/motion/animator.js +140 -19
- package/dist/motion/uikit/index.d.ts +2 -1
- package/dist/motion/uikit/index.d.ts.map +1 -1
- package/dist/motion/uikit/index.js +2 -1
- package/dist/motion/uikit/slider.d.ts +97 -0
- package/dist/motion/uikit/slider.d.ts.map +1 -0
- package/dist/motion/uikit/slider.js +111 -0
- package/dist/motion/uikit/springs.d.ts +46 -1
- package/dist/motion/uikit/springs.d.ts.map +1 -1
- package/dist/motion/uikit/springs.js +48 -4
- package/package.json +5 -5
- package/src/AppShell/AppShell.doc.mjs +10 -0
- package/src/AppShell/AppShell.tsx +48 -2
- package/src/BottomSheet/BottomSheetPanel.tsx +16 -9
- package/src/Chat/Chat.doc.mjs +1 -0
- package/src/Chat/ChatComposerInput.doc.mjs +11 -0
- package/src/Chat/ChatComposerInput.tsx +11 -0
- package/src/Chat/ChatMessage.tsx +2 -2
- package/src/Chat/chatMessage.vars.stylex.ts +8 -8
- package/src/CommandPalette/CommandPaletteInput.tsx +6 -0
- package/src/Drawer/Drawer.tsx +6 -0
- package/src/DropdownMenu/useMenuOverflow.ts +44 -8
- package/src/Field/PanelSearchInput.tsx +6 -0
- package/src/Field/textEntryTraits.ts +6 -6
- package/src/Link/Link.tsx +3 -0
- package/src/Selector/Selector.tsx +29 -2
- package/src/Slider/Slider.doc.mjs +11 -7
- package/src/Slider/Slider.tsx +539 -132
- package/src/Slider/sliderTouchController.ts +1209 -0
- package/src/Slider/useSliderTouch.ts +78 -0
- package/src/Typeahead/BaseTypeahead.tsx +16 -8
- package/src/gestures/GestureArena.ts +1 -0
- package/src/gestures/GestureHost.ts +765 -5
- package/src/gestures/GestureRecognizer.ts +28 -0
- package/src/gestures/PanGestureRecognizer.ts +8 -0
- package/src/gestures/PinchGestureRecognizer.ts +16 -1
- package/src/gestures/README.md +63 -0
- package/src/gestures/ScreenEdgePanGestureRecognizer.ts +7 -5
- package/src/gestures/nativeScroll.ts +49 -9
- package/src/gestures/recognizerInternals.ts +9 -2
- package/src/gestures/types.ts +12 -0
- package/src/gestures/wheelSegmenter.ts +114 -0
- package/src/motion/animator.ts +193 -25
- package/src/motion/uikit/index.ts +2 -1
- package/src/motion/uikit/slider.ts +105 -0
- package/src/motion/uikit/springs.ts +37 -2
package/dist/motion/animator.js
CHANGED
|
@@ -643,7 +643,7 @@ export function createAnimator(element, options = {}) {
|
|
|
643
643
|
if (segment == null) {
|
|
644
644
|
return null;
|
|
645
645
|
}
|
|
646
|
-
if (time >=
|
|
646
|
+
if (time >= endOf(property, segment)) {
|
|
647
647
|
return null;
|
|
648
648
|
}
|
|
649
649
|
return segment;
|
|
@@ -668,26 +668,84 @@ export function createAnimator(element, options = {}) {
|
|
|
668
668
|
};
|
|
669
669
|
|
|
670
670
|
/**
|
|
671
|
-
*
|
|
672
|
-
*
|
|
673
|
-
|
|
674
|
-
|
|
671
|
+
* A held curve's start once a frame dated its call, as the browser's start
|
|
672
|
+
* moves it: by that frame's lead over the call's own time.
|
|
673
|
+
*/
|
|
674
|
+
const datedFromLatest = (segment, latest) => latest == null || segment.group == null ? null : {
|
|
675
|
+
latest,
|
|
676
|
+
start: segment.start + latest - segment.group.provisional
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* When a waiting curve's call had its first frame, which put the curve on
|
|
681
|
+
* screen. Undefined for a curve that does not wait, or whose call has had
|
|
682
|
+
* no first frame.
|
|
683
|
+
*/
|
|
684
|
+
const shownSince = (property, segment) => segment.group?.resolved === false ? segment.group.latest?.get(CHANNEL_OF[property]) : undefined;
|
|
685
|
+
|
|
686
|
+
/** A curve's end, dated from its call's first frame while it waits. */
|
|
687
|
+
const endOf = (property, segment) => (datedFromLatest(segment, shownSince(property, segment))?.start ?? segment.start) + segment.duration;
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Takes a curve on screen out of the call that still waits for the
|
|
691
|
+
* browser's start. The curve keeps its course, dated from the call's first
|
|
692
|
+
* frame. A call that has no channel left starts at that frame.
|
|
693
|
+
*/
|
|
694
|
+
const leaveWaitingCall = (segment, channel, latest) => {
|
|
695
|
+
const group = segment.group;
|
|
696
|
+
if (group == null) {
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
const index = group.segments.indexOf(segment);
|
|
700
|
+
if (index >= 0) {
|
|
701
|
+
group.segments.splice(index, 1);
|
|
702
|
+
}
|
|
703
|
+
segment.start += latest - group.provisional;
|
|
704
|
+
segment.group = undefined;
|
|
705
|
+
if (!CHANNELS[channel].some(p => segments.get(p)?.group === group)) {
|
|
706
|
+
group.latest?.delete(channel);
|
|
707
|
+
group.channels.delete(channel);
|
|
708
|
+
}
|
|
709
|
+
if (group.channels.size === 0 && group.segments.length === 0) {
|
|
710
|
+
resolveGroup(group, latest);
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
/**
|
|
715
|
+
* The value on screen at `time`. Until the browser reports its start, a
|
|
716
|
+
* held curve shows its first value. A frame that ran without that start
|
|
717
|
+
* dates the curve. Without that frame, a later time reads from the
|
|
718
|
+
* provisional start, so a companion that samples ahead follows the curve's
|
|
719
|
+
* shape.
|
|
675
720
|
*/
|
|
676
721
|
const valueAt = (property, time) => {
|
|
677
722
|
const segment = segments.get(property);
|
|
678
|
-
if (segment != null && isHeld(segment)
|
|
723
|
+
if (segment != null && isHeld(segment)) {
|
|
724
|
+
// The compositor starts the call near its first frame. The curve is
|
|
725
|
+
// dated as the browser's start would date it. A curve that joined by an
|
|
726
|
+
// older clock keeps its lead over the call's own time.
|
|
727
|
+
const latest = segment.group?.latest?.get(CHANNEL_OF[property]);
|
|
728
|
+
const dated = datedFromLatest(segment, latest);
|
|
729
|
+
if (dated != null) {
|
|
730
|
+
const elapsed = Math.max(time, dated.latest) - dated.start;
|
|
731
|
+
return elapsed >= segment.duration ? segment.target : segment.at(elapsed);
|
|
732
|
+
}
|
|
679
733
|
// Nothing has moved on screen until the browser starts the call.
|
|
680
|
-
|
|
734
|
+
if (time <= now()) {
|
|
735
|
+
return segment.at(0);
|
|
736
|
+
}
|
|
681
737
|
}
|
|
682
738
|
return curveAt(property, time);
|
|
683
739
|
};
|
|
684
740
|
const velocityAt = (property, time) => {
|
|
685
741
|
const held = segments.get(property);
|
|
686
742
|
if (held != null && isHeld(held)) {
|
|
687
|
-
// Still at its start on screen, but moving in the model
|
|
688
|
-
// carries the velocity the curve has reached by now
|
|
689
|
-
// moves all land before the browser starts any keeps its speed.
|
|
690
|
-
|
|
743
|
+
// Still at its start on screen, but moving in the model. A retarget
|
|
744
|
+
// carries the velocity the curve has reached by now. So a flick whose
|
|
745
|
+
// moves all land before the browser starts any keeps its speed. Past
|
|
746
|
+
// its first frame, it reads from that frame, as its value does.
|
|
747
|
+
const dated = datedFromLatest(held, held.group?.latest?.get(CHANNEL_OF[property]));
|
|
748
|
+
return held.speed(Math.max(0, dated != null && time > dated.latest ? time - dated.start : time - held.start));
|
|
691
749
|
}
|
|
692
750
|
const segment = segmentAt(property, time);
|
|
693
751
|
if (segment == null || time < segment.start) {
|
|
@@ -854,12 +912,49 @@ export function createAnimator(element, options = {}) {
|
|
|
854
912
|
// Settled curves become resting values.
|
|
855
913
|
for (const property of properties) {
|
|
856
914
|
const segment = segments.get(property);
|
|
857
|
-
if (segment != null && time >=
|
|
915
|
+
if (segment != null && time >= endOf(property, segment)) {
|
|
858
916
|
resting[property] = segment.target;
|
|
859
917
|
segments.delete(property);
|
|
860
918
|
}
|
|
861
919
|
}
|
|
862
920
|
const moving = properties.filter(p => segments.has(p));
|
|
921
|
+
if (callGroup == null) {
|
|
922
|
+
// A call that starts now rebuilds a channel the compositor has moving
|
|
923
|
+
// since a first frame without a known start. The channel carries on
|
|
924
|
+
// from that frame, with a start of its own, instead of starting its
|
|
925
|
+
// curve again.
|
|
926
|
+
for (const property of moving) {
|
|
927
|
+
const segment = segments.get(property);
|
|
928
|
+
const latest = shownSince(property, segment);
|
|
929
|
+
if (latest != null) {
|
|
930
|
+
leaveWaitingCall(segment, channel, latest);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
// An explicit call can rebuild a channel while one of its curves still
|
|
935
|
+
// waits for the browser's start. The animation then joins the current
|
|
936
|
+
// call, or else that waiting call, with no start of its own.
|
|
937
|
+
const waiting = callGroup ?? moving.map(p => segments.get(p).group).find(group => group != null && !group.resolved) ?? null;
|
|
938
|
+
const rebuiltAfterFirstFrame = waiting?.framed === true;
|
|
939
|
+
// The new animation starts at the frame that commits it, from its first
|
|
940
|
+
// keyframe. That holds for a waiting call it joins after that call's
|
|
941
|
+
// first frame, and for every waiting call it takes a curve from. So this
|
|
942
|
+
// channel's reads below, and until that frame, take that first value.
|
|
943
|
+
const restarted = new Set();
|
|
944
|
+
if (rebuiltAfterFirstFrame) {
|
|
945
|
+
restarted.add(waiting);
|
|
946
|
+
}
|
|
947
|
+
if (callGroup != null) {
|
|
948
|
+
for (const property of moving) {
|
|
949
|
+
const group = segments.get(property).group;
|
|
950
|
+
if (group != null && group !== callGroup && !group.resolved) {
|
|
951
|
+
restarted.add(group);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
for (const group of restarted) {
|
|
956
|
+
group.latest?.delete(channel);
|
|
957
|
+
}
|
|
863
958
|
if (channel === 'translate') {
|
|
864
959
|
// The animation built below starts from the value at `time` (its first
|
|
865
960
|
// keyframe); a rebase or a retarget builds a new one, so a new start.
|
|
@@ -887,10 +982,6 @@ export function createAnimator(element, options = {}) {
|
|
|
887
982
|
previous?.cancel();
|
|
888
983
|
return;
|
|
889
984
|
}
|
|
890
|
-
// A channel rebuilt by an explicit call (set, rebase, a retarget of
|
|
891
|
-
// another axis) while one of its curves still waits for the browser's
|
|
892
|
-
// start keeps that start: no explicit start for this animation.
|
|
893
|
-
const waiting = callGroup ?? moving.map(p => segments.get(p).group).find(group => group != null && !group.resolved) ?? null;
|
|
894
985
|
// The keyframes start where the animation will: at the waiting call's
|
|
895
986
|
// own time, which its start moves to the browser's (resolveGroup), so a
|
|
896
987
|
// write later in the task keeps the screen on the model's clock.
|
|
@@ -996,6 +1087,15 @@ export function createAnimator(element, options = {}) {
|
|
|
996
1087
|
waiting.channels.add(channel);
|
|
997
1088
|
// A cancel before the first frame rejects its ready promise.
|
|
998
1089
|
animation.ready?.catch(() => {});
|
|
1090
|
+
if (rebuiltAfterFirstFrame) {
|
|
1091
|
+
// The frame that commits it dates this channel's start again. The
|
|
1092
|
+
// call's other channels keep their own.
|
|
1093
|
+
requestFrame?.(() => {
|
|
1094
|
+
if (!waiting.resolved && running.get(channel) === animation && animation.startTime == null && animation.playState === 'running') {
|
|
1095
|
+
(waiting.latest ??= new Map()).set(channel, now());
|
|
1096
|
+
}
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
999
1099
|
} else {
|
|
1000
1100
|
// One clock: the keyframes were sampled from `time`.
|
|
1001
1101
|
animation.startTime = time;
|
|
@@ -1445,7 +1545,9 @@ export function createAnimator(element, options = {}) {
|
|
|
1445
1545
|
for (const channel of start === 'commit' ? [] : channels) {
|
|
1446
1546
|
for (const property of CHANNELS[channel]) {
|
|
1447
1547
|
const segment = segments.get(property);
|
|
1448
|
-
|
|
1548
|
+
// A call's first frame puts its channels on screen, even before the
|
|
1549
|
+
// browser reports the start. So such a channel is not at rest either.
|
|
1550
|
+
if (segment != null && time < endOf(property, segment) && (segment.group == null || segment.group.resolved || shownSince(property, segment) != null)) {
|
|
1449
1551
|
return null;
|
|
1450
1552
|
}
|
|
1451
1553
|
}
|
|
@@ -1614,6 +1716,17 @@ export function createAnimator(element, options = {}) {
|
|
|
1614
1716
|
if (!group.resolved && group.madeInFrame !== true && now() - (group.task?.first ?? group.provisional) <= LATE_START_MS && group.animations.some(animation => animation.startTime == null && animation.playState === 'running')) {
|
|
1615
1717
|
resolveGroup(group, now());
|
|
1616
1718
|
}
|
|
1719
|
+
// The browser's start is still unread. The compositor starts the call
|
|
1720
|
+
// near this frame, so each moving channel's reads take the curve from
|
|
1721
|
+
// now until the browser tells its start.
|
|
1722
|
+
if (!group.resolved) {
|
|
1723
|
+
for (const channel of group.channels) {
|
|
1724
|
+
const animation = running.get(channel);
|
|
1725
|
+
if (animation != null && group.animations.includes(animation) && animation.startTime == null && animation.playState === 'running') {
|
|
1726
|
+
(group.latest ??= new Map()).set(channel, now());
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1617
1730
|
});
|
|
1618
1731
|
ready.then(() => syncGroup(group), () => settleCancelled(group));
|
|
1619
1732
|
};
|
|
@@ -2822,8 +2935,10 @@ export function createAnimator(element, options = {}) {
|
|
|
2822
2935
|
}
|
|
2823
2936
|
owners.add(segment.owner);
|
|
2824
2937
|
// A curve still waiting for the browser's start stays in its call:
|
|
2825
|
-
// it starts with that call's commit.
|
|
2826
|
-
|
|
2938
|
+
// it starts with that call's commit. A curve whose call had its first
|
|
2939
|
+
// frame is on screen already, so it leaves the call (leaveWaitingCall).
|
|
2940
|
+
const latest = shownSince(property, segment);
|
|
2941
|
+
const group = latest == null && segment.group != null && !segment.group.resolved ? segment.group : undefined;
|
|
2827
2942
|
const replace = next => {
|
|
2828
2943
|
if (group != null) {
|
|
2829
2944
|
const index = group.segments.indexOf(segment);
|
|
@@ -2838,6 +2953,9 @@ export function createAnimator(element, options = {}) {
|
|
|
2838
2953
|
if (segment.spring != null) {
|
|
2839
2954
|
const from = valueAt(property, time) + delta;
|
|
2840
2955
|
const velocity = velocityAt(property, time);
|
|
2956
|
+
if (latest != null) {
|
|
2957
|
+
leaveWaitingCall(segment, CHANNEL_OF[property], latest);
|
|
2958
|
+
}
|
|
2841
2959
|
const curve = solveSpring(toSpring(segment.spring), {
|
|
2842
2960
|
from,
|
|
2843
2961
|
to: segment.target,
|
|
@@ -2857,6 +2975,9 @@ export function createAnimator(element, options = {}) {
|
|
|
2857
2975
|
spring: segment.spring
|
|
2858
2976
|
});
|
|
2859
2977
|
} else {
|
|
2978
|
+
if (latest != null) {
|
|
2979
|
+
leaveWaitingCall(segment, CHANNEL_OF[property], latest);
|
|
2980
|
+
}
|
|
2860
2981
|
replace({
|
|
2861
2982
|
...segment,
|
|
2862
2983
|
target: segment.target + delta,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @file index.ts
|
|
3
3
|
* @input The domain files of the UIKit constants table
|
|
4
4
|
* @output Re-exports `springs` and one constant per spring (`SHEET_PRESENT_SPRING`,
|
|
5
|
-
* …), `scroll`, `timing`, `navigation` and the
|
|
5
|
+
* …), `scroll`, `timing`, `navigation`, the `slider` domain and the
|
|
6
6
|
* gesture thresholds (one `UIKIT_*` group per recognizer, their union
|
|
7
7
|
* `UIKIT_GESTURES`, and the haptic tables)
|
|
8
8
|
* @position Entry of the UIKit constants table (motion/uikit). Internal to
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
export { HAPTIC_FEEDBACK_KINDS, HAPTIC_VIBRATION_PATTERNS, UIKIT_CLICK, UIKIT_CONTROL, UIKIT_GESTURES, UIKIT_LONG_PRESS, UIKIT_PAN, UIKIT_PINCH, UIKIT_PRESS, UIKIT_ROTATION, UIKIT_SCREEN_EDGE_PAN, UIKIT_SWIPE, UIKIT_TAP, UIKIT_VELOCITY, type GestureConstant, type GestureConstantUnit, type HapticFeedbackKind, } from './gestures.js';
|
|
20
20
|
export { navigation, registerNavigationTable } from './navigation.js';
|
|
21
21
|
export { registerScrollTable, scroll } from './scroll.js';
|
|
22
|
+
export { slider } from './slider.js';
|
|
22
23
|
export { ACTION_SHEET_DISMISS_SPRING, ACTION_SHEET_PRESENT_SPRING, ALERT_DISMISS_SPRING, ALERT_PRESENT_SPRING, BANNER_SPRING, CONTEXT_MENU_DISMISS_SPRING, CONTEXT_MENU_LIFT_SPRING, CONTEXT_MENU_MORPH_SPRING, DIRECT_CHANGE_SPRING, EMPHASIS_SPRING, FINGER_TRACKING_SPRING, KEYBOARD_SPRING, MENU_CLOSE_SPRING, MENU_OPEN_SPRING, MENU_REDUCED_MOTION_SPRING, NAVIGATION_BAR_ELEMENTS_SPRING, NAVIGATION_INTERACTIVE_POP_FINISH_SPRING, NAVIGATION_POP_SPRING, NAVIGATION_PUSH_SPRING, QUICK_CHANGE_SPRING, SEGMENTED_THUMB_SPRING, SETTLE_SPRING, SHEET_DETENT_SPRING, SHEET_DISMISS_SPRING, SHEET_DISMISS_SWIPE_SPRING, SHEET_PRESENT_SPRING, SHEET_RELEASE_FAST_SPRING, STATE_CHANGE_SPRING, SUB_MENU_BACK_SPRING, SUB_MENU_OPEN_SPRING, SWITCH_THUMB_MOVE_SPRING, SWITCH_THUMB_STRETCH_SPRING, TIMED_CHANGE_SPRING, VIEW_CHANGE_SPRING, registerSpringsTable, springs, } from './springs.js';
|
|
23
24
|
export { registerTimingTable, timing } from './timing.js';
|
|
24
25
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/motion/uikit/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,WAAW,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,WAAW,EACX,SAAS,EACT,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAC,UAAU,EAAE,uBAAuB,EAAC,MAAM,cAAc,CAAC;AACjE,OAAO,EAAC,mBAAmB,EAAE,MAAM,EAAC,MAAM,UAAU,CAAC;AACrD,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,0BAA0B,EAC1B,8BAA8B,EAC9B,wCAAwC,EACxC,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,mBAAmB,EAAE,MAAM,EAAC,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/motion/uikit/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,WAAW,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,WAAW,EACX,SAAS,EACT,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAC,UAAU,EAAE,uBAAuB,EAAC,MAAM,cAAc,CAAC;AACjE,OAAO,EAAC,mBAAmB,EAAE,MAAM,EAAC,MAAM,UAAU,CAAC;AACrD,OAAO,EAAC,MAAM,EAAC,MAAM,UAAU,CAAC;AAChC,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,0BAA0B,EAC1B,8BAA8B,EAC9B,wCAAwC,EACxC,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,2BAA2B,EAC3B,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,OAAO,GACR,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,mBAAmB,EAAE,MAAM,EAAC,MAAM,UAAU,CAAC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @file index.ts
|
|
5
5
|
* @input The domain files of the UIKit constants table
|
|
6
6
|
* @output Re-exports `springs` and one constant per spring (`SHEET_PRESENT_SPRING`,
|
|
7
|
-
* …), `scroll`, `timing`, `navigation` and the
|
|
7
|
+
* …), `scroll`, `timing`, `navigation`, the `slider` domain and the
|
|
8
8
|
* gesture thresholds (one `UIKIT_*` group per recognizer, their union
|
|
9
9
|
* `UIKIT_GESTURES`, and the haptic tables)
|
|
10
10
|
* @position Entry of the UIKit constants table (motion/uikit). Internal to
|
|
@@ -22,5 +22,6 @@
|
|
|
22
22
|
export { HAPTIC_FEEDBACK_KINDS, HAPTIC_VIBRATION_PATTERNS, UIKIT_CLICK, UIKIT_CONTROL, UIKIT_GESTURES, UIKIT_LONG_PRESS, UIKIT_PAN, UIKIT_PINCH, UIKIT_PRESS, UIKIT_ROTATION, UIKIT_SCREEN_EDGE_PAN, UIKIT_SWIPE, UIKIT_TAP, UIKIT_VELOCITY } from "./gestures.js";
|
|
23
23
|
export { navigation, registerNavigationTable } from "./navigation.js";
|
|
24
24
|
export { registerScrollTable, scroll } from "./scroll.js";
|
|
25
|
+
export { slider } from "./slider.js";
|
|
25
26
|
export { ACTION_SHEET_DISMISS_SPRING, ACTION_SHEET_PRESENT_SPRING, ALERT_DISMISS_SPRING, ALERT_PRESENT_SPRING, BANNER_SPRING, CONTEXT_MENU_DISMISS_SPRING, CONTEXT_MENU_LIFT_SPRING, CONTEXT_MENU_MORPH_SPRING, DIRECT_CHANGE_SPRING, EMPHASIS_SPRING, FINGER_TRACKING_SPRING, KEYBOARD_SPRING, MENU_CLOSE_SPRING, MENU_OPEN_SPRING, MENU_REDUCED_MOTION_SPRING, NAVIGATION_BAR_ELEMENTS_SPRING, NAVIGATION_INTERACTIVE_POP_FINISH_SPRING, NAVIGATION_POP_SPRING, NAVIGATION_PUSH_SPRING, QUICK_CHANGE_SPRING, SEGMENTED_THUMB_SPRING, SETTLE_SPRING, SHEET_DETENT_SPRING, SHEET_DISMISS_SPRING, SHEET_DISMISS_SWIPE_SPRING, SHEET_PRESENT_SPRING, SHEET_RELEASE_FAST_SPRING, STATE_CHANGE_SPRING, SUB_MENU_BACK_SPRING, SUB_MENU_OPEN_SPRING, SWITCH_THUMB_MOVE_SPRING, SWITCH_THUMB_STRETCH_SPRING, TIMED_CHANGE_SPRING, VIEW_CHANGE_SPRING, registerSpringsTable, springs } from "./springs.js";
|
|
26
27
|
export { registerTimingTable, timing } from "./timing.js";
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UISlider's touch values: hit target, tracking, release coast, lift, drop
|
|
3
|
+
* and the end-of-track haptic.
|
|
4
|
+
*/
|
|
5
|
+
export declare const slider: {
|
|
6
|
+
/**
|
|
7
|
+
* The thumb's touch target, a square in pt centered on the thumb. It is
|
|
8
|
+
* the 37 × 24 pt thumb grown by its hit edge insets: 12 pt above and
|
|
9
|
+
* below, 5.5 pt left and right. UIKit hit-tests inside the control's frame
|
|
10
|
+
* first, so the lab's 40 pt frame clipped it to 48 × 40.
|
|
11
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro.
|
|
12
|
+
* `_thumbHitEdgeInsets` reads {−12, −5.5, −12, −5.5}. Touch-downs on a
|
|
13
|
+
* 4 pt grid take the thumb from −24 to +20 pt in x. A track tap away
|
|
14
|
+
* from the thumb moves nothing. Oct 23 2026
|
|
15
|
+
*/
|
|
16
|
+
readonly thumbHitTarget: 48;
|
|
17
|
+
/**
|
|
18
|
+
* Value range per track length of finger travel. The value moves by
|
|
19
|
+
* (max − min) × translation ÷ the track's full length. The translation
|
|
20
|
+
* counts from the pan's threshold: the touch-down point plus 10 pt along
|
|
21
|
+
* the track. 1 means one full range per track length.
|
|
22
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. In
|
|
23
|
+
* drags at 120 to 2000 pt/s, each event's value is v0 plus the
|
|
24
|
+
* translation past 10 pt ÷ 300. Past the max end, the value leaves 1
|
|
25
|
+
* only once the finger comes back past where it reached 1. Oct 23 2026
|
|
26
|
+
*/
|
|
27
|
+
readonly trackingGain: 1;
|
|
28
|
+
/**
|
|
29
|
+
* The coast after the lift. The thumb and the value spring from where the
|
|
30
|
+
* finger left them to the projected target, with the release velocity.
|
|
31
|
+
* Critically damped, it never overshoots a target ahead of it.
|
|
32
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
33
|
+
* `UIViewSpringAnimationBehavior` at the lift reads response 0.4 and
|
|
34
|
+
* damping ratio 1. Four releases fit it per frame, at rms 0.11 pt or
|
|
35
|
+
* less. Oct 23 2026
|
|
36
|
+
*/
|
|
37
|
+
readonly releaseSpring: {
|
|
38
|
+
readonly response: 0.4;
|
|
39
|
+
readonly dampingRatio: 1;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The deceleration rate of the coast's momentum projection, per ms
|
|
43
|
+
* (WWDC18's `project`). It is not UIScrollView's normal rate (0.998), so
|
|
44
|
+
* pass it to the projection explicitly.
|
|
45
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
46
|
+
* release behavior's projection deceleration reads 0.996. Oct 23 2026
|
|
47
|
+
*/
|
|
48
|
+
readonly releaseProjectionRate: 0.996;
|
|
49
|
+
/**
|
|
50
|
+
* How much of the projection the coast travels. The target is the lift
|
|
51
|
+
* value plus this share of the projected distance. A finger lifted outside
|
|
52
|
+
* the control's tracking bounds coasts back to the lift value instead.
|
|
53
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
54
|
+
* release behavior's target smoothing reads 0.4. A 126.9 pt/s release
|
|
55
|
+
* travels 12.56 pt, against 12.64 predicted. Oct 23 2026
|
|
56
|
+
*/
|
|
57
|
+
readonly releaseProjectionShare: 0.4;
|
|
58
|
+
/**
|
|
59
|
+
* The thumb's growth under a finger, uniform about its center (37 × 24 to
|
|
60
|
+
* 57.35 × 37.2 pt).
|
|
61
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The lens
|
|
62
|
+
* frame settled during an 800 ms hold. Oct 23 2026
|
|
63
|
+
*/
|
|
64
|
+
readonly liftScale: 1.55;
|
|
65
|
+
/**
|
|
66
|
+
* The lift: the thumb grows to `liftScale` when the finger lands.
|
|
67
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The lens
|
|
68
|
+
* width per frame in an 800 ms hold fits one spring at rms 0.31 pt.
|
|
69
|
+
* Oct 23 2026
|
|
70
|
+
*/
|
|
71
|
+
readonly liftSpring: {
|
|
72
|
+
readonly response: 0.215;
|
|
73
|
+
readonly dampingRatio: 0.6;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* The drop: the thumb shrinks back to its rest size when the finger lifts,
|
|
77
|
+
* while the coast runs.
|
|
78
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
79
|
+
* lens's spring at the lift of an 800 ms hold reads response 0.5 s and
|
|
80
|
+
* damping ratio 0.7. The width per frame fits it at rms 0.10 pt.
|
|
81
|
+
* Oct 23 2026
|
|
82
|
+
*/
|
|
83
|
+
readonly dropSpring: {
|
|
84
|
+
readonly response: 0.5;
|
|
85
|
+
readonly dampingRatio: 0.7;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* The feedback each time the value reaches an end, once per entry. It
|
|
89
|
+
* re-arms when the value leaves the end, in the drag and the coast. UIKit
|
|
90
|
+
* plays "Micro Tap Medium", and the web stand-in is the closest kind.
|
|
91
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
92
|
+
* haptics log of drags into both ends shows the fluid slider generator's
|
|
93
|
+
* "Micro Tap Medium" once per entry. Oct 23 2026
|
|
94
|
+
*/
|
|
95
|
+
readonly endHaptic: "impactMedium";
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=slider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slider.d.ts","sourceRoot":"","sources":["../../../src/motion/uikit/slider.ts"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,eAAO,MAAM,MAAM;IACjB;;;;;;;;;OASG;;IAEH;;;;;;;;;OASG;;IAEH;;;;;;;;OAQG;;;;;IAEH;;;;;;OAMG;;IAEH;;;;;;;OAOG;;IAEH;;;;;OAKG;;IAEH;;;;;OAKG;;;;;IAEH;;;;;;;OAOG;;;;;IAEH;;;;;;;OAOG;;CAEK,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file slider.ts
|
|
5
|
+
* @input Nothing: data only
|
|
6
|
+
* @output Exports `slider`: UISlider's hit target, tracking rule, release
|
|
7
|
+
* coast, lift, drop and end haptic, measured on the iOS 26.2 simulator
|
|
8
|
+
* @position The slider domain of the UIKit constants table (motion/uikit).
|
|
9
|
+
* Lengths are in pt (CSS px). Tests check each leaf's `@source`.
|
|
10
|
+
*
|
|
11
|
+
* SYNC: When modified, update:
|
|
12
|
+
* - /packages/core/src/Slider/sliderTouchController.ts
|
|
13
|
+
* - /packages/core/src/Slider/Slider.tsx
|
|
14
|
+
* - /packages/core/src/motion/uikit/slider.test.ts
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { SLIDER_RELEASE_SPRING } from "./springs.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* UISlider's touch values: hit target, tracking, release coast, lift, drop
|
|
21
|
+
* and the end-of-track haptic.
|
|
22
|
+
*/
|
|
23
|
+
export const slider = {
|
|
24
|
+
/**
|
|
25
|
+
* The thumb's touch target, a square in pt centered on the thumb. It is
|
|
26
|
+
* the 37 × 24 pt thumb grown by its hit edge insets: 12 pt above and
|
|
27
|
+
* below, 5.5 pt left and right. UIKit hit-tests inside the control's frame
|
|
28
|
+
* first, so the lab's 40 pt frame clipped it to 48 × 40.
|
|
29
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro.
|
|
30
|
+
* `_thumbHitEdgeInsets` reads {−12, −5.5, −12, −5.5}. Touch-downs on a
|
|
31
|
+
* 4 pt grid take the thumb from −24 to +20 pt in x. A track tap away
|
|
32
|
+
* from the thumb moves nothing. Oct 23 2026
|
|
33
|
+
*/
|
|
34
|
+
thumbHitTarget: 48,
|
|
35
|
+
/**
|
|
36
|
+
* Value range per track length of finger travel. The value moves by
|
|
37
|
+
* (max − min) × translation ÷ the track's full length. The translation
|
|
38
|
+
* counts from the pan's threshold: the touch-down point plus 10 pt along
|
|
39
|
+
* the track. 1 means one full range per track length.
|
|
40
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. In
|
|
41
|
+
* drags at 120 to 2000 pt/s, each event's value is v0 plus the
|
|
42
|
+
* translation past 10 pt ÷ 300. Past the max end, the value leaves 1
|
|
43
|
+
* only once the finger comes back past where it reached 1. Oct 23 2026
|
|
44
|
+
*/
|
|
45
|
+
trackingGain: 1,
|
|
46
|
+
/**
|
|
47
|
+
* The coast after the lift. The thumb and the value spring from where the
|
|
48
|
+
* finger left them to the projected target, with the release velocity.
|
|
49
|
+
* Critically damped, it never overshoots a target ahead of it.
|
|
50
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
51
|
+
* `UIViewSpringAnimationBehavior` at the lift reads response 0.4 and
|
|
52
|
+
* damping ratio 1. Four releases fit it per frame, at rms 0.11 pt or
|
|
53
|
+
* less. Oct 23 2026
|
|
54
|
+
*/
|
|
55
|
+
releaseSpring: SLIDER_RELEASE_SPRING,
|
|
56
|
+
/**
|
|
57
|
+
* The deceleration rate of the coast's momentum projection, per ms
|
|
58
|
+
* (WWDC18's `project`). It is not UIScrollView's normal rate (0.998), so
|
|
59
|
+
* pass it to the projection explicitly.
|
|
60
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
61
|
+
* release behavior's projection deceleration reads 0.996. Oct 23 2026
|
|
62
|
+
*/
|
|
63
|
+
releaseProjectionRate: 0.996,
|
|
64
|
+
/**
|
|
65
|
+
* How much of the projection the coast travels. The target is the lift
|
|
66
|
+
* value plus this share of the projected distance. A finger lifted outside
|
|
67
|
+
* the control's tracking bounds coasts back to the lift value instead.
|
|
68
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
69
|
+
* release behavior's target smoothing reads 0.4. A 126.9 pt/s release
|
|
70
|
+
* travels 12.56 pt, against 12.64 predicted. Oct 23 2026
|
|
71
|
+
*/
|
|
72
|
+
releaseProjectionShare: 0.4,
|
|
73
|
+
/**
|
|
74
|
+
* The thumb's growth under a finger, uniform about its center (37 × 24 to
|
|
75
|
+
* 57.35 × 37.2 pt).
|
|
76
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The lens
|
|
77
|
+
* frame settled during an 800 ms hold. Oct 23 2026
|
|
78
|
+
*/
|
|
79
|
+
liftScale: 1.55,
|
|
80
|
+
/**
|
|
81
|
+
* The lift: the thumb grows to `liftScale` when the finger lands.
|
|
82
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The lens
|
|
83
|
+
* width per frame in an 800 ms hold fits one spring at rms 0.31 pt.
|
|
84
|
+
* Oct 23 2026
|
|
85
|
+
*/
|
|
86
|
+
liftSpring: {
|
|
87
|
+
response: 0.215,
|
|
88
|
+
dampingRatio: 0.6
|
|
89
|
+
},
|
|
90
|
+
/**
|
|
91
|
+
* The drop: the thumb shrinks back to its rest size when the finger lifts,
|
|
92
|
+
* while the coast runs.
|
|
93
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
94
|
+
* lens's spring at the lift of an 800 ms hold reads response 0.5 s and
|
|
95
|
+
* damping ratio 0.7. The width per frame fits it at rms 0.10 pt.
|
|
96
|
+
* Oct 23 2026
|
|
97
|
+
*/
|
|
98
|
+
dropSpring: {
|
|
99
|
+
response: 0.5,
|
|
100
|
+
dampingRatio: 0.7
|
|
101
|
+
},
|
|
102
|
+
/**
|
|
103
|
+
* The feedback each time the value reaches an end, once per entry. It
|
|
104
|
+
* re-arms when the value leaves the end, in the drag and the coast. UIKit
|
|
105
|
+
* plays "Micro Tap Medium", and the web stand-in is the closest kind.
|
|
106
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
107
|
+
* haptics log of drags into both ends shows the fluid slider generator's
|
|
108
|
+
* "Micro Tap Medium" once per entry. Oct 23 2026
|
|
109
|
+
*/
|
|
110
|
+
endHaptic: 'impactMedium'
|
|
111
|
+
};
|
|
@@ -399,6 +399,39 @@ export declare const BANNER_SPRING: {
|
|
|
399
399
|
readonly stiffness: 1000;
|
|
400
400
|
readonly damping: 500;
|
|
401
401
|
};
|
|
402
|
+
/**
|
|
403
|
+
* UISlider's release: after a finger lifts, the thumb settles on this spring
|
|
404
|
+
* toward 0.4 of the release's momentum projection. It is critically damped,
|
|
405
|
+
* so it never overshoots a target ahead of it.
|
|
406
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
407
|
+
* `UIViewSpringAnimationBehavior` at the lift reads response 0.4 and
|
|
408
|
+
* damping ratio 1. Four releases fit it per frame (the UIKit slider
|
|
409
|
+
* table). Oct 23 2026
|
|
410
|
+
*/
|
|
411
|
+
export declare const SLIDER_RELEASE_SPRING: {
|
|
412
|
+
readonly response: 0.4;
|
|
413
|
+
readonly dampingRatio: 1;
|
|
414
|
+
};
|
|
415
|
+
/**
|
|
416
|
+
* UISlider's lift: a finger's touch-down scales the thumb up on this spring.
|
|
417
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
418
|
+
* thumb's scale per frame after touch-down (the UIKit slider table).
|
|
419
|
+
* Oct 23 2026
|
|
420
|
+
*/
|
|
421
|
+
export declare const SLIDER_LIFT_SPRING: {
|
|
422
|
+
readonly response: 0.215;
|
|
423
|
+
readonly dampingRatio: 0.6;
|
|
424
|
+
};
|
|
425
|
+
/**
|
|
426
|
+
* UISlider's drop: the lift's end scales the thumb back down on this spring.
|
|
427
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
428
|
+
* thumb's scale per frame after the lift (the UIKit slider table).
|
|
429
|
+
* Oct 23 2026
|
|
430
|
+
*/
|
|
431
|
+
export declare const SLIDER_DROP_SPRING: {
|
|
432
|
+
readonly response: 0.5;
|
|
433
|
+
readonly dampingRatio: 0.7;
|
|
434
|
+
};
|
|
402
435
|
/**
|
|
403
436
|
* Every spring above, by row name: the table the existing readers use. A
|
|
404
437
|
* component imports only the rows it plays (`architecture:component-style-authoring`
|
|
@@ -550,9 +583,21 @@ export declare const springs: {
|
|
|
550
583
|
readonly stiffness: 1000;
|
|
551
584
|
readonly damping: 500;
|
|
552
585
|
};
|
|
586
|
+
readonly sliderRelease: {
|
|
587
|
+
readonly response: 0.4;
|
|
588
|
+
readonly dampingRatio: 1;
|
|
589
|
+
};
|
|
590
|
+
readonly sliderLift: {
|
|
591
|
+
readonly response: 0.215;
|
|
592
|
+
readonly dampingRatio: 0.6;
|
|
593
|
+
};
|
|
594
|
+
readonly sliderDrop: {
|
|
595
|
+
readonly response: 0.5;
|
|
596
|
+
readonly dampingRatio: 0.7;
|
|
597
|
+
};
|
|
553
598
|
};
|
|
554
599
|
/**
|
|
555
|
-
* Registers the springs
|
|
600
|
+
* Registers the role springs (`SPRING_ROLES`) as internal motion roles
|
|
556
601
|
* (motion/roles.ts), by their row names (`springs.settle`). Every other
|
|
557
602
|
* spring, UIKit's menu spring under Reduce Motion and the keyboard's
|
|
558
603
|
* included, is not a role. Nothing registers on import: the touch code that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"springs.d.ts","sourceRoot":"","sources":["../../../src/motion/uikit/springs.ts"],"names":[],"mappings":"AAmCA;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;CAAsC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;CAAyC,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,eAAe;;;CAAwC,CAAC;AAErE;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;CAGzB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;CAA6C,CAAC;AAE9E;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;CAGvB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;CAAsC,CAAC;AAEvE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,kBAAkB;;;;CAIrB,CAAC;AAMX;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB;;;CAA4C,CAAC;AAEhF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;CAA4C,CAAC;AAE/E;;;;;;GAMG;AACH,eAAO,MAAM,wCAAwC;;;CAG3C,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B;;;CAGjC,CAAC;AAMX;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB;;;;CAIvB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;CAIvB,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB;;;CAGtB,CAAC;AAEX;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB;;;CAG5B,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B;;;CAG7B,CAAC;AAMX;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB;;;;CAIvB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;CAIvB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B;;;;CAI9B,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,2BAA2B;;;;CAI9B,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;;CAA+C,CAAC;AAE7E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;CAAgD,CAAC;AAE/E;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,oBAAoB;;;CAGvB,CAAC;AAEX;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,oBAAoB;;;CAA4C,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB;;;CAG3B,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,2BAA2B;;;CAG9B,CAAC;AAEX;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB;;;CAG5B,CAAC;AAEX;;;;;;;;;GASG;AACH,eAAO,MAAM,0BAA0B;;;CAG7B,CAAC;AAMX;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB;;;CAG3B,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B;;;CAG9B,CAAC;AAEX;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB;;;CAGzB,CAAC;AAMX;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;CAIlB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,aAAa;;;;CAAoD,CAAC;AAE/E;;;;GAIG;AACH,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"springs.d.ts","sourceRoot":"","sources":["../../../src/motion/uikit/springs.ts"],"names":[],"mappings":"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"}
|
|
@@ -488,6 +488,42 @@ export const BANNER_SPRING = {
|
|
|
488
488
|
damping: 500
|
|
489
489
|
};
|
|
490
490
|
|
|
491
|
+
/**
|
|
492
|
+
* UISlider's release: after a finger lifts, the thumb settles on this spring
|
|
493
|
+
* toward 0.4 of the release's momentum projection. It is critically damped,
|
|
494
|
+
* so it never overshoots a target ahead of it.
|
|
495
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
496
|
+
* `UIViewSpringAnimationBehavior` at the lift reads response 0.4 and
|
|
497
|
+
* damping ratio 1. Four releases fit it per frame (the UIKit slider
|
|
498
|
+
* table). Oct 23 2026
|
|
499
|
+
*/
|
|
500
|
+
export const SLIDER_RELEASE_SPRING = {
|
|
501
|
+
response: 0.4,
|
|
502
|
+
dampingRatio: 1
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* UISlider's lift: a finger's touch-down scales the thumb up on this spring.
|
|
507
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
508
|
+
* thumb's scale per frame after touch-down (the UIKit slider table).
|
|
509
|
+
* Oct 23 2026
|
|
510
|
+
*/
|
|
511
|
+
export const SLIDER_LIFT_SPRING = {
|
|
512
|
+
response: 0.215,
|
|
513
|
+
dampingRatio: 0.6
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* UISlider's drop: the lift's end scales the thumb back down on this spring.
|
|
518
|
+
* @source measured: UIKit lab, iOS 26.2 simulator, iPhone 17 Pro. The
|
|
519
|
+
* thumb's scale per frame after the lift (the UIKit slider table).
|
|
520
|
+
* Oct 23 2026
|
|
521
|
+
*/
|
|
522
|
+
export const SLIDER_DROP_SPRING = {
|
|
523
|
+
response: 0.5,
|
|
524
|
+
dampingRatio: 0.7
|
|
525
|
+
};
|
|
526
|
+
|
|
491
527
|
/**
|
|
492
528
|
* Every spring above, by row name: the table the existing readers use. A
|
|
493
529
|
* component imports only the rows it plays (`architecture:component-style-authoring`
|
|
@@ -527,11 +563,16 @@ export const springs = {
|
|
|
527
563
|
switchThumbStretch: SWITCH_THUMB_STRETCH_SPRING,
|
|
528
564
|
segmentedThumb: SEGMENTED_THUMB_SPRING,
|
|
529
565
|
keyboard: KEYBOARD_SPRING,
|
|
530
|
-
banner: BANNER_SPRING
|
|
566
|
+
banner: BANNER_SPRING,
|
|
567
|
+
sliderRelease: SLIDER_RELEASE_SPRING,
|
|
568
|
+
sliderLift: SLIDER_LIFT_SPRING,
|
|
569
|
+
sliderDrop: SLIDER_DROP_SPRING
|
|
531
570
|
};
|
|
532
571
|
|
|
533
572
|
/**
|
|
534
|
-
* The
|
|
573
|
+
* The only springs that are motion roles. The touch presentations' record
|
|
574
|
+
* names some, and a component's own record names others, such as Slider's
|
|
575
|
+
* three. The generated motion role table lists each with its record.
|
|
535
576
|
* The registry takes these rows alone, so registering ships no other spring.
|
|
536
577
|
*/
|
|
537
578
|
const SPRING_ROLES = {
|
|
@@ -549,11 +590,14 @@ const SPRING_ROLES = {
|
|
|
549
590
|
subMenuBack: SUB_MENU_BACK_SPRING,
|
|
550
591
|
contextMenuLift: CONTEXT_MENU_LIFT_SPRING,
|
|
551
592
|
contextMenuDismiss: CONTEXT_MENU_DISMISS_SPRING,
|
|
552
|
-
contextMenuMorph: CONTEXT_MENU_MORPH_SPRING
|
|
593
|
+
contextMenuMorph: CONTEXT_MENU_MORPH_SPRING,
|
|
594
|
+
sliderRelease: SLIDER_RELEASE_SPRING,
|
|
595
|
+
sliderLift: SLIDER_LIFT_SPRING,
|
|
596
|
+
sliderDrop: SLIDER_DROP_SPRING
|
|
553
597
|
};
|
|
554
598
|
|
|
555
599
|
/**
|
|
556
|
-
* Registers the springs
|
|
600
|
+
* Registers the role springs (`SPRING_ROLES`) as internal motion roles
|
|
557
601
|
* (motion/roles.ts), by their row names (`springs.settle`). Every other
|
|
558
602
|
* spring, UIKit's menu spring under Reduce Motion and the keyboard's
|
|
559
603
|
* included, is not a role. Nothing registers on import: the touch code that
|