@threestarsoftware/tssgrid 0.1.0 → 0.1.1

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 CHANGED
@@ -3,6 +3,19 @@
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.1] - 2026-07-17
7
+
8
+ ### 変更(既定の挙動が変わります)
9
+ - **同梱プラグインの `inline` を既定 ON に**(`TssAutocomplete` / `TssCalendar` / `TssDatetime` / `TssTime`)— **旧挙動に戻すには `inline: false` を明示**してください。
10
+ - **理由**: 0.1.0 で `inline` を opt-in として出したが、既定 false +**プラグイン自身のドキュメント例に `inline` が無い**ため、**「`inline: true` と書いた人だけが直る」**状態だった。例をコピペした人には修正が届かず、出荷されたのは修正ではなく**フラグ**だった。
11
+ - **既定 false で実際に失われていたもの**(正確に言うと): IME が使えなくなるわけではない。クリック/F2 でポップアップを開けば、その中の自前 input は普通のフォーカス済み input なので**日本語は普通に打てる**。失われるのは **「セルにいきなり打ち始めて上書き」=打ち始めの経路**だけ(1文字目が捨てられる/IME 直打ちで編集に入れない)。
12
+ - **なぜそれが重いか**: それは TssGrid が他ライブラリの回避策を批判した時に挙げた代償そのもの(「セルにいきなり打ち込んで上書きができなくなる。表計算で一番よく使う操作なのに」)。**批判した妥協を自分の既定で出荷していた**ので、既定を反転する。
13
+ - **代償(日付系)**: 既定では**矢印キーを奪いません**=カレンダー内の日移動が既定で無くなります(セル移動のまま)。「キー派は打つ/マウス派はクリック」の割り切り。矢印で日を送りたい場合のみ `inline: false`。
14
+ - **自作カスタムエディタの `editor.inline` は既定 false のまま**(共有 input に乗るには実装側の合意が要るため。宣言しない限り挙動不変)。
15
+
16
+ ### 追加
17
+ - **日付/時刻ピッカーも `inline` 対応:`TssCalendar` / `TssDatetime` / `TssTime`**(プラグイン)— これらは**自前のテキスト入力を持たずポップアップにフォーカスする**型だったため、カスタムエディタとして付けると(`col.format`/`parse` 併用時は特に)**日付をそもそも打ち始められず、クリックで選ぶしかなかった**(=0.1.0 の `editor.inline` が解いた問題を、同梱の日付系も踏んでいた)。inline では本体の共有 input に乗り、**`6/20` のように直打ちでき(1文字目も落ちない)・IME 直打ちも効く**。ポップアップはフォーカスを奪わず"確認+クリック補助"に降りる。`TssCalendar` は打った内容に**追従してその月/日へジャンプ**(`onInput`+列の `parse` を解釈)。日をクリックで確定・Enter で打った値を確定・Esc で取消(本体既定)。
18
+
6
19
  ## [0.1.0] - 2026-07-17
7
20
 
8
21
  ### 追加
package/README.md CHANGED
@@ -387,7 +387,11 @@ new TssGrid(el, { columns: [{ editor: suggest }] });
387
387
  - `ctx` は通常の `{grid,r,c,value,td,commit,cancel}` に加えて **`input`(共有input)/ `setValue(v)`(候補で置換・確定はしない)/ `inline:true`** が入ります。
388
388
  - **確定は本体の `commit()`=関所を通る**ので `validator`/`parse`/`format`/読み取り専用/Undo はそのまま効きます。
389
389
  - ポップアップ側は **`mousedown` を `preventDefault`** してフォーカスを奪わないこと(共有 input に打ち続けられる)。
390
- - 対象は **text/number 系の列**(`dropdown`/`checkbox`/ネイティブ日付は従来どおり対象外)。**`inline` を書かない既存エディタの挙動は一切変わりません**(完全 opt-in)。
390
+ - 対象は **text/number 系の列**(`dropdown`/`checkbox`/ネイティブ日付は従来どおり対象外)。
391
+ - **自作エディタの `inline` は既定 false**(宣言しない限り挙動は一切変わりません)。共有 input に乗るには実装側の合意が要るためで、ここは opt-in が正しい既定です。
392
+ - **同梱プラグインの `inline` は既定 true**:`TssAutocomplete`(打ちながら候補を絞る)/`TssCalendar`・`TssDatetime`・`TssTime`(**日付/時刻をそのまま直打ち**できる。カレンダーは打った内容に追従してその日へジャンプ)。**何も書かずにコピペした人が、看板どおりの「打ち始めれば書ける」を得ます**。
393
+ - 日付系は **「キー派は打つ/マウス派はクリック」** の割り切り=**矢印キーは奪いません**(文字カーソル/セル移動のまま)。伝票入力のように「`6/20` と打つ方が速い」場面向け。
394
+ - `inline: false` で旧型(ポップアップにフォーカスし ←→↑↓ で日移動)に戻せます。ただし **セルにいきなり打ち始めて上書き**(表計算で一番よく使う操作)ができなくなる=クリック/F2 で開いてから打つことになります。矢印での日送りが要る場面だけ選んでください。
391
395
 
392
396
  ### 同梱プラグイン: 休日カレンダー対応の日付ピッカー
393
397
 
@@ -405,7 +409,9 @@ const cal = TssCalendar({
405
409
  });
406
410
  new TssGrid(el, { columns: [{ type: 'date', editor: cal, format: 'yyyy/mm/dd' }] });
407
411
  ```
408
- - セル右端に **📅** が出て**シングルクリックで開閉**(再クリックで閉じる=トグル)、開いている間も**フィルハンドルで下へコピー可**(ドロップダウンと同じ操作感)。**年・月はプルダウン**で直接ジャンプ。祝日は赤+**名称ツールチップ**、土日は色分け、キーボード操作(矢印/Enter/Esc/PageUp・Down)。保存値は ISO のまま。
412
+ - セル右端に **📅** が出て**シングルクリックで開閉**(再クリックで閉じる=トグル)、開いている間も**フィルハンドルで下へコピー可**(ドロップダウンと同じ操作感)。**年・月はプルダウン**で直接ジャンプ。祝日は赤+**名称ツールチップ**、土日は色分け。保存値は ISO のまま。
413
+ - **打つ人はそのまま打てます**(既定 `inline`): セルに `6/20` と打ち始めればそのまま編集開始(**1文字目も落ちない・IME 直打ちも効く**)、カレンダーは打った日へ追従。確定は Enter か日をクリック。**矢印はセル移動のまま**(カレンダーは奪いません)。
414
+ - 矢印/PageUp・Down でカレンダー内を移動する旧型が要るなら `inline: false`(→ [`editor.inline`](#editorinline-打鍵ime-直打ちを殺さないエディタサジェスト向け))。**セルに直接打ち始める操作は失われます**。
409
415
  - 見た目は CSS 変数(`--cal-accent` など)と `tss-cal-*` クラスで自由に(依存ゼロ)。グリッド外でも `cal.openAt(anchorEl, isoValue, onPick)` で単体利用可。
410
416
  - `opts`: `icon`(既定 `'📅'`, `''` で消す) / `openOnClick`(既定 true) / `yearMin`・`yearMax`(年プルダウンの範囲) も。
411
417
  - 仕組み: カスタムエディタが **`icon` / `openOnClick` を申告**すると、グリッドが右端アイコン表示+シングルクリック起動を行います(自作エディタでも同様に使えます)。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threestarsoftware/tssgrid",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "軽量・ノービルド・日本語IME堅牢な編集グリッド(vanilla JS / 依存なし / MIT)。Excel ライクな入力画面を <script> タグ1本で。",
5
5
  "license": "MIT",
6
6
  "author": "ThreeStarSoftware (https://www.threestarsoftware.co.jp/)",
@@ -9,9 +9,10 @@
9
9
  *
10
10
  * opts:
11
11
  * source : string[] か (query, ctx)=>string[]。必須。
12
- * inline : true=「セルに打ちながら絞る」型(既定 false)。本体の共有 input に乗る=**打鍵の1文字目も IME 直打ちも
13
- * 素のテキスト列と同じに効く**(自前 input を作らず focus も奪わない)。false は従来どおり
14
- * クリック/F2 でポップアップの自前 input を開く型(挙動不変)。
12
+ * inline : 「セルに打ちながら絞る」型(**既定 true**)。本体の共有 input に乗る=**打鍵の1文字目も IME 直打ちも
13
+ * 素のテキスト列と同じに効く**(自前 input を作らず focus も奪わない)。
14
+ * inline:false でポップアップの自前 input を開く旧型に戻せるが、**セルにいきなり打ち始めて上書き**が
15
+ * できなくなる(=クリック/F2 で開いてから打つ)。表計算で一番よく使う操作を捨てる選択なので非推奨。
15
16
  * strict : true=候補から選んだ値のみ許可(既定 false=自由入力可)。
16
17
  * minChars : この文字数以上で候補を出す(既定 0=開いた時点で全件)。
17
18
  * max : 候補表示の最大件数(既定 20)。
@@ -25,7 +26,7 @@
25
26
 
26
27
  function TssAutocomplete(opts) {
27
28
  opts = opts || {};
28
- var inline = !!opts.inline; // true=共有 input に乗る(打鍵/IME直打ちが効く)/false=従来の自前 input ポップアップ
29
+ var inline = opts.inline !== false; // true=共有 input に乗る(打鍵/IME直打ちが効く)/false=従来の自前 input ポップアップ
29
30
  var getSource = typeof opts.source === 'function' ? opts.source : function () { return opts.source || []; };
30
31
  var strict = !!opts.strict;
31
32
  var minChars = opts.minChars || 0;
@@ -2,6 +2,13 @@
2
2
  * 休日カレンダーを JSON で渡せる(勤怠・シフト等向け)。CSS は tss-calendar.css をクラス/変数で自由に。
3
3
  * 使い方(グリッド): columns: [{ type:'date', editor: TssCalendar({ holidays }) }]
4
4
  * 使い方(単体) : TssCalendar({holidays}).openAt(anchorEl, isoValue, onPick)
5
+ *
6
+ * opts.inline: 「キー派は打つ/マウス派はクリック」の型(**既定 true**)。
7
+ * 本体の共有 input に乗るので **日付をそのまま直打ちでき(1文字目も落ちない)・IME 直打ちも効く**。
8
+ * カレンダーはフォーカスを奪わず"確認+クリック補助"に降り、**矢印キーは奪わない**(=文字カーソル/セル移動のまま)。
9
+ * 打った内容に追従してカレンダーがその月/日へジャンプする。確定は Enter(打った値)or 日をクリック。
10
+ * inline:false で旧型(ポップアップにフォーカスし ←→↑↓ で日移動・Enter で選択)に戻せる。
11
+ * ただし **セルにいきなり打ち始めて上書き** ができなくなる(クリック/F2 で開いてから打つ)=矢印で日を送りたい時だけ。
5
12
  */
6
13
  (function (root) {
7
14
  'use strict';
@@ -26,6 +33,7 @@
26
33
  var yrLo = opts.yearMin || (minD ? minD.getFullYear() : ty - 12);
27
34
  var yrHi = opts.yearMax || (maxD ? maxD.getFullYear() : ty + 12);
28
35
  var pop = null, view = null, sel = null, focus = null, ref = null, done = false, outside = null;
36
+ var inline = opts.inline !== false; // true=共有 input に乗る(直打ち可・矢印は本体に返す)/false=従来のフォーカス奪取型
29
37
 
30
38
  function disabled(d) {
31
39
  if (minD && d < minD) return true;
@@ -110,6 +118,9 @@
110
118
  pop.addEventListener('keydown', onKey);
111
119
  render(); place(anchor);
112
120
  ref = { pick: onPick, cancel: onCancel };
121
+ // inline は「外側クリック/フォーカス」を本体(_commitActive / blur)が持つ=二重に閉じない・共有 input から
122
+ // フォーカスを奪わない(=打ち続けられる)。矢印/Enter/Esc も本体の既定に返す(onKey は pop 未フォーカスなので発火しない)。
123
+ if (inline) return;
113
124
  // 外側クリックで閉じる。ただしアンカー(開いた元セル)は除外=再クリックはグリッド側でトグル処理させる
114
125
  outside = function (e) { if (pop && !pop.contains(e.target) && !(anchor && anchor.contains && anchor.contains(e.target))) cancel(); };
115
126
  setTimeout(function () { document.addEventListener('mousedown', outside, true); }, 0);
@@ -125,6 +136,19 @@
125
136
  close: function () { teardown(); },
126
137
  icon: opts.icon != null ? opts.icon : '📅', // セル右端に表示する合図(opts.icon:'' で消せる)
127
138
  openOnClick: opts.openOnClick !== false, // シングルクリックで開く(既定 ON)
139
+ inline: inline, // true=共有 input に乗る(_usesTextEditor が見る)
140
+ // inline のみ: 打った内容にカレンダーが追従(列の parse があれば表示形→保存値に変換して解釈)。
141
+ // 矢印/Enter/Esc は本体に返す=onKeyDown は持たない(キー派は打つ・マウス派はクリック)。
142
+ onInput: inline ? function (v, ctx) {
143
+ if (!pop) return;
144
+ var d = null;
145
+ try {
146
+ var p = ctx.grid.colCfg(ctx.c).parse;
147
+ d = parseISO(typeof p === 'function' ? p(v, { r: ctx.r, c: ctx.c }) : v);
148
+ } catch (e) { d = null; }
149
+ if (!d) return; // 打ちかけ/不正はカレンダーを動かさない
150
+ sel = d; focus = new Date(d); view = new Date(d.getFullYear(), d.getMonth(), 1); render();
151
+ } : undefined,
128
152
  // 単体ウィジェット: 任意要素にアンカーして開く
129
153
  openAt: function (anchorEl, value, onPick) { show(anchorEl, value, function (v) { onPick(v); }, null); },
130
154
  };
@@ -3,6 +3,9 @@
3
3
  * 使い方(グリッド): columns: [{ type:'text', editor: TssDatetime({ step:5 }), format: TssDatetime.format }]
4
4
  * 使い方(単体) : TssDatetime({step:15}).openAt(anchorEl, 'YYYY-MM-DDTHH:MM', onPick)
5
5
  * opts: holidays / weekend / weekLabels / min / max(日付) / step(分刻み,既定1) / hour12 / icon(既定 '📅') / openOnClick(既定true) / className
6
+ * opts.inline: 既定 true=本体の共有 input に乗る(日時をそのまま直打ちでき・1文字目も落ちない・IME直打ちも効く/
7
+ * ピッカーはフォーカスを奪わずクリック補助に降りる)。inline:false で旧型(ピッカーにフォーカス)に戻せるが、
8
+ * **セルにいきなり打ち始めて上書き** ができなくなる(クリック/F2 で開いてから打つ)。
6
9
  */
7
10
  (function (root) {
8
11
  'use strict';
@@ -36,6 +39,7 @@
36
39
  var yrHi = opts.yearMax || (maxD ? maxD.getFullYear() : ty + 12);
37
40
 
38
41
  var pop = null, view = null, selD = null, selH = null, selM = null, ref = null, done = false, outside = null;
42
+ var inline = opts.inline !== false; // true=共有 input に乗る(直打ち可・矢印は本体に返す)/false=従来のフォーカス奪取型
39
43
 
40
44
  function dDisabled(d) { if (minD && d < minD) return true; if (maxD && d > maxD) return true; return false; }
41
45
 
@@ -152,6 +156,7 @@
152
156
  pop.addEventListener('keydown', onKey);
153
157
  render(); place(anchor);
154
158
  ref = { pick: onPick, cancel: onCancel };
159
+ if (inline) return; // inline は外側クリック/フォーカスを本体が持つ=共有 input から奪わない(打ち続けられる)
155
160
  outside = function (e) { if (pop && !pop.contains(e.target) && !(anchor && anchor.contains && anchor.contains(e.target))) commit(value()); }; // 外側クリックは確定(time と同方針)
156
161
  setTimeout(function () { document.addEventListener('mousedown', outside, true); }, 0);
157
162
  pop.focus();
@@ -165,6 +170,7 @@
165
170
  close: function () { teardown(); },
166
171
  icon: opts.icon != null ? opts.icon : '📅',
167
172
  openOnClick: opts.openOnClick !== false,
173
+ inline: inline, // true=共有 input に乗る=日時をそのまま直打ちできる(矢印/Enter/Esc は本体の既定)
168
174
  openAt: function (anchorEl, val, onPick) { show(anchorEl, val, function (v) { onPick(v); }, null); },
169
175
  };
170
176
  }
@@ -2,6 +2,9 @@
2
2
  * 時/分プルダウン方式(業務の任意時刻入力向き)。保存値は常に 24h 'HH:MM'(type:'time' と互換)。
3
3
  * 使い方(グリッド): columns: [{ type:'time', editor: TssTime({ step:15 }) }]
4
4
  * opts: step(分刻み,既定1) / hour12(AM/PM表示,既定false) / icon(既定 '🕐') / openOnClick(既定true) / className
5
+ * opts.inline: 既定 true=本体の共有 input に乗る(時刻をそのまま直打ちでき・1文字目も落ちない・IME直打ちも効く/
6
+ * ピッカーはフォーカスを奪わずクリック補助に降りる)。inline:false で旧型(ピッカーにフォーカス)に戻せるが、
7
+ * **セルにいきなり打ち始めて上書き** ができなくなる(クリック/F2 で開いてから打つ)。
5
8
  */
6
9
  (function (root) {
7
10
  'use strict';
@@ -13,6 +16,7 @@
13
16
  var step = Math.max(1, opts.step || 1);
14
17
  var hour12 = !!opts.hour12;
15
18
  var pop = null, ref = null, done = false, outside = null;
19
+ var inline = opts.inline !== false; // true=共有 input に乗る(直打ち可・矢印は本体に返す)/false=従来のフォーカス奪取型
16
20
 
17
21
  function opt(val, label, sel) { return '<option value="' + val + '"' + (sel ? ' selected' : '') + '>' + label + '</option>'; }
18
22
  function render(cur) {
@@ -70,6 +74,7 @@
70
74
  pop.addEventListener('keydown', onKey);
71
75
  render(parseHM(value)); place(anchor);
72
76
  ref = { pick: onPick, cancel: onCancel };
77
+ if (inline) return; // inline は外側クリック/フォーカスを本体が持つ=共有 input から奪わない(打ち続けられる)
73
78
  // 外側クリックは「確定」(時/分を選んで離す=採用)。未変更なら同値 commit=実質no-op。アンカーは除外(再クリックはグリッドがトグル)
74
79
  outside = function (e) { if (pop && !pop.contains(e.target) && !(anchor && anchor.contains && anchor.contains(e.target))) commit(readValue()); };
75
80
  setTimeout(function () { document.addEventListener('mousedown', outside, true); }, 0);
@@ -84,6 +89,7 @@
84
89
  close: function () { teardown(); },
85
90
  icon: opts.icon != null ? opts.icon : '🕐',
86
91
  openOnClick: opts.openOnClick !== false,
92
+ inline: inline, // true=共有 input に乗る=時刻をそのまま直打ちできる(矢印/Enter/Esc は本体の既定)
87
93
  openAt: function (anchorEl, value, onPick) { show(anchorEl, value, function (v) { onPick(v); }, null); },
88
94
  };
89
95
  }