@faceless-ui/window-info
Advanced tools
Comparing version 2.0.0 to 2.0.1
@@ -1,3 +0,3 @@ | ||
import { IWindowInfoContext } from '../WindowInfoContext/types'; | ||
import { IWindowInfoContext } from '../WindowInfoContext'; | ||
declare const useWindowInfo: () => IWindowInfoContext; | ||
export default useWindowInfo; |
/// <reference types="react" /> | ||
import { IWindowInfoContext } from './types'; | ||
import { Breakpoints } from '../types'; | ||
export interface IWindowInfoContext { | ||
width: number; | ||
height: number; | ||
'--vw': string; | ||
'--vh': string; | ||
breakpoints: Breakpoints; | ||
eventsFired: number; | ||
} | ||
declare const WindowInfoContext: import("react").Context<IWindowInfoContext>; | ||
export default WindowInfoContext; |
@@ -1,13 +0,6 @@ | ||
import { Component } from 'react'; | ||
import { IWindowInfoContext } from '../WindowInfoContext/types'; | ||
import { Props } from './types'; | ||
declare class WindowInfoProvider extends Component<Props, IWindowInfoContext> { | ||
constructor(props: Props); | ||
componentDidMount(): void; | ||
componentWillUnmount(): void; | ||
updateWindowInfoWithTimeout: () => void; | ||
requestAnimation: () => void; | ||
updateWindowInfo: () => void; | ||
render(): JSX.Element; | ||
} | ||
import React from 'react'; | ||
import { Breakpoints } from '../types'; | ||
declare const WindowInfoProvider: React.FC<{ | ||
breakpoints: Breakpoints; | ||
}>; | ||
export default WindowInfoProvider; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __assign = (this && this.__assign) || function () { | ||
@@ -53,83 +38,84 @@ __assign = Object.assign || function(t) { | ||
var WindowInfoContext_1 = __importDefault(require("../WindowInfoContext")); | ||
var WindowInfoProvider = /** @class */ (function (_super) { | ||
__extends(WindowInfoProvider, _super); | ||
function WindowInfoProvider(props) { | ||
var _this = _super.call(this, props) || this; | ||
_this.updateWindowInfoWithTimeout = function () { | ||
setTimeout(function () { | ||
_this.requestAnimation(); | ||
}, 500); | ||
var reducer = function (state, payload) { | ||
var breakpoints = payload.breakpoints, animationRef = payload.animationRef; | ||
animationRef.current = undefined; | ||
var prevEventsFired = state.eventsFired; | ||
var _a = document.documentElement, style = _a.style, clientWidth = _a.clientWidth, clientHeight = _a.clientHeight; | ||
var windowWidth = window.innerWidth, windowHeight = window.innerHeight; | ||
var viewportWidth = clientWidth / 100 + "px"; | ||
var viewportHeight = clientHeight / 100 + "px"; | ||
var newState = { | ||
width: windowWidth, | ||
height: windowHeight, | ||
'--vw': viewportWidth, | ||
'--vh': viewportHeight, | ||
breakpoints: Object.keys(breakpoints).reduce(function (matchMediaBreakpoints, key) { | ||
var _a; | ||
return (__assign(__assign({}, matchMediaBreakpoints), (_a = {}, _a[key] = window.matchMedia(breakpoints[key]).matches, _a))); | ||
}, {}), | ||
eventsFired: prevEventsFired + 1, | ||
}; | ||
// This method is a cross-browser patch to achieve above-the-fold, fullscreen mobile experiences. | ||
// The technique accounts for the collapsing bottom toolbar of some mobile browsers which are out of normal flow. | ||
// It provides an alternate to the "vw" and "vh" CSS units by generating respective CSS variables. | ||
// It specifically reads the size of documentElement since its height does not include the toolbar. | ||
style.setProperty('--vw', viewportWidth); | ||
style.setProperty('--vh', viewportHeight); | ||
return newState; | ||
}; | ||
var WindowInfoProvider = function (props) { | ||
var breakpoints = props.breakpoints, children = props.children; | ||
var animationRef = react_1.useRef(null); | ||
var _a = react_1.useReducer(reducer, { | ||
width: undefined, | ||
height: undefined, | ||
'--vw': '', | ||
'--vh': '', | ||
breakpoints: undefined, | ||
eventsFired: 0, | ||
}), state = _a[0], dispatch = _a[1]; | ||
var requestAnimation = react_1.useCallback(function () { | ||
if (animationRef.current) | ||
cancelAnimationFrame(animationRef.current); | ||
animationRef.current = requestAnimationFrame(function () { return dispatch({ | ||
breakpoints: breakpoints, | ||
animationRef: animationRef, | ||
}); }); | ||
}, [breakpoints]); | ||
var requestThrottledAnimation = react_1.useCallback(function () { | ||
setTimeout(function () { | ||
requestAnimation(); | ||
}, 500); | ||
}, [requestAnimation]); | ||
react_1.useEffect(function () { | ||
window.addEventListener('resize', requestAnimation); | ||
window.addEventListener('orientationchange', requestThrottledAnimation); | ||
return function () { | ||
window.removeEventListener('resize', requestAnimation); | ||
window.removeEventListener('orientationchange', requestThrottledAnimation); | ||
}; | ||
_this.requestAnimation = function () { | ||
var animationScheduled = _this.state.animationScheduled; | ||
if (!animationScheduled) { | ||
_this.setState({ | ||
animationScheduled: true, | ||
}, function () { return requestAnimationFrame(_this.updateWindowInfo); }); | ||
} | ||
}; | ||
_this.updateWindowInfo = function () { | ||
var _a = _this.props.breakpoints, _b = _a === void 0 ? {} : _a, xs = _b.xs, s = _b.s, m = _b.m, l = _b.l, xl = _b.xl; | ||
var prevEventsFired = _this.state.eventsFired; | ||
var _c = document.documentElement, style = _c.style, clientWidth = _c.clientWidth, clientHeight = _c.clientHeight; | ||
var windowWidth = window.innerWidth, windowHeight = window.innerHeight; | ||
var viewportWidth = clientWidth / 100 + "px"; | ||
var viewportHeight = clientHeight / 100 + "px"; | ||
_this.setState({ | ||
width: windowWidth, | ||
height: windowHeight, | ||
'--vw': viewportWidth, | ||
'--vh': viewportHeight, | ||
breakpoints: { | ||
xs: window.matchMedia("(max-width: " + xs + "px)").matches, | ||
s: window.matchMedia("(max-width: " + s + "px)").matches, | ||
m: window.matchMedia("(max-width: " + m + "px)").matches, | ||
l: window.matchMedia("(max-width: " + l + "px)").matches, | ||
xl: window.matchMedia("(max-width: " + xl + "px)").matches, | ||
}, | ||
eventsFired: prevEventsFired + 1, | ||
animationScheduled: false, | ||
}, [ | ||
requestAnimation, | ||
requestThrottledAnimation, | ||
]); | ||
// use this effect to test rAF debounce by requesting animation every 1ms, for a total 120ms | ||
// results: ~23 requests will be canceled, ~17 requests will be canceled, and only ~8 will truly dispatch | ||
// useEffect(() => { | ||
// const firstID = setInterval(requestAnimation, 1); | ||
// setInterval(() => clearInterval(firstID), 120); | ||
// }, [requestAnimation]); | ||
react_1.useEffect(function () { | ||
if (state.eventsFired === 0) { | ||
dispatch({ | ||
breakpoints: breakpoints, | ||
animationRef: animationRef, | ||
}); | ||
// This method is a cross-browser patch to achieve above-the-fold, fullscreen mobile experiences. | ||
// The technique accounts for the collapsing bottom toolbar of some mobile browsers which are out of normal flow. | ||
// It provides an alternate to the "vw" and "vh" CSS units by generating respective CSS variables. | ||
// It specifically reads the size of documentElement since its height does not include the toolbar. | ||
style.setProperty('--vw', viewportWidth); | ||
style.setProperty('--vh', viewportHeight); | ||
}; | ||
_this.state = { | ||
width: 0, | ||
height: 0, | ||
'--vw': '0px', | ||
'--vh': '0px', | ||
breakpoints: { | ||
xs: false, | ||
s: false, | ||
m: false, | ||
l: false, | ||
xl: false, | ||
}, | ||
eventsFired: 0, | ||
animationScheduled: false, | ||
}; | ||
return _this; | ||
} | ||
WindowInfoProvider.prototype.componentDidMount = function () { | ||
window.addEventListener('resize', this.requestAnimation); | ||
window.addEventListener('orientationchange', this.updateWindowInfoWithTimeout); | ||
this.updateWindowInfo(); | ||
}; | ||
WindowInfoProvider.prototype.componentWillUnmount = function () { | ||
window.removeEventListener('resize', this.requestAnimation); | ||
window.removeEventListener('orientationchange', this.updateWindowInfoWithTimeout); | ||
}; | ||
WindowInfoProvider.prototype.render = function () { | ||
var children = this.props.children; | ||
var windowInfo = __assign({}, this.state); | ||
delete windowInfo.animationScheduled; | ||
return (react_1.default.createElement(WindowInfoContext_1.default.Provider, { value: __assign({}, windowInfo) }, children && children)); | ||
}; | ||
return WindowInfoProvider; | ||
}(react_1.Component)); | ||
} | ||
}, [ | ||
breakpoints, | ||
state, | ||
]); | ||
return (react_1.default.createElement(WindowInfoContext_1.default.Provider, { value: __assign({}, state) }, children && children)); | ||
}; | ||
exports.default = WindowInfoProvider; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@faceless-ui/window-info", | ||
"version": "2.0.0", | ||
"version": "2.0.1", | ||
"main": "dist/index.js", | ||
@@ -38,4 +38,4 @@ "types": "dist/index.d.ts", | ||
"@trbl/utils": "^1.1.1", | ||
"@typescript-eslint/eslint-plugin": "^4.11.1", | ||
"@typescript-eslint/parser": "^4.11.1", | ||
"@typescript-eslint/eslint-plugin": "^4.22.1", | ||
"@typescript-eslint/parser": "^4.22.1", | ||
"enzyme": "^3.11.0", | ||
@@ -42,0 +42,0 @@ "enzyme-adapter-react-16": "^1.15.2", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21300
261