@mova-ui/react 0.4.10 → 0.4.11

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 (512) hide show
  1. package/dist/catalog/components/cards/CardTimeMachine.d.ts +7 -0
  2. package/dist/catalog/components/cards/CardTimeMachine.js +14 -11
  3. package/dist/catalog/components/dither-charts/DitherBook.d.ts +5 -2
  4. package/dist/catalog/components/dither-charts/DitherBook.js +35 -27
  5. package/dist/catalog/components/dither-charts/DitherChartsGrid.js +3 -3
  6. package/dist/catalog/components/simple-comp/DitherChartsGrid.js +3 -3
  7. package/dist/catalog/data/ditherCharts.js +3 -3
  8. package/dist/catalog/data/formElements.js +2 -2
  9. package/dist/catalog/data/installCommand.js +2 -2
  10. package/dist/catalog/data/metrics.js +2 -2
  11. package/dist/catalog/data/supportedRegistryIds.js +1 -1
  12. package/dist/catalog/data/textAnimations.js +2 -2
  13. package/dist/catalog/data/toggles.js +2 -2
  14. package/dist/catalog/data/transitions.js +2 -2
  15. package/dist/catalog-chunks/{chunk-YPZZOKH4.js → chunk-CQ7VYA46.js} +7 -0
  16. package/dist/catalog-chunks/{chunk-6NP66VN5.js → chunk-EYGZ2KK7.js} +1 -1
  17. package/dist/catalog-chunks/{chunk-WKFJSUM3.js → chunk-PMFHIVMP.js} +1 -1
  18. package/dist/index.d.ts +7 -0
  19. package/dist/index.js +2149 -143
  20. package/dist/styles.css +1 -1
  21. package/dist/ui/patterns/animated-mega-menu.d.ts +23 -0
  22. package/dist/ui/patterns/blur-carousel.d.ts +44 -0
  23. package/dist/ui/patterns/compare-slider.d.ts +15 -0
  24. package/dist/ui/patterns/fold-panel.d.ts +15 -0
  25. package/dist/ui/patterns/gesture-range-slider.d.ts +21 -0
  26. package/dist/ui/patterns/long-press-context-menu.d.ts +48 -0
  27. package/dist/ui/patterns/split-view.d.ts +17 -0
  28. package/package.json +1 -1
  29. package/registry/1.json +1 -1
  30. package/registry/10.json +1 -1
  31. package/registry/11.json +1 -1
  32. package/registry/12.json +1 -1
  33. package/registry/13.json +1 -1
  34. package/registry/14.json +1 -1
  35. package/registry/15.json +1 -1
  36. package/registry/16.json +1 -1
  37. package/registry/17.json +1 -1
  38. package/registry/18.json +1 -1
  39. package/registry/19.json +1 -1
  40. package/registry/2.json +1 -1
  41. package/registry/20.json +1 -1
  42. package/registry/21.json +1 -1
  43. package/registry/22.json +1 -1
  44. package/registry/23.json +1 -1
  45. package/registry/24.json +1 -1
  46. package/registry/25.json +1 -1
  47. package/registry/26.json +1 -1
  48. package/registry/27.json +1 -1
  49. package/registry/28.json +1 -1
  50. package/registry/29.json +1 -1
  51. package/registry/3.json +1 -1
  52. package/registry/30.json +1 -1
  53. package/registry/31.json +1 -1
  54. package/registry/32.json +1 -1
  55. package/registry/33.json +1 -1
  56. package/registry/34.json +1 -1
  57. package/registry/35.json +1 -1
  58. package/registry/36.json +1 -1
  59. package/registry/37.json +1 -1
  60. package/registry/4.json +1 -1
  61. package/registry/5.json +1 -1
  62. package/registry/6.json +1 -1
  63. package/registry/7.json +1 -1
  64. package/registry/8.json +1 -1
  65. package/registry/9.json +1 -1
  66. package/registry/LICENSE.third-party +52 -0
  67. package/registry/ab-segmented-tabs.json +1 -1
  68. package/registry/accordion-blind.json +1 -1
  69. package/registry/accordion-loader.json +1 -1
  70. package/registry/ai-approval-card.json +1 -1
  71. package/registry/ai-code-block.json +1 -1
  72. package/registry/ai-context-meter.json +1 -1
  73. package/registry/ai-fine-tune-card.json +1 -1
  74. package/registry/ai-prompt-bar.json +1 -1
  75. package/registry/ai-sidebar-nav.json +1 -1
  76. package/registry/ai-sources.json +1 -1
  77. package/registry/ai-suggestions.json +1 -1
  78. package/registry/ai-task-list.json +1 -1
  79. package/registry/ai-tool-call.json +1 -1
  80. package/registry/analyzing-image.json +1 -1
  81. package/registry/animated-mega-menu.json +21 -0
  82. package/registry/animated-sidebar.json +1 -1
  83. package/registry/animated-tags.json +1 -1
  84. package/registry/app-icon-load.json +1 -1
  85. package/registry/apple-breathe.json +1 -1
  86. package/registry/apple-equalizer.json +1 -1
  87. package/registry/apple-icon-morph.json +1 -1
  88. package/registry/apple-pulse-dots.json +1 -1
  89. package/registry/apple-scale-pulse.json +1 -1
  90. package/registry/apple-sound-wave.json +1 -1
  91. package/registry/apple-text-reveal.json +1 -1
  92. package/registry/apple-unlock.json +1 -1
  93. package/registry/arc-tracer.json +1 -1
  94. package/registry/balance-bar-chart-card.json +1 -1
  95. package/registry/bar-cascade.json +1 -1
  96. package/registry/bar-sweep.json +1 -1
  97. package/registry/blur-carousel.json +18 -0
  98. package/registry/blur-text.json +1 -1
  99. package/registry/blur-up-char.json +1 -1
  100. package/registry/blur-up-word.json +1 -1
  101. package/registry/bobbing-dots.json +1 -1
  102. package/registry/bookmark-corner-peel.json +1 -1
  103. package/registry/bookmark-save-pill.json +1 -1
  104. package/registry/bookmark-toggle.json +1 -1
  105. package/registry/border-trail-loading.json +1 -1
  106. package/registry/bounce-dots.json +1 -1
  107. package/registry/bounce-in-char.json +1 -1
  108. package/registry/bouncing-bars.json +1 -1
  109. package/registry/bouncing-dots.json +1 -1
  110. package/registry/bouncing-lines.json +1 -1
  111. package/registry/bouncing-square.json +1 -1
  112. package/registry/breathe-ring.json +1 -1
  113. package/registry/breathing-glow.json +1 -1
  114. package/registry/breathing-square.json +1 -1
  115. package/registry/btn-1.json +1 -1
  116. package/registry/btn-10.json +1 -1
  117. package/registry/btn-11.json +1 -1
  118. package/registry/btn-12.json +1 -1
  119. package/registry/btn-13.json +1 -1
  120. package/registry/btn-14.json +1 -1
  121. package/registry/btn-15.json +1 -1
  122. package/registry/btn-16.json +1 -1
  123. package/registry/btn-17.json +1 -1
  124. package/registry/btn-18.json +1 -1
  125. package/registry/btn-19.json +1 -1
  126. package/registry/btn-2.json +1 -1
  127. package/registry/btn-20.json +1 -1
  128. package/registry/btn-21.json +1 -1
  129. package/registry/btn-22.json +1 -1
  130. package/registry/btn-23.json +1 -1
  131. package/registry/btn-24.json +1 -1
  132. package/registry/btn-25.json +1 -1
  133. package/registry/btn-26.json +1 -1
  134. package/registry/btn-27.json +1 -1
  135. package/registry/btn-28.json +1 -1
  136. package/registry/btn-29.json +1 -1
  137. package/registry/btn-3.json +1 -1
  138. package/registry/btn-30.json +1 -1
  139. package/registry/btn-31.json +1 -1
  140. package/registry/btn-32.json +1 -1
  141. package/registry/btn-33.json +1 -1
  142. package/registry/btn-34.json +1 -1
  143. package/registry/btn-35.json +1 -1
  144. package/registry/btn-36.json +1 -1
  145. package/registry/btn-37.json +1 -1
  146. package/registry/btn-4.json +1 -1
  147. package/registry/btn-5.json +1 -1
  148. package/registry/btn-6.json +1 -1
  149. package/registry/btn-7.json +1 -1
  150. package/registry/btn-8.json +1 -1
  151. package/registry/btn-9.json +1 -1
  152. package/registry/button-slide-arrow.json +1 -1
  153. package/registry/cacheable-bandwidth-cost.json +1 -1
  154. package/registry/calendar-day-card.json +1 -1
  155. package/registry/card-arc-5.json +1 -1
  156. package/registry/card-arc-7.json +1 -1
  157. package/registry/card-carousel-mono.json +1 -1
  158. package/registry/card-carousel.json +1 -1
  159. package/registry/card-cascade-stagger.json +1 -1
  160. package/registry/card-corner-fan.json +1 -1
  161. package/registry/card-cover-flow-mono.json +1 -1
  162. package/registry/card-cover-flow.json +1 -1
  163. package/registry/card-deck-cascade.json +1 -1
  164. package/registry/card-glance-preview.json +1 -1
  165. package/registry/card-hover.json +1 -1
  166. package/registry/card-linear-spread.json +1 -1
  167. package/registry/card-long-arc-5.json +1 -1
  168. package/registry/card-scatter-spread.json +1 -1
  169. package/registry/card-stack-peel.json +1 -1
  170. package/registry/card-stamp-arc.json +1 -1
  171. package/registry/card-time-machine-mono.json +1 -1
  172. package/registry/card-time-machine.json +1 -1
  173. package/registry/card-wheel-fan.json +1 -1
  174. package/registry/category-select.json +1 -1
  175. package/registry/character-stagger.json +1 -1
  176. package/registry/checkbox-draw.json +1 -1
  177. package/registry/checkmark-draw.json +1 -1
  178. package/registry/circle-toggle.json +1 -1
  179. package/registry/circuit-trace-draw.json +1 -1
  180. package/registry/circular-bars.json +1 -1
  181. package/registry/circular-create-button.json +1 -1
  182. package/registry/classic-spinner.json +1 -1
  183. package/registry/classic-toggle.json +1 -1
  184. package/registry/clock-spinner.json +1 -1
  185. package/registry/comet-spinner.json +1 -1
  186. package/registry/compare-slider.json +19 -0
  187. package/registry/compass-needle-deflect.json +1 -1
  188. package/registry/concentric-pulse.json +1 -1
  189. package/registry/concentric-ring.json +1 -1
  190. package/registry/concentric-squares.json +1 -1
  191. package/registry/context-menu.json +1 -1
  192. package/registry/conveyor-loop.json +1 -1
  193. package/registry/credit-score-barcode-meter.json +1 -1
  194. package/registry/cross-spinner.json +1 -1
  195. package/registry/cube-flip-spring.json +1 -1
  196. package/registry/cursor-trail.json +1 -1
  197. package/registry/dash-ring.json +1 -1
  198. package/registry/dashed-spiral.json +1 -1
  199. package/registry/date-position-selector.json +1 -1
  200. package/registry/day-trading-order-ticket.json +1 -1
  201. package/registry/dia-text-reveal.json +1 -1
  202. package/registry/diamond-grid.json +1 -1
  203. package/registry/diamond-rotate-spring.json +1 -1
  204. package/registry/dislike-toggle.json +1 -1
  205. package/registry/dither-book.json +1 -1
  206. package/registry/domino-cascade.json +1 -1
  207. package/registry/dot-spinner.json +1 -1
  208. package/registry/dots-ring.json +1 -1
  209. package/registry/double-bounce-toggle.json +1 -1
  210. package/registry/double-ring.json +1 -1
  211. package/registry/download-icons.json +1 -1
  212. package/registry/drop-dot.json +1 -1
  213. package/registry/drop-in-char.json +1 -1
  214. package/registry/droplet-squish.json +1 -1
  215. package/registry/dual-arc.json +1 -1
  216. package/registry/dual-magnet-dipole.json +1 -1
  217. package/registry/dynamic-island.json +1 -1
  218. package/registry/elastic-bars.json +1 -1
  219. package/registry/elastic-square.json +1 -1
  220. package/registry/elastic-tag-snap.json +1 -1
  221. package/registry/error-shake.json +1 -1
  222. package/registry/expanding-cross.json +1 -1
  223. package/registry/expanding-icon-tabs.json +1 -1
  224. package/registry/face-id-scan.json +1 -1
  225. package/registry/fade-arc.json +1 -1
  226. package/registry/fade-dots.json +1 -1
  227. package/registry/fade-down.json +1 -1
  228. package/registry/fade-in-char.json +1 -1
  229. package/registry/fade-in-text.json +1 -1
  230. package/registry/fade-in-word.json +1 -1
  231. package/registry/fade-in.json +1 -1
  232. package/registry/fade-up.json +1 -1
  233. package/registry/file-upload-dropzone.json +1 -1
  234. package/registry/filter-tag-pill.json +1 -1
  235. package/registry/flip-square.json +1 -1
  236. package/registry/flip-x-char.json +1 -1
  237. package/registry/flip-y-char.json +1 -1
  238. package/registry/float-char.json +1 -1
  239. package/registry/float-word.json +1 -1
  240. package/registry/floating-diamonds.json +1 -1
  241. package/registry/floating-label-input.json +1 -1
  242. package/registry/fluid-bars.json +1 -1
  243. package/registry/fluid-diamond.json +1 -1
  244. package/registry/fluid-dot-orbit.json +1 -1
  245. package/registry/fluid-skeleton.json +1 -1
  246. package/registry/focus-blur.json +1 -1
  247. package/registry/fold-panel.json +19 -0
  248. package/registry/form-submit-button.json +1 -1
  249. package/registry/french-doors-3d.json +1 -1
  250. package/registry/gear-tooth-step.json +1 -1
  251. package/registry/gears.json +1 -1
  252. package/registry/gelatin-wobble.json +1 -1
  253. package/registry/geometric-iris-shutter.json +1 -1
  254. package/registry/gesture-range-slider.json +18 -0
  255. package/registry/glassmorphic-card.json +1 -1
  256. package/registry/glow-button.json +1 -1
  257. package/registry/glow-text.json +1 -1
  258. package/registry/gooey-popover.json +1 -1
  259. package/registry/gradient-arc.json +1 -1
  260. package/registry/gradient-shimmer.json +1 -1
  261. package/registry/grid-dots.json +1 -1
  262. package/registry/haptic-ring.json +1 -1
  263. package/registry/heartbeat.json +1 -1
  264. package/registry/hex-lattice-draw.json +1 -1
  265. package/registry/hexagon-spinner.json +1 -1
  266. package/registry/hourglass.json +1 -1
  267. package/registry/hover-lift-char.json +1 -1
  268. package/registry/hover-lift-word.json +1 -1
  269. package/registry/hover-link-card.json +1 -1
  270. package/registry/hover-scale-char.json +1 -1
  271. package/registry/hover-scale-word.json +1 -1
  272. package/registry/imessage-chat.json +1 -1
  273. package/registry/inertia-skid-stop.json +1 -1
  274. package/registry/infinity-path.json +1 -1
  275. package/registry/input-focus-glow.json +1 -1
  276. package/registry/inset-action-button.json +1 -1
  277. package/registry/inset-button.json +1 -1
  278. package/registry/intersecting-rings.json +1 -1
  279. package/registry/ios-spinner.json +1 -1
  280. package/registry/kinetic-metronome-tick.json +1 -1
  281. package/registry/kinetic-tension-capsule.json +1 -1
  282. package/registry/light-dark-morph.json +1 -1
  283. package/registry/like-toggle.json +1 -1
  284. package/registry/line-spinner.json +1 -1
  285. package/registry/liquid-dots.json +1 -1
  286. package/registry/liquid-glass-sheet.json +1 -1
  287. package/registry/long-press-context-menu.json +19 -0
  288. package/registry/mac-terminal.json +1 -1
  289. package/registry/magnetic-button.json +1 -1
  290. package/registry/magnetic-disks.json +1 -1
  291. package/registry/magnetic-dots.json +1 -1
  292. package/registry/magnetic-slide-btn.json +1 -1
  293. package/registry/manifest.json +785 -652
  294. package/registry/matrix-grid-loader.json +1 -1
  295. package/registry/minimal-triangle.json +1 -1
  296. package/registry/modular-tile-snap.json +1 -1
  297. package/registry/mono-activity-blue.json +1 -1
  298. package/registry/mono-activity-green.json +1 -1
  299. package/registry/mono-activity-purple.json +1 -1
  300. package/registry/mono-heatmap.json +1 -1
  301. package/registry/mono-rounded-area.json +1 -1
  302. package/registry/mono-rounded-bar.json +1 -1
  303. package/registry/mono-rounded-bubble.json +1 -1
  304. package/registry/mono-rounded-bullet.json +1 -1
  305. package/registry/mono-rounded-candlestick.json +1 -1
  306. package/registry/mono-rounded-composed.json +1 -1
  307. package/registry/mono-rounded-donut.json +1 -1
  308. package/registry/mono-rounded-funnel.json +1 -1
  309. package/registry/mono-rounded-gauge-arc.json +1 -1
  310. package/registry/mono-rounded-heatmap.json +1 -1
  311. package/registry/mono-rounded-kpi.json +1 -1
  312. package/registry/mono-rounded-line.json +1 -1
  313. package/registry/mono-rounded-meter.json +1 -1
  314. package/registry/mono-rounded-polar.json +1 -1
  315. package/registry/mono-rounded-pyramid.json +1 -1
  316. package/registry/mono-rounded-radar.json +1 -1
  317. package/registry/mono-rounded-radial-gauge.json +1 -1
  318. package/registry/mono-rounded-radial-group.json +1 -1
  319. package/registry/mono-rounded-range.json +1 -1
  320. package/registry/mono-rounded-sankey.json +1 -1
  321. package/registry/mono-rounded-scatter.json +1 -1
  322. package/registry/mono-rounded-sparkline.json +1 -1
  323. package/registry/mono-rounded-stacked-bar.json +1 -1
  324. package/registry/mono-rounded-step.json +1 -1
  325. package/registry/mono-rounded-stream.json +1 -1
  326. package/registry/mono-rounded-treemap.json +1 -1
  327. package/registry/mono-rounded-waterfall.json +1 -1
  328. package/registry/mono-stock.json +1 -1
  329. package/registry/morph-action-pill.json +1 -1
  330. package/registry/morph-dot-ring.json +1 -1
  331. package/registry/morph-loader.json +1 -1
  332. package/registry/morph-toggle.json +1 -1
  333. package/registry/morphing-bars.json +1 -1
  334. package/registry/morphing-infinity.json +1 -1
  335. package/registry/morphing-ring.json +1 -1
  336. package/registry/morphing-shape.json +1 -1
  337. package/registry/mouse-follow.json +1 -1
  338. package/registry/multi-select-chips.json +1 -1
  339. package/registry/multi-tab-bar.json +1 -1
  340. package/registry/neon-sign-draw.json +1 -1
  341. package/registry/nested-orbital-gimbal.json +1 -1
  342. package/registry/network-telemetry-matrix.json +1 -1
  343. package/registry/newtons-cradle.json +1 -1
  344. package/registry/noise-decibel-level.json +1 -1
  345. package/registry/obsidian-liquid-wave.json +1 -1
  346. package/registry/offset-rings.json +1 -1
  347. package/registry/orbiting-circles.json +1 -1
  348. package/registry/orbiting-dot.json +1 -1
  349. package/registry/origami-envelope-unfold.json +1 -1
  350. package/registry/origami-shape.json +1 -1
  351. package/registry/otp-input.json +1 -1
  352. package/registry/overview-bar-scrubber-card.json +1 -1
  353. package/registry/page-transition.json +1 -1
  354. package/registry/page-turn-curl.json +1 -1
  355. package/registry/password-toggle.json +1 -1
  356. package/registry/pendulum-bubble-level.json +1 -1
  357. package/registry/pendulum.json +1 -1
  358. package/registry/perspective-flip-stage.json +1 -1
  359. package/registry/perspective-flip.json +1 -1
  360. package/registry/perspective-layout-switcher.json +1 -1
  361. package/registry/physics-dock.json +1 -1
  362. package/registry/pill-tabs.json +1 -1
  363. package/registry/plus-minus-toggle.json +1 -1
  364. package/registry/presets.json +1 -1
  365. package/registry/prism-block-stack.json +1 -1
  366. package/registry/progress-indicator-piano.json +1 -1
  367. package/registry/progress-indicator.json +1 -1
  368. package/registry/progress-stepper.json +1 -1
  369. package/registry/pulsating-dots.json +1 -1
  370. package/registry/pulse-char.json +1 -1
  371. package/registry/pulse-dot.json +1 -1
  372. package/registry/pulse-dots.json +1 -1
  373. package/registry/pulse-square.json +1 -1
  374. package/registry/pulse-word.json +1 -1
  375. package/registry/pulse.json +1 -1
  376. package/registry/pumping-heart.json +1 -1
  377. package/registry/pyramid-block-build.json +1 -1
  378. package/registry/radar-sweep.json +1 -1
  379. package/registry/radial-iris-mask.json +1 -1
  380. package/registry/radial-spinner.json +1 -1
  381. package/registry/radio-scale.json +1 -1
  382. package/registry/range-slider.json +1 -1
  383. package/registry/receipt-tape-print.json +1 -1
  384. package/registry/rectangle-toggle.json +1 -1
  385. package/registry/repost-toggle.json +1 -1
  386. package/registry/reveal-text.json +1 -1
  387. package/registry/ribbon-banner-slide.json +1 -1
  388. package/registry/ring-sweep.json +1 -1
  389. package/registry/ripple-effect.json +1 -1
  390. package/registry/rise-up-word.json +1 -1
  391. package/registry/roller-blind-drop.json +1 -1
  392. package/registry/rolling-tumble.json +1 -1
  393. package/registry/rotate-in-char.json +1 -1
  394. package/registry/rotating-cross.json +1 -1
  395. package/registry/rotating-louvers.json +1 -1
  396. package/registry/rotating-triangle.json +1 -1
  397. package/registry/rudder-issue-board.json +1 -1
  398. package/registry/sales-analytics-dual-bars.json +1 -1
  399. package/registry/sales-overview-radial-dashboard.json +1 -1
  400. package/registry/sales-target-segmented-arc.json +1 -1
  401. package/registry/scale-in-char.json +1 -1
  402. package/registry/scale-in-text.json +1 -1
  403. package/registry/scale-in-word.json +1 -1
  404. package/registry/scale-in.json +1 -1
  405. package/registry/scramble-text.json +1 -1
  406. package/registry/scroll-canvas-unroll.json +1 -1
  407. package/registry/scroll-reveal.json +1 -1
  408. package/registry/search-expand.json +1 -1
  409. package/registry/segmented-arc-meter.json +1 -1
  410. package/registry/segmented-link-stretch.json +1 -1
  411. package/registry/segmented-step-bar.json +1 -1
  412. package/registry/segmented-stepper-dots.json +1 -1
  413. package/registry/select-dropdown.json +1 -1
  414. package/registry/server-performance-step-bars.json +1 -1
  415. package/registry/shape-shift-grid.json +1 -1
  416. package/registry/shimmer-line.json +1 -1
  417. package/registry/shimmer-text.json +1 -1
  418. package/registry/shutter-slide.json +1 -1
  419. package/registry/shutter-step-slices.json +1 -1
  420. package/registry/siri-wave.json +1 -1
  421. package/registry/skeleton-loader.json +1 -1
  422. package/registry/skeleton.json +1 -1
  423. package/registry/skew-x-char.json +1 -1
  424. package/registry/slide-down-char.json +1 -1
  425. package/registry/slide-down-word.json +1 -1
  426. package/registry/slide-left-char.json +1 -1
  427. package/registry/slide-left.json +1 -1
  428. package/registry/slide-right-char.json +1 -1
  429. package/registry/slide-right.json +1 -1
  430. package/registry/slide-up-char.json +1 -1
  431. package/registry/slide-up-text.json +1 -1
  432. package/registry/slide-up-word.json +1 -1
  433. package/registry/sliding-bars.json +1 -1
  434. package/registry/slinky-coil.json +1 -1
  435. package/registry/smart-card-dispenser.json +1 -1
  436. package/registry/smooth-dot-shift.json +1 -1
  437. package/registry/smooth-ring.json +1 -1
  438. package/registry/smooth-rounded-square.json +1 -1
  439. package/registry/solid-switch.json +1 -1
  440. package/registry/spatial-door-portal.json +1 -1
  441. package/registry/spinning-squares.json +1 -1
  442. package/registry/spiral-spinner.json +1 -1
  443. package/registry/split-gate-reveal.json +1 -1
  444. package/registry/split-view.json +18 -0
  445. package/registry/spotlight.json +1 -1
  446. package/registry/spring-bars.json +1 -1
  447. package/registry/spring-dot-matrix.json +1 -1
  448. package/registry/spring-hexagon.json +1 -1
  449. package/registry/spring-ring-expand.json +1 -1
  450. package/registry/spring-text-pop.json +1 -1
  451. package/registry/spring-text.json +1 -1
  452. package/registry/square-accordion.json +1 -1
  453. package/registry/square-grid.json +1 -1
  454. package/registry/square-snake.json +1 -1
  455. package/registry/square-spinner.json +1 -1
  456. package/registry/squash-sphere.json +1 -1
  457. package/registry/stacked-bar-pulse.json +1 -1
  458. package/registry/stagger-text.json +1 -1
  459. package/registry/staggered-glass-curtain.json +1 -1
  460. package/registry/sticky-note-peel.json +1 -1
  461. package/registry/sticky-reveal.json +1 -1
  462. package/registry/stretch-x-char.json +1 -1
  463. package/registry/stretch-y-char.json +1 -1
  464. package/registry/stroke-waveform.json +1 -1
  465. package/registry/submenu-flyout.json +1 -1
  466. package/registry/success-check.json +1 -1
  467. package/registry/sudden-brake.json +1 -1
  468. package/registry/swapping-dots.json +1 -1
  469. package/registry/swing-word.json +1 -1
  470. package/registry/swirling-spinner.json +1 -1
  471. package/registry/symmetric-wave.json +1 -1
  472. package/registry/terminal-loader.json +1 -1
  473. package/registry/text-blink.json +1 -1
  474. package/registry/text-dots.json +1 -1
  475. package/registry/text-morph.json +1 -1
  476. package/registry/text-reveal.json +1 -1
  477. package/registry/text-shimmer-wave.json +1 -1
  478. package/registry/text-shimmer.json +1 -1
  479. package/registry/textarea-auto-grow.json +1 -1
  480. package/registry/theme-toggle.json +1 -1
  481. package/registry/tilt-card.json +1 -1
  482. package/registry/timer-preparation-segmented.json +1 -1
  483. package/registry/tracking-in-text.json +1 -1
  484. package/registry/tracking-out-text.json +1 -1
  485. package/registry/trailing-dots.json +1 -1
  486. package/registry/triple-dot-spinner.json +1 -1
  487. package/registry/twin-orbit.json +1 -1
  488. package/registry/typewriter-text.json +1 -1
  489. package/registry/typing-indicator.json +1 -1
  490. package/registry/typing.json +1 -1
  491. package/registry/use-mouse-position.json +1 -1
  492. package/registry/use-reduced-motion.json +1 -1
  493. package/registry/use-scroll-progress.json +1 -1
  494. package/registry/use-stagger.json +1 -1
  495. package/registry/use-web-haptics.json +1 -1
  496. package/registry/users-growth-pill-progress.json +1 -1
  497. package/registry/utils.json +1 -1
  498. package/registry/vertical-wheel-counter.json +1 -1
  499. package/registry/views-hourly-wave-chart.json +1 -1
  500. package/registry/voice-assistant-card.json +1 -1
  501. package/registry/wandering-cube.json +1 -1
  502. package/registry/wandering-eyes.json +1 -1
  503. package/registry/watch-spinner.json +1 -1
  504. package/registry/wave-dots.json +1 -1
  505. package/registry/wave-physics-loader.json +1 -1
  506. package/registry/wave-reveal.json +1 -1
  507. package/registry/waveform-loader.json +1 -1
  508. package/registry/word-reveal.json +1 -1
  509. package/registry/zig-zag-pulse.json +1 -1
  510. package/registry/zoom-in-text.json +1 -1
  511. package/registry/zoom-in.json +1 -1
  512. package/registry/zoom-out-text.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "floating-diamonds",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "floating-diamonds.tsx",
6
6
  "sourcePath": "ui/loading/floating-diamonds.tsx",
7
7
  "registryFile": "floating-diamonds.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "floating-label-input",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "floating-label-input.tsx",
6
6
  "registryFile": "floating-label-input.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "fluid-bars",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "fluid-bars.tsx",
6
6
  "sourcePath": "ui/loading/fluid-bars.tsx",
7
7
  "registryFile": "fluid-bars.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "fluid-diamond",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "fluid-diamond.tsx",
6
6
  "sourcePath": "ui/loading/fluid-diamond.tsx",
7
7
  "registryFile": "fluid-diamond.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "fluid-dot-orbit",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "fluid-dot-orbit.tsx",
6
6
  "sourcePath": "ui/loading/fluid-dot-orbit.tsx",
7
7
  "registryFile": "fluid-dot-orbit.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "fluid-skeleton",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "fluid-skeleton.tsx",
6
6
  "sourcePath": "ui/loading/fluid-skeleton.tsx",
7
7
  "registryFile": "fluid-skeleton.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "focus-blur",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "focus-blur.tsx",
6
6
  "registryFile": "focus-blur.json",
7
7
  "exports": [
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": "fold-panel",
3
+ "tier": "free",
4
+ "version": "0.4.11",
5
+ "file": "fold-panel.tsx",
6
+ "sourcePath": "ui/patterns/fold-panel.tsx",
7
+ "registryFile": "fold-panel.json",
8
+ "exports": [
9
+ "FoldPanel",
10
+ "FoldPanelProps"
11
+ ],
12
+ "dependencies": [
13
+ "framer-motion",
14
+ "lucide-react"
15
+ ],
16
+ "license": "MIT",
17
+ "previewMode": "client",
18
+ "content": "\"use client\";\n/*\nReact web adaptation of https://kinetik-ui.dev/components/fold-panel\n\nMIT License\n\nCopyright (c) 2026 Nurullah Turgut\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n*/\nimport { useCallback, useEffect, useId, useRef, useState, type CSSProperties, type ReactNode } from 'react';\nimport { motion, useReducedMotion, useSpring, useTransform } from 'framer-motion';\nimport { ChevronDown } from 'lucide-react';\n\nexport interface FoldPanelProps {\n title: string;\n subtitle?: string;\n leading?: ReactNode;\n children: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n disabled?: boolean;\n theme?: 'dark' | 'light';\n className?: string;\n style?: CSSProperties;\n}\n\nconst foldSpring = { stiffness: 210, damping: 27, mass: 1 };\nconst focusStyle = 'focus-visible:outline-2 focus-visible:outline-offset-[-3px] focus-visible:outline-current';\n\nexport function FoldPanel({\n title, subtitle, leading, children, open, defaultOpen = false, onOpenChange,\n disabled = false, theme = 'dark', className, style,\n}: FoldPanelProps) {\n const [innerOpen, setInnerOpen] = useState(defaultOpen);\n const expanded = open ?? innerOpen;\n const reduced = useReducedMotion();\n const contentId = useId();\n const trigger = useRef<HTMLButtonElement>(null);\n const progress = useSpring(expanded ? 1 : 0, foldSpring);\n const rows = useTransform(progress, [0, 1], ['0fr', '1fr']);\n const opacity = useTransform(progress, [0.3, 0.8], [0, 1]);\n const offset = useTransform(progress, [0, 1], [-10, 0]);\n const rotate = useTransform(progress, [0, 1], [0, 180]);\n const dark = theme === 'dark';\n const backgroundColor = useTransform(progress, [0, 1], dark ? ['#0a0a0a', '#1c1c1c'] : ['#fafafa', '#ffffff']);\n const borderColor = useTransform(progress, [0, 1], dark\n ? ['rgba(255,255,255,.08)', 'rgba(255,255,255,.16)']\n : ['rgba(0,0,0,.08)', 'rgba(0,0,0,.16)']);\n\n useEffect(() => {\n const value = expanded ? 1 : 0;\n if (reduced) progress.jump(value);\n else progress.set(value);\n }, [expanded, progress, reduced]);\n\n const setContent = useCallback((element: HTMLDivElement | null) => {\n if (!element) return;\n if (!expanded && element.contains(document.activeElement)) trigger.current?.focus();\n element.inert = !expanded;\n }, [expanded]);\n\n function toggle() {\n if (open === undefined) setInnerOpen(!expanded);\n onOpenChange?.(!expanded);\n }\n\n return (\n <motion.div\n className={className}\n whileTap={disabled || reduced ? undefined : { scale: 0.99 }}\n transition={{ type: 'spring', stiffness: 520, damping: 38, mass: 1 }}\n style={{\n width: '100%', border: '1px solid', borderRadius: 20, overflow: 'hidden',\n opacity: disabled ? 0.5 : 1, color: dark ? '#ededed' : '#0a0a0a',\n backgroundColor, borderColor, ...style,\n }}\n >\n <button\n ref={trigger}\n type=\"button\"\n className={focusStyle}\n aria-controls={contentId}\n aria-expanded={expanded}\n disabled={disabled}\n onClick={toggle}\n style={{\n appearance: 'none', display: 'flex', alignItems: 'center', width: '100%',\n minHeight: 64, gap: 12, padding: '12px 16px', border: 0, background: 'none',\n color: 'inherit', font: 'inherit', cursor: disabled ? 'default' : 'pointer',\n textAlign: 'start',\n }}\n >\n {leading != null && (\n <span aria-hidden=\"true\" style={{\n display: 'grid', placeItems: 'center', width: 36, height: 36, flexShrink: 0,\n borderRadius: 10, color: dark ? '#7ab2ff' : '#1f5fe0',\n background: dark ? 'rgba(59,130,246,.16)' : 'rgba(31,95,224,.1)',\n }}>\n {leading}\n </span>\n )}\n <span style={{ display: 'grid', flex: 1, minWidth: 0, gap: 2 }}>\n <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontSize: 16, lineHeight: 1.2, fontWeight: 600 }}>{title}</span>\n {subtitle && (\n <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontSize: 14, lineHeight: 1.3, color: dark ? '#a1a1a1' : '#555' }}>{subtitle}</span>\n )}\n </span>\n <motion.span aria-hidden=\"true\" style={{ display: 'grid', placeItems: 'center', width: 20, height: 20, flexShrink: 0, rotate, color: dark ? '#a1a1a1' : '#555' }}>\n <ChevronDown size={16} strokeWidth={1.75} />\n </motion.span>\n </button>\n <motion.div ref={setContent} id={contentId} aria-hidden={!expanded} style={{ display: 'grid', gridTemplateRows: rows }}>\n <div style={{ minHeight: 0, overflow: 'hidden' }}>\n <motion.div style={{ padding: '0 16px 16px', opacity, y: offset }}>\n {children}\n </motion.div>\n </div>\n </motion.div>\n </motion.div>\n );\n}\n"
19
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "form-submit-button",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "form-submit-button.tsx",
6
6
  "registryFile": "form-submit-button.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "french-doors-3d",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "french-doors-3d.tsx",
6
6
  "registryFile": "french-doors-3d.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "gear-tooth-step",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "gear-tooth-step.tsx",
6
6
  "sourcePath": "components/css-animations/whimsical/ConceptTrios3.tsx",
7
7
  "registryFile": "gear-tooth-step.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "gears",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "gears.tsx",
6
6
  "sourcePath": "ui/loading/gears.tsx",
7
7
  "registryFile": "gears.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "gelatin-wobble",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "gelatin-wobble.tsx",
6
6
  "sourcePath": "components/css-animations/whimsical/WhimsicalVariations.tsx",
7
7
  "registryFile": "gelatin-wobble.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "geometric-iris-shutter",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "geometric-iris-shutter.tsx",
6
6
  "sourcePath": "components/css-animations/whimsical/RedesignedPhysicsTrios.tsx",
7
7
  "registryFile": "geometric-iris-shutter.json",
@@ -0,0 +1,18 @@
1
+ {
2
+ "id": "gesture-range-slider",
3
+ "tier": "free",
4
+ "version": "0.4.11",
5
+ "file": "gesture-range-slider.tsx",
6
+ "sourcePath": "ui/patterns/gesture-range-slider.tsx",
7
+ "registryFile": "gesture-range-slider.json",
8
+ "exports": [
9
+ "GestureRangeSlider",
10
+ "GestureRangeSliderProps"
11
+ ],
12
+ "dependencies": [
13
+ "framer-motion"
14
+ ],
15
+ "license": "MIT",
16
+ "previewMode": "client",
17
+ "content": "\"use client\";\n/*!\n * Adapted for the web from Reacticx Range Slider.\n * https://github.com/rit3zh/reacticx/tree/main/src/components/molecules/range-slider\n *\n * MIT License\n * Copyright (c) 2026 rit3zh\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n\"use client\";\n\nimport { useEffect, useRef, useState, type CSSProperties, type KeyboardEvent, type PointerEvent } from \"react\";\nimport { motion, useReducedMotion, useSpring, useTransform } from \"framer-motion\";\n\nexport interface GestureRangeSliderProps {\n value?: number;\n defaultValue?: number;\n onValueChange?: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n showTicks?: boolean;\n disabled?: boolean;\n trackColor?: string;\n fillColor?: string;\n thumbColor?: string;\n tickColor?: string;\n style?: CSSProperties;\n accessibilityLabel?: string;\n className?: string;\n theme?: \"dark\" | \"light\";\n}\n\nconst TRACK_HEIGHT = 40;\nconst THUMB_WIDTH = 6;\nconst THUMB_HEIGHT = 20;\nconst TICK_SIZE = 4;\nconst TICK_INSET = 18;\nconst SPRING_GLIDE = { stiffness: 700, damping: 50, mass: 0.5 };\nconst SPRING_BOUNCY = { type: \"spring\", stiffness: 500, damping: 14, mass: 0.7 } as const;\nconst PALETTE = {\n dark: { track: \"rgba(120,120,128,0.22)\", fill: \"rgba(255,255,255,0.16)\", thumb: \"#ffffff\", tick: \"rgba(255,255,255,0.25)\", focus: \"#ffffff\" },\n light: { track: \"rgba(120,120,128,0.20)\", fill: \"rgba(0,0,0,0.14)\", thumb: \"#171717\", tick: \"rgba(0,0,0,0.32)\", focus: \"#171717\" },\n};\n\nfunction clamp(value: number, min: number, max: number) {\n return Math.min(max, Math.max(min, value));\n}\n\nfunction decimalPlaces(value: number) {\n const [mantissa, exponent = \"0\"] = String(value).split(\"e\");\n return Math.max(0, (mantissa.split(\".\")[1]?.length ?? 0) - Number(exponent));\n}\n\nfunction thumbPosition(fraction: number, extra = 0) {\n const ratio = clamp(fraction, 0, 1);\n return `max(${extra}px, calc(${ratio * 100}% + ${extra - ratio * THUMB_WIDTH}px))`;\n}\n\nconst centerVertically = {\n position: \"absolute\",\n pointerEvents: \"none\",\n top: \"50%\",\n} as const;\n\nexport function GestureRangeSlider({\n value,\n defaultValue = 0,\n onValueChange,\n min = 0,\n max = 100,\n step = 1,\n showTicks = true,\n disabled = false,\n trackColor,\n fillColor,\n thumbColor,\n tickColor,\n style,\n accessibilityLabel = \"Value\",\n className,\n theme = \"dark\",\n}: GestureRangeSliderProps) {\n const minimum = Number.isFinite(min) ? min : 0;\n const maximum = Number.isFinite(max) ? Math.max(minimum, max) : Math.max(minimum, 100);\n const range = maximum - minimum;\n const increment = Number.isFinite(step) && step > 0 ? step : 1;\n const precision = Math.max(decimalPlaces(minimum), decimalPlaces(increment));\n const canAdjust = !disabled && range > 0 && Number.isFinite(range);\n const controlled = value !== undefined;\n const [internal, setInternal] = useState(defaultValue);\n const [dragging, setDragging] = useState(false);\n const pointerId = useRef<number | null>(null);\n const raw = value ?? internal;\n const current = clamp(Number.isFinite(raw) ? raw : minimum, minimum, maximum);\n const lastValue = useRef(current);\n const fraction = range > 0 && Number.isFinite(range) ? (current - minimum) / range : 0;\n const palette = PALETTE[theme];\n const reducedMotion = useReducedMotion();\n const position = useSpring(fraction, SPRING_GLIDE);\n const thumbLeft = useTransform(position, (ratio) => thumbPosition(ratio));\n const fillWidth = useTransform(position, (ratio) => thumbPosition(ratio, THUMB_WIDTH / 2));\n\n useEffect(() => {\n if (controlled || pointerId.current === null) lastValue.current = current;\n if (reducedMotion) position.jump(fraction);\n else position.set(fraction);\n }, [controlled, current, fraction, position, reducedMotion]);\n\n function commit(next: number) {\n if (lastValue.current === next) return;\n lastValue.current = next;\n if (!controlled) setInternal(next);\n onValueChange?.(next);\n }\n\n function valueFromStep(index: number) {\n const stepped = minimum + index * increment;\n const rounded = precision <= 100 ? Number(stepped.toFixed(precision)) : stepped;\n return clamp(rounded, minimum, maximum);\n }\n\n function updateFromPointer(event: PointerEvent<HTMLDivElement>) {\n const rect = event.currentTarget.getBoundingClientRect();\n if (rect.width <= 0) return;\n const ratio = clamp((event.clientX - rect.left) / rect.width, 0, 1);\n commit(valueFromStep(Math.round((ratio * range) / increment)));\n }\n\n function startDrag(event: PointerEvent<HTMLDivElement>) {\n if (!canAdjust || event.button !== 0 || pointerId.current !== null) return;\n pointerId.current = event.pointerId;\n lastValue.current = current;\n event.currentTarget.setPointerCapture(event.pointerId);\n setDragging(true);\n updateFromPointer(event);\n }\n\n function moveDrag(event: PointerEvent<HTMLDivElement>) {\n if (canAdjust && pointerId.current === event.pointerId) updateFromPointer(event);\n }\n\n function finishDrag(event: PointerEvent<HTMLDivElement>) {\n if (pointerId.current !== event.pointerId) return;\n if (canAdjust && event.type === \"pointerup\") updateFromPointer(event);\n pointerId.current = null;\n setDragging(false);\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n if (!canAdjust || pointerId.current !== null) return;\n const index = (current - minimum) / increment;\n const nearestIndex = Math.round(index);\n const onStep = valueFromStep(nearestIndex) === current;\n const nextIndex = onStep ? nearestIndex + 1 : Math.ceil(index);\n const previousIndex = onStep ? nearestIndex - 1 : Math.floor(index);\n let target: number;\n\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowUp\": target = valueFromStep(nextIndex); break;\n case \"ArrowLeft\":\n case \"ArrowDown\": target = valueFromStep(previousIndex); break;\n case \"PageUp\": target = valueFromStep(nextIndex + 9); break;\n case \"PageDown\": target = valueFromStep(previousIndex - 9); break;\n case \"Home\": target = minimum; break;\n case \"End\": target = maximum; break;\n default: return;\n }\n\n event.preventDefault();\n lastValue.current = current;\n commit(target);\n }\n\n const tickSteps = Math.floor(range / increment);\n const showMarkers = showTicks && tickSteps > 0 && tickSteps <= 50;\n\n return (\n <div\n role=\"slider\"\n aria-label={accessibilityLabel}\n aria-orientation=\"horizontal\"\n aria-valuemin={minimum}\n aria-valuemax={maximum}\n aria-valuenow={current}\n aria-disabled={!canAdjust || undefined}\n tabIndex={canAdjust ? 0 : -1}\n data-mova-gesture-range=\"\"\n className={className}\n onKeyDown={handleKeyDown}\n onPointerDown={startDrag}\n onPointerMove={moveDrag}\n onPointerUp={finishDrag}\n onPointerCancel={finishDrag}\n onLostPointerCapture={finishDrag}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: TRACK_HEIGHT,\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n borderRadius: 10,\n cursor: canAdjust ? \"pointer\" : \"default\",\n touchAction: canAdjust ? \"none\" : \"auto\",\n userSelect: \"none\",\n color: palette.focus,\n backgroundColor: trackColor ?? palette.track,\n opacity: disabled ? 0.5 : 1,\n ...style,\n }}\n >\n <style>{`[data-mova-gesture-range]:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }`}</style>\n <motion.span\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n pointerEvents: \"none\",\n top: 0,\n bottom: 0,\n left: 0,\n width: fillWidth,\n backgroundColor: fillColor ?? palette.fill,\n }}\n />\n {showMarkers && Array.from({ length: tickSteps + 1 }, (_, index) => {\n const ratio = index / tickSteps;\n return (\n <span\n key={index}\n aria-hidden=\"true\"\n style={{\n ...centerVertically,\n width: TICK_SIZE,\n height: TICK_SIZE,\n marginTop: -TICK_SIZE / 2,\n left: `clamp(0px, calc(${ratio * 100}% + ${TICK_INSET * (1 - 2 * ratio) - TICK_SIZE / 2}px), 100%)`,\n borderRadius: \"50%\",\n backgroundColor: tickColor ?? palette.tick,\n }}\n />\n );\n })}\n <motion.span\n aria-hidden=\"true\"\n initial={false}\n animate={{ scaleY: dragging && canAdjust && !reducedMotion ? 1.35 : 1 }}\n transition={reducedMotion ? { duration: 0 } : SPRING_BOUNCY}\n style={{\n ...centerVertically,\n left: thumbLeft,\n width: THUMB_WIDTH,\n height: THUMB_HEIGHT,\n marginTop: -THUMB_HEIGHT / 2,\n borderRadius: 3,\n backgroundColor: thumbColor ?? palette.thumb,\n }}\n />\n </div>\n );\n}\n\nexport default GestureRangeSlider;\n"
18
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "glassmorphic-card",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "glassmorphic-card.tsx",
6
6
  "sourcePath": "ui/loading/glassmorphic-card.tsx",
7
7
  "registryFile": "glassmorphic-card.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "glow-button",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "glow-button.tsx",
6
6
  "sourcePath": "ui/hover/glow-button.tsx",
7
7
  "registryFile": "glow-button.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "glow-text",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "glow-text.tsx",
6
6
  "registryFile": "glow-text.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "gooey-popover",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "gooey-popover.tsx",
6
6
  "sourcePath": "ui/patterns/gooey-popover.tsx",
7
7
  "registryFile": "gooey-popover.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "gradient-arc",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "gradient-arc.tsx",
6
6
  "sourcePath": "ui/loading/gradient-arc.tsx",
7
7
  "registryFile": "gradient-arc.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "gradient-shimmer",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "gradient-shimmer.tsx",
6
6
  "registryFile": "gradient-shimmer.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "grid-dots",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "grid-dots.tsx",
6
6
  "sourcePath": "ui/loading/grid-dots.tsx",
7
7
  "registryFile": "grid-dots.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "haptic-ring",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "haptic-ring.tsx",
6
6
  "sourcePath": "ui/loading/haptic-ring.tsx",
7
7
  "registryFile": "haptic-ring.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "heartbeat",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "heartbeat.tsx",
6
6
  "sourcePath": "ui/loading/heartbeat.tsx",
7
7
  "registryFile": "heartbeat.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "hex-lattice-draw",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "hex-lattice-draw.tsx",
6
6
  "sourcePath": "components/css-animations/whimsical/RedesignedPhysicsTrios.tsx",
7
7
  "registryFile": "hex-lattice-draw.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "hexagon-spinner",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "hexagon-spinner.tsx",
6
6
  "sourcePath": "ui/loading/hexagon-spinner.tsx",
7
7
  "registryFile": "hexagon-spinner.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "hourglass",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "hourglass.tsx",
6
6
  "sourcePath": "ui/loading/hourglass.tsx",
7
7
  "registryFile": "hourglass.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "hover-lift-char",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "hover-lift-char.tsx",
6
6
  "registryFile": "hover-lift-char.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "hover-lift-word",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "hover-lift-word.tsx",
6
6
  "registryFile": "hover-lift-word.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "hover-link-card",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "hover-link-card.tsx",
6
6
  "sourcePath": "components/css-animations/yui-components/YuiUiKit1.tsx",
7
7
  "registryFile": "hover-link-card.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "hover-scale-char",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "hover-scale-char.tsx",
6
6
  "registryFile": "hover-scale-char.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "hover-scale-word",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "hover-scale-word.tsx",
6
6
  "registryFile": "hover-scale-word.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "imessage-chat",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "imessage-chat.tsx",
6
6
  "sourcePath": "ui/cards/imessage-chat.tsx",
7
7
  "registryFile": "imessage-chat.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "inertia-skid-stop",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "inertia-skid-stop.tsx",
6
6
  "sourcePath": "components/css-animations/whimsical/YuiPhysicsExperiments.tsx",
7
7
  "registryFile": "inertia-skid-stop.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "infinity-path",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "infinity-path.tsx",
6
6
  "sourcePath": "ui/loading/infinity-path.tsx",
7
7
  "registryFile": "infinity-path.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "input-focus-glow",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "input-focus-glow.tsx",
6
6
  "registryFile": "input-focus-glow.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "inset-action-button",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "inset-action-button.tsx",
6
6
  "registryFile": "inset-action-button.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "inset-button",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "inset-button.tsx",
6
6
  "sourcePath": "ui/hover/inset-button.tsx",
7
7
  "registryFile": "inset-button.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "intersecting-rings",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "intersecting-rings.tsx",
6
6
  "sourcePath": "ui/loading/intersecting-rings.tsx",
7
7
  "registryFile": "intersecting-rings.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "ios-spinner",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "ios-spinner.tsx",
6
6
  "sourcePath": "ui/loading/ios-spinner.tsx",
7
7
  "registryFile": "ios-spinner.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "kinetic-metronome-tick",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "kinetic-metronome-tick.tsx",
6
6
  "sourcePath": "components/css-animations/whimsical/RedesignedPhysicsTrios.tsx",
7
7
  "registryFile": "kinetic-metronome-tick.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "kinetic-tension-capsule",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "kinetic-tension-capsule.tsx",
6
6
  "sourcePath": "components/css-animations/whimsical/KineticTensionCapsule.tsx",
7
7
  "registryFile": "kinetic-tension-capsule.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "light-dark-morph",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "light-dark-morph.tsx",
6
6
  "sourcePath": "components/css-animations/yui-components/YuiUiKit1.tsx",
7
7
  "registryFile": "light-dark-morph.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "like-toggle",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "like-toggle.tsx",
6
6
  "registryFile": "like-toggle.json",
7
7
  "exports": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "line-spinner",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "line-spinner.tsx",
6
6
  "sourcePath": "ui/loading/line-spinner.tsx",
7
7
  "registryFile": "line-spinner.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "liquid-dots",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "liquid-dots.tsx",
6
6
  "sourcePath": "ui/loading/liquid-dots.tsx",
7
7
  "registryFile": "liquid-dots.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "liquid-glass-sheet",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "liquid-glass-sheet.tsx",
6
6
  "sourcePath": "ui/cards/liquid-glass-sheet.tsx",
7
7
  "registryFile": "liquid-glass-sheet.json",
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": "long-press-context-menu",
3
+ "tier": "free",
4
+ "version": "0.4.11",
5
+ "file": "long-press-context-menu.tsx",
6
+ "sourcePath": "ui/patterns/long-press-context-menu.tsx",
7
+ "registryFile": "long-press-context-menu.json",
8
+ "exports": [
9
+ "ContextMenu",
10
+ "ContextMenuAction",
11
+ "ContextMenuProps"
12
+ ],
13
+ "dependencies": [
14
+ "framer-motion"
15
+ ],
16
+ "license": "MIT",
17
+ "previewMode": "client",
18
+ "content": "\"use client\";\n\"use client\";\n\n/**\n * Adapted from Reacticx's Context Menu.\n * https://reacticx.com/components/context-menu\n * https://github.com/rit3zh/reacticx/blob/main/src/components/molecules/context-menu/index.tsx\n *\n * MIT License\n *\n * Copyright (c) 2026 rit3zh\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport React, { Fragment, useEffect, useId, useLayoutEffect, useRef, useState } from \"react\";\nimport type { CSSProperties, KeyboardEvent, PointerEvent, ReactNode, RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { AnimatePresence, motion, useIsPresent, useReducedMotion } from \"framer-motion\";\n\nexport type ContextMenuAction = {\n id: string;\n label: string;\n subtitle?: string;\n icon?: ReactNode;\n separatorBefore?: boolean;\n destructive?: boolean;\n disabled?: boolean;\n onSelect?: () => void;\n};\n\nexport type ContextMenuProps = {\n children: ReactNode;\n items: readonly ContextMenuAction[];\n label?: string;\n theme?: \"light\" | \"dark\";\n disabled?: boolean;\n className?: string;\n};\n\nconst LONG_PRESS_DURATION = 250;\nconst PRESS_SCALE = 0.97;\nconst PREVIEW_SCALE = 1.04;\nconst MENU_WIDTH = 250;\nconst MENU_GAP = 30;\nconst SCREEN_PADDING = 22;\nconst OPEN_SPRING = { type: \"spring\", damping: 12, mass: 0.5, stiffness: 120 } as const;\nconst CLOSE_TRANSITION = { duration: 0.18, ease: \"easeOut\" } as const;\nconst useClientLayoutEffect = typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\nconst palette = {\n light: {\n background: \"rgb(250 250 250 / 90%)\",\n text: \"#111111\",\n subtitle: \"#54545a\",\n destructive: \"#b51d13\",\n backdrop: \"rgb(0 0 0 / 8%)\",\n separator: \"rgb(0 0 0 / 9%)\",\n highlight: \"rgb(0 0 0 / 8%)\",\n },\n dark: {\n background: \"rgb(37 37 37 / 84%)\",\n text: \"#ffffff\",\n subtitle: \"#b0b0b5\",\n destructive: \"#ff5d54\",\n backdrop: \"rgb(0 0 0 / 35%)\",\n separator: \"rgb(255 255 255 / 10%)\",\n highlight: \"rgb(255 255 255 / 12%)\",\n },\n};\n\nconst contextMenuCss = `\n [data-mova-context-trigger]:focus-visible {\n outline: 2px solid Highlight;\n outline-offset: 4px;\n }\n [data-mova-context-action] { background: transparent; }\n [data-mova-context-action]:enabled:focus-visible {\n outline: 2px solid Highlight;\n outline-offset: -2px;\n background: var(--mova-context-highlight);\n }\n @media (hover: hover) {\n [data-mova-context-action]:enabled:hover { background: var(--mova-context-highlight); }\n }\n [data-mova-context-action]:enabled:active { background: var(--mova-context-highlight); }\n`;\n\ntype MenuPlacement = {\n left: number;\n top: number;\n width: number;\n maxHeight: number;\n origin: string;\n shiftX: number;\n shiftY: number;\n scale: number;\n};\n\nfunction placeMenu(rect: DOMRectReadOnly, height: number, reducedMotion: boolean): MenuPlacement {\n const viewport = window.visualViewport;\n const width = viewport?.width ?? document.documentElement.clientWidth;\n const viewportHeight = viewport?.height ?? document.documentElement.clientHeight;\n const inset = Math.min(SCREEN_PADDING, width / 10, viewportHeight / 10);\n const left = (viewport?.offsetLeft ?? 0) + inset;\n const top = (viewport?.offsetTop ?? 0) + inset;\n const availableWidth = width - inset * 2;\n const availableHeight = viewportHeight - inset * 2;\n const bottom = top + availableHeight;\n const gap = Math.min(MENU_GAP, availableHeight / 8);\n const menuWidth = Math.min(MENU_WIDTH, availableWidth);\n const scale = Math.min(\n reducedMotion ? 1 : PREVIEW_SCALE,\n availableWidth / Math.max(1, rect.width),\n availableHeight * 0.55 / Math.max(1, rect.height),\n );\n const previewWidth = rect.width * scale;\n const previewHeight = rect.height * scale;\n const maxHeight = availableHeight - gap - previewHeight;\n const menuHeight = Math.min(height, maxHeight);\n const centeredPreviewLeft = rect.left + (rect.width - previewWidth) / 2;\n const centeredPreviewTop = rect.top + (rect.height - previewHeight) / 2;\n const previewLeft = Math.max(left, Math.min(left + availableWidth - previewWidth, centeredPreviewLeft));\n const previewCenter = previewLeft + previewWidth / 2;\n const menuLeft = Math.max(left, Math.min(left + availableWidth - menuWidth, previewCenter - menuWidth / 2));\n const spaceAbove = centeredPreviewTop - top;\n const spaceBelow = bottom - (centeredPreviewTop + previewHeight);\n const above = spaceBelow < gap + menuHeight && spaceAbove > spaceBelow;\n const totalHeight = previewHeight + gap + menuHeight;\n const proposedTop = above ? centeredPreviewTop - gap - menuHeight : centeredPreviewTop;\n const groupTop = Math.max(top, Math.min(bottom - totalHeight, proposedTop));\n const previewTop = above ? groupTop + menuHeight + gap : groupTop;\n\n return {\n left: menuLeft,\n top: above ? groupTop : previewTop + previewHeight + gap,\n width: menuWidth,\n maxHeight,\n origin: `${Math.max(0, Math.min(menuWidth, previewCenter - menuLeft))}px ${above ? \"bottom\" : \"top\"}`,\n shiftX: previewLeft - centeredPreviewLeft,\n shiftY: previewTop - centeredPreviewTop,\n scale,\n };\n}\n\ntype Anchor = {\n rect: DOMRectReadOnly;\n pressed: boolean;\n font: string;\n color: string;\n};\n\ntype ContextMenuOverlayProps = {\n anchor: Anchor;\n triggerRef: RefObject<HTMLButtonElement | null>;\n id: string;\n label: string;\n children: ReactNode;\n items: readonly ContextMenuAction[];\n theme: NonNullable<ContextMenuProps[\"theme\"]>;\n reducedMotion: boolean;\n close: (restoreFocus?: boolean) => void;\n};\n\nfunction ContextMenuOverlay({\n anchor, triggerRef, id, label, children, items, theme, reducedMotion, close,\n}: ContextMenuOverlayProps) {\n const menuRef = useRef<HTMLDivElement>(null);\n const [placement, setPlacement] = useState<MenuPlacement | null>(null);\n const colors = palette[theme];\n const isPresent = useIsPresent();\n const closeRef = useRef(close);\n\n useClientLayoutEffect(() => { closeRef.current = close; }, [close]);\n\n useClientLayoutEffect(() => {\n const menu = menuRef.current;\n const trigger = triggerRef.current;\n if (!menu || !trigger) return;\n const update = () => setPlacement(placeMenu(anchor.rect, menu.scrollHeight, reducedMotion));\n const observer = new ResizeObserver(update);\n observer.observe(menu);\n if (menu.firstElementChild) observer.observe(menu.firstElementChild);\n window.addEventListener(\"resize\", update);\n window.visualViewport?.addEventListener(\"resize\", update);\n window.visualViewport?.addEventListener(\"scroll\", update);\n update();\n return () => {\n observer.disconnect();\n window.removeEventListener(\"resize\", update);\n window.visualViewport?.removeEventListener(\"resize\", update);\n window.visualViewport?.removeEventListener(\"scroll\", update);\n };\n }, [anchor, triggerRef, reducedMotion]);\n\n const ready = placement !== null;\n\n useClientLayoutEffect(() => {\n const menu = menuRef.current;\n if (!menu || !ready || !isPresent) return;\n const first = menu.querySelector<HTMLButtonElement>(\"[data-mova-context-action]:enabled\");\n (first ?? menu).focus({ preventScroll: true });\n\n const handleFocus = (event: FocusEvent) => {\n if (event.target instanceof Node && !menu.contains(event.target)) closeRef.current(false);\n };\n document.addEventListener(\"focusin\", handleFocus);\n return () => document.removeEventListener(\"focusin\", handleFocus);\n }, [isPresent, ready]);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"Tab\") {\n close();\n return;\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n close();\n return;\n }\n if (event.altKey || event.ctrlKey || event.metaKey) return;\n const buttons = Array.from(event.currentTarget.querySelectorAll<HTMLButtonElement>(\"[data-mova-context-action]:enabled\"));\n if (!buttons.length) return;\n const focused = buttons.indexOf(document.activeElement as HTMLButtonElement);\n let next: number;\n switch (event.key) {\n case \"ArrowDown\": next = (focused + 1) % buttons.length; break;\n case \"ArrowUp\": next = (focused < 0 ? buttons.length - 1 : (focused - 1 + buttons.length) % buttons.length); break;\n case \"Home\": next = 0; break;\n case \"End\": next = buttons.length - 1; break;\n default: {\n if (event.key.length !== 1 || event.key === \" \") return;\n const key = event.key.toLocaleLowerCase();\n const ordered = [...buttons.slice(focused + 1), ...buttons.slice(0, focused + 1)];\n const match = ordered.find((button) => button.dataset.movaContextAction?.toLocaleLowerCase().startsWith(key));\n if (!match) return;\n next = buttons.indexOf(match);\n }\n }\n event.preventDefault();\n event.stopPropagation();\n buttons[next].focus();\n };\n\n const enter = reducedMotion ? { duration: 0 } : OPEN_SPRING;\n const exit = reducedMotion ? { duration: 0 } : CLOSE_TRANSITION;\n const menuRestScale = reducedMotion ? 1 : 0.8;\n\n return (\n <motion.div\n style={{ position: \"fixed\", inset: 0, zIndex: 2147483647, pointerEvents: \"none\" }}\n onContextMenu={(event) => event.preventDefault()}\n >\n <motion.div\n aria-hidden=\"true\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1, transition: enter }}\n exit={{ opacity: 0, transition: exit }}\n onClick={() => close()}\n style={{\n position: \"absolute\",\n inset: 0,\n pointerEvents: isPresent ? \"auto\" : \"none\",\n touchAction: \"none\",\n background: colors.backdrop,\n backdropFilter: \"blur(9px)\",\n WebkitBackdropFilter: \"blur(9px)\",\n }}\n />\n <motion.div\n aria-hidden=\"true\"\n initial={{ x: 0, y: 0, scale: anchor.pressed && !reducedMotion ? PRESS_SCALE : 1 }}\n animate={placement ? { x: placement.shiftX, y: placement.shiftY, scale: placement.scale, transition: enter } : undefined}\n exit={{ x: 0, y: 0, scale: 1, transition: exit }}\n style={{\n position: \"absolute\",\n left: anchor.rect.left,\n top: anchor.rect.top,\n width: anchor.rect.width,\n height: anchor.rect.height,\n font: anchor.font,\n color: anchor.color,\n }}\n >\n {children}\n </motion.div>\n <motion.div\n ref={menuRef}\n id={id}\n role=\"menu\"\n tabIndex={-1}\n aria-label={label}\n aria-hidden={!isPresent || undefined}\n onKeyDown={handleKeyDown}\n initial={{ opacity: 0, scale: menuRestScale }}\n animate={placement ? { opacity: 1, scale: 1, transition: enter } : undefined}\n exit={{ opacity: 0, scale: menuRestScale, transition: exit }}\n style={{\n \"--mova-context-highlight\": colors.highlight,\n boxSizing: \"border-box\",\n position: \"absolute\",\n left: placement?.left ?? 0,\n top: placement?.top ?? 0,\n width: placement?.width ?? `min(${MENU_WIDTH}px, 80vw)`,\n maxHeight: placement?.maxHeight,\n visibility: ready ? \"visible\" : \"hidden\",\n pointerEvents: isPresent ? \"auto\" : \"none\",\n transformOrigin: placement?.origin,\n background: colors.background,\n color: colors.text,\n borderRadius: 36,\n paddingBlock: 12,\n overflowY: \"auto\",\n overscrollBehavior: \"contain\",\n scrollbarWidth: \"thin\",\n boxShadow: \"0 12px 24px rgb(0 0 0 / 20%)\",\n backdropFilter: \"blur(24px)\",\n WebkitBackdropFilter: \"blur(24px)\",\n font: anchor.font,\n } as CSSProperties}\n >\n <div role=\"presentation\" style={{ paddingInline: 8 }}>\n {items.map((item) => (\n <Fragment key={item.id}>\n {item.separatorBefore && (\n <div role=\"separator\" style={{ height: 1, margin: \"4px 4px\", background: colors.separator }} />\n )}\n <button\n type=\"button\"\n role=\"menuitem\"\n data-mova-context-action={item.label}\n tabIndex={-1}\n disabled={item.disabled}\n onClick={() => { close(); item.onSelect?.(); }}\n style={{\n appearance: \"none\",\n border: 0,\n borderRadius: 18,\n width: \"100%\",\n minHeight: 50,\n display: \"flex\",\n alignItems: \"center\",\n padding: \"8px 10px\",\n gap: 16,\n color: item.destructive ? colors.destructive : \"inherit\",\n opacity: item.disabled ? 0.45 : 1,\n font: \"inherit\",\n textAlign: \"start\",\n cursor: item.disabled ? \"default\" : \"pointer\",\n }}\n >\n {item.icon !== undefined && (\n <span aria-hidden=\"true\" style={{ display: \"grid\", placeItems: \"center\", flex: \"0 0 26px\" }}>\n {item.icon}\n </span>\n )}\n <span style={{ display: \"grid\", gap: 1, minWidth: 0 }}>\n <span style={{ fontSize: 17, lineHeight: 1.2, overflowWrap: \"anywhere\" }}>{item.label}</span>\n {item.subtitle && (\n <span style={{ fontSize: 13, lineHeight: 1.25, color: colors.subtitle, overflowWrap: \"anywhere\" }}>\n {item.subtitle}\n </span>\n )}\n </span>\n </button>\n </Fragment>\n ))}\n </div>\n </motion.div>\n </motion.div>\n );\n}\n\ntype Press = { pointerId: number; x: number; y: number; timer: ReturnType<typeof setTimeout> };\n\nexport function ContextMenu({\n children,\n items,\n label = \"Actions\",\n theme = \"light\",\n disabled = false,\n className,\n}: ContextMenuProps) {\n const triggerRef = useRef<HTMLButtonElement>(null);\n const pressRef = useRef<Press | null>(null);\n const ignoreClick = useRef(false);\n const id = useId();\n const reducedMotion = useReducedMotion() ?? false;\n const [pressing, setPressing] = useState(false);\n const [anchor, setAnchor] = useState<Anchor | null>(null);\n const [showPreview, setShowPreview] = useState(false);\n const unavailable = disabled || items.length === 0;\n\n useEffect(() => {\n const trigger = triggerRef.current;\n const preventLongPressClick = (event: TouchEvent) => {\n // The browser can retarget the compatibility click to the backdrop on release.\n if (ignoreClick.current && event.cancelable) event.preventDefault();\n };\n trigger?.addEventListener(\"touchend\", preventLongPressClick, { passive: false });\n\n return () => {\n trigger?.removeEventListener(\"touchend\", preventLongPressClick);\n if (pressRef.current) clearTimeout(pressRef.current.timer);\n };\n }, []);\n\n const cancelPress = () => {\n if (pressRef.current) clearTimeout(pressRef.current.timer);\n pressRef.current = null;\n setPressing(false);\n };\n\n const open = (pressed = false) => {\n const trigger = triggerRef.current;\n if (!trigger || trigger.disabled || anchor) return;\n const { font, color } = getComputedStyle(trigger);\n setAnchor({ rect: trigger.getBoundingClientRect(), font, color, pressed });\n setShowPreview(true);\n };\n\n const close = (restoreFocus = true) => {\n setAnchor(null);\n if (restoreFocus) triggerRef.current?.focus({ preventScroll: true });\n };\n\n useEffect(() => {\n if (unavailable && anchor) {\n setAnchor(null);\n setShowPreview(false);\n }\n }, [anchor, unavailable]);\n\n const handlePointerDown = (event: PointerEvent<HTMLButtonElement>) => {\n if (!event.isPrimary || event.button !== 0 || anchor) return;\n ignoreClick.current = false;\n const timer = setTimeout(() => {\n ignoreClick.current = true;\n cancelPress();\n open(true);\n }, LONG_PRESS_DURATION);\n pressRef.current = { pointerId: event.pointerId, x: event.clientX, y: event.clientY, timer };\n setPressing(true);\n };\n\n const handlePointerMove = (event: PointerEvent<HTMLButtonElement>) => {\n const press = pressRef.current;\n if (!press || press.pointerId !== event.pointerId) return;\n if (Math.hypot(event.clientX - press.x, event.clientY - press.y) < 10) return;\n ignoreClick.current = true;\n cancelPress();\n };\n\n return (\n <div className={className} style={{ position: \"relative\", display: \"inline-grid\", maxWidth: \"100%\" }}>\n <style>{contextMenuCss}</style>\n <motion.div\n animate={{ scale: !reducedMotion && pressing ? PRESS_SCALE : 1 }}\n transition={{ duration: reducedMotion ? 0 : pressing ? 0.25 : 0.16, ease: \"easeOut\" }}\n style={{ minWidth: 0, visibility: showPreview ? \"hidden\" : undefined }}\n >\n {children}\n </motion.div>\n <button\n ref={triggerRef}\n type=\"button\"\n data-mova-context-trigger=\"\"\n aria-label={label}\n aria-haspopup=\"menu\"\n aria-expanded={anchor !== null}\n aria-controls={anchor ? id : undefined}\n aria-keyshortcuts=\"Shift+F10 ContextMenu\"\n disabled={unavailable}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={cancelPress}\n onPointerCancel={cancelPress}\n onPointerLeave={cancelPress}\n onContextMenu={(event) => {\n if (unavailable) return;\n event.preventDefault();\n event.stopPropagation();\n cancelPress();\n open();\n }}\n onKeyDown={(event) => {\n if (event.key !== \"ContextMenu\" && !(event.key === \"F10\" && event.shiftKey)) return;\n event.preventDefault();\n event.stopPropagation();\n open();\n }}\n onClick={(event) => {\n if (ignoreClick.current && event.detail !== 0) {\n ignoreClick.current = false;\n return;\n }\n open();\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n appearance: \"none\",\n border: 0,\n padding: 0,\n borderRadius: \"inherit\",\n background: \"transparent\",\n color: \"inherit\",\n font: \"inherit\",\n cursor: unavailable ? undefined : \"context-menu\",\n touchAction: \"manipulation\",\n WebkitTouchCallout: \"none\",\n }}\n />\n {typeof document !== \"undefined\" && createPortal(\n <AnimatePresence onExitComplete={() => setShowPreview(false)}>\n {anchor && (\n <ContextMenuOverlay\n key=\"menu\"\n anchor={anchor}\n triggerRef={triggerRef}\n id={id}\n label={label}\n items={items}\n theme={theme}\n reducedMotion={reducedMotion}\n close={close}\n >\n {children}\n </ContextMenuOverlay>\n )}\n </AnimatePresence>,\n document.body,\n )}\n </div>\n );\n}\n"
19
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "mac-terminal",
3
3
  "tier": "free",
4
- "version": "0.4.10",
4
+ "version": "0.4.11",
5
5
  "file": "mac-terminal.tsx",
6
6
  "sourcePath": "ui/loading/mac-terminal.tsx",
7
7
  "registryFile": "mac-terminal.json",