-
-
Notifications
You must be signed in to change notification settings - Fork 424
Expand file tree
/
Copy pathuseSettings.ts
More file actions
134 lines (115 loc) · 3.54 KB
/
useSettings.ts
File metadata and controls
134 lines (115 loc) · 3.54 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
132
133
134
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
/**
* 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()
function toggleRelativeDates() {
settings.value.relativeDates = !settings.value.relativeDates
}
return {
relativeDates: computed(() => settings.value.relativeDates),
toggleRelativeDates,
}
}
/**
* Composable for managing accent color.
*/
export function useAccentColor() {
const { settings } = useSettings()
const accentColors = Object.entries(ACCENT_COLORS).map(([id, value]) => ({
id: id as AccentColorId,
name: id,
value,
}))
function setAccentColor(id: AccentColorId | null) {
const color = id ? ACCENT_COLORS[id] : null
if (color) {
document.documentElement.style.setProperty('--accent-color', color)
} 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,
}
}