react-sticky-kit 0.1.5 → 0.1.6
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 +60 -1
- package/dist/react-sticky.es.js +81 -84
- package/dist/react-sticky.umd.js +1 -1
- package/package.json +15 -4
package/README.md
CHANGED
|
@@ -4,15 +4,24 @@
|
|
|
4
4
|
<a href="https://www.npmjs.com/package/react-sticky-kit" target="_blank">
|
|
5
5
|
<img src="https://img.shields.io/npm/v/react-sticky-kit.svg?style=flat-square" alt="NPM Version" />
|
|
6
6
|
</a>
|
|
7
|
+
<a href="https://img.shields.io/npm/dm/react-sticky-kit?style=flat-square" target="_blank">
|
|
8
|
+
<img src="https://img.shields.io/npm/dm/react-sticky-kit?style=flat-square" alt="NPM Downloads" />
|
|
9
|
+
</a>
|
|
7
10
|
<a href="https://github.com/oe/react-sticky-kit" target="_blank">
|
|
8
11
|
<img src="https://img.shields.io/github/stars/oe/react-sticky-kit?style=flat-square" alt="GitHub Stars" />
|
|
9
12
|
</a>
|
|
10
13
|
<a href="https://github.com/oe/react-sticky-kit/actions" target="_blank">
|
|
11
|
-
<img src="https://
|
|
14
|
+
<img src="https://img.shields.io/github/actions/workflow/status/oe/react-sticky-kit/ci.yml?style=flat-square" alt="Build Status" />
|
|
12
15
|
</a>
|
|
13
16
|
<a href="https://github.com/oe/react-sticky-kit/blob/main/LICENSE" target="_blank">
|
|
14
17
|
<img src="https://img.shields.io/github/license/oe/react-sticky-kit?style=flat-square" alt="License" />
|
|
15
18
|
</a>
|
|
19
|
+
<a href="https://www.typescriptlang.org/" target="_blank">
|
|
20
|
+
<img src="https://img.shields.io/badge/TypeScript-5.0%2B-blue?logo=typescript&style=flat-square" alt="TypeScript" />
|
|
21
|
+
</a>
|
|
22
|
+
<a href="#ssr-ssg-support" target="_blank">
|
|
23
|
+
<img src="https://img.shields.io/badge/SSR%2FSSG-Compatible-brightgreen?style=flat-square" alt="SSR/SSG Compatible" />
|
|
24
|
+
</a>
|
|
16
25
|
</p>
|
|
17
26
|
|
|
18
27
|
A lightweight, flexible React sticky container and item component library. Easily create sticky headers, sections, and advanced sticky layouts with support for multiple modes and edge cases.
|
|
@@ -22,6 +31,7 @@ A lightweight, flexible React sticky container and item component library. Easil
|
|
|
22
31
|
- 📦 Simple API: `<StickyContainer>` and `<StickyItem>`
|
|
23
32
|
- 🧩 Supports `replace`, `stack`, and `none` sticky modes
|
|
24
33
|
- 🏷️ Customizable offset, z-index (baseZIndex), and sticky logic
|
|
34
|
+
- 🔄 Supports SSR/SSG (Next.js, Gatsby, Astro, etc.)
|
|
25
35
|
- 🧪 Handles edge cases: empty sections, dynamic heights, zero-height headers, long headers, etc.
|
|
26
36
|
- ⚡️ Written in TypeScript, fully typed
|
|
27
37
|
- 🧪 Includes demo pages for real-world scenarios
|
|
@@ -36,6 +46,9 @@ yarn add react-sticky-kit
|
|
|
36
46
|
pnpm add react-sticky-kit
|
|
37
47
|
```
|
|
38
48
|
|
|
49
|
+
## Demo
|
|
50
|
+
- [Apple iOS Contact App](https://codesandbox.io/p/sandbox/dreamy-hofstadter-v9dzfz)
|
|
51
|
+
|
|
39
52
|
## Usage
|
|
40
53
|
|
|
41
54
|
```tsx
|
|
@@ -95,6 +108,52 @@ Open [http://localhost:5173](http://localhost:5173) and switch between demo page
|
|
|
95
108
|
* [Mixed mode](http://localhost:5173/#mixed-mode) mix replace/stack/none mode
|
|
96
109
|
* [Nested](http://localhost:5173/#dynamic-height) nest sticky containers
|
|
97
110
|
* [Dynamic sticky items](http://localhost:5173/#nested) dynamic sticky items(add/remove)
|
|
111
|
+
* [Dynamic offsetTop](http://localhost:5173/#dynamic-offset) dynamic offsetTop that adapts to header height changes
|
|
112
|
+
|
|
113
|
+
## SSR/SSG Support
|
|
114
|
+
|
|
115
|
+
React Sticky Kit supports Server-Side Rendering (SSR) and Static Site Generation (SSG), working seamlessly with frameworks like Next.js, Gatsby, Astro, and more.
|
|
116
|
+
|
|
117
|
+
### Next.js Example
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
// pages/index.tsx
|
|
121
|
+
import { StickyContainer, StickyItem } from 'react-sticky-kit'
|
|
122
|
+
import 'react-sticky-kit/dist/style.css'
|
|
123
|
+
|
|
124
|
+
export default function Home() {
|
|
125
|
+
return (
|
|
126
|
+
<StickyContainer>
|
|
127
|
+
<StickyItem>
|
|
128
|
+
<header>Sticky Header</header>
|
|
129
|
+
</StickyItem>
|
|
130
|
+
<main>Content...</main>
|
|
131
|
+
</StickyContainer>
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Astro Example
|
|
137
|
+
|
|
138
|
+
```astro
|
|
139
|
+
---
|
|
140
|
+
// src/pages/index.astro
|
|
141
|
+
import { StickyContainer, StickyItem } from 'react-sticky-kit'
|
|
142
|
+
import 'react-sticky-kit/dist/style.css'
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
<html>
|
|
146
|
+
<head>...</head>
|
|
147
|
+
<body>
|
|
148
|
+
<StickyContainer client:load>
|
|
149
|
+
<StickyItem>
|
|
150
|
+
<header>Sticky Header</header>
|
|
151
|
+
</StickyItem>
|
|
152
|
+
<div>Content...</div>
|
|
153
|
+
</StickyContainer>
|
|
154
|
+
</body>
|
|
155
|
+
</html>
|
|
156
|
+
```
|
|
98
157
|
|
|
99
158
|
## License
|
|
100
159
|
|
package/dist/react-sticky.es.js
CHANGED
|
@@ -1,66 +1,62 @@
|
|
|
1
1
|
import { jsx as R } from "react/jsx-runtime";
|
|
2
|
-
import { createContext as b, useContext as
|
|
3
|
-
const x = 20,
|
|
2
|
+
import { createContext as b, useContext as Z, useRef as h, useState as L, useEffect as E, useCallback as w, useMemo as N } from "react";
|
|
3
|
+
const x = 20, T = 200, $ = b(null);
|
|
4
4
|
function _() {
|
|
5
|
-
return
|
|
5
|
+
return Z($);
|
|
6
6
|
}
|
|
7
|
-
function
|
|
8
|
-
const e = _(),
|
|
7
|
+
function F({ mode: u, children: f, className: g, ...k }) {
|
|
8
|
+
const e = _(), S = h(null), I = h(null), [r, m] = L(!1), t = h({
|
|
9
9
|
fixedOffsetTop: (e == null ? void 0 : e.fixedOffsetTop) || 0,
|
|
10
10
|
isSticky: r,
|
|
11
11
|
baseZIndex: (e == null ? void 0 : e.baseZIndex) || x
|
|
12
12
|
});
|
|
13
|
-
return
|
|
14
|
-
const
|
|
15
|
-
if (!e || !
|
|
16
|
-
|
|
13
|
+
return t.current.baseZIndex = (e == null ? void 0 : e.baseZIndex) || x, t.current.fixedOffsetTop = (e == null ? void 0 : e.fixedOffsetTop) || 0, t.current.isSticky = r, E(() => {
|
|
14
|
+
const n = I.current, a = S.current, l = u || (e == null ? void 0 : e.mode);
|
|
15
|
+
if (!e || !a || !n || l === "none" || !l || !e.register) {
|
|
16
|
+
m(!1);
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
|
-
const
|
|
20
|
-
el:
|
|
21
|
-
update: (d,
|
|
22
|
-
if (!d)
|
|
23
|
-
return
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return f.style.height = `${h}px`, n.current.isSticky || t(!0), u.style.top = `${v}px`, u.style.width = `${f.offsetWidth}px`, u.style.zIndex = `${n.current.baseZIndex + (a === "replace" ? -H : H)}`, a === "replace" ? 0 : h;
|
|
33
|
-
} else
|
|
34
|
-
t(!1);
|
|
35
|
-
return 0;
|
|
19
|
+
const s = {
|
|
20
|
+
el: a,
|
|
21
|
+
update: (d, c, i, o, C) => {
|
|
22
|
+
if (!d || c > i)
|
|
23
|
+
return t.current.isSticky && m(!1), 0;
|
|
24
|
+
const p = n.getBoundingClientRect().height;
|
|
25
|
+
let H = i;
|
|
26
|
+
if (l === "replace" && typeof o < "u") {
|
|
27
|
+
const y = o - (i + p);
|
|
28
|
+
if (y < 0 && (H = i + y, y + p < 0))
|
|
29
|
+
return t.current.isSticky && m(!1), 0;
|
|
30
|
+
}
|
|
31
|
+
return a.style.height = `${p}px`, t.current.isSticky || m(!0), n.style.top = `${H}px`, n.style.width = `${a.offsetWidth}px`, n.style.zIndex = `${t.current.baseZIndex + (l === "replace" ? -C : C)}`, l === "replace" ? 0 : p;
|
|
36
32
|
}
|
|
37
33
|
};
|
|
38
|
-
return e.register(
|
|
39
|
-
}, [e == null ? void 0 : e.mode, e == null ? void 0 : e.register,
|
|
40
|
-
const
|
|
41
|
-
if (!r || !
|
|
34
|
+
return e.register(s);
|
|
35
|
+
}, [e == null ? void 0 : e.mode, e == null ? void 0 : e.register, u]), E(() => {
|
|
36
|
+
const n = S.current, a = I.current, l = e == null ? void 0 : e.updateStickyItemsHeight;
|
|
37
|
+
if (!r || !n || !a || !l)
|
|
42
38
|
return;
|
|
43
|
-
const
|
|
39
|
+
const v = l(a.getBoundingClientRect().height);
|
|
44
40
|
return () => {
|
|
45
|
-
O(
|
|
41
|
+
O(n, ["height"]), O(a, ["top", "z-index", "width"]), v();
|
|
46
42
|
};
|
|
47
|
-
}, [r, e == null ? void 0 : e.updateStickyItemsHeight]), /* @__PURE__ */ R("div", { className: "oe-sticky-item " + (
|
|
43
|
+
}, [r, e == null ? void 0 : e.updateStickyItemsHeight]), /* @__PURE__ */ R("div", { className: "oe-sticky-item " + (g || ""), ...k, ref: S, children: /* @__PURE__ */ R("div", { className: "oe-sticky-content " + (r ? "is-sticky" : ""), ref: I, children: f }) });
|
|
48
44
|
}
|
|
49
|
-
function O(
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
function O(u, f) {
|
|
46
|
+
f.forEach((g) => {
|
|
47
|
+
u.style.removeProperty(g);
|
|
52
48
|
});
|
|
53
49
|
}
|
|
54
|
-
function
|
|
55
|
-
children:
|
|
56
|
-
offsetTop:
|
|
57
|
-
baseZIndex:
|
|
50
|
+
function M({
|
|
51
|
+
children: u,
|
|
52
|
+
offsetTop: f = 0,
|
|
53
|
+
baseZIndex: g,
|
|
58
54
|
onStickyItemsHeightChange: k,
|
|
59
55
|
defaultMode: e = "replace",
|
|
60
|
-
...
|
|
56
|
+
...S
|
|
61
57
|
}) {
|
|
62
|
-
const I =
|
|
63
|
-
fixedOffsetTop:
|
|
58
|
+
const I = h(null), r = h([]), m = h(null), t = h({
|
|
59
|
+
fixedOffsetTop: f,
|
|
64
60
|
defaultMode: e,
|
|
65
61
|
stickyItemsHeight: 0,
|
|
66
62
|
onStickyItemsHeightChange: k,
|
|
@@ -69,77 +65,78 @@ function P({
|
|
|
69
65
|
t.current.onStickyItemsHeightChange = k;
|
|
70
66
|
const n = w(() => {
|
|
71
67
|
const s = I.current;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
68
|
+
!s || m.current || (m.current = requestAnimationFrame(() => {
|
|
69
|
+
m.current = null;
|
|
70
|
+
const d = s.getBoundingClientRect(), { fixedOffsetTop: c, stickyItemsHeight: i } = t.current, o = !(d.top > c || d.bottom < c);
|
|
71
|
+
if (!o) {
|
|
72
|
+
t.current.lastCanSticky !== o && (s.classList.toggle("can-sticky", !1), r.current.forEach((y) => y.update(!1, 0, 0, 0, 0)), t.current.lastCanSticky = o);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
t.current.lastCanSticky = o, i > 0 && s.classList.toggle("can-sticky", !0);
|
|
76
|
+
let C = c, p = d.bottom - (c + i);
|
|
77
|
+
p > 0 && (p = 0);
|
|
78
|
+
const H = r.current.map((y) => y.el.getBoundingClientRect().top);
|
|
79
|
+
r.current.forEach((y, B) => {
|
|
80
|
+
C += y.update(o, H[B], C + p, H[B + 1], B);
|
|
81
|
+
});
|
|
82
|
+
}));
|
|
83
|
+
}, []), a = w((s) => {
|
|
84
|
+
const d = t.current.stickyItemsHeight + s;
|
|
85
|
+
return t.current.stickyItemsHeight = d, setTimeout(() => {
|
|
86
|
+
var c, i;
|
|
87
|
+
(i = (c = t.current).onStickyItemsHeightChange) == null || i.call(c, d);
|
|
91
88
|
}, 0), () => {
|
|
92
|
-
const
|
|
93
|
-
t.current.stickyItemsHeight =
|
|
94
|
-
var i,
|
|
95
|
-
(
|
|
89
|
+
const c = t.current.stickyItemsHeight - s;
|
|
90
|
+
t.current.stickyItemsHeight = c, setTimeout(() => {
|
|
91
|
+
var i, o;
|
|
92
|
+
(o = (i = t.current).onStickyItemsHeightChange) == null || o.call(i, c);
|
|
96
93
|
}, 0);
|
|
97
94
|
};
|
|
98
95
|
}, []);
|
|
99
96
|
E(() => {
|
|
100
|
-
t.current.fixedOffsetTop =
|
|
97
|
+
t.current.fixedOffsetTop = f, t.current.defaultMode = e, setTimeout(() => {
|
|
101
98
|
n();
|
|
102
99
|
}, 10);
|
|
103
|
-
}, [
|
|
104
|
-
const
|
|
105
|
-
r.current = r.current.filter((
|
|
100
|
+
}, [f, e, n]);
|
|
101
|
+
const l = w((s) => (r.current.push(s), r.current = z(r.current), n(), () => {
|
|
102
|
+
r.current = r.current.filter((d) => d !== s), n();
|
|
106
103
|
}), [n]);
|
|
107
104
|
E(() => (window.addEventListener("scroll", n, { passive: !0 }), window.addEventListener("resize", n, { passive: !0 }), () => {
|
|
108
105
|
window.removeEventListener("scroll", n), window.removeEventListener("resize", n);
|
|
109
106
|
}), [n]);
|
|
110
|
-
const
|
|
107
|
+
const v = N(() => A(g), [g]);
|
|
111
108
|
return /* @__PURE__ */ R(
|
|
112
109
|
$.Provider,
|
|
113
110
|
{
|
|
114
111
|
value: {
|
|
115
|
-
register:
|
|
116
|
-
baseZIndex:
|
|
117
|
-
updateStickyItemsHeight:
|
|
118
|
-
fixedOffsetTop:
|
|
112
|
+
register: l,
|
|
113
|
+
baseZIndex: v,
|
|
114
|
+
updateStickyItemsHeight: a,
|
|
115
|
+
fixedOffsetTop: f,
|
|
119
116
|
mode: e
|
|
120
117
|
},
|
|
121
118
|
children: /* @__PURE__ */ R(
|
|
122
119
|
"div",
|
|
123
120
|
{
|
|
124
|
-
...
|
|
121
|
+
...S,
|
|
125
122
|
ref: I,
|
|
126
123
|
className: "oe-sticky-container",
|
|
127
|
-
children:
|
|
124
|
+
children: u
|
|
128
125
|
}
|
|
129
126
|
)
|
|
130
127
|
}
|
|
131
128
|
);
|
|
132
129
|
}
|
|
133
|
-
function
|
|
134
|
-
return typeof
|
|
130
|
+
function A(u) {
|
|
131
|
+
return typeof u > "u" ? T : Math.max(Number(u) || 0, x);
|
|
135
132
|
}
|
|
136
|
-
function
|
|
137
|
-
return
|
|
138
|
-
const k =
|
|
133
|
+
function z(u) {
|
|
134
|
+
return u.sort((f, g) => {
|
|
135
|
+
const k = f.el.getBoundingClientRect(), e = g.el.getBoundingClientRect();
|
|
139
136
|
return k.top - e.top;
|
|
140
137
|
});
|
|
141
138
|
}
|
|
142
139
|
export {
|
|
143
|
-
|
|
144
|
-
|
|
140
|
+
M as StickyContainer,
|
|
141
|
+
F as StickyItem
|
|
145
142
|
};
|
package/dist/react-sticky.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(p,m){typeof exports=="object"&&typeof module<"u"?m(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],m):(p=typeof globalThis<"u"?globalThis:p||self,m(p.ReactSticky={},p.jsxRuntime,p.React))})(this,function(p,m,r){"use strict";const B=r.createContext(null);function x(){return r.useContext(B)}const $="";function Z({mode:o,children:l,className:h,...S}){const e=x(),C=r.useRef(null),E=r.useRef(null),[s,k]=r.useState(!1),t=r.useRef({fixedOffsetTop:(e==null?void 0:e.fixedOffsetTop)||0,isSticky:s,baseZIndex:(e==null?void 0:e.baseZIndex)||20});return t.current.baseZIndex=(e==null?void 0:e.baseZIndex)||20,t.current.fixedOffsetTop=(e==null?void 0:e.fixedOffsetTop)||0,t.current.isSticky=s,r.useEffect(()=>{const n=E.current,d=C.current,a=o||(e==null?void 0:e.mode);if(!e||!d||!n||a==="none"||!a||!e.register){k(!1);return}const c={el:d,update:(y,u,i,f,R)=>{if(!y||u>i)return t.current.isSticky&&k(!1),0;const I=n.getBoundingClientRect().height;let _=i;if(a==="replace"&&typeof f<"u"){const g=f-(i+I);if(g<0&&(_=i+g,g+I<0))return t.current.isSticky&&k(!1),0}return d.style.height=`${I}px`,t.current.isSticky||k(!0),n.style.top=`${_}px`,n.style.width=`${d.offsetWidth}px`,n.style.zIndex=`${t.current.baseZIndex+(a==="replace"?-R:R)}`,a==="replace"?0:I}};return e.register(c)},[e==null?void 0:e.mode,e==null?void 0:e.register,o]),r.useEffect(()=>{const n=C.current,d=E.current,a=e==null?void 0:e.updateStickyItemsHeight;if(!s||!n||!d||!a)return;const H=a(d.getBoundingClientRect().height);return()=>{N(n,["height"]),N(d,["top","z-index","width"]),H()}},[s,e==null?void 0:e.updateStickyItemsHeight]),m.jsx("div",{className:"oe-sticky-item "+(h||""),...S,ref:C,children:m.jsx("div",{className:"oe-sticky-content "+(s?"is-sticky":""),ref:E,children:l})})}function N(o,l){l.forEach(h=>{o.style.removeProperty(h)})}function b({children:o,offsetTop:l=0,baseZIndex:h,onStickyItemsHeightChange:S,defaultMode:e="replace",...C}){const E=r.useRef(null),s=r.useRef([]),k=r.useRef(null),t=r.useRef({fixedOffsetTop:l,defaultMode:e,stickyItemsHeight:0,onStickyItemsHeightChange:S,lastCanSticky:!1});t.current.onStickyItemsHeightChange=S;const n=r.useCallback(()=>{const c=E.current;!c||k.current||(k.current=requestAnimationFrame(()=>{k.current=null;const y=c.getBoundingClientRect(),{fixedOffsetTop:u,stickyItemsHeight:i}=t.current,f=!(y.top>u||y.bottom<u);if(!f){t.current.lastCanSticky!==f&&(c.classList.toggle("can-sticky",!1),s.current.forEach(g=>g.update(!1,0,0,0,0)),t.current.lastCanSticky=f);return}t.current.lastCanSticky=f,i>0&&c.classList.toggle("can-sticky",!0);let R=u,I=y.bottom-(u+i);I>0&&(I=0);const _=s.current.map(g=>g.el.getBoundingClientRect().top);s.current.forEach((g,v)=>{R+=g.update(f,_[v],R+I,_[v+1],v)})}))},[]),d=r.useCallback(c=>{const y=t.current.stickyItemsHeight+c;return t.current.stickyItemsHeight=y,setTimeout(()=>{var u,i;(i=(u=t.current).onStickyItemsHeightChange)==null||i.call(u,y)},0),()=>{const u=t.current.stickyItemsHeight-c;t.current.stickyItemsHeight=u,setTimeout(()=>{var i,f;(f=(i=t.current).onStickyItemsHeightChange)==null||f.call(i,u)},0)}},[]);r.useEffect(()=>{t.current.fixedOffsetTop=l,t.current.defaultMode=e,setTimeout(()=>{n()},10)},[l,e,n]);const a=r.useCallback(c=>(s.current.push(c),s.current=O(s.current),n(),()=>{s.current=s.current.filter(y=>y!==c),n()}),[n]);r.useEffect(()=>(window.addEventListener("scroll",n,{passive:!0}),window.addEventListener("resize",n,{passive:!0}),()=>{window.removeEventListener("scroll",n),window.removeEventListener("resize",n)}),[n]);const H=r.useMemo(()=>w(h),[h]);return m.jsx(B.Provider,{value:{register:a,baseZIndex:H,updateStickyItemsHeight:d,fixedOffsetTop:l,mode:e},children:m.jsx("div",{...C,ref:E,className:"oe-sticky-container",children:o})})}function w(o){return typeof o>"u"?200:Math.max(Number(o)||0,20)}function O(o){return o.sort((l,h)=>{const S=l.el.getBoundingClientRect(),e=h.el.getBoundingClientRect();return S.top-e.top})}p.StickyContainer=b,p.StickyItem=Z,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-sticky-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A lightweight, flexible React sticky container and item component library supporting multiple sticky modes, advanced layouts, and edge cases.",
|
|
6
6
|
"keywords": [
|
|
@@ -26,6 +26,9 @@
|
|
|
26
26
|
"preview": "vite preview",
|
|
27
27
|
"type-check": "tsc --noEmit",
|
|
28
28
|
"lint": "eslint src demo --ext .ts,.tsx,.js,.jsx",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test:watch": "vitest",
|
|
31
|
+
"coverage": "vitest run --coverage",
|
|
29
32
|
"pub": "tsx ./scripts/publish.ts"
|
|
30
33
|
},
|
|
31
34
|
"files": [
|
|
@@ -36,9 +39,9 @@
|
|
|
36
39
|
"types": "dist/index.d.ts",
|
|
37
40
|
"exports": {
|
|
38
41
|
".": {
|
|
42
|
+
"types": "./dist/index.d.ts",
|
|
39
43
|
"import": "./dist/react-sticky.es.js",
|
|
40
|
-
"require": "./dist/react-sticky.umd.js"
|
|
41
|
-
"types": "./dist/index.d.ts"
|
|
44
|
+
"require": "./dist/react-sticky.umd.js"
|
|
42
45
|
},
|
|
43
46
|
"./style": "./dist/style.css",
|
|
44
47
|
"./dist/style.css": "./dist/style.css"
|
|
@@ -49,25 +52,33 @@
|
|
|
49
52
|
},
|
|
50
53
|
"devDependencies": {
|
|
51
54
|
"@eslint/js": "^9.25.0",
|
|
55
|
+
"@testing-library/jest-dom": "^6.1.6",
|
|
56
|
+
"@testing-library/react": "^14.1.2",
|
|
57
|
+
"@testing-library/user-event": "^14.4.3",
|
|
52
58
|
"@types/node": "^22.15.18",
|
|
53
59
|
"@types/react": "^19.1.2",
|
|
54
60
|
"@types/react-dom": "^19.1.2",
|
|
55
61
|
"@typescript-eslint/eslint-plugin": "^8.32.1",
|
|
56
62
|
"@typescript-eslint/parser": "^8.32.1",
|
|
57
63
|
"@vitejs/plugin-react": "^4.0.0",
|
|
64
|
+
"@vitest/coverage-v8": "^3.1.3",
|
|
58
65
|
"eslint": "^9.26.0",
|
|
59
66
|
"eslint-config-prettier": "^10.1.5",
|
|
60
67
|
"eslint-plugin-jsx-a11y": "^6.8.0",
|
|
61
68
|
"eslint-plugin-react": "^7.33.2",
|
|
62
69
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
63
70
|
"globals": "^16.0.0",
|
|
71
|
+
"identity-obj-proxy": "^3.0.0",
|
|
72
|
+
"jsdom": "^26.1.0",
|
|
64
73
|
"react": "^19.1.0",
|
|
65
74
|
"react-dom": "^19.1.0",
|
|
66
75
|
"sass": "^1.88.0",
|
|
76
|
+
"ts-node": "^10.9.2",
|
|
67
77
|
"tsx": "^4.19.4",
|
|
68
78
|
"typescript": "^5.0.0",
|
|
69
79
|
"typescript-eslint": "^8.30.1",
|
|
70
80
|
"vite": "^4.0.0",
|
|
71
|
-
"vite-plugin-dts": "^4.5.4"
|
|
81
|
+
"vite-plugin-dts": "^4.5.4",
|
|
82
|
+
"vitest": "^3.1.3"
|
|
72
83
|
}
|
|
73
84
|
}
|