@verisoft/ui-core 19.0.0-rc001 → 20.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +48 -0
- package/README.md +314 -3
- package/jest.config.ts +21 -0
- package/ng-package.json +11 -0
- package/package.json +16 -31
- package/project.json +36 -0
- package/{index.d.ts → src/index.ts} +1 -1
- package/src/lib/common/angular-helper.ts +44 -0
- package/src/lib/common/constants.ts +5 -0
- package/src/lib/common/control.models.ts +80 -0
- package/src/lib/common/datasource-component.model.spec.ts +42 -0
- package/src/lib/common/datasource-component.model.ts +43 -0
- package/{lib/common/deactivate-guard.model.d.ts → src/lib/common/deactivate-guard.model.ts} +2 -1
- package/src/lib/common/download-file.ts +20 -0
- package/src/lib/common/filter.ts +7 -0
- package/{lib/common/icons.d.ts → src/lib/common/icons.ts} +34 -34
- package/{lib/common/index.d.ts → src/lib/common/index.ts} +10 -10
- package/{lib/common/notificable-property.model.d.ts → src/lib/common/notificable-property.model.ts} +5 -4
- package/src/lib/common/rxjs.spec.ts +58 -0
- package/src/lib/common/rxjs.ts +21 -0
- package/src/lib/components/action-button-group/action-button-group.model.ts +15 -0
- package/src/lib/components/action-button-group/action-button.model.ts +15 -0
- package/{lib/components/action-button-group/index.d.ts → src/lib/components/action-button-group/index.ts} +2 -2
- package/src/lib/components/base-form/base-form-input.component.ts +120 -0
- package/src/lib/components/base-form/base-form.component.ts +236 -0
- package/src/lib/components/base-form/directives/detail-store.directive.ts +219 -0
- package/{lib/components/base-form/index.d.ts → src/lib/components/base-form/index.ts} +2 -2
- package/src/lib/components/base-form/models/base-form-input.models.ts +11 -0
- package/src/lib/components/base-form/models/base-form.models.ts +31 -0
- package/{lib/components/base-form/models/index.d.ts → src/lib/components/base-form/models/index.ts} +1 -1
- package/{lib/components/breadcrumb/breadcrumb.model.d.ts → src/lib/components/breadcrumb/breadcrumb.model.ts} +6 -1
- package/src/lib/components/breadcrumb/breadcrumb.service.ts +9 -0
- package/src/lib/components/breadcrumb/breadcrumbcore.component.ts +117 -0
- package/src/lib/components/breadcrumb/index.ts +3 -0
- package/{lib/components/button/button.model.d.ts → src/lib/components/button/button.model.ts} +5 -1
- package/src/lib/components/button/index.ts +1 -0
- package/{lib/components/calendar/calendar.model.d.ts → src/lib/components/calendar/calendar.model.ts} +6 -2
- package/src/lib/components/calendar/index.ts +1 -0
- package/{lib/components/checkbox/checkbox.model.d.ts → src/lib/components/checkbox/checkbox.model.ts} +5 -1
- package/src/lib/components/checkbox/index.ts +1 -0
- package/src/lib/components/confirm-dialog/confirm-dialog.model.ts +31 -0
- package/src/lib/components/confirm-dialog/index.ts +1 -0
- package/{lib/components/dropdown/dropdown.model.d.ts → src/lib/components/dropdown/dropdown.model.ts} +5 -1
- package/src/lib/components/dropdown/index.ts +1 -0
- package/{lib/components/dropdown-button/dropdown-button.model.d.ts → src/lib/components/dropdown-button/dropdown-button.model.ts} +18 -14
- package/src/lib/components/dropdown-button/index.ts +1 -0
- package/src/lib/components/dynamic-component/dynamic-component.model.ts +2 -0
- package/src/lib/components/dynamic-component/index.ts +1 -0
- package/src/lib/components/filter/filter.model.ts +17 -0
- package/{lib/components/filter/index.d.ts → src/lib/components/filter/index.ts} +1 -1
- package/{lib/components/form-field/form-field.model.d.ts → src/lib/components/form-field/form-field.model.ts} +6 -2
- package/src/lib/components/form-field/index.ts +1 -0
- package/{lib/components/generic-field/generic-field.model.d.ts → src/lib/components/generic-field/generic-field.model.ts} +5 -1
- package/src/lib/components/generic-field/index.ts +1 -0
- package/src/lib/components/generic-form/generic-form.component.ts +33 -0
- package/{lib/components/generic-form/index.d.ts → src/lib/components/generic-form/index.ts} +1 -1
- package/{lib/components/header/header.model.d.ts → src/lib/components/header/header.model.ts} +9 -2
- package/src/lib/components/header/index.ts +1 -0
- package/src/lib/components/icons/icons.component.ts +22 -0
- package/src/lib/components/icons/icons.model.ts +16 -0
- package/src/lib/components/icons/index.ts +2 -0
- package/{lib/components/index.d.ts → src/lib/components/index.ts} +2 -0
- package/src/lib/components/input-group/index.ts +1 -0
- package/{lib/components/input-group/input-group.model.d.ts → src/lib/components/input-group/input-group.model.ts} +7 -2
- package/src/lib/components/loader/index.ts +1 -0
- package/src/lib/components/loader/loader.model.ts +7 -0
- package/src/lib/components/multiselect/index.ts +1 -0
- package/{lib/components/multiselect/mutiselect.model.d.ts → src/lib/components/multiselect/mutiselect.model.ts} +6 -2
- package/src/lib/components/number-input/index.ts +1 -0
- package/{lib/components/number-input/number-input.model.d.ts → src/lib/components/number-input/number-input.model.ts} +6 -2
- package/{lib/components/page-header/index.d.ts → src/lib/components/page-header/index.ts} +1 -1
- package/{lib/components/page-header/page-header.model.d.ts → src/lib/components/page-header/page-header.model.ts} +5 -1
- package/src/lib/components/page-header/page-header.service.ts +9 -0
- package/src/lib/components/page-header/page-headercore.component.ts +42 -0
- package/src/lib/components/password/index.ts +1 -0
- package/{lib/components/password/password.model.d.ts → src/lib/components/password/password.model.ts} +9 -3
- package/src/lib/components/radiobutton/index.ts +1 -0
- package/{lib/components/radiobutton/radiobutton.model.d.ts → src/lib/components/radiobutton/radiobutton.model.ts} +8 -3
- package/src/lib/components/section/index.ts +1 -0
- package/{lib/components/section/section.model.d.ts → src/lib/components/section/section.model.ts} +6 -2
- package/src/lib/components/side-menu/directives/side-menu-service.directive.ts +31 -0
- package/{lib/components/side-menu/index.d.ts → src/lib/components/side-menu/index.ts} +1 -1
- package/src/lib/components/side-menu/services/side-menu-provider.service.ts +13 -0
- package/src/lib/components/side-menu/services/side-menu.service.ts +62 -0
- package/src/lib/components/side-menu/side-menu.model.ts +67 -0
- package/src/lib/components/slider/index.ts +1 -0
- package/{lib/components/slider/slider.model.d.ts → src/lib/components/slider/slider.model.ts} +6 -2
- package/src/lib/components/snackbar/index.ts +1 -0
- package/src/lib/components/snackbar/snackbar.model.ts +7 -0
- package/src/lib/components/stepper/index.ts +1 -0
- package/{lib/components/stepper/stepper.model.d.ts → src/lib/components/stepper/stepper.model.ts} +10 -5
- package/src/lib/components/switch/index.ts +1 -0
- package/src/lib/components/switch/switch.model.ts +8 -0
- package/src/lib/components/tab-view/index.ts +1 -0
- package/{lib/components/tab-view/tab-view.model.d.ts → src/lib/components/tab-view/tab-view.model.ts} +8 -3
- package/src/lib/components/table/column-configuration.ts +38 -0
- package/src/lib/components/table/table-builder.ts +93 -0
- package/src/lib/components/table/table-column.directive.ts +62 -0
- package/src/lib/components/table/table.models.ts +261 -0
- package/src/lib/components/table-filter/index.ts +1 -0
- package/{lib/components/table-filter/table-filter.model.d.ts → src/lib/components/table-filter/table-filter.model.ts} +6 -1
- package/src/lib/components/tag/index.ts +1 -0
- package/src/lib/components/tag/tag.model.ts +13 -0
- package/src/lib/components/textarea/index.ts +1 -0
- package/{lib/components/textarea/textarea.model.d.ts → src/lib/components/textarea/textarea.model.ts} +5 -1
- package/src/lib/components/textfield/index.ts +1 -0
- package/{lib/components/textfield/textfield.model.d.ts → src/lib/components/textfield/textfield.model.ts} +6 -2
- package/src/lib/components/tooltip/index.ts +1 -0
- package/src/lib/components/tooltip/tooltip.model.ts +13 -0
- package/src/lib/components/unsubscribe.component.ts +12 -0
- package/src/lib/directives/datasource.directive.ts +275 -0
- package/{lib/directives/index.d.ts → src/lib/directives/index.ts} +4 -4
- package/src/lib/directives/shortcut.directive.ts +37 -0
- package/src/lib/directives/table-datasource.directive.ts +184 -0
- package/src/lib/directives/table-filter.directive.ts +69 -0
- package/src/lib/format/format.ts +74 -0
- package/src/lib/pipes/error/error.codes.ts +11 -0
- package/src/lib/pipes/error/error.models.ts +27 -0
- package/src/lib/pipes/error/error.pipe.ts +27 -0
- package/src/lib/pipes/error/warning.codes.ts +5 -0
- package/src/lib/pipes/error/warning.pipe.ts +27 -0
- package/src/lib/pipes/helper/enumToList.pipe.ts +16 -0
- package/{lib/pipes/index.d.ts → src/lib/pipes/index.ts} +1 -1
- package/src/lib/pipes/keyOrFn/keyOrFn.pipe.ts +23 -0
- package/src/lib/services/confirm-dialog.service.ts +44 -0
- package/{lib/services/index.d.ts → src/lib/services/index.ts} +4 -4
- package/src/lib/services/leave-form.service.ts +53 -0
- package/src/lib/services/screen-size.service.ts +25 -0
- package/src/lib/services/table.service.ts +22 -0
- package/src/test-setup.ts +8 -0
- package/tsconfig.json +28 -0
- package/tsconfig.lib.json +17 -0
- package/tsconfig.lib.prod.json +9 -0
- package/tsconfig.spec.json +16 -0
- package/fesm2022/verisoft-ui-core.mjs +0 -2013
- package/fesm2022/verisoft-ui-core.mjs.map +0 -1
- package/lib/common/angular-helper.d.ts +0 -1
- package/lib/common/constants.d.ts +0 -3
- package/lib/common/control.models.d.ts +0 -62
- package/lib/common/datasource-component.model.d.ts +0 -19
- package/lib/common/download-file.d.ts +0 -2
- package/lib/common/filter.d.ts +0 -1
- package/lib/common/rxjs.d.ts +0 -2
- package/lib/components/action-button-group/action-button-group.model.d.ts +0 -12
- package/lib/components/action-button-group/action-button.model.d.ts +0 -14
- package/lib/components/base-form/base-form-input.component.d.ts +0 -30
- package/lib/components/base-form/base-form.component.d.ts +0 -50
- package/lib/components/base-form/directives/detail-store.directive.d.ts +0 -35
- package/lib/components/base-form/models/base-form-input.models.d.ts +0 -7
- package/lib/components/base-form/models/base-form.models.d.ts +0 -18
- package/lib/components/breadcrumb/breadcrumb.service.d.ts +0 -8
- package/lib/components/breadcrumb/breadcrumbcore.component.d.ts +0 -30
- package/lib/components/breadcrumb/index.d.ts +0 -3
- package/lib/components/button/index.d.ts +0 -1
- package/lib/components/calendar/index.d.ts +0 -1
- package/lib/components/checkbox/index.d.ts +0 -1
- package/lib/components/confirm-dialog/confirm-dialog.model.d.ts +0 -25
- package/lib/components/confirm-dialog/index.d.ts +0 -1
- package/lib/components/dropdown/index.d.ts +0 -1
- package/lib/components/dropdown-button/index.d.ts +0 -1
- package/lib/components/dynamic-component/dynamic-component.model.d.ts +0 -3
- package/lib/components/dynamic-component/index.d.ts +0 -1
- package/lib/components/filter/filter.model.d.ts +0 -13
- package/lib/components/form-field/index.d.ts +0 -1
- package/lib/components/generic-field/index.d.ts +0 -1
- package/lib/components/generic-form/generic-form.component.d.ts +0 -30
- package/lib/components/header/index.d.ts +0 -1
- package/lib/components/icons/icons.component.d.ts +0 -6
- package/lib/components/icons/icons.model.d.ts +0 -6
- package/lib/components/icons/index.d.ts +0 -2
- package/lib/components/input-group/index.d.ts +0 -1
- package/lib/components/loader/index.d.ts +0 -1
- package/lib/components/loader/loader.model.d.ts +0 -3
- package/lib/components/multiselect/index.d.ts +0 -1
- package/lib/components/number-input/index.d.ts +0 -1
- package/lib/components/page-header/page-header.service.d.ts +0 -8
- package/lib/components/page-header/page-headercore.component.d.ts +0 -20
- package/lib/components/password/index.d.ts +0 -1
- package/lib/components/radiobutton/index.d.ts +0 -1
- package/lib/components/section/index.d.ts +0 -1
- package/lib/components/side-menu/directives/side-menu-service.directive.d.ts +0 -11
- package/lib/components/side-menu/services/side-menu-provider.service.d.ts +0 -10
- package/lib/components/side-menu/services/side-menu.service.d.ts +0 -15
- package/lib/components/side-menu/side-menu.model.d.ts +0 -42
- package/lib/components/slider/index.d.ts +0 -1
- package/lib/components/snackbar/index.d.ts +0 -1
- package/lib/components/snackbar/snackbar.model.d.ts +0 -3
- package/lib/components/stepper/index.d.ts +0 -1
- package/lib/components/switch/index.d.ts +0 -1
- package/lib/components/switch/switch.model.d.ts +0 -4
- package/lib/components/tab-view/index.d.ts +0 -1
- package/lib/components/table/column-configuration.d.ts +0 -12
- package/lib/components/table/table-builder.d.ts +0 -15
- package/lib/components/table/table-column.directive.d.ts +0 -25
- package/lib/components/table/table.models.d.ts +0 -132
- package/lib/components/table-filter/index.d.ts +0 -1
- package/lib/components/textarea/index.d.ts +0 -1
- package/lib/components/textfield/index.d.ts +0 -1
- package/lib/components/unsubscribe.component.d.ts +0 -9
- package/lib/directives/datasource.directive.d.ts +0 -32
- package/lib/directives/shortcut.directive.d.ts +0 -11
- package/lib/directives/table-datasource.directive.d.ts +0 -29
- package/lib/directives/table-filter.directive.d.ts +0 -17
- package/lib/format/format.d.ts +0 -9
- package/lib/pipes/error/error.codes.d.ts +0 -5
- package/lib/pipes/error/error.models.d.ts +0 -8
- package/lib/pipes/error/error.pipe.d.ts +0 -8
- package/lib/pipes/error/warning.codes.d.ts +0 -5
- package/lib/pipes/error/warning.pipe.d.ts +0 -8
- package/lib/pipes/helper/enumToList.pipe.d.ts +0 -7
- package/lib/pipes/keyOrFn/keyOrFn.pipe.d.ts +0 -7
- package/lib/services/confirm-dialog.service.d.ts +0 -12
- package/lib/services/leave-form.service.d.ts +0 -13
- package/lib/services/screen-size.service.d.ts +0 -10
- package/lib/services/table.service.d.ts +0 -13
- /package/{lib/components/table/index.d.ts → src/lib/components/table/index.ts} +0 -0
package/.eslintrc.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": ["../../../.eslintrc.base.json"],
|
|
3
|
+
"ignorePatterns": ["!**/*"],
|
|
4
|
+
"overrides": [
|
|
5
|
+
{
|
|
6
|
+
"files": ["*.ts"],
|
|
7
|
+
"extends": [
|
|
8
|
+
"plugin:@nx/angular",
|
|
9
|
+
"plugin:@angular-eslint/template/process-inline-templates"
|
|
10
|
+
],
|
|
11
|
+
"rules": {
|
|
12
|
+
"@angular-eslint/directive-selector": [
|
|
13
|
+
"error",
|
|
14
|
+
{
|
|
15
|
+
"type": "attribute",
|
|
16
|
+
"prefix": "v",
|
|
17
|
+
"style": "camelCase"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"@angular-eslint/component-selector": [
|
|
21
|
+
"error",
|
|
22
|
+
{
|
|
23
|
+
"type": "element",
|
|
24
|
+
"prefix": "v",
|
|
25
|
+
"style": "kebab-case"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"files": ["*.html"],
|
|
32
|
+
"extends": ["plugin:@nx/angular-template"],
|
|
33
|
+
"rules": {}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"files": ["*.json"],
|
|
37
|
+
"parser": "jsonc-eslint-parser",
|
|
38
|
+
"rules": {
|
|
39
|
+
"@nx/dependency-checks": [
|
|
40
|
+
"error",
|
|
41
|
+
{
|
|
42
|
+
"ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
package/README.md
CHANGED
|
@@ -1,7 +1,318 @@
|
|
|
1
|
-
# ui-core
|
|
1
|
+
# @verisoft/ui-core
|
|
2
2
|
|
|
3
|
-
This library
|
|
3
|
+
A foundational Angular library that provides core UI functionalities, directives, interfaces, and base classes for building consistent user interfaces. This library serves as the architectural foundation for all UI component libraries within the Verisoft ecosystem, offering shared utilities, base components, and common interfaces without implementing concrete UI components.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `@verisoft/ui-core` library provides essential infrastructure and utilities that enable other UI libraries to build consistent, accessible, and well-structured components. It includes base classes, interfaces, directives, services, and utilities that standardize component behavior across the entire Verisoft UI ecosystem.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
### Core Infrastructure
|
|
12
|
+
- **Base Classes**: Abstract base classes for form components, input controls, and lifecycle management
|
|
13
|
+
- **Component Interfaces**: TypeScript interfaces defining component contracts and APIs
|
|
14
|
+
- **Tokens & Providers**: Injection tokens for component registration and dependency injection
|
|
15
|
+
- **Type Definitions**: Comprehensive type definitions for component properties and events
|
|
16
|
+
|
|
17
|
+
### Directives
|
|
18
|
+
- **Form Directives**: Enhanced form behavior, validation helpers, and form state management
|
|
19
|
+
- **Utility Directives**: Common DOM manipulation, event handling, and accessibility helpers
|
|
20
|
+
- **Validation Directives**: Custom validators and validation feedback mechanisms
|
|
21
|
+
|
|
22
|
+
### Services & Utilities
|
|
23
|
+
- **Format Services**: Date, number, currency, and text formatting utilities
|
|
24
|
+
- **Screen Service**: Responsive design utilities and screen size detection
|
|
25
|
+
- **Menu Service**: Navigation and menu state management
|
|
26
|
+
- **Common Services**: Shared utilities for HTTP, storage, and application state
|
|
27
|
+
|
|
28
|
+
### Base Components
|
|
29
|
+
- **UnsubscribeComponent**: Automatic subscription cleanup and memory leak prevention
|
|
30
|
+
- **BaseFormComponent**: Foundation for all form-related functionality
|
|
31
|
+
- **BaseInputComponent**: Core input control behavior and validation integration
|
|
32
|
+
|
|
33
|
+
### Key Features
|
|
34
|
+
- ✅ **Architecture Foundation**: Provides the structural foundation for all UI libraries
|
|
35
|
+
- ✅ **Type Safety**: Full TypeScript support with comprehensive type definitions
|
|
36
|
+
- ✅ **Extensibility**: Designed to be extended by specialized UI component libraries
|
|
37
|
+
- ✅ **Consistency**: Ensures consistent behavior across all UI components
|
|
38
|
+
- ✅ **Performance**: Optimized base classes with OnPush change detection support
|
|
39
|
+
- ✅ **Accessibility**: Built-in accessibility patterns and ARIA support
|
|
40
|
+
- ✅ **Form Integration**: Deep Angular Reactive Forms integration and validation
|
|
41
|
+
- ✅ **State Management**: Integration with `@verisoft/store` for application state
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install @verisoft/ui-core
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Peer Dependencies
|
|
50
|
+
|
|
51
|
+
Make sure you have the following peer dependencies installed:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install @verisoft/core @verisoft/store @angular/core @angular/common @angular/forms @angular/platform-browser
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
1. **Import base classes and interfaces** in your component library:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import {
|
|
63
|
+
BaseFormInputComponent,
|
|
64
|
+
ButtonCore,
|
|
65
|
+
TextfieldCore,
|
|
66
|
+
BUTTON_COMPONENT_TOKEN
|
|
67
|
+
} from '@verisoft/ui-core';
|
|
68
|
+
|
|
69
|
+
@Component({
|
|
70
|
+
selector: 'my-button',
|
|
71
|
+
providers: [{
|
|
72
|
+
provide: BUTTON_COMPONENT_TOKEN,
|
|
73
|
+
useExisting: MyButtonComponent
|
|
74
|
+
}]
|
|
75
|
+
})
|
|
76
|
+
export class MyButtonComponent extends BaseFormInputComponent implements ButtonCore {
|
|
77
|
+
// Component implementation
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
2. **Use services and utilities**:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { ScreenSizeService, FormatService } from '@verisoft/ui-core';
|
|
85
|
+
|
|
86
|
+
@Component({
|
|
87
|
+
// ...
|
|
88
|
+
})
|
|
89
|
+
export class MyComponent {
|
|
90
|
+
constructor(
|
|
91
|
+
private screenService: ScreenSizeService,
|
|
92
|
+
private formatService: FormatService
|
|
93
|
+
) {}
|
|
94
|
+
|
|
95
|
+
get isMobile() {
|
|
96
|
+
return this.screenService.isMobile();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
formatCurrency(value: number) {
|
|
100
|
+
return this.formatService.currency(value);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Usage Examples
|
|
106
|
+
|
|
107
|
+
### Creating a Custom Component with Base Classes
|
|
108
|
+
```typescript
|
|
109
|
+
import {
|
|
110
|
+
BaseFormInputComponent,
|
|
111
|
+
TextfieldCore,
|
|
112
|
+
TEXTFIELD_COMPONENT_TOKEN,
|
|
113
|
+
FieldSizeType,
|
|
114
|
+
FieldTypeType
|
|
115
|
+
} from '@verisoft/ui-core';
|
|
116
|
+
import { Component, Input, Optional, Self } from '@angular/core';
|
|
117
|
+
import { ControlValueAccessor, NgControl } from '@angular/forms';
|
|
118
|
+
|
|
119
|
+
@Component({
|
|
120
|
+
selector: 'custom-textfield',
|
|
121
|
+
template: `
|
|
122
|
+
<input
|
|
123
|
+
[type]="type"
|
|
124
|
+
[value]="value"
|
|
125
|
+
[disabled]="disabled"
|
|
126
|
+
(input)="onInput($event)"
|
|
127
|
+
(blur)="onBlur()"
|
|
128
|
+
[class]="getInputClasses()"
|
|
129
|
+
/>
|
|
130
|
+
`,
|
|
131
|
+
providers: [{
|
|
132
|
+
provide: TEXTFIELD_COMPONENT_TOKEN,
|
|
133
|
+
useExisting: CustomTextfieldComponent
|
|
134
|
+
}]
|
|
135
|
+
})
|
|
136
|
+
export class CustomTextfieldComponent
|
|
137
|
+
extends BaseFormInputComponent
|
|
138
|
+
implements ControlValueAccessor, TextfieldCore {
|
|
139
|
+
|
|
140
|
+
@Input() type: FieldTypeType = 'text';
|
|
141
|
+
@Input() size: FieldSizeType = 'medium';
|
|
142
|
+
|
|
143
|
+
constructor(@Optional() @Self() ngControl: NgControl) {
|
|
144
|
+
super(ngControl);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
protected getInputClasses(): string {
|
|
148
|
+
return `input input--${this.size} ${this.disabled ? 'input--disabled' : ''}`;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Using Core Services
|
|
154
|
+
```typescript
|
|
155
|
+
import {
|
|
156
|
+
ScreenSizeService,
|
|
157
|
+
SideMenuService,
|
|
158
|
+
FormatService
|
|
159
|
+
} from '@verisoft/ui-core';
|
|
160
|
+
|
|
161
|
+
@Component({
|
|
162
|
+
selector: 'my-responsive-component',
|
|
163
|
+
template: `
|
|
164
|
+
<div [class]="containerClass">
|
|
165
|
+
<span>{{ formattedPrice }}</span>
|
|
166
|
+
<button (click)="toggleMenu()" *ngIf="!isMobile">Menu</button>
|
|
167
|
+
</div>
|
|
168
|
+
`
|
|
169
|
+
})
|
|
170
|
+
export class ResponsiveComponent {
|
|
171
|
+
constructor(
|
|
172
|
+
private screenService: ScreenSizeService,
|
|
173
|
+
private menuService: SideMenuService,
|
|
174
|
+
private formatService: FormatService
|
|
175
|
+
) {}
|
|
176
|
+
|
|
177
|
+
get isMobile(): boolean {
|
|
178
|
+
return this.screenService.isMobile();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
get containerClass(): string {
|
|
182
|
+
return this.isMobile ? 'container-mobile' : 'container-desktop';
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
get formattedPrice(): string {
|
|
186
|
+
return this.formatService.currency(99.99, 'EUR');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
toggleMenu(): void {
|
|
190
|
+
this.menuService.toggle();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Implementing Component Interfaces
|
|
196
|
+
```typescript
|
|
197
|
+
import { ButtonCore, IconPositionType } from '@verisoft/ui-core';
|
|
198
|
+
|
|
199
|
+
export class MyButtonComponent implements ButtonCore {
|
|
200
|
+
@Input() primary: boolean = false;
|
|
201
|
+
@Input() disabled: boolean = false;
|
|
202
|
+
@Input() icon?: string;
|
|
203
|
+
@Input() iconPosition: IconPositionType = 'left';
|
|
204
|
+
@Input() loading: boolean = false;
|
|
205
|
+
@Input() size: 'small' | 'medium' | 'large' = 'medium';
|
|
206
|
+
|
|
207
|
+
// Implement required methods from ButtonCore interface
|
|
208
|
+
onClick(): void {
|
|
209
|
+
if (!this.disabled && !this.loading) {
|
|
210
|
+
// Handle click
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Architecture
|
|
217
|
+
|
|
218
|
+
### Base Classes
|
|
219
|
+
- **BaseFormComponent**: Foundation for all form-related components with validation integration
|
|
220
|
+
- **BaseFormInputComponent**: Base class for form input controls with ControlValueAccessor implementation
|
|
221
|
+
- **UnsubscribeComponent**: Automatic subscription management and memory leak prevention
|
|
222
|
+
- **BaseInputControls**: Core input control behavior and common properties
|
|
223
|
+
|
|
224
|
+
### Component Interfaces
|
|
225
|
+
- **ButtonCore**: Interface defining button component contract
|
|
226
|
+
- **TextfieldCore**: Interface for text input components
|
|
227
|
+
- **DropdownCore**: Interface for dropdown/select components
|
|
228
|
+
- **TableCore**: Interface for data table components
|
|
229
|
+
- **FormFieldCore**: Interface for form field wrapper components
|
|
230
|
+
|
|
231
|
+
### Injection Tokens
|
|
232
|
+
- **BUTTON_COMPONENT_TOKEN**: Token for registering button implementations
|
|
233
|
+
- **TEXTFIELD_COMPONENT_TOKEN**: Token for registering textfield implementations
|
|
234
|
+
- **DROPDOWN_COMPONENT_TOKEN**: Token for registering dropdown implementations
|
|
235
|
+
- **TABLE_COMPONENT_TOKEN**: Token for registering table implementations
|
|
236
|
+
|
|
237
|
+
### Services
|
|
238
|
+
- **ScreenSizeService**: Responsive design utilities and breakpoint detection
|
|
239
|
+
- **SideMenuService**: Navigation menu state management
|
|
240
|
+
- **FormatService**: Formatting utilities for dates, numbers, and currencies
|
|
241
|
+
- **ValidationService**: Custom validation logic and error handling
|
|
242
|
+
|
|
243
|
+
### Type Definitions
|
|
244
|
+
- **FieldSizeType**: Standardized size options ('small' | 'medium' | 'large')
|
|
245
|
+
- **FieldTypeType**: Input field types ('text' | 'email' | 'password' | etc.)
|
|
246
|
+
- **IconPositionType**: Icon positioning ('left' | 'right')
|
|
247
|
+
- **ControlSeverityType**: Validation state types ('success' | 'warning' | 'error')
|
|
248
|
+
|
|
249
|
+
## API Documentation
|
|
250
|
+
|
|
251
|
+
For detailed component APIs, properties, and methods, please refer to the component documentation or use your IDE's IntelliSense for comprehensive inline documentation.
|
|
252
|
+
|
|
253
|
+
## API Documentation
|
|
254
|
+
|
|
255
|
+
For detailed APIs, interfaces, and base class documentation, please refer to:
|
|
256
|
+
- TypeScript definitions and IntelliSense in your IDE
|
|
257
|
+
- Base class documentation for extension patterns
|
|
258
|
+
- Interface definitions for component contracts
|
|
259
|
+
- Service documentation for utility functions
|
|
260
|
+
|
|
261
|
+
## Development
|
|
262
|
+
|
|
263
|
+
### Running unit tests
|
|
6
264
|
|
|
7
265
|
Run `nx test ui-core` to execute the unit tests.
|
|
266
|
+
|
|
267
|
+
### Building the library
|
|
268
|
+
|
|
269
|
+
Run `nx build ui-core` to build the library.
|
|
270
|
+
|
|
271
|
+
### Linting
|
|
272
|
+
|
|
273
|
+
Run `nx lint ui-core` to run ESLint on the library.
|
|
274
|
+
|
|
275
|
+
## Extending the Library
|
|
276
|
+
|
|
277
|
+
The `ui-core` library is designed to be extended by other UI component libraries. Here's how to create a new UI library:
|
|
278
|
+
|
|
279
|
+
### Creating a Component Library
|
|
280
|
+
```typescript
|
|
281
|
+
// 1. Extend base classes
|
|
282
|
+
import { BaseFormInputComponent, ButtonCore } from '@verisoft/ui-core';
|
|
283
|
+
|
|
284
|
+
export class MyButtonComponent extends BaseFormInputComponent implements ButtonCore {
|
|
285
|
+
// Your implementation
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// 2. Provide component tokens
|
|
289
|
+
@Component({
|
|
290
|
+
providers: [{
|
|
291
|
+
provide: BUTTON_COMPONENT_TOKEN,
|
|
292
|
+
useExisting: MyButtonComponent
|
|
293
|
+
}]
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
// 3. Use core services
|
|
297
|
+
constructor(
|
|
298
|
+
private screenService: ScreenSizeService,
|
|
299
|
+
private formatService: FormatService
|
|
300
|
+
) {
|
|
301
|
+
super();
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Best Practices
|
|
306
|
+
- Always extend `BaseFormInputComponent` for form controls
|
|
307
|
+
- Implement the appropriate Core interface for your component type
|
|
308
|
+
- Use injection tokens to register your components
|
|
309
|
+
- Leverage core services for consistent behavior
|
|
310
|
+
- Follow the established type definitions and naming conventions
|
|
311
|
+
|
|
312
|
+
## Contributing
|
|
313
|
+
|
|
314
|
+
This library is part of the Verisoft framework. Please follow the established coding standards and architectural patterns when contributing.
|
|
315
|
+
|
|
316
|
+
## License
|
|
317
|
+
|
|
318
|
+
Copyright © Verisoft. All rights reserved.
|
package/jest.config.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
displayName: 'ui-core',
|
|
3
|
+
preset: '../../../jest.preset.js',
|
|
4
|
+
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
|
5
|
+
coverageDirectory: '../../../coverage/src/libs/ui-core',
|
|
6
|
+
transform: {
|
|
7
|
+
'^.+\\.(ts|mjs|js|html)$': [
|
|
8
|
+
'jest-preset-angular',
|
|
9
|
+
{
|
|
10
|
+
tsconfig: '<rootDir>/tsconfig.spec.json',
|
|
11
|
+
stringifyContentPathRegex: '\\.(html|svg)$',
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
|
|
16
|
+
snapshotSerializers: [
|
|
17
|
+
'jest-preset-angular/build/serializers/no-ng-attributes',
|
|
18
|
+
'jest-preset-angular/build/serializers/ng-snapshot',
|
|
19
|
+
'jest-preset-angular/build/serializers/html-comment',
|
|
20
|
+
],
|
|
21
|
+
};
|
package/ng-package.json
ADDED
package/package.json
CHANGED
|
@@ -1,36 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verisoft/ui-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "20.1.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@verisoft/core": "
|
|
6
|
-
"@verisoft/store": "
|
|
7
|
-
"@angular/core": "
|
|
8
|
-
"@angular/common": "
|
|
9
|
-
"@angular/forms": "
|
|
10
|
-
"@angular/platform-browser": "
|
|
11
|
-
"@angular/router": "
|
|
12
|
-
"@ngrx/store": "
|
|
13
|
-
"@ngx-translate/core": "^
|
|
14
|
-
"
|
|
15
|
-
"rxjs": "~7.8.0",
|
|
16
|
-
"uuid": "^10.0.0"
|
|
17
|
-
},
|
|
18
|
-
"sideEffects": false,
|
|
19
|
-
"publishConfig": {
|
|
20
|
-
"access": "public"
|
|
21
|
-
},
|
|
22
|
-
"module": "fesm2022/verisoft-ui-core.mjs",
|
|
23
|
-
"typings": "index.d.ts",
|
|
24
|
-
"exports": {
|
|
25
|
-
"./package.json": {
|
|
26
|
-
"default": "./package.json"
|
|
27
|
-
},
|
|
28
|
-
".": {
|
|
29
|
-
"types": "./index.d.ts",
|
|
30
|
-
"default": "./fesm2022/verisoft-ui-core.mjs"
|
|
31
|
-
}
|
|
5
|
+
"@verisoft/core": "~20.1.0",
|
|
6
|
+
"@verisoft/store": "~20.1.0",
|
|
7
|
+
"@angular/core": "~20.2.0",
|
|
8
|
+
"@angular/common": "~20.2.0",
|
|
9
|
+
"@angular/forms": "~20.2.0",
|
|
10
|
+
"@angular/platform-browser": "~20.2.0",
|
|
11
|
+
"@angular/router": "~20.2.0",
|
|
12
|
+
"@ngrx/store": "~20.0.0",
|
|
13
|
+
"@ngx-translate/core": "^17.0.0",
|
|
14
|
+
"rxjs": "~7.8.0"
|
|
32
15
|
},
|
|
33
16
|
"dependencies": {
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
}
|
|
17
|
+
"lodash-es": "^4.17.21",
|
|
18
|
+
"uuid": "^11.0.0"
|
|
19
|
+
},
|
|
20
|
+
"sideEffects": false
|
|
21
|
+
}
|
package/project.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ui-core",
|
|
3
|
+
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"sourceRoot": "src/libs/ui-core/src",
|
|
5
|
+
"prefix": "lib",
|
|
6
|
+
"projectType": "library",
|
|
7
|
+
"tags": [],
|
|
8
|
+
"targets": {
|
|
9
|
+
"build": {
|
|
10
|
+
"executor": "@nx/angular:package",
|
|
11
|
+
"outputs": ["{workspaceRoot}/dist/{projectRoot}"],
|
|
12
|
+
"options": {
|
|
13
|
+
"project": "src/libs/ui-core/ng-package.json"
|
|
14
|
+
},
|
|
15
|
+
"configurations": {
|
|
16
|
+
"production": {
|
|
17
|
+
"tsConfig": "src/libs/ui-core/tsconfig.lib.prod.json"
|
|
18
|
+
},
|
|
19
|
+
"development": {
|
|
20
|
+
"tsConfig": "src/libs/ui-core/tsconfig.lib.json"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"defaultConfiguration": "production"
|
|
24
|
+
},
|
|
25
|
+
"test": {
|
|
26
|
+
"executor": "@nx/jest:jest",
|
|
27
|
+
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
|
28
|
+
"options": {
|
|
29
|
+
"jestConfig": "src/libs/ui-core/jest.config.ts"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"lint": {
|
|
33
|
+
"executor": "@nx/eslint:lint"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { OnChanges, SimpleChange, SimpleChanges } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
export function setComponentProperties<TComponent>(
|
|
4
|
+
component: TComponent,
|
|
5
|
+
value: Partial<TComponent>,
|
|
6
|
+
firstChange = false
|
|
7
|
+
) {
|
|
8
|
+
if (!value || !component) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const simpleChanges = Object.keys(value).reduce(
|
|
13
|
+
(changes: SimpleChanges, property: string) => {
|
|
14
|
+
const indexedComponent = component as unknown as {
|
|
15
|
+
[key: string]: TComponent[keyof TComponent];
|
|
16
|
+
};
|
|
17
|
+
const indexedValue = value as unknown as {
|
|
18
|
+
[key: string]: TComponent[keyof TComponent];
|
|
19
|
+
};
|
|
20
|
+
const previousValue = indexedComponent[property];
|
|
21
|
+
const currentValue = indexedValue[
|
|
22
|
+
property
|
|
23
|
+
] as TComponent[keyof TComponent];
|
|
24
|
+
if (currentValue !== previousValue) {
|
|
25
|
+
indexedComponent[property] = currentValue;
|
|
26
|
+
const change = new SimpleChange(
|
|
27
|
+
previousValue,
|
|
28
|
+
currentValue,
|
|
29
|
+
firstChange
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return { ...changes, [property]: change };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return changes;
|
|
36
|
+
},
|
|
37
|
+
{}
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const changeableComponent = component as unknown as OnChanges;
|
|
41
|
+
if (changeableComponent['ngOnChanges']) {
|
|
42
|
+
changeableComponent.ngOnChanges(simpleChanges);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export enum ControlSeverity {
|
|
2
|
+
success = 'success',
|
|
3
|
+
info = 'info',
|
|
4
|
+
warning = 'warning',
|
|
5
|
+
danger = 'danger',
|
|
6
|
+
help = 'help',
|
|
7
|
+
primary = 'primary',
|
|
8
|
+
secondary = 'secondary',
|
|
9
|
+
contrast = 'contrast',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export enum GovControlSeverity {
|
|
13
|
+
primary = 'primary',
|
|
14
|
+
secondary = 'secondary',
|
|
15
|
+
neutral = 'neutral',
|
|
16
|
+
error = 'error',
|
|
17
|
+
success = 'success',
|
|
18
|
+
warning = 'warning',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export enum GovButtonType {
|
|
22
|
+
solid = 'solid',
|
|
23
|
+
outlined = "outlined",
|
|
24
|
+
base = "base",
|
|
25
|
+
link = "link"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export enum IconPosition {
|
|
29
|
+
left = 'left',
|
|
30
|
+
right = 'right',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export enum SlotPosition {
|
|
34
|
+
top = 'top',
|
|
35
|
+
bottom = 'bottom',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export enum Position{
|
|
39
|
+
top = 'top',
|
|
40
|
+
bottom = 'bottom',
|
|
41
|
+
left = 'left',
|
|
42
|
+
right = 'right',
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export enum FieldSize {
|
|
46
|
+
small = 'small',
|
|
47
|
+
medium = 'medium',
|
|
48
|
+
large = 'large',
|
|
49
|
+
xl = 'xl',
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export enum FieldAlign {
|
|
53
|
+
left = 'left',
|
|
54
|
+
center = 'center',
|
|
55
|
+
right = 'right',
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export enum FieldType {
|
|
59
|
+
text = 'text',
|
|
60
|
+
number = 'number',
|
|
61
|
+
password = 'password',
|
|
62
|
+
search = 'search',
|
|
63
|
+
date = 'date',
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export enum LayoutType {
|
|
67
|
+
horizontal = 'horizontal',
|
|
68
|
+
vertical = 'vertical',
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type ControlSeverityType = keyof typeof ControlSeverity;
|
|
72
|
+
export type GovControlSeverityType = keyof typeof GovControlSeverity;
|
|
73
|
+
export type GovButtonTypeType = keyof typeof GovButtonType;
|
|
74
|
+
export type IconPositionType = keyof typeof IconPosition;
|
|
75
|
+
export type SlotPositionType = keyof typeof SlotPosition;
|
|
76
|
+
export type PositionType = keyof typeof Position;
|
|
77
|
+
export type FieldSizeType = keyof typeof FieldSize;
|
|
78
|
+
export type FieldAlignType = keyof typeof FieldAlign;
|
|
79
|
+
export type FieldTypeType = keyof typeof FieldType;
|
|
80
|
+
export type LayoutTypeType = keyof typeof LayoutType;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { setDataToArray } from './datasource-component.model';
|
|
2
|
+
|
|
3
|
+
describe('setDataToArray', () => {
|
|
4
|
+
test('Should return data when target array is null and data is passed.', () => {
|
|
5
|
+
const data = ['item 1', 'item 2'];
|
|
6
|
+
const targetData = undefined;
|
|
7
|
+
|
|
8
|
+
const actual = setDataToArray(targetData, data);
|
|
9
|
+
|
|
10
|
+
expect(actual).toEqual(data);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('Should return data when target array is null and data is passed.', () => {
|
|
14
|
+
const data = ['item 1', 'item 2'];
|
|
15
|
+
const targetData: string[] = [];
|
|
16
|
+
|
|
17
|
+
const actual = setDataToArray(targetData, data);
|
|
18
|
+
|
|
19
|
+
expect(actual).toEqual(data);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('Should return extended target array when target array is empty and data is passed and offset is specified.', () => {
|
|
23
|
+
const data = ['item 1', 'item 2'];
|
|
24
|
+
const targetData: string[] = [];
|
|
25
|
+
const offset = 1;
|
|
26
|
+
|
|
27
|
+
const actual = setDataToArray(targetData, data, offset);
|
|
28
|
+
|
|
29
|
+
expect(actual).toEqual([undefined, ...data]);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('Should return target array extended to total items when data is passed and total is specified.', () => {
|
|
33
|
+
const data = ['item 1', 'item 2'];
|
|
34
|
+
const targetData: string[] = [];
|
|
35
|
+
const total = 5;
|
|
36
|
+
const offset = 0;
|
|
37
|
+
|
|
38
|
+
const actual = setDataToArray(targetData, data, offset, total);
|
|
39
|
+
|
|
40
|
+
expect(actual.length).toEqual(total);
|
|
41
|
+
});
|
|
42
|
+
});
|