VNL Works
VNL Works
VNL Works
← Components
Download ZIPRegistry JSON
Package: tailwind-motion-kit
patterns

Segmented Toolbar

セグメントとタブを組み合わせたツールバー。

segmentedtabsnavigationtogglepattern

Install

“壊れにくさ”優先のため、依存は増やさずに ファイルをコピーして使う 形式です。

Files

まずは下記ファイルをプロジェクトに配置してください。

required-files.md
- tailwind-motion-kit/css/00_tokens.css (css)
- tailwind-motion-kit/css/44_segmented.css (css)
- tailwind-motion-kit/css/20_tabs.css (css)
Option A

まずは Bundle を読み込んで、動作を確認するのがおすすめです。

globals.css
/* Bundle: まずはこれが一番簡単 */
@import "./tailwind-motion-kit/css/99_bundle.css";
Option B

必要な CSS だけ読み込みたい場合はこちら。

globals.css
/* 1) CSS: グローバルCSSに追記 */
@import "./tailwind-motion-kit/css/00_tokens.css";
@import "./tailwind-motion-kit/css/44_segmented.css";
@import "./tailwind-motion-kit/css/20_tabs.css";
JavaScript

CSS-only のため初期化は不要です。

init.js
/* JS 初期化は不要です */

Snippets

Copy & paste

この部品には snippet が登録されていません。

Files

この部品が参照する実ファイルです。

tailwind-motion-kit/css/00_tokens.css
css
tailwind-motion-kit/css/00_tokens.css
/*!
 * Tailwind Motion Kit (mk) - Tokens
 * --------------------------------
 * 目的: 速度・距離・イージング等の“モーション言語”を統一し、
 *       パーツを増やしても品位が崩れない状態を作ります。
 *
 * 使い方:
 *  - :root の変数を上書きするだけで全体の動きを一括調整できます。
 *  - 個別要素は style="" か data-mk-* 属性で上書きできます(JSがある場合)。
 */

:root {
  /* --- イージング(加減速) --- */
  --mk-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --mk-ease-in: cubic-bezier(0.32, 0, 0.67, 0);
  --mk-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  /* “少しだけ遊び”が欲しい時用(多用は上品さを損ねます) */
  --mk-ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* --- 時間 --- */
  --mk-duration-fast: 160ms;
  --mk-duration-medium: 280ms;
  --mk-duration-slow: 600ms;
  --mk-duration-slower: 900ms;

  /* コンポーネントが参照する“共通デフォルト” */
  --mk-duration: var(--mk-duration-medium);
  --mk-ease: var(--mk-ease-out);
  --mk-delay: 0ms;

  /* --- 移動量 --- */
  --mk-distance-1: 6px;
  --mk-distance-2: 12px;
  --mk-distance-3: 20px;
  --mk-distance: var(--mk-distance-2);

  /* --- ぼかし --- */
  --mk-blur-0: 0px;
  --mk-blur-1: 6px;
  --mk-blur-2: 10px;
  --mk-blur: var(--mk-blur-1);

  /* --- 影(浮遊感) --- */
  --mk-shadow-lift: 0 12px 30px rgba(0, 0, 0, 0.14);
  --mk-shadow-soft: 0 10px 22px rgba(0, 0, 0, 0.10);

  /* --- アンダーライン --- */
  --mk-underline-thickness: 2px;
  --mk-underline-offset: 0.2em;

  /* --- フォーカスリング --- */
  --mk-ring-color: rgba(59, 130, 246, 0.35);
  --mk-ring-size: 3px;

  /* --- コントロール(button / input / select) --- */
  --mk-control-radius: 12px;
  --mk-control-bg: rgba(255, 255, 255, 0.05);
  --mk-control-border: rgba(255, 255, 255, 0.16);

  /* --- スケルトン(ロード中) --- */
  --mk-skeleton-a: rgba(0, 0, 0, 0.06);
  --mk-skeleton-b: rgba(0, 0, 0, 0.12);
  --mk-skeleton-speed: 1250ms;

  /* --- スピナー --- */
  --mk-spinner-size: 1.2em;
  --mk-spinner-border: 2px;

  /* --- テキスト分割表示 --- */
  --mk-char-step: 25ms; /* 1文字ごとの遅延 */


  /* --- ダイアログ / ドロワー --- */
  --mk-dialog-duration: var(--mk-duration-slow);
  --mk-dialog-ease: var(--mk-ease-out);
  --mk-dialog-backdrop-opacity: 0.45;
  --mk-dialog-offset: var(--mk-distance-3);
  --mk-dialog-scale-from: 0.995;
  --mk-dialog-radius: 18px;

  /* --- 折りたたみ(アコーディオン) --- */
  --mk-collapse-duration: var(--mk-duration-medium);
  --mk-collapse-ease: var(--mk-ease);

  /* --- Toast / 通知 --- */
  --mk-toast-gap: 10px;
  --mk-toast-width: min(360px, calc(100vw - 24px));
  --mk-toast-duration: var(--mk-duration-medium);
  --mk-toast-ease: var(--mk-ease-out);

  /* --- スクロール進捗(トップバー) --- */
  --mk-scroll-progress-top: 0px;
  --mk-scroll-progress-height: 3px;
  --mk-scroll-progress-ease: linear;

  /* --- ナビ下線インジケータ --- */
  --mk-nav-underline-height: 2px;
  --mk-nav-underline-radius: 999px;
  --mk-nav-duration: var(--mk-duration-medium);
  --mk-nav-ease: var(--mk-ease-out);


  /* --- UI state(idle/loading/success/error) --- */
  --mk-state-hold-success: 900ms;
  --mk-state-hold-error: 1400ms;


  /* --- Tabs --- */
  --mk-tabs-gap: 10px;
  --mk-tabs-radius: 999px;
  --mk-tabs-duration: var(--mk-duration-medium);
  --mk-tabs-ease: var(--mk-ease-out);
  --mk-tabs-underline-height: 2px;
  --mk-tabs-underline-color: currentColor;

  /* --- Tooltip --- */
  --mk-tooltip-bg: rgba(0, 0, 0, 0.82);
  --mk-tooltip-fg: #fff;
  --mk-tooltip-radius: 10px;
  --mk-tooltip-padding: 10px 12px;
  --mk-tooltip-gap: 8px;
  --mk-tooltip-shadow: 0 18px 60px rgba(0,0,0,0.35);
  --mk-tooltip-max-width: 260px;

  /* --- Stepper --- */
  --mk-stepper-gap: 14px;
  --mk-step-size: 28px;
  --mk-step-line: rgba(255, 255, 255, 0.14);
  --mk-step-done: rgba(59, 130, 246, 1);
  --mk-step-current: rgba(255, 255, 255, 0.92);
  --mk-step-todo: rgba(255, 255, 255, 0.5);

  /* --- Card --- */
  --mk-card-radius: 20px;

}

/* motion減衰設定のあるユーザーには、動きを最小化して“結果”を出します */
@media (prefers-reduced-motion: reduce) {
  :root {
    --mk-duration-fast: 0ms;
    --mk-duration-medium: 0ms;
    --mk-duration-slow: 0ms;
    --mk-duration-slower: 0ms;
    --mk-duration: 0ms;
    --mk-delay: 0ms;
  }
}
tailwind-motion-kit/css/44_segmented.css
css
tailwind-motion-kit/css/44_segmented.css
/*
 * Tailwind Motion Kit (mk) - Segmented Control
 * -------------------------------------------
 * 目的: 複数のモード/期間を切り替える。
 */

.mk-segmented {
  display: inline-flex;
  padding: 4px;
  gap: 4px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.04);
}

.mk-segmented-button {
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.65);
  transition: color var(--mk-duration-fast) var(--mk-ease-out),
    background var(--mk-duration-fast) var(--mk-ease-out);
}

.mk-segmented-button[data-active="true"] {
  background: rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.95);
}
tailwind-motion-kit/css/20_tabs.css
css
tailwind-motion-kit/css/20_tabs.css
/*!
 * Tailwind Motion Kit (mk) - Tabs
 * ------------------------------
 * 目的: “情報の切り替え”を、軽く・上品に。
 * 方針: CSSは見た目 / JSは状態(active)とアクセシビリティ(ARIA)を担当。
 *
 * 推奨マークアップ:
 * <div class="mk-tabs" data-mk-tabs>
 *   <div class="mk-tablist" role="tablist" aria-label="Example">
 *     <button class="mk-tab" role="tab" aria-selected="true" data-mk-tab>Tab A</button>
 *     <button class="mk-tab" role="tab" aria-selected="false" data-mk-tab>Tab B</button>
 *   </div>
 *   <div class="mk-tabpanels">
 *     <section class="mk-tabpanel" role="tabpanel" data-mk-panel>...</section>
 *     <section class="mk-tabpanel" role="tabpanel" data-mk-panel hidden>...</section>
 *   </div>
 * </div>
 *
 * JS:
 *   import { initTabs } from "./js/tabs.js";
 *   initTabs();
 */

.mk-tabs {
  display: grid;
  gap: 14px;
}

.mk-tablist {
  display: flex;
  gap: var(--mk-tabs-gap);
  align-items: center;
  flex-wrap: wrap;
}

.mk-tab {
  position: relative;
  cursor: pointer;
  user-select: none;

  padding: 10px 12px;
  border-radius: var(--mk-tabs-radius);
  background: transparent;
  color: inherit;
  border: 1px solid rgba(255, 255, 255, 0.10);
  opacity: 0.75;

  transition:
    opacity var(--mk-tabs-duration) var(--mk-tabs-ease),
    background var(--mk-tabs-duration) var(--mk-tabs-ease),
    border-color var(--mk-tabs-duration) var(--mk-tabs-ease);
}

.mk-tab:hover {
  opacity: 0.92;
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.16);
}

.mk-tab[data-mk-state="active"] {
  opacity: 1;
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.22);
}

.mk-tab:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--mk-ring-size) var(--mk-ring-color);
}

/* underline */
.mk-tab::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: -2px;
  height: var(--mk-tabs-underline-height);
  border-radius: 999px;
  background: var(--mk-tabs-underline-color);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--mk-tabs-duration) var(--mk-tabs-ease);
  opacity: 0.85;
}

.mk-tab[data-mk-state="active"]::after {
  transform: scaleX(1);
}

/* Panels
 *
 * Progressive enhancement:
 *  - JS が動かない環境では、パネルはすべて表示(情報欠落を避ける)
 *  - JS 初期化後(data-mk-enhanced="true")のみ、active 以外を非表示
 */
.mk-tabpanel {
  display: block;
}

@keyframes mk-tabs-panel-in {
  from { opacity: 0; transform: translate3d(0, 6px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* JS 初期化後のみ切り替え(panelを隠す) */
[data-mk-tabs][data-mk-enhanced="true"] .mk-tabpanel {
  display: none;
}

[data-mk-tabs][data-mk-enhanced="true"] .mk-tabpanel[data-mk-state="active"] {
  display: block;
  animation: mk-tabs-panel-in var(--mk-tabs-duration) var(--mk-tabs-ease) both;
}

@media (prefers-reduced-motion: reduce) {
  .mk-tab,
  .mk-tab::after {
    transition: none !important;
  }
  .mk-tabpanel[data-mk-state="active"] {
    animation: none !important;
  }
}
Preview
Tips
  • • デザイン側は CSS 変数(tokens)で一括調整できます。
  • • 動きは “短く・小さく・同じ癖” を優先すると品位が保てます。
  • • prefers-reduced-motion を必ず考慮してください。