ngx-strata 0.4.3-beta.2 → 0.4.3

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable, provideAppInitializer, makeEnvironmentProviders, DOCUMENT, signal, computed, effect, InjectionToken, provideEnvironmentInitializer, ElementRef, input, model, output, Directive, Renderer2, DestroyRef, Pipe, HostBinding, Component, contentChildren, forwardRef, contentChild, HostListener, ViewContainerRef, viewChild, Injector, LOCALE_ID, viewChildren, booleanAttribute, ContentChildren, TemplateRef } from '@angular/core';
2
+ import { inject, Injectable, provideAppInitializer, makeEnvironmentProviders, DOCUMENT, signal, computed, effect, InjectionToken, provideEnvironmentInitializer, ElementRef, input, model, output, Directive, Renderer2, DestroyRef, Pipe, HostBinding, Component, contentChildren, forwardRef, contentChild, HostListener, ViewContainerRef, viewChild, numberAttribute, booleanAttribute, Injector, LOCALE_ID, viewChildren, ContentChildren, TemplateRef } from '@angular/core';
3
3
  import { Observable, tap, map, fromEvent, switchMap, filter } from 'rxjs';
4
4
  import { HttpClient } from '@angular/common/http';
5
5
  import { DomSanitizer } from '@angular/platform-browser';
@@ -2060,12 +2060,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImpor
2060
2060
  }] });
2061
2061
 
2062
2062
  class StrataInputFieldComponent {
2063
+ hostElement = inject((ElementRef));
2063
2064
  size = input('md', /* @ts-ignore */
2064
2065
  ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
2066
+ maxLength = input(undefined, { ...(ngDevMode ? { debugName: "maxLength" } : /* istanbul ignore next */ {}), transform: (value) => value === undefined || value === null || value === '' ? undefined : numberAttribute(value) });
2067
+ showCharacterCounter = input(false, { ...(ngDevMode ? { debugName: "showCharacterCounter" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2068
+ characterCounterFormatter = input(undefined, /* @ts-ignore */
2069
+ ...(ngDevMode ? [{ debugName: "characterCounterFormatter" }] : /* istanbul ignore next */ []));
2065
2070
  iconComponents = contentChildren(StrataIconComponent, { ...(ngDevMode ? { debugName: "iconComponents" } : /* istanbul ignore next */ {}), descendants: true });
2066
2071
  inputField = contentChild(StrataNativeInputRefDirective, { ...(ngDevMode ? { debugName: "inputField" } : /* istanbul ignore next */ {}), descendants: true });
2067
2072
  pendingFocus = signal(false, /* @ts-ignore */
2068
2073
  ...(ngDevMode ? [{ debugName: "pendingFocus" }] : /* istanbul ignore next */ []));
2074
+ currentLength = signal(0, /* @ts-ignore */
2075
+ ...(ngDevMode ? [{ debugName: "currentLength" }] : /* istanbul ignore next */ []));
2076
+ nativeMaxLength = signal(undefined, /* @ts-ignore */
2077
+ ...(ngDevMode ? [{ debugName: "nativeMaxLength" }] : /* istanbul ignore next */ []));
2078
+ effectiveMaxLength = computed(() => this.maxLength() ?? this.nativeMaxLength(), /* @ts-ignore */
2079
+ ...(ngDevMode ? [{ debugName: "effectiveMaxLength" }] : /* istanbul ignore next */ []));
2080
+ counterText = computed(() => {
2081
+ const current = this.currentLength();
2082
+ const max = this.effectiveMaxLength();
2083
+ const formatter = this.characterCounterFormatter();
2084
+ if (formatter) {
2085
+ return formatter(current, max);
2086
+ }
2087
+ if (max !== undefined) {
2088
+ return `${current} / ${max}`;
2089
+ }
2090
+ return `${current}`;
2091
+ }, /* @ts-ignore */
2092
+ ...(ngDevMode ? [{ debugName: "counterText" }] : /* istanbul ignore next */ []));
2069
2093
  constructor() {
2070
2094
  effect(() => {
2071
2095
  const input = this.inputField();
@@ -2077,27 +2101,67 @@ class StrataInputFieldComponent {
2077
2101
  }
2078
2102
  ngAfterViewInit() {
2079
2103
  setTimeout(() => this.iconComponents().forEach((icon) => icon.size.set('sm')), 1);
2104
+ this.syncNativeState();
2105
+ }
2106
+ ngAfterContentChecked() {
2107
+ this.syncNativeState();
2108
+ }
2109
+ onNativeInput() {
2110
+ this.syncNativeState();
2080
2111
  }
2081
2112
  focus() {
2082
2113
  this.pendingFocus.set(true);
2083
2114
  }
2084
2115
  blur() {
2085
- this.inputField()?.el.nativeElement.blur();
2116
+ this.nativeInput?.blur();
2086
2117
  }
2087
2118
  get nativeInput() {
2088
- return this.inputField()?.el.nativeElement;
2119
+ return (this.inputField()?.el.nativeElement ??
2120
+ this.hostElement.nativeElement.querySelector('input, textarea') ??
2121
+ undefined);
2122
+ }
2123
+ syncNativeState() {
2124
+ const input = this.nativeInput;
2125
+ if (!input) {
2126
+ return;
2127
+ }
2128
+ const explicitMax = this.maxLength();
2129
+ if (explicitMax !== undefined) {
2130
+ const maxStr = String(explicitMax);
2131
+ if (input.getAttribute('maxlength') !== maxStr) {
2132
+ input.setAttribute('maxlength', maxStr);
2133
+ }
2134
+ if (input.value.length > explicitMax) {
2135
+ input.value = input.value.slice(0, explicitMax);
2136
+ input.dispatchEvent(new Event('input', { bubbles: true }));
2137
+ }
2138
+ }
2139
+ else {
2140
+ const attr = input.getAttribute('maxlength');
2141
+ const parsed = attr !== null && attr !== '' ? parseInt(attr, 10) : undefined;
2142
+ const validMax = parsed !== undefined && !isNaN(parsed) && parsed >= 0 ? parsed : undefined;
2143
+ if (this.nativeMaxLength() !== validMax) {
2144
+ this.nativeMaxLength.set(validMax);
2145
+ }
2146
+ }
2147
+ const currentLen = input.value.length;
2148
+ if (this.currentLength() !== currentLen) {
2149
+ this.currentLength.set(currentLen);
2150
+ }
2089
2151
  }
2090
2152
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataInputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2091
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.1", type: StrataInputFieldComponent, isStandalone: true, selector: "st-input-field", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.st-size-sm": "size() === \"sm\"", "class.st-size-md": "size() === \"md\"", "class.st-size-lg": "size() === \"lg\"" } }, queries: [{ propertyName: "iconComponents", predicate: StrataIconComponent, descendants: true, isSignal: true }, { propertyName: "inputField", first: true, predicate: StrataNativeInputRefDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-content select=\"label\"></ng-content>\n<div class=\"st-input-wrapper\">\n <div class=\"affix\">\n <ng-content select=\"[prefix]\"></ng-content>\n </div>\n <ng-content select=\"input,textarea\"></ng-content>\n <div class=\"affix\">\n <ng-content select=\"[suffix]\"></ng-content>\n </div>\n</div>\n" });
2153
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.1", type: StrataInputFieldComponent, isStandalone: true, selector: "st-input-field", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, showCharacterCounter: { classPropertyName: "showCharacterCounter", publicName: "showCharacterCounter", isSignal: true, isRequired: false, transformFunction: null }, characterCounterFormatter: { classPropertyName: "characterCounterFormatter", publicName: "characterCounterFormatter", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "input": "onNativeInput()", "change": "onNativeInput()" }, properties: { "class.st-size-sm": "size() === \"sm\"", "class.st-size-md": "size() === \"md\"", "class.st-size-lg": "size() === \"lg\"" } }, queries: [{ propertyName: "iconComponents", predicate: StrataIconComponent, descendants: true, isSignal: true }, { propertyName: "inputField", first: true, predicate: StrataNativeInputRefDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-content select=\"label\"></ng-content>\n<div class=\"st-input-wrapper\">\n <div class=\"affix\">\n <ng-content select=\"[prefix]\"></ng-content>\n </div>\n <ng-content select=\"input,textarea\"></ng-content>\n <div class=\"affix\">\n <ng-content select=\"[suffix]\"></ng-content>\n </div>\n</div>\n@if (showCharacterCounter()) {\n <div class=\"st-input-field-footer\">\n <span class=\"st-input-field-counter\" aria-live=\"polite\">{{ counterText() }}</span>\n </div>\n}\n" });
2092
2154
  }
2093
2155
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataInputFieldComponent, decorators: [{
2094
2156
  type: Component,
2095
2157
  args: [{ selector: 'st-input-field', imports: [], host: {
2096
2158
  '[class.st-size-sm]': 'size() === "sm"',
2097
2159
  '[class.st-size-md]': 'size() === "md"',
2098
- '[class.st-size-lg]': 'size() === "lg"'
2099
- }, template: "<ng-content select=\"label\"></ng-content>\n<div class=\"st-input-wrapper\">\n <div class=\"affix\">\n <ng-content select=\"[prefix]\"></ng-content>\n </div>\n <ng-content select=\"input,textarea\"></ng-content>\n <div class=\"affix\">\n <ng-content select=\"[suffix]\"></ng-content>\n </div>\n</div>\n" }]
2100
- }], ctorParameters: () => [], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], iconComponents: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrataIconComponent), { ...{ descendants: true }, isSignal: true }] }], inputField: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrataNativeInputRefDirective), { ...{
2160
+ '[class.st-size-lg]': 'size() === "lg"',
2161
+ '(input)': 'onNativeInput()',
2162
+ '(change)': 'onNativeInput()'
2163
+ }, template: "<ng-content select=\"label\"></ng-content>\n<div class=\"st-input-wrapper\">\n <div class=\"affix\">\n <ng-content select=\"[prefix]\"></ng-content>\n </div>\n <ng-content select=\"input,textarea\"></ng-content>\n <div class=\"affix\">\n <ng-content select=\"[suffix]\"></ng-content>\n </div>\n</div>\n@if (showCharacterCounter()) {\n <div class=\"st-input-field-footer\">\n <span class=\"st-input-field-counter\" aria-live=\"polite\">{{ counterText() }}</span>\n </div>\n}\n" }]
2164
+ }], ctorParameters: () => [], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], showCharacterCounter: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCharacterCounter", required: false }] }], characterCounterFormatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "characterCounterFormatter", required: false }] }], iconComponents: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrataIconComponent), { ...{ descendants: true }, isSignal: true }] }], inputField: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrataNativeInputRefDirective), { ...{
2101
2165
  descendants: true
2102
2166
  }, isSignal: true }] }] } });
2103
2167
 
@@ -3997,7 +4061,7 @@ class StrataSingleSelectComponent {
3997
4061
  useExisting: forwardRef(() => StrataSingleSelectComponent),
3998
4062
  multi: true
3999
4063
  }
4000
- ], queries: [{ propertyName: "selectItems", predicate: StrataSelectItemComponent, isSignal: true }, { propertyName: "triggerTemplate", first: true, predicate: StrataSelectTriggerDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "inputField", first: true, predicate: StrataInputFieldComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n<label class=\"st-label\" [for]=\"name()\"> {{ label() }}</label>\n}\n<div class=\"single-select-input\" [class.disabled]=\"effectiveDisabled()\" [id]=\"name()\" #singleSelectInput (click)=\"toggle($event)\" (keydown.space)=\"toggle($event)\" (keydown.enter)=\"toggle($event)\" (keydown.escape)=\"open.set(false)\" [attr.data-open]=\"open()\"\n [attr.tabindex]=\"effectiveDisabled() ? -1 : 0\" [stOverlay]=\"selector\" [overlayOpen]=\"open()\" [overlayPlacement]=\"placement()\">\n @if (selectedItem()) {\n @if (triggerTemplate()) {\n <ng-container *ngTemplateOutlet=\"triggerTemplate()!\"></ng-container>\n } @else {\n {{ selectedItem()!.text() }}\n }\n } @else {\n <span class=\"placeholder-text\">{{ placeholder() }}</span>\n }\n\n <st-icon name=\"expand-up-down\"></st-icon>\n</div>\n\n<ng-template #selector>\n <div class=\"single-select-selector\" #singleSelectSelector [class.full-width]=\"fullWidth()\">\n @if (searchable()) {\n <st-input-field>\n <input stInput #searchField type=\"text\" [value]=\"searchQuery() || ''\" (input)=\"searchQuery.set($any($event.target).value); onSearchChange(searchQuery())\" [placeholder]=\"searchPlaceholder()\" />\n <button stButton variant=\"ghost\" [class.visible]=\"searchQuery() !== undefined && searchQuery()!.length > 0\" suffix\n size=\"sm\" (click)=\"searchQuery.set(undefined); onSearchChange(undefined)\">\n x\n </button>\n </st-input-field>\n }\n <div class=\"single-select-items-container\">\n <ng-content select=\"st-select-item\"></ng-content>\n </div>\n </div>\n</ng-template>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataInputFieldComponent, selector: "st-input-field", inputs: ["size"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: StrataNativeInputRefDirective, selector: "input[stInput], textarea[stInput]" }, { kind: "directive", type: StrataButtonDirective, selector: "[stButton]", inputs: ["variant", "size", "fullWidth"] }] });
4064
+ ], queries: [{ propertyName: "selectItems", predicate: StrataSelectItemComponent, isSignal: true }, { propertyName: "triggerTemplate", first: true, predicate: StrataSelectTriggerDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "inputField", first: true, predicate: StrataInputFieldComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n<label class=\"st-label\" [for]=\"name()\"> {{ label() }}</label>\n}\n<div class=\"single-select-input\" [class.disabled]=\"effectiveDisabled()\" [id]=\"name()\" #singleSelectInput (click)=\"toggle($event)\" (keydown.space)=\"toggle($event)\" (keydown.enter)=\"toggle($event)\" (keydown.escape)=\"open.set(false)\" [attr.data-open]=\"open()\"\n [attr.tabindex]=\"effectiveDisabled() ? -1 : 0\" [stOverlay]=\"selector\" [overlayOpen]=\"open()\" [overlayPlacement]=\"placement()\">\n @if (selectedItem()) {\n @if (triggerTemplate()) {\n <ng-container *ngTemplateOutlet=\"triggerTemplate()!\"></ng-container>\n } @else {\n {{ selectedItem()!.text() }}\n }\n } @else {\n <span class=\"placeholder-text\">{{ placeholder() }}</span>\n }\n\n <st-icon name=\"expand-up-down\"></st-icon>\n</div>\n\n<ng-template #selector>\n <div class=\"single-select-selector\" #singleSelectSelector [class.full-width]=\"fullWidth()\">\n @if (searchable()) {\n <st-input-field>\n <input stInput #searchField type=\"text\" [value]=\"searchQuery() || ''\" (input)=\"searchQuery.set($any($event.target).value); onSearchChange(searchQuery())\" [placeholder]=\"searchPlaceholder()\" />\n <button stButton variant=\"ghost\" [class.visible]=\"searchQuery() !== undefined && searchQuery()!.length > 0\" suffix\n size=\"sm\" (click)=\"searchQuery.set(undefined); onSearchChange(undefined)\">\n x\n </button>\n </st-input-field>\n }\n <div class=\"single-select-items-container\">\n <ng-content select=\"st-select-item\"></ng-content>\n </div>\n </div>\n</ng-template>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: StrataIconComponent, selector: "st-icon", inputs: ["name", "size", "ariaLabel"], outputs: ["sizeChange"] }, { kind: "directive", type: StrataOverlayDirective, selector: "[stOverlay]", inputs: ["stOverlay", "overlayOpen", "overlayPlacement", "overlayOffset", "overlayFitViewport"], outputs: ["overlayOpenChange"] }, { kind: "component", type: StrataInputFieldComponent, selector: "st-input-field", inputs: ["size", "maxLength", "showCharacterCounter", "characterCounterFormatter"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: StrataNativeInputRefDirective, selector: "input[stInput], textarea[stInput]" }, { kind: "directive", type: StrataButtonDirective, selector: "[stButton]", inputs: ["variant", "size", "fullWidth"] }] });
4001
4065
  }
4002
4066
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.1", ngImport: i0, type: StrataSingleSelectComponent, decorators: [{
4003
4067
  type: Component,