@kyralabs/m3e-motion 1.4.0 → 1.6.0

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/index.d.ts CHANGED
@@ -57,9 +57,10 @@ declare class SpringAnimatable {
57
57
  snapTo(value: number): void;
58
58
  /**
59
59
  * Animates to `target` from the value and velocity at `now` (ms); a null spec (e.g. a spatial
60
- * spring under reduced motion) jumps there.
60
+ * spring under reduced motion) jumps there. `velocity` (units per second) overrides the current
61
+ * velocity, e.g. after the value was driven by something else (a drag, a tween).
61
62
  */
62
- animateTo(target: number, spec: SpringSpec | null, now: number): void;
63
+ animateTo(target: number, spec: SpringSpec | null, now: number, velocity?: number): void;
63
64
  /** Advances to `now` (ms) and returns the value; the animation ends once its duration is up. */
64
65
  sample(now: number): number;
65
66
  }
@@ -75,12 +76,22 @@ declare const fabMenuItemVisible: (index: number, itemCount: number, stagger: nu
75
76
  */
76
77
  declare function menuNavigationTarget(key: string, count: number, current: number): number | null;
77
78
 
79
+ /** React Aria useTypeSelect clears the typed string after this long (TYPEAHEAD_DEBOUNCE_WAIT_MS). */
80
+ declare const TYPEAHEAD_TIMEOUT_MS = 1000;
81
+ /**
82
+ * Index of the first item in `texts` that starts with `search`, from `from` (the focused item,
83
+ * −1: none) to the end, then from the start; −1 when none does.
84
+ */
85
+ declare function typeSelectTarget(texts: readonly string[], from: number, search: string): number;
86
+
78
87
  type ToolbarOrientation = 'horizontal' | 'vertical';
88
+ /** A toolbar orientation, or `both`: both arrow key pairs move along the one item order. */
89
+ type NavigationOrientation = ToolbarOrientation | 'both';
79
90
  /**
80
91
  * The item index `key` moves focus to from `current` (−1: none focused) among `count` items, or
81
- * null when the key does not navigate. At either end the index stays put (no wrapping).
92
+ * null when the key does not navigate. At either end the index stays put unless `wrap`.
82
93
  */
83
- declare function toolbarNavigationTarget(key: string, count: number, current: number, orientation?: ToolbarOrientation, rtl?: boolean): number | null;
94
+ declare function toolbarNavigationTarget(key: string, count: number, current: number, orientation?: NavigationOrientation, rtl?: boolean, wrap?: boolean): number | null;
84
95
 
85
96
  /** Where a floating toolbar leaves the screen (FloatingToolbarExitDirection), logical. */
86
97
  type FloatingToolbarExitDirection = 'bottom' | 'top' | 'start' | 'end';
@@ -591,4 +602,752 @@ declare function buttonGroupVisibleCount(widths: readonly number[], spacing: num
591
602
  */
592
603
  declare function buttonGroupWidths(items: readonly ButtonGroupItemSize[], pressed: readonly number[], expandedRatio: number, visibleCount?: number): number[];
593
604
 
594
- export { AmplitudeAnimation, type AmplitudeTween, type AppBarScrollBehavior, type AppBarScrollState, type ButtonGroupItemSize, type CircularIndeterminateFrame, type CircularIndeterminateTiming, DEFAULT_DISPLACEMENT_THRESHOLD, type Easing, FAST_OUT_LINEAR_IN_EASING, type FloatingToolbarExitDirection, type FloatingToolbarScrollState, type IndeterminateFrame, type LinearEasing, type LinearEasingOptions, type LinearIndeterminateTiming, type LoadingIndicatorTiming, type MenuAnchorPosition, type MenuPositionInput, type MenuPositionResult, type MenuRect, type Motion, SEARCH_BAR_EXPANDED_THRESHOLD, SEARCH_DROPDOWN_VISIBLE_PROGRESS, SearchBarAnimation, type SearchBarSample, type SearchBarSpecs, type SearchRect, type SearchViewFrame, type SearchViewInput, type SearchViewMetrics, type SearchViewVariant, SpringAnimatable, SpringSimulation, type SpringSpec, TOP_TITLE_ALPHA_EASING, type ToolbarExpansionScroll, type ToolbarOrientation, TweenAnimatable, type TweenSpec, type TwoRowsFrame, animatedInt, appBarScrollState, buttonGroupVisibleCount, buttonGroupWidths, circularIndeterminateFrame, collapsedFraction, cubicBezier, dampingCoefficient, dampingRatioFromCoefficient, estimateAnimationDurationMillis, estimateAnimationDurationMillisDouble, fabMenuItemVisible, floatingToolbarScrollState, indeterminateFrame, indicatorAmplitude, initialIndeterminateFrame, isScrolledUnder, linearIndeterminateFractions, menuNavigationTarget, menuPosition, menuTransformOrigin, morphSpringDurationMillis, overlappedFraction, parseCubicBezier, scrollAppBar, scrollFloatingToolbar, scrollToolbarExpansion, searchNavigationTarget, searchViewFrame, settleTarget, springDurationMillis, springToLinear, springValue, springVelocity, toolbarCollapsedFraction, toolbarExpansionScroll, toolbarNavigationTarget, toolbarSettleTarget, twoRowsFrame, waveOffset, waveTravelMillis, withHeight, withHeightOffset, withToolbarOffset, withToolbarOffsetLimit };
605
+ /** Width size classes, smallest first (DpWidthSizeClasses). */
606
+ type WindowWidthSizeClass = 'compact' | 'medium' | 'expanded' | 'large' | 'extra-large';
607
+ /** Height size classes, smallest first (DpHeightSizeClasses). */
608
+ type WindowHeightSizeClass = 'compact' | 'medium' | 'expanded';
609
+ /** Lower bound (min-width, dp = CSS px) of each width size class (WindowSizeClass L146-155). */
610
+ declare const WINDOW_WIDTH_BREAKPOINTS: Readonly<Record<WindowWidthSizeClass, number>>;
611
+ /** Lower bound (min-height, dp = CSS px) of each height size class (WindowSizeClass L158-161). */
612
+ declare const WINDOW_HEIGHT_BREAKPOINTS: Readonly<Record<WindowHeightSizeClass, number>>;
613
+ /** A window's (or container's) size class: androidx `WindowSizeClass` plus its bucket names. */
614
+ interface WindowSizeClass {
615
+ readonly widthClass: WindowWidthSizeClass;
616
+ readonly heightClass: WindowHeightSizeClass;
617
+ /** Lower bound of the width class in CSS px (`minWidthDp`). */
618
+ readonly minWidth: number;
619
+ /** Lower bound of the height class in CSS px (`minHeightDp`). */
620
+ readonly minHeight: number;
621
+ }
622
+ interface WindowSizeClassOptions {
623
+ /**
624
+ * Classify widths into the large and extra-large classes (currentWindowAdaptiveInfoV2; default
625
+ * `true`). `false` keeps the V1 set, where every width from 840 is `expanded`.
626
+ */
627
+ largeAndExtraLargeWidth?: boolean | undefined;
628
+ }
629
+ /**
630
+ * The width size class of a window `widthPx` CSS px wide. Negative or NaN widths (androidx
631
+ * rejects them) classify as compact.
632
+ */
633
+ declare function windowWidthSizeClass(widthPx: number, options?: WindowSizeClassOptions): WindowWidthSizeClass;
634
+ /** The height size class of a window `heightPx` CSS px tall. */
635
+ declare function windowHeightSizeClass(heightPx: number): WindowHeightSizeClass;
636
+ /** The size class of a `width` × `height` CSS px window or container. */
637
+ declare function windowSizeClass(size: {
638
+ readonly width: number;
639
+ readonly height: number;
640
+ }, options?: WindowSizeClassOptions): WindowSizeClass;
641
+ /** Whether two size classes are the same bucket (WindowSizeClass.equals). */
642
+ declare function sameWindowSizeClass(a: WindowSizeClass, b: WindowSizeClass): boolean;
643
+ /**
644
+ * `minWidth >= breakpoint` (isWidthAtLeastBreakpoint, L98-100). `breakpoint` is a class name or a
645
+ * px lower bound. Like androidx, check from the largest breakpoint down.
646
+ */
647
+ declare function isWidthAtLeastBreakpoint(sizeClass: WindowSizeClass, breakpoint: WindowWidthSizeClass | number): boolean;
648
+ /** `minHeight >= breakpoint` (isHeightAtLeastBreakpoint, L107-109). */
649
+ declare function isHeightAtLeastBreakpoint(sizeClass: WindowSizeClass, breakpoint: WindowHeightSizeClass | number): boolean;
650
+ /** Both of the above (isAtLeastBreakpoint, L117-120). */
651
+ declare function isAtLeastBreakpoint(sizeClass: WindowSizeClass, widthBreakpoint: WindowWidthSizeClass | number, heightBreakpoint: WindowHeightSizeClass | number): boolean;
652
+ /** Posture input for the directive and the navigation suite (Compose `Posture.isTabletop`). */
653
+ interface WindowPostureOptions {
654
+ /** A half-folded device with a horizontal hinge. Default `false`. */
655
+ isTabletop?: boolean | undefined;
656
+ }
657
+ /** Material's recommended pane layout for a size class (PaneScaffoldDirective, without hinges). */
658
+ interface PaneScaffoldDirective {
659
+ /** Panes side by side at most: 1 at compact/medium, 2 at expanded, 3 from large. */
660
+ readonly maxHorizontalPartitions: number;
661
+ /** Spacer between side-by-side panes, CSS px. */
662
+ readonly horizontalPartitionSpacerSize: number;
663
+ /** Panes stacked at most: 2 on a tabletop posture or a single-pane expanded-height window. */
664
+ readonly maxVerticalPartitions: number;
665
+ readonly verticalPartitionSpacerSize: number;
666
+ /** Default preferred pane width, CSS px (the fixed pane of a fixed-and-flexible layout). */
667
+ readonly defaultPanePreferredWidth: number;
668
+ readonly defaultPanePreferredHeight: number;
669
+ }
670
+ /** calculatePaneScaffoldDirective (PaneScaffoldDirective.kt L48-106), without hinge bounds. */
671
+ declare function paneScaffoldDirective(sizeClass: WindowSizeClass, options?: WindowPostureOptions): PaneScaffoldDirective;
672
+ /**
673
+ * NavigationSuiteType (NavigationSuiteScaffold.kt L1068-1155) without the types of deprecated
674
+ * components (`NavigationBar`, `NavigationRail`: the legacy bar / rail, D4): which navigation
675
+ * component a navigation suite shows. `none` shows none.
676
+ */
677
+ type NavigationSuiteType = 'short-navigation-bar-compact' | 'short-navigation-bar-medium' | 'wide-navigation-rail-collapsed' | 'wide-navigation-rail-expanded' | 'navigation-drawer' | 'none';
678
+ /** The suite types, in NavigationSuiteType's order. */
679
+ declare const NAVIGATION_SUITE_TYPES: readonly NavigationSuiteType[];
680
+ /** Whether a type puts the navigation at the bottom (`NavigationSuiteType.isNavigationBar`). */
681
+ declare function isNavigationBarType(type: NavigationSuiteType): boolean;
682
+ interface NavigationSuiteTypeOptions extends WindowPostureOptions {
683
+ /**
684
+ * From this width class (or px lower bound, compared with the class's lower bound like
685
+ * `isWidthAtLeastBreakpoint`) on, windows that would get the collapsed rail get `expandedType`
686
+ * instead. Compose's default never expands (`undefined` / `null`); the navigation suite scaffold
687
+ * passes {@link NAVIGATION_SUITE_EXPANDED_FROM}. The bar rules (compact width, then tabletop or
688
+ * compact height) still come first, as in Compose's custom configuration sample.
689
+ */
690
+ expandedFrom?: WindowWidthSizeClass | number | null | undefined;
691
+ /** What the expanded suite shows: the expanded wide navigation rail (default) or a drawer. */
692
+ expandedType?: 'wide-navigation-rail-expanded' | 'navigation-drawer' | undefined;
693
+ }
694
+ /**
695
+ * The navigation suite scaffold's default `expandedFrom`: the expanded wide navigation rail at
696
+ * large and extra-large widths (m3.material.io guidance, owner decision 2026-10-17, COMPONENT_SPEC
697
+ * §16). Not a Compose default: Compose's navigationSuiteType never returns the expanded rail.
698
+ */
699
+ declare const NAVIGATION_SUITE_EXPANDED_FROM: WindowWidthSizeClass;
700
+ /**
701
+ * NavigationSuiteScaffoldDefaults.navigationSuiteType (L1167-1180): a short navigation bar at
702
+ * compact width (compact arrangement), a short navigation bar with the medium (horizontal item)
703
+ * arrangement on a tabletop posture or at compact height, otherwise a collapsed wide navigation
704
+ * rail. With `expandedFrom`, the collapsed rail becomes `expandedType` (default: the expanded wide
705
+ * navigation rail) from that width on.
706
+ */
707
+ declare function navigationSuiteType(sizeClass: WindowSizeClass, options?: NavigationSuiteTypeOptions): NavigationSuiteType;
708
+
709
+ interface NavigationSuiteSample {
710
+ /** The layout's animationProgress: 0 hidden … 1 shown. */
711
+ readonly progress: number;
712
+ /** Either spring is still moving (the caller keeps its frame loop going). */
713
+ readonly running: boolean;
714
+ }
715
+ /**
716
+ * NavigationSuiteScaffoldState plus its layout's progress, driven by the caller's clock (ms).
717
+ * `spec` is the scaffold's AnimationSpec (`--m3e-comp-navigation-suite-scaffold-visibility-*`), or
718
+ * null to jump (the spatial spring under reduced motion).
719
+ */
720
+ declare class NavigationSuiteScaffoldAnimation {
721
+ #private;
722
+ /** `hidden`: rememberNavigationSuiteScaffoldState(initialValue = Hidden); rendered at rest. */
723
+ constructor(hidden?: boolean);
724
+ /** NavigationSuiteScaffoldState.targetValue == Hidden. */
725
+ get targetHidden(): boolean;
726
+ /** NavigationSuiteScaffoldState.currentValue == Hidden (anything but exactly Visible). */
727
+ get currentHidden(): boolean;
728
+ /** NavigationSuiteScaffoldState.isAnimating (the state's spring, not the layout's). */
729
+ get isAnimating(): boolean;
730
+ /** NavigationSuiteScaffoldState.hide(). */
731
+ hide(spec: SpringSpec | null, now: number): void;
732
+ /** NavigationSuiteScaffoldState.show(). */
733
+ show(spec: SpringSpec | null, now: number): void;
734
+ /** NavigationSuiteScaffoldState.toggle(): towards the opposite of the target. */
735
+ toggle(spec: SpringSpec | null, now: number): void;
736
+ /** NavigationSuiteScaffoldState.snapTo(): the state jumps; the layout animates from `now`. */
737
+ snapTo(hidden: boolean, spec: SpringSpec | null, now: number): void;
738
+ /** Advances both springs to `now`; the layout retargets when currentValue changes. */
739
+ sample(now: number): NavigationSuiteSample;
740
+ }
741
+ /**
742
+ * How far the navigation is pushed out of the layout (px) for `size` (its height with a bar, its
743
+ * width otherwise) at `progress`: `size − (size × progress).toInt()`. The content gets the rest of
744
+ * the layout; the navigation sits at `layoutHeight − (height × progress).toInt()` (bar types) or
745
+ * `−(width × (1 − progress)).toInt()` (L417-479).
746
+ */
747
+ declare function navigationSuiteOffset(size: number, progress: number): number;
748
+
749
+ /** ModalWideNavigationRail: the window rail expands once positionProgress reaches this (L600). */
750
+ declare const MODAL_RAIL_EXPANDED_PROGRESS = 0.3;
751
+ /** The springs of a wide navigation rail (null jumps: reduced motion snaps spatial springs). */
752
+ interface WideNavigationRailSpecs {
753
+ /** WideNavigationRailLayout `animationSpec` (L324): non-modal width, item spacing / min height. */
754
+ readonly width: SpringSpec | null;
755
+ /** `modalAnimationSpec` (L325): the modal window rail's width. */
756
+ readonly modalWidth: SpringSpec | null;
757
+ /** AnimatedNavigationItem `iconPositionProgress` (NavigationItem.kt L488-493). */
758
+ readonly iconPosition: SpringSpec | null;
759
+ /** ModalWideNavigationRail `positionProgress` (L593-598). */
760
+ readonly position: SpringSpec | null;
761
+ /** The modal scrim alpha (L826-831). */
762
+ readonly scrim: SpringSpec | null;
763
+ /** hideOnCollapse: ModalWideNavigationRailState (L732-736). */
764
+ readonly slide: SpringSpec | null;
765
+ }
766
+ /** One frame of a {@link WideNavigationRailAnimation}. */
767
+ interface WideNavigationRailSample {
768
+ /** The items' iconPositionProgress (0 top icon … 1 start icon); expressive springs overshoot. */
769
+ readonly item: number;
770
+ /** The rail's minWidth / widthFullRange progress (0 collapsed … 1 expanded). */
771
+ readonly width: number;
772
+ /** itemVerticalSpacedBy / itemMinHeight progress (0 collapsed … 1 expanded). */
773
+ readonly layout: number;
774
+ /** Modal: the window (scrim + rail in the top layer) is shown. */
775
+ readonly open: boolean;
776
+ /**
777
+ * The `expanded` WideNavigationRailLayout measures with: the target (non-modal); in the modal
778
+ * window `hideOnCollapse || modalExpanded`; false for the collapsed rail of a modal one.
779
+ */
780
+ readonly railExpanded: boolean;
781
+ /** Modal: the scrim alpha, 0…1. */
782
+ readonly scrim: number;
783
+ /** hideOnCollapse: 0 off screen (offset −width) … 1 in place. */
784
+ readonly slide: number;
785
+ /** Any value is still moving. */
786
+ readonly running: boolean;
787
+ }
788
+ interface WideNavigationRailAnimationOptions {
789
+ readonly expanded: boolean;
790
+ /** ModalWideNavigationRail. */
791
+ readonly modal?: boolean;
792
+ /** ModalWideNavigationRail(hideOnCollapse = true): slides in expanded instead of expanding. */
793
+ readonly hideOnCollapse?: boolean;
794
+ /**
795
+ * Visibility threshold of the width spring in progress units: animateDpAsState uses
796
+ * Spring.DefaultDisplacementThreshold (0.01dp) over the width range (default: 0.01 / 264dp).
797
+ */
798
+ readonly widthThreshold?: number;
799
+ /** Likewise for spacing / min height (default: 0.01 / 16dp, the min-height range). */
800
+ readonly layoutThreshold?: number;
801
+ }
802
+ /**
803
+ * WideNavigationRailState plus the animations it drives. `setExpanded` retargets every value from
804
+ * its current value and velocity (Compose `animate*AsState` / `Animatable.animateTo`).
805
+ */
806
+ declare class WideNavigationRailAnimation {
807
+ #private;
808
+ readonly modal: boolean;
809
+ readonly hideOnCollapse: boolean;
810
+ constructor(options: WideNavigationRailAnimationOptions);
811
+ /** WideNavigationRailState.targetValue. */
812
+ get expanded(): boolean;
813
+ get isRunning(): boolean;
814
+ /** expand() / collapse() at `now` (ms). */
815
+ setExpanded(expanded: boolean, specs: WideNavigationRailSpecs, now: number): void;
816
+ /** WideNavigationRailState.snapTo. */
817
+ snapTo(expanded: boolean): void;
818
+ sample(now: number): WideNavigationRailSample;
819
+ }
820
+ /** The dp values WideNavigationRailLayout and AnimatedNavigationItem measure with. */
821
+ interface WideNavigationRailMetrics {
822
+ /** NavigationRailCollapsedTokens.ContainerWidth (96dp). */
823
+ readonly collapsedWidth: number;
824
+ /** NavigationRailExpandedTokens.ContainerWidthMinimum (220dp). */
825
+ readonly expandedMinWidth: number;
826
+ /** NavigationRailExpandedTokens.ContainerWidthMaximum (360dp). */
827
+ readonly expandedMaxWidth: number;
828
+ /** WNRItemHorizontalPadding (20dp). */
829
+ readonly itemHorizontalPadding: number;
830
+ /** NavigationRailBaselineItemTokens.IconSize (24dp). */
831
+ readonly iconSize: number;
832
+ /** NavigationRailHorizontalItemTokens.IconLabelSpace (8dp). */
833
+ readonly iconLabelSpace: number;
834
+ /** Indicator horizontal padding per side, collapsed: (ActiveIndicatorWidth − IconSize) / 2. */
835
+ readonly collapsedIndicatorPadding: number;
836
+ /** Expanded: NavigationRailHorizontalItemTokens.FullWidthLeadingSpace. */
837
+ readonly expandedIndicatorPadding: number;
838
+ }
839
+ /**
840
+ * An item's measured width (placeAnimatedLabelAndIcon, NavigationItem.kt L1119-1133). `content` is
841
+ * the item's start-icon pill width (icon + gap + label + both expanded paddings), or null for an
842
+ * icon-only item (TopIconOrIconOnlyMeasurePolicy: the 56dp circle plus the padding on both sides).
843
+ * `maxWidth` is the rail's item constraint (expanded: rail maximum − item padding).
844
+ */
845
+ declare function wideNavigationRailItemWidth(content: number | null, progress: number, m: WideNavigationRailMetrics, maxWidth: number): number;
846
+ interface WideNavigationRailWidthInput {
847
+ /** `expanded` passed to WideNavigationRailLayout (the state's target, or modalExpanded). */
848
+ readonly expanded: boolean;
849
+ /** minWidth / widthFullRange progress. */
850
+ readonly widthProgress: number;
851
+ /** The items' iconPositionProgress. */
852
+ readonly itemProgress: number;
853
+ /** Each item's start-icon pill width (null: icon only). */
854
+ readonly items: readonly (number | null)[];
855
+ /** The header's width (0 without one). */
856
+ readonly header: number;
857
+ /** The width of the previous frame (`currentWidth`). */
858
+ readonly previousWidth: number;
859
+ /** `actualMaxExpandedWidth > 0`: the rail was wider than its expanded minimum. */
860
+ readonly wide: boolean;
861
+ /** The available width (the rail's maximum when unconstrained). */
862
+ readonly maxWidth?: number;
863
+ readonly metrics: WideNavigationRailMetrics;
864
+ }
865
+ /**
866
+ * WideNavigationRailLayout's measured width (L373-476): expanding, `widthFullRange` up to the
867
+ * widest item (+ padding) or header when that is wider than the expanded minimum, else
868
+ * `minWidth`; collapsing from such a rail, `widthFullRange` kept between `minWidth` and the previous
869
+ * width. Returns the width and whether the rail is now `wide`.
870
+ */
871
+ declare function wideNavigationRailWidth(input: WideNavigationRailWidthInput): {
872
+ width: number;
873
+ wide: boolean;
874
+ };
875
+
876
+ /** NavigationDrawer.kt `DrawerPositionalThreshold` (L1339): a fraction of the sheet width. */
877
+ declare const DRAWER_POSITIONAL_THRESHOLD = 0.5;
878
+ /** NavigationDrawer.kt `DrawerVelocityThreshold` (L1340-1341), in dp (= CSS px) per second. */
879
+ declare const DRAWER_VELOCITY_THRESHOLD = 400;
880
+ /** NavigationDrawer.kt `AnchoredDraggableDefaultAnimationSpec` (L1354): the settle tween. */
881
+ declare const DRAWER_SETTLE_MILLIS = 256;
882
+ /** The springs and settle tween of a drawer (null jumps: reduced motion). */
883
+ interface DrawerSpecs {
884
+ readonly open: SpringSpec | null;
885
+ readonly close: SpringSpec | null;
886
+ /** AnchoredDraggableDefaultAnimationSpec; null (0ms) jumps. */
887
+ readonly settle: {
888
+ readonly duration: number;
889
+ readonly easing: Easing;
890
+ } | null;
891
+ }
892
+ /** FloatExponentialDecaySpec.getTargetValue (L132-141). */
893
+ declare function exponentialDecayTarget(value: number, velocity: number): number;
894
+ /**
895
+ * DraggableAnchors.computeTarget (AnchoredDraggable.kt L1485-1514) for the drawer's two anchors:
896
+ * whether a release at `offset` (px, −width…0) with `velocity` (px/s, positive towards open)
897
+ * settles open. `velocityThreshold` is px/s.
898
+ */
899
+ declare function drawerSettlesOpen(offset: number, velocity: number, width: number, velocityThreshold?: number): boolean;
900
+ /** One frame of a {@link DrawerAnimation}. */
901
+ interface DrawerSample {
902
+ /** Sheet offset in px: −width (closed) … 0 (open); above 0 while an open spring overshoots. */
903
+ readonly offset: number;
904
+ /** calculateFraction(closed, open, offset): 0 closed … 1 open (the scrim alpha). */
905
+ readonly fraction: number;
906
+ /** Something is moving (an animation or a drag). */
907
+ readonly running: boolean;
908
+ /** The sheet is visible (fraction > 0): Compose only places it then. */
909
+ readonly visible: boolean;
910
+ }
911
+ /** DrawerState: the offset, its animations, drags and the settle after a release. */
912
+ declare class DrawerAnimation {
913
+ #private;
914
+ /** @param open initial value (at rest); @param width the sheet width in px. */
915
+ constructor(open: boolean, width: number);
916
+ /** DrawerState.targetValue === Open. */
917
+ get isOpen(): boolean;
918
+ /** DrawerState.currentValue === Open: the last anchor it settled on. */
919
+ get isSettledOpen(): boolean;
920
+ get isDragging(): boolean;
921
+ get width(): number;
922
+ /** Units: px per second, positive towards open (AnchoredDraggableState.lastVelocity). */
923
+ get velocity(): number;
924
+ /** New anchors (the sheet was measured): at rest the offset follows its anchor. */
925
+ setWidth(width: number): void;
926
+ /** Jumps (DrawerState.snapTo). */
927
+ snapTo(open: boolean): void;
928
+ /** DrawerState.open() / close() at `now` (ms): springs from the current offset and velocity. */
929
+ animateTo(open: boolean, specs: DrawerSpecs, now: number): void;
930
+ /** Grabs the sheet (pointer down past the slop): stops any animation where it is. */
931
+ startDrag(now: number): void;
932
+ /** Moves the offset by `delta` px (positive towards open), coerced between the anchors. */
933
+ dragBy(delta: number): void;
934
+ /**
935
+ * Ends a drag with the pointer `velocity` (px/s, positive towards open): picks the target
936
+ * (computeTarget) and settles on it (animateToWithDecay). Returns whether it settles open.
937
+ * `velocityThreshold`: DrawerVelocityThreshold in px/s.
938
+ */
939
+ release(velocity: number, specs: DrawerSpecs, now: number, velocityThreshold?: number, confirm?: (open: boolean) => boolean): boolean;
940
+ /** Advances to `now` (ms). */
941
+ sample(now: number): DrawerSample;
942
+ }
943
+
944
+ /** No `steps`: a key moves 1 % of the range (slideOnKeyEvents: `if (steps > 0) steps + 1 else 100`). */
945
+ declare const SLIDER_KEY_DIVISIONS = 100;
946
+ /** PageUp / PageDown: `(actualSteps / 10).coerceIn(1, 10)` steps. */
947
+ declare const SLIDER_PAGE_DIVISOR = 10;
948
+ declare const SLIDER_PAGE_MAX_STEPS = 10;
949
+ /**
950
+ * Compose `steps` for a web `step` (a value increment; 0, negative or absent = continuous):
951
+ * the stops between the ends, `round((max − min) / step) − 1`, at least 0. A `step` that does not
952
+ * divide the range gives evenly spaced ticks the nearest to it.
953
+ */
954
+ declare function sliderSteps(min: number, max: number, step?: number): number;
955
+ /** stepsToTickFractions: `steps + 2` fractions i / (steps + 1); none without steps. */
956
+ declare function sliderTickFractions(steps: number): number[];
957
+ /** calcFraction: the 0..1 fraction `value` is of min..max (0 for an empty range). */
958
+ declare function sliderFraction(value: number, min: number, max: number): number;
959
+ /** The value at `fraction` of min..max. */
960
+ declare const sliderValueAt: (fraction: number, min: number, max: number) => number;
961
+ /** snapValueToTick in value space: the nearest tick value (the first of equals), or `value`. */
962
+ declare function sliderSnap(value: number, steps: number, min: number, max: number): number;
963
+ /** The bounds of one thumb: the track, or for a range thumb up to / from the other thumb. */
964
+ interface SliderThumbBounds {
965
+ readonly min: number;
966
+ readonly max: number;
967
+ }
968
+ /**
969
+ * The value a thumb takes for a requested `value`: coerced into its bounds, then snapped to the
970
+ * nearest tick of the whole track (SliderState.value / RangeSliderState.startValue / endValue).
971
+ */
972
+ declare function sliderThumbValue(value: number, bounds: SliderThumbBounds, steps: number, min: number, max: number): number;
973
+ /** The bounds of thumb `index` among `values` (one thumb, or a range's start and end). */
974
+ declare function sliderThumbBounds(values: readonly number[], index: number, min: number, max: number): SliderThumbBounds;
975
+ /** One key step: `rangeLength / actualSteps`. */
976
+ declare function sliderKeyDelta(steps: number, min: number, max: number): number;
977
+ /** PageUp / PageDown: how many key steps a page is. */
978
+ declare function sliderPageSteps(steps: number): number;
979
+ type SliderKeyAction = 'increment' | 'decrement' | 'page-increment' | 'page-decrement' | 'min' | 'max';
980
+ interface SliderKeyOptions {
981
+ readonly vertical?: boolean;
982
+ /** Right-to-left layout: the horizontal arrows swap (Compose `sign = -1`). */
983
+ readonly rtl?: boolean;
984
+ /** Shift held: an arrow moves a page (m3.material.io "a larger interval"; React Aria). */
985
+ readonly shiftKey?: boolean;
986
+ }
987
+ /**
988
+ * What a key does. Compose: ArrowRight / ArrowLeft on a horizontal slider (swapped in RTL),
989
+ * ArrowUp / ArrowDown on a vertical one (minimum at the bottom: up increases, owner decision
990
+ * M8 #21), PageUp / PageDown, Home / End. The web adds the other arrow pair per the ARIA slider
991
+ * pattern (Up / Right increase) and Shift + arrow for a page (m3.material.io keyboard table);
992
+ * Compose ignores them. Other keys: null.
993
+ */
994
+ declare function sliderKeyAction(key: string, options?: SliderKeyOptions): SliderKeyAction | null;
995
+ /**
996
+ * The value a key action gives thumb `index` (the result is coerced into the thumb's bounds and
997
+ * snapped). Home / End go to the thumb's bounds: a range start thumb's End meets the end thumb.
998
+ */
999
+ declare function sliderKeyValue(action: SliderKeyAction, values: readonly number[], index: number, steps: number, min: number, max: number): number;
1000
+ /**
1001
+ * The range thumb a press at `value` moves (RangeSliderLogic): the closer one; when both are as
1002
+ * close, the start thumb if it lies after the pointer (stacked thumbs pressed before them), else
1003
+ * the end thumb.
1004
+ */
1005
+ declare function sliderClosestThumb(values: readonly number[], value: number): number;
1006
+ /** Input of `sliderTrackGeometry` (one axis; slider.css mirrors it for RTL and vertical). */
1007
+ interface SliderTrackInput {
1008
+ /** Track length: the slider's length less the thumb width. */
1009
+ readonly length: number;
1010
+ /** Outer corner size (the default Track: thickness / 2). */
1011
+ readonly cornerSize: number;
1012
+ /** TrackInsideCornerSize. */
1013
+ readonly insideCornerSize: number;
1014
+ /** ThumbWidth (the thumb's layout size along the track; its handle may be narrower). */
1015
+ readonly thumbWidth: number;
1016
+ /** ThumbTrackGapSize. */
1017
+ readonly gapSize: number;
1018
+ readonly steps: number;
1019
+ /** The single thumb's fraction, or the range end's. */
1020
+ readonly fraction: number;
1021
+ /** A range's start fraction. */
1022
+ readonly startFraction?: number;
1023
+ readonly centered?: boolean;
1024
+ /** Track(trackCornerSize) and CenteredTrack shrink corners; the default Track does not. */
1025
+ readonly cornerShrinking?: boolean;
1026
+ /** Stop indicators drawn (SliderWithTrackIconsSample passes null). Default true. */
1027
+ readonly stopIndicator?: boolean;
1028
+ }
1029
+ type SliderTrackPartKind = 'inactive-start' | 'active' | 'inactive-end';
1030
+ interface SliderTrackPart {
1031
+ readonly kind: SliderTrackPartKind;
1032
+ readonly start: number;
1033
+ readonly end: number;
1034
+ readonly startRadius: number;
1035
+ readonly endRadius: number;
1036
+ }
1037
+ interface SliderTick {
1038
+ readonly position: number;
1039
+ readonly active: boolean;
1040
+ }
1041
+ interface SliderTrackGeometry {
1042
+ /** Thumb centres along the track (one, or a range's start and end). */
1043
+ readonly thumbs: readonly number[];
1044
+ readonly parts: readonly SliderTrackPart[];
1045
+ /** Stop indicator centres. */
1046
+ readonly stops: readonly number[];
1047
+ readonly ticks: readonly SliderTick[];
1048
+ }
1049
+ /**
1050
+ * SliderImpl's thumb placement and drawTrack (LTR, horizontal), in track coordinates: with steps,
1051
+ * a value off the first and last tick sits between the corners
1052
+ * ((length − 2 × corner) × fraction + corner), else length × fraction.
1053
+ */
1054
+ declare function sliderTrackGeometry(input: SliderTrackInput): SliderTrackGeometry;
1055
+
1056
+ /** TabRow.kt L461 / L608: `maxOf(contentWidth, 24.dp)` ("Enforce minimum touch target of 24.dp"). */
1057
+ declare const TAB_INDICATOR_MIN_WIDTH = 24;
1058
+ type TabRowVariant = 'primary' | 'secondary';
1059
+ /** What the caller measures per tab: its laid-out width and its content's width. */
1060
+ interface TabMeasure {
1061
+ readonly width: number;
1062
+ readonly contentWidth: number;
1063
+ }
1064
+ /** Compose `TabPosition`. */
1065
+ interface TabPosition {
1066
+ readonly left: number;
1067
+ readonly width: number;
1068
+ readonly contentWidth: number;
1069
+ }
1070
+ /** The tabs' positions from `start` (a scrollable row's edge padding; 0 for a fixed row). */
1071
+ declare function tabPositions(tabs: readonly TabMeasure[], start?: number, minIndicatorWidth?: number): TabPosition[];
1072
+ /** The indicator's target: offset (the tab's left) and width (per variant). */
1073
+ declare function tabIndicatorTarget(position: TabPosition, variant: TabRowVariant): {
1074
+ offset: number;
1075
+ width: number;
1076
+ };
1077
+ /** One frame of the indicator. */
1078
+ interface TabIndicatorSample {
1079
+ /** The animated offset (a tab's left edge). */
1080
+ readonly offset: number;
1081
+ readonly width: number;
1082
+ readonly running: boolean;
1083
+ }
1084
+ /** TabIndicatorOffsetNode: the offset and width Animatables. */
1085
+ declare class TabIndicatorAnimation {
1086
+ #private;
1087
+ /** Starts at rest on the first layout's target (Compose: initialOffset / initialWidth). */
1088
+ constructor(offset: number, width: number);
1089
+ get offset(): SpringAnimatable;
1090
+ get width(): SpringAnimatable;
1091
+ get running(): boolean;
1092
+ /**
1093
+ * Retargets each Animatable whose target changed, from its value and velocity at `now`; a null
1094
+ * spec (reduced motion) jumps.
1095
+ */
1096
+ animateTo(offset: number, width: number, spec: SpringSpec | null, now: number): void;
1097
+ snapTo(offset: number, width: number): void;
1098
+ sample(now: number): TabIndicatorSample;
1099
+ }
1100
+ /**
1101
+ * The indicator's shift from where the selected tab draws it at rest (centred in the tab), in the
1102
+ * row's logical direction: the centre is offset + tab width / 2 in both cases, so the shift is the
1103
+ * animated offset less the tab's left.
1104
+ */
1105
+ declare const tabIndicatorShift: (sample: {
1106
+ offset: number;
1107
+ }, selected: TabPosition) => number;
1108
+ /**
1109
+ * ScrollableTabData.calculateTabOffset: the scroll position centring `tab` (its left includes the
1110
+ * edge padding) in a row `scrollWidth` wide (edge padding × 2 + the tabs) seen through
1111
+ * `visibleWidth`, clamped to the scroll range.
1112
+ */
1113
+ declare function scrollableTabOffset(tab: Pick<TabPosition, 'left' | 'width'>, scrollWidth: number, visibleWidth: number): number;
1114
+ /** animateScrollTo: a Float animation from the current scroll position, from rest. */
1115
+ declare class TabScrollAnimation {
1116
+ readonly value: SpringAnimatable;
1117
+ constructor(position: number);
1118
+ /** Starts a new scroll from `from` (the scroll state's value), velocity 0. */
1119
+ animateTo(from: number, target: number, spec: SpringSpec | null, now: number): void;
1120
+ }
1121
+
1122
+ /** ThreePaneScaffoldRole. */
1123
+ type ThreePaneScaffoldRole = 'primary' | 'secondary' | 'tertiary';
1124
+ /** Roles in priority order (forEachPaneByPriority's tail, ThreePaneScaffoldValue.kt L187-189). */
1125
+ declare const THREE_PANE_SCAFFOLD_ROLES: readonly ThreePaneScaffoldRole[];
1126
+ /** AdaptStrategy.Hide, or AdaptStrategy.Reflow(reflowUnder). */
1127
+ type AdaptStrategy = 'hide' | {
1128
+ readonly reflowUnder: ThreePaneScaffoldRole;
1129
+ };
1130
+ type ThreePaneScaffoldAdaptStrategies = Readonly<Record<ThreePaneScaffoldRole, AdaptStrategy>>;
1131
+ /** ListDetailPaneScaffoldDefaults.adaptStrategies() (L208-217): every pane hides. */
1132
+ declare const LIST_DETAIL_ADAPT_STRATEGIES: ThreePaneScaffoldAdaptStrategies;
1133
+ /**
1134
+ * SupportingPaneScaffoldDefaults.adaptStrategies() (L190-200): the supporting pane reflows under
1135
+ * the main pane; the others hide.
1136
+ */
1137
+ declare const SUPPORTING_PANE_ADAPT_STRATEGIES: ThreePaneScaffoldAdaptStrategies;
1138
+ /** ListDetailPaneScaffoldRole (ListDetailPaneScaffold.kt L238-259). */
1139
+ declare const ListDetailPaneScaffoldRole: Readonly<{
1140
+ readonly List: "secondary";
1141
+ readonly Detail: "primary";
1142
+ readonly Extra: "tertiary";
1143
+ }>;
1144
+ /** SupportingPaneScaffoldRole (SupportingPaneScaffold.kt L221-243). */
1145
+ declare const SupportingPaneScaffoldRole: Readonly<{
1146
+ readonly Main: "primary";
1147
+ readonly Supporting: "secondary";
1148
+ readonly Extra: "tertiary";
1149
+ }>;
1150
+ /** Start-to-end order: list (secondary), detail (primary), extra (ListDetailPaneScaffold L224-229). */
1151
+ declare const LIST_DETAIL_PANE_ORDER: readonly ThreePaneScaffoldRole[];
1152
+ /** Start-to-end order: main, supporting, extra (SupportingPaneScaffold L207-212). */
1153
+ declare const SUPPORTING_PANE_ORDER: readonly ThreePaneScaffoldRole[];
1154
+ /** PaneAdaptedValue (Levitated is not ported). */
1155
+ type PaneAdaptedValue = 'expanded' | 'reflowed' | 'hidden';
1156
+ /** ThreePaneScaffoldValue. */
1157
+ interface ThreePaneScaffoldValue {
1158
+ readonly primary: PaneAdaptedValue;
1159
+ readonly secondary: PaneAdaptedValue;
1160
+ readonly tertiary: PaneAdaptedValue;
1161
+ /** The destination the value was calculated for (internal in Compose; not part of equality). */
1162
+ readonly currentDestination: ThreePaneScaffoldRole | null;
1163
+ }
1164
+ /** ThreePaneScaffoldValue.equals (L260-267): the three adapted values. */
1165
+ declare function sameThreePaneScaffoldValue(a: ThreePaneScaffoldValue, b: ThreePaneScaffoldValue): boolean;
1166
+ /** ThreePaneScaffoldDestinationItem. */
1167
+ interface ThreePaneScaffoldDestinationItem<T = unknown> {
1168
+ readonly pane: ThreePaneScaffoldRole;
1169
+ readonly contentKey?: T | undefined;
1170
+ }
1171
+ /**
1172
+ * calculateThreePaneScaffoldValue (ThreePaneScaffoldValue.kt L86-179): the last destination
1173
+ * first, then the earlier ones (newest first), then primary, secondary, tertiary each take a free
1174
+ * horizontal partition; with a single partition and `maxVerticalPartitions` ≥ 2, the first pane
1175
+ * whose strategy is Reflow goes under its (expanded) anchor instead.
1176
+ */
1177
+ declare function calculateThreePaneScaffoldValue(maxHorizontalPartitions: number, adaptStrategies: ThreePaneScaffoldAdaptStrategies, destinationHistory: readonly ThreePaneScaffoldDestinationItem[], maxVerticalPartitions?: number): ThreePaneScaffoldValue;
1178
+ /** The roles a value expands, in `order` (start to end). */
1179
+ declare function expandedPanes(value: ThreePaneScaffoldValue, order: readonly ThreePaneScaffoldRole[]): ThreePaneScaffoldRole[];
1180
+ /**
1181
+ * How many panes may sit side by side: `recommended` (the default, owner decision 2026-10-18) =
1182
+ * m3.material.io Breakpoints (1 / 1 / 2 / 2 / 3: two panes at large, three at extra-large), never
1183
+ * more than Compose allows; `compose` = calculatePaneScaffoldDirective (1 / 1 / 2 / 3 / 3 by width
1184
+ * class: three panes from large).
1185
+ */
1186
+ type PaneRule = 'compose' | 'recommended';
1187
+ /** m3.material.io Foundations › Layout › Breakpoints, "recommended" pane counts (FOUNDATIONS §9). */
1188
+ declare const RECOMMENDED_MAX_PANES: Readonly<Record<WindowWidthSizeClass, number>>;
1189
+ interface ThreePaneScaffoldDirectiveOptions {
1190
+ /** Default `recommended`; `compose` keeps calculatePaneScaffoldDirective's counts. */
1191
+ paneRule?: PaneRule | undefined;
1192
+ isTabletop?: boolean | undefined;
1193
+ }
1194
+ /**
1195
+ * paneScaffoldDirective (calculatePaneScaffoldDirective) with the `paneRule` cap applied: capped by
1196
+ * RECOMMENDED_MAX_PANES unless `paneRule` is `compose`.
1197
+ */
1198
+ declare function threePaneScaffoldDirective(sizeClass: WindowSizeClass, options?: ThreePaneScaffoldDirectiveOptions): PaneScaffoldDirective;
1199
+ /** BackNavigationBehavior (BackNavigationBehavior.kt L40-75). */
1200
+ type BackNavigationBehavior = 'pop-latest' | 'pop-until-scaffold-value-change' | 'pop-until-current-destination-change' | 'pop-until-content-change';
1201
+ interface ThreePaneScaffoldNavigatorOptions<T> {
1202
+ scaffoldDirective: PaneScaffoldDirective;
1203
+ adaptStrategies: ThreePaneScaffoldAdaptStrategies;
1204
+ /** Default `true` (rememberListDetailPaneScaffoldNavigator). */
1205
+ isDestinationHistoryAware?: boolean | undefined;
1206
+ /** Default: the list pane (list-detail) or main pane (supporting pane); see the defaults below. */
1207
+ initialDestinationHistory: readonly ThreePaneScaffoldDestinationItem<T>[];
1208
+ }
1209
+ /** DefaultListDetailPaneHistory (ThreePaneScaffoldNavigator.kt L536-537): the list. */
1210
+ declare const LIST_DETAIL_INITIAL_HISTORY: readonly ThreePaneScaffoldDestinationItem<never>[];
1211
+ /** DefaultSupportingPaneHistory (L540-541): the main pane. */
1212
+ declare const SUPPORTING_PANE_INITIAL_HISTORY: readonly ThreePaneScaffoldDestinationItem<never>[];
1213
+ /**
1214
+ * DefaultThreePaneScaffoldNavigator (ThreePaneScaffoldNavigator.kt L359-490) without Compose's
1215
+ * transition state: navigateTo / navigateBack change the history and the value at once; the
1216
+ * caller animates (and Compose's directive change snaps, L349-354: so does setting
1217
+ * `scaffoldDirective` here). Content keys compare with Object.is (Kotlin `equals` for data
1218
+ * classes: use primitives or shared objects).
1219
+ */
1220
+ declare class ThreePaneScaffoldNavigator<T = unknown> {
1221
+ #private;
1222
+ constructor(options: ThreePaneScaffoldNavigatorOptions<T>);
1223
+ get scaffoldDirective(): PaneScaffoldDirective;
1224
+ set scaffoldDirective(directive: PaneScaffoldDirective);
1225
+ get adaptStrategies(): ThreePaneScaffoldAdaptStrategies;
1226
+ set adaptStrategies(strategies: ThreePaneScaffoldAdaptStrategies);
1227
+ get isDestinationHistoryAware(): boolean;
1228
+ set isDestinationHistoryAware(aware: boolean);
1229
+ /** The destination history, oldest first. */
1230
+ get destinationHistory(): readonly ThreePaneScaffoldDestinationItem<T>[];
1231
+ get currentDestination(): ThreePaneScaffoldDestinationItem<T> | null;
1232
+ get scaffoldValue(): ThreePaneScaffoldValue;
1233
+ /** Calls `listener` after every change of the history or the value; returns the unsubscriber. */
1234
+ subscribe(listener: () => void): () => void;
1235
+ peekPreviousScaffoldValue(behavior?: BackNavigationBehavior): ThreePaneScaffoldValue;
1236
+ navigateTo(pane: ThreePaneScaffoldRole, contentKey?: T): void;
1237
+ canNavigateBack(behavior?: BackNavigationBehavior): boolean;
1238
+ /** Returns true when there was a destination to go back to (else the history is cleared). */
1239
+ navigateBack(behavior?: BackNavigationBehavior): boolean;
1240
+ }
1241
+ /** A pane's bounds in the scaffold, CSS px, physical (x from the left edge). */
1242
+ interface PaneRect {
1243
+ readonly x: number;
1244
+ readonly y: number;
1245
+ readonly width: number;
1246
+ readonly height: number;
1247
+ }
1248
+ /** PaneExpansionState as the layout reads it (all CSS px). */
1249
+ interface PaneExpansionLayout {
1250
+ /** currentDraggingOffset: the handle's centre while dragging or settling. */
1251
+ readonly draggingOffset?: number | undefined;
1252
+ /** firstPaneWidth: a resting split (set from an anchor or a released drag). */
1253
+ readonly firstPaneWidth?: number | undefined;
1254
+ }
1255
+ interface ThreePaneScaffoldLayoutInput {
1256
+ readonly width: number;
1257
+ readonly height: number;
1258
+ readonly directive: PaneScaffoldDirective;
1259
+ readonly value: ThreePaneScaffoldValue;
1260
+ /** Start to end, already mirrored for RTL (physical left to right). */
1261
+ readonly order: readonly ThreePaneScaffoldRole[];
1262
+ readonly adaptStrategies: ThreePaneScaffoldAdaptStrategies;
1263
+ /** Panes that exist (a scaffold without an extra pane has no tertiary pane). Default: all. */
1264
+ readonly present?: readonly ThreePaneScaffoldRole[] | undefined;
1265
+ /** PaneScaffoldScope.preferredWidth per pane (px); default the directive's. */
1266
+ readonly preferredWidths?: Partial<Record<ThreePaneScaffoldRole, number>> | undefined;
1267
+ /** PaneScaffoldScope.preferredHeight per pane (px); default the directive's. */
1268
+ readonly preferredHeights?: Partial<Record<ThreePaneScaffoldRole, number>> | undefined;
1269
+ readonly expansion?: PaneExpansionLayout | undefined;
1270
+ }
1271
+ interface ThreePaneScaffoldLayout {
1272
+ /** Bounds of the expanded and reflowed panes (a collapsed pane of a split has width 0). */
1273
+ readonly panes: Partial<Record<ThreePaneScaffoldRole, PaneRect>>;
1274
+ /** The drag handle's centre x when exactly two panes are expanded, else null. */
1275
+ readonly handleOffset: number | null;
1276
+ }
1277
+ /** ThreePaneContentMeasurePolicy.measure (ThreePaneScaffold.kt L256-594), no hinges. */
1278
+ declare function threePaneScaffoldLayout(input: ThreePaneScaffoldLayoutInput): ThreePaneScaffoldLayout;
1279
+ /** PaneMotion (PaneMotion.kt L556-632; EnterAsModal / ExitAsModal belong to Levitate). */
1280
+ type PaneMotion = 'none' | 'animate-bounds' | 'enter-from-left' | 'enter-from-right' | 'enter-from-left-delayed' | 'enter-from-right-delayed' | 'exit-to-left' | 'exit-to-right' | 'enter-with-expand' | 'exit-with-shrink';
1281
+ /** calculatePaneMotion (PaneMotion.kt L636-750) for the panes in `order` (physical, LTR). */
1282
+ declare function calculatePaneMotion(previous: ThreePaneScaffoldValue, current: ThreePaneScaffoldValue, order: readonly ThreePaneScaffoldRole[]): Record<ThreePaneScaffoldRole, PaneMotion>;
1283
+ /** Where each pane animates from and to for a motion (the default enter / exit transitions). */
1284
+ interface PaneTransition {
1285
+ readonly motion: PaneMotion;
1286
+ readonly from: PaneRect;
1287
+ readonly to: PaneRect;
1288
+ /** EnterFrom*Delayed: DelayedSpringSpec's delayedRatio (PaneMotionDefaults L167-173). */
1289
+ readonly delayed: boolean;
1290
+ }
1291
+ /** PaneMotionDefaults.DelayedAnimationSpec's delayedRatio (PaneMotion.kt L171). */
1292
+ declare const PANE_MOTION_DELAYED_RATIO = 0.1;
1293
+ /**
1294
+ * calculateDefaultEnterTransition / calculateDefaultExitTransition (PaneMotion.kt L425-476) with
1295
+ * the slide offsets (L276-414): `origin` holds the bounds before the change (the panes shown
1296
+ * then), `target` the bounds after it, both from threePaneScaffoldLayout. Entering panes slide (or
1297
+ * expand) from outside to `target`; exiting panes slide (or shrink) from `origin` out; panes shown
1298
+ * before and after animate their bounds.
1299
+ */
1300
+ declare function paneTransitions(motions: Readonly<Record<ThreePaneScaffoldRole, PaneMotion>>, order: readonly ThreePaneScaffoldRole[], origin: Partial<Record<ThreePaneScaffoldRole, PaneRect>>, target: Partial<Record<ThreePaneScaffoldRole, PaneRect>>, scaffoldWidth: number): Partial<Record<ThreePaneScaffoldRole, PaneTransition>>;
1301
+ /** PaneExpansionAnchor: Proportion, Offset.fromStart or Offset.fromEnd (px). */
1302
+ type PaneExpansionAnchor = {
1303
+ readonly proportion: number;
1304
+ } | {
1305
+ readonly offsetFromStart: number;
1306
+ } | {
1307
+ readonly offsetFromEnd: number;
1308
+ };
1309
+ /**
1310
+ * The samples' anchors (ThreePaneScaffoldSample.kt L1102-1109): 0 %, 240dp from the start, 50 %,
1311
+ * 240dp from the end, 100 %. Compose's own default is no anchors.
1312
+ */
1313
+ declare const PANE_EXPANSION_SAMPLE_ANCHORS: readonly PaneExpansionAnchor[];
1314
+ /** PaneExpansionState.AnchoringVelocityThreshold (px/s, L648). */
1315
+ declare const PANE_EXPANSION_ANCHORING_VELOCITY_THRESHOLD = 200;
1316
+ /** PaneExpansionAnchor.positionIn (L700-712, L754-755, L835-856): the handle's centre x. */
1317
+ declare function paneExpansionAnchorPosition(anchor: PaneExpansionAnchor, width: number, rtl?: boolean): number;
1318
+ /**
1319
+ * The anchor a release settles to (getPositionOfTheClosestAnchor, L610-646): the closest one, or
1320
+ * with |velocity| ≥ 200 px/s the closest in the direction of the fling (the closest overall when
1321
+ * none lies that way). Returns the index into `anchors`, or -1 without anchors. Compose first runs
1322
+ * the fling's decay and settles from where it stops; this picks from the release position.
1323
+ */
1324
+ declare function closestPaneExpansionAnchor(anchors: readonly PaneExpansionAnchor[], width: number, position: number, velocity: number, rtl?: boolean): number;
1325
+ /**
1326
+ * PaneExpansionState.nextAnchor (L345-366): the first anchor (by position) right of `position`,
1327
+ * wrapping to the leftmost. The drag handle's click action moves there. -1 without anchors.
1328
+ */
1329
+ declare function nextPaneExpansionAnchor(anchors: readonly PaneExpansionAnchor[], width: number, position: number, rtl?: boolean): number;
1330
+ /** PaneMotionDefaults' IntRect / IntOffset visibility threshold (PaneMotion.kt L148): 1px. */
1331
+ declare const PANE_MOTION_VISIBILITY_THRESHOLD = 1;
1332
+ interface ThreePaneScaffoldSample {
1333
+ /** The animated bounds of every pane in the transition (entering, shown, exiting). */
1334
+ readonly panes: Partial<Record<ThreePaneScaffoldRole, PaneRect>>;
1335
+ readonly running: boolean;
1336
+ }
1337
+ /**
1338
+ * The pane transitions of one scaffold change, driven by the caller's clock (ms): each pane's
1339
+ * bounds run on PaneMotionDefaults.AnimationSpec (spring 0.8 / 380 at a 1px threshold, each
1340
+ * component on its own, as Compose's IntRect / IntOffset springs), EnterFrom*Delayed after 10 % of
1341
+ * that spring's duration (DelayedSpringSpec, PaneMotion.kt L822-908). A new `start` mid-flight
1342
+ * continues every pane still in the transition from its current bounds and velocity. `spec` null
1343
+ * (reduced motion) jumps to the end.
1344
+ */
1345
+ declare class ThreePaneScaffoldAnimation {
1346
+ #private;
1347
+ start(transitions: Partial<Record<ThreePaneScaffoldRole, PaneTransition>>, spec: SpringSpec | null, now: number): void;
1348
+ /** Jumps every pane to its target. */
1349
+ finish(): void;
1350
+ sample(now: number): ThreePaneScaffoldSample;
1351
+ }
1352
+
1353
+ export { type AdaptStrategy, AmplitudeAnimation, type AmplitudeTween, type AppBarScrollBehavior, type AppBarScrollState, type BackNavigationBehavior, type ButtonGroupItemSize, type CircularIndeterminateFrame, type CircularIndeterminateTiming, DEFAULT_DISPLACEMENT_THRESHOLD, DRAWER_POSITIONAL_THRESHOLD, DRAWER_SETTLE_MILLIS, DRAWER_VELOCITY_THRESHOLD, DrawerAnimation, type DrawerSample, type DrawerSpecs, type Easing, FAST_OUT_LINEAR_IN_EASING, type FloatingToolbarExitDirection, type FloatingToolbarScrollState, type IndeterminateFrame, LIST_DETAIL_ADAPT_STRATEGIES, LIST_DETAIL_INITIAL_HISTORY, LIST_DETAIL_PANE_ORDER, type LinearEasing, type LinearEasingOptions, type LinearIndeterminateTiming, ListDetailPaneScaffoldRole, type LoadingIndicatorTiming, MODAL_RAIL_EXPANDED_PROGRESS, type MenuAnchorPosition, type MenuPositionInput, type MenuPositionResult, type MenuRect, type Motion, NAVIGATION_SUITE_EXPANDED_FROM, NAVIGATION_SUITE_TYPES, type NavigationOrientation, type NavigationSuiteSample, NavigationSuiteScaffoldAnimation, type NavigationSuiteType, type NavigationSuiteTypeOptions, PANE_EXPANSION_ANCHORING_VELOCITY_THRESHOLD, PANE_EXPANSION_SAMPLE_ANCHORS, PANE_MOTION_DELAYED_RATIO, PANE_MOTION_VISIBILITY_THRESHOLD, type PaneAdaptedValue, type PaneExpansionAnchor, type PaneExpansionLayout, type PaneMotion, type PaneRect, type PaneRule, type PaneScaffoldDirective, type PaneTransition, RECOMMENDED_MAX_PANES, SEARCH_BAR_EXPANDED_THRESHOLD, SEARCH_DROPDOWN_VISIBLE_PROGRESS, SLIDER_KEY_DIVISIONS, SLIDER_PAGE_DIVISOR, SLIDER_PAGE_MAX_STEPS, SUPPORTING_PANE_ADAPT_STRATEGIES, SUPPORTING_PANE_INITIAL_HISTORY, SUPPORTING_PANE_ORDER, SearchBarAnimation, type SearchBarSample, type SearchBarSpecs, type SearchRect, type SearchViewFrame, type SearchViewInput, type SearchViewMetrics, type SearchViewVariant, type SliderKeyAction, type SliderKeyOptions, type SliderThumbBounds, type SliderTick, type SliderTrackGeometry, type SliderTrackInput, type SliderTrackPart, type SliderTrackPartKind, SpringAnimatable, SpringSimulation, type SpringSpec, SupportingPaneScaffoldRole, TAB_INDICATOR_MIN_WIDTH, THREE_PANE_SCAFFOLD_ROLES, TOP_TITLE_ALPHA_EASING, TYPEAHEAD_TIMEOUT_MS, TabIndicatorAnimation, type TabIndicatorSample, type TabMeasure, type TabPosition, type TabRowVariant, TabScrollAnimation, type ThreePaneScaffoldAdaptStrategies, ThreePaneScaffoldAnimation, type ThreePaneScaffoldDestinationItem, type ThreePaneScaffoldDirectiveOptions, type ThreePaneScaffoldLayout, type ThreePaneScaffoldLayoutInput, ThreePaneScaffoldNavigator, type ThreePaneScaffoldNavigatorOptions, type ThreePaneScaffoldRole, type ThreePaneScaffoldSample, type ThreePaneScaffoldValue, type ToolbarExpansionScroll, type ToolbarOrientation, TweenAnimatable, type TweenSpec, type TwoRowsFrame, WINDOW_HEIGHT_BREAKPOINTS, WINDOW_WIDTH_BREAKPOINTS, WideNavigationRailAnimation, type WideNavigationRailAnimationOptions, type WideNavigationRailMetrics, type WideNavigationRailSample, type WideNavigationRailSpecs, type WideNavigationRailWidthInput, type WindowHeightSizeClass, type WindowPostureOptions, type WindowSizeClass, type WindowSizeClassOptions, type WindowWidthSizeClass, animatedInt, appBarScrollState, buttonGroupVisibleCount, buttonGroupWidths, calculatePaneMotion, calculateThreePaneScaffoldValue, circularIndeterminateFrame, closestPaneExpansionAnchor, collapsedFraction, cubicBezier, dampingCoefficient, dampingRatioFromCoefficient, drawerSettlesOpen, estimateAnimationDurationMillis, estimateAnimationDurationMillisDouble, expandedPanes, exponentialDecayTarget, fabMenuItemVisible, floatingToolbarScrollState, indeterminateFrame, indicatorAmplitude, initialIndeterminateFrame, isAtLeastBreakpoint, isHeightAtLeastBreakpoint, isNavigationBarType, isScrolledUnder, isWidthAtLeastBreakpoint, linearIndeterminateFractions, menuNavigationTarget, menuPosition, menuTransformOrigin, morphSpringDurationMillis, navigationSuiteOffset, navigationSuiteType, nextPaneExpansionAnchor, overlappedFraction, paneExpansionAnchorPosition, paneScaffoldDirective, paneTransitions, parseCubicBezier, sameThreePaneScaffoldValue, sameWindowSizeClass, scrollAppBar, scrollFloatingToolbar, scrollToolbarExpansion, scrollableTabOffset, searchNavigationTarget, searchViewFrame, settleTarget, sliderClosestThumb, sliderFraction, sliderKeyAction, sliderKeyDelta, sliderKeyValue, sliderPageSteps, sliderSnap, sliderSteps, sliderThumbBounds, sliderThumbValue, sliderTickFractions, sliderTrackGeometry, sliderValueAt, springDurationMillis, springToLinear, springValue, springVelocity, tabIndicatorShift, tabIndicatorTarget, tabPositions, threePaneScaffoldDirective, threePaneScaffoldLayout, toolbarCollapsedFraction, toolbarExpansionScroll, toolbarNavigationTarget, toolbarSettleTarget, twoRowsFrame, typeSelectTarget, waveOffset, waveTravelMillis, wideNavigationRailItemWidth, wideNavigationRailWidth, windowHeightSizeClass, windowSizeClass, windowWidthSizeClass, withHeight, withHeightOffset, withToolbarOffset, withToolbarOffsetLimit };