@diabolic/hangover 0.1.6 → 0.2.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/README.md +2 -2
- package/dist/index.cjs.js +26 -7
- package/dist/index.esm.js +26 -7
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -36,7 +36,6 @@ npm install @diabolic/hangover
|
|
|
36
36
|
|
|
37
37
|
```jsx
|
|
38
38
|
import { Dropdown } from '@diabolic/hangover'
|
|
39
|
-
import '@diabolic/hangover/styles'
|
|
40
39
|
|
|
41
40
|
export default function App() {
|
|
42
41
|
return (
|
|
@@ -59,7 +58,8 @@ export default function App() {
|
|
|
59
58
|
}
|
|
60
59
|
```
|
|
61
60
|
|
|
62
|
-
|
|
61
|
+
Styles are imported automatically with the component. Do not import from
|
|
62
|
+
`dist/...` directly.
|
|
63
63
|
|
|
64
64
|
---
|
|
65
65
|
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require('./hangover.css');
|
|
1
2
|
'use strict';
|
|
2
3
|
|
|
3
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
@@ -737,12 +738,16 @@ function DropdownContent({
|
|
|
737
738
|
if (displayMode !== 'scroll') return;
|
|
738
739
|
const list = contentRef.current;
|
|
739
740
|
if (!list) return;
|
|
740
|
-
|
|
741
|
+
let rafId = null;
|
|
742
|
+
function computeBottomSpace() {
|
|
743
|
+
rafId = null;
|
|
741
744
|
const sections = list.querySelectorAll('[data-section-for]');
|
|
742
745
|
const lastSection = sections[sections.length - 1];
|
|
743
746
|
if (!lastSection) {
|
|
744
|
-
|
|
745
|
-
|
|
747
|
+
if (bottomPadRef.current !== 0) {
|
|
748
|
+
list.style.paddingBottom = '';
|
|
749
|
+
bottomPadRef.current = 0;
|
|
750
|
+
}
|
|
746
751
|
return;
|
|
747
752
|
}
|
|
748
753
|
|
|
@@ -755,20 +760,34 @@ function DropdownContent({
|
|
|
755
760
|
const listTop = list.getBoundingClientRect().top;
|
|
756
761
|
const lastTopWithinContent = lastSection.getBoundingClientRect().top - listTop + list.scrollTop;
|
|
757
762
|
const spaceBelowLastTop = naturalScrollHeight - lastTopWithinContent;
|
|
758
|
-
const pad = Math.max(0, available - spaceBelowLastTop);
|
|
763
|
+
const pad = Math.max(0, Math.round(available - spaceBelowLastTop));
|
|
764
|
+
|
|
765
|
+
// Only touch the DOM when the reserved space actually changes by a whole
|
|
766
|
+
// pixel — this ignores sub-pixel/floating jitter from the observer and
|
|
767
|
+
// keeps the value stable.
|
|
768
|
+
if (Math.abs(pad - bottomPadRef.current) < 1) return;
|
|
759
769
|
bottomPadRef.current = pad;
|
|
760
770
|
list.style.paddingBottom = `${pad}px`;
|
|
761
771
|
}
|
|
762
|
-
|
|
772
|
+
|
|
773
|
+
// Coalesce bursts of observer callbacks into a single measurement per frame.
|
|
774
|
+
function scheduleBottomSpace() {
|
|
775
|
+
if (rafId !== null) return;
|
|
776
|
+
rafId = requestAnimationFrame(computeBottomSpace);
|
|
777
|
+
}
|
|
778
|
+
scheduleBottomSpace();
|
|
763
779
|
|
|
764
780
|
// Observe both the container (viewport resize) and every section (group
|
|
765
781
|
// expand/collapse, late reflows) so the reserved space stays accurate.
|
|
766
|
-
const observer = new ResizeObserver(
|
|
782
|
+
const observer = new ResizeObserver(scheduleBottomSpace);
|
|
767
783
|
observer.observe(list);
|
|
768
784
|
list.querySelectorAll('[data-section-for]').forEach(section => {
|
|
769
785
|
observer.observe(section);
|
|
770
786
|
});
|
|
771
|
-
return () =>
|
|
787
|
+
return () => {
|
|
788
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
789
|
+
observer.disconnect();
|
|
790
|
+
};
|
|
772
791
|
}, [displayMode, contentRef, children, searchQuery]);
|
|
773
792
|
function handleSearch(e) {
|
|
774
793
|
fireEvent('search', {
|
package/dist/index.esm.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import './hangover.css';
|
|
1
2
|
import { useContext, createContext, Children, cloneElement, useState, useRef, useCallback, useEffect, isValidElement, createElement, useMemo, forwardRef, useImperativeHandle } from 'react';
|
|
2
3
|
import { createPortal } from 'react-dom';
|
|
3
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -733,12 +734,16 @@ function DropdownContent({
|
|
|
733
734
|
if (displayMode !== 'scroll') return;
|
|
734
735
|
const list = contentRef.current;
|
|
735
736
|
if (!list) return;
|
|
736
|
-
|
|
737
|
+
let rafId = null;
|
|
738
|
+
function computeBottomSpace() {
|
|
739
|
+
rafId = null;
|
|
737
740
|
const sections = list.querySelectorAll('[data-section-for]');
|
|
738
741
|
const lastSection = sections[sections.length - 1];
|
|
739
742
|
if (!lastSection) {
|
|
740
|
-
|
|
741
|
-
|
|
743
|
+
if (bottomPadRef.current !== 0) {
|
|
744
|
+
list.style.paddingBottom = '';
|
|
745
|
+
bottomPadRef.current = 0;
|
|
746
|
+
}
|
|
742
747
|
return;
|
|
743
748
|
}
|
|
744
749
|
|
|
@@ -751,20 +756,34 @@ function DropdownContent({
|
|
|
751
756
|
const listTop = list.getBoundingClientRect().top;
|
|
752
757
|
const lastTopWithinContent = lastSection.getBoundingClientRect().top - listTop + list.scrollTop;
|
|
753
758
|
const spaceBelowLastTop = naturalScrollHeight - lastTopWithinContent;
|
|
754
|
-
const pad = Math.max(0, available - spaceBelowLastTop);
|
|
759
|
+
const pad = Math.max(0, Math.round(available - spaceBelowLastTop));
|
|
760
|
+
|
|
761
|
+
// Only touch the DOM when the reserved space actually changes by a whole
|
|
762
|
+
// pixel — this ignores sub-pixel/floating jitter from the observer and
|
|
763
|
+
// keeps the value stable.
|
|
764
|
+
if (Math.abs(pad - bottomPadRef.current) < 1) return;
|
|
755
765
|
bottomPadRef.current = pad;
|
|
756
766
|
list.style.paddingBottom = `${pad}px`;
|
|
757
767
|
}
|
|
758
|
-
|
|
768
|
+
|
|
769
|
+
// Coalesce bursts of observer callbacks into a single measurement per frame.
|
|
770
|
+
function scheduleBottomSpace() {
|
|
771
|
+
if (rafId !== null) return;
|
|
772
|
+
rafId = requestAnimationFrame(computeBottomSpace);
|
|
773
|
+
}
|
|
774
|
+
scheduleBottomSpace();
|
|
759
775
|
|
|
760
776
|
// Observe both the container (viewport resize) and every section (group
|
|
761
777
|
// expand/collapse, late reflows) so the reserved space stays accurate.
|
|
762
|
-
const observer = new ResizeObserver(
|
|
778
|
+
const observer = new ResizeObserver(scheduleBottomSpace);
|
|
763
779
|
observer.observe(list);
|
|
764
780
|
list.querySelectorAll('[data-section-for]').forEach(section => {
|
|
765
781
|
observer.observe(section);
|
|
766
782
|
});
|
|
767
|
-
return () =>
|
|
783
|
+
return () => {
|
|
784
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
785
|
+
observer.disconnect();
|
|
786
|
+
};
|
|
768
787
|
}, [displayMode, contentRef, children, searchQuery]);
|
|
769
788
|
function handleSearch(e) {
|
|
770
789
|
fireEvent('search', {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diabolic/hangover",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A headless-style, compound React dropdown/field-picker component library",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "bugrakaan",
|
|
@@ -26,8 +26,7 @@
|
|
|
26
26
|
".": {
|
|
27
27
|
"import": "./dist/index.esm.js",
|
|
28
28
|
"require": "./dist/index.cjs.js"
|
|
29
|
-
}
|
|
30
|
-
"./styles": "./dist/hangover.css"
|
|
29
|
+
}
|
|
31
30
|
},
|
|
32
31
|
"files": [
|
|
33
32
|
"dist"
|