💭
LWCでテーブルの行コンポーネントがうまく表示されなかったので、display:table-row;した
LWCでDatatableを作るには lightning-datatable
が利用できますが、HTML と Salesforce の Lightning Design System を使えばスクラッチでもそれっぽく作成する事ができます。簡単に出来るだろうと思って作ってみたら意外なところでハマったので、今回はトラブルシューティングな小ネタです。
行コンポーネントがうまく表示されない
サンプルとして CustomDatatable
という自作のデータテーブルから、行コンポーネントである Tr
を呼び出しています。テーブルで表示するデータは例のごとくサンプルデータのハードコードです。
customDatatable.html
<table class="slds-table slds-table_cell-buffer slds-table_bordered">
<thead>
<tr class="slds-line-height_reset">
<template for:each={headers} for:item="header">
<th key={header.key} scope="col">
<div class="slds-truncate">{header.label}</div>
</th>
</template>
</tr>
</thead>
<tbody>
<template for:each={records} for:item="record">
<c-tr key={record.id} class="slds-hint-parent" record={record}></c-tr>
</template>
</tbody>
</table>
customDatatable,js
import { LightningElement } from "lwc";
const headers = [
{ label: "氏名", key: "name" },
{ label: "生年月日", key: "birthdate" }
];
const records = [
{
id: "001",
name: "林恵美",
birthdate: "1980/01/01"
}
];
export default class CustomDatatable extends LightningElement {
headers = headers;
records = records;
}
そして、Tr
コンポーネントの実装はこちらです。CustomDatatable
から受け取ったrecord
を行として描画しています。
tr.html
<template>
<tr>
<th scope="row">
<div class="slds-truncate">{record.name}</div>
</th>
<td>
<div class="slds-truncate">{record.birthdate}</div>
</td>
</tr>
</template>
tr.js
import { LightningElement, api } from "lwc";
export default class Tr extends LightningElement {
@api record;
}
一見なんの問題も内容にみえます(少なくとも当時の私にはそう見えていました)が、このコンポーネントを実際に表示してみると表示が崩れています。
display:table-row;
で対応する
生成されたHTMLを確認すると分かりますが、tbody
とtr
の間に行コンポーネントであるc-tr
タグが入っているのでtable
の構造体ではなくなっているのが原因です。
対応策としてはc-tr
をtr
として認識させればいいので、まずtr.html
からtr
タグを削除します。
tr.html
<template>
<th scope="row">
<div class="slds-truncate">{record.name}</div>
</th>
<td>
<div class="slds-truncate">{record.birthdate}</div>
</td>
</template>
そして、c-tr
タグをtr
として認識させるために、tr.css
を作成して:host
セレクタにdisplay: table-row;
を追加します。
tr.css
:host {
display: table-row;
}
:host > th:first-child {
padding-left: var(--lwc-spacingLarge, 1.5rem);
}
(ちゃっかり左パディングも追加😏)
これで想定通り表示されるようになりました。
Discussion