v1.2.0

Getting started

Table, Bro is the Custom Element ‹table-bro›: it takes the columns, the rows and a config with the name of its skin, and renders the table with its toolbar and its paginator.

Angular

import {ChangeDetectionStrategy, Component, signal} from '@angular/core';

import {TableBroNg}                     from '@table-bro/angular';
import type {BroCol, BroConfig, BroRow} from '@table-bro/core';

interface Order extends BroRow {
  description: string;
  price: number;
}

@Component({
  selector: 'app-orders',
  template: `
    <table-bro-ng class="bro-table-shadow-container" tableId="orders"
                  [cols]="cols()" [rows]="rows()" [conf]="conf()"></table-bro-ng>`,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [
    TableBroNg
  ]
})
export class OrdersComponent {
  cols = signal<BroCol<Order>[]>([
    {
      title: 'Description',
      name: 'description'
    }, {
      title: 'Price',
      name: 'price',
      dataType: 'number',
      className: 'bro-col_text-right'
    }
  ]);

  rows = signal<Order[]>([
    {
      description: 'Modern Cotton Chair',
      price: 100
    }, {
      description: 'Awesome Concrete Ball',
      price: 200
    }
  ]);

  conf = signal<BroConfig>({
    skin: 'mat',
    toolbarTitle: 'Orders'
  });
}

Vanilla JS

import type {BroCol, BroConfig, BroRow} from '@table-bro/core';

interface Order extends BroRow {
  description: string;
  price: number;
}

const cols: BroCol<Order>[] = [
  {
    title: 'Description',
    name: 'description'
  }, {
    title: 'Price',
    name: 'price',
    dataType: 'number',
    className: 'bro-col_text-right'
  }
];

const rows: Order[] = [
  {
    description: 'Modern Cotton Chair',
    price: 100
  }, {
    description: 'Awesome Concrete Ball',
    price: 200
  }
];

const conf: BroConfig = {
  skin: 'bs', // 'nv' for Vanilla HTML
  toolbarTitle: 'Orders'
};

const table = document.createElement('table-bro');

table.id = 'orders';
table.configure({cols, rows, conf});

// The shadows of the table fall into the margins of this element: the visible table takes its full width
const container = document.createElement('div');

container.className = 'bro-table-shadow-container';
container.append(table);
document.body.append(container);
Loading
Items per page:
Clear

Table, Bro + Angular Material

See a working page

  1. Install the packages

    The table and the parts it needs; a project without Angular Material adds it first with ng add @angular/material.

    npm install @table-bro/core @table-bro/angular @table-bro/angular-material @angular/elements
    
  2. Add the CSS

    To "styles" of angular.json:

    "styles": [
      "node_modules/@table-bro/core/dist/table-bro.min.css",
      "node_modules/@table-bro/angular-material/dist/table-bro.material.min.css"
    ]
    
  3. Register the skin and its elements

    In the providers of app.config.ts. The elements that only some tables use come with their functions: withTags() for tags, withSwitch() for switches, withToolbarMenu() for the menu of the toolbar; a project that registers the skin already adds the ones of a new table to the call.

    import type {ApplicationConfig} from '@angular/core';
    
    import {provideTableBroMatSkin} from '@table-bro/angular-material';
    
    export const appConfig: ApplicationConfig = {
      providers: [
        provideTableBroMatSkin()
      ]
    };
    
  4. Keep the theme of Angular Material

    The mat skin takes the theme of the application, as the components of Angular Material do: the table looks as a mat-table of the project, and a table in the dark theme takes the dark scheme of the theme. ng add @angular/material writes the theme into styles.scss; a project without it adds it:

    @use '@angular/material' as mat;
    
    html {
      @include mat.theme((
        color: (
          primary: mat.$azure-palette,
          tertiary: mat.$blue-palette,
        ),
        typography: Roboto,
        density: 0,
      ));
    }
    
  5. Load the fonts of the icons

    The mat skin shows the ligature icons of Material, as Angular Material asks; the cells and the dialogs of the page take the newer Material Symbols. In index.html:

    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,300,0,0" rel="stylesheet">
    

Table, Bro + Vanilla Bootstrap

See a working page

  1. Install the packages

    The table and the parts it needs:

    npm install @table-bro/core @table-bro/bootstrap bootstrap @types/bootstrap
    
  2. Link the CSS

    On the page:

    <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="node_modules/@table-bro/core/dist/table-bro.min.css">
    <link rel="stylesheet" href="node_modules/@table-bro/bootstrap/dist/table-bro.bootstrap.min.css">
    
  3. Register the skin

    Once, before the tables: the import registers the skin, which takes the classes of Bootstrap. The elements that only some tables use come with their functions: withTags() for tags, withSwitch() for switches; a project that registers the skin already adds the ones of a new table. A page may define them itself, as customElements.define('bro-bs-tags', BroBootstrapTagsComponent).

    import {useBootstrap}      from '@table-bro/bootstrap';
    import {Dropdown, Tooltip} from 'bootstrap';
    
    useBootstrap({Dropdown, Tooltip});
    

Table, Bro + Vanilla HTML

See a working page

  1. Install the packages

    The table and the parts it needs:

    npm install @table-bro/core @table-bro/native
    
  2. Link the CSS

    On the page:

    <link rel="stylesheet" href="node_modules/@table-bro/core/dist/table-bro.min.css">
    <link rel="stylesheet" href="node_modules/@table-bro/native/dist/table-bro.native.min.css">
    
  3. Register the skin

    Once, before the tables: the import registers the skin. The elements that only some tables use come with their functions: withTags() for tags, withSwitch() for switches; a project that registers the skin already adds the ones of a new table. A page may define them itself, as customElements.define('bro-nv-tags', BroNativeTagsComponent).

    import '@table-bro/native';
    

Without a build

See a working page, StackBlitz

A page without a bundler takes the same packages from jsDelivr, the CDN of npm, at an exact version: the CSS by ‹link›, the modules by an import map, which gives @table-bro/core to the skin (MDN, importmap). index.html:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Table, Bro + Vanilla HTML without a build</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@table-bro/core@1.2.0/dist/table-bro.min.css" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@table-bro/native@1.2.0/dist/table-bro.native.min.css" />
    <!-- The page around the table, as on table-bro.com -->
    <link rel="stylesheet" href="sample-page.css" />
    <script type="importmap">
      {
        "imports": {
          "@table-bro/core": "https://cdn.jsdelivr.net/npm/@table-bro/core@1.2.0/dist/table-bro.esm.js",
          "@table-bro/native": "https://cdn.jsdelivr.net/npm/@table-bro/native@1.2.0/dist/table-bro.native.esm.js"
        }
      }
    </script>
  </head>
  <body>
    <script type="module" src="app.js"></script>
  </body>
</html>

app.js imports the skin and gives the table its columns, rows and config:

// The import of the skin defines <table-bro> and registers the skin nv
import '@table-bro/native';

const cols = [
  {
    title: 'Description',
    name: 'description'
  }, {
    title: 'Price',
    name: 'price',
    dataType: 'number',
    className: 'bro-col_text-right'
  }
];

const rows = [
  {
    description: 'Modern Cotton Chair',
    price: 100
  }, {
    description: 'Awesome Concrete Ball',
    price: 200
  }
];

const conf = {
  skin: 'nv',
  toolbarTitle: 'Orders'
};

const table = document.createElement('table-bro');

table.id = 'orders';
table.configure({cols, rows, conf});
table.addEventListener('bro-action', event => console.log(event.detail.action));

// The shadows of the table fall into the margins of this element: the visible table takes its full width
const container = document.createElement('div');

container.className = 'bro-table-shadow-container';
container.append(table);
document.body.append(container);
DJ