@yewdiel21/motion-kit 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +3 -35
- package/README.md +93 -81
- package/dist/auto/index.d.ts +22 -3
- package/dist/auto/index.js +43 -5
- package/dist/auto/index.js.map +1 -1
- package/dist/{chunk-KLY5BRRI.js → chunk-34EZ7DF4.js} +1 -1
- package/dist/chunk-34EZ7DF4.js.map +1 -0
- package/dist/{chunk-RFDIZYFX.js → chunk-DOOMULVV.js} +20 -20
- package/dist/chunk-DOOMULVV.js.map +1 -0
- package/dist/{chunk-ABNRDDO7.js → chunk-I3DXF2KQ.js} +2 -2
- package/dist/{chunk-Q4LVFNLN.js → chunk-IKQ5FODN.js} +4 -4
- package/dist/chunk-IKQ5FODN.js.map +1 -0
- package/dist/{chunk-2BQGFOA7.js → chunk-J6OCFNGU.js} +2 -2
- package/dist/chunk-J6OCFNGU.js.map +1 -0
- package/dist/{chunk-6OJAP6ZL.js → chunk-QFBOHPWZ.js} +3 -3
- package/dist/chunk-QFBOHPWZ.js.map +1 -0
- package/dist/{chunk-J27KH2A2.js → chunk-RVSKEBIC.js} +1 -1
- package/dist/chunk-RVSKEBIC.js.map +1 -0
- package/dist/{chunk-34XYOXHG.js → chunk-TFNRIZHU.js} +1615 -12
- package/dist/chunk-TFNRIZHU.js.map +1 -0
- package/dist/{chunk-FS2HJVVY.js → chunk-XAKC2QY7.js} +1204 -5
- package/dist/chunk-XAKC2QY7.js.map +1 -0
- package/dist/css/components/calendar.css +159 -0
- package/dist/css/components/chat-background.css +2 -2
- package/dist/css/components/chat.css +1 -1
- package/dist/css/components/cursor.css +3 -3
- package/dist/css/components/dialog.css +3 -3
- package/dist/css/components/hover-card.css +14 -0
- package/dist/css/components/input-otp.css +10 -0
- package/dist/css/components/island.css +1 -1
- package/dist/css/components/menu.css +1 -1
- package/dist/css/components/nav.css +1 -5
- package/dist/css/components/pagination.css +11 -0
- package/dist/css/components/quantity.css +16 -0
- package/dist/css/components/slot-picker.css +126 -0
- package/dist/css/components/steps.css +2 -2
- package/dist/css/components/studio-dock.css +35 -0
- package/dist/css/components/theme-picker.css +1 -1
- package/dist/css/components/toast.css +1 -1
- package/dist/css/components/trailer.css +37 -0
- package/dist/css/controls.css +78 -13
- package/dist/css/effects.css +8 -8
- package/dist/css/fonts.css +1 -1
- package/dist/css/themes/black-green.css +1 -1
- package/dist/css/themes/black.css +1 -1
- package/dist/css/themes/blue.css +1 -1
- package/dist/css/themes/brown.css +1 -1
- package/dist/css/themes/cold-blue.css +1 -1
- package/dist/css/themes/funny.css +1 -1
- package/dist/css/themes/gray.css +1 -1
- package/dist/css/themes/green.css +1 -1
- package/dist/css/themes/modern-1.css +1 -1
- package/dist/css/themes/neogreen.css +1 -1
- package/dist/css/themes/new.css +1 -1
- package/dist/css/themes/new2.css +1 -1
- package/dist/css/themes/oled.css +1 -1
- package/dist/css/themes/orange.css +1 -1
- package/dist/css/themes/pastel-pink.css +1 -1
- package/dist/css/themes/pink.css +1 -1
- package/dist/css/themes/purple.css +1 -1
- package/dist/css/themes/red.css +1 -1
- package/dist/css/themes/super-blue.css +1 -1
- package/dist/css/themes.css +19 -19
- package/dist/css/tokens.css +9 -9
- package/dist/elements/index.d.ts +75 -7
- package/dist/elements/index.js +172 -6
- package/dist/elements/index.js.map +1 -1
- package/dist/{engine-CUr9QijM.d.ts → engine-GDGwQnJE.d.ts} +2 -2
- package/dist/gl/index.js +3 -3
- package/dist/index.css +1076 -63
- package/dist/index.d.ts +17 -17
- package/dist/index.js +49 -7
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +139 -40
- package/dist/react/index.js +355 -8
- package/dist/react/index.js.map +1 -1
- package/dist/{reduced-BM4Ls0g5.d.ts → reduced-BmBzKH94.d.ts} +215 -18
- package/dist/{reveal-WFUWDrei.d.ts → reveal-jsX-uwUz.d.ts} +233 -24
- package/dist/{store-Bqy_obnD.d.ts → store-DYb3tTsZ.d.ts} +5 -5
- package/dist/theme/generate.d.ts +1 -1
- package/dist/theme/generate.js +2 -2
- package/dist/theme/generate.js.map +1 -1
- package/dist/theme/index.d.ts +2 -2
- package/dist/theme/index.js +2 -2
- package/dist/{theme-BFMoCzi6.d.ts → theme-Bjf9qIIy.d.ts} +1 -1
- package/package.json +2 -2
- package/registry.json +230 -156
- package/skills/motion-kit/SKILL.md +209 -189
- package/skills/motion-kit/reference/components.md +5 -5
- package/skills/motion-kit/reference/design.md +14 -14
- package/skills/motion-kit/reference/recipes.md +48 -49
- package/src/auto/auto-init.ts +38 -0
- package/src/components/calendar/README.md +82 -0
- package/src/components/calendar/calendar.css +158 -0
- package/src/components/calendar/element.ts +27 -0
- package/src/components/calendar/engine.ts +412 -0
- package/src/components/calendar/react.tsx +69 -0
- package/src/components/chat/README.md +1 -3
- package/src/components/chat/chat.css +1 -1
- package/src/components/chat/engine.ts +1 -1
- package/src/components/chat/react.tsx +1 -1
- package/src/components/chat-background/README.md +1 -3
- package/src/components/chat-background/audio.ts +1 -1
- package/src/components/chat-background/chat-background.css +2 -2
- package/src/components/chat-background/engine.ts +1 -1
- package/src/components/chat-background/react.tsx +1 -1
- package/src/components/cursor/README.md +3 -5
- package/src/components/cursor/cursor.css +3 -3
- package/src/components/cursor/element.ts +2 -2
- package/src/components/cursor/engine.ts +5 -5
- package/src/components/cursor/react.tsx +1 -1
- package/src/components/dialog/README.md +4 -8
- package/src/components/dialog/dialog.css +3 -3
- package/src/components/dialog/engine.ts +2 -2
- package/src/components/dialog/react.tsx +1 -1
- package/src/components/hover-card/README.md +16 -0
- package/src/components/hover-card/element.ts +8 -0
- package/src/components/hover-card/engine.ts +69 -0
- package/src/components/hover-card/hover-card.css +13 -0
- package/src/components/hover-card/react.tsx +19 -0
- package/src/components/input-otp/README.md +18 -0
- package/src/components/input-otp/element.ts +14 -0
- package/src/components/input-otp/engine.ts +106 -0
- package/src/components/input-otp/input-otp.css +9 -0
- package/src/components/input-otp/react.tsx +21 -0
- package/src/components/island/README.md +7 -7
- package/src/components/island/engine.ts +3 -3
- package/src/components/island/island.css +1 -1
- package/src/components/island/react.tsx +3 -3
- package/src/components/menu/README.md +2 -4
- package/src/components/menu/engine.ts +1 -1
- package/src/components/menu/menu.css +1 -1
- package/src/components/menu/react.tsx +1 -1
- package/src/components/nav/README.md +12 -14
- package/src/components/nav/engine.ts +5 -5
- package/src/components/nav/nav.css +1 -5
- package/src/components/nav/react.tsx +3 -3
- package/src/components/pagination/README.md +17 -0
- package/src/components/pagination/element.ts +14 -0
- package/src/components/pagination/engine.ts +102 -0
- package/src/components/pagination/pagination.css +10 -0
- package/src/components/pagination/react.tsx +22 -0
- package/src/components/quantity/README.md +20 -0
- package/src/components/quantity/element.ts +14 -0
- package/src/components/quantity/engine.ts +85 -0
- package/src/components/quantity/quantity.css +15 -0
- package/src/components/quantity/react.tsx +21 -0
- package/src/components/slot-picker/README.md +68 -0
- package/src/components/slot-picker/element.ts +27 -0
- package/src/components/slot-picker/engine.ts +412 -0
- package/src/components/slot-picker/react.tsx +76 -0
- package/src/components/slot-picker/slot-picker.css +125 -0
- package/src/components/steps/README.md +1 -3
- package/src/components/steps/engine.ts +3 -3
- package/src/components/steps/react.tsx +2 -2
- package/src/components/steps/steps.css +2 -2
- package/src/components/studio-dock/README.md +44 -0
- package/src/components/studio-dock/element.ts +11 -0
- package/src/components/studio-dock/engine.ts +212 -0
- package/src/components/studio-dock/react.tsx +23 -0
- package/src/components/studio-dock/studio-dock.css +34 -0
- package/src/components/theme-picker/README.md +3 -5
- package/src/components/theme-picker/engine.ts +2 -2
- package/src/components/theme-picker/react.tsx +1 -1
- package/src/components/theme-picker/theme-picker.css +1 -1
- package/src/components/toast/README.md +1 -3
- package/src/components/toast/engine.ts +2 -2
- package/src/components/toast/react.tsx +1 -1
- package/src/components/toast/store.ts +1 -2
- package/src/components/toast/toast.css +1 -1
- package/src/components/trailer/README.md +28 -0
- package/src/components/trailer/element.ts +13 -0
- package/src/components/trailer/engine.ts +189 -0
- package/src/components/trailer/react.tsx +16 -0
- package/src/components/trailer/trailer.css +36 -0
- package/src/core/channels.ts +3 -3
- package/src/core/curves.ts +3 -3
- package/src/core/dates.ts +98 -0
- package/src/core/gsap.ts +2 -2
- package/src/core/loop.ts +1 -1
- package/src/core/math.ts +1 -1
- package/src/core/physics-spring.ts +2 -2
- package/src/core/scroll-track.ts +2 -4
- package/src/core/spring.ts +1 -1
- package/src/core/timing.ts +21 -22
- package/src/css/controls/README.md +24 -20
- package/src/css/controls/burger.css +1 -1
- package/src/css/controls/button.css +4 -4
- package/src/css/controls/checkbox.css +1 -1
- package/src/css/controls/chip.css +1 -1
- package/src/css/controls/field.css +2 -2
- package/src/css/controls/glass.css +4 -4
- package/src/css/controls/status.css +63 -0
- package/src/css/default-theme.css +1 -1
- package/src/css/effects/README.md +19 -21
- package/src/css/effects/anim.css +1 -1
- package/src/css/effects/fade.css +1 -1
- package/src/css/effects/float.css +1 -1
- package/src/css/effects/frost.css +1 -1
- package/src/css/effects/grain.css +1 -1
- package/src/css/effects/loading.css +1 -1
- package/src/css/effects/success.css +1 -1
- package/src/css/effects/text.css +1 -1
- package/src/css/fonts.css +1 -1
- package/src/css/states.css +1 -1
- package/src/css/themes/black-green.css +1 -1
- package/src/css/themes/black.css +1 -1
- package/src/css/themes/blue.css +1 -1
- package/src/css/themes/brown.css +1 -1
- package/src/css/themes/cold-blue.css +1 -1
- package/src/css/themes/funny.css +1 -1
- package/src/css/themes/gray.css +1 -1
- package/src/css/themes/green.css +1 -1
- package/src/css/themes/modern-1.css +1 -1
- package/src/css/themes/neogreen.css +1 -1
- package/src/css/themes/new.css +1 -1
- package/src/css/themes/new2.css +1 -1
- package/src/css/themes/oled.css +1 -1
- package/src/css/themes/orange.css +1 -1
- package/src/css/themes/pastel-pink.css +1 -1
- package/src/css/themes/pink.css +1 -1
- package/src/css/themes/purple.css +1 -1
- package/src/css/themes/red.css +1 -1
- package/src/css/themes/super-blue.css +1 -1
- package/src/css/tokens.css +8 -8
- package/src/elements/index.ts +24 -0
- package/src/gl/liquid-blend/README.md +3 -3
- package/src/gl/matcap/README.md +3 -3
- package/src/gl/particle-hero/README.md +1 -1
- package/src/gl/particle-hero/create-particle-hero.ts +3 -5
- package/src/gl/particle-hero/shaders.ts +1 -1
- package/src/gl/shader-blur/README.md +3 -3
- package/src/gl/shader-grain/README.md +3 -3
- package/src/index.ts +25 -0
- package/src/motion/chat.ts +2 -2
- package/src/motion/confetti.ts +1 -1
- package/src/motion/count.ts +1 -1
- package/src/motion/details.ts +1 -1
- package/src/motion/drag-dismiss.ts +1 -1
- package/src/motion/effects.ts +1 -1
- package/src/motion/entrances.ts +1 -1
- package/src/motion/floating.ts +1 -1
- package/src/motion/flow.ts +2 -2
- package/src/motion/indicator.ts +1 -1
- package/src/motion/layout.ts +1 -1
- package/src/motion/liquid.ts +1 -1
- package/src/motion/morph.ts +2 -2
- package/src/motion/reveal.ts +1 -1
- package/src/motion/sheet.ts +1 -1
- package/src/motion/surface.ts +1 -1
- package/src/react/animated-number.tsx +2 -2
- package/src/react/flip-group.tsx +1 -1
- package/src/react/frost.tsx +1 -1
- package/src/react/index.ts +21 -0
- package/src/react/slot-text.tsx +1 -1
- package/src/react/use-action-button.ts +6 -0
- package/src/react/use-card-dock.ts +1 -1
- package/src/react/use-cascade.ts +1 -1
- package/src/react/use-contrast.ts +1 -1
- package/src/react/use-depth-grid.ts +1 -1
- package/src/react/use-editorial-reveal.ts +7 -0
- package/src/react/use-fill-text.ts +1 -1
- package/src/react/use-film-hero.ts +6 -0
- package/src/react/use-font-cycle.ts +7 -0
- package/src/react/use-frame-zoom.ts +1 -1
- package/src/react/use-image-zoom.ts +5 -0
- package/src/react/use-joined-cta.ts +5 -0
- package/src/react/use-letters.ts +1 -1
- package/src/react/use-local-clock.ts +5 -0
- package/src/react/use-marquee.ts +1 -1
- package/src/react/use-mask-text.ts +1 -1
- package/src/react/use-parallax.ts +1 -1
- package/src/react/use-particle-hero.ts +1 -1
- package/src/react/use-scroll-dock.ts +5 -0
- package/src/react/use-snap-strip.ts +1 -1
- package/src/react/use-sticker.ts +5 -0
- package/src/react/use-studio-dock.ts +8 -0
- package/src/react/use-text-roll.ts +1 -1
- package/src/react/use-thumbnail-nav.ts +7 -0
- package/src/react/use-trailer.ts +6 -0
- package/src/react/use-weight-hover.ts +5 -0
- package/src/recipes/action-button/README.md +31 -0
- package/src/recipes/action-button/action-button.css +113 -0
- package/src/recipes/action-button/create-action-button.ts +56 -0
- package/src/recipes/card-dock/README.md +1 -1
- package/src/recipes/card-dock/card-dock.css +1 -1
- package/src/recipes/card-dock/create-card-dock.ts +2 -2
- package/src/recipes/cascade/README.md +1 -3
- package/src/recipes/cascade/create-cascade.ts +3 -3
- package/src/recipes/contrast/README.md +0 -2
- package/src/recipes/contrast/create-contrast.ts +1 -1
- package/src/recipes/counter/README.md +0 -2
- package/src/recipes/counter/create-counter.ts +1 -1
- package/src/recipes/curved-carousel/README.md +0 -2
- package/src/recipes/curved-carousel/create-curved-carousel.ts +2 -2
- package/src/recipes/curved-carousel/curved-carousel.css +1 -1
- package/src/recipes/depth-grid/README.md +0 -2
- package/src/recipes/depth-grid/create-depth-grid.ts +3 -4
- package/src/recipes/details/README.md +0 -2
- package/src/recipes/details/create-details.ts +1 -1
- package/src/recipes/dock-pill/README.md +3 -3
- package/src/recipes/drag-ruler/README.md +3 -3
- package/src/recipes/editorial-reveal/README.md +35 -0
- package/src/recipes/editorial-reveal/create-editorial-reveal.ts +91 -0
- package/src/recipes/editorial-reveal/editorial-reveal.css +17 -0
- package/src/recipes/fill-text/README.md +1 -1
- package/src/recipes/fill-text/create-fill-text.ts +1 -1
- package/src/recipes/film-hero/README.md +23 -0
- package/src/recipes/film-hero/create-film-hero.ts +65 -0
- package/src/recipes/film-hero/film-hero.css +29 -0
- package/src/recipes/fit-text/README.md +0 -2
- package/src/recipes/flow/README.md +0 -2
- package/src/recipes/flow/create-flow.ts +1 -1
- package/src/recipes/font-cycle/README.md +11 -0
- package/src/recipes/font-cycle/create-font-cycle.ts +126 -0
- package/src/recipes/font-cycle/font-cycle.css +36 -0
- package/src/recipes/frame-zoom/README.md +1 -3
- package/src/recipes/frame-zoom/create-frame-zoom.ts +2 -2
- package/src/recipes/image-zoom/README.md +16 -0
- package/src/recipes/image-zoom/create-image-zoom.ts +27 -0
- package/src/recipes/image-zoom/image-zoom.css +7 -0
- package/src/recipes/infinite-reel/README.md +3 -3
- package/src/recipes/joined-cta/README.md +13 -0
- package/src/recipes/joined-cta/create-joined-cta.ts +22 -0
- package/src/recipes/joined-cta/joined-cta.css +17 -0
- package/src/recipes/letters/README.md +2 -4
- package/src/recipes/letters/create-letters.ts +3 -3
- package/src/recipes/local-clock/README.md +31 -0
- package/src/recipes/local-clock/create-local-clock.ts +61 -0
- package/src/recipes/marquee/README.md +0 -2
- package/src/recipes/marquee/create-marquee.ts +3 -3
- package/src/recipes/marquee/marquee.css +1 -1
- package/src/recipes/mask-text/README.md +3 -5
- package/src/recipes/mask-text/create-mask-text.ts +4 -4
- package/src/recipes/parallax/README.md +1 -3
- package/src/recipes/parallax/create-parallax.ts +1 -1
- package/src/recipes/pile/README.md +0 -2
- package/src/recipes/pile/create-pile.ts +1 -1
- package/src/recipes/pile/pile-math.ts +1 -1
- package/src/recipes/pile/pile.css +1 -1
- package/src/recipes/pill/README.md +0 -2
- package/src/recipes/pill/pill.css +2 -2
- package/src/recipes/pop/README.md +0 -2
- package/src/recipes/pop/create-pop.ts +1 -1
- package/src/recipes/radial-menu/README.md +0 -2
- package/src/recipes/radial-menu/create-radial-menu.ts +1 -1
- package/src/recipes/radial-menu/radial-menu.css +1 -1
- package/src/recipes/reflow/README.md +3 -5
- package/src/recipes/reflow/create-reflow.ts +1 -1
- package/src/recipes/repel-bento/README.md +3 -3
- package/src/recipes/reveal/README.md +0 -2
- package/src/recipes/reveal/create-reveal.ts +1 -1
- package/src/recipes/rotator/README.md +3 -3
- package/src/recipes/scroll-dock/README.md +46 -0
- package/src/recipes/scroll-dock/create-scroll-dock.ts +72 -0
- package/src/recipes/scroll-dock/scroll-dock.css +70 -0
- package/src/recipes/slot-text/README.md +0 -2
- package/src/recipes/slot-text/create-slot-text.ts +1 -1
- package/src/recipes/snap-strip/README.md +1 -1
- package/src/recipes/snap-strip/create-snap-strip.ts +5 -6
- package/src/recipes/snap-strip/snap-strip.css +1 -1
- package/src/recipes/sortable/README.md +3 -5
- package/src/recipes/sortable/create-sortable.ts +4 -4
- package/src/recipes/sortable/sortable.css +1 -1
- package/src/recipes/spring-cards/README.md +0 -2
- package/src/recipes/spring-cards/create-spring-cards.ts +1 -1
- package/src/recipes/spring-cards/spring-cards.css +1 -1
- package/src/recipes/sticker/README.md +59 -0
- package/src/recipes/sticker/create-sticker.ts +490 -0
- package/src/recipes/sticker/sticker.css +112 -0
- package/src/recipes/stretch-footer/README.md +0 -2
- package/src/recipes/stretch-footer/create-stretch-footer.ts +1 -1
- package/src/recipes/stretch-footer/stretch-footer.css +1 -1
- package/src/recipes/tabs/README.md +0 -2
- package/src/recipes/tabs/create-tabs.ts +1 -1
- package/src/recipes/text-roll/README.md +1 -3
- package/src/recipes/text-roll/create-text-roll.ts +3 -3
- package/src/recipes/text-roll/text-roll.css +1 -1
- package/src/recipes/thumbnail-nav/README.md +16 -0
- package/src/recipes/thumbnail-nav/create-thumbnail-nav.ts +165 -0
- package/src/recipes/thumbnail-nav/thumbnail-nav.css +108 -0
- package/src/recipes/ticket-menu/README.md +3 -3
- package/src/recipes/weight-hover/README.md +37 -0
- package/src/recipes/weight-hover/create-weight-hover.ts +136 -0
- package/src/recipes/weight-hover/weight-hover.css +7 -0
- package/src/recipes/words/README.md +0 -2
- package/src/recipes/words/create-words.ts +1 -1
- package/src/theme/generate.ts +1 -1
- package/src/theme/presets.ts +2 -2
- package/src/theme/theme.ts +1 -2
- package/dist/chunk-2BQGFOA7.js.map +0 -1
- package/dist/chunk-34XYOXHG.js.map +0 -1
- package/dist/chunk-6OJAP6ZL.js.map +0 -1
- package/dist/chunk-FS2HJVVY.js.map +0 -1
- package/dist/chunk-J27KH2A2.js.map +0 -1
- package/dist/chunk-KLY5BRRI.js.map +0 -1
- package/dist/chunk-Q4LVFNLN.js.map +0 -1
- package/dist/chunk-RFDIZYFX.js.map +0 -1
- /package/dist/{chunk-ABNRDDO7.js.map → chunk-I3DXF2KQ.js.map} +0 -0
|
@@ -4,6 +4,6 @@ import type { DependencyList, RefObject } from 'react';
|
|
|
4
4
|
import { useRecipe } from './use-recipe';
|
|
5
5
|
import { createFrameZoom, type FrameZoomOptions } from '../recipes/frame-zoom/create-frame-zoom';
|
|
6
6
|
|
|
7
|
-
/**
|
|
7
|
+
/** video mask: frame and picture scale in opposite directions. */
|
|
8
8
|
export const useFrameZoom = (ref: RefObject<HTMLElement | null>, options?: FrameZoomOptions, deps?: DependencyList) =>
|
|
9
9
|
useRecipe(ref, createFrameZoom, options, deps);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type { RefObject, DependencyList } from 'react';
|
|
3
|
+
import { useRecipe } from './use-recipe';
|
|
4
|
+
import { createImageZoom, type ImageZoomOptions } from '../recipes/image-zoom/create-image-zoom';
|
|
5
|
+
export const useImageZoom = (ref: RefObject<HTMLElement | null>, options?: ImageZoomOptions, deps?: DependencyList) => useRecipe(ref, createImageZoom, options, deps);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type { RefObject, DependencyList } from 'react';
|
|
3
|
+
import { useRecipe } from './use-recipe';
|
|
4
|
+
import { createJoinedCta, type JoinedCtaOptions } from '../recipes/joined-cta/create-joined-cta';
|
|
5
|
+
export const useJoinedCta = (ref: RefObject<HTMLElement | null>, options?: JoinedCtaOptions, deps?: DependencyList) => useRecipe(ref, createJoinedCta, options, deps);
|
package/src/react/use-letters.ts
CHANGED
|
@@ -4,6 +4,6 @@ import type { DependencyList, RefObject } from 'react';
|
|
|
4
4
|
import { useRecipe } from './use-recipe';
|
|
5
5
|
import { createLetters, type LettersOptions } from '../recipes/letters/create-letters';
|
|
6
6
|
|
|
7
|
-
/**
|
|
7
|
+
/** hero letters (scale on hover or pastel blink). */
|
|
8
8
|
export const useLetters = (ref: RefObject<HTMLElement | null>, options?: LettersOptions, deps?: DependencyList) =>
|
|
9
9
|
useRecipe(ref, createLetters, options, deps);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type { RefObject, DependencyList } from 'react';
|
|
3
|
+
import { useRecipe } from './use-recipe';
|
|
4
|
+
import { createLocalClock, type LocalClockOptions } from '../recipes/local-clock/create-local-clock';
|
|
5
|
+
export const useLocalClock = (ref: RefObject<HTMLElement | null>, options?: LocalClockOptions, deps?: DependencyList) => useRecipe(ref, createLocalClock, options, deps);
|
package/src/react/use-marquee.ts
CHANGED
|
@@ -4,6 +4,6 @@ import type { DependencyList, RefObject } from 'react';
|
|
|
4
4
|
import { useRecipe } from './use-recipe';
|
|
5
5
|
import { createMarquee, type MarqueeOptions } from '../recipes/marquee/create-marquee';
|
|
6
6
|
|
|
7
|
-
/**
|
|
7
|
+
/** seamless marquee. */
|
|
8
8
|
export const useMarquee = (ref: RefObject<HTMLElement | null>, options?: MarqueeOptions, deps?: DependencyList) =>
|
|
9
9
|
useRecipe(ref, createMarquee, options, deps);
|
|
@@ -4,6 +4,6 @@ import type { DependencyList, RefObject } from 'react';
|
|
|
4
4
|
import { useRecipe } from './use-recipe';
|
|
5
5
|
import { createMaskText, type MaskTextOptions } from '../recipes/mask-text/create-mask-text';
|
|
6
6
|
|
|
7
|
-
/** Masked lines / words / letters rising into view
|
|
7
|
+
/** Masked lines / words / letters rising into view. */
|
|
8
8
|
export const useMaskText = (ref: RefObject<HTMLElement | null>, options?: MaskTextOptions, deps?: DependencyList) =>
|
|
9
9
|
useRecipe(ref, createMaskText, options, deps);
|
|
@@ -4,6 +4,6 @@ import type { DependencyList, RefObject } from 'react';
|
|
|
4
4
|
import { useRecipe } from './use-recipe';
|
|
5
5
|
import { createParallax, type ParallaxOptions } from '../recipes/parallax/create-parallax';
|
|
6
6
|
|
|
7
|
-
/**
|
|
7
|
+
/** photo parallax inside its frame. */
|
|
8
8
|
export const useParallax = (ref: RefObject<HTMLElement | null>, options?: ParallaxOptions, deps?: DependencyList) =>
|
|
9
9
|
useRecipe(ref, createParallax, options, deps);
|
|
@@ -4,6 +4,6 @@ import type { DependencyList, RefObject } from 'react';
|
|
|
4
4
|
import { useRecipe } from './use-recipe';
|
|
5
5
|
import { createParticleHero, type ParticleHeroOptions } from '../gl/particle-hero/create-particle-hero';
|
|
6
6
|
|
|
7
|
-
/**
|
|
7
|
+
/** particle hero (WebGL2, Canvas2D fallback). The canvas joins the ref's element. */
|
|
8
8
|
export const useParticleHero = (ref: RefObject<HTMLElement | null>, options?: ParticleHeroOptions, deps?: DependencyList) =>
|
|
9
9
|
useRecipe(ref, createParticleHero, options, deps);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type { RefObject, DependencyList } from 'react';
|
|
3
|
+
import { useRecipe } from './use-recipe';
|
|
4
|
+
import { createScrollDock, type ScrollDockOptions } from '../recipes/scroll-dock/create-scroll-dock';
|
|
5
|
+
export const useScrollDock = (ref: RefObject<HTMLElement | null>, options?: ScrollDockOptions, deps?: DependencyList) => useRecipe(ref, createScrollDock, options, deps);
|
|
@@ -4,6 +4,6 @@ import type { DependencyList, RefObject } from 'react';
|
|
|
4
4
|
import { useRecipe } from './use-recipe';
|
|
5
5
|
import { createSnapStrip, type SnapStripOptions } from '../recipes/snap-strip/create-snap-strip';
|
|
6
6
|
|
|
7
|
-
/**
|
|
7
|
+
/** phone cards: an autoplaying scroll-snap strip. */
|
|
8
8
|
export const useSnapStrip = (ref: RefObject<HTMLElement | null>, options?: SnapStripOptions, deps?: DependencyList) =>
|
|
9
9
|
useRecipe(ref, createSnapStrip, options, deps);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type { RefObject, DependencyList } from 'react';
|
|
3
|
+
import { useRecipe } from './use-recipe';
|
|
4
|
+
import { createSticker, type StickerOptions } from '../recipes/sticker/create-sticker';
|
|
5
|
+
export const useSticker = (ref: RefObject<HTMLElement | null>, options?: StickerOptions, deps?: DependencyList) => useRecipe(ref, createSticker, options, deps);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type { DependencyList, RefObject } from 'react';
|
|
3
|
+
import { useLatest, useRecipe } from './use-recipe';
|
|
4
|
+
import { createStudioDock, type StudioDockOptions } from '../components/studio-dock/engine';
|
|
5
|
+
export function useStudioDock(ref: RefObject<HTMLElement | null>, options: StudioDockOptions = {}, deps?: DependencyList) {
|
|
6
|
+
const change = useLatest(options.onChange);
|
|
7
|
+
return useRecipe(ref, createStudioDock, { ...options, onChange: state => change.current?.(state) }, deps);
|
|
8
|
+
}
|
|
@@ -4,6 +4,6 @@ import type { DependencyList, RefObject } from 'react';
|
|
|
4
4
|
import { useRecipe } from './use-recipe';
|
|
5
5
|
import { createTextRoll, type TextRollOptions } from '../recipes/text-roll/create-text-roll';
|
|
6
6
|
|
|
7
|
-
/**
|
|
7
|
+
/** slot title. `.current.play()` spins it. */
|
|
8
8
|
export const useTextRoll = (ref: RefObject<HTMLElement | null>, options?: TextRollOptions, deps?: DependencyList) =>
|
|
9
9
|
useRecipe(ref, createTextRoll, options, deps);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type { DependencyList, RefObject } from 'react';
|
|
3
|
+
import { useRecipe } from './use-recipe';
|
|
4
|
+
import { createThumbnailNav, type ThumbnailNavOptions } from '../recipes/thumbnail-nav/create-thumbnail-nav';
|
|
5
|
+
|
|
6
|
+
export const useThumbnailNav = (ref: RefObject<HTMLElement | null>, options?: ThumbnailNavOptions, deps?: DependencyList) =>
|
|
7
|
+
useRecipe(ref, createThumbnailNav, options, deps);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type { DependencyList, RefObject } from 'react';
|
|
3
|
+
import { useRecipe } from './use-recipe';
|
|
4
|
+
import { createTrailer, type TrailerOptions } from '../components/trailer/engine';
|
|
5
|
+
export const useTrailer = (ref: RefObject<HTMLElement | null>, options?: TrailerOptions, deps?: DependencyList) =>
|
|
6
|
+
useRecipe(ref, createTrailer, options, deps);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import type { RefObject, DependencyList } from 'react';
|
|
3
|
+
import { useRecipe } from './use-recipe';
|
|
4
|
+
import { createWeightHover, type WeightHoverOptions } from '../recipes/weight-hover/create-weight-hover';
|
|
5
|
+
export const useWeightHover = (ref: RefObject<HTMLElement | null>, options?: WeightHoverOptions, deps?: DependencyList) => useRecipe(ref, createWeightHover, options, deps);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# action-button
|
|
2
|
+
|
|
3
|
+
Botones con sombra firme inspirados en Don't Look Up y etiquetas en máscara inspiradas en la ficha A24.
|
|
4
|
+
|
|
5
|
+
## HTML / Astro
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<button class="mk-action-button" data-mk="action-button" data-mk-variant="primary">Empezar</button>
|
|
9
|
+
<button class="mk-action-button" data-mk="action-button" data-mk-variant="film">
|
|
10
|
+
<span data-mk-action-label>Ver trailer ↗</span>
|
|
11
|
+
</button>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
const button = createActionButton(element, {
|
|
16
|
+
variant: 'icon', toggle: true,
|
|
17
|
+
onPressedChange: value => console.log(value),
|
|
18
|
+
});
|
|
19
|
+
button.setPressed(true);
|
|
20
|
+
button.destroy();
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
React: `useActionButton(ref, options, deps?)`. Conserva botones/enlaces semánticos escritos por el consumidor; la receta no ejecuta navegación ni reproduce sonidos. Variantes: `primary`, `secondary`, `icon`, `stepper`, `film`. Las variantes también pueden usarse sólo con CSS mediante `data-mk-action-variant`; `film` necesita el motor para duplicar su etiqueta marcada.
|
|
24
|
+
|
|
25
|
+
## Movimiento / accesibilidad
|
|
26
|
+
|
|
27
|
+
Press 130ms ease-out, color150ms ease. Hover baja3px y reduce sombra; active5×6px. Film usa clip.4s/translate.35s/scale.3s y copia retrasada75ms. Es una adaptación reusable; no reproduce todos los overrides particulares del juego original ni su lógica económica.
|
|
28
|
+
|
|
29
|
+
`toggle` es opt-in y usa `aria-pressed`; controles disabled y `aria-disabled` no cambian el estado. Un icono necesita `aria-label`. La copia rolling tiene `aria-hidden`, el nodo original se conserva. Focus visible explícito. Reduced-motion elimina las transiciones y la duplicación visual; los gestos de botón siguen indicando estado. `destroy()` restaura nodos/atributos y retira listeners.
|
|
30
|
+
|
|
31
|
+
Tokens: `--mk-action-ink`, `--mk-action-paper`, `--mk-action-lift`, `--mk-action-tilt`, `--mk-action-focus`, `--mk-film-font`.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
.mk-action-button {
|
|
2
|
+
--mk-action-ink: var(--mk-text, #171713);
|
|
3
|
+
--mk-action-paper: var(--mk-surface, #f7f5ee);
|
|
4
|
+
--mk-action-lift: 5px;
|
|
5
|
+
--mk-action-tilt: -1.2deg;
|
|
6
|
+
appearance: none;
|
|
7
|
+
position: relative;
|
|
8
|
+
display: inline-flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
justify-content: center;
|
|
11
|
+
gap: .6em;
|
|
12
|
+
min-height: 44px;
|
|
13
|
+
padding: .65em 1.5em;
|
|
14
|
+
border: 3px solid var(--mk-action-paper);
|
|
15
|
+
border-radius: 24px 30px 22px 28px / 30px 22px 28px 24px;
|
|
16
|
+
background: var(--mk-action-ink);
|
|
17
|
+
color: var(--mk-action-paper);
|
|
18
|
+
box-shadow: var(--mk-action-lift) calc(var(--mk-action-lift) + 1px) 0 var(--mk-action-ink);
|
|
19
|
+
transform: rotate(var(--mk-action-tilt));
|
|
20
|
+
font: 700 .85rem/1.15 var(--mk-font, sans-serif);
|
|
21
|
+
letter-spacing: .045em;
|
|
22
|
+
text-transform: uppercase;
|
|
23
|
+
text-decoration: none;
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
touch-action: manipulation;
|
|
26
|
+
transition: transform 130ms ease-out, box-shadow 130ms ease-out, background-color 150ms ease, color 150ms ease, border-color 150ms ease;
|
|
27
|
+
}
|
|
28
|
+
.mk-action-button[data-mk-action-variant="secondary"],
|
|
29
|
+
.mk-action-button[data-mk-action-variant="icon"] {
|
|
30
|
+
--mk-action-tilt: 1.1deg;
|
|
31
|
+
background: var(--mk-action-paper);
|
|
32
|
+
border-color: var(--mk-action-ink);
|
|
33
|
+
color: var(--mk-action-ink);
|
|
34
|
+
}
|
|
35
|
+
.mk-action-button[data-mk-action-variant="icon"] {
|
|
36
|
+
width: 44px;
|
|
37
|
+
padding: 8px;
|
|
38
|
+
border-radius: 16px 20px 15px 19px / 20px 15px 19px 16px;
|
|
39
|
+
}
|
|
40
|
+
.mk-action-button svg { width: 1.25em; height: 1.25em; flex: none; }
|
|
41
|
+
.mk-action-button[data-mk-action-variant="stepper"] {
|
|
42
|
+
--mk-action-tilt: 0deg;
|
|
43
|
+
min-width: 44px;
|
|
44
|
+
padding: .5em;
|
|
45
|
+
border: 2px solid var(--mk-action-ink);
|
|
46
|
+
border-radius: 11px;
|
|
47
|
+
background: var(--mk-action-paper);
|
|
48
|
+
color: var(--mk-action-ink);
|
|
49
|
+
box-shadow: none;
|
|
50
|
+
}
|
|
51
|
+
.mk-action-button[data-mk-action-variant="film"] {
|
|
52
|
+
--mk-action-tilt: 0deg;
|
|
53
|
+
border: 0;
|
|
54
|
+
border-radius: 0;
|
|
55
|
+
background: transparent;
|
|
56
|
+
color: inherit;
|
|
57
|
+
box-shadow: none;
|
|
58
|
+
padding: .5em 0;
|
|
59
|
+
font-family: var(--mk-film-font, Georgia, serif);
|
|
60
|
+
font-size: 1.25rem;
|
|
61
|
+
}
|
|
62
|
+
.mk-action-button[data-mk-action-variant="film"]::before,
|
|
63
|
+
.mk-action-button[data-mk-action-variant="film"]::after {
|
|
64
|
+
content: "";
|
|
65
|
+
position: absolute;
|
|
66
|
+
inset: 0 0 auto;
|
|
67
|
+
height: 1px;
|
|
68
|
+
background: currentColor;
|
|
69
|
+
transition: transform .4s cubic-bezier(.32,.72,0,1);
|
|
70
|
+
}
|
|
71
|
+
.mk-action-button[data-mk-action-variant="film"]::after { inset: auto 0 0; }
|
|
72
|
+
[data-mk-action-label] { display: inline-grid; overflow: clip; }
|
|
73
|
+
.mk-action-button__line, .mk-action-button__copy {
|
|
74
|
+
grid-area: 1 / 1;
|
|
75
|
+
transition: clip-path .4s cubic-bezier(.32,.72,0,1), translate .35s cubic-bezier(.32,.72,0,1), scale .3s cubic-bezier(.34,2.27,.64,1);
|
|
76
|
+
}
|
|
77
|
+
.mk-action-button__line { clip-path: inset(0); transform-origin: bottom; }
|
|
78
|
+
.mk-action-button__copy { clip-path: inset(0 0 100%); translate: 0 -.25em; scale: 1.05; transform-origin: top; }
|
|
79
|
+
@media (hover: hover) {
|
|
80
|
+
.mk-action-button:not(:disabled):not([aria-disabled="true"]):hover {
|
|
81
|
+
transform: rotate(var(--mk-action-tilt)) translate(3px, 3px);
|
|
82
|
+
box-shadow: 2px 3px 0 var(--mk-action-ink);
|
|
83
|
+
}
|
|
84
|
+
.mk-action-button:is([data-mk-action-variant="secondary"], [data-mk-action-variant="icon"], [data-mk-action-variant="stepper"]):not(:disabled):not([aria-disabled="true"]):hover {
|
|
85
|
+
background: var(--mk-action-ink);
|
|
86
|
+
border-color: var(--mk-action-paper);
|
|
87
|
+
color: var(--mk-action-paper);
|
|
88
|
+
}
|
|
89
|
+
.mk-action-button[data-mk-action-variant="stepper"]:not(:disabled):not([aria-disabled="true"]):hover { transform: none; box-shadow: none; }
|
|
90
|
+
}
|
|
91
|
+
.mk-action-button:not(:disabled):not([aria-disabled="true"]):active,
|
|
92
|
+
.mk-action-button[aria-pressed="true"] {
|
|
93
|
+
transform: rotate(var(--mk-action-tilt)) translate(var(--mk-action-lift), calc(var(--mk-action-lift) + 1px));
|
|
94
|
+
box-shadow: 0 0 0 var(--mk-action-ink);
|
|
95
|
+
}
|
|
96
|
+
.mk-action-button[aria-pressed="true"] { background: var(--mk-action-ink); color: var(--mk-action-paper); }
|
|
97
|
+
.mk-action-button[aria-pressed="true"]:not(:disabled):not([aria-disabled="true"]):hover { transform: rotate(var(--mk-action-tilt)) translate(var(--mk-action-lift), calc(var(--mk-action-lift) + 1px)); box-shadow: none; }
|
|
98
|
+
.mk-action-button[data-mk-action-variant="stepper"]:not(:disabled):not([aria-disabled="true"]):active { transform: translateY(1px); box-shadow: none; }
|
|
99
|
+
.mk-action-button[data-mk-action-variant="film"]:is(:hover, :focus-visible):not(:disabled):not([aria-disabled="true"]) {
|
|
100
|
+
transform: scale(1.03) rotate(-.75deg);
|
|
101
|
+
box-shadow: none;
|
|
102
|
+
}
|
|
103
|
+
.mk-action-button[data-mk-action-variant="film"]:is(:hover, :focus-visible):not(:disabled):not([aria-disabled="true"]) .mk-action-button__line { clip-path: inset(100% 0 0); translate: 0 .25em; scale: .95; }
|
|
104
|
+
.mk-action-button[data-mk-action-variant="film"]:is(:hover, :focus-visible):not(:disabled):not([aria-disabled="true"]) .mk-action-button__copy { clip-path: inset(0); translate: 0; scale: 1; transition-delay: 75ms; }
|
|
105
|
+
.mk-action-button[data-mk-action-variant="film"]:active:not(:disabled) { transform: scale(.97); }
|
|
106
|
+
.mk-action-button:focus-visible { outline: 3px solid var(--mk-action-focus, #356bdf); outline-offset: 7px; }
|
|
107
|
+
.mk-action-button:disabled, .mk-action-button[aria-disabled="true"] { opacity: .35; cursor: default; }
|
|
108
|
+
@media (prefers-reduced-motion: reduce) {
|
|
109
|
+
.mk-action-button, .mk-action-button *, .mk-action-button::before, .mk-action-button::after { transition: none; }
|
|
110
|
+
.mk-action-button[data-mk-action-variant="film"]:is(:hover, :focus-visible):not(:disabled):not([aria-disabled="true"]) { transform: none; }
|
|
111
|
+
.mk-action-button[data-mk-action-variant="film"]:is(:hover, :focus-visible):not(:disabled):not([aria-disabled="true"]) .mk-action-button__line { clip-path: none; translate: none; scale: 1; }
|
|
112
|
+
.mk-action-button__copy { display: none; }
|
|
113
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { createScope } from '../../core/scope';
|
|
2
|
+
import { inert, type Instance } from '../../core/types';
|
|
3
|
+
|
|
4
|
+
export type ActionButtonVariant = 'primary' | 'secondary' | 'icon' | 'stepper' | 'film';
|
|
5
|
+
export interface ActionButtonOptions {
|
|
6
|
+
variant?: ActionButtonVariant;
|
|
7
|
+
/** Toggle aria-pressed on activation. Ordinary action buttons leave it unset. */
|
|
8
|
+
toggle?: boolean;
|
|
9
|
+
pressed?: boolean;
|
|
10
|
+
onPressedChange?: (pressed: boolean) => void;
|
|
11
|
+
}
|
|
12
|
+
export interface ActionButtonInstance extends Instance {
|
|
13
|
+
setPressed(pressed: boolean): void;
|
|
14
|
+
readonly pressed: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Drawn press buttons and a masked rolling-label film variant. Uses native activation. */
|
|
18
|
+
export function createActionButton(root: HTMLElement | null, options: ActionButtonOptions = {}): ActionButtonInstance {
|
|
19
|
+
if (!root) return inert({ setPressed() {}, pressed: false });
|
|
20
|
+
const scope = createScope();
|
|
21
|
+
const variant = options.variant ?? (root.getAttribute('data-mk-action-variant') as ActionButtonVariant | null) ?? 'primary';
|
|
22
|
+
scope.attr(root, 'data-mk-action-variant', variant);
|
|
23
|
+
scope.attr(root, 'data-mk-action-ready', '');
|
|
24
|
+
const label = root.querySelector<HTMLElement>('[data-mk-action-label]');
|
|
25
|
+
if (label && variant === 'film') {
|
|
26
|
+
const nodes = [...label.childNodes];
|
|
27
|
+
const line = document.createElement('span');
|
|
28
|
+
line.className = 'mk-action-button__line';
|
|
29
|
+
line.append(...nodes);
|
|
30
|
+
const copy = document.createElement('span');
|
|
31
|
+
copy.className = 'mk-action-button__copy';
|
|
32
|
+
copy.setAttribute('aria-hidden', 'true');
|
|
33
|
+
// Plain text prevents duplicate interactive controls or IDs inside the label.
|
|
34
|
+
copy.textContent = line.textContent;
|
|
35
|
+
label.append(line, copy);
|
|
36
|
+
scope.add(() => { label.replaceChildren(...nodes); });
|
|
37
|
+
}
|
|
38
|
+
let pressed = options.pressed ?? root.getAttribute('aria-pressed') === 'true';
|
|
39
|
+
if (options.toggle || options.pressed !== undefined) scope.attr(root, 'aria-pressed', String(pressed));
|
|
40
|
+
const setPressed = (next: boolean) => {
|
|
41
|
+
if (scope.disposed || next === pressed) return;
|
|
42
|
+
pressed = next;
|
|
43
|
+
scope.attr(root, 'aria-pressed', String(pressed));
|
|
44
|
+
options.onPressedChange?.(pressed);
|
|
45
|
+
root.dispatchEvent(new CustomEvent('mk:action-change', { bubbles: true, detail: { pressed } }));
|
|
46
|
+
};
|
|
47
|
+
scope.on(root, 'click', (event) => {
|
|
48
|
+
if (event.defaultPrevented) return;
|
|
49
|
+
if (root.hasAttribute('disabled') || root.getAttribute('aria-disabled') === 'true') {
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (options.toggle) setPressed(!pressed);
|
|
54
|
+
});
|
|
55
|
+
return { setPressed, get pressed() { return pressed; }, destroy: () => scope.dispose() };
|
|
56
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Un dock de tarjetas de cristal apiladas: las que están detrás de la del frente bajan 90 % / 180 % / 270 % (360 % la quinta) y encogen a .93 / .87 / .8 (.73). Al pasar el puntero o enfocar se despliegan hacia arriba (0.8 s `cubic-bezier(.48,.01,0,1.08)`, con un pequeño rebote), la tarjeta bajo el puntero crece de 4rem a 4.5rem (0.6 s) y su nombre sale hacia la izquierda; al salir se apilan de nuevo (0.64 s). Al cargar se ven desplegadas 1.6 s y luego se apilan y aparece el CTA.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Superficie con blur de 19 px, borde sutil y radio .9rem. Incluye presentación de carga, primer toque para desplegar en tabletas sin hover, Escape y cierre al hacer clic fuera.
|
|
6
6
|
|
|
7
7
|
## HTML / Astro
|
|
8
8
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
*
|
|
2
|
+
* product dock. Cards are .mk-card-dock__item children (the last one
|
|
3
3
|
* is the front card); the optional .mk-card-dock__cta shows next to the stack
|
|
4
4
|
* once it has settled. Without JavaScript the stack still opens on hover/focus.
|
|
5
5
|
*/
|
|
@@ -4,7 +4,7 @@ import { TIMING } from '../../core/timing';
|
|
|
4
4
|
import { inert, warnOnce, type Instance } from '../../core/types';
|
|
5
5
|
|
|
6
6
|
/*
|
|
7
|
-
*
|
|
7
|
+
* product dock: a stack of glass cards where the ones behind the front
|
|
8
8
|
* card drop 90 % / 180 % / 270 % and shrink to .93 / .87 / .8. Hover or focus
|
|
9
9
|
* spreads them out (0.8 s, cubic-bezier(.48,.01,0,1.08)), the card under the
|
|
10
10
|
* pointer grows and its name slides out; leaving stacks them again (0.64 s).
|
|
@@ -13,7 +13,7 @@ import { inert, warnOnce, type Instance } from '../../core/types';
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
export interface CardDockOptions {
|
|
16
|
-
/** Milliseconds the cards stay spread out on load before stacking (
|
|
16
|
+
/** Milliseconds the cards stay spread out on load before stacking (default: 1600; 0 skips it). */
|
|
17
17
|
intro?: number;
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# cascade
|
|
2
2
|
|
|
3
|
-
Un bloque que entra pieza a pieza: rayas que crecen desde un lado (alternando izquierda y derecha), textos que aparecen y líneas que suben desde su recorte. 1.2 s `expo.out`, 30 ms entre piezas, cuando el 30 % del bloque se ve (o el 30 % de la pantalla si el bloque es más alto). Al salir de la pantalla todo vuelve a su estado inicial, así que entra de nuevo al volver (salvo `once`)
|
|
4
|
-
|
|
5
|
-
Origen: Siena Film Foundation, grupos `[data-a]` (`line`, `alpha`, `item`); el `fade` es también el `alpha` de OFFFICE.
|
|
3
|
+
Un bloque que entra pieza a pieza: rayas que crecen desde un lado (alternando izquierda y derecha), textos que aparecen y líneas que suben desde su recorte. 1.2 s `expo.out`, 30 ms entre piezas, cuando el 30 % del bloque se ve (o el 30 % de la pantalla si el bloque es más alto). Al salir de la pantalla todo vuelve a su estado inicial, así que entra de nuevo al volver (salvo `once`).
|
|
6
4
|
|
|
7
5
|
## HTML / Astro
|
|
8
6
|
|
|
@@ -6,9 +6,9 @@ import { inert, warnOnce, type Instance } from '../../core/types';
|
|
|
6
6
|
import { shows, thresholds } from '../../core/visible';
|
|
7
7
|
|
|
8
8
|
/*
|
|
9
|
-
*
|
|
9
|
+
* reveal group: when the block shows (30 %), its marked children enter
|
|
10
10
|
* one after another, 30 ms apart, 1.2 s expo.out — rules grow from alternating
|
|
11
|
-
* sides (scaleX 0 → 1), fades appear
|
|
11
|
+
* sides (scaleX 0 → 1), fades appear, rises come up from 200 %
|
|
12
12
|
* inside their clip. When it leaves, every child goes back to its start state
|
|
13
13
|
* so the block enters again next time (unless once).
|
|
14
14
|
* Children: [data-mk-cascade="rule|fade|rise"].
|
|
@@ -26,7 +26,7 @@ export interface CascadeOptions {
|
|
|
26
26
|
|
|
27
27
|
export interface CascadeInstance extends Instance {
|
|
28
28
|
play(): void;
|
|
29
|
-
/** Every child back to its start state
|
|
29
|
+
/** Every child back to its start state. */
|
|
30
30
|
reset(): void;
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
La cabecera cambia de tono según la sección que tiene debajo: las secciones dicen si son claras u oscuras (`data-mk-tone="light"` / `"dark"`) y la que cruza el 10 % superior de la pantalla escribe su tono en la cabecera (`data-mk-on`). Tu CSS decide los colores.
|
|
4
4
|
|
|
5
|
-
Origen: Siena Film Foundation, logo que pasa a negro sobre secciones claras (`rootMargin: 0% 0% -90% 0%`).
|
|
6
|
-
|
|
7
5
|
## HTML / Astro
|
|
8
6
|
|
|
9
7
|
```html
|
|
@@ -2,7 +2,7 @@ import { createScope } from '../../core/scope';
|
|
|
2
2
|
import { inert, warnOnce, type Instance } from '../../core/types';
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
|
-
*
|
|
5
|
+
* header contrast: sections say what they are (data-mk-tone="light" or
|
|
6
6
|
* "dark"); the section crossing the top 10 % of the screen gives its tone to
|
|
7
7
|
* the header (data-mk-on), and the page's CSS turns the logo and links dark on
|
|
8
8
|
* light sections and light on dark ones.
|
|
@@ -4,7 +4,7 @@ import { inert, warnOnce, type Instance } from '../../core/types';
|
|
|
4
4
|
import { TIMING } from '../../core/timing';
|
|
5
5
|
import { countTo } from '../../motion/count';
|
|
6
6
|
|
|
7
|
-
/*
|
|
7
|
+
/* animated number: counts to its value with `numberSoft` (0.6 s), from the value shown. */
|
|
8
8
|
|
|
9
9
|
export interface CounterOptions {
|
|
10
10
|
/** Final value. Default: the number written in the element. */
|
|
@@ -8,7 +8,7 @@ import { wrap } from '../../core/math';
|
|
|
8
8
|
import { FRICTION, slideX, snapOffset } from './carousel-math';
|
|
9
9
|
|
|
10
10
|
/*
|
|
11
|
-
*
|
|
11
|
+
* curved-carousel: offset with friction .85, drag follows the pointer,
|
|
12
12
|
* release multiplies the velocity and snaps to the slide nearest the projected
|
|
13
13
|
* rest. Slides loop by wrapping their x; CSS turns the distance from the centre
|
|
14
14
|
* (`--mk-t`) into the arc (see curved-carousel.css).
|
|
@@ -130,7 +130,7 @@ export function createCurvedCarousel(root: HTMLElement | null, options: CurvedCa
|
|
|
130
130
|
dragDelta = 0;
|
|
131
131
|
offset -= v;
|
|
132
132
|
} else if (target !== null) {
|
|
133
|
-
// Geometric approach to the snap point:
|
|
133
|
+
// Geometric approach to the snap point: using velocity decay.
|
|
134
134
|
const next = offset + (target - offset) * (1 - Math.pow(o.friction, dt));
|
|
135
135
|
v = offset - next;
|
|
136
136
|
offset = next;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* curved-carousel —
|
|
2
|
+
* curved-carousel — Layout rules apply only while the
|
|
3
3
|
* recipe runs (`[data-mk-carousel]`); without JS the root keeps whatever fallback
|
|
4
4
|
* the page gives it (e.g. a horizontal scroll row).
|
|
5
5
|
*/
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Un grid de imágenes que llega desde la profundidad: cada imagen parte empujada hacia fuera del centro (900 px), hundida en la pantalla (hasta −3000 px), girada (hasta 160°), casi transparente (.05) y pequeña (.4), y se coloca en su sitio mientras el grid baja desde que su borde superior toca el centro de la pantalla hasta que su borde inferior toca el borde inferior. Primero las del centro; 0.15 s repartidos hacia los bordes. Sigue al scroll sin retraso (`lerp: .1` para suavizarlo).
|
|
4
4
|
|
|
5
|
-
Origen: Siena Film Foundation, página About (`Rv`, `Un`). Siena busca el timeline en segundos y las del borde se quedan al 85 %; aquí se usa el progreso y el grid termina montado.
|
|
6
|
-
|
|
7
5
|
## HTML / Astro
|
|
8
6
|
|
|
9
7
|
```html
|
|
@@ -6,13 +6,12 @@ import { TIMING } from '../../core/timing';
|
|
|
6
6
|
import { inert, warnOnce, type Instance } from '../../core/types';
|
|
7
7
|
|
|
8
8
|
/*
|
|
9
|
-
*
|
|
9
|
+
* About grid: the pictures come from far away — pushed out from the
|
|
10
10
|
* grid's centre (900 px), deep into the screen (up to −3000 px), tilted (up to
|
|
11
11
|
* 160°), nearly transparent (.05) and small (.4) — and gather into their places
|
|
12
12
|
* as the grid scrolls from its top at the screen's centre to its bottom at the
|
|
13
13
|
* screen's bottom (eased .1 a frame). Centre first, 0.15 s spread to the edges.
|
|
14
|
-
*
|
|
15
|
-
* progress, so the grid ends fully assembled.
|
|
14
|
+
* The timeline follows normalized progress, ending with the grid fully assembled.
|
|
16
15
|
*/
|
|
17
16
|
|
|
18
17
|
export interface DepthGridOptions {
|
|
@@ -29,7 +28,7 @@ export interface DepthGridInstance extends Instance {
|
|
|
29
28
|
|
|
30
29
|
const STYLES = ['transform', 'translate', 'rotate', 'scale', 'opacity', 'visibility'];
|
|
31
30
|
|
|
32
|
-
/**
|
|
31
|
+
/** Initial position: where a child starts, from its centre relative to the grid's. */
|
|
33
32
|
function origin(child: Element, box: DOMRect) {
|
|
34
33
|
const t = TIMING.depthGrid;
|
|
35
34
|
const own = child.getBoundingClientRect();
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Los `<details>` crecen hasta la altura de su contenido mientras este aparece, y se pliegan de vuelta (0.32 s, curva signature). Un `[data-mk-chevron]` dentro del `<summary>` gira 180° en 0.25 s.
|
|
4
4
|
|
|
5
|
-
Origen: Stepbro — PrettyDetails (`details` en el kit).
|
|
6
|
-
|
|
7
5
|
## Vanilla / Astro
|
|
8
6
|
|
|
9
7
|
```html
|
|
@@ -2,7 +2,7 @@ import { inert, warnOnce, type Instance } from '../../core/types';
|
|
|
2
2
|
import { installDetailsMotion } from '../../motion/details';
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
|
-
*
|
|
5
|
+
* Details for every <details> under `root` (or `root` itself):
|
|
6
6
|
* height and content fade in 0.32 s on the signature curve, chevron 180° in 0.25 s.
|
|
7
7
|
*/
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dock-pill
|
|
2
2
|
|
|
3
|
-
Indicador spring que sigue la opción activa de un dock
|
|
3
|
+
Indicador spring que sigue la opción activa de un dock.
|
|
4
4
|
|
|
5
5
|
```html
|
|
6
6
|
<nav class="mk-dock-pill" data-mk="dock-pill" aria-label="Secciones">
|
|
@@ -16,8 +16,8 @@ const instance = createDockPill(root);
|
|
|
16
16
|
instance.destroy();
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
`index` (o aria-current="page" existente), `onSelect(index,item)`. `select(index)`, `index`; evento `mk:select`. Medición de la opción activa con ResizeObserver, indicador spring 380/30. Flechas, Home/End; evita opciones deshabilitadas. Conserva los enlaces y la navegación del consumidor.
|
|
19
|
+
`index` (o aria-current="page" existente), `onSelect(index,item)`. `select(index)`, `index`; evento `mk:select`. Medición de la opción activa con ResizeObserver, indicador spring 380/30. Flechas, Home/End; evita opciones deshabilitadas. Conserva los enlaces y la navegación del consumidor.
|
|
20
20
|
|
|
21
21
|
Vanilla declarativo: `autoInit(root)`. React: `useDockPill(ref, options, deps)` devuelve una ref a la instancia; se destruye al desmontar. Con movimiento reducido no se ejecuta movimiento decorativo. `destroy()` restaura atributos y estilos y quita listeners, observers y nodos generados.
|
|
22
22
|
|
|
23
|
-
Desde 0.8.0.
|
|
23
|
+
Desde 0.8.0.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# drag-ruler
|
|
2
2
|
|
|
3
|
-
Regla numérica arrastrable de 60 px por unidad, paso y teclado
|
|
3
|
+
Regla numérica arrastrable de 60 px por unidad, paso y teclado.
|
|
4
4
|
|
|
5
5
|
```html
|
|
6
6
|
<div class="mk-drag-ruler" data-mk="drag-ruler" aria-label="Años de experiencia" data-mk-value="8"></div>
|
|
@@ -14,8 +14,8 @@ const instance = createDragRuler(root);
|
|
|
14
14
|
instance.destroy();
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
`min` 0, `max` 8, `step` .1, `value` max, `pixelsPerUnit` 60, `onChange(value)`. `set(value)`, `value`; evento `mk:change` con detail.value. Role slider, aria-valuemin/max/now y nombre accesible provisto por el consumidor. Flechas, Home/End y PageUp/PageDown. Drag usa pointer capture, respeta pointercancel.
|
|
17
|
+
`min` 0, `max` 8, `step` .1, `value` max, `pixelsPerUnit` 60, `onChange(value)`. `set(value)`, `value`; evento `mk:change` con detail.value. Role slider, aria-valuemin/max/now y nombre accesible provisto por el consumidor. Flechas, Home/End y PageUp/PageDown. Drag usa pointer capture, respeta pointercancel.
|
|
18
18
|
|
|
19
19
|
Vanilla declarativo: `autoInit(root)`. React: `useDragRuler(ref, options, deps)` devuelve una ref a la instancia; se destruye al desmontar. Con movimiento reducido no se ejecuta movimiento decorativo. `destroy()` restaura atributos y estilos y quita listeners, observers y nodos generados.
|
|
20
20
|
|
|
21
|
-
Desde 0.8.0.
|
|
21
|
+
Desde 0.8.0.
|