@nexterajs/ui 0.0.2 → 0.1.0
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 +279 -34
- package/fesm2022/nexterajs-ui-charts.mjs +1096 -0
- package/fesm2022/nexterajs-ui-charts.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-core.mjs +652 -12
- package/fesm2022/nexterajs-ui-core.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-display.mjs +1142 -0
- package/fesm2022/nexterajs-ui-display.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-dropdowns.mjs +321 -33
- package/fesm2022/nexterajs-ui-dropdowns.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-file-uploader.mjs +572 -10
- package/fesm2022/nexterajs-ui-file-uploader.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-forms.mjs +2027 -136
- package/fesm2022/nexterajs-ui-forms.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-grid.mjs +1222 -188
- package/fesm2022/nexterajs-ui-grid.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-intl.mjs +103 -11
- package/fesm2022/nexterajs-ui-intl.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-navigation.mjs +1054 -0
- package/fesm2022/nexterajs-ui-navigation.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-notify.mjs +46 -44
- package/fesm2022/nexterajs-ui-notify.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-overlay.mjs +1671 -0
- package/fesm2022/nexterajs-ui-overlay.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-pivot.mjs +51 -26
- package/fesm2022/nexterajs-ui-pivot.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-shell.mjs +542 -0
- package/fesm2022/nexterajs-ui-shell.mjs.map +1 -0
- package/fesm2022/nexterajs-ui-tree-view.mjs +5 -2
- package/fesm2022/nexterajs-ui-tree-view.mjs.map +1 -1
- package/fesm2022/nexterajs-ui-validation.mjs +42 -11
- package/fesm2022/nexterajs-ui-validation.mjs.map +1 -1
- package/fesm2022/nexterajs-ui.mjs +5 -0
- package/fesm2022/nexterajs-ui.mjs.map +1 -1
- package/package.json +33 -2
- package/styles/_dropdown.scss +5 -5
- package/styles/_editor.scss +52 -17
- package/styles/_mixins.scss +1 -1
- package/styles/_scrollbar.scss +5 -5
- package/styles/_status.scss +21 -0
- package/styles/_toast.scss +14 -14
- package/styles/_tokens.scss +420 -3
- package/styles/_widget.scss +14 -3
- package/styles/index.scss +6 -4
- package/types/nexterajs-ui-charts.d.ts +446 -0
- package/types/nexterajs-ui-core.d.ts +387 -22
- package/types/nexterajs-ui-display.d.ts +720 -0
- package/types/nexterajs-ui-dropdowns.d.ts +191 -48
- package/types/nexterajs-ui-file-uploader.d.ts +236 -7
- package/types/nexterajs-ui-forms.d.ts +675 -30
- package/types/nexterajs-ui-grid.d.ts +448 -93
- package/types/nexterajs-ui-intl.d.ts +39 -4
- package/types/nexterajs-ui-navigation.d.ts +531 -0
- package/types/nexterajs-ui-notify.d.ts +4 -2
- package/types/nexterajs-ui-overlay.d.ts +703 -0
- package/types/nexterajs-ui-pivot.d.ts +56 -48
- package/types/nexterajs-ui-shell.d.ts +294 -0
- package/types/nexterajs-ui-tree-view.d.ts +6 -3
- package/types/nexterajs-ui-validation.d.ts +20 -11
- package/types/nexterajs-ui.d.ts +5 -0
package/README.md
CHANGED
|
@@ -1,64 +1,309 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @nexterajs/ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An Angular 22 component library that replaces DevExtreme: data grid and tree list, pivot grid, editors and pickers,
|
|
4
|
+
dialogs, menus, tabs, an app shell, toasts, and a zero-dependency XLSX writer and reader. Every component is standalone,
|
|
5
|
+
signal-based and OnPush, and every colour, size and string can be changed by the application: colours through
|
|
6
|
+
`--nxe-ui-*` CSS custom properties, strings through a runtime-switchable message bundle (English and Indonesian ship).
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
The package is split into 18 secondary entry points, so an application only bundles what it imports.
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
## Install
|
|
8
11
|
|
|
9
12
|
```bash
|
|
10
|
-
|
|
13
|
+
npm install @nexterajs/ui @angular/cdk @angular/animations luxon
|
|
11
14
|
```
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
| Peer dependency | Version | Needed for |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `@angular/core`, `@angular/common`, `@angular/forms` | `^22.0.0` | everything |
|
|
19
|
+
| `@angular/cdk` | `^22.0.0` | overlays, dialogs, menus, focus traps |
|
|
20
|
+
| `@angular/animations` | `^22.0.0` | shared animation definitions |
|
|
21
|
+
| `luxon` | `^3.0.0` | date box, calendar, date formats |
|
|
22
|
+
| `rxjs` | `^7.8.0` | everything |
|
|
23
|
+
| `@angular/router` | `^22.0.0`, **optional** | `@nexterajs/ui/shell` and `@nexterajs/ui/navigation` |
|
|
14
24
|
|
|
15
|
-
|
|
16
|
-
|
|
25
|
+
`@angular/router` is optional: an application that never imports the shell or navigation entry points does not need
|
|
26
|
+
it. The package root re-exports every entry point, so an application that imports from the bare `@nexterajs/ui` does
|
|
27
|
+
need it installed.
|
|
28
|
+
|
|
29
|
+
## Register the styles
|
|
30
|
+
|
|
31
|
+
Component look and feel is encapsulated in each component; what has to be global ships as one SCSS bundle,
|
|
32
|
+
`@nexterajs/ui/styles` (`styles/index.scss`). Register it **last** in `angular.json`, under
|
|
33
|
+
`projects.<app>.architect.build.options.styles` (and under `test` if your tests render components):
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
"styles": [
|
|
37
|
+
"src/styles.scss",
|
|
38
|
+
"node_modules/@nexterajs/ui/styles/index.scss"
|
|
39
|
+
]
|
|
17
40
|
```
|
|
18
41
|
|
|
19
|
-
|
|
42
|
+
That is all a DevExtreme-era application needs: the bundle and the component sheets carry dx.light's look themselves
|
|
43
|
+
(the widget base and its `#333` text, the grid's structure, cell padding and header, the editor and dropdown chrome), so
|
|
44
|
+
a copy of `dx.light.css` or an extract of it (`dx-compat.css`) can be deleted. Where an app skinned DevExtreme, it sets
|
|
45
|
+
tokens (see Theming) instead of restating selectors. From SCSS, `@use '@nexterajs/ui/styles';` loads the same bundle.
|
|
20
46
|
|
|
21
|
-
|
|
47
|
+
Two optional sheets stay outside the bundle, because each is a port of a third-party stylesheet whose overrides depend on
|
|
48
|
+
load order:
|
|
22
49
|
|
|
23
|
-
|
|
24
|
-
|
|
50
|
+
| File | Required | Holds | Where in the list |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| `styles/index.scss` | always | design tokens, widget base, grid structure, editor and dropdown chrome, icons, drag and badge rules | **last** |
|
|
53
|
+
| `styles/_toast.scss` | if you use `NxeToastService` (`@nexterajs/ui/notify`) | toast container, positions, colours, progress bar | **before** your own stylesheet |
|
|
54
|
+
| `styles/_scrollbar.scss` | only if you use `[nxeScrollbar]` (`@nexterajs/ui/styling`) | hides the native bar, draws the rails | **before** your own stylesheet |
|
|
55
|
+
|
|
56
|
+
**The bundle does not include the toast or scrollbar chrome.** Without `_toast.scss` toasts render with no fixed
|
|
57
|
+
container, position or colours; without `_scrollbar.scss` an `[nxeScrollbar]` element keeps its native scrollbar and
|
|
58
|
+
the rails the directive adds are unstyled. Each file is a value-for-value port of the stylesheet it replaces
|
|
59
|
+
(ngx-toastr's `toastr.css`, `perfect-scrollbar.css`), so register it where that stylesheet used to sit: before your own
|
|
60
|
+
stylesheet, so your overrides of the toast or rail rules (a `width` on `.toast-top-center`) still win on order.
|
|
61
|
+
|
|
62
|
+
`index.scss` goes last so its component chrome lands above any reset you ship. Your token overrides do not depend on
|
|
63
|
+
order (see Theming): the library declares its tokens at `:where(:root)`, which has zero specificity, so a plain
|
|
64
|
+
`:root { }` block in `src/styles.scss` (or any app token file) wins wherever it sits in the list. The toast and
|
|
65
|
+
scrollbar files read the same tokens, with fallbacks, so they need nothing else.
|
|
66
|
+
|
|
67
|
+
## Use a component
|
|
68
|
+
|
|
69
|
+
Import the standalone component from its entry point:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { Component, signal } from '@angular/core';
|
|
73
|
+
import { NxeButtonComponent, NxeTextBoxComponent } from '@nexterajs/ui/forms';
|
|
74
|
+
import { NxeColumnComponent, NxeDataGridComponent } from '@nexterajs/ui/grid';
|
|
75
|
+
|
|
76
|
+
@Component({
|
|
77
|
+
selector: 'app-orders',
|
|
78
|
+
imports: [NxeButtonComponent, NxeTextBoxComponent, NxeDataGridComponent, NxeColumnComponent],
|
|
79
|
+
template: `
|
|
80
|
+
<nxe-text-box [(value)]="search" placeholder="Search" />
|
|
81
|
+
<nxe-data-grid [dataSource]="orders()">
|
|
82
|
+
<nxe-column dataField="poNumber" caption="PO" />
|
|
83
|
+
<nxe-column dataField="total" caption="Total" dataType="number" />
|
|
84
|
+
</nxe-data-grid>
|
|
85
|
+
<nxe-button type="default" text="Save" (onClick)="save()" />
|
|
86
|
+
`,
|
|
87
|
+
})
|
|
88
|
+
export class OrdersComponent {
|
|
89
|
+
readonly search = signal('');
|
|
90
|
+
readonly orders = signal<Order[]>([]);
|
|
91
|
+
save(): void { /* … */ }
|
|
92
|
+
}
|
|
25
93
|
```
|
|
26
94
|
|
|
27
|
-
|
|
95
|
+
Prefer a specific entry point over the bare `@nexterajs/ui`: it keeps the pivot engine and the XLSX writer out of your
|
|
96
|
+
bundle and out of your dev-server rebuilds.
|
|
28
97
|
|
|
29
|
-
|
|
98
|
+
## Theming
|
|
30
99
|
|
|
31
|
-
|
|
100
|
+
Override `--nxe-ui-*` custom properties from your own `:root`. No build step, no `!important`. The defaults reproduce
|
|
101
|
+
DevExtreme's dx.light, so setting nothing changes nothing.
|
|
32
102
|
|
|
33
|
-
|
|
103
|
+
```scss
|
|
104
|
+
// src/styles.scss (or an app token file it uses)
|
|
105
|
+
:root {
|
|
106
|
+
--nxe-ui-font-size: 13px;
|
|
107
|
+
--nxe-ui-accent: #005caa; // primary buttons, focus, selection
|
|
108
|
+
--nxe-ui-button-hover-bg-primary: #004d8f; // hover and pressed shades are literals:
|
|
109
|
+
--nxe-ui-button-active-bg-primary: #003d72; // set them whenever you set the fill
|
|
110
|
+
--nxe-ui-button-focus-ring: var(--nxe-ui-focus-ring); // opt in to a visible keyboard focus ring
|
|
111
|
+
}
|
|
34
112
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
113
|
+
// Dark theme: the library switches its values under a `.dark` class (on <html> or any ancestor).
|
|
114
|
+
// Restate every token you overrode, or the library's own dark value replaces yours.
|
|
115
|
+
:root.dark {
|
|
116
|
+
--nxe-ui-accent: #4da3e8;
|
|
117
|
+
--nxe-ui-button-hover-bg-primary: #7ab9e8;
|
|
118
|
+
--nxe-ui-button-active-bg-primary: #9acbee;
|
|
119
|
+
}
|
|
120
|
+
```
|
|
38
121
|
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
npm publish
|
|
42
|
-
```
|
|
122
|
+
What to know before you theme:
|
|
43
123
|
|
|
44
|
-
|
|
124
|
+
- **Your `:root` beats the library, in any order.** The library's light defaults are declared at `:where(:root)` and
|
|
125
|
+
its dark values at `:where(.dark)`, both zero specificity.
|
|
126
|
+
- **Restate overrides under `:root.dark`.** A token you set only in `:root` is replaced by the library's dark value as
|
|
127
|
+
soon as `.dark` is on.
|
|
128
|
+
- **Set button hover and active shades explicitly.** `--nxe-ui-button-bg-{primary,success,danger}` follow
|
|
129
|
+
`--nxe-ui-accent`, `--nxe-ui-success` and `--nxe-ui-danger`, but `--nxe-ui-button-hover-bg-*` and
|
|
130
|
+
`--nxe-ui-button-active-bg-*` are fixed colours (dx's shades are not a constant mix), so a new fill keeps the old
|
|
131
|
+
hover and pressed colours until you set them too.
|
|
132
|
+
- **Buttons draw no focus ring by default**, as in DevExtreme. Opt in with
|
|
133
|
+
`--nxe-ui-button-focus-ring: var(--nxe-ui-focus-ring)` (or any `box-shadow` value). Do: a keyboard user otherwise
|
|
134
|
+
cannot see which button has focus.
|
|
135
|
+
- **Accessibility: override the stock danger and success buttons.** The default danger button is white text on
|
|
136
|
+
`#d9534f`, 3.96:1, which fails WCAG AA (4.5:1) for button-sized text; the default success button (white on `#5cb85c`)
|
|
137
|
+
is 2.48:1. For example:
|
|
45
138
|
|
|
46
|
-
|
|
139
|
+
```scss
|
|
140
|
+
:root {
|
|
141
|
+
--nxe-ui-button-bg-danger: #b4322a; // 6.1:1 with white
|
|
142
|
+
--nxe-ui-button-hover-bg-danger: #9a2a23;
|
|
143
|
+
--nxe-ui-button-active-bg-danger: #7a211b;
|
|
144
|
+
}
|
|
145
|
+
```
|
|
47
146
|
|
|
48
|
-
|
|
49
|
-
|
|
147
|
+
Do the same for `--nxe-ui-button-bg-success` and its hover and active tokens, and restate them under `:root.dark`.
|
|
148
|
+
- A `nxe-density-compact` class on an ancestor tightens control heights and padding.
|
|
149
|
+
|
|
150
|
+
- **Skin the grid with tokens, not cell selectors.** `--nxe-ui-grid-cell-padding` (dx's 7px),
|
|
151
|
+
`--nxe-ui-grid-cell-vertical-align` (middle), `--nxe-ui-grid-edge-padding` (the first and last cell's outer side),
|
|
152
|
+
`--nxe-ui-grid-header-bg` and `--nxe-ui-grid-header-color` (the caption row), and `--nxe-ui-grid-indicator-scale` /
|
|
153
|
+
`--nxe-ui-grid-indicator-offset` (the sort and filter marks). Set them at `:root`, or on a subtree such as
|
|
154
|
+
`nxe-tree-list` or a card, and they reach every grid inside. The cell rules carry zero specificity, so an existing
|
|
155
|
+
app rule still wins while you move it to a token.
|
|
156
|
+
|
|
157
|
+
The full list of tokens (193, in 22 groups) with light defaults, dark values and what each one colours is in
|
|
158
|
+
`docs/TOKENS.md` in the nextera-library repository. It is generated from `styles/_tokens.scss`, which ships in this
|
|
159
|
+
package (`node_modules/@nexterajs/ui/styles/_tokens.scss`) and carries the same list with a comment on each token.
|
|
160
|
+
|
|
161
|
+
## Internationalisation
|
|
162
|
+
|
|
163
|
+
Every string the library renders itself (pager, no-data text, filter operators, calendar, validation, uploader, pivot
|
|
164
|
+
captions, shell and dialog labels) comes from `NxeMessageService` in `@nexterajs/ui/core`. English is the default and
|
|
165
|
+
Indonesian (`id`) ships; switching the language re-renders live components in place.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { provideNxeMessages } from '@nexterajs/ui/core';
|
|
169
|
+
|
|
170
|
+
bootstrapApplication(App, {
|
|
171
|
+
providers: [
|
|
172
|
+
provideNxeMessages({
|
|
173
|
+
locale: 'id', // 'en' (default) or 'id'; 'id-ID' picks 'id'
|
|
174
|
+
overrides: { 'grid.noData': 'Belum ada data' }, // kept across language switches
|
|
175
|
+
separators: true, // 1.234,5 under id, 1,234.5 under en
|
|
176
|
+
}),
|
|
177
|
+
],
|
|
178
|
+
});
|
|
50
179
|
```
|
|
51
180
|
|
|
52
|
-
|
|
181
|
+
```ts
|
|
182
|
+
import { inject } from '@angular/core';
|
|
183
|
+
import { NxeMessageService } from '@nexterajs/ui/core';
|
|
53
184
|
|
|
54
|
-
|
|
185
|
+
const messages = inject(NxeMessageService);
|
|
186
|
+
messages.use('en'); // switch at runtime
|
|
187
|
+
messages.use({ 'common.cancel': 'Annuler' }, 'fr'); // an ad hoc bundle under a locale
|
|
188
|
+
messages.override({ 'grid.pager.info': 'Hal. {0}/{1}' });
|
|
189
|
+
```
|
|
55
190
|
|
|
56
|
-
|
|
57
|
-
|
|
191
|
+
`provideNxeMessages` also takes `bundles` (more languages; a partial bundle falls back to English) and `luxon` (default
|
|
192
|
+
`true`: Luxon's default locale follows the language, so month and weekday names do too). A component input such as
|
|
193
|
+
`noDataText` always wins over the bundle. To follow an app-owned language service such as Transloco, subscribe to its
|
|
194
|
+
language stream with `takeUntilDestroyed()` and call `messages.use(lang)`. Form-field error messages are set with
|
|
195
|
+
`provideNxeErrorMessages` from `@nexterajs/ui/forms`.
|
|
196
|
+
|
|
197
|
+
## Entry points
|
|
198
|
+
|
|
199
|
+
| Entry point | Holds |
|
|
200
|
+
|---|---|
|
|
201
|
+
| `@nexterajs/ui/core` | Message service and bundles, default-options token, form-control and config-option base classes, `nxeTemplate` |
|
|
202
|
+
| `@nexterajs/ui/forms` | Button, text box, text area, number box, date box, check box, radio group, switch, OTP box, form field, scroll view |
|
|
203
|
+
| `@nexterajs/ui/dropdowns` | Select box, tag box, drop-down box, list, autocomplete |
|
|
204
|
+
| `@nexterajs/ui/grid` | Data grid and tree list, filter row, header filters, grouping, summaries, master-detail, remote data source, paginator, Excel export |
|
|
205
|
+
| `@nexterajs/ui/pivot` | Pivot grid, its data source, field panel and chooser, chart binding, Excel export |
|
|
206
|
+
| `@nexterajs/ui/display` | Tag, badge, spinner, skeleton, empty state, card, description list |
|
|
207
|
+
| `@nexterajs/ui/charts` | Line, area and donut charts: SVG, light and dark palette tokens, legend, tooltip, data table alternative |
|
|
208
|
+
| `@nexterajs/ui/overlay` | Dialog service, confirmation service, menu |
|
|
209
|
+
| `@nexterajs/ui/navigation` | Tabs, with a router mode (needs `@angular/router`) |
|
|
210
|
+
| `@nexterajs/ui/shell` | App shell, side navigation, top bar (needs `@angular/router`) |
|
|
211
|
+
| `@nexterajs/ui/notify` | Toast service and toast component (register `styles/_toast.scss`) |
|
|
212
|
+
| `@nexterajs/ui/tree-view` | Tree view |
|
|
213
|
+
| `@nexterajs/ui/file-uploader` | File uploader |
|
|
214
|
+
| `@nexterajs/ui/validation` | Validator, validation rules and group, rule evaluators |
|
|
215
|
+
| `@nexterajs/ui/intl` | Date and number format engines, number separator tokens |
|
|
216
|
+
| `@nexterajs/ui/excel` | Zero-dependency XLSX writer and reader, zip, `nxeSaveAs` |
|
|
217
|
+
| `@nexterajs/ui/styling` | Overlay pane helper, `[nxeScrollbar]` (register `styles/_scrollbar.scss`), DevExtreme class-name compatibility |
|
|
218
|
+
| `@nexterajs/ui/animations` | Shared animation definitions |
|
|
219
|
+
|
|
220
|
+
## Component index
|
|
221
|
+
|
|
222
|
+
Names only. Inputs, outputs, keyboard behaviour and examples are in the full documentation: the `README.md` at the root
|
|
223
|
+
of the nextera-library repository.
|
|
224
|
+
|
|
225
|
+
- **core**: `NxeMessageService`, `provideNxeMessages`, `NXE_MESSAGES_EN`, `NXE_MESSAGES_ID`, `NXE_DEFAULT_OPTIONS`,
|
|
226
|
+
`NxeFormControlBase`, `NxeConfigOptionBase`, `[nxeTemplate]`
|
|
227
|
+
- **forms**: `nxe-button`, `nxe-text-box`, `nxe-text-area`, `nxe-number-box`, `nxe-date-box`, `nxe-check-box`,
|
|
228
|
+
`nxe-radio-group`, `nxe-switch`, `nxe-otp-box`, `nxe-form-field`, `nxe-scroll-view`, `provideNxeErrorMessages`
|
|
229
|
+
- **dropdowns**: `nxe-select-box`, `nxe-tag-box`, `nxe-drop-down-box`, `nxe-list`, `nxe-autocomplete` (with
|
|
230
|
+
`[nxeAutocomplete]` and `nxe-option`), `nxe-auto-complete`
|
|
231
|
+
- **grid**: `nxe-data-grid`, `nxe-tree-list`, `nxe-column`, `nxe-selection`, `nxe-paging`, `nxe-pager`,
|
|
232
|
+
`nxe-filter-row`, `nxe-header-filter`, `nxe-grouping`, `nxe-group-panel`, `nxe-summary`, `nxe-editing`,
|
|
233
|
+
`nxe-master-detail`, `nxe-scrolling`, `nxe-paginator`, `NxeRemoteDataSource`, `nxeFlattenFilter`, `nxeFilterAnd`,
|
|
234
|
+
`nxeFilterOr`, `exportDataGrid`, `exportNxeGridToExcel`
|
|
235
|
+
- **pivot**: `nxe-pivot-grid`, `NxePivotDataSource`, `nxe-pivot-field-panel`, `nxe-pivot-field-chooser`, `nxe-chart`,
|
|
236
|
+
`NxeExcelExportService`
|
|
237
|
+
- **display**: `nxe-tag`, `nxe-badge` (with `[nxeBadgeAnchor]`), `nxe-spinner`, `nxe-skeleton`, `nxe-empty-state`,
|
|
238
|
+
`nxe-card`, `nxe-description-list`, `nxe-description-item`
|
|
239
|
+
- **overlay**: `NxeDialogService`, `NxeDialogRef`, `NxeConfirmService`, `[nxe-dialog-title]`, `[nxe-dialog-content]`,
|
|
240
|
+
`[nxe-dialog-actions]`, `nxe-menu`, `[nxeMenuTriggerFor]`, `nxe-menu-item` / `[nxe-menu-item]`, `nxe-menu-divider`
|
|
241
|
+
- **navigation**: `nxe-tabs`, `nxe-tab`, `ng-template[nxeTabContent]`
|
|
242
|
+
- **shell**: `nxe-shell`, `nxe-sidenav`, `nxe-topbar`, `ng-template[nxeSidenavIcon]`
|
|
243
|
+
- **notify**: `NxeToastService`, `provideNxeToast`, `nxe-toast`
|
|
244
|
+
- **tree-view**: `nxe-tree-view`
|
|
245
|
+
- **file-uploader**: `nxe-file-uploader`
|
|
246
|
+
- **validation**: `nxe-validator`, `nxe-validation-rule`, `nxe-validation-group`, `NxeValidators`
|
|
247
|
+
- **intl**: `formatNumber`, `parseNumber`, `formatDisplay`, `parseDisplay`, `NXE_NUMBER_SEPARATORS`,
|
|
248
|
+
`NXE_ID_SEPARATORS`
|
|
249
|
+
- **excel**: `NxeWorkbook`, `NxeWorksheet`, `readXlsxFirstSheet`, `nxeSaveAs`
|
|
250
|
+
- **styling**: `[nxeScrollbar]`, `nxePane`, `provideNxeDxCompat`
|
|
251
|
+
- **animations**: `nxeAnimations`, `NxeAnimationCurves`, `NxeAnimationDurations`
|
|
252
|
+
|
|
253
|
+
## Consuming a local build (`file:` or `npm link`)
|
|
254
|
+
|
|
255
|
+
To try an unreleased build, point the application at the built package (`npm run build:ui` in the library repository
|
|
256
|
+
writes `dist/nextera-ui`):
|
|
257
|
+
|
|
258
|
+
```json
|
|
259
|
+
"dependencies": { "@nexterajs/ui": "file:../nextera-library/dist/nextera-ui" }
|
|
58
260
|
```
|
|
59
261
|
|
|
60
|
-
|
|
262
|
+
npm installs a `file:` directory dependency (and `npm link`) as a symlink. Followed to its real path, the library
|
|
263
|
+
resolves `@angular/core` from the library repository's own `node_modules`, so the application ends up with two copies
|
|
264
|
+
of Angular: `NG0203` (`inject()` called outside an injection context) at runtime, or `INPUT_SIGNAL_BRAND` type errors
|
|
265
|
+
in the editor. Three settings keep the library on the application's copy:
|
|
266
|
+
|
|
267
|
+
1. `angular.json`, the build target's options:
|
|
268
|
+
|
|
269
|
+
```json
|
|
270
|
+
"build": { "options": { "preserveSymlinks": true } }
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
2. `tsconfig.json`, `compilerOptions`:
|
|
274
|
+
|
|
275
|
+
```json
|
|
276
|
+
"preserveSymlinks": true
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
3. Unit tests with `@angular/build:unit-test` (Vitest). Vitest loads dependencies with Node's own resolver, which
|
|
280
|
+
follows the symlink regardless, so inline the package to route its imports through Vite. Turn on the runner config
|
|
281
|
+
in `angular.json`:
|
|
282
|
+
|
|
283
|
+
```json
|
|
284
|
+
"test": { "builder": "@angular/build:unit-test", "options": { "runnerConfig": true } }
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
and add `vitest-base.config.mjs` next to `angular.json` (the file `runnerConfig: true` looks for):
|
|
288
|
+
|
|
289
|
+
```js
|
|
290
|
+
import { defineConfig } from 'vitest/config';
|
|
291
|
+
|
|
292
|
+
export default defineConfig({
|
|
293
|
+
test: {
|
|
294
|
+
server: { deps: { inline: [/@nexterajs\/ui/] } },
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Remove all three when you switch back to a published version.
|
|
300
|
+
|
|
301
|
+
## Browser support
|
|
302
|
+
|
|
303
|
+
The browsers Angular 22 supports. The stylesheets use `color-mix()`, `:where()`, `:has()`, container queries and
|
|
304
|
+
`dvh` units, which puts the floor at Chrome and Edge 111, Firefox 121 and Safari 16.4. Internet Explorer and legacy
|
|
305
|
+
Edge are not supported.
|
|
61
306
|
|
|
62
|
-
##
|
|
307
|
+
## License
|
|
63
308
|
|
|
64
|
-
|
|
309
|
+
Apache-2.0. See `LICENSE` and `NOTICE` in this package.
|