Menu

Change language

GitHub repo

Documentation Sidebar

blocklayout

Docs-style sidebar with a version switcher at the top, a search input below, and collapsible navigation groups. All sample data inlined so consumers edit routes in place.

Installation

$npx uipkge-ng@latest add sidebar-03
Manifest:https://uipkge.dev/r/angular/sidebar-03.jsonInstalls to:src/app/components/blocks/sidebar-03/

Variants

Loading interactive previews…

Files installed (4)

  • src/app/components/blocks/sidebar-03/sidebar-03.component.ts5.8 kB
    // Docs-style sidebar: version switcher + search in the header, collapsible nav groups
    // below. All sample data inlined so consumers edit routes in place.
    // Port of the React block 1:1.
    import { ChangeDetectionStrategy, Component } from '@angular/core'
    import { ChevronRight, LucideAngularModule } from 'lucide-angular'
    import {
      UiCollapsibleComponent,
      UiCollapsibleContentComponent,
      UiCollapsibleTriggerComponent,
    } from '@/ui/collapsible/collapsible.component'
    import {
      UiSidebarComponent,
      UiSidebarContentComponent,
      UiSidebarGroupComponent,
      UiSidebarGroupContentComponent,
      UiSidebarGroupLabelComponent,
      UiSidebarHeaderComponent,
      UiSidebarMenuButtonComponent,
      UiSidebarMenuComponent,
      UiSidebarMenuItemComponent,
      UiSidebarRailComponent,
    } from '@/ui/sidebar/sidebar.component'
    import { Sidebar03SearchFormComponent } from './search-form.component'
    import { Sidebar03VersionSwitcherComponent } from './version-switcher.component'
    
    // This is sample data.
    const data: {
      versions: string[]
      navMain: {
        title: string
        url: string
        items: { title: string; url: string; isActive?: boolean }[]
      }[]
    } = {
      versions: ['1.0.1', '1.1.0-alpha', '2.0.0-beta1'],
      navMain: [
        {
          title: 'Getting Started',
          url: '#',
          items: [
            { title: 'Installation', url: '#' },
            { title: 'Project Structure', url: '#' },
          ],
        },
        {
          title: 'Building Your Application',
          url: '#',
          items: [
            { title: 'Routing', url: '#' },
            { title: 'Data Fetching', url: '#', isActive: true },
            { title: 'Rendering', url: '#' },
            { title: 'Caching', url: '#' },
            { title: 'Styling', url: '#' },
            { title: 'Optimizing', url: '#' },
            { title: 'Configuring', url: '#' },
            { title: 'Testing', url: '#' },
            { title: 'Authentication', url: '#' },
            { title: 'Deploying', url: '#' },
            { title: 'Upgrading', url: '#' },
            { title: 'Examples', url: '#' },
          ],
        },
        {
          title: 'API Reference',
          url: '#',
          items: [
            { title: 'Components', url: '#' },
            { title: 'File Conventions', url: '#' },
            { title: 'Functions', url: '#' },
            { title: 'next.config.js Options', url: '#' },
            { title: 'CLI', url: '#' },
            { title: 'Edge Runtime', url: '#' },
          ],
        },
        {
          title: 'Architecture',
          url: '#',
          items: [
            { title: 'Accessibility', url: '#' },
            { title: 'Fast Refresh', url: '#' },
            { title: 'Next.js Compiler', url: '#' },
            { title: 'Supported Browsers', url: '#' },
            { title: 'Turbopack', url: '#' },
          ],
        },
        {
          title: 'Community',
          url: '#',
          items: [{ title: 'Contribution Guide', url: '#' }],
        },
      ],
    }
    
    /**
     * Sidebar03 -- the React block, 1:1: a default Sidebar with a VersionSwitcher +
     * SearchForm header and collapsible nav groups (all open). It reads the surrounding
     * <ui-sidebar-provider> (pair with <ui-sidebar-inset> + <ui-sidebar-trigger>).
     * Edit `data` to change versions and routes.
     */
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-sidebar-03, [ui-sidebar-03]',
      standalone: true,
      // React renders <Sidebar> itself: keep this wrapper out of the provider's flex layout.
      host: { class: 'contents' },
      imports: [
        LucideAngularModule,
        UiCollapsibleComponent,
        UiCollapsibleTriggerComponent,
        UiCollapsibleContentComponent,
        UiSidebarComponent,
        UiSidebarHeaderComponent,
        UiSidebarContentComponent,
        UiSidebarGroupComponent,
        UiSidebarGroupLabelComponent,
        UiSidebarGroupContentComponent,
        UiSidebarMenuComponent,
        UiSidebarMenuItemComponent,
        UiSidebarMenuButtonComponent,
        UiSidebarRailComponent,
        Sidebar03SearchFormComponent,
        Sidebar03VersionSwitcherComponent,
      ],
      template: `
        <ui-sidebar>
          <ui-sidebar-header>
            <sidebar-03-version-switcher [versions]="data.versions" [defaultVersion]="data.versions[0]!" />
            <sidebar-03-search-form />
          </ui-sidebar-header>
          <ui-sidebar-content class="gap-0">
            @for (item of data.navMain; track item.title) {
              <!-- Angular's group label has no asChild slot: the trigger carries the label's
                   hover classes so the whole row stays clickable, like React's asChild. -->
              <div ui-collapsible [attr.title]="item.title" defaultOpen class="group/collapsible">
                <ui-sidebar-group>
                  <ui-sidebar-group-label
                    class="group/label text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground text-sm"
                  >
                    <button type="button" ui-collapsible-trigger class="flex w-full items-center gap-2 text-left">
                      {{ item.title }}
                      <lucide-icon
                        [img]="ChevronRight"
                        class="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90"
                      />
                    </button>
                  </ui-sidebar-group-label>
                  <ui-collapsible-content>
                    <ui-sidebar-group-content>
                      <ul ui-sidebar-menu>
                        @for (childItem of item.items; track childItem.title) {
                          <li ui-sidebar-menu-item>
                            <a ui-sidebar-menu-button [href]="childItem.url" [isActive]="!!childItem.isActive">
                              <span>{{ childItem.title }}</span>
                            </a>
                          </li>
                        }
                      </ul>
                    </ui-sidebar-group-content>
                  </ui-collapsible-content>
                </ui-sidebar-group>
              </div>
            }
          </ui-sidebar-content>
          <button ui-sidebar-rail></button>
        </ui-sidebar>
      `,
    })
    export class UiSidebar03Component {
      readonly data = data
      protected readonly ChevronRight = ChevronRight
    }
    
  • src/app/components/blocks/sidebar-03/search-form.component.ts1.6 kB
  • src/app/components/blocks/sidebar-03/version-switcher.component.ts3.2 kB
  • src/app/components/blocks/sidebar-03/index.ts0.2 kB

Raw manifest:https://uipkge.dev/r/angular/sidebar-03.json