@propbinder/mobile-design 0.1.15 → 0.1.16

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 { signal, computed, effect, Injectable, inject, Input, Component, input, Directive, EventEmitter, HostListener, Output, PLATFORM_ID, output, ViewChild, ViewEncapsulation, CUSTOM_ELEMENTS_SCHEMA, model, ElementRef, createComponent } from '@angular/core';
2
+ import { signal, computed, effect, Injectable, inject, Input, Component, input, Directive, EventEmitter, HostListener, Output, PLATFORM_ID, output, ViewChild, ViewEncapsulation, CUSTOM_ELEMENTS_SCHEMA, model, ElementRef, createComponent, forwardRef } from '@angular/core';
3
3
  import * as i1$2 from '@angular/common';
4
4
  import { CommonModule, isPlatformBrowser } from '@angular/common';
5
5
  import * as i1$3 from '@angular/router';
@@ -10,7 +10,7 @@ import { ImpactStyle, Haptics } from '@capacitor/haptics';
10
10
  import { DsIconButtonComponent, DsIconComponent, DsButtonComponent, DsAvatarComponent, DsShapeIndicatorComponent } from '@propbinder/design-system';
11
11
  import { StatusBar } from '@capacitor/status-bar';
12
12
  import * as i1$1 from '@angular/forms';
13
- import { FormsModule } from '@angular/forms';
13
+ import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
14
14
  import { Keyboard } from '@capacitor/keyboard';
15
15
  import { Camera, CameraSource, CameraResultType } from '@capacitor/camera';
16
16
  import { filter } from 'rxjs/operators';
@@ -9565,6 +9565,213 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
9565
9565
  args: ['click']
9566
9566
  }] } });
9567
9567
 
9568
+ /**
9569
+ * DsTextInputComponent
9570
+ *
9571
+ * Mobile-first text input field component following the design system.
9572
+ * Supports email, phone, text, and other input types.
9573
+ *
9574
+ * Features:
9575
+ * - All design system states (default, hover, focus, error, disabled)
9576
+ * - Validation error state with destructive border color
9577
+ * - Automatic error clearing when input becomes valid (configurable)
9578
+ * - Built-in validation based on input type or custom validator function
9579
+ * - Accessible with proper ARIA attributes
9580
+ * - ControlValueAccessor for Angular forms integration
9581
+ *
9582
+ * @example
9583
+ * ```html
9584
+ * <!-- Basic usage -->
9585
+ * <ds-text-input
9586
+ * type="email"
9587
+ * placeholder="Enter your email"
9588
+ * [(ngModel)]="email">
9589
+ * </ds-text-input>
9590
+ *
9591
+ * <!-- With validation error and auto-clear -->
9592
+ * <ds-text-input
9593
+ * type="email"
9594
+ * placeholder="Enter your email"
9595
+ * [hasError]="emailInvalid"
9596
+ * errorMessage="Please enter a valid email"
9597
+ * [autoClearError]="true"
9598
+ * (errorCleared)="emailInvalid = false"
9599
+ * [(ngModel)]="email">
9600
+ * </ds-text-input>
9601
+ *
9602
+ * <!-- With custom validator -->
9603
+ * <ds-text-input
9604
+ * type="text"
9605
+ * placeholder="Enter phone number"
9606
+ * [validator]="phoneValidator"
9607
+ * [hasError]="phoneInvalid"
9608
+ * (errorCleared)="phoneInvalid = false"
9609
+ * [(ngModel)]="phone">
9610
+ * </ds-text-input>
9611
+ * ```
9612
+ */
9613
+ class DsTextInputComponent {
9614
+ // Input properties
9615
+ type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : []));
9616
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
9617
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
9618
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
9619
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
9620
+ hasError = input(false, ...(ngDevMode ? [{ debugName: "hasError" }] : []));
9621
+ errorMessage = input('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
9622
+ autocomplete = input('', ...(ngDevMode ? [{ debugName: "autocomplete" }] : []));
9623
+ inputmode = input(undefined, ...(ngDevMode ? [{ debugName: "inputmode" }] : []));
9624
+ autoClearError = input(true, ...(ngDevMode ? [{ debugName: "autoClearError" }] : []));
9625
+ validator = input(null, ...(ngDevMode ? [{ debugName: "validator" }] : []));
9626
+ // Output events
9627
+ valueChange = output();
9628
+ blur = output();
9629
+ focus = output();
9630
+ errorCleared = output();
9631
+ // Internal state
9632
+ _value = signal('', ...(ngDevMode ? [{ debugName: "_value" }] : []));
9633
+ value = computed(() => this._value(), ...(ngDevMode ? [{ debugName: "value" }] : []));
9634
+ // Generate unique ID for accessibility
9635
+ inputId = `ds-text-input-${Math.random().toString(36).substring(2, 9)}`;
9636
+ // ControlValueAccessor implementation
9637
+ onChange = (value) => { };
9638
+ onTouched = () => { };
9639
+ onInput(event) {
9640
+ const target = event.target;
9641
+ const newValue = target.value;
9642
+ this._value.set(newValue);
9643
+ this.onChange(newValue);
9644
+ this.valueChange.emit(newValue);
9645
+ // Auto-clear error if input becomes valid
9646
+ if (this.autoClearError() && this.hasError()) {
9647
+ const isValid = this.validateInput(newValue);
9648
+ if (isValid) {
9649
+ this.errorCleared.emit();
9650
+ }
9651
+ }
9652
+ }
9653
+ /**
9654
+ * Validates the input value based on type or custom validator
9655
+ */
9656
+ validateInput(value) {
9657
+ // Use custom validator if provided
9658
+ const customValidator = this.validator();
9659
+ if (customValidator) {
9660
+ return customValidator(value);
9661
+ }
9662
+ // Use built-in validation based on input type
9663
+ const inputType = this.type();
9664
+ const inputElement = document.createElement('input');
9665
+ inputElement.type = inputType;
9666
+ inputElement.value = value;
9667
+ // For email type, use HTML5 validation
9668
+ if (inputType === 'email') {
9669
+ return inputElement.validity.valid;
9670
+ }
9671
+ // For required fields, check if value exists
9672
+ if (this.required() && !value.trim()) {
9673
+ return false;
9674
+ }
9675
+ // Default: valid if HTML5 validation passes
9676
+ return inputElement.validity.valid;
9677
+ }
9678
+ onBlur() {
9679
+ this.onTouched();
9680
+ }
9681
+ onFocus() {
9682
+ // Focus event can be emitted if needed
9683
+ }
9684
+ // ControlValueAccessor methods
9685
+ writeValue(value) {
9686
+ this._value.set(value || '');
9687
+ }
9688
+ registerOnChange(fn) {
9689
+ this.onChange = fn;
9690
+ }
9691
+ registerOnTouched(fn) {
9692
+ this.onTouched = fn;
9693
+ }
9694
+ setDisabledState(isDisabled) {
9695
+ // Angular forms will handle this via the disabled input
9696
+ }
9697
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DsTextInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9698
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", type: DsTextInputComponent, isStandalone: true, selector: "ds-text-input", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, inputmode: { classPropertyName: "inputmode", publicName: "inputmode", isSignal: true, isRequired: false, transformFunction: null }, autoClearError: { classPropertyName: "autoClearError", publicName: "autoClearError", isSignal: true, isRequired: false, transformFunction: null }, validator: { classPropertyName: "validator", publicName: "validator", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", blur: "blur", focus: "focus", errorCleared: "errorCleared" }, providers: [
9699
+ {
9700
+ provide: NG_VALUE_ACCESSOR,
9701
+ useExisting: forwardRef(() => DsTextInputComponent),
9702
+ multi: true
9703
+ }
9704
+ ], ngImport: i0, template: `
9705
+ <div class="text-input-wrapper">
9706
+ <input
9707
+ [type]="type()"
9708
+ [placeholder]="placeholder()"
9709
+ [value]="value()"
9710
+ [disabled]="disabled()"
9711
+ [readonly]="readonly()"
9712
+ [required]="required()"
9713
+ [autocomplete]="autocomplete() || null"
9714
+ [attr.inputmode]="inputmode() || null"
9715
+ [class.error]="hasError()"
9716
+ [attr.aria-invalid]="hasError()"
9717
+ [attr.aria-describedby]="hasError() && errorMessage() ? 'error-' + inputId : null"
9718
+ class="text-input"
9719
+ (input)="onInput($event)"
9720
+ (blur)="onBlur()"
9721
+ (focus)="onFocus()"
9722
+ [id]="inputId">
9723
+
9724
+ @if (hasError() && errorMessage()) {
9725
+ <div
9726
+ class="error-message"
9727
+ [id]="'error-' + inputId"
9728
+ role="alert">
9729
+ {{ errorMessage() }}
9730
+ </div>
9731
+ }
9732
+ </div>
9733
+ `, isInline: true, styles: [":host{display:block;width:100%}.text-input-wrapper{position:relative;width:100%}.text-input{width:100%;height:48px;padding:0 16px;box-sizing:border-box;font-family:Brockmann,system-ui,-apple-system,sans-serif;font-size:var(--font-size-base);font-weight:400;line-height:1.4;color:var(--text-color-default-primary);background-color:var(--color-background-neutral-primary);border:1px solid var(--border-color-default);border-radius:8px;transition:border-color var(--transition-duration-fast) var(--ease-smooth),background-color var(--transition-duration-fast) var(--ease-smooth),box-shadow var(--transition-duration-fast) var(--ease-smooth);outline:none;-webkit-appearance:none;appearance:none}.text-input::placeholder{color:var(--text-color-default-tertiary)}.text-input:hover:not(:disabled):not(:focus){border-color:var(--border-color-default);background-color:var(--color-background-neutral-primary-hover)}.text-input:focus{border-color:var(--color-brand-base);background-color:var(--color-background-neutral-primary);box-shadow:0 0 0 3px var(--outline-color-default)}.text-input.error{border-color:var(--color-destructive-base)}.text-input.error:focus{border-color:var(--color-destructive-base);box-shadow:0 0 0 3px #dc26261a}.text-input:disabled{background-color:var(--color-background-neutral-disabled);border-color:var(--border-color-default);color:var(--text-color-default-disabled);cursor:not-allowed}.text-input:disabled::placeholder{color:var(--text-color-default-disabled)}.error-message{margin-top:8px;font-family:Brockmann,system-ui,-apple-system,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-destructive-base)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
9734
+ }
9735
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: DsTextInputComponent, decorators: [{
9736
+ type: Component,
9737
+ args: [{ selector: 'ds-text-input', standalone: true, imports: [CommonModule, FormsModule], providers: [
9738
+ {
9739
+ provide: NG_VALUE_ACCESSOR,
9740
+ useExisting: forwardRef(() => DsTextInputComponent),
9741
+ multi: true
9742
+ }
9743
+ ], template: `
9744
+ <div class="text-input-wrapper">
9745
+ <input
9746
+ [type]="type()"
9747
+ [placeholder]="placeholder()"
9748
+ [value]="value()"
9749
+ [disabled]="disabled()"
9750
+ [readonly]="readonly()"
9751
+ [required]="required()"
9752
+ [autocomplete]="autocomplete() || null"
9753
+ [attr.inputmode]="inputmode() || null"
9754
+ [class.error]="hasError()"
9755
+ [attr.aria-invalid]="hasError()"
9756
+ [attr.aria-describedby]="hasError() && errorMessage() ? 'error-' + inputId : null"
9757
+ class="text-input"
9758
+ (input)="onInput($event)"
9759
+ (blur)="onBlur()"
9760
+ (focus)="onFocus()"
9761
+ [id]="inputId">
9762
+
9763
+ @if (hasError() && errorMessage()) {
9764
+ <div
9765
+ class="error-message"
9766
+ [id]="'error-' + inputId"
9767
+ role="alert">
9768
+ {{ errorMessage() }}
9769
+ </div>
9770
+ }
9771
+ </div>
9772
+ `, styles: [":host{display:block;width:100%}.text-input-wrapper{position:relative;width:100%}.text-input{width:100%;height:48px;padding:0 16px;box-sizing:border-box;font-family:Brockmann,system-ui,-apple-system,sans-serif;font-size:var(--font-size-base);font-weight:400;line-height:1.4;color:var(--text-color-default-primary);background-color:var(--color-background-neutral-primary);border:1px solid var(--border-color-default);border-radius:8px;transition:border-color var(--transition-duration-fast) var(--ease-smooth),background-color var(--transition-duration-fast) var(--ease-smooth),box-shadow var(--transition-duration-fast) var(--ease-smooth);outline:none;-webkit-appearance:none;appearance:none}.text-input::placeholder{color:var(--text-color-default-tertiary)}.text-input:hover:not(:disabled):not(:focus){border-color:var(--border-color-default);background-color:var(--color-background-neutral-primary-hover)}.text-input:focus{border-color:var(--color-brand-base);background-color:var(--color-background-neutral-primary);box-shadow:0 0 0 3px var(--outline-color-default)}.text-input.error{border-color:var(--color-destructive-base)}.text-input.error:focus{border-color:var(--color-destructive-base);box-shadow:0 0 0 3px #dc26261a}.text-input:disabled{background-color:var(--color-background-neutral-disabled);border-color:var(--border-color-default);color:var(--text-color-default-disabled);cursor:not-allowed}.text-input:disabled::placeholder{color:var(--text-color-default-disabled)}.error-message{margin-top:8px;font-family:Brockmann,system-ui,-apple-system,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-destructive-base)}\n"] }]
9773
+ }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], hasError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasError", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], inputmode: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputmode", required: false }] }], autoClearError: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoClearError", required: false }] }], validator: [{ type: i0.Input, args: [{ isSignal: true, alias: "validator", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], blur: [{ type: i0.Output, args: ["blur"] }], focus: [{ type: i0.Output, args: ["focus"] }], errorCleared: [{ type: i0.Output, args: ["errorCleared"] }] } });
9774
+
9568
9775
  // Mobile Page Components
9569
9776
 
9570
9777
  /**
@@ -13034,5 +13241,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
13034
13241
  * Generated bundle index. Do not edit.
13035
13242
  */
13036
13243
 
13037
- export { ActionCommentComponent, ActionLikeComponent, ContentRowComponent, DsMobileActionsBottomSheetComponent, DsMobileBottomSheetService, DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent, DsMobileCommentComponent, DsMobileContactListItemComponent, DsMobileContentComponent, DsMobileContentSectionComponent, DsMobileHandbookDetailModalComponent, DsMobileHandbookDetailModalService, DsMobileHandbookFolderComponent, DsMobileHandbookFolderMiniComponent, DsMobileHeaderContentComponent, DsMobileHeaderContentTileComponent, DsMobileInlinePhotoComponent, DsMobileInlineTabsComponent, DsMobileInteractiveListItemInquiryComponent, DsMobileInteractiveListItemMessageComponent, DsMobileInteractiveListItemPostComponent, DsMobileLightboxImageComponent as DsMobileLightboxComponent, DsMobileLightboxFooterComponent, DsMobileLightboxHeaderComponent, DsMobileLightboxImageComponent, DsMobileLightboxPdfComponent, DsMobileLightboxService, DsMobileListItemComponent, DsMobileListItemStaticComponent, DsMobileLongPressDirective, DsMobileModalService, DsMobilePageDetailsComponent, DsMobilePageMainComponent, DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent, DsMobilePostComposerComponent, DsMobilePostCreateBottomSheetComponent, DsMobilePostDetailModalComponent, DsMobilePostDetailModalService, DsMobileTabBarComponent, DsMobileTabsComponent, MobileCommunityPageComponent, MobileHandbookPageComponent, MobileHomePageComponent, MobileInquiriesPageComponent, MobileInquiryDetailPageComponent, MobilePageBase, MobilePostDetailPageComponent, MobileTabsExampleComponent, PostActionsComponent, PostAttachmentsComponent, PostContentComponent, PostCreatePageComponent, PostMediaComponent, PostPdfAttachmentComponent, PostTextComponent, SectionHeaderComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, UserService, WhitelabelDemoPage, WhitelabelService, customBackTransition, customPageTransition };
13244
+ export { ActionCommentComponent, ActionLikeComponent, ContentRowComponent, DsMobileActionsBottomSheetComponent, DsMobileBottomSheetService, DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent, DsMobileCommentComponent, DsMobileContactListItemComponent, DsMobileContentComponent, DsMobileContentSectionComponent, DsMobileHandbookDetailModalComponent, DsMobileHandbookDetailModalService, DsMobileHandbookFolderComponent, DsMobileHandbookFolderMiniComponent, DsMobileHeaderContentComponent, DsMobileHeaderContentTileComponent, DsMobileInlinePhotoComponent, DsMobileInlineTabsComponent, DsMobileInteractiveListItemInquiryComponent, DsMobileInteractiveListItemMessageComponent, DsMobileInteractiveListItemPostComponent, DsMobileLightboxImageComponent as DsMobileLightboxComponent, DsMobileLightboxFooterComponent, DsMobileLightboxHeaderComponent, DsMobileLightboxImageComponent, DsMobileLightboxPdfComponent, DsMobileLightboxService, DsMobileListItemComponent, DsMobileListItemStaticComponent, DsMobileLongPressDirective, DsMobileModalService, DsMobilePageDetailsComponent, DsMobilePageMainComponent, DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent, DsMobilePostComposerComponent, DsMobilePostCreateBottomSheetComponent, DsMobilePostDetailModalComponent, DsMobilePostDetailModalService, DsMobileTabBarComponent, DsMobileTabsComponent, DsTextInputComponent, MobileCommunityPageComponent, MobileHandbookPageComponent, MobileHomePageComponent, MobileInquiriesPageComponent, MobileInquiryDetailPageComponent, MobilePageBase, MobilePostDetailPageComponent, MobileTabsExampleComponent, PostActionsComponent, PostAttachmentsComponent, PostContentComponent, PostCreatePageComponent, PostMediaComponent, PostPdfAttachmentComponent, PostTextComponent, SectionHeaderComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, UserService, WhitelabelDemoPage, WhitelabelService, customBackTransition, customPageTransition };
13038
13245
  //# sourceMappingURL=propbinder-mobile-design.mjs.map