@orioncactuscorp/ui 1.17.0 → 1.18.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/CHANGELOG.md +91 -0
- package/README.md +16 -14
- package/dist/components/BackgroundIconButton/BackgroundIconButton.css +1 -1
- package/dist/components/Modal/Modal.css +1 -1
- package/dist/components/Modal/Modal.js +514 -471
- package/dist/components/Modal/Modal.module.scss.js +59 -57
- package/dist/components/Modal/fieldReveal.js +57 -0
- package/dist/components/Modal/headerTapScroll.js +10 -0
- package/dist/components/Modal/keyboardEditable.js +31 -0
- package/dist/components/Modal/keyboardInsetMemory.js +24 -0
- package/dist/components/Modal/keyboardSession.js +46 -73
- package/dist/components/Modal/scrollportScroller.js +43 -0
- package/dist/components/Modal/tapCaret.js +32 -0
- package/dist/components/Modal/useBottomSheetIntrinsicHeight.js +26 -23
- package/dist/components/Modal/useFieldReveal.js +81 -0
- package/dist/components/Modal/useModalDrag.js +1025 -977
- package/dist/components/Modal/useModalKeyboardAvoidance.js +200 -117
- package/dist/components/Modal/useModalViewportGeometry.js +35 -19
- package/dist/components/PositionSnap/policy.js +40 -43
- package/dist/styles.css +2 -2
- package/dist/ui/src/components/Modal/Modal.d.ts +1 -1
- package/dist/ui/src/components/Modal/Modal.d.ts.map +1 -1
- package/dist/ui/src/components/Modal/Modal.test.utils.d.ts +12 -0
- package/dist/ui/src/components/Modal/Modal.test.utils.d.ts.map +1 -0
- package/dist/ui/src/components/Modal/contexts.d.ts +5 -0
- package/dist/ui/src/components/Modal/contexts.d.ts.map +1 -1
- package/dist/ui/src/components/Modal/fieldReveal.d.ts +18 -0
- package/dist/ui/src/components/Modal/fieldReveal.d.ts.map +1 -0
- package/dist/ui/src/components/Modal/headerTapScroll.d.ts +5 -0
- package/dist/ui/src/components/Modal/headerTapScroll.d.ts.map +1 -0
- package/dist/ui/src/components/Modal/keyboardEditable.d.ts +6 -0
- package/dist/ui/src/components/Modal/keyboardEditable.d.ts.map +1 -0
- package/dist/ui/src/components/Modal/keyboardInsetMemory.d.ts +5 -0
- package/dist/ui/src/components/Modal/keyboardInsetMemory.d.ts.map +1 -0
- package/dist/ui/src/components/Modal/keyboardSession.d.ts +4 -11
- package/dist/ui/src/components/Modal/keyboardSession.d.ts.map +1 -1
- package/dist/ui/src/components/Modal/scrollportScroller.d.ts +20 -0
- package/dist/ui/src/components/Modal/scrollportScroller.d.ts.map +1 -0
- package/dist/ui/src/components/Modal/tapCaret.d.ts +10 -0
- package/dist/ui/src/components/Modal/tapCaret.d.ts.map +1 -0
- package/dist/ui/src/components/Modal/useBottomSheetIntrinsicHeight.d.ts +8 -1
- package/dist/ui/src/components/Modal/useBottomSheetIntrinsicHeight.d.ts.map +1 -1
- package/dist/ui/src/components/Modal/useFieldReveal.d.ts +28 -0
- package/dist/ui/src/components/Modal/useFieldReveal.d.ts.map +1 -0
- package/dist/ui/src/components/Modal/useModalDrag.d.ts.map +1 -1
- package/dist/ui/src/components/Modal/useModalKeyboardAvoidance.d.ts +6 -1
- package/dist/ui/src/components/Modal/useModalKeyboardAvoidance.d.ts.map +1 -1
- package/dist/ui/src/components/Modal/useModalViewportGeometry.d.ts +1 -0
- package/dist/ui/src/components/Modal/useModalViewportGeometry.d.ts.map +1 -1
- package/dist/ui/src/components/PositionSnap/policy.d.ts.map +1 -1
- package/dist/ui/src/utils/gesture.d.ts +58 -0
- package/dist/ui/src/utils/gesture.d.ts.map +1 -0
- package/dist/utils/gesture.d.ts +2 -0
- package/dist/utils/gesture.js +103 -0
- package/docs/gesture.md +64 -0
- package/docs/selector-contract.md +5 -1
- package/docs/spring.md +4 -0
- package/package.json +5 -1
|
@@ -2,7 +2,7 @@ import { ModalBodyProps, ModalCloseProps, ModalContentProps, ModalFooterProps, M
|
|
|
2
2
|
export declare function ModalRoot({ children, open, defaultOpen, modal, onOpenChange, onOpenChangeComplete, canCloseAttempt: canCloseAttemptProp, onCloseAttempt, presentationState: presentationStateProp, defaultPresentationState, onPresentationStateChange, disablePointerDismissal, navigationDepth, dismissBehavior, }: ModalRootProps): import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
export declare function ModalTrigger({ className, children, render, nativeButton, }: ModalTriggerProps): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
export declare function ModalContent({ className, children, variant, size, resize, contentTransition, backdrop, backdropFrom, drag, peekable, snapPoints, defaultSnapPoint, snapPositions, defaultSnapPosition, initialFocus, peekHeight, closeThreshold, scrollLockTimeout, container, style, ...props }: ModalContentProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
-
export declare function ModalHeader({ className, title, children, leadingContent, trailingContent, bottomContent, closeLabel, closeButton, handle, ref, ...props }: ModalHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function ModalHeader({ className, title, children, leadingContent, trailingContent, bottomContent, closeLabel, closeButton, handle, onClick, ref, ...props }: ModalHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
export declare function ModalNavigationSection({ handle, ...props }: ModalNavigationSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
7
7
|
export declare function ModalBody({ className, children, layout, containerClassName, containerProps, ref, ...props }: ModalBodyProps): import("react/jsx-runtime").JSX.Element;
|
|
8
8
|
export declare function ModalFooter({ className, children, background, ref, ...props }: ModalFooterProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/Modal.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/Modal.tsx"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EACV,cAAc,EAId,eAAe,EAEf,iBAAiB,EAGjB,gBAAgB,EAChB,gBAAgB,EAChB,2BAA2B,EAG3B,cAAc,EAEd,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAmNjB,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,KAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,eAAe,EAAE,mBAAmB,EACpC,cAAc,EACd,iBAAiB,EAAE,qBAAqB,EACxC,wBAAoC,EACpC,yBAAyB,EACzB,uBAAuB,EACvB,eAAmB,EACnB,eAAe,GAChB,EAAE,cAAc,2CAyOhB;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAc,EACd,QAAQ,EACR,MAAM,EACN,YAAY,GACb,EAAE,iBAAiB,2CAsBnB;AAED,wBAAgB,YAAY,CAAC,EAC3B,SAAc,EACd,QAAQ,EACR,OAAoB,EACpB,IAAe,EACf,MAAkB,EAClB,iBAA0B,EAC1B,QAAiB,EACjB,YAAY,EACZ,IAAgB,EAChB,QAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,iBAAiB,2CA0mBnB;AAED,wBAAgB,WAAW,CAAC,EAC1B,SAAc,EACd,KAAK,EACL,QAAQ,EACR,cAAc,EACd,eAAe,EACf,aAAa,EACb,UAAiB,EACjB,WAAkB,EAClB,MAAa,EACb,OAAO,EACP,GAAG,EACH,GAAG,KAAK,EACT,EAAE,gBAAgB,2CAmFlB;AAED,wBAAgB,sBAAsB,CAAC,EACrC,MAAa,EACb,GAAG,KAAK,EACT,EAAE,2BAA2B,2CAiB7B;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAc,EACd,QAAQ,EACR,MAAkB,EAClB,kBAAuB,EACvB,cAAc,EACd,GAAG,EACH,GAAG,KAAK,EACT,EAAE,cAAc,2CA2BhB;AAED,wBAAgB,WAAW,CAAC,EAC1B,SAAc,EACd,QAAQ,EACR,UAAmB,EACnB,GAAG,EACH,GAAG,KAAK,EACT,EAAE,gBAAgB,2CAsBlB;AAED,wBAAgB,UAAU,CAAC,EACzB,SAAc,EACd,QAA6B,EAC7B,KAAY,EACZ,IAAS,EACT,QAAQ,EACR,OAAO,EACP,GAAG,KAAK,EACT,EAAE,eAAe,2CAsBjB;AAED,QAAA,MAAM,KAAK;;;;;;;;;CAST,CAAC;AAEH,eAAe,KAAK,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const MODAL_SPRING_SETTLE_WAIT_OPTIONS: {
|
|
2
|
+
readonly timeout: 10000;
|
|
3
|
+
};
|
|
4
|
+
export declare function mockClientRect(element: HTMLElement, { top, bottom }: {
|
|
5
|
+
top: number;
|
|
6
|
+
bottom: number;
|
|
7
|
+
}): void;
|
|
8
|
+
export declare function mockKeyboardScrollTo(body: HTMLElement, { maxScrollTop }?: {
|
|
9
|
+
maxScrollTop?: number;
|
|
10
|
+
}): import('vitest').Mock<(options: ScrollToOptions) => void>;
|
|
11
|
+
export declare function installTestResizeObserver(callbacks: ResizeObserverCallback[]): () => void;
|
|
12
|
+
//# sourceMappingURL=Modal.test.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Modal.test.utils.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/Modal.test.utils.tsx"],"names":[],"mappings":"AAKA,eAAO,MAAM,gCAAgC;;CAA+B,CAAC;AAE7E,wBAAgB,cAAc,CAC5B,OAAO,EAAE,WAAW,EACpB,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,QAajD;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,WAAW,EACjB,EAAE,YAAuC,EAAE,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAO,mCAS1C,eAAe,WAUjD;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,sBAAsB,EAAE,cAgC5E"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ModalCloseAttemptDetails, ModalPlacement, ModalPresentationState } from './types';
|
|
2
2
|
import { ModalScrollState } from './modalScrollArbitration';
|
|
3
|
+
import { ScrollportScroller } from './scrollportScroller';
|
|
3
4
|
export interface ModalContextValue {
|
|
4
5
|
open: boolean;
|
|
5
6
|
modal: boolean | 'trap-focus';
|
|
@@ -22,6 +23,9 @@ export interface ModalContextValue {
|
|
|
22
23
|
setCanPeek: (canPeek: boolean) => void;
|
|
23
24
|
canRenderHandle: boolean;
|
|
24
25
|
setCanRenderHandle: (canRenderHandle: boolean) => void;
|
|
26
|
+
/** The handle area is an interactive sheet chrome target when dragging is enabled. */
|
|
27
|
+
handleDraggable: boolean;
|
|
28
|
+
setHandleDraggable: (handleDraggable: boolean) => void;
|
|
25
29
|
popupSnapLayoutVersion: number;
|
|
26
30
|
notifyPopupSnapLayoutChange: () => void;
|
|
27
31
|
navigationDepth: number;
|
|
@@ -33,6 +37,7 @@ export interface ModalContextValue {
|
|
|
33
37
|
setFooterNode: (node: HTMLElement | null) => void;
|
|
34
38
|
bodyNode: HTMLElement | null;
|
|
35
39
|
setBodyNode: (node: HTMLElement | null) => void;
|
|
40
|
+
bodyScroller: ScrollportScroller;
|
|
36
41
|
scrollState: ModalScrollState;
|
|
37
42
|
setScrollState: (state: ModalScrollState) => void;
|
|
38
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contexts.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/contexts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,wBAAwB,EACxB,cAAc,EACd,sBAAsB,EACvB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"contexts.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/contexts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,wBAAwB,EACxB,cAAc,EACd,sBAAsB,EACvB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,GAAG,YAAY,CAAC;IAC9B,SAAS,EAAE,cAAc,CAAC;IAC1B,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,iBAAiB,EAAE,sBAAsB,CAAC;IAC1C,oBAAoB,EAAE,CAAC,iBAAiB,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC1E,YAAY,EAAE,CACZ,OAAO,CAAC,EAAE,wBAAwB,EAClC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,KAClD,OAAO,CAAC;IACb,oBAAoB,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,OAAO,CAAC;IACtE,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,OAAO,CAAC;IACjE,uBAAuB,EAAE,MAAM,CAAC;IAChC,0BAA0B,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,IAAI,CAAC;IACzE,uBAAuB,EAAE,OAAO,CAAC;IACjC,4BAA4B,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1D,wBAAwB,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,CAAC,eAAe,EAAE,OAAO,KAAK,IAAI,CAAC;IACvD,sFAAsF;IACtF,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,CAAC,eAAe,EAAE,OAAO,KAAK,IAAI,CAAC;IACvD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,2BAA2B,EAAE,MAAM,IAAI,CAAC;IACxC,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAClD,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,aAAa,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAClD,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAEhD,YAAY,EAAE,kBAAkB,CAAC;IACjC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,cAAc,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACnD;AAID,eAAO,MAAM,aAAa,oDAAwB,CAAC;AAEnD,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,qBAUpD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const KEYBOARD_REVEAL_SCROLL_PADDING = 16;
|
|
2
|
+
export declare const KEYBOARD_REVEAL_LABEL_MAX_GAP = 48;
|
|
3
|
+
export declare function getKeyboardRevealRect({ labelRects, targetRect, }: {
|
|
4
|
+
labelRects: readonly Pick<DOMRect, 'top' | 'bottom'>[];
|
|
5
|
+
targetRect: Pick<DOMRect, 'top' | 'bottom'>;
|
|
6
|
+
}): Pick<DOMRect, 'top' | 'bottom'>;
|
|
7
|
+
export declare function getKeyboardRevealLabels(target: HTMLElement): HTMLElement[];
|
|
8
|
+
export declare function getKeyboardRevealTargetRect(target: HTMLElement): Pick<DOMRect, "bottom" | "top">;
|
|
9
|
+
export declare function parseScrollPadding(value: string | undefined): number;
|
|
10
|
+
export declare function getKeyboardRevealScrollDelta({ bodyRect, clearanceInset, footerHeight, revealed, scrollPaddingStart, targetRect, }: {
|
|
11
|
+
bodyRect: Pick<DOMRect, 'top' | 'bottom'>;
|
|
12
|
+
clearanceInset: number;
|
|
13
|
+
footerHeight: number;
|
|
14
|
+
revealed: boolean;
|
|
15
|
+
scrollPaddingStart: number;
|
|
16
|
+
targetRect: Pick<DOMRect, 'top' | 'bottom'>;
|
|
17
|
+
}): number;
|
|
18
|
+
//# sourceMappingURL=fieldReveal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldReveal.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/fieldReveal.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAMjD,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,UAAU,GACX,EAAE;IACD,UAAU,EAAE,SAAS,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,QAAQ,CAAC,EAAE,CAAC;IACvD,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;CAC7C,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,QAAQ,CAAC,CAgBlC;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,EAAE,CAsB1E;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,WAAW,mCAO9D;AAGD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,UAI3D;AAgBD,wBAAgB,4BAA4B,CAAC,EAC3C,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,kBAAkB,EAClB,UAAU,GACX,EAAE;IACD,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;IAC1C,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IAIrB,QAAQ,EAAE,OAAO,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,QAAQ,CAAC,CAAC;CAC7C,UAYA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headerTapScroll.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/headerTapScroll.ts"],"names":[],"mappings":"AASA,wBAAgB,8BAA8B,CAAC,EAC7C,SAAS,EACT,MAAM,GACP,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;CAC5B,WAEA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type KeyboardClass = 'numeric' | 'text';
|
|
2
|
+
export declare function isKeyboardEditable(target: EventTarget | null): target is HTMLElement;
|
|
3
|
+
export declare function getTapEditable(target: EventTarget | null): HTMLElement | null;
|
|
4
|
+
export declare function getKeyboardClass(target: HTMLElement): KeyboardClass;
|
|
5
|
+
export declare function hasSoftKeyboardEnvironment(targetWindow: Window): boolean;
|
|
6
|
+
//# sourceMappingURL=keyboardEditable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboardEditable.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/keyboardEditable.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,MAAM,CAAC;AAO/C,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,GAAG,IAAI,GACzB,MAAM,IAAI,WAAW,CAsBvB;AAKD,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,sBAQxD;AAID,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,aAAa,CAWnE;AAKD,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,MAAM,WAM9D"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { KeyboardClass } from './keyboardEditable';
|
|
2
|
+
export declare function recordMeasuredKeyboardInset(width: number, keyboardClass: KeyboardClass, inset: number): void;
|
|
3
|
+
export declare function getSeedKeyboardInset(width: number, keyboardClass: KeyboardClass): number | undefined;
|
|
4
|
+
export declare function resetModalKeyboardAvoidanceMemory(): void;
|
|
5
|
+
//# sourceMappingURL=keyboardInsetMemory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboardInsetMemory.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/keyboardInsetMemory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAexD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,MAAM,QASd;AAMD,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,aAAa,sBAiB7B;AAGD,wBAAgB,iCAAiC,SAEhD"}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { ModalViewportGeometry } from './useModalViewportGeometry';
|
|
2
|
+
import { KeyboardClass } from './keyboardEditable';
|
|
2
3
|
export declare const KEYBOARD_VIEWPORT_WIDTH_CHANGE_THRESHOLD = 80;
|
|
3
4
|
export declare const KEYBOARD_VIEWPORT_RESTORE_EPSILON = 2;
|
|
4
|
-
export declare const KEYBOARD_REVEAL_SCROLL_PADDING = 16;
|
|
5
|
-
export declare function recordMeasuredKeyboardInset(width: number, inset: number): void;
|
|
6
|
-
export declare function getSeedKeyboardInset(width: number): number | undefined;
|
|
7
|
-
export declare function resetModalKeyboardAvoidanceMemory(): void;
|
|
8
5
|
export type KeyboardSessionPhase = 'active' | 'closing';
|
|
9
6
|
export type KeyboardSession = {
|
|
10
7
|
baselineHeight: number;
|
|
11
8
|
baselineOffsetLeft: number;
|
|
12
9
|
baselineOffsetTop: number;
|
|
13
10
|
baselineWidth: number;
|
|
11
|
+
keyboardClass: KeyboardClass;
|
|
14
12
|
phase: KeyboardSessionPhase;
|
|
15
13
|
sawKeyboard: boolean;
|
|
16
14
|
target: HTMLElement | null;
|
|
@@ -18,9 +16,11 @@ export type KeyboardSession = {
|
|
|
18
16
|
export type KeyboardSessionEvent = {
|
|
19
17
|
type: 'focus';
|
|
20
18
|
geometry: ModalViewportGeometry;
|
|
19
|
+
keyboardClass: KeyboardClass;
|
|
21
20
|
target: HTMLElement;
|
|
22
21
|
} | {
|
|
23
22
|
type: 'retain';
|
|
23
|
+
keyboardClass: KeyboardClass;
|
|
24
24
|
target: HTMLElement;
|
|
25
25
|
} | {
|
|
26
26
|
type: 'close';
|
|
@@ -30,17 +30,10 @@ export type KeyboardSessionEvent = {
|
|
|
30
30
|
type: 'release';
|
|
31
31
|
};
|
|
32
32
|
export declare function keyboardSessionReducer(session: KeyboardSession | undefined, event: KeyboardSessionEvent): KeyboardSession | undefined;
|
|
33
|
-
export declare function isKeyboardEditable(target: EventTarget | null): target is HTMLElement;
|
|
34
33
|
export declare function isSessionGeometryCompatible(session: KeyboardSession | undefined, geometry: ModalViewportGeometry | undefined): boolean;
|
|
35
34
|
export declare function isSessionGeometryRestored(session: KeyboardSession, geometry: ModalViewportGeometry): boolean;
|
|
36
35
|
export declare function getKeyboardInset(session: KeyboardSession | undefined, geometry: ModalViewportGeometry | undefined): number;
|
|
37
36
|
export declare function getSessionStableViewportGeometry(session: KeyboardSession | undefined, geometry: ModalViewportGeometry | undefined): ModalViewportGeometry | undefined;
|
|
38
|
-
export declare function getKeyboardRevealScrollDelta({ bodyRect, clearanceInset, footerHeight, targetRect, }: {
|
|
39
|
-
bodyRect: Pick<DOMRect, 'top' | 'bottom'>;
|
|
40
|
-
clearanceInset: number;
|
|
41
|
-
footerHeight: number;
|
|
42
|
-
targetRect: Pick<DOMRect, 'top' | 'bottom'>;
|
|
43
|
-
}): number;
|
|
44
37
|
export declare function supportsTransitionSettleDetection(node: HTMLElement | null): node is HTMLElement;
|
|
45
38
|
export declare function hasRunningTransformTransition(node: HTMLElement): boolean;
|
|
46
39
|
//# sourceMappingURL=keyboardSession.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboardSession.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/keyboardSession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"keyboardSession.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/keyboardSession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,eAAO,MAAM,wCAAwC,KAAK,CAAC;AAC3D,eAAO,MAAM,iCAAiC,IAAI,CAAC;AAKnD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAExD,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IAEtB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,oBAAoB,CAAC;IAK5B,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAE5B;IACE,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,qBAAqB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,WAAW,CAAC;CACrB,GAGD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,aAAa,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAErE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GAEjB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GAGnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,KAAK,EAAE,oBAAoB,GAC1B,eAAe,GAAG,SAAS,CAuD7B;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,QAAQ,EAAE,qBAAqB,GAAG,SAAS,WAQ5C;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,qBAAqB,WAMhC;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,QAAQ,EAAE,qBAAqB,GAAG,SAAS,UAiB5C;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,QAAQ,EAAE,qBAAqB,GAAG,SAAS,GAC1C,qBAAqB,GAAG,SAAS,CAgBnC;AAED,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,WAAW,GAAG,IAAI,GACvB,IAAI,IAAI,WAAW,CAMrB;AAMD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,WAAW,WAS9D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface ScrollportScroller {
|
|
2
|
+
scrollTo: (scrollport: HTMLElement, top: number, options?: {
|
|
3
|
+
smooth?: boolean;
|
|
4
|
+
}) => void;
|
|
5
|
+
isRunning: () => boolean;
|
|
6
|
+
stop: () => void;
|
|
7
|
+
destroy: () => void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* One animated scroll at a time for a scrollport, shared by everything that
|
|
11
|
+
* moves it (the keyboard field reveal, the header tap to top) so a new move
|
|
12
|
+
* takes over the one in flight instead of fighting it.
|
|
13
|
+
*
|
|
14
|
+
* The sheet spring, not the platform's `behavior: 'smooth'`: that has a
|
|
15
|
+
* fixed easing of its own and no tie to the motion tokens, and the keyboard
|
|
16
|
+
* chases (footer lift, pan) are trimmed to iOS's keyboard animation, which
|
|
17
|
+
* is too short for a content scroll to read as anything but a jump.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createScrollportScroller(): ScrollportScroller;
|
|
20
|
+
//# sourceMappingURL=scrollportScroller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrollportScroller.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/scrollportScroller.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,kBAAkB;IAGjC,QAAQ,EAAE,CACR,UAAU,EAAE,WAAW,EACvB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAC3B,IAAI,CAAC;IACV,SAAS,EAAE,MAAM,OAAO,CAAC;IAGzB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,IAAI,kBAAkB,CAyD7D"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type TapCaret = {
|
|
2
|
+
kind: 'offset';
|
|
3
|
+
offset: number;
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'range';
|
|
6
|
+
range: Range;
|
|
7
|
+
};
|
|
8
|
+
export declare function captureTapCaret(target: HTMLElement, x: number, y: number): TapCaret | null;
|
|
9
|
+
export declare function restoreTapCaret(target: HTMLElement, caret: TapCaret | null): void;
|
|
10
|
+
//# sourceMappingURL=tapCaret.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tapCaret.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/tapCaret.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpC,wBAAgB,eAAe,CAC7B,MAAM,EAAE,WAAW,EACnB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,GACR,QAAQ,GAAG,IAAI,CAgCjB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,QAsB1E"}
|
|
@@ -6,14 +6,21 @@
|
|
|
6
6
|
* in the commit that changes `discreteKey` (a depth swap), so the drag hook's
|
|
7
7
|
* canvas settle starts in the same frame as the content. Later content-size
|
|
8
8
|
* changes arrive through the body content observer.
|
|
9
|
+
*
|
|
10
|
+
* While `frozen`, the resting height is held: a soft-keyboard session must
|
|
11
|
+
* not resize the sheet shell (the keyboard reserve lands as body padding and
|
|
12
|
+
* would otherwise read back as taller content, lifting the sheet top), so
|
|
13
|
+
* the keyboard is absorbed by the internal scroll inset alone and a content
|
|
14
|
+
* change during the session lands once the session releases.
|
|
9
15
|
*/
|
|
10
|
-
export declare function useBottomSheetIntrinsicHeight({ enabled, bodyNode, surfaceMotionNode, snapSheetHeight, viewportHeight, discreteKey, }: {
|
|
16
|
+
export declare function useBottomSheetIntrinsicHeight({ enabled, bodyNode, surfaceMotionNode, snapSheetHeight, viewportHeight, discreteKey, frozen, }: {
|
|
11
17
|
enabled: boolean;
|
|
12
18
|
bodyNode: HTMLElement | null;
|
|
13
19
|
surfaceMotionNode: HTMLElement | null;
|
|
14
20
|
snapSheetHeight: number | undefined;
|
|
15
21
|
viewportHeight: number;
|
|
16
22
|
discreteKey: unknown;
|
|
23
|
+
frozen?: boolean;
|
|
17
24
|
}): {
|
|
18
25
|
intrinsicSheetHeight: number;
|
|
19
26
|
shouldDeferSettle: () => boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBottomSheetIntrinsicHeight.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/useBottomSheetIntrinsicHeight.ts"],"names":[],"mappings":"AAsBA
|
|
1
|
+
{"version":3,"file":"useBottomSheetIntrinsicHeight.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/useBottomSheetIntrinsicHeight.ts"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,6BAA6B,CAAC,EAC5C,OAAO,EACP,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,WAAW,EACX,MAAc,GACf,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,WAAW,GAAG,IAAI,CAAC;IACtC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;;;EAuDA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ScrollportScroller } from './scrollportScroller';
|
|
2
|
+
export declare const KEYBOARD_INSET_SETTLED_PROPERTY = "--_-modal-keyboard-inset-settled";
|
|
3
|
+
interface UseFieldRevealOptions {
|
|
4
|
+
bodyNode: HTMLElement | null;
|
|
5
|
+
footerHeight: number;
|
|
6
|
+
onReserveRendered: (inset: number) => void;
|
|
7
|
+
scroller: ScrollportScroller;
|
|
8
|
+
viewportNode: HTMLElement | null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Moves the Modal body to reveal a focused field: instant alignment, the
|
|
12
|
+
* sheet-spring reveal, the pose held while iOS snapshots the focused field,
|
|
13
|
+
* and the early reserve write those need. The keyboard session owns when
|
|
14
|
+
* each runs; this hook only knows the scrollport.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useFieldReveal({ bodyNode, footerHeight, onReserveRendered, scroller, viewportNode, }: UseFieldRevealOptions): {
|
|
17
|
+
alignTarget: (target: HTMLElement, { clearanceInset, revealed, smooth, }: {
|
|
18
|
+
clearanceInset: number;
|
|
19
|
+
revealed: boolean;
|
|
20
|
+
smooth: boolean;
|
|
21
|
+
}) => boolean;
|
|
22
|
+
isRevealing: () => boolean;
|
|
23
|
+
poseTargetAtReveal: (target: HTMLElement, clearanceInset: number) => () => void;
|
|
24
|
+
renderReserve: (inset: number) => void;
|
|
25
|
+
stopReveal: () => void;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=useFieldReveal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFieldReveal.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/useFieldReveal.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAI/D,eAAO,MAAM,+BAA+B,qCACR,CAAC;AAErC,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAE7B,YAAY,EAAE,MAAM,CAAC;IAGrB,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAG3C,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EACR,YAAY,GACb,EAAE,qBAAqB;0BAqBV,WAAW,yCAKhB;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE;;iCAyD1D,WAAW,kBAAkB,MAAM;2BAxBJ,MAAM;;EA+DjD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModalDrag.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/useModalDrag.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useModalDrag.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/useModalDrag.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EACV,wBAAwB,EACxB,SAAS,EACT,cAAc,EACd,iBAAiB,EAClB,MAAM,SAAS,CAAC;AA23BjB,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,QAAQ,EACR,WAAgC,EAChC,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACvB,aAAoC,EACpC,mBAAmB,EACnB,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,WAAkB,EAClB,cAAsB,EACtB,gBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,cAAqB,EACrB,iBAAuB,EACvB,sBAA0B,GAC3B,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,cAAc,CAAC;IAC1B,gBAAgB,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACzD,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACpD,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,uBAAuB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,aAAa,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC7C,mBAAmB,CAAC,EAAE,iBAAiB,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,QAAQ,CAAC;IACxB,iBAAiB,EAAE,SAAS,GAAG,QAAQ,CAAC;IACxC,oBAAoB,EAAE,CAAC,iBAAiB,EAAE,SAAS,GAAG,QAAQ,KAAK,IAAI,CAAC;IACxE,YAAY,EAAE,CACZ,OAAO,CAAC,EAAE,wBAAwB,EAClC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,KAClD,OAAO,CAAC;IACb,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,OAAO,CAAC;IACjE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uBAAuB,CAAC,EAAE,MAAM,OAAO,CAAC;IACxC,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;;;+BA8vDW,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;+BA0OlC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;6BA+OlC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;iCAAlC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;sCAelC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC;8BAsLlC,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC;4BAuMhC,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC;;;EA0G3C"}
|
|
@@ -1,16 +1,21 @@
|
|
|
1
|
+
import { ScrollportScroller } from './scrollportScroller';
|
|
1
2
|
import { ModalViewportGeometry } from './useModalViewportGeometry';
|
|
2
3
|
interface UseModalKeyboardAvoidanceOptions {
|
|
3
4
|
bodyNode: HTMLElement | null;
|
|
4
5
|
enabled: boolean;
|
|
5
6
|
footerHeight: number;
|
|
7
|
+
scroller: ScrollportScroller;
|
|
6
8
|
surfaceNode: HTMLElement | null;
|
|
7
9
|
viewportGeometry: ModalViewportGeometry | undefined;
|
|
8
10
|
viewportNode: HTMLElement | null;
|
|
9
11
|
}
|
|
10
|
-
export declare function useModalKeyboardAvoidance({ bodyNode, enabled, footerHeight, surfaceNode, viewportGeometry, viewportNode, }: UseModalKeyboardAvoidanceOptions): {
|
|
12
|
+
export declare function useModalKeyboardAvoidance({ bodyNode, enabled, footerHeight, scroller, surfaceNode, viewportGeometry, viewportNode, }: UseModalKeyboardAvoidanceOptions): {
|
|
11
13
|
active: boolean;
|
|
14
|
+
closing: boolean;
|
|
15
|
+
footerHeight: number;
|
|
12
16
|
keyboardInset: number;
|
|
13
17
|
settledKeyboardInset: number;
|
|
18
|
+
shellHeld: boolean;
|
|
14
19
|
viewportGeometry: ModalViewportGeometry | undefined;
|
|
15
20
|
};
|
|
16
21
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModalKeyboardAvoidance.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/useModalKeyboardAvoidance.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useModalKeyboardAvoidance.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/useModalKeyboardAvoidance.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAsBxE,UAAU,gCAAgC;IACxC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,gBAAgB,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACpD,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;CAClC;AA2CD,wBAAgB,yBAAyB,CAAC,EACxC,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,YAAY,GACb,EAAE,gCAAgC;;;;;;;;EA0elC"}
|
|
@@ -4,6 +4,7 @@ export interface ModalViewportGeometry {
|
|
|
4
4
|
offsetTop: number;
|
|
5
5
|
width: number;
|
|
6
6
|
}
|
|
7
|
+
export declare function isPinchZoomedViewport(viewport: Pick<VisualViewport, 'scale'> | null | undefined): boolean;
|
|
7
8
|
export declare function getModalViewportGeometry(targetWindow: Window): ModalViewportGeometry;
|
|
8
9
|
export declare function useModalViewportGeometry(enabled: boolean): ModalViewportGeometry | undefined;
|
|
9
10
|
//# sourceMappingURL=useModalViewportGeometry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModalViewportGeometry.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/useModalViewportGeometry.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"useModalViewportGeometry.d.ts","sourceRoot":"","sources":["../../../../../src/components/Modal/useModalViewportGeometry.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAmBD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,WAS3D;AAQD,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,MAAM,GACnB,qBAAqB,CA2BvB;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,qCAgDxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../../../src/components/PositionSnap/policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../../../src/components/PositionSnap/policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,KAAK,kBAAkB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI,iBAAiB,GAAG;IAC1E,GAAG,EAAE,IAAI,CAAC;CACX,CAAC;AAUF,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,iBAAiB,UAGzB;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,SAAS,kBAAkB,EAClC,OAAO,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,iBAAiB,WAOtD;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,SAAS,kBAAkB,EAClC,EACA,YAAY,EACZ,QAAQ,EACR,OAAO,GACR,EAAE;IACD,YAAY,EAAE,iBAAiB,CAAC;IAChC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC;CAC7B,WAiCA;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,KAAK,EACL,IAAI,EACJ,OAAO,GACR,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC;IACzB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACxC;;;EAYA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export interface OcGestureDecelerationState {
|
|
2
|
+
/** Position in pixels. */
|
|
3
|
+
position: number;
|
|
4
|
+
/** Velocity in pixels per second. */
|
|
5
|
+
velocity: number;
|
|
6
|
+
}
|
|
7
|
+
export interface OcGestureDecelerationOptions {
|
|
8
|
+
/** Velocity retention per millisecond, strictly between 0 and 1. */
|
|
9
|
+
rate?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface OcGestureVelocitySample {
|
|
12
|
+
/** Monotonic time in milliseconds, in the same clock as read(now). */
|
|
13
|
+
time: number;
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
}
|
|
17
|
+
export interface OcGestureVelocity {
|
|
18
|
+
/** Pixels per second. */
|
|
19
|
+
x: number;
|
|
20
|
+
/** Pixels per second. */
|
|
21
|
+
y: number;
|
|
22
|
+
}
|
|
23
|
+
export interface OcGestureVelocityTrackerOptions {
|
|
24
|
+
windowMs?: number;
|
|
25
|
+
minimumSpanMs?: number;
|
|
26
|
+
/** Time since the last changed position before read returns zero. */
|
|
27
|
+
stopAfterMs?: number;
|
|
28
|
+
/** Per-axis speed limit in pixels per second. */
|
|
29
|
+
maxPxPerSecond?: number;
|
|
30
|
+
}
|
|
31
|
+
export interface OcGestureVelocityTracker {
|
|
32
|
+
push: (sample: OcGestureVelocitySample) => void;
|
|
33
|
+
read: (now: number) => OcGestureVelocity;
|
|
34
|
+
clear: () => void;
|
|
35
|
+
}
|
|
36
|
+
declare function rubberBand(offset: number, dimension: number, resistance?: number): number;
|
|
37
|
+
declare function rubberBandClamp(value: number, min: number, max: number, dimension: number, resistance?: number): number;
|
|
38
|
+
declare function decelerate(state: OcGestureDecelerationState, elapsedMs: number, options?: OcGestureDecelerationOptions): OcGestureDecelerationState;
|
|
39
|
+
declare function projectDeceleration(velocity: number, options?: OcGestureDecelerationOptions): number;
|
|
40
|
+
declare function projectFling(position: number, velocity: number, options?: OcGestureDecelerationOptions): number;
|
|
41
|
+
declare function isDecelerationAtRest(velocity: number, threshold?: number): boolean;
|
|
42
|
+
declare function createVelocityTracker({ windowMs, minimumSpanMs, stopAfterMs, maxPxPerSecond, }?: OcGestureVelocityTrackerOptions): OcGestureVelocityTracker;
|
|
43
|
+
/** Gesture math uses px, px/s, and explicit millisecond timestamps; no DOM or React runtime. */
|
|
44
|
+
export declare const ocGesture: Readonly<{
|
|
45
|
+
rubberBand: typeof rubberBand;
|
|
46
|
+
rubberBandClamp: typeof rubberBandClamp;
|
|
47
|
+
decelerationRates: Readonly<{
|
|
48
|
+
normal: 0.998;
|
|
49
|
+
fast: 0.99;
|
|
50
|
+
}>;
|
|
51
|
+
decelerate: typeof decelerate;
|
|
52
|
+
projectDeceleration: typeof projectDeceleration;
|
|
53
|
+
projectFling: typeof projectFling;
|
|
54
|
+
isDecelerationAtRest: typeof isDecelerationAtRest;
|
|
55
|
+
createVelocityTracker: typeof createVelocityTracker;
|
|
56
|
+
}>;
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=gesture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gesture.d.ts","sourceRoot":"","sources":["../../../../src/utils/gesture.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,0BAA0B;IACzC,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,4BAA4B;IAC3C,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,iBAAiB;IAChC,yBAAyB;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,yBAAyB;IACzB,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,IAAI,CAAC;IAChD,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,iBAAiB,CAAC;IACzC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AA8BD,iBAAS,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,SAAO,UAcvE;AAED,iBAAS,eAAe,CACtB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,UAAU,SAAO,UAalB;AAED,iBAAS,UAAU,CACjB,KAAK,EAAE,0BAA0B,EACjC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,4BAAiC,GACzC,0BAA0B,CAc5B;AAED,iBAAS,mBAAmB,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,4BAAiC,UAI3C;AAED,iBAAS,YAAY,CACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,4BAAiC,UAI3C;AAED,iBAAS,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,SAAK,WAI7D;AAED,iBAAS,qBAAqB,CAAC,EAC7B,QAAc,EACd,aAAiB,EACjB,WAAiB,EACjB,cAAqB,GACtB,GAAE,+BAAoC,GAAG,wBAAwB,CAkDjE;AAED,gGAAgG;AAChG,eAAO,MAAM,SAAS;;;;;;;;;;;;EASpB,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
function r(t, e) {
|
|
2
|
+
if (!Number.isFinite(e)) throw new TypeError(`${t} must be finite.`);
|
|
3
|
+
return e;
|
|
4
|
+
}
|
|
5
|
+
function m(t, e) {
|
|
6
|
+
if (r(t, e), e < 0) throw new RangeError(`${t} must be non-negative.`);
|
|
7
|
+
return e;
|
|
8
|
+
}
|
|
9
|
+
function f(t, e) {
|
|
10
|
+
if (m(t, e), e === 0) throw new RangeError(`${t} must be positive.`);
|
|
11
|
+
return e;
|
|
12
|
+
}
|
|
13
|
+
const b = Object.freeze({ normal: 0.998, fast: 0.99 });
|
|
14
|
+
function g({
|
|
15
|
+
rate: t = b.normal
|
|
16
|
+
}) {
|
|
17
|
+
if (r("rate", t), t <= 0 || t >= 1)
|
|
18
|
+
throw new RangeError("rate must be between 0 and 1.");
|
|
19
|
+
return Math.log(t);
|
|
20
|
+
}
|
|
21
|
+
function y(t, e, o = 0.55) {
|
|
22
|
+
if (r("offset", t), m("dimension", e), f("resistance", o), t === 0 || e === 0) return 0;
|
|
23
|
+
const u = Math.abs(t), n = u * o, s = n <= e ? n / (1 + n / e) : e / (1 + e / u / o);
|
|
24
|
+
return Math.sign(t) * s;
|
|
25
|
+
}
|
|
26
|
+
function x(t, e, o, u, n = 0.55) {
|
|
27
|
+
if (r("value", t), r("min", e), r("max", o), m("dimension", u), f("resistance", n), e > o) throw new RangeError("min must not exceed max.");
|
|
28
|
+
const s = Math.min(Math.max(t, e), o);
|
|
29
|
+
return r(
|
|
30
|
+
"result",
|
|
31
|
+
s + y(t - s, u, n)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
function d(t, e, o = {}) {
|
|
35
|
+
r("position", t.position), r("velocity", t.velocity), m("elapsedMs", e);
|
|
36
|
+
const u = g(o), n = e * u;
|
|
37
|
+
return {
|
|
38
|
+
position: r(
|
|
39
|
+
"result.position",
|
|
40
|
+
t.position + t.velocity / 1e3 * (Math.expm1(n) / u)
|
|
41
|
+
),
|
|
42
|
+
velocity: t.velocity * Math.exp(n)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function p(t, e = {}) {
|
|
46
|
+
return r("velocity", t), r("result", -(t / 1e3) / g(e));
|
|
47
|
+
}
|
|
48
|
+
function M(t, e, o = {}) {
|
|
49
|
+
return r("position", t), r("result", t + p(e, o));
|
|
50
|
+
}
|
|
51
|
+
function R(t, e = 10) {
|
|
52
|
+
return r("velocity", t), f("threshold", e), Math.abs(t) < e;
|
|
53
|
+
}
|
|
54
|
+
function E({
|
|
55
|
+
windowMs: t = 100,
|
|
56
|
+
minimumSpanMs: e = 8,
|
|
57
|
+
stopAfterMs: o = 100,
|
|
58
|
+
maxPxPerSecond: u = 4e3
|
|
59
|
+
} = {}) {
|
|
60
|
+
if (f("windowMs", t), f("minimumSpanMs", e), f("stopAfterMs", o), f("maxPxPerSecond", u), e > t)
|
|
61
|
+
throw new RangeError("minimumSpanMs must not exceed windowMs.");
|
|
62
|
+
let n = [], s;
|
|
63
|
+
const h = (i) => Math.min(Math.max(i, -u), u);
|
|
64
|
+
return {
|
|
65
|
+
push(i) {
|
|
66
|
+
r("time", i.time), r("x", i.x), r("y", i.y);
|
|
67
|
+
const c = n.at(-1);
|
|
68
|
+
if (c && i.time < c.time)
|
|
69
|
+
throw new RangeError("Samples must be chronological.");
|
|
70
|
+
(!c || i.x !== c.x || i.y !== c.y) && (s = i.time), c?.time === i.time && n.pop(), n = n.filter((a) => a.time >= i.time - t), n.push({ ...i });
|
|
71
|
+
},
|
|
72
|
+
read(i) {
|
|
73
|
+
r("now", i);
|
|
74
|
+
const c = n.at(-1);
|
|
75
|
+
if (c && i < c.time)
|
|
76
|
+
throw new RangeError("now must not precede the latest sample.");
|
|
77
|
+
const a = n.find((w) => w.time >= i - t);
|
|
78
|
+
if (!a || !c || s === void 0 || i - s >= o || c.time - a.time < e)
|
|
79
|
+
return { x: 0, y: 0 };
|
|
80
|
+
const l = (c.time - a.time) / 1e3;
|
|
81
|
+
return {
|
|
82
|
+
x: h((c.x - a.x) / l),
|
|
83
|
+
y: h((c.y - a.y) / l)
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
clear() {
|
|
87
|
+
n = [], s = void 0;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const v = Object.freeze({
|
|
92
|
+
rubberBand: y,
|
|
93
|
+
rubberBandClamp: x,
|
|
94
|
+
decelerationRates: b,
|
|
95
|
+
decelerate: d,
|
|
96
|
+
projectDeceleration: p,
|
|
97
|
+
projectFling: M,
|
|
98
|
+
isDecelerationAtRest: R,
|
|
99
|
+
createVelocityTracker: E
|
|
100
|
+
});
|
|
101
|
+
export {
|
|
102
|
+
v as ocGesture
|
|
103
|
+
};
|
package/docs/gesture.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# 제스처 계산 — ocGesture
|
|
2
|
+
|
|
3
|
+
`ocGesture`는 DOM·React·CSS·스케줄러에 의존하지 않는 제스처 계산 진입점입니다. 루트 export 대신 전용 경로로 가져옵니다. 런타임 named export는 `ocGesture` 하나이며 타입은 `OcGesture*` 이름으로 제공합니다.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { ocGesture } from '@orioncactuscorp/ui/utils/gesture';
|
|
7
|
+
|
|
8
|
+
const displayedX = ocGesture.rubberBandClamp(rawX, -200, 200, 100);
|
|
9
|
+
const tracker = ocGesture.createVelocityTracker();
|
|
10
|
+
tracker.push({ time: performance.now(), x: rawX, y: rawY });
|
|
11
|
+
const velocity = tracker.read(performance.now());
|
|
12
|
+
const next = ocGesture.decelerate(
|
|
13
|
+
{ position: displayedX, velocity: velocity.x },
|
|
14
|
+
elapsedMs,
|
|
15
|
+
{ rate: ocGesture.decelerationRates.fast },
|
|
16
|
+
);
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 단위와 API
|
|
20
|
+
|
|
21
|
+
위치·dimension은 `px`, 속도는 **`px/s`**, 시간은 명시적인 `ms`입니다. 감속률은 매 밀리초의 속도 유지 비율입니다. 기존 spring에 속도를 전달할 때 추가로 1000을 곱하지 않습니다.
|
|
22
|
+
|
|
23
|
+
| API | 계약 |
|
|
24
|
+
| ---------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
25
|
+
| `rubberBand(offset, dimension, resistance = 0.55)` | 부호를 유지하는 저항. dimension은 완충 거리의 점근적 한도이며 0이면 결과 0 |
|
|
26
|
+
| `rubberBandClamp(value, min, max, dimension, resistance = 0.55)` | 범위 안은 그대로, 밖은 경계부터 저항 적용. min = max 허용 |
|
|
27
|
+
| `decelerationRates` | 읽기 전용 `{ normal: 0.998, fast: 0.99 }` |
|
|
28
|
+
| `decelerate(state, elapsedMs, { rate }?)` | 지수 감속의 연속 적분. 새 `{ position, velocity }` 반환 |
|
|
29
|
+
| `projectDeceleration(velocity, { rate }?)` | 같은 모델의 남은 이동 거리 |
|
|
30
|
+
| `projectFling(position, velocity, { rate }?)` | 현재 위치 + 남은 이동 거리 |
|
|
31
|
+
| `isDecelerationAtRest(velocity, threshold = 10)` | 절댓값이 threshold 미만이면 true. 최종 위치에 도달했다는 의미는 아님 |
|
|
32
|
+
| `createVelocityTracker(options?)` | `push(sample)`, `read(now)`, `clear()` 제공 |
|
|
33
|
+
|
|
34
|
+
감속 API 기본 rate는 `normal`입니다. 더 짧은 관성 이동이 필요한 이미지 뷰어에서는 `fast`를 명시할 수 있습니다. `Δx = (velocity / 1000) × expm1(elapsedMs × ln(rate)) / ln(rate)`로 계산하므로 경계 없는 적분은 프레임을 나누어도 같은 경로를 따릅니다. 투사 역시 이 연속 모델을 사용합니다.
|
|
35
|
+
|
|
36
|
+
모든 숫자는 유한해야 합니다. dimension과 elapsedMs는 0 이상, resistance와 정지 threshold는 0 초과, rate는 0 초과 1 미만, min은 max 이하입니다. 비유한 입력은 `TypeError`, 범위 위반은 `RangeError`이며 계산 결과가 표현 가능한 유한 범위를 넘으면 `TypeError`입니다. 내부 계산이 유한 정밀도로 수행되므로 극단적으로 작은 값은 0으로 반올림될 수 있습니다.
|
|
37
|
+
|
|
38
|
+
## 속도 추적
|
|
39
|
+
|
|
40
|
+
| 옵션 | 기본값 | 의미 |
|
|
41
|
+
| ---------------- | ------ | -------------------------------------------- |
|
|
42
|
+
| `windowMs` | 100 | read 시점부터 최근 샘플을 선택하는 창 |
|
|
43
|
+
| `minimumSpanMs` | 8 | 첫/마지막 샘플 사이 최소 간격. windowMs 이하 |
|
|
44
|
+
| `stopAfterMs` | 100 | 마지막 좌표 변경 이후 정지로 판단하는 시간 |
|
|
45
|
+
| `maxPxPerSecond` | 4000 | 축별 속도 상한 |
|
|
46
|
+
|
|
47
|
+
모든 옵션은 유한한 양수입니다. 최소 두 시각의 샘플이 필요합니다. 같은 시각의 샘플은 마지막 값으로 대체하고 역순 시각은 거부합니다. `read(now)`는 마지막 샘플보다 이른 시각을 거부합니다. timestamp에는 같은 단조 시계를 사용하세요. 샘플이 부족하거나 오래되었거나 stopAfterMs 이상 좌표 변경이 없으면 0을 반환합니다. 중복 좌표 push는 정지 타이머를 연장하지 않습니다. read는 상태를 변경하지 않습니다.
|
|
48
|
+
|
|
49
|
+
포인터 이동 속도와 화면에 표시된 콘텐츠 속도는 rubber band 구간에서 다릅니다. 어떤 좌표를 추적할지는 호출부가 선택합니다. 새 pointerdown과 pointercancel에서는 `clear()`를 호출하고, cancel을 정상 release로 처리하지 마세요. flick 임계값과 스냅 선택은 컴포넌트 정책입니다.
|
|
50
|
+
|
|
51
|
+
## 마찰과 spring 조합
|
|
52
|
+
|
|
53
|
+
자유 팬은 `decelerate`로 진행합니다. 고정된 스냅 목표나 경계 복귀에는 [spring API](./spring.md)를 사용합니다. spring은 초기 속도를 보존하지만 목표 거리와 설정에 따라 이후 가속할 수 있으므로, 자유 팬을 단순히 `projectFling` 목표로 spring 이동시키면 마찰 감속과 다른 경로가 됩니다.
|
|
54
|
+
|
|
55
|
+
이 API는 프레임 실행·경계 감지·바운스·중단을 소유하지 않습니다. 경계 있는 실행기를 구현할 때는 정확한 경계 도달 시각과 속도를 구한 후 남은 프레임 시간을 spring에 적용해야 합니다. 프레임 끝에서 경계를 발견하고 bounce를 시작하면 프레임 간격에 따라 경로가 달라집니다. 사용자 모션 설정과 입력 중단은 호출부가 처리합니다.
|
|
56
|
+
|
|
57
|
+
Modal과 PositionSnap은 같은 rubber band 계산을 사용합니다. Modal의 방향별 완충 한도와 기존 스냅·닫기 투사·속도 측정 정책은 유지됩니다. 이 유틸이 특정 OS의 모든 스크롤 동작을 재현한다는 보장은 없습니다.
|
|
58
|
+
|
|
59
|
+
## Migration Notes
|
|
60
|
+
|
|
61
|
+
- 기존 컴포넌트 소비자의 필수 변경은 없습니다.
|
|
62
|
+
- 로컬 구현을 교체할 때 기존 속도가 px/ms이면 입력에 1000을 곱하고 이후부터 px/s로 통일하세요.
|
|
63
|
+
- rate 인자는 `{ rate }` 객체이며 기본값은 `normal`입니다. 기존 fast 기반 뷰어는 명시적으로 `fast`를 지정하세요.
|
|
64
|
+
- React 훅이나 플링 애니메이터는 이번 API에 포함되지 않습니다.
|