@carefirst/library 1.3.8 → 1.3.10

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 (126) hide show
  1. package/.eslintrc.json +31 -0
  2. package/ng-package.json +8 -0
  3. package/package.json +11 -14
  4. package/public/styles/colors.scss +2 -2
  5. package/public/styles/font.scss +2 -2
  6. package/src/lib/components/alert/alert.component.html +0 -0
  7. package/src/lib/components/alert/alert.component.scss +63 -0
  8. package/src/lib/components/alert/alert.component.spec.ts +23 -0
  9. package/src/lib/components/alert/alert.component.ts +73 -0
  10. package/src/lib/components/badge/badge.component.html +5 -0
  11. package/src/lib/components/badge/badge.component.scss +96 -0
  12. package/src/lib/components/badge/badge.component.spec.ts +23 -0
  13. package/src/lib/components/badge/badge.component.ts +61 -0
  14. package/src/lib/components/button/button.component.html +20 -0
  15. package/src/lib/components/button/button.component.scss +153 -0
  16. package/src/lib/components/button/button.component.spec.ts +21 -0
  17. package/src/lib/components/button/button.component.ts +94 -0
  18. package/src/lib/components/calendar/calendar.component.html +9 -0
  19. package/src/lib/components/calendar/calendar.component.scss +34 -0
  20. package/src/lib/components/calendar/calendar.component.spec.ts +23 -0
  21. package/src/lib/components/calendar/calendar.component.ts +53 -0
  22. package/src/lib/components/chat-bubble/chat-bubble.component.html +9 -0
  23. package/src/lib/components/chat-bubble/chat-bubble.component.scss +31 -0
  24. package/src/lib/components/chat-bubble/chat-bubble.component.spec.ts +23 -0
  25. package/src/lib/components/chat-bubble/chat-bubble.component.ts +43 -0
  26. package/src/lib/components/form-input/form-input.component.html +37 -0
  27. package/src/lib/components/form-input/form-input.component.scss +23 -0
  28. package/src/lib/components/form-input/form-input.component.spec.ts +23 -0
  29. package/src/lib/components/form-input/form-input.component.ts +95 -0
  30. package/src/lib/components/form-input-select/form-input-select.component.html +27 -0
  31. package/src/lib/components/form-input-select/form-input-select.component.scss +40 -0
  32. package/src/lib/components/form-input-select/form-input-select.component.spec.ts +23 -0
  33. package/src/lib/components/form-input-select/form-input-select.component.ts +61 -0
  34. package/src/lib/components/form-input-text-area/form-input-text-area.component.html +29 -0
  35. package/src/lib/components/form-input-text-area/form-input-text-area.component.scss +19 -0
  36. package/src/lib/components/form-input-text-area/form-input-text-area.component.spec.ts +23 -0
  37. package/src/lib/components/form-input-text-area/form-input-text-area.component.ts +76 -0
  38. package/src/lib/components/form-validation/form-validation.component.html +8 -0
  39. package/src/lib/components/form-validation/form-validation.component.scss +8 -0
  40. package/src/lib/components/form-validation/form-validation.component.spec.ts +23 -0
  41. package/src/lib/components/form-validation/form-validation.component.ts +34 -0
  42. package/src/lib/components/icon/icon.component.html +529 -0
  43. package/src/lib/components/icon/icon.component.scss +61 -0
  44. package/src/lib/components/icon/icon.component.spec.ts +21 -0
  45. package/src/lib/components/icon/icon.component.ts +40 -0
  46. package/src/lib/components/logo/logo.component.html +10 -0
  47. package/src/lib/components/logo/logo.component.scss +5 -0
  48. package/src/lib/components/logo/logo.component.spec.ts +23 -0
  49. package/src/lib/components/logo/logo.component.ts +21 -0
  50. package/src/lib/components/notification/notification.component.html +39 -0
  51. package/src/lib/components/notification/notification.component.scss +20 -0
  52. package/src/lib/components/notification/notification.component.spec.ts +21 -0
  53. package/src/lib/components/notification/notification.component.ts +23 -0
  54. package/src/lib/components/page/page.component.html +5 -0
  55. package/src/lib/components/page/page.component.scss +35 -0
  56. package/src/lib/components/page/page.component.spec.ts +21 -0
  57. package/src/lib/components/page/page.component.ts +42 -0
  58. package/src/lib/components/spacer/spacer.component.html +4 -0
  59. package/src/lib/components/spacer/spacer.component.scss +27 -0
  60. package/src/lib/components/spacer/spacer.component.spec.ts +21 -0
  61. package/src/lib/components/spacer/spacer.component.ts +43 -0
  62. package/src/lib/components/spinner/spinner.component.html +1 -0
  63. package/src/lib/components/spinner/spinner.component.scss +14 -0
  64. package/src/lib/components/spinner/spinner.component.spec.ts +23 -0
  65. package/src/lib/components/spinner/spinner.component.ts +33 -0
  66. package/src/lib/directives/button-loader.directive.spec.ts +8 -0
  67. package/src/lib/directives/button-loader.directive.ts +77 -0
  68. package/src/lib/interfaces/alert.interface.ts +20 -0
  69. package/src/lib/interfaces/icon.interface.ts +62 -0
  70. package/src/lib/interfaces/input.interface.ts +8 -0
  71. package/src/lib/interfaces/notification.interface.ts +15 -0
  72. package/src/lib/interfaces/spacer.interface.ts +6 -0
  73. package/src/lib/library.module.ts +66 -0
  74. package/src/lib/utils/attribute.util.ts +66 -0
  75. package/src/lib/utils/form-validators-utility.ts +186 -0
  76. package/{public-api.d.ts → src/public-api.ts} +21 -0
  77. package/tsconfig.lib.json +12 -0
  78. package/tsconfig.lib.prod.json +10 -0
  79. package/tsconfig.spec.json +14 -0
  80. package/esm2022/carefirst-library.mjs +0 -2
  81. package/esm2022/lib/components/alert/alert.component.mjs +0 -56
  82. package/esm2022/lib/components/button/button.component.mjs +0 -87
  83. package/esm2022/lib/components/calendar/calendar.component.mjs +0 -39
  84. package/esm2022/lib/components/form-input/form-input.component.mjs +0 -87
  85. package/esm2022/lib/components/form-input-select/form-input-select.component.mjs +0 -46
  86. package/esm2022/lib/components/form-input-text-area/form-input-text-area.component.mjs +0 -61
  87. package/esm2022/lib/components/form-validation/form-validation.component.mjs +0 -20
  88. package/esm2022/lib/components/icon/icon.component.mjs +0 -29
  89. package/esm2022/lib/components/logo/logo.component.mjs +0 -18
  90. package/esm2022/lib/components/notification/notification.component.mjs +0 -22
  91. package/esm2022/lib/components/page/page.component.mjs +0 -31
  92. package/esm2022/lib/components/spacer/spacer.component.mjs +0 -30
  93. package/esm2022/lib/directives/button-loader.directive.mjs +0 -41
  94. package/esm2022/lib/interfaces/alert.interface.mjs +0 -2
  95. package/esm2022/lib/interfaces/icon.interface.mjs +0 -52
  96. package/esm2022/lib/interfaces/input.interface.mjs +0 -2
  97. package/esm2022/lib/interfaces/notification.interface.mjs +0 -2
  98. package/esm2022/lib/interfaces/spacer.interface.mjs +0 -2
  99. package/esm2022/lib/library.module.mjs +0 -85
  100. package/esm2022/lib/utils/attribute.util.mjs +0 -34
  101. package/esm2022/lib/utils/form-validators-utility.mjs +0 -113
  102. package/esm2022/public-api.mjs +0 -21
  103. package/fesm2022/carefirst-library.mjs +0 -799
  104. package/fesm2022/carefirst-library.mjs.map +0 -1
  105. package/index.d.ts +0 -2
  106. package/lib/components/alert/alert.component.d.ts +0 -14
  107. package/lib/components/button/button.component.d.ts +0 -30
  108. package/lib/components/calendar/calendar.component.d.ts +0 -15
  109. package/lib/components/form-input/form-input.component.d.ts +0 -37
  110. package/lib/components/form-input-select/form-input-select.component.d.ts +0 -21
  111. package/lib/components/form-input-text-area/form-input-text-area.component.d.ts +0 -27
  112. package/lib/components/form-validation/form-validation.component.d.ts +0 -9
  113. package/lib/components/icon/icon.component.d.ts +0 -13
  114. package/lib/components/logo/logo.component.d.ts +0 -7
  115. package/lib/components/notification/notification.component.d.ts +0 -9
  116. package/lib/components/page/page.component.d.ts +0 -13
  117. package/lib/components/spacer/spacer.component.d.ts +0 -14
  118. package/lib/directives/button-loader.directive.d.ts +0 -12
  119. package/lib/interfaces/alert.interface.d.ts +0 -11
  120. package/lib/interfaces/icon.interface.d.ts +0 -4
  121. package/lib/interfaces/input.interface.d.ts +0 -4
  122. package/lib/interfaces/notification.interface.d.ts +0 -11
  123. package/lib/interfaces/spacer.interface.d.ts +0 -3
  124. package/lib/library.module.d.ts +0 -22
  125. package/lib/utils/attribute.util.d.ts +0 -4
  126. package/lib/utils/form-validators-utility.d.ts +0 -8
@@ -0,0 +1,94 @@
1
+ /**
2
+ * CareFirst Library - Button
3
+ *
4
+ * @file button.component
5
+ * @description Contains all the logic for generating a CareFirst Button
6
+ * @author Jacques Coetzee
7
+ * @since 2023 - 11 - 07
8
+ * @usage <cf-btn type="'primary' | 'secondary' | 'tertiary'" fontSize="'small' | 'large'" %customColor="var() | hex"% %disabled% %alert% %action% %snug%>TEXT</cf-btn>
9
+ */
10
+
11
+ import { Component, Input, type SimpleChanges, type OnChanges, HostBinding } from '@angular/core';
12
+ import { checkTruthAttribute, validateStringValue } from '../../utils/attribute.util';
13
+ import { iconsC, type IconsT } from '../../interfaces/icon.interface';
14
+
15
+ @Component({
16
+ selector: 'cf-btn',
17
+ templateUrl: './button.component.html',
18
+ styleUrls: ['./button.component.scss'],
19
+ })
20
+ export class ButtonComponent implements OnChanges {
21
+ @Input() type: 'primary' | 'secondary' | 'tertiary' = 'primary';
22
+ @Input() disabled?: boolean | string | undefined;
23
+ @Input() alert?: boolean | string | undefined;
24
+ @Input() action?: boolean | string | undefined;
25
+ @Input() snug?: boolean | string | undefined;
26
+ @Input() fontSize?: 'small' | 'large';
27
+ @Input() iconStart?: IconsT | undefined;
28
+ @Input() iconEnd?: IconsT | undefined;
29
+ @Input() loading?: boolean | string | undefined;
30
+ @Input() customColor?: string | undefined;
31
+
32
+ @HostBinding('style.pointer-events') get parentEvents(): string {
33
+ if (this.disabled) {
34
+ return 'none';
35
+ }
36
+ return 'auto';
37
+ }
38
+
39
+ //--- Local variables
40
+ inputType: typeof this.type = 'primary';
41
+ inputFontSize: typeof this.fontSize | undefined = undefined;
42
+ inputDisabled = false;
43
+ inputAlert = false;
44
+ inputAction = false;
45
+ inputSnug = false;
46
+ inputIconStart: typeof this.iconStart | undefined = undefined;
47
+ inputIconEnd: typeof this.iconEnd | undefined = undefined;
48
+ inputLoading = false;
49
+ inputCustomColor = '';
50
+
51
+ /**----------------------------------------------------------------
52
+ * @name ngOnChanges
53
+ * @description Update various values on input changes
54
+ * @returns {void}
55
+ */
56
+ ngOnChanges(changes: SimpleChanges): void {
57
+ //--- Type
58
+ this.inputType =
59
+ validateStringValue<'primary' | 'secondary' | 'tertiary'>(changes, 'type', ['primary', 'secondary', 'tertiary'], this.inputType) || 'primary';
60
+ //--- Font Size
61
+ this.inputFontSize = validateStringValue<'small' | 'large'>(changes, 'fontSize', ['small', 'large'], this.inputFontSize);
62
+ //--- Disabled
63
+ this.inputDisabled = checkTruthAttribute(changes, 'disabled', this.inputDisabled);
64
+ //--- Alert
65
+ this.inputAlert = checkTruthAttribute(changes, 'alert', this.inputAlert);
66
+ //--- Action
67
+ this.inputAction = checkTruthAttribute(changes, 'action', this.inputAction);
68
+ //--- Snug
69
+ this.inputSnug = checkTruthAttribute(changes, 'snug', this.inputSnug);
70
+ //--- Icon Start
71
+ this.inputIconStart = validateStringValue<IconsT>(changes, 'iconStart', iconsC.slice(), this.inputIconStart);
72
+ //--- Icon Start
73
+ this.inputIconEnd = validateStringValue<IconsT>(changes, 'iconEnd', iconsC.slice(), this.inputIconEnd);
74
+ //--- Loading
75
+ this.inputLoading = checkTruthAttribute(changes, 'loading', this.inputLoading);
76
+ //--- Custom color
77
+ if (changes['customColor']?.currentValue) this.inputCustomColor = this.checkCustomColor(changes['customColor'].currentValue);
78
+ }
79
+
80
+ /**----------------------------------------------------------------
81
+ * @name checkCustomColor
82
+ * @description Check if the custom color is valid
83
+ * @param {string} color
84
+ * @returns {string}
85
+ */
86
+ checkCustomColor(color: string): string {
87
+ //--- Check for a css variable
88
+ if (color.startsWith('var')) return color;
89
+ //--- Check hex
90
+ if (color.startsWith('#') && (color.length === 4 || color.length === 7) && color.split('').every((char) => char.match(/[#0-9a-fA-F]+/)))
91
+ return color;
92
+ return '';
93
+ }
94
+ }
@@ -0,0 +1,9 @@
1
+ <ion-datetime
2
+ [class]="inputColor"
3
+ mode="ios"
4
+ firstDayOfWeek="1"
5
+ [min]="min"
6
+ [max]="max"
7
+ [presentation]="inputTime ? 'date-time' : 'date'"
8
+ (ionChange)="setValue($event.detail.value)">
9
+ </ion-datetime>
@@ -0,0 +1,34 @@
1
+ ion-datetime {
2
+ --background: var(--cf-app-background-light);
3
+ color: var(--cf-app-text-color-default);
4
+ }
5
+
6
+ ion-datetime::part(calendar-day) {
7
+ font-size: 1.6rem;
8
+ }
9
+
10
+ ion-datetime::part(month-year-button) {
11
+ font-size: 1.8rem;
12
+ font-weight: 900;
13
+ color: var(--cf-app-text-color-default);
14
+ }
15
+
16
+ ion-datetime.accent::part(today) {
17
+ border: 1px solid var(--cf-app-color-accent);
18
+ color: var(--cf-app-color-accent);
19
+ }
20
+
21
+ ion-datetime.accent::part(active) {
22
+ background-color: var(--cf-app-color-accent);
23
+ color: var(--cf-app-text-color-light);
24
+ }
25
+
26
+ ion-datetime.success::part(today) {
27
+ border: 1px solid var(--cf-app-color-primary);
28
+ color: var(--cf-app-text-color-default);
29
+ }
30
+
31
+ ion-datetime.success::part(active) {
32
+ background-color: var(--cf-app-system-color-success);
33
+ color: var(--cf-app-text-color-light);
34
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { CalendarComponent } from './calendar.component';
4
+
5
+ describe('CalendarComponent', () => {
6
+ let component: CalendarComponent;
7
+ let fixture: ComponentFixture<CalendarComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [CalendarComponent]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(CalendarComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,53 @@
1
+ /**
2
+ * CareFirst Library Calendar
3
+ *
4
+ * @file calendar.component
5
+ * @description Contains all the logic for generating a CareFirst Calendar
6
+ * @author Arno Jansen van Vuuren
7
+ * @since 2023 - 12 - 01
8
+ * @usage <cf-calendar %displayTime% %color%="success | accent" %min% %max%></cf-calendar>
9
+ */
10
+
11
+ import { Component, EventEmitter, Input, Output, type OnChanges, type SimpleChanges } from '@angular/core';
12
+ import dayjs from 'dayjs';
13
+ //--- Utils
14
+ import { checkTruthAttribute, validateStringValue } from '../../utils/attribute.util';
15
+
16
+ @Component({
17
+ selector: 'cf-calendar',
18
+ templateUrl: './calendar.component.html',
19
+ styleUrl: './calendar.component.scss',
20
+ })
21
+ export class CalendarComponent implements OnChanges {
22
+ @Input() displayTime?: boolean | string | undefined;
23
+ @Input() color?: 'success' | 'accent';
24
+ @Input() min?: string | undefined = undefined;
25
+ @Input() max?: string | undefined = undefined;
26
+ @Output() value = new EventEmitter<string>();
27
+
28
+ //--- Local variables
29
+ inputTime = false;
30
+ inputColor: typeof this.color = 'accent';
31
+
32
+ /**----------------------------------------------------------------
33
+ * @name ngOnChanges
34
+ * @description Update various values on component input changes
35
+ * @returns {void}
36
+ */
37
+ ngOnChanges(changes: SimpleChanges): void {
38
+ //--- Display Time
39
+ this.inputTime = checkTruthAttribute(changes, 'displayTime', this.inputTime);
40
+ //--- Color
41
+ this.inputColor = validateStringValue<'success' | 'accent'>(changes, 'color', ['success', 'accent'], this.inputColor) || 'accent';
42
+ }
43
+
44
+ /**----------------------------------------------------------------
45
+ * @name setValue
46
+ * @description Emit the selected date value
47
+ * @param {string | string[] | null | undefined} value
48
+ * @returns {void}
49
+ */
50
+ setValue(value: string | string[] | null | undefined): void {
51
+ if (typeof value === 'string') this.value.emit(dayjs(value).format('YYYY-MM-DD' + (this.inputTime ? ' HH:mm' : '')));
52
+ }
53
+ }
@@ -0,0 +1,9 @@
1
+ <div id="container" [ngClass]="inputType">
2
+ <div id="message">
3
+ <p class="body-extra-small">{{ inputDate }}</p>
4
+ <cf-spacer default="4"></cf-spacer>
5
+ <div id="bubble">
6
+ <p class="body-extra-small">{{ inputMessage }}</p>
7
+ </div>
8
+ </div>
9
+ </div>
@@ -0,0 +1,31 @@
1
+ #container {
2
+ display: flex;
3
+
4
+ #message {
5
+ p {
6
+ color: var(--cf-app-text-color-default);
7
+ }
8
+ #bubble {
9
+ background: var(--message-background-color);
10
+ border-radius: var(--border-radius);
11
+ padding: 12px 16px;
12
+ p {
13
+ color: var(--cf-app-text-color-light);
14
+ }
15
+ }
16
+ }
17
+ }
18
+
19
+ #container.outgoing {
20
+ justify-content: end;
21
+ text-align: end;
22
+ --border-radius: 16px 4px 16px 16px;
23
+ --message-background-color: var(--cf-app-color-primary);
24
+ }
25
+
26
+ #container.incoming {
27
+ justify-content: start;
28
+ text-align: start;
29
+ --border-radius: 4px 16px 16px 16px;
30
+ --message-background-color: var(--cf-app-color-secondary);
31
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ChatBubbleComponent } from './chat-bubble.component';
4
+
5
+ describe('ChatBubbleComponent', () => {
6
+ let component: ChatBubbleComponent;
7
+ let fixture: ComponentFixture<ChatBubbleComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [ChatBubbleComponent]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(ChatBubbleComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,43 @@
1
+ /**
2
+ * CareFirst Chat Bubble
3
+ *
4
+ * @file chat-bubble.component
5
+ * @description Contains all the logic for generating a CareFirst Chat Bubble
6
+ * @author Jacques Coetzee
7
+ * @since 2024 - 02 - 22
8
+ * @usage <cf-chat-bubble type="outgoing | incoming" date="string" message="string"></cf-chat-bubble>
9
+ */
10
+
11
+ import { Component, Input, type OnChanges, type SimpleChanges } from '@angular/core';
12
+ //--- Utils
13
+ import { validateStringValue } from '../../utils/attribute.util';
14
+
15
+ @Component({
16
+ selector: 'cf-chat-bubble',
17
+ templateUrl: './chat-bubble.component.html',
18
+ styleUrl: './chat-bubble.component.scss',
19
+ })
20
+ export class ChatBubbleComponent implements OnChanges {
21
+ @Input() type: 'outgoing' | 'incoming' = 'outgoing';
22
+ @Input() date: string = '';
23
+ @Input() message: string = '';
24
+
25
+ //--- Local variables
26
+ inputType: typeof this.type = 'incoming';
27
+ inputDate: typeof this.date = '';
28
+ inputMessage: typeof this.message = '';
29
+
30
+ /**----------------------------------------------------------------
31
+ * @name ngOnChanges
32
+ * @description Update various values on input changes
33
+ * @returns {void}
34
+ */
35
+ ngOnChanges(changes: SimpleChanges): void {
36
+ //--- Type
37
+ this.inputType = validateStringValue<typeof this.type>(changes, 'type', ['incoming', 'outgoing'], this.inputType) || 'outgoing';
38
+ //--- Date
39
+ this.inputDate = changes['date']?.currentValue || '';
40
+ //--- Message
41
+ this.inputMessage = changes['message']?.currentValue || '';
42
+ }
43
+ }
@@ -0,0 +1,37 @@
1
+ <!-- ngModel -->
2
+ <ion-input
3
+ *ngIf="!control"
4
+ [ngClass]="{ 'text-center': inputTextCenter, 'grey-background': inputGreyBackground }"
5
+ [label]="label"
6
+ [labelPlacement]="inputLabelPlacement"
7
+ [placeholder]="placeholder"
8
+ fill="outline"
9
+ [clearInput]="!inputClear"
10
+ [autocapitalize]="autoCapitalize"
11
+ mode="md"
12
+ [inputmode]="localInputMode"
13
+ [min]="min"
14
+ [max]="max"
15
+ [maxlength]="maxLength || null"
16
+ [type]="type"
17
+ (ionInput)="valueChange.emit($event.detail.value ?? undefined)"
18
+ [value]="value"></ion-input>
19
+ <!-- Form Control -->
20
+ <ion-input
21
+ *ngIf="control"
22
+ [ngClass]="{ 'text-center': inputTextCenter, 'grey-background': inputGreyBackground }"
23
+ [label]="label"
24
+ [labelPlacement]="inputLabelPlacement"
25
+ [placeholder]="placeholder"
26
+ fill="outline"
27
+ [clearInput]="!inputClear"
28
+ [autocapitalize]="autoCapitalize"
29
+ mode="md"
30
+ [inputmode]="localInputMode"
31
+ [formControl]="control"
32
+ [min]="min"
33
+ [max]="max"
34
+ [maxlength]="maxLength || null"
35
+ [type]="type"
36
+ (ionInput)="valueChange.emit($event.detail.value ?? undefined)"></ion-input>
37
+ <cf-form-validation *ngIf="control" [control]="control"></cf-form-validation>
@@ -0,0 +1,23 @@
1
+ /*===============================================
2
+ ================== Form Items ===================
3
+ ===============================================*/
4
+ ion-input {
5
+ font-family: 'Roboto', sans-serif;
6
+ font-weight: 400;
7
+ font-style: normal;
8
+ font-size: 1.6rem;
9
+ color: var(--cf-app-text-color-default);
10
+ text-align: start;
11
+ --border-radius: 8px !important; //--- important overrides the fill option
12
+ --highlight-color-focused: var(--cf-app-color-primary);
13
+ --highlight-color-invalid: var(--cf-app-system-color-error);
14
+ --highlight-color-valid: var(--cf-app-color-primary);
15
+ }
16
+
17
+ ion-input.text-center {
18
+ text-align: center;
19
+ }
20
+
21
+ ion-input.grey-background {
22
+ --background: var(--cf-app-system-color-outline);
23
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { FormInputComponent } from './form-input.component';
4
+
5
+ describe('FormInputComponent', () => {
6
+ let component: FormInputComponent;
7
+ let fixture: ComponentFixture<FormInputComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [FormInputComponent]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(FormInputComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Carefirst Library Form Input
3
+ *
4
+ * @file form-input.component
5
+ * @description Contains all the logic for generating a CareFirst Form Input Field
6
+ * @author Arno Jansen van Vuuren
7
+ * @since 2023 - 12 - 14
8
+ * @usage <cf-form-input label="Label Name" %labelPlacement% %inputMode% %noClearButton% %textCenter% %min% %max% %autoCapitalize% %type% %[(value)]="twoWayComs"% %(valueChange)="currentValueEvent"% %[control]%="formName.controls.controlName"></cf-form-input>
9
+ * disable input by disabling the form control
10
+ */
11
+
12
+ import { Component, Input, Output, type OnChanges, type SimpleChanges, EventEmitter } from '@angular/core';
13
+ import { FormControl } from '@angular/forms';
14
+ //--- Utils
15
+ import { checkTruthAttribute, validateStringValue } from '../../utils/attribute.util';
16
+
17
+ /**==============================================
18
+ * @interface inputsC
19
+ * @description Define available input values
20
+ */
21
+ const inputsC = {
22
+ labelPlacement: ['fixed', 'floating', 'stacked', 'start', 'end'],
23
+ inputMode: ['text', 'email', 'numeric', 'tel', 'decimal', 'url', 'search'],
24
+ autoCapitalize: ['off', 'none', 'on', 'sentences', 'words', 'characters'],
25
+ type: ['date', 'datetime-local', 'email', 'month', 'number', 'password', 'search', 'tel', 'text', 'time', 'url', 'week'],
26
+ } as const;
27
+
28
+ @Component({
29
+ selector: 'cf-form-input',
30
+ templateUrl: './form-input.component.html',
31
+ styleUrl: './form-input.component.scss',
32
+ })
33
+ export class FormInputComponent implements OnChanges {
34
+ @Input() label!: string;
35
+ @Input() min: number | string = 'none';
36
+ @Input() max: number | string = 'none';
37
+ @Input() labelPlacement?: (typeof inputsC.labelPlacement)[number];
38
+ @Input() placeholder?: string | undefined;
39
+ @Input() inputmode?: (typeof inputsC.inputMode)[number];
40
+ @Input() autoCapitalize?: (typeof inputsC.autoCapitalize)[number];
41
+ @Input() type?: (typeof inputsC.type)[number];
42
+ @Input() noClearButton?: boolean | string | undefined;
43
+ @Input() control?: FormControl | null;
44
+ @Input() textCenter?: boolean | string | undefined;
45
+ @Input() maxLength?: number | string;
46
+ @Input() greyBackground?: boolean | string | undefined;
47
+
48
+ //--- ngModel
49
+ @Input() value: string | undefined;
50
+ @Output() valueChange = new EventEmitter<typeof this.value>();
51
+
52
+ //--- Local variables
53
+ inputLabelPlacement: typeof this.labelPlacement;
54
+ localInputMode: typeof this.inputmode;
55
+ inputClear = false;
56
+ inputTextCenter = false;
57
+ inputType: typeof this.type;
58
+ inputAutoCapitalize: typeof this.autoCapitalize;
59
+ inputGreyBackground = false;
60
+
61
+ /**----------------------------------------------------------------
62
+ * @name ngOnChanges
63
+ * @description Detect changes to input values
64
+ * @param {SimpleChanges} changes
65
+ */
66
+ ngOnChanges(changes: SimpleChanges): void {
67
+ //--- Label Placement
68
+ this.inputLabelPlacement =
69
+ validateStringValue<(typeof inputsC.labelPlacement)[number]>(
70
+ changes,
71
+ 'labelPlacement',
72
+ inputsC.labelPlacement.slice(),
73
+ this.inputLabelPlacement
74
+ ) || 'floating';
75
+ //--- Input Type (keyboard)
76
+ this.localInputMode =
77
+ validateStringValue<(typeof inputsC.inputMode)[number]>(changes, 'inputmode', inputsC.inputMode.slice(), this.localInputMode) || 'text';
78
+ //--- Clear Button
79
+ this.inputClear = checkTruthAttribute(changes, 'noClearButton', this.inputClear);
80
+ //--- Text Center
81
+ this.inputTextCenter = checkTruthAttribute(changes, 'textCenter', this.inputTextCenter);
82
+ //--- Type
83
+ this.inputType = validateStringValue<(typeof inputsC.type)[number]>(changes, 'type', inputsC.type.slice(), this.inputType) || 'text';
84
+ //--- Auto Capitalize
85
+ this.inputAutoCapitalize =
86
+ validateStringValue<(typeof inputsC.autoCapitalize)[number]>(
87
+ changes,
88
+ 'autoCapitalize',
89
+ inputsC.autoCapitalize.slice(),
90
+ this.inputAutoCapitalize
91
+ ) || 'none';
92
+ //--- Grey Background
93
+ this.inputGreyBackground = checkTruthAttribute(changes, 'greyBackground', this.inputGreyBackground);
94
+ }
95
+ }
@@ -0,0 +1,27 @@
1
+ <!-- ngModel -->
2
+ <ion-select
3
+ *ngIf="!control"
4
+ [label]="label"
5
+ [labelPlacement]="inputLabelPlacement"
6
+ [placeholder]="placeholder"
7
+ fill="outline"
8
+ mode="md"
9
+ interface="popover"
10
+ (ionChange)="valueChange.emit($event.detail.value ?? undefined)"
11
+ [value]="value">
12
+ <ion-select-option *ngFor="let option of options" [value]="option.value">{{ option.displayName }}</ion-select-option>
13
+ </ion-select>
14
+ <!-- Form Control -->
15
+ <ion-select
16
+ *ngIf="control"
17
+ [label]="label"
18
+ [labelPlacement]="inputLabelPlacement"
19
+ [placeholder]="placeholder"
20
+ fill="outline"
21
+ mode="md"
22
+ interface="popover"
23
+ [formControl]="control"
24
+ (ionChange)="valueChange.emit($event.detail.value ?? undefined)">
25
+ <ion-select-option *ngFor="let option of options" [value]="option.value">{{ option.displayName }}</ion-select-option>
26
+ </ion-select>
27
+ <cf-form-validation *ngIf="control" [control]="control"></cf-form-validation>
@@ -0,0 +1,40 @@
1
+ /*===============================================
2
+ ================== Form Items ===================
3
+ ===============================================*/
4
+ ion-select {
5
+ font-family: 'Roboto', sans-serif;
6
+ font-weight: 400;
7
+ font-style: normal;
8
+ font-size: 1.6rem;
9
+ color: var(--cf-app-text-color-default);
10
+ text-align: start;
11
+ --border-radius: 8px !important; //--- important overrides the fill option
12
+ --highlight-color-focused: var(--cf-app-color-primary);
13
+ --highlight-color-invalid: var(--cf-app-system-color-error);
14
+ --highlight-color-valid: var(--cf-app-color-primary);
15
+ }
16
+
17
+ /*===============================================
18
+ ================ Select Popovers ================
19
+ ===============================================*/
20
+ ::ng-deep ion-select-popover ion-list[class*='popover'] {
21
+ background: var(--cf-app-background-light);
22
+ ion-item[class*='popover'] {
23
+ ion-radio {
24
+ font-family: 'Roboto', sans-serif;
25
+ font-weight: 400;
26
+ font-style: normal;
27
+ font-size: 1.6rem;
28
+ color: var(--cf-app-text-color-default);
29
+ text-align: start;
30
+ }
31
+
32
+ --background: transparent;
33
+ --border-radius: 8px;
34
+ --background-focused: var(--cf-app-color-accent);
35
+ --background-focused-opacity: 0.5;
36
+ --background-hover: var(--cf-app-color-primary);
37
+ --background-hover-opacity: 0.1;
38
+ padding: 4px;
39
+ }
40
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { FormInputSelectComponent } from './form-input-select.component';
4
+
5
+ describe('FormInputSelectComponent', () => {
6
+ let component: FormInputSelectComponent;
7
+ let fixture: ComponentFixture<FormInputSelectComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [FormInputSelectComponent]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(FormInputSelectComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Carefirst Library Form Input Select
3
+ *
4
+ * @file form-input-select.component
5
+ * @description Contains all the logic for generating a CareFirst Select
6
+ * @author Arno Jansen van Vuuren
7
+ * @since 2023 - 12 - 14
8
+ * @usage <cf-form-input-select label="Label Name" [options]="[{ displayName: string; value: string | number | boolean | null | undefined }]" %labelPlacement% %(valueChange)="currentValue"% %[(value)]="twoWayComs"% %[control]%="formName.controls.controlName"></cf-form-input-select>
9
+ * disable input by disabling the form control
10
+ */
11
+
12
+ import { Component, EventEmitter, Input, Output, type OnChanges, type SimpleChanges } from '@angular/core';
13
+ import { FormControl } from '@angular/forms';
14
+ //--- Utils
15
+ import { validateStringValue } from '../../utils/attribute.util';
16
+ //--- Interfaces
17
+ import type { FormInputSelectOptionsI } from '../../interfaces/input.interface';
18
+
19
+ /**==============================================
20
+ * @interface inputSelectC
21
+ * @description Define available input select values
22
+ */
23
+ const inputSelectC = {
24
+ labelPlacement: ['fixed', 'floating', 'stacked', 'start', 'end'],
25
+ } as const;
26
+
27
+ @Component({
28
+ selector: 'cf-form-input-select',
29
+ templateUrl: './form-input-select.component.html',
30
+ styleUrl: './form-input-select.component.scss',
31
+ })
32
+ export class FormInputSelectComponent<T> implements OnChanges {
33
+ @Input() label!: string;
34
+ @Input() options!: FormInputSelectOptionsI<T>[];
35
+ @Input() labelPlacement?: (typeof inputSelectC.labelPlacement)[number];
36
+ @Input() placeholder?: string | undefined;
37
+ @Input() control?: FormControl | null;
38
+
39
+ //--- ngModel
40
+ @Input() value: FormInputSelectOptionsI<T>['value'] | undefined;
41
+ @Output() valueChange = new EventEmitter<typeof this.value>();
42
+
43
+ //--- Local variables
44
+ inputLabelPlacement: typeof this.labelPlacement;
45
+
46
+ /**----------------------------------------------------------------
47
+ * @name ngOnChanges
48
+ * @description Detect changes to input values
49
+ * @param {SimpleChanges} changes
50
+ */
51
+ ngOnChanges(changes: SimpleChanges): void {
52
+ //--- Label Placement
53
+ this.inputLabelPlacement =
54
+ validateStringValue<(typeof inputSelectC.labelPlacement)[number]>(
55
+ changes,
56
+ 'labelPlacement',
57
+ inputSelectC.labelPlacement.slice(),
58
+ this.inputLabelPlacement
59
+ ) || 'floating';
60
+ }
61
+ }