ng-hub-ui-forms 22.1.2 → 22.3.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 +52 -1
- package/fesm2022/ng-hub-ui-forms.mjs +192 -5
- package/fesm2022/ng-hub-ui-forms.mjs.map +1 -1
- package/ng-hub-ui-forms-22.3.0.tgz +0 -0
- package/package.json +1 -1
- package/src/lib/styles/_tokens.scss +12 -0
- package/types/ng-hub-ui-forms.d.ts +120 -4
- package/ng-hub-ui-forms-22.1.2.tgz +0 -0
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ng-hub-ui-forms",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.3.0",
|
|
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)",
|
|
@@ -70,6 +70,18 @@
|
|
|
70
70
|
--hub-input-group-addon-color: var(--hub-sys-text-muted, #6c757d);
|
|
71
71
|
--hub-input-group-addon-border-color: var(--hub-input-border-color);
|
|
72
72
|
|
|
73
|
+
// Input · affix (projected leading/trailing content, e.g. a <hub-icon>)
|
|
74
|
+
--hub-input-icon-color: var(--hub-sys-text-muted, #6c757d);
|
|
75
|
+
--hub-input-icon-size: var(--hub-ref-font-size-base, 1rem);
|
|
76
|
+
--hub-input-affix-inset: var(--hub-input-padding-x);
|
|
77
|
+
--hub-input-affix-gap: var(--hub-ref-space-2, 0.5rem);
|
|
78
|
+
|
|
79
|
+
// Input · clear button ([clearable]) — glyph is a swappable mask
|
|
80
|
+
--hub-input-clear-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='black' d='M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E");
|
|
81
|
+
--hub-input-clear-size: var(--hub-ref-font-size-base, 1rem);
|
|
82
|
+
--hub-input-clear-color: var(--hub-sys-text-muted, #6c757d);
|
|
83
|
+
--hub-input-clear-hover-color: var(--hub-sys-color-danger, #dc3545);
|
|
84
|
+
|
|
73
85
|
// Input · counter format (−/+)
|
|
74
86
|
--hub-input-counter-button-bg: var(--hub-sys-surface-elevated, #f8f9fa);
|
|
75
87
|
--hub-input-counter-button-color: var(--hub-sys-text-primary, #212529);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { OnInit, AfterContentInit, OnDestroy, TemplateRef, ElementRef, InjectionToken, EnvironmentProviders, PipeTransform, NgZone } from '@angular/core';
|
|
2
|
+
import { OnInit, AfterContentInit, OnDestroy, TemplateRef, ElementRef, InjectionToken, EnvironmentProviders, PipeTransform, NgZone, ViewContainerRef } from '@angular/core';
|
|
3
3
|
import { NgControl, ControlContainer, ControlValueAccessor, ValidationErrors, AbstractControl, ValidatorFn } from '@angular/forms';
|
|
4
4
|
import { Subject, OperatorFunction } from 'rxjs';
|
|
5
5
|
import * as ng_hub_ui_forms from 'ng-hub-ui-forms';
|
|
@@ -383,6 +383,44 @@ declare enum HubInputFormats {
|
|
|
383
383
|
File = "file"
|
|
384
384
|
}
|
|
385
385
|
|
|
386
|
+
/**
|
|
387
|
+
* Projects content into the **inline-start** affix area of a `<hub-input>` (left in
|
|
388
|
+
* LTR, right in RTL). Use it for a leading icon — a `<hub-icon>`, currency symbol,
|
|
389
|
+
* inline `<svg>` or even a small button.
|
|
390
|
+
*
|
|
391
|
+
* The input automatically reserves inline padding so its text never overlaps the
|
|
392
|
+
* affix, and themes a projected `<hub-icon>` with its `--hub-input-icon-*` tokens.
|
|
393
|
+
*
|
|
394
|
+
* ```html
|
|
395
|
+
* <hub-input placeholder="Search…">
|
|
396
|
+
* <hub-icon hubInputPrefix name="fa:solid:magnifying-glass" />
|
|
397
|
+
* </hub-input>
|
|
398
|
+
* ```
|
|
399
|
+
*/
|
|
400
|
+
declare class HubInputPrefixDirective {
|
|
401
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<HubInputPrefixDirective, never>;
|
|
402
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HubInputPrefixDirective, "[hubInputPrefix]", never, {}, {}, never, never, true, never>;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Projects content into the **inline-end** affix area of a `<hub-input>` (right in
|
|
407
|
+
* LTR, left in RTL). Use it for a trailing icon or a unit label. For a clear
|
|
408
|
+
* button, prefer the built-in `[clearable]` input instead of projecting one.
|
|
409
|
+
*
|
|
410
|
+
* The input automatically reserves inline padding so its text never overlaps the
|
|
411
|
+
* affix, and themes a projected `<hub-icon>` with its `--hub-input-icon-*` tokens.
|
|
412
|
+
*
|
|
413
|
+
* ```html
|
|
414
|
+
* <hub-input>
|
|
415
|
+
* <hub-icon hubInputSuffix name="fa:solid:circle-info" />
|
|
416
|
+
* </hub-input>
|
|
417
|
+
* ```
|
|
418
|
+
*/
|
|
419
|
+
declare class HubInputSuffixDirective {
|
|
420
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<HubInputSuffixDirective, never>;
|
|
421
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<HubInputSuffixDirective, "[hubInputSuffix]", never, {}, {}, never, never, true, never>;
|
|
422
|
+
}
|
|
423
|
+
|
|
386
424
|
/** Value held by a `<hub-input>` across its supported formats. */
|
|
387
425
|
type HubInputValue = number | string | boolean | File | FileList | null;
|
|
388
426
|
/**
|
|
@@ -437,6 +475,23 @@ declare class HubInputComponent extends HubFieldControl {
|
|
|
437
475
|
readonly prepend: _angular_core.InputSignal<string | string[]>;
|
|
438
476
|
/** Text shown after the control as an input-group addon (text-like formats). */
|
|
439
477
|
readonly append: _angular_core.InputSignal<string | string[]>;
|
|
478
|
+
/** Projected inline-start affix (`[hubInputPrefix]`) — e.g. a `<hub-icon>`, when present. */
|
|
479
|
+
protected readonly prefixDir: _angular_core.Signal<HubInputPrefixDirective | undefined>;
|
|
480
|
+
/** Projected inline-end affix (`[hubInputSuffix]`) — e.g. a `<hub-icon>`, when present. */
|
|
481
|
+
protected readonly suffixDir: _angular_core.Signal<HubInputSuffixDirective | undefined>;
|
|
482
|
+
/**
|
|
483
|
+
* When true, a clear (✕) button is rendered inside the field once it holds a
|
|
484
|
+
* value; activating it resets the control. The glyph comes from the
|
|
485
|
+
* `--hub-input-clear-icon` CSS token, so it can be restyled without touching
|
|
486
|
+
* the template.
|
|
487
|
+
*/
|
|
488
|
+
readonly clearable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
489
|
+
/** Whether the internal clear button should be shown right now. */
|
|
490
|
+
protected readonly showClear: _angular_core.Signal<boolean>;
|
|
491
|
+
/** Whether an inline-start affix (projected prefix) is present. */
|
|
492
|
+
protected readonly hasPrefix: _angular_core.Signal<boolean>;
|
|
493
|
+
/** Whether an inline-end affix (projected suffix or the clear button) is present. */
|
|
494
|
+
protected readonly hasSuffix: _angular_core.Signal<boolean>;
|
|
440
495
|
/** Extra CSS classes applied to the host element. */
|
|
441
496
|
readonly classlist: _angular_core.InputSignal<string>;
|
|
442
497
|
/**
|
|
@@ -455,6 +510,16 @@ declare class HubInputComponent extends HubFieldControl {
|
|
|
455
510
|
readonly valueChange: _angular_core.OutputEmitterRef<HubInputValue>;
|
|
456
511
|
/** Emits the current value when Enter is pressed. */
|
|
457
512
|
readonly enter: _angular_core.OutputEmitterRef<HubInputValue>;
|
|
513
|
+
/** Debounce in milliseconds before {@link search} fires. `0` emits on every keystroke. */
|
|
514
|
+
readonly debounceTime: _angular_core.InputSignalWithTransform<number, unknown>;
|
|
515
|
+
/**
|
|
516
|
+
* Debounced typeahead event: emits the current term (stringified) `debounceTime`
|
|
517
|
+
* ms after the user stops typing. Wire it to drive search / autocomplete without
|
|
518
|
+
* rolling your own debounce. Text-like formats only; `valueChange` stays synchronous.
|
|
519
|
+
*/
|
|
520
|
+
readonly search: _angular_core.OutputEmitterRef<string>;
|
|
521
|
+
/** Clears any pending debounce timer when the component is destroyed. */
|
|
522
|
+
private readonly _searchCleanup;
|
|
458
523
|
/** Accepted file types (file format), e.g. `image/*,.pdf`. */
|
|
459
524
|
readonly accept: _angular_core.InputSignal<string>;
|
|
460
525
|
/** Whether multiple files can be selected (file format). */
|
|
@@ -465,6 +530,8 @@ declare class HubInputComponent extends HubFieldControl {
|
|
|
465
530
|
protected readonly fileInput: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
|
|
466
531
|
/** Whether the current format renders a checkable control (checkbox / switch). */
|
|
467
532
|
protected readonly isCheckable: _angular_core.Signal<boolean>;
|
|
533
|
+
/** Whether the current format renders a typeable text-like control (drives the `search` event). */
|
|
534
|
+
protected readonly isTextLike: _angular_core.Signal<boolean>;
|
|
468
535
|
/** Display label for the selected file(s). */
|
|
469
536
|
protected readonly fileLabel: _angular_core.Signal<string>;
|
|
470
537
|
/** Normalized list of prepend addons. */
|
|
@@ -497,10 +564,12 @@ declare class HubInputComponent extends HubFieldControl {
|
|
|
497
564
|
* @param event - The native `change` event of the file input.
|
|
498
565
|
*/
|
|
499
566
|
protected setFileValue(event: Event): void;
|
|
567
|
+
/** Resets a text-like control to empty via the internal clear button. */
|
|
568
|
+
protected clear(): void;
|
|
500
569
|
/** Clears the selected file(s). */
|
|
501
570
|
protected clearFile(): void;
|
|
502
571
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<HubInputComponent, never>;
|
|
503
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<HubInputComponent, "hub-input", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "labelType": { "alias": "labelType"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "formText": { "alias": "formText"; "required": false; "isSignal": true; }; "formTextType": { "alias": "formTextType"; "required": false; "isSignal": true; }; "prepend": { "alias": "prepend"; "required": false; "isSignal": true; }; "append": { "alias": "append"; "required": false; "isSignal": true; }; "classlist": { "alias": "classlist"; "required": false; "isSignal": true; }; "mask": { "alias": "mask"; "required": false; "isSignal": true; }; "unmaskValue": { "alias": "unmaskValue"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "buttonLabel": { "alias": "buttonLabel"; "required": false; "isSignal": true; }; }, { "labelType": "labelTypeChange"; "placeholder": "placeholderChange"; "min": "minChange"; "max": "maxChange"; "valueChange": "valueChange"; "enter": "enter"; },
|
|
572
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<HubInputComponent, "hub-input", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "labelType": { "alias": "labelType"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "formText": { "alias": "formText"; "required": false; "isSignal": true; }; "formTextType": { "alias": "formTextType"; "required": false; "isSignal": true; }; "prepend": { "alias": "prepend"; "required": false; "isSignal": true; }; "append": { "alias": "append"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "classlist": { "alias": "classlist"; "required": false; "isSignal": true; }; "mask": { "alias": "mask"; "required": false; "isSignal": true; }; "unmaskValue": { "alias": "unmaskValue"; "required": false; "isSignal": true; }; "debounceTime": { "alias": "debounceTime"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "buttonLabel": { "alias": "buttonLabel"; "required": false; "isSignal": true; }; }, { "labelType": "labelTypeChange"; "placeholder": "placeholderChange"; "min": "minChange"; "max": "maxChange"; "valueChange": "valueChange"; "enter": "enter"; "search": "search"; }, ["prefixDir", "suffixDir"], ["[hubInputPrefix]", "[hubInputSuffix]"], true, never>;
|
|
504
573
|
}
|
|
505
574
|
|
|
506
575
|
/** Character set accepted by the OTP field. */
|
|
@@ -1478,5 +1547,52 @@ declare function isMaskActive(mask: string | null | undefined): boolean;
|
|
|
1478
1547
|
*/
|
|
1479
1548
|
declare function applyMask(value: string | null | undefined, mask: string): HubMaskResult;
|
|
1480
1549
|
|
|
1481
|
-
|
|
1482
|
-
|
|
1550
|
+
/** A `{ value, label }` option for select-kind controls. */
|
|
1551
|
+
interface HubFormControlOption {
|
|
1552
|
+
value: unknown;
|
|
1553
|
+
label: string;
|
|
1554
|
+
}
|
|
1555
|
+
/**
|
|
1556
|
+
* Framework-neutral description of a primitive control to render dynamically.
|
|
1557
|
+
*
|
|
1558
|
+
* The shape mirrors (structurally) the contract other ng-hub-ui libraries expose
|
|
1559
|
+
* for optional control hosting (e.g. `ng-hub-ui-paginable`'s table), so this
|
|
1560
|
+
* adapter can be wired into them without either package importing the other.
|
|
1561
|
+
*/
|
|
1562
|
+
interface HubFormControlConfig {
|
|
1563
|
+
kind: 'input' | 'select';
|
|
1564
|
+
value: unknown;
|
|
1565
|
+
type?: string;
|
|
1566
|
+
placeholder?: string;
|
|
1567
|
+
ariaLabel?: string;
|
|
1568
|
+
cssClass?: string;
|
|
1569
|
+
options?: ReadonlyArray<HubFormControlOption>;
|
|
1570
|
+
onValueChange: (value: unknown) => void;
|
|
1571
|
+
}
|
|
1572
|
+
/** Live handle to a control created by {@link hubFormControlAdapter}. */
|
|
1573
|
+
interface HubFormControlHandle {
|
|
1574
|
+
/** Pushes a new value into the control (external updates). */
|
|
1575
|
+
setValue(value: unknown): void;
|
|
1576
|
+
/** Destroys the control and releases its resources. */
|
|
1577
|
+
destroy(): void;
|
|
1578
|
+
}
|
|
1579
|
+
/** Adapter that renders primitive controls with the ng-hub-ui-forms components. */
|
|
1580
|
+
interface HubFormControlAdapter {
|
|
1581
|
+
create(container: ViewContainerRef, config: HubFormControlConfig): HubFormControlHandle;
|
|
1582
|
+
}
|
|
1583
|
+
/**
|
|
1584
|
+
* Ready-made {@link HubFormControlAdapter} backed by `HubInputComponent` /
|
|
1585
|
+
* `HubSelectComponent`.
|
|
1586
|
+
*
|
|
1587
|
+
* Wire it into any ng-hub-ui primitive that exposes an optional form-controls
|
|
1588
|
+
* token, e.g. `provideHubPaginableFormControls(hubFormControlAdapter)`. The host
|
|
1589
|
+
* library keeps **zero hard dependency** on `ng-hub-ui-forms`; only an app that
|
|
1590
|
+
* opts in pulls these components.
|
|
1591
|
+
*
|
|
1592
|
+
* Requires `provideHubForms()` (or the default config) to be available in the
|
|
1593
|
+
* environment so the field components can resolve their configuration.
|
|
1594
|
+
*/
|
|
1595
|
+
declare const hubFormControlAdapter: HubFormControlAdapter;
|
|
1596
|
+
|
|
1597
|
+
export { FormTextTypes, HUB_FORMS_CONFIG, HubAutoresizeDirective, HubDatepickerComponent, HubFieldControl, HubFieldsetComponent, HubFormComponent, HubFormControl, HubFormTextDirective, HubGroupControl, HubInputComponent, HubInputFormats, HubInputPrefixDirective, HubInputSuffixDirective, HubInvertColorPipe, HubJoinButLastPipe, HubLabelTypes, HubLegendComponent, HubLegendDirective, HubMapPipe, HubOtpInputComponent, HubSafeUrlPipe, HubSelectComponent, HubSelectFormats, HubSliderComponent, HubSnakeUpperPipe, HubTextareaComponent, HubUcfirstPipe, HubValidationErrorDirective, NgClearButtonTemplateDirective, NgFooterTemplateDirective, NgHeaderTemplateDirective, NgLabelTemplateDirective, NgLoadingSpinnerTemplateDirective, NgLoadingTextTemplateDirective, NgMultiLabelTemplateDirective, NgNotFoundTemplateDirective, NgOptgroupTemplateDirective, NgOptionComponent, NgOptionTemplateDirective, NgSelectConfig, NgTagTemplateDirective, NgTypeToSearchTemplateDirective, applyMask, areEqual, camelToSnakeUpper, controlHasMinOrMaxValidator, defaultHubDatepickerConfig, defaultHubDatepickerLabels, defaultHubFormsConfig, defaultInvalidFeedback, get, getActiveElement, getMinOrMaxValueFromValidator, hubAreEqual, hubFormControlAdapter, isDefined, isMaskActive, isString, joinButLast, provideHubForms, runInZone, uuid };
|
|
1598
|
+
export type { FormTextType, HubDateRange, HubDateValue, HubDatepickerConfig, HubDatepickerLabels, HubDatepickerMode, HubFormControlAdapter, HubFormControlConfig, HubFormControlHandle, HubFormControlOption, HubFormsConfig, HubGroupErrorTrigger, HubInputFormat, HubLabelType, HubMaskResult, HubOtpMode, HubSelectFormat, HubSliderValue };
|
|
Binary file
|