ng-hub-ui-forms 22.32.0 → 22.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -14
- package/fesm2022/ng-hub-ui-forms.mjs +230 -199
- package/fesm2022/ng-hub-ui-forms.mjs.map +1 -1
- package/package.json +8 -3
- package/styles/_field.scss +21 -0
- package/types/ng-hub-ui-forms.d.ts +38 -6
package/README.md
CHANGED
|
@@ -50,10 +50,11 @@ This library is part of the **ng-hub-ui** ecosystem:
|
|
|
50
50
|
npm install ng-hub-ui-forms
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
`ng-hub-ui-utils` is a peer dependency (the datepicker opens its panel through its overlay
|
|
54
|
+
service, and every field renders its tooltip helper text with `hubTooltip`):
|
|
54
55
|
|
|
55
56
|
```bash
|
|
56
|
-
npm install
|
|
57
|
+
npm install ng-hub-ui-utils
|
|
57
58
|
```
|
|
58
59
|
|
|
59
60
|
### 2. Import
|
|
@@ -86,15 +87,15 @@ bind them with **Reactive Forms** and the matching validation errors appear
|
|
|
86
87
|
**automatically** at the control, group and form level. Fields are standalone,
|
|
87
88
|
`OnPush` and signal-native; the select is a maintained fork of
|
|
88
89
|
[ng-select](https://github.com/ng-select/ng-select) (see [Credits](#-credits)); the
|
|
89
|
-
datepicker is built from scratch on native `Date` and the
|
|
90
|
+
datepicker is built from scratch on native `Date` and the `ng-hub-ui-utils` overlay.
|
|
90
91
|
Everything is themed through canonical `--hub-*` CSS variables with runtime dark
|
|
91
92
|
mode — no Bootstrap dependency.
|
|
92
93
|
|
|
93
94
|
## 🎯 Features
|
|
94
95
|
|
|
95
|
-
- **Fields** — `hub-input` (text/number/email/password/color/switch/checkbox/counter, with input-group addons & masks, projected in-field affixes, a built-in `clearable` button, the mixed `indeterminate` state on checkboxes and debounced typeahead `search`; the `file` format is **deprecated** → use `hub-file-input`), `hub-otp-input`, `hub-textarea` (+ `hubAutoresize`), `hub-slider` (single / dual thumb, gradient fill), `hub-segmented` (segmented control field — single & multiple selection, horizontal & vertical, with label + validation), `hub-select` (dropdown format, grouping, client-side search via `searchable` **and** server-side async typeahead via a `typeahead` Subject, tag creation with `addTag`, custom templates, `prepend` / `append` group addons and attached icons/buttons via `hubPrepend` / `hubAppend`; the `buttons` / `checkbox` / `radio` formats are **deprecated** → use `hub-segmented`), `hub-datepicker` (single & range at any granularity from a year to a second, time picking, min/max down to the minute, keyboard nav, i18n), `hub-file-input` (drag & drop, clipboard paste, type/size limits, previews, optional upload progress).
|
|
96
|
-
- **Automatic error display** — bind a field and its control errors render below it; `
|
|
97
|
-
- **Containers** — `hub-fieldset
|
|
96
|
+
- **Fields** — `hub-input` (text/number/email/password/color/switch/checkbox/counter, with input-group addons & masks, projected in-field affixes, a built-in `clearable` button, the mixed `indeterminate` state on checkboxes and debounced typeahead `search`; the `file` format is **deprecated** → use `hub-file-input`), `hub-otp-input`, `hub-textarea` (+ `hubAutoresize`), `hub-slider` (single / dual thumb, gradient fill), `hub-segmented` (segmented control field — single & multiple selection, horizontal & vertical, with label + validation), `hub-select` (dropdown format, grouping, client-side search via `searchable` **and** server-side async typeahead via a `typeahead` Subject, tag creation with `addTag`, custom templates, `prepend` / `append` group addons and attached icons/buttons via `hubPrepend` / `hubAppend`; the `buttons` / `checkbox` / `radio` formats are **deprecated** → use `hub-segmented`), `hub-datepicker` (single & range at any granularity from a year to a second, time picking, min/max down to the minute, keyboard nav, i18n), `hub-timepicker` (a time of day as `HH:MM`, on the platform's own time control, with `min` / `max` / `step`), `hub-file-input` (drag & drop, clipboard paste, type/size limits, previews, optional upload progress).
|
|
97
|
+
- **Automatic error display** — bind a field and its control errors render below it; `fieldset[hubFieldset]`, `form[hubForm]` and `hub-legend` surface group- and form-level (cross-field) errors the same way, with zero wiring.
|
|
98
|
+
- **Containers** — `fieldset[hubFieldset]` (or the `<hub-fieldset>` element) / `form[hubForm]` group fields and show their group errors; `hub-legend` renders an accessible legend.
|
|
98
99
|
- **Configurable** — `provideHubForms({ … })` sets the invalid-feedback templates, datepicker locale/labels, file-input labels and more, app-wide or per instance.
|
|
99
100
|
- **Validators & helpers** — `hubAreEqual` cross-field validator, the file validators (`hubAcceptedFiles`, `hubMaxFileSize`, `hubMinFileSize`, `hubMaxTotalSize`, `hubMaxFiles`, `hubMinFiles`), `hubValidationError` / `hubFormText` projection directives, and a set of utility pipes.
|
|
100
101
|
- **Signal Forms ready** — an opt-in [`ng-hub-ui-forms/signals`](#-signal-forms-opt-in) secondary entry point integrates Angular Signal Forms; the core stays Reactive-Forms-based and Angular-21-safe.
|
|
@@ -130,18 +131,18 @@ section.
|
|
|
130
131
|
## 📦 Installation
|
|
131
132
|
|
|
132
133
|
```bash
|
|
133
|
-
npm install ng-hub-ui-forms
|
|
134
|
+
npm install ng-hub-ui-forms ng-hub-ui-utils
|
|
134
135
|
```
|
|
135
136
|
|
|
136
137
|
### Peer Dependencies
|
|
137
138
|
|
|
138
139
|
```json
|
|
139
140
|
{
|
|
140
|
-
"@angular/cdk": ">=21.0.0",
|
|
141
141
|
"@angular/common": ">=21.0.0",
|
|
142
142
|
"@angular/core": ">=21.0.0",
|
|
143
143
|
"@angular/forms": ">=21.0.0",
|
|
144
|
-
"@angular/platform-browser": ">=21.0.0"
|
|
144
|
+
"@angular/platform-browser": ">=21.0.0",
|
|
145
|
+
"ng-hub-ui-utils": ">=22.12.0"
|
|
145
146
|
}
|
|
146
147
|
```
|
|
147
148
|
|
|
@@ -188,7 +189,7 @@ string, so asking it to carry markup would drop the markup silently.
|
|
|
188
189
|
```html
|
|
189
190
|
<hub-input formControlName="email" type="email" label="Email" required />
|
|
190
191
|
<hub-input formControlName="amount" type="number" label="Amount" />
|
|
191
|
-
<hub-input formControlName="darkMode"
|
|
192
|
+
<hub-input formControlName="darkMode" type="switch" label="Dark mode" />
|
|
192
193
|
```
|
|
193
194
|
|
|
194
195
|
#### Icon affix & typeahead (search boxes)
|
|
@@ -476,6 +477,27 @@ Three independent axes control the formats:
|
|
|
476
477
|
ISO strings of any width, `Date` instances and epoch milliseconds are detected automatically, so
|
|
477
478
|
`parse` is only needed for dialects outside that set.
|
|
478
479
|
|
|
480
|
+
### Timepicker
|
|
481
|
+
|
|
482
|
+
A time of day, as `HH:MM`. Built on the platform's `<input type="time">`, so it brings the
|
|
483
|
+
numeric keyboard on a phone, the stepper, and the reader's own 12- or 24-hour presentation —
|
|
484
|
+
while what the control holds is normalised to `HH:MM`, and so does not change with the locale.
|
|
485
|
+
|
|
486
|
+
```html
|
|
487
|
+
<hub-timepicker formControlName="opensAt" label="Opens at" />
|
|
488
|
+
<hub-timepicker formControlName="closesAt" [step]="900" min="08:00" max="22:00" />
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
| Input | Type | Default | What it does |
|
|
492
|
+
| ------ | ------------------ | ------- | --------------------------------------------------------------------------------------------------------------- |
|
|
493
|
+
| `min` | `string` (`HH:MM`) | `''` | Earliest time the field accepts. |
|
|
494
|
+
| `max` | `string` (`HH:MM`) | `''` | Latest time the field accepts. |
|
|
495
|
+
| `step` | `number` (seconds) | `0` | Granularity. `900` offers quarter hours; under `60` the control shows seconds, which an opening time never has. |
|
|
496
|
+
|
|
497
|
+
An empty field publishes `null`, not `''` — "no time" is an absence, and a zero-length string
|
|
498
|
+
sails past a `required` written as a null check. `label`, `labelType`, `readonly`, `prepend` /
|
|
499
|
+
`append` and the projected `hubPrepend` / `hubAppend` behave as on every other field.
|
|
500
|
+
|
|
479
501
|
### File input
|
|
480
502
|
|
|
481
503
|
Drag & drop, clipboard paste, constraints and previews. The control value stays native — a `File`, a `File[]`, or `null` — so it goes straight into a `FormData`.
|
|
@@ -571,10 +593,10 @@ The dropzone is built from a glyph, an invitation and a browse action, each them
|
|
|
571
593
|
|
|
572
594
|
```html
|
|
573
595
|
<form [formGroup]="form" hubForm (submit)="save()">
|
|
574
|
-
<
|
|
596
|
+
<fieldset hubFieldset legend="Credentials">
|
|
575
597
|
<hub-input formControlName="email" type="email" label="Email" required />
|
|
576
598
|
<hub-input formControlName="confirm" type="email" label="Confirm email" required />
|
|
577
|
-
</
|
|
599
|
+
</fieldset>
|
|
578
600
|
<button type="submit">Create account</button>
|
|
579
601
|
</form>
|
|
580
602
|
```
|
|
@@ -589,6 +611,25 @@ form = new FormGroup(
|
|
|
589
611
|
On submit, each invalid field shows its error and the cross-field `hubAreEqual`
|
|
590
612
|
error is surfaced by the fieldset/form — no manual error markup anywhere.
|
|
591
613
|
|
|
614
|
+
#### Two ways to write the fieldset
|
|
615
|
+
|
|
616
|
+
`hubFieldset` is an attribute on the native element, so the group costs one element instead of
|
|
617
|
+
two: the `<fieldset hubFieldset>` you write **is** the fieldset the browser sees. The
|
|
618
|
+
`<hub-fieldset>` element form is still supported and takes the same inputs, but it has to render
|
|
619
|
+
a `<fieldset>` of its own inside the host. Prefer the attribute — it is the markup a plain HTML
|
|
620
|
+
form would have written anyway.
|
|
621
|
+
|
|
622
|
+
```html
|
|
623
|
+
<!-- preferred: the host is the fieldset -->
|
|
624
|
+
<fieldset hubFieldset legend="Credentials" [group]="form.controls.credentials">…</fieldset>
|
|
625
|
+
|
|
626
|
+
<!-- equivalent, one element deeper -->
|
|
627
|
+
<hub-fieldset legend="Credentials" [group]="form.controls.credentials">…</hub-fieldset>
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
The attribute is restricted to `<fieldset>` on purpose: on a `<div>` it would draw a legend over
|
|
631
|
+
a group with none of the semantics assistive technology reads from a real fieldset.
|
|
632
|
+
|
|
592
633
|
### Validation states (invalid is automatic, valid is opt-in)
|
|
593
634
|
|
|
594
635
|
The **invalid** state is always automatic: a touched, invalid field shows its
|
|
@@ -637,7 +678,7 @@ Everything is themed through `--hub-*` CSS custom properties. The package ships
|
|
|
637
678
|
shared SCSS tokens; import them once at the app root:
|
|
638
679
|
|
|
639
680
|
```scss
|
|
640
|
-
@use 'ng-hub-ui-forms/
|
|
681
|
+
@use 'ng-hub-ui-forms/styles' as hub-forms;
|
|
641
682
|
```
|
|
642
683
|
|
|
643
684
|
```css
|
|
@@ -707,7 +748,7 @@ import { HubSignalFieldControl, hubSignalErrorMessages } from 'ng-hub-ui-forms/s
|
|
|
707
748
|
## ♿ Accessibility
|
|
708
749
|
|
|
709
750
|
- Labels are associated with their control (`for`/`id`); required fields are marked.
|
|
710
|
-
- `required` — set inline or derived from `Validators.required`, with `formControlName` **or** a direct `[formControl]` binding — is reflected as `aria-required` on every field, including the select's combobox search input, the segmented `radiogroup` and each OTP cell.
|
|
751
|
+
- `required` — set inline or derived from `Validators.required`, with `formControlName` **or** a direct `[formControl]` binding — is reflected as `aria-required` on every field, including the select's combobox search input, the segmented `radiogroup` and each OTP cell. On a reactive binding the control's validators decide: an inline `required` is overwritten by them, so declare it on the validators. Template-driven bindings (`ngModel`) keep honouring the inline input.
|
|
711
752
|
- Validation errors render in an `role="alert"` region tied to the field.
|
|
712
753
|
- The select exposes correct combobox/listbox semantics; the datepicker is fully keyboard-navigable.
|
|
713
754
|
|