-
-
Notifications
You must be signed in to change notification settings - Fork 425
Expand file tree
/
Copy pathuseSettings.ts
More file actions
131 lines (113 loc) · 3.53 KB
/
useSettings.ts
File metadata and controls
131 lines (113 loc) · 3.53 KB
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
130
131
import type { RemovableRef } from '@vueuse/core'
import { useLocalStorage } from '@vueuse/core'
import { ACCENT_COLORS } from '#shared/utils/constants'
import type { LocaleObject } from '@nuxtjs/i18n'
import { BACKGROUND_THEMES } from '#shared/utils/constants'
type BackgroundThemeId = keyof typeof BACKGROUND_THEMES
type AccentColorId = keyof typeof ACCENT_COLORS.light
/**
* Application settings stored in localStorage
*/
export interface AppSettings {
/** Display dates as relative (e.g., "3 days ago") instead of absolute */
relativeDates: boolean
/** Include @types/* package in install command for packages without built-in types */
includeTypesInInstall: boolean
/** Accent color theme */
accentColorId: AccentColorId | null
/** Preferred background shade */
preferredBackgroundTheme: BackgroundThemeId | null
/** Hide platform-specific packages (e.g., @scope/pkg-linux-x64) from search results */
hidePlatformPackages: boolean
/** User-selected locale */
selectedLocale: LocaleObject['code'] | null
sidebar: {
collapsed: string[]
}
}
const DEFAULT_SETTINGS: AppSettings = {
relativeDates: false,
includeTypesInInstall: true,
accentColorId: null,
hidePlatformPackages: true,
selectedLocale: null,
preferredBackgroundTheme: null,
sidebar: {
collapsed: [],
},
}
const STORAGE_KEY = 'npmx-settings'
// Shared settings instance (singleton per app)
let settingsRef: RemovableRef<AppSettings> | null = null
/**
* Composable for managing application settings with localStorage persistence.
* Settings are shared across all components that use this composable.
*/
export function useSettings() {
if (!settingsRef) {
settingsRef = useLocalStorage<AppSettings>(STORAGE_KEY, DEFAULT_SETTINGS, {
mergeDefaults: true,
})
}
return {
settings: settingsRef,
}
}
/**
* Composable for accessing just the relative dates setting.
* Useful for components that only need to read this specific setting.
*/
export function useRelativeDates() {
const { settings } = useSettings()
return computed(() => settings.value.relativeDates)
}
/**
* Composable for managing accent color.
*/
export function useAccentColor() {
const { settings } = useSettings()
const colorMode = useColorMode()
const accentColors = computed(() => {
const isDark = colorMode.value === 'dark'
const colors = isDark ? ACCENT_COLORS.dark : ACCENT_COLORS.light
return Object.entries(colors).map(([id, value]) => ({
id: id as AccentColorId,
name: id,
value,
}))
})
function setAccentColor(id: AccentColorId | null) {
if (id) {
document.documentElement.style.setProperty('--accent-color', `var(--swatch-${id})`)
} else {
document.documentElement.style.removeProperty('--accent-color')
}
settings.value.accentColorId = id
}
return {
accentColors,
selectedAccentColor: computed(() => settings.value.accentColorId),
setAccentColor,
}
}
export function useBackgroundTheme() {
const backgroundThemes = Object.entries(BACKGROUND_THEMES).map(([id, value]) => ({
id: id as BackgroundThemeId,
name: id,
value,
}))
const { settings } = useSettings()
function setBackgroundTheme(id: BackgroundThemeId | null) {
if (id) {
document.documentElement.dataset.bgTheme = id
} else {
document.documentElement.removeAttribute('data-bg-theme')
}
settings.value.preferredBackgroundTheme = id
}
return {
backgroundThemes,
selectedBackgroundTheme: computed(() => settings.value.preferredBackgroundTheme),
setBackgroundTheme,
}
}