@rainbow-oh/yee-c 0.4.0 → 0.4.1
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/dist/cjs/Anchor/anchor.js +29 -14
- package/dist/cjs/style/themes.css +1 -1
- package/dist/cjs/style/variables.css +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/Anchor/anchor.js +37 -15
- package/dist/esm/style/themes.css +1 -1
- package/dist/esm/style/variables.css +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/umd/yee-c.min.js +1 -1
- package/package.json +1 -1
- package/src/Anchor/anchor.tsx +35 -16
- package/src/version.ts +1 -1
package/package.json
CHANGED
package/src/Anchor/anchor.tsx
CHANGED
|
@@ -6,13 +6,11 @@ import React, {
|
|
|
6
6
|
useCallback,
|
|
7
7
|
useContext,
|
|
8
8
|
useEffect,
|
|
9
|
-
useLayoutEffect,
|
|
10
9
|
useRef,
|
|
11
10
|
useState,
|
|
12
11
|
} from 'react';
|
|
13
12
|
import { GlobalContext } from '../Config-Provider';
|
|
14
13
|
import useMergedState from '../hooks/useMergedState';
|
|
15
|
-
import debounce from '../utils/debounce';
|
|
16
14
|
import mergeContextToProps from '../utils/mergeContextToProps';
|
|
17
15
|
import AnchorItem from './anchor-item';
|
|
18
16
|
import type {
|
|
@@ -124,6 +122,8 @@ const Anchor = forwardRef<HTMLDivElement, AnchorProps>((baseprops, ref) => {
|
|
|
124
122
|
// Empty array guard
|
|
125
123
|
if (!currentItems || currentItems.length === 0) return;
|
|
126
124
|
|
|
125
|
+
// Pick the last anchor whose top has crossed the activation line.
|
|
126
|
+
let nextActiveKey: string | undefined;
|
|
127
127
|
for (let i = currentItems.length - 1; i >= 0; i--) {
|
|
128
128
|
const item = currentItems[i];
|
|
129
129
|
const target = document.getElementById(item.key);
|
|
@@ -131,27 +131,50 @@ const Anchor = forwardRef<HTMLDivElement, AnchorProps>((baseprops, ref) => {
|
|
|
131
131
|
if (target) {
|
|
132
132
|
const targetTop = getTargetOffsetTop(target);
|
|
133
133
|
if (scrollTop + offsetTop >= targetTop) {
|
|
134
|
-
|
|
135
|
-
setMergedActiveKey(item.key);
|
|
136
|
-
onChange?.(item.key);
|
|
137
|
-
}
|
|
134
|
+
nextActiveKey = item.key;
|
|
138
135
|
break;
|
|
139
136
|
}
|
|
140
137
|
}
|
|
141
138
|
}
|
|
139
|
+
|
|
140
|
+
// Scrolled above the first anchor — reset to the top item.
|
|
141
|
+
if (nextActiveKey === undefined) {
|
|
142
|
+
const first = currentItems.find(
|
|
143
|
+
(item) => document.getElementById(item.key),
|
|
144
|
+
);
|
|
145
|
+
nextActiveKey = first?.key;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (nextActiveKey && activeKeyRef.current !== nextActiveKey) {
|
|
149
|
+
setMergedActiveKey(nextActiveKey);
|
|
150
|
+
onChange?.(nextActiveKey);
|
|
151
|
+
}
|
|
142
152
|
}, [auto, anchorList, items, offsetTop, onChange, getTargetOffsetTop]);
|
|
143
153
|
|
|
144
154
|
useEffect(() => {
|
|
145
|
-
|
|
155
|
+
// Resolve in a passive effect: parent-owned refs passed via `getContainer`
|
|
156
|
+
// aren't attached until after child layout effects run.
|
|
157
|
+
const container = getContainer ? getContainer() : window;
|
|
158
|
+
containerRef.current = container;
|
|
146
159
|
if (!container) return;
|
|
147
160
|
|
|
148
|
-
|
|
149
|
-
|
|
161
|
+
// rAF throttle so the active key tracks scroll live.
|
|
162
|
+
let rafId: ReturnType<typeof requestAnimationFrame> | null = null;
|
|
163
|
+
const onScroll = () => {
|
|
164
|
+
if (rafId !== null) return;
|
|
165
|
+
rafId = requestAnimationFrame(() => {
|
|
166
|
+
rafId = null;
|
|
167
|
+
handleScroll();
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
container.addEventListener('scroll', onScroll as EventListener);
|
|
150
171
|
handleScroll();
|
|
151
172
|
|
|
152
173
|
return () => {
|
|
153
|
-
container.removeEventListener('scroll',
|
|
154
|
-
|
|
174
|
+
container.removeEventListener('scroll', onScroll as EventListener);
|
|
175
|
+
if (rafId !== null) {
|
|
176
|
+
cancelAnimationFrame(rafId);
|
|
177
|
+
}
|
|
155
178
|
};
|
|
156
179
|
}, [getContainer, handleScroll]);
|
|
157
180
|
|
|
@@ -178,11 +201,7 @@ const Anchor = forwardRef<HTMLDivElement, AnchorProps>((baseprops, ref) => {
|
|
|
178
201
|
[offsetTop, getTargetOffsetTop],
|
|
179
202
|
);
|
|
180
203
|
|
|
181
|
-
|
|
182
|
-
containerRef.current = getContainer ? getContainer() : window;
|
|
183
|
-
}, [getContainer]);
|
|
184
|
-
|
|
185
|
-
useLayoutEffect(() => {
|
|
204
|
+
useEffect(() => {
|
|
186
205
|
if (defaultActiveKey) {
|
|
187
206
|
scrollToAnchor(defaultActiveKey);
|
|
188
207
|
}
|