Skip to content

Instantly share code, notes, and snippets.

@SpenceDiNicolantonio
Created April 30, 2024 22:12
Show Gist options
  • Save SpenceDiNicolantonio/7258a9e6d312bec980d26979f7115162 to your computer and use it in GitHub Desktop.
Save SpenceDiNicolantonio/7258a9e6d312bec980d26979f7115162 to your computer and use it in GitHub Desktop.
Svelte/Tailwind transition directive #svelte #tailwind #animation #transition #directive
import { linear } from 'svelte/easing';
type TickFunc = (t: number) => number | void;
export interface TailwindTransitionOptions {
delay?: number;
easing?: (t: number) => number;
base?: string;
from?: string;
to?: string;
}
function durationFromClassList(classes: string): number | undefined {
const matches = classes.match(/duration-(\d+)/);
if (matches) {
return parseInt(matches?.[1]);
}
}
export default function (node: HTMLElement, { delay, easing, base, from, to }: TailwindTransitionOptions = {}) {
const baseClasses = base ? base.split(' ') : [];
const fromClasses = from ? from.split(' ') : [];
const toClasses = to ? to.split(' ') : [];
const duration = (base && durationFromClassList(base)) || 300;
easing = easing || linear;
// Add base and from classes to node (if provided
if (baseClasses.length || fromClasses.length) {
node.classList.add(...[...baseClasses, ...fromClasses]);
}
let updated = false;
let completed = false;
const tick: TickFunc = (t) => {
const isStart = t !== 1 && t !== 0 && !updated;
const isEnd = (t === 1 || t === 0) && updated && !completed;
if (isStart) {
updated = true;
if (fromClasses.length) {
node.classList.remove(...fromClasses);
}
if (toClasses.length) {
node.classList.add(...toClasses);
}
}
if (isEnd) {
completed = true;
if (baseClasses.length) {
node.classList.remove(...baseClasses);
}
}
};
return { delay, duration, easing, tick };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment