Motion
Fade in
A block that rises into place as it scrolls into view.
betav0.1.0 Chromium 103 ui-scale safe
Install
Copies the file into
components/ds/, with its registry dependencies and npm packages. See Installation for the one-time setup.bunx shadcn@3 add @fastrp/fade-inExamples
Default
01
Hesabını bağla
02
Karakterini yarat
03
Şehre gir
from={{ x: -60 }} soldan kayarak gelir.
API
<FadeIn />Fades a block into place the first time it scrolls into view. Under reduced motion it is a fade with no travel. The travel is a CSS calc on `--fade` (1 → 0) times `--ui-px`, not motion's own `x`/`y`: an inline transform in pixels would stay 1080p-sized in the FiveM NUI, which scales every length through `--ui-px`. `transform`, not the `translate` property, which Chromium 103 lacks.
| Prop | Type | Default | Notes |
|---|---|---|---|
| about | string | — | |
| accessKey | string | — | |
| aria-activedescendant | string | — | |
| aria-atomic | Booleanish | — | |
| aria-autocomplete | "none" | "list" | "inline" | "both" | — | |
| aria-braillelabel | string | — | |
| aria-brailleroledescription | string | — | |
| aria-busy | Booleanish | — | |
| aria-checked | boolean | "true" | "false" | "mixed" | — | |
| aria-colcount | number | — | |
| aria-colindex | number | — | |
| aria-colindextext | string | — | |
| aria-colspan | number | — | |
| aria-controls | string | — | |
| aria-current | boolean | "true" | "false" | "time" | "page" | "step" | "location" | "date" | — | |
| aria-describedby | string | — | |
| aria-description | string | — | |
| aria-details | string | — | |
| aria-disabled | Booleanish | — | |
| aria-dropeffect | "link" | "none" | "copy" | "execute" | "move" | "popup" | — | |
| aria-errormessage | string | — | |
| aria-expanded | Booleanish | — | |
| aria-flowto | string | — | |
| aria-grabbed | Booleanish | — | |
| aria-haspopup | boolean | "true" | "false" | "dialog" | "menu" | "grid" | "listbox" | "tree" | — | |
| aria-hidden | Booleanish | — | |
| aria-invalid | boolean | "true" | "false" | "grammar" | "spelling" | — | |
| aria-keyshortcuts | string | — | |
| aria-label | string | — | |
| aria-labelledby | string | — | |
| aria-level | number | — | |
| aria-live | "off" | "assertive" | "polite" | — | |
| aria-modal | Booleanish | — | |
| aria-multiline | Booleanish | — | |
| aria-multiselectable | Booleanish | — | |
| aria-orientation | "horizontal" | "vertical" | — | |
| aria-owns | string | — | |
| aria-placeholder | string | — | |
| aria-posinset | number | — | |
| aria-pressed | boolean | "true" | "false" | "mixed" | — | |
| aria-readonly | Booleanish | — | |
| aria-relevant | "text" | "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text additions" | "text removals" | — | |
| aria-required | Booleanish | — | |
| aria-roledescription | string | — | |
| aria-rowcount | number | — | |
| aria-rowindex | number | — | |
| aria-rowindextext | string | — | |
| aria-rowspan | number | — | |
| aria-selected | Booleanish | — | |
| aria-setsize | number | — | |
| aria-sort | "none" | "ascending" | "descending" | "other" | — | |
| aria-valuemax | number | — | |
| aria-valuemin | number | — | |
| aria-valuenow | number | — | |
| aria-valuetext | string | — | |
| autoCapitalize | "off" | "none" | "on" | "sentences" | "words" | "characters" | (string & {}) | — | |
| autoCorrect | string | — | |
| autoFocus | boolean | — | |
| autoSave | string | — | |
| className | string | — | |
| color | string | — | |
| content | string | — | |
| contentEditable | Booleanish | "inherit" | "plaintext-only" | — | |
| contextMenu | string | — | |
| dangerouslySetInnerHTML | { __html: string | TrustedHTML; } | — | |
| datatype | string | — | |
| defaultChecked | boolean | — | |
| defaultValue | string | number | readonly string[] | — | |
| delay | number | 0 | Seconds. |
| dir | string | — | |
| draggable | Booleanish | — | |
| duration | number | DURATION_S.slower | Seconds; `DURATION_S.slower` by default. |
| enterKeyHint | "search" | "enter" | "done" | "go" | "next" | "previous" | "send" | — | |
| exportparts | string | — | |
| from | { x?: number; y?: number; } | undefined | { y: 40 } | Where it comes from, in pixels at 1080p: `y` rises, `x` slides in from that side. |
| hidden | boolean | — | |
| id | string | — | |
| inert | boolean | — | |
| inlist | any | — | |
| inputMode | "search" | "text" | "none" | "tel" | "url" | "email" | "numeric" | "decimal" | — | |
| is | string | — | |
| itemID | string | — | |
| itemProp | string | — | |
| itemRef | string | — | |
| itemScope | boolean | — | |
| itemType | string | — | |
| key | Key | — | |
| lang | string | — | |
| nonce | string | — | |
| onAbort | ReactEventHandler<HTMLDivElement> | — | |
| onAbortCapture | ReactEventHandler<HTMLDivElement> | — | |
| onAnimationEnd | AnimationEventHandler<HTMLDivElement> | — | |
| onAnimationEndCapture | AnimationEventHandler<HTMLDivElement> | — | |
| onAnimationIteration | AnimationEventHandler<HTMLDivElement> | — | |
| onAnimationIterationCapture | AnimationEventHandler<HTMLDivElement> | — | |
| onAnimationStartCapture | AnimationEventHandler<HTMLDivElement> | — | |
| onAuxClick | MouseEventHandler<HTMLDivElement> | — | |
| onAuxClickCapture | MouseEventHandler<HTMLDivElement> | — | |
| onBeforeInput | InputEventHandler<HTMLDivElement> | — | |
| onBeforeInputCapture | InputEventHandler<HTMLDivElement> | — | |
| onBeforeToggle | ToggleEventHandler<HTMLDivElement> | — | |
| onBlur | FocusEventHandler<HTMLDivElement> | — | |
| onBlurCapture | FocusEventHandler<HTMLDivElement> | — | |
| onCanPlay | ReactEventHandler<HTMLDivElement> | — | |
| onCanPlayCapture | ReactEventHandler<HTMLDivElement> | — | |
| onCanPlayThrough | ReactEventHandler<HTMLDivElement> | — | |
| onCanPlayThroughCapture | ReactEventHandler<HTMLDivElement> | — | |
| onChange | ChangeEventHandler<HTMLDivElement, Element> | — | |
| onChangeCapture | ChangeEventHandler<HTMLDivElement, Element> | — | |
| onClick | MouseEventHandler<HTMLDivElement> | — | |
| onClickCapture | MouseEventHandler<HTMLDivElement> | — | |
| onCompositionEnd | CompositionEventHandler<HTMLDivElement> | — | |
| onCompositionEndCapture | CompositionEventHandler<HTMLDivElement> | — | |
| onCompositionStart | CompositionEventHandler<HTMLDivElement> | — | |
| onCompositionStartCapture | CompositionEventHandler<HTMLDivElement> | — | |
| onCompositionUpdate | CompositionEventHandler<HTMLDivElement> | — | |
| onCompositionUpdateCapture | CompositionEventHandler<HTMLDivElement> | — | |
| onContextMenu | MouseEventHandler<HTMLDivElement> | — | |
| onContextMenuCapture | MouseEventHandler<HTMLDivElement> | — | |
| onCopy | ClipboardEventHandler<HTMLDivElement> | — | |
| onCopyCapture | ClipboardEventHandler<HTMLDivElement> | — | |
| onCut | ClipboardEventHandler<HTMLDivElement> | — | |
| onCutCapture | ClipboardEventHandler<HTMLDivElement> | — | |
| onDoubleClick | MouseEventHandler<HTMLDivElement> | — | |
| onDoubleClickCapture | MouseEventHandler<HTMLDivElement> | — | |
| onDragCapture | DragEventHandler<HTMLDivElement> | — | |
| onDragEndCapture | DragEventHandler<HTMLDivElement> | — | |
| onDragEnter | DragEventHandler<HTMLDivElement> | — | |
| onDragEnterCapture | DragEventHandler<HTMLDivElement> | — | |
| onDragExit | DragEventHandler<HTMLDivElement> | — | |
| onDragExitCapture | DragEventHandler<HTMLDivElement> | — | |
| onDragLeave | DragEventHandler<HTMLDivElement> | — | |
| onDragLeaveCapture | DragEventHandler<HTMLDivElement> | — | |
| onDragOver | DragEventHandler<HTMLDivElement> | — | |
| onDragOverCapture | DragEventHandler<HTMLDivElement> | — | |
| onDragStartCapture | DragEventHandler<HTMLDivElement> | — | |
| onDrop | DragEventHandler<HTMLDivElement> | — | |
| onDropCapture | DragEventHandler<HTMLDivElement> | — | |
| onDurationChange | ReactEventHandler<HTMLDivElement> | — | |
| onDurationChangeCapture | ReactEventHandler<HTMLDivElement> | — | |
| onEmptied | ReactEventHandler<HTMLDivElement> | — | |
| onEmptiedCapture | ReactEventHandler<HTMLDivElement> | — | |
| onEncrypted | ReactEventHandler<HTMLDivElement> | — | |
| onEncryptedCapture | ReactEventHandler<HTMLDivElement> | — | |
| onEnded | ReactEventHandler<HTMLDivElement> | — | |
| onEndedCapture | ReactEventHandler<HTMLDivElement> | — | |
| onError | ReactEventHandler<HTMLDivElement> | — | |
| onErrorCapture | ReactEventHandler<HTMLDivElement> | — | |
| onFocus | FocusEventHandler<HTMLDivElement> | — | |
| onFocusCapture | FocusEventHandler<HTMLDivElement> | — | |
| onGotPointerCapture | PointerEventHandler<HTMLDivElement> | — | |
| onGotPointerCaptureCapture | PointerEventHandler<HTMLDivElement> | — | |
| onInput | InputEventHandler<HTMLDivElement> | — | |
| onInputCapture | InputEventHandler<HTMLDivElement> | — | |
| onInvalid | ReactEventHandler<HTMLDivElement> | — | |
| onInvalidCapture | ReactEventHandler<HTMLDivElement> | — | |
| onKeyDown | KeyboardEventHandler<HTMLDivElement> | — | |
| onKeyDownCapture | KeyboardEventHandler<HTMLDivElement> | — | |
| onKeyPress | KeyboardEventHandler<HTMLDivElement> | — | |
| onKeyPressCapture | KeyboardEventHandler<HTMLDivElement> | — | |
| onKeyUp | KeyboardEventHandler<HTMLDivElement> | — | |
| onKeyUpCapture | KeyboardEventHandler<HTMLDivElement> | — | |
| onLoad | ReactEventHandler<HTMLDivElement> | — | |
| onLoadCapture | ReactEventHandler<HTMLDivElement> | — | |
| onLoadedData | ReactEventHandler<HTMLDivElement> | — | |
| onLoadedDataCapture | ReactEventHandler<HTMLDivElement> | — | |
| onLoadedMetadata | ReactEventHandler<HTMLDivElement> | — | |
| onLoadedMetadataCapture | ReactEventHandler<HTMLDivElement> | — | |
| onLoadStart | ReactEventHandler<HTMLDivElement> | — | |
| onLoadStartCapture | ReactEventHandler<HTMLDivElement> | — | |
| onLostPointerCapture | PointerEventHandler<HTMLDivElement> | — | |
| onLostPointerCaptureCapture | PointerEventHandler<HTMLDivElement> | — | |
| onMouseDown | MouseEventHandler<HTMLDivElement> | — | |
| onMouseDownCapture | MouseEventHandler<HTMLDivElement> | — | |
| onMouseEnter | MouseEventHandler<HTMLDivElement> | — | |
| onMouseLeave | MouseEventHandler<HTMLDivElement> | — | |
| onMouseMove | MouseEventHandler<HTMLDivElement> | — | |
| onMouseMoveCapture | MouseEventHandler<HTMLDivElement> | — | |
| onMouseOut | MouseEventHandler<HTMLDivElement> | — | |
| onMouseOutCapture | MouseEventHandler<HTMLDivElement> | — | |
| onMouseOver | MouseEventHandler<HTMLDivElement> | — | |
| onMouseOverCapture | MouseEventHandler<HTMLDivElement> | — | |
| onMouseUp | MouseEventHandler<HTMLDivElement> | — | |
| onMouseUpCapture | MouseEventHandler<HTMLDivElement> | — | |
| onPaste | ClipboardEventHandler<HTMLDivElement> | — | |
| onPasteCapture | ClipboardEventHandler<HTMLDivElement> | — | |
| onPause | ReactEventHandler<HTMLDivElement> | — | |
| onPauseCapture | ReactEventHandler<HTMLDivElement> | — | |
| onPlay | ReactEventHandler<HTMLDivElement> | — | |
| onPlayCapture | ReactEventHandler<HTMLDivElement> | — | |
| onPlaying | ReactEventHandler<HTMLDivElement> | — | |
| onPlayingCapture | ReactEventHandler<HTMLDivElement> | — | |
| onPointerCancel | PointerEventHandler<HTMLDivElement> | — | |
| onPointerCancelCapture | PointerEventHandler<HTMLDivElement> | — | |
| onPointerDown | PointerEventHandler<HTMLDivElement> | — | |
| onPointerDownCapture | PointerEventHandler<HTMLDivElement> | — | |
| onPointerEnter | PointerEventHandler<HTMLDivElement> | — | |
| onPointerLeave | PointerEventHandler<HTMLDivElement> | — | |
| onPointerMove | PointerEventHandler<HTMLDivElement> | — | |
| onPointerMoveCapture | PointerEventHandler<HTMLDivElement> | — | |
| onPointerOut | PointerEventHandler<HTMLDivElement> | — | |
| onPointerOutCapture | PointerEventHandler<HTMLDivElement> | — | |
| onPointerOver | PointerEventHandler<HTMLDivElement> | — | |
| onPointerOverCapture | PointerEventHandler<HTMLDivElement> | — | |
| onPointerUp | PointerEventHandler<HTMLDivElement> | — | |
| onPointerUpCapture | PointerEventHandler<HTMLDivElement> | — | |
| onProgress | ReactEventHandler<HTMLDivElement> | — | |
| onProgressCapture | ReactEventHandler<HTMLDivElement> | — | |
| onRateChange | ReactEventHandler<HTMLDivElement> | — | |
| onRateChangeCapture | ReactEventHandler<HTMLDivElement> | — | |
| onReset | ReactEventHandler<HTMLDivElement> | — | |
| onResetCapture | ReactEventHandler<HTMLDivElement> | — | |
| onScroll | UIEventHandler<HTMLDivElement> | — | |
| onScrollCapture | UIEventHandler<HTMLDivElement> | — | |
| onScrollEnd | UIEventHandler<HTMLDivElement> | — | |
| onScrollEndCapture | UIEventHandler<HTMLDivElement> | — | |
| onSeeked | ReactEventHandler<HTMLDivElement> | — | |
| onSeekedCapture | ReactEventHandler<HTMLDivElement> | — | |
| onSeeking | ReactEventHandler<HTMLDivElement> | — | |
| onSeekingCapture | ReactEventHandler<HTMLDivElement> | — | |
| onSelect | ReactEventHandler<HTMLDivElement> | — | |
| onSelectCapture | ReactEventHandler<HTMLDivElement> | — | |
| onStalled | ReactEventHandler<HTMLDivElement> | — | |
| onStalledCapture | ReactEventHandler<HTMLDivElement> | — | |
| onSubmit | SubmitEventHandler<HTMLDivElement> | — | |
| onSubmitCapture | SubmitEventHandler<HTMLDivElement> | — | |
| onSuspend | ReactEventHandler<HTMLDivElement> | — | |
| onSuspendCapture | ReactEventHandler<HTMLDivElement> | — | |
| onTimeUpdate | ReactEventHandler<HTMLDivElement> | — | |
| onTimeUpdateCapture | ReactEventHandler<HTMLDivElement> | — | |
| onToggle | ToggleEventHandler<HTMLDivElement> | — | |
| onTouchCancel | TouchEventHandler<HTMLDivElement> | — | |
| onTouchCancelCapture | TouchEventHandler<HTMLDivElement> | — | |
| onTouchEnd | TouchEventHandler<HTMLDivElement> | — | |
| onTouchEndCapture | TouchEventHandler<HTMLDivElement> | — | |
| onTouchMove | TouchEventHandler<HTMLDivElement> | — | |
| onTouchMoveCapture | TouchEventHandler<HTMLDivElement> | — | |
| onTouchStart | TouchEventHandler<HTMLDivElement> | — | |
| onTouchStartCapture | TouchEventHandler<HTMLDivElement> | — | |
| onTransitionCancel | TransitionEventHandler<HTMLDivElement> | — | |
| onTransitionCancelCapture | TransitionEventHandler<HTMLDivElement> | — | |
| onTransitionEnd | TransitionEventHandler<HTMLDivElement> | — | |
| onTransitionEndCapture | TransitionEventHandler<HTMLDivElement> | — | |
| onTransitionRun | TransitionEventHandler<HTMLDivElement> | — | |
| onTransitionRunCapture | TransitionEventHandler<HTMLDivElement> | — | |
| onTransitionStart | TransitionEventHandler<HTMLDivElement> | — | |
| onTransitionStartCapture | TransitionEventHandler<HTMLDivElement> | — | |
| onVolumeChange | ReactEventHandler<HTMLDivElement> | — | |
| onVolumeChangeCapture | ReactEventHandler<HTMLDivElement> | — | |
| onWaiting | ReactEventHandler<HTMLDivElement> | — | |
| onWaitingCapture | ReactEventHandler<HTMLDivElement> | — | |
| onWheel | WheelEventHandler<HTMLDivElement> | — | |
| onWheelCapture | WheelEventHandler<HTMLDivElement> | — | |
| part | string | — | |
| popover | "" | "auto" | "manual" | "hint" | — | |
| popoverTarget | string | — | |
| popoverTargetAction | "toggle" | "show" | "hide" | — | |
| prefix | string | — | |
| property | string | — | |
| radioGroup | string | — | |
| ref | Ref<HTMLDivElement> | — | |
| rel | string | — | |
| repeat | boolean | false | Play again every time it re-enters, instead of once. |
| resource | string | — | |
| results | number | — | |
| rev | string | — | |
| role | AriaRole | — | |
| security | string | — | |
| slot | string | — | |
| spellCheck | Booleanish | — | |
| suppressContentEditableWarning | boolean | — | |
| suppressHydrationWarning | boolean | — | |
| tabIndex | number | — | |
| title | string | — | |
| translate | "yes" | "no" | — | |
| typeof | string | — | |
| unselectable | "off" | "on" | — | |
| vocab | string | — |
Dependencies
npm
- @fastrp/design-tokens
- motion@^12.40.0
Registry
Source
components/ds/fade-in.tsxShowHide
'use client';
import { DURATION_S, EASE } from '@fastrp/design-tokens/motion';
import { type HTMLMotionProps, motion, useReducedMotion } from 'motion/react';
import { useScrollRoot } from '@/components/ds/scroll-root';
// @fast-ds [email protected]
export type FadeInProps = Omit<
HTMLMotionProps<'div'>,
'initial' | 'whileInView' | 'viewport' | 'animate'
> & {
/** Where it comes from, in pixels at 1080p: `y` rises, `x` slides in from that side. */
from?: { x?: number; y?: number };
/** Seconds. */
delay?: number;
/** Seconds; `DURATION_S.slower` by default. */
duration?: number;
/** Play again every time it re-enters, instead of once. */
repeat?: boolean;
};
/**
* Fades a block into place the first time it scrolls into view. Under reduced motion it is a fade
* with no travel.
*
* The travel is a CSS calc on `--fade` (1 → 0) times `--ui-px`, not motion's own `x`/`y`: an inline
* transform in pixels would stay 1080p-sized in the FiveM NUI, which scales every length through
* `--ui-px`. `transform`, not the `translate` property, which Chromium 103 lacks.
*/
function FadeIn({
from = { y: 40 },
delay = 0,
duration = DURATION_S.slower,
repeat = false,
style,
children,
...props
}: FadeInProps) {
const reduceMotion = useReducedMotion();
const root = useScrollRoot();
const x = from.x ?? 0;
const y = from.y ?? 0;
return (
<motion.div
data-slot="fade-in"
initial={{ opacity: 0, '--fade': reduceMotion ? 0 : 1 }}
whileInView={{ opacity: 1, '--fade': 0 }}
viewport={{ once: !repeat, margin: '0px 0px -10% 0px', root }}
transition={{ duration, delay, ease: EASE }}
style={{
transform: `translate3d(calc(var(--fade, 0) * ${x} * var(--ui-px, 1px)), calc(var(--fade, 0) * ${y} * var(--ui-px, 1px)), 0)`,
...style,
}}
{...props}
>
{children}
</motion.div>
);
}
export { FadeIn };