curls
Version:
💪 Responsive, expressive UI primitives for React written with Style Hooks and Emotion
125 lines (106 loc) • 2.83 kB
JavaScript
exports.__esModule = true
exports.default = void 0
var _react = require('react')
var _json2mq = _interopRequireDefault(require('json2mq'))
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {default: obj}
}
const queriesDidChange = (prevQueries, nextQueries) => {
if (
Array.isArray(prevQueries) === true &&
Array.isArray(nextQueries) === true
) {
if (prevQueries.length === nextQueries.length) {
for (let i = 0; i < nextQueries.length; i++)
if (nextQueries[i] !== prevQueries[i]) return true
} else return true
} else return prevQueries !== nextQueries
return false
}
const init = ({queries, defaultMatches}) => {
queries = Array.isArray(queries) === true ? queries : [queries]
let mediaQueries = [],
matches = [],
i = 0
if (typeof window === 'undefined')
return {
mediaQueries: queries,
matches: defaultMatches,
}
for (; i < queries.length; i++) {
const mq =
typeof queries[i] === 'string'
? queries[i]
: (0, _json2mq.default)(queries[i]),
mql = window.matchMedia(mq)
matches.push(mql.matches)
mediaQueries.push(mql)
}
return {
mediaQueries,
matches,
}
}
const reducer = (state, action) => {
let matches = [],
i = 0
switch (action.type) {
case 'updateMatch':
for (; i < state.mediaQueries.length; i++)
matches.push(state.mediaQueries[i].matches)
return {
matches,
mediaQueries: state.mediaQueries,
}
case 'setQueries':
return init(action)
}
if (process.env.NODE_ENV !== 'production')
throw `Unrecognized action: ${action.type}`
}
var _default = (queries, defaultMatches) => {
const prevQueries = (0, _react.useRef)(queries),
[state, dispatch] = (0, _react.useReducer)(
reducer,
{
queries,
defaultMatches,
},
init
)
;(0, _react.useEffect)(() => {
if (queriesDidChange(queries, prevQueries.current)) {
dispatch({
type: 'setQueries',
queries,
defaultMatches,
})
prevQueries.current = queries
}
}, [queries])
;(0, _react.useEffect)(() => {
const callbacks = []
for (let i = 0; i < state.mediaQueries.length; i++) {
const mq = state.mediaQueries[i]
callbacks.push(() =>
dispatch({
type: 'updateMatch',
mq,
})
)
mq.addListener(callbacks[i])
}
return () => {
for (let i = 0; i < state.mediaQueries.length; i++)
state.mediaQueries[i].removeListener(callbacks[i])
}
}, [state.mediaQueries])
const {matches} = state
return {
matches,
matchesAny: matches.some(Boolean),
matchesAll: matches.length > 0 && matches.every(Boolean),
}
}
exports.default = _default