@aiquants/spreadsheet 0.13.1 → 0.15.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 +38 -0
- package/README.md +53 -7
- package/dist/index.cjs +8 -15
- package/dist/index.d.cts +12 -11
- package/dist/index.d.ts +12 -11
- package/dist/index.js +1176 -1255
- package/dist/styles/spreadsheet.standalone.css +1 -1
- package/dist/tsv-B6TDExlk.js +91 -0
- package/dist/tsv-BHXbWK5W.cjs +8 -0
- package/dist/tsv.cjs +1 -0
- package/dist/tsv.d.cts +13 -0
- package/dist/tsv.d.ts +13 -0
- package/dist/tsv.js +5 -0
- package/dist/view.cjs +1 -0
- package/dist/view.d.cts +49 -0
- package/dist/view.d.ts +49 -0
- package/dist/view.js +14 -0
- package/package.json +31 -7
- package/src/Spreadsheet.tsx +20 -50
- package/src/grid/GridBody.tsx +7 -6
- package/src/header/ColumnHeader.tsx +10 -6
- package/src/header/RowHeader.tsx +4 -3
- package/src/model/labels.ts +23 -22
- package/src/model/viewStore.ts +1 -4
- package/src/overlay/SelectionOverlay.tsx +3 -3
- package/src/popover/placement.ts +4 -4
- package/src/styles/spreadsheet.css +1 -1
- package/src/tsv.ts +13 -0
- package/src/view.ts +62 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
|
|
2
2
|
/*! @aiquants/spreadsheet standalone CSS — 非 Tailwind ホスト専用。ホストの Tailwind ビルドと混在させないこと */
|
|
3
|
-
@layer theme,base;@layer components{@layer components{.aqvs-scroll-pane{display:flex;position:relative}.aqvs-scroll-pane[data-self-measured=true]{height:100%}.aqvs-scroll-pane-content{box-sizing:border-box;flex:1;height:100%;position:relative;overflow:hidden}.aqvs-tap-scroll-circle{touch-action:none;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;transition-property:transform;transition-duration:.1s;transition-timing-function:cubic-bezier(0,0,.2,1);display:flex;position:relative}.aqvs-tap-scroll-circle-visual-outer{border-radius:9999px;position:absolute;inset:0}.aqvs-tap-scroll-circle-gradient{background:linear-gradient(to bottom right,#1d4ed899,#60a5fa8c,#bfdbfe66);border:1px solid #fff6;border-radius:9999px;position:absolute;inset:0;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f}.aqvs-tap-scroll-circle-inner{border-radius:9999px;position:absolute;inset:18%}.aqvs-sample-visual-pupil{box-sizing:border-box;background-color:#ffffffd9;border:1px solid #ffffff80;border-radius:9999px;position:absolute;top:50%;left:50%}.aqvs-sample-visual-highlight{background-color:#fffc;border-radius:9999px;position:absolute;top:50%;left:50%}.aqvs-sample-visual-rod{background-color:#ffffff80;border-radius:9999px;position:absolute;top:50%;left:50%}.aqvs-scrollbar{z-index:50;cursor:default;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;touch-action:none;background-color:#fff;position:relative}.aqvs-scrollbar-horizontal{flex-direction:row;align-items:stretch;display:flex}.aqvs-scrollbar-vertical{flex-direction:column;align-items:stretch;display:flex}.aqvs-scrollbar[data-visible=false],.aqvs-scrollbar-thumb-wrapper[data-visible=false]{opacity:0;pointer-events:none}.aqvs-scrollbar-tap-circle-wrapper{pointer-events:auto;transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1);position:absolute}.aqvs-scrollbar-arrow-button{color:#313131;letter-spacing:normal;background-color:#e0e0e0;border:0 solid;justify-content:center;align-items:center;padding:0;font-family:system-ui,sans-serif;font-size:.75rem;font-weight:400;line-height:1rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:flex}.aqvs-scrollbar-arrow-button:focus{outline-offset:2px;outline:2px solid #0000}.aqvs-scrollbar-arrow-button:focus-visible{outline-offset:1px;outline:2px solid #60a5fa}.aqvs-scrollbar-arrow-button:disabled{cursor:not-allowed;opacity:.5}.aqvs-scrollbar-arrow-button:enabled:hover{background-color:#d4d4d4}.aqvs-scrollbar-track{background-color:#f5f5f5;flex:1;position:relative}.aqvs-scrollbar-overlay{pointer-events:none;position:absolute;inset:0}.aqvs-scrollbar-thumb-wrapper{touch-action:none;position:absolute}.aqvs-scrollbar-thumb{transform-origin:50%;background-color:#7f7f7f;transition:transform 80ms ease-out;position:absolute}.aqvs-scrollbar-thumb[data-thumb-state=disabled]{transition:none;transform:none}.aqvs-scrollbar-thumb[data-thumb-state=hover]{background-color:#5f5f5f}.aqvs-scrollbar-thumb[data-thumb-state=dragging]{background-color:#4f4f4f;transition:transform 60ms ease-out}.aqvs-scrollbar-thumb-horizontal{inset:1.5px 0}.aqvs-scrollbar-thumb-horizontal[data-thumb-state=hover]{top:-.5px;bottom:-.5px;transform:scaleY(1.06)}.aqvs-scrollbar-thumb-horizontal[data-thumb-state=dragging]{top:-.5px;bottom:-.5px;transform:scaleY(1.12)}.aqvs-scrollbar-thumb-vertical{inset:0 1.5px}.aqvs-scrollbar-thumb-vertical[data-thumb-state=hover]{left:-.5px;right:-.5px;transform:scaleX(1.06)}.aqvs-scrollbar-thumb-vertical[data-thumb-state=dragging]{left:-.5px;right:-.5px;transform:scaleX(1.12)}.aqvs-scroll-to-edge-button{pointer-events:auto;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;color:#fff;text-transform:uppercase;letter-spacing:.05em;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background-color:#1f2937cc;border:0 solid;border-radius:9999px;padding:.25rem 3rem;font-family:inherit;font-size:10px;font-weight:500;line-height:1.5;transition-property:transform,background-color;transition-duration:.15s;transform:none;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f}.aqvs-scroll-to-edge-button:focus{outline-offset:2px;outline:2px solid #0000}.aqvs-scroll-to-edge-button:focus-visible{outline-offset:1px;outline:2px solid #60a5fa}.aqvs-scroll-to-edge-button:hover{background-color:#374151}.aqvs-scroll-to-edge-button:active{transform:scale(.95)}.aqvs-scroll-to-edge-overlay{pointer-events:none;z-index:10;transition-property:opacity;transition-duration:.5s;position:absolute;inset:0}.aqvs-scroll-to-edge-overlay[data-visible=true]{opacity:1}.aqvs-scroll-to-edge-overlay[data-visible=false]{opacity:0}.aqvs-scroll-to-edge-overlay[data-visible=false] .aqvs-scroll-to-edge-button{pointer-events:none}.aqvs-scroll-to-edge-button-container{justify-content:center;display:flex;position:absolute;left:0;right:0}.aqvs-scroll-to-edge-button-container-top{top:.5rem}.aqvs-scroll-to-edge-button-container-bottom{bottom:.5rem}.aqvs-no-items-container{width:100%;position:absolute;top:0}.aqvs-no-items-text{text-align:center;color:#6b7280}.aqvs-item-container,.aqvs-bottom-inset,.aqvs-items-wrapper{width:100%;position:absolute}.aqvs-live-region{clip-path:inset(50%);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.aqvs-grid{grid-template-rows:minmax(0,1fr) auto;width:100%;height:100%;display:grid;position:relative;overflow:hidden}.aqvs-grid-has-frozen-rows{grid-template-rows:auto minmax(0,1fr) auto}.aqvs-grid-has-trailing-rows{grid-template-rows:minmax(0,1fr) auto auto}.aqvs-grid-has-frozen-rows.aqvs-grid-has-trailing-rows{grid-template-rows:auto minmax(0,1fr) auto auto}.aqvs-grid-frozen-rows{min-width:0;position:relative;overflow:hidden}.aqvs-grid-frozen-band-row{position:absolute;left:0;overflow:hidden}.aqvs-grid-trailing-rows{min-width:0;position:relative;overflow:hidden}.aqvs-grid-trailing-rows-inner{position:absolute;bottom:0;left:0;right:0}.aqvs-grid-trailing-band-row{position:absolute;left:0;overflow:hidden}.aqvs-grid-main{min-width:0;min-height:0;position:relative}.aqvs-grid-row{width:100%;height:100%;transform:translateX(var(--aqvs-grid-hx-residual,0px));position:relative;overflow:visible}.aqvs-grid-cell{height:100%;position:absolute;top:0;overflow:hidden}.aqvs-grid-row.aqvs-grid-row-frozen-host{transform:none}.aqvs-grid-row-scroll{height:100%;top:0;left:var(--aqvs-grid-frozen-width,0px);right:var(--aqvs-grid-trailing-width,0px);position:absolute;overflow:hidden}.aqvs-grid-row-scroll-inner{width:100%;height:100%;transform:translateX(calc(var(--aqvs-grid-hx-residual,0px) - var(--aqvs-grid-frozen-width,0px)));position:absolute;top:0;left:0}.aqvs-grid-row-trailing{height:100%;top:0;left:max(var(--aqvs-grid-frozen-width,0px), calc(100% - var(--aqvs-grid-trailing-width,0px)));position:absolute;right:0;overflow:hidden}.aqvs-grid-row-trailing-inner{height:100%;width:var(--aqvs-grid-trailing-width,0px);position:absolute;top:0;right:0}.aqvs-grid-hbar-strip{min-width:0;padding-left:var(--aqvs-grid-frozen-width,0px);position:relative}.aqvs-grid-live-region{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.aqvs-grid-tap-circle-wrapper{z-index:50;pointer-events:auto;position:absolute}.aqvs-grid-tap-circle{transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}@media (forced-colors:active){.aqvs-tap-scroll-circle{outline-offset:-1px;border-radius:50%;outline:1px solid canvastext}}}.aqsp-root,.aqsp-root *,.aqsp-root :before,.aqsp-root :after{box-sizing:border-box}.aqsp-root{--aqsp-row-header-width:64px;--aqsp-col-header-height:24px;--aqsp-band-row:#0084ff;--aqsp-band-column:#42ff4f;--aqsp-band-intersection:#e1ff00;--aqsp-band-opacity:.2;color:#1f2937;background:#fff;width:100%;height:100%;font-size:13px;line-height:1;position:relative;overflow:hidden}.aqsp-zoom{grid-template-columns:var(--aqsp-row-header-width) minmax(0, 1fr);grid-template-rows:var(--aqsp-col-header-height) minmax(0, 1fr);transform-origin:0 0;width:100%;height:100%;display:grid}.aqsp-corner{background:#f3f4f6;border-bottom:1px solid #d1d5db;border-right:1px solid #d1d5db;grid-area:1/1}.aqsp-col-header{-webkit-user-select:none;user-select:none;background:#f3f4f6;border-bottom:1px solid #d1d5db;grid-area:1/2;position:relative;overflow:hidden}.aqsp-col-header-scroll{height:100%;position:absolute;top:0;right:0;overflow:hidden}.aqsp-row-header-scroll{width:100%;position:absolute;bottom:0;left:0;overflow:hidden}.aqsp-col-header-track{will-change:transform;position:absolute;inset:0}.aqsp-col-header-cell{white-space:nowrap;color:#4b5563;border-right:1px solid #e5e7eb;justify-content:center;align-items:center;height:100%;display:flex;position:absolute;top:0;overflow:hidden}.aqsp-row-header{-webkit-user-select:none;user-select:none;background:#f3f4f6;border-right:1px solid #d1d5db;grid-area:2/1;position:relative;overflow:hidden}.aqsp-row-header-track{will-change:transform;position:absolute;top:0;left:0;right:0}.aqsp-row-header-cell{white-space:nowrap;color:#4b5563;font-variant-numeric:tabular-nums;border-bottom:1px solid #e5e7eb;justify-content:flex-end;align-items:center;padding-right:6px;display:flex;position:absolute;left:0;right:0;overflow:hidden}.aqsp-body{position:absolute;inset:0}.aqsp-row{cursor:default}.aqsp-cell{white-space:nowrap;background:#fff;border-bottom:1px solid #e5e7eb;border-right:1px solid #e5e7eb;align-items:center;padding:0 4px;display:flex}.aqsp-cell[data-aqsp-valign=top]{align-items:flex-start}.aqsp-cell[data-aqsp-valign=bottom]{align-items:flex-end}.aqsp-cell[data-aqsp-wrap]{white-space:pre-wrap;overflow-wrap:anywhere}.aqsp-cell[data-aqsp-note]:after,.aqsp-cell[data-aqsp-comment]:after{content:"";pointer-events:none;border:5px solid #4b5563;border-color:#4b5563 #4b5563 #0000 #0000;width:0;height:0;position:absolute;top:0;right:0}.aqsp-cell[data-aqsp-comment]:after{border-top-color:#f97316;border-right-color:#f97316}.aqsp-cell[data-aqsp-invalid]:before{content:"";pointer-events:none;border:5px solid #0000;border-color:#0000 #0000 #dc2626 #dc2626;width:0;height:0;position:absolute;bottom:0;left:0}.aqsp-cell[data-aqsp-link]{color:#1d4ed8;text-decoration:underline}.aqsp-body-stack{grid-area:2/2;position:relative}.aqsp-overlay{pointer-events:none;position:absolute;inset:0;overflow:hidden}.aqsp-overlay-quad{pointer-events:none;position:absolute;overflow:hidden}.aqsp-selection-fill{mix-blend-mode:multiply;background:#3b82f62e;border:1px solid #2563ebd9;position:absolute;top:0;left:0}.aqsp-active-frame{box-sizing:border-box;border:2px solid #2563eb;position:absolute;top:0;left:0}.aqsp-drag-rect{background:#3b82f61a;border:1px solid #2563eb;position:absolute;top:0;left:0}.aqsp-drag-rect[data-aqsp-drag-mode=subtract]{background:#dc262614;border:1px dashed #dc2626}.aqsp-drag-rect[data-aqsp-drag-mode=point]{background:#16a34a14;border:1px dashed #16a34a}.aqsp-band{opacity:var(--aqsp-band-opacity);pointer-events:none;position:absolute;top:0;left:0}.aqsp-band[data-aqsp-band=row]{background:var(--aqsp-band-row)}.aqsp-band[data-aqsp-band=column]{background:var(--aqsp-band-column)}.aqsp-band[data-aqsp-band=intersection]{background:var(--aqsp-band-intersection)}.aqsp-clip-marquee{position:absolute;top:0;left:0}.aqsp-clip-marquee:after{content:"";top:var(--aqsp-clip-outset-top,-3px);right:var(--aqsp-clip-outset-right,-3px);bottom:var(--aqsp-clip-outset-bottom,-3px);left:var(--aqsp-clip-outset-left,-3px);background-image:linear-gradient(90deg,#2563eb 50%,#fff 50%),linear-gradient(90deg,#2563eb 50%,#fff 50%),linear-gradient(#fff 50%,#2563eb 50%),linear-gradient(#fff 50%,#2563eb 50%);background-position:0 0,8px 100%,0 8px,100% 0;background-repeat:repeat-x,repeat-x,repeat-y,repeat-y;background-size:8px 2px,8px 2px,2px 8px,2px 8px;animation:.4s linear infinite aqsp-marching-ants;position:absolute}@keyframes aqsp-marching-ants{to{background-position:8px 0,0 100%,0 0,100% 8px}}@media (prefers-reduced-motion:reduce){.aqsp-clip-marquee:after{animation:none}}.aqsp-col-resize-strip{cursor:col-resize;height:100%;position:absolute;top:0}.aqsp-row-resize-strip{cursor:row-resize;position:absolute;left:0;right:0}.aqsp-col-header .aqsp-unhide-marker{cursor:col-resize;opacity:.7;background:repeating-linear-gradient(90deg,#2563eb 0 1px,#0000 1px 3px);height:100%;position:absolute;top:0}.aqsp-row-header .aqsp-unhide-marker{cursor:row-resize;opacity:.7;background:repeating-linear-gradient(#2563eb 0 1px,#0000 1px 3px);position:absolute;left:0;right:0}.aqsp-resize-guide{pointer-events:none;background:#2563eb;position:absolute;top:0;left:0}.aqsp-autofill-handle{box-sizing:content-box;pointer-events:auto;cursor:crosshair;background:#2563eb;border:1px solid #fff;width:6px;height:6px;position:absolute;top:0;left:0}.aqsp-autofill-preview{border:1px dashed #16a34a;position:absolute;top:0;left:0}@media (forced-colors:active){.aqsp-band{outline-offset:-2px;background:0 0;outline:2px solid highlight}.aqsp-cell[data-aqsp-note]:after,.aqsp-cell[data-aqsp-comment]:after,.aqsp-cell[data-aqsp-invalid]:before{border:1px solid canvastext;width:6px;height:6px}.aqsp-drag-rect[data-aqsp-drag-mode=point]{background:0 0;border-color:highlight}.aqsp-selection-fill{outline-offset:-2px;background:0 0;border:none;outline:2px solid highlight}.aqsp-clip-marquee:after{background-image:none;border:2px dashed highlight;animation:none}}.aqsp-col-header-cell[data-aqsp-in-selection],.aqsp-row-header-cell[data-aqsp-in-selection]{color:#1d4ed8;background:#dbeafe;font-weight:600}.aqsp-live-region{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.aqsp-sink{opacity:0;resize:none;pointer-events:auto;cursor:default;border:0;width:1px;height:1px;padding:0;position:absolute}.aqsp-sink[data-aqsp-editing]{opacity:1;z-index:1;box-sizing:border-box;color:#1f2937;caret-color:#1f2937;white-space:pre;outline-offset:-2px;cursor:text;background:#fff;outline:2px solid #2563eb;padding:0 4px;font-family:inherit;font-size:13px;line-height:1;overflow:hidden}.aqsp-sink[data-aqsp-pointing]{caret-color:#16a34a}.aqsp-popover-layer{pointer-events:none;position:absolute;inset:0;overflow:visible}.aqsp-popover-anchor{pointer-events:none;position:absolute;top:0;left:0}.aqsp-popover-anchor[inert]{visibility:hidden}.aqsp-popover{color:#1f2937;text-align:start;white-space:normal;cursor:default;pointer-events:auto;background:#fff;border:1px solid #d1d5db;border-radius:8px;flex-direction:column;width:320px;max-width:320px;font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Noto Sans JP,sans-serif;font-size:13px;line-height:1.4;display:flex;position:absolute;overflow:hidden;box-shadow:0 1px 2px #00000014,0 8px 24px #00000024}.aqsp-popover:focus-visible{outline-offset:-2px;outline:2px solid #2563eb}.aqsp-popover[data-aqsp-popover-frame=note-tip]{background:#fffbeb;border-color:#f59e0b;box-shadow:0 2px 8px #0000001f}.aqsp-popover-note,.aqsp-popover-comment,.aqsp-popover-link,.aqsp-popover-message{flex-direction:column;min-height:0;padding:10px 12px;display:flex}.aqsp-popover-list{flex-direction:column;min-height:0;padding:6px;display:flex}.aqsp-popover-note-tip{overscroll-behavior:contain;white-space:pre-wrap;overflow-wrap:anywhere;min-height:0;padding:8px 10px;overflow-y:auto}[data-aqsp-popover][data-aqsp-popover-rejected]{border-inline-start:3px solid #dc2626;padding-inline-start:9px}.aqsp-popover-title{color:#374151;align-items:baseline;gap:6px;margin:0 0 6px;font-size:12px;font-weight:600;display:flex}.aqsp-popover-count{color:#6b7280;font-weight:400}.aqsp-popover-textarea,.aqsp-popover-input{width:100%;color:inherit;font:inherit;background:#fff;border:1px solid #d1d5db;border-radius:6px;margin:0;padding:5px 8px;line-height:1.4;display:block}.aqsp-popover-textarea{resize:none;white-space:pre-wrap;flex:auto;height:104px;min-height:56px;overflow:auto}.aqsp-popover-comment .aqsp-popover-textarea{flex:none;height:64px}.aqsp-popover-input{flex:none;height:28px}.aqsp-popover-textarea:focus-visible,.aqsp-popover-input:focus-visible{outline-offset:-1px;border-color:#2563eb;outline:2px solid #2563eb}.aqsp-popover-textarea[aria-invalid=true],.aqsp-popover-input[aria-invalid=true]{border-color:#dc2626}.aqsp-popover-textarea[aria-invalid=true]:focus-visible,.aqsp-popover-input[aria-invalid=true]:focus-visible{border-color:#dc2626;outline-color:#dc2626}.aqsp-popover-hint{color:#6b7280;margin:4px 0 0;font-size:12px}[data-aqsp-popover-rejected] .aqsp-popover-hint{color:#b91c1c}.aqsp-popover-field{flex-direction:column;flex:none;gap:3px;margin:0 0 8px;display:flex}.aqsp-popover-field-label{color:#6b7280;font-size:12px}.aqsp-popover-actions{flex:none;align-items:center;gap:6px;margin-top:8px;display:flex}.aqsp-popover-button{color:#1f2937;min-width:56px;height:26px;font:inherit;cursor:pointer;background:#f9fafb;border:1px solid #d1d5db;border-radius:6px;justify-content:center;align-items:center;margin:0;padding:0 10px;font-size:12px;font-weight:500;line-height:1;display:inline-flex}.aqsp-popover-button:not(:disabled):hover{background:#f3f4f6;border-color:#9ca3af}.aqsp-popover-button:focus-visible{outline-offset:1px;outline:2px solid #2563eb}.aqsp-popover-button:disabled{opacity:.5;cursor:not-allowed}.aqsp-popover-button[data-aqsp-popover-save],.aqsp-popover-button[data-aqsp-popover-post]{color:#fff;background:#2563eb;border-color:#2563eb}.aqsp-popover-button[data-aqsp-popover-save]:not(:disabled):hover,.aqsp-popover-button[data-aqsp-popover-post]:not(:disabled):hover{background:#1d4ed8;border-color:#1d4ed8}.aqsp-popover-button[data-aqsp-popover-close]{color:#6b7280;background:0 0;border-color:#0000;width:26px;min-width:0;margin-inline-start:auto;padding:0;font-size:16px;font-weight:400}.aqsp-popover-button[data-aqsp-popover-close]:not(:disabled):hover{color:#1f2937;background:#f3f4f6;border-color:#0000}.aqsp-popover-thread{overscroll-behavior:contain;flex:auto;min-height:48px;max-height:220px;margin:0 0 8px;padding:0;list-style:none;overflow-y:auto}.aqsp-popover-comment-item{border-top:1px solid #f3f4f6;padding:6px 0}.aqsp-popover-comment-item:first-child{border-top:0;padding-top:0}.aqsp-popover-comment-author{color:#111827;font-size:12px;font-weight:600}.aqsp-popover-comment-time{color:#6b7280;font-variant-numeric:tabular-nums;margin-inline-start:6px;font-size:11px}.aqsp-popover-comment-text{white-space:pre-wrap;overflow-wrap:anywhere;margin:2px 0 0}.aqsp-popover-list .aqsp-popover-input{margin-bottom:4px}.aqsp-popover-options{overscroll-behavior:contain;flex:auto;min-height:0;max-height:240px;overflow-y:auto}.aqsp-popover-option{white-space:nowrap;text-overflow:ellipsis;cursor:pointer;border-radius:4px;padding:5px 8px;overflow:hidden}.aqsp-popover-option:hover{background:#f3f4f6}.aqsp-popover-option[aria-selected=true]{color:#1e3a8a;background:#dbeafe}.aqsp-popover-option:focus-visible{outline-offset:-2px;outline:2px solid #2563eb}.aqsp-popover-empty{color:#6b7280;padding:6px 8px;font-size:12px}.aqsp-popover-message{padding-inline-end:40px;position:relative}.aqsp-popover-message .aqsp-popover-title{margin-bottom:2px}.aqsp-popover-message-text{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.aqsp-popover-message .aqsp-popover-button[data-aqsp-popover-close]{position:absolute;inset-block-start:6px;inset-inline-end:6px}.aqsp-popover-message[data-aqsp-popover-rejected]{background:#fef2f2}.aqsp-popover-message[data-aqsp-popover-rejected] .aqsp-popover-title{color:#b91c1c}@media (forced-colors:active){.aqsp-popover-option:hover,.aqsp-popover-option[aria-selected=true]{outline-offset:-2px;outline:2px solid highlight}.aqsp-popover-textarea[aria-invalid=true],.aqsp-popover-input[aria-invalid=true]{border-style:dashed}.aqsp-popover-button[data-aqsp-popover-close]{border-color:buttontext}}[data-aqsp-empty]{width:100%;height:100%;display:block}.aqsp-freeze-divider{background:var(--aqsp-divider-color,#9ca3af);pointer-events:none;position:absolute}.aqsp-freeze-divider-v{width:var(--aqsp-divider-width,2px)}.aqsp-freeze-divider-h{height:var(--aqsp-divider-width,2px)}@media (forced-colors:active){.aqsp-freeze-divider{background:canvastext}}}@layer utilities;
|
|
3
|
+
@layer theme,base;@layer components{@layer components{.aqvs-scroll-pane{display:flex;position:relative}.aqvs-scroll-pane[data-self-measured=true],.aqvs-scroll-pane[data-aqvs-stretched-viewport=true]{height:100%}.aqvs-scroll-pane-content{box-sizing:border-box;flex:1;height:100%;position:relative;overflow:hidden}.aqvs-scroll-pane-content-overlay{box-sizing:border-box;padding:inherit;pointer-events:none;position:absolute;inset:0}.aqvs-scroll-pane-content-overlay-box{height:100%;position:relative;overflow:hidden}.aqvs-tap-scroll-circle{touch-action:none;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;transition-property:transform;transition-duration:.1s;transition-timing-function:cubic-bezier(0,0,.2,1);display:flex;position:relative}.aqvs-tap-scroll-circle-visual-outer{border-radius:9999px;position:absolute;inset:0}.aqvs-tap-scroll-circle-gradient{background:linear-gradient(to bottom right,#1d4ed899,#60a5fa8c,#bfdbfe66);border:1px solid #fff6;border-radius:9999px;position:absolute;inset:0;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f}.aqvs-tap-scroll-circle-inner{border-radius:9999px;position:absolute;inset:18%}.aqvs-sample-visual-pupil{box-sizing:border-box;background-color:#ffffffd9;border:1px solid #ffffff80;border-radius:9999px;position:absolute;top:50%;left:50%}.aqvs-sample-visual-highlight{background-color:#fffc;border-radius:9999px;position:absolute;top:50%;left:50%}.aqvs-sample-visual-rod{background-color:#ffffff80;border-radius:9999px;position:absolute;top:50%;left:50%}.aqvs-scrollbar{z-index:50;cursor:default;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;touch-action:none;background-color:#fff;position:relative}.aqvs-scrollbar-horizontal{flex-direction:row;align-items:stretch;display:flex}.aqvs-scrollbar-vertical{flex-direction:column;align-items:stretch;display:flex}.aqvs-scrollbar[data-visible=false],.aqvs-scrollbar-thumb-wrapper[data-visible=false]{opacity:0;pointer-events:none}.aqvs-scrollbar-track:focus-visible,.aqvs-scroll-pane-content:focus-visible{outline:none}.aqvs-scrollbar-track:focus-visible:after,.aqvs-scroll-pane-content:focus-visible:not([data-aqvs-active-item=visible]):after{content:"";outline:2px solid var(--aqvs-focus-ring-color,#2563eb);outline-offset:-2px;pointer-events:none;position:absolute;inset:0}.aqvs-scrollbar-tap-circle-wrapper{pointer-events:auto;transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1);position:absolute}.aqvs-scrollbar-arrow-button{color:#313131;background-color:#e0e0e0;border:0 solid;justify-content:center;align-items:center;padding:0;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:flex}.aqvs-scrollbar-arrow-button:focus{outline-offset:2px;outline:2px solid #0000}.aqvs-scrollbar-arrow-button:disabled{cursor:not-allowed;opacity:.5}.aqvs-scrollbar-arrow-button:enabled:hover{background-color:#d4d4d4}.aqvs-scrollbar-arrow-button:enabled:focus-visible{color:#fff;background-color:#2563eb;outline:none}.aqvs-scrollbar-track{background-color:#f5f5f5;flex:1;position:relative}.aqvs-scrollbar-overlay{pointer-events:none;position:absolute;inset:0}.aqvs-scrollbar-thumb-wrapper{touch-action:none;position:absolute}.aqvs-scrollbar-thumb{transform-origin:50%;background-color:#7f7f7f;transition:transform 80ms ease-out;position:absolute}.aqvs-scrollbar-thumb[data-thumb-state=disabled]{transition:none;transform:none}.aqvs-scrollbar-thumb[data-thumb-state=hover]{background-color:#5f5f5f}.aqvs-scrollbar-thumb[data-thumb-state=dragging]{background-color:#4f4f4f;transition:transform 60ms ease-out}.aqvs-scrollbar-thumb-horizontal{inset:1.5px 0}.aqvs-scrollbar-thumb-horizontal[data-thumb-state=hover]{top:-.5px;bottom:-.5px;transform:scaleY(1.06)}.aqvs-scrollbar-thumb-horizontal[data-thumb-state=dragging]{top:-.5px;bottom:-.5px;transform:scaleY(1.12)}.aqvs-scrollbar-thumb-vertical{inset:0 1.5px}.aqvs-scrollbar-thumb-vertical[data-thumb-state=hover]{left:-.5px;right:-.5px;transform:scaleX(1.06)}.aqvs-scrollbar-thumb-vertical[data-thumb-state=dragging]{left:-.5px;right:-.5px;transform:scaleX(1.12)}.aqvs-scroll-to-edge-button{isolation:isolate;pointer-events:auto;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;box-sizing:border-box;min-width:44px;min-height:44px;font-family:inherit;font-weight:500;font-size:var(--aqvs-font-size-body,.8125rem);line-height:var(--aqvs-line-height-body,1.25rem);color:#fff;text-transform:uppercase;letter-spacing:.05em;background-color:#0000;border:0 solid;justify-content:center;align-items:center;padding:12px 3rem;display:inline-flex;position:relative;transform:none}.aqvs-scroll-to-edge-button:before{content:"";z-index:-1;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background-color:#1f2937cc;border-radius:9999px;transition-property:transform,background-color;transition-duration:.15s;position:absolute;inset:8px 0;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f}.aqvs-scroll-to-edge-button:focus{outline-offset:2px;outline:2px solid #0000}.aqvs-scroll-to-edge-button:focus-visible{outline:none}.aqvs-scroll-to-edge-button:focus-visible:before{outline:2px solid var(--aqvs-focus-ring-color,#2563eb);outline-offset:1px}.aqvs-scroll-to-edge-button:hover:before{background-color:#374151}.aqvs-scroll-to-edge-button:active:before{transform:scale(.95)}.aqvs-scroll-to-edge-overlay{pointer-events:none;z-index:10;transition-property:opacity;transition-duration:.5s;position:absolute;inset:0}.aqvs-scroll-to-edge-overlay[data-visible=true]{opacity:1}.aqvs-scroll-to-edge-overlay[data-visible=false]{opacity:0}.aqvs-scroll-to-edge-overlay[data-visible=false] .aqvs-scroll-to-edge-button{pointer-events:none}.aqvs-scroll-to-edge-button-container{justify-content:center;display:flex;position:absolute;left:0;right:0}.aqvs-scroll-to-edge-button-container-top{top:0}.aqvs-scroll-to-edge-button-container-bottom{bottom:0}.aqvs-no-items-container{width:100%;position:absolute;top:0}.aqvs-no-items-text{text-align:center;color:#6b7280}.aqvs-item-container,.aqvs-bottom-inset{width:100%;position:absolute}.aqvs-items-boundary{contain:size layout style;height:0;position:absolute;top:0;left:0;right:0}.aqvs-items-wrapper{width:100%;position:absolute}.aqvs-live-region{clip-path:inset(50%);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.aqvs-grid{grid-template-rows:minmax(0,1fr) auto;width:100%;height:100%;display:grid;position:relative;overflow:hidden}.aqvs-grid-has-frozen-rows{grid-template-rows:auto minmax(0,1fr) auto}.aqvs-grid-has-trailing-rows{grid-template-rows:minmax(0,1fr) auto auto}.aqvs-grid-has-frozen-rows.aqvs-grid-has-trailing-rows{grid-template-rows:auto minmax(0,1fr) auto auto}.aqvs-grid-frozen-rows{min-width:0;position:relative;overflow:hidden}.aqvs-grid-frozen-band-row{position:absolute;left:0;overflow:hidden}.aqvs-grid-trailing-rows{min-width:0;position:relative;overflow:hidden}.aqvs-grid-trailing-rows-inner{position:absolute;bottom:0;left:0;right:0}.aqvs-grid-trailing-band-row{position:absolute;left:0;overflow:hidden}.aqvs-grid-main{min-width:0;min-height:0;position:relative}.aqvs-grid-row{width:100%;height:100%;transform:translateX(var(--aqvs-grid-hx-residual,0px));position:relative;overflow:visible}.aqvs-grid-cell{height:100%;position:absolute;top:0;overflow:hidden}.aqvs-grid-row.aqvs-grid-row-frozen-host{transform:none}.aqvs-grid-row-scroll{height:100%;top:0;left:var(--aqvs-grid-frozen-width,0px);right:var(--aqvs-grid-trailing-width,0px);position:absolute;overflow:hidden}.aqvs-grid-row-scroll-inner{width:100%;height:100%;transform:translateX(calc(var(--aqvs-grid-hx-residual,0px) - var(--aqvs-grid-frozen-width,0px)));position:absolute;top:0;left:0}.aqvs-grid-row-trailing{height:100%;top:0;left:max(var(--aqvs-grid-frozen-width,0px), calc(100% - var(--aqvs-grid-trailing-width,0px)));position:absolute;right:0;overflow:hidden}.aqvs-grid-row-trailing-inner{height:100%;width:var(--aqvs-grid-trailing-width,0px);position:absolute;top:0;right:0}.aqvs-grid-hbar-strip{min-width:0;padding-left:var(--aqvs-grid-frozen-width,0px);position:relative}.aqvs-grid-live-region{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.aqvs-grid-tap-circle-wrapper{z-index:50;pointer-events:auto;position:absolute}.aqvs-grid-tap-circle{transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}@media (forced-colors:active){.aqvs-tap-scroll-circle{outline-offset:-1px;border-radius:50%;outline:1px solid canvastext}.aqvs-scrollbar,.aqvs-scrollbar-track{outline-offset:-1px;outline:1px solid graytext}.aqvs-scrollbar-thumb{forced-color-adjust:none;background-color:canvastext}.aqvs-scrollbar-thumb[data-thumb-state=hover],.aqvs-scrollbar-thumb[data-thumb-state=dragging]{background-color:highlight}.aqvs-scrollbar-thumb[data-thumb-state=disabled]{background-color:graytext}.aqvs-scrollbar-arrow-button:enabled:focus-visible{forced-color-adjust:none;color:highlighttext;background-color:highlight}.aqvs-sample-visual-highlight,.aqvs-sample-visual-rod{forced-color-adjust:none;background-color:canvastext}.aqvs-scroll-to-edge-button:before{border:1px solid buttontext}}@media (prefers-reduced-motion:reduce){.aqvs-tap-scroll-circle,.aqvs-tap-scroll-circle *,.aqvs-grid-tap-circle,.aqvs-scrollbar-tap-circle-wrapper,.aqvs-scrollbar-arrow-button,.aqvs-scrollbar-thumb,.aqvs-scroll-to-edge-button:before,.aqvs-scroll-to-edge-overlay{transition:none!important;animation:none!important}}}.aqsp-root,.aqsp-root *,.aqsp-root :before,.aqsp-root :after{box-sizing:border-box}.aqsp-root{--aqsp-row-header-width:64px;--aqsp-col-header-height:24px;--aqsp-band-row:#0084ff;--aqsp-band-column:#42ff4f;--aqsp-band-intersection:#e1ff00;--aqsp-band-opacity:.2;color:#1f2937;background:#fff;width:100%;height:100%;font-size:13px;line-height:1;position:relative;overflow:hidden}.aqsp-zoom{grid-template-columns:var(--aqsp-row-header-width) minmax(0, 1fr);grid-template-rows:var(--aqsp-col-header-height) minmax(0, 1fr);transform-origin:0 0;width:100%;height:100%;display:grid}.aqsp-corner{background:#f3f4f6;border-bottom:1px solid #d1d5db;border-right:1px solid #d1d5db;grid-area:1/1}.aqsp-col-header{-webkit-user-select:none;user-select:none;background:#f3f4f6;border-bottom:1px solid #d1d5db;grid-area:1/2;position:relative;overflow:hidden}.aqsp-col-header-scroll{height:100%;position:absolute;top:0;right:0;overflow:hidden}.aqsp-row-header-scroll{width:100%;position:absolute;bottom:0;left:0;overflow:hidden}.aqsp-col-header-track{will-change:transform;position:absolute;inset:0}.aqsp-col-header-cell{white-space:nowrap;color:#4b5563;border-right:1px solid #e5e7eb;justify-content:center;align-items:center;height:100%;display:flex;position:absolute;top:0;overflow:hidden}.aqsp-row-header{-webkit-user-select:none;user-select:none;background:#f3f4f6;border-right:1px solid #d1d5db;grid-area:2/1;position:relative;overflow:hidden}.aqsp-row-header-track{will-change:transform;position:absolute;top:0;left:0;right:0}.aqsp-row-header-cell{white-space:nowrap;color:#4b5563;font-variant-numeric:tabular-nums;border-bottom:1px solid #e5e7eb;justify-content:flex-end;align-items:center;padding-right:6px;display:flex;position:absolute;left:0;right:0;overflow:hidden}.aqsp-body{position:absolute;inset:0}.aqsp-row{cursor:default}.aqsp-cell{white-space:nowrap;background:#fff;border-bottom:1px solid #e5e7eb;border-right:1px solid #e5e7eb;align-items:center;padding:0 4px;display:flex}.aqsp-cell[data-aqsp-valign=top]{align-items:flex-start}.aqsp-cell[data-aqsp-valign=bottom]{align-items:flex-end}.aqsp-cell[data-aqsp-wrap]{white-space:pre-wrap;overflow-wrap:anywhere}.aqsp-cell[data-aqsp-note]:after,.aqsp-cell[data-aqsp-comment]:after{content:"";pointer-events:none;border:5px solid #4b5563;border-color:#4b5563 #4b5563 #0000 #0000;width:0;height:0;position:absolute;top:0;right:0}.aqsp-cell[data-aqsp-comment]:after{border-top-color:#f97316;border-right-color:#f97316}.aqsp-cell[data-aqsp-invalid]:before{content:"";pointer-events:none;border:5px solid #0000;border-color:#0000 #0000 #dc2626 #dc2626;width:0;height:0;position:absolute;bottom:0;left:0}.aqsp-cell[data-aqsp-link]{color:#1d4ed8;text-decoration:underline}.aqsp-body-stack{grid-area:2/2;position:relative}.aqsp-overlay{pointer-events:none;position:absolute;inset:0;overflow:hidden}.aqsp-overlay-quad{pointer-events:none;position:absolute;overflow:hidden}.aqsp-selection-fill{mix-blend-mode:multiply;background:#3b82f62e;border:1px solid #2563ebd9;position:absolute;top:0;left:0}.aqsp-active-frame{box-sizing:border-box;border:2px solid #2563eb;position:absolute;top:0;left:0}.aqsp-drag-rect{background:#3b82f61a;border:1px solid #2563eb;position:absolute;top:0;left:0}.aqsp-drag-rect[data-aqsp-drag-mode=subtract]{background:#dc262614;border:1px dashed #dc2626}.aqsp-drag-rect[data-aqsp-drag-mode=point]{background:#16a34a14;border:1px dashed #16a34a}.aqsp-band{opacity:var(--aqsp-band-opacity);pointer-events:none;position:absolute;top:0;left:0}.aqsp-band[data-aqsp-band=row]{background:var(--aqsp-band-row)}.aqsp-band[data-aqsp-band=column]{background:var(--aqsp-band-column)}.aqsp-band[data-aqsp-band=intersection]{background:var(--aqsp-band-intersection)}.aqsp-clip-marquee{position:absolute;top:0;left:0}.aqsp-clip-marquee:after{content:"";top:var(--aqsp-clip-outset-top,-3px);right:var(--aqsp-clip-outset-right,-3px);bottom:var(--aqsp-clip-outset-bottom,-3px);left:var(--aqsp-clip-outset-left,-3px);background-image:linear-gradient(90deg,#2563eb 50%,#fff 50%),linear-gradient(90deg,#2563eb 50%,#fff 50%),linear-gradient(#fff 50%,#2563eb 50%),linear-gradient(#fff 50%,#2563eb 50%);background-position:0 0,8px 100%,0 8px,100% 0;background-repeat:repeat-x,repeat-x,repeat-y,repeat-y;background-size:8px 2px,8px 2px,2px 8px,2px 8px;animation:.4s linear infinite aqsp-marching-ants;position:absolute}@keyframes aqsp-marching-ants{to{background-position:8px 0,0 100%,0 0,100% 8px}}@media (prefers-reduced-motion:reduce){.aqsp-clip-marquee:after{animation:none}}.aqsp-col-resize-strip{cursor:col-resize;height:100%;position:absolute;top:0}.aqsp-row-resize-strip{cursor:row-resize;position:absolute;left:0;right:0}.aqsp-col-header .aqsp-unhide-marker{cursor:col-resize;opacity:.7;background:repeating-linear-gradient(90deg,#2563eb 0 1px,#0000 1px 3px);height:100%;position:absolute;top:0}.aqsp-row-header .aqsp-unhide-marker{cursor:row-resize;opacity:.7;background:repeating-linear-gradient(#2563eb 0 1px,#0000 1px 3px);position:absolute;left:0;right:0}.aqsp-resize-guide{pointer-events:none;background:#2563eb;position:absolute;top:0;left:0}.aqsp-autofill-handle{box-sizing:content-box;pointer-events:auto;cursor:crosshair;background:#2563eb;border:1px solid #fff;width:6px;height:6px;position:absolute;top:0;left:0}.aqsp-autofill-preview{border:1px dashed #16a34a;position:absolute;top:0;left:0}@media (forced-colors:active){.aqsp-band{outline-offset:-2px;background:0 0;outline:2px solid highlight}.aqsp-cell[data-aqsp-note]:after,.aqsp-cell[data-aqsp-comment]:after,.aqsp-cell[data-aqsp-invalid]:before{border:1px solid canvastext;width:6px;height:6px}.aqsp-drag-rect[data-aqsp-drag-mode=point]{background:0 0;border-color:highlight}.aqsp-selection-fill{outline-offset:-2px;background:0 0;border:none;outline:2px solid highlight}.aqsp-clip-marquee:after{background-image:none;border:2px dashed highlight;animation:none}}.aqsp-col-header-cell[data-aqsp-in-selection],.aqsp-row-header-cell[data-aqsp-in-selection]{color:#1d4ed8;background:#dbeafe;font-weight:600}.aqsp-live-region{clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.aqsp-sink{opacity:0;resize:none;pointer-events:auto;cursor:default;border:0;width:1px;height:1px;padding:0;position:absolute}.aqsp-sink[data-aqsp-editing]{opacity:1;z-index:1;box-sizing:border-box;color:#1f2937;caret-color:#1f2937;white-space:pre;outline-offset:-2px;cursor:text;background:#fff;outline:2px solid #2563eb;padding:0 4px;font-family:inherit;font-size:13px;line-height:1;overflow:hidden}.aqsp-sink[data-aqsp-pointing]{caret-color:#16a34a}.aqsp-popover-layer{pointer-events:none;position:absolute;inset:0;overflow:visible}.aqsp-popover-anchor{pointer-events:none;position:absolute;top:0;left:0}.aqsp-popover-anchor[inert]{visibility:hidden}.aqsp-popover{color:#1f2937;text-align:start;white-space:normal;cursor:default;pointer-events:auto;background:#fff;border:1px solid #d1d5db;border-radius:8px;flex-direction:column;width:320px;max-width:320px;font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica Neue,Noto Sans JP,sans-serif;font-size:13px;line-height:1.4;display:flex;position:absolute;overflow:hidden;box-shadow:0 1px 2px #00000014,0 8px 24px #00000024}.aqsp-popover:focus-visible{outline-offset:-2px;outline:2px solid #2563eb}.aqsp-popover[data-aqsp-popover-frame=note-tip]{background:#fffbeb;border-color:#f59e0b;box-shadow:0 2px 8px #0000001f}.aqsp-popover-note,.aqsp-popover-comment,.aqsp-popover-link,.aqsp-popover-message{flex-direction:column;min-height:0;padding:10px 12px;display:flex}.aqsp-popover-list{flex-direction:column;min-height:0;padding:6px;display:flex}.aqsp-popover-note-tip{overscroll-behavior:contain;white-space:pre-wrap;overflow-wrap:anywhere;min-height:0;padding:8px 10px;overflow-y:auto}[data-aqsp-popover][data-aqsp-popover-rejected]{border-inline-start:3px solid #dc2626;padding-inline-start:9px}.aqsp-popover-title{color:#374151;align-items:baseline;gap:6px;margin:0 0 6px;font-size:12px;font-weight:600;display:flex}.aqsp-popover-count{color:#6b7280;font-weight:400}.aqsp-popover-textarea,.aqsp-popover-input{width:100%;color:inherit;font:inherit;background:#fff;border:1px solid #d1d5db;border-radius:6px;margin:0;padding:5px 8px;line-height:1.4;display:block}.aqsp-popover-textarea{resize:none;white-space:pre-wrap;flex:auto;height:104px;min-height:56px;overflow:auto}.aqsp-popover-comment .aqsp-popover-textarea{flex:none;height:64px}.aqsp-popover-input{flex:none;height:28px}.aqsp-popover-textarea:focus-visible,.aqsp-popover-input:focus-visible{outline-offset:-1px;border-color:#2563eb;outline:2px solid #2563eb}.aqsp-popover-textarea[aria-invalid=true],.aqsp-popover-input[aria-invalid=true]{border-color:#dc2626}.aqsp-popover-textarea[aria-invalid=true]:focus-visible,.aqsp-popover-input[aria-invalid=true]:focus-visible{border-color:#dc2626;outline-color:#dc2626}.aqsp-popover-hint{color:#6b7280;margin:4px 0 0;font-size:12px}[data-aqsp-popover-rejected] .aqsp-popover-hint{color:#b91c1c}.aqsp-popover-field{flex-direction:column;flex:none;gap:3px;margin:0 0 8px;display:flex}.aqsp-popover-field-label{color:#6b7280;font-size:12px}.aqsp-popover-actions{flex:none;align-items:center;gap:6px;margin-top:8px;display:flex}.aqsp-popover-button{color:#1f2937;min-width:56px;height:26px;font:inherit;cursor:pointer;background:#f9fafb;border:1px solid #d1d5db;border-radius:6px;justify-content:center;align-items:center;margin:0;padding:0 10px;font-size:12px;font-weight:500;line-height:1;display:inline-flex}.aqsp-popover-button:not(:disabled):hover{background:#f3f4f6;border-color:#9ca3af}.aqsp-popover-button:focus-visible{outline-offset:1px;outline:2px solid #2563eb}.aqsp-popover-button:disabled{opacity:.5;cursor:not-allowed}.aqsp-popover-button[data-aqsp-popover-save],.aqsp-popover-button[data-aqsp-popover-post]{color:#fff;background:#2563eb;border-color:#2563eb}.aqsp-popover-button[data-aqsp-popover-save]:not(:disabled):hover,.aqsp-popover-button[data-aqsp-popover-post]:not(:disabled):hover{background:#1d4ed8;border-color:#1d4ed8}.aqsp-popover-button[data-aqsp-popover-close]{color:#6b7280;background:0 0;border-color:#0000;width:26px;min-width:0;margin-inline-start:auto;padding:0;font-size:16px;font-weight:400}.aqsp-popover-button[data-aqsp-popover-close]:not(:disabled):hover{color:#1f2937;background:#f3f4f6;border-color:#0000}.aqsp-popover-thread{overscroll-behavior:contain;flex:auto;min-height:48px;max-height:220px;margin:0 0 8px;padding:0;list-style:none;overflow-y:auto}.aqsp-popover-comment-item{border-top:1px solid #f3f4f6;padding:6px 0}.aqsp-popover-comment-item:first-child{border-top:0;padding-top:0}.aqsp-popover-comment-author{color:#111827;font-size:12px;font-weight:600}.aqsp-popover-comment-time{color:#6b7280;font-variant-numeric:tabular-nums;margin-inline-start:6px;font-size:11px}.aqsp-popover-comment-text{white-space:pre-wrap;overflow-wrap:anywhere;margin:2px 0 0}.aqsp-popover-list .aqsp-popover-input{margin-bottom:4px}.aqsp-popover-options{overscroll-behavior:contain;flex:auto;min-height:0;max-height:240px;overflow-y:auto}.aqsp-popover-option{white-space:nowrap;text-overflow:ellipsis;cursor:pointer;border-radius:4px;padding:5px 8px;overflow:hidden}.aqsp-popover-option:hover{background:#f3f4f6}.aqsp-popover-option[aria-selected=true]{color:#1e3a8a;background:#dbeafe}.aqsp-popover-option:focus-visible{outline-offset:-2px;outline:2px solid #2563eb}.aqsp-popover-empty{color:#6b7280;padding:6px 8px;font-size:12px}.aqsp-popover-message{padding-inline-end:40px;position:relative}.aqsp-popover-message .aqsp-popover-title{margin-bottom:2px}.aqsp-popover-message-text{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.aqsp-popover-message .aqsp-popover-button[data-aqsp-popover-close]{position:absolute;inset-block-start:6px;inset-inline-end:6px}.aqsp-popover-message[data-aqsp-popover-rejected]{background:#fef2f2}.aqsp-popover-message[data-aqsp-popover-rejected] .aqsp-popover-title{color:#b91c1c}@media (forced-colors:active){.aqsp-popover-option:hover,.aqsp-popover-option[aria-selected=true]{outline-offset:-2px;outline:2px solid highlight}.aqsp-popover-textarea[aria-invalid=true],.aqsp-popover-input[aria-invalid=true]{border-style:dashed}.aqsp-popover-button[data-aqsp-popover-close]{border-color:buttontext}}[data-aqsp-empty]{width:100%;height:100%;display:block}.aqsp-freeze-divider{background:var(--aqsp-divider-color,#9ca3af);pointer-events:none;position:absolute}.aqsp-freeze-divider-v{width:var(--aqsp-divider-width,2px)}.aqsp-freeze-divider-h{height:var(--aqsp-divider-width,2px)}@media (forced-colors:active){.aqsp-freeze-divider{background:canvastext}}}@layer utilities;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const o = (e) => (
|
|
2
|
+
// 終端 CRLF は必須 (Excel 実挙動)。parseTsv の「終端の改行 1 つを剥がす」規約と対 —
|
|
3
|
+
// 終端なしだと [["a"],[""]] が [["a"]] に潰れ (cut-move で clear されるべき先に旧値が残る)、
|
|
4
|
+
// [[""]] は "" になって §6.5.4-5 の空ガードに飲まれ「空セル貼り付けで clear」が不発になる
|
|
5
|
+
`${e.map((l) => l.map(h).join(" ")).join(`\r
|
|
6
|
+
`)}\r
|
|
7
|
+
`
|
|
8
|
+
), h = (e) => /[\t\r\n]/.test(e) ? `"${e.replaceAll('"', '""')}"` : e, u = (e) => e.endsWith(`\r
|
|
9
|
+
`) ? e.slice(0, -2) : e.endsWith(`
|
|
10
|
+
`) || e.endsWith("\r") ? e.slice(0, -1) : e, a = (e, l, t) => {
|
|
11
|
+
let n = 0;
|
|
12
|
+
for (; ; ) {
|
|
13
|
+
let s;
|
|
14
|
+
if (e[n] === '"') {
|
|
15
|
+
const r = f(e, n);
|
|
16
|
+
if (r !== null)
|
|
17
|
+
s = r.value, n = r.nextIndex;
|
|
18
|
+
else {
|
|
19
|
+
const i = c(e, n);
|
|
20
|
+
s = e.slice(n, i), n = i;
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
const r = c(e, n);
|
|
24
|
+
s = e.slice(n, r), n = r;
|
|
25
|
+
}
|
|
26
|
+
if (l(s), n >= e.length) {
|
|
27
|
+
t();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
e[n] === " " ? n += 1 : (n += e[n] === "\r" && e[n + 1] === `
|
|
31
|
+
` ? 2 : 1, t());
|
|
32
|
+
}
|
|
33
|
+
}, p = (e) => {
|
|
34
|
+
const l = u(e);
|
|
35
|
+
if (l === "")
|
|
36
|
+
return [[""]];
|
|
37
|
+
const t = [];
|
|
38
|
+
let n = [];
|
|
39
|
+
a(
|
|
40
|
+
l,
|
|
41
|
+
(r) => {
|
|
42
|
+
n.push(r);
|
|
43
|
+
},
|
|
44
|
+
() => {
|
|
45
|
+
t.push(n), n = [];
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
let s = 0;
|
|
49
|
+
for (const r of t)
|
|
50
|
+
r.length > s && (s = r.length);
|
|
51
|
+
return t.map((r) => r.length === s ? r : [...r, ...Array(s - r.length).fill("")]);
|
|
52
|
+
}, g = (e) => {
|
|
53
|
+
const l = u(e);
|
|
54
|
+
if (l === "")
|
|
55
|
+
return { rows: 1, cols: 1 };
|
|
56
|
+
let t = 0, n = 0, s = 0;
|
|
57
|
+
return a(
|
|
58
|
+
l,
|
|
59
|
+
() => {
|
|
60
|
+
s += 1;
|
|
61
|
+
},
|
|
62
|
+
() => {
|
|
63
|
+
t += 1, s > n && (n = s), s = 0;
|
|
64
|
+
}
|
|
65
|
+
), { rows: t, cols: n };
|
|
66
|
+
}, f = (e, l) => {
|
|
67
|
+
let t = "", n = l + 1;
|
|
68
|
+
for (; n < e.length; )
|
|
69
|
+
if (e[n] === '"')
|
|
70
|
+
if (e[n + 1] === '"')
|
|
71
|
+
t += '"', n += 2;
|
|
72
|
+
else {
|
|
73
|
+
const s = n + 1;
|
|
74
|
+
return (s >= e.length || e[s] === " " || e[s] === `
|
|
75
|
+
` || e[s] === "\r") && /[\t\r\n]/.test(t) ? { value: t, nextIndex: s } : null;
|
|
76
|
+
}
|
|
77
|
+
else
|
|
78
|
+
t += e[n], n += 1;
|
|
79
|
+
return null;
|
|
80
|
+
}, c = (e, l) => {
|
|
81
|
+
for (let t = l; t < e.length; t += 1)
|
|
82
|
+
if (e[t] === " " || e[t] === `
|
|
83
|
+
` || e[t] === "\r")
|
|
84
|
+
return t;
|
|
85
|
+
return e.length;
|
|
86
|
+
};
|
|
87
|
+
export {
|
|
88
|
+
g as m,
|
|
89
|
+
p,
|
|
90
|
+
o as s
|
|
91
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";const h=e=>`${e.map(l=>l.map(f).join(" ")).join(`\r
|
|
2
|
+
`)}\r
|
|
3
|
+
`,f=e=>/[\t\r\n]/.test(e)?`"${e.replaceAll('"','""')}"`:e,u=e=>e.endsWith(`\r
|
|
4
|
+
`)?e.slice(0,-2):e.endsWith(`
|
|
5
|
+
`)||e.endsWith("\r")?e.slice(0,-1):e,a=(e,l,t)=>{let n=0;for(;;){let s;if(e[n]==='"'){const r=p(e,n);if(r!==null)s=r.value,n=r.nextIndex;else{const i=c(e,n);s=e.slice(n,i),n=i}}else{const r=c(e,n);s=e.slice(n,r),n=r}if(l(s),n>=e.length){t();return}e[n]===" "?n+=1:(n+=e[n]==="\r"&&e[n+1]===`
|
|
6
|
+
`?2:1,t())}},o=e=>{const l=u(e);if(l==="")return[[""]];const t=[];let n=[];a(l,r=>{n.push(r)},()=>{t.push(n),n=[]});let s=0;for(const r of t)r.length>s&&(s=r.length);return t.map(r=>r.length===s?r:[...r,...Array(s-r.length).fill("")])},g=e=>{const l=u(e);if(l==="")return{rows:1,cols:1};let t=0,n=0,s=0;return a(l,()=>{s+=1},()=>{t+=1,s>n&&(n=s),s=0}),{rows:t,cols:n}},p=(e,l)=>{let t="",n=l+1;for(;n<e.length;)if(e[n]==='"')if(e[n+1]==='"')t+='"',n+=2;else{const s=n+1;return(s>=e.length||e[s]===" "||e[s]===`
|
|
7
|
+
`||e[s]==="\r")&&/[\t\r\n]/.test(t)?{value:t,nextIndex:s}:null}else t+=e[n],n+=1;return null},c=(e,l)=>{for(let t=l;t<e.length;t+=1)if(e[t]===" "||e[t]===`
|
|
8
|
+
`||e[t]==="\r")return t;return e.length};exports.measureTsv=g;exports.parseTsv=o;exports.serializeTsv=h;
|
package/dist/tsv.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./tsv-BHXbWK5W.cjs");exports.parseTsv=e.parseTsv;exports.serializeTsv=e.serializeTsv;
|
package/dist/tsv.d.cts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses Excel-behavior TSV into a rectangular matrix (ragged rows are right-padded).
|
|
3
|
+
* Excel 実挙動 TSV を矩形行列へ解析 (ギザギザ行は右パディング)。
|
|
4
|
+
*/
|
|
5
|
+
export declare const parseTsv: (text: string) => string[][];
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Serializes a matrix to Excel-behavior TSV with a trailing CRLF.
|
|
9
|
+
* 行列を終端 CRLF つきの Excel 実挙動 TSV へ直列化。
|
|
10
|
+
*/
|
|
11
|
+
export declare const serializeTsv: (matrix: readonly (readonly string[])[]) => string;
|
|
12
|
+
|
|
13
|
+
export { }
|
package/dist/tsv.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses Excel-behavior TSV into a rectangular matrix (ragged rows are right-padded).
|
|
3
|
+
* Excel 実挙動 TSV を矩形行列へ解析 (ギザギザ行は右パディング)。
|
|
4
|
+
*/
|
|
5
|
+
export declare const parseTsv: (text: string) => string[][];
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Serializes a matrix to Excel-behavior TSV with a trailing CRLF.
|
|
9
|
+
* 行列を終端 CRLF つきの Excel 実挙動 TSV へ直列化。
|
|
10
|
+
*/
|
|
11
|
+
export declare const serializeTsv: (matrix: readonly (readonly string[])[]) => string;
|
|
12
|
+
|
|
13
|
+
export { }
|
package/dist/tsv.js
ADDED
package/dist/view.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=24,o=64,R=12,e=.25,t=4,H=E=>{if(!Number.isFinite(E))throw new RangeError(`[spreadsheet] zoom must be a finite number (got ${E})`);return Math.min(t,Math.max(e,E))},s=(E,S)=>S>0?(Math.floor(E*10+1e-6)+1)/10:(Math.ceil(E*10-1e-6)-1)/10;exports.SPREADSHEET_COLUMN_HEADER_HEIGHT_PX=_;exports.SPREADSHEET_ROW_HEADER_WIDTH_PX=o;exports.SPREADSHEET_SCROLLBAR_SIZE_PX=R;exports.SPREADSHEET_ZOOM_MAX=t;exports.SPREADSHEET_ZOOM_MIN=e;exports.clampSpreadsheetZoom=H;exports.stepSpreadsheetZoom=s;
|
package/dist/view.d.cts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clamps a zoom into [SPREADSHEET_ZOOM_MIN, SPREADSHEET_ZOOM_MAX] without quantizing it, so a host may set any value
|
|
3
|
+
* such as 1.25; the gestures quantize their own arithmetic before they request a zoom. A non-finite value (NaN or
|
|
4
|
+
* ±Infinity) fails fast: Math.min and Math.max would pass NaN through every division by the zoom and defeat the grid's
|
|
5
|
+
* same-value bail.
|
|
6
|
+
* 拡大率を [下限, 上限] へ切る処理。量子化しないため、ホストは 1.25 などどの値でも置ける (操作は求める前に自分の計算で刻む)。
|
|
7
|
+
* 有限でない値 (NaN・±Infinity) はすぐに投げる (Math.min と Math.max は NaN を素通しし、拡大率で割る所をすべて汚し、同じ値なら
|
|
8
|
+
* 何もしないグリッドの判定も効かなくなるため)。
|
|
9
|
+
*
|
|
10
|
+
* @param value - The requested zoom. 求める拡大率。
|
|
11
|
+
* @returns The clamped zoom. 切った拡大率。
|
|
12
|
+
* @throws {RangeError} When the value is not finite. 有限でない場合。
|
|
13
|
+
*/
|
|
14
|
+
export declare const clampSpreadsheetZoom: (value: number) => number;
|
|
15
|
+
|
|
16
|
+
/** The height of the column-header band in CSS px (`--aqsp-col-header-height` in the stylesheet). 列見出しの帯の高さ (CSS px。スタイルシートの `--aqsp-col-header-height`)。 */
|
|
17
|
+
export declare const SPREADSHEET_COLUMN_HEADER_HEIGHT_PX = 24;
|
|
18
|
+
|
|
19
|
+
/** The width of the row-header band in CSS px (`--aqsp-row-header-width` in the stylesheet). 行見出しの帯の幅 (CSS px。スタイルシートの `--aqsp-row-header-width`)。 */
|
|
20
|
+
export declare const SPREADSHEET_ROW_HEADER_WIDTH_PX = 64;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The thickness of each scroll bar the grid always reserves, in CSS px: the vertical bar's width and the horizontal
|
|
24
|
+
* bar's height, both reserved whether or not the grid scrolls.
|
|
25
|
+
* グリッドが常に取っておくスクロールバーの太さ (CSS px)。縦のバーの幅と横のバーの高さで、スクロールしなくても両方を取る。
|
|
26
|
+
*/
|
|
27
|
+
export declare const SPREADSHEET_SCROLLBAR_SIZE_PX = 12;
|
|
28
|
+
|
|
29
|
+
/** The largest package zoom. パッケージの拡大率の上限。 */
|
|
30
|
+
export declare const SPREADSHEET_ZOOM_MAX = 4;
|
|
31
|
+
|
|
32
|
+
/** The smallest package zoom. パッケージの拡大率の下限。 */
|
|
33
|
+
export declare const SPREADSHEET_ZOOM_MIN = 0.25;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The 0.1-grid step of the zoom gestures (Alt+Wheel and Ctrl+Alt+= / -), unclamped and free of float drift. From an
|
|
37
|
+
* off-grid value (the 0.25 bound or a host's 1.25) the step lands on the nearest detent in the travel direction (0.25
|
|
38
|
+
* goes to 0.3 up and 0.2 down); rounding would skip a detent (0.25 to 0.4). Clamp the result with clampSpreadsheetZoom.
|
|
39
|
+
* 拡大縮小の操作 (Alt+ホイールと Ctrl+Alt+= / -) の 0.1 刻み (範囲で切らず、浮動小数のずれを持ち込まない)。刻みの外の値
|
|
40
|
+
* (下限の 0.25 やホストの 1.25) からは、進む向きの最寄りの刻みへ着く (0.25 から上は 0.3、下は 0.2)。丸めると刻みを飛ばす
|
|
41
|
+
* (0.25 から 0.4) ため使わない。結果は clampSpreadsheetZoom で切る。
|
|
42
|
+
*
|
|
43
|
+
* @param value - The current zoom. 今の拡大率。
|
|
44
|
+
* @param direction - 1 to zoom in, -1 to zoom out. 拡大は 1、縮小は -1。
|
|
45
|
+
* @returns The next detent in that direction. その向きの次の刻み。
|
|
46
|
+
*/
|
|
47
|
+
export declare const stepSpreadsheetZoom: (value: number, direction: 1 | -1) => number;
|
|
48
|
+
|
|
49
|
+
export { }
|
package/dist/view.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clamps a zoom into [SPREADSHEET_ZOOM_MIN, SPREADSHEET_ZOOM_MAX] without quantizing it, so a host may set any value
|
|
3
|
+
* such as 1.25; the gestures quantize their own arithmetic before they request a zoom. A non-finite value (NaN or
|
|
4
|
+
* ±Infinity) fails fast: Math.min and Math.max would pass NaN through every division by the zoom and defeat the grid's
|
|
5
|
+
* same-value bail.
|
|
6
|
+
* 拡大率を [下限, 上限] へ切る処理。量子化しないため、ホストは 1.25 などどの値でも置ける (操作は求める前に自分の計算で刻む)。
|
|
7
|
+
* 有限でない値 (NaN・±Infinity) はすぐに投げる (Math.min と Math.max は NaN を素通しし、拡大率で割る所をすべて汚し、同じ値なら
|
|
8
|
+
* 何もしないグリッドの判定も効かなくなるため)。
|
|
9
|
+
*
|
|
10
|
+
* @param value - The requested zoom. 求める拡大率。
|
|
11
|
+
* @returns The clamped zoom. 切った拡大率。
|
|
12
|
+
* @throws {RangeError} When the value is not finite. 有限でない場合。
|
|
13
|
+
*/
|
|
14
|
+
export declare const clampSpreadsheetZoom: (value: number) => number;
|
|
15
|
+
|
|
16
|
+
/** The height of the column-header band in CSS px (`--aqsp-col-header-height` in the stylesheet). 列見出しの帯の高さ (CSS px。スタイルシートの `--aqsp-col-header-height`)。 */
|
|
17
|
+
export declare const SPREADSHEET_COLUMN_HEADER_HEIGHT_PX = 24;
|
|
18
|
+
|
|
19
|
+
/** The width of the row-header band in CSS px (`--aqsp-row-header-width` in the stylesheet). 行見出しの帯の幅 (CSS px。スタイルシートの `--aqsp-row-header-width`)。 */
|
|
20
|
+
export declare const SPREADSHEET_ROW_HEADER_WIDTH_PX = 64;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The thickness of each scroll bar the grid always reserves, in CSS px: the vertical bar's width and the horizontal
|
|
24
|
+
* bar's height, both reserved whether or not the grid scrolls.
|
|
25
|
+
* グリッドが常に取っておくスクロールバーの太さ (CSS px)。縦のバーの幅と横のバーの高さで、スクロールしなくても両方を取る。
|
|
26
|
+
*/
|
|
27
|
+
export declare const SPREADSHEET_SCROLLBAR_SIZE_PX = 12;
|
|
28
|
+
|
|
29
|
+
/** The largest package zoom. パッケージの拡大率の上限。 */
|
|
30
|
+
export declare const SPREADSHEET_ZOOM_MAX = 4;
|
|
31
|
+
|
|
32
|
+
/** The smallest package zoom. パッケージの拡大率の下限。 */
|
|
33
|
+
export declare const SPREADSHEET_ZOOM_MIN = 0.25;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The 0.1-grid step of the zoom gestures (Alt+Wheel and Ctrl+Alt+= / -), unclamped and free of float drift. From an
|
|
37
|
+
* off-grid value (the 0.25 bound or a host's 1.25) the step lands on the nearest detent in the travel direction (0.25
|
|
38
|
+
* goes to 0.3 up and 0.2 down); rounding would skip a detent (0.25 to 0.4). Clamp the result with clampSpreadsheetZoom.
|
|
39
|
+
* 拡大縮小の操作 (Alt+ホイールと Ctrl+Alt+= / -) の 0.1 刻み (範囲で切らず、浮動小数のずれを持ち込まない)。刻みの外の値
|
|
40
|
+
* (下限の 0.25 やホストの 1.25) からは、進む向きの最寄りの刻みへ着く (0.25 から上は 0.3、下は 0.2)。丸めると刻みを飛ばす
|
|
41
|
+
* (0.25 から 0.4) ため使わない。結果は clampSpreadsheetZoom で切る。
|
|
42
|
+
*
|
|
43
|
+
* @param value - The current zoom. 今の拡大率。
|
|
44
|
+
* @param direction - 1 to zoom in, -1 to zoom out. 拡大は 1、縮小は -1。
|
|
45
|
+
* @returns The next detent in that direction. その向きの次の刻み。
|
|
46
|
+
*/
|
|
47
|
+
export declare const stepSpreadsheetZoom: (value: number, direction: 1 | -1) => number;
|
|
48
|
+
|
|
49
|
+
export { }
|
package/dist/view.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const e = 24, o = 64, _ = 12, S = 0.25, n = 4, s = (E) => {
|
|
2
|
+
if (!Number.isFinite(E))
|
|
3
|
+
throw new RangeError(`[spreadsheet] zoom must be a finite number (got ${E})`);
|
|
4
|
+
return Math.min(4, Math.max(0.25, E));
|
|
5
|
+
}, r = (E, t) => t > 0 ? (Math.floor(E * 10 + 1e-6) + 1) / 10 : (Math.ceil(E * 10 - 1e-6) - 1) / 10;
|
|
6
|
+
export {
|
|
7
|
+
e as SPREADSHEET_COLUMN_HEADER_HEIGHT_PX,
|
|
8
|
+
o as SPREADSHEET_ROW_HEADER_WIDTH_PX,
|
|
9
|
+
_ as SPREADSHEET_SCROLLBAR_SIZE_PX,
|
|
10
|
+
n as SPREADSHEET_ZOOM_MAX,
|
|
11
|
+
S as SPREADSHEET_ZOOM_MIN,
|
|
12
|
+
s as clampSpreadsheetZoom,
|
|
13
|
+
r as stepSpreadsheetZoom
|
|
14
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiquants/spreadsheet",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Excel-grade spreadsheet grid for React: multi-cell selection, TSV/HTML clipboard, in-place editing on top of @aiquants/virtualscroll",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"**/*.css"
|
|
@@ -21,6 +21,28 @@
|
|
|
21
21
|
},
|
|
22
22
|
"default": "./dist/index.js"
|
|
23
23
|
},
|
|
24
|
+
"./view": {
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./dist/view.d.ts",
|
|
27
|
+
"default": "./dist/view.js"
|
|
28
|
+
},
|
|
29
|
+
"require": {
|
|
30
|
+
"types": "./dist/view.d.cts",
|
|
31
|
+
"default": "./dist/view.cjs"
|
|
32
|
+
},
|
|
33
|
+
"default": "./dist/view.js"
|
|
34
|
+
},
|
|
35
|
+
"./tsv": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/tsv.d.ts",
|
|
38
|
+
"default": "./dist/tsv.js"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/tsv.d.cts",
|
|
42
|
+
"default": "./dist/tsv.cjs"
|
|
43
|
+
},
|
|
44
|
+
"default": "./dist/tsv.js"
|
|
45
|
+
},
|
|
24
46
|
"./styles/spreadsheet.css": "./dist/styles/spreadsheet.css",
|
|
25
47
|
"./styles/spreadsheet.standalone.css": "./dist/styles/spreadsheet.standalone.css"
|
|
26
48
|
},
|
|
@@ -34,12 +56,12 @@
|
|
|
34
56
|
"LICENSE.md"
|
|
35
57
|
],
|
|
36
58
|
"peerDependencies": {
|
|
37
|
-
"@aiquants/virtualscroll": "^3.
|
|
59
|
+
"@aiquants/virtualscroll": "^3.22.0",
|
|
38
60
|
"react": "^19.2.7",
|
|
39
61
|
"react-dom": "^19.2.7"
|
|
40
62
|
},
|
|
41
63
|
"devDependencies": {
|
|
42
|
-
"@aiquants/virtualscroll": "3.
|
|
64
|
+
"@aiquants/virtualscroll": "3.22.0",
|
|
43
65
|
"@playwright/test": "^1.59.1",
|
|
44
66
|
"@tailwindcss/cli": "^4.1.18",
|
|
45
67
|
"@testing-library/jest-dom": "^6.9.1",
|
|
@@ -76,7 +98,9 @@
|
|
|
76
98
|
"access": "public"
|
|
77
99
|
},
|
|
78
100
|
"scripts": {
|
|
79
|
-
"build": "
|
|
101
|
+
"build": "pnpm -w run workspace:build \"$PNPM_SCRIPT_SRC_DIR\"",
|
|
102
|
+
"prebuild:self": "pnpm -w run workspace:sync \"$PNPM_SCRIPT_SRC_DIR\"",
|
|
103
|
+
"build:self": "rimraf dist && vite build && pnpm build:css && pnpm build:cts",
|
|
80
104
|
"build:css": "tailwindcss -i src/styles/components.entry.css -o dist/styles/spreadsheet.css --minify && tailwindcss -i src/styles/standalone.entry.css -o dist/styles/spreadsheet.standalone.css --minify",
|
|
81
105
|
"build:cts": "node -e \"const fs=require('node:fs');const re=/(from\\s+')(\\.{1,2}\\/[^']+)\\.(?:tsx|ts)(')/g;for(const f of fs.readdirSync('dist')){if(!f.endsWith('.d.ts'))continue;const s=fs.readFileSync('dist/'+f,'utf8').replace(re,(_m,p,spec,q)=>p+spec+'.cjs'+q).replace(/^\\/\\/# sourceMappingURL=.*(\\r?\\n)?/gm,'');fs.writeFileSync('dist/'+f.slice(0,-5)+'.d.cts',s)}\"",
|
|
82
106
|
"typecheck": "tsc --noEmit",
|
|
@@ -87,8 +111,8 @@
|
|
|
87
111
|
"test:e2e": "playwright test",
|
|
88
112
|
"lint": "biome check src tests demo/src",
|
|
89
113
|
"clean": "rimraf dist",
|
|
90
|
-
"publish:patch": "pnpm run typecheck && pnpm run --if-present test && node ../../.config/scripts/check-publish-leaks.mjs && pnpm version patch --no-git-tag-version --no-git-checks && pnpm publish --no-git-checks",
|
|
91
|
-
"publish:minor": "pnpm run typecheck && pnpm run --if-present test && node ../../.config/scripts/check-publish-leaks.mjs && pnpm version minor --no-git-tag-version --no-git-checks && pnpm publish --no-git-checks",
|
|
92
|
-
"publish:major": "pnpm run typecheck && pnpm run --if-present test && node ../../.config/scripts/check-publish-leaks.mjs && pnpm version major --no-git-tag-version --no-git-checks && pnpm publish --no-git-checks"
|
|
114
|
+
"publish:patch": "pnpm run typecheck && pnpm run --if-present test && pnpm run build && node ../../.config/scripts/check-publish-leaks.mjs && pnpm version patch --no-git-tag-version --no-git-checks && pnpm publish --no-git-checks",
|
|
115
|
+
"publish:minor": "pnpm run typecheck && pnpm run --if-present test && pnpm run build && node ../../.config/scripts/check-publish-leaks.mjs && pnpm version minor --no-git-tag-version --no-git-checks && pnpm publish --no-git-checks",
|
|
116
|
+
"publish:major": "pnpm run typecheck && pnpm run --if-present test && pnpm run build && node ../../.config/scripts/check-publish-leaks.mjs && pnpm version major --no-git-tag-version --no-git-checks && pnpm publish --no-git-checks"
|
|
93
117
|
}
|
|
94
118
|
}
|
package/src/Spreadsheet.tsx
CHANGED
|
@@ -85,6 +85,7 @@ import { clampSelectionToGrid, reduceActiveCycle, reduceSelectionExtend, reduceS
|
|
|
85
85
|
import { useAutoScroller } from "./selection/useAutoScroller.ts"
|
|
86
86
|
import { type PointDragOwner, usePointDrag } from "./selection/usePointDrag.ts"
|
|
87
87
|
import { useSelectionEngine } from "./selection/useSelectionEngine.ts"
|
|
88
|
+
import { clampSpreadsheetZoom, stepSpreadsheetZoom } from "./view.ts"
|
|
88
89
|
|
|
89
90
|
export type { SelectionState } from "./selection/selectionState.ts"
|
|
90
91
|
|
|
@@ -460,14 +461,14 @@ export type SpreadsheetProps = {
|
|
|
460
461
|
locale?: SpreadsheetLocale
|
|
461
462
|
/**
|
|
462
463
|
* UI label vocabulary (v0.8 §1.6) — folds the former `sinkAriaLabel` / `rootAriaLabel` props
|
|
463
|
-
* (clean cut-over).
|
|
464
|
-
*
|
|
465
|
-
* explicitly `undefined` key keeps the value of the `locale` catalog. An unknown key
|
|
466
|
-
* empty / blank value throws a RangeError during render, and the resolved `sinkAriaLabel`
|
|
467
|
-
* mention "Escape" (WCAG 2.1.2 escape advisement, §10-4).
|
|
464
|
+
* (clean cut-over). Keys = every engine chrome key of `@aiquants/virtualscroll`
|
|
465
|
+
* (`VIRTUAL_SCROLL_LABEL_KEYS`, e.g. scrollUp / scrollToTop / noItems) + 21 own keys. An omitted
|
|
466
|
+
* prop or an explicitly `undefined` key keeps the value of the `locale` catalog. An unknown key
|
|
467
|
+
* or an empty / blank value throws a RangeError during render, and the resolved `sinkAriaLabel`
|
|
468
|
+
* MUST mention "Escape" (WCAG 2.1.2 escape advisement, §10-4).
|
|
468
469
|
* UI ラベル語彙 (v0.8 §1.6) — 旧 sinkAriaLabel / rootAriaLabel prop を畳込み (クリーンカットオーバー)。
|
|
469
|
-
*
|
|
470
|
-
*
|
|
470
|
+
* キー = `@aiquants/virtualscroll` のエンジンクロームキー全件 (`VIRTUAL_SCROLL_LABEL_KEYS` — scrollUp /
|
|
471
|
+
* scrollToTop / noItems など) + 固有 21 キー。prop 省略 / 明示 undefined のキーは `locale` のカタログ値。
|
|
471
472
|
* 未知キー・空 / 空白値は render 中 RangeError、解決後の sinkAriaLabel は "Escape" を含むこと (§10-4)。
|
|
472
473
|
*/
|
|
473
474
|
labels?: SpreadsheetLabelOverrides
|
|
@@ -476,7 +477,7 @@ export type SpreadsheetProps = {
|
|
|
476
477
|
* list, `null` unbinds it. Validated at prop time — a non-canonical chord, a modifier-less
|
|
477
478
|
* chord, a single string, an override of a non-rebindable row (`pasteSpecial`), a clash with
|
|
478
479
|
* a non-rebindable built-in row in the command's column, or one chord bound to two commands
|
|
479
|
-
* throws a RangeError during render (`
|
|
480
|
+
* throws a RangeError during render (`clampSpreadsheetZoom` precedent). Consulted through a ref.
|
|
480
481
|
* 再バインド可能なコマンドチョード (v0.8 §1.9 / ADR-17)。配列は既定一覧の置換、null は未束縛。
|
|
481
482
|
* prop 時検証 (非正準 / 修飾なし / 単一 string / 非再バインド行の上書き / 列内予約行との一致 /
|
|
482
483
|
* 二重束縛は render 中 RangeError)。ref 経由で参照。
|
|
@@ -572,37 +573,6 @@ export type SpreadsheetProps = {
|
|
|
572
573
|
className?: string
|
|
573
574
|
}
|
|
574
575
|
|
|
575
|
-
/** Zoom clamp bounds (v0.3) — the 0.1 gesture grid lives in stepZoom's ×10 integer arithmetic. / ズームの clamp 境界 (v0.3) — ジェスチャの 0.1 グリッドは stepZoom の ×10 整数算術側。 */
|
|
576
|
-
const ZOOM_MIN = 0.25
|
|
577
|
-
const ZOOM_MAX = 4
|
|
578
|
-
|
|
579
|
-
/**
|
|
580
|
-
* Pure clamp — NO quantization (a 0.25 bound is not 0.1-quantizable; consumers may set any
|
|
581
|
-
* value like 1.25). Gestures quantize their own arithmetic before requesting. Non-finite
|
|
582
|
-
* input (NaN / ±Infinity) fail-fasts: Math.min/max would propagate NaN through every ÷z
|
|
583
|
-
* boundary and defeat the same-value gesture bail (unsuppressed onZoomChange(NaN) spam).
|
|
584
|
-
* 純 clamp — 量子化しない (境界 0.25 は 0.1 量子化不能。consumer は 1.25 等の任意値を設定
|
|
585
|
-
* できる)。量子化はジェスチャ側が要求前に自分の加算へ適用する。非有限値 (NaN / ±Infinity) は
|
|
586
|
-
* fail-fast — Math.min/max は NaN を素通しし、全 ÷z 境界の汚染と同値バウンド無効化 (NaN 同士は
|
|
587
|
-
* 不一致) による onZoomChange(NaN) 連射を招くため。
|
|
588
|
-
*/
|
|
589
|
-
const clampZoom = (value: number): number => {
|
|
590
|
-
if (!Number.isFinite(value)) {
|
|
591
|
-
throw new RangeError(`[spreadsheet] zoom must be a finite number (got ${value})`)
|
|
592
|
-
}
|
|
593
|
-
return Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, value))
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
/**
|
|
597
|
-
* 0.1-grid gesture step (float-drift-free). From an off-grid value (the 0.25 clamp bound or
|
|
598
|
-
* a controlled 1.25) the step lands on the NEAREST detent in the travel direction (0.25 →
|
|
599
|
-
* 0.3 / 0.2) — round-based arithmetic skipped a detent (0.25 → 0.4).
|
|
600
|
-
* ジェスチャの 0.1 グリッド刻み (float ドリフト遮断)。グリッド外の値 (clamp 境界 0.25 や制御
|
|
601
|
-
* 1.25) からは進行方向の最寄りデテントへ着地 (0.25 → 0.3 / 0.2) — 丸め方式はデテントを飛ばす
|
|
602
|
-
* (0.25 → 0.4) ため採らない。
|
|
603
|
-
*/
|
|
604
|
-
const stepZoom = (value: number, direction: 1 | -1): number => (direction > 0 ? (Math.floor(value * 10 + 1e-6) + 1) / 10 : (Math.ceil(value * 10 - 1e-6) - 1) / 10)
|
|
605
|
-
|
|
606
576
|
/**
|
|
607
577
|
* Validates one overscan prop and returns it unchanged (fail-fast — the engine does NOT
|
|
608
578
|
* validate overscan: a negative value silently shrinks the rendering window past the visible
|
|
@@ -740,10 +710,10 @@ const requirePasteSheet = (sheet: PasteSheet | undefined): PasteSheet => {
|
|
|
740
710
|
}
|
|
741
711
|
|
|
742
712
|
/**
|
|
743
|
-
* Keeps the previous engine label object while
|
|
713
|
+
* Keeps the previous engine label object while every engine string is value-equal, so the object handed
|
|
744
714
|
* to the memoized GridBody changes identity only when a string changes (a host passing an inline
|
|
745
715
|
* `labels={{…}}` must not re-render the grid body on every shell render).
|
|
746
|
-
*
|
|
716
|
+
* エンジン文字列がすべて値等価の間は前回のエンジンラベル object を保持 — memo 化された GridBody へ渡す
|
|
747
717
|
* object の identity は文字列が変わった時だけ変わる (インライン `labels={{…}}` のホストでも shell
|
|
748
718
|
* 再レンダー毎に本体を再描画させない)。
|
|
749
719
|
*
|
|
@@ -843,12 +813,12 @@ export const Spreadsheet = forwardRef<SpreadsheetHandle, SpreadsheetProps & Spre
|
|
|
843
813
|
}
|
|
844
814
|
const viewStore = viewStoreRef.current
|
|
845
815
|
|
|
846
|
-
// ---- prop 時検証 (v0.8 §4.2.13 —
|
|
816
|
+
// ---- prop 時検証 (v0.8 §4.2.13 — clampSpreadsheetZoom と同じく render 中に RangeError を投げる) ----
|
|
847
817
|
// 非対応ロケールはここで render 中 RangeError — 以降の検証メッセージ / GridBody は解決済み値だけを受ける
|
|
848
818
|
const uiLocale = resolveVirtualScrollLocale(locale)
|
|
849
819
|
// ラベルの畳込み: resolveLabels が Escape 告知 (§10-4) を検証する (RC22)
|
|
850
820
|
const resolvedLabels = useMemo(() => resolveLabels(locale, labels), [locale, labels])
|
|
851
|
-
// GridBody は memo 境界 — インライン labels で毎回新 object
|
|
821
|
+
// GridBody は memo 境界 — インライン labels で毎回新 object になってもエンジン文字列が同じなら identity を保つ
|
|
852
822
|
const scrollLabels = useValueStableScrollLabels(pickEngineLabels(resolvedLabels))
|
|
853
823
|
// コマンド表: validateShortcuts の 5 条件 (+ 未知キー) は consumer の設定誤り — render 中に表面化
|
|
854
824
|
const commandTable = useMemo(() => validateShortcuts(shortcuts), [shortcuts])
|
|
@@ -887,8 +857,8 @@ export const Spreadsheet = forwardRef<SpreadsheetHandle, SpreadsheetProps & Spre
|
|
|
887
857
|
|
|
888
858
|
const rootRef = useRef<HTMLDivElement | null>(null)
|
|
889
859
|
// ---- ズーム (v0.3): 制御 (zoom prop) / 非制御 (内部 state) の標準二相。実効値は常に clamp ----
|
|
890
|
-
const [internalZoom, setInternalZoom] = useState(() =>
|
|
891
|
-
const zoomValue =
|
|
860
|
+
const [internalZoom, setInternalZoom] = useState(() => clampSpreadsheetZoom(defaultZoom ?? 1))
|
|
861
|
+
const zoomValue = clampSpreadsheetZoom(zoom ?? internalZoom)
|
|
892
862
|
const zoomRef = useRef(zoomValue)
|
|
893
863
|
zoomRef.current = zoomValue
|
|
894
864
|
// ジェスチャ連打はレンダーフラッシュ前に複数イベントが届く — zoomRef (レンダー同期 = 実効値)
|
|
@@ -905,7 +875,7 @@ export const Spreadsheet = forwardRef<SpreadsheetHandle, SpreadsheetProps & Spre
|
|
|
905
875
|
zoomControlledRef.current = zoom !== undefined
|
|
906
876
|
/** Applies a gesture's zoom request (controlled mode only notifies). / ジェスチャのズーム要求適用 (制御モードは通知のみ)。 */
|
|
907
877
|
const requestZoom = useCallback((next: number) => {
|
|
908
|
-
const clamped =
|
|
878
|
+
const clamped = clampSpreadsheetZoom(next)
|
|
909
879
|
if (clamped === requestedZoomRef.current) {
|
|
910
880
|
return
|
|
911
881
|
}
|
|
@@ -954,7 +924,7 @@ export const Spreadsheet = forwardRef<SpreadsheetHandle, SpreadsheetProps & Spre
|
|
|
954
924
|
if (isDraggingAnyRef.current?.()) {
|
|
955
925
|
return
|
|
956
926
|
}
|
|
957
|
-
requestZoom(
|
|
927
|
+
requestZoom(stepSpreadsheetZoom(requestedZoomRef.current, event.deltaY < 0 ? 1 : -1))
|
|
958
928
|
}
|
|
959
929
|
const onKeyDown = (event: KeyboardEvent) => {
|
|
960
930
|
// 外側請求済みは素通し (wheel 側と同じ規律 — ホストの capture ショートカットと二重発火しない)
|
|
@@ -984,7 +954,7 @@ export const Spreadsheet = forwardRef<SpreadsheetHandle, SpreadsheetProps & Spre
|
|
|
984
954
|
// ズームイン) — 配列非依存の和音が必要なホストは event.code で先に請求すること。
|
|
985
955
|
// 素通しした和音は ctrl+alt 印字形状の遅延開始 (useGridKeyboard §6.6.2-4) により実文字が到着
|
|
986
956
|
// しない限り編集セッションを開かない
|
|
987
|
-
const next = event.key === "=" || event.key === "+" ?
|
|
957
|
+
const next = event.key === "=" || event.key === "+" ? stepSpreadsheetZoom(requestedZoomRef.current, 1) : event.key === "-" ? stepSpreadsheetZoom(requestedZoomRef.current, -1) : event.key === "0" ? 1 : null
|
|
988
958
|
if (next === null) {
|
|
989
959
|
return
|
|
990
960
|
}
|
|
@@ -1695,7 +1665,7 @@ export const Spreadsheet = forwardRef<SpreadsheetHandle, SpreadsheetProps & Spre
|
|
|
1695
1665
|
colAxis.resize(entry.index, size)
|
|
1696
1666
|
handle?.updateColSize(entry.index, size)
|
|
1697
1667
|
}
|
|
1698
|
-
// hx 再クランプと可視セルの再配置はグリッド内部 (総幅同期 +
|
|
1668
|
+
// hx 再クランプと可視セルの再配置はグリッド内部 (総幅同期 + 列幅木の版数) が担う —
|
|
1699
1669
|
// ここでの明示 reclamp は退役。ヘッダーの再レンダーは colVersion、残差は末尾 repaint
|
|
1700
1670
|
viewStore.bumpColVersion()
|
|
1701
1671
|
repaintColHeaders()
|
|
@@ -2676,7 +2646,7 @@ export const Spreadsheet = forwardRef<SpreadsheetHandle, SpreadsheetProps & Spre
|
|
|
2676
2646
|
colAxis.resize(col, size)
|
|
2677
2647
|
handleRef.current?.updateColSize(col, size)
|
|
2678
2648
|
// ヘッダー再レンダーは colVersion (購読 2)、セル再配置と hx 再クランプはグリッドの
|
|
2679
|
-
//
|
|
2649
|
+
// 列幅木の版数 + 総幅同期が担う。残差 transform は同期 repaint
|
|
2680
2650
|
viewStore.bumpColVersion()
|
|
2681
2651
|
repaintColHeaders()
|
|
2682
2652
|
repaintOverlay()
|