Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ npm_package(
":tinyvectors",
],
package = "@tummycrypt/tinyvectors",
version = "0.3.0",
version = "0.3.1",
visibility = ["//visibility:public"],
)

Expand Down
2 changes: 1 addition & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Usage from external repo:

module(
name = "tummycrypt_tinyvectors",
version = "0.3.0",
version = "0.3.1",
compatibility_level = 1,
)

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tummycrypt/tinyvectors",
"version": "0.3.0",
"version": "0.3.1",
"description": "Animated vector blob backgrounds with physics simulation for Svelte 5",
"type": "module",
"packageManager": "pnpm@9.15.9",
Expand Down
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ export {
generateThemeCSS,
isDarkMode,
watchDarkMode,
getThemePreviewColors,
getThemeVectorColors,
getThemeCatalogEntry,
getThemeCatalog,
type PackageThemeName,
type ThemeCatalogEntry,
} from './themes/index.js';

export {
Expand Down
84 changes: 83 additions & 1 deletion src/themes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@



import { THEME_PRESETS, type ThemePreset } from '../core/theme-presets.js';
import {
THEME_PRESETS,
type ThemePreset,
type ThemePresetName,
} from '../core/theme-presets.js';

export {
THEME_PRESETS,
Expand All @@ -22,6 +26,84 @@ export function getThemePreset(name: string): ThemePreset | undefined {
return THEME_PRESETS[name as keyof typeof THEME_PRESETS];
}

// Theme catalog — the package-curated set of presets with derived preview/
// vector color swatches. Hub/spoke consumers (e.g. @tummycrypt/tinyland-stores
// themeStore) render this catalog; keeping it here makes the package the
// single source of truth for which themes ship and how they preview.
export type PackageThemeName = Exclude<ThemePresetName, 'custom'>;

export interface ThemeCatalogEntry {
name: PackageThemeName;
label: string;
description: string;
hasVectors: boolean;
colors: string[];
previewColors: string[];
vectorColors: string[];
source: 'tinyvectors';
}

const PACKAGE_THEME_ORDER = [
'tinyland',
'trans',
'pride',
'high-contrast',
] as const satisfies readonly PackageThemeName[];

const THEME_DESCRIPTIONS: Record<PackageThemeName, string> = {
tinyland: 'Soft violet, blue, and pink glow',
trans: 'Soft trans pride palette',
pride: 'Rainbow signal colors with diffuse vectors',
'high-contrast': 'WCAG AAA compliant for maximum readability',
};

const THEME_PREVIEW_OVERRIDES: Partial<Record<PackageThemeName, string[]>> = {
'high-contrast': ['#000000', '#FFFFFF', '#0040FF'],
};

function getThemePalette(name: string, count?: number): string[] {
const preset = getThemePreset(name);
if (!preset?.hasVectors) return [];

const colors = preset.colors.map((entry) => entry.color);
return count === undefined ? colors : colors.slice(0, count);
}

export function getThemePreviewColors(name: string, count = 3): string[] {
return getThemePalette(name, count);
}

export function getThemeVectorColors(name: string, count = 5): string[] {
return getThemePalette(name, count);
}

export function getThemeCatalogEntry(
name: PackageThemeName,
): ThemeCatalogEntry | undefined {
const preset = getThemePreset(name);
if (!preset) return undefined;

const previewColors =
THEME_PREVIEW_OVERRIDES[name] ?? getThemePreviewColors(name);

return {
name,
label: preset.label,
description: THEME_DESCRIPTIONS[name],
hasVectors: preset.hasVectors,
colors: previewColors,
previewColors,
vectorColors: getThemeVectorColors(name),
source: 'tinyvectors',
};
}

export function getThemeCatalog(): ThemeCatalogEntry[] {
return PACKAGE_THEME_ORDER.map((name) => getThemeCatalogEntry(name)).filter(
(theme): theme is ThemeCatalogEntry => theme !== undefined,
);
}




Expand Down
Loading