@mks2508/mks-ui 0.5.2 → 0.5.7
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/index.js +8 -3
- package/dist/react-ui/primitives/index.js +5 -0
- package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts +120 -0
- package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts +10 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.js +190 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyFilter.d.ts +7 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyFilter.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/GooeyFilter.js +78 -0
- package/dist/react-ui/primitives/waapi/Gooey/MorphPath.d.ts +7 -0
- package/dist/react-ui/primitives/waapi/Gooey/MorphPath.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/MorphPath.js +51 -0
- package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.d.ts +94 -0
- package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.js +182 -0
- package/dist/react-ui/primitives/waapi/Gooey/index.d.ts +28 -0
- package/dist/react-ui/primitives/waapi/Gooey/index.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/index.js +5 -0
- package/dist/react-ui/primitives/waapi/Gooey/useMorphPath.d.ts +7 -0
- package/dist/react-ui/primitives/waapi/Gooey/useMorphPath.d.ts.map +1 -0
- package/dist/react-ui/primitives/waapi/Gooey/useMorphPath.js +47 -0
- package/dist/react-ui/primitives/waapi/index.d.ts +2 -0
- package/dist/react-ui/primitives/waapi/index.d.ts.map +1 -1
- package/dist/react-ui/primitives/waapi/index.js +6 -0
- package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts +26 -16
- package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts.map +1 -1
- package/dist/react-ui/ui/DataCard/DataCard.styles.js +36 -74
- package/dist/react-ui/ui/DataCard/DataCard.types.d.ts +50 -70
- package/dist/react-ui/ui/DataCard/DataCard.types.d.ts.map +1 -1
- package/dist/react-ui/ui/DataCard/index.d.ts +24 -93
- package/dist/react-ui/ui/DataCard/index.d.ts.map +1 -1
- package/dist/react-ui/ui/DataCard/index.js +76 -118
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle-DOR3Ld-k.css +376 -0
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.css +376 -0
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.js +0 -0
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts +20 -8
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.js +55 -27
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts +69 -14
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/index.d.ts +22 -20
- package/dist/react-ui/ui/DynamicToggle/index.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/index.js +133 -96
- package/dist/react-ui/ui/Switch/index.js +1 -1
- package/dist/react-ui/ui/index.js +2 -2
- package/package.json +2 -2
- package/src/css.d.ts +1 -0
- package/src/react-ui/primitives/waapi/Gooey/Gooey.types.ts +141 -0
- package/src/react-ui/primitives/waapi/Gooey/GooeyCanvas.tsx +217 -0
- package/src/react-ui/primitives/waapi/Gooey/GooeyFilter.tsx +77 -0
- package/src/react-ui/primitives/waapi/Gooey/MorphPath.tsx +58 -0
- package/src/react-ui/primitives/waapi/Gooey/gooey-utils.ts +253 -0
- package/src/react-ui/primitives/waapi/Gooey/index.ts +50 -0
- package/src/react-ui/primitives/waapi/Gooey/useMorphPath.ts +48 -0
- package/src/react-ui/primitives/waapi/index.ts +23 -0
- package/src/react-ui/ui/DataCard/DataCard.styles.ts +45 -101
- package/src/react-ui/ui/DataCard/DataCard.types.ts +52 -73
- package/src/react-ui/ui/DataCard/index.tsx +118 -184
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.css +320 -94
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.styles.ts +60 -40
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.types.ts +101 -14
- package/src/react-ui/ui/DynamicToggle/index.tsx +172 -96
- package/src/react-ui/ui/DynamicToggle/prototype-v7-ios.html +413 -0
- package/src/react-ui/ui/DynamicToggle/prototype-v7.html +615 -0
- package/src/react-ui/ui/DynamicToggle/prototype-v8-gooey-safari.html +560 -0
- package/src/react-ui/ui/DynamicToggle/prototype-v8b-react-structure.html +227 -0
- package/src/react-ui/ui/DynamicToggle/prototype.html +419 -0
- package/src/react-ui/ui/Switch/index.tsx +1 -1
- /package/dist/react-ui/blocks/Terminal/panel/{terminal-filter-dropdown.module-DAcl_XQZ.css → terminal-filter-dropdown.module-C6oDcFBS.css} +0 -0
- /package/dist/react-ui/blocks/Terminal/panel/{terminal-session-tabs.module-DNAop5e3.css → terminal-session-tabs.module-D_-sgyza.css} +0 -0
- /package/dist/react-ui/components/MorphingPopover/{morphing-popover.module-BJrjXisF.css → morphing-popover.module-B1ftlaYj.css} +0 -0
package/dist/react-ui/index.js
CHANGED
|
@@ -22,6 +22,11 @@ import { useCSSGridMorph } from "./primitives/waapi/Morph/techniques/useCSSGridM
|
|
|
22
22
|
import { useViewTransitions } from "./primitives/waapi/Morph/techniques/useViewTransitions.js";
|
|
23
23
|
import { useMorph } from "./primitives/waapi/Morph/useMorph.js";
|
|
24
24
|
import { Morph } from "./primitives/waapi/Morph/index.js";
|
|
25
|
+
import { GOOEY_DEFAULTS, buildColorMatrixValues, buildFilterString, computeBlur, morphPathDown, morphPathUp } from "./primitives/waapi/Gooey/gooey-utils.js";
|
|
26
|
+
import { GooeyFilter } from "./primitives/waapi/Gooey/GooeyFilter.js";
|
|
27
|
+
import { GooeyCanvas } from "./primitives/waapi/Gooey/GooeyCanvas.js";
|
|
28
|
+
import { useMorphPath } from "./primitives/waapi/Gooey/useMorphPath.js";
|
|
29
|
+
import { MorphPath } from "./primitives/waapi/Gooey/MorphPath.js";
|
|
25
30
|
import "./primitives/index.js";
|
|
26
31
|
import { getStrictContext } from "./lib/get-strict-context.js";
|
|
27
32
|
import { useControlledState } from "./hooks/State/UseControlledState.js";
|
|
@@ -68,8 +73,8 @@ import { dataCardStyles, dataCardVariants } from "./ui/DataCard/DataCard.styles.
|
|
|
68
73
|
import { DataCard, DataCardActions, DataCardBracket, DataCardLabel, DataCardToggle, DataCardValue, useDataCard } from "./ui/DataCard/index.js";
|
|
69
74
|
import { useListFormat } from "./hooks/Formatting/UseListFormat.js";
|
|
70
75
|
import { TextFlow } from "./ui/TextFlow/index.js";
|
|
71
|
-
import { dynamicToggleStyles } from "./ui/DynamicToggle/DynamicToggle.styles.js";
|
|
72
|
-
import { DynamicToggle, DynamicToggleGroup, DynamicToggleOption } from "./ui/DynamicToggle/index.js";
|
|
76
|
+
import { dynamicToggleStyles, dynamicToggleVariants } from "./ui/DynamicToggle/DynamicToggle.styles.js";
|
|
77
|
+
import { DynamicToggle, DynamicToggleGroup, DynamicToggleOption, useDynamicToggle } from "./ui/DynamicToggle/index.js";
|
|
73
78
|
import "./ui/index.js";
|
|
74
79
|
import { MorphingPopover, MorphingPopoverWithTarget } from "./components/MorphingPopover/index.js";
|
|
75
80
|
import "./components/index.js";
|
|
@@ -110,4 +115,4 @@ import { HugeIcons } from "./icons/index.js";
|
|
|
110
115
|
import { IconWrapper } from "./lib/icon-wrapper.js";
|
|
111
116
|
import "./lib/index.js";
|
|
112
117
|
|
|
113
|
-
export { ANIMATION_CONFIGS, ANIMATION_DEFAULTS, Accordion, AccordionHeader, AccordionItem, AccordionPanel, AccordionStyles, AccordionTrigger, ActivityIcon, AlertDialog, AlertDialogBackdrop, AlertDialogClose, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPopup, AlertDialogPortal, AlertDialogStyles, AlertDialogTitle, AlertDialogTrigger, ArrowDownToLineIcon, ArrowUpIcon, AutoHeight, Badge, BellElectricIcon, BellIcon, BotIcon, BoxIcon, Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Check, Checkbox, CheckboxIndicator, CircleCheckIcon, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, CornerBracket, CountingNumber, DataCard, DataCardActions, DataCardBracket, DataCardLabel, DataCardToggle, DataCardValue, DeleteIcon, Dialog, DialogBackdrop, DialogClose, DialogDescription, DialogFooter, DialogHeader, DialogPopup, DialogPortal, DialogTitle, DialogTrigger, DownloadIcon, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, DynamicToggle, DynamicToggleGroup, DynamicToggleOption, EASINGS, EFFECTS, Edit2, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Globe, Highlight, HighlightItem, HomeIcon, HugeIcons, IconWrapper, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, Layers, LayoutPanelTopIcon, ListIcon, Menu, MenuArrow, MenuCheckboxItem, MenuCheckboxItemIndicator, MenuGroup, MenuGroupLabel, MenuHighlight, MenuHighlightItem, MenuItem, MenuPopup, MenuPortal, MenuPositioner, MenuRadioGroup, MenuRadioItem, MenuRadioItemIndicator, MenuSeparator, MenuShortcut, MenuSubmenu, MenuSubmenuTrigger, MenuTrigger, Morph, MorphingPopover, MorphingPopoverWithTarget, PRESETS, Package, Palette, PlusIcon, Popover, PopoverArrow, PopoverBackdrop, PopoverClose, PopoverDescription, PopoverPopup, PopoverPortal, PopoverPositioner, PopoverTitle, PopoverTrigger, Progress, ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue, RESPONSIVE_CONFIGS, RefreshCw, ReorderRoot as Reorder, Rocket, Save, SearchIcon, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SettingsIcon, SlidingNumber, SlidingText, Slot, Switch, SwitchIcon, SwitchThumb, TIMING, TRANSFORMS, Tabs, TabsHighlight, TabsHighlightItem, TabsList, TabsPanel, TabsPanels, TabsTab, TerminalIcon, TextFlow, Textarea, Tooltip, TooltipArrow, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipProvider, TooltipTrigger, Trash2, TrendingDownIcon, TrendingUpIcon, Type, Upload, XIcon, accordionVariants, badgeVariants, bracketVariants, buttonStateStyles, buttonVariants, calculateSeparatorCoordination, cardVariants, checkboxStyles, cn, dataCardStyles, dataCardVariants, dialogStyles, dynamicToggleStyles, fieldVariants, getResponsiveDuration, getResponsiveStagger, getStrictContext, inputGroupAddonVariants, inputGroupButtonVariants, popoverStyles, progressStyles, shouldShowSeparator, switchStyles, tabsIndicatorVariants, tabsListVariants, tabsTabVariants, tooltipStyles, useAccordionItem, useAlertDialog, useAnimationOrchestrator, useAutoHeight, useCSSGridMorph, useCheckbox, useComboboxAnchor, useControlledState, useDataCard, useDataState, useDialog, useElementRegistry, useFLIPAnimation, useFLIPClipPath, useHighlight, useIsInView, useListFormat, useMenu, useMenuActiveValue, useMorph, useMorphContext, usePopover, usePositionCapture, useProgress, useReorder, useReorderPresence, useSwitch, useTooltip, useViewTransitions };
|
|
118
|
+
export { ANIMATION_CONFIGS, ANIMATION_DEFAULTS, Accordion, AccordionHeader, AccordionItem, AccordionPanel, AccordionStyles, AccordionTrigger, ActivityIcon, AlertDialog, AlertDialogBackdrop, AlertDialogClose, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPopup, AlertDialogPortal, AlertDialogStyles, AlertDialogTitle, AlertDialogTrigger, ArrowDownToLineIcon, ArrowUpIcon, AutoHeight, Badge, BellElectricIcon, BellIcon, BotIcon, BoxIcon, Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Check, Checkbox, CheckboxIndicator, CircleCheckIcon, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, CornerBracket, CountingNumber, DataCard, DataCardActions, DataCardBracket, DataCardLabel, DataCardToggle, DataCardValue, DeleteIcon, Dialog, DialogBackdrop, DialogClose, DialogDescription, DialogFooter, DialogHeader, DialogPopup, DialogPortal, DialogTitle, DialogTrigger, DownloadIcon, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, DynamicToggle, DynamicToggleGroup, DynamicToggleOption, EASINGS, EFFECTS, Edit2, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, GOOEY_DEFAULTS, Globe, GooeyCanvas, GooeyFilter, Highlight, HighlightItem, HomeIcon, HugeIcons, IconWrapper, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, Layers, LayoutPanelTopIcon, ListIcon, Menu, MenuArrow, MenuCheckboxItem, MenuCheckboxItemIndicator, MenuGroup, MenuGroupLabel, MenuHighlight, MenuHighlightItem, MenuItem, MenuPopup, MenuPortal, MenuPositioner, MenuRadioGroup, MenuRadioItem, MenuRadioItemIndicator, MenuSeparator, MenuShortcut, MenuSubmenu, MenuSubmenuTrigger, MenuTrigger, Morph, MorphPath, MorphingPopover, MorphingPopoverWithTarget, PRESETS, Package, Palette, PlusIcon, Popover, PopoverArrow, PopoverBackdrop, PopoverClose, PopoverDescription, PopoverPopup, PopoverPortal, PopoverPositioner, PopoverTitle, PopoverTrigger, Progress, ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue, RESPONSIVE_CONFIGS, RefreshCw, ReorderRoot as Reorder, Rocket, Save, SearchIcon, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SettingsIcon, SlidingNumber, SlidingText, Slot, Switch, SwitchIcon, SwitchThumb, TIMING, TRANSFORMS, Tabs, TabsHighlight, TabsHighlightItem, TabsList, TabsPanel, TabsPanels, TabsTab, TerminalIcon, TextFlow, Textarea, Tooltip, TooltipArrow, TooltipPopup, TooltipPortal, TooltipPositioner, TooltipProvider, TooltipTrigger, Trash2, TrendingDownIcon, TrendingUpIcon, Type, Upload, XIcon, accordionVariants, badgeVariants, bracketVariants, buildColorMatrixValues, buildFilterString, buttonStateStyles, buttonVariants, calculateSeparatorCoordination, cardVariants, checkboxStyles, cn, computeBlur, dataCardStyles, dataCardVariants, dialogStyles, dynamicToggleStyles, dynamicToggleVariants, fieldVariants, getResponsiveDuration, getResponsiveStagger, getStrictContext, inputGroupAddonVariants, inputGroupButtonVariants, morphPathDown, morphPathUp, popoverStyles, progressStyles, shouldShowSeparator, switchStyles, tabsIndicatorVariants, tabsListVariants, tabsTabVariants, tooltipStyles, useAccordionItem, useAlertDialog, useAnimationOrchestrator, useAutoHeight, useCSSGridMorph, useCheckbox, useComboboxAnchor, useControlledState, useDataCard, useDataState, useDialog, useDynamicToggle, useElementRegistry, useFLIPAnimation, useFLIPClipPath, useHighlight, useIsInView, useListFormat, useMenu, useMenuActiveValue, useMorph, useMorphContext, useMorphPath, usePopover, usePositionCapture, useProgress, useReorder, useReorderPresence, useSwitch, useTooltip, useViewTransitions };
|
|
@@ -19,4 +19,9 @@ import { useCSSGridMorph } from "./waapi/Morph/techniques/useCSSGridMorph.js";
|
|
|
19
19
|
import { useViewTransitions } from "./waapi/Morph/techniques/useViewTransitions.js";
|
|
20
20
|
import { useMorph } from "./waapi/Morph/useMorph.js";
|
|
21
21
|
import { Morph } from "./waapi/Morph/index.js";
|
|
22
|
+
import { GOOEY_DEFAULTS, buildColorMatrixValues, buildFilterString, computeBlur, morphPathDown, morphPathUp } from "./waapi/Gooey/gooey-utils.js";
|
|
23
|
+
import { GooeyFilter } from "./waapi/Gooey/GooeyFilter.js";
|
|
24
|
+
import { GooeyCanvas } from "./waapi/Gooey/GooeyCanvas.js";
|
|
25
|
+
import { useMorphPath } from "./waapi/Gooey/useMorphPath.js";
|
|
26
|
+
import { MorphPath } from "./waapi/Gooey/MorphPath.js";
|
|
22
27
|
import "./waapi/index.js";
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gooey morphing primitive types.
|
|
3
|
+
*
|
|
4
|
+
* @module @mks2508/mks-ui/react/primitives/waapi/Gooey
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Props for the GooeyFilter SVG filter definition.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* <GooeyFilter id="my-goo" blur={8} />
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export interface IGooeyFilterProps {
|
|
15
|
+
/** Unique filter ID — referenced via `filter: url(#id)` */
|
|
16
|
+
id: string;
|
|
17
|
+
/** Gaussian blur stdDeviation (default: 8) */
|
|
18
|
+
blur?: number;
|
|
19
|
+
/** Alpha channel multiplier in feColorMatrix (default: 20) */
|
|
20
|
+
alphaGain?: number;
|
|
21
|
+
/** Alpha channel offset in feColorMatrix (default: -10) */
|
|
22
|
+
alphaOffset?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Props for the GooeyCanvas container.
|
|
26
|
+
*
|
|
27
|
+
* Wraps children with an SVG gooey filter. All same-colored children
|
|
28
|
+
* inside automatically merge visually into an organic blob.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <GooeyCanvas height={40}>
|
|
33
|
+
* <div className="bg-card rounded-full h-10 w-64" />
|
|
34
|
+
* <div className="bg-card absolute bottom-full w-32 h-6" />
|
|
35
|
+
* </GooeyCanvas>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export interface IGooeyCanvasProps {
|
|
39
|
+
/** Blur radius override. If omitted, auto-calculated from `height`. */
|
|
40
|
+
blur?: number;
|
|
41
|
+
/** Pill height in px (default: 32) */
|
|
42
|
+
height?: number;
|
|
43
|
+
/** Pill width in px (default: 260) */
|
|
44
|
+
width?: number;
|
|
45
|
+
/** Border radius in px (default: 9999) */
|
|
46
|
+
radius?: number;
|
|
47
|
+
/** Fill color (default: 'var(--card)') */
|
|
48
|
+
fillColor?: string;
|
|
49
|
+
/** Bubble height in px when expanded (default: 40% of height) */
|
|
50
|
+
bubbleHeight?: number;
|
|
51
|
+
/** Bubble inset from edges as fraction 0-1 (default: 0.2) */
|
|
52
|
+
bubbleInset?: number;
|
|
53
|
+
/** Whether the bubble is expanded */
|
|
54
|
+
expanded?: boolean;
|
|
55
|
+
/** Drop-shadow outline blur in px (default: 0.5) */
|
|
56
|
+
outlineBlur?: number;
|
|
57
|
+
/** Drop-shadow outline color (default: 'var(--border)') */
|
|
58
|
+
outlineColor?: string;
|
|
59
|
+
/** Number of stacked drop-shadows for outline thickness (default: 2) */
|
|
60
|
+
outlineLayers?: number;
|
|
61
|
+
/** Alpha gain override */
|
|
62
|
+
alphaGain?: number;
|
|
63
|
+
/** Alpha offset override */
|
|
64
|
+
alphaOffset?: number;
|
|
65
|
+
/** Expand animation duration in ms (default: 550) */
|
|
66
|
+
expandDuration?: number;
|
|
67
|
+
/** Collapse animation duration in ms (default: 400) */
|
|
68
|
+
collapseDuration?: number;
|
|
69
|
+
/** Expand easing override (default: SPRING_GENTLE) */
|
|
70
|
+
expandEasing?: string;
|
|
71
|
+
/** Collapse easing override (default: EASE_OUT_CUBIC) */
|
|
72
|
+
collapseEasing?: string;
|
|
73
|
+
/** Extra className on the filter container */
|
|
74
|
+
className?: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Props for the MorphPath SVG path component.
|
|
78
|
+
*
|
|
79
|
+
* Renders a parametric `<path>` that morphs from a pill shape to a
|
|
80
|
+
* pill+body blob based on the `progress` value.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```tsx
|
|
84
|
+
* <svg>
|
|
85
|
+
* <MorphPath pillWidth={260} bodyWidth={180} totalHeight={60} progress={0.5} fill="var(--card)" />
|
|
86
|
+
* </svg>
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export interface IMorphPathProps extends React.SVGProps<SVGPathElement> {
|
|
90
|
+
/** Pill width in px */
|
|
91
|
+
pillWidth: number;
|
|
92
|
+
/** Body (expanded area) width in px */
|
|
93
|
+
bodyWidth: number;
|
|
94
|
+
/** Total height (pill + body) in px */
|
|
95
|
+
totalHeight: number;
|
|
96
|
+
/** Morph progress: 0 = pill only, 1 = fully expanded */
|
|
97
|
+
progress: number;
|
|
98
|
+
/** Pill height (default: 34) */
|
|
99
|
+
pillHeight?: number;
|
|
100
|
+
/** Body expansion direction relative to pill */
|
|
101
|
+
direction?: 'down' | 'up';
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Options for the useMorphPath hook.
|
|
105
|
+
*/
|
|
106
|
+
export interface IUseMorphPathOptions {
|
|
107
|
+
/** Pill width in px */
|
|
108
|
+
pillWidth: number;
|
|
109
|
+
/** Body width in px */
|
|
110
|
+
bodyWidth: number;
|
|
111
|
+
/** Total height in px */
|
|
112
|
+
totalHeight: number;
|
|
113
|
+
/** Morph progress 0→1 */
|
|
114
|
+
progress: number;
|
|
115
|
+
/** Pill height (default: 34) */
|
|
116
|
+
pillHeight?: number;
|
|
117
|
+
/** Body direction */
|
|
118
|
+
direction?: 'down' | 'up';
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=Gooey.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gooey.types.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/Gooey/Gooey.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC;IACrE,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAMD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IGooeyCanvasProps } from './Gooey.types';
|
|
2
|
+
/**
|
|
3
|
+
* GooeyCanvas — SVG rects + gooey filter, WAAPI-animated bubble.
|
|
4
|
+
*/
|
|
5
|
+
declare function GooeyCanvas({ blur, height, width, radius, fillColor, bubbleHeight: bubbleHeightProp, bubbleInset, expanded, outlineBlur, outlineColor, outlineLayers, alphaGain, alphaOffset, expandDuration, collapseDuration, expandEasing, collapseEasing, className, }: IGooeyCanvasProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
declare namespace GooeyCanvas {
|
|
7
|
+
var displayName: string;
|
|
8
|
+
}
|
|
9
|
+
export { GooeyCanvas };
|
|
10
|
+
//# sourceMappingURL=GooeyCanvas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GooeyCanvas.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/Gooey/GooeyCanvas.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD;;GAEG;AACH,iBAAS,WAAW,CAAC,EACnB,IAAI,EACJ,MAAW,EACX,KAAW,EACX,MAAa,EACb,SAAyB,EACzB,YAAY,EAAE,gBAAgB,EAC9B,WAAiB,EACjB,QAAgB,EAChB,WAAiB,EACjB,YAA8B,EAC9B,aAAiB,EACjB,SAAS,EACT,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,SAAS,GACV,EAAE,iBAAiB,2CAuKnB;kBA1LQ,WAAW;;;AA8LpB,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../../lib/utils.js";
|
|
4
|
+
import { EASINGS, getResponsiveDuration } from "../core/animationConstants.js";
|
|
5
|
+
import { GOOEY_TIMING, computeBlur } from "./gooey-utils.js";
|
|
6
|
+
import * as React$1 from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
|
|
9
|
+
//#region src/react-ui/primitives/waapi/Gooey/GooeyCanvas.tsx
|
|
10
|
+
/**
|
|
11
|
+
* GooeyCanvas — SVG-based gooey filter with animated pill + bubble rects.
|
|
12
|
+
*
|
|
13
|
+
* Uses SVG `<rect>` elements inside a filtered container. The bubble rect
|
|
14
|
+
* animates via WAAPI for smooth cross-browser rendering.
|
|
15
|
+
*
|
|
16
|
+
* Key patterns (derived from Sileo):
|
|
17
|
+
* - Filter applied to canvas div, SVG content inside (not HTML children)
|
|
18
|
+
* - `transform: translateZ(0)` + `contain: layout style` on canvas
|
|
19
|
+
* - No DOM mutation during/after animation — `fill: 'forwards'` only
|
|
20
|
+
* - Readiness gate: 1-frame rAF delay before first animation (Sileo pattern)
|
|
21
|
+
*
|
|
22
|
+
* @module @mks2508/mks-ui/react/primitives/waapi/Gooey
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* GooeyCanvas — SVG rects + gooey filter, WAAPI-animated bubble.
|
|
26
|
+
*/
|
|
27
|
+
function GooeyCanvas({ blur, height = 32, width = 260, radius = 9999, fillColor = "var(--card)", bubbleHeight: bubbleHeightProp, bubbleInset = .2, expanded = false, outlineBlur = .5, outlineColor = "var(--border)", outlineLayers = 2, alphaGain, alphaOffset, expandDuration, collapseDuration, expandEasing, collapseEasing, className }) {
|
|
28
|
+
const filterId = React$1.useId().replace(/:/g, "") + "-goo";
|
|
29
|
+
const computedBlur = blur ?? computeBlur(height);
|
|
30
|
+
const bubbleRectRef = React$1.useRef(null);
|
|
31
|
+
const animRef = React$1.useRef(null);
|
|
32
|
+
const [ready, setReady] = React$1.useState(false);
|
|
33
|
+
const lastValues = React$1.useRef({
|
|
34
|
+
y: -1,
|
|
35
|
+
h: -1
|
|
36
|
+
});
|
|
37
|
+
const pad = 2;
|
|
38
|
+
const effectiveR = Math.min(radius, height / 2);
|
|
39
|
+
const bubbleH = bubbleHeightProp ?? Math.round(height * .4);
|
|
40
|
+
const insetPx = width * bubbleInset;
|
|
41
|
+
const bubbleW = width - 2 * insetPx;
|
|
42
|
+
const bubbleR = Math.min(effectiveR * .6, bubbleH * .45, 12);
|
|
43
|
+
const totalH = height + bubbleH;
|
|
44
|
+
const filterUrl = React$1.useMemo(() => `url(#${filterId})`, [filterId]);
|
|
45
|
+
const outlineShadow = React$1.useMemo(() => {
|
|
46
|
+
const shadow = `drop-shadow(0 0 ${outlineBlur}px ${outlineColor})`;
|
|
47
|
+
return Array(outlineLayers).fill(shadow).join(" ");
|
|
48
|
+
}, [
|
|
49
|
+
outlineBlur,
|
|
50
|
+
outlineColor,
|
|
51
|
+
outlineLayers
|
|
52
|
+
]);
|
|
53
|
+
const canvasStyle = React$1.useMemo(() => ({
|
|
54
|
+
filter: `${filterUrl} ${outlineShadow}`,
|
|
55
|
+
transform: "translateZ(0)",
|
|
56
|
+
contain: "layout style"
|
|
57
|
+
}), [filterUrl, outlineShadow]);
|
|
58
|
+
React$1.useEffect(() => {
|
|
59
|
+
const rect = bubbleRectRef.current;
|
|
60
|
+
if (!rect) return;
|
|
61
|
+
lastValues.current = {
|
|
62
|
+
y: expanded ? 0 : bubbleH,
|
|
63
|
+
h: expanded ? bubbleH : 0
|
|
64
|
+
};
|
|
65
|
+
if (expanded) rect.animate([{
|
|
66
|
+
y: "0px",
|
|
67
|
+
height: `${bubbleH}px`
|
|
68
|
+
}], {
|
|
69
|
+
duration: 0,
|
|
70
|
+
fill: "forwards"
|
|
71
|
+
});
|
|
72
|
+
const raf = requestAnimationFrame(() => setReady(true));
|
|
73
|
+
return () => cancelAnimationFrame(raf);
|
|
74
|
+
}, []);
|
|
75
|
+
React$1.useEffect(() => {
|
|
76
|
+
const rect = bubbleRectRef.current;
|
|
77
|
+
if (!rect || !ready) return;
|
|
78
|
+
const isExpanding = expanded;
|
|
79
|
+
const duration = getResponsiveDuration(isExpanding ? expandDuration ?? GOOEY_TIMING.EXPAND_DURATION : collapseDuration ?? GOOEY_TIMING.COLLAPSE_DURATION);
|
|
80
|
+
const easing = isExpanding ? expandEasing ?? EASINGS.SPRING_GENTLE : collapseEasing ?? EASINGS.EASE_OUT_CUBIC;
|
|
81
|
+
const toY = isExpanding ? 0 : bubbleH;
|
|
82
|
+
const toH = isExpanding ? bubbleH : 0;
|
|
83
|
+
const fromY = lastValues.current.y;
|
|
84
|
+
const fromH = lastValues.current.h;
|
|
85
|
+
lastValues.current = {
|
|
86
|
+
y: toY,
|
|
87
|
+
h: toH
|
|
88
|
+
};
|
|
89
|
+
if (duration === 0) {
|
|
90
|
+
if (animRef.current) animRef.current.cancel();
|
|
91
|
+
rect.animate([{
|
|
92
|
+
y: `${toY}px`,
|
|
93
|
+
height: `${toH}px`
|
|
94
|
+
}], {
|
|
95
|
+
duration: 0,
|
|
96
|
+
fill: "forwards"
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (animRef.current) animRef.current.cancel();
|
|
101
|
+
animRef.current = rect.animate([{
|
|
102
|
+
y: `${fromY}px`,
|
|
103
|
+
height: `${fromH}px`
|
|
104
|
+
}, {
|
|
105
|
+
y: `${toY}px`,
|
|
106
|
+
height: `${toH}px`
|
|
107
|
+
}], {
|
|
108
|
+
duration,
|
|
109
|
+
easing,
|
|
110
|
+
fill: "forwards"
|
|
111
|
+
});
|
|
112
|
+
}, [
|
|
113
|
+
ready,
|
|
114
|
+
expanded,
|
|
115
|
+
bubbleH,
|
|
116
|
+
expandDuration,
|
|
117
|
+
collapseDuration,
|
|
118
|
+
expandEasing,
|
|
119
|
+
collapseEasing
|
|
120
|
+
]);
|
|
121
|
+
return /* @__PURE__ */ jsx("div", {
|
|
122
|
+
"data-slot": "gooey-canvas",
|
|
123
|
+
style: canvasStyle,
|
|
124
|
+
className: cn("absolute inset-0 rounded-[inherit] pointer-events-none z-0 overflow-visible", className),
|
|
125
|
+
children: /* @__PURE__ */ jsxs("svg", {
|
|
126
|
+
"data-slot": "gooey-svg",
|
|
127
|
+
width,
|
|
128
|
+
height: totalH,
|
|
129
|
+
viewBox: `0 0 ${width} ${totalH}`,
|
|
130
|
+
style: {
|
|
131
|
+
position: "absolute",
|
|
132
|
+
top: -bubbleH,
|
|
133
|
+
left: 0,
|
|
134
|
+
overflow: "visible"
|
|
135
|
+
},
|
|
136
|
+
"aria-hidden": "true",
|
|
137
|
+
children: [
|
|
138
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("filter", {
|
|
139
|
+
id: filterId,
|
|
140
|
+
x: "-20%",
|
|
141
|
+
y: "-20%",
|
|
142
|
+
width: "140%",
|
|
143
|
+
height: "140%",
|
|
144
|
+
colorInterpolationFilters: "sRGB",
|
|
145
|
+
children: [
|
|
146
|
+
/* @__PURE__ */ jsx("feGaussianBlur", {
|
|
147
|
+
in: "SourceGraphic",
|
|
148
|
+
stdDeviation: computedBlur,
|
|
149
|
+
result: "blur"
|
|
150
|
+
}),
|
|
151
|
+
/* @__PURE__ */ jsx("feColorMatrix", {
|
|
152
|
+
in: "blur",
|
|
153
|
+
mode: "matrix",
|
|
154
|
+
values: `1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 ${alphaGain ?? 20} ${alphaOffset ?? -10}`,
|
|
155
|
+
result: "goo"
|
|
156
|
+
}),
|
|
157
|
+
/* @__PURE__ */ jsx("feComposite", {
|
|
158
|
+
in: "SourceGraphic",
|
|
159
|
+
in2: "goo",
|
|
160
|
+
operator: "atop"
|
|
161
|
+
})
|
|
162
|
+
]
|
|
163
|
+
}) }),
|
|
164
|
+
/* @__PURE__ */ jsx("rect", {
|
|
165
|
+
x: pad,
|
|
166
|
+
y: bubbleH,
|
|
167
|
+
width: width - pad * 2,
|
|
168
|
+
height: height - pad * 2,
|
|
169
|
+
rx: effectiveR,
|
|
170
|
+
ry: effectiveR,
|
|
171
|
+
fill: fillColor
|
|
172
|
+
}),
|
|
173
|
+
/* @__PURE__ */ jsx("rect", {
|
|
174
|
+
ref: bubbleRectRef,
|
|
175
|
+
x: insetPx,
|
|
176
|
+
y: bubbleH,
|
|
177
|
+
width: bubbleW,
|
|
178
|
+
height: 0,
|
|
179
|
+
rx: bubbleR,
|
|
180
|
+
ry: bubbleR,
|
|
181
|
+
fill: fillColor
|
|
182
|
+
})
|
|
183
|
+
]
|
|
184
|
+
})
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
GooeyCanvas.displayName = "GooeyCanvas";
|
|
188
|
+
|
|
189
|
+
//#endregion
|
|
190
|
+
export { GooeyCanvas };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IGooeyFilterProps } from './Gooey.types';
|
|
2
|
+
/**
|
|
3
|
+
* GooeyFilter — renders an SVG filter definition for gooey morphing.
|
|
4
|
+
*/
|
|
5
|
+
declare const GooeyFilter: import("react").MemoExoticComponent<({ id, blur, alphaGain, alphaOffset, }: IGooeyFilterProps) => import("react/jsx-runtime").JSX.Element>;
|
|
6
|
+
export { GooeyFilter };
|
|
7
|
+
//# sourceMappingURL=GooeyFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GooeyFilter.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/Gooey/GooeyFilter.tsx"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAUvD;;GAEG;AACH,QAAA,MAAM,WAAW,8EAKd,iBAAiB,6CAwBlB,CAAC;AAIH,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { GOOEY_DEFAULTS, buildColorMatrixValues } from "./gooey-utils.js";
|
|
4
|
+
import { memo } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/react-ui/primitives/waapi/Gooey/GooeyFilter.tsx
|
|
8
|
+
/**
|
|
9
|
+
* GooeyFilter — SVG filter definition for gooey morphing effects.
|
|
10
|
+
*
|
|
11
|
+
* Renders a hidden `<svg>` with a `<filter>` that uses `feGaussianBlur` +
|
|
12
|
+
* `feColorMatrix` + `feComposite` to merge same-colored shapes organically.
|
|
13
|
+
*
|
|
14
|
+
* Apply via `filter: url(#id)` on a container. All same-colored children merge.
|
|
15
|
+
* `feComposite operator="atop"` preserves sharp text/content on top.
|
|
16
|
+
*
|
|
17
|
+
* @param id - Unique filter ID
|
|
18
|
+
* @param blur - Gaussian blur stdDeviation (default: 8)
|
|
19
|
+
* @param alphaGain - Alpha multiplier for merge threshold (default: 20)
|
|
20
|
+
* @param alphaOffset - Alpha offset for edge sharpness (default: -10)
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <GooeyFilter id="my-goo" blur={6} />
|
|
25
|
+
* <div style={{ filter: 'url(#my-goo)' }}>
|
|
26
|
+
* <div className="bg-card" /> // these merge
|
|
27
|
+
* <div className="bg-card" /> // organically
|
|
28
|
+
* </div>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @module @mks2508/mks-ui/react/primitives/waapi/Gooey
|
|
32
|
+
*/
|
|
33
|
+
const HIDDEN_SVG_STYLE = {
|
|
34
|
+
position: "absolute",
|
|
35
|
+
width: 0,
|
|
36
|
+
height: 0,
|
|
37
|
+
overflow: "hidden",
|
|
38
|
+
pointerEvents: "none"
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* GooeyFilter — renders an SVG filter definition for gooey morphing.
|
|
42
|
+
*/
|
|
43
|
+
const GooeyFilter = memo(function GooeyFilter({ id, blur = 8, alphaGain = GOOEY_DEFAULTS.ALPHA_GAIN, alphaOffset = GOOEY_DEFAULTS.ALPHA_OFFSET }) {
|
|
44
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
45
|
+
"aria-hidden": "true",
|
|
46
|
+
style: HIDDEN_SVG_STYLE,
|
|
47
|
+
children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("filter", {
|
|
48
|
+
id,
|
|
49
|
+
x: "-20%",
|
|
50
|
+
y: "-20%",
|
|
51
|
+
width: "140%",
|
|
52
|
+
height: "140%",
|
|
53
|
+
colorInterpolationFilters: "sRGB",
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ jsx("feGaussianBlur", {
|
|
56
|
+
in: "SourceGraphic",
|
|
57
|
+
stdDeviation: blur,
|
|
58
|
+
result: "blur"
|
|
59
|
+
}),
|
|
60
|
+
/* @__PURE__ */ jsx("feColorMatrix", {
|
|
61
|
+
in: "blur",
|
|
62
|
+
mode: "matrix",
|
|
63
|
+
values: buildColorMatrixValues(alphaGain, alphaOffset),
|
|
64
|
+
result: "goo"
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ jsx("feComposite", {
|
|
67
|
+
in: "SourceGraphic",
|
|
68
|
+
in2: "goo",
|
|
69
|
+
operator: "atop"
|
|
70
|
+
})
|
|
71
|
+
]
|
|
72
|
+
}) })
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
GooeyFilter.displayName = "GooeyFilter";
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { GooeyFilter };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IMorphPathProps } from './Gooey.types';
|
|
2
|
+
/**
|
|
3
|
+
* MorphPath — parametric SVG path for pill→blob morphing.
|
|
4
|
+
*/
|
|
5
|
+
declare const MorphPath: import("react").MemoExoticComponent<({ pillWidth, bodyWidth, totalHeight, progress, pillHeight, direction, ...pathProps }: IMorphPathProps) => import("react/jsx-runtime").JSX.Element>;
|
|
6
|
+
export { MorphPath };
|
|
7
|
+
//# sourceMappingURL=MorphPath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MorphPath.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/Gooey/MorphPath.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD;;GAEG;AACH,QAAA,MAAM,SAAS,6HAQZ,eAAe,6CAWhB,CAAC;AAIH,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { GOOEY_DEFAULTS } from "./gooey-utils.js";
|
|
4
|
+
import { useMorphPath } from "./useMorphPath.js";
|
|
5
|
+
import { memo } from "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
|
|
8
|
+
//#region src/react-ui/primitives/waapi/Gooey/MorphPath.tsx
|
|
9
|
+
/**
|
|
10
|
+
* MorphPath — SVG `<path>` component with parametric pill-to-blob morphing.
|
|
11
|
+
*
|
|
12
|
+
* Generates a `<path d="...">` that transitions from a pill shape to an
|
|
13
|
+
* expanded blob based on the `progress` value (0→1). Uses quadratic Bezier
|
|
14
|
+
* curves at the junction for organic concave connections.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <svg width={300} height={80} style={{ position: 'absolute' }}>
|
|
19
|
+
* <MorphPath
|
|
20
|
+
* pillWidth={260}
|
|
21
|
+
* bodyWidth={180}
|
|
22
|
+
* totalHeight={80}
|
|
23
|
+
* progress={expanded ? 1 : 0}
|
|
24
|
+
* direction="up"
|
|
25
|
+
* fill="var(--card)"
|
|
26
|
+
* />
|
|
27
|
+
* </svg>
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @module @mks2508/mks-ui/react/primitives/waapi/Gooey
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* MorphPath — parametric SVG path for pill→blob morphing.
|
|
34
|
+
*/
|
|
35
|
+
const MorphPath = memo(function MorphPath({ pillWidth, bodyWidth, totalHeight, progress, pillHeight = GOOEY_DEFAULTS.PILL_HEIGHT, direction = "down", ...pathProps }) {
|
|
36
|
+
return /* @__PURE__ */ jsx("path", {
|
|
37
|
+
d: useMorphPath({
|
|
38
|
+
pillWidth,
|
|
39
|
+
bodyWidth,
|
|
40
|
+
totalHeight,
|
|
41
|
+
progress,
|
|
42
|
+
pillHeight,
|
|
43
|
+
direction
|
|
44
|
+
}),
|
|
45
|
+
...pathProps
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
MorphPath.displayName = "MorphPath";
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { MorphPath };
|
|
@@ -0,0 +1,94 @@
|
|
|
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
|
+
/** Gooey animation timing constants. */
|
|
7
|
+
export declare const GOOEY_TIMING: {
|
|
8
|
+
/** Expand duration in ms — spring-like with room for overshoot */
|
|
9
|
+
readonly EXPAND_DURATION: 550;
|
|
10
|
+
/** Collapse duration in ms — snappier settle, no overshoot */
|
|
11
|
+
readonly COLLAPSE_DURATION: 400;
|
|
12
|
+
};
|
|
13
|
+
/** Default gooey filter parameters. */
|
|
14
|
+
export declare const GOOEY_DEFAULTS: {
|
|
15
|
+
/** Blur = height * BLUR_RATIO */
|
|
16
|
+
readonly BLUR_RATIO: 0.15;
|
|
17
|
+
/** feColorMatrix alpha channel multiplier */
|
|
18
|
+
readonly ALPHA_GAIN: 20;
|
|
19
|
+
/** feColorMatrix alpha channel offset */
|
|
20
|
+
readonly ALPHA_OFFSET: -10;
|
|
21
|
+
/** Default pill height (px) */
|
|
22
|
+
readonly PILL_HEIGHT: 34;
|
|
23
|
+
/** Quadratic bezier curve factor at full expansion */
|
|
24
|
+
readonly CURVE_FACTOR: 14;
|
|
25
|
+
/** Max body corner radius (px) */
|
|
26
|
+
readonly MAX_CORNER_RADIUS: 16;
|
|
27
|
+
/** Corner radius to body-height ratio */
|
|
28
|
+
readonly CORNER_RATIO: 0.45;
|
|
29
|
+
/** Minimum body height delta to show rounded corners */
|
|
30
|
+
readonly MIN_BODY_DELTA: 8;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Compute the optimal Gaussian blur for a gooey filter based on element height.
|
|
34
|
+
*
|
|
35
|
+
* @param height - Element height in pixels
|
|
36
|
+
* @returns Blur stdDeviation value
|
|
37
|
+
*/
|
|
38
|
+
export declare function computeBlur(height: number): number;
|
|
39
|
+
/**
|
|
40
|
+
* Build the feColorMatrix `values` string.
|
|
41
|
+
*
|
|
42
|
+
* @param gain - Alpha multiplier (default: 20)
|
|
43
|
+
* @param offset - Alpha offset (default: -10)
|
|
44
|
+
* @returns Matrix values string for feColorMatrix
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildColorMatrixValues(gain?: number, offset?: number): string;
|
|
47
|
+
/**
|
|
48
|
+
* Build the CSS filter string with gooey + optional drop-shadow outline.
|
|
49
|
+
*
|
|
50
|
+
* @param filterId - SVG filter ID to reference
|
|
51
|
+
* @param outlineBlur - Drop-shadow blur (px)
|
|
52
|
+
* @param outlineColor - Drop-shadow color
|
|
53
|
+
* @param outlineLayers - Number of stacked drop-shadows for thickness
|
|
54
|
+
* @returns CSS filter property value
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildFilterString(filterId: string, outlineBlur?: number, outlineColor?: string, outlineLayers?: number): string;
|
|
57
|
+
type PathFn = (pw: number, bw: number, th: number, t: number, ph: number) => string;
|
|
58
|
+
/**
|
|
59
|
+
* Memoize a path generation function — caches last result to avoid
|
|
60
|
+
* recomputing identical paths on consecutive animation frames.
|
|
61
|
+
*
|
|
62
|
+
* @param fn - Path generation function
|
|
63
|
+
* @returns Memoized function
|
|
64
|
+
*/
|
|
65
|
+
export declare function memoizePath(fn: PathFn): PathFn;
|
|
66
|
+
/**
|
|
67
|
+
* Generate an SVG path for a pill that morphs downward into a body blob.
|
|
68
|
+
* Adapted from goey-toast's morphPathRaw.
|
|
69
|
+
*
|
|
70
|
+
* @param pw - Pill width
|
|
71
|
+
* @param bw - Body width (expanded)
|
|
72
|
+
* @param th - Total height (pill + body)
|
|
73
|
+
* @param t - Transition progress 0 (pill only) → 1 (full blob)
|
|
74
|
+
* @param ph - Pill height (default: PILL_HEIGHT)
|
|
75
|
+
* @returns SVG path d-string
|
|
76
|
+
*/
|
|
77
|
+
export declare function morphPathDown(pw: number, bw: number, th: number, t: number, ph?: number): string;
|
|
78
|
+
/**
|
|
79
|
+
* Generate an SVG path for a pill that morphs UPWARD into a body blob.
|
|
80
|
+
* Used for DynamicToggle's bubble-above-pill layout.
|
|
81
|
+
*
|
|
82
|
+
* @param pw - Pill width
|
|
83
|
+
* @param bw - Body (bubble) width
|
|
84
|
+
* @param th - Total height (bubble + pill)
|
|
85
|
+
* @param t - Transition progress 0 (pill only) → 1 (full blob with bubble)
|
|
86
|
+
* @param ph - Pill height
|
|
87
|
+
* @returns SVG path d-string
|
|
88
|
+
*/
|
|
89
|
+
export declare function morphPathUp(pw: number, bw: number, th: number, t: number, ph?: number): string;
|
|
90
|
+
/** Memoized versions for animation performance. */
|
|
91
|
+
export declare const morphPathDownMemo: PathFn;
|
|
92
|
+
export declare const morphPathUpMemo: PathFn;
|
|
93
|
+
export {};
|
|
94
|
+
//# sourceMappingURL=gooey-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gooey-utils.d.ts","sourceRoot":"","sources":["../../../../../src/react-ui/primitives/waapi/Gooey/gooey-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,wCAAwC;AACxC,eAAO,MAAM,YAAY;IACvB,kEAAkE;;IAElE,8DAA8D;;CAEtD,CAAC;AAEX,uCAAuC;AACvC,eAAO,MAAM,cAAc;IACzB,iCAAiC;;IAEjC,6CAA6C;;IAE7C,yCAAyC;;IAEzC,+BAA+B;;IAE/B,sDAAsD;;IAEtD,kCAAkC;;IAElC,yCAAyC;;IAEzC,wDAAwD;;CAEhD,CAAC;AAMX;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,GAAE,MAAkC,EACxC,MAAM,GAAE,MAAoC,GAC3C,MAAM,CAER;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,MAAY,EACzB,YAAY,GAAE,MAAwB,EACtC,aAAa,GAAE,MAAU,GACxB,MAAM,CAKR;AAMD,KAAK,MAAM,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;AAEpF;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAW9C;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,CAAC,EAAE,MAAM,EACT,EAAE,GAAE,MAAmC,GACtC,MAAM,CAwCR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,CAAC,EAAE,MAAM,EACT,EAAE,GAAE,MAAmC,GACtC,MAAM,CAsDR;AAED,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,QAA6B,CAAC;AAC5D,eAAO,MAAM,eAAe,QAA2B,CAAC"}
|