npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fumikaz/split-flap

v0.4.0

Published

Accessible split-flap display components for React and TypeScript

Readme

@fumikaz/split-flap

React と TypeScript 向けの、アクセシブルな反転フラップ表示コンポーネントです。文字や値をフラップ式の回転アニメーションで表示します。

特徴

  • ESM / CommonJS / 型定義を配布
  • Unicode コードポイント対応で、日本語と絵文字を安全に扱う
  • sequenceshuffledirect の3つのアニメーションモード
  • prefers-reduced-motion とスクリーンリーダーに対応
  • CSS カスタムプロパティで外観を調整可能
  • 値マップの背景色、空の値、複数文字を1パネルに収める表示に対応
  • SSR 環境から安全に import 可能

インストール

npm install @fumikaz/split-flap

スタイルシートをアプリケーションのエントリーポイントで一度読み込みます。

import "@fumikaz/split-flap/styles.css";

基本例

import { SplitFlap } from "@fumikaz/split-flap";
import "@fumikaz/split-flap/styles.css";

export default function App() {
  return (
    <SplitFlap value="HELLO 10:24" length={11} interval={100} stagger={0} />
  );
}

多言語テキスト

漢字のように巨大な文字集合では、目的文字までの順送りを避ける shuffle が便利です。characters に目的の文字を含めなくても、最後に直接表示されます。

<SplitFlap value="こんにちは" length={5} animationMode="shuffle" />

色付きの値マップと背景

値マップでは、value に選択するキーを渡します。オブジェクトの定義順に選択先まで1件ずつ反転し、各値の bgColor は文字と同じfrom/to面へ追従します。

import type { SplitFlapValueMap } from "@fumikaz/split-flap";

const displayValues = {
  "0001": { value: "待機中", bgColor: "#f0ffff" },
  "0002": { value: "処理中", bgColor: "#fff4d6" },
  "0003": { value: "完了", bgColor: "#ffe5e5" },
} satisfies SplitFlapValueMap;

<SplitFlap
  values={displayValues}
  value="0003"
  valueTransitionInterval={350}
  charactersPerPanel={4}
  backgroundOptions={{
    widthMode: "fixed",
    alignment: "left",
    fixedWidth: 180,
    horizontalPadding: 18,
    verticalPadding: 6,
    borderRadius: 8,
  }}
/>;

bgColor が省略または空文字の場合は、背景バッジを描画しません。数値の寸法はpxとして扱います。

固定幅

widthMode: "fixed" では、文字列バッジの基準幅を fixedWidth に固定し、左右の horizontalPadding を加えた幅をバッジに使います。黒いフラップの幅は --split-flap-width で独立して決まり、バッジが広すぎる場合はパネル内に収まる幅へ制限されます。長い文字列は1行のままクリップされます。

可変幅

widthMode: "content" では、文字列の実幅に左右の horizontalPadding を加えた幅になります。黒いフラップの幅は --split-flap-width で独立して決まり、各バッジの横位置は alignment で指定します。verticalPadding は両モードで文字列バッジの高さへ一度だけ適用されます。

横位置

alignment は文字列と背景バッジを一体で配置します。"left""center""right" を指定でき、既定値は "center" です。左寄せ・右寄せでは、文字列にも背景の左右paddingを適用します。

<SplitFlap
  values={displayValues}
  value="0003"
  charactersPerPanel={4}
  backgroundOptions={{
    widthMode: "content",
    horizontalPadding: 18,
    verticalPadding: 6,
    borderRadius: 8,
  }}
/>

背景色はフラップ面を塗らず、文字列だけを囲む角丸長方形として静止面に描画します。反転するのは黒いフラップパネルと文字であり、色付きバッジ自体は回転しません。バッジは上半分・下半分の親要素でクリッピングされるため、中央の分割線に別の角丸は付きません。

文字列の実幅がバッジの内容領域を超える場合は、文字だけを自動で縮小してバッジ内へ収めます。静止面と反転面では同じ縮小率を使います。

空の値

value: "" を候補に含めると、文字を表示しない1枚のフラップを描画します。候補配列で空の値が連続する場合も、各候補は統合されず、それぞれでフラップアニメーションが実行されます。

<SplitFlap
  values={[
    { key: "ready", value: "READY" },
    { key: "blank-one", value: "" },
    { key: "blank-two", value: "" },
  ]}
  selectedValueKey="blank-two"
/>

旧候補配列との互換性

既存の readonly SplitFlapValue[]selectedValueKey も引き続き使用できます。配列候補に bgColor を付けた場合も、同じ背景面の処理が使われます。

<SplitFlap
  values={[
    { key: "0001", value: "待機中", bgColor: "#f0ffff" },
    { key: "0002", value: "処理中", bgColor: "#fff4d6" },
  ]}
  selectedValueKey="0002"
/>

Props

| Prop | 型 | 既定値 | 説明 | | ------------------------- | ------------------------------------- | ------------------ | ----------------------------------------------------------------------------- | | value | string | - | 単体モードの表示文字列、または値マップモードの選択キー | | values | SplitFlapValueMap | - | キーごとの { value, bgColor? }。空文字を含められ、定義順に通過する候補 | | backgroundOptions | Partial<SplitFlapBackgroundOptions> | 下記 | 背景の幅、横位置、余白、角丸 | | selectedValueKey | string | - | 旧候補配列モードで到達する候補のキー | | valueTransitionInterval | number | interval | 候補モードで次の候補へ進む間隔(ms) | | length | number | value の文字数 | パネル数。空文字のときは1 | | charactersPerPanel | number | 1 | 1パネルに収めるUnicode文字数。値マップでは省略時に最長値全体を1パネルへ収める | | characters | string \| readonly string[] | LATIN_CHARACTERS | 順送り・シャッフルに使う文字集合 | | interval | number | 360 | 上面・下面を含む1回の反転時間(ms) | | stagger | number | 0 | 各フラップの開始間隔(ms) | | padCharacter | string | " " | 短い値を埋める文字。複数文字の場合は最初のコードポイントを使用 | | animationMode | "sequence" \| "shuffle" \| "direct" | "sequence" | アニメーション方式 | | direction | "forward" \| "shortest" | "forward" | sequence の進行方向 | | shuffleCount | number | 6 | shuffle 時のランダム表示回数 | | className | string | - | 盤面のクラス名 | | characterClassName | string | - | 全フラップに付与するクラス名 | | ariaLabel | string | value | 盤面の代替テキスト | | wrapLongText | boolean | false | パネル幅に収まらない文字列を2行に折り返す | | alwaysWrapText | boolean | false | 文字数に関わらず常に2行に折り返す | | wrapThreshold | number | 0 | wrapLongTexttrue のときのみ有効。この文字数を超えたら、先頭からこの文字数で改行して2行表示(1行目=この文字数、残りを2行目)。以下なら文字を縮小して1行に収める。0(または未設定)で無効 | | onAnimationStart | () => void | - | 値変更によるアニメーション開始時 | | onAnimationComplete | () => void | - | 最新のアニメーション完了時 |

SplitFlapBackgroundOptions の既定値は次のとおりです。

{
  widthMode: "fixed",
  alignment: "center",
  fixedWidth: 160,
  horizontalPadding: 16,
  verticalPadding: 6,
  borderRadius: 8,
}

Animation modes

  • sequence: 文字集合を現在文字から目的文字まで順に反転します。
  • shuffle: ランダム文字を shuffleCount 回表示してから目的文字にします。同じ文字の連続を避けます。
  • direct: 1回の反転で目的文字へ切り替えます。

direction="shortest"sequence の際に、文字集合内で前後どちらが短いか選びます。

複数文字パネル

charactersPerPanel を指定すると、連続するUnicode文字を1枚のパネルへまとめて表示できます。length は文字数ではなくパネル数になります。

<SplitFlap value="TOKYO" length={2} charactersPerPanel={3} />

独自の文字集合

プリセットとして LATIN_CHARACTERSNUMBER_CHARACTERSJAPANESE_KANA_CHARACTERS を export しています。独自の配列も渡せます。

const symbols = [" ", "遅", "延", "着", "発", "-", "0", "1", "2", "3"];

<SplitFlap value="遅延" length={4} characters={symbols} />;

CSS カスタマイズ

コンポーネントの親要素または className に以下の変数を設定できます。

.my-board {
  --split-flap-width: 2.5rem;
  --split-flap-height: 3.5rem;
  --split-flap-gap: 0.2rem;
  --split-flap-font-size: 2.2rem;
  --split-flap-font-family: "Courier New", monospace;
  --split-flap-font-weight: 700;
  --split-flap-color: #f4ecc1;
  --split-flap-background: #171717;
  --split-flap-border-color: #343434;
  --split-flap-border-radius: 0.2rem;
  --split-flap-shadow: 0 0.18rem 0.32rem rgb(0 0 0 / 32%);
  --split-flap-frame-color: #111416;
  --split-flap-frame-edge-color: #32373a;
  --split-flap-frame-size: 1px;
  --split-flap-perspective: 900px;
  --split-flap-hinge-color: #080808;
  /* --split-flap-hinge-height: 0.5px; */
  --split-flap-text-offset: 0em;
  --split-flap-bg-fixed-width: 160px;
  --split-flap-bg-horizontal-padding: 16px;
  --split-flap-bg-vertical-padding: 6px;
  --split-flap-bg-border-radius: 8px;
}

Next.js

コンポーネントを使うファイルをクライアントコンポーネントにしてください。

"use client";

import { SplitFlap } from "@fumikaz/split-flap";
import "@fumikaz/split-flap/styles.css";

export function StatusDisplay() {
  return <SplitFlap value="READY" length={5} animationMode="shuffle" />;
}

アクセシビリティとブラウザ対応

外側の盤面だけに role="img" と文字列全体の aria-label を設定し、各フラップは aria-hidden にします。ライブリージョンは使用しません。prefers-reduced-motion: reduce が有効な利用者には、アニメーションせず最終文字を表示します。

CSS の 3D transform と ES2020 をサポートするモダンブラウザを対象とします。

開発

npm run dev       # デモを起動
npm run lint
npm run typecheck
npm run test
npm run test:run
npm run build     # dist にライブラリを出力
npm run preview
npm pack --dry-run

npm への公開

main への push と pull request では、CI が lint、型チェック、テスト、ビルド、パッケージ内容を検証します。

ローカルから公開する場合は、npm にログインして未公開のバージョンへ更新してから実行します。

npm version patch
npm publish

GitHub Release を published にすると、Publish to npm workflow が npm registry へ公開します。リリースタグは v<version> 形式にし、リポジトリの Actions secrets に npm の公開権限を持つ NPM_TOKEN を設定してください。

ライセンス

MIT