@threestarsoftware/tssgrid 0.1.9 → 0.1.11
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/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/tssgrid.d.ts +12 -5
- package/src/tssgrid.js +29 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
TssGrid の各リリースの変更点。日付は JST。形式は [Keep a Changelog](https://keepachangelog.com/ja/1.1.0/) 準拠(ゆるめ)。
|
|
4
4
|
数値は特記なき限り**自社調べ**(headless Chrome / Windows 11・環境差あり)。
|
|
5
5
|
|
|
6
|
+
## [0.1.11] - 2026-09-16
|
|
7
|
+
|
|
8
|
+
### 修正
|
|
9
|
+
- **表全体版 `cellClass` / `cellStyle` / `rowClass` と `CellClassCtx` の `src`(元レコード)を `any` に**(型定義のみ・実行時は不変)— `src` は関数の**引数(反変位置)**なので `Record<string, any> | null` で固定すると、**自分で行の型を書いている利用者が関数を渡せず** `as unknown as MyRow` の二重キャストを強いられていた(0.1.9〜0.1.10 で該当)。`any` にすると利用側が `src: MyRow` と**そのまま注釈でき、関数内はその型で検査される**(今より安全側・既に `row: any[]` なので揃う)。d.ts 4か所(`CellClassCtx.src` / 表全体 `cellClass`・`cellStyle`・`rowClass`)+ api.html を更新。※将来の `TssGrid<Row>` ジェネリック化は 0.2 系で検討。
|
|
10
|
+
|
|
11
|
+
## [0.1.10] - 2026-09-16
|
|
12
|
+
|
|
13
|
+
### 追加
|
|
14
|
+
- **`scrollToRow(r, align?)`(指定行までスクロール=HTML の `#` アンカー相当)**(コア)— 任意の行を画面の**先頭へ**持ってくる公開メソッド。`align` は `'start'`(既定=先頭・sticky ヘッダ直下)/ `'center'` / `'end'` / `'nearest'`(可視ならそのまま)。**仮想(均一行高)でも非仮想(実DOM測定・可変行高)でも動く**。範囲外の `r` は自動クランプ。**選択は変えない**(目印が欲しい時は `rowClass` 等を併用)。動く例 `examples/scroll-to-row.html`(1000行・行番号ジャンプ+align 切替+rowClass ハイライト)。
|
|
15
|
+
|
|
6
16
|
## [0.1.9] - 2026-09-15
|
|
7
17
|
|
|
8
18
|
### 追加
|
package/README.md
CHANGED
|
@@ -918,7 +918,7 @@ new TssGrid(el, {
|
|
|
918
918
|
});
|
|
919
919
|
```
|
|
920
920
|
|
|
921
|
-
メソッド: `getData()` / `getRows()` / `getRow(r)` / `getColumn(cOrKey)` / `getColumns()` / `setData(rows)` / `appendRows(rows,opts?)`(**背景で"育てる"追記**=data末尾に足し可視窓だけ再描画。buildTable全再描画せずスクロール位置・選択・編集中エディタを保ち履歴にも積まない。「先頭ページを描く→残りをidleでappendRows」でfirst-paintを早める土台。既存経路は不変のopt-in) / `setRowCount(total)` + `fillRows(start,rows)`(**遅延ロード=on-demand**=virtual前提。総件数を確保し未取得ぶんは「読込中」行、`onViewportChange(start,end)` で要る範囲を受け `fillRows` で実データを流し込む。sort/filterは遅延中ローカル計算せず `onSortFilterChange` でサーバ委譲、未取得セルは編集不可、export(getData/toCSV)はロード済みのみ=AG Grid の Infinite Row Model 相当を push で) / `getValue(r,cOrKey)` / `setValue(r,cOrKey,val,force?)` / `setValueRaw(r,cOrKey,val)`(履歴に積まない派生値書き込み・計算列用) / `hideColumn(c)` / `showColumn(c)` / `toggleColumn(c)` / `isColumnHidden(c)` / `getHiddenColumns()` / `setAlignment(align,range?)` / `getAlignment(r,c)` / `setCellReadOnly(flag,range?)` / `autoSizeColumn(c)` / `autoSizeAllColumns()` / `sortBy(cOrKey, dir)` / `sortRows(cmp)` / `addShortcut(s)` / `removeShortcut(name)` / `usePlugin(fn)` / `getPlugin(name)` / `destroy()` / `setActive(r,c)` / `selectRow(r)` / `selectCol(c)` / `selectAll()` / `setColWidth(c,px)` / `setRowHeight(r,px)` / `freezeCols(n)` / `freezeRows(n)` / `moveRow(from,to)` / `moveRows(r0,r1,to)` / `clearSort()` / `toCSV(opts)` / `downloadCSV(name,opts)` / `insertRow(ri,'above'|'below')` / `insertRows(ri,count?,'above'|'below')`(count 行を1回の再描画・1 undo で一括挿入=大量挿入が O(N)) / `deleteRows(r0,r1?)` / `insertCol(ci,'left'|'right')` / `deleteCols(c0,c1?)` / `redraw()`(列定義変更後の再描画, データ・選択は保持)ほか。
|
|
921
|
+
メソッド: `getData()` / `getRows()` / `getRow(r)` / `getColumn(cOrKey)` / `getColumns()` / `setData(rows)` / `appendRows(rows,opts?)`(**背景で"育てる"追記**=data末尾に足し可視窓だけ再描画。buildTable全再描画せずスクロール位置・選択・編集中エディタを保ち履歴にも積まない。「先頭ページを描く→残りをidleでappendRows」でfirst-paintを早める土台。既存経路は不変のopt-in) / `setRowCount(total)` + `fillRows(start,rows)`(**遅延ロード=on-demand**=virtual前提。総件数を確保し未取得ぶんは「読込中」行、`onViewportChange(start,end)` で要る範囲を受け `fillRows` で実データを流し込む。sort/filterは遅延中ローカル計算せず `onSortFilterChange` でサーバ委譲、未取得セルは編集不可、export(getData/toCSV)はロード済みのみ=AG Grid の Infinite Row Model 相当を push で) / `getValue(r,cOrKey)` / `setValue(r,cOrKey,val,force?)` / `setValueRaw(r,cOrKey,val)`(履歴に積まない派生値書き込み・計算列用) / `hideColumn(c)` / `showColumn(c)` / `toggleColumn(c)` / `isColumnHidden(c)` / `getHiddenColumns()` / `setAlignment(align,range?)` / `getAlignment(r,c)` / `setCellReadOnly(flag,range?)` / `autoSizeColumn(c)` / `autoSizeAllColumns()` / `sortBy(cOrKey, dir)` / `sortRows(cmp)` / `addShortcut(s)` / `removeShortcut(name)` / `usePlugin(fn)` / `getPlugin(name)` / `destroy()` / `setActive(r,c)` / `scrollToRow(r, align?)`(**指定行までスクロール=HTML の `#` アンカー相当**。`align` は `'start'`〔既定=先頭・sticky ヘッダ直下〕/`'center'`/`'end'`/`'nearest'`〔可視ならそのまま〕。仮想・非仮想どちらでも動き、範囲外 `r` は自動クランプ。**選択は変えない**ので目印は `rowClass` 等を併用。例 `examples/scroll-to-row.html`) / `selectRow(r)` / `selectCol(c)` / `selectAll()` / `setColWidth(c,px)` / `setRowHeight(r,px)` / `freezeCols(n)` / `freezeRows(n)` / `moveRow(from,to)` / `moveRows(r0,r1,to)` / `clearSort()` / `toCSV(opts)` / `downloadCSV(name,opts)` / `insertRow(ri,'above'|'below')` / `insertRows(ri,count?,'above'|'below')`(count 行を1回の再描画・1 undo で一括挿入=大量挿入が O(N)) / `deleteRows(r0,r1?)` / `insertCol(ci,'left'|'right')` / `deleteCols(c0,c1?)` / `redraw()`(列定義変更後の再描画, データ・選択は保持)ほか。
|
|
922
922
|
|
|
923
923
|
## イベント
|
|
924
924
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@threestarsoftware/tssgrid",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "軽量・ノービルド・日本語IME堅牢な編集グリッド(vanilla JS / 依存なし / MIT)。Excel ライクな入力画面を <script> タグ1本で。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ThreeStarSoftware (https://www.threestarsoftware.co.jp/)",
|
package/src/tssgrid.d.ts
CHANGED
|
@@ -25,8 +25,9 @@ export interface ChangeItem {
|
|
|
25
25
|
/** 選択範囲。r0/c0=開始、r1/c1=終了(昇順とは限らない)。 */
|
|
26
26
|
export interface SelectionRange { r0: number; c0: number; r1: number; c1: number; }
|
|
27
27
|
export interface CellCoord { r: number; c: number; }
|
|
28
|
-
/** cellClass/cellStyle(列版)が受け取る第2引数。row=その行の値配列, src=元レコード(object モード時・非表示フィールドも見える/配列モードは null)。
|
|
29
|
-
|
|
28
|
+
/** cellClass/cellStyle(列版)が受け取る第2引数。row=その行の値配列, src=元レコード(object モード時・非表示フィールドも見える/配列モードは null)。
|
|
29
|
+
* src は `any`=利用側が自分の行型(`src: MyRow`)でそのまま受けられる(`Record<string,any>|null` だと二重キャストを強いるため)。 */
|
|
30
|
+
export interface CellClassCtx { r: number; c: number; row: any[]; src: any; }
|
|
30
31
|
/** cellClass/cellStyle の戻り値のクラス。文字列(空白区切り可)/配列/null 等(=クラス無し)。 */
|
|
31
32
|
export type ClassValue = string | string[] | null | undefined | false;
|
|
32
33
|
/** cellStyle の戻り値。CSS プロパティのオブジェクト(`{'background':'#fde','--pct':'42%'}`)か文字列(`'background:#fde;--pct:42%'`)。 */
|
|
@@ -114,12 +115,12 @@ export interface TssGridOptions {
|
|
|
114
115
|
columns?: ColumnDef[];
|
|
115
116
|
/** 表全体の条件付きクラス(全セルで呼ばれる)。**引数は `(r, c, value, row, src)`**(先頭が行/列番号・列版と順序が違う)。
|
|
116
117
|
* `row`=その行の値配列, `src`=元レコード(object モード時・非表示フィールドも見える)。行に色を付けたいなら `rowClass` の方が簡単。 */
|
|
117
|
-
cellClass?: (r: number, c: number, value: any, row: any[], src:
|
|
118
|
+
cellClass?: (r: number, c: number, value: any, row: any[], src: any) => ClassValue;
|
|
118
119
|
/** 表全体のセル単位インラインスタイル。**引数は `(r, c, value, row, src)`**。返り値は CSS オブジェクト or 文字列。 */
|
|
119
|
-
cellStyle?: (r: number, c: number, value: any, row: any[], src:
|
|
120
|
+
cellStyle?: (r: number, c: number, value: any, row: any[], src: any) => StyleValue;
|
|
120
121
|
/** 行ごとに `<tr>` へ付与する CSS クラス(**行に色を付けるならこれ**)。`(r, row, src)` で呼ばれ、文字列/配列を返す。
|
|
121
122
|
* 編集でセルが再描画されると即追従。CSS は `.tssgrid tr.クラス > td { … }` のように行単位で当てる。 */
|
|
122
|
-
rowClass?: (r: number, row: any[], src:
|
|
123
|
+
rowClass?: (r: number, row: any[], src: any) => ClassValue;
|
|
123
124
|
/** 検証NG時。'revert'=元に戻す / 'keep'=赤く警告して残す。 */
|
|
124
125
|
invalidMode?: 'revert' | 'keep';
|
|
125
126
|
invalidTitle?: boolean;
|
|
@@ -399,6 +400,12 @@ export declare class TssGrid {
|
|
|
399
400
|
selectRow(r: number): void;
|
|
400
401
|
selectCol(c: number): void;
|
|
401
402
|
selectAll(): void;
|
|
403
|
+
/**
|
|
404
|
+
* 指定行までスクロール(HTML の `#` アンカー相当・選択は変えない)。
|
|
405
|
+
* `align` は `'start'`(既定=その行を先頭=sticky ヘッダ直下へ)/ `'center'` / `'end'` / `'nearest'`(可視ならそのまま)。
|
|
406
|
+
* 仮想(均一行高)でも非仮想(可変行高・実DOM測定)でも動く。範囲外の `r` は自動でクランプ。
|
|
407
|
+
*/
|
|
408
|
+
scrollToRow(r: number, align?: 'start' | 'center' | 'end' | 'nearest'): void;
|
|
402
409
|
/** 選択中の列インデックス(Ctrl+ヘッダクリックの飛び飛び選択に対応・昇順)。列選択モードでなければ `[]`。 */
|
|
403
410
|
getSelectedColumns(): number[];
|
|
404
411
|
/** 選択中の行インデックス(Ctrl+行ヘッダクリックの飛び飛び選択に対応・昇順)。行選択モードでなければ `[]`。 */
|
package/src/tssgrid.js
CHANGED
|
@@ -1486,6 +1486,35 @@
|
|
|
1486
1486
|
if (st !== cur) this.wrap.scrollTop = st;
|
|
1487
1487
|
this._renderWindow(this._vWindow(), false); // 窓を即同期(place 前に DOM を確定)
|
|
1488
1488
|
}
|
|
1489
|
+
// 指定行までスクロール(HTML の # アンカー相当)。align: 'start'(既定=先頭へ)/'center'/'end'/'nearest'。
|
|
1490
|
+
// 仮想(均一行高)でも非仮想(実DOM・可変行高)でも動く。sticky ヘッダの下にちゃんと収める。
|
|
1491
|
+
scrollToRow(r, align = 'start') {
|
|
1492
|
+
if (!this.wrap || !this.ROWS) return;
|
|
1493
|
+
r = Math.max(0, Math.min(this.ROWS - 1, Math.trunc(r || 0)));
|
|
1494
|
+
if (align === 'nearest' && this.virtual) { this._vEnsureVisible(r); return; } // 最小移動は既存ロジックに委譲
|
|
1495
|
+
const head = this.colHeaders ? (this._theadH || 0) : 0;
|
|
1496
|
+
const viewH = this.wrap.clientHeight || 400;
|
|
1497
|
+
let top, rowH;
|
|
1498
|
+
if (this.virtual) {
|
|
1499
|
+
rowH = this.defRowH; top = r * rowH; // 均一行高: content-top(sticky thead 直下が基準)
|
|
1500
|
+
} else {
|
|
1501
|
+
const tr = this.table && this.table.querySelector('tbody tr[data-r="' + r + '"]');
|
|
1502
|
+
if (!tr) return;
|
|
1503
|
+
const t = tr.getBoundingClientRect(), w = this.wrap.getBoundingClientRect();
|
|
1504
|
+
rowH = t.height; top = t.top - w.top + this.wrap.scrollTop - head; // 実DOMから測る(可変行高対応)
|
|
1505
|
+
}
|
|
1506
|
+
let st = top; // start: 行を先頭(sticky thead 直下)へ
|
|
1507
|
+
if (align === 'center') st = top - Math.max(0, (viewH - head - rowH) / 2);
|
|
1508
|
+
else if (align === 'end') st = top - Math.max(0, viewH - head - rowH);
|
|
1509
|
+
else if (align === 'nearest') { // 非仮想の nearest: 既に可視なら動かさない
|
|
1510
|
+
const vt = top - this.wrap.scrollTop;
|
|
1511
|
+
if (vt >= 0 && vt + rowH <= viewH - head) return;
|
|
1512
|
+
if (vt > 0) st = top - (viewH - head - rowH); // 下にはみ出し→下端、上は top のまま
|
|
1513
|
+
}
|
|
1514
|
+
const max = this.wrap.scrollHeight - this.wrap.clientHeight;
|
|
1515
|
+
this.wrap.scrollTop = Math.max(0, Math.min(st, max));
|
|
1516
|
+
if (this.virtual) this._renderWindow(this._vWindow(), false); // 窓を即同期
|
|
1517
|
+
}
|
|
1489
1518
|
buildTable() {
|
|
1490
1519
|
if (this._renderPaused) { this._renderDirty = true; return; } // バッチ描画中は最後にまとめて1回(_withBatchedRender)
|
|
1491
1520
|
if (this._customEditor && this._customCancel) this._customCancel(); // 開いているカスタムエディタを閉じる(body直下ポップアップの取り残し防止・_commitActive と同じ扱い)
|