Preferences, layouts, and theming
Preferences
Call initPreferences before mounting Vue (apps/web/src/main.ts):
const env = import.meta.env.PROD ? 'prod' : 'dev';
const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`;
await initPreferences({
namespace,
overrides: overridesPreferences,
});
namespace isolates StorageManager keys so two apps (or dev vs prod) do not share prefs.
apps/web/src/preferences.ts:
export const overridesPreferences = defineOverridesPreferences({
app: {
defaultHomePath: '/todos/manage',
name: import.meta.env.VITE_APP_TITLE,
},
});
taman-core defaults (when you do not override) include:
| Key | Default |
|---|---|
app.accessMode | 'frontend' |
app.defaultHomePath | '/dashboard' — no such route in this template |
app.timezone | 'Asia/Makassar' |
app.layout | 'sidebar-nav' |
app.locale | 'en-US' |
app.name | 'Taman Admin' |
Clear the cached preferences key after changing overrides or they may not apply (cache fills fields you did not set).
API (@vinicunca/taman-core/preferences)
import {
clearCache,
defineOverridesPreferences,
getPreferences,
initPreferences,
preferences,
preferencesManager,
resetPreferences,
updatePreferences,
usePreferences,
} from '@vinicunca/taman-core/preferences';
updatePreferences(partial)— merge + persist (debounced 150 ms)resetPreferences()— back to the init snapshotusePreferences()— computedisDark,layout,locale,isMobile, shortcut flags, button placement, …
usePreferences().app is a snapshot of appPreferences.value at setup time, not a computed. Prefer getPreferences() or the dedicated computeds for reactive reads.
Layouts
TamanCoreLayout (@vinicunca/taman-ui/layout) is the admin chrome. The web app wraps it in apps/web/src/layouts/core.vue. Auth pages use layouts/auth.vue.
app.layout values (from preferences types): sidebar-nav, sidebar-mixed-nav, header-nav, header-mixed-nav, header-sidebar-nav, mixed-nav, full-content. On mobile, layout is forced to sidebar-nav.
Auth page layouts: panel-left | panel-right (default) | panel-center.
Theming
apps/web/vite.config.ts uses Pohon unstyled:
vitePohon({
colorMode: false,
theme: { unstyled: true },
ui: { colors: { primary: 'blue', /* … */ }, ...ui },
scanPackages: ['@vinicunca/taman-ui', '@taman/app-ui'],
});
@taman/designs supplies tokens and vitePohonTheme. Bootstrap imports virtual:uno.css, @taman/designs/styles, and virtual:pohon-theme.
For a standalone taman-ui consumer (the template already does all four in apps/web):
vitePohon({ scanPackages: ['@vinicunca/taman-ui'] })optimizeDeps.exclude: ['pohon-ui', '@vinicunca/taman-ui']resolve.dedupe: ['pohon-ui', 'vue']- UnoCSS
content.pipeline.includemust containTAMAN_UI_CONTENTfrom@vinicunca/taman-ui/unocss(/@vinicunca[\\/]taman-ui[\\/]dist[\\/].*\.mjs$/)
Without TAMAN_UI_CONTENT, compiled components render without their utilities.
Color CSS variables are generated with generatorColorVariables (@vinicunca/taman-core/color) as --taman-color-<name>-<shade>.