From 8a86fdcd43cb95c1bbbd9cf2f0d08076de55f0b0 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 16 Oct 2025 11:26:48 +0300 Subject: [PATCH] feat(collection/presentation): add listing for themes --- .../collections/presentation/themes.ts | 61 +++++++++++++++++++ .../ribbon/collection-properties-config.ts | 13 +++- packages/commons/src/lib/attribute_names.ts | 1 + 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 apps/client/src/widgets/collections/presentation/themes.ts diff --git a/apps/client/src/widgets/collections/presentation/themes.ts b/apps/client/src/widgets/collections/presentation/themes.ts new file mode 100644 index 000000000..dca1b8760 --- /dev/null +++ b/apps/client/src/widgets/collections/presentation/themes.ts @@ -0,0 +1,61 @@ +interface ThemeDefinition { + name: string; + loadTheme: () => Promise; +} + +const themes: Record = { + black: { + name: "Black", + loadTheme: () => import("reveal.js/dist/theme/black.css?raw") + }, + white: { + name: "White", + loadTheme: () => import("reveal.js/dist/theme/black.css?raw") + }, + beige: { + name: "Beige", + loadTheme: () => import("reveal.js/dist/theme/black.css?raw") + }, + serif: { + name: "Serif", + loadTheme: () => import("reveal.js/dist/theme/black.css?raw") + }, + simple: { + name: "Simple", + loadTheme: () => import("reveal.js/dist/theme/black.css?raw") + }, + solarized: { + name: "Solarized", + loadTheme: () => import("reveal.js/dist/theme/black.css?raw") + }, + moon: { + name: "Moon", + loadTheme: () => import("reveal.js/dist/theme/black.css?raw") + }, + dracula: { + name: "Dracula", + loadTheme: () => import("reveal.js/dist/theme/black.css?raw") + }, + sky: { + name: "Sky", + loadTheme: () => import("reveal.js/dist/theme/black.css?raw") + }, + blood: { + name: "Blood", + loadTheme: () => import("reveal.js/dist/theme/black.css?raw") + } +} as const; + +export function getPresentationThemes() { + return Object.entries(themes).map(([ id, theme ]) => ({ + id: id, + name: theme.name + })); +} + +export async function loadPresentationTheme(name: keyof typeof themes) { + const theme = themes[name]; + if (!theme) return; + + return (await theme.loadTheme()).default; +} diff --git a/apps/client/src/widgets/ribbon/collection-properties-config.ts b/apps/client/src/widgets/ribbon/collection-properties-config.ts index bb4dd405b..0416c98fc 100644 --- a/apps/client/src/widgets/ribbon/collection-properties-config.ts +++ b/apps/client/src/widgets/ribbon/collection-properties-config.ts @@ -5,6 +5,7 @@ import NoteContextAwareWidget from "../note_context_aware_widget"; import { DEFAULT_MAP_LAYER_NAME, MAP_LAYERS, type MapLayer } from "../collections/geomap/map_layer"; import { ViewTypeOptions } from "../collections/interface"; import { FilterLabelsByType } from "@triliumnext/commons"; +import { getPresentationThemes } from "../collections/presentation/themes"; interface BookConfig { properties: BookProperty[]; @@ -161,7 +162,17 @@ export const bookPropertiesConfig: Record = { properties: [] }, presentation: { - properties: [] + properties: [ + { + label: "Theme", + type: "combobox", + bindToLabel: "presentation:theme", + options: getPresentationThemes().map(theme => ({ + value: theme.id, + label: theme.name + })) + } + ] } }; diff --git a/packages/commons/src/lib/attribute_names.ts b/packages/commons/src/lib/attribute_names.ts index 8b8de89c1..314cc8c9c 100644 --- a/packages/commons/src/lib/attribute_names.ts +++ b/packages/commons/src/lib/attribute_names.ts @@ -39,6 +39,7 @@ type Labels = { "board:groupBy": string; maxNestingDepth: number; includeArchived: boolean; + "presentation:theme": string; } /**