All files / packages/core/src/tokens index.ts

100% Statements 18/18
50% Branches 1/2
100% Functions 12/12
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129                                                                                              46x         1978x                       46x 1978x           46x 690x           1978x                     208x                 88x                 86x                 86x           1978x         1978x  
// SPDX-License-Identifier: MIT
/**
 * Platform-agnostic design tokens export
 *
 * This module exports pure theme data (colors, typography, etc.) without
 * any DOM, CSS, or platform-specific code. Use this for:
 *
 * - React Native apps
 * - Flutter apps (via JSON export)
 * - iOS/Android native apps
 * - Any platform that needs theme colors
 *
 * For web apps, you can also import the CSS files directly:
 * import '@lgtm-hq/turbo-themes/css/catppuccin-mocha.css'
 */
 
// Re-export types for consumers
export type { ThemeTokens, ThemeFlavor, ThemePackage } from '../themes/types.js';
 
// Re-export the generated ThemeId union and its backing tuple. These have no
// runtime dependencies, so exposing them here is import-cycle-safe (the runtime
// curation API lives in ../catalog to avoid a metadata<->tokens init cycle).
export type { ThemeId } from '../themes/theme-ids.js';
export { THEME_IDS } from '../themes/theme-ids.js';
 
import type { ThemeFlavor, ThemeTokens } from '../themes/types.js';
 
// Import tokens data (copied from dist/tokens.json during build)
import tokensData from '../themes/tokens.json' with { type: 'json' };
 
// Type assertion for the imported JSON
interface TokensJson {
  themes: Record<string, {
    id: string;
    label: string;
    vendor: string;
    appearance: 'light' | 'dark';
    iconUrl?: string;
    tokens: ThemeTokens;
  }>;
  byVendor: Record<string, {
    name: string;
    homepage: string;
    themes: string[];
  }>;
}
 
const tokens = tokensData as TokensJson;
 
/**
 * All available theme flavors as a flat array
 */
export const flavors: readonly ThemeFlavor[] = Object.values(tokens.themes).map((theme) => ({
  id: theme.id,
  label: theme.label,
  vendor: theme.vendor,
  appearance: theme.appearance,
  ...(theme.iconUrl !== undefined && { iconUrl: theme.iconUrl }),
  tokens: theme.tokens,
}));
 
/**
 * Theme flavors indexed by ID for quick lookup
 */
export const themesById: Record<string, ThemeFlavor> = /*#__PURE__*/ Object.fromEntries(
  flavors.map((flavor) => [flavor.id, flavor])
);
 
/**
 * All available theme packages (grouped by vendor)
 */
export const packages = /*#__PURE__*/ Object.fromEntries(
  Object.entries(tokens.byVendor).map(([vendorId, vendor]) => [
    vendorId,
    {
      id: vendorId,
      name: vendor.name,
      homepage: vendor.homepage,
      flavors: vendor.themes.map((themeId) => themesById[themeId]).filter(Boolean),
    },
  ])
);
 
/**
 * Get a theme by ID
 * @param id - Theme identifier (e.g., 'catppuccin-mocha')
 * @returns The theme flavor or undefined if not found
 */
export function getTheme(id: string): ThemeFlavor | undefined {
  return themesById[id];
}
 
/**
 * Get theme tokens by ID (convenience function)
 * @param id - Theme identifier (e.g., 'catppuccin-mocha')
 * @returns The theme tokens or undefined if not found
 */
export function getTokens(id: string): ThemeTokens | undefined {
  return themesById[id]?.tokens;
}
 
/**
 * Get all themes matching an appearance (light/dark)
 * @param appearance - 'light' or 'dark'
 * @returns Array of matching theme flavors
 */
export function getThemesByAppearance(appearance: 'light' | 'dark'): readonly ThemeFlavor[] {
  return flavors.filter((f) => f.appearance === appearance);
}
 
/**
 * Get all themes from a specific vendor
 * @param vendor - Vendor name (e.g., 'catppuccin', 'github')
 * @returns Array of matching theme flavors
 */
export function getThemesByVendor(vendor: string): readonly ThemeFlavor[] {
  return flavors.filter((f) => f.vendor === vendor);
}
 
/**
 * List of all available theme IDs
 */
export const themeIds: readonly string[] = /*#__PURE__*/ flavors.map((f) => f.id);
 
/**
 * List of all available vendors
 */
export const vendors: readonly string[] = /*#__PURE__*/ [...new Set(flavors.map((f) => f.vendor))];