Skip to content

Migration from ds-ng

This guide helps you migrate an application from @bnotk/ds-ng (Angular-only) to @bnotk/dsx (framework-agnostic).

ds-ngdsxChange type
Angular componentsLit Web ComponentsElement replacement
SCSS (compiled)Plain CSSImport change
Bootstrap gridCSS Grid utilitiesClass renaming
AG Grid wrapper<dsx-table>API simplification
ng-select wrapper<dsx-dropdown-typeahead>Element replacement
ng-bootstrap modal<dsx-dialog>Element replacement
ng-bootstrap accordion<dsx-accordion>Element replacement
NgModel bindingCustom eventsPattern change
Terminal window
npm install @bnotk/dsx

Before (ds-ng):

@use '@bnotk/ds-ng/styles';

After (dsx):

@import '@bnotk/dsx/css/index.css';

Or in angular.json:

{
"styles": [
"node_modules/@bnotk/dsx/css/index.css",
"src/styles.css"
]
}

In every Angular component that uses dsx Web Components:

import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
@Component({
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
// ...
})

In your main.ts or in each component file:

import '@bnotk/dsx/components/dialog.js';
import '@bnotk/dsx/components/table.js';
// ... etc
<!-- ds-ng -->
<button bButton variant="primary" size="sm">Click</button>
<!-- dsx -->
<button class="dsx-btn dsx-btn--primary dsx-btn--sm">Click</button>
<!-- ds-ng -->
<b-dialog [heading]="'Confirm'" [size]="'md'" (closed)="onClose()">
<ng-template bDialogBody>Content</ng-template>
<ng-template bDialogFooter>
<button bButton>OK</button>
</ng-template>
</b-dialog>
<!-- dsx -->
<dsx-dialog heading="Confirm" size="md" (dsx-close)="onClose()">
<div slot="body">Content</div>
<div slot="footer">
<button class="dsx-btn dsx-btn--primary">OK</button>
</div>
</dsx-dialog>
<!-- ds-ng (AG Grid wrapper) -->
<b-grid [columnDefs]="colDefs" [rowData]="rows"
(rowClicked)="onRow($event)"></b-grid>
<!-- dsx -->
<dsx-table [columns]="columns" [rows]="rows"
sortable column-toggle
(dsx-row-click)="onRow($event)"></dsx-table>

Column definition changes:

// ds-ng (AG Grid ColDef)
colDefs = [
{ field: 'name', headerName: 'Name', resizable: true, sortable: true },
{ field: 'email', headerName: 'E-Mail', width: 200 },
];
// dsx
columns = [
{ id: 'name', label: 'Name', resizable: true },
{ id: 'email', label: 'E-Mail', width: '200px' },
];
<!-- ds-ng (ng-select wrapper) -->
<b-dropdown [items]="options" [bindLabel]="'name'"
[(ngModel)]="selected"></b-dropdown>
<!-- dsx (simple) -->
<select class="dsx-select">
<option *ngFor="let o of options" [value]="o.id">{{o.name}}</option>
</select>
<!-- dsx (typeahead/multi) -->
<dsx-dropdown-typeahead [options]="mappedOptions"
searchable multiple
(dsx-change)="onSelect($event)">
</dsx-dropdown-typeahead>
<!-- ds-ng (ng-bootstrap) -->
<b-accordion>
<b-accordion-item [header]="'Section 1'" [expanded]="true">
Content
</b-accordion-item>
</b-accordion>
<!-- dsx -->
<dsx-accordion>
<dsx-accordion-item header="Section 1" expanded>
Content
</dsx-accordion-item>
</dsx-accordion>

dsx Web Components emit standard CustomEvents instead of supporting [(ngModel)].

// ds-ng
<b-datepicker [(ngModel)]="date"></b-datepicker>
// dsx
<dsx-datepicker [value]="date"
(dsx-change)="date = $event.detail.value">
</dsx-datepicker>
Terminal window
npm uninstall @bnotk/ds-ng @ng-bootstrap/ng-bootstrap bootstrap ag-grid-angular ag-grid-community @ng-select/ng-select ngx-scrollbar
ds-ng classdsx class
btn-primarydsx-btn dsx-btn--primary
btn-secondarydsx-btn dsx-btn--secondary
btn-dangerdsx-btn dsx-btn--danger
form-controldsx-input
form-selectdsx-select
form-check-inputdsx-checkbox / dsx-radio
nav-tabsdsx-tabs
tabledsx-table (CSS class)
badgedsx-status
alertdsx-infobox
progressdsx-progress
  1. No [(ngModel)] — Use event binding (dsx-change)="handler($event)"
  2. CUSTOM_ELEMENTS_SCHEMA required — Angular won’t recognize <dsx-*> tags without it
  3. Shadow DOM — Styles inside WCs are encapsulated. Use ::part() or CSS custom properties to customize.
  4. Property binding — Complex objects (arrays, objects) use Lit’s .prop syntax in HTML, or [prop] in Angular templates.