web_lib

Common web application libraries
git clone https://radroots.dev/git/web_lib.git
Log | Files | Refs | LICENSE

theme_utils.ts (3555B)


      1 import type { ThemeKey, ThemeMode } from "../core/types.js";
      2 import { parse_theme_key } from "../core/utils.js";
      3 import { theme_layouts } from "../layout/index.js";
      4 import type { ThemeLayoutKey, ThemeVariable } from "../layout/types.js";
      5 import { theme_presets } from "../presets/index.js";
      6 import type { HslTuple, OsThemePreset } from "../presets/types.js";
      7 
      8 export const theme_modes: ThemeMode[] = ["dark", "light"];
      9 
     10 const theme_layer_order: Array<keyof OsThemePreset> = ["ly0", "ly1", "ly2"];
     11 
     12 export interface ThemeColorEntry {
     13   layer_key: keyof OsThemePreset;
     14   category: "surfaces" | "glyphs";
     15   token_key: string;
     16 }
     17 
     18 export const tabs = (n: number): string => "    ".repeat(n);
     19 
     20 export const format_hsl = (tuple: HslTuple): string => {
     21   const [h, s, l] = tuple;
     22   return `hsl(${h}, ${s}%, ${l}%)`;
     23 };
     24 
     25 export const to_css_name_suffix = (key: string): string => {
     26   const trimmed_key = key.replace(/^_+/, "");
     27   if (trimmed_key.length === 0) {
     28     return "";
     29   }
     30   return `-${trimmed_key.replace(/_/g, "-")}`;
     31 };
     32 
     33 export const collect_theme_color_entries = (
     34   theme: OsThemePreset
     35 ): ThemeColorEntry[] => {
     36   const entries: ThemeColorEntry[] = [];
     37 
     38   for (const layer_key of theme_layer_order) {
     39     const layer = theme[layer_key];
     40 
     41     const surface_keys = Object.keys(
     42       layer.surfaces
     43     ) as Array<keyof typeof layer.surfaces>;
     44     for (const surface_key of surface_keys) {
     45       entries.push({
     46         layer_key,
     47         category: "surfaces",
     48         token_key: String(surface_key)
     49       });
     50     }
     51 
     52     const glyph_keys = Object.keys(
     53       layer.glyphs
     54     ) as Array<keyof typeof layer.glyphs>;
     55     for (const glyph_key of glyph_keys) {
     56       entries.push({
     57         layer_key,
     58         category: "glyphs",
     59         token_key: String(glyph_key)
     60       });
     61     }
     62   }
     63 
     64   return entries;
     65 };
     66 
     67 export const select_theme_presets_keys = (
     68   presets: string[] | undefined
     69 ): ThemeKey[] => {
     70   const all_keys = Object.keys(theme_presets);
     71   if (!presets || presets.length === 0) {
     72     return all_keys.map(parse_theme_key);
     73   }
     74 
     75   const trimmed_presets = presets
     76     .map(preset => preset.trim())
     77     .filter(preset => preset.length > 0);
     78 
     79   if (trimmed_presets.length === 0) {
     80     return all_keys.map(parse_theme_key);
     81   }
     82 
     83   const unknown_presets = trimmed_presets.filter(
     84     preset => !all_keys.includes(preset)
     85   );
     86   if (unknown_presets.length > 0) {
     87     throw new Error(
     88       `Unknown theme preset(s): ${unknown_presets.join(", ")}`
     89     );
     90   }
     91 
     92   return all_keys
     93     .filter(key => trimmed_presets.includes(key))
     94     .map(parse_theme_key);
     95 };
     96 
     97 export const select_theme_layout_keys = (
     98   presets: string[] | undefined
     99 ): ThemeLayoutKey[] => {
    100   const all_keys = Object.keys(theme_layouts) as ThemeLayoutKey[];
    101 
    102   if (!presets || presets.length === 0) {
    103     return all_keys;
    104   }
    105 
    106   const trimmed_presets = presets
    107     .map(preset => preset.trim())
    108     .filter(preset => preset.length > 0);
    109 
    110   if (trimmed_presets.length === 0) {
    111     return all_keys;
    112   }
    113 
    114   const unknown_presets = trimmed_presets.filter(
    115     preset => !all_keys.includes(preset as ThemeLayoutKey)
    116   );
    117 
    118   if (unknown_presets.length > 0) {
    119     throw new Error(
    120       `Unknown layout preset(s): ${unknown_presets.join(", ")}`
    121     );
    122   }
    123 
    124   return all_keys.filter(key => trimmed_presets.includes(key));
    125 };
    126 
    127 export const collect_layout_variables = (
    128   keys: ThemeLayoutKey[]
    129 ): ThemeVariable[] => {
    130   const variables: ThemeVariable[] = [];
    131 
    132   for (const key of keys) {
    133     const layout = theme_layouts[key];
    134     variables.push(...layout.variables);
    135   }
    136 
    137   return variables;
    138 };