> ## Documentation Index
> Fetch the complete documentation index at: https://docs.deploystack.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Settings Menu

> A composable sidebar navigation component for settings pages, following the shadcn-vue pattern.

A vertical navigation menu for settings and configuration pages. Built as composable components that can be combined to create grouped menu structures with icons, separators, and active states.

## Component Location

```
services/frontend/src/components/ui/settings-menu/
 - SettingsMenu.vue           # Root container
 - SettingsMenuGroup.vue      # Group with optional title
 - SettingsMenuItem.vue       # Clickable menu item (RouterLink)
 - SettingsMenuSeparator.vue  # Horizontal separator
-- index.ts                   # Exports
```

## Components

### SettingsMenu

Root container that provides consistent spacing between groups.

```vue theme={null}
<SettingsMenu>
  <!-- SettingsMenuGroup or SettingsMenuSeparator children -->
</SettingsMenu>
```

### SettingsMenuGroup

Groups related menu items together. The title prop is optional.

| Prop    | Type     | Default     | Description                      |
| ------- | -------- | ----------- | -------------------------------- |
| `title` | `string` | `undefined` | Optional heading above the group |

```vue theme={null}
<!-- With title -->
<SettingsMenuGroup title="Account Settings">
  <SettingsMenuItem to="/settings/profile">Profile</SettingsMenuItem>
</SettingsMenuGroup>

<!-- Without title -->
<SettingsMenuGroup>
  <SettingsMenuItem to="/settings/other">Other</SettingsMenuItem>
</SettingsMenuGroup>
```

### SettingsMenuItem

A RouterLink-based menu item with support for icons.

| Prop      | Type        | Default     | Description                            |
| --------- | ----------- | ----------- | -------------------------------------- |
| `to`      | `string`    | required    | RouterLink destination path            |
| `active`  | `boolean`   | `false`     | Whether the item is currently selected |
| `icon`    | `Component` | `undefined` | Lucide icon component                  |
| `iconUrl` | `string`    | `undefined` | URL for an image icon                  |

Icon priority: `iconUrl` takes precedence over `icon`. If neither is provided, no icon is rendered.

```vue theme={null}
<!-- With URL icon -->
<SettingsMenuItem
  to="/config/vscode"
  icon-url="/icons/vscode.svg"
  :active="currentPath === '/config/vscode'"
>
  VS Code
</SettingsMenuItem>

<!-- With Lucide icon -->
<SettingsMenuItem
  to="/settings/profile"
  :icon="User"
  :active="currentPath === '/settings/profile'"
>
  Profile
</SettingsMenuItem>

<!-- Without icon -->
<SettingsMenuItem to="/settings/other" :active="false">
  Other Settings
</SettingsMenuItem>
```

### SettingsMenuSeparator

A horizontal line to visually separate groups.

```vue theme={null}
<SettingsMenuSeparator />
```

## Usage

Import all components from the settings-menu index:

```vue theme={null}
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { User, Settings, Bell } from 'lucide-vue-next'
import {
  SettingsMenu,
  SettingsMenuGroup,
  SettingsMenuItem,
  SettingsMenuSeparator
} from '@/components/ui/settings-menu'

const route = useRoute()
</script>

<template>
  <aside class="w-1/5 border-r pr-8">
    <SettingsMenu>
      <SettingsMenuGroup title="Account">
        <SettingsMenuItem
          to="/settings/profile"
          :icon="User"
          :active="route.path === '/settings/profile'"
        >
          Profile
        </SettingsMenuItem>
        <SettingsMenuItem
          to="/settings/notifications"
          :icon="Bell"
          :active="route.path === '/settings/notifications'"
        >
          Notifications
        </SettingsMenuItem>
      </SettingsMenuGroup>

      <SettingsMenuSeparator />

      <SettingsMenuGroup title="System">
        <SettingsMenuItem
          to="/settings/preferences"
          :icon="Settings"
          :active="route.path === '/settings/preferences'"
        >
          Preferences
        </SettingsMenuItem>
      </SettingsMenuGroup>
    </SettingsMenu>
  </aside>
</template>
```

## Dynamic Menu from Data

When rendering menus from an array of items:

```vue theme={null}
<script setup lang="ts">
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import {
  SettingsMenu,
  SettingsMenuGroup,
  SettingsMenuItem,
  SettingsMenuSeparator
} from '@/components/ui/settings-menu'

interface MenuItem {
  id: string
  name: string
  iconPath?: string
}

interface MenuCategory {
  id: string
  name: string
  items: MenuItem[]
}

const route = useRoute()
const categories = ref<MenuCategory[]>([])
const selectedId = ref<string>('')
</script>

<template>
  <SettingsMenu>
    <template v-for="(category, index) in categories" :key="category.id">
      <SettingsMenuGroup :title="category.name">
        <SettingsMenuItem
          v-for="item in category.items"
          :key="item.id"
          :to="`/config/${category.id}/${item.id}`"
          :icon-url="item.iconPath"
          :active="selectedId === item.id"
        >
          {{ item.name }}
        </SettingsMenuItem>
      </SettingsMenuGroup>
      <SettingsMenuSeparator v-if="index < categories.length - 1" />
    </template>
  </SettingsMenu>
</template>
```

## Styling

The component uses shadcn-vue design tokens for consistent theming:

* **Active state**: `bg-neutral-200 text-foreground font-medium`
* **Inactive state**: `text-muted-foreground hover:bg-neutral-200 hover:text-foreground`
* **Group title**: `font-semibold text-sm text-foreground`
* **Separator**: `h-px bg-border`
* **Icon size**: `w-5 h-5`
