Skip to content
OGE logoOGE

Migrate from PrimeNG

PrimeNG and OGE cover the same ground, so most screens move by renaming elements and inputs. What needs care is smaller: a handful of defaults point the other way, menus use another item model, and confirm and toast calls return promises instead of taking callbacks. This page lists all three and the adapters that keep your existing models.

component map defaults MenuItem adapter

Codemod

Every OGE package ships a migrate-primeng schematic. It rewrites p-button, p-dialog, p-tree and pTooltip in templates (files and inline template: strings), swaps the PrimeNG modules for the OGE standalone imports, and turns MenuItem into OgePrimeMenuItem. What it cannot translate one-to-one — a table's columns, a defaults difference, a bound style flag — it keeps and marks with TODO(oge-migrate), and the run ends with a list of those spots. Commit first and review the diff.

# from the workspace root, on a clean working tree
ng generate @oge-ui/buttons:migrate-primeng            # src/ by default
ng generate @oge-ui/overlay:migrate-primeng --path=src/app/admin

# before → after
<p-button label="Save" icon="pi pi-save" [outlined]="true" (onClick)="save()" />
<oge-button text="Save" iconClass="pi pi-save" (clicked)="save()" stylingMode="outlined" />

<p-dialog header="Edit" [(visible)]="open" [modal]="true">…</p-dialog>
<!-- TODO(oge-migrate): p-dialog relied on PrimeNG defaults (draggable, resizable, dismissableMask); … -->
<oge-modal title="Edit" [(opened)]="open">…</oge-modal>

Component map

Every Angular element has a React twin with the same options, so a mixed codebase moves with one vocabulary.

PrimeNG components and their OGE counterparts
PrimeNGOGE (Angular · React)Package
p-tableoge-grid · <OgeGrid>@oge-ui/grid · @oge-ui/react-grid
p-treeTableoge-tree-list · <OgeTreeList>@oge-ui/tree-list
p-treeoge-tree-view · <OgeTreeView>@oge-ui/navigation
p-dialogoge-modal · <OgeModal>@oge-ui/overlay
p-confirmDialog + ConfirmationServiceOgeModalService.confirm() · useOgeModals().confirm()@oge-ui/overlay
p-toast + MessageServiceOgeToastService · useOgeToasts()@oge-ui/overlay
p-contextMenu[ogeContextMenu] · <OgeContextMenu>@oge-ui/overlay
p-menu , p-tieredMenuoge-menu-list · <OgeMenuList>@oge-ui/overlay
p-menubaroge-menubar · <OgeMenubar>@oge-ui/navigation
p-popover ( p-overlayPanel ) oge-popover · <OgePopover>@oge-ui/overlay
pTooltip[ogeTooltip] · <OgeTooltip>@oge-ui/overlay
p-buttonoge-button · <OgeButton>@oge-ui/buttons
p-selectButtonoge-button-group · <OgeButtonGroup>@oge-ui/buttons
p-splitButtonoge-drop-down-button · <OgeDropDownButton>@oge-ui/buttons
p-select ( p-dropdown ) oge-select-box · <OgeSelectBox>@oge-ui/inputs
p-multiSelectoge-tag-box · <OgeTagBox>@oge-ui/inputs
p-datepicker ( p-calendar ) oge-date-box · <OgeDateBox>@oge-ui/inputs
p-inputNumberoge-number-box · <OgeNumberBox>@oge-ui/inputs
p-tabs ( p-tabView ) oge-tabs · <OgeTabs>@oge-ui/tabs
p-breadcrumboge-breadcrumb · <OgeBreadcrumb>@oge-ui/navigation
p-paginatoroge-pagination · <OgePagination>@oge-ui/navigation
p-stepperoge-stepper · <OgeStepper>@oge-ui/navigation
p-drawer ( p-sidebar ) oge-drawer · <OgeDrawer>@oge-ui/navigation
p-fileUploadoge-file-uploader · <OgeFileUploader>@oge-ui/upload
p-editoroge-editor · <OgeEditor>@oge-ui/editor
p-chartoge-chart · <OgeChart>@oge-ui/charts

Defaults that differ

These are the defaults a one-to-one port gets wrong without an error — check them on every screen you move.

Defaults that differ
BehaviourPrimeNG defaultOGE default
Dialog is modal modal = false always modal ( oge-window is the non-modal one)
Backdrop click closes dismissableMask = falsecloseOnBackdropClick = true
Dialog can be dragged draggable = truedragEnabled = false
Dialog can be resized resizable = trueresizeEnabled = false
Page scroll locked while open blockScroll = falsescrollLock = true
Escape closes closeOnEscape = truecloseOnEscape = true — hiding ✕ does not turn it off
Toast lifetime life = 3000 ms toastDisplayTime = 4000 ms
Toast position top-rightbottom-end (logical: mirrors in RTL)
Tooltip side tooltipPosition = righttooltipPlacement = top
Tooltip delay none tooltipShowDelayMs = 400 ms
Text column filter startsWithcontains — accent- and case-insensitive, Turkish İ / ı included

OGE menus take OgeMenuItem. ogeFromPrimeMenuItems() converts your PrimeNG MenuItem arrays as they are, submenus included: label → text, command → action, an icon class → iconClass, routerLink (with queryParams and fragment) → url, styleClass → cssClass, title / tooltip → hint; separator, disabled, visible, badge, shortcut and items keep their names. A router link becomes a real href (middle-click opens a tab); hand it to the router in the item-click handler.

import { Component, computed, input } from '@angular/core';
import { Router } from '@angular/router';
import {
  OgeContextMenu,
  ogeFromPrimeMenuItems,
  type OgeMenuListItemClickEvent,
  type OgePrimeMenuItem, // your PrimeNG MenuItem[] fits this shape as is
} from '@oge-ui/overlay';

@Component({
  selector: 'app-row-actions',
  imports: [OgeContextMenu],
  template: `<div [ogeContextMenu]="items()" (contextMenuItemClick)="go($event)">…</div>`,
})
export class RowActions {
  // the PrimeNG model you already have, unchanged
  readonly model = input.required<OgePrimeMenuItem[]>();
  // label → text, command → action, icon → iconClass, routerLink → url,
  // styleClass → cssClass, title / tooltip → hint; separators and submenus stay
  protected readonly items = computed(() => ogeFromPrimeMenuItems(this.model()));

  constructor(private readonly router: Router) {}

  // a routerLink became a real href: let the router take it
  protected go(event: OgeMenuListItemClickEvent): void {
    const url = event.item.url;
    if (url?.startsWith('/')) {
      event.event.preventDefault();
      void this.router.navigateByUrl(url);
    }
  }
}
import {
  OgeContextMenu,
  ogeFromPrimeMenuItems,
  type OgePrimeMenuItem, // your PrimeNG MenuItem[] fits this shape as is
} from '@oge-ui/react-overlay';

declare const model: OgePrimeMenuItem[];
const items = ogeFromPrimeMenuItems(model);

<OgeContextMenu items={items}>
  <div tabIndex={0}>Right-click me</div>
</OgeContextMenu>;

Buttons

p-button inputs on oge-button
PrimeNGOGE
labeltext
icon (a CSS class) iconClass — or project an SVG with [ogeButtonIcon]
severity : secondary · success · info · warn · danger · help · contrastseverity : normal · success · accent · warning · danger ( color for anything else)
outlined · text · linkstylingMode: 'outlined' | 'text' | 'link'
roundedshape: 'pill'
fluidfluid
loading · loadingIconloading · loadingText
badgebadge
(onClick)(clicked) — passes the click guard, hold-to-confirm and single-flight action
<!-- PrimeNG -->
<p-button label="Save" icon="pi pi-save" severity="secondary" [outlined]="true"
          [rounded]="true" [loading]="saving" (onClick)="save()" />

<!-- OGE: the label is text, an icon class is iconClass, styles are one input -->
<oge-button text="Save" iconClass="pi pi-save" stylingMode="outlined"
            shape="pill" [loading]="saving" (clicked)="save()" />

Dialogs, confirm and toasts

A dialog that relied on PrimeNG's defaults needs its options spelled out — or dropped, since OGE's are the usual modal ones:

<!-- PrimeNG: non-modal, draggable and resizable unless told otherwise -->
<p-dialog header="Edit" [(visible)]="open" [modal]="true" [dismissableMask]="true">…</p-dialog>

<!-- OGE: modal, fixed, closes on a backdrop click — opt in to the rest -->
<oge-modal title="Edit" [(opened)]="open">…</oge-modal>
<oge-modal title="Edit" [(opened)]="open"
           [closeOnBackdropClick]="false" [dragEnabled]="true" [resizeEnabled]="true">…</oge-modal>

Confirm and toast services need no host element in the template. confirm() resolves to a boolean, and it adds gates for irreversible actions that PrimeNG leaves to you (details, typeToConfirm, acknowledgeLabel). Toast severities are info, success, warning and error:

// PrimeNG: ConfirmationService with accept / reject callbacks
this.confirmation.confirm({
  header: 'Delete file?',
  message: 'report.xlsx will be removed permanently.',
  accept: () => this.remove(),
});

// OGE: a promise — true for the primary button, false otherwise
const ok = await this.modals.confirm({
  title: 'Delete file?',
  message: 'report.xlsx will be removed permanently.',
  severity: 'danger',
});
if (ok) this.remove();
// PrimeNG: MessageService + <p-toast>; severity 'warn', life in ms
this.messages.add({ severity: 'warn', summary: 'Quota', detail: '90% used', life: 3000 });

// OGE: OgeToastService (no host element to place); severity 'warning'
this.toasts.warning('90% used', { title: 'Quota', displayTime: 3000 });

Trees

OGE trees read your own objects instead of a TreeNode wrapper: name the key, label and children fields (or pass flat rows with a parent id). Drops report through itemReordered and never mutate your data; itemDragStarting, itemDragOver and allowDropBetween replace PrimeNG's draggableNodes / droppableNodes checks.

// PrimeNG: TreeNode[] with label / children / key
const nodes: TreeNode[] = [{ key: '1', label: 'Documents', children: [/* … */] }];

// OGE: your own objects — say which fields to read
<oge-tree-view [items]="nodes" keyExpr="key" displayExpr="label" itemsExpr="children"
               [allowDragging]="true" (itemReordered)="move($event)" />

Dark mode

PrimeNG's darkModeSelector has two OGE forms: the prebuilt dark-class.css for .dark and [data-theme="dark"], and the Sass theme() mixin for any other selector. See Styling for the tokens and the bridge themes.

/* PrimeNG: providePrimeNG({ theme: { options: { darkModeSelector: '.app-dark' } } }) */

/* OGE, Tailwind-style .dark or [data-theme="dark"]: one import */
@import '@oge-ui/core/themes/dark-class.css';

/* OGE, any other selector (.app-dark here): the Sass mixin */
@use '@oge-ui/core/themes/dark.scss' as oge-dark;
@include oge-dark.theme('.app-dark');

Moving one screen at a time

  • Both libraries can live in one app while you move: OGE styles target only .oge-* classes and declare only --oge-* tokens, so they never restyle a PrimeNG element.
  • Start with the screens whose grids carry the most logic — server filtering, grouping, export — since that is where the APIs differ most; the filter contract describes what the grid sends to your server.
  • Keep your MenuItem models and convert them at the edge with ogeFromPrimeMenuItems() until the last PrimeNG menu is gone.