From 8ce5366e80176e94f636e569eca726fafc7024fc Mon Sep 17 00:00:00 2001 From: syuilo Date: Sun, 29 Mar 2020 16:09:44 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=86=E3=83=BC=E3=83=9E=E9=96=A2=E4=BF=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/theme.ts | 26 ++++++++++----- src/docs/theme.ja-JP.md | 74 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 9 deletions(-) create mode 100644 src/docs/theme.ja-JP.md diff --git a/src/client/theme.ts b/src/client/theme.ts index cc69ee406..2f4920e3a 100644 --- a/src/client/theme.ts +++ b/src/client/theme.ts @@ -27,7 +27,7 @@ export const builtinThemes = [ require('./themes/danboard.json5'), require('./themes/olive.json5'), require('./themes/tweetdeck.json5'), -]; +] as Theme[]; let timeout = null; @@ -66,16 +66,21 @@ export function applyTheme(theme: Theme, persist = true) { } } -function compile(theme: Theme): { [key: string]: string } { - function getColor(code: string): tinycolor.Instance { - // ref - if (code[0] == '@') { - return getColor(theme.props[code.substr(1)]); +function compile(theme: Theme): Record { + function getColor(val: string): tinycolor.Instance { + // ref (prop) + if (val[0] === '@') { + return getColor(theme.props[val.substr(1)]); + } + + // ref (const) + else if (val[0] === '$') { + return getColor(theme.props[val]); } // func - if (code[0] == ':') { - const parts = code.split('<'); + else if (val[0] === ':') { + const parts = val.split('<'); const func = parts.shift().substr(1); const arg = parseFloat(parts.shift()); const color = getColor(parts.join('<')); @@ -87,12 +92,15 @@ function compile(theme: Theme): { [key: string]: string } { } } - return tinycolor(code); + // other case + return tinycolor(val); } const props = {}; for (const [k, v] of Object.entries(theme.props)) { + if (k.startsWith('$')) continue; // ignore const + props[k] = genValue(getColor(v)); } diff --git a/src/docs/theme.ja-JP.md b/src/docs/theme.ja-JP.md new file mode 100644 index 000000000..c9604da41 --- /dev/null +++ b/src/docs/theme.ja-JP.md @@ -0,0 +1,74 @@ +# テーマ + +テーマを設定して、Misskeyクライアントの見た目を変更できます。 + +## テーマの設定 +設定 > テーマ + +## テーマを作成する +テーマコードはJSON5で記述されたテーマオブジェクトです。 +テーマは以下のようなオブジェクトです。 +``` js +{ + id: '17587283-dd92-4a2c-a22c-be0637c9e22a', + + name: 'Danboard', + author: 'syuilo', + + base: 'light', + + props: { + accent: 'rgb(218, 141, 49)', + bg: 'rgb(218, 212, 190)', + fg: 'rgb(115, 108, 92)', + panel: 'rgb(236, 232, 220)', + renote: 'rgb(100, 152, 106)', + link: 'rgb(100, 152, 106)', + mention: '@accent', + hashtag: 'rgb(100, 152, 106)', + header: 'rgba(239, 227, 213, 0.75)', + navBg: 'rgb(216, 206, 182)', + inputBorder: 'rgba(0, 0, 0, 0.1)', + }, +} + +``` + +* `id` ... テーマの一意なID。UUIDをおすすめします。 +* `name` ... テーマ名 +* `author` ... テーマの作者 +* `desc` ... テーマの説明(オプション) +* `base` ... 明るいテーマか、暗いテーマか + * `light`にすると明るいテーマになり、`dark`にすると暗いテーマになります。 + * テーマはここで設定されたベーステーマを継承します。 +* `props` ... テーマのスタイル定義。これから説明します。 + +### テーマのスタイル定義 +`props`下にはテーマのスタイルを定義します。 +キーがCSSの変数名になり、バリューで中身を指定します。 +なお、この`props`オブジェクトはベーステーマから継承されます。 +ベーステーマは、このテーマの`base`が`light`なら[_light.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_light.json5)で、`dark`なら[_dark.json5](https://github.com/syuilo/misskey/blob/develop/src/client/themes/_dark.json5)です。 +つまり、このテーマ内の`props`に`panel`というキーが無くても、そこにはベーステーマの`panel`があると見なされます。 + +#### バリューで使える構文 +* 16進数で表された色 + * 例: `#00ff00` +* `rgb(r, g, b)`形式で表された色 + * 例: `rgb(0, 255, 0)` +* `rgb(r, g, b, a)`形式で表された透明度を含む色 + * 例: `rgba(0, 255, 0, 0.5)` +* 他のキーの値の参照 + * `@{キー名}`と書くと他のキーの値の参照になります。`{キー名}`は参照したいキーの名前に置き換えます。 + * 例: `@panel` +* 定数(後述)の参照 + * `${定数名}`と書くと定数の参照になります。`{定数名}`は参照したい定数の名前に置き換えます。 + * 例: `$main` +* 関数(後述) + * `:{関数名}<{引数}<{色}` + +#### 定数 +「CSS変数として出力はしたくないが、他のCSS変数の値として使いまわしたい」値があるときは、定数を使うと便利です。 +キー名を`$`で始めると、そのキーはCSS変数として出力されません。 + +#### 関数 +wip