01 Melt UI デザインシステムのインターフェースプレビュー 配置を変更し、文字間隔スライダーを動かしてグリッドを切り替えてください。ビルダーストアに応じて元のポスターが更新されます。
Svelte 5.57.1で動作する @melt-ui/svelte 0.86.6 のビルダーを使用。属性とアクションを明示し、Meltのプリプロセッサは不要。·
実装リファレンス 02
Melt UI デザインシステムのデザインリファレンス Svelte 5.57.1で動作する、検証済みの @melt-ui/svelte 0.86.6 ストア/アクションビルダーを使用しています。これはドキュメント化されたビルダー API であり、別系統の次世代 runes API ではありません。Meltはヘッドレスです。以下の --study-* のビジュアル値はすべて、アプリケーション側で設定する独自の値として完全に記述しています。
名前 / ルール 値 / 設定 用途 --study-canvas#f3f0e9 ページ外側。 --study-surface#fffdf8 コントロールパネル。 --study-ink#32352e 本文テキスト。 --study-muted#77796a 補助テキスト。 --study-line#dbdece トラックとパネルの境界。 --study-action#486348 選択中のラジオボタンとアクティブな範囲。 --study-on-action#fffアクション上のテキスト。 --study-focus#8aa77c キーボードフォーカスリング。 --study-poster#e0e8bb オリジナルポスターの用紙。 --study-accent#d68f57 装飾的な軌道形状。
名前 / ルール 値 / 設定 用途 --study-space-14pxアプリケーション側で名前を付けたスペーシング。Meltのデフォルト値ではありません。 --study-space-28pxアプリケーション側で名前を付けたスペーシング。Meltのデフォルト値ではありません。 --study-space-312pxアプリケーション側で名前を付けたスペーシング。Meltのデフォルト値ではありません。 --study-space-416pxアプリケーション側で名前を付けたスペーシング。Meltのデフォルト値ではありません。 --study-space-624pxアプリケーション側で名前を付けたスペーシング。Meltのデフォルト値ではありません。 --study-space-832pxアプリケーション側で名前を付けたスペーシング。Meltのデフォルト値ではありません。 Text familysystem-ui, sans-serif外部フォントへの依存なし。 Page title34px / 1.15; 29px narrow独自の見出し階層。 Poster titleclamp(28px,5.5vw,64px); 28px below 360px独自のレスポンシブ表示スケール。 Poster tracking0–8px, step 1; default 2pxスライダーで実際に調整できる文字間隔。 Grid spacing24px × 24pxネイティブスイッチで切り替える装飾ガイド。 Focus ring3px solid #8aa77c; 4px offset明示的な focus-visible のスタイル。
名前 / ルール 値 / 設定 用途 createRadioGroup.defaultValueleft配置は1つだけ選択可能。 Radio orientation / loophorizontal / true矢印キーによるナビゲーションは横方向のグループに沿って移動し、端から端へ循環します。 createSlider.defaultValue[2]つまみが1つでも、ストアは配列を保持します。 Slider min / max / step0 / 8 / 1範囲制限付きの整数で文字間隔を調整。 Slider elements.thumbsArray-producing builder store0.86.6で返されるのは単一のthumb要素ではなく、thumbの配列です。 createSwitch.defaultCheckedtrueガイドは表示状態で開始します。 Builder attributes + action{...$builder} use:builderMeltのオプションのプリプロセッサがなくても、明示的な構文を使用できます。 Thumb attributes + action{...thumb} use:thumb.action生成される各thumbに、それぞれの属性とアクションが付与されます。
03 Melt UI デザインシステム完全ガイド 実際のインターフェースで、このデザインシステムを選び、適用し、レビューするための実践ガイドです。
DESIGN-melt-ui.md 詳しいガイダンス、実装の出発点、ソースへのリンクをまとめています。
ガイドをダウンロード Melt UI デザインシステム:Meltで所有するマークアップに動作を追加する Meltで所有するマークアップに動作を追加する この例では、@melt-ui/svelte 0.86.6 のストア/アクション API を使用します。createRadioGroup、createSlider、createSwitch は、要素ビルダーと状態ストアを返します。通常のボタン、span、divに属性とアクションを設定することで、ネイティブのコントロール動作と連携させます。
パッケージには、緑色の用紙、ポスターのタイポグラフィ、パネルの形状は含まれていません。これらはオリジナルのスタイルシートにすべて定義されています。また、ドキュメントでは新しい別系統の runes API も紹介されています。このページでは、互換性のない2世代の例を混在させず、検証済みのビルダーバージョンを明示しています。
関連する仕様を確認する
Melt UI デザインシステム:属性の展開とアクションの設定を一緒に行う 属性の展開とアクションの設定を一緒に行う 要素には、ビルダーの属性とアクションの両方が必要です。この例では、{...$alignRoot} use:alignRoot や {...$alignItem(value)} use:alignItem のような形式を使います。属性はロール、状態、配置情報を担い、アクションはインタラクティブな動作とクリーンアップ処理を設定します。
簡略化された use:melt 構文には、Meltのオプションのプリプロセッサが必要です。プリプロセッサなしでは、ビルダーが適用されないままになるのではなく、実行時に具体的なエラーが発生します。修正後のコードでは明示的な構文を一貫して使用しているため、以下のVite設定に隠れた前処理の依存関係はありません。各スライダーのthumbも同様に、返された属性を展開し、thumb.actionを呼び出します。
関連する仕様を確認する
Melt UI デザインシステム:アプリケーション CSS でヘッドレスなビジュアルシステムを定義する アプリケーション CSS でヘッドレスなビジュアルシステムを定義する --study-* のロールで、外側のキャンバス、コントロール面、テキスト、区切り線、アクション、フォーカス、ポスターの用紙、装飾アクセントを区別します。名前付きのスペーシング値は6つあり、4ピクセルから32ピクセルまで設定されています。これらは、この構成を再現可能にするための独自の選択であり、Meltが管理するトークンカタログではありません。
ラジオボタンとスイッチが選択されている場合はdata-state=checkedが設定されます。スライダーは、返されたインライン位置に基づいて、つまみと選択範囲の表示位置が決まります。スタイルシートで追加するのは、形状と色だけです。これらの標準位置を手作業で計算したパーセンテージに置き換えると、ロジックが重複し、向きや方向のサポートを損なうおそれがあります。
関連する仕様を確認する
Melt UI デザインシステム:ネイティブのグループナビゲーションで、選択状態を1つに保つ ネイティブのグループナビゲーションで選択状態を1つに保つ createRadioGroupは、水平向きでループを有効にし、初期状態をleftに設定します。各ラジオ項目には、left、center、rightのいずれかの固定値を割り当てます。ポスターのtext-alignは選択された値を直接読み取るため、キーボード操作とポインター操作のどちらでも、同じ見た目に反映されます。
グループには、「テキストの配置」というアクセシブルなラベルを付けます。3つの選択肢には、手動でクラスを切り替える通常のボタンではなく、ビルダーに紐づくネイティブのラジオコントロールを使います。選択状態はセマンティクスと、塗りつぶしの見た目に使うdata-stateセレクターの両方に反映されます。
「中央」を選び、ポスターの配置を確認します。 「文字間隔」スライダーにフォーカスし、Endキーを押して8pxに設定します。 レイアウトグリッドをオフにして、できあがった構成をローカルに保存します。 関連する仕様を確認する
Melt UI デザインシステム:つまみが1つでも、値は配列として扱う つまみが1つでも値を配列として扱う スライダーの初期値には、単一の値ではなくdefaultValue:[2]を指定します。インストール済みの0.86.6では、ビルダーは配列を生成するelements.thumbsストアを公開しており、テンプレートでは返された各つまみを描画します。ポスターは$tracking[0]を読み取り、文字間隔のピクセル値として適用します。
範囲は0から8までで、ステップは1です。HomeキーとEndキーでそれぞれ上限・下限に移動し、矢印キーで定義されたステップずつ移動します。このつまみが1つの構成では$tracking[0]を読み取ります。つまみを追加する場合も配列モデルを維持し、別個のスカラー状態を導入しないでください。
関連する仕様を確認する
Melt UI デザインシステム:ビジュアルガイドをデザイン値から分離する ビジュアルガイドをデザイン値から切り離す createSwitchはオンの状態で始まり、その状態によってポスターにguidesクラスが付きます。このクラスは、24ピクセル間隔の控えめなグリッドを2つの繰り返しグラデーションで描画します。オフにすると、配置や文字間隔を変えずにグラデーションだけが消えます。
表示されている「レイアウトグリッドを表示」ラベルは、スイッチの固定IDと関連付けます。つまみの移動にはCSSトランジションを設定し、動きを抑える設定にも対応します。装飾用の軌道イラストはaria-hiddenに設定して操作要素にせず、実際のコントロールのセマンティクスを損なわないようにします。
関連する仕様を確認する
Melt UI デザインシステム:書き込み可能なストアを連携し、コントロールの状態を重複させない 書き込み可能なストアを、制御状態を重複させずに連携させる 配置、文字間隔、グリッドの表示状態は、ビルダーの書き込み可能なストアで管理します。描画されるポスターはこれらのストアを直接読み取り、text-alignには配置、letter-spacingにはスライダー値の先頭、CSSクラスにはスイッチのオン・オフ状態を使います。同じ3つの設定を別のアプリケーションモデルにも持たせると、不要な同期処理が発生します。
保存済みかどうかは、これらの値のシグネチャから判定します。値が変わると確認状態は解除され、リセット時にはストアにそれぞれleft、[2]、trueを書き戻します。要素が1つの配列である点は重要です。表示されるつまみが1つだけでも、スライダーの値の仕様に合わないスカラー値2を設定することはできません。
関連する仕様を確認する
Melt UI デザインシステム:各ビルダーに属性、アクション、名前を設定する 各ビルダーに属性、アクション、名前を設定する ラジオグループには「テキストの配置」というラベルを付け、スライダーのつまみは表示されている「文字間隔」のテキストを参照し、スイッチは表示ラベルと関連付けます。これらの名前は、周囲の装飾用ラッパーではなく、ビルダーに紐づく実際の要素に設定します。
明示的なテンプレート構文で、属性とアクションをまとめて設定します。スライダーのつまみでは、返される項目にアクションが含まれるため、ループ内でつまみの属性を展開し、thumb.actionを呼び出します。トラックと範囲のスタイルを設定する際は、ビルダーが出力する位置情報を維持してください。位置情報は実際の数値状態と方向を示し、スタイルシートは色と形状を定義します。
数値ラベルだけでなく、実際に計算された出力を確認してください。 ラベルはネイティブのビルダー要素に設定してください。 カスタムの視覚的なトランジションでは、動きを抑える設定に対応してください。 関連する仕様を確認する
Melt UI デザインシステム:検証済みのビルダーAPIを通常のSvelteプロジェクトで使う 通常のSvelteプロジェクトで検証済みのビルダー API を使う 完成したコンポーネントでは、$alignment、$tracking、$gridを使ってSvelteストアを購読します。Svelte 5では、この確立されたコンポーネント構文をコンパイルできます。エントリーポイントでは、現行のmount関数を使用します。ビジュアル全体は上記のコードで実現できるため、独自のアイコンライブラリやスタイルシートパッケージは不要です。
以下の標準的なVite Svelteセットアップでは、@melt-ui/svelte 0.86.6とSvelte 5.57.1を固定しています。コンポーネントですでに明示的な同等の構文を使っているため、Meltプリプロセッサはインストールしません。新しいrunesパッケージに移行するときは、依存関係のバージョンだけを変更するのではなく、APIを意図して書き換えてください。
関連する仕様を確認する
Melt UI デザインシステムのコンポーネント例 ストアとアクションを組み合わせた完全なビルダー構成 createRadioGroup、createSlider、createSwitchは、通常のマークアップにネイティブのセマンティクスと動作を追加します。
svelte コードをコピー
<script>
import {createRadioGroup,createSlider,createSwitch} from '@melt-ui/svelte';
const {elements:{root:alignRoot,item:alignItem},states:{value:alignment}}=createRadioGroup({defaultValue:'left',orientation:'horizontal',loop:true});
const {elements:{root:trackingRoot,range:trackingRange,thumbs},states:{value:tracking}}=createSlider({defaultValue:[2],min:0,max:8,step:1});
const {elements:{root:gridRoot},states:{checked:grid}}=createSwitch({defaultChecked:true});
let saved='';let previous='';
$: current=`${$alignment}|${$tracking[0]}|${$grid}`;
$: if(current!==previous){saved='';previous=current}
function save(){saved=`Saved locally: ${$alignment} aligned, ${$tracking[0]}px tracking, grid ${$grid?'on':'off'}.`}
function reset(){alignment.set('left');tracking.set([2]);grid.set(true);saved=''}
</script>
<main class="poster-shell"><header><p class="eyebrow">TYPE COMPOSITION · LIVE STUDY</p><h1>A small change. A different rhythm.</h1><p>Use native Melt UI builders to change the alignment, tracking and guide visibility of an original typographic poster.</p></header><div class="poster-layout"><section class="controls"><h2>Composition</h2><p class="control-label" id="alignment-label">Text alignment</p><div {...$alignRoot} use:alignRoot aria-labelledby="alignment-label" class="alignment">{#each ['left','center','right'] as value}<button {...$alignItem(value)} use:alignItem class="align-option">{value[0].toUpperCase()+value.slice(1)}</button>{/each}</div><div class="tracking-control"><p class="control-label" id="tracking-label">Letter spacing <strong>{$tracking[0]}px</strong></p><div {...$trackingRoot} use:trackingRoot class="slider"><div {...$trackingRange} use:trackingRange class="slider-range"></div>{#each $thumbs as thumb}<span {...thumb} use:thumb.action aria-labelledby="tracking-label" class="slider-thumb"></span>{/each}</div><div class="scale"><span>0px</span><span>8px</span></div></div><div class="grid-control"><label for="show-grid">Show layout grid</label><button id="show-grid" {...$gridRoot} use:gridRoot class="switch"><span></span></button></div><p class="hint">The grid is a visual aid. It does not change the poster’s text or spacing.</p><button class="primary" on:click={save} disabled={!!saved}>Save composition</button><button class="reset" on:click={reset}>Restore initial settings</button><p class="result" role="status">{saved||'This study changes only the local preview.'}</p></section><section class="poster" class:guides={$grid} style:text-align={$alignment} aria-label="Live typographic poster"><div class="poster-top"><span>TYPE / 2026</span><span>STUDY 04</span></div><div class="poster-orbit" aria-hidden="true"><i></i><b></b></div><div class="poster-title" style:letter-spacing={`${$tracking[0]}px`}><span>SPACE</span><span>TO</span><span>THINK.</span></div><div class="poster-bottom"><p>A pause between<br/>one idea and the next.</p><span>Original type study<br/>{$alignment} · {$tracking[0]}px</span></div></section></div></main>
コードリファレンス
スライダーの値は配列で、ポスターはその先頭の値を読み取ります。 明示的な属性の展開とアクションを使い、明示されていないプリプロセッサへの依存を避けています。 ビルダーのストアが変更されると、保存状態は無効になります。 ポスター本体とコントロールのスタイル一式 セマンティックなCSS変数、コントロールのdata-stateセレクター、フォーカスリング、画面幅に応じたタイポグラフィのポスター。
CSS コードをコピー
:root{--study-canvas:#f3f0e9;--study-surface:#fffdf8;--study-ink:#32352e;--study-muted:#77796a;--study-line:#dbdece;--study-action:#486348;--study-on-action:#fff;--study-focus:#8aa77c;--study-poster:#e0e8bb;--study-accent:#d68f57;--study-space-1:4px;--study-space-2:8px;--study-space-3:12px;--study-space-4:16px;--study-space-6:24px;--study-space-8:32px}html,body,#app{height:auto;min-height:0;margin:0}*{box-sizing:border-box}body{background:var(--study-canvas);color:var(--study-ink);font-family:system-ui,sans-serif}button{font:inherit;cursor:pointer}button:focus-visible,[role=slider]:focus-visible{outline:3px solid var(--study-focus);outline-offset:4px}button:disabled{opacity:.45;cursor:default}.poster-shell{max-width:1060px;margin:auto;padding:32px}.eyebrow{font-size:10px;font-weight:700;letter-spacing:.14em;color:var(--study-muted)}h1{font-size:34px;line-height:1.15;max-width:650px;margin:12px 0}header>p:last-child{font-size:14px;line-height:1.7;color:var(--study-muted);max-width:620px}.poster-layout{display:grid;grid-template-columns:300px minmax(0,1fr);gap:24px;margin-top:28px}.controls{padding:24px;background:var(--study-surface);border:1px solid var(--study-line);border-radius:14px;align-self:start;min-width:0}.controls h2{font-size:20px;margin:0 0 24px}.control-label{font-size:12px;font-weight:600;margin:0 0 12px}.control-label strong{float:right;color:var(--study-action)}.alignment{display:flex;border:1px solid var(--study-line);padding:4px;border-radius:8px;gap:4px}.align-option{border:0;flex:1;padding:9px 4px;border-radius:5px;font-size:12px;background:transparent;color:var(--study-muted)}.align-option[data-state=checked]{background:var(--study-action);color:var(--study-on-action)}.tracking-control{margin-top:26px}.slider{position:relative;height:24px;display:flex;align-items:center;touch-action:none}.slider:before{content:'';height:4px;background:var(--study-line);position:absolute;inset:10px 0;border-radius:4px}.slider-range{height:4px;position:absolute;background:var(--study-action);border-radius:4px}.slider-thumb{height:20px;width:20px;border:2px solid var(--study-action);background:white;border-radius:50%;cursor:grab}.scale{display:flex;justify-content:space-between;font-size:10px;color:var(--study-muted);margin-top:8px}.grid-control{display:flex;align-items:center;justify-content:space-between;gap:12px;border-top:1px solid var(--study-line);padding-top:22px;margin-top:24px;font-size:13px}.switch{width:42px;height:24px;padding:3px;border:0;border-radius:999px;background:#b7beaf;flex-shrink:0}.switch span{display:block;width:18px;height:18px;border-radius:50%;background:white;transition:transform .15s}.switch[data-state=checked]{background:var(--study-action)}.switch[data-state=checked] span{transform:translateX(18px)}.hint{font-size:11px;line-height:1.7;color:var(--study-muted);margin:12px 0 24px}.primary{display:block;width:100%;padding:12px;border:0;border-radius:7px;background:var(--study-action);color:white;font-size:13px;font-weight:600}.reset{width:100%;padding:12px 0;border:0;background:transparent;color:var(--study-muted);font-size:11px}.result{font-size:11px;line-height:1.7;color:var(--study-muted);margin:8px 0 0}.poster{background:var(--study-poster);padding:28px;border-radius:14px;min-width:0;overflow:hidden;position:relative}.poster.guides{background-image:linear-gradient(#6680561c 1px,transparent 1px),linear-gradient(90deg,#6680561c 1px,transparent 1px);background-size:24px 24px}.poster-top{display:flex;justify-content:space-between;gap:12px;font-size:9px;font-weight:700;letter-spacing:.1em;position:relative;z-index:1}.poster-orbit{height:130px;position:relative;margin:10px 0 20px}.poster-orbit i{display:block;position:absolute;width:140px;height:140px;background:var(--study-accent);border-radius:50%;right:10%;top:0}.poster-orbit b{display:block;position:absolute;width:140px;height:140px;border:2px solid #617748;border-radius:50%;right:27%;top:0}.poster-title{font-size:clamp(28px,5.5vw,64px);line-height:1.08;font-weight:800;position:relative}.poster-title span{display:block}.poster-bottom{display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;border-top:1px solid #9fac7c;margin-top:26px;padding-top:18px;font-size:11px;line-height:1.7}.poster-bottom p{margin:0}.poster-bottom>span{font-size:9px;color:#627046}@media(max-width:740px){.poster-layout{grid-template-columns:minmax(0,1fr)}.poster-shell{padding:20px}h1{font-size:29px}.poster-title{font-size:clamp(30px,9vw,56px)}}@media(max-width:360px){.poster-shell{padding:14px}.controls,.poster{padding:16px}.poster-title{font-size:28px}.poster-orbit{height:110px}.poster-orbit i,.poster-orbit b{width:115px;height:115px}.poster-top{font-size:8px}}@media(prefers-reduced-motion:reduce){.switch span{transition:none}}
コードリファレンス
視覚デザインに使うトークンはすべて独自のものであり、Melt公式のデフォルト値ではありません。 スライダーのつまみと範囲の位置は、ネイティブのビルダー属性から取得します。 装飾用グリッドの表示状態は、文字間隔と独立しています。 04
Melt UI デザインシステムのエージェント設定 実装の出発点 Svelte 5.57.1で動作確認済みの、@melt-ui/svelte 0.86.6のストアとアクションを使うAPI。明示的なビルダー構文により、オプションのMeltプリプロセッサは不要です。これは、別個の次世代runesAPIではありません。
JavaScript サンプルをコピー
// npm create vite@latest melt-type-study -- --template svelte
// cd melt-type-study && npm install
// npm install [email protected] @melt-ui/[email protected]
// Save the complete examples as src/App.svelte and src/style.css.
// src/main.js:
import {mount} from 'svelte';
import App from './App.svelte';
import './style.css';
mount(App, {target:document.querySelector('#app')});
// index.html: <div id="app"></div><script type="module" src="/src/main.js"></script>
// npm run dev あなたのプロジェクト向けプロンプト AI エージェント用プロンプト プロンプトをコピー
タイポグラフィ構成のスタディでは、Svelte 5と@melt-ui/svelte 0.86.6のストア/アクションビルダーを使用してください。createRadioGroup、createSlider、createSwitchの各要素には、属性とアクションの両方を適用します。明示された構文を使い、指定されていないプリプロセッサを必要としないようにしてください。スライダーの1要素配列とelements.thumbsの契約、配置値、グリッドの表示状態を維持してください。ポスターの計算済みスタイルはこれらのストアに直接バインドし、変更後は保存済みのフィードバックを無効にして、left、[2]、trueにリセットしてください。新しいrunes APIや予約モデルを混在させないでください。 05
Melt UI デザインシステムの情報源と範囲 Svelte 5.57.1と@melt-ui/svelte 0.86.6のストア/アクションビルダーを使用しています。ビジュアルトークンとポスターのコンテンツはすべてオリジナルです。保存されるのはローカルのプレビュー状態のみで、デザインのエクスポートや公開は行いません。