Imperative, type-safe, promise-based dialogs & overlays for Angular — the Angular counterpart of react-call's
createCallable.
▶ Live demo & 21 examples → hebus.github.io/ngx-call
Call a dialog like a function. Await a confirm, resolve a value — no template wiring, no boilerplate.
// 1 — bind any component, once
export const Confirm = createCallable<{ message: string }, boolean>(ConfirmDialog);
// 2 — call it like a function, anywhere
const ok = await Confirm.call({ message: "Delete this item?" });
// ^ resolves to boolean — fully typed- Imperative API —
call,upsert,update,end,setRoot, mirroring react-call's full surface. - Type-safe — arguments and the resolved value are typed end-to-end.
- Promise-based —
awaitany overlay; each call stacks an independent instance. - Zero dependencies — built on Angular signals and DI.
- Anything overlay-shaped — confirms, prompts, toasts, drawers, command palettes, wizards… see the demo.
Beyond the obvious Angular-vs-React: react-call is headless — it gives you the callable/stacking mechanism and you render and style the overlay yourself. ngx-call keeps that same headless engine (createCallable, injectCallRef, stacking, closeAll) and ships optional UI primitives built directly on web-platform standards:
- Native
<dialog>element — theDialogwrapper drives the real element viashowModal()/show(), so you get the browser top layer, the native::backdrop, focus trapping and Esc-to-close for free — no re-implemented modal logic. - Standard Popover API —
showPopover()opens in the top layer with native light-dismiss (closedby="any"), ideal for menus, tooltips and non-modal panels — no overlay<div>, no manual outside-click handling. - Single-backdrop stacking — stacked native modals would each paint their own
::backdropand cumulatively darken the page; ngx-call keeps exactly one visible backdrop across the whole stack. - No
<Root/>to place — react-call requires you to render<X.Root />in your component tree; ngx-call mounts instances imperatively (todocument.body) onceprovideCallable()is registered, so there's nothing to wire into a template. - Signals throughout —
call.props(),call.index(),call.stackSize()andDialogService.openCountare Angular signals.
The UI primitives are optional: use the headless createCallable with your own markup, or lean on Dialog / DialogContent for the batteries-included path.
Familiar by design — the public API deliberately mirrors react-call's surface (createCallable, and call / upsert / update / end / setRoot). Porting a dialog between React and Angular — in either direction — is closer to a mechanical rename than a rewrite.
npm i ngx-callThen capture the root injector at bootstrap:
bootstrapApplication(App, { providers: [provideCallable()] });This is a multi-project Angular workspace: the ngx-call library and a demo application.
npm install
npm start # serves the demo at http://localhost:4200/
npx ng build ngx-call # builds the library
npx ng build demo # builds the demo app
npm test # runs unit tests (Vitest)The demo is built and published to GitHub Pages on every push to main via
.github/workflows/deploy.yml →
hebus.github.io/ngx-call.
A direct port of desko27/react-call to Angular.