melta-app 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/module/components/Card.js +32 -18
- package/lib/module/components/Card.js.map +1 -1
- package/lib/module/contracts/contract-types.js +2 -2
- package/lib/module/theme/ThemeProvider.js +17 -7
- package/lib/module/theme/ThemeProvider.js.map +1 -1
- package/lib/module/theme/define-theme.js +95 -17
- package/lib/module/theme/define-theme.js.map +1 -1
- package/lib/module/theme/index.js +7 -1
- package/lib/module/theme/index.js.map +1 -1
- package/lib/typescript/src/components/Card.d.ts +27 -4
- package/lib/typescript/src/components/Card.d.ts.map +1 -1
- package/lib/typescript/src/contracts/contract-types.d.ts +2 -2
- package/lib/typescript/src/primitives/Button.d.ts +1 -1
- package/lib/typescript/src/theme/ThemeProvider.d.ts.map +1 -1
- package/lib/typescript/src/theme/define-theme.d.ts +13 -1
- package/lib/typescript/src/theme/define-theme.d.ts.map +1 -1
- package/lib/typescript/src/theme/index.d.ts +7 -1
- package/lib/typescript/src/theme/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/components/Card.tsx +40 -14
- package/src/contracts/contract-types.ts +2 -2
- package/src/theme/ThemeProvider.tsx +17 -7
- package/src/theme/define-theme.ts +96 -12
- package/src/theme/index.ts +6 -1
|
@@ -11,6 +11,23 @@
|
|
|
11
11
|
* action/link は pressed 時 elevation.sm→md(§2 hover→pressed mapping)。
|
|
12
12
|
* focus-within は RN 非サポートとして Phase1 明示 drop(§2)。
|
|
13
13
|
* - 型で action/link は onPress 必須を強制(§4 の DU 精神。無言で非対話に落ちる事故を防ぐ)。
|
|
14
|
+
* - **カード面自体は操作要素にしない**(contract 2.1.0 の a11y.required)。面の Pressable は
|
|
15
|
+
* `accessibilityRole` を名乗らず `accessible={false}`。理由は2つ:
|
|
16
|
+
* 1. 面に button role を付けると、中に Button を置いたとき web で `<button>` の入れ子になり
|
|
17
|
+
* hydration error になる(production では minified React error #418 に潰れて原因が読めない)
|
|
18
|
+
* 2. 面はキーボードでもスクリーンリーダーでも押せない。面のタップは**ポインタ向けの近道**で、
|
|
19
|
+
* 他の入力手段からの到達は内包する `primaryAction` が担う
|
|
20
|
+
* そのため action/link は `primaryAction` を必須にする。書き忘れると「ポインタでしか押せない
|
|
21
|
+
* カード」が静かに出来上がるので、型で止める。
|
|
22
|
+
* - `role="article"` は contract の a11y.role をそのまま表現したもの(RN の W3C 準拠 prop。
|
|
23
|
+
* react-native-web では実際に `<article>` 要素になる)。accessibilityRole 系とは別系統。
|
|
24
|
+
* - **focus ring は Card では描かない**。フォーカスを受けるのは `primaryAction` 側で、
|
|
25
|
+
* melta の Button は自前の ring を持つ。カードにも出すと1回のフォーカスで ring が二重に描かれる。
|
|
26
|
+
* contract の focus-within は RN 非サポートとして Phase1 で明示 drop 済み(app recipe に記録あり)で、
|
|
27
|
+
* web だけ動く実装を残すとプラットフォーム非対称になるため、実装ごと持たない。
|
|
28
|
+
* - `accessibilityLabel` は 0.5.0 で削除した。面が `accessible={false}` なので native では
|
|
29
|
+
* 原理的に読まれず、web だけ `aria-label` として効く非対称な prop だった。
|
|
30
|
+
* 名前は操作要素が持つべきなので `primaryAction` 側に付ける。
|
|
14
31
|
* - Card は Image/Metric に依存しない(§1)。media/header/footer/children に呼び出し側が差し込む。
|
|
15
32
|
* 呼び出し側(例: D2I)は用途に応じて slot に Image+Metric を compose する。
|
|
16
33
|
* - media variant は overflow:hidden で角丸に画像をクリップし、body だけにパディング(contract と整合)。
|
|
@@ -18,11 +35,11 @@
|
|
|
18
35
|
|
|
19
36
|
import { Pressable, View } from "react-native";
|
|
20
37
|
import { useTheme } from "../theme/index.js";
|
|
21
|
-
import { useFocusRing, FocusRing } from "../primitives/_internal/focus-ring.js";
|
|
22
38
|
import { CONTRACTS } from "../contracts/contract-types.js";
|
|
23
39
|
import { CARD_INTERACTIVE, resolveCardShape, resolveCardBodyStyle } from "./card.styles.js";
|
|
24
40
|
|
|
25
|
-
// action/link(インタラクティブ)は onPress
|
|
41
|
+
// action/link(インタラクティブ)は onPress と primaryAction が必須、
|
|
42
|
+
// basic/media はどちらも取らない(§4 DU 精神)。
|
|
26
43
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
27
44
|
export function Card({
|
|
28
45
|
variant = "basic",
|
|
@@ -30,7 +47,7 @@ export function Card({
|
|
|
30
47
|
footer,
|
|
31
48
|
media,
|
|
32
49
|
onPress,
|
|
33
|
-
|
|
50
|
+
primaryAction,
|
|
34
51
|
style,
|
|
35
52
|
testID,
|
|
36
53
|
children
|
|
@@ -39,10 +56,6 @@ export function Card({
|
|
|
39
56
|
theme,
|
|
40
57
|
mode
|
|
41
58
|
} = useTheme();
|
|
42
|
-
const {
|
|
43
|
-
focused,
|
|
44
|
-
focusHandlers
|
|
45
|
-
} = useFocusRing();
|
|
46
59
|
const interactive = CARD_INTERACTIVE[variant] && onPress != null;
|
|
47
60
|
const isMedia = variant === "media";
|
|
48
61
|
const inner = /*#__PURE__*/_jsxs(_Fragment, {
|
|
@@ -50,7 +63,7 @@ export function Card({
|
|
|
50
63
|
children: media
|
|
51
64
|
}), /*#__PURE__*/_jsxs(View, {
|
|
52
65
|
style: resolveCardBodyStyle(theme, variant),
|
|
53
|
-
children: [header, children, footer]
|
|
66
|
+
children: [header, children, footer, primaryAction]
|
|
54
67
|
})]
|
|
55
68
|
});
|
|
56
69
|
|
|
@@ -65,26 +78,27 @@ export function Card({
|
|
|
65
78
|
}) : inner;
|
|
66
79
|
if (!interactive) {
|
|
67
80
|
return /*#__PURE__*/_jsx(View, {
|
|
81
|
+
role: "article",
|
|
68
82
|
testID: testID,
|
|
69
83
|
style: [resolveCardShape(theme, mode, variant), style],
|
|
70
84
|
children: content
|
|
71
85
|
});
|
|
72
86
|
}
|
|
73
87
|
|
|
74
|
-
// action/link: pressed 時 elevation.sm→md
|
|
75
|
-
return /*#__PURE__*/
|
|
76
|
-
|
|
77
|
-
onPress: onPress
|
|
78
|
-
accessibilityRole
|
|
79
|
-
|
|
88
|
+
// action/link: pressed 時 elevation.sm→md(focus 表示は primaryAction 側が持つ)。
|
|
89
|
+
return /*#__PURE__*/_jsx(Pressable, {
|
|
90
|
+
role: "article",
|
|
91
|
+
onPress: onPress
|
|
92
|
+
// 面は「操作要素」ではなく article(contract 2.1.0)。accessibilityRole は名乗らない。
|
|
93
|
+
// accessible={false} で a11y ツリーから子を畳まないことで、内包する primaryAction が
|
|
94
|
+
// 独立した操作要素として読み上げられる(既定の Pressable は子を畳んでしまう)。
|
|
95
|
+
,
|
|
96
|
+
accessible: false,
|
|
80
97
|
testID: testID,
|
|
81
98
|
style: ({
|
|
82
99
|
pressed
|
|
83
100
|
}) => [resolveCardShape(theme, mode, variant, pressed), style],
|
|
84
|
-
children:
|
|
85
|
-
visible: focused,
|
|
86
|
-
radius: theme.radius.lg
|
|
87
|
-
})]
|
|
101
|
+
children: content
|
|
88
102
|
});
|
|
89
103
|
}
|
|
90
104
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Pressable","View","useTheme","
|
|
1
|
+
{"version":3,"names":["Pressable","View","useTheme","CONTRACTS","CARD_INTERACTIVE","resolveCardShape","resolveCardBodyStyle","jsx","_jsx","jsxs","_jsxs","Fragment","_Fragment","Card","variant","header","footer","media","onPress","primaryAction","style","testID","children","theme","mode","interactive","isMedia","inner","content","borderRadius","radius","lg","overflow","role","accessible","pressed","__contract","card"],"sourceRoot":"../../../src","sources":["components/Card.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA,SAASA,SAAS,EAAEC,IAAI,QAAwC,cAAc;AAC9E,SAASC,QAAQ,QAAQ,mBAAU;AACnC,SAASC,SAAS,QAAQ,gCAA6B;AACvD,SAASC,gBAAgB,EAAEC,gBAAgB,EAAEC,oBAAoB,QAAQ,kBAAe;;AAYxF;AACA;AAAA,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA,EAAAC,QAAA,IAAAC,SAAA;AAgBA,OAAO,SAASC,IAAIA,CAAC;EACnBC,OAAO,GAAG,OAAO;EACjBC,MAAM;EACNC,MAAM;EACNC,KAAK;EACLC,OAAO;EACPC,aAAa;EACbC,KAAK;EACLC,MAAM;EACNC;AACS,CAAC,EAAE;EACZ,MAAM;IAAEC,KAAK;IAAEC;EAAK,CAAC,GAAGtB,QAAQ,CAAC,CAAC;EAClC,MAAMuB,WAAW,GAAGrB,gBAAgB,CAACU,OAAO,CAAC,IAAII,OAAO,IAAI,IAAI;EAChE,MAAMQ,OAAO,GAAGZ,OAAO,KAAK,OAAO;EAEnC,MAAMa,KAAK,gBACTjB,KAAA,CAAAE,SAAA;IAAAU,QAAA,GACGL,KAAK,IAAI,IAAI,iBAAIT,IAAA,CAACP,IAAI;MAAAqB,QAAA,EAAEL;IAAK,CAAO,CAAC,eACtCP,KAAA,CAACT,IAAI;MAACmB,KAAK,EAAEd,oBAAoB,CAACiB,KAAK,EAAET,OAAO,CAAE;MAAAQ,QAAA,GAC/CP,MAAM,EACNO,QAAQ,EACRN,MAAM,EACNG,aAAa;IAAA,CACV,CAAC;EAAA,CACP,CACH;;EAED;EACA;EACA,MAAMS,OAAO,GAAGF,OAAO,gBACrBlB,IAAA,CAACP,IAAI;IAACmB,KAAK,EAAE;MAAES,YAAY,EAAEN,KAAK,CAACO,MAAM,CAACC,EAAE;MAAEC,QAAQ,EAAE;IAAS,CAAE;IAAAV,QAAA,EAAEK;EAAK,CAAO,CAAC,GAElFA,KACD;EAED,IAAI,CAACF,WAAW,EAAE;IAChB,oBACEjB,IAAA,CAACP,IAAI;MAACgC,IAAI,EAAC,SAAS;MAACZ,MAAM,EAAEA,MAAO;MAACD,KAAK,EAAE,CAACf,gBAAgB,CAACkB,KAAK,EAAEC,IAAI,EAAEV,OAAO,CAAC,EAAEM,KAAK,CAAE;MAAAE,QAAA,EACzFM;IAAO,CACJ,CAAC;EAEX;;EAEA;EACA,oBACEpB,IAAA,CAACR,SAAS;IACRiC,IAAI,EAAC,SAAS;IACdf,OAAO,EAAEA;IACT;IACA;IACA;IAAA;IACAgB,UAAU,EAAE,KAAM;IAClBb,MAAM,EAAEA,MAAO;IACfD,KAAK,EAAEA,CAAC;MAAEe;IAAQ,CAAC,KAAK,CAAC9B,gBAAgB,CAACkB,KAAK,EAAEC,IAAI,EAAEV,OAAO,EAAEqB,OAAO,CAAC,EAAEf,KAAK,CAAE;IAAAE,QAAA,EAEhFM;EAAO,CACC,CAAC;AAEhB;;AAEA;AACAf,IAAI,CAACuB,UAAU,GAAGjC,SAAS,CAACkC,IAAI","ignoreList":[]}
|
|
@@ -16,7 +16,7 @@ export const CONTRACTS = {
|
|
|
16
16
|
},
|
|
17
17
|
button: {
|
|
18
18
|
id: "button",
|
|
19
|
-
version: "2.
|
|
19
|
+
version: "2.1.0",
|
|
20
20
|
variants: ["contained", "outlined", "brand-outline", "neutral", "lighted", "danger", "subtle"],
|
|
21
21
|
sizes: ["small", "medium", "large"],
|
|
22
22
|
states: ["default", "hover", "focus", "disabled", "loading"]
|
|
@@ -30,7 +30,7 @@ export const CONTRACTS = {
|
|
|
30
30
|
},
|
|
31
31
|
card: {
|
|
32
32
|
id: "card",
|
|
33
|
-
version: "2.
|
|
33
|
+
version: "2.1.0",
|
|
34
34
|
variants: ["basic", "media", "action", "link"],
|
|
35
35
|
sizes: [],
|
|
36
36
|
states: ["default", "hover", "focus-within"]
|
|
@@ -31,12 +31,22 @@ const DEFAULT_THEME = defineTheme({
|
|
|
31
31
|
id: "melta"
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
/**
|
|
35
|
+
* 同じ矛盾を毎レンダー報告しないためのラッチ(StrictMode の二重 render も1回に畳む)。
|
|
36
|
+
*
|
|
37
|
+
* キーは **theme の参照**。id 文字列にすると、id 未設定の theme 同士や同じ id を持つ別 theme が
|
|
38
|
+
* 互いの警告を打ち消してしまう(報告されるべき矛盾が黙る)。WeakMap なので theme が捨てられれば
|
|
39
|
+
* エントリも消える=動的に theme を作るアプリでも溜まらない。
|
|
40
|
+
*/
|
|
41
|
+
const reportedViolations = new WeakMap();
|
|
42
|
+
function reportViolation(theme, violation) {
|
|
43
|
+
let reported = reportedViolations.get(theme);
|
|
44
|
+
if (reported === undefined) {
|
|
45
|
+
reported = new Set();
|
|
46
|
+
reportedViolations.set(theme, reported);
|
|
47
|
+
}
|
|
48
|
+
if (reported.has(violation.requested)) return;
|
|
49
|
+
reported.add(violation.requested);
|
|
40
50
|
console.error(`melta: forcedMode="${violation.requested}" が指定されたが、この theme は ` + `colorScheme=${violation.colorScheme} なので "${violation.resolved}" で描画する。` + `useTheme().capabilities.colorScheme を見て、対応していない mode は UI 側で出さないこと。`);
|
|
41
51
|
}
|
|
42
52
|
export function ThemeProvider({
|
|
@@ -50,7 +60,7 @@ export function ThemeProvider({
|
|
|
50
60
|
mode,
|
|
51
61
|
violation
|
|
52
62
|
} = resolveMode(activeTheme.capabilities.colorScheme, forcedMode, system === "dark" ? "dark" : "light");
|
|
53
|
-
if (isDev && violation) reportViolation(activeTheme
|
|
63
|
+
if (isDev && violation) reportViolation(activeTheme, violation);
|
|
54
64
|
const value = useMemo(() => {
|
|
55
65
|
const colors = activeTheme.color.semantic[mode];
|
|
56
66
|
if (!colors) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createContext","useContext","useMemo","useColorScheme","nativeTheme","defineTheme","isDev","resolveMode","jsx","_jsx","ThemeContext","DEFAULT_THEME","id","reportedViolations","
|
|
1
|
+
{"version":3,"names":["createContext","useContext","useMemo","useColorScheme","nativeTheme","defineTheme","isDev","resolveMode","jsx","_jsx","ThemeContext","DEFAULT_THEME","id","reportedViolations","WeakMap","reportViolation","theme","violation","reported","get","undefined","Set","set","has","requested","add","console","error","colorScheme","resolved","ThemeProvider","children","forcedMode","system","activeTheme","mode","capabilities","value","colors","color","semantic","Error","Provider","useTheme","ctx"],"sourceRoot":"../../../src","sources":["theme/ThemeProvider.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -182,11 +182,27 @@ export function deriveColorScheme(semantic) {
|
|
|
182
182
|
throw new Error("melta: theme.color.semantic に light / dark のどちらも無い。最低1つの mode が要る。");
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
/**
|
|
185
|
+
/**
|
|
186
|
+
* capability が実際に描ける mode。
|
|
187
|
+
*
|
|
188
|
+
* 未知の値は**黙って light-dark 扱いにしない**。TypeScript を使わない消費者や、将来
|
|
189
|
+
* capability の値が増えたときに、誤った値が「両対応の theme」として通ってしまうと、
|
|
190
|
+
* 持っていない mode で描画されて初めて壊れる(=原因から遠い場所で落ちる)。
|
|
191
|
+
*/
|
|
186
192
|
export function supportedModes(colorScheme) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
193
|
+
switch (colorScheme) {
|
|
194
|
+
case "light-dark":
|
|
195
|
+
return ["light", "dark"];
|
|
196
|
+
case "single-dark":
|
|
197
|
+
return ["dark"];
|
|
198
|
+
case "single-light":
|
|
199
|
+
return ["light"];
|
|
200
|
+
default:
|
|
201
|
+
{
|
|
202
|
+
const unknown = colorScheme;
|
|
203
|
+
throw new Error(`melta: 未知の colorScheme capability "${String(unknown)}"。`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
190
206
|
}
|
|
191
207
|
|
|
192
208
|
// ---------------------------------------------------------------------------
|
|
@@ -206,6 +222,10 @@ export function supportedModes(colorScheme) {
|
|
|
206
222
|
export function resolveMode(colorScheme, forcedMode, systemMode) {
|
|
207
223
|
const supported = supportedModes(colorScheme);
|
|
208
224
|
const requested = forcedMode ?? systemMode;
|
|
225
|
+
// 未知の mode を supported[0] へ黙って倒すと、typo が「正常な light 表示」に化ける。
|
|
226
|
+
if (!MODES.includes(requested)) {
|
|
227
|
+
throw new Error(`melta: 未知の mode "${String(requested)}"。light / dark のみ。`);
|
|
228
|
+
}
|
|
209
229
|
if (supported.includes(requested)) return {
|
|
210
230
|
mode: requested
|
|
211
231
|
};
|
|
@@ -229,9 +249,23 @@ export function resolveMode(colorScheme, forcedMode, systemMode) {
|
|
|
229
249
|
// validation(開発時のみ。純関数なのでテストからも直接呼べる)
|
|
230
250
|
// ---------------------------------------------------------------------------
|
|
231
251
|
|
|
252
|
+
/**
|
|
253
|
+
* 欠けているキーを返す。**accessor で埋めた欄も「ある」と数える**(消費者が「まだ埋められない欄」に
|
|
254
|
+
* getter を置くのは正当な使い方なので、descriptor の存在だけを見る)。
|
|
255
|
+
*
|
|
256
|
+
* data property のときは値も見る(`undefined` を入れて型検査だけすり抜けた欄を拾う)。
|
|
257
|
+
* accessor は**呼ばない** — 呼ぶと消費者の開発用プローブが theme 構築時に全部発火し、
|
|
258
|
+
* 「melta が実際にどの欄を読んだか」の信号を壊してしまう。
|
|
259
|
+
*/
|
|
232
260
|
function missingKeys(target, keys) {
|
|
233
261
|
if (target === null || typeof target !== "object") return [...keys].map(String);
|
|
234
|
-
return keys.filter(key =>
|
|
262
|
+
return keys.filter(key => {
|
|
263
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, key);
|
|
264
|
+
if (descriptor === undefined) return true;
|
|
265
|
+
// accessor は値を読まずに「ある」とみなす
|
|
266
|
+
if (!("value" in descriptor)) return false;
|
|
267
|
+
return descriptor.value === undefined;
|
|
268
|
+
}).map(String);
|
|
235
269
|
}
|
|
236
270
|
|
|
237
271
|
/**
|
|
@@ -240,6 +274,12 @@ function missingKeys(target, keys) {
|
|
|
240
274
|
* 「宣言した mode の色が欠けている」「as キャストでキーが抜けた」といった、型を通り抜けた欠落を拾う。
|
|
241
275
|
* `defineTheme()` が dev で1回だけ呼ぶ。**render 中に呼ばないこと**(theme-ui は Provider の
|
|
242
276
|
* render body で毎レンダー全色を再帰走査して性能を落とした前例がある)。
|
|
277
|
+
*
|
|
278
|
+
* ⚠️ **完全な runtime validation ではない**。キーの存在と(data property のときだけ)
|
|
279
|
+
* `undefined` でないことを見るだけで、値の型・範囲・accessor の戻り値までは検査しない。
|
|
280
|
+
* 意図的にそうしている(上の missingKeys のコメント参照)。
|
|
281
|
+
*
|
|
282
|
+
* @experimental 公開しているが安定 API ではない。検査範囲とメッセージは予告なく変わりうる。
|
|
243
283
|
*/
|
|
244
284
|
export function validateTheme(options) {
|
|
245
285
|
const problems = [];
|
|
@@ -316,13 +356,52 @@ function installMissingModeGuards(semantic, where, colorScheme) {
|
|
|
316
356
|
}
|
|
317
357
|
}
|
|
318
358
|
|
|
319
|
-
/**
|
|
359
|
+
/** プレーンなオブジェクト(クラスインスタンスや null プロトタイプ以外の特殊物を除く)か。 */
|
|
360
|
+
function isPlainObject(value) {
|
|
361
|
+
if (typeof value !== "object" || value === null) return false;
|
|
362
|
+
const proto = Object.getPrototypeOf(value);
|
|
363
|
+
return proto === Object.prototype || proto === null;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* トークンの木を**複製する**。melta が自分のコピーを所有するために要る。
|
|
368
|
+
*
|
|
369
|
+
* なぜ単純な spread や structuredClone でないか:
|
|
370
|
+
* - **accessor を呼ばない**。消費者は「まだ埋められない欄」に getter を置くことがある
|
|
371
|
+
* (capability が無い軸を検出する開発用プローブ)。値を読んで複製すると、theme を
|
|
372
|
+
* 組み立てた時点で全部発火し、「melta が実際にどの欄を読んだか」の信号が壊れる。
|
|
373
|
+
* descriptor をそのまま移せば、getter は getter のまま運ばれる。
|
|
374
|
+
* - 再帰するのは plain object / array の **data property** だけ。それ以外(関数・
|
|
375
|
+
* クラスインスタンス・accessor)は素通しする。
|
|
376
|
+
*/
|
|
377
|
+
function cloneTokenTree(value) {
|
|
378
|
+
if (Array.isArray(value)) return value.map(item => cloneTokenTree(item));
|
|
379
|
+
if (!isPlainObject(value)) return value;
|
|
380
|
+
const source = Object.getOwnPropertyDescriptors(value);
|
|
381
|
+
const target = {};
|
|
382
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
383
|
+
const descriptor = source[key];
|
|
384
|
+
target[key] = "value" in descriptor ? {
|
|
385
|
+
...descriptor,
|
|
386
|
+
value: cloneTokenTree(descriptor.value)
|
|
387
|
+
} : descriptor;
|
|
388
|
+
}
|
|
389
|
+
return Object.defineProperties({}, target);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* dev 限定の再帰 freeze。**accessor は呼ばずに素通りする**(cloneTokenTree と同じ理由)。
|
|
394
|
+
* 呼ぶ相手は cloneTokenTree で作った melta 所有のコピーだけ。消費者の入力や、公開 export の
|
|
395
|
+
* `nativeTheme` の入れ子は凍らせない(凍らせると `{...nativeTheme}` からの派生が dev で壊れる)。
|
|
396
|
+
*/
|
|
320
397
|
function deepFreeze(value) {
|
|
321
|
-
if (value
|
|
398
|
+
if (!isPlainObject(value) && !Array.isArray(value)) return;
|
|
322
399
|
if (Object.isFrozen(value)) return;
|
|
323
400
|
Object.freeze(value);
|
|
324
|
-
|
|
325
|
-
|
|
401
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
402
|
+
for (const descriptor of Object.values(descriptors)) {
|
|
403
|
+
// accessor は呼ばない(呼ぶと消費者の開発用プローブが発火する)
|
|
404
|
+
if ("value" in descriptor) deepFreeze(descriptor.value);
|
|
326
405
|
}
|
|
327
406
|
}
|
|
328
407
|
|
|
@@ -343,16 +422,15 @@ export function defineTheme(options) {
|
|
|
343
422
|
throw new Error(`melta: theme の形が不正。\n- ${problems.join("\n- ")}`);
|
|
344
423
|
}
|
|
345
424
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
425
|
+
|
|
426
|
+
// 入力と参照を共有しない。共有すると (a) 呼び出し側の後からの書き換えが解決済み theme に
|
|
427
|
+
// 波及し(再レンダーは起きないので画面ごとに新旧が混在する)(b) dev の deepFreeze が
|
|
428
|
+
// 呼び出し側の入力と公開 export の nativeTheme まで凍らせて、正当な派生を壊す。
|
|
429
|
+
const owned = cloneTokenTree(options);
|
|
430
|
+
const semantic = owned.color.semantic;
|
|
349
431
|
const colorScheme = deriveColorScheme(semantic);
|
|
350
432
|
const theme = {
|
|
351
|
-
...
|
|
352
|
-
color: {
|
|
353
|
-
...options.color,
|
|
354
|
-
semantic
|
|
355
|
-
},
|
|
433
|
+
...owned,
|
|
356
434
|
capabilities: {
|
|
357
435
|
colorScheme
|
|
358
436
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["isDev","__DEV__","globalThis","process","env","NODE_ENV","keysOf","map","Object","keys","MODES","light","dark","SEMANTIC_KEYS","PRIMARY_KEYS","STATUS_KINDS","success","warning","danger","STATUS_COLOR_KEYS","base","subtleLight","textLight","subtleDark","textDark","SPACING_KEYS","RADIUS_KEYS","sm","md","lg","full","ELEVATION_KEYS","none","overlay","FONT_SIZE_KEYS","xxs","xs","xl","FONT_WEIGHT_KEYS","normal","medium","semibold","bold","declaredModes","semantic","withValue","Set","filter","mode","has","deriveColorScheme","modes","length","Error","supportedModes","colorScheme","resolveMode","forcedMode","systemMode","supported","requested","includes","resolved","undefined","violation","kind","missingKeys","target","String","key","prototype","hasOwnProperty","call","validateTheme","options","problems","where","id","color","push","unknownModes","missing","join","groups","primary","spacing","radius","elevation","typography","fontSize","fontWeight","status","label","installMissingModeGuards","defineProperty","enumerable","configurable","get","deepFreeze","value","isFrozen","freeze","defineTheme","theme","capabilities","$$melta"],"sourceRoot":"../../../src","sources":["theme/define-theme.ts"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["isDev","__DEV__","globalThis","process","env","NODE_ENV","keysOf","map","Object","keys","MODES","light","dark","SEMANTIC_KEYS","PRIMARY_KEYS","STATUS_KINDS","success","warning","danger","STATUS_COLOR_KEYS","base","subtleLight","textLight","subtleDark","textDark","SPACING_KEYS","RADIUS_KEYS","sm","md","lg","full","ELEVATION_KEYS","none","overlay","FONT_SIZE_KEYS","xxs","xs","xl","FONT_WEIGHT_KEYS","normal","medium","semibold","bold","declaredModes","semantic","withValue","Set","filter","mode","has","deriveColorScheme","modes","length","Error","supportedModes","colorScheme","unknown","String","resolveMode","forcedMode","systemMode","supported","requested","includes","resolved","undefined","violation","kind","missingKeys","target","key","descriptor","getOwnPropertyDescriptor","value","validateTheme","options","problems","where","id","color","push","unknownModes","missing","join","groups","primary","spacing","radius","elevation","typography","fontSize","fontWeight","status","label","prototype","hasOwnProperty","call","installMissingModeGuards","defineProperty","enumerable","configurable","get","isPlainObject","proto","getPrototypeOf","cloneTokenTree","Array","isArray","item","source","getOwnPropertyDescriptors","Reflect","ownKeys","defineProperties","deepFreeze","isFrozen","freeze","descriptors","values","defineTheme","owned","theme","capabilities","$$melta"],"sourceRoot":"../../../src","sources":["theme/define-theme.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -9,7 +9,13 @@
|
|
|
9
9
|
export * from "./types.js";
|
|
10
10
|
export { nativeTheme } from "./native-theme.js";
|
|
11
11
|
export { ThemeProvider, useTheme } from "./ThemeProvider.js";
|
|
12
|
-
export { defineTheme
|
|
12
|
+
export { defineTheme } from "./define-theme.js";
|
|
13
|
+
/**
|
|
14
|
+
* 以下は theme の解決規則を外から検証・再利用するためのヘルパ。
|
|
15
|
+
* **@experimental — 安定 API ではない。** 挙動・シグネチャ・メッセージは予告なく変わりうる。
|
|
16
|
+
* アプリの実行時ロジックが依存する場合は、useTheme().capabilities を使うほうが安全。
|
|
17
|
+
*/
|
|
18
|
+
export { validateTheme, resolveMode, supportedModes, deriveColorScheme, declaredModes } from "./define-theme.js";
|
|
13
19
|
/**
|
|
14
20
|
* letterSpacingRatio(em 相当の比率)を、適用先の fontSize から RN の letterSpacing(pt) に解決する。
|
|
15
21
|
* 例: resolveLetterSpacing(18, theme.typography.letterSpacingRatio.body)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["nativeTheme","ThemeProvider","useTheme","defineTheme","validateTheme","resolveMode","supportedModes","deriveColorScheme","declaredModes","resolveLetterSpacing","fontSize","ratio"],"sourceRoot":"../../../src","sources":["theme/index.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;;AAEA,cAAc,YAAS;AACvB,SAASA,WAAW,QAAQ,mBAAgB;AAC5C,SAASC,aAAa,EAAEC,QAAQ,QAAQ,oBAAiB;AAEzD,
|
|
1
|
+
{"version":3,"names":["nativeTheme","ThemeProvider","useTheme","defineTheme","validateTheme","resolveMode","supportedModes","deriveColorScheme","declaredModes","resolveLetterSpacing","fontSize","ratio"],"sourceRoot":"../../../src","sources":["theme/index.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;;AAEA,cAAc,YAAS;AACvB,SAASA,WAAW,QAAQ,mBAAgB;AAC5C,SAASC,aAAa,EAAEC,QAAQ,QAAQ,oBAAiB;AAEzD,SAASC,WAAW,QAAQ,mBAAgB;AAC5C;AACA;AACA;AACA;AACA;AACA,SACEC,aAAa,EACbC,WAAW,EACXC,cAAc,EACdC,iBAAiB,EACjBC,aAAa,QACR,mBAAgB;AASvB;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,oBAAoBA,CAACC,QAAgB,EAAEC,KAAa,EAAU;EAC5E,OAAOD,QAAQ,GAAGC,KAAK;AACzB","ignoreList":[]}
|
|
@@ -9,17 +9,33 @@
|
|
|
9
9
|
* action/link は pressed 時 elevation.sm→md(§2 hover→pressed mapping)。
|
|
10
10
|
* focus-within は RN 非サポートとして Phase1 明示 drop(§2)。
|
|
11
11
|
* - 型で action/link は onPress 必須を強制(§4 の DU 精神。無言で非対話に落ちる事故を防ぐ)。
|
|
12
|
+
* - **カード面自体は操作要素にしない**(contract 2.1.0 の a11y.required)。面の Pressable は
|
|
13
|
+
* `accessibilityRole` を名乗らず `accessible={false}`。理由は2つ:
|
|
14
|
+
* 1. 面に button role を付けると、中に Button を置いたとき web で `<button>` の入れ子になり
|
|
15
|
+
* hydration error になる(production では minified React error #418 に潰れて原因が読めない)
|
|
16
|
+
* 2. 面はキーボードでもスクリーンリーダーでも押せない。面のタップは**ポインタ向けの近道**で、
|
|
17
|
+
* 他の入力手段からの到達は内包する `primaryAction` が担う
|
|
18
|
+
* そのため action/link は `primaryAction` を必須にする。書き忘れると「ポインタでしか押せない
|
|
19
|
+
* カード」が静かに出来上がるので、型で止める。
|
|
20
|
+
* - `role="article"` は contract の a11y.role をそのまま表現したもの(RN の W3C 準拠 prop。
|
|
21
|
+
* react-native-web では実際に `<article>` 要素になる)。accessibilityRole 系とは別系統。
|
|
22
|
+
* - **focus ring は Card では描かない**。フォーカスを受けるのは `primaryAction` 側で、
|
|
23
|
+
* melta の Button は自前の ring を持つ。カードにも出すと1回のフォーカスで ring が二重に描かれる。
|
|
24
|
+
* contract の focus-within は RN 非サポートとして Phase1 で明示 drop 済み(app recipe に記録あり)で、
|
|
25
|
+
* web だけ動く実装を残すとプラットフォーム非対称になるため、実装ごと持たない。
|
|
26
|
+
* - `accessibilityLabel` は 0.5.0 で削除した。面が `accessible={false}` なので native では
|
|
27
|
+
* 原理的に読まれず、web だけ `aria-label` として効く非対称な prop だった。
|
|
28
|
+
* 名前は操作要素が持つべきなので `primaryAction` 側に付ける。
|
|
12
29
|
* - Card は Image/Metric に依存しない(§1)。media/header/footer/children に呼び出し側が差し込む。
|
|
13
30
|
* 呼び出し側(例: D2I)は用途に応じて slot に Image+Metric を compose する。
|
|
14
31
|
* - media variant は overflow:hidden で角丸に画像をクリップし、body だけにパディング(contract と整合)。
|
|
15
32
|
*/
|
|
16
|
-
import type { ReactNode } from "react";
|
|
33
|
+
import type { ReactElement, ReactNode } from "react";
|
|
17
34
|
import { type StyleProp, type ViewStyle } from "react-native";
|
|
18
35
|
interface CardBase {
|
|
19
36
|
header?: ReactNode;
|
|
20
37
|
footer?: ReactNode;
|
|
21
38
|
media?: ReactNode;
|
|
22
|
-
accessibilityLabel?: string;
|
|
23
39
|
style?: StyleProp<ViewStyle>;
|
|
24
40
|
testID?: string;
|
|
25
41
|
/** body。 */
|
|
@@ -28,15 +44,22 @@ interface CardBase {
|
|
|
28
44
|
type CardProps = CardBase & ({
|
|
29
45
|
variant?: "basic" | "media";
|
|
30
46
|
onPress?: never;
|
|
47
|
+
primaryAction?: never;
|
|
31
48
|
} | {
|
|
32
49
|
variant: "action" | "link";
|
|
33
50
|
onPress: () => void;
|
|
51
|
+
/**
|
|
52
|
+
* 面のタップと同じ遷移先を持つ操作要素(Button 等)。footer 位置に描画される。
|
|
53
|
+
* 面は role を持たないので、キーボード / スクリーンリーダーからの唯一の到達手段になる。
|
|
54
|
+
* 内包する操作要素が他にもある場合、ここに置くのは**主アクション**(contract 2.1.0)。
|
|
55
|
+
*/
|
|
56
|
+
primaryAction: ReactElement;
|
|
34
57
|
});
|
|
35
|
-
export declare function Card({ variant, header, footer, media, onPress,
|
|
58
|
+
export declare function Card({ variant, header, footer, media, onPress, primaryAction, style, testID, children, }: CardProps): import("react/jsx-runtime").JSX.Element;
|
|
36
59
|
export declare namespace Card {
|
|
37
60
|
var __contract: {
|
|
38
61
|
readonly id: "card";
|
|
39
|
-
readonly version: "2.
|
|
62
|
+
readonly version: "2.1.0";
|
|
40
63
|
readonly variants: readonly ["basic", "media", "action", "link"];
|
|
41
64
|
readonly sizes: readonly [];
|
|
42
65
|
readonly states: readonly ["default", "hover", "focus-within"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../../src/components/Card.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../../src/components/Card.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAK/E,UAAU,QAAQ;IAChB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY;IACZ,QAAQ,EAAE,SAAS,CAAC;CACrB;AAID,KAAK,SAAS,GAAG,QAAQ,GACvB,CACI;IAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,aAAa,CAAC,EAAE,KAAK,CAAA;CAAE,GACvE;IACE,OAAO,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;;OAIG;IACH,aAAa,EAAE,YAAY,CAAC;CAC7B,CACJ,CAAC;AAEJ,wBAAgB,IAAI,CAAC,EACnB,OAAiB,EACjB,MAAM,EACN,MAAM,EACN,KAAK,EACL,OAAO,EACP,aAAa,EACb,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE,SAAS,2CAgDX;yBA1De,IAAI"}
|
|
@@ -16,7 +16,7 @@ export declare const CONTRACTS: {
|
|
|
16
16
|
};
|
|
17
17
|
readonly button: {
|
|
18
18
|
readonly id: "button";
|
|
19
|
-
readonly version: "2.
|
|
19
|
+
readonly version: "2.1.0";
|
|
20
20
|
readonly variants: readonly ["contained", "outlined", "brand-outline", "neutral", "lighted", "danger", "subtle"];
|
|
21
21
|
readonly sizes: readonly ["small", "medium", "large"];
|
|
22
22
|
readonly states: readonly ["default", "hover", "focus", "disabled", "loading"];
|
|
@@ -30,7 +30,7 @@ export declare const CONTRACTS: {
|
|
|
30
30
|
};
|
|
31
31
|
readonly card: {
|
|
32
32
|
readonly id: "card";
|
|
33
|
-
readonly version: "2.
|
|
33
|
+
readonly version: "2.1.0";
|
|
34
34
|
readonly variants: readonly ["basic", "media", "action", "link"];
|
|
35
35
|
readonly sizes: readonly [];
|
|
36
36
|
readonly states: readonly ["default", "hover", "focus-within"];
|
|
@@ -38,7 +38,7 @@ export declare function Button(props: ButtonProps): import("react/jsx-runtime").
|
|
|
38
38
|
export declare namespace Button {
|
|
39
39
|
var __contract: {
|
|
40
40
|
readonly id: "button";
|
|
41
|
-
readonly version: "2.
|
|
41
|
+
readonly version: "2.1.0";
|
|
42
42
|
readonly variants: readonly ["contained", "outlined", "brand-outline", "neutral", "lighted", "danger", "subtle"];
|
|
43
43
|
readonly sizes: readonly ["small", "medium", "large"];
|
|
44
44
|
readonly states: readonly ["default", "hover", "focus", "disabled", "loading"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../../src/theme/ThemeProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG3E,OAAO,EAAmC,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAA2B,MAAM,gBAAgB,CAAC;AAC/I,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEtE,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,KAAK,EAAE,WAAW,CAAC;IACnB,gBAAgB;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,2EAA2E;IAC3E,MAAM,EAAE,cAAc,CAAC;IACvB,mDAAmD;IACnD,YAAY,EAAE,oBAAoB,CAAC;CACpC;
|
|
1
|
+
{"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../../src/theme/ThemeProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG3E,OAAO,EAAmC,KAAK,oBAAoB,EAAE,KAAK,mBAAmB,EAA2B,MAAM,gBAAgB,CAAC;AAC/I,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEtE,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,KAAK,EAAE,WAAW,CAAC;IACnB,gBAAgB;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,2EAA2E;IAC3E,MAAM,EAAE,cAAc,CAAC;IACvB,mDAAmD;IACnD,YAAY,EAAE,oBAAoB,CAAC;CACpC;AAmCD,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;OAIG;IACH,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,kBAAkB,2CAiChF;AAED,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C"}
|
|
@@ -82,7 +82,13 @@ export interface ThemeModeViolation {
|
|
|
82
82
|
export declare function declaredModes(semantic: Partial<Record<ThemeMode, SemanticColors>>): ThemeMode[];
|
|
83
83
|
/** colorScheme capability を `color.semantic` のキー集合から導出する。 */
|
|
84
84
|
export declare function deriveColorScheme(semantic: Partial<Record<ThemeMode, SemanticColors>>): ColorSchemeCapability;
|
|
85
|
-
/**
|
|
85
|
+
/**
|
|
86
|
+
* capability が実際に描ける mode。
|
|
87
|
+
*
|
|
88
|
+
* 未知の値は**黙って light-dark 扱いにしない**。TypeScript を使わない消費者や、将来
|
|
89
|
+
* capability の値が増えたときに、誤った値が「両対応の theme」として通ってしまうと、
|
|
90
|
+
* 持っていない mode で描画されて初めて壊れる(=原因から遠い場所で落ちる)。
|
|
91
|
+
*/
|
|
86
92
|
export declare function supportedModes(colorScheme: ColorSchemeCapability): ThemeMode[];
|
|
87
93
|
/**
|
|
88
94
|
* 表示 mode を解決する(純関数。ThemeProvider はこの結果に従うだけで判定はしない)。
|
|
@@ -104,6 +110,12 @@ export declare function resolveMode(colorScheme: ColorSchemeCapability, forcedMo
|
|
|
104
110
|
* 「宣言した mode の色が欠けている」「as キャストでキーが抜けた」といった、型を通り抜けた欠落を拾う。
|
|
105
111
|
* `defineTheme()` が dev で1回だけ呼ぶ。**render 中に呼ばないこと**(theme-ui は Provider の
|
|
106
112
|
* render body で毎レンダー全色を再帰走査して性能を落とした前例がある)。
|
|
113
|
+
*
|
|
114
|
+
* ⚠️ **完全な runtime validation ではない**。キーの存在と(data property のときだけ)
|
|
115
|
+
* `undefined` でないことを見るだけで、値の型・範囲・accessor の戻り値までは検査しない。
|
|
116
|
+
* 意図的にそうしている(上の missingKeys のコメント参照)。
|
|
117
|
+
*
|
|
118
|
+
* @experimental 公開しているが安定 API ではない。検査範囲とメッセージは予告なく変わりうる。
|
|
107
119
|
*/
|
|
108
120
|
export declare function validateTheme(options: ThemeOptions): string[];
|
|
109
121
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-theme.d.ts","sourceRoot":"","sources":["../../../../src/theme/define-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAIV,WAAW,EAGX,cAAc,EAGd,UAAU,EACV,SAAS,EACV,MAAM,SAAS,CAAC;AAMjB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,KAAK,EAAE,OAID,CAAC;AAMpB,4DAA4D;AAC5D,MAAM,MAAM,qBAAqB,GAAG,YAAY,GAAG,cAAc,GAAG,aAAa,CAAC;AAElF;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,qBAAqB,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9D,gEAAgE;IAChE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG;QACpC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;KACtD,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;CAC7C;AAED,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,yBAAyB,CAAC;IAChC,oCAAoC;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,oBAAoB;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,qBAAqB,CAAC;CACpC;AA0GD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,GAAG,SAAS,EAAE,CAG/F;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,GACnD,qBAAqB,CAQvB;AAED
|
|
1
|
+
{"version":3,"file":"define-theme.d.ts","sourceRoot":"","sources":["../../../../src/theme/define-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAIV,WAAW,EAGX,cAAc,EAGd,UAAU,EACV,SAAS,EACV,MAAM,SAAS,CAAC;AAMjB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,KAAK,EAAE,OAID,CAAC;AAMpB,4DAA4D;AAC5D,MAAM,MAAM,qBAAqB,GAAG,YAAY,GAAG,cAAc,GAAG,aAAa,CAAC;AAElF;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,qBAAqB,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9D,gEAAgE;IAChE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG;QACpC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;KACtD,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;CAC7C;AAED,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,yBAAyB,CAAC;IAChC,oCAAoC;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,oBAAoB;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,EAAE,qBAAqB,CAAC;CACpC;AA0GD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,GAAG,SAAS,EAAE,CAG/F;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,GACnD,qBAAqB,CAQvB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,qBAAqB,GAAG,SAAS,EAAE,CAa9E;AAMD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,qBAAqB,EAClC,UAAU,EAAE,SAAS,GAAG,SAAS,EACjC,UAAU,EAAE,SAAS,GACpB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,kBAAkB,CAAA;CAAE,CAgBrD;AA2BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,EAAE,CAwD7D;AA4FD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,mBAAmB,CA4BtE"}
|
|
@@ -7,7 +7,13 @@ export * from "./types";
|
|
|
7
7
|
export { nativeTheme } from "./native-theme";
|
|
8
8
|
export { ThemeProvider, useTheme } from "./ThemeProvider";
|
|
9
9
|
export type { ThemeContextValue, ThemeMode } from "./ThemeProvider";
|
|
10
|
-
export { defineTheme
|
|
10
|
+
export { defineTheme } from "./define-theme";
|
|
11
|
+
/**
|
|
12
|
+
* 以下は theme の解決規則を外から検証・再利用するためのヘルパ。
|
|
13
|
+
* **@experimental — 安定 API ではない。** 挙動・シグネチャ・メッセージは予告なく変わりうる。
|
|
14
|
+
* アプリの実行時ロジックが依存する場合は、useTheme().capabilities を使うほうが安全。
|
|
15
|
+
*/
|
|
16
|
+
export { validateTheme, resolveMode, supportedModes, deriveColorScheme, declaredModes, } from "./define-theme";
|
|
11
17
|
export type { ColorSchemeCapability, ResolvedCapabilities, ResolvedNativeTheme, ThemeModeViolation, ThemeOptions, } from "./define-theme";
|
|
12
18
|
/**
|
|
13
19
|
* letterSpacingRatio(em 相当の比率)を、適用先の fontSize から RN の letterSpacing(pt) に解決する。
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/theme/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/theme/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C;;;;GAIG;AACH,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "melta-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "melta for APP — melta デザインシステムの React Native UI kit。melta-contracts(デザイン契約)を single source of truth に RN 実装でその契約を満たす。アプリ本体ではなくライブラリ。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://app.melta.tsubotax.com",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"@types/react": "~19.2.2",
|
|
75
75
|
"eslint": "^10.4.1",
|
|
76
76
|
"jest": "^29.7.0",
|
|
77
|
-
"melta-contracts": "^0.
|
|
77
|
+
"melta-contracts": "^0.6.0",
|
|
78
78
|
"react": "19.2.3",
|
|
79
79
|
"react-native": "0.85.3",
|
|
80
80
|
"react-native-builder-bob": "^0.40.13",
|
package/src/components/Card.tsx
CHANGED
|
@@ -9,15 +9,31 @@
|
|
|
9
9
|
* action/link は pressed 時 elevation.sm→md(§2 hover→pressed mapping)。
|
|
10
10
|
* focus-within は RN 非サポートとして Phase1 明示 drop(§2)。
|
|
11
11
|
* - 型で action/link は onPress 必須を強制(§4 の DU 精神。無言で非対話に落ちる事故を防ぐ)。
|
|
12
|
+
* - **カード面自体は操作要素にしない**(contract 2.1.0 の a11y.required)。面の Pressable は
|
|
13
|
+
* `accessibilityRole` を名乗らず `accessible={false}`。理由は2つ:
|
|
14
|
+
* 1. 面に button role を付けると、中に Button を置いたとき web で `<button>` の入れ子になり
|
|
15
|
+
* hydration error になる(production では minified React error #418 に潰れて原因が読めない)
|
|
16
|
+
* 2. 面はキーボードでもスクリーンリーダーでも押せない。面のタップは**ポインタ向けの近道**で、
|
|
17
|
+
* 他の入力手段からの到達は内包する `primaryAction` が担う
|
|
18
|
+
* そのため action/link は `primaryAction` を必須にする。書き忘れると「ポインタでしか押せない
|
|
19
|
+
* カード」が静かに出来上がるので、型で止める。
|
|
20
|
+
* - `role="article"` は contract の a11y.role をそのまま表現したもの(RN の W3C 準拠 prop。
|
|
21
|
+
* react-native-web では実際に `<article>` 要素になる)。accessibilityRole 系とは別系統。
|
|
22
|
+
* - **focus ring は Card では描かない**。フォーカスを受けるのは `primaryAction` 側で、
|
|
23
|
+
* melta の Button は自前の ring を持つ。カードにも出すと1回のフォーカスで ring が二重に描かれる。
|
|
24
|
+
* contract の focus-within は RN 非サポートとして Phase1 で明示 drop 済み(app recipe に記録あり)で、
|
|
25
|
+
* web だけ動く実装を残すとプラットフォーム非対称になるため、実装ごと持たない。
|
|
26
|
+
* - `accessibilityLabel` は 0.5.0 で削除した。面が `accessible={false}` なので native では
|
|
27
|
+
* 原理的に読まれず、web だけ `aria-label` として効く非対称な prop だった。
|
|
28
|
+
* 名前は操作要素が持つべきなので `primaryAction` 側に付ける。
|
|
12
29
|
* - Card は Image/Metric に依存しない(§1)。media/header/footer/children に呼び出し側が差し込む。
|
|
13
30
|
* 呼び出し側(例: D2I)は用途に応じて slot に Image+Metric を compose する。
|
|
14
31
|
* - media variant は overflow:hidden で角丸に画像をクリップし、body だけにパディング(contract と整合)。
|
|
15
32
|
*/
|
|
16
33
|
|
|
17
|
-
import type { ReactNode } from "react";
|
|
34
|
+
import type { ReactElement, ReactNode } from "react";
|
|
18
35
|
import { Pressable, View, type StyleProp, type ViewStyle } from "react-native";
|
|
19
36
|
import { useTheme } from "../theme";
|
|
20
|
-
import { useFocusRing, FocusRing } from "../primitives/_internal/focus-ring";
|
|
21
37
|
import { CONTRACTS } from "../contracts/contract-types";
|
|
22
38
|
import { CARD_INTERACTIVE, resolveCardShape, resolveCardBodyStyle } from "./card.styles";
|
|
23
39
|
|
|
@@ -25,18 +41,27 @@ interface CardBase {
|
|
|
25
41
|
header?: ReactNode;
|
|
26
42
|
footer?: ReactNode;
|
|
27
43
|
media?: ReactNode;
|
|
28
|
-
accessibilityLabel?: string;
|
|
29
44
|
style?: StyleProp<ViewStyle>;
|
|
30
45
|
testID?: string;
|
|
31
46
|
/** body。 */
|
|
32
47
|
children: ReactNode;
|
|
33
48
|
}
|
|
34
49
|
|
|
35
|
-
// action/link(インタラクティブ)は onPress
|
|
50
|
+
// action/link(インタラクティブ)は onPress と primaryAction が必須、
|
|
51
|
+
// basic/media はどちらも取らない(§4 DU 精神)。
|
|
36
52
|
type CardProps = CardBase &
|
|
37
53
|
(
|
|
38
|
-
| { variant?: "basic" | "media"; onPress?: never }
|
|
39
|
-
| {
|
|
54
|
+
| { variant?: "basic" | "media"; onPress?: never; primaryAction?: never }
|
|
55
|
+
| {
|
|
56
|
+
variant: "action" | "link";
|
|
57
|
+
onPress: () => void;
|
|
58
|
+
/**
|
|
59
|
+
* 面のタップと同じ遷移先を持つ操作要素(Button 等)。footer 位置に描画される。
|
|
60
|
+
* 面は role を持たないので、キーボード / スクリーンリーダーからの唯一の到達手段になる。
|
|
61
|
+
* 内包する操作要素が他にもある場合、ここに置くのは**主アクション**(contract 2.1.0)。
|
|
62
|
+
*/
|
|
63
|
+
primaryAction: ReactElement;
|
|
64
|
+
}
|
|
40
65
|
);
|
|
41
66
|
|
|
42
67
|
export function Card({
|
|
@@ -45,13 +70,12 @@ export function Card({
|
|
|
45
70
|
footer,
|
|
46
71
|
media,
|
|
47
72
|
onPress,
|
|
48
|
-
|
|
73
|
+
primaryAction,
|
|
49
74
|
style,
|
|
50
75
|
testID,
|
|
51
76
|
children,
|
|
52
77
|
}: CardProps) {
|
|
53
78
|
const { theme, mode } = useTheme();
|
|
54
|
-
const { focused, focusHandlers } = useFocusRing();
|
|
55
79
|
const interactive = CARD_INTERACTIVE[variant] && onPress != null;
|
|
56
80
|
const isMedia = variant === "media";
|
|
57
81
|
|
|
@@ -62,6 +86,7 @@ export function Card({
|
|
|
62
86
|
{header}
|
|
63
87
|
{children}
|
|
64
88
|
{footer}
|
|
89
|
+
{primaryAction}
|
|
65
90
|
</View>
|
|
66
91
|
</>
|
|
67
92
|
);
|
|
@@ -76,24 +101,25 @@ export function Card({
|
|
|
76
101
|
|
|
77
102
|
if (!interactive) {
|
|
78
103
|
return (
|
|
79
|
-
<View testID={testID} style={[resolveCardShape(theme, mode, variant), style]}>
|
|
104
|
+
<View role="article" testID={testID} style={[resolveCardShape(theme, mode, variant), style]}>
|
|
80
105
|
{content}
|
|
81
106
|
</View>
|
|
82
107
|
);
|
|
83
108
|
}
|
|
84
109
|
|
|
85
|
-
// action/link: pressed 時 elevation.sm→md
|
|
110
|
+
// action/link: pressed 時 elevation.sm→md(focus 表示は primaryAction 側が持つ)。
|
|
86
111
|
return (
|
|
87
112
|
<Pressable
|
|
88
|
-
|
|
113
|
+
role="article"
|
|
89
114
|
onPress={onPress}
|
|
90
|
-
accessibilityRole
|
|
91
|
-
|
|
115
|
+
// 面は「操作要素」ではなく article(contract 2.1.0)。accessibilityRole は名乗らない。
|
|
116
|
+
// accessible={false} で a11y ツリーから子を畳まないことで、内包する primaryAction が
|
|
117
|
+
// 独立した操作要素として読み上げられる(既定の Pressable は子を畳んでしまう)。
|
|
118
|
+
accessible={false}
|
|
92
119
|
testID={testID}
|
|
93
120
|
style={({ pressed }) => [resolveCardShape(theme, mode, variant, pressed), style]}
|
|
94
121
|
>
|
|
95
122
|
{content}
|
|
96
|
-
<FocusRing visible={focused} radius={theme.radius.lg} />
|
|
97
123
|
</Pressable>
|
|
98
124
|
);
|
|
99
125
|
}
|
|
@@ -21,7 +21,7 @@ export const CONTRACTS = {
|
|
|
21
21
|
},
|
|
22
22
|
button: {
|
|
23
23
|
id: "button",
|
|
24
|
-
version: "2.
|
|
24
|
+
version: "2.1.0",
|
|
25
25
|
variants: ["contained", "outlined", "brand-outline", "neutral", "lighted", "danger", "subtle"],
|
|
26
26
|
sizes: ["small", "medium", "large"],
|
|
27
27
|
states: ["default", "hover", "focus", "disabled", "loading"],
|
|
@@ -35,7 +35,7 @@ export const CONTRACTS = {
|
|
|
35
35
|
},
|
|
36
36
|
card: {
|
|
37
37
|
id: "card",
|
|
38
|
-
version: "2.
|
|
38
|
+
version: "2.1.0",
|
|
39
39
|
variants: ["basic", "media", "action", "link"],
|
|
40
40
|
sizes: [],
|
|
41
41
|
states: ["default", "hover", "focus-within"],
|
|
@@ -46,13 +46,23 @@ const ThemeContext = createContext<ThemeContextValue | null>(null);
|
|
|
46
46
|
*/
|
|
47
47
|
const DEFAULT_THEME: ResolvedNativeTheme = defineTheme({ ...nativeTheme, id: "melta" });
|
|
48
48
|
|
|
49
|
-
/**
|
|
50
|
-
|
|
49
|
+
/**
|
|
50
|
+
* 同じ矛盾を毎レンダー報告しないためのラッチ(StrictMode の二重 render も1回に畳む)。
|
|
51
|
+
*
|
|
52
|
+
* キーは **theme の参照**。id 文字列にすると、id 未設定の theme 同士や同じ id を持つ別 theme が
|
|
53
|
+
* 互いの警告を打ち消してしまう(報告されるべき矛盾が黙る)。WeakMap なので theme が捨てられれば
|
|
54
|
+
* エントリも消える=動的に theme を作るアプリでも溜まらない。
|
|
55
|
+
*/
|
|
56
|
+
const reportedViolations = new WeakMap<ResolvedNativeTheme, Set<ThemeMode>>();
|
|
51
57
|
|
|
52
|
-
function reportViolation(
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
58
|
+
function reportViolation(theme: ResolvedNativeTheme, violation: ThemeModeViolation): void {
|
|
59
|
+
let reported = reportedViolations.get(theme);
|
|
60
|
+
if (reported === undefined) {
|
|
61
|
+
reported = new Set();
|
|
62
|
+
reportedViolations.set(theme, reported);
|
|
63
|
+
}
|
|
64
|
+
if (reported.has(violation.requested)) return;
|
|
65
|
+
reported.add(violation.requested);
|
|
56
66
|
console.error(
|
|
57
67
|
`melta: forcedMode="${violation.requested}" が指定されたが、この theme は ` +
|
|
58
68
|
`colorScheme=${violation.colorScheme} なので "${violation.resolved}" で描画する。` +
|
|
@@ -87,7 +97,7 @@ export function ThemeProvider({ children, forcedMode, theme }: ThemeProviderProp
|
|
|
87
97
|
forcedMode,
|
|
88
98
|
system === "dark" ? "dark" : "light",
|
|
89
99
|
);
|
|
90
|
-
if (isDev && violation) reportViolation(activeTheme
|
|
100
|
+
if (isDev && violation) reportViolation(activeTheme, violation);
|
|
91
101
|
|
|
92
102
|
const value = useMemo<ThemeContextValue>(() => {
|
|
93
103
|
const colors = activeTheme.color.semantic[mode];
|
|
@@ -233,11 +233,26 @@ export function deriveColorScheme(
|
|
|
233
233
|
);
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
/**
|
|
236
|
+
/**
|
|
237
|
+
* capability が実際に描ける mode。
|
|
238
|
+
*
|
|
239
|
+
* 未知の値は**黙って light-dark 扱いにしない**。TypeScript を使わない消費者や、将来
|
|
240
|
+
* capability の値が増えたときに、誤った値が「両対応の theme」として通ってしまうと、
|
|
241
|
+
* 持っていない mode で描画されて初めて壊れる(=原因から遠い場所で落ちる)。
|
|
242
|
+
*/
|
|
237
243
|
export function supportedModes(colorScheme: ColorSchemeCapability): ThemeMode[] {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
244
|
+
switch (colorScheme) {
|
|
245
|
+
case "light-dark":
|
|
246
|
+
return ["light", "dark"];
|
|
247
|
+
case "single-dark":
|
|
248
|
+
return ["dark"];
|
|
249
|
+
case "single-light":
|
|
250
|
+
return ["light"];
|
|
251
|
+
default: {
|
|
252
|
+
const unknown: never = colorScheme;
|
|
253
|
+
throw new Error(`melta: 未知の colorScheme capability "${String(unknown)}"。`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
241
256
|
}
|
|
242
257
|
|
|
243
258
|
// ---------------------------------------------------------------------------
|
|
@@ -261,6 +276,10 @@ export function resolveMode(
|
|
|
261
276
|
): { mode: ThemeMode; violation?: ThemeModeViolation } {
|
|
262
277
|
const supported = supportedModes(colorScheme);
|
|
263
278
|
const requested = forcedMode ?? systemMode;
|
|
279
|
+
// 未知の mode を supported[0] へ黙って倒すと、typo が「正常な light 表示」に化ける。
|
|
280
|
+
if (!(MODES as string[]).includes(requested)) {
|
|
281
|
+
throw new Error(`melta: 未知の mode "${String(requested)}"。light / dark のみ。`);
|
|
282
|
+
}
|
|
264
283
|
if (supported.includes(requested)) return { mode: requested };
|
|
265
284
|
|
|
266
285
|
const resolved = supported[0];
|
|
@@ -276,9 +295,25 @@ export function resolveMode(
|
|
|
276
295
|
// validation(開発時のみ。純関数なのでテストからも直接呼べる)
|
|
277
296
|
// ---------------------------------------------------------------------------
|
|
278
297
|
|
|
298
|
+
/**
|
|
299
|
+
* 欠けているキーを返す。**accessor で埋めた欄も「ある」と数える**(消費者が「まだ埋められない欄」に
|
|
300
|
+
* getter を置くのは正当な使い方なので、descriptor の存在だけを見る)。
|
|
301
|
+
*
|
|
302
|
+
* data property のときは値も見る(`undefined` を入れて型検査だけすり抜けた欄を拾う)。
|
|
303
|
+
* accessor は**呼ばない** — 呼ぶと消費者の開発用プローブが theme 構築時に全部発火し、
|
|
304
|
+
* 「melta が実際にどの欄を読んだか」の信号を壊してしまう。
|
|
305
|
+
*/
|
|
279
306
|
function missingKeys(target: object | undefined, keys: readonly (string | number)[]): string[] {
|
|
280
307
|
if (target === null || typeof target !== "object") return [...keys].map(String);
|
|
281
|
-
return keys
|
|
308
|
+
return keys
|
|
309
|
+
.filter((key) => {
|
|
310
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, key);
|
|
311
|
+
if (descriptor === undefined) return true;
|
|
312
|
+
// accessor は値を読まずに「ある」とみなす
|
|
313
|
+
if (!("value" in descriptor)) return false;
|
|
314
|
+
return descriptor.value === undefined;
|
|
315
|
+
})
|
|
316
|
+
.map(String);
|
|
282
317
|
}
|
|
283
318
|
|
|
284
319
|
/**
|
|
@@ -287,6 +322,12 @@ function missingKeys(target: object | undefined, keys: readonly (string | number
|
|
|
287
322
|
* 「宣言した mode の色が欠けている」「as キャストでキーが抜けた」といった、型を通り抜けた欠落を拾う。
|
|
288
323
|
* `defineTheme()` が dev で1回だけ呼ぶ。**render 中に呼ばないこと**(theme-ui は Provider の
|
|
289
324
|
* render body で毎レンダー全色を再帰走査して性能を落とした前例がある)。
|
|
325
|
+
*
|
|
326
|
+
* ⚠️ **完全な runtime validation ではない**。キーの存在と(data property のときだけ)
|
|
327
|
+
* `undefined` でないことを見るだけで、値の型・範囲・accessor の戻り値までは検査しない。
|
|
328
|
+
* 意図的にそうしている(上の missingKeys のコメント参照)。
|
|
329
|
+
*
|
|
330
|
+
* @experimental 公開しているが安定 API ではない。検査範囲とメッセージは予告なく変わりうる。
|
|
290
331
|
*/
|
|
291
332
|
export function validateTheme(options: ThemeOptions): string[] {
|
|
292
333
|
const problems: string[] = [];
|
|
@@ -386,13 +427,53 @@ function installMissingModeGuards(
|
|
|
386
427
|
}
|
|
387
428
|
}
|
|
388
429
|
|
|
389
|
-
/**
|
|
430
|
+
/** プレーンなオブジェクト(クラスインスタンスや null プロトタイプ以外の特殊物を除く)か。 */
|
|
431
|
+
function isPlainObject(value: unknown): value is Record<PropertyKey, unknown> {
|
|
432
|
+
if (typeof value !== "object" || value === null) return false;
|
|
433
|
+
const proto: unknown = Object.getPrototypeOf(value);
|
|
434
|
+
return proto === Object.prototype || proto === null;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* トークンの木を**複製する**。melta が自分のコピーを所有するために要る。
|
|
439
|
+
*
|
|
440
|
+
* なぜ単純な spread や structuredClone でないか:
|
|
441
|
+
* - **accessor を呼ばない**。消費者は「まだ埋められない欄」に getter を置くことがある
|
|
442
|
+
* (capability が無い軸を検出する開発用プローブ)。値を読んで複製すると、theme を
|
|
443
|
+
* 組み立てた時点で全部発火し、「melta が実際にどの欄を読んだか」の信号が壊れる。
|
|
444
|
+
* descriptor をそのまま移せば、getter は getter のまま運ばれる。
|
|
445
|
+
* - 再帰するのは plain object / array の **data property** だけ。それ以外(関数・
|
|
446
|
+
* クラスインスタンス・accessor)は素通しする。
|
|
447
|
+
*/
|
|
448
|
+
function cloneTokenTree<T>(value: T): T {
|
|
449
|
+
if (Array.isArray(value)) return value.map((item: unknown) => cloneTokenTree(item)) as T;
|
|
450
|
+
if (!isPlainObject(value)) return value;
|
|
451
|
+
|
|
452
|
+
const source = Object.getOwnPropertyDescriptors(value);
|
|
453
|
+
const target: PropertyDescriptorMap = {};
|
|
454
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
455
|
+
const descriptor = source[key as keyof typeof source] as PropertyDescriptor;
|
|
456
|
+
target[key as string] =
|
|
457
|
+
"value" in descriptor
|
|
458
|
+
? { ...descriptor, value: cloneTokenTree(descriptor.value) }
|
|
459
|
+
: descriptor;
|
|
460
|
+
}
|
|
461
|
+
return Object.defineProperties({}, target) as T;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* dev 限定の再帰 freeze。**accessor は呼ばずに素通りする**(cloneTokenTree と同じ理由)。
|
|
466
|
+
* 呼ぶ相手は cloneTokenTree で作った melta 所有のコピーだけ。消費者の入力や、公開 export の
|
|
467
|
+
* `nativeTheme` の入れ子は凍らせない(凍らせると `{...nativeTheme}` からの派生が dev で壊れる)。
|
|
468
|
+
*/
|
|
390
469
|
function deepFreeze(value: unknown): void {
|
|
391
|
-
if (value
|
|
470
|
+
if (!isPlainObject(value) && !Array.isArray(value)) return;
|
|
392
471
|
if (Object.isFrozen(value)) return;
|
|
393
472
|
Object.freeze(value);
|
|
394
|
-
|
|
395
|
-
|
|
473
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
474
|
+
for (const descriptor of Object.values<PropertyDescriptor>(descriptors)) {
|
|
475
|
+
// accessor は呼ばない(呼ぶと消費者の開発用プローブが発火する)
|
|
476
|
+
if ("value" in descriptor) deepFreeze(descriptor.value);
|
|
396
477
|
}
|
|
397
478
|
}
|
|
398
479
|
|
|
@@ -414,12 +495,15 @@ export function defineTheme(options: ThemeOptions): ResolvedNativeTheme {
|
|
|
414
495
|
}
|
|
415
496
|
}
|
|
416
497
|
|
|
417
|
-
|
|
498
|
+
// 入力と参照を共有しない。共有すると (a) 呼び出し側の後からの書き換えが解決済み theme に
|
|
499
|
+
// 波及し(再レンダーは起きないので画面ごとに新旧が混在する)(b) dev の deepFreeze が
|
|
500
|
+
// 呼び出し側の入力と公開 export の nativeTheme まで凍らせて、正当な派生を壊す。
|
|
501
|
+
const owned = cloneTokenTree(options);
|
|
502
|
+
const semantic = owned.color.semantic;
|
|
418
503
|
const colorScheme = deriveColorScheme(semantic);
|
|
419
504
|
|
|
420
505
|
const theme: ResolvedNativeTheme = {
|
|
421
|
-
...
|
|
422
|
-
color: { ...options.color, semantic },
|
|
506
|
+
...owned,
|
|
423
507
|
capabilities: { colorScheme },
|
|
424
508
|
$$melta: true,
|
|
425
509
|
};
|
package/src/theme/index.ts
CHANGED
|
@@ -8,8 +8,13 @@ export * from "./types";
|
|
|
8
8
|
export { nativeTheme } from "./native-theme";
|
|
9
9
|
export { ThemeProvider, useTheme } from "./ThemeProvider";
|
|
10
10
|
export type { ThemeContextValue, ThemeMode } from "./ThemeProvider";
|
|
11
|
+
export { defineTheme } from "./define-theme";
|
|
12
|
+
/**
|
|
13
|
+
* 以下は theme の解決規則を外から検証・再利用するためのヘルパ。
|
|
14
|
+
* **@experimental — 安定 API ではない。** 挙動・シグネチャ・メッセージは予告なく変わりうる。
|
|
15
|
+
* アプリの実行時ロジックが依存する場合は、useTheme().capabilities を使うほうが安全。
|
|
16
|
+
*/
|
|
11
17
|
export {
|
|
12
|
-
defineTheme,
|
|
13
18
|
validateTheme,
|
|
14
19
|
resolveMode,
|
|
15
20
|
supportedModes,
|