@flikk/ui 1.0.0-beta.13 → 1.0.0-beta.15

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.
Files changed (283) hide show
  1. package/dist/components/ai/CodeBlock/CodeBlock.theme.js +1 -1
  2. package/dist/components/ai/PromptInput/PromptInput.js +4 -2
  3. package/dist/components/ai/PromptInput/VoiceRecorder.js +1 -1
  4. package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.js +4 -4
  5. package/dist/components/ai/StreamingResponse/StreamingResponse.js +6 -0
  6. package/dist/components/ai/ThinkingIndicator/ThinkingIndicator.js +3 -14
  7. package/dist/components/ai/index.d.ts +0 -5
  8. package/dist/components/ai/index.js +8 -4
  9. package/dist/components/charts/DonutChart/DonutChart.js +1 -1
  10. package/dist/components/charts/DonutChart/MultiSegmentDonutChart.js +1 -1
  11. package/dist/components/charts/FunnelChart/FunnelChart.js +2 -2
  12. package/dist/components/charts/shared/ChartLegend/ChartLegend.types.d.ts +13 -1
  13. package/dist/components/charts/shared/ChartLegend/ChartLegendContent.js +1 -1
  14. package/dist/components/charts/shared/ChartTooltip/ChartTooltip.types.d.ts +13 -2
  15. package/dist/components/core/Accordion/AccordionItem.js +1 -1
  16. package/dist/components/core/Accordion/AccordionTrigger.js +1 -1
  17. package/dist/components/core/Alert/Alert.animations.d.ts +11 -0
  18. package/dist/components/core/Alert/Alert.animations.js +44 -0
  19. package/dist/components/core/Alert/Alert.js +16 -3
  20. package/dist/components/core/Avatar/Avatar.js +12 -7
  21. package/dist/components/core/Avatar/Avatar.theme.d.ts +4 -6
  22. package/dist/components/core/Avatar/Avatar.theme.js +22 -12
  23. package/dist/components/core/Avatar/Avatar.types.d.ts +9 -0
  24. package/dist/components/core/AvatarGroup/AvatarGroup.animations.js +2 -2
  25. package/dist/components/core/AvatarGroup/AvatarGroup.js +1 -2
  26. package/dist/components/core/AvatarGroup/AvatarGroup.theme.js +1 -1
  27. package/dist/components/core/Badge/Badge.animations.js +1 -1
  28. package/dist/components/core/Badge/Badge.js +26 -50
  29. package/dist/components/core/Badge/Badge.theme.js +49 -63
  30. package/dist/components/core/Badge/Badge.types.d.ts +6 -30
  31. package/dist/components/core/Button/Button.js +2 -2
  32. package/dist/components/core/Button/Button.ripple.js +1 -1
  33. package/dist/components/core/Button/Button.theme.d.ts +1 -1
  34. package/dist/components/core/Button/Button.theme.js +5 -5
  35. package/dist/components/core/Button/Button.types.d.ts +1 -1
  36. package/dist/components/core/ButtonGroup/ButtonGroup.theme.js +6 -6
  37. package/dist/components/core/ButtonGroup/ButtonGroupText.js +1 -3
  38. package/dist/components/core/Calendar/Calendar.js +29 -3
  39. package/dist/components/core/Calendar/Calendar.theme.js +11 -7
  40. package/dist/components/core/Calendar/Calendar.types.d.ts +3 -0
  41. package/dist/components/core/Calendar/CalendarMini/CalendarMini.js +2 -2
  42. package/dist/components/core/Carousel/CarouselBody.js +0 -1
  43. package/dist/components/core/CommandPalette/CommandItem.js +1 -1
  44. package/dist/components/core/CommandPalette/CommandPalette.js +6 -4
  45. package/dist/components/core/CommandPalette/CommandPalette.theme.js +1 -0
  46. package/dist/components/core/CommandPalette/CommandPalette.types.d.ts +6 -0
  47. package/dist/components/core/ContextMenu/ContextMenu.js +5 -4
  48. package/dist/components/core/ContextMenu/ContextMenuTrigger.js +5 -6
  49. package/dist/components/core/Drawer/Drawer.d.ts +1 -1
  50. package/dist/components/core/Drawer/Drawer.js +25 -2
  51. package/dist/components/core/Drawer/Drawer.theme.js +2 -2
  52. package/dist/components/core/Drawer/Drawer.types.d.ts +6 -0
  53. package/dist/components/core/Drawer/DrawerHeader.js +1 -1
  54. package/dist/components/core/Dropdown/Dropdown.d.ts +1 -1
  55. package/dist/components/core/Dropdown/Dropdown.js +5 -1
  56. package/dist/components/core/Dropdown/Dropdown.types.d.ts +1 -0
  57. package/dist/components/core/Dropdown/DropdownItem.js +1 -1
  58. package/dist/components/core/Dropdown/DropdownMenu.js +4 -4
  59. package/dist/components/core/Dropdown/DropdownSection.js +1 -1
  60. package/dist/components/core/Dropdown/DropdownSeparator.js +1 -1
  61. package/dist/components/core/Dropdown/DropdownTrigger.d.ts +6 -1
  62. package/dist/components/core/Dropdown/DropdownTrigger.js +10 -8
  63. package/dist/components/core/Kbd/Kbd.theme.js +3 -3
  64. package/dist/components/core/Link/Link.js +4 -2
  65. package/dist/components/core/Message/Message.d.ts +9 -0
  66. package/dist/components/core/Message/Message.js +44 -3
  67. package/dist/components/core/Message/Message.theme.js +22 -0
  68. package/dist/components/core/Message/Message.types.d.ts +115 -0
  69. package/dist/components/core/Message/MessageAudio.d.ts +8 -0
  70. package/dist/components/core/Message/MessageAudio.js +11 -0
  71. package/dist/components/core/Message/MessageContext.d.ts +3 -1
  72. package/dist/components/core/Message/MessageDateDivider.d.ts +6 -0
  73. package/dist/components/core/Message/MessageDateDivider.js +10 -0
  74. package/dist/components/core/Message/MessageFile.d.ts +9 -0
  75. package/dist/components/core/Message/MessageFile.js +15 -0
  76. package/dist/components/core/Message/MessageImage.d.ts +11 -0
  77. package/dist/components/core/Message/MessageImage.js +13 -0
  78. package/dist/components/core/Message/MessageLink.d.ts +10 -0
  79. package/dist/components/core/Message/MessageLink.js +15 -0
  80. package/dist/components/core/Message/MessageReactions.d.ts +8 -0
  81. package/dist/components/core/Message/MessageReactions.js +12 -0
  82. package/dist/components/core/Message/MessageReply.d.ts +8 -0
  83. package/dist/components/core/Message/MessageReply.js +10 -0
  84. package/dist/components/core/Message/MessageSenderName.d.ts +6 -0
  85. package/dist/components/core/Message/MessageSenderName.js +10 -0
  86. package/dist/components/core/Message/MessageStatusIndicator.d.ts +9 -0
  87. package/dist/components/core/Message/MessageStatusIndicator.js +45 -0
  88. package/dist/components/core/Message/index.d.ts +19 -1
  89. package/dist/components/core/Modal/Modal.animations.d.ts +1 -0
  90. package/dist/components/core/Modal/Modal.animations.js +14 -11
  91. package/dist/components/core/Modal/ModalHeader.js +1 -1
  92. package/dist/components/core/NavItem/NavItem.js +100 -52
  93. package/dist/components/core/NavItem/NavItem.theme.js +6 -3
  94. package/dist/components/core/NavItem/NavItem.types.d.ts +44 -30
  95. package/dist/components/core/NavItem/index.d.ts +1 -1
  96. package/dist/components/core/Pagination/Pagination.theme.js +1 -1
  97. package/dist/components/core/Pill/Pill.theme.js +1 -1
  98. package/dist/components/core/Popover/Popover.d.ts +1 -1
  99. package/dist/components/core/Popover/PopoverBody.js +2 -2
  100. package/dist/components/core/Popover/PopoverTrigger.d.ts +1 -1
  101. package/dist/components/core/Popover/PopoverTrigger.js +11 -11
  102. package/dist/components/core/Progress/Progress.d.ts +9 -8
  103. package/dist/components/core/Progress/Progress.js +16 -16
  104. package/dist/components/core/Progress/Progress.theme.js +5 -16
  105. package/dist/components/core/Progress/Progress.types.d.ts +2 -20
  106. package/dist/components/core/Progress/index.d.ts +1 -1
  107. package/dist/components/core/ScrollArea/ScrollArea.js +49 -7
  108. package/dist/components/core/ScrollArea/ScrollArea.types.d.ts +12 -3
  109. package/dist/components/core/ScrollArea/index.d.ts +1 -1
  110. package/dist/components/core/Segmented/SegmentedItem.js +1 -1
  111. package/dist/components/core/Sidebar/Sidebar.d.ts +11 -1
  112. package/dist/components/core/Sidebar/Sidebar.js +51 -17
  113. package/dist/components/core/Sidebar/Sidebar.theme.js +9 -7
  114. package/dist/components/core/Sidebar/Sidebar.types.d.ts +57 -0
  115. package/dist/components/core/Sidebar/SidebarContent.js +3 -1
  116. package/dist/components/core/Sidebar/SidebarContext.d.ts +14 -0
  117. package/dist/components/core/Sidebar/SidebarContext.js +63 -11
  118. package/dist/components/core/Sidebar/SidebarFooter.js +3 -1
  119. package/dist/components/core/Sidebar/SidebarHeader.js +6 -2
  120. package/dist/components/core/Sidebar/SidebarMobileTrigger.d.ts +3 -0
  121. package/dist/components/core/Sidebar/SidebarMobileTrigger.js +29 -0
  122. package/dist/components/core/Sidebar/SidebarNav.js +3 -2
  123. package/dist/components/core/Sidebar/SidebarNavGroup.js +4 -2
  124. package/dist/components/core/Sidebar/SidebarToggle.js +2 -1
  125. package/dist/components/core/Sidebar/SidebarUserProfile.d.ts +3 -0
  126. package/dist/components/core/Sidebar/SidebarUserProfile.js +35 -0
  127. package/dist/components/core/Sidebar/index.d.ts +3 -1
  128. package/dist/components/core/SocialIcon/SocialIcon.js +1 -1
  129. package/dist/components/core/Sortable/Sortable.js +2 -2
  130. package/dist/components/core/Sortable/Sortable.theme.js +1 -1
  131. package/dist/components/core/Sortable/Sortable.types.d.ts +7 -5
  132. package/dist/components/core/Tabs/Tabs.theme.d.ts +1 -1
  133. package/dist/components/core/Tabs/Tabs.theme.js +3 -3
  134. package/dist/components/core/Tabs/TabsBody.js +1 -1
  135. package/dist/components/core/Tabs/TabsTrigger.js +1 -1
  136. package/dist/components/core/Tag/Tag.js +2 -2
  137. package/dist/components/core/Toast/Toast.d.ts +2 -2
  138. package/dist/components/core/Toast/Toast.js +30 -21
  139. package/dist/components/core/Toast/Toast.theme.js +4 -9
  140. package/dist/components/core/Toast/Toast.types.d.ts +4 -21
  141. package/dist/components/core/Toast/index.d.ts +1 -1
  142. package/dist/components/core/Tooltip/Tooltip.js +1 -1
  143. package/dist/components/core/Tooltip/Tooltip.theme.js +1 -1
  144. package/dist/components/core/index.js +11 -0
  145. package/dist/components/data-display/GanttChart/GanttChart.types.d.ts +2 -2
  146. package/dist/components/data-display/GanttChart/GanttToolbar.js +1 -1
  147. package/dist/components/data-display/Table/Table.types.d.ts +8 -8
  148. package/dist/components/effects/CustomCursor/CustomCursor.js +2 -2
  149. package/dist/components/effects/GlassSurface/GlassSurface.d.ts +1 -1
  150. package/dist/components/effects/GlassSurface/GlassSurface.js +12 -4
  151. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.animations.d.ts +39 -0
  152. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.animations.js +98 -0
  153. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.d.ts +3 -0
  154. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.js +104 -0
  155. package/dist/components/effects/InteractiveCharacters/InteractiveCharacters.types.d.ts +30 -0
  156. package/dist/components/effects/InteractiveCharacters/characters/BlobCharacter.d.ts +3 -0
  157. package/dist/components/effects/InteractiveCharacters/characters/BlobCharacter.js +36 -0
  158. package/dist/components/effects/InteractiveCharacters/characters/SmallCharacter.d.ts +3 -0
  159. package/dist/components/effects/InteractiveCharacters/characters/SmallCharacter.js +36 -0
  160. package/dist/components/effects/InteractiveCharacters/characters/TallCharacter.d.ts +3 -0
  161. package/dist/components/effects/InteractiveCharacters/characters/TallCharacter.js +37 -0
  162. package/dist/components/effects/InteractiveCharacters/hooks/useBlink.d.ts +14 -0
  163. package/dist/components/effects/InteractiveCharacters/hooks/useBlink.js +41 -0
  164. package/dist/components/effects/InteractiveCharacters/hooks/useIdleAnimation.d.ts +25 -0
  165. package/dist/components/effects/InteractiveCharacters/hooks/useIdleAnimation.js +84 -0
  166. package/dist/components/effects/InteractiveCharacters/hooks/useMouseTracking.d.ts +18 -0
  167. package/dist/components/effects/InteractiveCharacters/hooks/useMouseTracking.js +35 -0
  168. package/dist/components/effects/InteractiveCharacters/index.d.ts +2 -0
  169. package/dist/components/effects/MorphingText/MorphingText.d.ts +1 -1
  170. package/dist/components/effects/MorphingText/MorphingText.js +6 -5
  171. package/dist/components/effects/Neumorphic/InsetCircleButton.d.ts +9 -0
  172. package/dist/components/effects/Neumorphic/InsetCircleButton.js +10 -0
  173. package/dist/components/effects/Neumorphic/InsetPill.d.ts +7 -0
  174. package/dist/components/effects/Neumorphic/InsetPill.js +7 -0
  175. package/dist/components/effects/Neumorphic/index.d.ts +4 -0
  176. package/dist/components/effects/NoiseOverlay/NoiseOverlay.d.ts +1 -1
  177. package/dist/components/effects/NoiseOverlay/NoiseOverlay.js +4 -4
  178. package/dist/components/effects/Overlay/Overlay.js +6 -4
  179. package/dist/components/effects/PageTransition/PageTransition.animations.d.ts +8 -0
  180. package/dist/components/effects/PageTransition/PageTransition.animations.js +53 -0
  181. package/dist/components/effects/PageTransition/PageTransition.d.ts +3 -0
  182. package/dist/components/effects/PageTransition/PageTransition.js +71 -0
  183. package/dist/components/effects/PageTransition/PageTransition.types.d.ts +15 -0
  184. package/dist/components/effects/PageTransition/index.d.ts +2 -0
  185. package/dist/components/effects/index.d.ts +6 -0
  186. package/dist/components/effects/index.js +4 -0
  187. package/dist/components/forms/Checkbox/Checkbox.animations.d.ts +14 -0
  188. package/dist/components/forms/Checkbox/Checkbox.animations.js +53 -0
  189. package/dist/components/forms/Checkbox/Checkbox.js +4 -2
  190. package/dist/components/forms/Checkbox/Checkbox.theme.js +3 -3
  191. package/dist/components/forms/ColorPicker/ColorPicker.types.d.ts +1 -1
  192. package/dist/components/forms/ColorPicker/ColorPickerBody.js +3 -3
  193. package/dist/components/forms/Combobox/Combobox.js +5 -3
  194. package/dist/components/forms/DatePicker/DatePickerBody.js +1 -1
  195. package/dist/components/forms/DateRangePicker/DateRangePicker.animations.d.ts +1 -0
  196. package/dist/components/forms/DateRangePicker/DateRangePicker.d.ts +37 -0
  197. package/dist/components/forms/DateRangePicker/DateRangePicker.js +110 -0
  198. package/dist/components/forms/DateRangePicker/DateRangePicker.theme.d.ts +5 -0
  199. package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +52 -0
  200. package/dist/components/forms/DateRangePicker/DateRangePicker.types.d.ts +154 -0
  201. package/dist/components/forms/DateRangePicker/DateRangePickerBody.d.ts +6 -0
  202. package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +208 -0
  203. package/dist/components/forms/DateRangePicker/DateRangePickerPresets.d.ts +6 -0
  204. package/dist/components/forms/DateRangePicker/DateRangePickerPresets.js +41 -0
  205. package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.d.ts +6 -0
  206. package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +32 -0
  207. package/dist/components/forms/DateRangePicker/dateRangePresets.d.ts +5 -0
  208. package/dist/components/forms/DateRangePicker/dateRangePresets.js +59 -0
  209. package/dist/components/forms/DateRangePicker/index.d.ts +4 -0
  210. package/dist/components/forms/FileUpload/FileUploadProgress.animations.d.ts +36 -0
  211. package/dist/components/forms/FileUpload/FileUploadProgress.animations.js +22 -0
  212. package/dist/components/forms/FileUpload/FileUploadProgress.d.ts +3 -0
  213. package/dist/components/forms/FileUpload/FileUploadProgress.js +111 -0
  214. package/dist/components/forms/FileUpload/FileUploadProgress.theme.d.ts +19 -0
  215. package/dist/components/forms/FileUpload/FileUploadProgress.theme.js +27 -0
  216. package/dist/components/forms/FileUpload/FileUploadProgress.types.d.ts +33 -0
  217. package/dist/components/forms/FileUpload/index.d.ts +3 -0
  218. package/dist/components/forms/Input/Input.js +8 -13
  219. package/dist/components/forms/Input/Input.types.d.ts +6 -0
  220. package/dist/components/forms/InputAddress/InputAddress.theme.js +1 -1
  221. package/dist/components/forms/InputCounter/InputCounter.js +1 -1
  222. package/dist/components/forms/InputCreditCard/InputCreditCard.theme.js +1 -1
  223. package/dist/components/forms/InputOTP/InputOTP.theme.js +1 -1
  224. package/dist/components/forms/Radio/Radio.animations.d.ts +10 -0
  225. package/dist/components/forms/Radio/Radio.animations.js +33 -0
  226. package/dist/components/forms/Radio/Radio.js +11 -2
  227. package/dist/components/forms/Radio/Radio.theme.js +3 -3
  228. package/dist/components/forms/RichTextEditor/RichTextEditor.js +23 -14
  229. package/dist/components/forms/RichTextEditor/RichTextEditor.theme.js +2 -2
  230. package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +11 -0
  231. package/dist/components/forms/Select/Select.d.ts +1 -1
  232. package/dist/components/forms/Select/Select.js +7 -7
  233. package/dist/components/forms/Select/Select.types.d.ts +3 -3
  234. package/dist/components/forms/SelectableCard/SelectableCard.js +1 -1
  235. package/dist/components/forms/Slider/Slider.theme.js +1 -1
  236. package/dist/components/forms/Switch/Switch.theme.js +3 -3
  237. package/dist/components/forms/forms.theme.js +1 -1
  238. package/dist/components/forms/index.d.ts +6 -0
  239. package/dist/components/forms/index.js +8 -0
  240. package/dist/hooks/index.d.ts +1 -0
  241. package/dist/hooks/useMediaQuery.d.ts +5 -0
  242. package/dist/hooks/useMediaQuery.js +21 -0
  243. package/dist/index.js +23 -0
  244. package/dist/styles.css +1 -1
  245. package/dist/utils/dateUtils.js +56 -5
  246. package/dist/utils/formatUtils.d.ts +10 -0
  247. package/dist/utils/formatUtils.js +24 -0
  248. package/dist/utils/index.d.ts +1 -1
  249. package/package.json +12 -4
  250. package/src/global.scss +320 -39
  251. package/src/styles/theme.css +151 -62
  252. package/src/theme-plugin.css +13 -0
  253. package/dist/components/ai/ApprovalCard/ApprovalCard.d.ts +0 -3
  254. package/dist/components/ai/ApprovalCard/ApprovalCard.js +0 -16
  255. package/dist/components/ai/ApprovalCard/ApprovalCard.theme.d.ts +0 -13
  256. package/dist/components/ai/ApprovalCard/ApprovalCard.theme.js +0 -15
  257. package/dist/components/ai/ApprovalCard/ApprovalCard.types.d.ts +0 -43
  258. package/dist/components/ai/ApprovalCard/index.d.ts +0 -2
  259. package/dist/components/ai/MessageHistory/MessageHistory.d.ts +0 -18
  260. package/dist/components/ai/MessageHistory/MessageHistory.js +0 -98
  261. package/dist/components/ai/MessageHistory/MessageHistory.theme.d.ts +0 -2
  262. package/dist/components/ai/MessageHistory/MessageHistory.theme.js +0 -8
  263. package/dist/components/ai/MessageHistory/MessageHistory.types.d.ts +0 -94
  264. package/dist/components/ai/MessageHistory/index.d.ts +0 -3
  265. package/dist/icons/Icon.d.ts +0 -24
  266. package/dist/icons/Icon.js +0 -30
  267. package/dist/icons/Index.d.ts +0 -16
  268. package/dist/icons/core/ChevronUpDown.d.ts +0 -1
  269. package/dist/icons/core/ChevronUpDown.js +0 -7
  270. package/dist/icons/core/DollarIcon.d.ts +0 -1
  271. package/dist/icons/core/DollarIcon.js +0 -5
  272. package/dist/icons/core/LockIcon.d.ts +0 -1
  273. package/dist/icons/core/LockIcon.js +0 -5
  274. package/dist/icons/core/MinusIcon.d.ts +0 -1
  275. package/dist/icons/core/MinusIcon.js +0 -7
  276. package/dist/icons/core/PlusIcon.d.ts +0 -1
  277. package/dist/icons/core/PlusIcon.js +0 -7
  278. package/dist/icons/core/SearchIcon.d.ts +0 -1
  279. package/dist/icons/core/SearchIcon.js +0 -7
  280. package/dist/icons/core/TickIcon.d.ts +0 -1
  281. package/dist/icons/core/TickIcon.js +0 -5
  282. package/dist/icons/core/User.d.ts +0 -1
  283. package/dist/utils/useClickOutside.d.ts +0 -1
@@ -0,0 +1,14 @@
1
+ interface UseBlinkOptions {
2
+ /** Whether blinking is enabled */
3
+ enabled?: boolean;
4
+ /** Min time between blinks in ms (default: 2000) */
5
+ minInterval?: number;
6
+ /** Max time between blinks in ms (default: 5000) */
7
+ maxInterval?: number;
8
+ }
9
+ /**
10
+ * Returns a MotionValue representing eyelid close amount (0 = open, 1 = closed).
11
+ * Fires periodic natural blinks when enabled.
12
+ */
13
+ export declare function useBlink({ enabled, minInterval, maxInterval, }?: UseBlinkOptions): import("motion-dom").MotionValue<number>;
14
+ export {};
@@ -0,0 +1,41 @@
1
+ import { useRef, useCallback, useEffect } from 'react';
2
+ import { useMotionValue, useSpring } from 'motion/react';
3
+
4
+ /**
5
+ * Returns a MotionValue representing eyelid close amount (0 = open, 1 = closed).
6
+ * Fires periodic natural blinks when enabled.
7
+ */
8
+ function useBlink({ enabled = true, minInterval = 2000, maxInterval = 5000, } = {}) {
9
+ const raw = useMotionValue(0);
10
+ const blink = useSpring(raw, { stiffness: 600, damping: 30 });
11
+ const timeoutRef = useRef(undefined);
12
+ const doBlink = useCallback(() => {
13
+ // Close eyes
14
+ raw.set(1);
15
+ // Open after 120ms
16
+ setTimeout(() => raw.set(0), 120);
17
+ }, [raw]);
18
+ const scheduleNext = useCallback(() => {
19
+ const delay = minInterval + Math.random() * (maxInterval - minInterval);
20
+ timeoutRef.current = setTimeout(() => {
21
+ if (enabled) {
22
+ doBlink();
23
+ scheduleNext();
24
+ }
25
+ }, delay);
26
+ }, [enabled, minInterval, maxInterval, doBlink]);
27
+ useEffect(() => {
28
+ if (!enabled) {
29
+ raw.set(0);
30
+ return;
31
+ }
32
+ scheduleNext();
33
+ return () => {
34
+ if (timeoutRef.current)
35
+ clearTimeout(timeoutRef.current);
36
+ };
37
+ }, [enabled, scheduleNext, raw]);
38
+ return blink;
39
+ }
40
+
41
+ export { useBlink };
@@ -0,0 +1,25 @@
1
+ interface UseIdleAnimationOptions {
2
+ /** Whether idle animation is active */
3
+ enabled?: boolean;
4
+ /** Amplitude of the sway in SVG units (default: 2) */
5
+ swayAmount?: number;
6
+ /** Speed multiplier for the sway cycle (default: 1) */
7
+ swaySpeed?: number;
8
+ /** Amplitude of the breathing scale oscillation (default: 0.01) */
9
+ breathAmount?: number;
10
+ /** Amplitude of head tilt in degrees (default: 3) */
11
+ headTiltAmount?: number;
12
+ /** Amplitude of random head nudge in SVG units (default: 1.5) */
13
+ headNudgeAmount?: number;
14
+ /** Phase offset in seconds — staggers characters so they don't move in sync */
15
+ phaseOffset?: number;
16
+ }
17
+ export declare function useIdleAnimation({ enabled, swayAmount, swaySpeed, breathAmount, headTiltAmount, headNudgeAmount, phaseOffset, }?: UseIdleAnimationOptions): {
18
+ sway: import("motion-dom").MotionValue<number>;
19
+ bob: import("motion-dom").MotionValue<number>;
20
+ breath: import("motion-dom").MotionValue<number>;
21
+ headTilt: import("motion-dom").MotionValue<number>;
22
+ headX: import("motion-dom").MotionValue<number>;
23
+ headY: import("motion-dom").MotionValue<number>;
24
+ };
25
+ export {};
@@ -0,0 +1,84 @@
1
+ import { useRef, useCallback, useEffect } from 'react';
2
+ import { useReducedMotion, useMotionValue, useSpring } from 'motion/react';
3
+
4
+ function useIdleAnimation({ enabled = true, swayAmount = 2, swaySpeed = 1, breathAmount = 0.01, headTiltAmount = 3, headNudgeAmount = 1.5, phaseOffset = 0, } = {}) {
5
+ const shouldReduceMotion = useReducedMotion();
6
+ const rafRef = useRef(0);
7
+ const startTimeRef = useRef(null);
8
+ const isFirstFrame = useRef(true);
9
+ const rawSway = useMotionValue(0);
10
+ const rawBob = useMotionValue(0);
11
+ const rawBreath = useMotionValue(1);
12
+ const rawHeadTilt = useMotionValue(0);
13
+ const rawHeadX = useMotionValue(0);
14
+ const rawHeadY = useMotionValue(0);
15
+ const sway = useSpring(rawSway, { stiffness: 40, damping: 15 });
16
+ const bob = useSpring(rawBob, { stiffness: 40, damping: 15 });
17
+ const breath = useSpring(rawBreath, { stiffness: 40, damping: 15 });
18
+ const headTilt = useSpring(rawHeadTilt, { stiffness: 30, damping: 12 });
19
+ const headX = useSpring(rawHeadX, { stiffness: 35, damping: 14 });
20
+ const headY = useSpring(rawHeadY, { stiffness: 35, damping: 14 });
21
+ const animate = useCallback((time) => {
22
+ if (startTimeRef.current === null)
23
+ startTimeRef.current = time;
24
+ const t = (time - startTimeRef.current) / 1000 + phaseOffset;
25
+ // Body sway: slow sinusoidal
26
+ const swayVal = Math.sin(t * 0.8 * swaySpeed) * swayAmount;
27
+ rawSway.set(swayVal);
28
+ // Body bob: slightly different frequency
29
+ const bobVal = Math.sin(t * 1.2 * swaySpeed) * (swayAmount * 0.5);
30
+ rawBob.set(bobVal);
31
+ // Breathing: subtle scale oscillation
32
+ const breathVal = 1 + Math.sin(t * 1.5 * swaySpeed) * breathAmount;
33
+ rawBreath.set(breathVal);
34
+ // Head tilt: layered sinusoids for organic, non-repeating feel
35
+ const tilt1 = Math.sin(t * 0.5 * swaySpeed) * 0.6;
36
+ const tilt2 = Math.sin(t * 1.3 * swaySpeed) * 0.3;
37
+ const tilt3 = Math.sin(t * 0.3 * swaySpeed) * 0.1;
38
+ const tiltVal = (tilt1 + tilt2 + tilt3) * headTiltAmount;
39
+ rawHeadTilt.set(tiltVal);
40
+ // Head nudge X/Y: different frequencies from body for independence
41
+ const headXVal = (Math.sin(t * 0.7 * swaySpeed) * 0.6 +
42
+ Math.sin(t * 1.9 * swaySpeed) * 0.4) *
43
+ headNudgeAmount;
44
+ rawHeadX.set(headXVal);
45
+ const headYVal = (Math.sin(t * 0.9 * swaySpeed) * 0.5 +
46
+ Math.sin(t * 2.1 * swaySpeed) * 0.3) *
47
+ headNudgeAmount *
48
+ 0.6;
49
+ rawHeadY.set(headYVal);
50
+ // On first frame, jump springs directly to skip settling animation
51
+ if (isFirstFrame.current) {
52
+ isFirstFrame.current = false;
53
+ sway.jump(swayVal);
54
+ bob.jump(bobVal);
55
+ breath.jump(breathVal);
56
+ headTilt.jump(tiltVal);
57
+ headX.jump(headXVal);
58
+ headY.jump(headYVal);
59
+ }
60
+ rafRef.current = requestAnimationFrame(animate);
61
+ }, [
62
+ rawSway, rawBob, rawBreath, rawHeadTilt, rawHeadX, rawHeadY,
63
+ sway, bob, breath, headTilt, headX, headY,
64
+ swayAmount, swaySpeed, breathAmount, headTiltAmount, headNudgeAmount, phaseOffset,
65
+ ]);
66
+ useEffect(() => {
67
+ if (!enabled || shouldReduceMotion) {
68
+ rawSway.set(0);
69
+ rawBob.set(0);
70
+ rawBreath.set(1);
71
+ rawHeadTilt.set(0);
72
+ rawHeadX.set(0);
73
+ rawHeadY.set(0);
74
+ return;
75
+ }
76
+ startTimeRef.current = null;
77
+ isFirstFrame.current = true;
78
+ rafRef.current = requestAnimationFrame(animate);
79
+ return () => cancelAnimationFrame(rafRef.current);
80
+ }, [enabled, shouldReduceMotion, animate, rawSway, rawBob, rawBreath, rawHeadTilt, rawHeadX, rawHeadY]);
81
+ return { sway, bob, breath, headTilt, headX, headY };
82
+ }
83
+
84
+ export { useIdleAnimation };
@@ -0,0 +1,18 @@
1
+ import type { RefObject } from 'react';
2
+ interface UseMouseTrackingOptions {
3
+ /** Reference to the SVG container element */
4
+ containerRef: RefObject<SVGSVGElement | null>;
5
+ /** Whether tracking is enabled */
6
+ enabled?: boolean;
7
+ /** Spring stiffness (default: 150) */
8
+ stiffness?: number;
9
+ /** Spring damping (default: 25) */
10
+ damping?: number;
11
+ /** Maximum eye offset in pixels (default: 6) */
12
+ maxOffset?: number;
13
+ }
14
+ export declare function useMouseTracking({ containerRef, enabled, stiffness, damping, maxOffset, }: UseMouseTrackingOptions): {
15
+ x: import("motion-dom").MotionValue<number>;
16
+ y: import("motion-dom").MotionValue<number>;
17
+ };
18
+ export {};
@@ -0,0 +1,35 @@
1
+ import { useCallback, useEffect } from 'react';
2
+ import { useReducedMotion, useMotionValue, useSpring } from 'motion/react';
3
+
4
+ function useMouseTracking({ containerRef, enabled = true, stiffness = 150, damping = 25, maxOffset = 6, }) {
5
+ const shouldReduceMotion = useReducedMotion();
6
+ const rawX = useMotionValue(0);
7
+ const rawY = useMotionValue(0);
8
+ const x = useSpring(rawX, { stiffness, damping });
9
+ const y = useSpring(rawY, { stiffness, damping });
10
+ const handleMouseMove = useCallback((e) => {
11
+ const el = containerRef.current;
12
+ if (!el)
13
+ return;
14
+ const rect = el.getBoundingClientRect();
15
+ const centerX = rect.left + rect.width / 2;
16
+ const centerY = rect.top + rect.height / 2;
17
+ // Normalize to -1..1 range based on distance from center
18
+ const nx = Math.max(-1, Math.min(1, (e.clientX - centerX) / (rect.width / 2)));
19
+ const ny = Math.max(-1, Math.min(1, (e.clientY - centerY) / (rect.height / 2)));
20
+ rawX.set(nx * maxOffset);
21
+ rawY.set(ny * maxOffset);
22
+ }, [containerRef, rawX, rawY, maxOffset]);
23
+ useEffect(() => {
24
+ if (!enabled || shouldReduceMotion) {
25
+ rawX.set(0);
26
+ rawY.set(0);
27
+ return;
28
+ }
29
+ window.addEventListener('mousemove', handleMouseMove);
30
+ return () => window.removeEventListener('mousemove', handleMouseMove);
31
+ }, [enabled, shouldReduceMotion, handleMouseMove, rawX, rawY]);
32
+ return { x, y };
33
+ }
34
+
35
+ export { useMouseTracking };
@@ -0,0 +1,2 @@
1
+ export { InteractiveCharacters } from './InteractiveCharacters';
2
+ export type { InteractiveCharactersProps, CharacterState, CharacterSize, } from './InteractiveCharacters.types';
@@ -14,4 +14,4 @@ import type { MorphingTextProps } from './MorphingText.types';
14
14
  * />
15
15
  * ```
16
16
  */
17
- export declare const MorphingText: React.FC<MorphingTextProps>;
17
+ export declare const MorphingText: React.ForwardRefExoticComponent<MorphingTextProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useId, useState, useRef, useCallback, useEffect } from 'react';
2
+ import React__default, { useId, useState, useRef, useCallback, useEffect } from 'react';
3
3
  import { useReducedMotion, AnimatePresence, motion } from 'motion/react';
4
4
  import { cn } from '../../../utils/cn.js';
5
5
 
@@ -17,7 +17,7 @@ import { cn } from '../../../utils/cn.js';
17
17
  * />
18
18
  * ```
19
19
  */
20
- const MorphingText = ({ texts, interval = 3000, transitionDuration = 800, loop = true, pauseOnHover = false, currentIndex: controlledIndex, onTextChange, className, ...props }) => {
20
+ const MorphingText = React__default.forwardRef(({ texts, interval = 3000, transitionDuration = 800, loop = true, pauseOnHover = false, currentIndex: controlledIndex, onTextChange, className, ...props }, ref) => {
21
21
  const filterId = useId();
22
22
  const shouldReduceMotion = useReducedMotion();
23
23
  const isControlled = controlledIndex !== undefined;
@@ -80,12 +80,13 @@ const MorphingText = ({ texts, interval = 3000, transitionDuration = 800, loop =
80
80
  const currentText = texts[safeIndex];
81
81
  // Reduced motion: instant swap with no animation
82
82
  if (shouldReduceMotion) {
83
- return (jsx("div", { className: cn('relative inline-block', className), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, "aria-live": "polite", "aria-atomic": "true", ...props, children: jsx("span", { children: currentText }) }));
83
+ return (jsx("div", { ref: ref, className: cn('relative inline-block', className), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, "aria-live": "polite", "aria-atomic": "true", ...props, children: jsx("span", { children: currentText }) }));
84
84
  }
85
- return (jsxs("div", { className: cn('relative inline-block', className), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, "aria-live": "polite", "aria-atomic": "true", ...props, children: [jsx("svg", { className: "absolute h-0 w-0", "aria-hidden": "true", children: jsx("defs", { children: jsx("filter", { id: `${filterId}-blur`, children: jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "0" }) }) }) }), jsx("span", { className: "invisible block", "aria-hidden": "true", children: currentText }), jsx(AnimatePresence, { mode: "popLayout", initial: false, children: jsx(motion.span, { className: "absolute inset-0 flex items-center", initial: { opacity: 0, filter: 'blur(8px)' }, animate: { opacity: 1, filter: 'blur(0px)' }, exit: { opacity: 0, filter: 'blur(8px)' }, transition: {
85
+ return (jsxs("div", { ref: ref, className: cn('relative inline-block', className), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, "aria-live": "polite", "aria-atomic": "true", ...props, children: [jsx("svg", { className: "absolute h-0 w-0", "aria-hidden": "true", children: jsx("defs", { children: jsx("filter", { id: `${filterId}-blur`, children: jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "0" }) }) }) }), jsx("span", { className: "invisible block", "aria-hidden": "true", children: currentText }), jsx(AnimatePresence, { mode: "popLayout", initial: false, children: jsx(motion.span, { className: "absolute inset-0 flex items-center", initial: { opacity: 0, filter: 'blur(8px)' }, animate: { opacity: 1, filter: 'blur(0px)' }, exit: { opacity: 0, filter: 'blur(8px)' }, transition: {
86
86
  duration: durationSeconds,
87
87
  ease: 'easeInOut',
88
88
  }, children: currentText }, safeIndex) })] }));
89
- };
89
+ });
90
+ MorphingText.displayName = "MorphingText";
90
91
 
91
92
  export { MorphingText };
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ export interface InsetCircleButtonProps {
3
+ children: React.ReactNode;
4
+ size?: number;
5
+ className?: string;
6
+ classNameDisc?: string;
7
+ classNameHover?: string;
8
+ }
9
+ export declare function InsetCircleButton({ children, size, className, classNameDisc, classNameHover, }: InsetCircleButtonProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { motion } from 'motion/react';
3
+ import { cn } from '../../../utils/cn.js';
4
+ import 'react';
5
+
6
+ function InsetCircleButton({ children, size = 44, className, classNameDisc, classNameHover, }) {
7
+ return (jsx("div", { className: cn("neu-circle-groove group shrink-0 cursor-pointer bg-neutral-200/80 dark:bg-neutral-900", className), style: { width: size, height: size }, children: jsxs(motion.div, { className: cn("neu-circle-disc bg-linear-to-br from-neutral-100 to-neutral-300 dark:from-neutral-700 dark:to-neutral-900", classNameDisc), whileHover: { scale: 1 }, whileTap: { scale: 0.975 }, transition: { type: "spring", stiffness: 200, damping: 20 }, children: [jsx("div", { className: cn("absolute inset-0 rounded-full bg-linear-to-br from-neutral-300 to-neutral-200 dark:from-neutral-900 dark:to-neutral-700 opacity-0 group-hover:opacity-100 transition-opacity duration-300", classNameHover) }), jsx("div", { className: "relative z-2", children: children })] }) }));
8
+ }
9
+
10
+ export { InsetCircleButton };
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ export interface InsetPillProps {
3
+ children: React.ReactNode;
4
+ className?: string;
5
+ padding?: string;
6
+ }
7
+ export declare function InsetPill({ children, className, padding, }: InsetPillProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+
3
+ function InsetPill({ children, className, padding = "10px 18px", }) {
4
+ return (jsx("div", { className: `neu-inset inline-flex items-center gap-2 cursor-pointer rounded-full bg-neutral-200/60 dark:bg-neutral-800/80 ${className !== null && className !== void 0 ? className : ""}`, style: { padding }, children: jsx("div", { className: "relative z-2 flex items-center gap-2", children: children }) }));
5
+ }
6
+
7
+ export { InsetPill };
@@ -0,0 +1,4 @@
1
+ export { InsetCircleButton } from "./InsetCircleButton";
2
+ export type { InsetCircleButtonProps } from "./InsetCircleButton";
3
+ export { InsetPill } from "./InsetPill";
4
+ export type { InsetPillProps } from "./InsetPill";
@@ -25,4 +25,4 @@ import type { NoiseOverlayProps } from "./NoiseOverlay.types";
25
25
  * </div>
26
26
  * ```
27
27
  */
28
- export declare const NoiseOverlay: React.FC<NoiseOverlayProps>;
28
+ export declare const NoiseOverlay: React.ForwardRefExoticComponent<NoiseOverlayProps & React.RefAttributes<HTMLDivElement>>;
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useId, useRef, useEffect } from 'react';
2
+ import React__default, { useId, useRef, useEffect } from 'react';
3
3
  import { useReducedMotion } from 'motion/react';
4
4
  import { cn } from '../../../utils/cn.js';
5
5
 
@@ -28,7 +28,7 @@ import { cn } from '../../../utils/cn.js';
28
28
  * </div>
29
29
  * ```
30
30
  */
31
- const NoiseOverlay = ({ opacity = 0.15, frequency = 0.65, octaves = 4, blendMode = "overlay", animated = false, className, style, ...props }) => {
31
+ const NoiseOverlay = React__default.forwardRef(({ opacity = 0.15, frequency = 0.65, octaves = 4, blendMode = "overlay", animated = false, className, style, ...props }, ref) => {
32
32
  const filterId = useId();
33
33
  const shouldReduceMotion = useReducedMotion();
34
34
  const turbulenceRef = useRef(null);
@@ -50,12 +50,12 @@ const NoiseOverlay = ({ opacity = 0.15, frequency = 0.65, octaves = 4, blendMode
50
50
  clearInterval(intervalId);
51
51
  };
52
52
  }, [isAnimating]);
53
- return (jsx("div", { className: cn("absolute inset-0 pointer-events-none", className), style: {
53
+ return (jsx("div", { ref: ref, className: cn("absolute inset-0 pointer-events-none", className), style: {
54
54
  mixBlendMode: blendMode,
55
55
  opacity,
56
56
  ...style,
57
57
  }, "aria-hidden": "true", ...props, children: jsxs("svg", { className: "absolute inset-0 w-full h-full", xmlns: "http://www.w3.org/2000/svg", preserveAspectRatio: "none", children: [jsx("filter", { id: filterId, children: jsx("feTurbulence", { ref: turbulenceRef, type: "fractalNoise", baseFrequency: frequency, numOctaves: octaves, stitchTiles: "stitch", seed: 0 }) }), jsx("rect", { width: "100%", height: "100%", filter: `url(#${filterId})` })] }) }));
58
- };
58
+ });
59
59
  NoiseOverlay.displayName = "NoiseOverlay";
60
60
 
61
61
  export { NoiseOverlay };
@@ -97,14 +97,16 @@ const Overlay = React__default.forwardRef(({ isOpen, onClose, closeOnOverlayClic
97
97
  const finalContentAnimations = { ...contentAnimations };
98
98
  if (animationDuration) {
99
99
  if (animationDuration.enter && finalOverlayAnimations.animate) {
100
- finalOverlayAnimations.animate.transition = {
101
- ...finalOverlayAnimations.animate.transition,
100
+ const animate = finalOverlayAnimations.animate;
101
+ animate.transition = {
102
+ ...animate.transition,
102
103
  duration: animationDuration.enter,
103
104
  };
104
105
  }
105
106
  if (animationDuration.exit && finalOverlayAnimations.exit) {
106
- finalOverlayAnimations.exit.transition = {
107
- ...finalOverlayAnimations.exit.transition,
107
+ const exit = finalOverlayAnimations.exit;
108
+ exit.transition = {
109
+ ...exit.transition,
108
110
  duration: animationDuration.exit,
109
111
  };
110
112
  }
@@ -0,0 +1,8 @@
1
+ import type { PageTransitionDirection } from './PageTransition.types';
2
+ import type { Variants } from 'motion/react';
3
+ export declare const buildCurtainVariants: (direction: PageTransitionDirection, duration: number) => Variants;
4
+ export declare const buildLogoParallaxVariants: (direction: PageTransitionDirection, duration: number) => Variants;
5
+ export declare const buildSplitVariants: (axis: "h" | "v", duration: number) => {
6
+ panel1: Variants;
7
+ panel2: Variants;
8
+ };
@@ -0,0 +1,53 @@
1
+ const exitMap = {
2
+ up: { y: '-100%', x: 0 },
3
+ down: { y: '100%', x: 0 },
4
+ left: { x: '-100%', y: 0 },
5
+ right: { x: '100%', y: 0 },
6
+ };
7
+ const buildCurtainVariants = (direction, duration) => ({
8
+ covered: { y: 0, x: 0 },
9
+ exit: {
10
+ ...exitMap[direction],
11
+ transition: {
12
+ duration,
13
+ ease: [0.76, 0, 0.24, 1],
14
+ },
15
+ },
16
+ });
17
+ // Logo is rendered INSIDE the curtain. These are relative offsets that
18
+ // counteract ~30% of the curtain's motion, making the logo appear to
19
+ // move at ~70% of the curtain's speed (parallax lag effect).
20
+ const logoInnerOffsetMap = {
21
+ up: { y: '30vh', x: 0 },
22
+ down: { y: '-30vh', x: 0 },
23
+ left: { x: '30vw', y: 0 },
24
+ right: { x: '-30vw', y: 0 },
25
+ };
26
+ const buildLogoParallaxVariants = (direction, duration) => ({
27
+ covered: { y: 0, x: 0 },
28
+ exit: {
29
+ ...logoInnerOffsetMap[direction],
30
+ transition: {
31
+ duration,
32
+ ease: [0.76, 0, 0.24, 1],
33
+ },
34
+ },
35
+ });
36
+ const buildSplitVariants = (axis, duration) => ({
37
+ panel1: {
38
+ covered: {},
39
+ exit: {
40
+ [axis === 'h' ? 'y' : 'x']: '-100%',
41
+ transition: { duration, ease: [0.76, 0, 0.24, 1] },
42
+ },
43
+ },
44
+ panel2: {
45
+ covered: {},
46
+ exit: {
47
+ [axis === 'h' ? 'y' : 'x']: '100%',
48
+ transition: { duration, ease: [0.76, 0, 0.24, 1] },
49
+ },
50
+ },
51
+ });
52
+
53
+ export { buildCurtainVariants, buildLogoParallaxVariants, buildSplitVariants };
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import type { PageTransitionProps } from "./PageTransition.types";
3
+ export declare const PageTransition: React.FC<PageTransitionProps>;
@@ -0,0 +1,71 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { useState, useEffect } from 'react';
3
+ import { motion } from 'motion/react';
4
+ import { cn } from '../../../utils/cn.js';
5
+ import { buildCurtainVariants, buildLogoParallaxVariants, buildSplitVariants } from './PageTransition.animations.js';
6
+
7
+ const PageTransition = ({ children, logo, type = "slide", direction = "up", duration = 0.8, delay = 0.8, color = "bg-[var(--color-primary)]", className, parallax = true, onStart, onComplete, }) => {
8
+ const [phase, setPhase] = useState("covered");
9
+ const [completedPanels, setCompletedPanels] = useState(0);
10
+ useEffect(() => {
11
+ let cancelled = false;
12
+ const loadPromise = new Promise((resolve) => {
13
+ if (document.readyState === "complete") {
14
+ resolve();
15
+ }
16
+ else {
17
+ window.addEventListener("load", () => resolve(), { once: true });
18
+ }
19
+ });
20
+ const delayPromise = new Promise((resolve) => {
21
+ setTimeout(resolve, delay * 1000);
22
+ });
23
+ Promise.all([loadPromise, delayPromise]).then(() => {
24
+ if (!cancelled) {
25
+ setPhase("exit");
26
+ setTimeout(() => {
27
+ if (!cancelled)
28
+ onStart === null || onStart === void 0 ? void 0 : onStart();
29
+ }, 250);
30
+ }
31
+ });
32
+ return () => {
33
+ cancelled = true;
34
+ };
35
+ }, [delay]);
36
+ useEffect(() => {
37
+ if (type === "split" && completedPanels === 2) {
38
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete();
39
+ }
40
+ }, [completedPanels, type, onComplete]);
41
+ if (type === "split") {
42
+ const axis = direction === "up" || direction === "down" ? "h" : "v";
43
+ const splitVars = buildSplitVariants(axis, duration);
44
+ return (jsxs(Fragment, { children: [children, jsxs("div", { className: "fixed inset-0 z-[9999] pointer-events-none", children: [jsx(motion.div, { className: cn(axis === "h"
45
+ ? "absolute inset-x-0 top-0 h-1/2"
46
+ : "absolute inset-y-0 left-0 w-1/2", color, className), variants: splitVars.panel1, initial: "covered", animate: phase, onAnimationComplete: (def) => {
47
+ if (def === "exit")
48
+ setCompletedPanels((n) => n + 1);
49
+ } }), jsx(motion.div, { className: cn(axis === "h"
50
+ ? "absolute inset-x-0 bottom-0 h-1/2"
51
+ : "absolute inset-y-0 right-0 w-1/2", color, className), variants: splitVars.panel2, initial: "covered", animate: phase, onAnimationComplete: (def) => {
52
+ if (def === "exit")
53
+ setCompletedPanels((n) => n + 1);
54
+ } }), logo && (jsx("div", { className: "absolute inset-0 flex items-center justify-center z-10 pointer-events-none select-none", children: logo }))] })] }));
55
+ }
56
+ // Default: slide
57
+ const curtainVariants = buildCurtainVariants(direction, duration);
58
+ if (type === "slide" && parallax) {
59
+ const logoVariants = buildLogoParallaxVariants(direction, duration);
60
+ return (jsxs(Fragment, { children: [children, jsx(motion.div, { className: cn("fixed inset-0 z-[9999] flex items-center justify-center", color, className), style: { willChange: "transform" }, variants: curtainVariants, initial: "covered", animate: phase, onAnimationComplete: (def) => {
61
+ if (def === "exit")
62
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete();
63
+ }, children: logo && (jsx(motion.div, { className: "relative z-10 select-none", variants: logoVariants, initial: "covered", animate: phase, children: logo })) })] }));
64
+ }
65
+ return (jsxs(Fragment, { children: [children, jsx(motion.div, { className: cn("fixed inset-0 z-[9999] flex items-center justify-center", color, className), style: { willChange: "transform" }, variants: curtainVariants, initial: "covered", animate: phase, onAnimationComplete: (def) => {
66
+ if (def === "exit")
67
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete();
68
+ }, children: logo && jsx("div", { className: "relative z-10 select-none", children: logo }) })] }));
69
+ };
70
+
71
+ export { PageTransition };
@@ -0,0 +1,15 @@
1
+ export type PageTransitionDirection = 'up' | 'down' | 'left' | 'right';
2
+ export type PageTransitionType = 'slide' | 'split';
3
+ export interface PageTransitionProps {
4
+ children: React.ReactNode;
5
+ logo?: React.ReactNode;
6
+ type?: PageTransitionType;
7
+ direction?: PageTransitionDirection;
8
+ duration?: number;
9
+ delay?: number;
10
+ color?: string;
11
+ className?: string;
12
+ parallax?: boolean;
13
+ onStart?: () => void;
14
+ onComplete?: () => void;
15
+ }
@@ -0,0 +1,2 @@
1
+ export { PageTransition } from './PageTransition';
2
+ export type { PageTransitionProps, PageTransitionDirection } from './PageTransition.types';
@@ -30,3 +30,9 @@ export { ScrollReveal } from "./ScrollReveal";
30
30
  export type { ScrollRevealProps, ScrollRevealPreset } from "./ScrollReveal";
31
31
  export { StickyScroll } from "./StickyScroll";
32
32
  export type { StickyScrollProps, StickyScrollSection, } from "./StickyScroll";
33
+ export { PageTransition } from "./PageTransition";
34
+ export type { PageTransitionProps, PageTransitionDirection, } from "./PageTransition";
35
+ export { InteractiveCharacters } from "./InteractiveCharacters";
36
+ export type { InteractiveCharactersProps, CharacterState, CharacterSize, } from "./InteractiveCharacters";
37
+ export { InsetCircleButton, InsetPill } from "./Neumorphic";
38
+ export type { InsetCircleButtonProps, InsetPillProps, } from "./Neumorphic";
@@ -14,3 +14,7 @@ export { Spotlight } from './Spotlight/Spotlight.js';
14
14
  export { ParallaxSection } from './ParallaxSection/ParallaxSection.js';
15
15
  export { ScrollReveal } from './ScrollReveal/ScrollReveal.js';
16
16
  export { StickyScroll } from './StickyScroll/StickyScroll.js';
17
+ export { PageTransition } from './PageTransition/PageTransition.js';
18
+ export { InteractiveCharacters } from './InteractiveCharacters/InteractiveCharacters.js';
19
+ export { InsetCircleButton } from './Neumorphic/InsetCircleButton.js';
20
+ export { InsetPill } from './Neumorphic/InsetPill.js';
@@ -0,0 +1,14 @@
1
+ import { Variants } from "motion/react";
2
+ /**
3
+ * Checkmark SVG path draw-on animation
4
+ * Animates pathLength from 0 → 1 for a smooth draw effect
5
+ */
6
+ export declare const checkmarkVariants: Variants;
7
+ /**
8
+ * Indeterminate dash draw-on animation
9
+ */
10
+ export declare const indeterminateVariants: Variants;
11
+ /**
12
+ * Reduced motion variants — instant opacity toggle, no path draw
13
+ */
14
+ export declare const reducedMotionVariants: Variants;
@@ -0,0 +1,53 @@
1
+ const smoothEase = [0.65, 0, 0.35, 1];
2
+ /**
3
+ * Checkmark SVG path draw-on animation
4
+ * Animates pathLength from 0 → 1 for a smooth draw effect
5
+ */
6
+ const checkmarkVariants = {
7
+ unchecked: {
8
+ pathLength: 0,
9
+ opacity: 0,
10
+ transition: {
11
+ pathLength: { duration: 0.15, ease: smoothEase },
12
+ opacity: { duration: 0.1, ease: "easeOut" },
13
+ },
14
+ },
15
+ checked: {
16
+ pathLength: 1,
17
+ opacity: 1,
18
+ transition: {
19
+ pathLength: { duration: 0.2, ease: smoothEase },
20
+ opacity: { duration: 0.05, ease: "easeOut" },
21
+ },
22
+ },
23
+ };
24
+ /**
25
+ * Indeterminate dash draw-on animation
26
+ */
27
+ const indeterminateVariants = {
28
+ unchecked: {
29
+ pathLength: 0,
30
+ opacity: 0,
31
+ transition: {
32
+ pathLength: { duration: 0.1, ease: smoothEase },
33
+ opacity: { duration: 0.08, ease: "easeOut" },
34
+ },
35
+ },
36
+ checked: {
37
+ pathLength: 1,
38
+ opacity: 1,
39
+ transition: {
40
+ pathLength: { duration: 0.15, ease: smoothEase },
41
+ opacity: { duration: 0.05, ease: "easeOut" },
42
+ },
43
+ },
44
+ };
45
+ /**
46
+ * Reduced motion variants — instant opacity toggle, no path draw
47
+ */
48
+ const reducedMotionVariants = {
49
+ unchecked: { opacity: 0 },
50
+ checked: { opacity: 1 },
51
+ };
52
+
53
+ export { checkmarkVariants, indeterminateVariants, reducedMotionVariants };