境界を溶かすUIを、APPへ
melta UI の React Native / Expo 版。
デザイン契約(melta-contracts)を SSOT に、web と APP が同じ言語で溶け合う。
web と APP、同じ契約から。
melta-app は melta デザインシステムの React Native 実装。
見た目のルールはコードに書かず、デザイン契約(melta-contracts)に宣言する。
web(Tailwind)と APP(React Native)は、同じ契約を満たす2つの実装にすぎない。
契約ファースト
variants / sizes / states / tokens は契約が規範。実装は契約を満たすことを conformance テストで機械検証する。手書きの「仕様書と実装のズレ」が構造的に起きない。
本物だけを見せる
この showcase の Live Catalog は React Native 実装そのものの web export(react-native-web)。HTML で作り直した再現デモではなく、iOS / Android で動くコードと同一。
AI-Ready
契約・recipe・実装状態(appStatus)はすべて機械可読。このページのコンポーネント表も契約からビルド時に生成していて、手書きの表は存在しない。
Live Catalog
実 RN コンポーネントのカタログ。light / dark 切替、Feed(dogfood 画面)、overlay 系の実挙動まですべて動く。
これは何?
-
example アプリ(dogfood + カタログ)を
expo export --platform webした静的サイト -
各セクションの
__contractchip は、その実装が満たす契約のメタデータ - 下部タブの Feed / Loading / Empty は公開 primitive だけで組んだ dogfood 画面
Components
全契約の APP 実装状態。この表は melta-contracts の appStatus からビルド時に生成される(手書きではない)。
| 契約 | Component | APP | 形(appMapping) | メモ |
|---|---|---|---|---|
| action-sheet | ActionSheet |
implemented | — | |
| alert | Alert |
implemented | — | |
| avatar | Avatar |
implemented | — | |
| bottom-sheet | BottomSheet |
implemented | — | |
| button | Button |
implemented | — | |
| card | Card |
implemented | — | |
| checkbox | Checkbox |
implemented | — | |
| empty-state | EmptyState |
implemented | — | |
| header | Header |
implemented | — | |
| icon | Icon |
implemented | — | |
| image | Image |
implemented | — | |
| metric | Metric |
implemented | — | |
| modal | Modal |
implemented | — | |
| progress | Progress |
implemented | — | |
| radio | Radio |
implemented | — | |
| row | Row |
implemented | — | |
| screen | Screen |
implemented | — | |
| skeleton | Skeleton |
implemented | — | |
| stack | Stack |
implemented | — | |
| surface | Surface |
implemented | — | |
| tag | Tag |
implemented | — | |
| text | Text |
implemented | — | |
| textfield | TextField |
implemented | — | |
| toast | Toast |
implemented | — | |
| toggle | Toggle |
implemented | — | |
| accordion | — | planned | — | |
| badge | — | planned | — | |
| datepicker | — | planned | adapted | カレンダー自作はしない。OS 標準の日付ピッカー(@react-native-community/datetimepicker 等)への委譲でトークンのみ供給 |
| divider | — | planned | — | |
| dropdown | — | planned | adapted | hover 起動は存在しない。タップ起動の Menu(アンカー付き)or ActionSheet に変換 |
| list | — | planned | — | |
| select | — | planned | adapted | web のドロップリストは持ち込まない。ActionSheet / BottomSheet / OS Picker で開く選択 UI に変換(gluestack/Tamagui も native では Sheet 化) |
| stepper | — | planned | — | |
| tabs | — | planned | adapted | トップタブ / SegmentedControl 型として実装(web の下線タブ意味論を M3 segmented / iOS UISegmentedControl に写像) |
| breadcrumb | — | not planned | — | RN 主要ライブラリ提供 0/5。Apple HIG が multisegment breadcrumb を明示的に否定。back ボタン + nav bar タイトルで代替 |
| copy-button | — | not planned | — | DS プリミティブでなくアプリ層のコンポジット(button + clipboard + toast) |
| pagination | — | not planned | — | モバイルは無限スクロール(FlatList onEndReached)で代替。カルーセル文脈は PageControl の領分 |
| sidebar | — | not planned | — | Navigation Drawer の領分=react-navigation 側の責務。DS はトークン供給のみ |
| table | — | not planned | — | モバイルは単列リスト / Card への再構成が定石(M3 に data table なし)。list + metric で分解表現する |
| tooltip | — | not planned | — | hover 前提のため。iPhone HIG に tooltip 概念なし。必要になれば長押し Hint として別契約を切る |
adapted = web と同じ見た目を持ち込まず、モバイルの慣習に形を変えて提供(例: select → ActionSheet)。not planned = HIG / モバイル UX 上の判断で APP には実装しない宣言。
Install
runtime 依存ゼロ。peer は react / react-native のみ(Icon を使う場合のみ react-native-svg を opt-in)。
インストール
npm install melta-app
使う
import { ThemeProvider, Screen, Header, Button, Card } from "melta-app";
export default function App() {
return (
<ThemeProvider>
<Screen variant="scroll" header={<Header title="ツーリング" />}>
<Card>...</Card>
<Button label="記録する" onPress={...} />
</Screen>
</ThemeProvider>
);
}
アイコン(opt-in subpath)
npm install react-native-svg
import { Icon } from "melta-app/icons";
ハーネス(品質ゲート)
「契約と実装がズレない」を人間の注意力ではなく CI の構造で守る。melta-app に入っている主なゲート:
conformance
契約の variants / sizes / states / tokens と RN 実装の resolver を機械照合。recipe との不一致はテストで落ちる。
drift-check
README のコンポーネント表を契約から生成し、カタログの掲載漏れ・「未実装」主張の腐りを CI で検知。
installability gate
pack した tarball を fixture に install → import → 型解決まで検証。「npm install すれば APP が作れる」の機械証明。
mount smoke + design lint
RN runtime での描画木生成を Testing Library で証明。raw color / radius の直書きは lint(--max-warnings 0)で禁止。