b2b-tools 0.2.2 → 0.3.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 CHANGED
@@ -1,153 +1,751 @@
1
- [![Angular](https://img.shields.io/badge/Angular-21-red?logo=angular)](https://angular.io/)
2
- [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
3
- [![npm version](https://img.shields.io/npm/v/b2b-tools.svg)](https://www.npmjs.com/package/b2b-tools)
4
- [![Build Status](https://img.shields.io/badge/build-passing-brightgreen)](#)
5
-
6
- `b2b-tools` is a reusable Angular 21 standalone component library
7
- designed for scalable, enterprise-ready UI components.
8
-
9
- ---
10
-
11
- ## 🔗 Repository
12
-
13
- The source code for this library is hosted on GitHub:
14
-
15
- 👉 **https://github.com/LuisEmilianoCortes/b2b-tools**
16
-
17
- ---
18
-
19
- ## 🏗️ Technology Stack
20
-
21
- - Angular 21
22
- - Standalone Components
23
- - Signals-based state management
24
- - Strict TypeScript
25
- - CSS variable theming
26
-
27
- ---
28
-
29
- # 📚 Index
30
-
31
- - [Components](#-components)
32
- - [AdvancedTableComponent](#-advancedtablecomponent)
33
- - [AdvancedCardComponent](#-advancedcardcomponent)
34
- - [Theming](#-theming)
35
- - [Design Principles](#-design-principles)
36
- - [Future Enhancements](#-future-enhancements)
37
-
38
- ---
39
-
40
- # 🧩 Components
41
-
42
- The library currently provides the following core components:
43
-
44
- ---
45
-
46
- ## 🔹 AdvancedTableComponent
47
-
48
- A modular and extensible data table component designed for structured
49
- data visualization.
50
-
51
- ### Features
52
-
53
- - Strongly typed column configuration
54
- - Sorting support
55
- - Pagination support
56
- - Flexible cell rendering
57
- - Standalone usage
58
- - Domain-agnostic design
59
-
60
- ### Basic Usage
61
-
62
- ```ts
63
- import { AdvancedTableComponent } from 'b2b-tools';
64
- ```
65
-
66
- ```html
67
- <advanced-table [columns]="columns" [rows]="rows"></advanced-table>
68
- ```
69
-
70
- ---
71
-
72
- ## 🔹 AdvancedCardComponent
73
-
74
- A highly configurable, domain-agnostic card component designed to
75
- display summary information and expandable detailed content.
76
-
77
- ### Features
78
-
79
- - Compact and expanded modes
80
- - Inline / Drawer / Modal expansion
81
- - Highlight metrics
82
- - Summary blocks
83
- - Header actions
84
- - Tab system
85
- - Template projection
86
- - CSS variable theming
87
- - Signals-based internal state
88
-
89
- ---
90
-
91
- ### Basic Usage
92
-
93
- ```ts
94
- import { AdvancedCardComponent } from 'b2b-tools';
95
- ```
96
-
97
- ```html
98
- <advanced-card
99
- [config]="cardConfig"
100
- (action)="onHeaderAction($event)"
101
- (tabChanged)="onTabChanged($event)"
102
- (tabAction)="onTabAction($event)"
103
- >
104
- <ng-template advancedCardTemplate="example" let-cardId="cardId" let-tabId="tabId">
105
- <div>Example content for {{ cardId }} (tab: {{ tabId }})</div>
106
- </ng-template>
107
- </advanced-card>
108
- ```
109
-
110
- ---
111
-
112
- # 🎨 Theming
113
-
114
- Both components support CSS variables for styling customization.
115
-
116
- Example:
117
-
118
- ```html
119
- <advanced-card
120
- [config]="cardConfig"
121
- style="--ac-primary: #f58026; --ac-radius: 18px; --ac-overlay: rgba(0,0,0,.55)"
122
- ></advanced-card>
123
- ```
124
-
125
- Common tokens:
126
-
127
- - --ac-primary
128
- - --ac-radius
129
- - --ac-overlay
130
- - --ac-surface
131
- - --ac-border
132
- - --ac-text
133
-
134
- ---
135
-
136
- # 📐 Design Principles
137
-
138
- - Domain-agnostic
139
- - Strongly typed configuration
140
- - Projection-based extensibility
141
- - Composable architecture
142
- - Enterprise-ready scalability
143
- - Minimal coupling
144
-
145
- ---
146
-
147
- # 🔮 Future Enhancements
148
-
149
- - Animation support
150
- - Accessibility improvements
151
- - Storybook documentation
152
- - Public API documentation
153
- - Context generics support
1
+ **b2b-tools** is an Angular 21 standalone component library for enterprise UIs. Zero runtime dependencies beyond Angular itself. Signals-based reactivity, strict TypeScript, and full CSS variable theming.
2
+
3
+ [![Angular](https://img.shields.io/badge/Angular-21-red?logo=angular)](https://angular.io/)
4
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
5
+ [![npm version](https://img.shields.io/npm/v/b2b-tools.svg)](https://www.npmjs.com/package/b2b-tools)
6
+ [![Build Status](https://img.shields.io/badge/build-passing-brightgreen)](#)
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.