@mks2508/mks-ui 0.5.7 → 0.5.8
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/primitives/waapi/Gooey/Gooey.types.d.ts +2 -0
- package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts.map +1 -1
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts +1 -1
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts.map +1 -1
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.js +173 -43
- package/dist/react-ui/ui/DynamicToggle/{DynamicToggle-DOR3Ld-k.css → DynamicToggle-DJLwEkHr.css} +12 -19
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.css +12 -20
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts +1 -0
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.js +7 -1
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts +55 -31
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/index.d.ts +9 -3
- package/dist/react-ui/ui/DynamicToggle/index.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/index.js +47 -34
- package/package.json +52 -13
- package/src/assets/react.svg +0 -1
- package/src/core/index.ts +0 -7
- package/src/core/types.ts +0 -82
- package/src/css.d.ts +0 -7
- package/src/index.css +0 -129
- package/src/index.ts +0 -29
- package/src/react-ui/blocks/Terminal/ResttyAdapter.ts +0 -278
- package/src/react-ui/blocks/Terminal/Terminal.adapter.ts +0 -97
- package/src/react-ui/blocks/Terminal/Terminal.theme.restty.ts +0 -155
- package/src/react-ui/blocks/Terminal/Terminal.theme.ts +0 -80
- package/src/react-ui/blocks/Terminal/Terminal.types.ts +0 -438
- package/src/react-ui/blocks/Terminal/TerminalDisplay.styles.ts +0 -38
- package/src/react-ui/blocks/Terminal/TerminalDisplay.tsx +0 -254
- package/src/react-ui/blocks/Terminal/TerminalDisplay.types.ts +0 -73
- package/src/react-ui/blocks/Terminal/TerminalPanel.tsx +0 -269
- package/src/react-ui/blocks/Terminal/TerminalRestty.tsx +0 -326
- package/src/react-ui/blocks/Terminal/TerminalXterm.tsx +0 -230
- package/src/react-ui/blocks/Terminal/XTermAdapter.ts +0 -163
- package/src/react-ui/blocks/Terminal/chrome.ts +0 -25
- package/src/react-ui/blocks/Terminal/components/LogLineBadges.tsx +0 -316
- package/src/react-ui/blocks/Terminal/components/SpecializedSyntaxHighlighter.tsx +0 -218
- package/src/react-ui/blocks/Terminal/components/SyntaxHighlight.tsx +0 -386
- package/src/react-ui/blocks/Terminal/components/TerminalLogBadge.tsx +0 -67
- package/src/react-ui/blocks/Terminal/components/index.ts +0 -10
- package/src/react-ui/blocks/Terminal/display.ts +0 -46
- package/src/react-ui/blocks/Terminal/hooks/index.ts +0 -22
- package/src/react-ui/blocks/Terminal/hooks/useTerminalSettings.ts +0 -229
- package/src/react-ui/blocks/Terminal/hooks/useTerminalWebSocket.ts +0 -292
- package/src/react-ui/blocks/Terminal/index.ts +0 -111
- package/src/react-ui/blocks/Terminal/panel/LogLinesViewer.tsx +0 -330
- package/src/react-ui/blocks/Terminal/panel/TerminalDebugPanel.tsx +0 -242
- package/src/react-ui/blocks/Terminal/panel/TerminalFilterDropdown.tsx +0 -202
- package/src/react-ui/blocks/Terminal/panel/TerminalFilterTabs.tsx +0 -140
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.tsx +0 -68
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.types.ts +0 -85
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanelRestty.tsx +0 -383
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanelXterm.tsx +0 -439
- package/src/react-ui/blocks/Terminal/panel/TerminalLogsPanel.tsx +0 -550
- package/src/react-ui/blocks/Terminal/panel/TerminalLogsPanel.types.ts +0 -259
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.styles.ts +0 -75
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.tsx +0 -266
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.types.ts +0 -82
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelFooter.tsx +0 -112
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelHeader.tsx +0 -178
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelToolbar.tsx +0 -203
- package/src/react-ui/blocks/Terminal/panel/TerminalSessionControl.tsx +0 -252
- package/src/react-ui/blocks/Terminal/panel/TerminalSessionTabs.tsx +0 -334
- package/src/react-ui/blocks/Terminal/panel/TerminalSettingsPopover.tsx +0 -261
- package/src/react-ui/blocks/Terminal/panel/TerminalThemeSelector.tsx +0 -248
- package/src/react-ui/blocks/Terminal/panel/index.ts +0 -72
- package/src/react-ui/blocks/Terminal/panel/terminal-filter-dropdown.module.css +0 -59
- package/src/react-ui/blocks/Terminal/panel/terminal-session-tabs.module.css +0 -59
- package/src/react-ui/blocks/Terminal/parsing/BadgeFormatter.ts +0 -180
- package/src/react-ui/blocks/Terminal/parsing/HttpLogParser.ts +0 -248
- package/src/react-ui/blocks/Terminal/parsing/LogParser.types.ts +0 -283
- package/src/react-ui/blocks/Terminal/parsing/LogParserService.ts +0 -686
- package/src/react-ui/blocks/Terminal/parsing/MultilineAggregator.ts +0 -466
- package/src/react-ui/blocks/Terminal/parsing/PersistentLogBuffer.ts +0 -343
- package/src/react-ui/blocks/Terminal/parsing/SyntaxHighlighter.ts +0 -167
- package/src/react-ui/blocks/Terminal/parsing/TableParser.ts +0 -348
- package/src/react-ui/blocks/Terminal/parsing/ansi/AnsiColorMapper.ts +0 -251
- package/src/react-ui/blocks/Terminal/parsing/ansi/AnsiParser.ts +0 -390
- package/src/react-ui/blocks/Terminal/parsing/ansi/ansi.constants.ts +0 -320
- package/src/react-ui/blocks/Terminal/parsing/ansi/index.ts +0 -20
- package/src/react-ui/blocks/Terminal/parsing/index.ts +0 -69
- package/src/react-ui/blocks/Terminal/parsing/levels/LogLevel.types.ts +0 -68
- package/src/react-ui/blocks/Terminal/parsing/levels/LogLevelDetector.ts +0 -436
- package/src/react-ui/blocks/Terminal/parsing/levels/index.ts +0 -14
- package/src/react-ui/blocks/index.ts +0 -11
- package/src/react-ui/components/MorphingPopover/MorphingPopover.types.ts +0 -49
- package/src/react-ui/components/MorphingPopover/index.tsx +0 -186
- package/src/react-ui/components/MorphingPopover/morphing-popover.module.css +0 -153
- package/src/react-ui/components/index.ts +0 -9
- package/src/react-ui/hooks/Animation/UseAutoHeight.tsx +0 -123
- package/src/react-ui/hooks/DOM/UseIsInView.tsx +0 -44
- package/src/react-ui/hooks/Formatting/UseListFormat.ts +0 -134
- package/src/react-ui/hooks/State/UseControlledState.tsx +0 -57
- package/src/react-ui/hooks/State/UseDataState.tsx +0 -76
- package/src/react-ui/hooks/index.ts +0 -20
- package/src/react-ui/icons/index.ts +0 -12
- package/src/react-ui/icons/lucide-animated/activity.tsx +0 -109
- package/src/react-ui/icons/lucide-animated/arrow-down-to-line.tsx +0 -51
- package/src/react-ui/icons/lucide-animated/arrow-up.tsx +0 -50
- package/src/react-ui/icons/lucide-animated/bell-electric.tsx +0 -124
- package/src/react-ui/icons/lucide-animated/bell.tsx +0 -93
- package/src/react-ui/icons/lucide-animated/bot.tsx +0 -122
- package/src/react-ui/icons/lucide-animated/box.tsx +0 -117
- package/src/react-ui/icons/lucide-animated/check.tsx +0 -21
- package/src/react-ui/icons/lucide-animated/circle-check.tsx +0 -107
- package/src/react-ui/icons/lucide-animated/delete.tsx +0 -133
- package/src/react-ui/icons/lucide-animated/download.tsx +0 -99
- package/src/react-ui/icons/lucide-animated/edit-2.tsx +0 -21
- package/src/react-ui/icons/lucide-animated/globe.tsx +0 -23
- package/src/react-ui/icons/lucide-animated/home.tsx +0 -103
- package/src/react-ui/icons/lucide-animated/index.ts +0 -38
- package/src/react-ui/icons/lucide-animated/layers.tsx +0 -23
- package/src/react-ui/icons/lucide-animated/layout-panel-top.tsx +0 -143
- package/src/react-ui/icons/lucide-animated/list.tsx +0 -54
- package/src/react-ui/icons/lucide-animated/package.tsx +0 -24
- package/src/react-ui/icons/lucide-animated/palette.tsx +0 -25
- package/src/react-ui/icons/lucide-animated/plus.tsx +0 -92
- package/src/react-ui/icons/lucide-animated/refresh-cw.tsx +0 -24
- package/src/react-ui/icons/lucide-animated/rocket.tsx +0 -24
- package/src/react-ui/icons/lucide-animated/save.tsx +0 -23
- package/src/react-ui/icons/lucide-animated/search.tsx +0 -94
- package/src/react-ui/icons/lucide-animated/settings.tsx +0 -92
- package/src/react-ui/icons/lucide-animated/terminal.tsx +0 -46
- package/src/react-ui/icons/lucide-animated/trash-2.tsx +0 -25
- package/src/react-ui/icons/lucide-animated/trending-down.tsx +0 -151
- package/src/react-ui/icons/lucide-animated/trending-up.tsx +0 -150
- package/src/react-ui/icons/lucide-animated/type.tsx +0 -23
- package/src/react-ui/icons/lucide-animated/upload.tsx +0 -23
- package/src/react-ui/icons/lucide-animated/x.tsx +0 -102
- package/src/react-ui/index.ts +0 -30
- package/src/react-ui/lib/get-strict-context.tsx +0 -56
- package/src/react-ui/lib/icon-wrapper.tsx +0 -70
- package/src/react-ui/lib/index.ts +0 -9
- package/src/react-ui/lib/utils.ts +0 -24
- package/src/react-ui/primitives/AutoHeight/index.tsx +0 -74
- package/src/react-ui/primitives/CountingNumber/index.tsx +0 -147
- package/src/react-ui/primitives/Highlight/Highlight.types.ts +0 -136
- package/src/react-ui/primitives/Highlight/index.tsx +0 -577
- package/src/react-ui/primitives/Slot/index.tsx +0 -128
- package/src/react-ui/primitives/index.ts +0 -16
- package/src/react-ui/primitives/waapi/Gooey/Gooey.types.ts +0 -141
- package/src/react-ui/primitives/waapi/Gooey/GooeyCanvas.tsx +0 -217
- package/src/react-ui/primitives/waapi/Gooey/GooeyFilter.tsx +0 -77
- package/src/react-ui/primitives/waapi/Gooey/MorphPath.tsx +0 -58
- package/src/react-ui/primitives/waapi/Gooey/gooey-utils.ts +0 -253
- package/src/react-ui/primitives/waapi/Gooey/index.ts +0 -50
- package/src/react-ui/primitives/waapi/Gooey/useMorphPath.ts +0 -48
- package/src/react-ui/primitives/waapi/Morph/Morph.types.ts +0 -106
- package/src/react-ui/primitives/waapi/Morph/MorphContext.tsx +0 -21
- package/src/react-ui/primitives/waapi/Morph/index.tsx +0 -56
- package/src/react-ui/primitives/waapi/Morph/techniques/index.ts +0 -12
- package/src/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.ts +0 -89
- package/src/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.ts +0 -176
- package/src/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.ts +0 -87
- package/src/react-ui/primitives/waapi/Morph/useMorph.ts +0 -101
- package/src/react-ui/primitives/waapi/Reorder/Reorder.types.ts +0 -177
- package/src/react-ui/primitives/waapi/Reorder/index.tsx +0 -260
- package/src/react-ui/primitives/waapi/Reorder/useReorder.ts +0 -47
- package/src/react-ui/primitives/waapi/Reorder/useReorderPresence.ts +0 -209
- package/src/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.ts +0 -104
- package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.ts +0 -14
- package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.ts +0 -84
- package/src/react-ui/primitives/waapi/SlidingNumber/index.tsx +0 -474
- package/src/react-ui/primitives/waapi/SlidingText/SlidingText.styles.ts +0 -32
- package/src/react-ui/primitives/waapi/SlidingText/SlidingText.types.ts +0 -69
- package/src/react-ui/primitives/waapi/SlidingText/index.tsx +0 -140
- package/src/react-ui/primitives/waapi/core/animationConstants.ts +0 -215
- package/src/react-ui/primitives/waapi/core/index.ts +0 -53
- package/src/react-ui/primitives/waapi/core/types.ts +0 -200
- package/src/react-ui/primitives/waapi/core/useAnimationOrchestrator.ts +0 -430
- package/src/react-ui/primitives/waapi/core/useElementRegistry.ts +0 -81
- package/src/react-ui/primitives/waapi/core/useFLIPAnimation.ts +0 -138
- package/src/react-ui/primitives/waapi/core/usePositionCapture.ts +0 -106
- package/src/react-ui/primitives/waapi/index.ts +0 -139
- package/src/react-ui/styles/animations.css +0 -369
- package/src/react-ui/ui/Accordion/Accordion.styles.ts +0 -72
- package/src/react-ui/ui/Accordion/Accordion.types.ts +0 -199
- package/src/react-ui/ui/Accordion/index.tsx +0 -362
- package/src/react-ui/ui/AlertDialog/AlertDialog.styles.ts +0 -38
- package/src/react-ui/ui/AlertDialog/AlertDialog.types.ts +0 -296
- package/src/react-ui/ui/AlertDialog/index.tsx +0 -540
- package/src/react-ui/ui/Badge/Badge.styles.ts +0 -43
- package/src/react-ui/ui/Badge/Badge.types.ts +0 -26
- package/src/react-ui/ui/Badge/index.tsx +0 -34
- package/src/react-ui/ui/Button/Button.styles.ts +0 -57
- package/src/react-ui/ui/Button/Button.types.ts +0 -63
- package/src/react-ui/ui/Button/index.tsx +0 -155
- package/src/react-ui/ui/Card/Card.styles.ts +0 -32
- package/src/react-ui/ui/Card/Card.types.ts +0 -39
- package/src/react-ui/ui/Card/index.tsx +0 -130
- package/src/react-ui/ui/Checkbox/Checkbox.styles.ts +0 -40
- package/src/react-ui/ui/Checkbox/Checkbox.types.ts +0 -98
- package/src/react-ui/ui/Checkbox/index.tsx +0 -233
- package/src/react-ui/ui/Combobox/Combobox.styles.ts +0 -34
- package/src/react-ui/ui/Combobox/Combobox.types.ts +0 -89
- package/src/react-ui/ui/Combobox/index.tsx +0 -331
- package/src/react-ui/ui/CornerBracket/CornerBracket.styles.ts +0 -38
- package/src/react-ui/ui/CornerBracket/CornerBracket.types.ts +0 -15
- package/src/react-ui/ui/CornerBracket/index.tsx +0 -49
- package/src/react-ui/ui/DataCard/DataCard.styles.ts +0 -94
- package/src/react-ui/ui/DataCard/DataCard.types.ts +0 -125
- package/src/react-ui/ui/DataCard/index.tsx +0 -340
- package/src/react-ui/ui/Dialog/Dialog.styles.ts +0 -59
- package/src/react-ui/ui/Dialog/Dialog.types.ts +0 -284
- package/src/react-ui/ui/Dialog/index.tsx +0 -452
- package/src/react-ui/ui/DropdownMenu/DropdownMenu.styles.ts +0 -35
- package/src/react-ui/ui/DropdownMenu/DropdownMenu.types.ts +0 -81
- package/src/react-ui/ui/DropdownMenu/index.tsx +0 -300
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.css +0 -376
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.styles.ts +0 -85
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.types.ts +0 -180
- package/src/react-ui/ui/DynamicToggle/index.tsx +0 -316
- package/src/react-ui/ui/DynamicToggle/prototype-v7-ios.html +0 -413
- package/src/react-ui/ui/DynamicToggle/prototype-v7.html +0 -615
- package/src/react-ui/ui/DynamicToggle/prototype-v8-gooey-safari.html +0 -560
- package/src/react-ui/ui/DynamicToggle/prototype-v8b-react-structure.html +0 -227
- package/src/react-ui/ui/DynamicToggle/prototype.html +0 -419
- package/src/react-ui/ui/Field/Field.styles.ts +0 -47
- package/src/react-ui/ui/Field/Field.types.ts +0 -60
- package/src/react-ui/ui/Field/index.tsx +0 -254
- package/src/react-ui/ui/Input/Input.styles.ts +0 -11
- package/src/react-ui/ui/Input/Input.types.ts +0 -10
- package/src/react-ui/ui/Input/index.tsx +0 -32
- package/src/react-ui/ui/InputGroup/InputGroup.styles.ts +0 -53
- package/src/react-ui/ui/InputGroup/InputGroup.types.ts +0 -44
- package/src/react-ui/ui/InputGroup/index.tsx +0 -149
- package/src/react-ui/ui/Label/Label.styles.ts +0 -10
- package/src/react-ui/ui/Label/Label.types.ts +0 -9
- package/src/react-ui/ui/Label/index.tsx +0 -27
- package/src/react-ui/ui/Menu/Menu.styles.ts +0 -71
- package/src/react-ui/ui/Menu/Menu.types.ts +0 -425
- package/src/react-ui/ui/Menu/index.tsx +0 -900
- package/src/react-ui/ui/Popover/Popover.styles.ts +0 -55
- package/src/react-ui/ui/Popover/Popover.types.ts +0 -261
- package/src/react-ui/ui/Popover/index.tsx +0 -422
- package/src/react-ui/ui/Progress/Progress.styles.ts +0 -36
- package/src/react-ui/ui/Progress/Progress.types.ts +0 -162
- package/src/react-ui/ui/Progress/index.tsx +0 -254
- package/src/react-ui/ui/Select/Select.styles.ts +0 -30
- package/src/react-ui/ui/Select/Select.types.ts +0 -51
- package/src/react-ui/ui/Select/index.tsx +0 -225
- package/src/react-ui/ui/Separator/Separator.styles.ts +0 -10
- package/src/react-ui/ui/Separator/Separator.types.ts +0 -10
- package/src/react-ui/ui/Separator/index.tsx +0 -37
- package/src/react-ui/ui/Switch/Switch.styles.ts +0 -50
- package/src/react-ui/ui/Switch/Switch.types.ts +0 -155
- package/src/react-ui/ui/Switch/index.tsx +0 -253
- package/src/react-ui/ui/Tabs/Tabs.css +0 -39
- package/src/react-ui/ui/Tabs/Tabs.styles.ts +0 -148
- package/src/react-ui/ui/Tabs/Tabs.types.ts +0 -255
- package/src/react-ui/ui/Tabs/index.tsx +0 -529
- package/src/react-ui/ui/TextFlow/TextFlow.styles.ts +0 -36
- package/src/react-ui/ui/TextFlow/TextFlow.types.ts +0 -118
- package/src/react-ui/ui/TextFlow/index.tsx +0 -276
- package/src/react-ui/ui/Textarea/Textarea.styles.ts +0 -10
- package/src/react-ui/ui/Textarea/Textarea.types.ts +0 -9
- package/src/react-ui/ui/Textarea/index.tsx +0 -27
- package/src/react-ui/ui/Tooltip/Tooltip.styles.ts +0 -43
- package/src/react-ui/ui/Tooltip/Tooltip.types.ts +0 -253
- package/src/react-ui/ui/Tooltip/index.tsx +0 -394
- package/src/react-ui/ui/index.ts +0 -41
- package/src/types/css-modules.d.ts +0 -18
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Gooey morphing utilities — pure functions for SVG filter and path generation.
|
|
3
|
-
*
|
|
4
|
-
* @module @mks2508/mks-ui/react/primitives/waapi/Gooey
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
// Constants
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
|
|
11
|
-
/** Gooey animation timing constants. */
|
|
12
|
-
export const GOOEY_TIMING = {
|
|
13
|
-
/** Expand duration in ms — spring-like with room for overshoot */
|
|
14
|
-
EXPAND_DURATION: 550,
|
|
15
|
-
/** Collapse duration in ms — snappier settle, no overshoot */
|
|
16
|
-
COLLAPSE_DURATION: 400,
|
|
17
|
-
} as const;
|
|
18
|
-
|
|
19
|
-
/** Default gooey filter parameters. */
|
|
20
|
-
export const GOOEY_DEFAULTS = {
|
|
21
|
-
/** Blur = height * BLUR_RATIO */
|
|
22
|
-
BLUR_RATIO: 0.15,
|
|
23
|
-
/** feColorMatrix alpha channel multiplier */
|
|
24
|
-
ALPHA_GAIN: 20,
|
|
25
|
-
/** feColorMatrix alpha channel offset */
|
|
26
|
-
ALPHA_OFFSET: -10,
|
|
27
|
-
/** Default pill height (px) */
|
|
28
|
-
PILL_HEIGHT: 34,
|
|
29
|
-
/** Quadratic bezier curve factor at full expansion */
|
|
30
|
-
CURVE_FACTOR: 14,
|
|
31
|
-
/** Max body corner radius (px) */
|
|
32
|
-
MAX_CORNER_RADIUS: 16,
|
|
33
|
-
/** Corner radius to body-height ratio */
|
|
34
|
-
CORNER_RATIO: 0.45,
|
|
35
|
-
/** Minimum body height delta to show rounded corners */
|
|
36
|
-
MIN_BODY_DELTA: 8,
|
|
37
|
-
} as const;
|
|
38
|
-
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
// Blur computation
|
|
41
|
-
// ---------------------------------------------------------------------------
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Compute the optimal Gaussian blur for a gooey filter based on element height.
|
|
45
|
-
*
|
|
46
|
-
* @param height - Element height in pixels
|
|
47
|
-
* @returns Blur stdDeviation value
|
|
48
|
-
*/
|
|
49
|
-
export function computeBlur(height: number): number {
|
|
50
|
-
return Math.round(height * GOOEY_DEFAULTS.BLUR_RATIO);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Build the feColorMatrix `values` string.
|
|
55
|
-
*
|
|
56
|
-
* @param gain - Alpha multiplier (default: 20)
|
|
57
|
-
* @param offset - Alpha offset (default: -10)
|
|
58
|
-
* @returns Matrix values string for feColorMatrix
|
|
59
|
-
*/
|
|
60
|
-
export function buildColorMatrixValues(
|
|
61
|
-
gain: number = GOOEY_DEFAULTS.ALPHA_GAIN,
|
|
62
|
-
offset: number = GOOEY_DEFAULTS.ALPHA_OFFSET,
|
|
63
|
-
): string {
|
|
64
|
-
return `1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 ${gain} ${offset}`;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Build the CSS filter string with gooey + optional drop-shadow outline.
|
|
69
|
-
*
|
|
70
|
-
* @param filterId - SVG filter ID to reference
|
|
71
|
-
* @param outlineBlur - Drop-shadow blur (px)
|
|
72
|
-
* @param outlineColor - Drop-shadow color
|
|
73
|
-
* @param outlineLayers - Number of stacked drop-shadows for thickness
|
|
74
|
-
* @returns CSS filter property value
|
|
75
|
-
*/
|
|
76
|
-
export function buildFilterString(
|
|
77
|
-
filterId: string,
|
|
78
|
-
outlineBlur: number = 0.5,
|
|
79
|
-
outlineColor: string = 'var(--border)',
|
|
80
|
-
outlineLayers: number = 2,
|
|
81
|
-
): string {
|
|
82
|
-
const goo = `url(#${filterId})`;
|
|
83
|
-
const shadow = `drop-shadow(0 0 ${outlineBlur}px ${outlineColor})`;
|
|
84
|
-
const shadows = Array(outlineLayers).fill(shadow).join(' ');
|
|
85
|
-
return `${goo} ${shadows}`;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// ---------------------------------------------------------------------------
|
|
89
|
-
// Path memoization
|
|
90
|
-
// ---------------------------------------------------------------------------
|
|
91
|
-
|
|
92
|
-
type PathFn = (pw: number, bw: number, th: number, t: number, ph: number) => string;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Memoize a path generation function — caches last result to avoid
|
|
96
|
-
* recomputing identical paths on consecutive animation frames.
|
|
97
|
-
*
|
|
98
|
-
* @param fn - Path generation function
|
|
99
|
-
* @returns Memoized function
|
|
100
|
-
*/
|
|
101
|
-
export function memoizePath(fn: PathFn): PathFn {
|
|
102
|
-
let lastArgs: [number, number, number, number, number] | null = null;
|
|
103
|
-
let lastResult = '';
|
|
104
|
-
return (pw, bw, th, t, ph) => {
|
|
105
|
-
if (lastArgs && lastArgs[0] === pw && lastArgs[1] === bw && lastArgs[2] === th && lastArgs[3] === t && lastArgs[4] === ph) {
|
|
106
|
-
return lastResult;
|
|
107
|
-
}
|
|
108
|
-
lastResult = fn(pw, bw, th, t, ph);
|
|
109
|
-
lastArgs = [pw, bw, th, t, ph];
|
|
110
|
-
return lastResult;
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// ---------------------------------------------------------------------------
|
|
115
|
-
// Parametric SVG path generation
|
|
116
|
-
// ---------------------------------------------------------------------------
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Generate an SVG path for a pill that morphs downward into a body blob.
|
|
120
|
-
* Adapted from goey-toast's morphPathRaw.
|
|
121
|
-
*
|
|
122
|
-
* @param pw - Pill width
|
|
123
|
-
* @param bw - Body width (expanded)
|
|
124
|
-
* @param th - Total height (pill + body)
|
|
125
|
-
* @param t - Transition progress 0 (pill only) → 1 (full blob)
|
|
126
|
-
* @param ph - Pill height (default: PILL_HEIGHT)
|
|
127
|
-
* @returns SVG path d-string
|
|
128
|
-
*/
|
|
129
|
-
export function morphPathDown(
|
|
130
|
-
pw: number,
|
|
131
|
-
bw: number,
|
|
132
|
-
th: number,
|
|
133
|
-
t: number,
|
|
134
|
-
ph: number = GOOEY_DEFAULTS.PILL_HEIGHT,
|
|
135
|
-
): string {
|
|
136
|
-
const pr = ph / 2;
|
|
137
|
-
const pillW = Math.min(pw, bw);
|
|
138
|
-
const bodyH = ph + (th - ph) * t;
|
|
139
|
-
|
|
140
|
-
// Pure pill when t ≤ 0 or body too small
|
|
141
|
-
if (t <= 0 || bodyH - ph < GOOEY_DEFAULTS.MIN_BODY_DELTA) {
|
|
142
|
-
return [
|
|
143
|
-
`M 0,${pr}`,
|
|
144
|
-
`A ${pr},${pr} 0 0 1 ${pr},0`,
|
|
145
|
-
`H ${pillW - pr}`,
|
|
146
|
-
`A ${pr},${pr} 0 0 1 ${pillW},${pr}`,
|
|
147
|
-
`A ${pr},${pr} 0 0 1 ${pillW - pr},${ph}`,
|
|
148
|
-
`H ${pr}`,
|
|
149
|
-
`A ${pr},${pr} 0 0 1 0,${pr}`,
|
|
150
|
-
`Z`,
|
|
151
|
-
].join(' ');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const curve = GOOEY_DEFAULTS.CURVE_FACTOR * t;
|
|
155
|
-
const cr = Math.min(GOOEY_DEFAULTS.MAX_CORNER_RADIUS, (bodyH - ph) * GOOEY_DEFAULTS.CORNER_RATIO);
|
|
156
|
-
const bodyW = pillW + (bw - pillW) * t;
|
|
157
|
-
const bodyTop = ph - curve;
|
|
158
|
-
const qEndX = Math.min(pillW + curve, bodyW - cr);
|
|
159
|
-
|
|
160
|
-
return [
|
|
161
|
-
`M 0,${pr}`,
|
|
162
|
-
`A ${pr},${pr} 0 0 1 ${pr},0`,
|
|
163
|
-
`H ${pillW - pr}`,
|
|
164
|
-
`A ${pr},${pr} 0 0 1 ${pillW},${pr}`,
|
|
165
|
-
`L ${pillW},${bodyTop}`,
|
|
166
|
-
`Q ${pillW},${bodyTop + curve} ${qEndX},${bodyTop + curve}`,
|
|
167
|
-
`H ${bodyW - cr}`,
|
|
168
|
-
`A ${cr},${cr} 0 0 1 ${bodyW},${bodyTop + curve + cr}`,
|
|
169
|
-
`L ${bodyW},${bodyH - cr}`,
|
|
170
|
-
`A ${cr},${cr} 0 0 1 ${bodyW - cr},${bodyH}`,
|
|
171
|
-
`H ${cr}`,
|
|
172
|
-
`A ${cr},${cr} 0 0 1 0,${bodyH - cr}`,
|
|
173
|
-
`Z`,
|
|
174
|
-
].join(' ');
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Generate an SVG path for a pill that morphs UPWARD into a body blob.
|
|
179
|
-
* Used for DynamicToggle's bubble-above-pill layout.
|
|
180
|
-
*
|
|
181
|
-
* @param pw - Pill width
|
|
182
|
-
* @param bw - Body (bubble) width
|
|
183
|
-
* @param th - Total height (bubble + pill)
|
|
184
|
-
* @param t - Transition progress 0 (pill only) → 1 (full blob with bubble)
|
|
185
|
-
* @param ph - Pill height
|
|
186
|
-
* @returns SVG path d-string
|
|
187
|
-
*/
|
|
188
|
-
export function morphPathUp(
|
|
189
|
-
pw: number,
|
|
190
|
-
bw: number,
|
|
191
|
-
th: number,
|
|
192
|
-
t: number,
|
|
193
|
-
ph: number = GOOEY_DEFAULTS.PILL_HEIGHT,
|
|
194
|
-
): string {
|
|
195
|
-
const pr = ph / 2;
|
|
196
|
-
const pillW = Math.min(pw, bw);
|
|
197
|
-
const bubbleH = (th - ph) * t;
|
|
198
|
-
|
|
199
|
-
// Pure pill when t ≤ 0 or bubble too small
|
|
200
|
-
if (t <= 0 || bubbleH < GOOEY_DEFAULTS.MIN_BODY_DELTA) {
|
|
201
|
-
const y0 = th - ph;
|
|
202
|
-
return [
|
|
203
|
-
`M 0,${y0 + pr}`,
|
|
204
|
-
`A ${pr},${pr} 0 0 1 ${pr},${y0}`,
|
|
205
|
-
`H ${pillW - pr}`,
|
|
206
|
-
`A ${pr},${pr} 0 0 1 ${pillW},${y0 + pr}`,
|
|
207
|
-
`A ${pr},${pr} 0 0 1 ${pillW - pr},${y0 + ph}`,
|
|
208
|
-
`H ${pr}`,
|
|
209
|
-
`A ${pr},${pr} 0 0 1 0,${y0 + pr}`,
|
|
210
|
-
`Z`,
|
|
211
|
-
].join(' ');
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const curve = GOOEY_DEFAULTS.CURVE_FACTOR * t;
|
|
215
|
-
const cr = Math.min(GOOEY_DEFAULTS.MAX_CORNER_RADIUS, bubbleH * GOOEY_DEFAULTS.CORNER_RATIO);
|
|
216
|
-
const bubbleW = pillW + (bw - pillW) * t;
|
|
217
|
-
const pillTop = th - ph;
|
|
218
|
-
const bubbleBottom = pillTop + curve;
|
|
219
|
-
const bubbleTop = pillTop - bubbleH + curve;
|
|
220
|
-
const qEndX = Math.min(pillW + curve, bubbleW - cr);
|
|
221
|
-
|
|
222
|
-
return [
|
|
223
|
-
// Pill bottom-left
|
|
224
|
-
`M 0,${pillTop + pr}`,
|
|
225
|
-
`A ${pr},${pr} 0 0 1 0,${pillTop + ph - pr}`,
|
|
226
|
-
// Pill bottom
|
|
227
|
-
`A ${pr},${pr} 0 0 1 ${pr},${pillTop + ph}`,
|
|
228
|
-
`H ${pillW - pr}`,
|
|
229
|
-
`A ${pr},${pr} 0 0 1 ${pillW},${pillTop + ph - pr}`,
|
|
230
|
-
// Pill right up to junction
|
|
231
|
-
`L ${pillW},${bubbleBottom}`,
|
|
232
|
-
// Right organic curve: pill to bubble
|
|
233
|
-
`Q ${pillW},${bubbleBottom - curve} ${qEndX},${bubbleBottom - curve}`,
|
|
234
|
-
// Bubble right side
|
|
235
|
-
`H ${bubbleW - cr}`,
|
|
236
|
-
`A ${cr},${cr} 0 0 0 ${bubbleW},${bubbleBottom - curve - cr}`,
|
|
237
|
-
// Bubble right edge up
|
|
238
|
-
`L ${bubbleW},${bubbleTop + cr}`,
|
|
239
|
-
// Bubble top-right corner
|
|
240
|
-
`A ${cr},${cr} 0 0 0 ${bubbleW - cr},${bubbleTop}`,
|
|
241
|
-
// Bubble top
|
|
242
|
-
`H ${cr}`,
|
|
243
|
-
// Bubble top-left corner
|
|
244
|
-
`A ${cr},${cr} 0 0 0 0,${bubbleTop + cr}`,
|
|
245
|
-
// Left edge down to pill
|
|
246
|
-
`Z`,
|
|
247
|
-
].join(' ');
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/** Memoized versions for animation performance. */
|
|
251
|
-
export const morphPathDownMemo = memoizePath(morphPathDown);
|
|
252
|
-
export const morphPathUpMemo = memoizePath(morphPathUp);
|
|
253
|
-
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Gooey — SVG-based morphing primitives for organic shape merging.
|
|
3
|
-
*
|
|
4
|
-
* Two techniques:
|
|
5
|
-
* - **Filter**: `GooeyCanvas` / `GooeyFilter` — SVG filter merges same-colored shapes
|
|
6
|
-
* - **Path**: `MorphPath` / `useMorphPath` — parametric SVG path with Bezier junctions
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```tsx
|
|
10
|
-
* // Filter approach — automatic merge
|
|
11
|
-
* <GooeyCanvas height={40}>
|
|
12
|
-
* <div className="bg-card rounded-full h-10 w-64" />
|
|
13
|
-
* <div className="bg-card absolute bottom-full rounded-lg h-6 w-32" />
|
|
14
|
-
* </GooeyCanvas>
|
|
15
|
-
*
|
|
16
|
-
* // Path approach — precise control
|
|
17
|
-
* <svg><MorphPath pillWidth={260} bodyWidth={180} totalHeight={60} progress={0.5} fill="var(--card)" /></svg>
|
|
18
|
-
* ```
|
|
19
|
-
*
|
|
20
|
-
* @module @mks2508/mks-ui/react/primitives/waapi/Gooey
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
// Components
|
|
24
|
-
export { GooeyFilter } from './GooeyFilter';
|
|
25
|
-
export { GooeyCanvas } from './GooeyCanvas';
|
|
26
|
-
export { MorphPath } from './MorphPath';
|
|
27
|
-
|
|
28
|
-
// Hooks
|
|
29
|
-
export { useMorphPath } from './useMorphPath';
|
|
30
|
-
|
|
31
|
-
// Utilities
|
|
32
|
-
export {
|
|
33
|
-
GOOEY_DEFAULTS,
|
|
34
|
-
computeBlur,
|
|
35
|
-
buildColorMatrixValues,
|
|
36
|
-
buildFilterString,
|
|
37
|
-
memoizePath,
|
|
38
|
-
morphPathDown,
|
|
39
|
-
morphPathUp,
|
|
40
|
-
morphPathDownMemo,
|
|
41
|
-
morphPathUpMemo,
|
|
42
|
-
} from './gooey-utils';
|
|
43
|
-
|
|
44
|
-
// Types
|
|
45
|
-
export type {
|
|
46
|
-
IGooeyFilterProps,
|
|
47
|
-
IGooeyCanvasProps,
|
|
48
|
-
IMorphPathProps,
|
|
49
|
-
IUseMorphPathOptions,
|
|
50
|
-
} from './Gooey.types';
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* useMorphPath — hook that generates a parametric SVG path d-string.
|
|
5
|
-
*
|
|
6
|
-
* Returns a memoized path for a pill shape morphing into a blob.
|
|
7
|
-
* Use with `<path d={path} />` in an SVG element.
|
|
8
|
-
*
|
|
9
|
-
* @param opts - Dimensions and progress
|
|
10
|
-
* @returns SVG path d-string
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```tsx
|
|
14
|
-
* const path = useMorphPath({
|
|
15
|
-
* pillWidth: 260,
|
|
16
|
-
* bodyWidth: 180,
|
|
17
|
-
* totalHeight: 60,
|
|
18
|
-
* progress: expanded ? 1 : 0,
|
|
19
|
-
* direction: 'up',
|
|
20
|
-
* });
|
|
21
|
-
* return <svg><path d={path} fill="var(--card)" /></svg>;
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* @module @mks2508/mks-ui/react/primitives/waapi/Gooey
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
import { useMemo } from 'react';
|
|
28
|
-
import { morphPathDown, morphPathUp, GOOEY_DEFAULTS } from './gooey-utils';
|
|
29
|
-
import type { IUseMorphPathOptions } from './Gooey.types';
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Generate a parametric SVG morph path from dimensions and progress.
|
|
33
|
-
*/
|
|
34
|
-
function useMorphPath({
|
|
35
|
-
pillWidth,
|
|
36
|
-
bodyWidth,
|
|
37
|
-
totalHeight,
|
|
38
|
-
progress,
|
|
39
|
-
pillHeight = GOOEY_DEFAULTS.PILL_HEIGHT,
|
|
40
|
-
direction = 'down',
|
|
41
|
-
}: IUseMorphPathOptions): string {
|
|
42
|
-
return useMemo(() => {
|
|
43
|
-
const fn = direction === 'up' ? morphPathUp : morphPathDown;
|
|
44
|
-
return fn(pillWidth, bodyWidth, totalHeight, progress, pillHeight);
|
|
45
|
-
}, [pillWidth, bodyWidth, totalHeight, progress, pillHeight, direction]);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export { useMorphPath };
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import type { ReactNode, RefObject } from 'react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Available morphing techniques.
|
|
5
|
-
*/
|
|
6
|
-
export type MorphTechnique = 'flip-clip-path' | 'css-grid' | 'view-transitions';
|
|
7
|
-
|
|
8
|
-
// =============================================================================
|
|
9
|
-
// FLIP + clip-path
|
|
10
|
-
// =============================================================================
|
|
11
|
-
|
|
12
|
-
/** Options for the FLIP + clip-path morphing technique */
|
|
13
|
-
export interface IFLIPClipPathOptions {
|
|
14
|
-
duration?: number;
|
|
15
|
-
easing?: string;
|
|
16
|
-
clipPathStart?: string;
|
|
17
|
-
clipPathEnd?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** API returned by useFLIPClipPath */
|
|
21
|
-
export interface IFLIPClipPathAPI {
|
|
22
|
-
isMorphing: boolean;
|
|
23
|
-
morph: (fromElement: HTMLElement, toElement: HTMLElement) => Promise<void>;
|
|
24
|
-
cancel: () => void;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// =============================================================================
|
|
28
|
-
// CSS Grid
|
|
29
|
-
// =============================================================================
|
|
30
|
-
|
|
31
|
-
/** Options for the CSS Grid expand/collapse technique */
|
|
32
|
-
export interface ICSSGridMorphOptions {
|
|
33
|
-
duration?: number;
|
|
34
|
-
easing?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** API returned by useCSSGridMorph */
|
|
38
|
-
export interface ICSSGridMorphAPI {
|
|
39
|
-
isExpanded: boolean;
|
|
40
|
-
expand: () => void;
|
|
41
|
-
collapse: () => void;
|
|
42
|
-
toggle: () => void;
|
|
43
|
-
containerRef: RefObject<HTMLElement | null>;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// =============================================================================
|
|
47
|
-
// View Transitions
|
|
48
|
-
// =============================================================================
|
|
49
|
-
|
|
50
|
-
/** Options for the View Transitions API wrapper */
|
|
51
|
-
export interface IViewTransitionsOptions {
|
|
52
|
-
name?: string;
|
|
53
|
-
types?: string[];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** API returned by useViewTransitions */
|
|
57
|
-
export interface IViewTransitionsAPI {
|
|
58
|
-
isSupported: boolean;
|
|
59
|
-
startTransition: (callback: () => void | Promise<void>) => Promise<void>;
|
|
60
|
-
setTypes: (types: string[]) => void;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// =============================================================================
|
|
64
|
-
// Unified Morph
|
|
65
|
-
// =============================================================================
|
|
66
|
-
|
|
67
|
-
/** Configuration for useMorph hook */
|
|
68
|
-
export interface IUseMorphConfig {
|
|
69
|
-
technique?: MorphTechnique;
|
|
70
|
-
duration?: number;
|
|
71
|
-
easing?: string;
|
|
72
|
-
onMorphStart?: () => void;
|
|
73
|
-
onMorphEnd?: () => void;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** Return type for useMorph hook */
|
|
77
|
-
export interface IUseMorphReturn {
|
|
78
|
-
isMorphing: boolean;
|
|
79
|
-
technique: MorphTechnique;
|
|
80
|
-
isViewTransitionsSupported: boolean;
|
|
81
|
-
morph: (fromElement: HTMLElement, toElement: HTMLElement) => Promise<void>;
|
|
82
|
-
cancel: () => void;
|
|
83
|
-
flipClipPath: IFLIPClipPathAPI;
|
|
84
|
-
cssGrid: ICSSGridMorphAPI;
|
|
85
|
-
viewTransitions: IViewTransitionsAPI;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// =============================================================================
|
|
89
|
-
// Component Props
|
|
90
|
-
// =============================================================================
|
|
91
|
-
|
|
92
|
-
/** Props for Morph container component */
|
|
93
|
-
export interface IMorphProps {
|
|
94
|
-
children: ReactNode;
|
|
95
|
-
technique?: MorphTechnique;
|
|
96
|
-
duration?: number;
|
|
97
|
-
easing?: string;
|
|
98
|
-
className?: string;
|
|
99
|
-
onMorphStart?: () => void;
|
|
100
|
-
onMorphEnd?: () => void;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/** Context value for Morph components */
|
|
104
|
-
export interface IMorphContextValue {
|
|
105
|
-
morph: IUseMorphReturn;
|
|
106
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import React, { createContext, useContext } from 'react';
|
|
4
|
-
import type { IMorphContextValue } from './Morph.types';
|
|
5
|
-
|
|
6
|
-
const MorphContext = createContext<IMorphContextValue | null>(null);
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Hook to access morph context
|
|
10
|
-
*
|
|
11
|
-
* @throws Error if used outside of Morph provider
|
|
12
|
-
*/
|
|
13
|
-
export function useMorphContext(): IMorphContextValue {
|
|
14
|
-
const context = useContext(MorphContext);
|
|
15
|
-
if (!context) {
|
|
16
|
-
throw new Error('useMorphContext must be used within a Morph component');
|
|
17
|
-
}
|
|
18
|
-
return context;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export { MorphContext };
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import React, { useMemo, type ReactNode } from 'react';
|
|
4
|
-
import { MorphContext } from './MorphContext';
|
|
5
|
-
import { useMorph } from './useMorph';
|
|
6
|
-
import type { IMorphProps, IMorphContextValue } from './Morph.types';
|
|
7
|
-
import { cn } from '@/react-ui/lib/utils';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Morph - Container component for morphable elements.
|
|
11
|
-
*
|
|
12
|
-
* Provides morphing capabilities to child components through context.
|
|
13
|
-
* Supports FLIP + clip-path, CSS Grid, and View Transitions techniques.
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```tsx
|
|
17
|
-
* <Morph technique="flip-clip-path" duration={300}>
|
|
18
|
-
* <button onClick={() => morph(fromRef.current, toRef.current)}>
|
|
19
|
-
* Morph
|
|
20
|
-
* </button>
|
|
21
|
-
* </Morph>
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export function Morph({
|
|
25
|
-
children,
|
|
26
|
-
technique = 'flip-clip-path',
|
|
27
|
-
duration,
|
|
28
|
-
easing,
|
|
29
|
-
className = '',
|
|
30
|
-
onMorphStart,
|
|
31
|
-
onMorphEnd
|
|
32
|
-
}: IMorphProps): ReactNode {
|
|
33
|
-
const morph = useMorph({
|
|
34
|
-
technique,
|
|
35
|
-
duration,
|
|
36
|
-
easing,
|
|
37
|
-
onMorphStart,
|
|
38
|
-
onMorphEnd
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
const contextValue = useMemo<IMorphContextValue>(() => ({
|
|
42
|
-
morph
|
|
43
|
-
}), [morph]);
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<MorphContext.Provider value={contextValue}>
|
|
47
|
-
<div className={cn('morph-container', className)}>
|
|
48
|
-
{children}
|
|
49
|
-
</div>
|
|
50
|
-
</MorphContext.Provider>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
Morph.displayName = 'Morph';
|
|
55
|
-
|
|
56
|
-
export type { IMorphProps, IMorphContextValue };
|
|
@@ -1,12 +0,0 @@
|
|
|
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
|
-
|
|
10
|
-
export { useFLIPClipPath } from './useFLIPClipPath';
|
|
11
|
-
export { useCSSGridMorph } from './useCSSGridMorph';
|
|
12
|
-
export { useViewTransitions } from './useViewTransitions';
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { useRef, useCallback, useState } from 'react';
|
|
3
|
-
import { TIMING, EASINGS } from '../../core/animationConstants';
|
|
4
|
-
import type { ICSSGridMorphOptions, ICSSGridMorphAPI } from '../Morph.types';
|
|
5
|
-
|
|
6
|
-
const DEFAULT_DURATION = TIMING.FLIP_DURATION;
|
|
7
|
-
const DEFAULT_EASING = EASINGS.MATERIAL_STANDARD;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Hook for CSS Grid-based expand/collapse animations.
|
|
11
|
-
*
|
|
12
|
-
* Uses the `grid-template-rows: 0fr/1fr` technique for smooth height
|
|
13
|
-
* animations without needing to know the content height in advance.
|
|
14
|
-
*
|
|
15
|
-
* CSS required on container:
|
|
16
|
-
* ```css
|
|
17
|
-
* .morph-container {
|
|
18
|
-
* display: grid;
|
|
19
|
-
* grid-template-rows: 0fr;
|
|
20
|
-
* transition: grid-template-rows 300ms ease;
|
|
21
|
-
* }
|
|
22
|
-
* .morph-container.expanded {
|
|
23
|
-
* grid-template-rows: 1fr;
|
|
24
|
-
* }
|
|
25
|
-
* .morph-content {
|
|
26
|
-
* overflow: hidden;
|
|
27
|
-
* }
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @param options - Duration and easing overrides
|
|
31
|
-
* @returns Grid morph API with expand, collapse, toggle, and container ref
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```tsx
|
|
35
|
-
* const { isExpanded, toggle, containerRef } = useCSSGridMorph();
|
|
36
|
-
*
|
|
37
|
-
* return (
|
|
38
|
-
* <div ref={containerRef} className={isExpanded ? 'expanded' : ''}>
|
|
39
|
-
* <div className="morph-content">Collapsible content</div>
|
|
40
|
-
* </div>
|
|
41
|
-
* );
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
export function useCSSGridMorph(options?: ICSSGridMorphOptions): ICSSGridMorphAPI {
|
|
45
|
-
const [isExpanded, setIsExpanded] = useState(false);
|
|
46
|
-
const containerRef = useRef<HTMLElement | null>(null);
|
|
47
|
-
const optionsRef = useRef(options);
|
|
48
|
-
|
|
49
|
-
const duration = optionsRef.current?.duration ?? DEFAULT_DURATION;
|
|
50
|
-
const easing = optionsRef.current?.easing ?? DEFAULT_EASING;
|
|
51
|
-
|
|
52
|
-
const applyTransition = useCallback(() => {
|
|
53
|
-
if (containerRef.current) {
|
|
54
|
-
containerRef.current.style.transition = `grid-template-rows ${duration}ms ${easing}`;
|
|
55
|
-
}
|
|
56
|
-
}, [duration, easing]);
|
|
57
|
-
|
|
58
|
-
const expand = useCallback(() => {
|
|
59
|
-
applyTransition();
|
|
60
|
-
if (containerRef.current) {
|
|
61
|
-
containerRef.current.style.gridTemplateRows = '1fr';
|
|
62
|
-
}
|
|
63
|
-
setIsExpanded(true);
|
|
64
|
-
}, [applyTransition]);
|
|
65
|
-
|
|
66
|
-
const collapse = useCallback(() => {
|
|
67
|
-
applyTransition();
|
|
68
|
-
if (containerRef.current) {
|
|
69
|
-
containerRef.current.style.gridTemplateRows = '0fr';
|
|
70
|
-
}
|
|
71
|
-
setIsExpanded(false);
|
|
72
|
-
}, [applyTransition]);
|
|
73
|
-
|
|
74
|
-
const toggle = useCallback(() => {
|
|
75
|
-
if (isExpanded) {
|
|
76
|
-
collapse();
|
|
77
|
-
} else {
|
|
78
|
-
expand();
|
|
79
|
-
}
|
|
80
|
-
}, [isExpanded, expand, collapse]);
|
|
81
|
-
|
|
82
|
-
return {
|
|
83
|
-
isExpanded,
|
|
84
|
-
expand,
|
|
85
|
-
collapse,
|
|
86
|
-
toggle,
|
|
87
|
-
containerRef
|
|
88
|
-
};
|
|
89
|
-
}
|