@aiquants/spreadsheet 0.8.0
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 +1103 -0
- package/LICENSE.md +155 -0
- package/README.md +817 -0
- package/dist/index.cjs +21 -0
- package/dist/index.d.cts +1960 -0
- package/dist/index.d.ts +1960 -0
- package/dist/index.js +7711 -0
- package/dist/styles/spreadsheet.css +2 -0
- package/dist/styles/spreadsheet.standalone.css +3 -0
- package/package.json +94 -0
- package/src/Spreadsheet.tsx +2313 -0
- package/src/clipboard/clipPayload.ts +1242 -0
- package/src/clipboard/fixtures/excel.fixture.ts +301 -0
- package/src/clipboard/fixtures/html.fixture.ts +90 -0
- package/src/clipboard/fixtures/sheets.fixture.ts +83 -0
- package/src/clipboard/htmlInterop.ts +1694 -0
- package/src/clipboard/numberFormatCodec.ts +870 -0
- package/src/clipboard/pasteSpecial.ts +608 -0
- package/src/clipboard/tiling.ts +370 -0
- package/src/clipboard/tsv.ts +186 -0
- package/src/clipboard/useClipboard.ts +1154 -0
- package/src/commands/selfCalc.ts +279 -0
- package/src/commands/useCommands.ts +946 -0
- package/src/editor/useCellEditor.ts +708 -0
- package/src/grid/CellView.tsx +51 -0
- package/src/grid/GridBody.tsx +489 -0
- package/src/header/ColumnHeader.tsx +167 -0
- package/src/header/RowHeader.tsx +144 -0
- package/src/header/columnName.ts +31 -0
- package/src/header/resizeGates.ts +146 -0
- package/src/header/resizeStrips.ts +79 -0
- package/src/header/useHeaderResize.ts +598 -0
- package/src/header/useHeaderSelection.ts +454 -0
- package/src/index.ts +122 -0
- package/src/keyboard/compositionGuard.ts +53 -0
- package/src/keyboard/ensureCellVisible.ts +77 -0
- package/src/keyboard/shortcuts.ts +718 -0
- package/src/keyboard/useGridKeyboard.ts +940 -0
- package/src/model/axisModel.ts +186 -0
- package/src/model/cellAnnotations.ts +92 -0
- package/src/model/cellCoord.ts +114 -0
- package/src/model/cellFormat.ts +562 -0
- package/src/model/cellPaint.ts +537 -0
- package/src/model/conditionalFormat.ts +805 -0
- package/src/model/dataAdapter.ts +478 -0
- package/src/model/dataValidation.ts +542 -0
- package/src/model/formulaRefs.ts +984 -0
- package/src/model/frozenPartition.ts +100 -0
- package/src/model/labels.ts +228 -0
- package/src/model/viewStore.ts +124 -0
- package/src/overlay/SelectionOverlay.tsx +1425 -0
- package/src/overlay/useFillHandle.ts +432 -0
- package/src/popover/CommentPopover.tsx +109 -0
- package/src/popover/LinkPopover.tsx +108 -0
- package/src/popover/ListPopover.tsx +161 -0
- package/src/popover/MessagePopover.tsx +36 -0
- package/src/popover/NotePopover.tsx +106 -0
- package/src/popover/NoteTip.tsx +26 -0
- package/src/popover/PopoverLayer.tsx +210 -0
- package/src/popover/placement.ts +138 -0
- package/src/popover/usePopovers.ts +642 -0
- package/src/selection/selectionState.ts +239 -0
- package/src/selection/useAutoScroller.ts +226 -0
- package/src/selection/usePointDrag.ts +273 -0
- package/src/selection/useSelectionEngine.ts +687 -0
- package/src/styles/components.entry.css +10 -0
- package/src/styles/spreadsheet.css +1029 -0
- package/src/styles/standalone.entry.css +9 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Self-implemented nearest-visibility scroll (§6.6.3). scrollToCell has NO
|
|
3
|
+
* "no-op when visible" align (start/end/center only, and it pins anchors), so arrow-key
|
|
4
|
+
* navigation must use edge-delta scrollBy on BOTH axes to avoid per-keystroke snapping
|
|
5
|
+
* (§7-7 of the VirtualGrid design plan — scrollTo is the floor-and-pin jump API and is
|
|
6
|
+
* deliberately not used here).
|
|
7
|
+
*
|
|
8
|
+
* 自前 nearest 可視化スクロール (§6.6.3)。scrollToCell に「可視なら no-op」は存在しない
|
|
9
|
+
* (start/end/center のみ、かつアンカーを張る) ため、矢印ナビは両軸ともはみ出し分だけの
|
|
10
|
+
* scrollBy で自作する (設計計画 §7-7 — scrollTo は floor + アンカー張りのジャンプ API で不使用)。
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { VirtualGridHandle } from "@aiquants/virtualscroll"
|
|
14
|
+
import type { RefObject } from "react"
|
|
15
|
+
import type { AxisModel } from "../model/axisModel.ts"
|
|
16
|
+
import type { CellCoord } from "../model/cellCoord.ts"
|
|
17
|
+
|
|
18
|
+
/** Factory dependencies. / 構築時依存。 */
|
|
19
|
+
type EnsureCellVisibleDeps = {
|
|
20
|
+
handleRef: RefObject<VirtualGridHandle | null>
|
|
21
|
+
rowAxis: AxisModel
|
|
22
|
+
colAxis: AxisModel
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Builds the ensureCellVisible helper (constructed once in Spreadsheet, injected into
|
|
27
|
+
* keyboard / editor / Shift+F10 — §6.9-7 ownership). Both axes read the grid handle
|
|
28
|
+
* synchronously (the truth — §7-4) and land via edge-delta scrollBy.
|
|
29
|
+
* ensureCellVisible の構築 (Spreadsheet で 1 回構築し keyboard / editor / Shift+F10 へ配る)。
|
|
30
|
+
* 両軸ともグリッドハンドルの同期読み (§7-4 の真実) + 端差分 scrollBy で着地する。
|
|
31
|
+
*/
|
|
32
|
+
export const createEnsureCellVisible = ({ handleRef, rowAxis, colAxis }: EnsureCellVisibleDeps) => {
|
|
33
|
+
return (cell: CellCoord): void => {
|
|
34
|
+
const handle = handleRef.current
|
|
35
|
+
if (handle === null) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
// 位置と窓寸はハンドルから同期で読む (§7-4 の鮮度序列 — viewStore に位置は存在しない)。
|
|
39
|
+
// ペイン未接続の番兵 ({-1,-1}) と寸法 0 (未測定 / 不可視) では何もしない — 寸法 0 の
|
|
40
|
+
// ビューポートに「可視化」は定義できず、全打鍵が無意味な scrollBy を飛ばすため
|
|
41
|
+
const { x: hx, y: vy } = handle.getScrollPosition()
|
|
42
|
+
const { width: viewportW, height: viewportH } = handle.getViewportSize()
|
|
43
|
+
if (vy < 0 || hx < 0) {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
// 縦: 論理座標で可視域と比較し、はみ出しぶんだけ scrollBy (端差分 — §7-7)。
|
|
47
|
+
// 凍結行 (v0.6 計画 §3 — 横の凍結列 no-op と同文) は常時可視のため縦成分のみ no-op
|
|
48
|
+
// (横調整は下ブロックで続行 — 凍結行 × スクロール列のセルは横スクロールが要る)。
|
|
49
|
+
// スクロール行の上可視限界は木座標 H_F + vy (viewport 上端 y = H_F がスクロール帯の始まり)
|
|
50
|
+
if (viewportH > 0 && cell.row >= handle.getFrozenSize().rows) {
|
|
51
|
+
const frozenHeight = handle.getFrozenSize().height
|
|
52
|
+
const top = rowAxis.offsetOf(cell.row)
|
|
53
|
+
const bottom = top + rowAxis.sizeOf(cell.row)
|
|
54
|
+
if (top < frozenHeight + vy) {
|
|
55
|
+
handle.scrollBy({ y: top - (frozenHeight + vy) })
|
|
56
|
+
} else if (bottom > vy + viewportH) {
|
|
57
|
+
handle.scrollBy({ y: bottom - (vy + viewportH) })
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// 横: 同型の nearest 計算 → 端差分 scrollBy (クランプはハンドルが担う)。
|
|
61
|
+
// 凍結列 (v0.5 計画 §3-4) は常時可視のため no-op。スクロール列の左可視限界は木座標
|
|
62
|
+
// W_F + hx (viewport 左端 x = W_F がスクロール帯の始まり — エンジン §8-a)
|
|
63
|
+
if (viewportW > 0) {
|
|
64
|
+
const frozen = handle.getFrozenSize()
|
|
65
|
+
if (cell.col < frozen.cols) {
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
const left = colAxis.offsetOf(cell.col)
|
|
69
|
+
const right = left + colAxis.sizeOf(cell.col)
|
|
70
|
+
if (left < frozen.width + hx) {
|
|
71
|
+
handle.scrollBy({ x: left - (frozen.width + hx) })
|
|
72
|
+
} else if (right > hx + viewportW) {
|
|
73
|
+
handle.scrollBy({ x: right - (hx + viewportW) })
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|