@acontplus/ng-components 3.1.0 → 3.2.1
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 +101 -234
- package/fesm2022/acontplus-ng-components.mjs +1151 -132
- package/fesm2022/acontplus-ng-components.mjs.map +1 -1
- package/package.json +1 -1
- package/src/lib/components/button/v2/button.scss +8 -0
- package/src/lib/components/date-range-input/date-range-input.scss +1 -6
- package/src/lib/components/dialog/acp-dialog-container.scss +140 -0
- package/src/lib/components/dialog-wrapper/dialog-wrapper.scss +0 -4
- package/types/acontplus-ng-components.d.ts +688 -49
package/README.md
CHANGED
|
@@ -104,281 +104,148 @@ export class ProductComponent {}
|
|
|
104
104
|
|
|
105
105
|
### Buttons
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
> **The legacy `Button` component is deprecated.** New code should import and
|
|
108
|
+
> use `AcpButton` (v2) instead. The legacy `Button` will be removed in a future
|
|
109
|
+
> major release.
|
|
108
110
|
|
|
109
|
-
|
|
111
|
+
#### AcpButton (v2)
|
|
112
|
+
|
|
113
|
+
Current button implementation with `input()` signals, loading state, form
|
|
114
|
+
association and full Material Design variants.
|
|
110
115
|
|
|
111
116
|
```typescript
|
|
112
|
-
import {
|
|
117
|
+
import { AcpButton } from '@acontplus/ng-components';
|
|
113
118
|
|
|
114
119
|
@Component({
|
|
115
|
-
template: `
|
|
116
|
-
|
|
117
|
-
<acp-button
|
|
118
|
-
[variant]="'primary'"
|
|
119
|
-
[text]="'Save'"
|
|
120
|
-
[icon]="'save'"
|
|
121
|
-
[matStyle]="'elevated'"
|
|
122
|
-
[disabled]="false"
|
|
123
|
-
(handleClick)="onSave()"
|
|
124
|
-
/>
|
|
125
|
-
|
|
126
|
-
<!-- Report button with automatic icon, color, and title -->
|
|
127
|
-
<acp-button
|
|
128
|
-
[reportFormat]="REPORT_FORMAT.PDF"
|
|
129
|
-
[text]="'Export Report'"
|
|
130
|
-
[title]="'Download'"
|
|
131
|
-
(handleClick)="exportReport($event)"
|
|
132
|
-
/>
|
|
133
|
-
<!-- Automatically shows PDF icon, danger color, and title "Download - PDF" -->
|
|
134
|
-
|
|
135
|
-
<!-- Report button with format-only (no explicit text) -->
|
|
136
|
-
<acp-button [reportFormat]="REPORT_FORMAT.EXCEL" (handleClick)="exportExcel()" />
|
|
137
|
-
<!-- Shows Excel icon, success color, and "Excel" as title -->
|
|
138
|
-
`,
|
|
139
|
-
imports: [Button],
|
|
120
|
+
template: ` <acp-button text="Save" color="success" (clicked)="save()" /> `,
|
|
121
|
+
imports: [AcpButton],
|
|
140
122
|
})
|
|
141
|
-
export class
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
exportReport() {
|
|
145
|
-
console.log('Exporting PDF report...');
|
|
123
|
+
export class SaveComponent {
|
|
124
|
+
save() {
|
|
125
|
+
// handle click
|
|
146
126
|
}
|
|
147
127
|
}
|
|
148
128
|
```
|
|
149
129
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
The Button component includes optional built-in support for report/export buttons with automatic styling:
|
|
153
|
-
|
|
154
|
-
**Available Report Formats:**
|
|
155
|
-
|
|
156
|
-
- `REPORT_FORMAT.PDF` - Red/danger color, PDF icon
|
|
157
|
-
- `REPORT_FORMAT.EXCEL` - Green/success color, table icon
|
|
158
|
-
- `REPORT_FORMAT.WORD` - Blue/primary color, document icon
|
|
159
|
-
- `REPORT_FORMAT.CSV` - Green/success color, grid icon
|
|
160
|
-
- `REPORT_FORMAT.XML` - Orange/warning color, code icon
|
|
161
|
-
- `REPORT_FORMAT.IMAGE` - Blue/info color, image icon
|
|
162
|
-
- `REPORT_FORMAT.HTML` - Blue/info color, HTML icon
|
|
163
|
-
- `REPORT_FORMAT.MHTML` - Gray/secondary color, web icon
|
|
130
|
+
### AcpDialog
|
|
164
131
|
|
|
165
|
-
|
|
132
|
+
Reusable, strongly-typed dialog service built on Angular Material. Every dialog
|
|
133
|
+
renders inside `AcpDialogContainer`, so content components always read data with
|
|
134
|
+
`inject(ACP_DIALOG_DATA)` and close with `inject(AcpDialogRef<R>)`.
|
|
166
135
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
- **Auto Title**: Appends format name to tooltip (e.g., "Export - PDF")
|
|
170
|
-
- **Optional**: All report features are completely optional
|
|
171
|
-
- **Overridable**: Explicit `icon`, `variant`, or `title` inputs take precedence
|
|
136
|
+
The service is `AcpDialogService`; `acp-dialog` is the declarative layout
|
|
137
|
+
wrapper used inside content components.
|
|
172
138
|
|
|
173
|
-
|
|
139
|
+
#### Imperative usage
|
|
174
140
|
|
|
175
141
|
```typescript
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
[reportFormat]="REPORT_FORMAT.WORD"
|
|
194
|
-
[icon]="'download'"
|
|
195
|
-
[text]="'Get Document'"
|
|
196
|
-
/>
|
|
197
|
-
// Result: Custom download icon, primary color (from Word format)
|
|
198
|
-
|
|
199
|
-
// Override color but keep auto-icon
|
|
200
|
-
<acp-button
|
|
201
|
-
[reportFormat]="REPORT_FORMAT.CSV"
|
|
202
|
-
[variant]="'secondary'"
|
|
203
|
-
[text]="'Export Data'"
|
|
204
|
-
/>
|
|
205
|
-
// Result: Grid icon (from CSV), secondary color (overridden)
|
|
142
|
+
import { Component, inject } from '@angular/core';
|
|
143
|
+
import { AcpDialogRef, AcpDialogService } from '@acontplus/ng-components';
|
|
144
|
+
|
|
145
|
+
@Component({ ... })
|
|
146
|
+
export class UserListComponent {
|
|
147
|
+
private dialogs = inject(AcpDialogService);
|
|
148
|
+
|
|
149
|
+
openEdit(userId: number) {
|
|
150
|
+
const ref = this.dialogs.open<UserForm, { id: number }, boolean>(UserForm, {
|
|
151
|
+
title: 'Edit user',
|
|
152
|
+
size: 'lg',
|
|
153
|
+
data: { id: userId },
|
|
154
|
+
actions: [
|
|
155
|
+
{ text: 'Cancel', appearance: 'text', result: false },
|
|
156
|
+
{ text: 'Save', color: 'success', result: true },
|
|
157
|
+
],
|
|
158
|
+
});
|
|
206
159
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
160
|
+
ref.afterClosed().subscribe(result => {
|
|
161
|
+
if (result) {
|
|
162
|
+
// user saved
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
214
167
|
```
|
|
215
168
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
**Material Styles:**
|
|
221
|
-
|
|
222
|
-
- `filled` (default), `elevated`, `outlined`, `text`, `tonal`
|
|
223
|
-
- `icon`, `fab`, `mini-fab`, `extended-fab`
|
|
169
|
+
Clicking a configured action emits `ref.clickedResult` and then closes the
|
|
170
|
+
dialog with `action.result` (or `action.key` when `result` is not set). To
|
|
171
|
+
intercept the click without closing, call `event.preventDefault()` inside a
|
|
172
|
+
`clickedResult` subscriber.
|
|
224
173
|
|
|
225
|
-
|
|
174
|
+
#### Reactive action state
|
|
226
175
|
|
|
227
|
-
|
|
176
|
+
`AcpDialogAction.disabled` and `AcpDialogAction.loading` accept a boolean, a
|
|
177
|
+
`Signal<boolean>` or an `Observable<boolean>`:
|
|
228
178
|
|
|
229
179
|
```typescript
|
|
230
|
-
|
|
180
|
+
actions: [
|
|
181
|
+
{ text: 'Cancel', appearance: 'text' },
|
|
182
|
+
{
|
|
183
|
+
text: 'Save',
|
|
184
|
+
color: 'success',
|
|
185
|
+
disabled: this.canSave, // signal<boolean>
|
|
186
|
+
loading: this.saving, // signal<boolean>
|
|
187
|
+
},
|
|
188
|
+
],
|
|
231
189
|
```
|
|
232
190
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
#### SvgIcon
|
|
191
|
+
#### Declarative layout
|
|
236
192
|
|
|
237
|
-
|
|
193
|
+
For full control inside a dialog content template, use `acp-dialog` with
|
|
194
|
+
`acp-dialog-titlebar`, `acp-dialog-content` and `acp-dialog-actions`:
|
|
238
195
|
|
|
239
|
-
|
|
196
|
+
```html
|
|
197
|
+
<acp-dialog>
|
|
198
|
+
<acp-dialog-titlebar title="Edit user" icon="person" />
|
|
240
199
|
|
|
241
|
-
-
|
|
242
|
-
|
|
243
|
-
-
|
|
244
|
-
- ✅ Signal-based reactive primitives
|
|
245
|
-
- ✅ Fallback icon support for missing icons
|
|
246
|
-
- ✅ Dynamic online icon loading from URLs
|
|
247
|
-
- ✅ Customizable size, color, and dimensions
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
import { SvgIcon, IconRegistryService } from '@acontplus/ng-components';
|
|
251
|
-
|
|
252
|
-
@Component({
|
|
253
|
-
template: `
|
|
254
|
-
<!-- Basic usage -->
|
|
255
|
-
<acp-svg-icon name="home" />
|
|
200
|
+
<acp-dialog-content>
|
|
201
|
+
<p>Dialog body</p>
|
|
202
|
+
</acp-dialog-content>
|
|
256
203
|
|
|
257
|
-
|
|
258
|
-
<acp-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
<acp-svg-icon [name]="currentIcon" size="24px" />
|
|
268
|
-
`,
|
|
269
|
-
imports: [SvgIcon],
|
|
270
|
-
})
|
|
271
|
-
export class IconExampleComponent {
|
|
272
|
-
currentIcon = 'menu';
|
|
273
|
-
}
|
|
204
|
+
<acp-dialog-actions align="end">
|
|
205
|
+
<acp-button text="Cancel" appearance="text" (clicked)="ref.close()" />
|
|
206
|
+
<acp-button
|
|
207
|
+
text="Save"
|
|
208
|
+
color="success"
|
|
209
|
+
[disabled]="form.invalid"
|
|
210
|
+
(clicked)="ref.close(form.value)"
|
|
211
|
+
/>
|
|
212
|
+
</acp-dialog-actions>
|
|
213
|
+
</acp-dialog>
|
|
274
214
|
```
|
|
275
215
|
|
|
276
|
-
|
|
277
|
-
`home`, `user`, `settings`, `search`, `close`, `check`, `arrow-right`, `arrow-left`, `menu`, `info`, `warning`, `error`
|
|
278
|
-
|
|
279
|
-
**Configuring the Icon Registry:**
|
|
216
|
+
#### Defaults
|
|
280
217
|
|
|
281
218
|
```typescript
|
|
282
|
-
import {
|
|
283
|
-
import { IconRegistryService } from '@acontplus/ng-components';
|
|
284
|
-
import { provideHttpClient } from '@angular/common/http';
|
|
285
|
-
|
|
286
|
-
export const appConfig: ApplicationConfig = {
|
|
287
|
-
providers: [
|
|
288
|
-
provideHttpClient(), // Required for online icon loading
|
|
289
|
-
// ... other providers
|
|
290
|
-
],
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
// In your app component or initialization
|
|
294
|
-
export class AppComponent implements OnInit {
|
|
295
|
-
private iconRegistry = inject(IconRegistryService);
|
|
296
|
-
|
|
297
|
-
ngOnInit() {
|
|
298
|
-
// Configure with fallback icon
|
|
299
|
-
this.iconRegistry.configure({
|
|
300
|
-
fallbackIcon: `<svg>...</svg>`, // Fallback when icon not found
|
|
301
|
-
showWarnings: true, // Log warnings for missing icons
|
|
302
|
-
iconBaseUrl: 'https://cdn.example.com/icons', // Base URL for auto-loading
|
|
303
|
-
});
|
|
219
|
+
import { provideAcpDialogDefaults } from '@acontplus/ng-components';
|
|
304
220
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
</svg>
|
|
312
|
-
`,
|
|
313
|
-
);
|
|
314
|
-
|
|
315
|
-
// Register multiple icons
|
|
316
|
-
this.iconRegistry.registerIcons([
|
|
317
|
-
{ name: 'icon-one', data: '<svg>...</svg>' },
|
|
318
|
-
{ name: 'icon-two', data: '<svg>...</svg>' },
|
|
319
|
-
]);
|
|
320
|
-
|
|
321
|
-
// Load icons from URLs
|
|
322
|
-
await this.iconRegistry.loadIconFromUrl('github', 'https://example.com/github.svg');
|
|
323
|
-
|
|
324
|
-
// Load multiple icons from URLs
|
|
325
|
-
await this.iconRegistry.loadIconsFromUrls([
|
|
326
|
-
{ name: 'twitter', url: 'https://example.com/twitter.svg' },
|
|
327
|
-
{ name: 'linkedin', url: 'https://example.com/linkedin.svg' },
|
|
328
|
-
]);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
221
|
+
providers: [
|
|
222
|
+
provideAcpDialogDefaults({
|
|
223
|
+
fullScreenOnMobile: true,
|
|
224
|
+
closeOn: { escapeKey: true, backdropClick: false },
|
|
225
|
+
}),
|
|
226
|
+
],
|
|
331
227
|
```
|
|
332
228
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
| Method | Description |
|
|
336
|
-
| ----------------------------- | ----------------------------------------- |
|
|
337
|
-
| `configure(config)` | Set fallback icon, warnings, and base URL |
|
|
338
|
-
| `registerIcon(name, svgData)` | Register a single icon |
|
|
339
|
-
| `registerIcons(icons[])` | Register multiple icons |
|
|
340
|
-
| `loadIconFromUrl(name, url)` | Load icon from URL (requires HttpClient) |
|
|
341
|
-
| `loadIconsFromUrls(icons[])` | Load multiple icons from URLs |
|
|
342
|
-
| `getIcon(name)` | Get icon (returns fallback if not found) |
|
|
343
|
-
| `getIconAsync(name)` | Get icon with auto-loading from base URL |
|
|
344
|
-
| `hasIcon(name)` | Check if icon exists |
|
|
345
|
-
| `getRegisteredIcons()` | Get all registered icon names |
|
|
346
|
-
| `removeIcon(name)` | Remove specific icon |
|
|
347
|
-
| `clearRegistry()` | Clear all icons |
|
|
348
|
-
|
|
349
|
-
**Handling Missing Icons:**
|
|
350
|
-
|
|
351
|
-
When an icon is not found:
|
|
352
|
-
|
|
353
|
-
1. If `fallbackIcon` is configured, it displays the fallback
|
|
354
|
-
2. If `useFallback` input is `false`, nothing is displayed
|
|
355
|
-
3. Console warning is shown (if `showWarnings: true`)
|
|
229
|
+
#### API
|
|
356
230
|
|
|
357
|
-
|
|
231
|
+
- `AcpDialogService.open(component, config)` / `open({ content, ...config })`
|
|
232
|
+
- `AcpDialogRef.afterClosed()`, `close(result)`, `clickedResult`, `actionClicked$`
|
|
233
|
+
- `AcpDialogConfig` supports `size`, `width`, `height`, `title`, `header`,
|
|
234
|
+
`actions`, `actionsAlign`, `closeOn`, `fullScreenOnMobile`, `bindings`,
|
|
235
|
+
`ariaLabel`, `role`, etc.
|
|
236
|
+
- `AcpDialog`, `AcpDialogContent`, `AcpDialogTitlebar` and `AcpDialogActions` for
|
|
237
|
+
declarative headers, body and footers.
|
|
358
238
|
|
|
359
|
-
|
|
360
|
-
// Manual loading
|
|
361
|
-
await this.iconRegistry.loadIconFromUrl('brand-icon', 'https://cdn.example.com/brand.svg');
|
|
362
|
-
|
|
363
|
-
// Auto-loading with base URL
|
|
364
|
-
this.iconRegistry.configure({
|
|
365
|
-
iconBaseUrl: 'https://cdn.example.com/icons'
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
// Component automatically tries to load from:
|
|
369
|
-
// https://cdn.example.com/icons/brand-icon.svg
|
|
370
|
-
<acp-svg-icon name="brand-icon" />
|
|
371
|
-
|
|
372
|
-
// Or use async method
|
|
373
|
-
const icon = await this.iconRegistry.getIconAsync('brand-icon');
|
|
374
|
-
```
|
|
239
|
+
### Dialog Wrapper
|
|
375
240
|
|
|
376
|
-
|
|
241
|
+
> **The `DialogWrapper` component is deprecated.** Use `AcpDialogService` and
|
|
242
|
+
> the `AcpDialog` declarative layout components instead. The wrapper will be
|
|
243
|
+
> removed in a future major release.
|
|
377
244
|
|
|
378
|
-
|
|
245
|
+
Enhanced dialog components with wrapper functionality for consistent dialog management.
|
|
379
246
|
|
|
380
247
|
```typescript
|
|
381
|
-
import {
|
|
248
|
+
import { DialogWrapper } from '@acontplus/ng-components';
|
|
382
249
|
```
|
|
383
250
|
|
|
384
251
|
### Input Chip
|