@mks2508/mks-ui 0.2.1 → 0.3.1
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/react-ui/hooks/Animation/UseAutoHeight.js +7 -7
- package/dist/react-ui/hooks/DOM/UseIsInView.js +3 -3
- package/dist/react-ui/hooks/Formatting/UseListFormat.d.ts +49 -0
- package/dist/react-ui/hooks/Formatting/UseListFormat.d.ts.map +1 -0
- package/dist/react-ui/hooks/Formatting/UseListFormat.js +105 -0
- package/dist/react-ui/hooks/State/UseControlledState.js +4 -4
- package/dist/react-ui/hooks/State/UseDataState.js +5 -5
- package/dist/react-ui/hooks/index.d.ts +2 -0
- package/dist/react-ui/hooks/index.d.ts.map +1 -1
- package/dist/react-ui/hooks/index.js +1 -0
- package/dist/react-ui/index.js +22 -2
- package/dist/react-ui/lib/get-strict-context.js +3 -3
- package/dist/react-ui/primitives/CountingNumber/index.js +3 -3
- package/dist/react-ui/primitives/Highlight/index.js +26 -26
- package/dist/react-ui/primitives/Slot/index.js +3 -3
- package/dist/react-ui/primitives/index.d.ts +1 -0
- package/dist/react-ui/primitives/index.d.ts.map +1 -1
- package/dist/react-ui/primitives/index.js +18 -0
- package/dist/react-ui/primitives/waapi/Morph/Morph.types.d.ts +76 -0
- package/dist/react-ui/primitives/waapi/Morph/Morph.types.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Morph/MorphContext.d.ts +11 -0
- package/dist/react-ui/primitives/waapi/Morph/MorphContext.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Morph/MorphContext.js +19 -0
- package/dist/react-ui/primitives/waapi/Morph/index.d.ts +23 -0
- package/dist/react-ui/primitives/waapi/Morph/index.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Morph/index.js +45 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/index.d.ts +12 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/index.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.d.ts +38 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.js +78 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.d.ts +23 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.js +140 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.d.ts +28 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.js +77 -0
- package/dist/react-ui/primitives/waapi/Morph/useMorph.d.ts +27 -0
- package/dist/react-ui/primitives/waapi/Morph/useMorph.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Morph/useMorph.js +86 -0
- package/dist/react-ui/primitives/waapi/Reorder/Reorder.types.d.ts +168 -0
- package/dist/react-ui/primitives/waapi/Reorder/Reorder.types.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Reorder/index.d.ts +25 -0
- package/dist/react-ui/primitives/waapi/Reorder/index.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Reorder/index.js +186 -0
- package/dist/react-ui/primitives/waapi/Reorder/useReorder.d.ts +26 -0
- package/dist/react-ui/primitives/waapi/Reorder/useReorder.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Reorder/useReorder.js +48 -0
- package/dist/react-ui/primitives/waapi/Reorder/useReorderPresence.d.ts +33 -0
- package/dist/react-ui/primitives/waapi/Reorder/useReorderPresence.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Reorder/useReorderPresence.js +137 -0
- package/dist/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.d.ts +47 -0
- package/dist/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.js +72 -0
- package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.d.ts +10 -0
- package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.d.ts +74 -0
- package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/SlidingNumber/index.d.ts +33 -0
- package/dist/react-ui/primitives/waapi/SlidingNumber/index.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/SlidingNumber/index.js +354 -0
- package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.styles.d.ts +25 -0
- package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.styles.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.types.d.ts +57 -0
- package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.types.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/SlidingText/index.d.ts +26 -0
- package/dist/react-ui/primitives/waapi/SlidingText/index.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/SlidingText/index.js +105 -0
- package/dist/react-ui/primitives/waapi/core/animationConstants.d.ts +156 -0
- package/dist/react-ui/primitives/waapi/core/animationConstants.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/core/animationConstants.js +180 -0
- package/dist/react-ui/primitives/waapi/core/index.d.ts +16 -0
- package/dist/react-ui/primitives/waapi/core/index.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/core/index.js +5 -0
- package/dist/react-ui/primitives/waapi/core/types.d.ts +143 -0
- package/dist/react-ui/primitives/waapi/core/types.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/core/useAnimationOrchestrator.d.ts +32 -0
- package/dist/react-ui/primitives/waapi/core/useAnimationOrchestrator.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/core/useAnimationOrchestrator.js +322 -0
- package/dist/react-ui/primitives/waapi/core/useElementRegistry.d.ts +21 -0
- package/dist/react-ui/primitives/waapi/core/useElementRegistry.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/core/useElementRegistry.js +65 -0
- package/dist/react-ui/primitives/waapi/core/useFLIPAnimation.d.ts +20 -0
- package/dist/react-ui/primitives/waapi/core/useFLIPAnimation.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/core/useFLIPAnimation.js +99 -0
- package/dist/react-ui/primitives/waapi/core/usePositionCapture.d.ts +24 -0
- package/dist/react-ui/primitives/waapi/core/usePositionCapture.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/core/usePositionCapture.js +75 -0
- package/dist/react-ui/primitives/waapi/index.d.ts +33 -0
- package/dist/react-ui/primitives/waapi/index.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/index.js +18 -0
- package/dist/react-ui/ui/Accordion/index.js +3 -3
- package/dist/react-ui/ui/Button/index.js +8 -8
- package/dist/react-ui/ui/Combobox/index.js +2 -2
- package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts +35 -0
- package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts.map +1 -0
- package/dist/react-ui/ui/DataCard/DataCard.styles.js +114 -0
- package/dist/react-ui/ui/DataCard/DataCard.types.d.ts +135 -0
- package/dist/react-ui/ui/DataCard/DataCard.types.d.ts.map +1 -0
- package/dist/react-ui/ui/DataCard/index.d.ts +129 -0
- package/dist/react-ui/ui/DataCard/index.d.ts.map +1 -0
- package/dist/react-ui/ui/DataCard/index.js +276 -0
- package/dist/react-ui/ui/Menu/index.js +2 -2
- package/dist/react-ui/ui/Switch/index.js +3 -3
- package/dist/react-ui/ui/Tabs/index.js +3 -3
- package/dist/react-ui/ui/TextFlow/TextFlow.styles.d.ts +16 -0
- package/dist/react-ui/ui/TextFlow/TextFlow.styles.d.ts.map +1 -0
- package/dist/react-ui/ui/TextFlow/TextFlow.types.d.ts +101 -0
- package/dist/react-ui/ui/TextFlow/TextFlow.types.d.ts.map +1 -0
- package/dist/react-ui/ui/TextFlow/index.d.ts +26 -0
- package/dist/react-ui/ui/TextFlow/index.d.ts.map +1 -0
- package/dist/react-ui/ui/TextFlow/index.js +187 -0
- package/dist/react-ui/ui/index.d.ts +2 -1
- package/dist/react-ui/ui/index.d.ts.map +1 -1
- package/dist/react-ui/ui/index.js +3 -1
- package/package.json +6 -2
- package/src/react-ui/hooks/Formatting/UseListFormat.ts +134 -0
- package/src/react-ui/hooks/index.ts +3 -0
- package/src/react-ui/primitives/index.ts +3 -0
- package/src/react-ui/primitives/waapi/Morph/Morph.types.ts +106 -0
- package/src/react-ui/primitives/waapi/Morph/MorphContext.tsx +21 -0
- package/src/react-ui/primitives/waapi/Morph/index.tsx +56 -0
- package/src/react-ui/primitives/waapi/Morph/techniques/index.ts +12 -0
- package/src/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.ts +88 -0
- package/src/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.ts +175 -0
- package/src/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.ts +86 -0
- package/src/react-ui/primitives/waapi/Morph/useMorph.ts +100 -0
- package/src/react-ui/primitives/waapi/Reorder/Reorder.types.ts +177 -0
- package/src/react-ui/primitives/waapi/Reorder/index.tsx +260 -0
- package/src/react-ui/primitives/waapi/Reorder/useReorder.ts +46 -0
- package/src/react-ui/primitives/waapi/Reorder/useReorderPresence.ts +208 -0
- package/src/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.ts +104 -0
- package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.ts +14 -0
- package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.ts +84 -0
- package/src/react-ui/primitives/waapi/SlidingNumber/index.tsx +474 -0
- package/src/react-ui/primitives/waapi/SlidingText/SlidingText.styles.ts +32 -0
- package/src/react-ui/primitives/waapi/SlidingText/SlidingText.types.ts +69 -0
- package/src/react-ui/primitives/waapi/SlidingText/index.tsx +140 -0
- package/src/react-ui/primitives/waapi/core/animationConstants.ts +215 -0
- package/src/react-ui/primitives/waapi/core/index.ts +53 -0
- package/src/react-ui/primitives/waapi/core/types.ts +200 -0
- package/src/react-ui/primitives/waapi/core/useAnimationOrchestrator.ts +429 -0
- package/src/react-ui/primitives/waapi/core/useElementRegistry.ts +80 -0
- package/src/react-ui/primitives/waapi/core/useFLIPAnimation.ts +137 -0
- package/src/react-ui/primitives/waapi/core/usePositionCapture.ts +105 -0
- package/src/react-ui/primitives/waapi/index.ts +116 -0
- package/src/react-ui/styles/animations.css +369 -0
- package/src/react-ui/ui/DataCard/DataCard.styles.ts +150 -0
- package/src/react-ui/ui/DataCard/DataCard.types.ts +146 -0
- package/src/react-ui/ui/DataCard/index.tsx +406 -0
- package/src/react-ui/ui/TextFlow/TextFlow.styles.ts +36 -0
- package/src/react-ui/ui/TextFlow/TextFlow.types.ts +118 -0
- package/src/react-ui/ui/TextFlow/index.tsx +276 -0
- package/src/react-ui/ui/index.ts +4 -1
- /package/dist/react-ui/components/MorphingPopover/{morphing-popover.module-CgbYV_HS.css → morphing-popover.module-BycNI8nU.css} +0 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ReactNode, RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Available morphing techniques.
|
|
4
|
+
*/
|
|
5
|
+
export type MorphTechnique = 'flip-clip-path' | 'css-grid' | 'view-transitions';
|
|
6
|
+
/** Options for the FLIP + clip-path morphing technique */
|
|
7
|
+
export interface IFLIPClipPathOptions {
|
|
8
|
+
duration?: number;
|
|
9
|
+
easing?: string;
|
|
10
|
+
clipPathStart?: string;
|
|
11
|
+
clipPathEnd?: string;
|
|
12
|
+
}
|
|
13
|
+
/** API returned by useFLIPClipPath */
|
|
14
|
+
export interface IFLIPClipPathAPI {
|
|
15
|
+
isMorphing: boolean;
|
|
16
|
+
morph: (fromElement: HTMLElement, toElement: HTMLElement) => Promise<void>;
|
|
17
|
+
cancel: () => void;
|
|
18
|
+
}
|
|
19
|
+
/** Options for the CSS Grid expand/collapse technique */
|
|
20
|
+
export interface ICSSGridMorphOptions {
|
|
21
|
+
duration?: number;
|
|
22
|
+
easing?: string;
|
|
23
|
+
}
|
|
24
|
+
/** API returned by useCSSGridMorph */
|
|
25
|
+
export interface ICSSGridMorphAPI {
|
|
26
|
+
isExpanded: boolean;
|
|
27
|
+
expand: () => void;
|
|
28
|
+
collapse: () => void;
|
|
29
|
+
toggle: () => void;
|
|
30
|
+
containerRef: RefObject<HTMLElement | null>;
|
|
31
|
+
}
|
|
32
|
+
/** Options for the View Transitions API wrapper */
|
|
33
|
+
export interface IViewTransitionsOptions {
|
|
34
|
+
name?: string;
|
|
35
|
+
types?: string[];
|
|
36
|
+
}
|
|
37
|
+
/** API returned by useViewTransitions */
|
|
38
|
+
export interface IViewTransitionsAPI {
|
|
39
|
+
isSupported: boolean;
|
|
40
|
+
startTransition: (callback: () => void | Promise<void>) => Promise<void>;
|
|
41
|
+
setTypes: (types: string[]) => void;
|
|
42
|
+
}
|
|
43
|
+
/** Configuration for useMorph hook */
|
|
44
|
+
export interface IUseMorphConfig {
|
|
45
|
+
technique?: MorphTechnique;
|
|
46
|
+
duration?: number;
|
|
47
|
+
easing?: string;
|
|
48
|
+
onMorphStart?: () => void;
|
|
49
|
+
onMorphEnd?: () => void;
|
|
50
|
+
}
|
|
51
|
+
/** Return type for useMorph hook */
|
|
52
|
+
export interface IUseMorphReturn {
|
|
53
|
+
isMorphing: boolean;
|
|
54
|
+
technique: MorphTechnique;
|
|
55
|
+
isViewTransitionsSupported: boolean;
|
|
56
|
+
morph: (fromElement: HTMLElement, toElement: HTMLElement) => Promise<void>;
|
|
57
|
+
cancel: () => void;
|
|
58
|
+
flipClipPath: IFLIPClipPathAPI;
|
|
59
|
+
cssGrid: ICSSGridMorphAPI;
|
|
60
|
+
viewTransitions: IViewTransitionsAPI;
|
|
61
|
+
}
|
|
62
|
+
/** Props for Morph container component */
|
|
63
|
+
export interface IMorphProps {
|
|
64
|
+
children: ReactNode;
|
|
65
|
+
technique?: MorphTechnique;
|
|
66
|
+
duration?: number;
|
|
67
|
+
easing?: string;
|
|
68
|
+
className?: string;
|
|
69
|
+
onMorphStart?: () => void;
|
|
70
|
+
onMorphEnd?: () => void;
|
|
71
|
+
}
|
|
72
|
+
/** Context value for Morph components */
|
|
73
|
+
export interface IMorphContextValue {
|
|
74
|
+
morph: IUseMorphReturn;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=Morph.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Morph.types.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/Morph/Morph.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,UAAU,GAAG,kBAAkB,CAAC;AAMhF,0DAA0D;AAC1D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,sCAAsC;AACtC,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAMD,yDAAyD;AACzD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,sCAAsC;AACtC,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,YAAY,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC7C;AAMD,mDAAmD;AACnD,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,yCAAyC;AACzC,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACrC;AAMD,sCAAsC;AACtC,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,cAAc,CAAC;IAC1B,0BAA0B,EAAE,OAAO,CAAC;IACpC,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,eAAe,EAAE,mBAAmB,CAAC;CACtC;AAMD,0CAA0C;AAC1C,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,yCAAyC;AACzC,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,eAAe,CAAC;CACxB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { IMorphContextValue } from './Morph.types';
|
|
3
|
+
declare const MorphContext: React.Context<IMorphContextValue | null>;
|
|
4
|
+
/**
|
|
5
|
+
* Hook to access morph context
|
|
6
|
+
*
|
|
7
|
+
* @throws Error if used outside of Morph provider
|
|
8
|
+
*/
|
|
9
|
+
export declare function useMorphContext(): IMorphContextValue;
|
|
10
|
+
export { MorphContext };
|
|
11
|
+
//# sourceMappingURL=MorphContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MorphContext.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/Morph/MorphContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,QAAA,MAAM,YAAY,0CAAiD,CAAC;AAEpE;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,kBAAkB,CAMpD;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/react-ui/primitives/waapi/Morph/MorphContext.tsx
|
|
6
|
+
const MorphContext = createContext(null);
|
|
7
|
+
/**
|
|
8
|
+
* Hook to access morph context
|
|
9
|
+
*
|
|
10
|
+
* @throws Error if used outside of Morph provider
|
|
11
|
+
*/
|
|
12
|
+
function useMorphContext() {
|
|
13
|
+
const context = useContext(MorphContext);
|
|
14
|
+
if (!context) throw new Error("useMorphContext must be used within a Morph component");
|
|
15
|
+
return context;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { MorphContext, useMorphContext };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { IMorphProps, IMorphContextValue } from './Morph.types';
|
|
3
|
+
/**
|
|
4
|
+
* Morph - Container component for morphable elements.
|
|
5
|
+
*
|
|
6
|
+
* Provides morphing capabilities to child components through context.
|
|
7
|
+
* Supports FLIP + clip-path, CSS Grid, and View Transitions techniques.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <Morph technique="flip-clip-path" duration={300}>
|
|
12
|
+
* <button onClick={() => morph(fromRef.current, toRef.current)}>
|
|
13
|
+
* Morph
|
|
14
|
+
* </button>
|
|
15
|
+
* </Morph>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function Morph({ children, technique, duration, easing, className, onMorphStart, onMorphEnd }: IMorphProps): ReactNode;
|
|
19
|
+
export declare namespace Morph {
|
|
20
|
+
var displayName: string;
|
|
21
|
+
}
|
|
22
|
+
export type { IMorphProps, IMorphContextValue };
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/Morph/index.tsx"],"names":[],"mappings":"AAEA,OAAc,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvD,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGrE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAC,EACpB,QAAQ,EACR,SAA4B,EAC5B,QAAQ,EACR,MAAM,EACN,SAAc,EACd,YAAY,EACZ,UAAU,EACX,EAAE,WAAW,GAAG,SAAS,CAoBzB;yBA5Be,KAAK;;;AAgCrB,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../../lib/utils.js";
|
|
4
|
+
import { MorphContext } from "./MorphContext.js";
|
|
5
|
+
import { useMorph } from "./useMorph.js";
|
|
6
|
+
import React, { useMemo } from "react";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
|
|
9
|
+
//#region src/react-ui/primitives/waapi/Morph/index.tsx
|
|
10
|
+
/**
|
|
11
|
+
* Morph - Container component for morphable elements.
|
|
12
|
+
*
|
|
13
|
+
* Provides morphing capabilities to child components through context.
|
|
14
|
+
* Supports FLIP + clip-path, CSS Grid, and View Transitions techniques.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <Morph technique="flip-clip-path" duration={300}>
|
|
19
|
+
* <button onClick={() => morph(fromRef.current, toRef.current)}>
|
|
20
|
+
* Morph
|
|
21
|
+
* </button>
|
|
22
|
+
* </Morph>
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function Morph({ children, technique = "flip-clip-path", duration, easing, className = "", onMorphStart, onMorphEnd }) {
|
|
26
|
+
const morph = useMorph({
|
|
27
|
+
technique,
|
|
28
|
+
duration,
|
|
29
|
+
easing,
|
|
30
|
+
onMorphStart,
|
|
31
|
+
onMorphEnd
|
|
32
|
+
});
|
|
33
|
+
const contextValue = useMemo(() => ({ morph }), [morph]);
|
|
34
|
+
return /* @__PURE__ */ jsx(MorphContext.Provider, {
|
|
35
|
+
value: contextValue,
|
|
36
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
37
|
+
className: cn("morph-container", className),
|
|
38
|
+
children
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
Morph.displayName = "Morph";
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
export { Morph };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Morph techniques.
|
|
3
|
+
*
|
|
4
|
+
* Individual morphing implementations that can be used
|
|
5
|
+
* standalone or composed through useMorph.
|
|
6
|
+
*
|
|
7
|
+
* @module primitives/waapi/Morph/techniques
|
|
8
|
+
*/
|
|
9
|
+
export { useFLIPClipPath } from './useFLIPClipPath';
|
|
10
|
+
export { useCSSGridMorph } from './useCSSGridMorph';
|
|
11
|
+
export { useViewTransitions } from './useViewTransitions';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/react-ui/primitives/waapi/Morph/techniques/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ICSSGridMorphOptions, ICSSGridMorphAPI } from '../Morph.types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook for CSS Grid-based expand/collapse animations.
|
|
4
|
+
*
|
|
5
|
+
* Uses the `grid-template-rows: 0fr/1fr` technique for smooth height
|
|
6
|
+
* animations without needing to know the content height in advance.
|
|
7
|
+
*
|
|
8
|
+
* CSS required on container:
|
|
9
|
+
* ```css
|
|
10
|
+
* .morph-container {
|
|
11
|
+
* display: grid;
|
|
12
|
+
* grid-template-rows: 0fr;
|
|
13
|
+
* transition: grid-template-rows 300ms ease;
|
|
14
|
+
* }
|
|
15
|
+
* .morph-container.expanded {
|
|
16
|
+
* grid-template-rows: 1fr;
|
|
17
|
+
* }
|
|
18
|
+
* .morph-content {
|
|
19
|
+
* overflow: hidden;
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @param options - Duration and easing overrides
|
|
24
|
+
* @returns Grid morph API with expand, collapse, toggle, and container ref
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* const { isExpanded, toggle, containerRef } = useCSSGridMorph();
|
|
29
|
+
*
|
|
30
|
+
* return (
|
|
31
|
+
* <div ref={containerRef} className={isExpanded ? 'expanded' : ''}>
|
|
32
|
+
* <div className="morph-content">Collapsible content</div>
|
|
33
|
+
* </div>
|
|
34
|
+
* );
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function useCSSGridMorph(options?: ICSSGridMorphOptions): ICSSGridMorphAPI;
|
|
38
|
+
//# sourceMappingURL=useCSSGridMorph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCSSGridMorph.d.ts","sourceRoot":"","sources":["../../../../../../src/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAK7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,gBAAgB,CA6ChF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { EASINGS, TIMING } from "../../core/animationConstants.js";
|
|
2
|
+
import { useCallback, useRef, useState } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.ts
|
|
5
|
+
const DEFAULT_DURATION = TIMING.FLIP_DURATION;
|
|
6
|
+
const DEFAULT_EASING = EASINGS.MATERIAL_STANDARD;
|
|
7
|
+
/**
|
|
8
|
+
* Hook for CSS Grid-based expand/collapse animations.
|
|
9
|
+
*
|
|
10
|
+
* Uses the `grid-template-rows: 0fr/1fr` technique for smooth height
|
|
11
|
+
* animations without needing to know the content height in advance.
|
|
12
|
+
*
|
|
13
|
+
* CSS required on container:
|
|
14
|
+
* ```css
|
|
15
|
+
* .morph-container {
|
|
16
|
+
* display: grid;
|
|
17
|
+
* grid-template-rows: 0fr;
|
|
18
|
+
* transition: grid-template-rows 300ms ease;
|
|
19
|
+
* }
|
|
20
|
+
* .morph-container.expanded {
|
|
21
|
+
* grid-template-rows: 1fr;
|
|
22
|
+
* }
|
|
23
|
+
* .morph-content {
|
|
24
|
+
* overflow: hidden;
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @param options - Duration and easing overrides
|
|
29
|
+
* @returns Grid morph API with expand, collapse, toggle, and container ref
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* const { isExpanded, toggle, containerRef } = useCSSGridMorph();
|
|
34
|
+
*
|
|
35
|
+
* return (
|
|
36
|
+
* <div ref={containerRef} className={isExpanded ? 'expanded' : ''}>
|
|
37
|
+
* <div className="morph-content">Collapsible content</div>
|
|
38
|
+
* </div>
|
|
39
|
+
* );
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
function useCSSGridMorph(options) {
|
|
43
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
44
|
+
const containerRef = useRef(null);
|
|
45
|
+
const optionsRef = useRef(options);
|
|
46
|
+
const duration = optionsRef.current?.duration ?? DEFAULT_DURATION;
|
|
47
|
+
const easing = optionsRef.current?.easing ?? DEFAULT_EASING;
|
|
48
|
+
const applyTransition = useCallback(() => {
|
|
49
|
+
if (containerRef.current) containerRef.current.style.transition = `grid-template-rows ${duration}ms ${easing}`;
|
|
50
|
+
}, [duration, easing]);
|
|
51
|
+
const expand = useCallback(() => {
|
|
52
|
+
applyTransition();
|
|
53
|
+
if (containerRef.current) containerRef.current.style.gridTemplateRows = "1fr";
|
|
54
|
+
setIsExpanded(true);
|
|
55
|
+
}, [applyTransition]);
|
|
56
|
+
const collapse = useCallback(() => {
|
|
57
|
+
applyTransition();
|
|
58
|
+
if (containerRef.current) containerRef.current.style.gridTemplateRows = "0fr";
|
|
59
|
+
setIsExpanded(false);
|
|
60
|
+
}, [applyTransition]);
|
|
61
|
+
return {
|
|
62
|
+
isExpanded,
|
|
63
|
+
expand,
|
|
64
|
+
collapse,
|
|
65
|
+
toggle: useCallback(() => {
|
|
66
|
+
if (isExpanded) collapse();
|
|
67
|
+
else expand();
|
|
68
|
+
}, [
|
|
69
|
+
isExpanded,
|
|
70
|
+
expand,
|
|
71
|
+
collapse
|
|
72
|
+
]),
|
|
73
|
+
containerRef
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { useCSSGridMorph };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IFLIPClipPathOptions, IFLIPClipPathAPI } from '../Morph.types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook for FLIP + clip-path morphing technique.
|
|
4
|
+
*
|
|
5
|
+
* Combines:
|
|
6
|
+
* 1. FLIP for position/size transitions
|
|
7
|
+
* 2. clip-path for shape morphing
|
|
8
|
+
* 3. Opacity crossfade for smooth visual transition
|
|
9
|
+
*
|
|
10
|
+
* @param options - Duration, easing, and clip-path overrides
|
|
11
|
+
* @returns API with morph trigger, cancel, and morphing state
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const { isMorphing, morph, cancel } = useFLIPClipPath({ duration: 300 });
|
|
16
|
+
*
|
|
17
|
+
* const handleMorph = async () => {
|
|
18
|
+
* await morph(fromRef.current, toRef.current);
|
|
19
|
+
* };
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function useFLIPClipPath(options?: IFLIPClipPathOptions): IFLIPClipPathAPI;
|
|
23
|
+
//# sourceMappingURL=useFLIPClipPath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFLIPClipPath.d.ts","sourceRoot":"","sources":["../../../../../../src/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAK7E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,gBAAgB,CAsIhF"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { EASINGS, TIMING } from "../../core/animationConstants.js";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.ts
|
|
5
|
+
const DEFAULT_DURATION = TIMING.FLIP_DURATION;
|
|
6
|
+
const DEFAULT_EASING = EASINGS.EASE_OUT_CUBIC;
|
|
7
|
+
/**
|
|
8
|
+
* Hook for FLIP + clip-path morphing technique.
|
|
9
|
+
*
|
|
10
|
+
* Combines:
|
|
11
|
+
* 1. FLIP for position/size transitions
|
|
12
|
+
* 2. clip-path for shape morphing
|
|
13
|
+
* 3. Opacity crossfade for smooth visual transition
|
|
14
|
+
*
|
|
15
|
+
* @param options - Duration, easing, and clip-path overrides
|
|
16
|
+
* @returns API with morph trigger, cancel, and morphing state
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* const { isMorphing, morph, cancel } = useFLIPClipPath({ duration: 300 });
|
|
21
|
+
*
|
|
22
|
+
* const handleMorph = async () => {
|
|
23
|
+
* await morph(fromRef.current, toRef.current);
|
|
24
|
+
* };
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function useFLIPClipPath(options) {
|
|
28
|
+
const [isMorphing, setIsMorphing] = useState(false);
|
|
29
|
+
const activeAnimationsRef = useRef([]);
|
|
30
|
+
const optionsRef = useRef(options);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
optionsRef.current = options;
|
|
33
|
+
}, [options]);
|
|
34
|
+
const cancel = useCallback(() => {
|
|
35
|
+
activeAnimationsRef.current.forEach((anim) => anim.cancel());
|
|
36
|
+
activeAnimationsRef.current = [];
|
|
37
|
+
setIsMorphing(false);
|
|
38
|
+
}, []);
|
|
39
|
+
const morph = useCallback(async (fromElement, toElement) => {
|
|
40
|
+
if (isMorphing) cancel();
|
|
41
|
+
setIsMorphing(true);
|
|
42
|
+
const duration = optionsRef.current?.duration ?? DEFAULT_DURATION;
|
|
43
|
+
const easing = optionsRef.current?.easing ?? DEFAULT_EASING;
|
|
44
|
+
const fromRect = fromElement.getBoundingClientRect();
|
|
45
|
+
const toRect = toElement.getBoundingClientRect();
|
|
46
|
+
const deltaX = fromRect.left - toRect.left;
|
|
47
|
+
const deltaY = fromRect.top - toRect.top;
|
|
48
|
+
const scaleX = fromRect.width / toRect.width;
|
|
49
|
+
const scaleY = fromRect.height / toRect.height;
|
|
50
|
+
const fromBorderRadius = getComputedStyle(fromElement).borderRadius;
|
|
51
|
+
const toBorderRadius = getComputedStyle(toElement).borderRadius;
|
|
52
|
+
const fromClipPath = optionsRef.current?.clipPathStart || borderRadiusToInset(fromBorderRadius, fromRect);
|
|
53
|
+
const toClipPath = optionsRef.current?.clipPathEnd || borderRadiusToInset(toBorderRadius, toRect);
|
|
54
|
+
const originalFromStyles = {
|
|
55
|
+
position: fromElement.style.position,
|
|
56
|
+
opacity: fromElement.style.opacity,
|
|
57
|
+
pointerEvents: fromElement.style.pointerEvents
|
|
58
|
+
};
|
|
59
|
+
const originalToStyles = {
|
|
60
|
+
position: toElement.style.position,
|
|
61
|
+
opacity: toElement.style.opacity,
|
|
62
|
+
transform: toElement.style.transform,
|
|
63
|
+
clipPath: toElement.style.clipPath
|
|
64
|
+
};
|
|
65
|
+
fromElement.style.position = "absolute";
|
|
66
|
+
fromElement.style.pointerEvents = "none";
|
|
67
|
+
toElement.style.position = "relative";
|
|
68
|
+
toElement.style.transform = `translate(${deltaX}px, ${deltaY}px) scale(${scaleX}, ${scaleY})`;
|
|
69
|
+
toElement.style.clipPath = fromClipPath;
|
|
70
|
+
toElement.style.opacity = "0";
|
|
71
|
+
const fromFadeOut = fromElement.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
72
|
+
duration: duration * .5,
|
|
73
|
+
easing,
|
|
74
|
+
fill: "forwards"
|
|
75
|
+
});
|
|
76
|
+
const toFadeIn = toElement.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
77
|
+
duration: duration * .5,
|
|
78
|
+
delay: duration * .25,
|
|
79
|
+
easing,
|
|
80
|
+
fill: "forwards"
|
|
81
|
+
});
|
|
82
|
+
const toTransform = toElement.animate([{
|
|
83
|
+
transform: `translate(${deltaX}px, ${deltaY}px) scale(${scaleX}, ${scaleY})`,
|
|
84
|
+
clipPath: fromClipPath
|
|
85
|
+
}, {
|
|
86
|
+
transform: "translate(0, 0) scale(1, 1)",
|
|
87
|
+
clipPath: toClipPath
|
|
88
|
+
}], {
|
|
89
|
+
duration,
|
|
90
|
+
easing,
|
|
91
|
+
fill: "forwards"
|
|
92
|
+
});
|
|
93
|
+
activeAnimationsRef.current = [
|
|
94
|
+
fromFadeOut,
|
|
95
|
+
toFadeIn,
|
|
96
|
+
toTransform
|
|
97
|
+
];
|
|
98
|
+
try {
|
|
99
|
+
await Promise.all([
|
|
100
|
+
fromFadeOut.finished,
|
|
101
|
+
toFadeIn.finished,
|
|
102
|
+
toTransform.finished
|
|
103
|
+
]);
|
|
104
|
+
} catch {
|
|
105
|
+
Object.assign(fromElement.style, originalFromStyles);
|
|
106
|
+
Object.assign(toElement.style, originalToStyles);
|
|
107
|
+
setIsMorphing(false);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
Object.assign(fromElement.style, originalFromStyles);
|
|
111
|
+
toElement.style.transform = "";
|
|
112
|
+
toElement.style.clipPath = "";
|
|
113
|
+
toElement.style.opacity = "1";
|
|
114
|
+
activeAnimationsRef.current = [];
|
|
115
|
+
setIsMorphing(false);
|
|
116
|
+
}, [isMorphing, cancel]);
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
return () => {
|
|
119
|
+
cancel();
|
|
120
|
+
};
|
|
121
|
+
}, [cancel]);
|
|
122
|
+
return {
|
|
123
|
+
isMorphing,
|
|
124
|
+
morph,
|
|
125
|
+
cancel
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Convert a CSS border-radius value to an inset() clip-path with rounded corners.
|
|
130
|
+
* @param borderRadius - CSS border-radius string
|
|
131
|
+
* @param rect - Bounding rect of the element
|
|
132
|
+
* @returns inset() clip-path string
|
|
133
|
+
*/
|
|
134
|
+
function borderRadiusToInset(borderRadius, rect) {
|
|
135
|
+
const radius = parseFloat(borderRadius) || 0;
|
|
136
|
+
return `inset(0 round ${radius / rect.width * 100}% ${radius / rect.height * 100}%)`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
140
|
+
export { useFLIPClipPath };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IViewTransitionsOptions, IViewTransitionsAPI } from '../Morph.types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook for the View Transitions API.
|
|
4
|
+
*
|
|
5
|
+
* Provides a wrapper around the native View Transitions API
|
|
6
|
+
* with automatic feature detection and fallback handling.
|
|
7
|
+
*
|
|
8
|
+
* Browser support:
|
|
9
|
+
* - Chrome 111+
|
|
10
|
+
* - Firefox 144+
|
|
11
|
+
* - Safari latest
|
|
12
|
+
*
|
|
13
|
+
* @param options - Optional view transition name and types
|
|
14
|
+
* @returns View Transitions API with support detection and transition trigger
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* const { isSupported, startTransition } = useViewTransitions({ name: 'hero' });
|
|
19
|
+
*
|
|
20
|
+
* const handleTransition = async () => {
|
|
21
|
+
* await startTransition(() => {
|
|
22
|
+
* setActiveImage(nextImage);
|
|
23
|
+
* });
|
|
24
|
+
* };
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function useViewTransitions(options?: IViewTransitionsOptions): IViewTransitionsAPI;
|
|
28
|
+
//# sourceMappingURL=useViewTransitions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useViewTransitions.d.ts","sourceRoot":"","sources":["../../../../../../src/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEnF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,mBAAmB,CAyDzF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { useCallback, useMemo, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.ts
|
|
4
|
+
/**
|
|
5
|
+
* Hook for the View Transitions API.
|
|
6
|
+
*
|
|
7
|
+
* Provides a wrapper around the native View Transitions API
|
|
8
|
+
* with automatic feature detection and fallback handling.
|
|
9
|
+
*
|
|
10
|
+
* Browser support:
|
|
11
|
+
* - Chrome 111+
|
|
12
|
+
* - Firefox 144+
|
|
13
|
+
* - Safari latest
|
|
14
|
+
*
|
|
15
|
+
* @param options - Optional view transition name and types
|
|
16
|
+
* @returns View Transitions API with support detection and transition trigger
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* const { isSupported, startTransition } = useViewTransitions({ name: 'hero' });
|
|
21
|
+
*
|
|
22
|
+
* const handleTransition = async () => {
|
|
23
|
+
* await startTransition(() => {
|
|
24
|
+
* setActiveImage(nextImage);
|
|
25
|
+
* });
|
|
26
|
+
* };
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function useViewTransitions(options) {
|
|
30
|
+
const optionsRef = useRef(options);
|
|
31
|
+
const typesRef = useRef(options?.types || []);
|
|
32
|
+
const isSupported = useMemo(() => {
|
|
33
|
+
if (typeof document === "undefined") return false;
|
|
34
|
+
return "startViewTransition" in document;
|
|
35
|
+
}, []);
|
|
36
|
+
const setTypes = useCallback((types) => {
|
|
37
|
+
typesRef.current = types;
|
|
38
|
+
}, []);
|
|
39
|
+
return {
|
|
40
|
+
isSupported,
|
|
41
|
+
startTransition: useCallback(async (callback) => {
|
|
42
|
+
if (!document.startViewTransition) {
|
|
43
|
+
await callback();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const viewTransitionName = optionsRef.current?.name;
|
|
47
|
+
const setupStyles = () => {
|
|
48
|
+
if (viewTransitionName) {
|
|
49
|
+
const styleEl = document.createElement("style");
|
|
50
|
+
styleEl.id = `view-transition-${viewTransitionName}`;
|
|
51
|
+
styleEl.textContent = `
|
|
52
|
+
::view-transition-old(${viewTransitionName}),
|
|
53
|
+
::view-transition-new(${viewTransitionName}) {
|
|
54
|
+
animation-duration: 300ms;
|
|
55
|
+
animation-timing-function: ease-out;
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
document.head.appendChild(styleEl);
|
|
59
|
+
return () => {
|
|
60
|
+
styleEl.remove();
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return () => {};
|
|
64
|
+
};
|
|
65
|
+
const cleanup = setupStyles();
|
|
66
|
+
try {
|
|
67
|
+
await document.startViewTransition(callback).finished;
|
|
68
|
+
} finally {
|
|
69
|
+
cleanup();
|
|
70
|
+
}
|
|
71
|
+
}, []),
|
|
72
|
+
setTypes
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
77
|
+
export { useViewTransitions };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IUseMorphReturn, IUseMorphConfig } from './Morph.types';
|
|
2
|
+
/**
|
|
3
|
+
* Unified hook for morphing animations.
|
|
4
|
+
*
|
|
5
|
+
* Provides access to multiple morphing techniques:
|
|
6
|
+
* - FLIP + clip-path (default): Best for element-to-element transitions
|
|
7
|
+
* - CSS Grid: Best for expand/collapse animations
|
|
8
|
+
* - View Transitions: Best for page/route transitions (requires browser support)
|
|
9
|
+
*
|
|
10
|
+
* Falls back to FLIP + clip-path when View Transitions API is unsupported.
|
|
11
|
+
*
|
|
12
|
+
* @param options - Technique selection, timing, and callbacks
|
|
13
|
+
* @returns Unified morph API with access to individual techniques
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* const morph = useMorph({ technique: 'flip-clip-path' });
|
|
18
|
+
*
|
|
19
|
+
* // Unified API:
|
|
20
|
+
* await morph.morph(fromElement, toElement);
|
|
21
|
+
*
|
|
22
|
+
* // Or individual techniques:
|
|
23
|
+
* morph.cssGrid.toggle();
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function useMorph(options?: IUseMorphConfig): IUseMorphReturn;
|
|
27
|
+
//# sourceMappingURL=useMorph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMorph.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/Morph/useMorph.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAkB,MAAM,eAAe,CAAC;AAEtF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,eAAe,CAqEnE"}
|