@aesthetic/system
Version:
Web based building blocks for the Aesthetic design system.
171 lines (135 loc) • 4.19 kB
JavaScript
// Bundled with Packemon: https://packemon.dev
// Platform: browser, Support: stable, Format: esm
import { T as Theme } from './bundle-8c53cc4f.js';
export { B as BORDER_SIZES, a as BREAKPOINT_SIZES, b as DEPTHS, D as Design, H as HEADING_LEVELS, c as HEADING_SIZES, P as PALETTE_TYPES, d as SHADE_RANGES, e as SHADOW_SIZES, S as SIZES, f as SPACING_SIZES, g as TEXT_SIZES, T as Theme, m as mixin } from './bundle-8c53cc4f.js';
import '@aesthetic/utils';
class ThemeRegistry {
constructor() {
this.darkTheme = '';
this.defaultTheme = '';
this.lightTheme = '';
this.themes = {};
}
/**
* Return the default dark theme.
*/
getDarkTheme() {
return this.getTheme(this.darkTheme);
}
/**
* Return the default light theme.
*/
getLightTheme() {
return this.getTheme(this.lightTheme);
}
/**
* Find an approprite theme based on the user's or device's preferences.
* Will check for preferred color schemes and contrast levels.
*/
getPreferredTheme({
matchColorScheme,
matchContrastLevel
} = {}) {
const prefersDarkScheme = matchColorScheme?.('dark');
const prefersLightScheme = matchColorScheme?.('light');
const prefersHighContrast = matchContrastLevel?.('high');
const prefersLowContrast = matchContrastLevel?.('low');
const schemeCheckOrder = [];
if (prefersDarkScheme) {
schemeCheckOrder.push('dark');
} else if (prefersLightScheme) {
schemeCheckOrder.push('light');
}
let possibleTheme; // Find a theme based on device preferences
schemeCheckOrder.some(scheme => {
const contrastCheckOrder = ['normal'];
if (prefersHighContrast) {
contrastCheckOrder.unshift('high');
} else if (prefersLowContrast) {
contrastCheckOrder.unshift('low');
}
return contrastCheckOrder.some(contrast => {
possibleTheme = this.query({
contrast,
scheme
});
return !!possibleTheme;
});
});
if (possibleTheme) {
return possibleTheme;
}
if (this.defaultTheme) {
return this.getTheme(this.defaultTheme);
}
throw new Error('No themes have been registered.');
}
/**
* Return a theme by name or throw an error if not found.
*/
getTheme(name) {
if (process.env.NODE_ENV !== "production" && !name) {
throw new Error('Cannot find a theme without a name.');
}
const theme = this.themes[name];
if (process.env.NODE_ENV !== "production" && !theme) {
throw new Error(`Theme "${name}" does not exist. Has it been registered?`);
}
return theme;
}
/**
* Query for a theme that matches the defined parameters.
*/
query(params) {
return Object.values(this.themes).find(theme => {
const conditions = [];
if (params.contrast) {
conditions.push(theme.contrast === params.contrast);
}
if (params.scheme) {
conditions.push(theme.scheme === params.scheme);
}
return conditions.every(c => !!c);
});
}
/**
* Register a theme with a unique name. Can optionally mark a theme
* as default for their defined color scheme.
*/
register(name, theme, isDefault = false) {
if (process.env.NODE_ENV !== "production" && !(theme instanceof Theme)) {
throw new TypeError('Only a `Theme` object can be registered.');
}
if (isDefault) {
if (theme.scheme === 'dark') {
this.darkTheme = name;
} else {
this.lightTheme = name;
}
}
if (theme.name && theme.name !== name) {
if (process.env.NODE_ENV !== "production") {
throw new Error(`Theme "${name}" has already been registered under "${theme.name}".`);
}
} else {
// eslint-disable-next-line no-param-reassign
theme.name = name;
}
if (!this.defaultTheme) {
this.defaultTheme = name;
}
this.themes[name] = theme;
return this;
}
/**
* Reset the registry to initial state.
*/
reset() {
this.darkTheme = '';
this.lightTheme = '';
this.defaultTheme = '';
this.themes = {};
}
}
export { ThemeRegistry };
//# sourceMappingURL=index.js.map