@aglyn/shared-ui-theme 1.0.0-beta.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +7 -0
- package/package.json +51 -0
- package/src/index.d.ts +34 -0
- package/src/index.js +50 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/host-theme-provider.d.ts +84 -0
- package/src/lib/components/host-theme-provider.js +146 -0
- package/src/lib/components/host-theme-provider.js.map +1 -0
- package/src/lib/components/theme-css-var-provider.d.ts +44 -0
- package/src/lib/components/theme-css-var-provider.js +79 -0
- package/src/lib/components/theme-css-var-provider.js.map +1 -0
- package/src/lib/console.theme.d.ts +34 -0
- package/src/lib/console.theme.js +598 -0
- package/src/lib/console.theme.js.map +1 -0
- package/src/lib/constants.d.ts +72 -0
- package/src/lib/constants.js +85 -0
- package/src/lib/constants.js.map +1 -0
- package/src/lib/hocs/create-with-emotion-client-cache.d.ts +30 -0
- package/src/lib/hocs/create-with-emotion-client-cache.js +53 -0
- package/src/lib/hocs/create-with-emotion-client-cache.js.map +1 -0
- package/src/lib/hocs/create-with-theme-provider.d.ts +86 -0
- package/src/lib/hocs/create-with-theme-provider.js +231 -0
- package/src/lib/hocs/create-with-theme-provider.js.map +1 -0
- package/src/lib/tenant.theme.d.ts +58 -0
- package/src/lib/tenant.theme.js +282 -0
- package/src/lib/tenant.theme.js.map +1 -0
- package/src/lib/theme.types.d.ts +26 -0
- package/src/lib/theme.types.js +18 -0
- package/src/lib/theme.types.js.map +1 -0
- package/src/lib/util/accent-text.d.ts +187 -0
- package/src/lib/util/accent-text.js +277 -0
- package/src/lib/util/accent-text.js.map +1 -0
- package/src/lib/util/accessible-shade.d.ts +61 -0
- package/src/lib/util/accessible-shade.js +117 -0
- package/src/lib/util/accessible-shade.js.map +1 -0
- package/src/lib/util/color-scheme-hint.d.ts +68 -0
- package/src/lib/util/color-scheme-hint.js +69 -0
- package/src/lib/util/color-scheme-hint.js.map +1 -0
- package/src/lib/util/create-responsive-theme.d.ts +71 -0
- package/src/lib/util/create-responsive-theme.js +287 -0
- package/src/lib/util/create-responsive-theme.js.map +1 -0
- package/src/lib/util/emotion-cache.d.ts +81 -0
- package/src/lib/util/emotion-cache.js +79 -0
- package/src/lib/util/emotion-cache.js.map +1 -0
- package/src/lib/util/generate-component-class-keys.d.ts +41 -0
- package/src/lib/util/generate-component-class-keys.js +53 -0
- package/src/lib/util/generate-component-class-keys.js.map +1 -0
- package/src/lib/util/host-theme.d.ts +92 -0
- package/src/lib/util/host-theme.js +340 -0
- package/src/lib/util/host-theme.js.map +1 -0
- package/src/lib/util/layered-emotion-cache.d.ts +78 -0
- package/src/lib/util/layered-emotion-cache.js +90 -0
- package/src/lib/util/layered-emotion-cache.js.map +1 -0
- package/src/lib/util/merge-sx-props.d.ts +22 -0
- package/src/lib/util/merge-sx-props.js +27 -0
- package/src/lib/util/merge-sx-props.js.map +1 -0
- package/src/lib/util/scheme-route-segment.d.ts +95 -0
- package/src/lib/util/scheme-route-segment.js +101 -0
- package/src/lib/util/scheme-route-segment.js.map +1 -0
- package/src/lib/util/theme-editor-defaults.d.ts +41 -0
- package/src/lib/util/theme-editor-defaults.js +49 -0
- package/src/lib/util/theme-editor-defaults.js.map +1 -0
- package/src/lib/util/theme-editor-fields.d.ts +315 -0
- package/src/lib/util/theme-editor-fields.js +714 -0
- package/src/lib/util/theme-editor-fields.js.map +1 -0
- package/src/lib/util/theme-mode-cookie.d.ts +48 -0
- package/src/lib/util/theme-mode-cookie.js +48 -0
- package/src/lib/util/theme-mode-cookie.js.map +1 -0
- package/src/vendor/emotion.d.ts +18 -0
- package/src/vendor/emotion.js +22 -0
- package/src/vendor/emotion.js.map +1 -0
- package/src/vendor/jss.d.ts +18 -0
- package/src/vendor/jss.js +20 -0
- package/src/vendor/jss.js.map +1 -0
- package/src/vendor/mui.d.ts +282 -0
- package/src/vendor/mui.js +20 -0
- package/src/vendor/mui.js.map +1 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright 2023 Aglyn LLC
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/ import { _isArr, _isNull } from "@aglyn/shared-util-tools";
|
|
19
|
+
import { getDisplayName, noop } from "@aglyn/shared-util-tools";
|
|
20
|
+
import { hoistNonReactStatics } from "@aglyn/shared-util-vendor";
|
|
21
|
+
import { CssBaseline, useMediaQuery } from "@mui/material";
|
|
22
|
+
import Cookies from "js-cookie";
|
|
23
|
+
import { createContext, forwardRef, useCallback, useContext, useMemo, useState } from "react";
|
|
24
|
+
import { useIsomorphicLayoutEffect } from "react-use";
|
|
25
|
+
import { createTheme, ThemeProvider } from "../../vendor/mui.js";
|
|
26
|
+
import { parseThemeModeCookie, THEME_MODE_COOKIE } from "../util/theme-mode-cookie.js";
|
|
27
|
+
export const THEME_DISPLAY_NAME = {
|
|
28
|
+
light: 'Light',
|
|
29
|
+
dark: 'Dark',
|
|
30
|
+
system: 'Device default'
|
|
31
|
+
};
|
|
32
|
+
export const getThemeModeDisplayName = (theme)=>{
|
|
33
|
+
return THEME_DISPLAY_NAME[theme] || THEME_DISPLAY_NAME.system;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* The cookie the visitor's choice is persisted in, spelled out as a type so
|
|
37
|
+
* the name has one definition across the browser reader here and the
|
|
38
|
+
* server-side one in `util/theme-mode-cookie`: the annotation fails to compile
|
|
39
|
+
* if the two ever name different cookies.
|
|
40
|
+
*/ export const COOKIE_THEME_KEY = THEME_MODE_COOKIE;
|
|
41
|
+
export const ThemeContextDispatch = /*#__PURE__*/ createContext([
|
|
42
|
+
[
|
|
43
|
+
'system',
|
|
44
|
+
'system'
|
|
45
|
+
],
|
|
46
|
+
noop,
|
|
47
|
+
'system'
|
|
48
|
+
]);
|
|
49
|
+
export function useThemeMode() {
|
|
50
|
+
return useContext(ThemeContextDispatch);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The stored choice as this browser reads it.
|
|
54
|
+
*
|
|
55
|
+
* `js-cookie` reads `document.cookie`, so on a server render there is nothing
|
|
56
|
+
* to read and every visitor looks like one who has chosen nothing. That is why
|
|
57
|
+
* a server-rendered surface passes the mode it resolved from the request's
|
|
58
|
+
* cookies into {@link useCookieThemeMode} instead of relying on this.
|
|
59
|
+
*/ function getCookieThemeMode() {
|
|
60
|
+
return parseThemeModeCookie(Cookies.get(COOKIE_THEME_KEY));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The visitor's stored light/dark choice, and a setter that persists it.
|
|
64
|
+
*
|
|
65
|
+
* `initialMode` is the mode the surface's server render resolved from the
|
|
66
|
+
* request's cookies — `null` when the request carried no choice. Supplying it
|
|
67
|
+
* is what makes the FIRST render right: the state starts at the visitor's
|
|
68
|
+
* choice on the server and at the identical value through hydration, rather
|
|
69
|
+
* than starting empty and being corrected by the effect below once React has
|
|
70
|
+
* hydrated the whole page. Omit it on a surface that only ever renders in a
|
|
71
|
+
* browser, and the cookie is read directly.
|
|
72
|
+
*/ export function useCookieThemeMode(initialMode) {
|
|
73
|
+
const [mode, setMode] = useState(()=>initialMode === undefined ? getCookieThemeMode() : initialMode);
|
|
74
|
+
/**
|
|
75
|
+
* Keeps the state in step with the cookie on each paint — another tab's
|
|
76
|
+
* switcher, or a seed that went stale between the server render and
|
|
77
|
+
* hydration. Browser-only: effects do not run during a server render, so
|
|
78
|
+
* this never overwrites the seed with the server's empty read.
|
|
79
|
+
*/ useIsomorphicLayoutEffect(()=>{
|
|
80
|
+
const cookieMode = getCookieThemeMode();
|
|
81
|
+
setMode((prev)=>prev !== cookieMode ? cookieMode : prev);
|
|
82
|
+
});
|
|
83
|
+
const setCookieThemeMode = useCallback((newMode)=>{
|
|
84
|
+
Cookies.set(COOKIE_THEME_KEY, newMode, {
|
|
85
|
+
expires: 365
|
|
86
|
+
});
|
|
87
|
+
setMode((prev)=>prev !== newMode ? newMode : prev);
|
|
88
|
+
}, []);
|
|
89
|
+
return useMemo(()=>[
|
|
90
|
+
mode,
|
|
91
|
+
setCookieThemeMode
|
|
92
|
+
], [
|
|
93
|
+
mode,
|
|
94
|
+
setCookieThemeMode
|
|
95
|
+
]);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The resolved theme mode, in two layers with the visitor's own choice on top.
|
|
99
|
+
*
|
|
100
|
+
* An EXPLICIT choice comes from the cookie, which a server render can read
|
|
101
|
+
* from the request — pass it as `initialMode` and the surface paints that
|
|
102
|
+
* scheme in its first byte. It outranks the device: a visitor who asked for
|
|
103
|
+
* light gets light on a dark laptop, and the ordering below is the only thing
|
|
104
|
+
* that decides it, so the two layers are kept as separate inputs rather than
|
|
105
|
+
* collapsed into one seed by the caller.
|
|
106
|
+
*
|
|
107
|
+
* DEVICE DEFAULT is the other layer. `prefers-color-scheme` is a media
|
|
108
|
+
* feature, so a server has nothing to evaluate it against and `useMediaQuery`
|
|
109
|
+
* answers light for every server render. `initialDeviceMode` supplies that
|
|
110
|
+
* answer from the request instead — the `Sec-CH-Prefers-Color-Scheme` client
|
|
111
|
+
* hint, where the browser sends one.
|
|
112
|
+
*
|
|
113
|
+
* It is fed in as `defaultMatches` rather than substituted for the media query
|
|
114
|
+
* because that is the value React reads for BOTH the server render and the
|
|
115
|
+
* hydration render: `useMediaQuery` publishes `defaultMatches` as its server
|
|
116
|
+
* snapshot and only switches to the live `matchMedia` result once hydration is
|
|
117
|
+
* complete. Seeding any earlier layer instead leaves the media query answering
|
|
118
|
+
* light for the hydration commit, and the tree repaints light before the real
|
|
119
|
+
* snapshot arrives — the flash this exists to remove, moved one frame later.
|
|
120
|
+
*/ export function useThemeModeState(initialMode, initialDeviceMode) {
|
|
121
|
+
const prefersDark = useMediaQuery('(prefers-color-scheme: dark)', {
|
|
122
|
+
defaultMatches: initialDeviceMode === 'dark'
|
|
123
|
+
});
|
|
124
|
+
const [cookieMode, setCookieMode] = useCookieThemeMode(initialMode);
|
|
125
|
+
const systemMode = useMemo(()=>{
|
|
126
|
+
return prefersDark ? 'dark' : 'light';
|
|
127
|
+
}, [
|
|
128
|
+
prefersDark
|
|
129
|
+
]);
|
|
130
|
+
const [type, mode] = useMemo(()=>{
|
|
131
|
+
if (cookieMode && cookieMode !== 'system') {
|
|
132
|
+
return [
|
|
133
|
+
'user',
|
|
134
|
+
cookieMode
|
|
135
|
+
];
|
|
136
|
+
}
|
|
137
|
+
return [
|
|
138
|
+
'system',
|
|
139
|
+
systemMode
|
|
140
|
+
];
|
|
141
|
+
}, [
|
|
142
|
+
cookieMode,
|
|
143
|
+
systemMode
|
|
144
|
+
]);
|
|
145
|
+
const toggleThemeMode = useCallback((event, to)=>{
|
|
146
|
+
let newMode;
|
|
147
|
+
switch(true){
|
|
148
|
+
case _isNull(to):
|
|
149
|
+
case to === 'system':
|
|
150
|
+
newMode = 'system';
|
|
151
|
+
break;
|
|
152
|
+
case to === 'dark':
|
|
153
|
+
case to === 'light':
|
|
154
|
+
newMode = to;
|
|
155
|
+
break;
|
|
156
|
+
case _isNull(cookieMode):
|
|
157
|
+
newMode = 'light';
|
|
158
|
+
break;
|
|
159
|
+
case cookieMode === 'light':
|
|
160
|
+
newMode = 'dark';
|
|
161
|
+
break;
|
|
162
|
+
case cookieMode === 'dark':
|
|
163
|
+
default:
|
|
164
|
+
newMode = 'system';
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
setCookieMode(newMode);
|
|
168
|
+
}, [
|
|
169
|
+
cookieMode,
|
|
170
|
+
setCookieMode
|
|
171
|
+
]);
|
|
172
|
+
return useMemo(()=>[
|
|
173
|
+
[
|
|
174
|
+
type,
|
|
175
|
+
mode
|
|
176
|
+
],
|
|
177
|
+
toggleThemeMode,
|
|
178
|
+
cookieMode
|
|
179
|
+
], [
|
|
180
|
+
type,
|
|
181
|
+
mode,
|
|
182
|
+
toggleThemeMode,
|
|
183
|
+
cookieMode
|
|
184
|
+
]);
|
|
185
|
+
}
|
|
186
|
+
export function createWithThemeProvider(options) {
|
|
187
|
+
const { theme, disableCssBaseline } = options;
|
|
188
|
+
const [lightTheme, darkTheme] = !_isArr(theme) ? [
|
|
189
|
+
theme,
|
|
190
|
+
createTheme(_extends({}, theme, {
|
|
191
|
+
palette: _extends({}, theme == null ? void 0 : theme.palette, {
|
|
192
|
+
mode: 'dark'
|
|
193
|
+
})
|
|
194
|
+
}))
|
|
195
|
+
] : theme;
|
|
196
|
+
return function withThemeProvider(WrappedComponent) {
|
|
197
|
+
const WithThemeProvider = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
198
|
+
const {} = props, rest = _extends({}, props);
|
|
199
|
+
const ThemeModeState = useThemeModeState();
|
|
200
|
+
const activeTheme = useMemo(()=>{
|
|
201
|
+
const [[, themeMode]] = ThemeModeState;
|
|
202
|
+
return themeMode === 'dark' ? darkTheme : lightTheme;
|
|
203
|
+
}, [
|
|
204
|
+
ThemeModeState
|
|
205
|
+
]);
|
|
206
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
207
|
+
const WrappedAny = WrappedComponent;
|
|
208
|
+
return /*#__PURE__*/ _jsx(ThemeContextDispatch.Provider, {
|
|
209
|
+
value: ThemeModeState,
|
|
210
|
+
children: /*#__PURE__*/ _jsx(ThemeProvider, {
|
|
211
|
+
theme: activeTheme,
|
|
212
|
+
children: disableCssBaseline ? /*#__PURE__*/ _jsx(WrappedAny, _extends({
|
|
213
|
+
ref: ref
|
|
214
|
+
}, rest)) : /*#__PURE__*/ _jsx(CssBaseline, {
|
|
215
|
+
enableColorScheme: true,
|
|
216
|
+
children: /*#__PURE__*/ _jsx(WrappedAny, _extends({
|
|
217
|
+
ref: ref
|
|
218
|
+
}, rest))
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
const displayName = getDisplayName(WrappedComponent);
|
|
224
|
+
WithThemeProvider.displayName = `WithThemeProvider(${displayName})`;
|
|
225
|
+
hoistNonReactStatics(WithThemeProvider, WrappedComponent);
|
|
226
|
+
return WithThemeProvider;
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
export default createWithThemeProvider;
|
|
230
|
+
|
|
231
|
+
//# sourceMappingURL=create-with-theme-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/shared/ui/theme/src/lib/hocs/create-with-theme-provider.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2023 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { _isArr, _isNull } from '@aglyn/shared-util-tools'\nimport { getDisplayName, noop } from '@aglyn/shared-util-tools'\nimport { hoistNonReactStatics } from '@aglyn/shared-util-vendor'\nimport { CssBaseline, useMediaQuery } from '@mui/material'\nimport Cookies from 'js-cookie'\nimport {\n type ComponentType,\n createContext,\n forwardRef,\n type SyntheticEvent,\n useCallback,\n useContext,\n useMemo,\n useState,\n} from 'react'\nimport { useIsomorphicLayoutEffect } from 'react-use'\nimport { createTheme, type Theme, ThemeProvider } from '../../vendor/mui'\nimport {\n parseThemeModeCookie,\n THEME_MODE_COOKIE,\n} from '../util/theme-mode-cookie'\n\nexport type ThemeMode = 'light' | 'dark' | 'system' | null\nexport type ThemeModeType = 'user' | 'system'\nexport type ThemeModeResult = [ThemeModeType, ThemeMode]\nexport type UseThemeMode = [\n mode: ThemeModeResult,\n toggleThemeMode: (event: SyntheticEvent<any>, to?: ThemeMode) => void,\n cookieMode: ThemeMode,\n /**\n * False when the surface renders light whatever the visitor asks for — a\n * site whose theme has no authored dark scheme (AGL-1292). Absent means\n * the surface can go dark; the console's own provider never sets it.\n */\n canGoDark?: boolean,\n]\n\nexport const THEME_DISPLAY_NAME: Record<ThemeMode, string> = {\n light: 'Light',\n dark: 'Dark',\n system: 'Device default',\n}\n\nexport const getThemeModeDisplayName = (theme: ThemeMode) => {\n return THEME_DISPLAY_NAME[theme] || THEME_DISPLAY_NAME.system\n}\n\n/**\n * The cookie the visitor's choice is persisted in, spelled out as a type so\n * the name has one definition across the browser reader here and the\n * server-side one in `util/theme-mode-cookie`: the annotation fails to compile\n * if the two ever name different cookies.\n */\nexport const COOKIE_THEME_KEY: 'theme-color-mode' = THEME_MODE_COOKIE\nexport const ThemeContextDispatch = createContext<UseThemeMode>([\n ['system', 'system'],\n noop,\n 'system',\n])\n\nexport function useThemeMode() {\n return useContext(ThemeContextDispatch)\n}\n\n/**\n * The stored choice as this browser reads it.\n *\n * `js-cookie` reads `document.cookie`, so on a server render there is nothing\n * to read and every visitor looks like one who has chosen nothing. That is why\n * a server-rendered surface passes the mode it resolved from the request's\n * cookies into {@link useCookieThemeMode} instead of relying on this.\n */\nfunction getCookieThemeMode(): ThemeMode {\n return parseThemeModeCookie(Cookies.get(COOKIE_THEME_KEY))\n}\n\n/**\n * The visitor's stored light/dark choice, and a setter that persists it.\n *\n * `initialMode` is the mode the surface's server render resolved from the\n * request's cookies — `null` when the request carried no choice. Supplying it\n * is what makes the FIRST render right: the state starts at the visitor's\n * choice on the server and at the identical value through hydration, rather\n * than starting empty and being corrected by the effect below once React has\n * hydrated the whole page. Omit it on a surface that only ever renders in a\n * browser, and the cookie is read directly.\n */\nexport function useCookieThemeMode(\n initialMode?: ThemeMode,\n): [ThemeMode, (mode: ThemeMode) => void] {\n const [mode, setMode] = useState<ThemeMode>(() =>\n initialMode === undefined ? getCookieThemeMode() : initialMode,\n )\n\n /**\n * Keeps the state in step with the cookie on each paint — another tab's\n * switcher, or a seed that went stale between the server render and\n * hydration. Browser-only: effects do not run during a server render, so\n * this never overwrites the seed with the server's empty read.\n */\n useIsomorphicLayoutEffect(() => {\n const cookieMode = getCookieThemeMode()\n setMode((prev) => (prev !== cookieMode ? cookieMode : prev))\n })\n\n const setCookieThemeMode = useCallback((newMode: ThemeMode) => {\n Cookies.set(COOKIE_THEME_KEY, newMode, { expires: 365 })\n setMode((prev) => (prev !== newMode ? newMode : prev))\n }, [])\n\n return useMemo(() => [mode, setCookieThemeMode], [mode, setCookieThemeMode])\n}\n\n/**\n * The resolved theme mode, in two layers with the visitor's own choice on top.\n *\n * An EXPLICIT choice comes from the cookie, which a server render can read\n * from the request — pass it as `initialMode` and the surface paints that\n * scheme in its first byte. It outranks the device: a visitor who asked for\n * light gets light on a dark laptop, and the ordering below is the only thing\n * that decides it, so the two layers are kept as separate inputs rather than\n * collapsed into one seed by the caller.\n *\n * DEVICE DEFAULT is the other layer. `prefers-color-scheme` is a media\n * feature, so a server has nothing to evaluate it against and `useMediaQuery`\n * answers light for every server render. `initialDeviceMode` supplies that\n * answer from the request instead — the `Sec-CH-Prefers-Color-Scheme` client\n * hint, where the browser sends one.\n *\n * It is fed in as `defaultMatches` rather than substituted for the media query\n * because that is the value React reads for BOTH the server render and the\n * hydration render: `useMediaQuery` publishes `defaultMatches` as its server\n * snapshot and only switches to the live `matchMedia` result once hydration is\n * complete. Seeding any earlier layer instead leaves the media query answering\n * light for the hydration commit, and the tree repaints light before the real\n * snapshot arrives — the flash this exists to remove, moved one frame later.\n */\nexport function useThemeModeState(\n initialMode?: ThemeMode,\n initialDeviceMode?: ThemeMode,\n): UseThemeMode {\n const prefersDark = useMediaQuery('(prefers-color-scheme: dark)', {\n defaultMatches: initialDeviceMode === 'dark',\n })\n const [cookieMode, setCookieMode] = useCookieThemeMode(initialMode)\n\n const systemMode = useMemo<ThemeMode>(() => {\n return prefersDark ? 'dark' : 'light'\n }, [prefersDark])\n\n const [type, mode] = useMemo<ThemeModeResult>(() => {\n if (cookieMode && cookieMode !== 'system') {\n return ['user', cookieMode]\n }\n return ['system', systemMode]\n }, [cookieMode, systemMode])\n\n const toggleThemeMode = useCallback(\n (event: SyntheticEvent<any>, to?: ThemeMode) => {\n let newMode: ThemeMode\n\n switch (true) {\n case _isNull(to):\n case to === 'system':\n newMode = 'system'\n break\n case to === 'dark':\n case to === 'light':\n newMode = to\n break\n case _isNull(cookieMode):\n newMode = 'light'\n break\n case cookieMode === 'light':\n newMode = 'dark'\n break\n case cookieMode === 'dark':\n default:\n newMode = 'system'\n break\n }\n\n setCookieMode(newMode)\n },\n [cookieMode, setCookieMode],\n )\n\n return useMemo(\n () => [[type, mode], toggleThemeMode, cookieMode],\n [type, mode, toggleThemeMode, cookieMode],\n )\n}\n\nexport type WithThemeProviderOptions = {\n theme: Theme | [lightTheme: Theme, darkTheme: Theme]\n disableCssBaseline?: boolean\n}\n\nexport function createWithThemeProvider(options: WithThemeProviderOptions) {\n const { theme, disableCssBaseline } = options\n const [lightTheme, darkTheme] = !_isArr(theme)\n ? [\n theme,\n createTheme({ ...theme, palette: { ...theme?.palette, mode: 'dark' } }),\n ]\n : theme\n\n return function withThemeProvider<P>(WrappedComponent: JSX.ComponentType<P>) {\n const WithThemeProvider = forwardRef<any, P>((props, ref) => {\n const { ...rest } = props\n const ThemeModeState = useThemeModeState()\n const activeTheme = useMemo<Theme>(() => {\n const [[, themeMode]] = ThemeModeState\n return themeMode === 'dark' ? darkTheme : lightTheme\n }, [ThemeModeState])\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const WrappedAny = WrappedComponent as ComponentType<any>\n return (\n <ThemeContextDispatch.Provider value={ThemeModeState}>\n <ThemeProvider theme={activeTheme}>\n {disableCssBaseline ? (\n <WrappedAny ref={ref} {...rest} />\n ) : (\n <CssBaseline enableColorScheme>\n <WrappedAny ref={ref} {...rest} />\n </CssBaseline>\n )}\n </ThemeProvider>\n </ThemeContextDispatch.Provider>\n )\n })\n const displayName = getDisplayName(WrappedComponent)\n WithThemeProvider.displayName = `WithThemeProvider(${displayName})`\n hoistNonReactStatics(WithThemeProvider, WrappedComponent)\n\n return WithThemeProvider\n }\n}\nexport default createWithThemeProvider\n"],"names":["_isArr","_isNull","getDisplayName","noop","hoistNonReactStatics","CssBaseline","useMediaQuery","Cookies","createContext","forwardRef","useCallback","useContext","useMemo","useState","useIsomorphicLayoutEffect","createTheme","ThemeProvider","parseThemeModeCookie","THEME_MODE_COOKIE","THEME_DISPLAY_NAME","light","dark","system","getThemeModeDisplayName","theme","COOKIE_THEME_KEY","ThemeContextDispatch","useThemeMode","getCookieThemeMode","get","useCookieThemeMode","initialMode","mode","setMode","undefined","cookieMode","prev","setCookieThemeMode","newMode","set","expires","useThemeModeState","initialDeviceMode","prefersDark","defaultMatches","setCookieMode","systemMode","type","toggleThemeMode","event","to","createWithThemeProvider","options","disableCssBaseline","lightTheme","darkTheme","palette","withThemeProvider","WrappedComponent","WithThemeProvider","props","ref","rest","ThemeModeState","activeTheme","themeMode","WrappedAny","Provider","value","enableColorScheme","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import type { Theme, ThemeOptions } from '../vendor/mui';
|
|
18
|
+
export declare const tenantOptions: ThemeOptions;
|
|
19
|
+
export declare const tenantOptionsDark: ThemeOptions;
|
|
20
|
+
export declare const tenantThemeLight: Theme;
|
|
21
|
+
export declare const tenantThemeDark: Theme;
|
|
22
|
+
export declare const PLATFORM_BRAND_HOSTS: ReadonlySet<string>;
|
|
23
|
+
export declare function wearsPlatformBrand(host: string | undefined): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The site key {@link wearsPlatformBrand} is asked about, read off a host
|
|
26
|
+
* document (AGL-3068).
|
|
27
|
+
*
|
|
28
|
+
* The tenant is handed its `[host]` route param, which is the attached domain
|
|
29
|
+
* under the middleware's `cname--` sentinel or a bare subdomain label. A
|
|
30
|
+
* console surface has the document instead, where those are two fields: the
|
|
31
|
+
* attached domain is what a platform-brand host is listed under, and the
|
|
32
|
+
* subdomain is what every other site is reachable by. Reading them in that
|
|
33
|
+
* order is what makes the editor ask the same question the published page
|
|
34
|
+
* answers.
|
|
35
|
+
*/
|
|
36
|
+
export declare function hostBrandKey(host: {
|
|
37
|
+
cname?: string;
|
|
38
|
+
subdomain?: string;
|
|
39
|
+
} | null | undefined): string | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* The options a site's own theme is layered onto: the platform's brand for
|
|
42
|
+
* the operator's own hosts, the neutral tenant default for everyone else
|
|
43
|
+
* (AGL-3068).
|
|
44
|
+
*
|
|
45
|
+
* One decision, because it used to be four. The tenant made it per host,
|
|
46
|
+
* while the besigner canvas, the theme editor's preview and the "Default ·
|
|
47
|
+
* #…" the editor prints beside every unset slot all built on the brand base
|
|
48
|
+
* unconditionally — so a customer site was authored in Aglyn's cyan and
|
|
49
|
+
* published in MUI's blue, and an author correcting contrast was correcting a
|
|
50
|
+
* page that does not exist.
|
|
51
|
+
*
|
|
52
|
+
* An unknown host is NOT a platform host, exactly as `wearsPlatformBrand`
|
|
53
|
+
* already reads it: the operator's hosts are the named exception, so a
|
|
54
|
+
* surface that cannot name the site resolves what a customer site resolves.
|
|
55
|
+
*/
|
|
56
|
+
export declare function siteBaseOptions(host: string | undefined, scheme: 'light' | 'dark'): ThemeOptions;
|
|
57
|
+
/** The built theme a site with no customization of its own renders under. */
|
|
58
|
+
export declare function siteFallbackTheme(host: string | undefined, scheme: 'light' | 'dark'): Theme;
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
17
|
+
var // Dot notation, not brackets: Next substitutes `process.env.NAME`
|
|
18
|
+
// TEXTUALLY, and never the bracket form, so a bracket read is `undefined`
|
|
19
|
+
// in any browser or edge bundle and silently falls back to the default
|
|
20
|
+
// below — which on a self-host install would hand the operator Aglyn's
|
|
21
|
+
// hosts (AGL-2037).
|
|
22
|
+
_process_env_NEXT_PUBLIC_PLATFORM_BRAND_HOSTS;
|
|
23
|
+
import { consoleOptions, consoleOptionsDark, consoleThemeDark, consoleThemeLight } from "./console.theme.js";
|
|
24
|
+
import createResponsiveTheme from "./util/create-responsive-theme.js";
|
|
25
|
+
/**
|
|
26
|
+
* The default palette a tenant site wears when it has authored none of its
|
|
27
|
+
* own.
|
|
28
|
+
*
|
|
29
|
+
* MUI's stock accents, extended with every slot this platform adds on top of
|
|
30
|
+
* a MUI palette — `tertiary`, `surface`, `tint`, `inputOutline` and the three
|
|
31
|
+
* `svg*` records — so a site that never opens the theme editor still resolves
|
|
32
|
+
* every token a component can ask for.
|
|
33
|
+
*
|
|
34
|
+
* Stock rather than the Aglyn brand because the brand palette carries a
|
|
35
|
+
* signed-off sub-AA pairing (white on `#00b0ff`, 2.43:1): a considered
|
|
36
|
+
* decision about OUR brand, and not one to hand a customer who never made it.
|
|
37
|
+
* Every accent here clears the 4.5:1 AA text bar as text and carries its own
|
|
38
|
+
* `contrastText` at AA on the fill, in both schemes.
|
|
39
|
+
*
|
|
40
|
+
* Non-palette options come from `consoleOptions`, so component behaviour,
|
|
41
|
+
* type ramp, spacing and shadows are identical platform-wide — the palette is
|
|
42
|
+
* the only thing a tenant default changes.
|
|
43
|
+
*/ /**
|
|
44
|
+
* The one grey ramp, read from the brand palette rather than copied. A
|
|
45
|
+
* neutral scale is not a brand decision, and a second copy is a second thing
|
|
46
|
+
* to drift.
|
|
47
|
+
*/ const grey = consoleOptions.palette.grey;
|
|
48
|
+
const tenantColorScheme = {
|
|
49
|
+
light: {
|
|
50
|
+
primary: {
|
|
51
|
+
main: '#1976d2',
|
|
52
|
+
// The accent-as-text shade (`ACCENT_TEXT_SHADE`): 7.50:1 on the page,
|
|
53
|
+
// 7.82:1 on paper. Authored for the same reason as the console's — the
|
|
54
|
+
// slot every link resolves to belongs in the palette, not in a walk.
|
|
55
|
+
dark: '#125393',
|
|
56
|
+
contrastText: '#FFFFFF'
|
|
57
|
+
},
|
|
58
|
+
secondary: {
|
|
59
|
+
main: '#9c27b0',
|
|
60
|
+
dark: '#6d1b7b',
|
|
61
|
+
contrastText: '#FFFFFF'
|
|
62
|
+
},
|
|
63
|
+
// A neutral slate for the third accent, matching the role `tertiary`
|
|
64
|
+
// plays in the console palette.
|
|
65
|
+
tertiary: {
|
|
66
|
+
main: '#4a5568',
|
|
67
|
+
dark: '#343b49',
|
|
68
|
+
contrastText: '#FFFFFF'
|
|
69
|
+
},
|
|
70
|
+
surface: {
|
|
71
|
+
main: '#f1f3f5',
|
|
72
|
+
contrastText: '#000000DE'
|
|
73
|
+
},
|
|
74
|
+
tint: {
|
|
75
|
+
primary: '#e8f1fb',
|
|
76
|
+
secondary: '#f5e9f7',
|
|
77
|
+
tertiary: '#eef0f3'
|
|
78
|
+
},
|
|
79
|
+
inputOutline: 'rgba(0, 0, 0, 0.23)',
|
|
80
|
+
background: {
|
|
81
|
+
default: '#fafafa',
|
|
82
|
+
paper: '#ffffff'
|
|
83
|
+
},
|
|
84
|
+
info: {
|
|
85
|
+
main: '#0288d1',
|
|
86
|
+
dark: '#015f92',
|
|
87
|
+
contrastText: '#000000DE'
|
|
88
|
+
},
|
|
89
|
+
error: {
|
|
90
|
+
main: '#d32f2f',
|
|
91
|
+
dark: '#942121',
|
|
92
|
+
contrastText: '#FFFFFF'
|
|
93
|
+
},
|
|
94
|
+
success: {
|
|
95
|
+
main: '#2e7d32',
|
|
96
|
+
dark: '#205823',
|
|
97
|
+
contrastText: '#FFFFFF'
|
|
98
|
+
},
|
|
99
|
+
warning: {
|
|
100
|
+
main: '#ed6c02',
|
|
101
|
+
dark: '#a64c01',
|
|
102
|
+
contrastText: '#000000DE'
|
|
103
|
+
},
|
|
104
|
+
grey,
|
|
105
|
+
svgBackground: {
|
|
106
|
+
main: '#FAFAFA',
|
|
107
|
+
hover: '#FAFAFA',
|
|
108
|
+
active: '#FAFAFA',
|
|
109
|
+
focus: '#FAFAFA'
|
|
110
|
+
},
|
|
111
|
+
svgFilled: {
|
|
112
|
+
main: '#9E9E9E',
|
|
113
|
+
hover: '#1976d2',
|
|
114
|
+
active: '#1976d2',
|
|
115
|
+
focus: '#1976d2'
|
|
116
|
+
},
|
|
117
|
+
svgStroke: {
|
|
118
|
+
main: '#FFFFFF',
|
|
119
|
+
hover: '#FFFFFF',
|
|
120
|
+
active: '#FFFFFF',
|
|
121
|
+
focus: '#FFFFFF'
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
dark: {
|
|
125
|
+
primary: {
|
|
126
|
+
main: '#1976d2',
|
|
127
|
+
// LIGHTER than `main`, as every accent-as-text shade must be on a dark
|
|
128
|
+
// ground: 6.70:1 on the page, 5.96:1 on paper. MUI derives `dark` by
|
|
129
|
+
// darkening in both schemes, which points the wrong way here.
|
|
130
|
+
dark: '#5e9fe0',
|
|
131
|
+
contrastText: '#FFFFFF'
|
|
132
|
+
},
|
|
133
|
+
secondary: {
|
|
134
|
+
main: '#9c27b0',
|
|
135
|
+
dark: '#ba68c8',
|
|
136
|
+
contrastText: '#FFFFFF'
|
|
137
|
+
},
|
|
138
|
+
// Lifted from the light scheme's slate: `#4a5568` is 1.9:1 against this
|
|
139
|
+
// page and would be a third accent nobody can read.
|
|
140
|
+
tertiary: {
|
|
141
|
+
main: '#94a3b8',
|
|
142
|
+
dark: '#b4bfcd',
|
|
143
|
+
contrastText: '#000000DE'
|
|
144
|
+
},
|
|
145
|
+
surface: {
|
|
146
|
+
main: '#242c35',
|
|
147
|
+
contrastText: '#FFFFFF'
|
|
148
|
+
},
|
|
149
|
+
// Tile fills, held around 1.5:1 from the page so a tinted tile has a
|
|
150
|
+
// visible edge without a border.
|
|
151
|
+
tint: {
|
|
152
|
+
primary: '#1e3a5c',
|
|
153
|
+
secondary: '#472653',
|
|
154
|
+
tertiary: '#2e3742'
|
|
155
|
+
},
|
|
156
|
+
inputOutline: 'rgba(255, 255, 255, 0.23)',
|
|
157
|
+
background: {
|
|
158
|
+
default: '#121212',
|
|
159
|
+
paper: '#1e1e1e'
|
|
160
|
+
},
|
|
161
|
+
info: {
|
|
162
|
+
main: '#0288d1',
|
|
163
|
+
dark: '#4eacdf',
|
|
164
|
+
contrastText: '#000000DE'
|
|
165
|
+
},
|
|
166
|
+
error: {
|
|
167
|
+
main: '#d32f2f',
|
|
168
|
+
dark: '#e06d6d',
|
|
169
|
+
contrastText: '#FFFFFF'
|
|
170
|
+
},
|
|
171
|
+
success: {
|
|
172
|
+
main: '#2e7d32',
|
|
173
|
+
dark: '#6da470',
|
|
174
|
+
contrastText: '#FFFFFF'
|
|
175
|
+
},
|
|
176
|
+
warning: {
|
|
177
|
+
main: '#ed6c02',
|
|
178
|
+
dark: '#f2984e',
|
|
179
|
+
contrastText: '#000000DE'
|
|
180
|
+
},
|
|
181
|
+
grey,
|
|
182
|
+
svgBackground: {
|
|
183
|
+
main: '#242c35',
|
|
184
|
+
hover: '#242c35',
|
|
185
|
+
active: '#242c35',
|
|
186
|
+
focus: '#242c35'
|
|
187
|
+
},
|
|
188
|
+
svgFilled: {
|
|
189
|
+
main: '#9E9E9E',
|
|
190
|
+
hover: '#5e9fe0',
|
|
191
|
+
active: '#5e9fe0',
|
|
192
|
+
focus: '#5e9fe0'
|
|
193
|
+
},
|
|
194
|
+
svgStroke: {
|
|
195
|
+
main: '#FFFFFF',
|
|
196
|
+
hover: '#FFFFFF',
|
|
197
|
+
active: '#FFFFFF',
|
|
198
|
+
focus: '#FFFFFF'
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
export const tenantOptions = _extends({}, consoleOptions, {
|
|
203
|
+
palette: _extends({
|
|
204
|
+
mode: 'light'
|
|
205
|
+
}, tenantColorScheme.light)
|
|
206
|
+
});
|
|
207
|
+
export const tenantOptionsDark = _extends({}, consoleOptionsDark, {
|
|
208
|
+
palette: _extends({
|
|
209
|
+
mode: 'dark'
|
|
210
|
+
}, tenantColorScheme.dark)
|
|
211
|
+
});
|
|
212
|
+
export const tenantThemeLight = createResponsiveTheme({
|
|
213
|
+
themeOptions: _extends({}, tenantOptions)
|
|
214
|
+
});
|
|
215
|
+
export const tenantThemeDark = createResponsiveTheme({
|
|
216
|
+
themeOptions: _extends({}, tenantOptionsDark)
|
|
217
|
+
});
|
|
218
|
+
/**
|
|
219
|
+
* Hosts whose brand IS the operator's own brand, and which therefore keep
|
|
220
|
+
* `consoleOptions` rather than the tenant default.
|
|
221
|
+
*
|
|
222
|
+
* Comma-separated in `NEXT_PUBLIC_PLATFORM_BRAND_HOSTS`, so a self-host
|
|
223
|
+
* operator points it at their own marketing domain and their customers still
|
|
224
|
+
* resolve the neutral tenant palette. The literal is the `??` default and
|
|
225
|
+
* nothing else reads it: the platform's own deployment needs no variable to
|
|
226
|
+
* keep its brand. Setting the variable to an empty string puts every host,
|
|
227
|
+
* including the operator's own, on the tenant default.
|
|
228
|
+
*
|
|
229
|
+
* Matched on the registrable domain, after stripping the `cname--` prefix the
|
|
230
|
+
* tenant middleware puts on a CUSTOM DOMAIN before it becomes the `[host]`
|
|
231
|
+
* route segment: the param this is handed reads `cname--example.com`, never
|
|
232
|
+
* the bare apex. A platform subdomain resolves to a bare label instead
|
|
233
|
+
* (`acme` for `acme.aglyn.app`), which correctly matches nothing — a customer
|
|
234
|
+
* on a platform subdomain is still a tenant.
|
|
235
|
+
*/ const CNAME_PREFIX = 'cname--';
|
|
236
|
+
export const PLATFORM_BRAND_HOSTS = new Set(((_process_env_NEXT_PUBLIC_PLATFORM_BRAND_HOSTS = process.env.NEXT_PUBLIC_PLATFORM_BRAND_HOSTS) != null ? _process_env_NEXT_PUBLIC_PLATFORM_BRAND_HOSTS : 'aglyn.com,aglyn.io').split(',').map((host)=>host.trim().toLowerCase()).filter(Boolean));
|
|
237
|
+
export function wearsPlatformBrand(host) {
|
|
238
|
+
if (!host) return false;
|
|
239
|
+
const normalized = host.trim().toLowerCase();
|
|
240
|
+
return PLATFORM_BRAND_HOSTS.has(normalized.startsWith(CNAME_PREFIX) ? normalized.slice(CNAME_PREFIX.length) : normalized);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* The site key {@link wearsPlatformBrand} is asked about, read off a host
|
|
244
|
+
* document (AGL-3068).
|
|
245
|
+
*
|
|
246
|
+
* The tenant is handed its `[host]` route param, which is the attached domain
|
|
247
|
+
* under the middleware's `cname--` sentinel or a bare subdomain label. A
|
|
248
|
+
* console surface has the document instead, where those are two fields: the
|
|
249
|
+
* attached domain is what a platform-brand host is listed under, and the
|
|
250
|
+
* subdomain is what every other site is reachable by. Reading them in that
|
|
251
|
+
* order is what makes the editor ask the same question the published page
|
|
252
|
+
* answers.
|
|
253
|
+
*/ export function hostBrandKey(host) {
|
|
254
|
+
return (host == null ? void 0 : host.cname) || (host == null ? void 0 : host.subdomain) || undefined;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* The options a site's own theme is layered onto: the platform's brand for
|
|
258
|
+
* the operator's own hosts, the neutral tenant default for everyone else
|
|
259
|
+
* (AGL-3068).
|
|
260
|
+
*
|
|
261
|
+
* One decision, because it used to be four. The tenant made it per host,
|
|
262
|
+
* while the besigner canvas, the theme editor's preview and the "Default ·
|
|
263
|
+
* #…" the editor prints beside every unset slot all built on the brand base
|
|
264
|
+
* unconditionally — so a customer site was authored in Aglyn's cyan and
|
|
265
|
+
* published in MUI's blue, and an author correcting contrast was correcting a
|
|
266
|
+
* page that does not exist.
|
|
267
|
+
*
|
|
268
|
+
* An unknown host is NOT a platform host, exactly as `wearsPlatformBrand`
|
|
269
|
+
* already reads it: the operator's hosts are the named exception, so a
|
|
270
|
+
* surface that cannot name the site resolves what a customer site resolves.
|
|
271
|
+
*/ export function siteBaseOptions(host, scheme) {
|
|
272
|
+
const brand = wearsPlatformBrand(host);
|
|
273
|
+
if (scheme === 'dark') return brand ? consoleOptionsDark : tenantOptionsDark;
|
|
274
|
+
return brand ? consoleOptions : tenantOptions;
|
|
275
|
+
}
|
|
276
|
+
/** The built theme a site with no customization of its own renders under. */ export function siteFallbackTheme(host, scheme) {
|
|
277
|
+
const brand = wearsPlatformBrand(host);
|
|
278
|
+
if (scheme === 'dark') return brand ? consoleThemeDark : tenantThemeDark;
|
|
279
|
+
return brand ? consoleThemeLight : tenantThemeLight;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
//# sourceMappingURL=tenant.theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/shared/ui/theme/src/lib/tenant.theme.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport type { PaletteOptions, Theme, ThemeOptions } from '../vendor/mui'\nimport {\n consoleOptions,\n consoleOptionsDark,\n consoleThemeDark,\n consoleThemeLight,\n} from './console.theme'\nimport createResponsiveTheme from './util/create-responsive-theme'\n\n/**\n * The default palette a tenant site wears when it has authored none of its\n * own.\n *\n * MUI's stock accents, extended with every slot this platform adds on top of\n * a MUI palette — `tertiary`, `surface`, `tint`, `inputOutline` and the three\n * `svg*` records — so a site that never opens the theme editor still resolves\n * every token a component can ask for.\n *\n * Stock rather than the Aglyn brand because the brand palette carries a\n * signed-off sub-AA pairing (white on `#00b0ff`, 2.43:1): a considered\n * decision about OUR brand, and not one to hand a customer who never made it.\n * Every accent here clears the 4.5:1 AA text bar as text and carries its own\n * `contrastText` at AA on the fill, in both schemes.\n *\n * Non-palette options come from `consoleOptions`, so component behaviour,\n * type ramp, spacing and shadows are identical platform-wide — the palette is\n * the only thing a tenant default changes.\n */\n/**\n * The one grey ramp, read from the brand palette rather than copied. A\n * neutral scale is not a brand decision, and a second copy is a second thing\n * to drift.\n */\nconst grey = (consoleOptions.palette as { grey: PaletteOptions['grey'] }).grey\n\nconst tenantColorScheme = {\n light: {\n primary: {\n main: '#1976d2',\n // The accent-as-text shade (`ACCENT_TEXT_SHADE`): 7.50:1 on the page,\n // 7.82:1 on paper. Authored for the same reason as the console's — the\n // slot every link resolves to belongs in the palette, not in a walk.\n dark: '#125393',\n contrastText: '#FFFFFF',\n },\n secondary: {\n main: '#9c27b0',\n dark: '#6d1b7b',\n contrastText: '#FFFFFF',\n },\n // A neutral slate for the third accent, matching the role `tertiary`\n // plays in the console palette.\n tertiary: {\n main: '#4a5568',\n dark: '#343b49',\n contrastText: '#FFFFFF',\n },\n surface: {\n main: '#f1f3f5',\n contrastText: '#000000DE',\n },\n tint: {\n primary: '#e8f1fb',\n secondary: '#f5e9f7',\n tertiary: '#eef0f3',\n },\n inputOutline: 'rgba(0, 0, 0, 0.23)',\n background: {\n default: '#fafafa',\n paper: '#ffffff',\n },\n info: {\n main: '#0288d1',\n dark: '#015f92',\n contrastText: '#000000DE',\n },\n error: {\n main: '#d32f2f',\n dark: '#942121',\n contrastText: '#FFFFFF',\n },\n success: {\n main: '#2e7d32',\n dark: '#205823',\n contrastText: '#FFFFFF',\n },\n warning: {\n main: '#ed6c02',\n dark: '#a64c01',\n contrastText: '#000000DE',\n },\n grey,\n svgBackground: {\n main: '#FAFAFA',\n hover: '#FAFAFA',\n active: '#FAFAFA',\n focus: '#FAFAFA',\n },\n svgFilled: {\n main: '#9E9E9E',\n hover: '#1976d2',\n active: '#1976d2',\n focus: '#1976d2',\n },\n svgStroke: {\n main: '#FFFFFF',\n hover: '#FFFFFF',\n active: '#FFFFFF',\n focus: '#FFFFFF',\n },\n },\n dark: {\n primary: {\n main: '#1976d2',\n // LIGHTER than `main`, as every accent-as-text shade must be on a dark\n // ground: 6.70:1 on the page, 5.96:1 on paper. MUI derives `dark` by\n // darkening in both schemes, which points the wrong way here.\n dark: '#5e9fe0',\n contrastText: '#FFFFFF',\n },\n secondary: {\n main: '#9c27b0',\n dark: '#ba68c8',\n contrastText: '#FFFFFF',\n },\n // Lifted from the light scheme's slate: `#4a5568` is 1.9:1 against this\n // page and would be a third accent nobody can read.\n tertiary: {\n main: '#94a3b8',\n dark: '#b4bfcd',\n contrastText: '#000000DE',\n },\n surface: {\n main: '#242c35',\n contrastText: '#FFFFFF',\n },\n // Tile fills, held around 1.5:1 from the page so a tinted tile has a\n // visible edge without a border.\n tint: {\n primary: '#1e3a5c',\n secondary: '#472653',\n tertiary: '#2e3742',\n },\n inputOutline: 'rgba(255, 255, 255, 0.23)',\n background: {\n default: '#121212',\n paper: '#1e1e1e',\n },\n info: {\n main: '#0288d1',\n dark: '#4eacdf',\n contrastText: '#000000DE',\n },\n error: {\n main: '#d32f2f',\n dark: '#e06d6d',\n contrastText: '#FFFFFF',\n },\n success: {\n main: '#2e7d32',\n dark: '#6da470',\n contrastText: '#FFFFFF',\n },\n warning: {\n main: '#ed6c02',\n dark: '#f2984e',\n contrastText: '#000000DE',\n },\n grey,\n svgBackground: {\n main: '#242c35',\n hover: '#242c35',\n active: '#242c35',\n focus: '#242c35',\n },\n svgFilled: {\n main: '#9E9E9E',\n hover: '#5e9fe0',\n active: '#5e9fe0',\n focus: '#5e9fe0',\n },\n svgStroke: {\n main: '#FFFFFF',\n hover: '#FFFFFF',\n active: '#FFFFFF',\n focus: '#FFFFFF',\n },\n },\n}\n\nexport const tenantOptions: ThemeOptions = {\n ...consoleOptions,\n palette: {\n mode: 'light',\n ...tenantColorScheme.light,\n },\n}\nexport const tenantOptionsDark: ThemeOptions = {\n ...consoleOptionsDark,\n palette: {\n mode: 'dark',\n ...tenantColorScheme.dark,\n },\n}\n\nexport const tenantThemeLight: Theme = createResponsiveTheme({\n themeOptions: { ...tenantOptions },\n})\nexport const tenantThemeDark: Theme = createResponsiveTheme({\n themeOptions: { ...tenantOptionsDark },\n})\n\n/**\n * Hosts whose brand IS the operator's own brand, and which therefore keep\n * `consoleOptions` rather than the tenant default.\n *\n * Comma-separated in `NEXT_PUBLIC_PLATFORM_BRAND_HOSTS`, so a self-host\n * operator points it at their own marketing domain and their customers still\n * resolve the neutral tenant palette. The literal is the `??` default and\n * nothing else reads it: the platform's own deployment needs no variable to\n * keep its brand. Setting the variable to an empty string puts every host,\n * including the operator's own, on the tenant default.\n *\n * Matched on the registrable domain, after stripping the `cname--` prefix the\n * tenant middleware puts on a CUSTOM DOMAIN before it becomes the `[host]`\n * route segment: the param this is handed reads `cname--example.com`, never\n * the bare apex. A platform subdomain resolves to a bare label instead\n * (`acme` for `acme.aglyn.app`), which correctly matches nothing — a customer\n * on a platform subdomain is still a tenant.\n */\nconst CNAME_PREFIX = 'cname--'\n\nexport const PLATFORM_BRAND_HOSTS: ReadonlySet<string> = new Set(\n // Dot notation, not brackets: Next substitutes `process.env.NAME`\n // TEXTUALLY, and never the bracket form, so a bracket read is `undefined`\n // in any browser or edge bundle and silently falls back to the default\n // below — which on a self-host install would hand the operator Aglyn's\n // hosts (AGL-2037).\n (process.env.NEXT_PUBLIC_PLATFORM_BRAND_HOSTS ?? 'aglyn.com,aglyn.io')\n .split(',')\n .map((host) => host.trim().toLowerCase())\n .filter(Boolean),\n)\n\nexport function wearsPlatformBrand(host: string | undefined): boolean {\n if (!host) return false\n const normalized = host.trim().toLowerCase()\n return PLATFORM_BRAND_HOSTS.has(\n normalized.startsWith(CNAME_PREFIX)\n ? normalized.slice(CNAME_PREFIX.length)\n : normalized,\n )\n}\n\n/**\n * The site key {@link wearsPlatformBrand} is asked about, read off a host\n * document (AGL-3068).\n *\n * The tenant is handed its `[host]` route param, which is the attached domain\n * under the middleware's `cname--` sentinel or a bare subdomain label. A\n * console surface has the document instead, where those are two fields: the\n * attached domain is what a platform-brand host is listed under, and the\n * subdomain is what every other site is reachable by. Reading them in that\n * order is what makes the editor ask the same question the published page\n * answers.\n */\nexport function hostBrandKey(\n host: { cname?: string; subdomain?: string } | null | undefined,\n): string | undefined {\n return host?.cname || host?.subdomain || undefined\n}\n\n/**\n * The options a site's own theme is layered onto: the platform's brand for\n * the operator's own hosts, the neutral tenant default for everyone else\n * (AGL-3068).\n *\n * One decision, because it used to be four. The tenant made it per host,\n * while the besigner canvas, the theme editor's preview and the \"Default ·\n * #…\" the editor prints beside every unset slot all built on the brand base\n * unconditionally — so a customer site was authored in Aglyn's cyan and\n * published in MUI's blue, and an author correcting contrast was correcting a\n * page that does not exist.\n *\n * An unknown host is NOT a platform host, exactly as `wearsPlatformBrand`\n * already reads it: the operator's hosts are the named exception, so a\n * surface that cannot name the site resolves what a customer site resolves.\n */\nexport function siteBaseOptions(\n host: string | undefined,\n scheme: 'light' | 'dark',\n): ThemeOptions {\n const brand = wearsPlatformBrand(host)\n if (scheme === 'dark') return brand ? consoleOptionsDark : tenantOptionsDark\n return brand ? consoleOptions : tenantOptions\n}\n\n/** The built theme a site with no customization of its own renders under. */\nexport function siteFallbackTheme(\n host: string | undefined,\n scheme: 'light' | 'dark',\n): Theme {\n const brand = wearsPlatformBrand(host)\n if (scheme === 'dark') return brand ? consoleThemeDark : tenantThemeDark\n return brand ? consoleThemeLight : tenantThemeLight\n}\n"],"names":["process","consoleOptions","consoleOptionsDark","consoleThemeDark","consoleThemeLight","createResponsiveTheme","grey","palette","tenantColorScheme","light","primary","main","dark","contrastText","secondary","tertiary","surface","tint","inputOutline","background","default","paper","info","error","success","warning","svgBackground","hover","active","focus","svgFilled","svgStroke","tenantOptions","mode","tenantOptionsDark","tenantThemeLight","themeOptions","tenantThemeDark","CNAME_PREFIX","PLATFORM_BRAND_HOSTS","Set","env","NEXT_PUBLIC_PLATFORM_BRAND_HOSTS","split","map","host","trim","toLowerCase","filter","Boolean","wearsPlatformBrand","normalized","has","startsWith","slice","length","hostBrandKey","cname","subdomain","undefined","siteBaseOptions","scheme","brand","siteFallbackTheme"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
export interface IActionStates {
|
|
18
|
+
main: string;
|
|
19
|
+
hover: string;
|
|
20
|
+
active: string;
|
|
21
|
+
focus: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ColorPropOverrides {
|
|
24
|
+
tertiary: true;
|
|
25
|
+
surface: true;
|
|
26
|
+
}
|