Menu

Change language

GitHub repo

Toggle Setting List

blocklayout

List of toggle-able settings in a SectionCard. Spell rows out inline with UiToggleSettingRow — each row is a controlled switch taking `checked` + `checkedChange`.

Installation

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

Variants

Loading interactive previews…

Includes

Files installed (2)

  • src/app/components/blocks/toggle-setting-list/toggle-setting-list.component.ts2.8 kB
    // List of toggle-able settings in a SectionCard. Spell rows out inline with
    // UiToggleSettingRow — each row is a controlled switch taking `checked` + `checkedChange`.
    // Port of the React block 1:1.
    import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'
    import { cn } from '@/lib/utils'
    import { UiSectionCardComponent } from '@/ui/section-card/section-card.component'
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-toggle-setting-list, [ui-toggle-setting-list]',
      standalone: true,
      // React renders the SectionCard itself: the host stays out of layout and `class` goes to the root.
      host: { '[attr.class]': '"contents"' },
      imports: [UiSectionCardComponent],
      template: `
        <div
          ui-section-card
          data-slot="toggle-setting-list"
          [title]="title"
          [description]="description"
          [class]="rootClass"
        >
          <div slot="header-action">
            <ng-content select="[header-icon]" />
          </div>
          <ul class="-my-4 divide-y">
            <ng-content />
          </ul>
        </div>
      `,
    })
    export class UiToggleSettingListComponent {
      @Input() title = 'Notifications'
      @Input() description?: string
      @Input('class') className?: string
    
      get rootClass(): string {
        return cn(this.className)
      }
    }
    
    /** One controlled switch row. Hold state in the parent and wire `checked` + `checkedChange` per row. */
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-toggle-setting-row, [ui-toggle-setting-row]',
      standalone: true,
      host: { '[attr.class]': '"contents"' },
      template: `
        <li class="flex items-center justify-between gap-4 py-4 first:pt-0">
          <div>
            <p class="text-sm font-medium">{{ label }}</p>
            @if (desc) {
              <p class="text-muted-foreground text-xs">{{ desc }}</p>
            }
          </div>
          <button
            type="button"
            role="switch"
            [attr.aria-label]="label"
            [attr.aria-checked]="checked"
            [class]="
              cn(
                'focus-visible:ring-ring relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full transition-colors focus:outline-none focus-visible:ring-2',
                checked ? 'bg-primary' : 'bg-muted-foreground/30'
              )
            "
            (click)="checkedChange.emit(!checked)"
          >
            <span
              [class]="
                cn(
                  'bg-background inline-block size-4 translate-y-0.5 rounded-full shadow transition-transform',
                  checked ? 'translate-x-[18px]' : 'translate-x-0.5'
                )
              "
            ></span>
          </button>
        </li>
      `,
    })
    export class UiToggleSettingRowComponent {
      protected readonly cn = cn
    
      @Input() label = ''
      @Input() desc?: string
      @Input() checked = false
      @Output() checkedChange = new EventEmitter<boolean>()
    }
    
  • src/app/components/blocks/toggle-setting-list/index.ts0.1 kB

Raw manifest:https://uipkge.dev/r/angular/toggle-setting-list.json