UNPKG

use-color-scheme

Version:

React Hook to get users prefered color scheme

127 lines (108 loc) 3.63 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) : typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) : (global = global || self, factory(global.UseColorScheme = {}, global.React)); }(this, function (exports, react) { 'use strict'; function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } var PREFERENCES = { DARK: 'dark', LIGHT: 'light', NONE: 'no-preference' }; var values = [PREFERENCES.DARK, PREFERENCES.LIGHT, PREFERENCES.NONE]; var makeQuery = function makeQuery(pref) { return "(prefers-color-scheme: ".concat(pref, ")"); }; var matchPreference = function matchPreference(pref) { return window.matchMedia(makeQuery(pref)); }; var getPreference = function getPreference(preferences) { return preferences.map(function (value) { return { preference: value, matchMedia: matchPreference(value) }; }).filter(function (pref) { return pref.matchMedia.matches; })[0]; }; var attachListener = function attachListener(pref, setScheme) { var unbind; var listener = function listener() { var newPref = getPreference(values); setScheme(newPref.preference); pref.matchMedia.removeListener(listener); // recursion // NOTE: we need to attach a new listener to ensure it fires on next change unbind = attachListener(newPref, setScheme); }; pref.matchMedia.addListener(listener); return function () { if (unbind) { unbind(); } else { pref.matchMedia.removeListener(listener); } }; }; // NOTE: outside hook to avoid this value recomputing var initialPreference = getPreference(values); var useColorScheme = function useColorScheme() { if (!('matchMedia' in window)) { // can not detect return { scheme: PREFERENCES.NONE }; } var _useState = react.useState(initialPreference ? initialPreference.preference : PREFERENCES.NONE), _useState2 = _slicedToArray(_useState, 2), scheme = _useState2[0], setScheme = _useState2[1]; react.useEffect(function () { if (!initialPreference) return; return attachListener(initialPreference, setScheme); }, []); return { scheme: scheme }; }; exports.PREFERENCES = PREFERENCES; exports.attachListener = attachListener; exports.getPreference = getPreference; exports.makeQuery = makeQuery; exports.matchPreference = matchPreference; exports.useColorScheme = useColorScheme; exports.values = values; Object.defineProperty(exports, '__esModule', { value: true }); }));