valixa-angular-material 0.0.0-stage → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Valixa contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,164 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# valixa-angular-material
|
|
2
|
+
|
|
3
|
+
Angular Material 21.2 control bindings for Valixa's Angular signal bridge. Angular
|
|
4
|
+
and Material remain peers. Built in partial-Ivy Angular Package Format.
|
|
5
|
+
|
|
6
|
+
## Getting started
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
import { Component } from '@angular/core';
|
|
10
|
+
import { MatInputModule } from '@angular/material/input';
|
|
11
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
12
|
+
import { createValixa } from 'valixa-angular';
|
|
13
|
+
import { VALIXA_MATERIAL } from 'valixa-angular-material';
|
|
14
|
+
|
|
15
|
+
@Component({
|
|
16
|
+
standalone: true,
|
|
17
|
+
imports: [...VALIXA_MATERIAL, MatInputModule, MatFormFieldModule],
|
|
18
|
+
template: `
|
|
19
|
+
<mat-form-field>
|
|
20
|
+
<mat-label>Email</mat-label>
|
|
21
|
+
<input matInput [valixaField]="email" required>
|
|
22
|
+
<mat-error>{{ email.error() }}</mat-error>
|
|
23
|
+
</mat-form-field>`
|
|
24
|
+
})
|
|
25
|
+
export class EmailField {
|
|
26
|
+
form = createValixa({ email: ['', 'required | email'] }, { id: 'email-form' });
|
|
27
|
+
email = this.form.field('email');
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`VALIXA_MATERIAL` contains `ValixaFieldDirective` and `ValixaMaterialDirective`.
|
|
32
|
+
Import your actual Material modules and styles normally. Do not add Angular Forms
|
|
33
|
+
directives on the same control. No FormControl/Group/Validators are created.
|
|
34
|
+
|
|
35
|
+
## Component contracts
|
|
36
|
+
|
|
37
|
+
| Control | Binding behavior |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| MatInput text/textarea | Native input events, initial/programmatic value writes, blur, flags, Material ID and error state |
|
|
40
|
+
| MatInput numeric | Explicit `numberCodec(emptyValue)` required; finite numeric/plain values |
|
|
41
|
+
| MatSelect | Its actual CVA, scalar/object/multiple values and reset; native `compareWith` remains application-owned |
|
|
42
|
+
| MatCheckbox | Its actual checked CVA; disabled/readonly and external error descriptions |
|
|
43
|
+
| MatRadioGroup | Its actual CVA, initial selection before children initialize, child events and blur/touch |
|
|
44
|
+
| MatSlideToggle | Its actual CVA and switch semantics |
|
|
45
|
+
| MatAutocomplete input | Its trigger CVA plus required codec; typed drafts distinguished from selected objects |
|
|
46
|
+
| MatDatepicker input | Its date-input CVA plus required codec; dates/parse failures encoded as plain values |
|
|
47
|
+
| MatError | Error-state matcher follows known core errors, including manual/server errors without an Angular control |
|
|
48
|
+
|
|
49
|
+
Material selectors and actual DI tokens identify these supported hosts. No runtime
|
|
50
|
+
class-name guessing or universal event extractor is used. CVAs already normalize
|
|
51
|
+
component-specific events, so their callbacks connect directly to core through codecs.
|
|
52
|
+
|
|
53
|
+
Input fields retain native readonly semantics. Select/Checkbox/RadioGroup/SlideToggle
|
|
54
|
+
lack equivalent readonly behavior, so readonly maps to disabled presentation; core
|
|
55
|
+
still records readonly separately and allows programmatic writes. Autocomplete is
|
|
56
|
+
readonly and closes/disables its panel. Date input readonly blocks typing and its
|
|
57
|
+
picker accessor disables selection. Disabled applies normally. Guarded writers also
|
|
58
|
+
restore values if an already captured event arrives after flags changed.
|
|
59
|
+
Radio group names use the unique form/field ID, preventing same-named fields in
|
|
60
|
+
separate Valixa forms from unchecking each other's native radios.
|
|
61
|
+
|
|
62
|
+
Labels and required metadata belong to the UI. Material manages form-field label
|
|
63
|
+
and helper IDs; the adapter keeps the input/control ID consistent and uses public
|
|
64
|
+
error-state APIs. Standalone checked/group controls can use explicit descriptions:
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<mat-checkbox [valixaField]="terms" required>Agree</mat-checkbox>
|
|
68
|
+
@if (terms.error()) { <mat-error [id]="terms.errorId">{{ terms.error() }}</mat-error> }
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Known core errors display immediately; no extra touched-based hiding policy or
|
|
72
|
+
Angular Validator engine is introduced. Core still controls when validation runs.
|
|
73
|
+
|
|
74
|
+
## Object/multiple selections and clearing
|
|
75
|
+
|
|
76
|
+
```html
|
|
77
|
+
<mat-select multiple [compareWith]="compareById" [valixaField]="offices">
|
|
78
|
+
@for (office of cities; track office.id) {
|
|
79
|
+
<mat-option [value]="office">{{ office.title }}</mat-option>
|
|
80
|
+
}
|
|
81
|
+
</mat-select>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Core copies plain objects. Supply a stable `compareWith` when identity matters:
|
|
85
|
+
`compareById = (a: City, b: City) => a?.id === b?.id`. Multiple selections use arrays;
|
|
86
|
+
null/undefined scalar models display unselected through the Material CVA. Ensure
|
|
87
|
+
option/clearing values match the field type. Annotate nullable fields or provide
|
|
88
|
+
an explicit codec such as `encode: value => value ?? ''` for a nonnullable string
|
|
89
|
+
clear policy. Valixa does not silently coerce every Material selection.
|
|
90
|
+
|
|
91
|
+
## Autocomplete: committed options and typed drafts
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
type City = { id: number; title: string };
|
|
95
|
+
const isCity = (value: unknown): value is City =>
|
|
96
|
+
value !== null && typeof value === 'object' && 'id' in value && 'title' in value;
|
|
97
|
+
form = createValixa({ city: { initial: null as City | null, rules: 'required' } });
|
|
98
|
+
city = this.form.field('city');
|
|
99
|
+
cityCodec = autocompleteCodec(isCity);
|
|
100
|
+
displayCity = (value: City | null) => value?.title ?? '';
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```html
|
|
104
|
+
<input matInput [matAutocomplete]="auto" [valixaField]="city" [valixaCodec]="cityCodec">
|
|
105
|
+
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayCity">
|
|
106
|
+
@for (city of cities; track city.id) { <mat-option [value]="city">{{ city.title }}</mat-option> }
|
|
107
|
+
</mat-autocomplete>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`autocompleteCodec(predicate)` commits selected objects and maps typed strings or
|
|
111
|
+
clearing to null. Editing an existing selection therefore cannot submit a stale
|
|
112
|
+
selected object. Own CVA updates do not echo back and erase the search draft;
|
|
113
|
+
programmatic changes/reset still write through the CVA. Match `required` or custom
|
|
114
|
+
rules to your draft/null policy. The helper is for object options; use a custom
|
|
115
|
+
codec/adapter for free text or string-option contracts that need selection tracking.
|
|
116
|
+
|
|
117
|
+
## Datepicker and numeric codecs
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
form = createValixa({ date: { initial: null as string | null,
|
|
121
|
+
validate: (value: string | null) => value !== 'invalid' || 'Choose a valid date.' }
|
|
122
|
+
});
|
|
123
|
+
date = this.form.field('date');
|
|
124
|
+
dateCodec = dateOnlyCodec;
|
|
125
|
+
// Component providers: [provideNativeDateAdapter()]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
```html
|
|
129
|
+
<input matInput [matDatepicker]="picker" [valixaField]="date" [valixaCodec]="dateCodec">
|
|
130
|
+
<mat-datepicker-toggle matIconSuffix [for]="picker" />
|
|
131
|
+
<mat-datepicker #picker />
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`dateOnlyCodec` is for NativeDateAdapter: valid local civil dates encode as
|
|
135
|
+
YYYY-MM-DD, clearing as null, invalid dates as `'invalid'`. Decode uses local
|
|
136
|
+
components, avoiding UTC day shifts. The adapter distinguishes parse failure from
|
|
137
|
+
empty input using the input text and DateAdapter's invalid-date value. No Date
|
|
138
|
+
instance reaches core. Declare the sentinel validator, and declare matching core
|
|
139
|
+
rules for any Material min/max/filter constraints; picker UI constraints do not
|
|
140
|
+
replace submission validation. Other date libraries need an explicit matching codec
|
|
141
|
+
and have not been tested here.
|
|
142
|
+
|
|
143
|
+
Numeric MatInput uses `numberCodec` from `valixa-angular`, with a typed empty value
|
|
144
|
+
such as null or zero. Unsupported implicit numeric coercion is rejected at runtime
|
|
145
|
+
when no codec is supplied. Strict consumer templates also check codec/field types.
|
|
146
|
+
|
|
147
|
+
## Requests, custom controls and packaging
|
|
148
|
+
|
|
149
|
+
Use the Angular wrapper's existing `submit` / setup-created `handleSubmit` APIs,
|
|
150
|
+
signals, `setError`, reset and cancellation. Catch request rejections explicitly;
|
|
151
|
+
map your known server payloads rather than guessing HTTP response shapes. Core
|
|
152
|
+
semantics, including conservative error invalidation and stale-run protection,
|
|
153
|
+
remain authoritative. No dependency graph or scheduler is included.
|
|
154
|
+
|
|
155
|
+
Custom controls use `provideValixaControl` or an existing CVA from `valixa-angular`.
|
|
156
|
+
No wrapper component is required. Explicit adapters map value/status/events and own
|
|
157
|
+
their teardown; controlled input/output components get accepted values echoed back,
|
|
158
|
+
while native/CVA bindings preserve their already-updated view.
|
|
159
|
+
|
|
160
|
+
The npm artifact is the `dist/` ng-packagr output with FESM2022, partial declarations,
|
|
161
|
+
maps, peers and this guide. Angular Material is not bundled. The base Angular package
|
|
162
|
+
works without Material installed. Production consumer compilation and browser checks
|
|
163
|
+
use independently installed tarballs. Supported evidence is Angular/Material 21.2
|
|
164
|
+
and reported Chromium on Windows, not other majors or full WCAG conformance.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, ElementRef, Renderer2, ChangeDetectorRef, forwardRef, Directive } from '@angular/core';
|
|
3
|
+
import { MatInput } from '@angular/material/input';
|
|
4
|
+
import { MatSelect } from '@angular/material/select';
|
|
5
|
+
import { MatCheckbox } from '@angular/material/checkbox';
|
|
6
|
+
import { MatRadioGroup } from '@angular/material/radio';
|
|
7
|
+
import { MatSlideToggle } from '@angular/material/slide-toggle';
|
|
8
|
+
import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
|
|
9
|
+
import { MatDatepickerInput } from '@angular/material/datepicker';
|
|
10
|
+
import { DateAdapter } from '@angular/material/core';
|
|
11
|
+
import { valueAccessorAdapter, nativeControlAdapter, VALIXA_CONTROL, ValixaFieldDirective } from 'valixa-angular';
|
|
12
|
+
|
|
13
|
+
/** Actual Material selectors and DI tokens define supported hosts; no component-name guessing. */
|
|
14
|
+
class ValixaMaterialDirective {
|
|
15
|
+
get requiresCodec() { return Boolean(this.autocomplete || this.date || this.input?.type === 'number'); }
|
|
16
|
+
constructor() {
|
|
17
|
+
this.preserveViewOnChange = true;
|
|
18
|
+
this.input = inject(MatInput, { self: true, optional: true });
|
|
19
|
+
this.select = inject(MatSelect, { self: true, optional: true });
|
|
20
|
+
this.checkbox = inject(MatCheckbox, { self: true, optional: true });
|
|
21
|
+
this.radio = inject(MatRadioGroup, { self: true, optional: true });
|
|
22
|
+
this.toggle = inject(MatSlideToggle, { self: true, optional: true });
|
|
23
|
+
this.autocomplete = inject(MatAutocompleteTrigger, { self: true, optional: true });
|
|
24
|
+
this.date = inject(MatDatepickerInput, { self: true, optional: true });
|
|
25
|
+
this.dateAdapter = inject(DateAdapter, { optional: true });
|
|
26
|
+
this.host = inject(ElementRef).nativeElement;
|
|
27
|
+
this.renderer = inject(Renderer2);
|
|
28
|
+
this.changeDetector = inject(ChangeDetectorRef);
|
|
29
|
+
this.invalid = false;
|
|
30
|
+
this.matcher = { isErrorState: () => this.invalid };
|
|
31
|
+
if (this.date && this.autocomplete)
|
|
32
|
+
throw new Error('Do not combine datepicker and autocomplete on one Valixa control');
|
|
33
|
+
const accessor = this.date ?? this.autocomplete ?? this.select ?? this.checkbox ?? this.radio ?? this.toggle;
|
|
34
|
+
this.adapter = accessor ? valueAccessorAdapter(accessor) : nativeControlAdapter(this.host, this.renderer);
|
|
35
|
+
if (this.input)
|
|
36
|
+
this.input.errorStateMatcher = this.matcher;
|
|
37
|
+
if (this.select)
|
|
38
|
+
this.select.errorStateMatcher = this.matcher;
|
|
39
|
+
}
|
|
40
|
+
writeValue(value) { this.adapter.writeValue(value); }
|
|
41
|
+
connect(change, touched) {
|
|
42
|
+
return this.adapter.connect(value => {
|
|
43
|
+
// A date CVA emits null for both clearing and parse failure. Preserve invalid drafts explicitly.
|
|
44
|
+
if (this.date && value === null && typeof this.host.value === 'string' && this.host.value.trim())
|
|
45
|
+
change(this.dateAdapter.invalid());
|
|
46
|
+
else
|
|
47
|
+
change(value);
|
|
48
|
+
}, touched);
|
|
49
|
+
}
|
|
50
|
+
setState(state) {
|
|
51
|
+
this.adapter.setState(state);
|
|
52
|
+
this.invalid = state.errors.length > 0;
|
|
53
|
+
this.renderer.setAttribute(this.host, 'aria-required', String(state.required ?? false));
|
|
54
|
+
this.renderer.setAttribute(this.host, 'aria-readonly', String(state.readonly));
|
|
55
|
+
if (this.input) {
|
|
56
|
+
this.input.id = state.id;
|
|
57
|
+
this.input.name = state.name;
|
|
58
|
+
this.input.readonly = state.readonly;
|
|
59
|
+
this.input.disabled = state.disabled;
|
|
60
|
+
this.input.updateErrorState();
|
|
61
|
+
}
|
|
62
|
+
if (this.select) {
|
|
63
|
+
this.select.id = state.id;
|
|
64
|
+
this.select.updateErrorState();
|
|
65
|
+
}
|
|
66
|
+
if (this.checkbox) {
|
|
67
|
+
this.checkbox.id = state.id;
|
|
68
|
+
this.checkbox.name = state.name;
|
|
69
|
+
this.checkbox.ariaDescribedby = state.errors.length ? state.errorId : '';
|
|
70
|
+
}
|
|
71
|
+
if (this.radio)
|
|
72
|
+
this.radio.name = state.id;
|
|
73
|
+
if (this.toggle) {
|
|
74
|
+
this.toggle.id = state.id;
|
|
75
|
+
this.toggle.name = state.name;
|
|
76
|
+
}
|
|
77
|
+
if (this.autocomplete) {
|
|
78
|
+
this.autocomplete.autocompleteDisabled = state.disabled || state.readonly;
|
|
79
|
+
if (this.autocomplete.autocompleteDisabled)
|
|
80
|
+
this.autocomplete.closePanel();
|
|
81
|
+
}
|
|
82
|
+
if (this.checkbox || this.radio || this.toggle) {
|
|
83
|
+
this.renderer.setAttribute(this.host, 'id', state.id);
|
|
84
|
+
if (state.errors.length)
|
|
85
|
+
this.renderer.setAttribute(this.host, 'aria-describedby', state.errorId);
|
|
86
|
+
else
|
|
87
|
+
this.renderer.removeAttribute(this.host, 'aria-describedby');
|
|
88
|
+
for (const input of this.host.querySelectorAll('input'))
|
|
89
|
+
this.renderer.setAttribute(input, 'aria-invalid', String(this.invalid));
|
|
90
|
+
}
|
|
91
|
+
this.changeDetector.markForCheck();
|
|
92
|
+
}
|
|
93
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.26", ngImport: i0, type: ValixaMaterialDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
94
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.26", type: ValixaMaterialDirective, isStandalone: true, selector: "input[matInput][valixaField],textarea[matInput][valixaField],mat-select[valixaField],mat-checkbox[valixaField],mat-radio-group[valixaField],mat-slide-toggle[valixaField]", providers: [{ provide: VALIXA_CONTROL, useExisting: forwardRef(() => ValixaMaterialDirective) }], ngImport: i0 }); }
|
|
95
|
+
}
|
|
96
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.26", ngImport: i0, type: ValixaMaterialDirective, decorators: [{
|
|
97
|
+
type: Directive,
|
|
98
|
+
args: [{
|
|
99
|
+
selector: 'input[matInput][valixaField],textarea[matInput][valixaField],mat-select[valixaField],mat-checkbox[valixaField],mat-radio-group[valixaField],mat-slide-toggle[valixaField]',
|
|
100
|
+
standalone: true,
|
|
101
|
+
providers: [{ provide: VALIXA_CONTROL, useExisting: forwardRef(() => ValixaMaterialDirective) }]
|
|
102
|
+
}]
|
|
103
|
+
}], ctorParameters: () => [] });
|
|
104
|
+
/** Import this tuple into a standalone component's imports. */
|
|
105
|
+
const VALIXA_MATERIAL = [ValixaFieldDirective, ValixaMaterialDirective];
|
|
106
|
+
|
|
107
|
+
/** NativeDateAdapter civil date codec. 'invalid' must be rejected by a blueprint validator. */
|
|
108
|
+
const dateOnlyCodec = Object.freeze({
|
|
109
|
+
encode(value) {
|
|
110
|
+
if (value === null)
|
|
111
|
+
return null;
|
|
112
|
+
if (!Number.isFinite(value.getTime()))
|
|
113
|
+
return 'invalid';
|
|
114
|
+
return `${String(value.getFullYear()).padStart(4, '0')}-${String(value.getMonth() + 1).padStart(2, '0')}-${String(value.getDate()).padStart(2, '0')}`;
|
|
115
|
+
},
|
|
116
|
+
decode(value) {
|
|
117
|
+
if (!value || !/^\d{4}-\d{2}-\d{2}$/.test(value))
|
|
118
|
+
return null;
|
|
119
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
120
|
+
const date = new Date(0);
|
|
121
|
+
date.setHours(0, 0, 0, 0);
|
|
122
|
+
date.setFullYear(year, month - 1, day);
|
|
123
|
+
return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day ? date : null;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
/** Object options commit; search strings/clearing commit null, preventing stale selection submission. */
|
|
127
|
+
function autocompleteCodec(isOption) {
|
|
128
|
+
return { encode: value => isOption(value) ? value : null, decode: value => value };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Generated bundle index. Do not edit.
|
|
133
|
+
*/
|
|
134
|
+
|
|
135
|
+
export { VALIXA_MATERIAL, ValixaMaterialDirective, autocompleteCodec, dateOnlyCodec };
|
|
136
|
+
//# sourceMappingURL=valixa-angular-material.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valixa-angular-material.mjs","sources":["../../src/material.ts","../../src/codecs.ts","../../src/valixa-angular-material.ts"],"sourcesContent":["import { ChangeDetectorRef, Directive, ElementRef, Renderer2, forwardRef, inject } from '@angular/core';\r\nimport type { ControlValueAccessor } from '@angular/forms';\r\nimport { MatInput } from '@angular/material/input';\r\nimport { MatSelect } from '@angular/material/select';\r\nimport { MatCheckbox } from '@angular/material/checkbox';\r\nimport { MatRadioGroup } from '@angular/material/radio';\r\nimport { MatSlideToggle } from '@angular/material/slide-toggle';\r\nimport { MatAutocompleteTrigger } from '@angular/material/autocomplete';\r\nimport { MatDatepickerInput } from '@angular/material/datepicker';\r\nimport { DateAdapter } from '@angular/material/core';\r\nimport { VALIXA_CONTROL, ValixaFieldDirective, nativeControlAdapter, valueAccessorAdapter } from 'valixa-angular';\r\nimport type { ControlStatus, ValixaControlAdapter } from 'valixa-angular';\r\n\r\n/** Actual Material selectors and DI tokens define supported hosts; no component-name guessing. */\r\n@Directive({\r\n selector: 'input[matInput][valixaField],textarea[matInput][valixaField],mat-select[valixaField],mat-checkbox[valixaField],mat-radio-group[valixaField],mat-slide-toggle[valixaField]',\r\n standalone: true,\r\n providers: [{ provide: VALIXA_CONTROL, useExisting: forwardRef(() => ValixaMaterialDirective) }]\r\n})\r\nexport class ValixaMaterialDirective implements ValixaControlAdapter<unknown> {\r\n readonly preserveViewOnChange = true;\r\n private readonly input = inject(MatInput, { self: true, optional: true });\r\n private readonly select = inject(MatSelect, { self: true, optional: true });\r\n private readonly checkbox = inject(MatCheckbox, { self: true, optional: true });\r\n private readonly radio = inject(MatRadioGroup, { self: true, optional: true });\r\n private readonly toggle = inject(MatSlideToggle, { self: true, optional: true });\r\n private readonly autocomplete = inject(MatAutocompleteTrigger, { self: true, optional: true });\r\n private readonly date = inject(MatDatepickerInput, { self: true, optional: true });\r\n private readonly dateAdapter = inject(DateAdapter, { optional: true });\r\n get requiresCodec(): boolean { return Boolean(this.autocomplete || this.date || this.input?.type === 'number'); }\r\n private readonly host = inject(ElementRef).nativeElement;\r\n private readonly renderer = inject(Renderer2);\r\n private readonly changeDetector = inject(ChangeDetectorRef);\r\n private readonly adapter: ValixaControlAdapter<unknown>;\r\n private invalid = false;\r\n private readonly matcher = { isErrorState: () => this.invalid };\r\n constructor() {\r\n if (this.date && this.autocomplete) throw new Error('Do not combine datepicker and autocomplete on one Valixa control');\r\n const accessor: ControlValueAccessor | null = this.date ?? this.autocomplete ?? this.select ?? this.checkbox ?? this.radio ?? this.toggle;\r\n this.adapter = accessor ? valueAccessorAdapter(accessor) : nativeControlAdapter(this.host, this.renderer);\r\n if (this.input) this.input.errorStateMatcher = this.matcher;\r\n if (this.select) this.select.errorStateMatcher = this.matcher;\r\n }\r\n writeValue(value: unknown): void { this.adapter.writeValue(value); }\r\n connect(change: (value: unknown) => void, touched: () => void): () => void {\r\n return this.adapter.connect(value => {\r\n // A date CVA emits null for both clearing and parse failure. Preserve invalid drafts explicitly.\r\n if (this.date && value === null && typeof this.host.value === 'string' && this.host.value.trim()) change(this.dateAdapter!.invalid());\r\n else change(value);\r\n }, touched);\r\n }\r\n setState(state: ControlStatus): void {\r\n this.adapter.setState(state); this.invalid = state.errors.length > 0;\r\n this.renderer.setAttribute(this.host, 'aria-required', String(state.required ?? false));\r\n this.renderer.setAttribute(this.host, 'aria-readonly', String(state.readonly));\r\n if (this.input) { this.input.id = state.id; this.input.name = state.name; this.input.readonly = state.readonly; this.input.disabled = state.disabled; this.input.updateErrorState(); }\r\n if (this.select) { this.select.id = state.id; this.select.updateErrorState(); }\r\n if (this.checkbox) { this.checkbox.id = state.id; this.checkbox.name = state.name; this.checkbox.ariaDescribedby = state.errors.length ? state.errorId : ''; }\r\n if (this.radio) this.radio.name = state.id;\r\n if (this.toggle) { this.toggle.id = state.id; this.toggle.name = state.name; }\r\n if (this.autocomplete) { this.autocomplete.autocompleteDisabled = state.disabled || state.readonly; if (this.autocomplete.autocompleteDisabled) this.autocomplete.closePanel(); }\r\n if (this.checkbox || this.radio || this.toggle) {\r\n this.renderer.setAttribute(this.host, 'id', state.id);\r\n if (state.errors.length) this.renderer.setAttribute(this.host, 'aria-describedby', state.errorId); else this.renderer.removeAttribute(this.host, 'aria-describedby');\r\n for (const input of this.host.querySelectorAll('input')) this.renderer.setAttribute(input, 'aria-invalid', String(this.invalid));\r\n }\r\n this.changeDetector.markForCheck();\r\n }\r\n}\r\n/** Import this tuple into a standalone component's imports. */\r\nexport const VALIXA_MATERIAL = [ValixaFieldDirective, ValixaMaterialDirective] as const;\r\n","import type { ValueCodec } from 'valixa-angular';\r\n\r\n/** NativeDateAdapter civil date codec. 'invalid' must be rejected by a blueprint validator. */\r\nexport const dateOnlyCodec: ValueCodec<string | null, Date | null> = Object.freeze({\r\n encode(value: Date | null): string | null {\r\n if (value === null) return null;\r\n if (!Number.isFinite(value.getTime())) return 'invalid';\r\n return `${String(value.getFullYear()).padStart(4, '0')}-${String(value.getMonth() + 1).padStart(2, '0')}-${String(value.getDate()).padStart(2, '0')}`;\r\n },\r\n decode(value: string | null): Date | null {\r\n if (!value || !/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return null;\r\n const [year, month, day] = value.split('-').map(Number) as [number, number, number];\r\n const date = new Date(0); date.setHours(0, 0, 0, 0); date.setFullYear(year, month - 1, day);\r\n return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day ? date : null;\r\n }\r\n});\r\n/** Object options commit; search strings/clearing commit null, preventing stale selection submission. */\r\nexport function autocompleteCodec<T extends object>(isOption: (value: unknown) => value is T): ValueCodec<T | null, T | string | null> {\r\n return { encode: value => isOption(value) ? value : null, decode: value => value };\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,64 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valixa-angular-material",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.0-rc.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"description": "Angular Material value-accessor and error presentation bindings for Valixa",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./types/valixa-angular-material.d.ts",
|
|
11
|
+
"default": "./fesm2022/valixa-angular-material.mjs"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": {
|
|
14
|
+
"default": "./package.json"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"@angular/core": "~21.2.0",
|
|
19
|
+
"@angular/common": "~21.2.0",
|
|
20
|
+
"@angular/forms": "~21.2.0",
|
|
21
|
+
"@angular/material": "~21.2.0",
|
|
22
|
+
"@angular/cdk": "~21.2.0",
|
|
23
|
+
"valixa-angular": "^1.0.0-rc.1",
|
|
24
|
+
"valixa": "^1.0.0-rc.1",
|
|
25
|
+
"rxjs": "^7.8.0"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"tslib": "^2.8.1"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public",
|
|
32
|
+
"registry": "https://registry.npmjs.org/",
|
|
33
|
+
"tag": "next"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"forms",
|
|
37
|
+
"validation",
|
|
38
|
+
"typescript",
|
|
39
|
+
"headless",
|
|
40
|
+
"valixa",
|
|
41
|
+
"angular"
|
|
42
|
+
],
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=20.19.0"
|
|
45
|
+
},
|
|
46
|
+
"types": "./types/valixa-angular-material.d.ts",
|
|
47
|
+
"files": [
|
|
48
|
+
"fesm2022",
|
|
49
|
+
"types",
|
|
50
|
+
"README.md",
|
|
51
|
+
"LICENSE"
|
|
52
|
+
],
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "https://github.com/Heshammesalam/Valixa.git",
|
|
56
|
+
"directory": "packages/angular-material"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://github.com/Heshammesalam/Valixa#readme",
|
|
59
|
+
"bugs": {
|
|
60
|
+
"url": "https://github.com/Heshammesalam/Valixa/issues"
|
|
61
|
+
},
|
|
62
|
+
"module": "fesm2022/valixa-angular-material.mjs",
|
|
63
|
+
"typings": "types/valixa-angular-material.d.ts"
|
|
6
64
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ValixaFieldDirective, ValixaControlAdapter, ControlStatus, ValueCodec } from 'valixa-angular';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
|
|
4
|
+
/** Actual Material selectors and DI tokens define supported hosts; no component-name guessing. */
|
|
5
|
+
declare class ValixaMaterialDirective implements ValixaControlAdapter<unknown> {
|
|
6
|
+
readonly preserveViewOnChange = true;
|
|
7
|
+
private readonly input;
|
|
8
|
+
private readonly select;
|
|
9
|
+
private readonly checkbox;
|
|
10
|
+
private readonly radio;
|
|
11
|
+
private readonly toggle;
|
|
12
|
+
private readonly autocomplete;
|
|
13
|
+
private readonly date;
|
|
14
|
+
private readonly dateAdapter;
|
|
15
|
+
get requiresCodec(): boolean;
|
|
16
|
+
private readonly host;
|
|
17
|
+
private readonly renderer;
|
|
18
|
+
private readonly changeDetector;
|
|
19
|
+
private readonly adapter;
|
|
20
|
+
private invalid;
|
|
21
|
+
private readonly matcher;
|
|
22
|
+
constructor();
|
|
23
|
+
writeValue(value: unknown): void;
|
|
24
|
+
connect(change: (value: unknown) => void, touched: () => void): () => void;
|
|
25
|
+
setState(state: ControlStatus): void;
|
|
26
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ValixaMaterialDirective, never>;
|
|
27
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<ValixaMaterialDirective, "input[matInput][valixaField],textarea[matInput][valixaField],mat-select[valixaField],mat-checkbox[valixaField],mat-radio-group[valixaField],mat-slide-toggle[valixaField]", never, {}, {}, never, never, true, never>;
|
|
28
|
+
}
|
|
29
|
+
/** Import this tuple into a standalone component's imports. */
|
|
30
|
+
declare const VALIXA_MATERIAL: readonly [typeof ValixaFieldDirective, typeof ValixaMaterialDirective];
|
|
31
|
+
|
|
32
|
+
/** NativeDateAdapter civil date codec. 'invalid' must be rejected by a blueprint validator. */
|
|
33
|
+
declare const dateOnlyCodec: ValueCodec<string | null, Date | null>;
|
|
34
|
+
/** Object options commit; search strings/clearing commit null, preventing stale selection submission. */
|
|
35
|
+
declare function autocompleteCodec<T extends object>(isOption: (value: unknown) => value is T): ValueCodec<T | null, T | string | null>;
|
|
36
|
+
|
|
37
|
+
export { VALIXA_MATERIAL, ValixaMaterialDirective, autocompleteCodec, dateOnlyCodec };
|
|
38
|
+
//# sourceMappingURL=valixa-angular-material.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"valixa-angular-material.d.ts","sources":["../../src/material.ts","../../src/codecs.ts"],"mappings":";;;AAaA;AACA,cAKa,uBAAwB,YAAW,oBAAoB;;AAElE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAQA;AACA;AAOA,oBAAgB,aAAa;yCAhClB,uBAAuB;2CAAvB,uBAAuB;AAiDnC;AACD;AACA,cAAa,eAAe,mBAAA,oBAAA,SAAA,uBAAA;;ACpE5B;AACA,cAAa,aAAa,EAAE,UAAU,gBAAgB,IAAI;AAa1D;AACA,iBAAgB,iBAAiB,8DAA8D,UAAU;;","names":[]}
|