Fix: An issue that would cause Matugen colors to not apply. (#929)
* Eslint updates * linter fixes * Type fixes * More type fixes * Fix isvis * More type fixes * Type Fixes * Consolidate logic to manage options * Linter fixes * Package lock update * Update configs * Version checker * Debug pipeline * Package lock update * Update ci * Strict check * Revert ci * Eslint * Remove rule since it causes issues in CI * Actual matugen fix
This commit is contained in:
169
src/lib/options/ConfigManager.ts
Normal file
169
src/lib/options/ConfigManager.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
import { readFile, writeFile, monitorFile } from 'astal/file';
|
||||
import { errorHandler, Notify } from '../utils';
|
||||
import { ensureDirectory } from '../session';
|
||||
import icons from '../icons/icons';
|
||||
|
||||
/**
|
||||
* Manages configuration file operations including reading, writing, and change monitoring
|
||||
*
|
||||
* The ConfigManager centralizes all configuration persistence operations and provides
|
||||
* utilities for working with nested configuration structures.
|
||||
*/
|
||||
export class ConfigManager {
|
||||
private _configPath: string;
|
||||
private _changeCallbacks: Array<() => void> = [];
|
||||
|
||||
/**
|
||||
* Creates a new configuration manager for a specific config file
|
||||
*
|
||||
* @param configPath - Path to the configuration file to manage
|
||||
*/
|
||||
constructor(configPath: string) {
|
||||
this._configPath = configPath;
|
||||
this._ensureConfigDirectory();
|
||||
this._setupConfigMonitor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a single option in the configuration file
|
||||
*
|
||||
* @param id - Dot-notation path of the option to update
|
||||
* @param value - New value to store for the option
|
||||
*/
|
||||
public updateOption(id: string, value: unknown): void {
|
||||
const config = this.readConfig();
|
||||
config[id] = value;
|
||||
this.writeConfig(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value from a nested object using a path
|
||||
*
|
||||
* @param dataObject - The object to search within
|
||||
* @param path - Dot-notation path or array of path segments
|
||||
* @returns The value at the specified path or undefined if not found
|
||||
*/
|
||||
public getNestedValue(dataObject: Record<string, unknown>, path: string | string[]): unknown {
|
||||
const pathArray = typeof path === 'string' ? path.split('.') : path;
|
||||
return this._findValueByPath(dataObject, pathArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current configuration from disk
|
||||
*
|
||||
* @returns The parsed configuration object or an empty object if the file doesn't exist
|
||||
*/
|
||||
public readConfig(): Record<string, unknown> {
|
||||
const raw = readFile(this._configPath);
|
||||
if (!raw || raw.trim() === '') {
|
||||
return {};
|
||||
}
|
||||
try {
|
||||
return JSON.parse(raw);
|
||||
} catch (error) {
|
||||
this._handleConfigError(error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes configuration to disk
|
||||
*
|
||||
* @param config - The configuration object to serialize and save
|
||||
*/
|
||||
public writeConfig(config: Record<string, unknown>): void {
|
||||
writeFile(this._configPath, JSON.stringify(config, null, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback to be called when the config file changes
|
||||
*
|
||||
* @param callback - Function to execute when config file changes are detected
|
||||
*/
|
||||
public onConfigChanged(callback: () => void): void {
|
||||
this._changeCallbacks.push(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively navigates an object to find a value at the specified path
|
||||
*
|
||||
* @param currentObject - The object currently being traversed
|
||||
* @param pathKeys - Remaining path segments to navigate
|
||||
* @returns The value at the path or undefined if not found
|
||||
*/
|
||||
private _findValueByPath(currentObject: Record<string, unknown>, pathKeys: string[]): unknown {
|
||||
const currentKey = pathKeys.shift();
|
||||
if (currentKey === undefined) {
|
||||
return currentObject;
|
||||
}
|
||||
if (!this._isObject(currentObject)) {
|
||||
return;
|
||||
}
|
||||
const propertyPath = [currentKey, ...pathKeys].join('.');
|
||||
if (propertyPath in currentObject) {
|
||||
return currentObject[propertyPath];
|
||||
}
|
||||
if (!(currentKey in currentObject)) {
|
||||
return;
|
||||
}
|
||||
const currentKeyValue = currentObject[currentKey];
|
||||
if (!this._isObject(currentKeyValue)) {
|
||||
return;
|
||||
}
|
||||
return this._findValueByPath(currentKeyValue, pathKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the directory for the config file exists
|
||||
*/
|
||||
private _ensureConfigDirectory(): void {
|
||||
ensureDirectory(this._configPath.split('/').slice(0, -1).join('/'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up file monitoring to detect external changes to the config file
|
||||
*/
|
||||
private _setupConfigMonitor(): void {
|
||||
const debounceTimeMs = 200;
|
||||
let lastEventTime = Date.now();
|
||||
monitorFile(this._configPath, () => {
|
||||
if (Date.now() - lastEventTime < debounceTimeMs) {
|
||||
return;
|
||||
}
|
||||
lastEventTime = Date.now();
|
||||
this._notifyConfigChanged();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all registered callbacks about config file changes
|
||||
*/
|
||||
private _notifyConfigChanged(): void {
|
||||
this._changeCallbacks.forEach((callback) => callback());
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles configuration parsing errors with appropriate logging and notification
|
||||
*
|
||||
* @param error - The error that occurred during config parsing
|
||||
*/
|
||||
private _handleConfigError(error: unknown): void {
|
||||
console.error(`Failed to load config file: ${error}`);
|
||||
Notify({
|
||||
summary: 'Failed to load config file',
|
||||
body: `${error}`,
|
||||
iconName: icons.ui.warning,
|
||||
});
|
||||
errorHandler(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard that checks if a value is a non-null object
|
||||
*
|
||||
* @param value - The value to check
|
||||
* @returns True if the value is a non-null object
|
||||
*/
|
||||
private _isObject(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === 'object' && value !== null;
|
||||
}
|
||||
}
|
||||
98
src/lib/options/Opt.ts
Normal file
98
src/lib/options/Opt.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import Variable from 'astal/variable';
|
||||
import { ConfigManager } from './ConfigManager';
|
||||
|
||||
/**
|
||||
* Properties that can be passed when creating an option
|
||||
*/
|
||||
export interface OptProps {
|
||||
persistent?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for set operations
|
||||
*/
|
||||
export interface WriteOptions {
|
||||
writeDisk?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* A managed application option with persistence capabilities
|
||||
*/
|
||||
export class Opt<T = unknown> extends Variable<T> {
|
||||
public readonly initial: T;
|
||||
public readonly persistent: boolean;
|
||||
private _id = '';
|
||||
private _configManager: ConfigManager;
|
||||
|
||||
constructor(initial: T, configManager: ConfigManager, { persistent = false }: OptProps = {}) {
|
||||
super(initial);
|
||||
this.initial = initial;
|
||||
this.persistent = persistent;
|
||||
this._configManager = configManager;
|
||||
}
|
||||
|
||||
public toJSON(): string {
|
||||
return `opt:${JSON.stringify(this.get())}`;
|
||||
}
|
||||
|
||||
public get value(): T {
|
||||
return this.get();
|
||||
}
|
||||
|
||||
public set value(val: T) {
|
||||
this.set(val);
|
||||
}
|
||||
|
||||
public get id(): string {
|
||||
return this._id;
|
||||
}
|
||||
|
||||
public set id(newId: string) {
|
||||
this._id = newId;
|
||||
}
|
||||
|
||||
public init(config: Record<string, unknown>): void {
|
||||
const value = this._configManager.getNestedValue(config, this._id);
|
||||
|
||||
if (value !== undefined) {
|
||||
this.set(value as T, { writeDisk: false });
|
||||
}
|
||||
}
|
||||
|
||||
public set = (value: T, { writeDisk = true }: WriteOptions = {}): void => {
|
||||
if (value === this.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.set(value);
|
||||
|
||||
if (writeDisk) {
|
||||
this._configManager.updateOption(this._id, value);
|
||||
}
|
||||
};
|
||||
|
||||
public reset(writeOptions: WriteOptions = {}): string | undefined {
|
||||
if (this.persistent) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hasChanged = this._hasChangedFromInitial();
|
||||
|
||||
if (hasChanged) {
|
||||
this.set(this.initial, writeOptions);
|
||||
return this._id;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private _hasChangedFromInitial(): boolean {
|
||||
let currentValue: string | T = this.get();
|
||||
currentValue = typeof currentValue === 'object' ? JSON.stringify(currentValue) : currentValue;
|
||||
|
||||
let initialValue: string | T = this.initial;
|
||||
initialValue = typeof initialValue === 'object' ? JSON.stringify(initialValue) : initialValue;
|
||||
|
||||
return currentValue !== initialValue;
|
||||
}
|
||||
}
|
||||
186
src/lib/options/OptionRegistry.ts
Normal file
186
src/lib/options/OptionRegistry.ts
Normal file
@@ -0,0 +1,186 @@
|
||||
import { Opt } from './Opt';
|
||||
import { ConfigManager } from './ConfigManager';
|
||||
import { MkOptionsResult, OptionsObject } from './options.types';
|
||||
import { errorHandler } from '../utils';
|
||||
|
||||
/**
|
||||
* Creates and manages a registry of application options
|
||||
*
|
||||
* Provides functionality to collect, initialize, reset, and track options throughout
|
||||
* the application. Handles configuration synchronization and dependency-based subscriptions.
|
||||
*/
|
||||
export class OptionRegistry<T extends OptionsObject> {
|
||||
private _options: Opt[] = [];
|
||||
private _optionsObj: T;
|
||||
private _configManager: ConfigManager;
|
||||
|
||||
/**
|
||||
* Creates a new option registry
|
||||
*
|
||||
* @param optionsObj - The object containing option definitions
|
||||
* @param configManager - The configuration manager to handle persistence
|
||||
*/
|
||||
constructor(optionsObj: T, configManager: ConfigManager) {
|
||||
this._optionsObj = optionsObj;
|
||||
this._configManager = configManager;
|
||||
this._initializeOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all registered options as an array
|
||||
*/
|
||||
public toArray(): Opt[] {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all options to their initial values
|
||||
*
|
||||
* @returns Newline-separated list of IDs for options that were reset
|
||||
*/
|
||||
public async reset(): Promise<string> {
|
||||
const results = await this._resetAllOptions(this._options);
|
||||
return results.join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback for options matching the provided dependency prefixes
|
||||
*
|
||||
* @param optionsToWatch - Array of option ID prefixes to watch
|
||||
* @param callback - Function to call when matching options change
|
||||
*/
|
||||
public handler(optionsToWatch: string[], callback: () => void): void {
|
||||
optionsToWatch.forEach((prefix) => {
|
||||
const matchingOptions = this._options.filter((opt) => opt.id.startsWith(prefix));
|
||||
|
||||
matchingOptions.forEach((opt) => opt.subscribe(callback));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates options based on changes to the config file
|
||||
*
|
||||
* Synchronizes in-memory option values with the current state of the config file
|
||||
*/
|
||||
public handleConfigFileChange(): void {
|
||||
const newConfig = this._configManager.readConfig();
|
||||
|
||||
for (const opt of this._options) {
|
||||
const newVal = this._configManager.getNestedValue(newConfig, opt.id);
|
||||
|
||||
if (newVal === undefined) {
|
||||
opt.reset({ writeDisk: false });
|
||||
continue;
|
||||
}
|
||||
|
||||
const oldVal = opt.get();
|
||||
if (newVal !== oldVal) {
|
||||
opt.set(newVal, { writeDisk: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the enhanced options object with additional methods
|
||||
*
|
||||
* @returns The original options object enhanced with registry methods
|
||||
*/
|
||||
public createEnhancedOptions(): T & MkOptionsResult {
|
||||
return Object.assign(this._optionsObj, {
|
||||
toArray: this.toArray.bind(this),
|
||||
reset: this.reset.bind(this),
|
||||
handler: this.handler.bind(this),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the option registry by collecting options and setting up monitoring
|
||||
*/
|
||||
private _initializeOptions(): void {
|
||||
this._options = this._collectOptions(this._optionsObj);
|
||||
this._initializeFromConfig();
|
||||
|
||||
this._configManager.onConfigChanged(() => {
|
||||
this.handleConfigFileChange();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes option values from the saved configuration
|
||||
*/
|
||||
private _initializeFromConfig(): void {
|
||||
const config = this._configManager.readConfig();
|
||||
|
||||
for (const opt of this._options) {
|
||||
opt.init(config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively collects all option instances from an object structure
|
||||
*
|
||||
* @param sourceObject - The object to search for options
|
||||
* @param path - Current path in the object hierarchy
|
||||
* @returns Array of found option instances
|
||||
*/
|
||||
private _collectOptions(sourceObject: Record<string, unknown>, path = ''): Opt[] {
|
||||
const result: Opt[] = [];
|
||||
|
||||
try {
|
||||
for (const key in sourceObject) {
|
||||
const value = sourceObject[key];
|
||||
const id = path ? `${path}.${key}` : key;
|
||||
|
||||
if (value instanceof Opt) {
|
||||
value.id = id;
|
||||
result.push(value);
|
||||
} else if (this._isNestedObject(value)) {
|
||||
result.push(...this._collectOptions(value, id));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
errorHandler(error);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all options to their initial values with a delay between operations
|
||||
*
|
||||
* @param opts - Array of options to reset
|
||||
* @returns Array of IDs for options that were reset
|
||||
*/
|
||||
private async _resetAllOptions(opts: Opt[]): Promise<string[]> {
|
||||
const results: string[] = [];
|
||||
|
||||
for (const opt of opts) {
|
||||
const id = opt.reset();
|
||||
|
||||
if (id !== undefined) {
|
||||
results.push(id);
|
||||
await this._sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple promise-based sleep function
|
||||
*
|
||||
* @param ms - Milliseconds to sleep
|
||||
*/
|
||||
private _sleep(ms = 0): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard to check if a value is a non-null object that can be traversed
|
||||
*
|
||||
* @param value - The value to check
|
||||
*/
|
||||
private _isNestedObject(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === 'object' && value !== null;
|
||||
}
|
||||
}
|
||||
25
src/lib/options/index.ts
Normal file
25
src/lib/options/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ConfigManager } from './ConfigManager';
|
||||
import { Opt, OptProps } from './Opt';
|
||||
import { OptionRegistry } from './OptionRegistry';
|
||||
import { MkOptionsResult, OptionsObject } from './options.types';
|
||||
|
||||
const CONFIG_PATH = CONFIG_FILE;
|
||||
|
||||
const configManager = new ConfigManager(CONFIG_PATH);
|
||||
|
||||
/**
|
||||
* Creates an option with the specified initial value
|
||||
*/
|
||||
export function opt<T>(initial: T, props?: OptProps): Opt<T> {
|
||||
return new Opt(initial, configManager, props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and initializes an options management system
|
||||
*/
|
||||
export function mkOptions<T extends OptionsObject>(optionsObj: T): T & MkOptionsResult {
|
||||
const registry = new OptionRegistry(optionsObj, configManager);
|
||||
return registry.createEnhancedOptions();
|
||||
}
|
||||
|
||||
export { Opt, OptProps, ConfigManager, OptionRegistry };
|
||||
287
src/lib/options/options.types.ts
Normal file
287
src/lib/options/options.types.ts
Normal file
@@ -0,0 +1,287 @@
|
||||
import { Astal } from 'astal/gtk3';
|
||||
import { dropdownMenuList } from '../constants/options';
|
||||
import { FontStyle } from 'src/components/settings/shared/inputs/font/utils';
|
||||
import { Variable } from 'astal';
|
||||
import { defaultColorMap } from '../types/defaults/options.types';
|
||||
import { LabelSettingProps } from 'src/components/settings/shared/Label';
|
||||
import { Opt } from './Opt';
|
||||
|
||||
export interface MkOptionsResult {
|
||||
toArray: () => Opt[];
|
||||
reset: () => Promise<string>;
|
||||
handler: (optionsToWatch: string[], callback: () => void) => void;
|
||||
}
|
||||
|
||||
export type RecursiveOptionsObject = {
|
||||
[key: string]:
|
||||
| RecursiveOptionsObject
|
||||
| Opt<string>
|
||||
| Opt<number>
|
||||
| Opt<boolean>
|
||||
| Variable<string>
|
||||
| Variable<number>
|
||||
| Variable<boolean>;
|
||||
};
|
||||
|
||||
export type OptionsObject = Record<string, unknown>;
|
||||
|
||||
export type BarLocation = 'top' | 'bottom';
|
||||
export type AutoHide = 'never' | 'fullscreen' | 'single-window';
|
||||
export type BarModule =
|
||||
| 'battery'
|
||||
| 'dashboard'
|
||||
| 'workspaces'
|
||||
| 'windowtitle'
|
||||
| 'media'
|
||||
| 'notifications'
|
||||
| 'volume'
|
||||
| 'network'
|
||||
| 'bluetooth'
|
||||
| 'clock'
|
||||
| 'ram'
|
||||
| 'cpu'
|
||||
| 'cputemp'
|
||||
| 'storage'
|
||||
| 'netstat'
|
||||
| 'kbinput'
|
||||
| 'updates'
|
||||
| 'submap'
|
||||
| 'weather'
|
||||
| 'power'
|
||||
| 'systray'
|
||||
| 'hypridle'
|
||||
| 'hyprsunset'
|
||||
| 'cava';
|
||||
|
||||
export type BarLayout = {
|
||||
left: BarModule[];
|
||||
middle: BarModule[];
|
||||
right: BarModule[];
|
||||
};
|
||||
export type BarLayouts = {
|
||||
[key: string]: BarLayout;
|
||||
};
|
||||
|
||||
export type Unit = 'imperial' | 'metric';
|
||||
export type PowerOptions = 'sleep' | 'reboot' | 'logout' | 'shutdown';
|
||||
export type NotificationAnchor =
|
||||
| 'top'
|
||||
| 'top right'
|
||||
| 'top left'
|
||||
| 'bottom'
|
||||
| 'bottom right'
|
||||
| 'bottom left'
|
||||
| 'left'
|
||||
| 'right';
|
||||
export type OSDAnchor =
|
||||
| 'top left'
|
||||
| 'top'
|
||||
| 'top right'
|
||||
| 'right'
|
||||
| 'bottom right'
|
||||
| 'bottom'
|
||||
| 'bottom left'
|
||||
| 'left';
|
||||
export type BarButtonStyles = 'default' | 'split' | 'wave' | 'wave2';
|
||||
|
||||
export type ThemeExportData = {
|
||||
filePath: string;
|
||||
themeOnly: boolean;
|
||||
};
|
||||
export type InputType =
|
||||
| 'number'
|
||||
| 'color'
|
||||
| 'float'
|
||||
| 'object'
|
||||
| 'string'
|
||||
| 'enum'
|
||||
| 'boolean'
|
||||
| 'img'
|
||||
| 'wallpaper'
|
||||
| 'export'
|
||||
| 'import'
|
||||
| 'config_import'
|
||||
| 'font';
|
||||
|
||||
export interface RowProps<T> {
|
||||
opt: Opt<T>;
|
||||
note?: string;
|
||||
type?: InputType;
|
||||
enums?: T[];
|
||||
max?: number;
|
||||
min?: number;
|
||||
disabledBinding?: Variable<boolean>;
|
||||
exportData?: ThemeExportData;
|
||||
subtitle?: LabelSettingProps['subtitle'];
|
||||
subtitleLink?: string;
|
||||
dependencies?: string[];
|
||||
increment?: number;
|
||||
fontStyle?: Opt<FontStyle>;
|
||||
fontLabel?: Opt<string>;
|
||||
}
|
||||
|
||||
export type OSDOrientation = 'horizontal' | 'vertical';
|
||||
|
||||
export type HexColor = `#${string}`;
|
||||
|
||||
export type WindowLayer = 'top' | 'bottom' | 'overlay' | 'background';
|
||||
|
||||
export type ActiveWsIndicator = 'underline' | 'highlight' | 'color';
|
||||
|
||||
export type MatugenColors = {
|
||||
background: HexColor;
|
||||
error: HexColor;
|
||||
error_container: HexColor;
|
||||
inverse_on_surface: HexColor;
|
||||
inverse_primary: HexColor;
|
||||
inverse_surface: HexColor;
|
||||
on_background: HexColor;
|
||||
on_error: HexColor;
|
||||
on_error_container: HexColor;
|
||||
on_primary: HexColor;
|
||||
on_primary_container: HexColor;
|
||||
on_primary_fixed: HexColor;
|
||||
on_primary_fixed_variant: HexColor;
|
||||
on_secondary: HexColor;
|
||||
on_secondary_container: HexColor;
|
||||
on_secondary_fixed: HexColor;
|
||||
on_secondary_fixed_variant: HexColor;
|
||||
on_surface: HexColor;
|
||||
on_surface_variant: HexColor;
|
||||
on_tertiary: HexColor;
|
||||
on_tertiary_container: HexColor;
|
||||
on_tertiary_fixed: HexColor;
|
||||
on_tertiary_fixed_variant: HexColor;
|
||||
outline: HexColor;
|
||||
outline_variant: HexColor;
|
||||
primary: HexColor;
|
||||
primary_container: HexColor;
|
||||
primary_fixed: HexColor;
|
||||
primary_fixed_dim: HexColor;
|
||||
scrim: HexColor;
|
||||
secondary: HexColor;
|
||||
secondary_container: HexColor;
|
||||
secondary_fixed: HexColor;
|
||||
secondary_fixed_dim: HexColor;
|
||||
shadow: HexColor;
|
||||
surface: HexColor;
|
||||
surface_bright: HexColor;
|
||||
surface_container: HexColor;
|
||||
surface_container_high: HexColor;
|
||||
surface_container_highest: HexColor;
|
||||
surface_container_low: HexColor;
|
||||
surface_container_lowest: HexColor;
|
||||
surface_dim: HexColor;
|
||||
surface_variant: HexColor;
|
||||
tertiary: HexColor;
|
||||
tertiary_container: HexColor;
|
||||
tertiary_fixed: HexColor;
|
||||
tertiary_fixed_dim: HexColor;
|
||||
};
|
||||
|
||||
export type MatugenVariation = {
|
||||
rosewater: HexColor;
|
||||
flamingo: HexColor;
|
||||
pink: HexColor;
|
||||
mauve: HexColor;
|
||||
red: HexColor;
|
||||
maroon: HexColor;
|
||||
peach: HexColor;
|
||||
yellow: HexColor;
|
||||
green: HexColor;
|
||||
teal: HexColor;
|
||||
sky: HexColor;
|
||||
sapphire: HexColor;
|
||||
blue: HexColor;
|
||||
lavender: HexColor;
|
||||
text: HexColor;
|
||||
subtext1: HexColor;
|
||||
subtext2: HexColor;
|
||||
overlay2: HexColor;
|
||||
overlay1: HexColor;
|
||||
overlay0: HexColor;
|
||||
surface2: HexColor;
|
||||
surface1: HexColor;
|
||||
surface0: HexColor;
|
||||
base2: HexColor;
|
||||
base: HexColor;
|
||||
mantle: HexColor;
|
||||
crust: HexColor;
|
||||
notifications_closer?: HexColor;
|
||||
notifications_background?: HexColor;
|
||||
dashboard_btn_text?: HexColor;
|
||||
red2: HexColor;
|
||||
peach2: HexColor;
|
||||
pink2: HexColor;
|
||||
mantle2: HexColor;
|
||||
surface1_2: HexColor;
|
||||
surface0_2: HexColor;
|
||||
overlay1_2: HexColor;
|
||||
text2: HexColor;
|
||||
lavender2: HexColor;
|
||||
crust2: HexColor;
|
||||
maroon2: HexColor;
|
||||
mauve2: HexColor;
|
||||
green2: HexColor;
|
||||
surface2_2: HexColor;
|
||||
sky2: HexColor;
|
||||
teal2: HexColor;
|
||||
yellow2: HexColor;
|
||||
pink3: HexColor;
|
||||
red3: HexColor;
|
||||
mantle3: HexColor;
|
||||
surface0_3: HexColor;
|
||||
surface2_3: HexColor;
|
||||
overlay1_3: HexColor;
|
||||
lavender3: HexColor;
|
||||
mauve3: HexColor;
|
||||
green3: HexColor;
|
||||
sky3: HexColor;
|
||||
teal3: HexColor;
|
||||
yellow3: HexColor;
|
||||
maroon3: HexColor;
|
||||
crust3: HexColor;
|
||||
};
|
||||
export type MatugenScheme =
|
||||
| 'content'
|
||||
| 'expressive'
|
||||
| 'fidelity'
|
||||
| 'fruit-salad'
|
||||
| 'monochrome'
|
||||
| 'neutral'
|
||||
| 'rainbow'
|
||||
| 'tonal-spot';
|
||||
|
||||
export type MatugenTheme = 'light' | 'dark';
|
||||
|
||||
export type MatugenVariations =
|
||||
| 'standard_1'
|
||||
| 'standard_2'
|
||||
| 'standard_3'
|
||||
| 'monochrome_1'
|
||||
| 'monochrome_2'
|
||||
| 'monochrome_3'
|
||||
| 'vivid_1'
|
||||
| 'vivid_2'
|
||||
| 'vivid_3';
|
||||
|
||||
export type ColorMapKey = keyof typeof defaultColorMap;
|
||||
export type ColorMapValue = (typeof defaultColorMap)[ColorMapKey];
|
||||
|
||||
export type ScalingPriority = 'gdk' | 'hyprland' | 'both';
|
||||
|
||||
export type BluetoothBatteryState = 'paired' | 'connected' | 'always';
|
||||
|
||||
export type BorderLocation =
|
||||
| 'none'
|
||||
| 'top'
|
||||
| 'right'
|
||||
| 'bottom'
|
||||
| 'left'
|
||||
| 'horizontal'
|
||||
| 'vertical'
|
||||
| 'full';
|
||||
|
||||
export type PositionAnchor = { [key: string]: Astal.WindowAnchor };
|
||||
|
||||
export type DropdownMenuList = (typeof dropdownMenuList)[number];
|
||||
Reference in New Issue
Block a user