@aiquants/virtualscroll 2.3.0 → 2.5.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.
@@ -1,2 +1,2 @@
1
1
  /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
2
- @layer components{.aqvs-scroll-pane{display:flex;position:relative}.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}}
2
+ @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}}
@@ -1,3 +1,3 @@
1
1
  /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
2
2
  /*! @aiquants/virtualscroll standalone CSS — 非 Tailwind ホスト専用。ホストの Tailwind ビルドと混在させないこと */
3
- @layer theme,base;@layer components{.aqvs-scroll-pane{display:flex;position:relative}.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}}@layer utilities;
3
+ @layer theme,base;@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}}@layer utilities;
@@ -0,0 +1,64 @@
1
+ import { RefCallback, RefObject } from 'react';
2
+ /**
3
+ * Anything that can apply a wheel event with the pane's own rules.
4
+ * ペイン自身の規則でホイールイベントを適用できるもの。
5
+ *
6
+ * `VirtualScrollHandle` と `ScrollPaneHandle` の両方が構造的にこれを満たすため、どちらのハンドルでも
7
+ * 同じフックが使える (`ScrollPane` を直接使う消費側が橋渡しを自作せずに済む)。
8
+ */
9
+ export type WheelBridgeTarget = {
10
+ applyWheel: (event: WheelEvent) => boolean;
11
+ };
12
+ /**
13
+ * Options for {@link useWheelBridge}.
14
+ * {@link useWheelBridge} のオプション。
15
+ */
16
+ export type WheelBridgeOptions = {
17
+ /**
18
+ * Set to `false` to detach the bridge without unmounting the element.
19
+ * 要素をアンマウントせずに橋渡しを止めたいとき `false` にする。既定 `true`。
20
+ */
21
+ enableBridge?: boolean;
22
+ };
23
+ /**
24
+ * Bridges wheel events from an element outside the pane into the list, with the pane's own semantics.
25
+ * ペイン外の要素のホイールを、ペイン自身と同じ意味論で一覧へ橋渡しするフック。
26
+ *
27
+ * 返り値を対象要素の `ref` に渡すだけでよい。
28
+ *
29
+ * ```tsx
30
+ * const listRef = useRef<VirtualScrollHandle>(null)
31
+ * const headerRef = useWheelBridge(listRef)
32
+ *
33
+ * <div ref={headerRef}>列ヘッダー (ペインの外)</div>
34
+ * <VirtualScroll ref={listRef} onWheelHorizontal={setScrollX} ... />
35
+ * ```
36
+ *
37
+ * ❗ **ホイールの意味論に影響する設定は一切受け取らないのが意図的な設計である。** 速度倍率・
38
+ * 横成分の委譲先・スクロール可否・慣性停止・軸分解のすべては、ハンドルの向こう側 (`applyWheel`) が
39
+ * 持つ。橋渡し側にも同じ設定口を用意すると同じグリッドなのに「ヘッダー帯の上だけスクロールが遅い」
40
+ * 「帯の上でだけ横に動かない」といった食い違いが静かに生まれる (橋渡し側にも設定口を置いた
41
+ * 実装途中の版で実測: `wheelSpeedMultiplier: 3` のとき同じ 1 ノッチがペイン上 30px / 帯の上 10px)。
42
+ * 唯一のオプション {@link WheelBridgeOptions.enableBridge} は意味論ではなく**橋渡し自体の ON/OFF** である。
43
+ * このフックの責務は **`{ passive: false }` での登録・後始末・その ON/OFF だけ**である。
44
+ *
45
+ * ❗ **`onWheel` プロップでは代用できない。** React 19 は `onWheel` を passive リスナーとして登録するため
46
+ * `preventDefault()` が効かず、ページ全体がスクロールしてしまう。
47
+ *
48
+ * ❗ **`handle.scrollTo` で自前に橋渡ししてはならない。** あれはジャンプ用 API で、絶対位置を丸めるため
49
+ * 1px 未満のデルタが消え、さらにスクロールアンカーを張るためサイズ変化のたびに一覧が過去の位置へ戻る。
50
+ *
51
+ * 自前の ref も必要なら合成してよい (多重登録に対して安全に作ってある)。
52
+ * ❗ **戻り値をそのまま `return` すること。** React 19 はこれをクリーンアップとして実行する。
53
+ * 返さない場合も動作は正しいままだが、`null` 呼び出しでは何も外さない設計のため、リスナーは
54
+ * 要素ごと GC されるまで残る。
55
+ *
56
+ * ```tsx
57
+ * <div ref={(node) => { myRef.current = node; return headerRef(node) }} />
58
+ * ```
59
+ *
60
+ * @param target - Ref to the list's imperative handle (`VirtualScrollHandle` / `ScrollPaneHandle`) / 一覧の命令ハンドルへの ref
61
+ * @param options - Bridge options / 橋渡しのオプション
62
+ * @returns A ref callback to attach to the source element / 発生元の要素へ渡す ref コールバック
63
+ */
64
+ export declare const useWheelBridge: (target: RefObject<WheelBridgeTarget | null>, options?: WheelBridgeOptions) => RefCallback<HTMLElement>;
@@ -0,0 +1,65 @@
1
+ import { RefCallback, RefObject } from 'react';
2
+ /**
3
+ * Anything that can apply a wheel event with the pane's own rules.
4
+ * ペイン自身の規則でホイールイベントを適用できるもの。
5
+ *
6
+ * `VirtualScrollHandle` と `ScrollPaneHandle` の両方が構造的にこれを満たすため、どちらのハンドルでも
7
+ * 同じフックが使える (`ScrollPane` を直接使う消費側が橋渡しを自作せずに済む)。
8
+ */
9
+ export type WheelBridgeTarget = {
10
+ applyWheel: (event: WheelEvent) => boolean;
11
+ };
12
+ /**
13
+ * Options for {@link useWheelBridge}.
14
+ * {@link useWheelBridge} のオプション。
15
+ */
16
+ export type WheelBridgeOptions = {
17
+ /**
18
+ * Set to `false` to detach the bridge without unmounting the element.
19
+ * 要素をアンマウントせずに橋渡しを止めたいとき `false` にする。既定 `true`。
20
+ */
21
+ enableBridge?: boolean;
22
+ };
23
+ /**
24
+ * Bridges wheel events from an element outside the pane into the list, with the pane's own semantics.
25
+ * ペイン外の要素のホイールを、ペイン自身と同じ意味論で一覧へ橋渡しするフック。
26
+ *
27
+ * 返り値を対象要素の `ref` に渡すだけでよい。
28
+ *
29
+ * ```tsx
30
+ * const listRef = useRef<VirtualScrollHandle>(null)
31
+ * const headerRef = useWheelBridge(listRef)
32
+ *
33
+ * <div ref={headerRef}>列ヘッダー (ペインの外)</div>
34
+ * <VirtualScroll ref={listRef} onWheelHorizontal={setScrollX} ... />
35
+ * ```
36
+ *
37
+ * ❗ **ホイールの意味論に影響する設定は一切受け取らないのが意図的な設計である。** 速度倍率・
38
+ * 横成分の委譲先・スクロール可否・慣性停止・軸分解のすべては、ハンドルの向こう側 (`applyWheel`) が
39
+ * 持つ。橋渡し側にも同じ設定口を用意すると同じグリッドなのに「ヘッダー帯の上だけスクロールが遅い」
40
+ * 「帯の上でだけ横に動かない」といった食い違いが静かに生まれる (橋渡し側にも設定口を置いた
41
+ * 実装途中の版で実測: `wheelSpeedMultiplier: 3` のとき同じ 1 ノッチがペイン上 30px / 帯の上 10px)。
42
+ * 唯一のオプション {@link WheelBridgeOptions.enableBridge} は意味論ではなく**橋渡し自体の ON/OFF** である。
43
+ * このフックの責務は **`{ passive: false }` での登録・後始末・その ON/OFF だけ**である。
44
+ *
45
+ * ❗ **`onWheel` プロップでは代用できない。** React 19 は `onWheel` を passive リスナーとして登録するため
46
+ * `preventDefault()` が効かず、ページ全体がスクロールしてしまう。
47
+ *
48
+ * ❗ **`handle.scrollTo` で自前に橋渡ししてはならない。** あれはジャンプ用 API で、絶対位置を丸めるため
49
+ * 1px 未満のデルタが消え、さらにスクロールアンカーを張るためサイズ変化のたびに一覧が過去の位置へ戻る。
50
+ *
51
+ * 自前の ref も必要なら合成してよい (多重登録に対して安全に作ってある)。
52
+ * ❗ **戻り値をそのまま `return` すること。** React 19 はこれをクリーンアップとして実行する。
53
+ * 返さない場合も動作は正しいままだが、`null` 呼び出しでは何も外さない設計のため、リスナーは
54
+ * 要素ごと GC されるまで残る。
55
+ *
56
+ * ```tsx
57
+ * <div ref={(node) => { myRef.current = node; return headerRef(node) }} />
58
+ * ```
59
+ *
60
+ * @param target - Ref to the list's imperative handle (`VirtualScrollHandle` / `ScrollPaneHandle`) / 一覧の命令ハンドルへの ref
61
+ * @param options - Bridge options / 橋渡しのオプション
62
+ * @returns A ref callback to attach to the source element / 発生元の要素へ渡す ref コールバック
63
+ */
64
+ export declare const useWheelBridge: (target: RefObject<WheelBridgeTarget | null>, options?: WheelBridgeOptions) => RefCallback<HTMLElement>;
65
+ //# sourceMappingURL=useWheelBridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWheelBridge.d.ts","sourceRoot":"","sources":["../src/useWheelBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAwC,MAAM,OAAO,CAAA;AAE9F;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC5B,UAAU,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAA;CAC7C,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,EAAE,UAAU,kBAAkB,KAAG,WAAW,CAAC,WAAW,CA+DjI,CAAA"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @module wheelAxes
3
+ * @description Single source of truth for how a wheel event is split into scroll axes.
4
+ * Used only by `ScrollPane.applyWheel`, which is itself the single seam every wheel caller goes
5
+ * through, so the rules cannot drift between the pane and elements outside it.
6
+ *
7
+ * @description ホイールイベントをスクロール軸へ分解する規則の単一の真実。呼び出し元は
8
+ * `ScrollPane.applyWheel` **だけ**であり、その `applyWheel` がすべてのホイール呼び出し元
9
+ * (ペイン根のリスナー / `useWheelBridge` / 消費側の直接呼び出し) の唯一のシームなので、
10
+ * ペイン内外で規則が食い違わない。
11
+ *
12
+ * ❗ **公開 API ではない** (`index.ts` から export しない)。公開すると `LINE_HEIGHT_PX = 16`・
13
+ * 同値時の横倒し・4 フィールドの形が恒久的に凍結される。
14
+ */
15
+ /**
16
+ * Wheel axes resolved from a raw wheel event.
17
+ * 生のホイールイベントから解決した軸情報。
18
+ */
19
+ export type ResolvedWheelAxes = {
20
+ /** True when ctrl is held, i.e. the browser treats it as zoom. Deltas are still reported as-is. / ctrl 押下 (ブラウザがズームとして扱う) の場合に true。デルタはそのまま報告する。 */
21
+ isZoomGesture: boolean;
22
+ /** True when the horizontal component dominates (includes shift+wheel). / 横成分が優勢な場合に true (shift+ホイールを含む)。 */
23
+ isHorizontalDominant: boolean;
24
+ /** Horizontal delta in px (deltaMode already converted). / px 単位の横方向デルタ (deltaMode 変換済み)。 */
25
+ horizontalDelta: number;
26
+ /** Vertical delta in px (deltaMode already converted). / px 単位の縦方向デルタ (deltaMode 変換済み)。 */
27
+ verticalDelta: number;
28
+ };
29
+ /**
30
+ * Splits a wheel event into scroll axes, in pixels, applying the package's gesture rules.
31
+ * ホイールイベントを px 単位の軸へ分解し、本パッケージのジェスチャ規則を適用する処理。
32
+ *
33
+ * 規則 (判定順序そのものが仕様):
34
+ *
35
+ * 1. **shift+ホイール**は `deltaX === 0` のとき縦量を横として読む (Windows 系の慣習)。ブラウザが既に
36
+ * `deltaX` へマップ済みなら通常の軸のまま扱う。
37
+ * 2. **横優勢判定**は横成分と縦成分の絶対値比較。等しい場合 (`|h| === |v|`) は横に倒す。ただし
38
+ * **両軸とも 0 のときは横優勢としない** — 慣性の惰性通知で毎 tick 送られる 0/0 を横として
39
+ * 消費すると、ページ側のスクロールを無言で飲み込む。
40
+ *
41
+ * ❗ **これは解決器であって方針ではない。** `isZoomGesture` (ctrl 押下) が true でもデルタは
42
+ * そのまま返す。「ズームは横取りしない」という**方針**は適用側 (`ScrollPane.applyWheel`) が持つ。
43
+ *
44
+ * @param event - The wheel event / ホイールイベント
45
+ * @param viewportSize - Viewport length for `DOM_DELTA_PAGE` conversion / `DOM_DELTA_PAGE` 変換に使うビューポート長
46
+ * @returns The resolved axes / 解決した軸情報
47
+ */
48
+ export declare const resolveWheelAxes: (event: WheelEvent, viewportSize: number) => ResolvedWheelAxes;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @module wheelAxes
3
+ * @description Single source of truth for how a wheel event is split into scroll axes.
4
+ * Used only by `ScrollPane.applyWheel`, which is itself the single seam every wheel caller goes
5
+ * through, so the rules cannot drift between the pane and elements outside it.
6
+ *
7
+ * @description ホイールイベントをスクロール軸へ分解する規則の単一の真実。呼び出し元は
8
+ * `ScrollPane.applyWheel` **だけ**であり、その `applyWheel` がすべてのホイール呼び出し元
9
+ * (ペイン根のリスナー / `useWheelBridge` / 消費側の直接呼び出し) の唯一のシームなので、
10
+ * ペイン内外で規則が食い違わない。
11
+ *
12
+ * ❗ **公開 API ではない** (`index.ts` から export しない)。公開すると `LINE_HEIGHT_PX = 16`・
13
+ * 同値時の横倒し・4 フィールドの形が恒久的に凍結される。
14
+ */
15
+ /**
16
+ * Wheel axes resolved from a raw wheel event.
17
+ * 生のホイールイベントから解決した軸情報。
18
+ */
19
+ export type ResolvedWheelAxes = {
20
+ /** True when ctrl is held, i.e. the browser treats it as zoom. Deltas are still reported as-is. / ctrl 押下 (ブラウザがズームとして扱う) の場合に true。デルタはそのまま報告する。 */
21
+ isZoomGesture: boolean;
22
+ /** True when the horizontal component dominates (includes shift+wheel). / 横成分が優勢な場合に true (shift+ホイールを含む)。 */
23
+ isHorizontalDominant: boolean;
24
+ /** Horizontal delta in px (deltaMode already converted). / px 単位の横方向デルタ (deltaMode 変換済み)。 */
25
+ horizontalDelta: number;
26
+ /** Vertical delta in px (deltaMode already converted). / px 単位の縦方向デルタ (deltaMode 変換済み)。 */
27
+ verticalDelta: number;
28
+ };
29
+ /**
30
+ * Splits a wheel event into scroll axes, in pixels, applying the package's gesture rules.
31
+ * ホイールイベントを px 単位の軸へ分解し、本パッケージのジェスチャ規則を適用する処理。
32
+ *
33
+ * 規則 (判定順序そのものが仕様):
34
+ *
35
+ * 1. **shift+ホイール**は `deltaX === 0` のとき縦量を横として読む (Windows 系の慣習)。ブラウザが既に
36
+ * `deltaX` へマップ済みなら通常の軸のまま扱う。
37
+ * 2. **横優勢判定**は横成分と縦成分の絶対値比較。等しい場合 (`|h| === |v|`) は横に倒す。ただし
38
+ * **両軸とも 0 のときは横優勢としない** — 慣性の惰性通知で毎 tick 送られる 0/0 を横として
39
+ * 消費すると、ページ側のスクロールを無言で飲み込む。
40
+ *
41
+ * ❗ **これは解決器であって方針ではない。** `isZoomGesture` (ctrl 押下) が true でもデルタは
42
+ * そのまま返す。「ズームは横取りしない」という**方針**は適用側 (`ScrollPane.applyWheel`) が持つ。
43
+ *
44
+ * @param event - The wheel event / ホイールイベント
45
+ * @param viewportSize - Viewport length for `DOM_DELTA_PAGE` conversion / `DOM_DELTA_PAGE` 変換に使うビューポート長
46
+ * @returns The resolved axes / 解決した軸情報
47
+ */
48
+ export declare const resolveWheelAxes: (event: WheelEvent, viewportSize: number) => ResolvedWheelAxes;
49
+ //# sourceMappingURL=wheelAxes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wheelAxes.d.ts","sourceRoot":"","sources":["../src/wheelAxes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC5B,qJAAqJ;IACrJ,aAAa,EAAE,OAAO,CAAA;IACtB,8GAA8G;IAC9G,oBAAoB,EAAE,OAAO,CAAA;IAC7B,6FAA6F;IAC7F,eAAe,EAAE,MAAM,CAAA;IACvB,2FAA2F;IAC3F,aAAa,EAAE,MAAM,CAAA;CACxB,CAAA;AAuBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,UAAU,EAAE,cAAc,MAAM,KAAG,iBAgB1E,CAAA"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @module wheelConsumption
3
+ * @description Tracks which wheel events this package has already applied.
4
+ *
5
+ * @description 本パッケージが既に適用したホイールイベントを記録するモジュール。
6
+ *
7
+ * ❗ **`event.defaultPrevented` では代用できない。** あれは「誰かがこのイベントを止めた」であって
8
+ * 「**我々が**消費した」ではない。両者を混同すると、ページ全体のスクロールロック
9
+ * (`document` に capture + `preventDefault` を張る定番の実装) を掛けただけで一覧が
10
+ * まったくスクロールできなくなる。逆に印が無いと、ペインの入れ子や祖先に張った `useWheelBridge` で
11
+ * **同じデルタが 2 回適用**される (実測: 内側と外側の一覧が 1 ノッチで両方 100px 動く)。
12
+ *
13
+ * `WeakSet` なのでイベントオブジェクトの寿命を延ばさない。
14
+ */
15
+ /**
16
+ * Marks a wheel event as applied by this package.
17
+ * ホイールイベントを「本パッケージが適用済み」として記録する処理。
18
+ *
19
+ * @param event - The wheel event that was applied / 適用したホイールイベント
20
+ */
21
+ export declare const markWheelConsumed: (event: WheelEvent) => void;
22
+ /**
23
+ * Reports whether this package already applied the given wheel event.
24
+ * 指定のホイールイベントを本パッケージが既に適用済みかどうかを返す処理。
25
+ *
26
+ * @param event - The wheel event to test / 判定するホイールイベント
27
+ * @returns True when it was already applied / 既に適用済みの場合に true
28
+ */
29
+ export declare const wasWheelConsumed: (event: WheelEvent) => boolean;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @module wheelConsumption
3
+ * @description Tracks which wheel events this package has already applied.
4
+ *
5
+ * @description 本パッケージが既に適用したホイールイベントを記録するモジュール。
6
+ *
7
+ * ❗ **`event.defaultPrevented` では代用できない。** あれは「誰かがこのイベントを止めた」であって
8
+ * 「**我々が**消費した」ではない。両者を混同すると、ページ全体のスクロールロック
9
+ * (`document` に capture + `preventDefault` を張る定番の実装) を掛けただけで一覧が
10
+ * まったくスクロールできなくなる。逆に印が無いと、ペインの入れ子や祖先に張った `useWheelBridge` で
11
+ * **同じデルタが 2 回適用**される (実測: 内側と外側の一覧が 1 ノッチで両方 100px 動く)。
12
+ *
13
+ * `WeakSet` なのでイベントオブジェクトの寿命を延ばさない。
14
+ */
15
+ /**
16
+ * Marks a wheel event as applied by this package.
17
+ * ホイールイベントを「本パッケージが適用済み」として記録する処理。
18
+ *
19
+ * @param event - The wheel event that was applied / 適用したホイールイベント
20
+ */
21
+ export declare const markWheelConsumed: (event: WheelEvent) => void;
22
+ /**
23
+ * Reports whether this package already applied the given wheel event.
24
+ * 指定のホイールイベントを本パッケージが既に適用済みかどうかを返す処理。
25
+ *
26
+ * @param event - The wheel event to test / 判定するホイールイベント
27
+ * @returns True when it was already applied / 既に適用済みの場合に true
28
+ */
29
+ export declare const wasWheelConsumed: (event: WheelEvent) => boolean;
30
+ //# sourceMappingURL=wheelConsumption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wheelConsumption.d.ts","sourceRoot":"","sources":["../src/wheelConsumption.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,UAAU,KAAG,IAErD,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,UAAU,KAAG,OAAyC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiquants/virtualscroll",
3
- "version": "2.3.0",
3
+ "version": "2.5.0",
4
4
  "description": "High-performance virtual scrolling component for React with variable item heights",
5
5
  "sideEffects": [
6
6
  "**/*.css"