react-sticky-kit 0.3.0 โ†’ 0.3.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.
Files changed (2) hide show
  1. package/README.md +71 -33
  2. package/package.json +12 -7
package/README.md CHANGED
@@ -24,56 +24,90 @@
24
24
  </a>
25
25
  </p>
26
26
 
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.
28
-
29
- ## Features
30
-
31
- - ๐Ÿ“ฆ Simple API: `<StickyContainer>` and `<StickyItem>`
32
- - ๐Ÿงฉ Supports `replace`, `stack`, and `none` sticky modes
33
- - ๐Ÿท๏ธ Customizable offset, z-index (baseZIndex), and sticky logic
34
- - ๐Ÿ–ฅ๏ธ Viewport-relative sticky offsets, including updates on nested scroll events
35
- - ๐Ÿ”„ Supports SSR/SSG (Next.js, Gatsby, Astro, etc.)
36
- - ๐Ÿงช Handles edge cases: empty sections, dynamic heights, zero-height headers, long headers, etc.
37
- - โšก๏ธ Written in TypeScript, fully typed
38
- - ๐Ÿงช Includes demo pages for real-world scenarios
27
+ Coordinate multiple sticky section headers in React. Stack headers using their actual
28
+ heights, replace a section header as the next one arrives, or mix both behaviors
29
+ under a shared viewport offset.
30
+
31
+ **Use native CSS `position: sticky` for a single header or a straightforward grouped
32
+ list.** Choose React Sticky Kit when you need dynamic-height stacking, mixed
33
+ stack/replace behavior, or the total sticky height without maintaining your own
34
+ measurement and scroll logic.
35
+
36
+ ## See the behavior
37
+
38
+ | Replace section headings | Stack reached headings |
39
+ | --- | --- |
40
+ | ![Replacing section headers while scrolling](docs/assets/replace.gif) | ![Stacking section headers while scrolling](docs/assets/stack.gif) |
41
+
42
+ - **Replace:** an alphabetical contact list updates its section heading as you scroll.
43
+ - **Stack:** previously reached headings accumulate below the shared offset; their
44
+ heights are measured automatically, including when content changes.
45
+ - **Mixed:** keep a page title stacked while section headings replace below it.
46
+
47
+ [Open the live demo](https://app.evecalm.com/react-sticky-kit/) โ€” no installation required.
48
+ Try [replace](https://app.evecalm.com/react-sticky-kit/#replace),
49
+ [stack](https://app.evecalm.com/react-sticky-kit/#stack), or
50
+ [mixed modes](https://app.evecalm.com/react-sticky-kit/#mixed-mode).
51
+ The demo also includes dynamic heights, nested groups and container boundaries.
52
+ To edit an example, use the [contact-list sandbox](https://codesandbox.io/p/sandbox/dreamy-hofstadter-v9dzfz);
53
+ see [running the demo](#run-the-demo) for local development.
39
54
 
40
55
  ## Installation
41
56
 
42
57
  ```bash
43
58
  npm install react-sticky-kit
44
- # or
45
- yarn add react-sticky-kit
46
- # or
47
- pnpm add react-sticky-kit
59
+ # or: pnpm add react-sticky-kit
48
60
  ```
49
61
 
50
- ## Demo
51
- - [Apple iOS Contact App](https://codesandbox.io/p/sandbox/dreamy-hofstadter-v9dzfz)
62
+ ## Quick start: replacing section headers
52
63
 
53
- ## Usage
64
+ Import the stylesheet once. Give sections enough content to scroll; headers replace
65
+ one another within the container's boundary.
54
66
 
55
67
  ```tsx
56
68
  import { StickyContainer, StickyItem } from 'react-sticky-kit';
57
- // !! Import styles for sticky components
58
- import 'react-sticky-kit/dist/style.css';
59
- // or `import 'react-sticky-kit/style';` for more clean style path(require modern bundler tools)
69
+ import 'react-sticky-kit/style';
60
70
 
61
- export default function Example() {
71
+ export default function Sections() {
62
72
  return (
63
- <StickyContainer offsetTop={48} defaultMode="stack" baseZIndex={300}>
64
- <StickyItem>
65
- <div>Sticky Header</div>
66
- </StickyItem>
67
- <div>Content...</div>
68
- <StickyItem mode="replace">
69
- <div>Another Sticky Header (replace mode)</div>
70
- </StickyItem>
71
- <div>More Content...</div>
73
+ <StickyContainer defaultMode="replace" offsetTop={48}>
74
+ <StickyItem><h2 style={{ margin: 0, padding: 12, background: '#fff' }}>Overview</h2></StickyItem>
75
+ <section style={{ minHeight: 600 }}>Overview content</section>
76
+ <StickyItem><h2 style={{ margin: 0, padding: 12, background: '#fff' }}>Details</h2></StickyItem>
77
+ <section style={{ minHeight: 600 }}>Details content</section>
72
78
  </StickyContainer>
73
79
  );
74
80
  }
75
81
  ```
76
82
 
83
+ Change `defaultMode` to `"stack"` to retain previously reached headings. To keep a
84
+ page title above replacing section headings, add a first `<StickyItem mode="stack">`.
85
+ Offsets are relative to the **viewport**, including when scrolling an inner element.
86
+ For offsets relative to a scrollable panel, prefer native CSS sticky positioning.
87
+
88
+ ## Which approach should I choose?
89
+
90
+ | Need | Start with |
91
+ | --- | --- |
92
+ | A single sticky navigation bar or simple grouped list | Native CSS `position: sticky` |
93
+ | A sidebar taller than the viewport | A sidebar-focused solution such as `react-sticky-box` |
94
+ | Dynamic-height headers that stack automatically | React Sticky Kit, `stack` mode |
95
+ | A persistent title above replacing section headings | React Sticky Kit, mixed modes |
96
+ | The current total sticky height | `onStickyItemsHeightChange` |
97
+ | Table columns, built-in virtualization, or hide-on-scroll navigation | A solution designed for that specific interaction |
98
+
99
+ React Sticky Kit uses fixed positioning while active. It is not a drop-in
100
+ replacement for scroll-container-relative sticky behavior. Ancestor transforms
101
+ and overflow clipping can affect fixed positioning.
102
+
103
+ React 17/18/19, SSR and TypeScript 5 NodeNext consumers are covered by package
104
+ checks. The ESM artifact is approximately **3.48 kB gzip**, excluding React and CSS;
105
+ there are no additional runtime dependencies. See the
106
+ [performance audit](docs/performance.md) for methods and tradeoffs.
107
+
108
+ For practical examples and existing-library migration, see the
109
+ [patterns and migration guide](docs/patterns-and-migration.md).
110
+
77
111
  ## Props
78
112
 
79
113
  ### `<StickyContainer />`
@@ -129,7 +163,11 @@ When you set `constraint="none"`, the sticky items will always stick when they r
129
163
 
130
164
  In contrast, the default behavior (without specifying a constraint) only makes items sticky when their parent container is visible in the viewport.
131
165
 
132
- ## Demo
166
+ ## Run the demo
167
+
168
+ The demo builds as a standalone static site with `pnpm build:demo`. Its relative
169
+ asset paths work when hosted under a repository subdirectory.
170
+ See [deployment instructions](docs/demo-deployment.md) for GitHub Pages setup.
133
171
 
134
172
  Run the demo locally:
135
173
 
package/package.json CHANGED
@@ -1,15 +1,19 @@
1
1
  {
2
2
  "name": "react-sticky-kit",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
- "description": "A lightweight, flexible React sticky container and item component library supporting multiple sticky modes, advanced layouts, and edge cases.",
5
+ "description": "React components for stacked and replacing sticky section headers, with automatic height coordination and viewport offsets.",
6
6
  "keywords": [
7
7
  "react",
8
8
  "sticky",
9
+ "sticky-header",
10
+ "sticky-headers",
11
+ "sticky-section",
12
+ "stacked-headers",
9
13
  "react-sticky",
10
14
  "sticky-container",
11
- "sticky-item",
12
- "z-index"
15
+ "typescript",
16
+ "nextjs"
13
17
  ],
14
18
  "repository": {
15
19
  "type": "git",
@@ -18,14 +22,14 @@
18
22
  "bugs": {
19
23
  "url": "https://github.com/oe/react-sticky-kit/issues"
20
24
  },
21
- "homepage": "https://github.com/oe/react-sticky-kit#readme",
25
+ "homepage": "https://app.evecalm.com/react-sticky-kit/",
22
26
  "license": "MIT",
23
27
  "scripts": {
24
28
  "dev": "vite",
25
29
  "build": "vite build && tsc -p tsconfig.build.json && node scripts/build-types.mjs",
26
30
  "preview": "vite preview",
27
31
  "type-check": "tsc --noEmit",
28
- "lint": "eslint src demo test scripts vite.config.ts vitest.config.ts playwright.config.ts",
32
+ "lint": "eslint src demo test scripts vite.config.ts vite.demo.config.ts vitest.config.ts playwright.config.ts",
29
33
  "test": "vitest run",
30
34
  "test:watch": "vitest",
31
35
  "coverage": "vitest run --coverage",
@@ -33,7 +37,8 @@
33
37
  "check:package": "node scripts/check-package.mjs",
34
38
  "test:browser": "playwright test",
35
39
  "prepublishOnly": "pnpm type-check && pnpm lint && pnpm test && pnpm build && pnpm check:package",
36
- "check:compatibility": "node scripts/check-compatibility.mjs"
40
+ "check:compatibility": "node scripts/check-compatibility.mjs",
41
+ "build:demo": "vite build --config vite.demo.config.ts"
37
42
  },
38
43
  "files": [
39
44
  "dist"