@sneat/components 0.25.0 → 0.26.1

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.
Files changed (41) hide show
  1. package/esm2022/lib/app-version/app-version.component.js +6 -6
  2. package/esm2022/lib/app-version/app-version.component.js.map +1 -1
  3. package/esm2022/lib/card-list/sneat-card-list.component.js +15 -16
  4. package/esm2022/lib/card-list/sneat-card-list.component.js.map +1 -1
  5. package/esm2022/lib/copyright/copyright.component.js +5 -5
  6. package/esm2022/lib/copyright/copyright.component.js.map +1 -1
  7. package/esm2022/lib/country-input/country-input.component.js +18 -18
  8. package/esm2022/lib/country-input/country-input.component.js.map +1 -1
  9. package/esm2022/lib/country-selector/countries-loader.service.js +5 -4
  10. package/esm2022/lib/country-selector/countries-loader.service.js.map +1 -1
  11. package/esm2022/lib/country-selector/country-selector.component.js +34 -32
  12. package/esm2022/lib/country-selector/country-selector.component.js.map +1 -1
  13. package/esm2022/lib/country-selector/country-selector.service.js +3 -3
  14. package/esm2022/lib/date-input/date-input.component.js +24 -15
  15. package/esm2022/lib/date-input/date-input.component.js.map +1 -1
  16. package/esm2022/lib/date-input/date-modal.component.js +14 -13
  17. package/esm2022/lib/date-input/date-modal.component.js.map +1 -1
  18. package/esm2022/lib/dialog-header/dialog-header.component.js +9 -10
  19. package/esm2022/lib/dialog-header/dialog-header.component.js.map +1 -1
  20. package/esm2022/lib/error-card/sneat-error-card.component.js +6 -6
  21. package/esm2022/lib/error-card/sneat-error-card.component.js.map +1 -1
  22. package/esm2022/lib/filter-item/filter-item.component.js +6 -5
  23. package/esm2022/lib/filter-item/filter-item.component.js.map +1 -1
  24. package/esm2022/lib/pipes/country-emoji.pipe.js +6 -6
  25. package/esm2022/lib/pipes/decimal64p2.pipe.js +6 -6
  26. package/esm2022/lib/pipes/gender.pipes.js +9 -9
  27. package/esm2022/lib/pipes/long-month-name.pipe.js +3 -3
  28. package/esm2022/lib/pipes/short-month-name.pipe.js +3 -3
  29. package/esm2022/lib/pipes/team-emoji.pipe.js +3 -3
  30. package/esm2022/lib/user-country/user-country.component.js +22 -17
  31. package/esm2022/lib/user-country/user-country.component.js.map +1 -1
  32. package/lib/card-list/sneat-card-list.component.d.ts +5 -5
  33. package/lib/country-input/country-input.component.d.ts +4 -4
  34. package/lib/country-selector/country-selector.component.d.ts +6 -6
  35. package/lib/date-input/date-input.component.d.ts +1 -1
  36. package/lib/date-input/date-modal.component.d.ts +3 -3
  37. package/lib/dialog-header/dialog-header.component.d.ts +2 -2
  38. package/lib/user-country/user-country.component.d.ts +2 -2
  39. package/package.json +6 -5
  40. package/src/sneat-styles.scss +10 -10
  41. package/tsconfig.lib.prod.tsbuildinfo +1 -1
@@ -1,9 +1,10 @@
1
1
  import { ChangeDetectionStrategy, Component, EventEmitter, input, Output, } from '@angular/core';
2
- import { IonButton, IonButtons, IonIcon, IonInput, IonItem, } from '@ionic/angular/standalone';
2
+ import { IonButton, IonButtons, IonIcon, IonInput, IonItem, } from '@ionic/angular';
3
3
  import * as i0 from "@angular/core";
4
4
  export class FilterItemComponent {
5
5
  constructor() {
6
- this.$filter = input.required(...(ngDevMode ? [{ debugName: "$filter" }] : []));
6
+ this.$filter = input.required(/* @ts-ignore */
7
+ ...(ngDevMode ? [{ debugName: "$filter" }] : /* istanbul ignore next */ []));
7
8
  this.changed = new EventEmitter();
8
9
  this.blured = new EventEmitter();
9
10
  }
@@ -23,10 +24,10 @@ export class FilterItemComponent {
23
24
  // console.log(`FilterItemComponent.emitChange(value=${value})`);
24
25
  this.changed.emit(value);
25
26
  }
26
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FilterItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
27
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: FilterItemComponent, isStandalone: true, selector: "sneat-filter-item", inputs: { $filter: { classPropertyName: "$filter", publicName: "$filter", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { changed: "changed", blured: "blured" }, ngImport: i0, template: "<ion-item class=\"with-buttons\" lines=\"none\">\n @if (!$filter()) {\n <ion-icon name=\"search-outline\" slot=\"start\" />\n }\n <ion-input\n [label]=\"$filter() ? 'Filter:' : ''\"\n placeholder=\"Filter\"\n [value]=\"$filter()\"\n (ionInput)=\"onFilterChanged($event)\"\n (ionBlur)=\"onBlured($event)\"\n />\n @if (!!$filter()) {\n <ion-buttons slot=\"end\">\n <ion-button color=\"medium\" (click)=\"clearFilter($event)\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n</ion-item>\n", dependencies: [{ kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
27
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: FilterItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
28
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: FilterItemComponent, isStandalone: true, selector: "sneat-filter-item", inputs: { $filter: { classPropertyName: "$filter", publicName: "$filter", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { changed: "changed", blured: "blured" }, ngImport: i0, template: "<ion-item class=\"with-buttons\" lines=\"none\">\n @if (!$filter()) {\n <ion-icon name=\"search-outline\" slot=\"start\" />\n }\n <ion-input\n [label]=\"$filter() ? 'Filter:' : ''\"\n placeholder=\"Filter\"\n [value]=\"$filter()\"\n (ionInput)=\"onFilterChanged($event)\"\n (ionBlur)=\"onBlured($event)\"\n />\n @if (!!$filter()) {\n <ion-buttons slot=\"end\">\n <ion-button color=\"medium\" (click)=\"clearFilter($event)\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n</ion-item>\n", dependencies: [{ kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"], outputs: ["ionFocus", "ionBlur"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
28
29
  }
29
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FilterItemComponent, decorators: [{
30
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: FilterItemComponent, decorators: [{
30
31
  type: Component,
31
32
  args: [{ selector: 'sneat-filter-item', imports: [IonItem, IonIcon, IonInput, IonButtons, IonButton], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-item class=\"with-buttons\" lines=\"none\">\n @if (!$filter()) {\n <ion-icon name=\"search-outline\" slot=\"start\" />\n }\n <ion-input\n [label]=\"$filter() ? 'Filter:' : ''\"\n placeholder=\"Filter\"\n [value]=\"$filter()\"\n (ionInput)=\"onFilterChanged($event)\"\n (ionBlur)=\"onBlured($event)\"\n />\n @if (!!$filter()) {\n <ion-buttons slot=\"end\">\n <ion-button color=\"medium\" (click)=\"clearFilter($event)\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n</ion-item>\n" }]
32
33
  }], propDecorators: { $filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "$filter", required: true }] }], changed: [{
@@ -1 +1 @@
1
- {"version":3,"file":"filter-item.component.js","sourceRoot":"","sources":["../../../../../../libs/components/src/lib/filter-item/filter-item.component.ts","../../../../../../libs/components/src/lib/filter-item/filter-item.component.html"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,YAAY,EACZ,KAAK,EACL,MAAM,GACP,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,SAAS,EACT,UAAU,EACV,OAAO,EACP,QAAQ,EACR,OAAO,GACR,MAAM,2BAA2B,CAAC;;AAQnC,MAAM,OAAO,mBAAmB;IANhC;QAOkB,YAAO,GAAG,KAAK,CAAC,QAAQ,kDAAU,CAAC;QAEhC,YAAO,GAAG,IAAI,YAAY,EAAU,CAAC;QACrC,WAAM,GAAG,IAAI,YAAY,EAAS,CAAC;KAqBvD;IAnBW,WAAW,CAAC,KAAY;QAChC,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IAES,eAAe,CAAC,KAAkB;QAC1C,+DAA+D;QAC/D,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAES,QAAQ,CAAC,KAAY;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAEO,WAAW,CAAC,KAAa;QAC/B,iEAAiE;QACjE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;8GAxBU,mBAAmB;kGAAnB,mBAAmB,yQCrBhC,mjBAmBA,4CDDY,OAAO,0NAAE,OAAO,2JAAE,QAAQ,8eAAE,UAAU,8EAAE,SAAS;;2FAGhD,mBAAmB;kBAN/B,SAAS;+BACE,mBAAmB,WAEpB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,mBAC3C,uBAAuB,CAAC,MAAM;;sBAK9C,MAAM;;sBACN,MAAM","sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n input,\n Output,\n} from '@angular/core';\nimport {\n IonButton,\n IonButtons,\n IonIcon,\n IonInput,\n IonItem,\n} from '@ionic/angular/standalone';\n\n@Component({\n selector: 'sneat-filter-item',\n templateUrl: './filter-item.component.html',\n imports: [IonItem, IonIcon, IonInput, IonButtons, IonButton],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FilterItemComponent {\n public readonly $filter = input.required<string>();\n\n @Output() readonly changed = new EventEmitter<string>();\n @Output() readonly blured = new EventEmitter<Event>();\n\n protected clearFilter(event: Event): void {\n event.stopPropagation();\n event.preventDefault();\n this.emitChanged('');\n }\n\n protected onFilterChanged(event: CustomEvent): void {\n // console.log(`FilterItemComponent.onFilterChanged()`, event);\n this.emitChanged(event.detail.value || '');\n }\n\n protected onBlured(event: Event): void {\n this.blured.emit(event);\n }\n\n private emitChanged(value: string): void {\n // console.log(`FilterItemComponent.emitChange(value=${value})`);\n this.changed.emit(value);\n }\n}\n","<ion-item class=\"with-buttons\" lines=\"none\">\n @if (!$filter()) {\n <ion-icon name=\"search-outline\" slot=\"start\" />\n }\n <ion-input\n [label]=\"$filter() ? 'Filter:' : ''\"\n placeholder=\"Filter\"\n [value]=\"$filter()\"\n (ionInput)=\"onFilterChanged($event)\"\n (ionBlur)=\"onBlured($event)\"\n />\n @if (!!$filter()) {\n <ion-buttons slot=\"end\">\n <ion-button color=\"medium\" (click)=\"clearFilter($event)\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n</ion-item>\n"]}
1
+ {"version":3,"file":"filter-item.component.js","sourceRoot":"","sources":["../../../../../../libs/components/src/lib/filter-item/filter-item.component.ts","../../../../../../libs/components/src/lib/filter-item/filter-item.component.html"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,YAAY,EACZ,KAAK,EACL,MAAM,GACP,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,SAAS,EACT,UAAU,EACV,OAAO,EACP,QAAQ,EACR,OAAO,GACR,MAAM,gBAAgB,CAAC;;AAQxB,MAAM,OAAO,mBAAmB;IANhC;QAOkB,YAAO,GAAG,KAAK,CAAC,QAAQ;oFAAU,CAAC;QAEhC,YAAO,GAAG,IAAI,YAAY,EAAU,CAAC;QACrC,WAAM,GAAG,IAAI,YAAY,EAAS,CAAC;KAqBvD;IAnBW,WAAW,CAAC,KAAY;QAChC,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IAES,eAAe,CAAC,KAAkB;QAC1C,+DAA+D;QAC/D,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAES,QAAQ,CAAC,KAAY;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAEO,WAAW,CAAC,KAAa;QAC/B,iEAAiE;QACjE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;8GAxBU,mBAAmB;kGAAnB,mBAAmB,yQCrBhC,mjBAmBA,4CDDY,OAAO,0NAAE,OAAO,2JAAE,QAAQ,8eAAE,UAAU,8EAAE,SAAS;;2FAGhD,mBAAmB;kBAN/B,SAAS;+BACE,mBAAmB,WAEpB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,mBAC3C,uBAAuB,CAAC,MAAM;;sBAK9C,MAAM;;sBACN,MAAM","sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n input,\n Output,\n} from '@angular/core';\nimport {\n IonButton,\n IonButtons,\n IonIcon,\n IonInput,\n IonItem,\n} from '@ionic/angular';\n\n@Component({\n selector: 'sneat-filter-item',\n templateUrl: './filter-item.component.html',\n imports: [IonItem, IonIcon, IonInput, IonButtons, IonButton],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FilterItemComponent {\n public readonly $filter = input.required<string>();\n\n @Output() readonly changed = new EventEmitter<string>();\n @Output() readonly blured = new EventEmitter<Event>();\n\n protected clearFilter(event: Event): void {\n event.stopPropagation();\n event.preventDefault();\n this.emitChanged('');\n }\n\n protected onFilterChanged(event: CustomEvent): void {\n // console.log(`FilterItemComponent.onFilterChanged()`, event);\n this.emitChanged(event.detail.value || '');\n }\n\n protected onBlured(event: Event): void {\n this.blured.emit(event);\n }\n\n private emitChanged(value: string): void {\n // console.log(`FilterItemComponent.emitChange(value=${value})`);\n this.changed.emit(value);\n }\n}\n","<ion-item class=\"with-buttons\" lines=\"none\">\n @if (!$filter()) {\n <ion-icon name=\"search-outline\" slot=\"start\" />\n }\n <ion-input\n [label]=\"$filter() ? 'Filter:' : ''\"\n placeholder=\"Filter\"\n [value]=\"$filter()\"\n (ionInput)=\"onFilterChanged($event)\"\n (ionBlur)=\"onBlured($event)\"\n />\n @if (!!$filter()) {\n <ion-buttons slot=\"end\">\n <ion-button color=\"medium\" (click)=\"clearFilter($event)\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n</ion-item>\n"]}
@@ -44,10 +44,10 @@ export class CountryFlagPipe extends CountryDataPipe {
44
44
  // Return country emoji from cache if available, otherwise return countryID
45
45
  return this.countriesCache?.[countryID]?.emoji || countryID;
46
46
  }
47
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CountryFlagPipe, deps: null, target: i0.ɵɵFactoryTarget.Pipe }); }
48
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: CountryFlagPipe, isStandalone: true, name: "countryFlag" }); }
47
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: CountryFlagPipe, deps: null, target: i0.ɵɵFactoryTarget.Pipe }); }
48
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: CountryFlagPipe, isStandalone: true, name: "countryFlag" }); }
49
49
  }
50
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CountryFlagPipe, decorators: [{
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: CountryFlagPipe, decorators: [{
51
51
  type: Pipe,
52
52
  args: [{ name: 'countryFlag' }]
53
53
  }] });
@@ -59,10 +59,10 @@ export class CountryTitle extends CountryDataPipe {
59
59
  // Return country title from cache if available, otherwise return countryID
60
60
  return this.countriesCache?.[countryID]?.title || countryID;
61
61
  }
62
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CountryTitle, deps: null, target: i0.ɵɵFactoryTarget.Pipe }); }
63
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: CountryTitle, isStandalone: true, name: "countryTitle" }); }
62
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: CountryTitle, deps: null, target: i0.ɵɵFactoryTarget.Pipe }); }
63
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: CountryTitle, isStandalone: true, name: "countryTitle" }); }
64
64
  }
65
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CountryTitle, decorators: [{
65
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: CountryTitle, decorators: [{
66
66
  type: Pipe,
67
67
  args: [{ name: 'countryTitle' }]
68
68
  }] });
@@ -4,10 +4,10 @@ export class Decimal64p2Pipe {
4
4
  constructor() {
5
5
  this.transform = (value) => (value ? value / 100 : 0);
6
6
  }
7
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: Decimal64p2Pipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
8
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: Decimal64p2Pipe, isStandalone: true, name: "decimal64p2" }); }
7
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: Decimal64p2Pipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
8
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: Decimal64p2Pipe, isStandalone: true, name: "decimal64p2" }); }
9
9
  }
10
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: Decimal64p2Pipe, decorators: [{
10
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: Decimal64p2Pipe, decorators: [{
11
11
  type: Pipe,
12
12
  args: [{ name: 'decimal64p2' }]
13
13
  }] });
@@ -37,10 +37,10 @@ export class Numeral2Pipe {
37
37
  return value;
38
38
  };
39
39
  }
40
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: Numeral2Pipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
41
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: Numeral2Pipe, isStandalone: true, name: "numeral" }); }
40
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: Numeral2Pipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
41
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: Numeral2Pipe, isStandalone: true, name: "numeral" }); }
42
42
  }
43
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: Numeral2Pipe, decorators: [{
43
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: Numeral2Pipe, decorators: [{
44
44
  type: Pipe,
45
45
  args: [{ name: 'numeral' }]
46
46
  }] });
@@ -16,10 +16,10 @@ export class GenderIconNamePipe {
16
16
  }
17
17
  return 'person-outline';
18
18
  }
19
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GenderIconNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
20
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: GenderIconNamePipe, isStandalone: true, name: "genderIconName" }); }
19
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: GenderIconNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
20
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: GenderIconNamePipe, isStandalone: true, name: "genderIconName" }); }
21
21
  }
22
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GenderIconNamePipe, decorators: [{
22
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: GenderIconNamePipe, decorators: [{
23
23
  type: Pipe,
24
24
  args: [{ name: 'genderIconName' }]
25
25
  }] });
@@ -33,10 +33,10 @@ export class GenderEmojiPipe {
33
33
  }
34
34
  return 'person-outline';
35
35
  }
36
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GenderEmojiPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
37
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: GenderEmojiPipe, isStandalone: true, name: "genderEmoji" }); }
36
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: GenderEmojiPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
37
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: GenderEmojiPipe, isStandalone: true, name: "genderEmoji" }); }
38
38
  }
39
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GenderEmojiPipe, decorators: [{
39
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: GenderEmojiPipe, decorators: [{
40
40
  type: Pipe,
41
41
  args: [{ name: 'genderEmoji' }]
42
42
  }] });
@@ -59,10 +59,10 @@ export class GenderColorPipe {
59
59
  constructor() {
60
60
  this.transform = genderColor;
61
61
  }
62
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GenderColorPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
63
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: GenderColorPipe, isStandalone: true, name: "genderColor" }); }
62
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: GenderColorPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
63
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: GenderColorPipe, isStandalone: true, name: "genderColor" }); }
64
64
  }
65
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GenderColorPipe, decorators: [{
65
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: GenderColorPipe, decorators: [{
66
66
  type: Pipe,
67
67
  args: [{ name: 'genderColor' }]
68
68
  }] });
@@ -31,10 +31,10 @@ export class LongMonthNamePipe {
31
31
  return '' + month;
32
32
  }
33
33
  }
34
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: LongMonthNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
35
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: LongMonthNamePipe, isStandalone: true, name: "longMonthName" }); }
34
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: LongMonthNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
35
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: LongMonthNamePipe, isStandalone: true, name: "longMonthName" }); }
36
36
  }
37
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: LongMonthNamePipe, decorators: [{
37
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: LongMonthNamePipe, decorators: [{
38
38
  type: Pipe,
39
39
  args: [{ name: 'longMonthName' }]
40
40
  }] });
@@ -21,10 +21,10 @@ export class ShortMonthNamePipe {
21
21
  }
22
22
  return '' + month;
23
23
  }
24
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ShortMonthNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
25
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: ShortMonthNamePipe, isStandalone: true, name: "shortMonthName" }); }
24
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ShortMonthNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
25
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: ShortMonthNamePipe, isStandalone: true, name: "shortMonthName" }); }
26
26
  }
27
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ShortMonthNamePipe, decorators: [{
27
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: ShortMonthNamePipe, decorators: [{
28
28
  type: Pipe,
29
29
  args: [{ name: 'shortMonthName' }]
30
30
  }] });
@@ -23,10 +23,10 @@ export class SpaceEmojiPipe {
23
23
  return undefined;
24
24
  }
25
25
  }
26
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SpaceEmojiPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
27
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: SpaceEmojiPipe, isStandalone: true, name: "spaceEmoji" }); }
26
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SpaceEmojiPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
27
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: SpaceEmojiPipe, isStandalone: true, name: "spaceEmoji" }); }
28
28
  }
29
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SpaceEmojiPipe, decorators: [{
29
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: SpaceEmojiPipe, decorators: [{
30
30
  type: Pipe,
31
31
  args: [{ name: 'spaceEmoji' }]
32
32
  }] });
@@ -1,6 +1,6 @@
1
1
  import { HttpClient, HttpHeaders } from '@angular/common/http';
2
- import { ChangeDetectionStrategy, Component, computed, effect, Input, signal, inject, } from '@angular/core';
3
- import { IonButton, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonIcon, IonLabel, } from '@ionic/angular/standalone';
2
+ import { ChangeDetectionStrategy, Component, computed, effect, signal, inject, input } from '@angular/core';
3
+ import { IonButton, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonIcon, IonLabel, } from '@ionic/angular';
4
4
  import { SneatUserService } from '@sneat/auth-core';
5
5
  import { ClassName, SneatBaseComponent } from '@sneat/ui';
6
6
  import { map, race, takeUntil } from 'rxjs';
@@ -23,17 +23,24 @@ export class UserCountryComponent extends SneatBaseComponent {
23
23
  this.httpClient = inject(HttpClient);
24
24
  this.userService = inject(SneatUserService);
25
25
  this.countriesLoader = inject(CountriesLoaderService);
26
- this.$ipCountryID = signal('', ...(ngDevMode ? [{ debugName: "$ipCountryID" }] : []));
27
- this.$ipCountry = signal(undefined, ...(ngDevMode ? [{ debugName: "$ipCountry" }] : []));
28
- this.$userCountryID = signal('', ...(ngDevMode ? [{ debugName: "$userCountryID" }] : []));
26
+ this.$ipCountryID = signal('', /* @ts-ignore */
27
+ ...(ngDevMode ? [{ debugName: "$ipCountryID" }] : /* istanbul ignore next */ []));
28
+ this.$ipCountry = signal(undefined, /* @ts-ignore */
29
+ ...(ngDevMode ? [{ debugName: "$ipCountry" }] : /* istanbul ignore next */ []));
30
+ this.$userCountryID = signal('', /* @ts-ignore */
31
+ ...(ngDevMode ? [{ debugName: "$userCountryID" }] : /* istanbul ignore next */ []));
29
32
  this.$userHasCountry = computed(() => {
30
33
  const userCountryID = this.$userCountryID();
31
34
  return !!userCountryID && userCountryID !== '--';
32
- }, ...(ngDevMode ? [{ debugName: "$userHasCountry" }] : []));
35
+ }, /* @ts-ignore */
36
+ ...(ngDevMode ? [{ debugName: "$userHasCountry" }] : /* istanbul ignore next */ []));
33
37
  this.isCountryDetectionStarted = false;
34
- this.$detectingCountry = signal(false, ...(ngDevMode ? [{ debugName: "$detectingCountry" }] : []));
35
- this.$saving = signal(false, ...(ngDevMode ? [{ debugName: "$saving" }] : []));
36
- this.doNotHide = false;
38
+ this.$detectingCountry = signal(false, /* @ts-ignore */
39
+ ...(ngDevMode ? [{ debugName: "$detectingCountry" }] : /* istanbul ignore next */ []));
40
+ this.$saving = signal(false, /* @ts-ignore */
41
+ ...(ngDevMode ? [{ debugName: "$saving" }] : /* istanbul ignore next */ []));
42
+ this.doNotHide = input(false, /* @ts-ignore */
43
+ ...(ngDevMode ? [{ debugName: "doNotHide" }] : /* istanbul ignore next */ []));
37
44
  this.trackUserRecord();
38
45
  // this.getIpCountry();
39
46
  effect(() => {
@@ -105,15 +112,15 @@ export class UserCountryComponent extends SneatBaseComponent {
105
112
  },
106
113
  });
107
114
  }
108
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: UserCountryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
109
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: UserCountryComponent, isStandalone: true, selector: "sneat-user-country", inputs: { doNotHide: "doNotHide" }, providers: [
115
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: UserCountryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
116
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: UserCountryComponent, isStandalone: true, selector: "sneat-user-country", inputs: { doNotHide: { classPropertyName: "doNotHide", publicName: "doNotHide", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
110
117
  {
111
118
  provide: ClassName,
112
119
  useValue: 'UserCountryComponent',
113
120
  },
114
- ], usesInheritance: true, ngImport: i0, template: "@let userCountryID = $userCountryID();\n@let userHasCountry = $userHasCountry();\n\n@if (doNotHide || ($ipCountry() && !userHasCountry)) {\n <ion-card>\n @if (userHasCountry || !$ipCountry()) {\n <ion-card-content>\n <sneat-country-input\n label=\"Country of residence\"\n [canReset]=\"false\"\n [countryID]=\"userCountryID || ''\"\n (countryIDChange)=\"onCountryOfResidenceChanged($event)\"\n />\n </ion-card-content>\n } @else {\n <ion-card-header>\n <ion-card-title>\n Is {{ $ipCountry()?.emoji }} {{ $ipCountry()?.title }} your country of\n residence?\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-button\n [disabled]=\"$saving()\"\n color=\"primary\"\n class=\"ion-padding-end\"\n (click)=\"setCountry($ipCountryID())\"\n >\n <ion-icon name=\"checkmark-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\"\n ><b\n >Yes, my primary residence is in {{ $ipCountry()?.title }}\n {{ $ipCountry()?.emoji }}</b\n ></ion-label\n >\n </ion-button>\n <ion-button color=\"light\" [disabled]=\"$saving()\">\n <ion-icon name=\"list-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\">Choose county</ion-label>\n </ion-button>\n </ion-card-content>\n }\n </ion-card>\n}\n", dependencies: [{ kind: "component", type: CountryInputComponent, selector: "sneat-country-input", inputs: ["mode", "canReset", "label", "countryID"], outputs: ["countryIDChange"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
121
+ ], usesInheritance: true, ngImport: i0, template: "@let userCountryID = $userCountryID();\n@let userHasCountry = $userHasCountry();\n\n@if (doNotHide() || ($ipCountry() && !userHasCountry)) {\n <ion-card>\n @if (userHasCountry || !$ipCountry()) {\n <ion-card-content>\n <sneat-country-input\n label=\"Country of residence\"\n [canReset]=\"false\"\n [countryID]=\"userCountryID || ''\"\n (countryIDChange)=\"onCountryOfResidenceChanged($event)\"\n />\n </ion-card-content>\n } @else {\n <ion-card-header>\n <ion-card-title>\n Is {{ $ipCountry()?.emoji }} {{ $ipCountry()?.title }} your country of\n residence?\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-button\n [disabled]=\"$saving()\"\n color=\"primary\"\n class=\"ion-padding-end\"\n (click)=\"setCountry($ipCountryID())\"\n >\n <ion-icon name=\"checkmark-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\"\n ><b\n >Yes, my primary residence is in {{ $ipCountry()?.title }}\n {{ $ipCountry()?.emoji }}</b\n ></ion-label\n >\n </ion-button>\n <ion-button color=\"light\" [disabled]=\"$saving()\">\n <ion-icon name=\"list-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\">Choose county</ion-label>\n </ion-button>\n </ion-card-content>\n }\n </ion-card>\n}\n", dependencies: [{ kind: "component", type: CountryInputComponent, selector: "sneat-country-input", inputs: ["mode", "canReset", "label", "countryID"], outputs: ["countryIDChange"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"], outputs: ["ionFocus", "ionBlur"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
115
122
  }
116
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: UserCountryComponent, decorators: [{
123
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: UserCountryComponent, decorators: [{
117
124
  type: Component,
118
125
  args: [{ imports: [
119
126
  CountryInputComponent,
@@ -129,8 +136,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
129
136
  provide: ClassName,
130
137
  useValue: 'UserCountryComponent',
131
138
  },
132
- ], changeDetection: ChangeDetectionStrategy.OnPush, selector: 'sneat-user-country', template: "@let userCountryID = $userCountryID();\n@let userHasCountry = $userHasCountry();\n\n@if (doNotHide || ($ipCountry() && !userHasCountry)) {\n <ion-card>\n @if (userHasCountry || !$ipCountry()) {\n <ion-card-content>\n <sneat-country-input\n label=\"Country of residence\"\n [canReset]=\"false\"\n [countryID]=\"userCountryID || ''\"\n (countryIDChange)=\"onCountryOfResidenceChanged($event)\"\n />\n </ion-card-content>\n } @else {\n <ion-card-header>\n <ion-card-title>\n Is {{ $ipCountry()?.emoji }} {{ $ipCountry()?.title }} your country of\n residence?\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-button\n [disabled]=\"$saving()\"\n color=\"primary\"\n class=\"ion-padding-end\"\n (click)=\"setCountry($ipCountryID())\"\n >\n <ion-icon name=\"checkmark-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\"\n ><b\n >Yes, my primary residence is in {{ $ipCountry()?.title }}\n {{ $ipCountry()?.emoji }}</b\n ></ion-label\n >\n </ion-button>\n <ion-button color=\"light\" [disabled]=\"$saving()\">\n <ion-icon name=\"list-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\">Choose county</ion-label>\n </ion-button>\n </ion-card-content>\n }\n </ion-card>\n}\n" }]
133
- }], ctorParameters: () => [], propDecorators: { doNotHide: [{
134
- type: Input
135
- }] } });
139
+ ], changeDetection: ChangeDetectionStrategy.OnPush, selector: 'sneat-user-country', template: "@let userCountryID = $userCountryID();\n@let userHasCountry = $userHasCountry();\n\n@if (doNotHide() || ($ipCountry() && !userHasCountry)) {\n <ion-card>\n @if (userHasCountry || !$ipCountry()) {\n <ion-card-content>\n <sneat-country-input\n label=\"Country of residence\"\n [canReset]=\"false\"\n [countryID]=\"userCountryID || ''\"\n (countryIDChange)=\"onCountryOfResidenceChanged($event)\"\n />\n </ion-card-content>\n } @else {\n <ion-card-header>\n <ion-card-title>\n Is {{ $ipCountry()?.emoji }} {{ $ipCountry()?.title }} your country of\n residence?\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-button\n [disabled]=\"$saving()\"\n color=\"primary\"\n class=\"ion-padding-end\"\n (click)=\"setCountry($ipCountryID())\"\n >\n <ion-icon name=\"checkmark-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\"\n ><b\n >Yes, my primary residence is in {{ $ipCountry()?.title }}\n {{ $ipCountry()?.emoji }}</b\n ></ion-label\n >\n </ion-button>\n <ion-button color=\"light\" [disabled]=\"$saving()\">\n <ion-icon name=\"list-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\">Choose county</ion-label>\n </ion-button>\n </ion-card-content>\n }\n </ion-card>\n}\n" }]
140
+ }], ctorParameters: () => [], propDecorators: { doNotHide: [{ type: i0.Input, args: [{ isSignal: true, alias: "doNotHide", required: false }] }] } });
136
141
  //# sourceMappingURL=user-country.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-country.component.js","sourceRoot":"","sources":["../../../../../../libs/components/src/lib/user-country/user-country.component.ts","../../../../../../libs/components/src/lib/user-country/user-country.component.html"],"names":[],"mappings":"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","sourcesContent":["import { HttpClient, HttpHeaders } from '@angular/common/http';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n Input,\n OnDestroy,\n signal,\n inject,\n} from '@angular/core';\nimport {\n IonButton,\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonIcon,\n IonLabel,\n} from '@ionic/angular/standalone';\nimport { SneatUserService } from '@sneat/auth-core';\nimport { ClassName, SneatBaseComponent } from '@sneat/ui';\nimport { map, race, takeUntil } from 'rxjs';\nimport { CountryInputComponent } from '../country-input';\nimport { ICountry, CountriesLoaderService } from '../country-selector';\n\nlet ipCountryCached: string | undefined; // TODO: Should have expiration?\n\n@Component({\n imports: [\n CountryInputComponent,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonButton,\n IonIcon,\n IonLabel,\n IonCard,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'UserCountryComponent',\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'sneat-user-country',\n templateUrl: './user-country.component.html',\n})\nexport class UserCountryComponent\n extends SneatBaseComponent\n implements OnDestroy\n{\n private readonly httpClient = inject(HttpClient);\n private readonly userService = inject(SneatUserService);\n private readonly countriesLoader = inject(CountriesLoaderService);\n\n protected readonly $ipCountryID = signal('');\n protected readonly $ipCountry = signal<ICountry | undefined>(undefined);\n\n protected readonly $userCountryID = signal<string>('');\n protected readonly $userHasCountry = computed(() => {\n const userCountryID = this.$userCountryID();\n return !!userCountryID && userCountryID !== '--';\n });\n\n protected isCountryDetectionStarted = false;\n protected readonly $detectingCountry = signal(false);\n protected readonly $saving = signal(false);\n\n @Input() public doNotHide = false;\n\n private trackUserRecord(): void {\n this.userService.userState\n .pipe(takeUntil(this.destroyed$))\n .subscribe((user) => {\n if (user.record) {\n this.$userCountryID.set(user?.record?.countryID || '--');\n }\n });\n }\n\n constructor() {\n super();\n this.trackUserRecord();\n // this.getIpCountry();\n effect(() => {\n const userCountryID = this.$userCountryID();\n if (\n userCountryID === '--' &&\n // It looks like using signal here can cause an infinite loop\n !this.isCountryDetectionStarted\n ) {\n this.getIpCountry();\n }\n });\n }\n\n protected onCountryOfResidenceChanged(countryID: string): void {\n this.setCountry(countryID);\n }\n\n private getIpCountry(): void {\n if (this.isCountryDetectionStarted) {\n return;\n }\n this.isCountryDetectionStarted = true;\n if (ipCountryCached) {\n this.$ipCountryID.set(ipCountryCached);\n this.countriesLoader.getCountryByID(ipCountryCached).then((country) => {\n this.$ipCountry.set(country);\n });\n return;\n }\n this.$detectingCountry.set(true);\n // console.log('UserCountryComponent: Detecting IP country...');\n race(\n this.httpClient\n .get<string>('https://ipapi.co/country', {\n headers: new HttpHeaders({\n Accept: 'text/plain',\n }),\n responseType: 'text' as 'json',\n })\n .pipe(\n map((country) => ({ source: 'https://ipapi.co/country', country })),\n ),\n ).subscribe({\n next: (response) => {\n // console.log('UserCountryComponent: Got IP country:', response);\n const ipCountryID = response.country;\n ipCountryCached = ipCountryID;\n this.$ipCountryID.set(ipCountryID);\n this.countriesLoader.getCountryByID(ipCountryID).then((country) => {\n this.$ipCountry.set(country);\n });\n this.$detectingCountry.set(false);\n },\n error: (err) => {\n this.$detectingCountry.set(false);\n // console.error('UserCountryComponent: Failed to get IP country', err);\n this.errorLogger.logError(\n err,\n 'UserCountryComponent: Failed to get IP country',\n {\n show: false,\n },\n );\n },\n });\n }\n\n protected setCountry(countryID?: string): void {\n if (!countryID) {\n return;\n }\n this.$saving.set(true);\n this.userService.setUserCountry(countryID).subscribe({\n next: () => {\n // console.log('UserCountryComponent: User country set to', countryID);\n this.$userCountryID.set(countryID);\n },\n error: (err) => {\n this.errorLogger.logError(\n 'UserCountryComponent: Failed to set user country',\n err,\n );\n this.$saving.set(false);\n },\n });\n }\n}\n","@let userCountryID = $userCountryID();\n@let userHasCountry = $userHasCountry();\n\n@if (doNotHide || ($ipCountry() && !userHasCountry)) {\n <ion-card>\n @if (userHasCountry || !$ipCountry()) {\n <ion-card-content>\n <sneat-country-input\n label=\"Country of residence\"\n [canReset]=\"false\"\n [countryID]=\"userCountryID || ''\"\n (countryIDChange)=\"onCountryOfResidenceChanged($event)\"\n />\n </ion-card-content>\n } @else {\n <ion-card-header>\n <ion-card-title>\n Is {{ $ipCountry()?.emoji }} {{ $ipCountry()?.title }} your country of\n residence?\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-button\n [disabled]=\"$saving()\"\n color=\"primary\"\n class=\"ion-padding-end\"\n (click)=\"setCountry($ipCountryID())\"\n >\n <ion-icon name=\"checkmark-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\"\n ><b\n >Yes, my primary residence is in {{ $ipCountry()?.title }}\n {{ $ipCountry()?.emoji }}</b\n ></ion-label\n >\n </ion-button>\n <ion-button color=\"light\" [disabled]=\"$saving()\">\n <ion-icon name=\"list-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\">Choose county</ion-label>\n </ion-button>\n </ion-card-content>\n }\n </ion-card>\n}\n"]}
1
+ {"version":3,"file":"user-country.component.js","sourceRoot":"","sources":["../../../../../../libs/components/src/lib/user-country/user-country.component.ts","../../../../../../libs/components/src/lib/user-country/user-country.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,QAAQ,EACR,MAAM,EAEN,MAAM,EACN,MAAM,EACN,KAAK,EACN,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,SAAS,EACT,OAAO,EACP,cAAc,EACd,aAAa,EACb,YAAY,EACZ,OAAO,EACP,QAAQ,GACT,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAY,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;;AAEvE,IAAI,eAAmC,CAAC,CAAC,gCAAgC;AAuBzE,MAAM,OAAO,oBACX,SAAQ,kBAAkB;IAsBlB,eAAe;QACrB,IAAI,CAAC,WAAW,CAAC,SAAS;aACvB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;aAChC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;YAClB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,IAAI,IAAI,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC,CAAC,CAAC;IACP,CAAC;IAED;QACE,KAAK,EAAE,CAAC;QA9BO,eAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QAChC,gBAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACvC,oBAAe,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAE/C,iBAAY,GAAG,MAAM,CAAC,EAAE;yFAAC,CAAC;QAC1B,eAAU,GAAG,MAAM,CAAuB,SAAS;uFAAC,CAAC;QAErD,mBAAc,GAAG,MAAM,CAAS,EAAE;2FAAC,CAAC;QACpC,oBAAe,GAAG,QAAQ,CAAC,GAAG,EAAE;YACjD,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5C,OAAO,CAAC,CAAC,aAAa,IAAI,aAAa,KAAK,IAAI,CAAC;QACnD,CAAC;4FAAC,CAAC;QAEO,8BAAyB,GAAG,KAAK,CAAC;QACzB,sBAAiB,GAAG,MAAM,CAAC,KAAK;8FAAC,CAAC;QAClC,YAAO,GAAG,MAAM,CAAC,KAAK;oFAAC,CAAC;QAE3B,cAAS,GAAG,KAAK,CAAC,KAAK;sFAAC,CAAC;QAcvC,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,uBAAuB;QACvB,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5C,IACE,aAAa,KAAK,IAAI;gBACtB,6DAA6D;gBAC7D,CAAC,IAAI,CAAC,yBAAyB,EAC/B,CAAC;gBACD,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAES,2BAA2B,CAAC,SAAiB;QACrD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IAEO,YAAY;QAClB,IAAI,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QACD,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAC;QACtC,IAAI,eAAe,EAAE,CAAC;YACpB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACvC,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBACpE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,gEAAgE;QAChE,IAAI,CACF,IAAI,CAAC,UAAU;aACZ,GAAG,CAAS,0BAA0B,EAAE;YACvC,OAAO,EAAE,IAAI,WAAW,CAAC;gBACvB,MAAM,EAAE,YAAY;aACrB,CAAC;YACF,YAAY,EAAE,MAAgB;SAC/B,CAAC;aACD,IAAI,CACH,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,0BAA0B,EAAE,OAAO,EAAE,CAAC,CAAC,CACpE,CACJ,CAAC,SAAS,CAAC;YACV,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;gBACjB,kEAAkE;gBAClE,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC;gBACrC,eAAe,GAAG,WAAW,CAAC;gBAC9B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBACnC,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;oBAChE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC/B,CAAC,CAAC,CAAC;gBACH,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;YACD,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;gBACb,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAClC,wEAAwE;gBACxE,IAAI,CAAC,WAAW,CAAC,QAAQ,CACvB,GAAG,EACH,gDAAgD,EAChD;oBACE,IAAI,EAAE,KAAK;iBACZ,CACF,CAAC;YACJ,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAES,UAAU,CAAC,SAAkB;QACrC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC;YACnD,IAAI,EAAE,GAAG,EAAE;gBACT,uEAAuE;gBACvE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACrC,CAAC;YACD,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE;gBACb,IAAI,CAAC,WAAW,CAAC,QAAQ,CACvB,kDAAkD,EAClD,GAAG,CACJ,CAAC;gBACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;SACF,CAAC,CAAC;IACL,CAAC;8GAzHU,oBAAoB;kGAApB,oBAAoB,iNAVpB;YACT;gBACE,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,sBAAsB;aACjC;SACF,iDC5CH,2+CA4CA,4CDdI,qBAAqB,kJACrB,cAAc,+EACd,aAAa,sGACb,YAAY,sFACZ,SAAS,sRACT,OAAO,2JACP,QAAQ,6FACR,OAAO;;2FAYE,oBAAoB;kBArBhC,SAAS;8BACC;wBACP,qBAAqB;wBACrB,cAAc;wBACd,aAAa;wBACb,YAAY;wBACZ,SAAS;wBACT,OAAO;wBACP,QAAQ;wBACR,OAAO;qBACR,aACU;wBACT;4BACE,OAAO,EAAE,SAAS;4BAClB,QAAQ,EAAE,sBAAsB;yBACjC;qBACF,mBACgB,uBAAuB,CAAC,MAAM,YACrC,oBAAoB","sourcesContent":["import { HttpClient, HttpHeaders } from '@angular/common/http';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n OnDestroy,\n signal,\n inject,\n input\n} from '@angular/core';\nimport {\n IonButton,\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonIcon,\n IonLabel,\n} from '@ionic/angular';\nimport { SneatUserService } from '@sneat/auth-core';\nimport { ClassName, SneatBaseComponent } from '@sneat/ui';\nimport { map, race, takeUntil } from 'rxjs';\nimport { CountryInputComponent } from '../country-input';\nimport { ICountry, CountriesLoaderService } from '../country-selector';\n\nlet ipCountryCached: string | undefined; // TODO: Should have expiration?\n\n@Component({\n imports: [\n CountryInputComponent,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonButton,\n IonIcon,\n IonLabel,\n IonCard,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'UserCountryComponent',\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'sneat-user-country',\n templateUrl: './user-country.component.html',\n})\nexport class UserCountryComponent\n extends SneatBaseComponent\n implements OnDestroy\n{\n private readonly httpClient = inject(HttpClient);\n private readonly userService = inject(SneatUserService);\n private readonly countriesLoader = inject(CountriesLoaderService);\n\n protected readonly $ipCountryID = signal('');\n protected readonly $ipCountry = signal<ICountry | undefined>(undefined);\n\n protected readonly $userCountryID = signal<string>('');\n protected readonly $userHasCountry = computed(() => {\n const userCountryID = this.$userCountryID();\n return !!userCountryID && userCountryID !== '--';\n });\n\n protected isCountryDetectionStarted = false;\n protected readonly $detectingCountry = signal(false);\n protected readonly $saving = signal(false);\n\n public readonly doNotHide = input(false);\n\n private trackUserRecord(): void {\n this.userService.userState\n .pipe(takeUntil(this.destroyed$))\n .subscribe((user) => {\n if (user.record) {\n this.$userCountryID.set(user?.record?.countryID || '--');\n }\n });\n }\n\n constructor() {\n super();\n this.trackUserRecord();\n // this.getIpCountry();\n effect(() => {\n const userCountryID = this.$userCountryID();\n if (\n userCountryID === '--' &&\n // It looks like using signal here can cause an infinite loop\n !this.isCountryDetectionStarted\n ) {\n this.getIpCountry();\n }\n });\n }\n\n protected onCountryOfResidenceChanged(countryID: string): void {\n this.setCountry(countryID);\n }\n\n private getIpCountry(): void {\n if (this.isCountryDetectionStarted) {\n return;\n }\n this.isCountryDetectionStarted = true;\n if (ipCountryCached) {\n this.$ipCountryID.set(ipCountryCached);\n this.countriesLoader.getCountryByID(ipCountryCached).then((country) => {\n this.$ipCountry.set(country);\n });\n return;\n }\n this.$detectingCountry.set(true);\n // console.log('UserCountryComponent: Detecting IP country...');\n race(\n this.httpClient\n .get<string>('https://ipapi.co/country', {\n headers: new HttpHeaders({\n Accept: 'text/plain',\n }),\n responseType: 'text' as 'json',\n })\n .pipe(\n map((country) => ({ source: 'https://ipapi.co/country', country })),\n ),\n ).subscribe({\n next: (response) => {\n // console.log('UserCountryComponent: Got IP country:', response);\n const ipCountryID = response.country;\n ipCountryCached = ipCountryID;\n this.$ipCountryID.set(ipCountryID);\n this.countriesLoader.getCountryByID(ipCountryID).then((country) => {\n this.$ipCountry.set(country);\n });\n this.$detectingCountry.set(false);\n },\n error: (err) => {\n this.$detectingCountry.set(false);\n // console.error('UserCountryComponent: Failed to get IP country', err);\n this.errorLogger.logError(\n err,\n 'UserCountryComponent: Failed to get IP country',\n {\n show: false,\n },\n );\n },\n });\n }\n\n protected setCountry(countryID?: string): void {\n if (!countryID) {\n return;\n }\n this.$saving.set(true);\n this.userService.setUserCountry(countryID).subscribe({\n next: () => {\n // console.log('UserCountryComponent: User country set to', countryID);\n this.$userCountryID.set(countryID);\n },\n error: (err) => {\n this.errorLogger.logError(\n 'UserCountryComponent: Failed to set user country',\n err,\n );\n this.$saving.set(false);\n },\n });\n }\n}\n","@let userCountryID = $userCountryID();\n@let userHasCountry = $userHasCountry();\n\n@if (doNotHide() || ($ipCountry() && !userHasCountry)) {\n <ion-card>\n @if (userHasCountry || !$ipCountry()) {\n <ion-card-content>\n <sneat-country-input\n label=\"Country of residence\"\n [canReset]=\"false\"\n [countryID]=\"userCountryID || ''\"\n (countryIDChange)=\"onCountryOfResidenceChanged($event)\"\n />\n </ion-card-content>\n } @else {\n <ion-card-header>\n <ion-card-title>\n Is {{ $ipCountry()?.emoji }} {{ $ipCountry()?.title }} your country of\n residence?\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-button\n [disabled]=\"$saving()\"\n color=\"primary\"\n class=\"ion-padding-end\"\n (click)=\"setCountry($ipCountryID())\"\n >\n <ion-icon name=\"checkmark-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\"\n ><b\n >Yes, my primary residence is in {{ $ipCountry()?.title }}\n {{ $ipCountry()?.emoji }}</b\n ></ion-label\n >\n </ion-button>\n <ion-button color=\"light\" [disabled]=\"$saving()\">\n <ion-icon name=\"list-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\">Choose county</ion-label>\n </ion-button>\n </ion-card-content>\n }\n </ion-card>\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter } from '@angular/core';
2
- import { IonInput } from '@ionic/angular/standalone';
2
+ import { IonInput } from '@ionic/angular';
3
3
  import { IRecord } from '@sneat/data';
4
4
  import { Observable } from 'rxjs';
5
5
  import * as i0 from "@angular/core";
@@ -14,8 +14,8 @@ interface IOptionallyTitled {
14
14
  export declare class SneatCardListComponent {
15
15
  private readonly errorLogger;
16
16
  title?: string;
17
- isFilterable?: boolean;
18
- isLoading?: boolean;
17
+ readonly isFilterable: import("@angular/core").InputSignal<boolean | undefined>;
18
+ readonly isLoading: import("@angular/core").InputSignal<boolean | undefined>;
19
19
  items?: {
20
20
  id?: unknown;
21
21
  title?: string;
@@ -25,7 +25,7 @@ export declare class SneatCardListComponent {
25
25
  tab?: string;
26
26
  tabs?: ICardTab[];
27
27
  noItemsText?: string;
28
- getRouterLink: (item: unknown) => string;
28
+ readonly getRouterLink: import("@angular/core").InputSignal<(item: unknown) => string>;
29
29
  readonly cardTitleClick: EventEmitter<void>;
30
30
  readonly itemClick: EventEmitter<unknown>;
31
31
  readonly tabChanged: EventEmitter<string>;
@@ -38,6 +38,6 @@ export declare class SneatCardListComponent {
38
38
  protected showAddForm(event: Event): void;
39
39
  protected tryCreate(): void;
40
40
  static ɵfac: i0.ɵɵFactoryDeclaration<SneatCardListComponent, never>;
41
- static ɵcmp: i0.ɵɵComponentDeclaration<SneatCardListComponent, "sneat-card-list", never, { "title": { "alias": "title"; "required": false; }; "isFilterable": { "alias": "isFilterable"; "required": false; }; "isLoading": { "alias": "isLoading"; "required": false; }; "items": { "alias": "items"; "required": false; }; "create": { "alias": "create"; "required": false; }; "itemIcon": { "alias": "itemIcon"; "required": false; }; "tab": { "alias": "tab"; "required": false; }; "tabs": { "alias": "tabs"; "required": false; }; "noItemsText": { "alias": "noItemsText"; "required": false; }; "getRouterLink": { "alias": "getRouterLink"; "required": false; }; }, { "cardTitleClick": "cardTitleClick"; "itemClick": "itemClick"; "tabChanged": "tabChanged"; }, never, never, true, never>;
41
+ static ɵcmp: i0.ɵɵComponentDeclaration<SneatCardListComponent, "sneat-card-list", never, { "title": { "alias": "title"; "required": false; }; "isFilterable": { "alias": "isFilterable"; "required": false; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; }; "create": { "alias": "create"; "required": false; }; "itemIcon": { "alias": "itemIcon"; "required": false; }; "tab": { "alias": "tab"; "required": false; }; "tabs": { "alias": "tabs"; "required": false; }; "noItemsText": { "alias": "noItemsText"; "required": false; }; "getRouterLink": { "alias": "getRouterLink"; "required": false; "isSignal": true; }; }, { "cardTitleClick": "cardTitleClick"; "itemClick": "itemClick"; "tabChanged": "tabChanged"; }, never, never, true, never>;
42
42
  }
43
43
  export {};
@@ -5,9 +5,9 @@ import * as i0 from "@angular/core";
5
5
  export type CountryInputMode = 'list' | 'dropdown';
6
6
  export declare class CountryInputComponent implements OnInit {
7
7
  private readonly countriesLoader;
8
- mode: CountryInputMode;
9
- canReset: boolean;
10
- label: string;
8
+ readonly mode: import("@angular/core").InputSignal<CountryInputMode>;
9
+ readonly canReset: import("@angular/core").InputSignal<boolean>;
10
+ readonly label: import("@angular/core").InputSignal<string>;
11
11
  countryID: string;
12
12
  countryIDChange: EventEmitter<string>;
13
13
  readonly countries: import("@angular/core").WritableSignal<readonly ICountry[]>;
@@ -20,5 +20,5 @@ export declare class CountryInputComponent implements OnInit {
20
20
  reset(event: Event): void;
21
21
  protected readonly filterCountryByCode: (item: ISelectItem, filter: string) => boolean;
22
22
  static ɵfac: i0.ɵɵFactoryDeclaration<CountryInputComponent, never>;
23
- static ɵcmp: i0.ɵɵComponentDeclaration<CountryInputComponent, "sneat-country-input", never, { "mode": { "alias": "mode"; "required": false; }; "canReset": { "alias": "canReset"; "required": false; }; "label": { "alias": "label"; "required": false; }; "countryID": { "alias": "countryID"; "required": false; }; }, { "countryIDChange": "countryIDChange"; }, never, never, true, never>;
23
+ static ɵcmp: i0.ɵɵComponentDeclaration<CountryInputComponent, "sneat-country-input", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "canReset": { "alias": "canReset"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "countryID": { "alias": "countryID"; "required": false; }; }, { "countryIDChange": "countryIDChange"; }, never, never, true, never>;
24
24
  }
@@ -9,11 +9,11 @@ export declare class CountrySelectorComponent implements OnInit, OnChanges {
9
9
  title?: string;
10
10
  }[];
11
11
  countryID?: string;
12
- defaultCountryID?: string;
13
- readonly: boolean;
14
- disabled: boolean;
15
- label: string;
16
- canBeUnknown: boolean;
12
+ readonly defaultCountryID: import("@angular/core").InputSignal<string | undefined>;
13
+ readonly readonly: import("@angular/core").InputSignal<boolean>;
14
+ readonly disabled: import("@angular/core").InputSignal<boolean>;
15
+ readonly label: import("@angular/core").InputSignal<string>;
16
+ readonly canBeUnknown: import("@angular/core").InputSignal<boolean>;
17
17
  readonly countryIDChange: EventEmitter<string>;
18
18
  protected readonly filter: import("@angular/core").WritableSignal<string>;
19
19
  protected readonly geoRegion: import("@angular/core").WritableSignal<GeoRegion | "All">;
@@ -30,5 +30,5 @@ export declare class CountrySelectorComponent implements OnInit, OnChanges {
30
30
  protected onRegionChanged(event: Event): void;
31
31
  protected readonly filterCountryByCode: (item: ISelectItem, filter: string) => boolean;
32
32
  static ɵfac: i0.ɵɵFactoryDeclaration<CountrySelectorComponent, never>;
33
- static ɵcmp: i0.ɵɵComponentDeclaration<CountrySelectorComponent, "sneat-country-selector", never, { "countryID": { "alias": "countryID"; "required": true; }; "defaultCountryID": { "alias": "defaultCountryID"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "label": { "alias": "label"; "required": false; }; "canBeUnknown": { "alias": "canBeUnknown"; "required": false; }; }, { "countryIDChange": "countryIDChange"; }, never, never, true, never>;
33
+ static ɵcmp: i0.ɵɵComponentDeclaration<CountrySelectorComponent, "sneat-country-selector", never, { "countryID": { "alias": "countryID"; "required": true; }; "defaultCountryID": { "alias": "defaultCountryID"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "canBeUnknown": { "alias": "canBeUnknown"; "required": false; "isSignal": true; }; }, { "countryIDChange": "countryIDChange"; }, never, never, true, never>;
34
34
  }
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter } from '@angular/core';
2
- import { PopoverController } from '@ionic/angular/standalone';
2
+ import { PopoverController } from '@ionic/angular';
3
3
  import * as i0 from "@angular/core";
4
4
  export declare class DateInputComponent {
5
5
  readonly $label: import("@angular/core").InputSignal<string>;
@@ -1,13 +1,13 @@
1
1
  import { SneatBaseComponent } from '@sneat/ui';
2
2
  import * as i0 from "@angular/core";
3
3
  export declare class DateModalComponent extends SneatBaseComponent {
4
- title?: string;
5
- max?: string;
4
+ readonly title: import("@angular/core").InputSignal<string | undefined>;
5
+ readonly max: import("@angular/core").InputSignal<string | undefined>;
6
6
  constructor();
7
7
  private popoverCtrl;
8
8
  protected readonly $date: import("@angular/core").WritableSignal<string | undefined>;
9
9
  protected onDateChanged(event: CustomEvent): void;
10
10
  protected dismiss(): void;
11
11
  static ɵfac: i0.ɵɵFactoryDeclaration<DateModalComponent, never>;
12
- static ɵcmp: i0.ɵɵComponentDeclaration<DateModalComponent, "sneat-contact-dob-modal", never, { "title": { "alias": "title"; "required": false; }; "max": { "alias": "max"; "required": false; }; }, {}, never, never, true, never>;
12
+ static ɵcmp: i0.ɵɵComponentDeclaration<DateModalComponent, "sneat-contact-dob-modal", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
13
13
  }
@@ -1,8 +1,8 @@
1
1
  import * as i0 from "@angular/core";
2
2
  export declare class DialogHeaderComponent {
3
3
  private readonly modalController;
4
- dialogTitle: string;
4
+ readonly dialogTitle: import("@angular/core").InputSignal<string>;
5
5
  close(event: Event): void;
6
6
  static ɵfac: i0.ɵɵFactoryDeclaration<DialogHeaderComponent, never>;
7
- static ɵcmp: i0.ɵɵComponentDeclaration<DialogHeaderComponent, "sneat-dialog-header", never, { "dialogTitle": { "alias": "dialogTitle"; "required": false; }; }, {}, never, never, true, never>;
7
+ static ɵcmp: i0.ɵɵComponentDeclaration<DialogHeaderComponent, "sneat-dialog-header", never, { "dialogTitle": { "alias": "dialogTitle"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
8
8
  }
@@ -13,12 +13,12 @@ export declare class UserCountryComponent extends SneatBaseComponent implements
13
13
  protected isCountryDetectionStarted: boolean;
14
14
  protected readonly $detectingCountry: import("@angular/core").WritableSignal<boolean>;
15
15
  protected readonly $saving: import("@angular/core").WritableSignal<boolean>;
16
- doNotHide: boolean;
16
+ readonly doNotHide: import("@angular/core").InputSignal<boolean>;
17
17
  private trackUserRecord;
18
18
  constructor();
19
19
  protected onCountryOfResidenceChanged(countryID: string): void;
20
20
  private getIpCountry;
21
21
  protected setCountry(countryID?: string): void;
22
22
  static ɵfac: i0.ɵɵFactoryDeclaration<UserCountryComponent, never>;
23
- static ɵcmp: i0.ɵɵComponentDeclaration<UserCountryComponent, "sneat-user-country", never, { "doNotHide": { "alias": "doNotHide"; "required": false; }; }, {}, never, never, true, never>;
23
+ static ɵcmp: i0.ɵɵComponentDeclaration<UserCountryComponent, "sneat-user-country", never, { "doNotHide": { "alias": "doNotHide"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
24
24
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@sneat/components",
3
- "version": "0.25.0",
3
+ "version": "0.26.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
7
  "peerDependencies": {
8
- "@angular/common": ">=21.0.0",
9
- "@angular/core": ">=21.0.0",
10
- "@ionic/angular": ">=8"
8
+ "@angular/common": ">=22.0.0 <23.0.0",
9
+ "@angular/core": ">=22.0.0 <23.0.0",
10
+ "@ionic/angular": ">=9.0.0 <10.0.0"
11
11
  },
12
12
  "dependencies": {
13
13
  "tslib": "2.8.1"
@@ -23,5 +23,6 @@
23
23
  "default": "./esm2022/sneat-components.js"
24
24
  }
25
25
  },
26
- "sideEffects": false
26
+ "sideEffects": false,
27
+ "type": "module"
27
28
  }
@@ -12,20 +12,20 @@
12
12
  */
13
13
 
14
14
  ///* Core CSS required for Ionic components to work properly */
15
- //@import '~@ionic/angular/css/core.css';
15
+ //@import '@ionic/angular/css/core.css';
16
16
  //
17
17
  ///* Basic CSS for apps built with Ionic */
18
- //@import '~@ionic/angular/css/normalize.css';
19
- //@import '~@ionic/angular/css/structure.css';
20
- //@import '~@ionic/angular/css/typography.css';
21
- //@import '~@ionic/angular/css/display.css';
18
+ //@import '@ionic/angular/css/normalize.css';
19
+ //@import '@ionic/angular/css/structure.css';
20
+ //@import '@ionic/angular/css/typography.css';
21
+ //@import '@ionic/angular/css/display.css';
22
22
  //
23
23
  ///* Optional CSS utils that can be commented out */
24
- //@import '~@ionic/angular/css/padding.css';
25
- //@import '~@ionic/angular/css/float-elements.css';
26
- //@import '~@ionic/angular/css/text-alignment.css';
27
- //@import '~@ionic/angular/css/text-transformation.css';
28
- //@import '~@ionic/angular/css/flex-utils.css';
24
+ //@import '@ionic/angular/css/padding.css';
25
+ //@import '@ionic/angular/css/float-elements.css';
26
+ //@import '@ionic/angular/css/text-alignment.css';
27
+ //@import '@ionic/angular/css/text-transformation.css';
28
+ //@import '@ionic/angular/css/flex-utils.css';
29
29
 
30
30
  @include meta.load-css('sneat-grid-layout');
31
31
  @include meta.load-css('theme/variables.scss');