Skip to content

Commit 7a0813d

Browse files
authored
feat: align support htmlRegion config (#332)
* docs: update demo * chore: update align of scroll region
1 parent 1b2e10b commit 7a0813d

File tree

3 files changed

+42
-17
lines changed

3 files changed

+42
-17
lines changed

docs/examples/container.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const builtinPlacements = {
3535
adjustY: true,
3636
},
3737
offset: [0, 10],
38+
htmlRegion: 'scroll' as const,
3839
},
3940
left: {
4041
points: ['cr', 'cl'],
@@ -54,7 +55,7 @@ const builtinPlacements = {
5455
},
5556
};
5657

57-
const popupPlacement = 'topLeft';
58+
const popupPlacement = 'bottom';
5859

5960
export default () => {
6061
console.log('Demo Render!');
@@ -140,7 +141,7 @@ export default () => {
140141
</div>
141142
}
142143
popupStyle={{ boxShadow: '0 0 5px red' }}
143-
// popupVisible
144+
popupVisible
144145
// getPopupContainer={() => popHolderRef.current}
145146
popupPlacement={popupPlacement}
146147
builtinPlacements={builtinPlacements}
@@ -163,6 +164,8 @@ export default () => {
163164
</div>
164165
</div>
165166
</div>
167+
168+
{/* <div style={{ height: '100vh' }} /> */}
166169
</React.StrictMode>
167170
);
168171
};

src/hooks/useAlign.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ export default function useAlign(
126126
const doc = popupElement.ownerDocument;
127127
const win = getWin(popupElement);
128128

129+
// Placement
130+
const placementInfo: AlignType =
131+
builtinPlacements[placement] || popupAlign || {};
132+
129133
// Reset first
130134
popupElement.style.left = '0';
131135
popupElement.style.top = '0';
@@ -150,18 +154,34 @@ export default function useAlign(
150154
}
151155
const popupRect = popupElement.getBoundingClientRect();
152156
const { width, height } = win.getComputedStyle(popupElement);
153-
const { clientWidth, clientHeight } = doc.documentElement;
157+
const {
158+
clientWidth,
159+
clientHeight,
160+
scrollWidth,
161+
scrollHeight,
162+
scrollTop,
163+
scrollLeft,
164+
} = doc.documentElement;
154165

155166
const popupHeight = popupRect.height;
156167
const popupWidth = popupRect.width;
157168

158169
// Get bounding of visible area
159-
const visibleArea = {
160-
left: 0,
161-
top: 0,
162-
right: clientWidth,
163-
bottom: clientHeight,
164-
};
170+
const visibleArea =
171+
placementInfo.htmlRegion === 'scroll'
172+
? // Scroll region should take scrollLeft & scrollTop into account
173+
{
174+
left: -scrollLeft,
175+
top: -scrollTop,
176+
right: scrollWidth - scrollLeft,
177+
bottom: scrollHeight - scrollTop,
178+
}
179+
: {
180+
left: 0,
181+
top: 0,
182+
right: clientWidth,
183+
bottom: clientHeight,
184+
};
165185

166186
(scrollerList || []).forEach((ele) => {
167187
const eleRect = ele.getBoundingClientRect();
@@ -179,10 +199,10 @@ export default function useAlign(
179199
Math.round((eleRect.height / eleOutHeight) * 1000) / 1000,
180200
);
181201

182-
const scrollWidth = (eleOutWidth - eleInnerWidth) * scaleX;
183-
const scrollHeight = (eleOutHeight - eleInnerHeight) * scaleY;
184-
const eleRight = eleRect.x + eleRect.width - scrollWidth;
185-
const eleBottom = eleRect.y + eleRect.height - scrollHeight;
202+
const eleScrollWidth = (eleOutWidth - eleInnerWidth) * scaleX;
203+
const eleScrollHeight = (eleOutHeight - eleInnerHeight) * scaleY;
204+
const eleRight = eleRect.x + eleRect.width - eleScrollWidth;
205+
const eleBottom = eleRect.y + eleRect.height - eleScrollHeight;
186206

187207
visibleArea.left = Math.max(visibleArea.left, eleRect.left);
188208
visibleArea.top = Math.max(visibleArea.top, eleRect.top);
@@ -202,10 +222,6 @@ export default function useAlign(
202222
Math.round((popupHeight / parseFloat(height)) * 1000) / 1000,
203223
);
204224

205-
// Placement
206-
const placementInfo: AlignType =
207-
builtinPlacements[placement] || popupAlign || {};
208-
209225
// Offset
210226
const { offset, targetOffset } = placementInfo;
211227
const [popupOffsetX = 0, popupOffsetY = 0] = offset || [];

src/interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ export interface AlignType {
4848
};
4949
/** Auto adjust arrow position */
5050
autoArrow?: boolean;
51+
/**
52+
* Config visible region check of html node. Default `visible`:
53+
* - `visible`: The visible region of user browser window. Use `clientHeight` for check.
54+
* - `scroll`: The whole region of the html scroll area. Use `scrollHeight` for check.
55+
*/
56+
htmlRegion?: 'visible' | 'scroll';
5157
/**
5258
* Whether use css right instead of left to position
5359
*/

0 commit comments

Comments
 (0)