easy-mat-ui-ng20 20.0.0 → 20.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +275 -253
- package/fesm2022/easy-mat-ui-ng20.mjs +362 -19
- package/fesm2022/easy-mat-ui-ng20.mjs.map +1 -1
- package/index.d.ts +250 -5
- package/package.json +9 -2
- package/page-generator/blocks.js +155 -0
- package/page-generator/catalog.js +132 -0
- package/page-generator/cli/main.js +314 -0
- package/page-generator/cli/project.js +252 -0
- package/page-generator/context.js +108 -0
- package/page-generator/generate.js +182 -0
- package/page-generator/index.js +33 -0
- package/page-generator/naming.js +53 -0
- package/page-generator/table.js +310 -0
- package/page-generator/types.js +6 -0
package/README.md
CHANGED
|
@@ -1,253 +1,275 @@
|
|
|
1
|
-
# easy-mat-ui
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/easy-mat-ui-ng20)
|
|
4
|
-
[](https://github.com/chaibiredouane/easy-mat-ui/actions/workflows/ci.yml)
|
|
5
|
-
[](https://angular.dev)
|
|
6
|
-
[](LICENSE)
|
|
7
|
-
|
|
8
|
-
**[Live demo](__SITE_URL__/)** · **[Documentation](__SITE_URL__/docs/)** · [npm](https://www.npmjs.com/package/easy-mat-ui-ng20) · [Changelog](CHANGELOG.md)
|
|
9
|
-
|
|
10
|
-
A set of customizable Angular Material components built around a configurable **data table**:
|
|
11
|
-
filtering, sorting, pagination, typed columns, expandable rows, tabbed child tables, a toolbar,
|
|
12
|
-
a configurable **create / edit / view dialog** and a **multi-select** control, with
|
|
13
|
-
[ngx-translate](https://github.com/ngx-translate/core) based i18n.
|
|
14
|
-
|
|
15
|
-
## Features
|
|
16
|
-
|
|
17
|
-
- `lib-easy-table` / `lib-easy-table-basic`: a Material table driven by a single `EasyTableConfig` object.
|
|
18
|
-
- Typed columns (`MatColumnTyped`): text, number, date, date-time, icon, icon-and-text, button, dropdown list, image
|
|
19
|
-
(flags), password and filter columns.
|
|
20
|
-
- **Column filters** under the titles (a compact text input or a multi-select per column), global search, sorting,
|
|
21
|
-
pagination, sticky columns and a header that stays pinned while the rows scroll.
|
|
22
|
-
- Expandable rows with **child tables**, or several child tables in **tabs** (`childConfig`).
|
|
23
|
-
- `EasyDialogService`: a configurable dialog to create, edit or view a record.
|
|
24
|
-
- `lib-easy-multi-select`: a searchable multi-select with select-all, clear, read-only and compact modes.
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
],
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
`
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
1
|
+
# easy-mat-ui
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/easy-mat-ui-ng20)
|
|
4
|
+
[](https://github.com/chaibiredouane/easy-mat-ui/actions/workflows/ci.yml)
|
|
5
|
+
[](https://angular.dev)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
**[Live demo](__SITE_URL__/)** · **[Documentation](__SITE_URL__/docs/)** · [npm](https://www.npmjs.com/package/easy-mat-ui-ng20) · [Changelog](CHANGELOG.md)
|
|
9
|
+
|
|
10
|
+
A set of customizable Angular Material components built around a configurable **data table**:
|
|
11
|
+
filtering, sorting, pagination, typed columns, expandable rows, tabbed child tables, a toolbar,
|
|
12
|
+
a configurable **create / edit / view dialog** and a **multi-select** control, with
|
|
13
|
+
[ngx-translate](https://github.com/ngx-translate/core) based i18n.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- `lib-easy-table` / `lib-easy-table-basic`: a Material table driven by a single `EasyTableConfig` object.
|
|
18
|
+
- Typed columns (`MatColumnTyped`): text, number, date, date-time, icon, icon-and-text, button, dropdown list, image
|
|
19
|
+
(flags), password and filter columns.
|
|
20
|
+
- **Column filters** under the titles (a compact text input or a multi-select per column), global search, sorting,
|
|
21
|
+
pagination, sticky columns and a header that stays pinned while the rows scroll.
|
|
22
|
+
- Expandable rows with **child tables**, or several child tables in **tabs** (`childConfig`).
|
|
23
|
+
- `EasyDialogService`: a configurable dialog to create, edit or view a record.
|
|
24
|
+
- `lib-easy-multi-select`: a searchable multi-select with select-all, clear, read-only and compact modes, or a single-choice dropdown (`single`).
|
|
25
|
+
- Reusable interface components, each with `@Input()` / `@Output()` and a typed model: `lib-easy-segmented`,
|
|
26
|
+
`lib-easy-chip-nav`, `lib-easy-language-switch`, `lib-easy-card` / `lib-easy-card-grid`, `lib-easy-stat` and
|
|
27
|
+
`lib-easy-page-header`.
|
|
28
|
+
- `npx easy-mat-ui add-page`: generates a page from these components and a table (see [Generate a page](#generate-a-page)).
|
|
29
|
+
- **Light and dark themes** switchable at runtime (`EasyThemeService`), driven by CSS variables.
|
|
30
|
+
- Responsive layout (tables adapt below 768 px and 1024 px) and no WCAG 2 A/AA violation reported by axe-core on the demo.
|
|
31
|
+
- Shared models, enums and configuration classes exported from one entry point.
|
|
32
|
+
|
|
33
|
+
## Requirements and supported versions
|
|
34
|
+
|
|
35
|
+
This package targets **Angular 20**. Each Angular major version has its own package so that applications
|
|
36
|
+
are never forced to upgrade:
|
|
37
|
+
|
|
38
|
+
| Angular | Package | Library version |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| 20 | `easy-mat-ui-ng20` | `20.x.x` |
|
|
41
|
+
| 21 | `easy-mat-ui-ng21` | `21.x.x` (planned) |
|
|
42
|
+
|
|
43
|
+
Peer dependencies: `@angular/core`, `@angular/common`, `@angular/forms`, `@angular/cdk`,
|
|
44
|
+
`@angular/material`, `@angular/platform-browser` (all `^20.0.0`), `@ngx-translate/core` `^16`,
|
|
45
|
+
`bootstrap` `^5`, `rxjs` `^7`. Optional: `@ngx-translate/http-loader`, `flag-icons` (country columns).
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm install easy-mat-ui-ng20
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Install the peer dependencies if your project does not have them yet:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
ng add @angular/material
|
|
57
|
+
npm install @ngx-translate/core @ngx-translate/http-loader bootstrap
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The components use Material icons. `ng add @angular/material` normally takes care of it; otherwise add the
|
|
61
|
+
font to your `index.html`:
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Bundle size budget
|
|
68
|
+
|
|
69
|
+
A new Angular project fails `ng build` in production with *"bundle initial exceeded maximum budget"* once Angular Material
|
|
70
|
+
and this library are added: two components embed the Bootstrap stylesheet (a slimmer stylesheet is planned for 20.1). Raise the
|
|
71
|
+
initial budget in `angular.json` (measured: about 1.9 MB raw, 254 kB transferred, for the quick start below):
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
"budgets": [
|
|
75
|
+
{ "type": "initial", "maximumWarning": "2.5MB", "maximumError": "4MB" }
|
|
76
|
+
]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Quick start
|
|
80
|
+
|
|
81
|
+
Provide ngx-translate once in your application config:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { ApplicationConfig } from '@angular/core';
|
|
85
|
+
import { provideTranslateService } from '@ngx-translate/core';
|
|
86
|
+
|
|
87
|
+
export const appConfig: ApplicationConfig = {
|
|
88
|
+
providers: [provideTranslateService({ defaultLanguage: 'en' })]
|
|
89
|
+
};
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Use the table in a standalone component:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { Component } from '@angular/core';
|
|
96
|
+
import { EasyTableComponent, EasyTableConfig, MatColumnTyped } from 'easy-mat-ui-ng20';
|
|
97
|
+
|
|
98
|
+
@Component({
|
|
99
|
+
selector: 'app-users',
|
|
100
|
+
standalone: true,
|
|
101
|
+
imports: [EasyTableComponent],
|
|
102
|
+
template: `<lib-easy-table [config]="config"></lib-easy-table>`
|
|
103
|
+
})
|
|
104
|
+
export class UsersComponent {
|
|
105
|
+
config: Partial<EasyTableConfig> = {
|
|
106
|
+
data: [
|
|
107
|
+
{ id: 1, name: 'Alice' },
|
|
108
|
+
{ id: 2, name: 'Bob' }
|
|
109
|
+
],
|
|
110
|
+
displayedColumns: [
|
|
111
|
+
new MatColumnTyped({ name: 'id' }),
|
|
112
|
+
new MatColumnTyped({ name: 'name' })
|
|
113
|
+
],
|
|
114
|
+
canCreate: true,
|
|
115
|
+
canUpdate: true,
|
|
116
|
+
canDelete: true
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Table events are exposed as outputs: `addItem`, `editItem`, `viewItem`, `deleteItem`, `customAction`,
|
|
122
|
+
`clickField`, and more (see `EasyTableComponent`).
|
|
123
|
+
|
|
124
|
+
## Dialog example
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import { inject } from '@angular/core';
|
|
128
|
+
import { CRUD, EasyDialogService, MatColumnTyped } from 'easy-mat-ui-ng20';
|
|
129
|
+
|
|
130
|
+
const dialog = inject(EasyDialogService);
|
|
131
|
+
|
|
132
|
+
dialog.open({
|
|
133
|
+
title: 'Edit user',
|
|
134
|
+
pk: 'id',
|
|
135
|
+
action: CRUD.UPDATE,
|
|
136
|
+
data: { id: 1, name: 'Alice' },
|
|
137
|
+
fields: [
|
|
138
|
+
new MatColumnTyped({ name: 'id', order: 1 }),
|
|
139
|
+
new MatColumnTyped({ name: 'name', order: 2, isRequired: true })
|
|
140
|
+
]
|
|
141
|
+
}).afterClosed().subscribe(result => console.log(result?.event, result?.data));
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Generate a page
|
|
145
|
+
|
|
146
|
+
`easy-mat-ui add-page` writes an Angular page for you. You pick the components (page header, key figures, category
|
|
147
|
+
buttons, segmented control, language picker, card grid, and a data table with an optional child table), and it
|
|
148
|
+
generates the component, the template, the table configuration and the models.
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npx easy-mat-ui add-page # asks what it needs
|
|
152
|
+
npx easy-mat-ui add-page --name stock-items --blocks page-header,stat,table --dry-run --print
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- **Models**: an existing `*.model.ts` that matches the page name is reused. Otherwise a generic model (`item1`,
|
|
156
|
+
`item2`, `item3`) is generated, with example rows and text, icon and action columns.
|
|
157
|
+
- **Translations**: with ngx-translate the code uses translation keys, and the new entries are added to your English
|
|
158
|
+
file. Without it the texts are written in the code. Nothing is ever installed.
|
|
159
|
+
- **Prefer a screen?** The *Page builder* of the [live demo](__SITE_URL__/) does the same with a preview, and downloads
|
|
160
|
+
a description that `--config` reads. `--help` lists every option.
|
|
161
|
+
|
|
162
|
+
## Demo application
|
|
163
|
+
|
|
164
|
+
The repository contains a runnable demo in [`projects/demo`](projects/demo). It needs no backend: a mock service
|
|
165
|
+
(`GeoService`) returns Observables like a real `HttpClient` service would, so replacing it is the only change a real
|
|
166
|
+
application needs.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
git clone https://github.com/chaibiredouane/easy-mat-ui.git
|
|
170
|
+
cd easy-mat-ui
|
|
171
|
+
npm ci
|
|
172
|
+
npm start # http://localhost:4200
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
It shows what the library is for: **almost nothing to code**. Every page is four small files, in the same layout:
|
|
176
|
+
|
|
177
|
+
| File | Role |
|
|
178
|
+
|---|---|
|
|
179
|
+
| `<page>.config.ts` | The whole configuration: columns, dialog fields, table options, tabs |
|
|
180
|
+
| `<page>.html` | A few lines: `<lib-easy-table [config]="..." [childConfig]="...">` and its events |
|
|
181
|
+
| `<page>.ts` | Loads data from the service and saves the dialog results |
|
|
182
|
+
| `<page>.scss` | Page styles |
|
|
183
|
+
|
|
184
|
+
Three pages, built on every country of the world (Algeria first) and their cities:
|
|
185
|
+
|
|
186
|
+
1. **Countries and their cities**: expandable rows; the child table is loaded when a row opens.
|
|
187
|
+
2. **Child tables in tabs**: `childConfig` as an array, one tab per configuration.
|
|
188
|
+
3. **Cities of any country**: one full table with header filters, flags, status icons and a complete
|
|
189
|
+
add / edit / view / delete dialog.
|
|
190
|
+
|
|
191
|
+
Each page has a *Show the code of this page* panel with its real source files, and the header has a
|
|
192
|
+
Light / Dark / System theme switcher.
|
|
193
|
+
|
|
194
|
+
Key points of the configuration:
|
|
195
|
+
|
|
196
|
+
- `childConfig` takes one configuration, or an array to get tabs (`tabTitle`, `tabIcon`).
|
|
197
|
+
- `isExpanded: true` on the parent adds the expand button; `extendRow` tells you which row opened.
|
|
198
|
+
- `sortedBy: ''` keeps the order given by your service (the default sorts by text).
|
|
199
|
+
- Rebuild a table configuration (a new `EasyTableConfig`) whenever its data changes.
|
|
200
|
+
|
|
201
|
+
The demo data lives under `projects/demo/src/app/data` and is **not** part of the npm package. Countries and cities
|
|
202
|
+
come from [GeoNames](https://www.geonames.org/) (CC BY 4.0), the administrative divisions of Algeria from Wikipedia
|
|
203
|
+
(CC BY-SA 4.0): see `DATA-LICENSE.md` and `WORLD-DATA-SOURCES.md` in that folder. Populations are source values of varying
|
|
204
|
+
years, not a census.
|
|
205
|
+
|
|
206
|
+
## Themes
|
|
207
|
+
|
|
208
|
+
Light and dark themes are driven by CSS variables (`--text-color`, `--card-bg`, `--border-color`,
|
|
209
|
+
`--color-primary-blue`, `--radius-md`, `--shadow-md`, ...), so an application can override them without touching the
|
|
210
|
+
library. `EasyThemeService` switches theme at runtime, without reloading the page:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import { inject } from '@angular/core';
|
|
214
|
+
import { EasyThemeService } from 'easy-mat-ui-ng20';
|
|
215
|
+
|
|
216
|
+
const theme = inject(EasyThemeService);
|
|
217
|
+
theme.setTheme('dark'); // 'light' | 'dark' | 'system' (follows the operating system, live)
|
|
218
|
+
theme.toggle();
|
|
219
|
+
theme.theme(); // the applied theme, as a signal
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The service does nothing until you call it, never stores anything unless you give it a `storageKey`
|
|
223
|
+
(`EASY_THEME_OPTIONS`), and only adds the `dark-theme` class to `<body>` (the class the library stylesheet already
|
|
224
|
+
used) and a `data-easy-theme` attribute on `<html>`. Applications that toggle `dark-theme` themselves keep working.
|
|
225
|
+
Material components follow when your Angular Material theme uses `color-scheme` (for example `mat.theme`).
|
|
226
|
+
|
|
227
|
+
## Responsive and accessibility
|
|
228
|
+
|
|
229
|
+
Below 768 px, tables size their columns to their content and scroll horizontally, and the sticky actions column shrinks
|
|
230
|
+
to its buttons so the data stays visible. The demo is checked at 320, 375, 430, 768, 1024, 1440 and 1920 px in both
|
|
231
|
+
themes (no horizontal overflow, no console error) and with axe-core (no WCAG 2 A/AA violation on the demo pages).
|
|
232
|
+
|
|
233
|
+
## Styles
|
|
234
|
+
|
|
235
|
+
Components embed their own styles. To also get the shared classes (`green`, `red`, `taupe`, `bg-*`,
|
|
236
|
+
spacing and Material overrides), add the stylesheet to the `styles` array of your `angular.json`:
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
"styles": [
|
|
240
|
+
"node_modules/easy-mat-ui-ng20/styles/styles.scss",
|
|
241
|
+
"node_modules/flag-icons/css/flag-icons.min.css"
|
|
242
|
+
]
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
`flag-icons` is only needed for flag columns (`ColumnType.IMAGE` with a country code such as `fr`); its stylesheet is not bundled with the components.
|
|
246
|
+
|
|
247
|
+
> **Troubleshooting:** with the Angular `application` builder, the `flag-icons` stylesheet can fail in
|
|
248
|
+
> development with `Two output files share the same path but have different contents: media/xx.svg`.
|
|
249
|
+
> Set `"outputHashing": "media"` in the `development` configuration of the `build` target of your
|
|
250
|
+
> `angular.json`.
|
|
251
|
+
|
|
252
|
+
## Versioning
|
|
253
|
+
|
|
254
|
+
The first number of the library version is the supported Angular major version (`20.x.x` supports
|
|
255
|
+
Angular 20). The remaining numbers follow [Semantic Versioning](https://semver.org/):
|
|
256
|
+
PATCH for bug fixes, MINOR for backward-compatible features, MAJOR for breaking changes within the
|
|
257
|
+
same Angular line. See [CHANGELOG.md](CHANGELOG.md).
|
|
258
|
+
|
|
259
|
+
## Development
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
npm ci
|
|
263
|
+
npm start # runs the demo application
|
|
264
|
+
npm run build # builds the library into dist/easy-mat-ui
|
|
265
|
+
npm test # runs the unit tests (headless Chrome)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Contributing
|
|
269
|
+
|
|
270
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) and the
|
|
271
|
+
[Code of Conduct](CODE_OF_CONDUCT.md). Report vulnerabilities as described in [SECURITY.md](SECURITY.md).
|
|
272
|
+
|
|
273
|
+
## License
|
|
274
|
+
|
|
275
|
+
[MIT](LICENSE)
|