CngxPopoverPanel
projects/common/popover/popover-panel.component.ts
Import#
import { CngxPopoverPanel } from '@cngx/common/popover'
Description#
Rich popover panel molecule with header/body/footer slots, variant styling, arrow, close button, and content state templates.
Composes CngxPopover via hostDirectives - all popover inputs
(placement, offset, closeOnEscape, mode, exclusive,
cngxPopoverOpen) are forwarded.
The variant input is a free-form string mapped to a CSS class
(cngx-popover-panel--{variant}). Five variants are pre-themed
in popover-panel-theme.scss: default, info, warning,
danger, success. Add custom variants via CSS.
Basic with header/body/footer
<button [cngxPopoverTrigger]="panel" (click)="panel.popover.toggle()">Menu</button>
<cngx-popover-panel #panel variant="danger" [showClose]="true" [showArrow]="true">
<span cngxPopoverHeader>Delete Item?</span>
<p cngxPopoverBody>This action cannot be undone.</p>
<div cngxPopoverFooter>
<cngx-popover-action role="dismiss">Cancel</cngx-popover-action>
<cngx-popover-action role="confirm" [action]="delete" variant="danger">
Delete
</cngx-popover-action>
</div>
</cngx-popover-panel>With loading state
<cngx-popover-panel [loading]="isLoading()" [error]="loadError()">
<p cngxPopoverBody>Loaded content here</p>
<ng-template cngxPopoverLoading>Loading...</ng-template>
<ng-template cngxPopoverError let-err>Failed: {{ err }}</ng-template>
</cngx-popover-panel>Metadata#
Host#
Providers#
CNGX_POPOVER_ARROW_BOUNDS- useExisting
CngxPopoverPanel
Dependencies#
Relationships
Used by2
Index#
Inputs#
Whether the panel content is in a loading state. Fallback when [state] is not set.
falseARIA role applied to the panel host. Defaults to 'dialog' because
the panel pairs aria-labelledby (header) with aria-describedby
(body) - the standard dialog pattern. Override with 'alertdialog'
for irrecoverable confirmations, 'tooltip' for passive callouts,
or 'menu' when the panel hosts a menu.
The trigger's aria-haspopup is hinted to 'dialog' in tandem via
the popover's haspopup signal; consumers overriding role here
should also override haspopup on the trigger to match.
'dialog'boolean | undefinedShow an arrow. Falls back to global config from providePopoverPanel(withArrow()).
undefined, { alias: 'showArrow' }boolean | undefinedShow a close button. Falls back to global config from providePopoverPanel(withCloseButton()).
undefined, { alias: 'showClose' }Bind an async state - drives loading, error, and empty slots from a single source.
When set, takes precedence over individual [loading], [error], [empty] inputs.
string | undefinedVariant string - mapped to CSS class cngx-popover-panel--{variant}.
Pre-themed: default, info, warning, danger, success.
Add custom variants via CSS.
Instance Properties#
HostBindings#
| Binding | Expression |
|---|---|
[class] | hostClass() |
[attr.role] | role() |
[attr.aria-labelledby] | headerId |
[attr.aria-describedby] | ariaDescribedBy() |
[attr.aria-busy] | effectiveLoading() || null |
Default visuals for CngxPopoverPanel. The host carries
.cngx-popover-panel via hostClass(); the CngxPopover host
directive toggles open / closing transition classes. The four
semantic accents sit outside the foundation primary so an Ember-
toned theme cannot accidentally tint a "success" panel.
State modifiers
Applied by CngxPopover to drive the open / close transition:
.cngx-popover--opening- opacity 0 + translate 4px / scale 0.98.cngx-popover--open- resting state.cngx-popover--closing- same as opening, animated outward:popover-open- native popover restore-display
Accent variants
Each pins --cngx-popover-panel-accent + -accent-text on the
panel and adds a border-left stripe. Child slots pick up both
tokens via inheritance:
--info- blue accent--success- success-coded--warning- warning-coded--danger- danger-coded
Arrow placement
Selected via [data-arrow-placement="top|bottom|left|right"]
written by CngxPopover from live trigger / panel geometry. The
45-degree arrow square positions itself off the matching edge;
--cngx-popover-arrow-offset (also written by CngxPopover)
carries the live perpendicular offset, with a 50% fallback for
the first paint before the offset computation lands.
Slots
__header- optional title row__body- main content__footer- action row, divided by top border__header-row- header + optional close button__close- circular dismiss button, hover wash + focus ring__arrow- 45-degree square positioned by arrow-placement__loading/__error/__empty- async-state surfaces;__errorpicks up--cngx-color-danger,__emptydims to 0.6
Inheritance
--cngx-popover-panel-bg->--cngx-color-surface(via:rootdelegation so dark-mode surface cascades through automatically)--cngx-popover-panel-color->--cngx-color-text- Layout / motion / header / footer tokens - leaf, no fallback chain
- Accent surface tokens - leaf; each variant rule pins them with light-mode defaults, the dark cascade overrides them at higher specificity outside the @scope wrap
Dark mode
Three hooks lift the alpha-on-black borders / shadow to alpha-on- white so they remain visible on dark surfaces, swap the close-button hover wash to white-alpha, and pin every variant accent to its dark-mode pair (lower L surface + lifted-L text):
prefers-color-scheme: dark[data-color-scheme="dark"]/.darkclass[data-color-scheme="light"]/.lightclass (explicit pin)
Reduced motion
Under prefers-reduced-motion: reduce the opacity + transform
transition is dropped so the panel snaps in and out.
Pair with
@cngx/themes/material/popover-panel-theme- Material 3 surface + elevation
Index#
Surface
Layout
Variant / Accent
State / Hover
Surface
<color>oklch(1 0 0)Panel background. Falls back through --cngx-color-surface.
See: [[--cngx-color-surface]]
<color>oklch(0.27 0.04 250)Panel text color. Falls back through --cngx-color-text.
See: [[--cngx-color-text]]
*0 8px 24px oklch(0 0 0 / 0.12)Drop-shadow shorthand for the panel. inherits: true so the
:root dark-mode override reaches the open panel element.
*1px solid oklch(0 0 0 / 0.08)Border shorthand for the panel.
Layout
<length>360pxMaximum inline size - caps long content before the floater collides with viewport edges.
<length>8pxSide length of the arrow square (the rotated 45° diamond - final
arrow side reads as size * sqrt(2)).
<length>28pxDiameter of the optional close button in the header row.
<length>8pxVertical gap between the header and the body slot.
Motion
<time>200msDuration of the opacity + transform transition between the open states.
*cubic-bezier(0.4, 0, 0.2, 1)Easing curve of the open / close transition.
Typography
<number>600Font-weight of the optional header slot.
Variant / Accent
*transparentAccent surface for the semantic-variant rules
(.cngx-popover-panel--info / --success / --warning /
--danger). Each variant rule pins this token plus the matching
accent-text token - child slots pick them up through
currentColor and var() fallbacks.
*currentColorText / outline color paired with the accent surface - used by focus rings and the variant border-left rule.
State / Hover
<color>oklch(0 0 0 / 0.06)Hover wash on the optional close button. Light: 6% black wash; dark: 8% white wash. Both sit subtly on top of the panel surface without competing for attention.