Skip to main content

セルの条件つき書式のように、値に応じて色を変えたい

やりたいこと

  • テーブルでセル内容によって背景色を変えたい
    • 'o', 'x', '-' に 完全一致 なら、背景 緑/赤/グレー にして中央揃え
    • 'o', 'x', '-' で 始まる なら、背景色をつけるが左寄せのまま
  • テーブル毎に動的ではなく、システム全体で構わない

ゴール

機能製品1製品2製品3
機能1. ◯◯ができるxo-
機能2. ◯◯の設定- なしx 以前はあったが廃止o XX画面で設定可

※ 横道
Docusaurus は ドキュメント内に こうやって 動作確認コードが書けるのが とても良い

できないこと

  • 👴 CSS で innerText の値によって切り替えることができれば、実現可能ではない?
  • 🤖 できません。 なぜなら CSS は構造に対して操作するのであって、コンテンツには関係しません。
  • 👴 実は :has() とか :contains() とか、あるんじゃないの(疑って検索)
  • 🤖 ないよ

方法1. JavaScript を使用(今回、不採用)

  • 🤖 JavaScript なら出来るよ
  • 👴 んー、ちょっと違う
html
<table>
<tr><td>OK</td></tr>
<tr><td>NG</td></tr>
</table>

<script>
document.querySelectorAll('td').forEach(td => {
if (td.innerText === 'o') {
td.style.backgroundColor = 'lightgreen';
} else if (td.innerText === 'x') {
td.style.backgroundColor = 'lightcoral';
}
});
</script>

方法2. remark プラグインで テーブルの動作をカスタマイズ

remark plugin の実装

remark-cell-colorizer.ts
import { Plugin } from 'unified';
import { visit } from 'unist-util-visit';
import { toString } from 'mdast-util-to-string';
import { TableCell } from 'mdast';

const remarkCellColorizer: Plugin = () => {
return (tree) => {
visit(tree, 'tableCell', (node: TableCell) => {
const rawText = toString(node);

const classNames: string[] = [];

if (rawText == 'o') {
classNames.push('md-cell-ok');
classNames.push('md-cell-center');
} else if (rawText == 'x') {
classNames.push('md-cell-ng');
classNames.push('md-cell-center');
} else if (rawText == '-') {
classNames.push('md-cell-disabled');
classNames.push('md-cell-center');
} else if (rawText.startsWith('o ')) {
classNames.push('md-cell-ok');
} else if (rawText.startsWith('x ')) {
classNames.push('md-cell-ng');
} else if (rawText.startsWith('- ')) {
classNames.push('md-cell-disabled');
}

if (classNames.length > 0) {
if (!node.data) node.data = {};
if (!node.data.hProperties) node.data.hProperties = {};
const existing = node.data.hProperties.className;
if (Array.isArray(existing)) {
node.data.hProperties.className = [...existing, ...classNames];
} else if (typeof existing === 'string') {
node.data.hProperties.className = [existing, ...classNames];
} else {
node.data.hProperties.className = classNames;
}
}
});
};
};

export default remarkCellColorizer;

docusaurus.config.ts からの読み込み

docusaurus.config.ts
import remarkCellColorizer from './src/plugins/remark-cell-colorizer';

...
const config: Config = {
...
presets: [
[
'classic',
{
docs: {
routeBasePath: '/',
sidebarPath: './sidebars.ts',
showLastUpdateTime: true,
remarkPlugins: [
remarkCellColorizer, // ← ★ ここに足す
],

css 設定の追加

custom.css
td.md-cell-ok {
background: #e0f8ecdd;
color: #008800;
}
td.md-cell-ng {
background: #fbeaeadd;
color: #dd0000;
}
td.md-cell-disabled {
background: #f2f2f2DD;
color: #9e9e9e;
}
td.md-cell-center {
text-align: center;
}