ng-hub-ui-forms 21.0.0 → 22.1.2
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 +48 -2
- package/fesm2022/ng-hub-ui-forms.mjs +51 -12
- package/fesm2022/ng-hub-ui-forms.mjs.map +1 -1
- package/ng-hub-ui-forms-22.1.2.tgz +0 -0
- package/package.json +2 -2
- package/src/lib/styles/_field.scss +16 -0
- package/src/lib/styles/_tokens.scss +28 -13
- package/types/ng-hub-ui-forms.d.ts +20 -1
- package/ng-hub-ui-forms-21.0.0.tgz +0 -0
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ng-hub-ui-forms",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "22.1.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Accessible, signal-based form fields for Angular (input, textarea, slider, select, datepicker) with automatic error display for controls, FormGroups and FormArrays. Reactive Forms today, Signal Forms ready. Part of the ng-hub-ui family.",
|
|
6
6
|
"author": "Carlos Morcillo <carlos.morcillo@me.com> (https://www.carlosmorcillo.com)",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/carlos-morcillo/ng-hub-ui-forms.git"
|
|
9
|
+
"url": "git+https://github.com/carlos-morcillo/ng-hub-ui-forms.git"
|
|
10
10
|
},
|
|
11
11
|
"homepage": "https://hubui.dev/",
|
|
12
12
|
"keywords": [
|
|
@@ -101,6 +101,17 @@
|
|
|
101
101
|
box-shadow: 0 0 0 var(--hub-form-focus-ring-width) var(--hub-form-invalid-focus-ring-color);
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
+
|
|
105
|
+
// Opt-in success state (mirror of `--invalid`); applied only when a field
|
|
106
|
+
// enables `showValid` and the control is touched + valid.
|
|
107
|
+
&--valid {
|
|
108
|
+
border-color: var(--hub-form-valid-border-color);
|
|
109
|
+
|
|
110
|
+
&:focus {
|
|
111
|
+
border-color: var(--hub-form-valid-border-color);
|
|
112
|
+
box-shadow: 0 0 0 var(--hub-form-focus-ring-width) var(--hub-form-valid-focus-ring-color);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
104
115
|
}
|
|
105
116
|
|
|
106
117
|
// Helper text below the control.
|
|
@@ -129,4 +140,9 @@
|
|
|
129
140
|
&-text {
|
|
130
141
|
display: block;
|
|
131
142
|
}
|
|
143
|
+
|
|
144
|
+
// Success feedback (opt-in valid state).
|
|
145
|
+
&--valid {
|
|
146
|
+
color: var(--hub-form-valid-feedback-color);
|
|
147
|
+
}
|
|
132
148
|
}
|
|
@@ -11,12 +11,21 @@
|
|
|
11
11
|
// ── Shared form contract (used by every field) ──────────────────────────
|
|
12
12
|
--hub-form-field-gap: var(--hub-ref-space-1, 0.25rem); // label ↔ control
|
|
13
13
|
--hub-form-row-gap: var(--hub-ref-space-3, 1rem); // horizontal label gutter
|
|
14
|
+
--hub-form-fieldset-padding-x: var(--hub-ref-space-3, 1rem);
|
|
15
|
+
--hub-form-fieldset-padding-y: var(--hub-ref-space-3, 1rem);
|
|
14
16
|
--hub-form-label-horizontal-max-width: 12rem; // horizontal label caps here, then ellipsizes
|
|
15
17
|
|
|
16
18
|
--hub-form-invalid-color: var(--hub-sys-color-danger, #dc3545);
|
|
17
19
|
--hub-form-invalid-border-color: var(--hub-sys-color-danger, #dc3545);
|
|
18
20
|
--hub-form-invalid-focus-ring-color: var(--hub-sys-color-danger-subtle, rgba(220, 53, 69, 0.25));
|
|
19
21
|
|
|
22
|
+
// Valid / success — mirror of the invalid contract, shown only when a field
|
|
23
|
+
// opts in via `showValid` (the success state is never automatic).
|
|
24
|
+
--hub-form-valid-color: var(--hub-sys-color-success, #198754);
|
|
25
|
+
--hub-form-valid-border-color: var(--hub-sys-color-success, #198754);
|
|
26
|
+
--hub-form-valid-focus-ring-color: var(--hub-sys-color-success-subtle, rgba(25, 135, 84, 0.25));
|
|
27
|
+
--hub-form-valid-feedback-color: var(--hub-form-valid-color);
|
|
28
|
+
|
|
20
29
|
--hub-form-feedback-color: var(--hub-form-invalid-color);
|
|
21
30
|
--hub-form-feedback-font-size: var(--hub-ref-font-size-sm, 0.875rem);
|
|
22
31
|
--hub-form-feedback-margin-top: var(--hub-ref-space-1, 0.25rem);
|
|
@@ -44,7 +53,7 @@
|
|
|
44
53
|
--hub-input-font-family: var(--hub-ref-font-family-base, system-ui, sans-serif);
|
|
45
54
|
--hub-input-font-size: var(--hub-ref-font-size-base, 1rem);
|
|
46
55
|
--hub-input-font-weight: var(--hub-ref-font-weight-base, 400);
|
|
47
|
-
--hub-input-line-height: 1.5;
|
|
56
|
+
--hub-input-line-height: var(--hub-ref-line-height-base, 1.5);
|
|
48
57
|
--hub-input-padding-y: 0.375rem;
|
|
49
58
|
--hub-input-padding-x: 0.75rem;
|
|
50
59
|
--hub-input-border-width: var(--hub-ref-border-width, 1px);
|
|
@@ -127,11 +136,13 @@
|
|
|
127
136
|
--hub-select-clear-color: var(--hub-sys-text-muted, #6c757d);
|
|
128
137
|
--hub-select-clear-hover-color: var(--hub-sys-color-danger, #dc3545);
|
|
129
138
|
--hub-select-option-color: var(--hub-sys-text-primary, #212529);
|
|
130
|
-
--hub-select-option-padding-x: var(--hub-ref-space-3,
|
|
139
|
+
--hub-select-option-padding-x: var(--hub-ref-space-3, 1rem);
|
|
131
140
|
--hub-select-option-padding-y: var(--hub-ref-space-2, 0.5rem);
|
|
132
|
-
--hub-select-option-marked-bg: var(--hub-sys-surface-elevated, #
|
|
141
|
+
--hub-select-option-marked-bg: var(--hub-sys-surface-elevated, #f8f9fa);
|
|
133
142
|
--hub-select-option-selected-bg: var(--hub-sys-color-primary, #0d6efd);
|
|
134
|
-
|
|
143
|
+
// Text on the selected option sits on the primary accent — read the derived
|
|
144
|
+
// contrast token so a light/custom primary keeps the label legible.
|
|
145
|
+
--hub-select-option-selected-color: var(--hub-sys-color-primary-on, var(--hub-ref-color-white, #fff));
|
|
135
146
|
--hub-select-optgroup-color: var(--hub-sys-text-muted, #6c757d);
|
|
136
147
|
--hub-select-value-bg: var(--hub-sys-surface-elevated, #f8f9fa);
|
|
137
148
|
--hub-select-value-color: var(--hub-sys-text-primary, #212529);
|
|
@@ -152,17 +163,20 @@
|
|
|
152
163
|
--hub-daterangepicker-border-color: var(--hub-sys-border-color-default, #dee2e6);
|
|
153
164
|
--hub-daterangepicker-border-radius: var(--hub-ref-radius-md, 0.375rem);
|
|
154
165
|
--hub-daterangepicker-box-shadow: var(--hub-sys-shadow, 0 0.5rem 1rem rgba(0, 0, 0, 0.12));
|
|
155
|
-
--hub-daterangepicker-padding: var(--hub-ref-space-3, 1rem);
|
|
166
|
+
--hub-daterangepicker-padding-x: var(--hub-ref-space-3, 1rem);
|
|
167
|
+
--hub-daterangepicker-padding-y: var(--hub-ref-space-3, 1rem);
|
|
156
168
|
--hub-daterangepicker-cell-size: 2rem;
|
|
157
169
|
--hub-daterangepicker-cell-color: var(--hub-sys-text-primary, #212529);
|
|
158
170
|
--hub-daterangepicker-cell-border-radius: var(--hub-ref-radius-sm, 0.25rem);
|
|
159
|
-
--hub-daterangepicker-cell-hover-bg: var(--hub-sys-surface-elevated, #
|
|
171
|
+
--hub-daterangepicker-cell-hover-bg: var(--hub-sys-surface-elevated, #f8f9fa);
|
|
160
172
|
--hub-daterangepicker-active-bg: var(--hub-sys-color-primary, #0d6efd);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
//
|
|
164
|
-
|
|
165
|
-
|
|
173
|
+
// Text on the active day sits on the primary accent — derived contrast token.
|
|
174
|
+
--hub-daterangepicker-active-color: var(--hub-sys-color-primary-on, var(--hub-ref-color-white, #fff));
|
|
175
|
+
// Soft primary tint for the in-range band. Mixed in OKLCH (perceptually even)
|
|
176
|
+
// rather than sRGB; kept independent of `-subtle` (which mixes over the page
|
|
177
|
+
// surface, not transparent) so the band reads as a translucent overlay.
|
|
178
|
+
--hub-daterangepicker-in-range-bg: color-mix(in oklch, var(--hub-sys-color-primary, #0d6efd) 14%, transparent);
|
|
179
|
+
--hub-daterangepicker-off-color: var(--hub-sys-text-muted, #6c757d);
|
|
166
180
|
--hub-daterangepicker-nav-arrow-color: var(--hub-sys-text-muted, #6c757d);
|
|
167
181
|
--hub-daterangepicker-nav-arrow-hover-color: var(--hub-sys-text-primary, #212529);
|
|
168
182
|
|
|
@@ -170,10 +184,11 @@
|
|
|
170
184
|
--hub-select-button-bg: var(--hub-sys-surface-page, #fff);
|
|
171
185
|
--hub-select-button-color: var(--hub-sys-text-primary, #212529);
|
|
172
186
|
--hub-select-button-border-color: var(--hub-sys-border-color-default, #dee2e6);
|
|
173
|
-
--hub-select-button-padding-x: var(--hub-ref-space-3,
|
|
187
|
+
--hub-select-button-padding-x: var(--hub-ref-space-3, 1rem);
|
|
174
188
|
--hub-select-button-padding-y: var(--hub-ref-space-2, 0.5rem);
|
|
175
189
|
--hub-select-button-gap: var(--hub-ref-space-2, 0.5rem);
|
|
176
190
|
--hub-select-button-selected-bg: var(--hub-sys-color-primary, #0d6efd);
|
|
177
|
-
|
|
191
|
+
// Text on the selected button sits on the primary accent — derived contrast token.
|
|
192
|
+
--hub-select-button-selected-color: var(--hub-sys-color-primary-on, var(--hub-ref-color-white, #fff));
|
|
178
193
|
--hub-select-button-selected-border-color: var(--hub-sys-color-primary, #0d6efd);
|
|
179
194
|
}
|
|
@@ -114,6 +114,15 @@ declare abstract class HubFieldControl extends HubFormControl implements Control
|
|
|
114
114
|
readonly disabled: _angular_core.ModelSignal<boolean>;
|
|
115
115
|
/** Per-field override for the invalid-feedback message builder. */
|
|
116
116
|
readonly invalidFeedbackTemplateFn: _angular_core.InputSignal<((key: string, value: any) => string) | null>;
|
|
117
|
+
/**
|
|
118
|
+
* Opt-in success state. When `true`, a touched + valid field renders the
|
|
119
|
+
* `--valid` styling (success border + ring). Defaults to the global
|
|
120
|
+
* {@link HubFormsConfig.showValid}; the success state is never automatic
|
|
121
|
+
* unless enabled. Has no effect while the field is invalid.
|
|
122
|
+
*/
|
|
123
|
+
readonly showValid: _angular_core.InputSignal<boolean>;
|
|
124
|
+
/** Optional success message shown below the control while {@link showsValid}. */
|
|
125
|
+
readonly validFeedback: _angular_core.InputSignal<string | null>;
|
|
117
126
|
onChange: (value: any) => void;
|
|
118
127
|
onTouched: () => void;
|
|
119
128
|
protected readonly _nativeErrors: _angular_core.WritableSignal<ValidationErrors | null>;
|
|
@@ -121,6 +130,10 @@ declare abstract class HubFieldControl extends HubFormControl implements Control
|
|
|
121
130
|
constructor();
|
|
122
131
|
/** Whether the field should display its error feedback (touched + invalid). */
|
|
123
132
|
get isInvalid(): boolean;
|
|
133
|
+
/** Whether the field is touched and valid (independent of the opt-in). */
|
|
134
|
+
get isValid(): boolean;
|
|
135
|
+
/** Whether the opt-in success state should be displayed (touched + valid + `showValid`). */
|
|
136
|
+
get showsValid(): boolean;
|
|
124
137
|
/** Current validation errors, from the reactive control or from native validity. */
|
|
125
138
|
get errors(): ValidationErrors | null;
|
|
126
139
|
ngAfterContentInit(): void;
|
|
@@ -149,7 +162,7 @@ declare abstract class HubFieldControl extends HubFormControl implements Control
|
|
|
149
162
|
*/
|
|
150
163
|
protected updateNativeErrors(target?: EventTarget | null): void;
|
|
151
164
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<HubFieldControl, never>;
|
|
152
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HubFieldControl, never, never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalidFeedbackTemplateFn": { "alias": "invalidFeedbackTemplateFn"; "required": false; "isSignal": true; }; }, { "disabled": "disabledChange"; }, ["formTextTmp", "errorTpts"], never, true, never>;
|
|
165
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HubFieldControl, never, never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalidFeedbackTemplateFn": { "alias": "invalidFeedbackTemplateFn"; "required": false; "isSignal": true; }; "showValid": { "alias": "showValid"; "required": false; "isSignal": true; }; "validFeedback": { "alias": "validFeedback"; "required": false; "isSignal": true; }; }, { "disabled": "disabledChange"; }, ["formTextTmp", "errorTpts"], never, true, never>;
|
|
153
166
|
}
|
|
154
167
|
|
|
155
168
|
/** When a container reveals its group-level validation errors. */
|
|
@@ -282,6 +295,12 @@ interface HubFormsConfig {
|
|
|
282
295
|
* @returns The message string (HTML allowed).
|
|
283
296
|
*/
|
|
284
297
|
invalidFeedbackTemplateFn: (key: string, value: any) => string;
|
|
298
|
+
/**
|
|
299
|
+
* Whether fields render the opt-in valid/success state by default once they
|
|
300
|
+
* are touched and valid. `false` keeps the success state off everywhere
|
|
301
|
+
* (only invalid is automatic); a per-field `showValid` input overrides this.
|
|
302
|
+
*/
|
|
303
|
+
showValid: boolean;
|
|
285
304
|
/** Global datepicker defaults (locale labels, formats, first day of week…). */
|
|
286
305
|
datepicker: HubDatepickerConfig;
|
|
287
306
|
}
|
|
Binary file
|