iss-ctrl 0.0.20 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/fesm2022/iss-ctrl-attachment.viewer-DVUL39xd.mjs +110 -0
- package/fesm2022/iss-ctrl-attachment.viewer-DVUL39xd.mjs.map +1 -0
- package/fesm2022/iss-ctrl-base.mjs +663 -0
- package/fesm2022/iss-ctrl-base.mjs.map +1 -0
- package/fesm2022/iss-ctrl-checkbox.field-Dj5EGLUr.mjs +92 -0
- package/fesm2022/iss-ctrl-checkbox.field-Dj5EGLUr.mjs.map +1 -0
- package/fesm2022/iss-ctrl-checkbox.mjs +143 -0
- package/fesm2022/iss-ctrl-checkbox.mjs.map +1 -0
- package/fesm2022/iss-ctrl-checkbox.viewer-C3SEUszR.mjs +31 -0
- package/fesm2022/iss-ctrl-checkbox.viewer-C3SEUszR.mjs.map +1 -0
- package/fesm2022/iss-ctrl-chips.field-BLLAjBbP.mjs +76 -0
- package/fesm2022/iss-ctrl-chips.field-BLLAjBbP.mjs.map +1 -0
- package/fesm2022/iss-ctrl-chips.mjs +168 -0
- package/fesm2022/iss-ctrl-chips.mjs.map +1 -0
- package/fesm2022/iss-ctrl-chips.viewer-BcKT2hcq.mjs +38 -0
- package/fesm2022/iss-ctrl-chips.viewer-BcKT2hcq.mjs.map +1 -0
- package/fesm2022/iss-ctrl-date-picker.field-BSpXukpO.mjs +98 -0
- package/fesm2022/iss-ctrl-date-picker.field-BSpXukpO.mjs.map +1 -0
- package/fesm2022/iss-ctrl-date-picker.mjs +200 -0
- package/fesm2022/iss-ctrl-date-picker.mjs.map +1 -0
- package/fesm2022/iss-ctrl-date-picker.viewer-Dsmsf91t.mjs +40 -0
- package/fesm2022/iss-ctrl-date-picker.viewer-Dsmsf91t.mjs.map +1 -0
- package/fesm2022/iss-ctrl-date-range-picker.field-CjNHU1RW.mjs +97 -0
- package/fesm2022/iss-ctrl-date-range-picker.field-CjNHU1RW.mjs.map +1 -0
- package/fesm2022/iss-ctrl-date-range-picker.mjs +307 -0
- package/fesm2022/iss-ctrl-date-range-picker.mjs.map +1 -0
- package/fesm2022/iss-ctrl-date-range-picker.viewer-tmTQGPFh.mjs +41 -0
- package/fesm2022/iss-ctrl-date-range-picker.viewer-tmTQGPFh.mjs.map +1 -0
- package/fesm2022/iss-ctrl-datetime-picker.field-DGMY9PaU.mjs +98 -0
- package/fesm2022/iss-ctrl-datetime-picker.field-DGMY9PaU.mjs.map +1 -0
- package/fesm2022/iss-ctrl-datetime-picker.mjs +226 -0
- package/fesm2022/iss-ctrl-datetime-picker.mjs.map +1 -0
- package/fesm2022/iss-ctrl-datetime-picker.viewer-BeUyEBKo.mjs +42 -0
- package/fesm2022/iss-ctrl-datetime-picker.viewer-BeUyEBKo.mjs.map +1 -0
- package/fesm2022/iss-ctrl-file-picker.field-CbepZaX6.mjs +210 -0
- package/fesm2022/iss-ctrl-file-picker.field-CbepZaX6.mjs.map +1 -0
- package/fesm2022/iss-ctrl-file-picker.mjs +272 -0
- package/fesm2022/iss-ctrl-file-picker.mjs.map +1 -0
- package/fesm2022/iss-ctrl-input.field-Ctlf3OCN.mjs +104 -0
- package/fesm2022/iss-ctrl-input.field-Ctlf3OCN.mjs.map +1 -0
- package/fesm2022/iss-ctrl-input.mjs +204 -0
- package/fesm2022/iss-ctrl-input.mjs.map +1 -0
- package/fesm2022/iss-ctrl-input.viewer-BOZnW0_e.mjs +22 -0
- package/fesm2022/iss-ctrl-input.viewer-BOZnW0_e.mjs.map +1 -0
- package/fesm2022/iss-ctrl-iss-ctrl-DvnkwSMG.mjs +1789 -0
- package/fesm2022/iss-ctrl-iss-ctrl-DvnkwSMG.mjs.map +1 -0
- package/fesm2022/{iss-ctrl-load-event-BcWMow3s.mjs → iss-ctrl-load-event-CuZ7pMjk.mjs} +4 -3
- package/fesm2022/iss-ctrl-load-event-CuZ7pMjk.mjs.map +1 -0
- package/fesm2022/{iss-ctrl-load-options-event-sTdrxJYn.mjs → iss-ctrl-load-options-event-B10rhdqh.mjs} +3 -3
- package/fesm2022/{iss-ctrl-load-options-event-sTdrxJYn.mjs.map → iss-ctrl-load-options-event-B10rhdqh.mjs.map} +1 -1
- package/fesm2022/{iss-ctrl-load-value-event-BG9zEexV.mjs → iss-ctrl-load-value-event-C-aRgKLx.mjs} +3 -3
- package/fesm2022/{iss-ctrl-load-value-event-BG9zEexV.mjs.map → iss-ctrl-load-value-event-C-aRgKLx.mjs.map} +1 -1
- package/fesm2022/iss-ctrl-mobile.field-DXVYT3q-.mjs +77 -0
- package/fesm2022/iss-ctrl-mobile.field-DXVYT3q-.mjs.map +1 -0
- package/fesm2022/iss-ctrl-mobile.mjs +2465 -0
- package/fesm2022/iss-ctrl-mobile.mjs.map +1 -0
- package/fesm2022/iss-ctrl-mobile.viewer-DQgxAcR-.mjs +22 -0
- package/fesm2022/iss-ctrl-mobile.viewer-DQgxAcR-.mjs.map +1 -0
- package/fesm2022/{iss-ctrl-note.field-DyOSzuIi.mjs → iss-ctrl-note.field-C8X9-mgD.mjs} +2 -2
- package/fesm2022/{iss-ctrl-note.field-DyOSzuIi.mjs.map → iss-ctrl-note.field-C8X9-mgD.mjs.map} +1 -1
- package/fesm2022/iss-ctrl-plate.field-aI81tAOV.mjs +92 -0
- package/fesm2022/iss-ctrl-plate.field-aI81tAOV.mjs.map +1 -0
- package/fesm2022/iss-ctrl-plate.mjs +491 -0
- package/fesm2022/iss-ctrl-plate.mjs.map +1 -0
- package/fesm2022/iss-ctrl-plate.viewer-B8PUBLH8.mjs +179 -0
- package/fesm2022/iss-ctrl-plate.viewer-B8PUBLH8.mjs.map +1 -0
- package/fesm2022/iss-ctrl-radio.field-B_JjPIlb.mjs +96 -0
- package/fesm2022/iss-ctrl-radio.field-B_JjPIlb.mjs.map +1 -0
- package/fesm2022/iss-ctrl-radio.mjs +101 -0
- package/fesm2022/iss-ctrl-radio.mjs.map +1 -0
- package/fesm2022/iss-ctrl-radio.viewer-EiDliZro.mjs +30 -0
- package/fesm2022/iss-ctrl-radio.viewer-EiDliZro.mjs.map +1 -0
- package/fesm2022/{iss-ctrl-replace-api-keys-CzJkn7fK.mjs → iss-ctrl-replace-api-keys-DLnagkOr.mjs} +2 -2
- package/fesm2022/{iss-ctrl-replace-api-keys-CzJkn7fK.mjs.map → iss-ctrl-replace-api-keys-DLnagkOr.mjs.map} +1 -1
- package/fesm2022/iss-ctrl-select.field-DoU4G_8t.mjs +87 -0
- package/fesm2022/iss-ctrl-select.field-DoU4G_8t.mjs.map +1 -0
- package/fesm2022/iss-ctrl-select.mjs +387 -0
- package/fesm2022/iss-ctrl-select.mjs.map +1 -0
- package/fesm2022/iss-ctrl-select.viewer-Dv9M-lG-.mjs +30 -0
- package/fesm2022/iss-ctrl-select.viewer-Dv9M-lG-.mjs.map +1 -0
- package/fesm2022/{iss-ctrl-set-value-event-B800MsyP.mjs → iss-ctrl-set-value-event-Dhw0Vj5J.mjs} +2 -2
- package/fesm2022/{iss-ctrl-set-value-event-B800MsyP.mjs.map → iss-ctrl-set-value-event-Dhw0Vj5J.mjs.map} +1 -1
- package/fesm2022/iss-ctrl-slide-toggle.field-TVVbAr6p.mjs +85 -0
- package/fesm2022/iss-ctrl-slide-toggle.field-TVVbAr6p.mjs.map +1 -0
- package/fesm2022/iss-ctrl-slide-toggle.mjs +72 -0
- package/fesm2022/iss-ctrl-slide-toggle.mjs.map +1 -0
- package/fesm2022/iss-ctrl-slide-toggle.viewer-hsIHwDj3.mjs +34 -0
- package/fesm2022/iss-ctrl-slide-toggle.viewer-hsIHwDj3.mjs.map +1 -0
- package/fesm2022/{iss-ctrl-table.field-CJmtpHsh.mjs → iss-ctrl-table.field-E0r9w0os.mjs} +142 -140
- package/fesm2022/iss-ctrl-table.field-E0r9w0os.mjs.map +1 -0
- package/fesm2022/iss-ctrl-textarea.field-CmHPDpk-.mjs +82 -0
- package/fesm2022/iss-ctrl-textarea.field-CmHPDpk-.mjs.map +1 -0
- package/fesm2022/iss-ctrl-textarea.mjs +115 -0
- package/fesm2022/iss-ctrl-textarea.mjs.map +1 -0
- package/fesm2022/iss-ctrl-textarea.viewer-CpmLauik.mjs +22 -0
- package/fesm2022/iss-ctrl-textarea.viewer-CpmLauik.mjs.map +1 -0
- package/fesm2022/iss-ctrl-time-picker.field-Cb0I5Ut1.mjs +77 -0
- package/fesm2022/iss-ctrl-time-picker.field-Cb0I5Ut1.mjs.map +1 -0
- package/fesm2022/iss-ctrl-time-picker.mjs +170 -0
- package/fesm2022/iss-ctrl-time-picker.mjs.map +1 -0
- package/fesm2022/iss-ctrl-time-picker.viewer-CJeFLrdI.mjs +22 -0
- package/fesm2022/iss-ctrl-time-picker.viewer-CJeFLrdI.mjs.map +1 -0
- package/fesm2022/iss-ctrl-toggle-button.field-Bj8WrkB-.mjs +105 -0
- package/fesm2022/iss-ctrl-toggle-button.field-Bj8WrkB-.mjs.map +1 -0
- package/fesm2022/iss-ctrl-toggle-button.mjs +156 -0
- package/fesm2022/iss-ctrl-toggle-button.mjs.map +1 -0
- package/fesm2022/iss-ctrl-toggle-button.viewer-CC-8_Dy4.mjs +30 -0
- package/fesm2022/iss-ctrl-toggle-button.viewer-CC-8_Dy4.mjs.map +1 -0
- package/fesm2022/iss-ctrl-tokens.mjs +25 -0
- package/fesm2022/iss-ctrl-tokens.mjs.map +1 -0
- package/fesm2022/{iss-ctrl-trigger-based-on-json-value-C5x0hyWn.mjs → iss-ctrl-trigger-based-on-json-value-D9rTXVD1.mjs} +2 -2
- package/fesm2022/{iss-ctrl-trigger-based-on-json-value-C5x0hyWn.mjs.map → iss-ctrl-trigger-based-on-json-value-D9rTXVD1.mjs.map} +1 -1
- package/fesm2022/{iss-ctrl-user-picker.field-CJqIvkMM.mjs → iss-ctrl-user-picker.field-BIzB5ZX6.mjs} +151 -150
- package/fesm2022/iss-ctrl-user-picker.field-BIzB5ZX6.mjs.map +1 -0
- package/fesm2022/iss-ctrl.mjs +3 -1
- package/fesm2022/iss-ctrl.mjs.map +1 -1
- package/package.json +69 -1
- package/types/iss-ctrl-base.d.ts +306 -0
- package/types/iss-ctrl-checkbox.d.ts +45 -0
- package/types/iss-ctrl-chips.d.ts +41 -0
- package/types/iss-ctrl-date-picker.d.ts +75 -0
- package/types/iss-ctrl-date-range-picker.d.ts +95 -0
- package/types/iss-ctrl-datetime-picker.d.ts +77 -0
- package/types/iss-ctrl-file-picker.d.ts +95 -0
- package/types/iss-ctrl-input.d.ts +76 -0
- package/types/iss-ctrl-mobile.d.ts +91 -0
- package/types/iss-ctrl-plate.d.ts +54 -0
- package/types/iss-ctrl-radio.d.ts +34 -0
- package/types/iss-ctrl-select.d.ts +75 -0
- package/types/iss-ctrl-slide-toggle.d.ts +26 -0
- package/types/iss-ctrl-textarea.d.ts +30 -0
- package/types/iss-ctrl-time-picker.d.ts +48 -0
- package/types/iss-ctrl-toggle-button.d.ts +41 -0
- package/types/iss-ctrl-tokens.d.ts +21 -0
- package/types/iss-ctrl.d.ts +120 -1792
- package/upgrade.scss +30 -18
- package/fesm2022/iss-ctrl-iss-ctrl-BnwwafES.mjs +0 -9629
- package/fesm2022/iss-ctrl-iss-ctrl-BnwwafES.mjs.map +0 -1
- package/fesm2022/iss-ctrl-load-event-BcWMow3s.mjs.map +0 -1
- package/fesm2022/iss-ctrl-table.field-CJmtpHsh.mjs.map +0 -1
- package/fesm2022/iss-ctrl-user-picker.field-CJqIvkMM.mjs.map +0 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { signal, CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
|
|
3
|
+
import { ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
4
|
+
import { MatChipGrid, MatChipRow, MatChipInput, MatChipRemove } from '@angular/material/chips';
|
|
5
|
+
import { MatFormField } from '@angular/material/form-field';
|
|
6
|
+
import * as i1 from '@angular/material/input';
|
|
7
|
+
import { MatInput, MatInputModule } from '@angular/material/input';
|
|
8
|
+
import { ControlBase } from 'iss-ctrl/base';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* `<iss-ctrl-chips>` — free text entered as removable chips.
|
|
12
|
+
*
|
|
13
|
+
* Each `Enter` turns the typed text into a chip. The form value is the comma separated list
|
|
14
|
+
* of chip labels.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```html
|
|
18
|
+
* <iss-ctrl-chips formControlName="tags" placeholder="Add a tag">
|
|
19
|
+
* <label>Tags</label>
|
|
20
|
+
* </iss-ctrl-chips>
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* ### Own inputs
|
|
24
|
+
* None — the control is configured entirely through the inherited properties.
|
|
25
|
+
*
|
|
26
|
+
* ### Inherited from {@link ControlBase}
|
|
27
|
+
* `formControlName` · `readonly` · `className` · `(onChange)` · `placeholder`
|
|
28
|
+
*
|
|
29
|
+
* Projects `<label>` into the floating label; omit it to render the control without one.
|
|
30
|
+
*/
|
|
31
|
+
class ChipsControl extends ControlBase {
|
|
32
|
+
/**
|
|
33
|
+
* The chips currently rendered. Internal state, not an input.
|
|
34
|
+
*/
|
|
35
|
+
keywords = signal([], ...(ngDevMode ? [{ debugName: "keywords" }] : /* istanbul ignore next */ []));
|
|
36
|
+
writeValue(value) {
|
|
37
|
+
if (typeof value === "string") {
|
|
38
|
+
this.keywords.set(this.#parseValues(value));
|
|
39
|
+
}
|
|
40
|
+
if (value === undefined || value === null) {
|
|
41
|
+
this.keywords.set([]);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
remove(keyword) {
|
|
45
|
+
if (this.disabled() || this.readonly()) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.markAsTouched();
|
|
49
|
+
this.keywords.update((keywords) => {
|
|
50
|
+
const index = keywords.indexOf(keyword);
|
|
51
|
+
if (index < 0) {
|
|
52
|
+
return keywords;
|
|
53
|
+
}
|
|
54
|
+
keywords.splice(index, 1);
|
|
55
|
+
return [...keywords];
|
|
56
|
+
});
|
|
57
|
+
this.emitValue(this.#stringifyValues());
|
|
58
|
+
}
|
|
59
|
+
add(event) {
|
|
60
|
+
if (this.disabled() || this.readonly()) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.markAsTouched();
|
|
64
|
+
const value = (event.value || "").trim();
|
|
65
|
+
if (value) {
|
|
66
|
+
this.keywords.update((keywords) => [...keywords, value]);
|
|
67
|
+
}
|
|
68
|
+
event.chipInput.clear();
|
|
69
|
+
this.emitValue(this.#stringifyValues());
|
|
70
|
+
}
|
|
71
|
+
// the chips are the value here; `ctrl` stays untouched
|
|
72
|
+
isEmpty() {
|
|
73
|
+
return this.keywords().length === 0;
|
|
74
|
+
}
|
|
75
|
+
#stringifyValues() {
|
|
76
|
+
return this.keywords().map((s) => s.trim()).join();
|
|
77
|
+
}
|
|
78
|
+
#parseValues(values) {
|
|
79
|
+
return values.split(",").map((c) => c.trim());
|
|
80
|
+
}
|
|
81
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ChipsControl, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
82
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ChipsControl, isStandalone: true, selector: "iss-ctrl-chips", providers: [
|
|
83
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: ChipsControl, multi: true }
|
|
84
|
+
], usesInheritance: true, ngImport: i0, template: `
|
|
85
|
+
<mat-form-field floatLabel="auto" class="">
|
|
86
|
+
<!-- Always rendered: upgrade.scss shows the floating label only while the projected <label> carries text, so an omitted or empty one collapses on its own. -->
|
|
87
|
+
<mat-label class="fs-16 fc-dark-gray">
|
|
88
|
+
<ng-content select="label"></ng-content>
|
|
89
|
+
</mat-label>
|
|
90
|
+
<input
|
|
91
|
+
matInput
|
|
92
|
+
[errorStateMatcher]="errorStateMatcher"
|
|
93
|
+
[placeholder]="placeholder()"
|
|
94
|
+
[matChipInputFor]="chipGrid"
|
|
95
|
+
[disabled]="disabled()"
|
|
96
|
+
[readonly]="readonly()"
|
|
97
|
+
(matChipInputTokenEnd)="add($event)"
|
|
98
|
+
/>
|
|
99
|
+
</mat-form-field>
|
|
100
|
+
<mat-chip-grid #chipGrid>
|
|
101
|
+
@for (keyword of keywords(); track keyword) {
|
|
102
|
+
<mat-chip-row (removed)="remove(keyword)">
|
|
103
|
+
{{ keyword }}
|
|
104
|
+
<button matChipRemove [disabled]="disabled() || readonly()">
|
|
105
|
+
<ds-icon icon="trash" class="fc-red"></ds-icon>
|
|
106
|
+
</button>
|
|
107
|
+
</mat-chip-row>
|
|
108
|
+
}
|
|
109
|
+
</mat-chip-grid>
|
|
110
|
+
`, isInline: true, dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "component", type: MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatChipRemove, selector: "[matChipRemove]" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i1.MatLabel, selector: "mat-label" }] });
|
|
111
|
+
}
|
|
112
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ChipsControl, decorators: [{
|
|
113
|
+
type: Component,
|
|
114
|
+
args: [{
|
|
115
|
+
selector: "iss-ctrl-chips",
|
|
116
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
117
|
+
imports: [
|
|
118
|
+
MatFormField,
|
|
119
|
+
MatChipGrid,
|
|
120
|
+
MatChipRow,
|
|
121
|
+
ReactiveFormsModule,
|
|
122
|
+
MatChipInput,
|
|
123
|
+
MatInput,
|
|
124
|
+
MatChipRemove,
|
|
125
|
+
MatInputModule,
|
|
126
|
+
],
|
|
127
|
+
providers: [
|
|
128
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: ChipsControl, multi: true }
|
|
129
|
+
],
|
|
130
|
+
template: `
|
|
131
|
+
<mat-form-field floatLabel="auto" class="">
|
|
132
|
+
<!-- Always rendered: upgrade.scss shows the floating label only while the projected <label> carries text, so an omitted or empty one collapses on its own. -->
|
|
133
|
+
<mat-label class="fs-16 fc-dark-gray">
|
|
134
|
+
<ng-content select="label"></ng-content>
|
|
135
|
+
</mat-label>
|
|
136
|
+
<input
|
|
137
|
+
matInput
|
|
138
|
+
[errorStateMatcher]="errorStateMatcher"
|
|
139
|
+
[placeholder]="placeholder()"
|
|
140
|
+
[matChipInputFor]="chipGrid"
|
|
141
|
+
[disabled]="disabled()"
|
|
142
|
+
[readonly]="readonly()"
|
|
143
|
+
(matChipInputTokenEnd)="add($event)"
|
|
144
|
+
/>
|
|
145
|
+
</mat-form-field>
|
|
146
|
+
<mat-chip-grid #chipGrid>
|
|
147
|
+
@for (keyword of keywords(); track keyword) {
|
|
148
|
+
<mat-chip-row (removed)="remove(keyword)">
|
|
149
|
+
{{ keyword }}
|
|
150
|
+
<button matChipRemove [disabled]="disabled() || readonly()">
|
|
151
|
+
<ds-icon icon="trash" class="fc-red"></ds-icon>
|
|
152
|
+
</button>
|
|
153
|
+
</mat-chip-row>
|
|
154
|
+
}
|
|
155
|
+
</mat-chip-grid>
|
|
156
|
+
`
|
|
157
|
+
}]
|
|
158
|
+
}] });
|
|
159
|
+
|
|
160
|
+
// The chips control. Its field and viewer stay in the primary entry point and reach it
|
|
161
|
+
// from there, so the control ships only to an app that renders it or imports it directly.
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Generated bundle index. Do not edit.
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
export { ChipsControl };
|
|
168
|
+
//# sourceMappingURL=iss-ctrl-chips.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iss-ctrl-chips.mjs","sources":["../../../projects/iss/chips/src/chips.control.ts","../../../projects/iss/chips/src/public-api.ts","../../../projects/iss/chips/src/iss-ctrl-chips.ts"],"sourcesContent":["import { Component, CUSTOM_ELEMENTS_SCHEMA, signal, WritableSignal } from \"@angular/core\";\nimport { NG_VALUE_ACCESSOR, ReactiveFormsModule } from \"@angular/forms\";\nimport { MatChipGrid, MatChipInput, MatChipInputEvent, MatChipRemove, MatChipRow } from \"@angular/material/chips\";\nimport { MatFormField } from \"@angular/material/form-field\";\nimport { MatInput, MatInputModule } from \"@angular/material/input\";\nimport { ControlBase } from \"iss-ctrl/base\";\n\n/**\n * `<iss-ctrl-chips>` — free text entered as removable chips.\n *\n * Each `Enter` turns the typed text into a chip. The form value is the comma separated list\n * of chip labels.\n *\n * @example\n * ```html\n * <iss-ctrl-chips formControlName=\"tags\" placeholder=\"Add a tag\">\n * <label>Tags</label>\n * </iss-ctrl-chips>\n * ```\n *\n * ### Own inputs\n * None — the control is configured entirely through the inherited properties.\n *\n * ### Inherited from {@link ControlBase}\n * `formControlName` · `readonly` · `className` · `(onChange)` · `placeholder`\n *\n * Projects `<label>` into the floating label; omit it to render the control without one.\n */\n@Component({\n selector: \"iss-ctrl-chips\",\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n imports: [\n MatFormField,\n MatChipGrid,\n MatChipRow,\n ReactiveFormsModule,\n MatChipInput,\n MatInput,\n MatChipRemove,\n MatInputModule,\n ],\n providers: [\n { provide: NG_VALUE_ACCESSOR, useExisting: ChipsControl, multi: true }\n ],\n template: `\n <mat-form-field floatLabel=\"auto\" class=\"\">\n <!-- Always rendered: upgrade.scss shows the floating label only while the projected <label> carries text, so an omitted or empty one collapses on its own. -->\n <mat-label class=\"fs-16 fc-dark-gray\">\n <ng-content select=\"label\"></ng-content>\n </mat-label>\n <input\n matInput\n [errorStateMatcher]=\"errorStateMatcher\"\n [placeholder]=\"placeholder()\"\n [matChipInputFor]=\"chipGrid\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n (matChipInputTokenEnd)=\"add($event)\"\n />\n </mat-form-field>\n <mat-chip-grid #chipGrid>\n @for (keyword of keywords(); track keyword) {\n <mat-chip-row (removed)=\"remove(keyword)\">\n {{ keyword }}\n <button matChipRemove [disabled]=\"disabled() || readonly()\">\n <ds-icon icon=\"trash\" class=\"fc-red\"></ds-icon>\n </button>\n </mat-chip-row>\n }\n </mat-chip-grid>\n `\n})\nexport class ChipsControl extends ControlBase {\n /**\n * The chips currently rendered. Internal state, not an input.\n */\n readonly keywords: WritableSignal<string[]> = signal([]);\n\n override writeValue(value: string | null) {\n if (typeof value === \"string\") {\n this.keywords.set(this.#parseValues(value));\n }\n if (value === undefined || value === null) {\n this.keywords.set([]);\n }\n }\n\n remove(keyword: string) {\n if (this.disabled() || this.readonly()) {\n return;\n }\n this.markAsTouched();\n this.keywords.update((keywords: string[]): string[] => {\n const index: number = keywords.indexOf(keyword);\n if (index < 0) {\n return keywords;\n }\n keywords.splice(index, 1);\n return [...keywords];\n });\n this.emitValue(this.#stringifyValues());\n }\n\n add(event: MatChipInputEvent): void {\n if (this.disabled() || this.readonly()) {\n return;\n }\n this.markAsTouched();\n const value: string = (event.value || \"\").trim();\n if (value) {\n this.keywords.update((keywords: string[]): string[] => [...keywords, value]);\n }\n event.chipInput!.clear();\n this.emitValue(this.#stringifyValues());\n }\n\n // the chips are the value here; `ctrl` stays untouched\n protected override isEmpty(): boolean {\n return this.keywords().length === 0;\n }\n\n #stringifyValues() {\n return this.keywords().map((s: string) => s.trim()).join();\n }\n\n #parseValues(values: string) {\n return values.split(\",\").map((c: string) => c.trim());\n }\n}\n","// The chips control. Its field and viewer stay in the primary entry point and reach it\n// from there, so the control ships only to an app that renders it or imports it directly.\n\nexport * from \"./chips.control\";\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { computed, Component } from '@angular/core';
|
|
3
|
+
import { MatChipSet, MatChip } from '@angular/material/chips';
|
|
4
|
+
import { ViewerBase } from 'iss-ctrl/base';
|
|
5
|
+
|
|
6
|
+
class ChipsViewer extends ViewerBase {
|
|
7
|
+
keywords = computed(() => {
|
|
8
|
+
return this.field().ctrlValue().split(",").map((c) => c.trim());
|
|
9
|
+
}, ...(ngDevMode ? [{ debugName: "keywords" }] : /* istanbul ignore next */ []));
|
|
10
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ChipsViewer, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
11
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: ChipsViewer, isStandalone: true, selector: "iss-viewer-chips", usesInheritance: true, ngImport: i0, template: `
|
|
12
|
+
<mat-chip-set>
|
|
13
|
+
@for (keyword of keywords(); track keyword) {
|
|
14
|
+
<mat-chip>{{ keyword }}</mat-chip>
|
|
15
|
+
}
|
|
16
|
+
</mat-chip-set>
|
|
17
|
+
`, isInline: true, dependencies: [{ kind: "component", type: MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }] });
|
|
18
|
+
}
|
|
19
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: ChipsViewer, decorators: [{
|
|
20
|
+
type: Component,
|
|
21
|
+
args: [{
|
|
22
|
+
selector: "iss-viewer-chips",
|
|
23
|
+
imports: [
|
|
24
|
+
MatChipSet,
|
|
25
|
+
MatChip
|
|
26
|
+
],
|
|
27
|
+
template: `
|
|
28
|
+
<mat-chip-set>
|
|
29
|
+
@for (keyword of keywords(); track keyword) {
|
|
30
|
+
<mat-chip>{{ keyword }}</mat-chip>
|
|
31
|
+
}
|
|
32
|
+
</mat-chip-set>
|
|
33
|
+
`
|
|
34
|
+
}]
|
|
35
|
+
}] });
|
|
36
|
+
|
|
37
|
+
export { ChipsViewer };
|
|
38
|
+
//# sourceMappingURL=iss-ctrl-chips.viewer-BcKT2hcq.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iss-ctrl-chips.viewer-BcKT2hcq.mjs","sources":["../../../projects/iss/src/components/controls/chips/chips.viewer.ts"],"sourcesContent":["import { Component, computed } from \"@angular/core\";\nimport { MatChip, MatChipSet } from \"@angular/material/chips\";\nimport { ViewerBase } from \"iss-ctrl/base\";\n\n@Component({\n selector: \"iss-viewer-chips\",\n imports: [\n MatChipSet,\n MatChip\n ],\n template: `\n <mat-chip-set>\n @for (keyword of keywords(); track keyword) {\n <mat-chip>{{ keyword }}</mat-chip>\n }\n </mat-chip-set>\n `\n})\nexport class ChipsViewer extends ViewerBase {\n keywords = computed(() => {\n return this.field().ctrlValue().split(\",\").map((c: string) => c.trim());\n });\n}\n"],"names":[],"mappings":";;;;;AAkBM,MAAO,WAAY,SAAQ,UAAU,CAAA;AACzC,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAK;QACvB,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;AACzE,IAAA,CAAC,+EAAC;uGAHS,WAAW,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EARZ;;;;;;GAMT,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EATC,UAAU,mGACV,OAAO,EAAA,QAAA,EAAA,wDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,OAAA,EAAA,OAAA,EAAA,WAAA,EAAA,aAAA,EAAA,eAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,SAAA,EAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAUE,WAAW,EAAA,UAAA,EAAA,CAAA;kBAdvB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,kBAAkB;AAC5B,oBAAA,OAAO,EAAE;wBACP,UAAU;wBACV;AACD,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;AAMT,EAAA;AACF,iBAAA;;;;;"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Component } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/forms';
|
|
4
|
+
import { ReactiveFormsModule } from '@angular/forms';
|
|
5
|
+
import { F as FieldBase, V as VIEW_PROVIDER, a as ValidationMessage, b as FieldViewer } from './iss-ctrl-iss-ctrl-DvnkwSMG.mjs';
|
|
6
|
+
import { DatePickerControl } from 'iss-ctrl/date-picker';
|
|
7
|
+
import { DatePickerViewer } from './iss-ctrl-date-picker.viewer-Dsmsf91t.mjs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `<iss-field-date-picker>` — a single date, picked from a calendar.
|
|
11
|
+
*
|
|
12
|
+
* Rendered by the outlet for fields of type `date`. In `edit` mode it renders
|
|
13
|
+
* {@link DatePickerControl} plus the validation message; in `view` mode the matching viewer.
|
|
14
|
+
*
|
|
15
|
+
* ### Supported `config` keys
|
|
16
|
+
* | Key | Type | Description |
|
|
17
|
+
* | --- | --- | --- |
|
|
18
|
+
* | `minDate` | `Date` | Earliest selectable date. |
|
|
19
|
+
* | `maxDate` | `Date` | Latest selectable date. |
|
|
20
|
+
* | `readonly` | `boolean` | Shows the value but blocks interaction. |
|
|
21
|
+
* | `hijriCalendar` | `boolean` | Renders an Umm al-Qura Hijri calendar while the emitted value stays Gregorian. |
|
|
22
|
+
* | `emitHijri` | `boolean` | Emits the Hijri date instead of the Gregorian one. Implies `hijriCalendar`. |
|
|
23
|
+
*
|
|
24
|
+
* ### Other field members used
|
|
25
|
+
* `label()`
|
|
26
|
+
*
|
|
27
|
+
* Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and
|
|
28
|
+
* `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```json
|
|
32
|
+
* { "name": "startsOn", "type": "date", "label": "Start date", "config": { "minDate": "2026-01-01" } }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
class DatePickerField extends FieldBase {
|
|
36
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatePickerField, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
37
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DatePickerField, isStandalone: true, selector: "iss-field-date-picker", usesInheritance: true, ngImport: i0, template: `
|
|
38
|
+
@if (field.visible()) {
|
|
39
|
+
@if (field.mode() === "edit") {
|
|
40
|
+
<iss-ctrl-date-picker
|
|
41
|
+
[formControlName]="field.name"
|
|
42
|
+
[minDate]="field.config.minDate() ?? null"
|
|
43
|
+
[maxDate]="field.config.maxDate() ?? null"
|
|
44
|
+
[readonly]="field.config.readonly() ?? false"
|
|
45
|
+
[hijriCalendar]="field.config.hijriCalendar() ?? false"
|
|
46
|
+
[emitHijri]="field.config.emitHijri() ?? false"
|
|
47
|
+
>
|
|
48
|
+
<label>{{ field.label() }}</label>
|
|
49
|
+
</iss-ctrl-date-picker>
|
|
50
|
+
<iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
|
|
51
|
+
} @else {
|
|
52
|
+
<iss-field-viewer>
|
|
53
|
+
<label>{{ field.label() }}</label>
|
|
54
|
+
<iss-viewer-date-picker [field]="field"/>
|
|
55
|
+
</iss-field-viewer>
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DatePickerControl, selector: "iss-ctrl-date-picker", inputs: ["disabledDays", "minDate", "maxDate", "hijriCalendar", "emitHijri"] }, { kind: "component", type: ValidationMessage, selector: "iss-validation-message-viewer", inputs: ["errors", "showMessage"] }, { kind: "component", type: DatePickerViewer, selector: "iss-viewer-date-picker" }, { kind: "component", type: FieldViewer, selector: "iss-field-viewer" }], viewProviders: [VIEW_PROVIDER] });
|
|
59
|
+
}
|
|
60
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatePickerField, decorators: [{
|
|
61
|
+
type: Component,
|
|
62
|
+
args: [{
|
|
63
|
+
selector: "iss-field-date-picker",
|
|
64
|
+
viewProviders: [VIEW_PROVIDER],
|
|
65
|
+
imports: [
|
|
66
|
+
ReactiveFormsModule,
|
|
67
|
+
DatePickerControl,
|
|
68
|
+
ValidationMessage,
|
|
69
|
+
DatePickerViewer,
|
|
70
|
+
FieldViewer
|
|
71
|
+
],
|
|
72
|
+
template: `
|
|
73
|
+
@if (field.visible()) {
|
|
74
|
+
@if (field.mode() === "edit") {
|
|
75
|
+
<iss-ctrl-date-picker
|
|
76
|
+
[formControlName]="field.name"
|
|
77
|
+
[minDate]="field.config.minDate() ?? null"
|
|
78
|
+
[maxDate]="field.config.maxDate() ?? null"
|
|
79
|
+
[readonly]="field.config.readonly() ?? false"
|
|
80
|
+
[hijriCalendar]="field.config.hijriCalendar() ?? false"
|
|
81
|
+
[emitHijri]="field.config.emitHijri() ?? false"
|
|
82
|
+
>
|
|
83
|
+
<label>{{ field.label() }}</label>
|
|
84
|
+
</iss-ctrl-date-picker>
|
|
85
|
+
<iss-validation-message-viewer [errors]="ctrl.errors" [showMessage]="!ctrl.untouched"/>
|
|
86
|
+
} @else {
|
|
87
|
+
<iss-field-viewer>
|
|
88
|
+
<label>{{ field.label() }}</label>
|
|
89
|
+
<iss-viewer-date-picker [field]="field"/>
|
|
90
|
+
</iss-field-viewer>
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
`
|
|
94
|
+
}]
|
|
95
|
+
}] });
|
|
96
|
+
|
|
97
|
+
export { DatePickerField };
|
|
98
|
+
//# sourceMappingURL=iss-ctrl-date-picker.field-BSpXukpO.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iss-ctrl-date-picker.field-BSpXukpO.mjs","sources":["../../../projects/iss/src/components/controls/date-picker/date-picker.field.ts"],"sourcesContent":["import { Component } from \"@angular/core\";\nimport { ReactiveFormsModule } from \"@angular/forms\";\nimport { VIEW_PROVIDER } from \"../../../shared/constants/view-provider.const\";\nimport { FieldViewer } from \"../../shared/field-viewer\";\nimport { ValidationMessage } from \"../../shared/validation-message\";\nimport { FieldBase } from \"../base/field-base\";\nimport { DatePickerControl } from \"iss-ctrl/date-picker\";\nimport { DatePickerViewer } from \"./date-picker.viewer\";\n\n/**\n * `<iss-field-date-picker>` — a single date, picked from a calendar.\n *\n * Rendered by the outlet for fields of type `date`. In `edit` mode it renders\n * {@link DatePickerControl} plus the validation message; in `view` mode the matching viewer.\n *\n * ### Supported `config` keys\n * | Key | Type | Description |\n * | --- | --- | --- |\n * | `minDate` | `Date` | Earliest selectable date. |\n * | `maxDate` | `Date` | Latest selectable date. |\n * | `readonly` | `boolean` | Shows the value but blocks interaction. |\n * | `hijriCalendar` | `boolean` | Renders an Umm al-Qura Hijri calendar while the emitted value stays Gregorian. |\n * | `emitHijri` | `boolean` | Emits the Hijri date instead of the Gregorian one. Implies `hijriCalendar`. |\n *\n * ### Other field members used\n * `label()`\n *\n * Every field also honours `visible`, `mode`, `validation`, `asyncValidation` and\n * `events` — see {@link IssField} for the full model and {@link FieldConfig} for all keys.\n *\n * @example\n * ```json\n * { \"name\": \"startsOn\", \"type\": \"date\", \"label\": \"Start date\", \"config\": { \"minDate\": \"2026-01-01\" } }\n * ```\n */\n@Component({\n selector: \"iss-field-date-picker\",\n viewProviders: [VIEW_PROVIDER],\n imports: [\n ReactiveFormsModule,\n DatePickerControl,\n ValidationMessage,\n DatePickerViewer,\n FieldViewer\n ],\n template: `\n @if (field.visible()) {\n @if (field.mode() === \"edit\") {\n <iss-ctrl-date-picker\n [formControlName]=\"field.name\"\n [minDate]=\"field.config.minDate() ?? null\"\n [maxDate]=\"field.config.maxDate() ?? null\"\n [readonly]=\"field.config.readonly() ?? false\"\n [hijriCalendar]=\"field.config.hijriCalendar() ?? false\"\n [emitHijri]=\"field.config.emitHijri() ?? false\"\n >\n <label>{{ field.label() }}</label>\n </iss-ctrl-date-picker>\n <iss-validation-message-viewer [errors]=\"ctrl.errors\" [showMessage]=\"!ctrl.untouched\"/>\n } @else {\n <iss-field-viewer>\n <label>{{ field.label() }}</label>\n <iss-viewer-date-picker [field]=\"field\"/>\n </iss-field-viewer>\n }\n }\n `\n})\nexport class DatePickerField extends FieldBase {}\n"],"names":[],"mappings":";;;;;;;;AASA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;AAkCG,MAAO,eAAgB,SAAQ,SAAS,CAAA;uGAAjC,eAAe,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAf,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAe,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvBhB;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EA3BC,mBAAmB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,iBAAiB,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,CAAA,cAAA,EAAA,SAAA,EAAA,SAAA,EAAA,eAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACjB,iBAAiB,EAAA,QAAA,EAAA,+BAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACjB,gBAAgB,EAAA,QAAA,EAAA,wBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAChB,WAAW,EAAA,QAAA,EAAA,kBAAA,EAAA,CAAA,EAAA,aAAA,EANE,CAAC,aAAa,CAAC,EAAA,CAAA;;2FA+BnB,eAAe,EAAA,UAAA,EAAA,CAAA;kBAjC3B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,uBAAuB;oBACjC,aAAa,EAAE,CAAC,aAAa,CAAC;AAC9B,oBAAA,OAAO,EAAE;wBACP,mBAAmB;wBACnB,iBAAiB;wBACjB,iBAAiB;wBACjB,gBAAgB;wBAChB;AACD,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA;AACF,iBAAA;;;;;"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { DatePipe } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { input, inject, effect, Component } from '@angular/core';
|
|
4
|
+
import * as i5 from '@angular/forms';
|
|
5
|
+
import { ReactiveFormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
|
6
|
+
import { DateAdapter } from '@angular/material/core';
|
|
7
|
+
import * as i3 from '@angular/material/datepicker';
|
|
8
|
+
import { MatDatepickerModule } from '@angular/material/datepicker';
|
|
9
|
+
import * as i1 from '@angular/material/form-field';
|
|
10
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
11
|
+
import * as i4 from '@angular/material/icon';
|
|
12
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
13
|
+
import * as i2 from '@angular/material/input';
|
|
14
|
+
import { MatInputModule } from '@angular/material/input';
|
|
15
|
+
import { format } from 'date-fns';
|
|
16
|
+
import { ControlBase, parseHijriDate, formatHijriDate, provideIssDateAdapter } from 'iss-ctrl/base';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* `<iss-ctrl-date-picker>` — single date selection through a Material calendar.
|
|
20
|
+
*
|
|
21
|
+
* The input itself is read-only; clicking it opens the calendar. The emitted value is a
|
|
22
|
+
* `yyyy-MM-dd` string, and a clear button appears once a date is picked.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```html
|
|
26
|
+
* <iss-ctrl-date-picker formControlName="startsOn" [minDate]="today" [disabledDays]="[5, 6]">
|
|
27
|
+
* <label>Start date</label>
|
|
28
|
+
* </iss-ctrl-date-picker>
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* ### Own inputs
|
|
32
|
+
* | Property | Type | Default | Description |
|
|
33
|
+
* | --- | --- | --- | --- |
|
|
34
|
+
* | `minDate` | `Date \| null` | `null` | Earliest selectable date. |
|
|
35
|
+
* | `maxDate` | `Date \| null` | `null` | Latest selectable date. |
|
|
36
|
+
* | `disabledDays` | `number[]` | `[]` | Week days to block, `0` = Sunday … `6` = Saturday. |
|
|
37
|
+
* | `hijriCalendar` | `boolean` | `false` | Shows an Umm al-Qura Hijri calendar; the value stays Gregorian. |
|
|
38
|
+
* | `emitHijri` | `boolean` | `false` | Emits the Hijri date instead of the Gregorian one. Implies `hijriCalendar`. |
|
|
39
|
+
*
|
|
40
|
+
* ### Hijri dates
|
|
41
|
+
* `hijriCalendar` only changes what the user sees: the calendar is Hijri, the input reads
|
|
42
|
+
* `dd/MM/yyyy` in Hijri, and a day shown as `16/03/1447` is still emitted as `2025-09-08`.
|
|
43
|
+
* Turn on `emitHijri` as well when the form value itself has to be the Hijri date. `minDate` and
|
|
44
|
+
* `maxDate` stay Gregorian in both cases — they are bounds on a day, not on a notation.
|
|
45
|
+
*
|
|
46
|
+
* ### Inherited from {@link ControlBase}
|
|
47
|
+
* `formControlName` · `readonly` · `className` · `(onChange)`
|
|
48
|
+
*
|
|
49
|
+
* Projects `<label>` into the floating label; omit it to render the control without one.
|
|
50
|
+
*/
|
|
51
|
+
class DatePickerControl extends ControlBase {
|
|
52
|
+
/**
|
|
53
|
+
* Week days that cannot be selected — `0` is Sunday through `6` for Saturday.
|
|
54
|
+
*/
|
|
55
|
+
disabledDays = input([], ...(ngDevMode ? [{ debugName: "disabledDays" }] : /* istanbul ignore next */ []));
|
|
56
|
+
/**
|
|
57
|
+
* Earliest selectable date.
|
|
58
|
+
*/
|
|
59
|
+
minDate = input(null, ...(ngDevMode ? [{ debugName: "minDate" }] : /* istanbul ignore next */ []));
|
|
60
|
+
/**
|
|
61
|
+
* Latest selectable date.
|
|
62
|
+
*/
|
|
63
|
+
maxDate = input(null, ...(ngDevMode ? [{ debugName: "maxDate" }] : /* istanbul ignore next */ []));
|
|
64
|
+
/**
|
|
65
|
+
* Renders the calendar as an Umm al-Qura Hijri calendar, leaving the emitted value Gregorian.
|
|
66
|
+
*/
|
|
67
|
+
hijriCalendar = input(false, ...(ngDevMode ? [{ debugName: "hijriCalendar" }] : /* istanbul ignore next */ []));
|
|
68
|
+
/**
|
|
69
|
+
* Emits the picked date as a Hijri `yyyy-MM-dd` string. Implies {@link hijriCalendar}.
|
|
70
|
+
*/
|
|
71
|
+
emitHijri = input(false, ...(ngDevMode ? [{ debugName: "emitHijri" }] : /* istanbul ignore next */ []));
|
|
72
|
+
#dateAdapter = inject(DateAdapter);
|
|
73
|
+
// the adapter is provided by this component, so switching it here leaves every other
|
|
74
|
+
// picker on the form on its own calendar
|
|
75
|
+
#hijriEffectRef = effect(() => this.#dateAdapter.setHijri(this.isHijri()), ...(ngDevMode ? [{ debugName: "#hijriEffectRef" }] : /* istanbul ignore next */ []));
|
|
76
|
+
/**
|
|
77
|
+
* Whether this picker is currently showing the Hijri calendar.
|
|
78
|
+
*/
|
|
79
|
+
isHijri() {
|
|
80
|
+
return this.hijriCalendar() || this.emitHijri();
|
|
81
|
+
}
|
|
82
|
+
writeValue(value) {
|
|
83
|
+
// a Hijri value read back from the form is `1447-03-15`, which is not the day
|
|
84
|
+
// `new Date("1447-03-15")` would give the calendar
|
|
85
|
+
if (this.emitHijri() && typeof value === "string") {
|
|
86
|
+
super.writeValue(parseHijriDate(value));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
super.writeValue(value);
|
|
90
|
+
}
|
|
91
|
+
clear(event) {
|
|
92
|
+
if (this.readonly()) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
event.stopImmediatePropagation();
|
|
96
|
+
this.ctrl.setValue(null);
|
|
97
|
+
this.propagateValue(null);
|
|
98
|
+
this.emitOnChangeEvent(null);
|
|
99
|
+
}
|
|
100
|
+
calendarDaysFilter = (d) => {
|
|
101
|
+
const day = (d || new Date()).getDay();
|
|
102
|
+
return !(this.disabledDays().includes(day));
|
|
103
|
+
};
|
|
104
|
+
emit($event) {
|
|
105
|
+
if (this.readonly()) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
this.markAsTouched();
|
|
109
|
+
const selectedDateString = this.emitHijri() ? formatHijriDate($event.value) : format($event.value, "yyyy-MM-dd");
|
|
110
|
+
this.propagateValue(selectedDateString);
|
|
111
|
+
this.emitOnChangeEvent(selectedDateString);
|
|
112
|
+
}
|
|
113
|
+
openPicker(picker) {
|
|
114
|
+
if (this.readonly()) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
picker.open();
|
|
118
|
+
this.markAsTouched();
|
|
119
|
+
}
|
|
120
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatePickerControl, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
121
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DatePickerControl, isStandalone: true, selector: "iss-ctrl-date-picker", inputs: { disabledDays: { classPropertyName: "disabledDays", publicName: "disabledDays", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, hijriCalendar: { classPropertyName: "hijriCalendar", publicName: "hijriCalendar", isSignal: true, isRequired: false, transformFunction: null }, emitHijri: { classPropertyName: "emitHijri", publicName: "emitHijri", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
122
|
+
DatePipe,
|
|
123
|
+
provideIssDateAdapter(),
|
|
124
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: DatePickerControl, multi: true },
|
|
125
|
+
{ provide: NG_VALIDATORS, useExisting: DatePickerControl, multi: true },
|
|
126
|
+
], usesInheritance: true, ngImport: i0, template: `
|
|
127
|
+
<mat-form-field floatLabel="auto" class="">
|
|
128
|
+
<!-- Always rendered: upgrade.scss shows the floating label only while the projected <label> carries text, so an omitted or empty one collapses on its own. -->
|
|
129
|
+
<mat-label class="fs-16 fc-dark-gray">
|
|
130
|
+
<ng-content select="label"></ng-content>
|
|
131
|
+
</mat-label>
|
|
132
|
+
<input
|
|
133
|
+
class="cursor-pointer"
|
|
134
|
+
matInput
|
|
135
|
+
[errorStateMatcher]="errorStateMatcher"
|
|
136
|
+
readonly
|
|
137
|
+
[matDatepicker]="picker"
|
|
138
|
+
(click)="openPicker(picker)"
|
|
139
|
+
[formControl]="ctrl"
|
|
140
|
+
[readonly]="readonly()"
|
|
141
|
+
[min]="minDate()"
|
|
142
|
+
[max]="maxDate()"
|
|
143
|
+
[matDatepickerFilter]="calendarDaysFilter"
|
|
144
|
+
(dateChange)="emit($event)"
|
|
145
|
+
/>
|
|
146
|
+
@if (ctrl.getRawValue()) {
|
|
147
|
+
<mat-icon matSuffix style="cursor: pointer" (click)="clear($event)">close</mat-icon>
|
|
148
|
+
}
|
|
149
|
+
<mat-datepicker-toggle matIconSuffix [for]="picker" [disabled]="readonly()"></mat-datepicker-toggle>
|
|
150
|
+
<mat-datepicker #picker [panelClass]="isHijri() ? 'iss-hijri-calendar' : ''"></mat-datepicker>
|
|
151
|
+
|
|
152
|
+
</mat-form-field>
|
|
153
|
+
`, isInline: true, styles: [""], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i3.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i3.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i3.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
|
|
154
|
+
}
|
|
155
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatePickerControl, decorators: [{
|
|
156
|
+
type: Component,
|
|
157
|
+
args: [{ selector: "iss-ctrl-date-picker", imports: [MatFormFieldModule, MatInputModule, MatDatepickerModule, MatIconModule, ReactiveFormsModule], providers: [
|
|
158
|
+
DatePipe,
|
|
159
|
+
provideIssDateAdapter(),
|
|
160
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: DatePickerControl, multi: true },
|
|
161
|
+
{ provide: NG_VALIDATORS, useExisting: DatePickerControl, multi: true },
|
|
162
|
+
], template: `
|
|
163
|
+
<mat-form-field floatLabel="auto" class="">
|
|
164
|
+
<!-- Always rendered: upgrade.scss shows the floating label only while the projected <label> carries text, so an omitted or empty one collapses on its own. -->
|
|
165
|
+
<mat-label class="fs-16 fc-dark-gray">
|
|
166
|
+
<ng-content select="label"></ng-content>
|
|
167
|
+
</mat-label>
|
|
168
|
+
<input
|
|
169
|
+
class="cursor-pointer"
|
|
170
|
+
matInput
|
|
171
|
+
[errorStateMatcher]="errorStateMatcher"
|
|
172
|
+
readonly
|
|
173
|
+
[matDatepicker]="picker"
|
|
174
|
+
(click)="openPicker(picker)"
|
|
175
|
+
[formControl]="ctrl"
|
|
176
|
+
[readonly]="readonly()"
|
|
177
|
+
[min]="minDate()"
|
|
178
|
+
[max]="maxDate()"
|
|
179
|
+
[matDatepickerFilter]="calendarDaysFilter"
|
|
180
|
+
(dateChange)="emit($event)"
|
|
181
|
+
/>
|
|
182
|
+
@if (ctrl.getRawValue()) {
|
|
183
|
+
<mat-icon matSuffix style="cursor: pointer" (click)="clear($event)">close</mat-icon>
|
|
184
|
+
}
|
|
185
|
+
<mat-datepicker-toggle matIconSuffix [for]="picker" [disabled]="readonly()"></mat-datepicker-toggle>
|
|
186
|
+
<mat-datepicker #picker [panelClass]="isHijri() ? 'iss-hijri-calendar' : ''"></mat-datepicker>
|
|
187
|
+
|
|
188
|
+
</mat-form-field>
|
|
189
|
+
` }]
|
|
190
|
+
}], propDecorators: { disabledDays: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledDays", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], hijriCalendar: [{ type: i0.Input, args: [{ isSignal: true, alias: "hijriCalendar", required: false }] }], emitHijri: [{ type: i0.Input, args: [{ isSignal: true, alias: "emitHijri", required: false }] }] } });
|
|
191
|
+
|
|
192
|
+
// The date-picker control. Its field and viewer stay in the primary entry point and reach it
|
|
193
|
+
// from there, so the control ships only to an app that renders it or imports it directly.
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Generated bundle index. Do not edit.
|
|
197
|
+
*/
|
|
198
|
+
|
|
199
|
+
export { DatePickerControl };
|
|
200
|
+
//# sourceMappingURL=iss-ctrl-date-picker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iss-ctrl-date-picker.mjs","sources":["../../../projects/iss/date-picker/src/date-picker.control.ts","../../../projects/iss/date-picker/src/public-api.ts","../../../projects/iss/date-picker/src/iss-ctrl-date-picker.ts"],"sourcesContent":["import { DatePipe } from \"@angular/common\";\nimport { Component, effect, inject, input, InputSignal } from \"@angular/core\";\nimport { NG_VALIDATORS, NG_VALUE_ACCESSOR, ReactiveFormsModule, Validator } from \"@angular/forms\";\nimport { DateAdapter } from \"@angular/material/core\";\nimport { MatDatepickerInputEvent, MatDatepickerModule } from \"@angular/material/datepicker\";\nimport { MatFormFieldModule } from \"@angular/material/form-field\";\nimport { MatIconModule } from \"@angular/material/icon\";\nimport { MatInputModule } from \"@angular/material/input\";\nimport { format } from \"date-fns\";\nimport { IssDateAdapter, provideIssDateAdapter } from \"iss-ctrl/base\";\nimport { formatHijriDate, parseHijriDate } from \"iss-ctrl/base\";\nimport { ControlBase } from \"iss-ctrl/base\";\n\n/**\n * `<iss-ctrl-date-picker>` — single date selection through a Material calendar.\n *\n * The input itself is read-only; clicking it opens the calendar. The emitted value is a\n * `yyyy-MM-dd` string, and a clear button appears once a date is picked.\n *\n * @example\n * ```html\n * <iss-ctrl-date-picker formControlName=\"startsOn\" [minDate]=\"today\" [disabledDays]=\"[5, 6]\">\n * <label>Start date</label>\n * </iss-ctrl-date-picker>\n * ```\n *\n * ### Own inputs\n * | Property | Type | Default | Description |\n * | --- | --- | --- | --- |\n * | `minDate` | `Date \\| null` | `null` | Earliest selectable date. |\n * | `maxDate` | `Date \\| null` | `null` | Latest selectable date. |\n * | `disabledDays` | `number[]` | `[]` | Week days to block, `0` = Sunday … `6` = Saturday. |\n * | `hijriCalendar` | `boolean` | `false` | Shows an Umm al-Qura Hijri calendar; the value stays Gregorian. |\n * | `emitHijri` | `boolean` | `false` | Emits the Hijri date instead of the Gregorian one. Implies `hijriCalendar`. |\n *\n * ### Hijri dates\n * `hijriCalendar` only changes what the user sees: the calendar is Hijri, the input reads\n * `dd/MM/yyyy` in Hijri, and a day shown as `16/03/1447` is still emitted as `2025-09-08`.\n * Turn on `emitHijri` as well when the form value itself has to be the Hijri date. `minDate` and\n * `maxDate` stay Gregorian in both cases — they are bounds on a day, not on a notation.\n *\n * ### Inherited from {@link ControlBase}\n * `formControlName` · `readonly` · `className` · `(onChange)`\n *\n * Projects `<label>` into the floating label; omit it to render the control without one.\n */\n@Component({\n selector: \"iss-ctrl-date-picker\",\n imports: [MatFormFieldModule, MatInputModule, MatDatepickerModule, MatIconModule, ReactiveFormsModule],\n providers: [\n DatePipe,\n provideIssDateAdapter(),\n { provide: NG_VALUE_ACCESSOR, useExisting: DatePickerControl, multi: true },\n { provide: NG_VALIDATORS, useExisting: DatePickerControl, multi: true },\n ],\n template: `\n <mat-form-field floatLabel=\"auto\" class=\"\">\n <!-- Always rendered: upgrade.scss shows the floating label only while the projected <label> carries text, so an omitted or empty one collapses on its own. -->\n <mat-label class=\"fs-16 fc-dark-gray\">\n <ng-content select=\"label\"></ng-content>\n </mat-label>\n <input\n class=\"cursor-pointer\"\n matInput\n [errorStateMatcher]=\"errorStateMatcher\"\n readonly\n [matDatepicker]=\"picker\"\n (click)=\"openPicker(picker)\"\n [formControl]=\"ctrl\"\n [readonly]=\"readonly()\"\n [min]=\"minDate()\"\n [max]=\"maxDate()\"\n [matDatepickerFilter]=\"calendarDaysFilter\"\n (dateChange)=\"emit($event)\"\n />\n @if (ctrl.getRawValue()) {\n <mat-icon matSuffix style=\"cursor: pointer\" (click)=\"clear($event)\">close</mat-icon>\n }\n <mat-datepicker-toggle matIconSuffix [for]=\"picker\" [disabled]=\"readonly()\"></mat-datepicker-toggle>\n <mat-datepicker #picker [panelClass]=\"isHijri() ? 'iss-hijri-calendar' : ''\"></mat-datepicker>\n\n </mat-form-field>\n `,\n styles: `\n ::ng-deep {\n tr:has(> .mat-calendar-body-label[colspan=\"7\"]) {\n opacity: 0 !important;\n display: none;\n }\n\n .mat-datepicker-content .mat-calendar {\n height: unset !important;\n }\n }\n `\n})\nexport class DatePickerControl extends ControlBase implements Validator {\n /**\n * Week days that cannot be selected — `0` is Sunday through `6` for Saturday.\n */\n disabledDays: InputSignal<number[]> = input<number[]>([]);\n /**\n * Earliest selectable date.\n */\n minDate: InputSignal<Date | null> = input<Date | null>(null);\n /**\n * Latest selectable date.\n */\n maxDate: InputSignal<Date | null> = input<Date | null>(null);\n /**\n * Renders the calendar as an Umm al-Qura Hijri calendar, leaving the emitted value Gregorian.\n */\n hijriCalendar: InputSignal<boolean> = input(false);\n /**\n * Emits the picked date as a Hijri `yyyy-MM-dd` string. Implies {@link hijriCalendar}.\n */\n emitHijri: InputSignal<boolean> = input(false);\n #dateAdapter: IssDateAdapter = inject(DateAdapter) as IssDateAdapter;\n // the adapter is provided by this component, so switching it here leaves every other\n // picker on the form on its own calendar\n #hijriEffectRef = effect(() => this.#dateAdapter.setHijri(this.isHijri()));\n\n /**\n * Whether this picker is currently showing the Hijri calendar.\n */\n isHijri(): boolean {\n return this.hijriCalendar() || this.emitHijri();\n }\n\n override writeValue(value: string | Date | null): void {\n // a Hijri value read back from the form is `1447-03-15`, which is not the day\n // `new Date(\"1447-03-15\")` would give the calendar\n if (this.emitHijri() && typeof value === \"string\") {\n super.writeValue(parseHijriDate(value));\n return;\n }\n super.writeValue(value);\n }\n\n clear(event: MouseEvent) {\n if (this.readonly()) {\n return;\n }\n event.stopImmediatePropagation();\n this.ctrl.setValue(null);\n\n this.propagateValue(null);\n this.emitOnChangeEvent(null);\n }\n\n protected calendarDaysFilter = (d: Date | null): boolean => {\n const day: number = (d || new Date()).getDay();\n return !(this.disabledDays().includes(day));\n };\n\n protected emit($event: MatDatepickerInputEvent<any>) {\n if (this.readonly()) {\n return;\n }\n this.markAsTouched();\n const selectedDateString = this.emitHijri() ? formatHijriDate($event.value) : format($event.value, \"yyyy-MM-dd\");\n this.propagateValue(selectedDateString);\n this.emitOnChangeEvent(selectedDateString);\n }\n\n protected openPicker(picker: any): void {\n if (this.readonly()) {\n return;\n }\n picker.open();\n this.markAsTouched();\n }\n}\n","// The date-picker control. Its field and viewer stay in the primary entry point and reach it\n// from there, so the control ships only to an app that renders it or imports it directly.\n\nexport * from \"./date-picker.control\";\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DatePipe } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { computed, Component } from '@angular/core';
|
|
4
|
+
import { ViewerBase, toHijriDisplay } from 'iss-ctrl/base';
|
|
5
|
+
|
|
6
|
+
class DatePickerViewer extends ViewerBase {
|
|
7
|
+
// a field picked on the Hijri calendar reads back as a Hijri date, whichever calendar its
|
|
8
|
+
// stored value is in
|
|
9
|
+
hijriDate = computed(() => toHijriDisplay(this.field().ctrlValue(), {
|
|
10
|
+
hijriCalendar: this.field().config?.hijriCalendar(),
|
|
11
|
+
emitHijri: this.field().config?.emitHijri(),
|
|
12
|
+
}), ...(ngDevMode ? [{ debugName: "hijriDate" }] : /* istanbul ignore next */ []));
|
|
13
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatePickerViewer, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
14
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: DatePickerViewer, isStandalone: true, selector: "iss-viewer-date-picker", usesInheritance: true, ngImport: i0, template: `
|
|
15
|
+
@if (hijriDate(); as hijri) {
|
|
16
|
+
{{ hijri }}
|
|
17
|
+
} @else {
|
|
18
|
+
{{ field().ctrlValue() | date: 'dd/MM/yyyy' }}
|
|
19
|
+
}
|
|
20
|
+
`, isInline: true, dependencies: [{ kind: "pipe", type: DatePipe, name: "date" }] });
|
|
21
|
+
}
|
|
22
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: DatePickerViewer, decorators: [{
|
|
23
|
+
type: Component,
|
|
24
|
+
args: [{
|
|
25
|
+
selector: "iss-viewer-date-picker",
|
|
26
|
+
imports: [
|
|
27
|
+
DatePipe
|
|
28
|
+
],
|
|
29
|
+
template: `
|
|
30
|
+
@if (hijriDate(); as hijri) {
|
|
31
|
+
{{ hijri }}
|
|
32
|
+
} @else {
|
|
33
|
+
{{ field().ctrlValue() | date: 'dd/MM/yyyy' }}
|
|
34
|
+
}
|
|
35
|
+
`
|
|
36
|
+
}]
|
|
37
|
+
}] });
|
|
38
|
+
|
|
39
|
+
export { DatePickerViewer };
|
|
40
|
+
//# sourceMappingURL=iss-ctrl-date-picker.viewer-Dsmsf91t.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iss-ctrl-date-picker.viewer-Dsmsf91t.mjs","sources":["../../../projects/iss/src/components/controls/date-picker/date-picker.viewer.ts"],"sourcesContent":["import { DatePipe } from \"@angular/common\";\nimport { Component, computed, Signal } from \"@angular/core\";\nimport { toHijriDisplay } from \"iss-ctrl/base\";\nimport { ViewerBase } from \"iss-ctrl/base\";\n\n@Component({\n selector: \"iss-viewer-date-picker\",\n imports: [\n DatePipe\n ],\n template: `\n @if (hijriDate(); as hijri) {\n {{ hijri }}\n } @else {\n {{ field().ctrlValue() | date: 'dd/MM/yyyy' }}\n }\n `\n})\nexport class DatePickerViewer extends ViewerBase {\n // a field picked on the Hijri calendar reads back as a Hijri date, whichever calendar its\n // stored value is in\n protected hijriDate: Signal<string | null> = computed(() => toHijriDisplay(this.field().ctrlValue(), {\n hijriCalendar: this.field().config?.hijriCalendar(),\n emitHijri: this.field().config?.emitHijri(),\n }));\n}\n"],"names":[],"mappings":";;;;;AAkBM,MAAO,gBAAiB,SAAQ,UAAU,CAAA;;;AAGpC,IAAA,SAAS,GAA0B,QAAQ,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,EAAE;QACnG,aAAa,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE;QACnD,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE;AAC5C,KAAA,CAAC,gFAAC;uGANQ,gBAAgB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EARjB;;;;;;AAMT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EARC,QAAQ,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA;;2FAUC,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAb5B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,wBAAwB;AAClC,oBAAA,OAAO,EAAE;wBACP;AACD,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;AAMT,EAAA;AACF,iBAAA;;;;;"}
|