quang 20.1.8 → 20.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.
@@ -4,35 +4,103 @@ The `QuangInputComponent` must be configured using the `componentType` input pro
4
4
 
5
5
  ## Supported Types
6
6
 
7
- - text
8
- - textarea
9
- - password
10
- - email
11
- - number
12
- - url
13
- - search
14
- - tel
15
- - color
7
+ The component supports the following input types, each with specific behaviors and configurations:
8
+
9
+ ### Text Input Types
10
+
11
+ - **text** — Standard text input for general text entry
12
+ - **email** — Email input with built-in email validation
13
+ - **password** — Password input with optional show/hide toggle functionality
14
+ - **url** — URL input with URL format validation
15
+ - **search** — Search input with native search behavior
16
+ - **tel** — Telephone number input
17
+
18
+ ### Numeric Input Types
19
+
20
+ - **number** — Numeric input with step controls and min/max validation
21
+
22
+ ### Special Input Types
23
+
24
+ - **textarea** — Multi-line text input with resizable functionality
25
+ - **color** — Color picker input
26
+
27
+ ### Type-Specific Features
28
+
29
+ #### Textarea (`componentType="textarea"`)
30
+
31
+ - **Multi-line support**: Automatically expands for content
32
+ - **Resizable control**: Use `resizable` input to enable/disable manual resizing
33
+ - **No min/max number constraints**: Number-related inputs are ignored
34
+
35
+ #### Password (`componentType="password"`)
36
+
37
+ - **Toggle visibility**: Built-in show/hide password functionality
38
+ - **Icon support**: Custom icons through content projection
39
+ - **Security**: Masks input by default, reveals on toggle
40
+
41
+ #### Number (`componentType="number"`)
42
+
43
+ - **Step controls**: Use `componentStep` to define increment/decrement values
44
+ - **Range validation**: Set `minNumber` and `maxNumber` for value constraints
45
+ - **Decimal support**: Supports decimal values when step allows
46
+
47
+ #### Email (`componentType="email"`)
48
+
49
+ - **Format validation**: Automatic email format validation
50
+ - **Autocomplete**: Enhanced with email-specific autocomplete
51
+
52
+ #### Search (`componentType="search"`)
53
+
54
+ - **Clear button**: Native clear functionality on supported browsers
55
+ - **Search behavior**: Platform-specific search enhancements
16
56
 
17
57
  ## Inputs
18
58
 
59
+ ### Core Configuration
60
+
19
61
  - `componentType`: `'text' | 'textarea' | 'password' | 'email' | 'number' | 'url' | 'search' | 'tel' | 'color'` — Specifies the type of input. **(Required)**
20
- - `maxLengthText`: `number | null` — Maximum length for text input.
21
- - `minLengthText`: `number | null` — Minimum length for text input.
22
- - `minNumber`: `number | undefined` — Minimum value for number input.
23
- - `maxNumber`: `number | undefined` — Maximum value for number input.
24
- - `componentStep`: `number` — Step for number input. Default: `1`.
25
- - `resizable`: `boolean` — If false, disables textarea resizing. Default: `true` (only for textarea).
26
- - All standard form/label/validation-related inputs inherited from `QuangBaseComponent`:
27
- - `isReadonly`, `componentLabel`, `componentPlaceholder`, `componentTabIndex`, `componentClass`, `errorMap`, `successMessage`, `helpMessage`, `formControl`
62
+
63
+ ### Text-Specific Inputs
64
+
65
+ - `maxLengthText`: `number | null` — Maximum length for text input. Applies to: `text`, `textarea`, `email`, `password`, `url`, `search`, `tel`
66
+ - `minLengthText`: `number | null` — Minimum length for text input. Applies to: `text`, `textarea`, `email`, `password`, `url`, `search`, `tel`
67
+
68
+ ### Number-Specific Inputs
69
+
70
+ - `minNumber`: `number | undefined` — Minimum value for number input. **Only applies to**: `number`
71
+ - `maxNumber`: `number | undefined` — Maximum value for number input. **Only applies to**: `number`
72
+ - `componentStep`: `number` — Step increment for number input. Default: `1`. **Only applies to**: `number`
73
+
74
+ ### Textarea-Specific Inputs
75
+
76
+ - `resizable`: `boolean` — Controls textarea resizing behavior. Default: `true`
77
+
78
+ ### Password-Specific Inputs
79
+
80
+ - `showHidePasswordButton`: `boolean` — Shows/hides the password toggle button. Default: `true`. **Only applies to**: `password`
81
+ - `buttonClass`: `string` — Additional CSS classes for the password toggle button. **Only applies to**: `password`
82
+
83
+ ### Universal Inputs
84
+
85
+ - `isReadonly`: `boolean` — Makes the input read-only
86
+ - `componentLabel`: `string` — Label text (supports i18n keys)
87
+ - `componentPlaceholder`: `string` — Placeholder text (supports i18n keys)
88
+ - `componentTabIndex`: `number` — Tab index for accessibility
89
+ - `componentClass`: `string` — Additional CSS classes for the input element
90
+ - `errorMap`: `Record<string, any>` — Validation error messages
91
+ - `successMessage`: `string` — Success message text
92
+ - `helpMessage`: `string` — Help text displayed below the input
93
+ - `formControl`: `FormControl` — Angular reactive form control
28
94
 
29
95
  ## Outputs
30
96
 
31
- - All standard outputs inherited from `QuangBaseComponent`:
32
- - `componentBlur`
97
+ - `showPassword`: `EventEmitter<boolean>` Emitted when the password visibility is toggled (password inputs only)
98
+ - `componentBlur`: `EventEmitter<void>` — Emitted when input loses focus
33
99
 
34
100
  ## Usage
35
101
 
102
+ ### Basic Text Input
103
+
36
104
  ```html
37
105
  <quang-input
38
106
  [errorMap]="errors()"
@@ -40,19 +108,75 @@ The `QuangInputComponent` must be configured using the `componentType` input pro
40
108
  componentType="text"
41
109
  formControlName="testInput"
42
110
  />
111
+ ```
112
+
113
+ ### Password Input with Toggle
114
+
115
+ ```html
116
+ <quang-input
117
+ [errorMap]="errors()"
118
+ [showHidePasswordButton]="true"
119
+ (showPassword)="onToggleShowPassword($event)"
120
+ componentLabel="form.label.password"
121
+ componentType="password"
122
+ formControlName="password"
123
+ >
124
+ @if (showPassword()) {
125
+ <svg-icon src="assets/icons/svg/visibility_off.svg" />
126
+ } @else {
127
+ <svg-icon src="assets/icons/svg/visibility.svg" />
128
+ }
129
+ </quang-input>
130
+ ```
131
+
132
+ #### TypeScript Example
133
+
134
+ ```typescript
135
+ export class MyComponent {
136
+ showPassword = signal<boolean>(false)
137
+
138
+ onToggleShowPassword(isVisible: boolean): void {
139
+ this.showPassword.set(isVisible)
140
+ }
141
+
142
+ errors(): Record<string, any> {
143
+ return this.form.get('password')?.errors ?? {}
144
+ }
145
+ }
146
+ ```
147
+
148
+ ### Number Input with Constraints
43
149
 
150
+ ```html
44
151
  <quang-input
152
+ [componentStep]="5"
45
153
  [errorMap]="errors()"
46
- [isReadonly]="isReadonly()"
47
- [maxNumber]="10"
154
+ [maxNumber]="100"
48
155
  [minNumber]="0"
49
- componentLabel="form.label.input"
156
+ componentLabel="form.label.quantity"
50
157
  componentType="number"
51
- formControlName="testInput"
52
- successMessage="form.label.success"
158
+ formControlName="quantity"
53
159
  />
54
160
  ```
55
161
 
56
- ## Notes
162
+ ### Textarea
163
+
164
+ ```html
165
+ <quang-input
166
+ [errorMap]="errors()"
167
+ [maxLengthText]="500"
168
+ componentLabel="form.label.description"
169
+ componentType="textarea"
170
+ formControlName="description"
171
+ />
172
+ ```
173
+
174
+ ### Type-Specific Features
175
+
176
+ The component supports various input types with specific behaviors:
57
177
 
58
- This component extends the `QuangBaseComponent` and inherits its features, such as label and validation messages.
178
+ - **text, email, url, search, tel**: Support text length constraints
179
+ - **password**: Built-in show/hide toggle functionality with icon support
180
+ - **number**: Step controls and min/max validation
181
+ - **textarea**: Multi-line support with resizable control
182
+ - **color**: Color picker input
@@ -10,9 +10,15 @@ declare class QuangInputComponent extends QuangBaseComponent<string | number> {
10
10
  maxNumber: _angular_core.InputSignal<number | undefined>;
11
11
  componentStep: _angular_core.InputSignal<number>;
12
12
  resizable: _angular_core.InputSignal<boolean>;
13
+ buttonClass: _angular_core.InputSignal<string>;
14
+ showHidePasswordButton: _angular_core.InputSignal<boolean>;
15
+ showPassword: _angular_core.OutputEmitterRef<boolean>;
16
+ private onShowPassword;
17
+ componentInputType: _angular_core.Signal<InputType>;
13
18
  constructor();
19
+ onTogglePasswordVisibility(): void;
14
20
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<QuangInputComponent, never>;
15
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<QuangInputComponent, "quang-input", never, { "componentType": { "alias": "componentType"; "required": true; "isSignal": true; }; "maxLengthText": { "alias": "maxLengthText"; "required": false; "isSignal": true; }; "minLengthText": { "alias": "minLengthText"; "required": false; "isSignal": true; }; "minNumber": { "alias": "minNumber"; "required": false; "isSignal": true; }; "maxNumber": { "alias": "maxNumber"; "required": false; "isSignal": true; }; "componentStep": { "alias": "componentStep"; "required": false; "isSignal": true; }; "resizable": { "alias": "resizable"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
21
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<QuangInputComponent, "quang-input", never, { "componentType": { "alias": "componentType"; "required": true; "isSignal": true; }; "maxLengthText": { "alias": "maxLengthText"; "required": false; "isSignal": true; }; "minLengthText": { "alias": "minLengthText"; "required": false; "isSignal": true; }; "minNumber": { "alias": "minNumber"; "required": false; "isSignal": true; }; "maxNumber": { "alias": "maxNumber"; "required": false; "isSignal": true; }; "componentStep": { "alias": "componentStep"; "required": false; "isSignal": true; }; "resizable": { "alias": "resizable"; "required": false; "isSignal": true; }; "buttonClass": { "alias": "buttonClass"; "required": false; "isSignal": true; }; "showHidePasswordButton": { "alias": "showHidePasswordButton"; "required": false; "isSignal": true; }; }, { "showPassword": "showPassword"; }, never, ["*"], true, never>;
16
22
  }
17
23
 
18
24
  export { QuangInputComponent };
@@ -1,43 +1,67 @@
1
1
  # QuangPaginatorComponent
2
2
 
3
- The `QuangPaginatorComponent` provides controls for navigating through pages of data, supporting configurations for total items, items per page, and current page.
4
-
5
- ## Features
6
-
7
- - Pagination controls
8
- - Configurable total items, items per page, and current page
9
- - Emits events for page changes
3
+ The `QuangPaginatorComponent` is a pagination control that provides navigation through large datasets with configurable page sizes and internationalization support.
10
4
 
11
5
  ## Inputs
12
6
 
13
- - `page`: `number` — Current page number. **(Required)**
14
- - `pageSize`: `number` — Number of items per page. **(Required)**
15
- - `sizeList`: `number[]` — List of selectable page sizes. Default: `[]`.
16
- - `totalItems`: `number` — Total number of items to paginate. **(Required)**
17
- - `showTotalElementsCount`: `boolean` — Show/hide total items count. Default: `true`.
18
- - `totalItemsText`: `string` — Translation key for total items label. Default: `'quangPaginator.totalItems'`.
19
- - `sizeText`: `string` — Translation key for size label. Default: `'quangPaginator.size'`.
20
- - `pageRangeText`: `string` — Translation key for page range label. Default: `'quangPaginator.pageRange'`. If the translation is overwritten, it should contain `{{page}}` and `{{amountPages}}` placeholders to display the correct numeric values.
21
- - `componentId`, `componentTabIndex`, `componentClass`: Standard component inputs.
7
+ - `page`: `number` — Current active page number (1-based indexing). **(Required)**
8
+ - `pageSize`: `number` — Number of items displayed per page. **(Required)**
9
+ - `totalItems`: `number` — Total number of items in the dataset. **(Required)**
10
+ - `sizeList`: `number[]` — Array of available page size options for user selection. Default: `[]`
11
+ - `showTotalElementsCount`: `boolean` — Controls visibility of total items count display. Default: `true`
12
+ - `totalItemsText`: `string` — Translation key for total items label text. Default: `'quangPaginator.totalItems'`
13
+ - `sizeText`: `string` — Translation key for page size selector label. Default: `'quangPaginator.size'`
14
+ - `pageRangeText`: `string` — Translation key for page range display. Must include `{{page}}` and `{{amountPages}}` placeholders. Default: `'quangPaginator.pageRange'`
15
+ - `componentId`: `string` Unique identifier for the paginator instance
16
+ - `componentTabIndex`: `number` — Base tab index for paginator controls. Default: `0`
17
+ - `componentClass`: `string | string[]` — Additional CSS classes for styling customization
22
18
 
23
19
  ## Outputs
24
20
 
25
- - `changePage`: Emits the new page number when the user navigates to a different page.
26
- - `changeSize`: Emits the new page size when the user changes it.
21
+ - `changePage`: `EventEmitter<number>` Emitted when user navigates to a different page
22
+ - `changeSize`: `EventEmitter<number>` Emitted when user changes the page size
27
23
 
28
24
  ## Usage
29
25
 
26
+ ### Basic Paginator
27
+
30
28
  ```html
31
29
  <quang-paginator
32
- [page]="1"
33
- [pageSize]="10"
34
- [sizeList]="[5, 10, 20]"
35
- [totalItems]="30"
36
- (changePage)="onChangePage($event)"
37
- (changeSize)="onChangePageSize($event)"
38
- />
30
+ [page]="currentPage"
31
+ [pageSize]="itemsPerPage"
32
+ [totalItems]="totalItemCount"
33
+ (changePage)="onPageChange($event)"
34
+ (changeSize)="onPageSizeChange($event)"
35
+ >
36
+ </quang-paginator>
39
37
  ```
40
38
 
41
- ## Notes
39
+ #### TypeScript Example
40
+
41
+ ```typescript
42
+ export class MyComponent {
43
+ currentPage = 1
44
+ itemsPerPage = 20
45
+ totalItemCount = 150
46
+
47
+ onPageChange(page: number): void {
48
+ this.currentPage = page
49
+ // Load data for new page
50
+ }
51
+
52
+ onPageSizeChange(pageSize: number): void {
53
+ this.itemsPerPage = pageSize
54
+ this.currentPage = 1 // Reset to first page
55
+ // Load data with new page size
56
+ }
57
+ }
58
+ ```
59
+
60
+ ### Translation Integration
61
+
62
+ The component uses QuangTranslationService for all text content:
42
63
 
43
- This component provides a user-friendly interface for pagination in lists and tables.
64
+ - **Default Keys**: Uses `quangPaginator.*` translation keys
65
+ - **Custom Override**: All text keys can be overridden via inputs
66
+ - **Placeholder Support**: Page range text supports `{{page}}` and `{{amountPages}}` placeholders
67
+ - **Dynamic Translation**: Responds to language changes automatically
@@ -2,53 +2,43 @@
2
2
 
3
3
  The `QuangSelectComponent` supports single or multiple selections from a dropdown list.
4
4
 
5
- ## Features
5
+ ## Input
6
6
 
7
- - Single selection
8
- - Multiple selection
9
- - Customizable options
7
+ - `selectOptions`: `SelectOption[]` - Array of options to display in the dropdown (required)
8
+ - `selectionMode`: `'single' | 'multiple'` - Selection mode (default: 'single')
10
9
 
11
- ## Inputs
10
+ All standard inputs inherited from `QuangBaseComponent`: `isReadonly`, `componentLabel`, `componentPlaceholder`, `componentTabIndex`, `componentClass`, `errorMap`, `successMessage`, `helpMessage`, `formControl`
12
11
 
13
- - `selectOptions`: `SelectOption[]` — Array of options to display in the dropdown. **(Required)**
14
- - `selectionMode`: `'single' | 'multiple'` — Enables single or multiple selection mode. Default: `'single'`.
15
- - All standard form/label/validation-related inputs inherited from `QuangBaseComponent`:
16
- - `isReadonly`, `componentLabel`, `componentPlaceholder`, `componentTabIndex`, `componentClass`, `errorMap`, `successMessage`, `helpMessage`, `formControl`
12
+ ## Output
17
13
 
18
- ## Outputs
19
-
20
- - All standard outputs inherited from `QuangBaseComponent`:
21
- - `componentBlur`
14
+ All standard outputs inherited from `QuangBaseComponent`: `componentBlur`
22
15
 
23
16
  ## Usage
24
17
 
18
+ ### Single Selection
25
19
  ```html
26
20
  <quang-select
27
21
  [errorMap]="errors()"
28
- [isReadonly]="isReadonly()"
29
22
  [selectOptions]="stringList"
30
- class="col-4"
31
23
  componentLabel="form.label.select"
32
- componentPlaceholder="Placeholder select singola scelta"
24
+ componentPlaceholder="Select an option"
33
25
  formControlName="testInput"
34
- playgroundSourceCode
35
- selectionMode="single"
36
- successMessage="form.label.success"
37
- />
26
+ selectionMode="single">
27
+ </quang-select>
28
+ ```
38
29
 
30
+ ### Multiple Selection
31
+ ```html
39
32
  <quang-select
40
33
  [errorMap]="errors()"
41
- [isReadonly]="isReadonly()"
42
34
  [selectOptions]="numberList"
43
- class="col-4"
44
35
  componentLabel="form.label.multipleSelect"
45
- componentPlaceholder="Placeholder select scelta multipla"
36
+ componentPlaceholder="Select multiple options"
46
37
  formControlName="testInputMultiple"
47
- selectionMode="multiple"
48
- successMessage="form.label.success"
49
- />
38
+ selectionMode="multiple">
39
+ </quang-select>
50
40
  ```
51
41
 
52
- ## Notes
42
+ ## QuangTranslationService Integration
53
43
 
54
- This component extends the `QuangBaseComponent` and inherits its features, such as label and validation messages.
44
+ The component supports automatic translation of all labels, help messages, and error messages through `QuangTranslationService`.
@@ -1,24 +1,90 @@
1
1
  # QuangTableComponent
2
2
 
3
- The `QuangTableComponent` allows for displaying data in a tabular format.
3
+ The `QuangTableComponent` allows for displaying data in a tabular format with advanced features for customization, sorting, and row selection.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - Tabular data display
8
8
  - Customizable headers and rows
9
- - Supports sorting and filtering
9
+ - Supports sorting by columns
10
+ - Custom cell rendering with templates
11
+ - Row selection and highlighting
12
+ - Sticky header option
13
+
14
+ ## Interfaces
15
+
16
+ ### TableConfiguration<T>
17
+ ```typescript
18
+ interface TableConfiguration<T> {
19
+ headers: TableHeader[];
20
+ rows: TableRow<T>[];
21
+ }
22
+ ```
23
+
24
+ ### TableHeader
25
+ ```typescript
26
+ interface TableHeader {
27
+ text?: string; // Display text for the header
28
+ sort?: SortCol; // Sort configuration for the column
29
+ css?: string[]; // CSS classes to apply to the header
30
+ renderer?: TemplateRef<any>; // Custom template for header rendering
31
+ payload?: any; // Additional data that can be used in custom renderers
32
+ }
33
+ ```
34
+
35
+ ### TableRow<T>
36
+ ```typescript
37
+ interface TableRow<T> {
38
+ payload?: T; // The data object for this row
39
+ rowId?: string | number; // Unique identifier for the row
40
+ css?: string[]; // CSS classes to apply to the row
41
+ cellData: TableCell[]; // Array of cells in this row
42
+ }
43
+ ```
44
+
45
+ ### TableCell
46
+ ```typescript
47
+ interface TableCell {
48
+ renderer?: TemplateRef<any>; // Custom template for cell rendering
49
+ payload?: any; // Additional data that can be used in custom renderers
50
+ text?: string; // Display text for the cell
51
+ css?: string[]; // CSS classes to apply to the cell
52
+ fullWidth?: boolean; // Whether the cell should span the full width
53
+ }
54
+ ```
55
+
56
+ ### SortCol
57
+ ```typescript
58
+ interface SortCol {
59
+ key: string; // Identifier for the column
60
+ sort: SortTable; // Sort direction (DEFAULT, ASC, DESC)
61
+ }
62
+ ```
10
63
 
11
64
  ## Inputs
12
65
 
13
- - `tableConfigurations`: `{ headers: TableHeader[]; rows: any[] }` — Table configuration object containing headers and rows. **(Required)**
14
- - `stickyTable`: `boolean` Enables sticky header/columns. Default: `false`.
15
- - All standard form/label/validation-related inputs inherited from `QuangBaseComponent` (if applicable):
16
- - `isReadonly`, `componentLabel`, `componentPlaceholder`, `componentTabIndex`, `componentClass`, `errorMap`, `successMessage`, `helpMessage`, `formControl`
66
+ - `tableConfigurations`: `TableConfiguration<T>` — Table configuration object containing headers and rows. **(Required)**
67
+ - This object defines the structure and data of your table.
68
+
69
+ - `clickableRow`: `boolean` Whether rows should be clickable. Default: `false`.
70
+ - When true, clicking a row will emit the row data through the `selectedRow` output.
71
+
72
+ - `selectedRows`: `string[] | number[]` — Array of rowIds that should be marked as selected.
73
+ - Use this to highlight specific rows in the table.
74
+
75
+ - `stickyTable`: `boolean` — Enables sticky header. Default: `true`.
76
+ - When true, the header will remain visible when scrolling.
77
+
78
+ - `noResultsText`: `string` — Text to display when no data is available. Default: 'quangTable.noResults'.
79
+ - This supports translation keys if using transloco.
17
80
 
18
81
  ## Outputs
19
82
 
20
- - `sortChanged`: Emits the sort state when the user changes sorting.
21
- - `rowClick`: Emits the clicked row data when a row is clicked.
83
+ - `sortChanged`: `EventEmitter<SortCol[]>` Emits when the user changes the sorting of a column.
84
+ - Returns an array of SortCol objects with the updated sorting state.
85
+
86
+ - `selectedRow`: `EventEmitter<TableRow<T>>` — Emits when a row is clicked (if clickableRow is true).
87
+ - Returns the full row data including payload.
22
88
 
23
89
  ## Usage
24
90
 
@@ -26,38 +92,148 @@ The `QuangTableComponent` allows for displaying data in a tabular format.
26
92
 
27
93
  ```html
28
94
  <quang-table
29
- [stickyTable]="true"
30
95
  [tableConfigurations]="tableConfig()"
96
+ [clickableRow]="true"
97
+ [stickyTable]="true"
98
+ [selectedRows]="selectedRowIds()"
99
+ (selectedRow)="onRowClick($event)"
31
100
  (sortChanged)="onChangeSort($event)"
32
- (rowClick)="onRowClick($event)"
33
101
  />
34
102
  ```
35
103
 
36
104
  ### TypeScript
37
105
 
38
106
  ```typescript
39
- import { computed, signal } from '@angular/core'
107
+ import { Component, signal, computed } from '@angular/core';
108
+ import {
109
+ TableConfiguration,
110
+ TableHeader,
111
+ TableRow,
112
+ TableCell,
113
+ SortTable,
114
+ SortCol
115
+ } from 'quang/components/table';
116
+
117
+ @Component({
118
+ selector: 'app-example',
119
+ templateUrl: './example.component.html',
120
+ })
121
+ export class ExampleComponent {
122
+ // Sample data
123
+ userData = signal([
124
+ { id: 1, name: 'John Doe', email: 'john@example.com', age: 30 },
125
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 25 },
126
+ { id: 3, name: 'Alice Johnson', email: 'alice@example.com', age: 35 },
127
+ ]);
128
+
129
+ selectedRowIds = signal<number[]>([1]); // Row with ID 1 will be highlighted
130
+
131
+ // Define headers
132
+ tableHeaders = [
133
+ {
134
+ text: 'ID',
135
+ sort: { key: 'id', sort: SortTable.DEFAULT }
136
+ },
137
+ {
138
+ text: 'Name',
139
+ sort: { key: 'name', sort: SortTable.DEFAULT }
140
+ },
141
+ {
142
+ text: 'Email',
143
+ sort: { key: 'email', sort: SortTable.DEFAULT }
144
+ },
145
+ {
146
+ text: 'Age',
147
+ sort: { key: 'age', sort: SortTable.DEFAULT }
148
+ }
149
+ ];
150
+
151
+ // Compute rows from data
152
+ tableRows = computed(() =>
153
+ this.userData().map(user => ({
154
+ rowId: user.id,
155
+ payload: user,
156
+ cellData: [
157
+ { text: user.id.toString() },
158
+ { text: user.name },
159
+ { text: user.email },
160
+ { text: user.age.toString() }
161
+ ]
162
+ }))
163
+ );
164
+
165
+ // Combine headers and rows into table configuration
166
+ tableConfig = computed<TableConfiguration<any>>(() => ({
167
+ headers: this.tableHeaders,
168
+ rows: this.tableRows()
169
+ }));
170
+
171
+ onRowClick(row: TableRow<any>): void {
172
+ console.log('Row clicked:', row.payload);
173
+ }
174
+
175
+ onChangeSort(sortCols: SortCol[]): void {
176
+ const sortCol = sortCols[0];
177
+ const sortDirection = sortCol.sort;
178
+
179
+ // Sort data based on column and direction
180
+ this.userData.update(users => {
181
+ return [...users].sort((a, b) => {
182
+ if (sortDirection === SortTable.DEFAULT) {
183
+ return 0;
184
+ }
185
+
186
+ const modifier = sortDirection === SortTable.ASC ? 1 : -1;
187
+ const aValue = a[sortCol.key];
188
+ const bValue = b[sortCol.key];
189
+
190
+ if (aValue < bValue) return -1 * modifier;
191
+ if (aValue > bValue) return 1 * modifier;
192
+ return 0;
193
+ });
194
+ });
195
+ }
196
+ }
197
+ ```
198
+
199
+ ## Advanced Usage with Custom Templates
40
200
 
41
- // Angular signals for table data and headers
201
+ You can use templates to customize cell rendering:
42
202
 
43
- tableRows = signal([
44
- { id: 1, name: 'John Doe', age: 30 },
45
- { id: 2, name: 'Jane Smith', age: 25 },
46
- { id: 3, name: 'Alice Johnson', age: 35 },
47
- ])
203
+ ```html
204
+ <ng-template #nameTemplate let-data>
205
+ <strong>{{ data.name }}</strong>
206
+ </ng-template>
48
207
 
49
- tableHeaders = [
50
- { key: 'id', label: 'ID', sortable: true },
51
- { key: 'name', label: 'Name', sortable: true },
52
- { key: 'age', label: 'Age', sortable: false },
53
- ]
208
+ <quang-table [tableConfigurations]="customTableConfig()">
209
+ </quang-table>
210
+ ```
54
211
 
55
- tableConfig = computed(() => ({
56
- headers: tableHeaders,
57
- rows: tableRows(),
212
+ ```typescript
213
+ nameTemplate = TemplateRef<ane>('nameTemplate')
214
+
215
+ customTableConfig = computed(() => ({
216
+ headers: [
217
+ { text: 'ID' },
218
+ { text: 'Name', renderer: this.nameTemplate },
219
+ { text: 'Email' },
220
+ { text: 'Age' }
221
+ ],
222
+ rows: this.userData().map(user => ({
223
+ rowId: user.id,
224
+ payload: user,
225
+ cellData: [
226
+ { text: user.id.toString() },
227
+ { payload: user }, // This will be accessible in the template
228
+ { text: user.email },
229
+ { text: user.age.toString() }
230
+ ]
231
+ }))
58
232
  }))
59
233
  ```
60
234
 
61
235
  ## Notes
62
236
 
63
- This component is highly customizable and can be styled to match your application's design.
237
+ - The table automatically adjusts column widths to match content.
238
+ - Use CSS classes to customize the appearance of specific rows, headers, or cells.
239
+ - For responsive tables, consider setting appropriate container widths.