├── .editorconfig
├── .gitignore
├── .npmignore
├── .prettierrc
├── .travis.yml
├── LICENSE
├── README.md
├── docs
├── examples.41ea0a7a.js
├── examples.41ea0a7a.js.map
├── examples.68d19066.css
├── examples.68d19066.css.map
├── index.html
├── legacy-browsers.68d19066.css
├── legacy-browsers.68d19066.css.map
├── legacy-browsers.71815c21.js
├── legacy-browsers.71815c21.js.map
└── legacy-browsers.html
├── examples
├── index.html
├── index.tsx
├── legacy-browsers.html
├── legacy-browsers.ts
└── styles.css
├── jest.config.js
├── lib
├── ElementResizeObserver.tsx
├── Sticky.tsx
├── StickyElement.tsx
├── StickyPlaceholder.tsx
├── StickyProvider.tsx
├── StickyScrollUp.tsx
├── __tests__
│ ├── browser.test.tsx
│ └── server.test.tsx
├── globals.d.ts
├── index.ts
├── types.ts
└── utils.ts
├── package-lock.json
├── package.json
├── rollup.config.js
├── tsconfig.json
├── tsconfig.test.json
└── tslint.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | charset = utf-8
7 | indent_style = space
8 | indent_size = 2
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | examples-dist/
3 | dist/
4 | .cache/
5 | coverage/
6 | .rpt2_cache/
7 | .vscode/
8 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | lib/
2 | examples/
3 | node_modules/
4 | examples-dist/
5 | .vscode/
6 | docs/
7 | .cache/
8 | coverage/
9 | .rpt2_cache/
10 | .editorconfig
11 | .prettierrc
12 | rollup.config.js
13 | tsconfig.json
14 | tsconfig.test.json
15 | tslint.json
16 | .travis.yml
17 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "typescript",
3 | "trailingComma": "all",
4 | "singleQuote": true
5 | }
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | matrix:
3 | include:
4 | - node_js: "14"
5 | - node_js: "12"
6 | - node_js: "10"
7 |
8 | script: "npm test -- --no-cache"
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Jannick Garthen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Stickup
2 |
3 | React components to stick elements at the top of the page while scrolling.
4 |
5 | 
6 | [](https://www.npmjs.com/package/react-stickup)
7 | 
8 | [](https://bundlephobia.com/result?p=react-stickup)
9 | [](https://travis-ci.org/garthenweb/react-stickup)
10 |
11 | ## Features
12 |
13 | * [`Sticky`](#sticky) component like `position: sticky` with options for elements bigger than the viewport
14 | * [`StickyScrollUp`](#stickyscrollup) component that is only visible when scrolling up (like the Chrome Browser url bar on Android)
15 | * Support for modern browsers (including IE11)
16 | * Build with performance in mind: Blazing fast, even on low end devices
17 | * Typescript
18 |
19 | [See the example to see how the library will work in production.](http://garthenweb.github.io/react-stickup)
20 |
21 | ## Installation
22 |
23 | ```
24 | npm install --save react-stickup
25 | ```
26 |
27 | ## Requirements
28 |
29 | * [react](https://reactjs.org/) version `16.3` or higher
30 |
31 | ## Static Types
32 |
33 | * Support for [Typescript](https://www.typescriptlang.org/) is included within this library, no need to install additional packages
34 | * [Flow](https://flow.org/en/) is not supported (feel free to create a PR)
35 |
36 | ## Client Support
37 |
38 | This library aims to support the following clients
39 |
40 | * Chrome/ Chrome Android (latest)
41 | * Firefox (latest)
42 | * Edge (latest)
43 | * Safari/ Safari iOS (latest)
44 | * NodeJS (latest)
45 | * Internet Explorer 11 (with @babel/polyfill)
46 |
47 | Please fill an issue in case your client is not supported or you see an issue in one of the above.
48 |
49 | ## Usage
50 |
51 | ### StickyProvider
52 |
53 | This component is required as a parent for `Sticky` and `StickyScrollUp` component to work. It will take care of registration of event handlers and provides a communication channel between components. The main implementation is based on [react-viewport-utils](https://github.com/garthenweb/react-viewport-utils).
54 |
55 | ### Sticky
56 |
57 | Acts like `position: sticky` css property.
58 | By default the component will be sticky when the top offset is reached and will stay that way. In case it should only stick within a certain container it can get assigned as a reference.
59 |
60 | **Important**: To work properly the `Sticky` component must have a `StickyProvider` as a parent within its tree.
61 |
62 | #### Example
63 |
64 | ``` javascript
65 | import * as React from 'react';
66 | import { Sticky } from 'react-stickup';
67 |
68 | const container = React.createRef();
69 |
70 | render(
71 |
72 |
73 |
74 | My Header
75 |
76 |
77 | Lots of content
78 |
79 |
80 |
81 | My Header
82 |
83 | ,
84 | document.querySelector('main')
85 | );
86 | ```
87 |
88 | #### Properties
89 |
90 | **`children?: React.ReactNode | ((options: { isSticky: boolean, isDockedToBottom: boolean, isNearToViewport: boolean, appliedOverflowScroll: 'end' | 'flow' }) => React.ReactNode)`**
91 |
92 | The child node that is rendered within the sticky container. When rendered as a function it will add further information the the function which can be used e.g. to update stylings.
93 |
94 | **`container?: React.RefObject`**
95 |
96 | The reference to the container to stick into. If this is not set, the component will be sticky regardless how far the user scrolls down.
97 |
98 | **`defaultOffsetTop?: number`**
99 |
100 | A top offset to create a padding between the browser window and the sticky component when sticky.
101 |
102 | **`overflowScroll?: 'end' | 'flow'`**
103 |
104 | Defines how the sticky element should react in case its bigger than the viewport.
105 | Different options are available:
106 |
107 | * `end`: The default value will keep the component sticky as long as it reaches the bottom of its container and only then will scroll down.
108 | * `flow`: The element scrolls with the flow of the scroll direction, therefore the content is easier to access.
109 |
110 | **`disabled?: boolean`**
111 |
112 | Allows to disable all sticky behavior. Use this in case you need to temporary disable the sticky behavior but you don't want to unmount it for performance reasons.
113 |
114 | **`disableHardwareAcceleration?: boolean`**
115 |
116 | By default css styles for hardware acceleration (`will-change` if supported, otherwise falls back to `transform`) are activated. This allows to turn it off.
117 |
118 | **`disableResizing?: boolean`**
119 |
120 | The components will resize when the width of the window changes to adjust its height and width. This allows to turn the resizing off.
121 |
122 | **`stickyProps?: {}`**
123 |
124 | All properties within this object are spread directly into the sticky element within the component. This e.g. allows to add css styles by `className` or `style`.
125 |
126 | **`style?: React.CSSProperties`**
127 |
128 | Will be merged with generated styles of the placeholder element. It also allows to override generated styles.
129 |
130 | **`className?: string`**
131 |
132 | The class name is passed directly to the placeholder element.
133 |
134 | ### StickyScrollUp
135 |
136 | Only Sticky to the top of the page in case it the page is scrolled up. When scrolled down, the content will just scroll out. `Sticky` next to the `StickyScrollUp` will stick to the bottom of it and will therefore not overlap.
137 |
138 | **Important**: To work properly the `StickyScrollUp` component must have a `StickyProvider` as a parent within its tree. All `Sticky` components must be wrapped by the same instance of the `StickyProvider`as the `StickyScrollUp` component to not overlap.
139 |
140 | #### Example
141 |
142 | ``` javascript
143 | import * as React from 'react';
144 | import { Sticky, StickyScrollUp, StickyProvider } from 'react-stickup';
145 |
146 | const container = React.createRef();
147 |
148 | render(
149 |
150 |
151 | My Stick up container
152 |
153 |
154 |
155 | My Header
156 |
157 |
158 | Lots of content
159 |
160 |
161 | ,
162 | document.querySelector('main')
163 | );
164 | ```
165 |
166 | #### Properties
167 |
168 | **`children?: React.ReactNode | ((options: { isSticky: boolean, isNearToViewport: boolean }) => React.ReactNode)`**
169 |
170 | The child node that is rendered within the sticky container. When rendered as a function it will add further information the the function which can be used e.g. to update stylings.
171 |
172 | **`disabled?: boolean`**
173 |
174 | Allows to disable all sticky behavior. Use this in case you need to temporary disable the sticky behavior but you don't want to unmount it for performance reasons.
175 |
176 | **`disableHardwareAcceleration?: boolean`**
177 |
178 | By default css styles for hardware acceleration (`will-change` if supported, otherwise falls back to `transform`) are activated. This allows to turn it off.
179 |
180 | **`disableResizing?: boolean`**
181 |
182 | The components will resize when the width of the window changes to adjust its height and width. This allows to turn the resizing off.
183 |
184 | **`stickyProps?: {}`**
185 |
186 | All properties within this object are spread directly into the sticky element within the component. This e.g. allows to add css styles by `className` or `style`.
187 |
188 | **`style?: React.CSSProperties`**
189 |
190 | Will be merged with generated styles of the placeholder element. It also allows to override generated styles.
191 |
192 | **`className?: string`**
193 |
194 | The class name is passed directly to the placeholder element.
195 |
196 | **`defaultOffsetTop?: number`**
197 |
198 | DEPRECATED: If not set, the start position is now calculated by default as it was already the case for the `Sticky` component. As there is no use case for this property anymore it will be removed in the future.
199 |
200 | When not initialized as the first element within the page (directly at the top) this allows to set an offset by hand from where the component will be sticky.
201 |
202 | ## Contributing
203 |
204 | Contributions are highly appreciated! The easiest is to fill an issue in case there is one before providing a PR so we can discuss the issue and a possible solution up front.
205 |
206 | At the moment there is not a test suite because its tricky to test the sticky behavior automated. I consider creating some e2e tests with Cypress in the future. In case you are interested in helping on that, please let me know!
207 |
208 | For now, please make sure to add a test case for all features in the examples.
209 |
210 | To start the example with the recent library changes just run `npm start` on the command.
211 |
212 | ## License
213 |
214 | Licensed under the [MIT License](https://opensource.org/licenses/mit-license.php).
215 |
--------------------------------------------------------------------------------
/docs/examples.68d19066.css:
--------------------------------------------------------------------------------
1 | *{padding:0;margin:0;box-sizing:border-box}body{color:#333;font-size:20px;line-height:1.5;font-family:Arial,Helvetica,sans-serif;text-align:center}.scrollPosition{background:#cd5c5c;color:indigo;position:fixed;top:0;right:0;z-index:100}.header-container{z-index:1}.header{width:100%;background:#009fe3;padding:50px 30px;font-weight:700}.sticky-inline{width:100%;background:#ff8080;padding:30px}.sticky-inline-odd{background:#e6ff60}.sticky-inline-sidebar{overflow:hidden;height:1000px;background-color:#556;background-image:linear-gradient(30deg,#445 12%,transparent 12.5%,transparent 87%,#445 87.5%,#445),linear-gradient(150deg,#445 12%,transparent 12.5%,transparent 87%,#445 87.5%,#445),linear-gradient(30deg,#445 12%,transparent 12.5%,transparent 87%,#445 87.5%,#445),linear-gradient(150deg,#445 12%,transparent 12.5%,transparent 87%,#445 87.5%,#445),linear-gradient(60deg,#99a 25%,transparent 25.5%,transparent 75%,#99a 0,#99a),linear-gradient(60deg,#99a 25%,transparent 25.5%,transparent 75%,#99a 0,#99a);background-size:80px 140px;background-position:0 0,0 0,40px 70px,40px 70px,0 0,40px 70px}.sticky-placeholder{padding-bottom:100px}.placeholder{width:100%;height:2500px;border-bottom:5px solid #333;color:#fff;background:linear-gradient(324deg,#fdfdfd 4%,transparent 0) -70px 43px,linear-gradient(36deg,#fdfdfd 4%,transparent 0) 30px 43px,linear-gradient(72deg,#e3d7bf 8.5%,transparent 0) 30px 43px,linear-gradient(288deg,#e3d7bf 8.5%,transparent 0) -70px 43px,linear-gradient(216deg,#e3d7bf 7.5%,transparent 0) -70px 23px,linear-gradient(144deg,#e3d7bf 7.5%,transparent 0) 30px 23px,linear-gradient(324deg,#fdfdfd 4%,transparent 0) -20px 93px,linear-gradient(36deg,#fdfdfd 4%,transparent 0) 80px 93px,linear-gradient(72deg,#e3d7bf 8.5%,transparent 0) 80px 93px,linear-gradient(288deg,#e3d7bf 8.5%,transparent 0) -20px 93px,linear-gradient(216deg,#e3d7bf 7.5%,transparent 0) -20px 73px,linear-gradient(144deg,#e3d7bf 7.5%,transparent 0) 80px 73px;background-color:#fdfdfd;background-size:100px 100px}.wrapper{margin:0 50px}
2 | /*# sourceMappingURL=https://garthenweb.github.io/react-stickup/examples.68d19066.css.map */
--------------------------------------------------------------------------------
/docs/examples.68d19066.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["styles.css"],"names":[],"mappings":"AAAA,EACE,SAAU,CACV,QAAS,CACT,qBACF,CAEA,KACE,UAAW,CACX,cAAe,CACf,eAAgB,CAChB,sCAAyC,CACzC,iBACF,CAEA,gBACE,kBAAqB,CACrB,YAAa,CACb,cAAe,CACf,KAAM,CACN,OAAQ,CACR,WACF,CAEA,kBACE,SACF,CAEA,QACE,UAAW,CACX,kBAAmB,CACnB,iBAAkB,CAClB,eACF,CAEA,eACE,UAAW,CACX,kBAAmB,CACnB,YACF,CAEA,mBACE,kBACF,CAEA,uBACE,eAAgB,CAChB,aAAc,CAEd,qBAAqB,CACrB,sfAKoF,CACpF,0BAA0B,CAC1B,6DACF,CAEA,oBACE,oBACF,CAEA,aACE,UAAW,CACX,aAAc,CACd,4BAA6B,CAC7B,UAAW,CAEX,guBAamE,CACjE,wBAAyB,CACzB,2BACJ,CAEA,SACE,aACF","file":"examples.68d19066.css","sourceRoot":"../examples","sourcesContent":["* {\n padding: 0;\n margin: 0;\n box-sizing: border-box;\n}\n\nbody {\n color: #333;\n font-size: 20px;\n line-height: 1.5;\n font-family: Arial, Helvetica, sans-serif;\n text-align: center;\n}\n\n.scrollPosition {\n background: indianred;\n color: indigo;\n position: fixed;\n top: 0;\n right: 0;\n z-index: 100;\n}\n\n.header-container {\n z-index: 1;\n}\n\n.header {\n width: 100%;\n background: #009FE3;\n padding: 50px 30px;\n font-weight: bold;\n}\n\n.sticky-inline {\n width: 100%;\n background: #ff8080;\n padding: 30px;\n}\n\n.sticky-inline-odd {\n background: #e6ff60;\n}\n\n.sticky-inline-sidebar {\n overflow: hidden;\n height: 1000px;\n /* pattern from https://leaverou.github.io/css3patterns/#japanese-cube */\n background-color:#556;\n background-image: linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),\n linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),\n linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),\n linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),\n linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a),\n linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a);\n background-size:80px 140px;\n background-position: 0 0, 0 0, 40px 70px, 40px 70px, 0 0, 40px 70px;\n}\n\n.sticky-placeholder {\n padding-bottom: 100px;\n}\n\n.placeholder {\n width: 100%;\n height: 2500px;\n border-bottom: 5px solid #333;\n color: #fff;\n /* pattern from http://lea.verou.me/css3patterns/#stars by Nicolas Gallagher */\n background:\n linear-gradient(324deg, #fdfdfd 4%, transparent 4%) -70px 43px,\n linear-gradient( 36deg, #fdfdfd 4%, transparent 4%) 30px 43px,\n linear-gradient( 72deg, #e3d7bf 8.5%, transparent 8.5%) 30px 43px,\n linear-gradient(288deg, #e3d7bf 8.5%, transparent 8.5%) -70px 43px,\n linear-gradient(216deg, #e3d7bf 7.5%, transparent 7.5%) -70px 23px,\n linear-gradient(144deg, #e3d7bf 7.5%, transparent 7.5%) 30px 23px,\n\n linear-gradient(324deg, #fdfdfd 4%, transparent 4%) -20px 93px,\n linear-gradient( 36deg, #fdfdfd 4%, transparent 4%) 80px 93px,\n linear-gradient( 72deg, #e3d7bf 8.5%, transparent 8.5%) 80px 93px,\n linear-gradient(288deg, #e3d7bf 8.5%, transparent 8.5%) -20px 93px,\n linear-gradient(216deg, #e3d7bf 7.5%, transparent 7.5%) -20px 73px,\n linear-gradient(144deg, #e3d7bf 7.5%, transparent 7.5%) 80px 73px;\n background-color: #fdfdfd;\n background-size: 100px 100px;\n}\n\n.wrapper {\n margin: 0 50px;\n}\n"]}
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 | Example
--------------------------------------------------------------------------------
/docs/legacy-browsers.68d19066.css:
--------------------------------------------------------------------------------
1 | *{padding:0;margin:0;box-sizing:border-box}body{color:#333;font-size:20px;line-height:1.5;font-family:Arial,Helvetica,sans-serif;text-align:center}.scrollPosition{background:#cd5c5c;color:indigo;position:fixed;top:0;right:0;z-index:100}.header-container{z-index:1}.header{width:100%;background:#009fe3;padding:50px 30px;font-weight:700}.sticky-inline{width:100%;background:#ff8080;padding:30px}.sticky-inline-odd{background:#e6ff60}.sticky-inline-sidebar{overflow:hidden;height:1000px;background-color:#556;background-image:linear-gradient(30deg,#445 12%,transparent 12.5%,transparent 87%,#445 87.5%,#445),linear-gradient(150deg,#445 12%,transparent 12.5%,transparent 87%,#445 87.5%,#445),linear-gradient(30deg,#445 12%,transparent 12.5%,transparent 87%,#445 87.5%,#445),linear-gradient(150deg,#445 12%,transparent 12.5%,transparent 87%,#445 87.5%,#445),linear-gradient(60deg,#99a 25%,transparent 25.5%,transparent 75%,#99a 0,#99a),linear-gradient(60deg,#99a 25%,transparent 25.5%,transparent 75%,#99a 0,#99a);background-size:80px 140px;background-position:0 0,0 0,40px 70px,40px 70px,0 0,40px 70px}.sticky-placeholder{padding-bottom:100px}.placeholder{width:100%;height:2500px;border-bottom:5px solid #333;color:#fff;background:linear-gradient(324deg,#fdfdfd 4%,transparent 0) -70px 43px,linear-gradient(36deg,#fdfdfd 4%,transparent 0) 30px 43px,linear-gradient(72deg,#e3d7bf 8.5%,transparent 0) 30px 43px,linear-gradient(288deg,#e3d7bf 8.5%,transparent 0) -70px 43px,linear-gradient(216deg,#e3d7bf 7.5%,transparent 0) -70px 23px,linear-gradient(144deg,#e3d7bf 7.5%,transparent 0) 30px 23px,linear-gradient(324deg,#fdfdfd 4%,transparent 0) -20px 93px,linear-gradient(36deg,#fdfdfd 4%,transparent 0) 80px 93px,linear-gradient(72deg,#e3d7bf 8.5%,transparent 0) 80px 93px,linear-gradient(288deg,#e3d7bf 8.5%,transparent 0) -20px 93px,linear-gradient(216deg,#e3d7bf 7.5%,transparent 0) -20px 73px,linear-gradient(144deg,#e3d7bf 7.5%,transparent 0) 80px 73px;background-color:#fdfdfd;background-size:100px 100px}.wrapper{margin:0 50px}
2 | /*# sourceMappingURL=https://garthenweb.github.io/react-stickup/legacy-browsers.68d19066.css.map */
--------------------------------------------------------------------------------
/docs/legacy-browsers.68d19066.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["styles.css"],"names":[],"mappings":"AAAA,EACE,SAAU,CACV,QAAS,CACT,qBACF,CAEA,KACE,UAAW,CACX,cAAe,CACf,eAAgB,CAChB,sCAAyC,CACzC,iBACF,CAEA,gBACE,kBAAqB,CACrB,YAAa,CACb,cAAe,CACf,KAAM,CACN,OAAQ,CACR,WACF,CAEA,kBACE,SACF,CAEA,QACE,UAAW,CACX,kBAAmB,CACnB,iBAAkB,CAClB,eACF,CAEA,eACE,UAAW,CACX,kBAAmB,CACnB,YACF,CAEA,mBACE,kBACF,CAEA,uBACE,eAAgB,CAChB,aAAc,CAEd,qBAAqB,CACrB,sfAKoF,CACpF,0BAA0B,CAC1B,6DACF,CAEA,oBACE,oBACF,CAEA,aACE,UAAW,CACX,aAAc,CACd,4BAA6B,CAC7B,UAAW,CAEX,guBAamE,CACjE,wBAAyB,CACzB,2BACJ,CAEA,SACE,aACF","file":"legacy-browsers.68d19066.css","sourceRoot":"../examples","sourcesContent":["* {\n padding: 0;\n margin: 0;\n box-sizing: border-box;\n}\n\nbody {\n color: #333;\n font-size: 20px;\n line-height: 1.5;\n font-family: Arial, Helvetica, sans-serif;\n text-align: center;\n}\n\n.scrollPosition {\n background: indianred;\n color: indigo;\n position: fixed;\n top: 0;\n right: 0;\n z-index: 100;\n}\n\n.header-container {\n z-index: 1;\n}\n\n.header {\n width: 100%;\n background: #009FE3;\n padding: 50px 30px;\n font-weight: bold;\n}\n\n.sticky-inline {\n width: 100%;\n background: #ff8080;\n padding: 30px;\n}\n\n.sticky-inline-odd {\n background: #e6ff60;\n}\n\n.sticky-inline-sidebar {\n overflow: hidden;\n height: 1000px;\n /* pattern from https://leaverou.github.io/css3patterns/#japanese-cube */\n background-color:#556;\n background-image: linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),\n linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),\n linear-gradient(30deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),\n linear-gradient(150deg, #445 12%, transparent 12.5%, transparent 87%, #445 87.5%, #445),\n linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a),\n linear-gradient(60deg, #99a 25%, transparent 25.5%, transparent 75%, #99a 75%, #99a);\n background-size:80px 140px;\n background-position: 0 0, 0 0, 40px 70px, 40px 70px, 0 0, 40px 70px;\n}\n\n.sticky-placeholder {\n padding-bottom: 100px;\n}\n\n.placeholder {\n width: 100%;\n height: 2500px;\n border-bottom: 5px solid #333;\n color: #fff;\n /* pattern from http://lea.verou.me/css3patterns/#stars by Nicolas Gallagher */\n background:\n linear-gradient(324deg, #fdfdfd 4%, transparent 4%) -70px 43px,\n linear-gradient( 36deg, #fdfdfd 4%, transparent 4%) 30px 43px,\n linear-gradient( 72deg, #e3d7bf 8.5%, transparent 8.5%) 30px 43px,\n linear-gradient(288deg, #e3d7bf 8.5%, transparent 8.5%) -70px 43px,\n linear-gradient(216deg, #e3d7bf 7.5%, transparent 7.5%) -70px 23px,\n linear-gradient(144deg, #e3d7bf 7.5%, transparent 7.5%) 30px 23px,\n\n linear-gradient(324deg, #fdfdfd 4%, transparent 4%) -20px 93px,\n linear-gradient( 36deg, #fdfdfd 4%, transparent 4%) 80px 93px,\n linear-gradient( 72deg, #e3d7bf 8.5%, transparent 8.5%) 80px 93px,\n linear-gradient(288deg, #e3d7bf 8.5%, transparent 8.5%) -20px 93px,\n linear-gradient(216deg, #e3d7bf 7.5%, transparent 7.5%) -20px 73px,\n linear-gradient(144deg, #e3d7bf 7.5%, transparent 7.5%) 80px 73px;\n background-color: #fdfdfd;\n background-size: 100px 100px;\n}\n\n.wrapper {\n margin: 0 50px;\n}\n"]}
--------------------------------------------------------------------------------
/docs/legacy-browsers.html:
--------------------------------------------------------------------------------
1 | Example
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Example
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { render } from 'react-dom';
3 | import { ObserveViewport, useRect } from 'react-viewport-utils';
4 |
5 | import { Sticky, StickyScrollUp, StickyProvider } from '../lib/index';
6 |
7 | import './styles.css';
8 |
9 | const Placeholder = () => ;
10 | const Test = () => {
11 | const div = React.useRef(null);
12 | return ;
13 | };
14 |
15 | class Example extends React.PureComponent<
16 | {},
17 | { disableHeader: boolean; disableAll: boolean }
18 | > {
19 | private container1: React.RefObject;
20 | private container2: React.RefObject;
21 | private container3: React.RefObject;
22 | private container4: React.RefObject;
23 | private container5: React.RefObject;
24 | private container6: React.RefObject;
25 | private container7: React.RefObject;
26 |
27 | constructor(props) {
28 | super(props);
29 | this.container1 = React.createRef();
30 | this.container2 = React.createRef();
31 | this.container3 = React.createRef();
32 | this.container4 = React.createRef();
33 | this.container5 = React.createRef();
34 | this.container6 = React.createRef();
35 | this.container7 = React.createRef();
36 | this.state = {
37 | disableHeader: false,
38 | disableAll: false,
39 | };
40 | }
41 |
42 | toggleHeaderState() {
43 | this.setState({
44 | disableHeader: !this.state.disableHeader,
45 | });
46 | }
47 |
48 | toggleAll() {
49 | this.setState({
50 | disableAll: !this.state.disableAll,
51 | });
52 | }
53 |
54 | render() {
55 | if (this.state.disableAll) {
56 | return ;
57 | }
58 | return (
59 | <>
60 |
61 |
62 |
63 | {({ scroll }) => (
64 |
146 | overflowScroll="flow"
147 |
148 |
149 | appliedOverflowScroll: {appliedOverflowScroll}
150 |
151 |
152 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
153 | do eiusmod tempor incididunt ut labore et dolore magna aliqua.
154 | Ut enim ad minim veniam, quis nostrud exercitation ullamco
155 | laboris nisi ut aliquip ex ea commodo consequat. Duis aute
156 | irure dolor in reprehenderit in voluptate velit esse cillum
157 | dolore eu fugiat nulla pariatur. Excepteur sint occaecat
158 | cupidatat non proident, sunt in culpa qui officia deserunt
159 | mollit anim id est laborum.
160 |
161 | )}
162 |
163 |
164 |
165 |
166 |
167 | overflowScroll="end"
168 |
169 |
170 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
171 | eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
172 | enim ad minim veniam, quis nostrud exercitation ullamco laboris
173 | nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
174 | in reprehenderit in voluptate velit esse cillum dolore eu fugiat
175 | nulla pariatur. Excepteur sint occaecat cupidatat non proident,
176 | sunt in culpa qui officia deserunt mollit anim id est laborum.
177 |