=h?p=0:(-1===p||h component higher in the tree to provide a loading indicator or placeholder to display."+ut(s))}Oa=!0,f=ra(f,s),u=c;do{switch(u.tag){case 3:u.effectTag|=2048,u.expirationTime=o,Gi(u,o=ba(u,f,o));break e;case 1:if(p=f,m=u.type,s=u.stateNode,0==(64&u.effectTag)&&("function"==typeof m.getDerivedStateFromError||null!==s&&"function"==typeof s.componentDidCatch&&(null===Da||!Da.has(s)))){u.effectTag|=2048,u.expirationTime=o,Gi(u,o=ka(u,p,o));break e}}u=u.return}while(null!==u)}Ea=Ba(i);continue}l=!0,Ro(t)}}break}if(Sa=!1,wa.current=n,Di=Ui=Ii=null,Xl(),l)Ca=null,e.finishedWork=null;else if(null!==Ea)e.finishedWork=null;else{if(null===(n=e.current.alternate)&&a("281"),Ca=null,Oa){if(l=e.latestPendingTime,i=e.latestSuspendedTime,o=e.latestPingedTime,0!==l&<?0:t)):(e.pendingCommitExpirationTime=r,e.finishedWork=n)}}function Qa(e,t){for(var n=e.return;null!==n;){switch(n.tag){case 1:var r=n.stateNode;if("function"==typeof n.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Da||!Da.has(r)))return Xi(n,e=ka(n,e=ra(t,e),1073741823)),void Xa(n,1073741823);break;case 3:return Xi(n,e=ba(n,e=ra(t,e),1073741823)),void Xa(n,1073741823)}n=n.return}3===e.tag&&(Xi(e,n=ba(e,n=ra(t,e),1073741823)),Xa(e,1073741823))}function Ka(e,t){var n=i.unstable_getCurrentPriorityLevel(),r=void 0;if(0==(1&t.mode))r=1073741823;else if(Sa&&!za)r=Pa;else{switch(n){case i.unstable_ImmediatePriority:r=1073741823;break;case i.unstable_UserBlockingPriority:r=1073741822-10*(1+((1073741822-e+15)/10|0));break;case i.unstable_NormalPriority:r=1073741822-25*(1+((1073741822-e+500)/25|0));break;case i.unstable_LowPriority:case i.unstable_IdlePriority:r=1;break;default:a("313")}null!==Ca&&r===Pa&&--r}return n===i.unstable_UserBlockingPriority&&(0===io||r=r&&(e.didError=!1,(0===(t=e.latestPingedTime)||t>n)&&(e.latestPingedTime=n),tl(n,e),0!==(n=e.expirationTime)&&wo(e,n)))}function Ya(e,t){e.expirationTimePa&&Fa(),Zr(e,t),Sa&&!za&&Ca===e||wo(e,e.expirationTime),vo>ho&&(vo=0,a("185")))}function Ga(e,t,n,r,l){return i.unstable_runWithPriority(i.unstable_ImmediatePriority,function(){return e(t,n,r,l)})}var Za=null,Ja=null,eo=0,to=void 0,no=!1,ro=null,lo=0,io=0,ao=!1,oo=null,uo=!1,co=!1,so=null,fo=i.unstable_now(),po=1073741822-(fo/10|0),mo=po,ho=50,vo=0,yo=null;function go(){po=1073741822-((i.unstable_now()-fo)/10|0)}function bo(e,t){if(0!==eo){if(te.expirationTime&&(e.expirationTime=t),no||(uo?co&&(ro=e,lo=1073741823,No(e,1073741823,!1)):1073741823===t?Co(1073741823,!1):bo(e,t))}function To(){var e=0,t=null;if(null!==Ja)for(var n=Ja,r=Za;null!==r;){var l=r.expirationTime;if(0===l){if((null===n||null===Ja)&&a("244"),r===r.nextScheduledRoot){Za=Ja=r.nextScheduledRoot=null;break}if(r===Za)Za=l=r.nextScheduledRoot,Ja.nextScheduledRoot=l,r.nextScheduledRoot=null;else{if(r===Ja){(Ja=n).nextScheduledRoot=Za,r.nextScheduledRoot=null;break}n.nextScheduledRoot=r.nextScheduledRoot,r.nextScheduledRoot=null}r=n.nextScheduledRoot}else{if(l>e&&(e=l,t=r),r===Ja)break;if(1073741823===e)break;n=r,r=r.nextScheduledRoot}}ro=t,lo=e}var _o=!1;function So(){return!!_o||!!i.unstable_shouldYield()&&(_o=!0)}function Eo(){try{if(!So()&&null!==Za){go();var e=Za;do{var t=e.expirationTime;0!==t&&po<=t&&(e.nextExpirationTimeToWorkOn=po),e=e.nextScheduledRoot}while(e!==Za)}Co(0,!0)}finally{_o=!1}}function Co(e,t){if(To(),t)for(go(),mo=po;null!==ro&&0!==lo&&e<=lo&&!(_o&&po>lo);)No(ro,lo,po>lo),To(),go(),mo=po;else for(;null!==ro&&0!==lo&&e<=lo;)No(ro,lo,!1),To();if(t&&(eo=0,to=null),0!==lo&&bo(ro,lo),vo=0,yo=null,null!==so)for(e=so,so=null,t=0;t=n&&(null===so?so=[r]:so.push(r),r._defer))return e.finishedWork=t,void(e.expirationTime=0);e.finishedWork=null,e===yo?vo++:(yo=e,vo=0),i.unstable_runWithPriority(i.unstable_ImmediatePriority,function(){Va(e,t)})}function Ro(e){null===ro&&a("246"),ro.expirationTime=0,ao||(ao=!0,oo=e)}function zo(e,t){var n=uo;uo=!0;try{return e(t)}finally{(uo=n)||no||Co(1073741823,!1)}}function Mo(e,t){if(uo&&!co){co=!0;try{return e(t)}finally{co=!1}}return e(t)}function Io(e,t,n){uo||no||0===io||(Co(io,!1),io=0);var r=uo;uo=!0;try{return i.unstable_runWithPriority(i.unstable_UserBlockingPriority,function(){return e(t,n)})}finally{(uo=r)||no||Co(1073741823,!1)}}function Uo(e,t,n,r,l){var i=t.current;e:if(n){t:{2===tn(n=n._reactInternalFiber)&&1===n.tag||a("170");var o=n;do{switch(o.tag){case 3:o=o.stateNode.context;break t;case 1:if(Mr(o.type)){o=o.stateNode.__reactInternalMemoizedMergedChildContext;break t}}o=o.return}while(null!==o);a("171"),o=void 0}if(1===n.tag){var u=n.type;if(Mr(u)){n=Fr(n,u,o);break e}}n=o}else n=Pr;return null===t.context?t.context=n:t.pendingContext=n,t=l,(l=qi(r)).payload={element:e},null!==(t=void 0===t?null:t)&&(l.callback=t),Wa(),Xi(i,l),Xa(i,r),r}function Do(e,t,n,r){var l=t.current;return Uo(e,t,n,l=Ka(xo(),l),r)}function Fo(e){if(!(e=e.current).child)return null;switch(e.child.tag){case 5:default:return e.child.stateNode}}function Lo(e){var t=1073741822-25*(1+((1073741822-xo()+500)/25|0));t>=_a&&(t=_a-1),this._expirationTime=_a=t,this._root=e,this._callbacks=this._next=null,this._hasChildren=this._didComplete=!1,this._children=null,this._defer=!0}function Ao(){this._callbacks=null,this._didCommit=!1,this._onCommit=this._onCommit.bind(this)}function jo(e,t,n){e={current:t=Hr(3,null,null,t?3:0),containerInfo:e,pendingChildren:null,pingCache:null,earliestPendingTime:0,latestPendingTime:0,earliestSuspendedTime:0,latestSuspendedTime:0,latestPingedTime:0,didError:!1,pendingCommitExpirationTime:0,finishedWork:null,timeoutHandle:-1,context:null,pendingContext:null,hydrate:n,nextExpirationTimeToWorkOn:0,expirationTime:0,firstBatch:null,nextScheduledRoot:null},this._internalRoot=t.stateNode=e}function Wo(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Vo(e,t,n,r,l){var i=n._reactRootContainer;if(i){if("function"==typeof l){var a=l;l=function(){var e=Fo(i._internalRoot);a.call(e)}}null!=e?i.legacy_renderSubtreeIntoContainer(e,t,l):i.render(t,l)}else{if(i=n._reactRootContainer=function(e,t){if(t||(t=!(!(t=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var n;n=e.lastChild;)e.removeChild(n);return new jo(e,!1,t)}(n,r),"function"==typeof l){var o=l;l=function(){var e=Fo(i._internalRoot);o.call(e)}}Mo(function(){null!=e?i.legacy_renderSubtreeIntoContainer(e,t,l):i.render(t,l)})}return Fo(i._internalRoot)}function Bo(e,t){var n=2=t;)n=r,r=r._next;e._next=r,null!==n&&(n._next=e)}return e},ze=zo,Me=Io,Ie=function(){no||0===io||(Co(io,!1),io=0)};var Ho,$o,Qo={createPortal:Bo,findDOMNode:function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternalFiber;return void 0===t&&("function"==typeof e.render?a("188"):a("268",Object.keys(e))),e=null===(e=rn(t))?null:e.stateNode},hydrate:function(e,t,n){return Wo(t)||a("200"),Vo(null,e,t,!0,n)},render:function(e,t,n){return Wo(t)||a("200"),Vo(null,e,t,!1,n)},unstable_renderSubtreeIntoContainer:function(e,t,n,r){return Wo(n)||a("200"),(null==e||void 0===e._reactInternalFiber)&&a("38"),Vo(e,t,n,!1,r)},unmountComponentAtNode:function(e){return Wo(e)||a("40"),!!e._reactRootContainer&&(Mo(function(){Vo(null,null,e,!1,function(){e._reactRootContainer=null})}),!0)},unstable_createPortal:function(){return Bo.apply(void 0,arguments)},unstable_batchedUpdates:zo,unstable_interactiveUpdates:Io,flushSync:function(e,t){no&&a("187");var n=uo;uo=!0;try{return Ga(e,t)}finally{uo=n,Co(1073741823,!1)}},unstable_createRoot:function(e,t){return Wo(e)||a("299","unstable_createRoot"),new jo(e,!0,null!=t&&!0===t.hydrate)},unstable_flushControlled:function(e){var t=uo;uo=!0;try{Ga(e)}finally{(uo=t)||no||Co(1073741823,!1)}},__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{Events:[D,F,L,N.injectEventPluginsByName,g,H,function(e){E(e,B)},Oe,Re,Pn,R]}};$o=(Ho={findFiberByHostInstance:U,bundleType:0,version:"16.8.6",rendererPackageName:"react-dom"}).findFiberByHostInstance,function(e){if("undefined"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__)return!1;var t=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(t.isDisabled||!t.supportsFiber)return!0;try{var n=t.inject(e);jr=Vr(function(e){return t.onCommitFiberRoot(n,e)}),Wr=Vr(function(e){return t.onCommitFiberUnmount(n,e)})}catch(e){}}(l({},Ho,{overrideProps:null,currentDispatcherRef:He.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=rn(e))?null:e.stateNode},findFiberByHostInstance:function(e){return $o?$o(e):null}}));var Ko={default:Qo},qo=Ko&&Qo||Ko;e.exports=qo.default||qo},function(e,t,n){"use strict";e.exports=n(6)},function(e,t,n){"use strict";(function(e){
23 | /** @license React v0.13.6
24 | * scheduler.production.min.js
25 | *
26 | * Copyright (c) Facebook, Inc. and its affiliates.
27 | *
28 | * This source code is licensed under the MIT license found in the
29 | * LICENSE file in the root directory of this source tree.
30 | */
31 | Object.defineProperty(t,"__esModule",{value:!0});var n=null,r=!1,l=3,i=-1,a=-1,o=!1,u=!1;function c(){if(!o){var e=n.expirationTime;u?T():u=!0,w(d,e)}}function s(){var e=n,t=n.next;if(n===t)n=null;else{var r=n.previous;n=r.next=t,t.previous=r}e.next=e.previous=null,r=e.callback,t=e.expirationTime,e=e.priorityLevel;var i=l,o=a;l=e,a=t;try{var u=r()}finally{l=i,a=o}if("function"==typeof u)if(u={callback:u,priorityLevel:e,expirationTime:t,next:null,previous:null},null===n)n=u.next=u.previous=u;else{r=null,e=n;do{if(e.expirationTime>=t){r=e;break}e=e.next}while(e!==n);null===r?r=n:r===n&&(n=u,c()),(t=r.previous).next=r.previous=u,u.next=r,u.previous=t}}function f(){if(-1===i&&null!==n&&1===n.priorityLevel){o=!0;try{do{s()}while(null!==n&&1===n.priorityLevel)}finally{o=!1,null!==n?c():u=!1}}}function d(e){o=!0;var l=r;r=e;try{if(e)for(;null!==n;){var i=t.unstable_now();if(!(n.expirationTime<=i))break;do{s()}while(null!==n&&n.expirationTime<=i)}else if(null!==n)do{s()}while(null!==n&&!_())}finally{o=!1,r=l,null!==n?c():u=!1,f()}}var p,m,h=Date,v="function"==typeof setTimeout?setTimeout:void 0,y="function"==typeof clearTimeout?clearTimeout:void 0,g="function"==typeof requestAnimationFrame?requestAnimationFrame:void 0,b="function"==typeof cancelAnimationFrame?cancelAnimationFrame:void 0;function k(e){p=g(function(t){y(m),e(t)}),m=v(function(){b(p),e(t.unstable_now())},100)}if("object"==typeof performance&&"function"==typeof performance.now){var x=performance;t.unstable_now=function(){return x.now()}}else t.unstable_now=function(){return h.now()};var w,T,_,S=null;if("undefined"!=typeof window?S=window:void 0!==e&&(S=e),S&&S._schedMock){var E=S._schedMock;w=E[0],T=E[1],_=E[2],t.unstable_now=E[3]}else if("undefined"==typeof window||"function"!=typeof MessageChannel){var C=null,P=function(e){if(null!==C)try{C(e)}finally{C=null}};w=function(e){null!==C?setTimeout(w,0,e):(C=e,setTimeout(P,0,!1))},T=function(){C=null},_=function(){return!1}}else{"undefined"!=typeof console&&("function"!=typeof g&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof b&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"));var N=null,O=!1,R=-1,z=!1,M=!1,I=0,U=33,D=33;_=function(){return I<=t.unstable_now()};var F=new MessageChannel,L=F.port2;F.port1.onmessage=function(){O=!1;var e=N,n=R;N=null,R=-1;var r=t.unstable_now(),l=!1;if(0>=I-r){if(!(-1!==n&&n<=r))return z||(z=!0,k(A)),N=e,void(R=n);l=!0}if(null!==e){M=!0;try{e(l)}finally{M=!1}}};var A=function(e){if(null!==N){k(A);var t=e-I+D;tt&&(t=8),D=tt?L.postMessage(void 0):z||(z=!0,k(A))},T=function(){N=null,O=!1,R=-1}}t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,n){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var r=l,a=i;l=e,i=t.unstable_now();try{return n()}finally{l=r,i=a,f()}},t.unstable_next=function(e){switch(l){case 1:case 2:case 3:var n=3;break;default:n=l}var r=l,a=i;l=n,i=t.unstable_now();try{return e()}finally{l=r,i=a,f()}},t.unstable_scheduleCallback=function(e,r){var a=-1!==i?i:t.unstable_now();if("object"==typeof r&&null!==r&&"number"==typeof r.timeout)r=a+r.timeout;else switch(l){case 1:r=a+-1;break;case 2:r=a+250;break;case 5:r=a+1073741823;break;case 4:r=a+1e4;break;default:r=a+5e3}if(e={callback:e,priorityLevel:l,expirationTime:r,next:null,previous:null},null===n)n=e.next=e.previous=e,c();else{a=null;var o=n;do{if(o.expirationTime>r){a=o;break}o=o.next}while(o!==n);null===a?a=n:a===n&&(n=e,c()),(r=a.previous).next=a.previous=e,e.next=a,e.previous=r}return e},t.unstable_cancelCallback=function(e){var t=e.next;if(null!==t){if(t===e)n=null;else{e===n&&(n=t);var r=e.previous;r.next=t,t.previous=r}e.next=e.previous=null}},t.unstable_wrapCallback=function(e){var n=l;return function(){var r=l,a=i;l=n,i=t.unstable_now();try{return e.apply(this,arguments)}finally{l=r,i=a,f()}}},t.unstable_getCurrentPriorityLevel=function(){return l},t.unstable_shouldYield=function(){return!r&&(null!==n&&n.expirationTime.5}),d=f[0],p=f[1],m=u(function(e){return{height:Math.floor(100*e)+"%",opacity:e}}),h=m[0],v=m[1];return l.a.createElement("div",{style:{maxWidth:"100vw",maxHeight:"100vh",overflowY:"scroll"}},l.a.createElement("div",{style:{width:"100vw",height:"500vh"}},l.a.createElement("div",{ref:t,style:s},r),l.a.createElement("div",{ref:a,style:s},o,"%"),l.a.createElement("div",{ref:d,style:c({},s,{fontSize:"5rem",textAlign:"center",backgroundColor:p?"#f00":"#00b"})},"50%",l.a.createElement("br",null),"over",l.a.createElement("br",null),p?"visible":"hidden"),l.a.createElement("div",{ref:h,style:c({},s,{backgroundColor:"transparent"})},l.a.createElement("img",{style:v,src:n(8)}))))},null),f)}]);
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | transform: {
3 | '^.+\\.(js|jsx|ts|tsx)$': 'babel-jest'
4 | },
5 | testRegex: '(\\.|/)(test|spec)\\.(t|j)sx?$',
6 | moduleNameMapper: {
7 | '^@/(.*)': '/src/$1'
8 | },
9 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
10 | collectCoverage: true,
11 | collectCoverageFrom: ['src/**/*.(t|j)s?(x)']
12 | }
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-hooks-visible",
3 | "version": "1.1.1",
4 | "license": "MIT",
5 | "description": "react intersectionObserver helper library.",
6 | "author": "kmkzt",
7 | "keywords": [
8 | "react",
9 | "intersectionObserver",
10 | "visible"
11 | ],
12 | "main": "lib/index.cjs.js",
13 | "module": "lib/index.esm.js",
14 | "browser": "lib/index.min.js",
15 | "types": "lib/index.d.ts",
16 | "files": [
17 | "lib/*.{js,ts}"
18 | ],
19 | "directories": {
20 | "lib": "lib",
21 | "doc": "README.md",
22 | "example": "src/example"
23 | },
24 | "repository": "github:kmkzt/react-hooks-visible",
25 | "homepage": "https://github.com/kmkzt/react-hooks-visible",
26 | "bugs": {
27 | "url": "https://github.com/kmkzt/react-hooks-visible/issues",
28 | "email": "info.pscreator@gmail.com"
29 | },
30 | "scripts": {
31 | "dev": "NODE_ENV=development webpack-dev-server",
32 | "prod": "npm-run-all build:*",
33 | "build:clear": "rimraf lib/* && rimraf docs/*",
34 | "build:rollup": "NODE_ENV=production rollup -c",
35 | "build:tsc": "NODE_ENV=production tsc --emitDeclarationOnly",
36 | "build:demo": "NODE_ENV=production webpack -p",
37 | "sample": "webpack-dev-server server.js",
38 | "test": "jest --passWithNoTests",
39 | "release": "release-it",
40 | "prepare": "yarn build:rollup; yarn build:tsc"
41 | },
42 | "peerDependencies": {
43 | "react": ">=16.8"
44 | },
45 | "devDependencies": {
46 | "@babel/core": "7.8.3",
47 | "@babel/plugin-proposal-class-properties": "7.8.3",
48 | "@babel/plugin-syntax-dynamic-import": "7.8.3",
49 | "@babel/plugin-transform-runtime": "7.8.3",
50 | "@babel/polyfill": "7.8.3",
51 | "@babel/preset-env": "7.8.3",
52 | "@babel/preset-react": "7.8.3",
53 | "@babel/preset-typescript": "7.8.3",
54 | "@rollup/plugin-commonjs": "11.0.2",
55 | "@rollup/plugin-json": "4.0.2",
56 | "@rollup/plugin-node-resolve": "7.1.1",
57 | "@rollup/plugin-replace": "2.3.1",
58 | "@types/autoprefixer": "9.5.0",
59 | "@types/babel-core": "6.25.6",
60 | "@types/babel__core": "7.1.2",
61 | "@types/dotenv-webpack": "1.7.0",
62 | "@types/eslint": "4.16.8",
63 | "@types/eslint-plugin-prettier": "2.2.0",
64 | "@types/html-webpack-plugin": "3.2.1",
65 | "@types/jest": "24.0.17",
66 | "@types/node": "12.7.2",
67 | "@types/node-sass": "4.11.0",
68 | "@types/prettier": "1.18.2",
69 | "@types/react": "16.9.2",
70 | "@types/react-dom": "16.8.5",
71 | "@types/rimraf": "2.0.2",
72 | "@types/uglifyjs-webpack-plugin": "1.1.0",
73 | "@types/webpack": "4.32.2",
74 | "@types/webpack-dev-server": "3.1.7",
75 | "@types/webpack-merge": "4.1.5",
76 | "@types/workbox-webpack-plugin": "4.1.0",
77 | "@typescript-eslint/eslint-plugin": "1.13.0",
78 | "@typescript-eslint/parser": "1.13.0",
79 | "@typescript-eslint/typescript-estree": "1.13.0",
80 | "autoprefixer": "9.6.1",
81 | "babel-core": "6.26.3",
82 | "babel-jest": "24.9.0",
83 | "babel-loader": "8.0.6",
84 | "babel-preset-es2015": "6.24.1",
85 | "babel-plugin-transform-react-remove-prop-types": "0.4.24",
86 | "css-loader": "2.1.1",
87 | "case-sensitive-paths-webpack-plugin": "2.3.0",
88 | "eslint": "5.16.0",
89 | "eslint-config-prettier": "4.3.0",
90 | "eslint-loader": "2.2.1",
91 | "eslint-plugin-prettier": "3.1.0",
92 | "eslint-plugin-react": "7.14.3",
93 | "eslint-plugin-react-hooks": "1.7.0",
94 | "fork-ts-checker-webpack-plugin": "4.1.0",
95 | "file-loader": "5.1.0",
96 | "html-loader": "0.5.5",
97 | "html-webpack-plugin": "3.2.0",
98 | "jest": "24.9.0",
99 | "node-sass": "4.13.1",
100 | "npm-run-all": "4.1.5",
101 | "postcss-loader": "3.0.0",
102 | "prettier": "1.18.2",
103 | "react": "16.9.0",
104 | "react-dom": "16.9.0",
105 | "release-it": "12.3.5",
106 | "resolve-url-loader": "3.1.0",
107 | "rimraf": "2.7.1",
108 | "rollup": "1.31.0",
109 | "rollup-plugin-babel": "4.4.0",
110 | "rollup-plugin-size-snapshot": "0.11.0",
111 | "rollup-plugin-sourcemaps": "0.5.0",
112 | "rollup-plugin-terser": "5.2.0",
113 | "sass-loader": "7.2.0",
114 | "style-loader": "0.23.1",
115 | "ts-loader": "6.0.4",
116 | "tsconfig-paths-webpack-plugin": "3.2.0",
117 | "typescript": "3.5.3",
118 | "webpack": "4.39.2",
119 | "webpack-cli": "3.3.6",
120 | "webpack-dev-server": "3.8.0",
121 | "webpack-merge": "4.2.1",
122 | "workbox-webpack-plugin": "4.3.1"
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | semi: false,
3 | singleQuote: true,
4 | printWidth: 80,
5 | tabWidth: 2
6 | // trailingComma: "es5",
7 | // bracketSpacing: true,
8 | // jsxBracketSameLine: true,
9 | // arrowParens: "always",
10 | // requirePragma: true,
11 | // insertPragma: true,
12 | // proseWrap: "always",
13 | }
14 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["config:base"],
3 | "labels": ["renovate"],
4 | "major": {
5 | "groupName": "all major dependencies"
6 | },
7 | "minor": {
8 | "groupName": "all minor dependencies"
9 | },
10 | "patch": {
11 | "automerge": true,
12 | "groupName": "all patch dependencies"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import nodeResolve from '@rollup/plugin-node-resolve'
2 | import replace from '@rollup/plugin-replace'
3 | import commonjs from '@rollup/plugin-commonjs'
4 | import babel from 'rollup-plugin-babel'
5 | // import json from "@rollup/plugin-json"
6 | import sourceMaps from 'rollup-plugin-sourcemaps'
7 | import { terser } from 'rollup-plugin-terser'
8 | import { sizeSnapshot } from 'rollup-plugin-size-snapshot'
9 | import pkg from './package.json'
10 |
11 | const input = './src/index.ts'
12 | const globals = {
13 | react: 'React'
14 | }
15 |
16 | const extensions = ['.js', '.jsx', '.ts', '.tsx', '.json']
17 | // TODO: research
18 | // const external = id => !id.startsWith('.') && !id.startsWith('/')
19 | const external = Object.keys(globals)
20 | const esm_targets = '>1%, not dead, not ie 11, not op_mini all'
21 |
22 | const getBabelOptions = ({ useESModules }) => ({
23 | extensions,
24 | babelrc: false,
25 | exclude: '**/node_modules/**',
26 | runtimeHelpers: true,
27 | presets: [
28 | [
29 | '@babel/preset-env',
30 | {
31 | loose: true,
32 | modules: false,
33 | targets: useESModules ? esm_targets : undefined
34 | }
35 | ],
36 | // react
37 | ['@babel/preset-react', { useBuiltIns: true }],
38 | '@babel/preset-typescript'
39 | ],
40 | plugins: [
41 | ['transform-react-remove-prop-types', { removeImport: true }],
42 | // '@babel/plugin-proposal-class-properties',
43 | // TODO: optimize bundle size
44 | // 'babel-plugin-annotate-pure-calls',
45 | ['@babel/plugin-transform-runtime', { regenerator: false, useESModules }]
46 | ]
47 | })
48 |
49 | export default [
50 | /**
51 | * umd
52 | */
53 | {
54 | input,
55 | output: {
56 | file: pkg.browser,
57 | format: 'umd',
58 | name: pkg.name,
59 | globals,
60 | exports: 'named',
61 | sourcemap: false
62 | },
63 | external: Object.keys(globals),
64 | plugins: [
65 | nodeResolve({ extensions }),
66 | babel(getBabelOptions({ useESModules: true })),
67 | commonjs(),
68 | sourceMaps(),
69 | replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),
70 | // terser({ output: { comments: /Copyright/i } }), // memo
71 | terser({}),
72 | sizeSnapshot()
73 | ]
74 | },
75 | /**
76 | * umd(development)
77 | */
78 | // {
79 | // input,
80 | // output: {
81 | // file: pkg.browser,
82 | // format: 'umd',
83 | // name: pkg.name,
84 | // globals,
85 | // exports: 'named',
86 | // sourcemap: false
87 | // },
88 | // external: Object.keys(globals),
89 | // plugins: [
90 | // babel(getBabelOptions({ useESModules: true })),
91 | // nodeResolve({ extensions }),
92 | // commonjs(),
93 | // replace({ 'process.env.NODE_ENV': JSON.stringify('development') }),
94 | // terser()
95 | // ]
96 | // },
97 | /**
98 | * cjs
99 | */
100 | {
101 | input,
102 | output: {
103 | file: pkg.main,
104 | format: 'cjs',
105 | exports: 'named',
106 | sourcemap: true
107 | },
108 | external,
109 | plugins: [
110 | babel(getBabelOptions({ useESModules: false })),
111 | commonjs(),
112 | nodeResolve({ extensions }),
113 | sourceMaps(),
114 | sizeSnapshot()
115 | ]
116 | },
117 | /**
118 | * esm
119 | */
120 | {
121 | input,
122 | output: { file: pkg.module, format: 'esm', sourcemap: true },
123 | external,
124 | plugins: [
125 | babel(getBabelOptions({ useESModules: true })),
126 | nodeResolve({ extensions }),
127 | sourceMaps(),
128 | sizeSnapshot()
129 | ]
130 | }
131 | ]
132 |
--------------------------------------------------------------------------------
/src/example/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kmkzt/react-hooks-visible/de8746aff7598d4e76e010a791fe65f62faa8c38/src/example/example.png
--------------------------------------------------------------------------------
/src/example/index.tsx:
--------------------------------------------------------------------------------
1 | import React, {
2 | useEffect,
3 | useRef,
4 | Fragment,
5 | useCallback,
6 | useState,
7 | CSSProperties
8 | } from 'react'
9 | import { render } from 'react-dom'
10 | import { useVisible } from '../'
11 |
12 | const BoxStyle: CSSProperties = {
13 | fontSize: '2rem',
14 | width: '500px',
15 | height: '500px',
16 | maxWidth: '100%',
17 | display: 'flex',
18 | justifyContent: 'center',
19 | alignItems: 'center',
20 | marginBottom: '10px',
21 | backgroundColor: '#ddd',
22 | boxSizing: 'border-box',
23 | overflow: 'hidden'
24 | }
25 | const Example = () => {
26 | const [defaultExampleRef, origin] = useVisible()
27 | const [percentExampleRef, percent] = useVisible(
28 | (vi: number) => Math.floor(vi * 100)
29 | )
30 | const [booleanExampleRef, isVisible] = useVisible(
31 | (vi: number) => vi > 0.5
32 | )
33 | const [styleExampleRef, visibleStyle] = useVisible<
34 | HTMLDivElement,
35 | CSSProperties
36 | >((vi: number) => ({
37 | height: `${Math.floor(vi * 100)}%`,
38 | opacity: vi
39 | }))
40 | return (
41 |
48 |
54 |
55 | {origin}
56 |
57 |
58 | {percent}%
59 |
60 |
69 | 50%
70 |
71 | over
72 |
73 | {isVisible ? 'visible' : 'hidden'}
74 |
75 |
82 |
})
83 |
84 |
85 |
86 | )
87 | }
88 |
89 | const app = document.createElement('div')
90 | document.body.appendChild(app)
91 | render(, app)
92 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './useVisible'
2 |
--------------------------------------------------------------------------------
/src/useVisible.tsx:
--------------------------------------------------------------------------------
1 | import React, {
2 | useRef,
3 | useEffect,
4 | useCallback,
5 | MutableRefObject,
6 | useState
7 | } from 'react'
8 |
9 | const defaultIntersectionObserverInit: IntersectionObserverInit = {
10 | root: null,
11 | rootMargin: '0px',
12 | threshold: Array.from({ length: 100 }, (v: undefined, i: number) => i * 0.01)
13 | }
14 | export const useVisible = (
15 | cb?: (vi: number) => V,
16 | option: Partial = {}
17 | ): [MutableRefObject, V] => {
18 | const targetRef = useRef(null)
19 | const observerRef = useRef(null)
20 | const [visible, setVisible] = useState(0)
21 | // TODO: visible types refactor
22 | const status: V = typeof cb === 'function' ? cb(visible) : (visible as any)
23 | const observerCallback: IntersectionObserverCallback = useCallback(
24 | (entries: IntersectionObserverEntry[]) => {
25 | entries.forEach((entry: IntersectionObserverEntry) => {
26 | setVisible(entry.intersectionRatio)
27 | })
28 | },
29 | []
30 | )
31 |
32 | useEffect(() => {
33 | if (observerRef.current) return
34 | if (!targetRef.current) return
35 | observerRef.current = new IntersectionObserver(observerCallback, {
36 | ...defaultIntersectionObserverInit,
37 | ...option
38 | })
39 | observerRef.current.observe(targetRef.current)
40 | })
41 |
42 | return [targetRef, status]
43 | }
44 |
--------------------------------------------------------------------------------
/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | react-hooks-visible
5 |
6 |
10 |
11 |
15 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "outDir": "./lib",
5 | "target": "esnext",
6 | "module": "esnext",
7 | "lib": ["es2018", "es2017", "dom"],
8 | "jsx": "react",
9 | "allowSyntheticDefaultImports": true,
10 | "esModuleInterop": true,
11 | "experimentalDecorators": true,
12 | "downlevelIteration": true,
13 | "declaration": true,
14 | "declarationDir": "./lib",
15 | "forceConsistentCasingInFileNames": true,
16 | "moduleResolution": "node",
17 | "noEmitOnError": true,
18 | "noUnusedLocals": false,
19 | "removeComments": true,
20 | "skipLibCheck": true,
21 | "strict": true,
22 | "strictNullChecks": true,
23 | "suppressImplicitAnyIndexErrors": true,
24 | "plugins": [],
25 | "paths": {
26 | "@*": ["src*"]
27 | },
28 | "typeRoots": ["node_modules/@types", "./src/typings"]
29 | },
30 | "include": ["src/**/*.ts"],
31 | "exclude": ["node_modules"]
32 | }
33 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const { join, resolve } = require('path')
2 | const HtmlWebpackPlugin = require('html-webpack-plugin')
3 | const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin')
4 | const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
5 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
6 |
7 | const isDev = process.env.NODE_ENV === 'development'
8 |
9 | module.exports = {
10 | mode: isDev ? 'development' : 'production',
11 | devtool: isDev ? 'source-map' : false,
12 | entry: resolve(__dirname, 'src/example/index.tsx'),
13 | output: {
14 | filename: isDev ? '[name].js' : '[name].[hash].js',
15 | path: resolve('docs')
16 | },
17 | module: {
18 | rules: [
19 | {
20 | enforce: 'pre',
21 | test: /\.jsx?$/,
22 | exclude: /node_modules/,
23 | use: [
24 | {
25 | loader: 'eslint-loader',
26 | options: {
27 | fix: true,
28 | failOnWarning: true
29 | }
30 | }
31 | ]
32 | },
33 | {
34 | enforce: 'pre',
35 | test: /\.tsx?$/,
36 | exclude: /node_modules/,
37 | use: [
38 | {
39 | loader: 'ts-loader',
40 | options: {
41 | transpileOnly: true
42 | }
43 | },
44 | {
45 | loader: 'eslint-loader',
46 | options: {
47 | fix: true,
48 | failOnWarning: true
49 | }
50 | }
51 | ]
52 | },
53 | {
54 | test: /\.[tj]sx$/,
55 | exclude: /node_modules/,
56 | loader: 'babel-loader'
57 | },
58 | {
59 | test: /\.(png|jpg|gif|svg)$/,
60 | exclude: /node_modules/,
61 | use: [
62 | {
63 | loader: 'file-loader',
64 | options: {
65 | name: '[name].[ext]?[hash]'
66 | }
67 | }
68 | ]
69 | },
70 | { test: /\.html$/, exclude: /node_modules/, use: 'html-loader' }
71 | ]
72 | },
73 | resolve: {
74 | extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
75 | modules: ['node_modules', 'web_modules'],
76 | plugins: [new TsconfigPathsPlugin()]
77 | },
78 | plugins: [
79 | new CaseSensitivePathsPlugin(),
80 | new ForkTsCheckerWebpackPlugin({
81 | reportFiles: ['src/**/*.{ts,tsx}']
82 | }),
83 | new HtmlWebpackPlugin({
84 | template: resolve('template.html')
85 | })
86 | ],
87 | optimization: {
88 | minimize: !isDev
89 | },
90 | devServer: {
91 | contentBase: join(__dirname, 'docs'),
92 | compress: true,
93 | port: 8888
94 | }
95 | }
96 |
--------------------------------------------------------------------------------