MCPcopy Index your code
hub / github.com/Danilaa1/slot-text

github.com/Danilaa1/slot-text @v0.3.2

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.3.2 ↗ · + Follow
38 symbols 85 edges 13 files 4 documented · 11%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

slot-text

npm version zero dependencies bundle size react vue solid svelte typescript

Dependency-free text roll animation for tiny, tactile UI labels.

📦 Install

Choose your preferred package manager:

npm

npm install slot-text

pnpm

pnpm add slot-text

Bun

bun add slot-text

Yarn

yarn add slot-text

🚀 Quick start

import "slot-text/style.css";
import { slotText, chromatic } from "slot-text";

const label = slotText(document.querySelector("#copy")!, "Copy");

// the classic Copy → Copied → Copy, in one call
label.flash("Copied", { enter: { color: chromatic() } });

That's it — import the CSS once, attach to an element, roll text.

🧩 API

Method What it does
set(text, options?) Roll to new text — the text stays
flash(text, options?) Roll in, then auto-revert to the previous text
destroy() Clean up
const label = slotText(element, "Copy", options);

label.set("Copied");                  // permanent change
label.set("Copy", { direction: "down" });
label.flash("Copied");                // temporary — rolls back after 1.4s
label.destroy();

💡 flash is spam-safe — repeat clicks restart the revert timer instead of queuing extra rolls, and an explicit set() cancels any pending revert.

label.flash("Copied", {
  revertAfter: 1400,                              // ms before rolling back
  enter: { direction: "up", color: chromatic() }, // roll-in
  exit: { direction: "down" },                    // roll-back
});

⚛️ React

import "slot-text/style.css";
import { SlotText } from "slot-text/react";
import { chromatic } from "slot-text";

<SlotText
  text={copied ? "Copied" : "Copy"}
  options={{ direction: copied ? "up" : "down", color: copied ? chromatic() : undefined }}
/>

💚 Vue

<script setup lang="ts">
import "slot-text/style.css";
import { SlotText } from "slot-text/vue";
</script>

<template>
  <SlotText text="Copied" :options="{ direction: 'up' }" />
</template>

🔷 Solid

import "slot-text/style.css";
import { createSignal } from "solid-js";
import { slotText } from "slot-text/solid";

const [label, setLabel] = createSignal("Copy");

<button aria-label={label()} onClick={() => setLabel("Copied")}>
  <span use:slotText={{ text: label(), options: { direction: "up" } }} />
</button>

🧡 Svelte

<script lang="ts">
  import "slot-text/style.css";
  import { slotText } from "slot-text/svelte";

  let label = "Copy";
</script>

<button aria-label={label} on:click={() => label = "Copied"}>
  <span use:slotText={{ text: label, options: { direction: "up" } }}></span>
</button>

⚙️ Options

Option Default Description
direction "down" Roll direction: "up" or "down"
stagger 45 Delay between characters (ms)
duration 300 Per-character animation time (ms)
exitOffset 50 Delay before the old character exits (ms)
easing springy bezier CSS easing function
bounce 0.6 Overshoot amount
color Color string, or (index, total) => string
colorFade 280 Fade back to base color (ms)
skipUnchanged true Don't re-roll identical characters
interrupt true See below 👇

🛑 interrupt

  • interrupt: true (default) — cuts off any roll in flight, starts fresh.
  • interrupt: false — lets the current roll finish; the latest call plays after it lands, duplicates are dropped. Ideal for spam-prone buttons.

🌈 chromatic()

Built-in rainbow color helper — pass it as color for a per-character hue sweep.

🔤 Font support

Each character animates in its own measured cell using your element's exact font, so widths are always correct.

Great with: monospace fonts, proportional Latin / Cyrillic / Greek (Geist, Inter, SF, …), italics, glyphs with overhang.

⚠️ Tradeoffs (inherent to any per-character slot animation):

  • Kerning is lost — pairs like AV sit slightly looser (invisible at label sizes).
  • Ligatures won't form (fi, fl, coding ligatures).
  • Joined scripts (Arabic, Devanagari) render as isolated forms.
  • ZWJ emoji sequences (👨‍👩‍👧) split into cells; single emoji are fine.
  • Very tall display fonts may clip at the roll mask (line-height: 1.3).

In short: ideal for short labels, numbers, statuses and commands — in essentially any font you'd use for those.

📝 Notes

  • Browser-only DOM utility, zero runtime dependencies.
  • React, Vue, Solid, and Svelte are optional peer dependencies — plain JS users don't need them.
  • Import the CSS once before using the animation.
  • Low-level helpers also exported: buildSlotText, animateSlotText, chromatic.

Extension points exported contracts — how you extend this code

SlotState (Interface)
Per-container record of the in-flight animation, so we can interrupt it.
src/slotText.ts
FlashOptions (Interface)
(no doc)
src/index.ts
SlotTextParams (Interface)
(no doc)
src/solid.ts
SlotTextParams (Interface)
(no doc)
src/svelte.ts
SlotTextProps (Interface)
(no doc)
src/react.ts
SlotOptions (Interface)
(no doc)
src/slotText.ts
SlotTextController (Interface)
(no doc)
src/index.ts
Directives (Interface)
(no doc)
src/solid.ts

Core symbols most depended-on inside this repo

slotText
called by 14
src/index.ts
set
called by 13
src/index.ts
destroy
called by 6
src/index.ts
buildSlotText
called by 6
src/slotText.ts
flash
called by 5
src/index.ts
animateSlotText
called by 5
src/slotText.ts
glyph
called by 3
src/slotText.ts
wobble
called by 3
src/slotText.ts

Shape

Function 26
Interface 9
Method 3

Languages

TypeScript100%

Modules by API surface

src/slotText.ts13 symbols
src/index.ts10 symbols
src/svelte.ts4 symbols
src/solid.ts3 symbols
tests/adapters.test.ts2 symbols
examples/solid.tsx2 symbols
tests/slotText.test.ts1 symbols
src/vue.ts1 symbols
src/react.ts1 symbols
examples/react.tsx1 symbols

For agents

$ claude mcp add slot-text \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page