@primer/react
Version:
An implementation of GitHub's Primer Design System using React
281 lines (274 loc) • 9.59 kB
JavaScript
import { c } from 'react-compiler-runtime';
import React from 'react';
import theme from './theme.js';
import deepmerge from 'deepmerge';
import { useSyncedState } from './hooks/useSyncedState.js';
import { jsx, jsxs } from 'react/jsx-runtime';
import { useId } from './hooks/useId.js';
const defaultColorMode = 'day';
const defaultDayScheme = 'light';
const defaultNightScheme = 'dark';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const ThemeContext = /*#__PURE__*/React.createContext({
setColorMode: () => null,
setDayScheme: () => null,
setNightScheme: () => null
});
// inspired from __NEXT_DATA__, we use application/json to avoid CSRF policy with inline scripts
const serverHandoffCache = new Map();
const emptyHandoff = {};
const getServerHandoff = id => {
if (typeof document === 'undefined') return emptyHandoff;
const cached = serverHandoffCache.get(id);
if (cached !== undefined) return cached;
try {
var _document$getElementB;
const serverData = (_document$getElementB = document.getElementById(`__PRIMER_DATA_${id}__`)) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.textContent;
if (serverData) {
const parsed = JSON.parse(serverData);
serverHandoffCache.set(id, parsed);
return parsed;
}
} catch (_error) {
// if document/element does not exist or JSON is invalid, suppress error
}
const empty = {};
serverHandoffCache.set(id, empty);
return empty;
};
const emptySubscribe = () => () => {};
const ThemeProvider = t0 => {
var _ref, _props$colorMode, _ref2, _props$dayScheme, _ref3, _props$nightScheme;
const $ = c(42);
let children;
let props;
if ($[0] !== t0) {
({
children,
...props
} = t0);
$[0] = t0;
$[1] = children;
$[2] = props;
} else {
children = $[1];
props = $[2];
}
const {
theme: fallbackTheme,
colorMode: fallbackColorMode,
dayScheme: fallbackDayScheme,
nightScheme: fallbackNightScheme
} = useTheme();
const theme$1 = fallbackTheme !== null && fallbackTheme !== void 0 ? fallbackTheme : theme;
const uniqueDataId = useId();
const [colorMode, setColorMode] = useSyncedState((_ref = (_props$colorMode = props.colorMode) !== null && _props$colorMode !== void 0 ? _props$colorMode : fallbackColorMode) !== null && _ref !== void 0 ? _ref : defaultColorMode);
const [dayScheme, setDayScheme] = useSyncedState((_ref2 = (_props$dayScheme = props.dayScheme) !== null && _props$dayScheme !== void 0 ? _props$dayScheme : fallbackDayScheme) !== null && _ref2 !== void 0 ? _ref2 : defaultDayScheme);
const [nightScheme, setNightScheme] = useSyncedState((_ref3 = (_props$nightScheme = props.nightScheme) !== null && _props$nightScheme !== void 0 ? _props$nightScheme : fallbackNightScheme) !== null && _ref3 !== void 0 ? _ref3 : defaultNightScheme);
const systemColorMode = useSystemColorMode();
let t1;
if ($[3] !== colorMode || $[4] !== systemColorMode) {
t1 = resolveColorMode(colorMode, systemColorMode);
$[3] = colorMode;
$[4] = systemColorMode;
$[5] = t1;
} else {
t1 = $[5];
}
const clientColorMode = t1;
let t2;
if ($[6] !== clientColorMode) {
t2 = () => clientColorMode;
$[6] = clientColorMode;
$[7] = t2;
} else {
t2 = $[7];
}
let t3;
if ($[8] !== clientColorMode || $[9] !== uniqueDataId) {
t3 = () => {
var _getServerHandoff$res;
return (_getServerHandoff$res = getServerHandoff(uniqueDataId).resolvedServerColorMode) !== null && _getServerHandoff$res !== void 0 ? _getServerHandoff$res : clientColorMode;
};
$[8] = clientColorMode;
$[9] = uniqueDataId;
$[10] = t3;
} else {
t3 = $[10];
}
const resolvedColorMode = React.useSyncExternalStore(emptySubscribe, t2, t3);
let t4;
if ($[11] !== dayScheme || $[12] !== nightScheme || $[13] !== resolvedColorMode) {
t4 = chooseColorScheme(resolvedColorMode, dayScheme, nightScheme);
$[11] = dayScheme;
$[12] = nightScheme;
$[13] = resolvedColorMode;
$[14] = t4;
} else {
t4 = $[14];
}
const colorScheme = t4;
let t5;
if ($[15] !== colorScheme || $[16] !== theme$1) {
t5 = applyColorScheme(theme$1, colorScheme);
$[15] = colorScheme;
$[16] = theme$1;
$[17] = t5;
} else {
t5 = $[17];
}
const {
resolvedTheme,
resolvedColorScheme
} = t5;
let t6;
if ($[18] !== colorMode || $[19] !== colorScheme || $[20] !== dayScheme || $[21] !== nightScheme || $[22] !== resolvedColorMode || $[23] !== resolvedColorScheme || $[24] !== resolvedTheme || $[25] !== setColorMode || $[26] !== setDayScheme || $[27] !== setNightScheme) {
t6 = {
theme: resolvedTheme,
colorScheme,
colorMode,
resolvedColorMode,
resolvedColorScheme,
dayScheme,
nightScheme,
setColorMode,
setDayScheme,
setNightScheme
};
$[18] = colorMode;
$[19] = colorScheme;
$[20] = dayScheme;
$[21] = nightScheme;
$[22] = resolvedColorMode;
$[23] = resolvedColorScheme;
$[24] = resolvedTheme;
$[25] = setColorMode;
$[26] = setDayScheme;
$[27] = setNightScheme;
$[28] = t6;
} else {
t6 = $[28];
}
const contextValue = t6;
const t7 = colorMode === "auto" ? "auto" : colorScheme.includes("dark") ? "dark" : "light";
let t8;
if ($[29] !== props.preventSSRMismatch || $[30] !== resolvedColorMode || $[31] !== uniqueDataId) {
t8 = props.preventSSRMismatch ? /*#__PURE__*/jsx("script", {
type: "application/json",
id: `__PRIMER_DATA_${uniqueDataId}__`,
dangerouslySetInnerHTML: {
__html: JSON.stringify({
resolvedServerColorMode: resolvedColorMode
})
}
}) : null;
$[29] = props.preventSSRMismatch;
$[30] = resolvedColorMode;
$[31] = uniqueDataId;
$[32] = t8;
} else {
t8 = $[32];
}
let t9;
if ($[33] !== children || $[34] !== dayScheme || $[35] !== nightScheme || $[36] !== t7 || $[37] !== t8) {
t9 = /*#__PURE__*/jsxs("div", {
"data-color-mode": t7,
"data-light-theme": dayScheme,
"data-dark-theme": nightScheme,
children: [children, t8]
});
$[33] = children;
$[34] = dayScheme;
$[35] = nightScheme;
$[36] = t7;
$[37] = t8;
$[38] = t9;
} else {
t9 = $[38];
}
let t10;
if ($[39] !== contextValue || $[40] !== t9) {
t10 = /*#__PURE__*/jsx(ThemeContext.Provider, {
value: contextValue,
children: t9
});
$[39] = contextValue;
$[40] = t9;
$[41] = t10;
} else {
t10 = $[41];
}
return t10;
};
function useTheme() {
return React.useContext(ThemeContext);
}
function useColorSchemeVar(values, fallback) {
var _values$colorScheme;
const {
colorScheme: t0
} = useTheme();
const colorScheme = t0 === undefined ? "" : t0;
return (_values$colorScheme = values[colorScheme]) !== null && _values$colorScheme !== void 0 ? _values$colorScheme : fallback;
}
function subscribeToSystemColorMode(callback) {
var _window, _window$matchMedia;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const media = (_window = window) === null || _window === void 0 ? void 0 : (_window$matchMedia = _window.matchMedia) === null || _window$matchMedia === void 0 ? void 0 : _window$matchMedia.call(_window, '(prefers-color-scheme: dark)');
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
media === null || media === void 0 ? void 0 : media.addEventListener('change', callback);
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
return () => media === null || media === void 0 ? void 0 : media.removeEventListener('change', callback);
}
function useSystemColorMode() {
return React.useSyncExternalStore(subscribeToSystemColorMode, getSystemColorMode, _temp);
}
function _temp() {
return "day";
}
function getSystemColorMode() {
var _window2, _window2$matchMedia, _window2$matchMedia$c;
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
return (_window2 = window) !== null && _window2 !== void 0 && (_window2$matchMedia = _window2.matchMedia) !== null && _window2$matchMedia !== void 0 && (_window2$matchMedia$c = _window2$matchMedia.call(_window2, '(prefers-color-scheme: dark)')) !== null && _window2$matchMedia$c !== void 0 && _window2$matchMedia$c.matches ? 'night' : 'day';
}
function resolveColorMode(colorMode, systemColorMode) {
switch (colorMode) {
case 'auto':
return systemColorMode;
default:
return colorMode;
}
}
function chooseColorScheme(colorMode, dayScheme, nightScheme) {
switch (colorMode) {
case 'day':
case 'light':
return dayScheme;
case 'dark':
case 'night':
return nightScheme;
}
}
function applyColorScheme(theme, colorScheme) {
if (!theme.colorSchemes) {
return {
resolvedTheme: theme,
resolvedColorScheme: undefined
};
}
if (!theme.colorSchemes[colorScheme]) {
// eslint-disable-next-line no-console
console.error(`\`${colorScheme}\` scheme not defined in \`theme.colorSchemes\``);
// Apply the first defined color scheme
const defaultColorScheme = Object.keys(theme.colorSchemes)[0];
return {
resolvedTheme: deepmerge(theme, theme.colorSchemes[defaultColorScheme]),
resolvedColorScheme: defaultColorScheme
};
}
return {
resolvedTheme: deepmerge(theme, theme.colorSchemes[colorScheme]),
resolvedColorScheme: colorScheme
};
}
export { ThemeProvider, ThemeProvider as default, defaultColorMode, useColorSchemeVar, useTheme };