Skip to content
Draft
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
15 changes: 7 additions & 8 deletions app/components/CollapsibleSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const props = withDefaults(defineProps<Props>(), {
headingLevel: 'h2',
})

const appSettings = useSettings()
const { sidebarPreferences } = usePackageSidebarPreferences()

const buttonId = `${props.id}-collapsible-button`
const contentId = `${props.id}-collapsible-content`
Expand All @@ -23,8 +23,8 @@ const headingId = `${props.id}-heading`
const isOpen = shallowRef(true)

onPrehydrate(() => {
const settings = JSON.parse(localStorage.getItem('npmx-settings') || '{}')
const collapsed: string[] = settings?.sidebar?.collapsed || []
const sidebar = JSON.parse(localStorage.getItem('npmx-sidebar-preferences') || '{}')
const collapsed: string[] = sidebar?.collapsed || []
for (const id of collapsed) {
if (!document.documentElement.dataset.collapsed?.includes(id)) {
document.documentElement.dataset.collapsed = (
Expand All @@ -45,17 +45,16 @@ onMounted(() => {
function toggle() {
isOpen.value = !isOpen.value

const removed = appSettings.settings.value.sidebar.collapsed.filter(c => c !== props.id)
const removed = sidebarPreferences.value.collapsed.filter(c => c !== props.id)

if (isOpen.value) {
appSettings.settings.value.sidebar.collapsed = removed
sidebarPreferences.value.collapsed = removed
} else {
removed.push(props.id)
appSettings.settings.value.sidebar.collapsed = removed
sidebarPreferences.value.collapsed = removed
}

document.documentElement.dataset.collapsed =
appSettings.settings.value.sidebar.collapsed.join(' ')
document.documentElement.dataset.collapsed = sidebarPreferences.value.collapsed.join(' ')
}

const ariaLabel = computed(() => {
Expand Down
6 changes: 3 additions & 3 deletions app/components/Settings/AccentColorPicker.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script setup lang="ts">
import { useAccentColor } from '~/composables/useSettings'
import { useAccentColor } from '~/composables/useUserPreferences'

const { accentColors, selectedAccentColor, setAccentColor } = useAccentColor()

onPrehydrate(el => {
const settings = JSON.parse(localStorage.getItem('npmx-settings') || '{}')
const id = settings.accentColorId
const preferences = JSON.parse(localStorage.getItem('npmx-user-preferences') || '{}')
const id = preferences.accentColorId
if (id) {
const input = el.querySelector<HTMLInputElement>(`input[value="${id}"]`)
if (input) {
Expand Down
4 changes: 2 additions & 2 deletions app/components/Settings/BgThemePicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
const { backgroundThemes, selectedBackgroundTheme, setBackgroundTheme } = useBackgroundTheme()

onPrehydrate(el => {
const settings = JSON.parse(localStorage.getItem('npmx-settings') || '{}')
const id = settings.preferredBackgroundTheme
const preferences = JSON.parse(localStorage.getItem('npmx-user-preferences') || '{}')
const id = preferences.preferredBackgroundTheme
if (id) {
const input = el.querySelector<HTMLInputElement>(`input[value="${id}"]`)
if (input) {
Expand Down
4 changes: 2 additions & 2 deletions app/composables/useInstallCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ export function useInstallCommand(
typesPackageName: MaybeRefOrGetter<string | null>,
) {
const selectedPM = useSelectedPackageManager()
const { settings } = useSettings()
const { preferences } = useUserPreferences()

// Check if we should show @types in install command
const showTypesInInstall = computed(() => {
return settings.value.includeTypesInInstall && !!toValue(typesPackageName)
return preferences.value.includeTypesInInstall && !!toValue(typesPackageName)
})

const installCommandParts = computed(() => {
Expand Down
34 changes: 34 additions & 0 deletions app/composables/useLocalStorageHashProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { createLocalStorageProvider } from '~/utils/storage'

export function useLocalStorageHashProvider<T extends object>(key: string, defaultValue: T) {
const provider = createLocalStorageProvider<T>(key)
const data = ref<T>(defaultValue)

onMounted(() => {
const stored = provider.get()
if (stored) {
data.value = { ...defaultValue, ...stored }
}
})

function save() {
provider.set(data.value)
}

function reset() {
data.value = { ...defaultValue }
provider.remove()
}

function update<K extends keyof T>(key: K, value: T[K]) {
data.value[key] = value
save()
}

return {
data,
save,
reset,
update,
}
}
7 changes: 3 additions & 4 deletions app/composables/usePackageListPreferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ import type {
} from '#shared/types/preferences'
import { DEFAULT_COLUMNS, DEFAULT_PREFERENCES } from '#shared/types/preferences'

const STORAGE_KEY = 'npmx-list-prefs'

/**
* Composable for managing package list display preferences
* Persists to localStorage and provides reactive state
*
*/
export function usePackageListPreferences() {
const {
data: preferences,
isHydrated,
save,
reset,
} = usePreferencesProvider<PackageListPreferences>(DEFAULT_PREFERENCES)
} = useLocalStorageHashProvider<PackageListPreferences>(STORAGE_KEY, DEFAULT_PREFERENCES)

// Computed accessors for common properties
const viewMode = computed({
Expand Down Expand Up @@ -90,7 +90,6 @@ export function usePackageListPreferences() {
return {
// Raw preferences
preferences,
isHydrated,

// Individual properties with setters
viewMode,
Expand Down
24 changes: 24 additions & 0 deletions app/composables/usePackageSidebarPreferences.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
interface SidebarPreferences {
collapsed: string[]
}

const STORAGE_KEY = 'npmx-sidebar-preferences'
const DEFAULT_SIDEBAR_PREFERENCES: SidebarPreferences = { collapsed: [] }

let sidebarRef: Ref<SidebarPreferences> | null = null

/**
* Composable for managing sidebar section collapsed state.
* This is local-only and uses its own LS key.
*/
export function usePackageSidebarPreferences() {
if (!sidebarRef) {
sidebarRef = useLocalStorage<SidebarPreferences>(STORAGE_KEY, DEFAULT_SIDEBAR_PREFERENCES, {
mergeDefaults: true,
})
}

return {
sidebarPreferences: sidebarRef,
}
}
100 changes: 0 additions & 100 deletions app/composables/usePreferencesProvider.ts

This file was deleted.

Loading