Skip to content

Releases

v0.2.1

Choose a tag to compare

@alexberce alexberce released this 20 Jul 11:45
a1e7263

Performance

  • The relayout pass (inferred FLIP and size animations) now skips elements far
    outside the viewport. It runs on every LiveView patch and measured every
    tracked element, so on a page with hundreds of animated elements a patch that
    changed three of them still cost tens of thousands of layout reads — twice,
    since the deferred exit removal triggers a second pass. Off-screen elements
    are now skipped, and the visibility observer reseeds their cached layout when
    they come back toward the viewport. The per-frame sibling remeasure during a
    size-collapse exit skips off-screen siblings the same way.

v0.2.0

Choose a tag to compare

@alexberce alexberce released this 20 Jul 00:11
9fd4570

Performance

  • Enter and exit animations on large streamed lists no longer thrash layout. Shift now batches the layout reads and writes for the whole burst, so a filter that adds or removes hundreds of rows forces layout once instead of once per row.
  • Elements far outside the viewport skip their enter and exit animation, so only the visible rows animate.

Added

  • New attribute: pin_exit. On exit, if a staying sibling would move up into the leaving element's slot, Shift lifts the element out of flow (position: fixed) so the neighbours close the gap during the exit instead of snapping shut once the node is removed. Best for fade and scale exits. Off by default.

v0.1.7

Choose a tag to compare

@alexberce alexberce released this 18 Jun 12:57

Fixed

  • live_redirect no longer waits for the outgoing page's exit animations
    before showing the new page. Shift now strips phx-remove off the outgoing
    animated nodes when the redirect starts, so LiveView swaps the page
    immediately.

v0.1.6

Choose a tag to compare

@alexberce alexberce released this 25 May 22:46

Added

  • package.json so the JS imports by name:

    import { init as initShift } from "shift"

v0.1.5

Choose a tag to compare

@alexberce alexberce released this 25 May 21:52

Fixed

  • Exit animations no longer fire during a live_redirect. Mid-page
    interactions (clicks, form submits) still animate exits normally
    because their loading kind is "element", not "redirect".

v0.1.4

Choose a tag to compare

@alexberce alexberce released this 25 May 21:40

Fixed

  • Layout cache now seeds when an element transitions from hidden to
    visible. The v0.1.3 fix stopped caching a bogus (0, 0) for elements
    inside a display: none ancestor, but the cache stayed empty until
    the first DOM mutation while visible — and by that point the move
    had already happened, leaving FLIP without a pre-move position to
    animate from. An IntersectionObserver now watches every tracked
    element and seeds the cache the moment visibility changes.

v0.1.3

Choose a tag to compare

@alexberce alexberce released this 25 May 21:22

Fixed

  • Elements that mount inside a display: none ancestor no longer cache
    a bogus (0, 0) layout. The next time they appear and then change,
    FLIP would diff against the stale zero and fly the element in from
    the top-left of the page. measure now returns null when the
    element has no layout, and the cache stays empty until the element
    is actually visible.
  • Cross-parent moves where the element becomes the first child of
    its new parent now animate. The previous local-position FLIP gate
    saw localTop = 0 in both the old and new parent and skipped the
    animation entirely. Relayout now also FLIPs whenever the element's
    parent itself changes, using the body-relative delta for the
    transform amount.

v0.1.2

Choose a tag to compare

@alexberce alexberce released this 25 May 18:16

Fixed

  • Position FLIP is now gated by the element's position relative to its
    immediate parent, not its body-relative offset. Previously, any layout
    change that shrank content above a tracked list — a delete in one
    demo, for instance — would shift everything below it in body
    coordinates, and Shift would FLIP every unrelated element down the
    page back to its old absolute position. Now only elements whose
    position within their own parent changes get animated; the body-
    relative delta is still what the FLIP translates by, so bottom-
    anchored layouts (toast stacks) keep working.
  • Cached layouts now refresh on window resize. The MutationObserver
    doesn't fire on a resize, so previously every tracked element's
    __shiftLayout went stale and the next real layout change would FLIP
    against the pre-resize positions — animating the resize delta into
    whatever change came next. A debounced resize listener now remeasures
    every tracked element so the next FLIP starts from the current layout.

v0.1.1

Choose a tag to compare

@alexberce alexberce released this 25 May 18:16

Fixed

  • Sibling layout caches now refresh on every animation frame during a
    size-collapsing exit, and are nulled when the element is finally
    removed. Previously, the post-removal relayout would FLIP each
    neighbor by the full reflow distance, snapping them back to their
    pre-exit positions and animating up again.

Added

  • Special-case collapse for <tr> exits. Because display: table-row
    derives its height from the tallest cell rather than its own CSS
    height, each cell's padding, font-size, and line-height are
    now animated to zero alongside the row's exit. The row's intrinsic
    height shrinks with the animation while the table layout stays
    intact.
  • fontSize and lineHeight added to PX_PROPS so the keyframe
    builder emits them with a px unit instead of as bare numbers
    (which WAAPI silently ignores).

v0.1.0

Choose a tag to compare

@alexberce alexberce released this 25 May 15:04

Initial release.

Install

```elixir
{:shift, "~> 0.1"}
```

What's in this release

  • `<.animated>` component — one component for enter, exit, layout (FLIP), and size animations.
  • Renders any HTML tag via `as=` (defaults to `div`).
  • Tween transitions with phase-aware easing defaults.
  • Spring transitions backed by a numerical ODE solver.
  • Smart defaults: opacity fade by default, auto-resolved targets, padding/margin/border collapse on size animations.
  • Inferred mid-life animations — position and size changes animate automatically; opt out per element with `disable: [:position, :size]`.
  • Server-driven exits via `phx-remove`, with cascading-order preservation and sliding-window stack handling out of the box.