Action Panel
The <smart-action-panel> component renders a standalone panel with a heading, description and one or more actions (buttons or links). It is typically used to surface a small "card" of contextual settings (e.g. Manage subscription, Update your email, Renew automatically). It follows the Base + Standard + Wrapper pattern with an InjectionToken-based extension mechanism. The abstract ActionPanelBaseComponent defines the shared API — options (IActionPanelOptions), cssClass (alias class), and the actionClick output. ActionPanelStandardComponent is a barebones placeholder using native <section>, <h3>, <p>, <a>, and <button> elements. ActionPanelComponent is the public wrapper that renders ActionPanelStandardComponent by default and accepts a custom replacement via ACTION_PANEL_STANDARD_COMPONENT_TOKEN.
Usage
<smart-action-panel [options]="options" (actionClick)="onActionClick($event)" />
Components
ActionPanelComponent (<smart-action-panel>)
Main wrapper. Delegates to ActionPanelStandardComponent by default. When ACTION_PANEL_STANDARD_COMPONENT_TOKEN is provided, renders the injected component via NgComponentOutlet. Re-emits actionClick.
ActionPanelStandardComponent (<smart-action-panel-standard>)
Barebones placeholder using native HTML. Renders an outer wrapper with cssClass, a <section class="action-panel"> containing an optional <h3>{{ options.title }}</h3>, an optional description (string options.description rendered as <p class="description"> or options.descriptionTpl rendered via NgTemplateOutlet), an optional <div class="content"> slot from options.contentTpl, and an optional <div class="actions"> row of <button class="action variant-{variant}"> (or <a> when action.href is provided) per options.actions entry that emits { actionId } via actionClick.
ActionPanelBaseComponent (abstract)
Abstract base directive. Exposes:
options: InputSignal<IActionPanelOptions | undefined>cssClass: InputSignal<string>(aliasclass)actionClick: OutputEmitterRef<IActionPanelActionClick>
IActionPanelActionClick = { actionId: string }.
API
Inputs
| Input | Type | Default | Description |
|---|---|---|---|
options | InputSignal<IActionPanelOptions | undefined> | - | Panel configuration |
class | InputSignal<string> | '' | External CSS classes (alias for cssClass) |
Outputs
| Output | Type | Description |
|---|---|---|
actionClick | OutputEmitterRef<IActionPanelActionClick> | Emitted when a button-type action is clicked |
Extending the base class
import {
ChangeDetectionStrategy,
Component,
input,
ViewEncapsulation,
} from '@angular/core';
import {
ActionPanelBaseComponent,
ActionPanelComponent,
ACTION_PANEL_STANDARD_COMPONENT_TOKEN,
IActionPanelOptions,
} from '@smartsoft001/angular';
@Component({
selector: 'docs-custom-action-panel',
template: `
<section class="docs-action-panel" [class]="cssClass()">
@if (options()?.title) {
<h3 class="docs-action-panel__title">{{ options()!.title }}</h3>
}
@if (options()?.description) {
<p class="docs-action-panel__description">
{{ options()!.description }}
</p>
}
@for (action of options()?.actions ?? []; track action.id) {
<button
type="button"
class="docs-action-panel__action"
(click)="actionClick.emit({ actionId: action.id })"
>
{{ action.label }}
</button>
}
</section>
`,
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CustomActionPanelComponent extends ActionPanelBaseComponent {
// NgComponentOutlet passes 'cssClass' by canonical name, not the 'class' alias.
override cssClass = input<string>('');
}
@Component({
selector: 'docs-action-panel-custom-example',
imports: [ActionPanelComponent],
providers: [
{
provide: ACTION_PANEL_STANDARD_COMPONENT_TOKEN,
useValue: CustomActionPanelComponent,
},
],
template: `<smart-action-panel [options]="options" />`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ActionPanelCustomExampleComponent {
options: IActionPanelOptions = {
layout: 'simple',
title: 'Transfer ownership',
description: 'Move this project to another workspace member.',
actions: [
{ id: 'transfer', label: 'Transfer', variant: 'primary' },
{ id: 'cancel', label: 'Cancel' },
],
};
}
Preset
ActionPanelPresetComponent (smart-action-panel-preset, action-panel/preset/) extends ActionPanelStandardComponent and restyles the panel as a bordered card (rounded-xl border bg-white p-4 shadow-2xs sm:p-6 + dark twin). Title uses text-base font-semibold text-gray-900, description text-sm text-gray-500; descriptionTpl overrides the description text. Class recipes live in preset-classes.util.ts (getActionPanel*Classes, not barrel-exported).
All eight SmartActionPanelLayout values are realized through a @switch (default simple):
simple/with-input/payment-method— title, description, content slot, then actions stacked below.with-link— actions rendered astext-blue-600 hover:underlinelinks.right-button— flex row, content left, actions right, vertically centered.top-right-button— actions in the title row, right-aligned.with-toggle— content slot placed beside the text (flex row), actions below.well— content and actions wrapped in an insetbg-gray-50 dark:bg-gray-900/50 rounded-lg p-4panel.
Actions map by variant: primary → solid bg-blue-600 text-white, others → outline border-gray-200 bg-white text-gray-800 + dark. href actions render as <a>, the rest as <button> calling the inherited onActionClick(id) (emits actionClick with the action id). DOM hooks: data-role of panel/title/description/content/actions/well, plus per-action data-role="action" with data-action-id; the panel also carries data-layout.
Unlike the standard component, the preset drops the class input alias (override cssClass = input<string>('')) so the wrapper's canonical componentInputs binding reaches it via NgComponentOutlet.
Register through the token to restyle every <smart-action-panel>:
Gaps: with-toggle / with-input / payment-method only position the content slot — the interactive control (toggle switch, input, card list) is supplied by the caller via contentTpl.
Source
The component lives in packages/shared/angular/src/lib/components/action-panel and is documented for Claude Code by the angular-components-action-panel skill.