b2b-tools 0.2.1 → 0.2.3
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 +751 -153
- package/fesm2022/b2b-tools.mjs +2 -2
- package/fesm2022/b2b-tools.mjs.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,153 +1,751 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
[](https://angular.io/)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://www.npmjs.com/package/b2b-tools)
|
|
6
|
+
[](#)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Index
|
|
11
|
+
|
|
12
|
+
- [Installation](#installation)
|
|
13
|
+
- [Components](#components)
|
|
14
|
+
- [AdvancedCard](#advancedcard)
|
|
15
|
+
- [AdvancedTable](#advancedtable)
|
|
16
|
+
- [SimpleTable](#simpletable)
|
|
17
|
+
- [Theming](#theming)
|
|
18
|
+
- [CSS Variables Reference](#css-variables-reference)
|
|
19
|
+
- [Color Customization](#color-customization)
|
|
20
|
+
- [Density & Size Variants](#density--size-variants)
|
|
21
|
+
- [i18n](#i18n)
|
|
22
|
+
- [Types Reference](#types-reference)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install b2b-tools
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Peer dependencies** (must already be in your project):
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
"@angular/common": "^21.1.0",
|
|
36
|
+
"@angular/core": "^21.1.0"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Components
|
|
42
|
+
|
|
43
|
+
### AdvancedCard
|
|
44
|
+
|
|
45
|
+
A configurable card with compact and expanded modes. Expansion can render inline, in a drawer, or in a modal. Supports highlight metrics, summary blocks, tabs, header actions, and custom template projection.
|
|
46
|
+
|
|
47
|
+
#### Import
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { AdvancedCard, AdvancedCardTemplateDirective } from 'b2b-tools';
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
#### Selector
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<advanced-card />
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### Inputs
|
|
60
|
+
|
|
61
|
+
| Input | Type | Default | Description |
|
|
62
|
+
|---|---|---|---|
|
|
63
|
+
| `config` | `AdvancedCardConfig` | **required** | Full card configuration object |
|
|
64
|
+
| `fullWidthOnExpand` | `boolean` | `true` | Expanded inline view takes full width |
|
|
65
|
+
| `stickyHeader` | `boolean` | `true` | Header stays fixed while scrolling expanded content |
|
|
66
|
+
| `closeOnEsc` | `boolean` | `true` | Press Escape closes drawer/modal |
|
|
67
|
+
|
|
68
|
+
#### Outputs
|
|
69
|
+
|
|
70
|
+
| Output | Payload | Description |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `expandedChange` | `boolean` | Fires when card opens or closes |
|
|
73
|
+
| `action` | `{ actionId: string; cardId: string }` | Header action button clicked |
|
|
74
|
+
| `tabChanged` | `{ tabId: string; cardId: string }` | Active tab changed |
|
|
75
|
+
| `tabAction` | `{ tabId: string; actionId: string; cardId: string }` | Action inside a tab clicked |
|
|
76
|
+
|
|
77
|
+
#### AdvancedCardConfig
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
interface AdvancedCardConfig {
|
|
81
|
+
id: string; // Unique card identifier
|
|
82
|
+
title: string; // Card title
|
|
83
|
+
subtitle?: string; // Secondary line below title
|
|
84
|
+
badge?: AdvancedBadge; // Status badge on header
|
|
85
|
+
highlights?: AdvancedHighlight[]; // Metric pills shown in compact view
|
|
86
|
+
summaryBlocks?: AdvancedSummaryBlock[]; // Collapsible data blocks in expanded view
|
|
87
|
+
primaryCta?: { label: string }; // Primary expand button label
|
|
88
|
+
actions?: AdvancedAction[]; // Header action buttons
|
|
89
|
+
tabs?: AdvancedCardTab[]; // Tab definitions
|
|
90
|
+
defaultTabId?: string; // Tab active by default
|
|
91
|
+
expandMode?: AdvancedExpandMode; // 'inline' | 'drawer' | 'modal'
|
|
92
|
+
closeOnBackdrop?: boolean; // Click backdrop to close drawer/modal
|
|
93
|
+
density?: AdvancedDensity; // 'compact' | 'comfortable'
|
|
94
|
+
size?: AdvancedSize; // 'sm' | 'md' | 'lg'
|
|
95
|
+
contentLayout?: 'stacked' | 'inline'; // Summary blocks layout
|
|
96
|
+
summaryToggle?: boolean; // Allow collapsing summary blocks
|
|
97
|
+
data?: any; // Arbitrary payload forwarded to templates
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### Supporting Types
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
type AdvancedTone = 'primary' | 'success' | 'warning' | 'danger' | 'neutral';
|
|
105
|
+
type AdvancedExpandMode = 'inline' | 'drawer' | 'modal';
|
|
106
|
+
type AdvancedDensity = 'compact' | 'comfortable';
|
|
107
|
+
type AdvancedSize = 'sm' | 'md' | 'lg';
|
|
108
|
+
type AdvancedTabKind = 'template' | 'text' | 'empty';
|
|
109
|
+
|
|
110
|
+
interface AdvancedBadge {
|
|
111
|
+
label: string;
|
|
112
|
+
tone?: AdvancedTone;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
interface AdvancedHighlight {
|
|
116
|
+
label: string;
|
|
117
|
+
value: string;
|
|
118
|
+
hint?: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
interface AdvancedAction {
|
|
122
|
+
id: string;
|
|
123
|
+
label: string;
|
|
124
|
+
tone?: 'primary' | 'secondary' | 'danger';
|
|
125
|
+
disabled?: boolean;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
interface AdvancedCardTab {
|
|
129
|
+
id: string;
|
|
130
|
+
label: string;
|
|
131
|
+
kind: AdvancedTabKind; // 'template' | 'text' | 'empty'
|
|
132
|
+
text?: string; // Content when kind = 'text'
|
|
133
|
+
templateId?: string; // Matches advancedCardTemplate directive
|
|
134
|
+
actions?: AdvancedTabAction[];
|
|
135
|
+
pill?: { label: string; tone?: AdvancedTone };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
interface AdvancedSummaryBlock {
|
|
139
|
+
title: string;
|
|
140
|
+
rows: AdvancedSummaryRow[];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
interface AdvancedSummaryRow {
|
|
144
|
+
label: string;
|
|
145
|
+
value: string;
|
|
146
|
+
kind?: AdvancedRowKind;
|
|
147
|
+
tone?: AdvancedTone;
|
|
148
|
+
icon?: string;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Template Projection
|
|
153
|
+
|
|
154
|
+
Use `advancedCardTemplate` directive to project custom content into tabs of `kind: 'template'`. The `templateId` must match the tab's `templateId`.
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { AdvancedCard, AdvancedCardTemplateDirective } from 'b2b-tools';
|
|
158
|
+
|
|
159
|
+
@Component({
|
|
160
|
+
imports: [AdvancedCard, AdvancedCardTemplateDirective],
|
|
161
|
+
template: `
|
|
162
|
+
<advanced-card [config]="config" (action)="onAction($event)">
|
|
163
|
+
|
|
164
|
+
<ng-template advancedCardTemplate="details" let-cardId="cardId" let-tabId="tabId">
|
|
165
|
+
<p>Custom content for card <strong>{{ cardId }}</strong></p>
|
|
166
|
+
</ng-template>
|
|
167
|
+
|
|
168
|
+
</advanced-card>
|
|
169
|
+
`
|
|
170
|
+
})
|
|
171
|
+
export class MyComponent {
|
|
172
|
+
config: AdvancedCardConfig = {
|
|
173
|
+
id: 'order-001',
|
|
174
|
+
title: 'Order #1042',
|
|
175
|
+
subtitle: 'Pending review',
|
|
176
|
+
badge: { label: 'Pending', tone: 'warning' },
|
|
177
|
+
highlights: [
|
|
178
|
+
{ label: 'Total', value: '$4,200.00' },
|
|
179
|
+
{ label: 'Items', value: '12' },
|
|
180
|
+
],
|
|
181
|
+
expandMode: 'drawer',
|
|
182
|
+
tabs: [
|
|
183
|
+
{ id: 'details', label: 'Details', kind: 'template', templateId: 'details' },
|
|
184
|
+
{ id: 'notes', label: 'Notes', kind: 'text', text: 'No notes yet.' },
|
|
185
|
+
],
|
|
186
|
+
actions: [
|
|
187
|
+
{ id: 'approve', label: 'Approve', tone: 'primary' },
|
|
188
|
+
{ id: 'reject', label: 'Reject', tone: 'danger' },
|
|
189
|
+
],
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
#### Expansion Modes
|
|
195
|
+
|
|
196
|
+
| Mode | Behavior |
|
|
197
|
+
|---|---|
|
|
198
|
+
| `inline` | Card expands in place, pushing content below |
|
|
199
|
+
| `drawer` | Slides up from the bottom as an overlay panel |
|
|
200
|
+
| `modal` | Centered modal dialog with backdrop |
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
### AdvancedTable
|
|
205
|
+
|
|
206
|
+
A full-featured data table. Generic over your row type `T`. Supports global search, per-column filters, multi-column sorting, pagination or infinite scroll, single/multiple row selection, and rich cell types.
|
|
207
|
+
|
|
208
|
+
#### Import
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import { AdvancedTable } from 'b2b-tools';
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### Selector
|
|
215
|
+
|
|
216
|
+
```html
|
|
217
|
+
<advanced-table />
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### Inputs
|
|
221
|
+
|
|
222
|
+
| Input | Type | Default | Description |
|
|
223
|
+
|---|---|---|---|
|
|
224
|
+
| `columns` | `TableColumn<T>[]` | `[]` | Column definitions |
|
|
225
|
+
| `data` | `T[]` | `[]` | Row data |
|
|
226
|
+
| `config` | `TableConfig` | see below | Table behavior configuration |
|
|
227
|
+
| `i18n` | `Partial<TableI18n>` | EN strings | Override any translation string |
|
|
228
|
+
| `lang` | `'EN' \| 'ES'` | `'EN'` | Built-in language preset |
|
|
229
|
+
|
|
230
|
+
#### Outputs
|
|
231
|
+
|
|
232
|
+
| Output | Payload | Description |
|
|
233
|
+
|---|---|---|
|
|
234
|
+
| `rowClick` | `T` | Row clicked |
|
|
235
|
+
| `selectionChange` | `RowId[]` | Selected row IDs changed |
|
|
236
|
+
| `actionClick` | `TableActionEvent<T>` | Action button clicked |
|
|
237
|
+
|
|
238
|
+
#### TableConfig
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
interface TableConfig {
|
|
242
|
+
globalSearch?: boolean; // Show global search bar (default: false)
|
|
243
|
+
columnFilters?: boolean; // Show per-column filter inputs (default: false)
|
|
244
|
+
selectable?: boolean; // Enable row selection (default: false)
|
|
245
|
+
selectionMode?: 'single' | 'multiple'; // Default: 'multiple'
|
|
246
|
+
pagination?: {
|
|
247
|
+
enabled: boolean;
|
|
248
|
+
pageSize: number;
|
|
249
|
+
pageSizeOptions?: number[]; // e.g. [10, 25, 50]
|
|
250
|
+
};
|
|
251
|
+
scroll?: {
|
|
252
|
+
mode: 'none' | 'infinite';
|
|
253
|
+
heightPx?: number; // Fixed table height for infinite scroll
|
|
254
|
+
batchSize?: number; // Rows per batch when mode = 'infinite'
|
|
255
|
+
};
|
|
256
|
+
fixedRowCount?: number; // Pin N rows at top regardless of sort/filter
|
|
257
|
+
emptyText?: string; // Override empty state message
|
|
258
|
+
rowIdKey?: string; // Property name used as row ID (default: 'id')
|
|
259
|
+
rowIdGetter?: (row: T) => string | number; // Custom row ID extractor
|
|
260
|
+
globalSearchVisibleOnly?: boolean; // Search only visible columns
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### TableColumn
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
interface TableColumn<T = unknown> {
|
|
268
|
+
key: string; // Property name in T (or virtual key when valueGetter used)
|
|
269
|
+
label: string; // Column header text
|
|
270
|
+
type: CellDataType; // Cell renderer (see below)
|
|
271
|
+
size?: CellSize; // Column width preset
|
|
272
|
+
align?: TextAlign; // 'left' | 'center' | 'right'
|
|
273
|
+
sortable?: boolean;
|
|
274
|
+
filterable?: boolean;
|
|
275
|
+
hidden?: boolean;
|
|
276
|
+
wrap?: boolean; // Allow cell text to wrap
|
|
277
|
+
valueGetter?: (row: T) => unknown; // Derive value from row
|
|
278
|
+
formatter?: (value: unknown, row: T) => string; // Format display string
|
|
279
|
+
actions?: TableAction<T>[]; // Inline row actions (type: 'actions')
|
|
280
|
+
options?: {
|
|
281
|
+
currency?: 'MXN';
|
|
282
|
+
dateFormat?: 'short' | 'medium' | 'long';
|
|
283
|
+
dateTimeFormat?: 'short' | 'medium' | 'long';
|
|
284
|
+
image?: {
|
|
285
|
+
hidden?: boolean;
|
|
286
|
+
openInModal?: boolean;
|
|
287
|
+
showFull?: boolean;
|
|
288
|
+
alt?: (row: T) => string;
|
|
289
|
+
};
|
|
290
|
+
status?: {
|
|
291
|
+
classMap?: Record<string, string>; // value → CSS class
|
|
292
|
+
};
|
|
293
|
+
link?: {
|
|
294
|
+
hrefGetter?: (row: T) => string;
|
|
295
|
+
labelGetter?: (row: T) => string;
|
|
296
|
+
target?: '_blank' | '_self';
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
#### Cell Types (`CellDataType`)
|
|
303
|
+
|
|
304
|
+
| Type | Renders | Notes |
|
|
305
|
+
|---|---|---|
|
|
306
|
+
| `string` | Plain text | Default |
|
|
307
|
+
| `integer` | Number (no decimals) | |
|
|
308
|
+
| `decimal` | Number (2 decimals) | |
|
|
309
|
+
| `currency` | Formatted currency | Use `options.currency` |
|
|
310
|
+
| `date` | Localized date | Use `options.dateFormat` |
|
|
311
|
+
| `datetime` | Localized date + time | Use `options.dateTimeFormat` |
|
|
312
|
+
| `boolean` | ✓ / ✗ | |
|
|
313
|
+
| `image` | `<img>` thumbnail | `options.image.openInModal` for lightbox |
|
|
314
|
+
| `status` | Colored badge | Map values to CSS classes via `options.status.classMap` |
|
|
315
|
+
| `link` | Anchor tag | `options.link.hrefGetter` / `labelGetter` |
|
|
316
|
+
| `custom` | Formatted string | Provide `formatter` |
|
|
317
|
+
| `actions` | Action buttons | Define `actions` array |
|
|
318
|
+
|
|
319
|
+
#### Column Size Presets (`CellSize`)
|
|
320
|
+
|
|
321
|
+
| Value | Approximate Width |
|
|
322
|
+
|---|---|
|
|
323
|
+
| `XS` | 60px |
|
|
324
|
+
| `SM` | 100px |
|
|
325
|
+
| `MD` | 150px |
|
|
326
|
+
| `LG` | 220px |
|
|
327
|
+
| `XL` | 320px |
|
|
328
|
+
| `AUTO-XL` | Flexible, grows wide |
|
|
329
|
+
| `AUTO` | Flexible, fills space |
|
|
330
|
+
|
|
331
|
+
#### Row Actions
|
|
332
|
+
|
|
333
|
+
```ts
|
|
334
|
+
interface TableAction<T> {
|
|
335
|
+
id: string;
|
|
336
|
+
label: string;
|
|
337
|
+
icon?: 'edit' | 'delete' | 'view' | 'copy' | string;
|
|
338
|
+
tooltip?: string;
|
|
339
|
+
variant?: ActionVariant;
|
|
340
|
+
render?: ActionRender;
|
|
341
|
+
visible?: (row: T) => boolean; // Conditionally show action
|
|
342
|
+
disabled?: (row: T) => boolean; // Conditionally disable action
|
|
343
|
+
confirm?: {
|
|
344
|
+
title?: string;
|
|
345
|
+
message: string; // Shows confirmation dialog before firing
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
interface TableActionEvent<T> {
|
|
350
|
+
actionId: string;
|
|
351
|
+
row: T;
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
#### Full Example
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
import { AdvancedTable, TableColumn, TableConfig } from 'b2b-tools';
|
|
359
|
+
|
|
360
|
+
interface Order {
|
|
361
|
+
id: number;
|
|
362
|
+
customer: string;
|
|
363
|
+
total: number;
|
|
364
|
+
status: string;
|
|
365
|
+
createdAt: string;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
@Component({
|
|
369
|
+
imports: [AdvancedTable],
|
|
370
|
+
template: `
|
|
371
|
+
<advanced-table
|
|
372
|
+
[columns]="columns"
|
|
373
|
+
[data]="orders"
|
|
374
|
+
[config]="config"
|
|
375
|
+
lang="ES"
|
|
376
|
+
(rowClick)="onRowClick($event)"
|
|
377
|
+
(actionClick)="onAction($event)"
|
|
378
|
+
/>
|
|
379
|
+
`
|
|
380
|
+
})
|
|
381
|
+
export class OrdersTableComponent {
|
|
382
|
+
orders: Order[] = [ /* ... */ ];
|
|
383
|
+
|
|
384
|
+
columns: TableColumn<Order>[] = [
|
|
385
|
+
{ key: 'id', label: '#', type: 'integer', size: 'XS', sortable: true },
|
|
386
|
+
{ key: 'customer', label: 'Customer', type: 'string', size: 'AUTO', filterable: true },
|
|
387
|
+
{ key: 'total', label: 'Total', type: 'currency', size: 'MD', sortable: true,
|
|
388
|
+
options: { currency: 'MXN' } },
|
|
389
|
+
{ key: 'status', label: 'Status', type: 'status', size: 'SM',
|
|
390
|
+
options: { status: { classMap: { active: 'badge-success', cancelled: 'badge-danger' } } } },
|
|
391
|
+
{ key: 'createdAt', label: 'Date', type: 'date', size: 'MD', sortable: true,
|
|
392
|
+
options: { dateFormat: 'medium' } },
|
|
393
|
+
{ key: '_actions', label: '', type: 'actions', size: 'XS',
|
|
394
|
+
actions: [
|
|
395
|
+
{ id: 'view', label: 'View', icon: 'view' },
|
|
396
|
+
{ id: 'delete', label: 'Delete', icon: 'delete', tone: 'danger',
|
|
397
|
+
confirm: { message: 'Delete this order?' },
|
|
398
|
+
visible: (row) => row.status !== 'shipped' },
|
|
399
|
+
]
|
|
400
|
+
},
|
|
401
|
+
];
|
|
402
|
+
|
|
403
|
+
config: TableConfig = {
|
|
404
|
+
globalSearch: true,
|
|
405
|
+
columnFilters: true,
|
|
406
|
+
selectable: true,
|
|
407
|
+
selectionMode: 'multiple',
|
|
408
|
+
pagination: { enabled: true, pageSize: 25, pageSizeOptions: [10, 25, 50] },
|
|
409
|
+
rowIdKey: 'id',
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
onRowClick(row: Order) { /* ... */ }
|
|
413
|
+
onAction(event: TableActionEvent<Order>) { /* ... */ }
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
### SimpleTable
|
|
420
|
+
|
|
421
|
+
Lightweight table with built-in client-side sorting. Use when you need a minimal table without the full AdvancedTable feature set.
|
|
422
|
+
|
|
423
|
+
#### Import
|
|
424
|
+
|
|
425
|
+
```ts
|
|
426
|
+
import { SimpleTable } from 'b2b-tools';
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
#### Selector
|
|
430
|
+
|
|
431
|
+
```html
|
|
432
|
+
<simple-table />
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
#### Inputs
|
|
436
|
+
|
|
437
|
+
| Input | Type | Default | Description |
|
|
438
|
+
|---|---|---|---|
|
|
439
|
+
| `headers` | `SimpleHaders<T>[]` | **required** | Column definitions |
|
|
440
|
+
| `data` | `T[]` | `[]` | Row data |
|
|
441
|
+
|
|
442
|
+
#### SimpleHaders
|
|
443
|
+
|
|
444
|
+
```ts
|
|
445
|
+
interface SimpleHaders<T> {
|
|
446
|
+
label: string; // Column header text
|
|
447
|
+
key: keyof T; // Property to display and sort by
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
#### Example
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
import { SimpleTable, SimpleHaders } from 'b2b-tools';
|
|
455
|
+
|
|
456
|
+
interface Product {
|
|
457
|
+
name: string;
|
|
458
|
+
price: number;
|
|
459
|
+
stock: number;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
@Component({
|
|
463
|
+
imports: [SimpleTable],
|
|
464
|
+
template: `
|
|
465
|
+
<simple-table [headers]="headers" [data]="products" />
|
|
466
|
+
`
|
|
467
|
+
})
|
|
468
|
+
export class ProductsComponent {
|
|
469
|
+
headers: SimpleHaders<Product>[] = [
|
|
470
|
+
{ label: 'Product', key: 'name' },
|
|
471
|
+
{ label: 'Price', key: 'price' },
|
|
472
|
+
{ label: 'Stock', key: 'stock' },
|
|
473
|
+
];
|
|
474
|
+
|
|
475
|
+
products: Product[] = [ /* ... */ ];
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## Theming
|
|
482
|
+
|
|
483
|
+
All visual tokens are CSS custom properties. Override them on the component element, a parent container, or `:root` — no build step required.
|
|
484
|
+
|
|
485
|
+
### CSS Variables Reference
|
|
486
|
+
|
|
487
|
+
#### Colors
|
|
488
|
+
|
|
489
|
+
| Variable | Default | Description |
|
|
490
|
+
|---|---|---|
|
|
491
|
+
| `--ac-primary` | `#2563eb` | Primary brand color (buttons, highlights, links) |
|
|
492
|
+
| `--ac-primary-soft` | `#eff6ff` | Light primary tint (selected row background, etc.) |
|
|
493
|
+
| `--ac-primary-glow` | `rgba(37,99,235,.12)` | Focus glow around primary elements |
|
|
494
|
+
| `--ac-accent-bar` | `linear-gradient(#3b82f6,#2563eb)` | Vertical accent bar on expanded card |
|
|
495
|
+
| `--ac-danger` | `#dc2626` | Destructive actions |
|
|
496
|
+
|
|
497
|
+
#### Surfaces & Borders
|
|
498
|
+
|
|
499
|
+
| Variable | Default | Description |
|
|
500
|
+
|---|---|---|
|
|
501
|
+
| `--ac-surface` | `#ffffff` | Card / panel background |
|
|
502
|
+
| `--ac-surface-2` | `#f8fafc` | Secondary surface (alternating rows, summary blocks) |
|
|
503
|
+
| `--ac-border` | `#e2e8f0` | Default border |
|
|
504
|
+
| `--ac-border-soft` | `#f1f5f9` | Subtle dividers |
|
|
505
|
+
|
|
506
|
+
#### Text
|
|
507
|
+
|
|
508
|
+
| Variable | Default | Description |
|
|
509
|
+
|---|---|---|
|
|
510
|
+
| `--ac-text` | `#0f172a` | Primary text |
|
|
511
|
+
| `--ac-text-secondary` | `#334155` | Secondary / label text |
|
|
512
|
+
| `--ac-muted` | `#64748b` | Muted / placeholder text |
|
|
513
|
+
|
|
514
|
+
#### Badge Tones
|
|
515
|
+
|
|
516
|
+
| Variable | Default | Description |
|
|
517
|
+
|---|---|---|
|
|
518
|
+
| `--ac-badge-success-bg` | `#ecfdf5` | Success badge background |
|
|
519
|
+
| `--ac-badge-success-fg` | `#059669` | Success badge text |
|
|
520
|
+
| `--ac-badge-warning-bg` | `#fffbeb` | Warning badge background |
|
|
521
|
+
| `--ac-badge-warning-fg` | `#d97706` | Warning badge text |
|
|
522
|
+
| `--ac-badge-danger-bg` | `#fef2f2` | Danger badge background |
|
|
523
|
+
| `--ac-badge-danger-fg` | `#dc2626` | Danger badge text |
|
|
524
|
+
| `--ac-badge-primary-bg` | `#eff6ff` | Primary badge background |
|
|
525
|
+
| `--ac-badge-primary-fg` | `#2563eb` | Primary badge text |
|
|
526
|
+
| `--ac-badge-neutral-bg` | `#f1f5f9` | Neutral badge background |
|
|
527
|
+
| `--ac-badge-neutral-fg` | `#475569` | Neutral badge text |
|
|
528
|
+
|
|
529
|
+
#### Overlays (Drawer / Modal)
|
|
530
|
+
|
|
531
|
+
| Variable | Default | Description |
|
|
532
|
+
|---|---|---|
|
|
533
|
+
| `--ac-overlay` | `rgba(15,23,42,.5)` | Backdrop color |
|
|
534
|
+
| `--ac-overlay-blur` | `4px` | Backdrop blur |
|
|
535
|
+
| `--ac-drawer-height` | `min(85vh, 900px)` | Maximum drawer panel height |
|
|
536
|
+
| `--ac-modal-max` | `1200px` | Modal max-width |
|
|
537
|
+
| `--ac-modal-height` | `min(80vh, 880px)` | Modal max-height |
|
|
538
|
+
|
|
539
|
+
#### Shadows
|
|
540
|
+
|
|
541
|
+
| Variable | Default | Description |
|
|
542
|
+
|---|---|---|
|
|
543
|
+
| `--ac-shadow` | subtle 2-layer | Card resting shadow |
|
|
544
|
+
| `--ac-shadow-hover` | elevated 2-layer | Shadow on hover |
|
|
545
|
+
| `--ac-shadow-panel` | deep 2-layer | Expanded panel shadow |
|
|
546
|
+
|
|
547
|
+
#### Shape & Spacing
|
|
548
|
+
|
|
549
|
+
| Variable | Default | Description |
|
|
550
|
+
|---|---|---|
|
|
551
|
+
| `--ac-radius` | `16px` | Card border radius |
|
|
552
|
+
| `--ac-radius-sm` | `12px` | Inner element radius |
|
|
553
|
+
| `--ac-btn-radius` | `8px` | Button border radius |
|
|
554
|
+
| `--ac-gap` | `16px` | Internal spacing gap |
|
|
555
|
+
| `--ac-pad-card` | `18px` | Card padding |
|
|
556
|
+
| `--ac-pad-header` | `16px 20px` | Header padding |
|
|
557
|
+
| `--ac-pad-body` | `20px` | Body content padding |
|
|
558
|
+
|
|
559
|
+
#### Typography
|
|
560
|
+
|
|
561
|
+
| Variable | Default | Description |
|
|
562
|
+
|---|---|---|
|
|
563
|
+
| `--ac-title-size` | `18px` | Card title font size |
|
|
564
|
+
| `--ac-subtitle-size` | `13px` | Subtitle font size |
|
|
565
|
+
| `--ac-btn-font` | `600` | Button font weight |
|
|
566
|
+
| `--ac-btn-pad` | `8px 14px` | Button padding |
|
|
567
|
+
|
|
568
|
+
---
|
|
569
|
+
|
|
570
|
+
### Color Customization
|
|
571
|
+
|
|
572
|
+
#### Inline override (single card)
|
|
573
|
+
|
|
574
|
+
```html
|
|
575
|
+
<advanced-card
|
|
576
|
+
[config]="config"
|
|
577
|
+
style="
|
|
578
|
+
--ac-primary: #7c3aed;
|
|
579
|
+
--ac-primary-soft: #f5f3ff;
|
|
580
|
+
--ac-accent-bar: linear-gradient(#8b5cf6, #7c3aed);
|
|
581
|
+
"
|
|
582
|
+
/>
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
#### Global override (all cards in your app)
|
|
586
|
+
|
|
587
|
+
```scss
|
|
588
|
+
// styles.scss
|
|
589
|
+
:root {
|
|
590
|
+
--ac-primary: #0d9488; /* teal brand */
|
|
591
|
+
--ac-primary-soft: #f0fdfa;
|
|
592
|
+
--ac-accent-bar: linear-gradient(#14b8a6, #0d9488);
|
|
593
|
+
--ac-radius: 12px;
|
|
594
|
+
--ac-surface: #fafafa;
|
|
595
|
+
}
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
#### Dark mode
|
|
599
|
+
|
|
600
|
+
```scss
|
|
601
|
+
[data-theme='dark'] {
|
|
602
|
+
--ac-surface: #1e1e2e;
|
|
603
|
+
--ac-surface-2: #181825;
|
|
604
|
+
--ac-border: #313244;
|
|
605
|
+
--ac-border-soft: #1e1e2e;
|
|
606
|
+
--ac-text: #cdd6f4;
|
|
607
|
+
--ac-text-secondary: #bac2de;
|
|
608
|
+
--ac-muted: #6c7086;
|
|
609
|
+
--ac-primary: #89b4fa;
|
|
610
|
+
--ac-primary-soft: #1e1e2e;
|
|
611
|
+
--ac-overlay: rgba(0, 0, 0, 0.7);
|
|
612
|
+
}
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
#### Brand presets
|
|
616
|
+
|
|
617
|
+
**Orange**
|
|
618
|
+
```css
|
|
619
|
+
--ac-primary: #ea580c;
|
|
620
|
+
--ac-primary-soft: #fff7ed;
|
|
621
|
+
--ac-accent-bar: linear-gradient(#f97316, #ea580c);
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
**Green**
|
|
625
|
+
```css
|
|
626
|
+
--ac-primary: #16a34a;
|
|
627
|
+
--ac-primary-soft: #f0fdf4;
|
|
628
|
+
--ac-accent-bar: linear-gradient(#22c55e, #16a34a);
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
**Rose**
|
|
632
|
+
```css
|
|
633
|
+
--ac-primary: #e11d48;
|
|
634
|
+
--ac-primary-soft: #fff1f2;
|
|
635
|
+
--ac-accent-bar: linear-gradient(#f43f5e, #e11d48);
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
### Density & Size Variants
|
|
641
|
+
|
|
642
|
+
Control spacing and text scale through `config.density` and `config.size`.
|
|
643
|
+
|
|
644
|
+
```ts
|
|
645
|
+
config: AdvancedCardConfig = {
|
|
646
|
+
id: 'card-1',
|
|
647
|
+
title: 'Compact card',
|
|
648
|
+
density: 'compact', // tighter spacing
|
|
649
|
+
size: 'sm', // smaller title, radius, modal max-width
|
|
650
|
+
};
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
| `density` | Effect |
|
|
654
|
+
|---|---|
|
|
655
|
+
| `comfortable` | Default spacing |
|
|
656
|
+
| `compact` | Reduced gap, padding, and font sizes |
|
|
657
|
+
|
|
658
|
+
| `size` | Title | Radius | Modal max-width |
|
|
659
|
+
|---|---|---|---|
|
|
660
|
+
| `sm` | 16px | 12px | 1000px |
|
|
661
|
+
| `md` | 18px | 16px | 1200px |
|
|
662
|
+
| `lg` | 20px | 18px | 1400px |
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
## i18n
|
|
667
|
+
|
|
668
|
+
`AdvancedTable` ships with English and Spanish. Use `lang` for a preset or `i18n` for full control.
|
|
669
|
+
|
|
670
|
+
```html
|
|
671
|
+
<!-- Spanish preset -->
|
|
672
|
+
<advanced-table [columns]="cols" [data]="rows" lang="ES" />
|
|
673
|
+
|
|
674
|
+
<!-- Partial override -->
|
|
675
|
+
<advanced-table [columns]="cols" [data]="rows" [i18n]="customStrings" />
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
```ts
|
|
679
|
+
customStrings: Partial<TableI18n> = {
|
|
680
|
+
noData: 'Sin registros',
|
|
681
|
+
search: 'Buscar…',
|
|
682
|
+
showing: (from, to, total) => `${from}-${to} de ${total} registros`,
|
|
683
|
+
};
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
#### TableI18n Interface
|
|
687
|
+
|
|
688
|
+
```ts
|
|
689
|
+
interface TableI18n {
|
|
690
|
+
noData: string;
|
|
691
|
+
rowsPerPage: string;
|
|
692
|
+
showing: (from: number, to: number, total: number) => string;
|
|
693
|
+
search: string;
|
|
694
|
+
clear: string;
|
|
695
|
+
actions: string;
|
|
696
|
+
previous?: string;
|
|
697
|
+
next?: string;
|
|
698
|
+
filter: string;
|
|
699
|
+
empty: string;
|
|
700
|
+
seeImage: string;
|
|
701
|
+
}
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
---
|
|
705
|
+
|
|
706
|
+
## Types Reference
|
|
707
|
+
|
|
708
|
+
All types are exported from the package root.
|
|
709
|
+
|
|
710
|
+
```ts
|
|
711
|
+
import {
|
|
712
|
+
// Card
|
|
713
|
+
AdvancedCardConfig,
|
|
714
|
+
AdvancedBadge,
|
|
715
|
+
AdvancedHighlight,
|
|
716
|
+
AdvancedAction,
|
|
717
|
+
AdvancedCardTab,
|
|
718
|
+
AdvancedSummaryBlock,
|
|
719
|
+
AdvancedSummaryRow,
|
|
720
|
+
AdvancedTone,
|
|
721
|
+
AdvancedExpandMode,
|
|
722
|
+
AdvancedDensity,
|
|
723
|
+
AdvancedSize,
|
|
724
|
+
AdvancedTabKind,
|
|
725
|
+
|
|
726
|
+
// Table
|
|
727
|
+
TableColumn,
|
|
728
|
+
TableConfig,
|
|
729
|
+
TableAction,
|
|
730
|
+
TableActionEvent,
|
|
731
|
+
TableI18n,
|
|
732
|
+
TableLang,
|
|
733
|
+
CellDataType,
|
|
734
|
+
CellSize,
|
|
735
|
+
TextAlign,
|
|
736
|
+
RowId,
|
|
737
|
+
|
|
738
|
+
// Simple Table
|
|
739
|
+
SimpleHaders,
|
|
740
|
+
} from 'b2b-tools';
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
---
|
|
744
|
+
|
|
745
|
+
## Repository
|
|
746
|
+
|
|
747
|
+
Source code: **https://github.com/LuisEmilianoCortes/b2b-tools**
|
|
748
|
+
|
|
749
|
+
npm: **https://www.npmjs.com/package/b2b-tools**
|
|
750
|
+
|
|
751
|
+
Issues and PRs welcome.
|