json-to-html-table-with-lit について
Litを使うWeb開発者向けのチュートリアルです。URLまたはインラインのJSONからHTMLテーブルを生成し、セル編集、イベント通知、ヘッダーのカスタマイズを追加する方法を紹介します。
主な機能
- 01URLまたはインラインJSONから表を生成
- 02テーブルセルの編集
- 03イベントによるセルデータの取得
- 04JSONキーに応じたヘッダーセルの置換
- 05CSSカスタムプロパティによるスタイル設定
活用シーン
- 01WebページでのJSONデータ表示
- 02JSONテーブルへのセル編集機能の追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rodydavis/ skills --skill json-to-html-table-with-litインストール後、Claude Code で/json-to-html-table-with-litを入力して読み込まれたか確認します。
詳細
Lit を使用した JSON から HTML テーブルへの変換
この記事では、Lit の Web コンポーネントをセットアップし、それを使用して JSON の URL またはインライン JSON から HTML の テーブルを作成する方法を説明します。
前提条件
- Vscode
- Node >= 16
- Typescript
はじめに
まず、ターミナルでプロジェクトの場所に移動し、次のコマンドを実行します。
npm init @vitejs/app --template lit-ts
次に、プロジェクト名として lit-html-table を入力します。プロジェクトを vscode で開き、依存関係をインストールします。
cd lit-html-table
npm i lit
npm i -D @types/node
code .
vite.config.ts を次のように更新します。
import { defineConfig } from "vite";
import { resolve } from "path";
export default defineConfig({
base: "/lit-html-table/",
build: {
lib: {
entry: "src/lit-html-table.ts",
formats: ["es"],
},
rollupOptions: {
input: {
main: resolve(__dirname, "index.html"),
},
},
},
});
テンプレート
index.html を開き、次のように更新します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JSON to Lit HTML Table</title>
<script type="module" src="/src/lit-html-table.ts"></script>
</head>
<body>
<lit-html-table src="https://jsonplaceholder.typicode.com/posts">
</lit-html-table>
</body>
</html>
この例では Web コンポーネントに src 属性を渡していますが、application/json を type 属性に設定した script タグを追加し、その内容に JSON を記述することもできます。
テーブルのヘッダーセルを置き換える必要がある場合は、JSON オブジェクトのキーを slot 名に設定した要素を指定できます。
Web コンポーネント
コンポーネントを更新する前に、my-element.ts の名前を lit-html-table.ts に変更します。
lit-html-table.ts を開き、次のように更新します。
import { html, css, LitElement } from "lit";
import { customElement, property } from "lit/decorators.js";
type ObjectData = { [key: string]: any };
@customElement("lit-html-table")
export class LitHtmlTable extends LitElement {
@property() src = "";
data?: ObjectData[];
static styles = css`
tr {
text-align: var(--table-tr-text-align, left);
vertical-align: var(--table-tr-vertical-align, top);
padding: var(--table-tr-padding, 10px);
}
`;
render() {
// Check if data is loaded
if (!this.values) {
return html`<slot name="loading">Loading...</slot>`;
}
// Check if items are not empty
if (this.values.length === 0) {
return html`<slot name="empty">No Items Found!</slot>`;
}
// Convert JSON to HTML Table
return html`
<table>
<thead>
<tr>
${Object.keys(this.values[0]).map((key) => {
const name = key.replace(/\b([a-z])/g, (_, val) =>
val.toUpperCase()
);
return html`<th>
<slot name="${key}">${name}</slot>
</th>`;
})}
</tr>
</thead>
<tbody>
${this.values.map((item) => {
return html`
<tr>
${Object.values(item).map((row) => {
return html`<td>${row}</td>`;
})}
</tr>
`;
})}
</tbody>
</table>
`;
}
async firstUpdated() {
await this.fetchData();
}
// Download the latest json and update it locally
async fetchData() {
let _data: any;
if (this.src.length > 0) {
// If a src attribute is set prefer it over any slots
_data = await fetch(this.src).then((res) => res.json());
} else {
// If no src attribute is set then grab the inline json in the slot
const elem = this.parentElement?.querySelector(
'script[type="application/json"]'
) as HTMLScriptElement;
if (elem) _data = JSON.parse(elem.innerHTML);
}
this.values = this.transform(_data ?? []);
this.requestUpdate();
}
transform(data: any) {
return data;
}
}
テーブルセルのスタイル設定用にいくつかの CSS カスタムプロパティ を定義しましたが、ここにはさらに多くのプロパティを追加できます。
すべてがうまくいったら、npm run dev コマンドを実行します。次のように表示されます。
![]()
編集
すべてのセルの編集に対応するにはどうすればよいでしょうか。Lit と Web コンポーネントを使えば、HTML を変更せずに段階的に機能を拡張できます。
クラスの先頭に、次のブール型プロパティを追加します。
@property({ type: Boolean }) editable = false;
次に、render メソッドの tbody タグを更新します。
<tbody>
${this.values.map((item, index) => {
return html`
<tr>
${Object.entries(item).map((row) => {
return html`<td>
${this.editable
? html`<input
value="${row[1]}"
type="text"
@input=${(e: any) => {
const value = e.target.value;
const key = row[0];
const current = this.values![index];
current[key] = value;
this.values![index] = current;
this.requestUpdate();
this.dispatchEvent(
new CustomEvent("input-cell", {
detail: {
index: index,
data: current,
},
})
);
}}
/>`
: html`${row[1]}`}
</td>`;
})}
</tr>
`;
})}
</tbody>
editable が true かどうかを確認し、true の場合は、データを更新して input イベントをディスパッチするイベントリスナーを備えた入力欄を返します。
index.html に editable 属性を追加します。
<lit-html-table editable> ... </lit-html-table>
再読み込みすると、テーブルは次のように表示され、どのセルも編集できるようになります。
![]()
最新の値やセルの情報を取得するには、index.html の閉じる body タグの直前にイベントリスナーを追加します。
<script>
const elem = document.querySelector("lit-html-table");
elem.addEventListener(
"input-cell",
(e) => {
// Index and data for the individual cell
const { index, data } = e.detail;
// New array of json items
const values = elem.values;
},
false
);
</script>
値の型を確認して、色、数値、またはチェックボックスの入力欄を返すことで、さらに機能を拡張できます。
まとめ
Lit を使った開発について詳しく知りたい場合は、ドキュメントをこちらでご覧いただけます。Lit playground にもこちらに例があります。 この例のソースはこちらで確認できます。