Compare commits

...

141 Commits

Author SHA1 Message Date
Pfeil, Scott Robert
8212d7146c Merge branch 'bugfix/CXTDT-626224' into 'develop'
CXTDT-626224

### Summary
CXTDT-626224
MVA/iOS: Progress section has visual defects that need to be corrected.
Change :-  Number size should be: (font-size: 32px / line-height: 36px and “%” symbol size should be: font-size: 11px / line-height: 16px

### JIRA Ticket
https://onejira.verizon.com/browse/CXTDT-626224![Screenshot_2024-10-17_at_7.15.02_PM](/uploads/e89f367a09b23c230ab4f461320fc669/Screenshot_2024-10-17_at_7.15.02_PM.png)

![Screenshot_2024-10-17_at_7.15.33_PM](/uploads/a5055585223f4ab2697d1ce79f52d43b/Screenshot_2024-10-17_at_7.15.33_PM.png)

Co-authored-by: rajani kumari  Gupta <rajani.kumari.gupta@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1204
2024-10-21 13:10:53 +00:00
rajani kumari Gupta
5c280b7922 Fix comment 2024-10-21 14:28:34 +05:30
Pfeil, Scott Robert
1eed9ebb76 Merge branch 'feature/safe_area_insets' into 'develop'
Digital ACT192 story ONEAPP-11297 - Updating insets to allow for more...

### Summary
Updating insets to allow flexibility with the safe area

### JIRA Ticket
https://onejira.verizon.com/browse/ONEAPP-6673

Co-authored-by: Scott Pfeil <Scott.Pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1203
2024-10-17 15:30:33 +00:00
Scott Pfeil
a210b8da9b Remove Spacer 2024-10-17 09:34:50 -04:00
Scott Pfeil
44adc76dcb Digital ACT192 story ONEAPP-11297 - Updating insets to allow for more flexibility and edge using. Removing the status bar view because it is no longer used. 2024-10-17 09:04:31 -04:00
rajani kumari Gupta
eb4f741f1a CXTDT-626224
MVA/iOS: Progress section has visual defects that need to be corrected.
issue fixed :- Number size should be: (font-size: 32px / line-height: 36px and “%” symbol size should be: font-size: 11px / line-height: 16px
2024-10-17 17:47:24 +05:30
Bruce, Matt R
928c8c5b54 Merge branch 'bugfix/CXTDT-626309' into 'develop'
Digital ACT191 defect CXTDT-626309 - Updating fonts and spacing

### Summary
Fixes to the header component defaults.
https://docs.google.com/spreadsheets/d/1DqG_ZDxIseuVsEtRaQTVRC5mHME79Ksmhdj067jLNr4/edit?pli=1&gid=0#gid=0

### JIRA Ticket
https://onejira.verizon.com/browse/CXTDT-626309
https://onejira.verizon.com/browse/CXTDT-628092

Co-authored-by: Scott Pfeil <Scott.Pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1202
2024-10-16 16:34:13 +00:00
Scott Pfeil
2dd3a7dca8 Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into bugfix/CXTDT-626309 2024-10-16 12:31:28 -04:00
Scott Pfeil
7bed914dca Digital ACT191 defect CXTDT-626309 - Updating fonts and spacing
Digital ACT191 defect CXTDT-628092 - Fixing accessibility trait header default.
2024-10-16 10:53:16 -04:00
Pfeil, Scott Robert
fe5bd4a9ac Merge branch 'feature/CXTDT-624895-Badge-Color-Updates' into 'develop'
refactored badge text/fill color

### Summary
Fixed bug in how fillColor is set.

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1200
2024-10-16 01:25:12 +00:00
Matt Bruce
7eb1a4ff4b redid the values
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-15 16:57:37 -05:00
Matt Bruce
76b58ec88a using type now and not the old way.
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-14 15:57:25 -05:00
Matt Bruce
4487f9b03b refactored badge text/fill color
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-14 15:53:31 -05:00
Scott Pfeil
3a06f7b43e Digital ACT191 defect CXTDT-626309 - Update to default header h2 padding 2024-10-14 11:03:24 -04:00
Hedden, Kyle Matthew
f3e97ecfd4 Merge branch 'feature/CXTDT-624895-Badge-Color-Updates' into 'develop'
VDS - iOS Badge - Include ability to select custom color for Label and Background

### Summary
CXT - Defect TrackerCXTDT-624895
VDS - iOS Badge - Include ability to select custom color for Label and Background
### JIRA Ticket
https://onejira.verizon.com/browse/CXTDT-624895

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1199
2024-10-09 13:04:36 +00:00
Matt Bruce
f66dc66818 undid comment
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-08 09:18:23 -05:00
Matt Bruce
bf2a3e7e5b removed isDark
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-08 09:10:04 -05:00
Matt Bruce
54b50bffd3 added fillColor codable
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-08 09:08:30 -05:00
Matt Bruce
3b2dc2d447 updated to use badgeModel
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-08 09:08:20 -05:00
Matt Bruce
c737ca1344 added textColor
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-08 09:08:05 -05:00
Pfeil, Scott Robert
d2e841c533 Merge branch 'bugfix/FontLabelAttribute-conversion' into 'develop'
added in model conversion to textStyle

### Summary
The size was not being used in the conversion along with the name. 

So now you either pass in a Style or a Name & Size.

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1197
2024-10-04 17:57:09 +00:00
Matt Bruce
69d057c45a added in model conversion to textStyle
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-10-04 12:03:18 -05:00
Pfeil, Scott Robert
0510cded89 Merge branch 'feature/ONEAPP-11359' into 'develop'
Digital ACT192 story ONEAPP-11359: Lift the minimum supported iOS version number to 15.

### Summary
Lift the minimum supported iOS version number to 15.

### JIRA Ticket
https://onejira.verizon.com/browse/ONEAPP-11359

Co-authored-by: Hedden, Kyle Matthew <kyle.hedden@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1196
2024-10-03 21:07:26 +00:00
Hedden, Kyle Matthew
03a8a2d925 Merge branch 'bugfix/missing_accessibility_identifiers' into 'develop'
Added missing accessibility identifier

### Summary
Added missing accessibilityIdentifiers

### JIRA Ticket
Awaiting

Co-authored-by: Scott Pfeil <Scott.Pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1195
2024-10-02 21:38:41 +00:00
Hedden, Kyle Matthew
65bf81830e Digital ACT192 story ONEAPP-11359: Lift the minimum supported iOS version number to 15. 2024-10-01 20:24:32 -04:00
Scott Pfeil
bb2fbe4bdd Added missing accessibility identifier 2024-09-27 12:13:09 -04:00
Pfeil, Scott Robert
ce038458dc Merge branch 'bugfix/atomic-vds-titleLockup-model-issue' into 'develop'
TitleLockup Model issue

### Summary
removed duplicate alignment property and updated the confluence to reference the correct textAlignment.

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1194
2024-09-27 14:40:34 +00:00
Matt Bruce
de33f8ffa1 fixed migration issue in checkboxLabel to integrate the VDS.CheckboxItem
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-09-27 09:38:36 -05:00
Matt Bruce
4d4765ccec removed duplicate alignment property and updated the confluence to reference the correct textAlignment.
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-09-27 09:03:12 -05:00
Bruce, Matt R
464e36606e Merge branch 'bugfix/MVAPCT-271' into 'develop'
Digital PCT265 defect MVAPCT-271 - Ensure the app doesn't crash on invalid color hex.

### Summary
Ensure the app doesn't crash on invalid color hex. 

### JIRA Ticket
https://onejira.verizon.com/browse/MVAPCT-271

Co-authored-by: Scott Pfeil <Scott.Pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1192
2024-09-20 18:05:55 +00:00
Scott Pfeil
8a7c07ecf2 Digital PCT265 defect MVAPCT-271 - greater than or equal to length fix 2024-09-20 14:04:44 -04:00
Scott Pfeil
740c3eeb31 Digital PCT265 defect MVAPCT-271 - Ensure the app doesn't crash on invalid color hex. 2024-09-20 12:45:11 -04:00
Hedden, Kyle Matthew
00a11cd5dc Merge branch 'feature/atomic-vds-sept2024' into 'develop'
September Atomic/VDS Release

### Summary
Added Breadcrumbs and Pagination 

### JIRA Ticket
- https://onejira.verizon.com/browse/ONEAPP-6827
- https://onejira.verizon.com/browse/ONEAPP-6978

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1185
2024-09-20 16:29:11 +00:00
Matt Bruce
03a1bd0920 made parentalmodelmolecule
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-09-20 08:30:51 -05:00
Matt Bruce
4f6b848e72 removed inits
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-09-20 08:30:37 -05:00
Matt Bruce
5043ff35a0 removed inits
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-09-20 08:30:27 -05:00
Bruce, Matt R
806ac9821a Merge branch 'bugfix/featured_products_defects' into 'develop'
Bugfix/featured products defects

### Summary
Fix for bold when the font isn't supported, and for bg image forcing full image size.

Co-authored-by: Scott Pfeil <Scott.Pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1191
2024-09-19 18:41:29 +00:00
Scott Pfeil
47e63e0c8b Digital ACT191 defect FeaturedProducts - Fix for bold when the font isn't supported, and for bg image forcing full image size. 2024-09-19 14:35:33 -04:00
Hedden, Kyle Matthew
2d7f8ae2ca Merge branch 'feature/MVAPCT-273' into 'develop'
MVAPCT-273

### Summary
Template Decoding Failed Error logs

### MVAPCT-273
https://onejira.verizon.com/browse/MVAPCT-273

Co-authored-by: Danish Phiroz <danish.phiroz@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1188
2024-09-19 12:27:47 +00:00
Phiroz, Danish
e708b97581 MVAPCT-273 2024-09-19 12:27:47 +00:00
Hedden, Kyle Matthew
1b5ca94988 Merge branch 'release/20_2_0' into 'develop'
release/20_2_0 hotfix merge

Co-authored-by: Pfeil, Scott Robert <scott.pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1182
2024-09-06 19:59:31 +00:00
Pfeil, Scott Robert
d7756b66b0 Merge branch 'bugfix/CXTDT-608227-2' into 'release/20_2_0'
Digital PCT032 defect CXTDT-608227: Set content compression resistance for RadioButton.

### Summary
Prevent the radio button from being crushed.

### JIRA Ticket
https://onejira.verizon.com/browse/CXTDT-608227

Co-authored-by: Hedden, Kyle Matthew <kyle.hedden@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1187
2024-08-29 17:59:42 +00:00
Hedden, Kyle Matthew
89842ee443 Digital PCT032 defect CXTDT-608227: Set content compression resistance for RadioButton. 2024-08-29 13:39:41 -04:00
Matt Bruce
61f9fb9946 enforce an action
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-27 16:38:17 -05:00
Matt Bruce
484b578568 added Pagination
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-27 14:30:39 -05:00
Matt Bruce
1c723c31de registered in core
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-26 16:13:16 -05:00
Matt Bruce
e79c1d7637 added breadcrumbs/model
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-26 16:13:05 -05:00
Bruce, Matt R
02a2da7f0a Merge branch 'bugfix/CXTDT-601365' into 'develop'
Fix for CXTDT-601365, enabling option for Icon to be accessible from JSON.

### Summary
Enabling option for Icon to be accessible from JSON.

### JIRA Ticket
[CXTDT-601365](https://onejira.verizon.com/browse/CXTDT-601365)

Co-authored-by: Sumanth Nadigadda <sumanth.nadigadda@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1183
2024-08-26 18:49:05 +00:00
Sumanth Nadigadda
22c30de62f Fix for CXTDT-601365, enabling option for Icon to be accessible from JSON. 2024-08-26 23:40:29 +05:30
Hedden, Kyle Matthew
f6f3cd53fe Merge branch 'feature/atomic-vds-new-forms-atoms' into 'develop'
Revert code

### Summary
Removed code since this was a fix in VDS

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1180
2024-08-23 17:29:19 +00:00
Matt Bruce
378c46facd removed this since it is no longer needed.
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-23 08:35:10 -05:00
Hedden, Kyle Matthew
c2e10582f8 Merge branch 'feature/atomic-vds-new-forms-atoms' into 'develop'
Last of the VDS FormFields

### Summary
Added in 
1. Checkboxes (VDS CheckboxGroup)
2. RadioButtons (VDS RadioButtonGroup)
3. CalendarView (VDS CalendarBase)
4. DatePickerEntryField (VDS DatePicker)

### JIRA Ticket
https://onejira.verizon.com/browse/ONEAPP-7001
https://onejira.verizon.com/browse/ONEAPP-7004
https://onejira.verizon.com/browse/ONEAPP-7016
https://onejira.verizon.com/browse/ONEAPP-7958

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1176
2024-08-22 21:46:28 +00:00
Matt Bruce
8670fa3193 removed visualEquivalent
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 14:25:48 -05:00
Matt Bruce
9bbf325640 removed since this is not needed.
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 14:11:14 -05:00
Matt Bruce
59e762f52e added == and != for equality
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 14:10:44 -05:00
Matt Bruce
62c1aa6a8a removed isVisuallyEqual since this was the same as isEqual
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 14:10:26 -05:00
Matt Bruce
df1846c295 added parentMoleculeModelProtocol
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 14:09:48 -05:00
Matt Bruce
533bcd2dea added isEqual to CalendarView
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:30:13 -05:00
Matt Bruce
e211d4dc22 added isEqual to TextViewEntryFieldModel
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:21:52 -05:00
Matt Bruce
f9915dfacc update func
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:20:22 -05:00
Matt Bruce
68a72f6b2e added isEqual to ItemDropDown
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:20:10 -05:00
Matt Bruce
2a497082a0 added isEqual to TextEntry
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:19:50 -05:00
Matt Bruce
961a0546a8 added isEqual to base model
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:19:37 -05:00
Matt Bruce
86d49053a6 add isEqual to DatePicker
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:12:58 -05:00
Matt Bruce
db8ba63892 added isEqual to Toggle
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:12:00 -05:00
Matt Bruce
878fd11c8a added isEqual to RadioButton variations
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:11:48 -05:00
Matt Bruce
c40dc5e396 added isEqual to RadioBox variations
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:11:35 -05:00
Matt Bruce
f94ddbf866 added isEqual to Checkbox variations
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:11:14 -05:00
Matt Bruce
b70d2f8add added isEqual
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 13:10:49 -05:00
Matt Bruce
398bf94811 removed obj-c compatibility
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-22 11:41:28 -05:00
Bruce, Matt R
7f9ee10c5e Merge branch 'feature/tile_cont_upd_view' into 'develop'
added updateView for molecule in tile container

Added this change as updateView for the molecule was not getting called resulting in the molecule and its children always pinned to their respective superviews.

Co-authored-by: Arun Kumar Chintakrinda <arun.kumar.chintakrinda@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1179
2024-08-22 14:25:37 +00:00
Arun Kumar Chintakrinda
6354174857 Merge remote-tracking branch 'refs/remotes/origin/develop' 2024-08-22 19:46:40 +05:30
Arun Kumar Chintakrinda
3be3b11e39 added updateView for molecule in tile container 2024-08-22 19:41:43 +05:30
Bruce, Matt R
de30c5d286 Merge branch 'bugfix/molecule_replacement_module_id_validation' into 'develop'
Digital PCT265 defect: Missing moecule.id to moduleName validation for the replacement behavior.

### Summary
Data validation bug on notification_count_fios module return.

Co-authored-by: Hedden, Kyle Matthew <kyle.hedden@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1178
2024-08-22 12:56:13 +00:00
Hedden, Kyle Matthew
472323f303 Digital PCT265 defect: Missing moecule.id to moduleName validation for the replacement behavior. 2024-08-21 19:59:46 -04:00
Matt Bruce
3b306a299a using enabled now
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 16:28:14 -05:00
Matt Bruce
de67fd7fb6 refactored
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 16:07:10 -05:00
Matt Bruce
60cefc57a6 pushed word change
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 15:47:27 -05:00
Matt Bruce
9185e185fd removed duplicate .
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 15:17:27 -05:00
Matt Bruce
3d5c188898 changed comment
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 15:16:26 -05:00
Matt Bruce
458f303972 fixed per comments
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 14:21:17 -05:00
Matt Bruce
ef08aa043e added other properties to encoder :D
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 14:14:01 -05:00
Matt Bruce
698f7b5520 subclass to formFieldModel
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 14:10:23 -05:00
Matt Bruce
3270f21951 used new isEnabled in model
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 14:10:09 -05:00
Matt Bruce
315eac1dac used new isEnabled in model
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 14:09:57 -05:00
Matt Bruce
c3290f83ba updated for change in RadioBoxModel
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 14:09:24 -05:00
Matt Bruce
c41cf3f18e converted to use FormFieldModel subclass
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 14:08:57 -05:00
Matt Bruce
56b4142c14 added isEnabled
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 14:07:59 -05:00
Matt Bruce
e7bcd32588 put the moleculeName in the base
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-21 13:07:51 -05:00
Bruce, Matt R
6c841c078a Merge branch 'release/20_1_1' into 'develop'
Digital PCT265 defect: VDS TabsTableViewCell delegate reset issue. Impacts UAD...

Co-authored-by: Subramaniam, Ramya <ramya.subramaniam@one.verizon.com>
Co-authored-by: Hedden, Kyle Matthew <kyle.hedden@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1177
2024-08-21 13:17:32 +00:00
Matt Bruce
29b56bf63b updated field
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 15:41:53 -05:00
Matt Bruce
e030b460ce added final properties 2024-08-20 14:19:22 -05:00
Matt Bruce
25dce9e88c refactored naming of method
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 14:19:15 -05:00
Matt Bruce
7b0f4e4328 update only after the model sets the properties
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 13:59:52 -05:00
Matt Bruce
8829bd7457 added new mapping
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 13:59:27 -05:00
Matt Bruce
478f2b6083 added codable for VDS
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 13:59:19 -05:00
Matt Bruce
94ace3d49a added new models/views
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 13:59:07 -05:00
Matt Bruce
e3f22efb12 updated to convertTo
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 08:49:51 -05:00
Matt Bruce
b71a4c5b25 refactored to convertTo
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 08:49:36 -05:00
Matt Bruce
3fd10bf199 added registration
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 08:49:20 -05:00
Matt Bruce
aeabee2666 refactored to convertToXXXModel
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 08:49:12 -05:00
Matt Bruce
d8c83f9230 removed delegate that isn't used anywhere.
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 08:45:38 -05:00
Matt Bruce
6b608b4a8a added showError
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 08:45:23 -05:00
Matt Bruce
13f9776a4f new Checkboxes/RadioButtons
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-20 08:45:04 -05:00
Pfeil, Scott Robert
ffd5242cde Merge branch 'bugfix/atomic-buttonGroup' into 'develop'
Fix for the reset() issue with default properties being reset for buttonGroup

### Summary
There were buttongroup properties added in the setup() method, however they were getting removed in reset(). 

### JIRA Ticket
https://onejira.verizon.com/browse/CXTDT-602228

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1175
2024-08-15 17:32:31 +00:00
Matt Bruce
e89272a3cd comments on the order of operations in reset()
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-15 12:31:50 -05:00
Matt Bruce
33dc411743 Fix for the reset() issue with default properties being reset for buttonGroup
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-15 11:08:25 -05:00
Pfeil, Scott Robert
558a3d7c55 Merge branch 'feature/negate_gone' into 'develop'
Digital PCT265 story VZWYZDG-1866 - Added action for negating the gone property on molecules.

### Summary
Action for negating the gone property on goneable molecules.
https://oneconfluence.verizon.com/x/AZT2UQ

### JIRA Ticket
https://onejira.verizon.com/browse/VZWYZDG-1866

![SuccessfulTest](/uploads/ac54fd745447ef52497843af641f24e4/SuccessfulTest.mp4)

Co-authored-by: Scott Pfeil <Scott.Pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1166
2024-08-14 18:56:12 +00:00
Scott Pfeil
17a94e2f04 Digital PCT265 story VZWYZDG-1866 - Ensure the footer stays at the bottom. 2024-08-14 12:32:50 -04:00
Scott Pfeil
4921d7d8db Digital PCT265 story VZWYZDG-1866 - Updating format per code review. 2024-08-14 11:33:40 -04:00
Subramaniam, Ramya
8c5a8776ab Merge branch 'bugfix/tabstableviewcell' into 'release/20_1_1'
Digital PCT265 defect: VDS TabsTableViewCell delegate reset issue. Impacts UAD.

### Summary
This issue is due to a change in the VDS tabs reset handling. The onTabSelect and onTabShouldSelect gets reset to nil. In the case of table cell reuse this reset gets called and our setup connection in the initializer is lost. Adding the delegate back in the model setter seems to resolve this immediate issue but we should expand out and see if there are other cases.

### JIRA Ticket
[CXTDT-601399](https://onejira.verizon.com/browse/CXTDT-601399)

Co-authored-by: Hedden, Kyle Matthew <kyle.hedden@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1174
2024-08-14 05:34:05 +00:00
Hedden, Kyle Matthew
3867384307 Digital PCT265 defect: VDS TabsTableViewCell delegate reset issue. Impacts UAD account tab switcher. 2024-08-13 23:25:18 -04:00
Pfeil, Scott Robert
efccb312e8 Merge branch 'release/20_1_0' into 'develop'
ensure viewModel?. is used outside of the viewModelDidUpdate method

### Summary
Hotfix

Co-authored-by: Hedden, Kyle Matthew <kyle.hedden@verizonwireless.com>
Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1173
2024-08-13 20:43:30 +00:00
Hedden, Kyle Matthew
f437fbaea9 Merge branch 'hotfix/20_1-vds-update' into 'release/20_1_0'
ensure viewModel?. is used outside of the viewModelDidUpdate method

### Summary
Crash from not using optional ? for the viewModels.

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1172
2024-08-12 14:47:10 +00:00
Matt Bruce
441525a610 ensure formModel exists
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-12 09:28:40 -05:00
Matt Bruce
07351c1a22 ensure viewModel?. is used outside of the viewModelDidUpdate method
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-12 09:28:31 -05:00
Hedden, Kyle Matthew
236a1969e9 Merge branch 'bugfix/vds-update' into 'develop'
Merge of release/20_1 and bugfix

### Summary
VDS Bugfix for new Generics plus all of the release/20_1 code that hasn't been merged down into develop.

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>
Co-authored-by: Pfeil, Scott Robert <scott.pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1170
2024-08-12 13:21:53 +00:00
Matt Bruce
f96b750302 Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui.git into test 2024-08-10 11:31:02 -05:00
Matt Bruce
715a911ee4 fixed issue with vds refactor 2024-08-10 11:30:47 -05:00
Hedden, Kyle Matthew
696b6b99d0 Merge branch 'hotfix/checkbox-showError' into 'release/20_1_0'
CXTDT-599891 - taking out showError for now

### Summary
Checkboxes have never had an error state, so until we figure out the default state, we need to turn it off. 

### JIRA Ticket
https://onejira.verizon.com/browse/CXTDT-599891

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1169
2024-08-09 22:52:31 +00:00
Matt Bruce
b41d2189bf taking out showError for now
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-09 17:48:05 -05:00
Matt Bruce
8c1577bb7f Merge branch 'release/20_1_0' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into release/20_1_0 2024-08-09 09:17:13 -05:00
Pfeil, Scott Robert
21d1e957d0 Merge branch 'bugfix/proddef_26055_2' into 'release/20_1_0'
bugfix PRODDEF-26055 Issue #2

### Summary
added missing view to getAcessibilityElements func

### JIRA Ticket
https://onejira.verizon.com/browse/PRODDEF-26055

Co-authored-by: Hedden, Kyle Matthew <kyle.hedden@verizonwireless.com>
Co-authored-by: Arun Kumar Chintakrinda <arun.kumar.chintakrinda@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1168
2024-08-08 20:56:49 +00:00
Hedden, Kyle Matthew
c34a5c7661 Merge branch 'hotfix/radioButton' into 'release/20_1_0'
CXTDT-598142 - RadioButton fix

### Summary
Updated VDS RadioButton had more atomic setting than required. 

### JIRA Ticket
https://onejira.verizon.com/browse/CXTDT-598142

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1167
2024-08-08 20:45:16 +00:00
Matt Bruce
d308bfc957 CXTDT-598142 - RadioButton fix
QA3||MVA||Prepay||IOS - 22053||Devices||From Add device screen

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-08-08 15:38:53 -05:00
Matt Bruce
92b28d767b Merge branch 'release/20_1_0' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into release/20_1_0 2024-08-08 14:32:35 -05:00
Scott Pfeil
a691f8d713 Digital PCT265 story VZWYZDG-1866 - Update name to proper jargon. 2024-08-08 14:14:03 -04:00
Scott Pfeil
f412fd70e1 Digital PCT265 story VZWYZDG-1866 - Added action for negating the gone property on molecules. 2024-08-08 14:02:21 -04:00
Pfeil, Scott Robert
50b0280ba4 Merge branch 'feature/MVAPCT-213' into 'develop'
Digital PCT265 story MVAPCT-213 - Allow for panels to override the supported...

### Summary
Allow for panels to override the supported orientation. Force chatbot panel to be full screen width on non tablet devices.

### JIRA Ticket
https://onejira.verizon.com/browse/MVAPCT-213

Co-authored-by: Scott Pfeil <Scott.Pfeil3@verizonwireless.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1165
2024-08-06 15:06:09 +00:00
Scott Pfeil
dfbb53f545 Digital PCT265 story MVAPCT-213 - Function name update 2024-08-06 10:31:18 -04:00
Scott Pfeil
1d2defeabb Digital PCT265 story MVAPCT-213 - Add Helper to update the orientation. 2024-08-06 09:53:59 -04:00
Hedden, Kyle Matthew
3d6d7c0cad Merge branch 'bugfix/proddef_26055_2' into 'develop'
bugfix PRODDEF-26055 Issue #2

### Summary
added missing view to getAcessibilityElements func

### JIRA Ticket
https://onejira.verizon.com/browse/PRODDEF-26055

Co-authored-by: Arun Kumar Chintakrinda <arun.kumar.chintakrinda@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1164
2024-08-06 13:38:57 +00:00
Arun Kumar Chintakrinda
2ce1b671bd added comment 2024-08-06 17:18:56 +05:30
Scott Pfeil
e13e8ca5ab Digital PCT265 story MVAPCT-213 - Allow for panels to override the supported orientation. Force chatbot panel to be full screen width on non tablet devices. 2024-08-05 13:59:59 -04:00
Arun Kumar Chintakrinda
100ede48fa added condition to check if view is available 2024-08-05 20:32:09 +05:30
Arun Kumar Chintakrinda
0d6fc3d15d bugfix PRODDEF-26055 Issue #2, added missing view to getAcessibilityElements func 2024-08-05 20:25:24 +05:30
Hedden, Kyle Matthew
5eca67fe0f Merge branch 'hotfix/checkbox-isSelected' into 'release/20_1_0'
HotFix Checkbox/CheckboxLabel

### Summary
reverted to old code so that if isSelected is set manually, the form will validate.

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1163
2024-08-02 19:49:04 +00:00
Matt Bruce
1a48113b0d Merge branch 'hotfix/checkbox-isSelected' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui.git into release/20_1_0 2024-08-02 13:14:35 -05:00
Matt Bruce
0938328ea2 Merge branch 'hotfix/checkbox-isSelected' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui.git into release/20_1_0 2024-08-02 12:42:10 -05:00
Hedden, Kyle Matthew
941312dd08 Merge branch 'bugfix/dropDownSelect' into 'release/20_1_0'
DropDownSelect update

### Summary
fixed issue with EstimatedHeight and delegate callback.

### JIRA Ticket
https://onejira.verizon.com/browse/ONEAPP-7135

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1162
2024-08-01 20:35:04 +00:00
Pfeil, Scott Robert
d69722c431 Merge branch 'bugfix/atomic-vds-selectorUpdate' into 'develop'
Updated Merged Selectors

### Summary
updated selectors for similar logic in valuechanged event 

### JIRA Ticket
https://onejira.verizon.com/browse/ONEAPP-7001

Co-authored-by: Matt Bruce <matt.bruce@verizon.com>

See merge request https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui/-/merge_requests/1159
2024-07-31 00:52:13 +00:00
157 changed files with 2259 additions and 426 deletions

View File

@ -307,6 +307,9 @@
AFA4932229E5EF2E001A9663 /* NotificationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4932129E5EF2E001A9663 /* NotificationHandler.swift */; };
AFA4933F29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */; };
AFA4935729EE3DCC001A9663 /* AlertDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */; };
AFB6336E2C65166E00791221 /* GoneableProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB6336D2C65166E00791221 /* GoneableProtocol.swift */; };
AFB633702C65175800791221 /* ActionUpdateVisibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB6336F2C65175800791221 /* ActionUpdateVisibility.swift */; };
AFB633722C653C0900791221 /* ActionUpdateVisibilityModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFB633712C653C0900791221 /* ActionUpdateVisibilityModel.swift */; };
AFE4A1D627DFBB6F00C458D0 /* UINavigationController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */; };
B4CC8FBD29DF34680005D28B /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBC29DF34680005D28B /* Badge.swift */; };
B4CC8FBF29DF34730005D28B /* BadgeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBE29DF34730005D28B /* BadgeModel.swift */; };
@ -591,6 +594,18 @@
EA6642932BCDA97D00D81DC4 /* TileContainerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6642922BCDA97D00D81DC4 /* TileContainerModel.swift */; };
EA6E8B952B504A43000139B4 /* ButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B942B504A43000139B4 /* ButtonGroup.swift */; };
EA6E8B972B504A4D000139B4 /* ButtonGroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */; };
EA7AE5472C73C01A00107C74 /* CheckboxesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE5462C73C01A00107C74 /* CheckboxesModel.swift */; };
EA7AE5492C7403DC00107C74 /* Checkboxes.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE5482C7403DC00107C74 /* Checkboxes.swift */; };
EA7AE54B2C74CACA00107C74 /* RadioButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE54A2C74CACA00107C74 /* RadioButtons.swift */; };
EA7AE54D2C74CAD700107C74 /* RadioButtonsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE54C2C74CAD700107C74 /* RadioButtonsModel.swift */; };
EA7AE54F2C74EB3700107C74 /* CalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE54E2C74EB3700107C74 /* CalendarView.swift */; };
EA7AE5512C74EB4500107C74 /* CalendarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE5502C74EB4500107C74 /* CalendarViewModel.swift */; };
EA7AE5532C74F1F600107C74 /* DatePickerEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE5522C74F1F600107C74 /* DatePickerEntryField.swift */; };
EA7AE5552C74F20600107C74 /* DatePickerEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE5542C74F20600107C74 /* DatePickerEntryFieldModel.swift */; };
EA7AE55C2C7D18A100107C74 /* BreadcrumbsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE55B2C7D18A100107C74 /* BreadcrumbsModel.swift */; };
EA7AE55E2C7D234500107C74 /* Breadcrumbs.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE55D2C7D234500107C74 /* Breadcrumbs.swift */; };
EA7AE5602C7E554700107C74 /* PaginationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE55F2C7E554700107C74 /* PaginationModel.swift */; };
EA7AE5622C7E555D00107C74 /* Pagination.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE5612C7E555D00107C74 /* Pagination.swift */; };
EA7D81602B2B6E6800D29F9E /* Icon.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7D815F2B2B6E6800D29F9E /* Icon.swift */; };
EA7D81622B2B6E7F00D29F9E /* IconModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7D81612B2B6E7F00D29F9E /* IconModel.swift */; };
EA7D81642B2BABCB00D29F9E /* TooltipModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7D81632B2BABCB00D29F9E /* TooltipModel.swift */; };
@ -931,6 +946,9 @@
AFA4932129E5EF2E001A9663 /* NotificationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationHandler.swift; sourceTree = "<group>"; };
AFA4933E29E874F0001A9663 /* MVMCoreUILoggingDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUILoggingDelegateProtocol.swift; sourceTree = "<group>"; };
AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertDelegateProtocol.swift; sourceTree = "<group>"; };
AFB6336D2C65166E00791221 /* GoneableProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoneableProtocol.swift; sourceTree = "<group>"; };
AFB6336F2C65175800791221 /* ActionUpdateVisibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionUpdateVisibility.swift; sourceTree = "<group>"; };
AFB633712C653C0900791221 /* ActionUpdateVisibilityModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionUpdateVisibilityModel.swift; sourceTree = "<group>"; };
AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Extension.swift"; sourceTree = "<group>"; };
B4CC8FBC29DF34680005D28B /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = "<group>"; };
B4CC8FBE29DF34730005D28B /* BadgeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeModel.swift; sourceTree = "<group>"; };
@ -1217,6 +1235,18 @@
EA6642922BCDA97D00D81DC4 /* TileContainerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainerModel.swift; sourceTree = "<group>"; };
EA6E8B942B504A43000139B4 /* ButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroup.swift; sourceTree = "<group>"; };
EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroupModel.swift; sourceTree = "<group>"; };
EA7AE5462C73C01A00107C74 /* CheckboxesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxesModel.swift; sourceTree = "<group>"; };
EA7AE5482C7403DC00107C74 /* Checkboxes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkboxes.swift; sourceTree = "<group>"; };
EA7AE54A2C74CACA00107C74 /* RadioButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtons.swift; sourceTree = "<group>"; };
EA7AE54C2C74CAD700107C74 /* RadioButtonsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonsModel.swift; sourceTree = "<group>"; };
EA7AE54E2C74EB3700107C74 /* CalendarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarView.swift; sourceTree = "<group>"; };
EA7AE5502C74EB4500107C74 /* CalendarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarViewModel.swift; sourceTree = "<group>"; };
EA7AE5522C74F1F600107C74 /* DatePickerEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickerEntryField.swift; sourceTree = "<group>"; };
EA7AE5542C74F20600107C74 /* DatePickerEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickerEntryFieldModel.swift; sourceTree = "<group>"; };
EA7AE55B2C7D18A100107C74 /* BreadcrumbsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BreadcrumbsModel.swift; sourceTree = "<group>"; };
EA7AE55D2C7D234500107C74 /* Breadcrumbs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Breadcrumbs.swift; sourceTree = "<group>"; };
EA7AE55F2C7E554700107C74 /* PaginationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationModel.swift; sourceTree = "<group>"; };
EA7AE5612C7E555D00107C74 /* Pagination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pagination.swift; sourceTree = "<group>"; };
EA7D815F2B2B6E6800D29F9E /* Icon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Icon.swift; sourceTree = "<group>"; };
EA7D81612B2B6E7F00D29F9E /* IconModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconModel.swift; sourceTree = "<group>"; };
EA7D81632B2BABCB00D29F9E /* TooltipModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TooltipModel.swift; sourceTree = "<group>"; };
@ -1287,6 +1317,7 @@
27F6B08B26052AFF008529AA /* ParentMoleculeModelProtocol.swift */,
27577DCC286CA959001EC47E /* MoleculeMaskingProtocol.swift */,
58E7561C2BE04C320088BB5D /* MoleculeComparisonProtocol.swift */,
AFB6336D2C65166E00791221 /* GoneableProtocol.swift */,
);
path = ModelProtocols;
sourceTree = "<group>";
@ -1598,6 +1629,8 @@
AF1C33722885D481006B1001 /* MVMCoreUIActionOpenPageHandler.swift */,
AF60A7F52892D2E300919EEB /* ActionDismissNotificationModel.swift */,
AF60A7F72892D34D00919EEB /* ActionDismissNotificationHandler.swift */,
AFB633712C653C0900791221 /* ActionUpdateVisibilityModel.swift */,
AFB6336F2C65175800791221 /* ActionUpdateVisibility.swift */,
);
path = Actions;
sourceTree = "<group>";
@ -2022,8 +2055,12 @@
BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */,
D264FAA6243FE13B00D98315 /* RadioBox.swift */,
0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */,
EA7AE54C2C74CAD700107C74 /* RadioButtonsModel.swift */,
EA7AE54A2C74CACA00107C74 /* RadioButtons.swift */,
011D95AE2407266E000E3791 /* RadioButtonModel.swift */,
01004F2F22721C3800991ECC /* RadioButton.swift */,
EA7AE5462C73C01A00107C74 /* CheckboxesModel.swift */,
EA7AE5482C7403DC00107C74 /* Checkboxes.swift */,
31BE15CA23D8924C00452370 /* CheckboxModel.swift */,
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */,
@ -2174,6 +2211,7 @@
D29DF10E21E67A77003B2FB9 /* Molecules */ = {
isa = PBXGroup;
children = (
EA7AE55A2C7D188900107C74 /* Breadcrumbs */,
D2EC7BD22527A1E400F540AF /* HeadersAndFooters */,
D2CAC7C9251104CB00C75681 /* TopNotification */,
D2509ED42472EE0B001BFB9D /* NavigationBar */,
@ -2335,6 +2373,8 @@
D20492A524329CE200A5EED6 /* LoadImageView.swift */,
0A51F3E02475CB73002E08B6 /* LoadingSpinnerModel.swift */,
0A51F3E12475CB73002E08B6 /* LoadingSpinner.swift */,
EA7AE55F2C7E554700107C74 /* PaginationModel.swift */,
EA7AE5612C7E555D00107C74 /* Pagination.swift */,
AA37CBD2251907200027344C /* StarsModel.swift */,
AA37CBD42519072F0027344C /* Stars.swift */,
AA07EA902510A442009A2AE3 /* StarModel.swift */,
@ -2353,6 +2393,8 @@
EA7D815F2B2B6E6800D29F9E /* Icon.swift */,
EA7D81632B2BABCB00D29F9E /* TooltipModel.swift */,
EA7D81652B2BABD200D29F9E /* Tooltip.swift */,
EA7AE5502C74EB4500107C74 /* CalendarViewModel.swift */,
EA7AE54E2C74EB3700107C74 /* CalendarView.swift */,
);
path = Views;
sourceTree = "<group>";
@ -2504,6 +2546,8 @@
D2BEFEF5248A954C00FAB3A9 /* FormFields */ = {
isa = PBXGroup;
children = (
EA7AE5542C74F20600107C74 /* DatePickerEntryFieldModel.swift */,
EA7AE5522C74F1F600107C74 /* DatePickerEntryField.swift */,
EA5DBDAA2C35B6C500290DF8 /* FormFieldModel.swift */,
D2BEFEF6248A957A00FAB3A9 /* Tags */,
D29DF22B21E6A0FA003B2FB9 /* TextFields */,
@ -2608,6 +2652,15 @@
path = Alerts;
sourceTree = "<group>";
};
EA7AE55A2C7D188900107C74 /* Breadcrumbs */ = {
isa = PBXGroup;
children = (
EA7AE55B2C7D18A100107C74 /* BreadcrumbsModel.swift */,
EA7AE55D2C7D234500107C74 /* Breadcrumbs.swift */,
);
path = Breadcrumbs;
sourceTree = "<group>";
};
EAA0CFAD275E7D5A00D65EB0 /* FormFieldEffect */ = {
isa = PBXGroup;
children = (
@ -2839,11 +2892,13 @@
AA7F32AD246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift in Sources */,
EAA482CE2B45F2F300978105 /* MFLoadingSpinner+VDS.swift in Sources */,
D272F5F92473163100BD1A8F /* BarButtonItem.swift in Sources */,
EA7AE54D2C74CAD700107C74 /* RadioButtonsModel.swift in Sources */,
D2D2FCF3252B72CF0033EAAA /* MoleculeSectionFooter.swift in Sources */,
0A9D09202433796500D2E6C0 /* BarsIndicatorView.swift in Sources */,
D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */,
01004F3022721C3800991ECC /* RadioButton.swift in Sources */,
D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */,
AFB633702C65175800791221 /* ActionUpdateVisibility.swift in Sources */,
D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */,
AA71AD4024A32FE700ACA76F /* HeadersH2Link.swift in Sources */,
D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */,
@ -2852,6 +2907,7 @@
EAB14BC127D935F00012AB2C /* RuleCompareModelProtocol.swift in Sources */,
011D95A924057AC7000E3791 /* FormGroupWatcherFieldProtocol.swift in Sources */,
EA1B02DE2C41BFD200F0758B /* RuleVDSModel.swift in Sources */,
EA7AE5532C74F1F600107C74 /* DatePickerEntryField.swift in Sources */,
EA985C892981AB7100F2FF2E /* VDS-TextStyle.swift in Sources */,
BB2BF0EA2452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift in Sources */,
D20C700B250BFDE40095B21C /* NotificationContainerView.swift in Sources */,
@ -2893,6 +2949,7 @@
D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */,
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */,
D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */,
AFB633722C653C0900791221 /* ActionUpdateVisibilityModel.swift in Sources */,
EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */,
D23A90002612347A007E14CE /* PageBehaviorContainerModelProtocol.swift in Sources */,
EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */,
@ -2906,6 +2963,7 @@
D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */,
D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */,
D28BA74D248589C800B75CB8 /* TabPageModelProtocol.swift in Sources */,
EA7AE5602C7E554700107C74 /* PaginationModel.swift in Sources */,
608211282AC6B57E00C3FC39 /* MVMCoreUILoggingHandler.swift in Sources */,
014AA72F23C5059B006F3E93 /* ThreeLayerPageTemplateModel.swift in Sources */,
0A21DB91235E0EDB00C160A2 /* DigitBox.swift in Sources */,
@ -2931,8 +2989,10 @@
525239C02407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift in Sources */,
D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */,
D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */,
EA7AE55C2C7D18A100107C74 /* BreadcrumbsModel.swift in Sources */,
D20F3B44252E00E4004B3F56 /* PageProtocol.swift in Sources */,
AA37CBD3251907200027344C /* StarsModel.swift in Sources */,
EA7AE5622C7E555D00107C74 /* Pagination.swift in Sources */,
8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */,
94C0150C2421564A005811A9 /* ActionCollapseNotificationModel.swift in Sources */,
D2CAC7CB251104E100C75681 /* NotificationXButtonModel.swift in Sources */,
@ -2959,6 +3019,7 @@
AAE96FA525341F7D0037A989 /* ListStoreLocator.swift in Sources */,
D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */,
944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */,
EA7AE55E2C7D234500107C74 /* Breadcrumbs.swift in Sources */,
D213347723843825008E41B3 /* Line.swift in Sources */,
D2E2A99C23D8D975000B42E6 /* ImageHeadlineBodyModel.swift in Sources */,
BB3BC1302550094500297977 /* ListLeftVariableIconWithRightCaretAllTextLinksModel.swift in Sources */,
@ -3097,7 +3158,9 @@
AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */,
AFA4935729EE3DCC001A9663 /* AlertDelegateProtocol.swift in Sources */,
58A9DD7D2AC2103300F5E0B0 /* ReplaceableMoleculeBehaviorModel.swift in Sources */,
EA7AE54B2C74CACA00107C74 /* RadioButtons.swift in Sources */,
D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */,
EA7AE5552C74F20600107C74 /* DatePickerEntryFieldModel.swift in Sources */,
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */,
EA6E8B972B504A4D000139B4 /* ButtonGroupModel.swift in Sources */,
@ -3176,6 +3239,7 @@
D2092355244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift in Sources */,
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
0A51F3E22475CB73002E08B6 /* LoadingSpinnerModel.swift in Sources */,
AFB6336E2C65166E00791221 /* GoneableProtocol.swift in Sources */,
D2169303251E53D9002A6324 /* SectionListTemplateModel.swift in Sources */,
EA6642932BCDA97D00D81DC4 /* TileContainerModel.swift in Sources */,
AF7E509929E477C1009DC2AD /* AlertController.swift in Sources */,
@ -3253,6 +3317,7 @@
01F2C20327C81F9700DC3D36 /* SubNavManagerNavigationController.swift in Sources */,
EABFC1412763BB8D00E78B40 /* FormLabel.swift in Sources */,
AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */,
EA7AE5492C7403DC00107C74 /* Checkboxes.swift in Sources */,
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */,
D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */,
@ -3283,6 +3348,7 @@
BB6C6AC824225290005F7224 /* ListOneColumnTextWithWhitespaceDividerShort.swift in Sources */,
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */,
D21B7F73243BAC6800051ABF /* CollectionItemModelProtocol.swift in Sources */,
EA7AE5512C74EB4500107C74 /* CalendarViewModel.swift in Sources */,
AA104B1A24474A66004D2810 /* HeadersH2Buttons.swift in Sources */,
C7192E7D23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift in Sources */,
D2D2FCF0252B72AF0033EAAA /* MoleculeSectionFooterModel.swift in Sources */,
@ -3303,6 +3369,7 @@
D2D3957D252FDBCD00047B11 /* ModalSectionListTemplateModel.swift in Sources */,
D2B9D0E4265EEE9D0084735C /* MoleculeListProtocol.swift in Sources */,
D29C559625C099630082E7D6 /* VideoDataManager.swift in Sources */,
EA7AE5472C73C01A00107C74 /* CheckboxesModel.swift in Sources */,
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
EA6642912BCDA97300D81DC4 /* TileContainer.swift in Sources */,
@ -3343,6 +3410,7 @@
D2169301251E51E7002A6324 /* SectionListTemplate.swift in Sources */,
0A6682AA2435125F00AD3CA1 /* Styler.swift in Sources */,
D264FAA7243FE13B00D98315 /* RadioBox.swift in Sources */,
EA7AE54F2C74EB3700107C74 /* CalendarView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3557,7 +3625,7 @@
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../SharedFrameworks";
INFOPLIST_FILE = MVMCoreUI/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -3587,7 +3655,7 @@
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../SharedFrameworks";
INFOPLIST_FILE = MVMCoreUI/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",

View File

@ -0,0 +1,47 @@
//
// ActionToggleGone.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 8/8/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import MVMCore
public struct ActionUpdateVisibility: MVMCoreActionHandlerProtocol {
public init() {}
public func execute(with model: any MVMCore.ActionModelProtocol, delegateObject: MVMCore.DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
guard let model = model as? ActionUpdateVisibilityModel,
let delegate = (delegateObject as? MVMCoreUIDelegateObject)?.moleculeDelegate else { return }
let stateMap = model.targets.reduce(into: [String: ActionUpdateVisibilityModel.VisibilityTarget.VisibilityState]()) {
$0[$1.id] = $1.state
}
let updatedModels: [MoleculeModelProtocol] = delegate.getRootMolecules().reduceDepthFirstTraverse(options: .parentFirst, depth: 0, initialResult: [], nextPartialResult: { accumulator, model, depth in
guard var model = model as? (GoneableProtocol & MoleculeModelProtocol),
let state = stateMap[model.id] else { return accumulator }
model.updateVisibility(state)
return accumulator + [model]
})
guard updatedModels.count > 0 else { return }
await delegate.updateUI(for: updatedModels)
}
}
extension GoneableProtocol {
mutating func updateVisibility(_ state: ActionUpdateVisibilityModel.VisibilityTarget.VisibilityState) {
switch state {
case .true:
gone = false
case .false:
gone = true
case .inverted:
gone = !gone
}
}
}

View File

@ -0,0 +1,42 @@
//
// ActionToggleGoneModel.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 8/8/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import MVMCore
public struct ActionUpdateVisibilityModel: ActionModelProtocol {
public static var identifier: String = "updateVisibility"
public var actionType: String = ActionUpdateVisibilityModel.identifier
public var extraParameters: JSONValueDictionary?
public var analyticsData: JSONValueDictionary?
public var targets: [VisibilityTarget]
public struct VisibilityTarget: Codable {
public enum VisibilityState: String, Codable {
case `true`
case `false`
case inverted
}
public var id: String
public var state: VisibilityState
public init(id: String, state: VisibilityState) {
self.id = id
self.state = state
}
}
public init(targets: [VisibilityTarget], extraParameters: JSONValueDictionary? = nil, analyticsData: JSONValueDictionary? = nil) {
self.targets = targets
self.extraParameters = extraParameters
self.analyticsData = analyticsData
}
}

View File

@ -38,7 +38,10 @@ open class ButtonGroup: VDS.ButtonGroup, VDSMoleculeViewProtocol {
return PillButton.estimatedHeight(with: buttonModel, delegateObject)
}
public func viewModelDidUpdate() {
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
surface = viewModel.surface
isEnabled = viewModel.enabled
alignment = viewModel.alignment

View File

@ -7,6 +7,7 @@
//
import Foundation
import MVMCore
import VDS
public class ButtonGroupModel: ParentMoleculeModelProtocol {
@ -17,6 +18,7 @@ public class ButtonGroupModel: ParentMoleculeModelProtocol {
public static var identifier: String = "buttonGroup"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var children: [MoleculeModelProtocol] { buttons }
@ -38,6 +40,7 @@ public class ButtonGroupModel: ParentMoleculeModelProtocol {
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case accessibilityIdentifier
case backgroundColor
case buttons
case alignment
@ -56,6 +59,7 @@ public class ButtonGroupModel: ParentMoleculeModelProtocol {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
surface = try typeContainer.decodeIfPresent(Surface.self, forKey: .surface) ?? .light
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
buttons = try typeContainer.decodeModels(codingKey: .buttons)
@ -70,6 +74,7 @@ public class ButtonGroupModel: ParentMoleculeModelProtocol {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(surface, forKey: .surface)
try container.encode(enabled, forKey: .enabled)
try container.encodeModels(buttons, forKey: .buttons)

View File

@ -15,7 +15,8 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro
public static var identifier: String = "imageButton"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var image: ImageViewModel?
@ -45,6 +46,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case accessibilityIdentifier
case image
case backgroundColor
case accessibilityText
@ -64,6 +66,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
image = try typeContainer.decodeIfPresent(ImageViewModel.self, forKey: .image)
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
@ -91,6 +94,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(image, forKey: .image)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)

View File

@ -0,0 +1,51 @@
//
// DatePickerEntryField.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/20/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
open class DatePickerEntryField: VDS.DatePicker, VDSMoleculeViewProtocol {
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
public var viewModel: DatePickerEntryFieldModel!
public var delegateObject: MVMCoreUIDelegateObject?
public var additionalData: [AnyHashable : Any]?
//--------------------------------------------------
// MARK: - Public Methods
//--------------------------------------------------
open override func setup() {
super.setup()
//turn off internal required rule
useRequiredRule = false
publisher(for: .valueChanged)
.sink { [weak self] control in
guard let self, let viewModel, isEnabled else { return }
viewModel.selectedDate = control.selectedDate
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
}.store(in: &subscribers)
}
public func viewModelDidUpdate() {
surface = viewModel.surface
labelText = viewModel.title
helperText = viewModel.feedback
helperTextPlacement = viewModel.feedbackTextPlacement
tooltipModel = viewModel.tooltip?.convertToVDSTooltipModel()
transparentBackground = viewModel.transparentBackground
width = viewModel.width
selectedDate = viewModel.selectedDate
calendarModel = viewModel.calendar.convertToVDSCalendarModel()
FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate)
}
public func updateView(_ size: CGFloat) {}
}

View File

@ -0,0 +1,121 @@
//
// DatePickerEntryFieldModel.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/20/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
open class DatePickerEntryFieldModel: FormFieldModel {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public override static var identifier: String { "datePicker" }
public var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeZone = NSTimeZone.system
formatter.locale = .current
formatter.formatterBehavior = .default
return formatter
}()
/// Update the property value to alter the format of how the date is presented.
public var dateFormat: String = "MMM d, y" {
didSet { dateFormatter.dateFormat = dateFormat }
}
public var selectedDate: Date?
public var calendar: CalendarViewModel = .init()
public var title: String?
public var feedback: String?
public var feedbackTextPlacement: VDS.DatePicker.HelperTextPlacement = .bottom
public var tooltip: TooltipModel?
public var transparentBackground: Bool = false
public var width: CGFloat?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case dateFormat
case selectedDate
case calendar
case title
case feedback
case feedbackTextPlacement
case tooltip
case transparentBackground
case width
}
//--------------------------------------------------
// MARK: - Form Validation
//--------------------------------------------------
/// Returns the fieldValue of the selectedDate.
public override func formFieldValue() -> AnyHashable? {
guard let selectedDate, enabled else { return nil }
return dateFormatter.string(from: selectedDate)
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let dateFormat = try container.decodeIfPresent(String.self, forKey: .dateFormat) {
self.dateFormat = dateFormat
dateFormatter.dateFormat = dateFormat
}
if let date = try container.decodeIfPresent(String.self, forKey: .selectedDate) {
selectedDate = calendar.dateFormatter.date(from: date)
}
if let calendar = try container.decodeIfPresent(CalendarViewModel.self, forKey: .calendar) {
self.calendar = calendar
}
title = try container.decodeIfPresent(String.self, forKey: .title)
feedback = try container.decodeIfPresent(String.self, forKey: .feedback)
feedbackTextPlacement = try container.decodeIfPresent(VDS.EntryFieldBase.HelperTextPlacement.self, forKey: .feedbackTextPlacement) ?? .bottom
tooltip = try container.decodeIfPresent(TooltipModel.self, forKey: .tooltip)
transparentBackground = try container.decodeIfPresent(Bool.self, forKey: .transparentBackground) ?? false
width = try container.decodeIfPresent(CGFloat.self, forKey: .width)
try super.init(from: decoder)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(selectedDate, forKey: .selectedDate)
try container.encode(calendar, forKey: .calendar)
try container.encodeIfPresent(title, forKey: .title)
try container.encodeIfPresent(feedback, forKey: .feedback)
try container.encode(feedbackTextPlacement, forKey: .feedbackTextPlacement)
try container.encodeIfPresent(tooltip, forKey: .tooltip)
try container.encode(transparentBackground, forKey: .transparentBackground)
try container.encodeIfPresent(width, forKey: .width)
}
open override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard super.isEqual(to: model), let model = model as? Self else { return false }
return dateFormat == model.dateFormat
&& selectedDate == model.selectedDate
&& calendar == model.calendar
&& title == model.title
&& feedback == model.feedback
&& feedbackTextPlacement == model.feedbackTextPlacement
&& tooltip == model.tooltip
&& transparentBackground == model.transparentBackground
&& width == model.width
}
}

View File

@ -15,6 +15,8 @@ import VDS
// MARK: - Properties
//--------------------------------------------------
public class var identifier: String { "" }
public var moleculeName: String { Self.identifier }
public var id: String = UUID().uuidString
public var backgroundColor: Color?
@ -23,7 +25,7 @@ import VDS
public var enabled: Bool = true
public var required: Bool = true
public var readOnly: Bool = false
public var showError: Bool?
public var showError: Bool = false
public var errorMessage: String?
public var initialErrorMessage: String?
@ -66,6 +68,7 @@ import VDS
case moleculeName
case accessibilityIdentifier
case errorMessage
case showError
case enabled
case readOnly
case required
@ -107,6 +110,7 @@ import VDS
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage)
initialErrorMessage = errorMessage
showError = try typeContainer.decodeIfPresent(Bool.self, forKey: .showError) ?? false
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required) ?? true
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
@ -126,9 +130,30 @@ import VDS
try container.encodeIfPresent(errorMessage, forKey: .errorMessage)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(groupName, forKey: .groupName)
try container.encode(showError, forKey: .showError)
try container.encode(readOnly, forKey: .readOnly)
try container.encode(enabled, forKey: .enabled)
try container.encode(required, forKey: .required)
try container.encode(inverted, forKey: .inverted)
}
open func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return moleculeName == model.moleculeName
&& enabled == model.enabled
&& showError == model.showError
&& errorMessage == model.errorMessage
&& readOnly == model.readOnly
&& required == model.required
&& inverted == model.inverted
&& fieldKey == model.fieldKey
&& groupName == model.groupName
&& accessibilityText == model.accessibilityText
&& accessibilityIdentifier == model.accessibilityIdentifier
&& accessibilityTraits == model.accessibilityTraits
}
}
extension FormFieldModel {
public var isEnabled: Bool { enabled && !readOnly }
}

View File

@ -12,13 +12,15 @@ import MVMCore
@objcMembers public class TagModel: MoleculeModelProtocol {
public static var identifier: String = "tag"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var label: LabelModel
public var action: ActionModelProtocol?
public var backgroundColor: Color?
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case label
case action
@ -42,6 +44,7 @@ import MVMCore
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
label = try typeContainer.decode(LabelModel.self, forKey: .label)
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
@ -50,6 +53,7 @@ import MVMCore
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(label, forKey: .label)
try container.encodeModelIfPresent(action, forKey: .action)

View File

@ -12,12 +12,14 @@ import MVMCore
@objcMembers public class TagsModel: MoleculeModelProtocol {
public static var identifier: String = "tags"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var tags: [TagModel]
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case backgroundColor
case tags
@ -34,6 +36,7 @@ import MVMCore
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
tags = try typeContainer.decode([TagModel].self, forKey: .tags)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
}
@ -41,6 +44,7 @@ import MVMCore
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(tags, forKey: .tags)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)

View File

@ -110,7 +110,7 @@ open class ItemDropdownEntryField: VDS.DropdownSelect, VDSMoleculeViewProtocol,
publisher(for: .valueChanged)
.sink { [weak self] control in
guard let self, let selectedItem else { return }
guard let self, let selectedItem, let viewModel else { return }
viewModel.selectedIndex = control.selectId
observeDropdownSelection?(selectedItem.text)
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
@ -130,7 +130,7 @@ open class ItemDropdownEntryField: VDS.DropdownSelect, VDSMoleculeViewProtocol,
guard let self else { return }
isEditting = false
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
if let valid = viewModel.isValid {
if let viewModel, let valid = viewModel.isValid {
updateValidation(valid)
}
performDropdownAction()
@ -146,7 +146,7 @@ open class ItemDropdownEntryField: VDS.DropdownSelect, VDSMoleculeViewProtocol,
isEnabled = viewModel.enabled
isReadOnly = viewModel.readOnly
isRequired = viewModel.required
tooltipModel = viewModel.tooltip?.toVDSTooltipModel()
tooltipModel = viewModel.tooltip?.convertToVDSTooltipModel()
width = viewModel.width
transparentBackground = viewModel.transparentBackground
@ -207,7 +207,7 @@ open class ItemDropdownEntryField: VDS.DropdownSelect, VDSMoleculeViewProtocol,
if setInitialValueInTextField {
let pickerIndex = optionsPicker.selectedRow(inComponent: 0)
viewModel.selectedIndex = pickerIndex
viewModel?.selectedIndex = pickerIndex
selectId = pickerIndex
}
}

View File

@ -17,7 +17,7 @@ import VDS
public var options: [String] = []
public var selectedIndex: Int?
public var showInlineLabel: Bool = false
public var feedbackTextPlacement: VDS.EntryFieldBase.HelperTextPlacement = .bottom
public var feedbackTextPlacement: VDS.DropdownSelect.HelperTextPlacement = .bottom
public init(with options: [String], selectedIndex: Int? = nil) {
self.options = options
@ -78,4 +78,13 @@ import VDS
try container.encode(feedbackTextPlacement, forKey: .feedbackTextPlacement)
try container.encodeModelIfPresent(action, forKey: .action)
}
open override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard super.isEqual(to: model), let model = model as? Self else { return false }
return options == model.options
&& selectedIndex == model.selectedIndex
&& showInlineLabel == model.showInlineLabel
&& feedbackTextPlacement == model.feedbackTextPlacement
&& action.isEqual(to: model.action)
}
}

View File

@ -34,7 +34,6 @@ import Foundation
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case backgroundColor
case title
case feedback
case errorTextColor
@ -86,7 +85,6 @@ import Foundation
required public init(from decoder: Decoder) throws {
try super.init(from: decoder)
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback)
errorTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .errorTextColor)
@ -106,7 +104,6 @@ import Foundation
open override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(title, forKey: .title)
try container.encodeIfPresent(feedback, forKey: .feedback)
try container.encodeIfPresent(text, forKey: .text)
@ -116,4 +113,16 @@ import Foundation
try container.encode(hideBorders, forKey: .hideBorders)
try container.encode(shouldMaskRecordedView, forKey: .shouldMaskRecordedView)
}
open override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard super.isEqual(to: model), let model = model as? Self else { return false }
return selected == model.selected
&& title == model.title
&& feedback == model.feedback
&& errorTextColor == model.errorTextColor
&& locked == model.locked
&& hideBorders == model.hideBorders
&& text == model.text
&& shouldMaskRecordedView == model.shouldMaskRecordedView
}
}

View File

@ -33,7 +33,7 @@ import VDS
private var isEditting: Bool = false {
didSet {
viewModel.selected = isEditting
viewModel?.selected = isEditting
}
}
@ -47,7 +47,7 @@ import VDS
open var validateWhenDoneEditing: Bool = true
open var shouldMaskWhileRecording: Bool {
return viewModel.shouldMaskRecordedView ?? false
return viewModel?.shouldMaskRecordedView ?? false
}
//--------------------------------------------------
// MARK: - Computed Properties
@ -99,7 +99,7 @@ import VDS
publisher(for: .valueChanged)
.sink { [weak self] control in
guard let self else { return }
guard let self, let viewModel else { return }
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
if (viewModel.type == .email) {
// remove spaces (either user entered Or auto-correct suggestion) for the email field
@ -112,7 +112,7 @@ import VDS
.sink { [weak self] textView in
guard let self else { return }
isEditting = true
if viewModel.clearTextOnTap {
if let viewModel, viewModel.clearTextOnTap {
text = ""
}
}.store(in: &subscribers)
@ -122,7 +122,7 @@ import VDS
.sink { [weak self] textView in
guard let self else { return }
isEditting = false
if validateWhenDoneEditing, let valid = viewModel.isValid {
if let viewModel, validateWhenDoneEditing, let valid = viewModel.isValid {
updateValidation(valid)
}
regexTextFieldOutputIfAvailable()
@ -173,7 +173,7 @@ import VDS
isEnabled = viewModel.enabled
isReadOnly = viewModel.readOnly
isRequired = viewModel.required
tooltipModel = viewModel.tooltip?.toVDSTooltipModel()
tooltipModel = viewModel.tooltip?.convertToVDSTooltipModel()
width = viewModel.width
transparentBackground = viewModel.transparentBackground

View File

@ -218,4 +218,21 @@ import VDS
try container.encode(transparentBackground, forKey: .transparentBackground)
try container.encodeIfPresent(width, forKey: .width)
}
open override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard super.isEqual(to: model), let model = model as? Self else { return false }
return placeholder == model.placeholder
&& textAlignment == model.textAlignment
&& enabledTextColor == model.enabledTextColor
&& disabledTextColor == model.disabledTextColor
&& keyboardOverride == model.keyboardOverride
&& type == model.type
&& clearTextOnTap == model.clearTextOnTap
&& displayFormat == model.displayFormat
&& displayMask == model.displayMask
&& enableClipboardActions == model.enableClipboardActions
&& tooltip == model.tooltip
&& transparentBackground == model.transparentBackground
&& width == model.width
}
}

View File

@ -29,7 +29,7 @@ open class TextViewEntryField: VDS.TextArea, VDSMoleculeViewProtocol, ObservingT
private var isEditting: Bool = false {
didSet {
viewModel.selected = isEditting
viewModel?.selected = isEditting
}
}
@ -37,7 +37,7 @@ open class TextViewEntryField: VDS.TextArea, VDSMoleculeViewProtocol, ObservingT
// MARK: - Computed Properties
//--------------------------------------------------
open var shouldMaskWhileRecording: Bool {
return viewModel.shouldMaskRecordedView ?? false
return viewModel?.shouldMaskRecordedView ?? false
}
/// Placeholder access for the textView.
@ -91,7 +91,7 @@ open class TextViewEntryField: VDS.TextArea, VDSMoleculeViewProtocol, ObservingT
publisher(for: .valueChanged)
.sink { [weak self] control in
guard let self else { return }
guard let self, let viewModel else { return }
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
}.store(in: &subscribers)
@ -108,7 +108,7 @@ open class TextViewEntryField: VDS.TextArea, VDSMoleculeViewProtocol, ObservingT
.sink { [weak self] textView in
guard let self else { return }
isEditting = false
if let valid = viewModel.isValid {
if let viewModel, let valid = viewModel.isValid {
updateValidation(valid)
}
@ -126,7 +126,7 @@ open class TextViewEntryField: VDS.TextArea, VDSMoleculeViewProtocol, ObservingT
isEnabled = viewModel.enabled
isReadOnly = viewModel.readOnly
isRequired = viewModel.required
tooltipModel = viewModel.tooltip?.toVDSTooltipModel()
tooltipModel = viewModel.tooltip?.convertToVDSTooltipModel()
width = viewModel.width
transparentBackground = viewModel.transparentBackground

View File

@ -21,7 +21,7 @@ public class TextViewEntryFieldModel: TextEntryFieldModel {
public var showsPlaceholder: Bool = false
public var minHeight: VDS.TextArea.Height = .twoX
public var maxLength: Int?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
@ -55,4 +55,13 @@ public class TextViewEntryFieldModel: TextEntryFieldModel {
try container.encode(minHeight, forKey: .minHeight)
try container.encodeIfPresent(maxLength, forKey: .maxLength)
}
open override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard super.isEqual(to: model), let model = model as? Self else { return false }
return accessibilityText == model.accessibilityText
&& editable == model.editable
&& minHeight == model.minHeight
&& maxLength == model.maxLength
}
}

View File

@ -123,6 +123,9 @@ import VDS
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
//forms
FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate)
groupName = viewModel.groupName
@ -131,7 +134,7 @@ import VDS
}
//properties
isEnabled = viewModel.enabled && !viewModel.readOnly
isEnabled = viewModel.isEnabled
isAnimated = viewModel.animated
//call super here to go around the didSet
@ -142,8 +145,9 @@ import VDS
viewModel.updateUI = {
MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in
guard let self = self else { return }
let isValid = viewModel.isValid ?? true
showError = !isValid
//let isValid = viewModel.isValid ?? true
//TODO: Fix issue with default state
//showError = !isValid
isEnabled = viewModel.enabled
})

View File

@ -94,4 +94,12 @@ import VDS
try container.encodeModelIfPresent(action, forKey: .action)
try container.encodeModelIfPresent(offAction, forKey: .offAction)
}
open override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard super.isEqual(to: model), let model = model as? Self else { return false }
return selected == model.selected
&& animated == model.animated
&& offAction.isEqual(to: model.offAction)
&& action.isEqual(to: model.action)
}
}

View File

@ -0,0 +1,58 @@
//
// Checkboxes.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/19/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
open class Checkboxes: VDS.CheckboxGroup, VDSMoleculeViewProtocol {
//------------------------------------------------------
// MARK: - Properties
//------------------------------------------------------
open var viewModel: CheckboxesModel!
open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
// Form Validation
var fieldKey: String?
var fieldValue: JSONValue?
var groupName: String?
/// The models for the molecules.
public var checkboxes: [CheckboxLabelModel]?
// MARK: - MoleculeViewProtocol
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
surface = viewModel.surface
showError = viewModel.showError
isEnabled = viewModel.enabled && !viewModel.readOnly
checkboxes = viewModel.checkboxes
checkboxes?.forEach {
FormValidator.setupValidation(for: $0.checkbox, delegate: delegateObject?.formHolderDelegate)
}
selectorModels = viewModel.checkboxes.convertToVDSCheckboxItemModel(surface: surface,
delegateObject: delegateObject,
additionalData: additionalData)
}
open func updateView(_ size: CGFloat) {}
open override func didSelect(_ selectedControl: CheckboxItem) {
super.didSelect(selectedControl)
// since the checkboxes has the state being tracked, we need to update the values here.
if let index = items.firstIndex(where: {$0 === selectedControl}), let selected = checkboxes?[index] {
selected.checkbox.selected = true
}
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
}
}

View File

@ -0,0 +1,101 @@
//
// CheckboxesModel.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/19/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import MVMCore
import VDS
public class CheckboxesModel: MoleculeModelProtocol, ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String { "checkboxes" }
public var id: String = UUID().uuidString
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var enabled: Bool = true
public var required: Bool = true
public var readOnly: Bool = false
public var showError: Bool = false
public var inverted: Bool = false
public var surface: Surface { inverted ? .dark : .light }
public var checkboxes: [CheckboxLabelModel]
public var children: [any MoleculeModelProtocol] { checkboxes }
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case accessibilityIdentifier
case inverted
case enabled
case readOnly
case showError
case checkboxes
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(with checkboxes: [CheckboxLabelModel]){
self.checkboxes = checkboxes
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
showError = try typeContainer.decodeIfPresent(Bool.self, forKey: .showError) ?? false
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
checkboxes = try typeContainer.decode([CheckboxLabelModel].self, forKey: .checkboxes)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(readOnly, forKey: .readOnly)
try container.encode(enabled, forKey: .enabled)
try container.encode(inverted, forKey: .inverted)
try container.encode(checkboxes, forKey: .checkboxes)
}
open func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return moleculeName == model.moleculeName
&& enabled == model.enabled
&& showError == model.showError
&& readOnly == model.readOnly
&& required == model.required
&& inverted == model.inverted
&& accessibilityText == model.accessibilityText
&& accessibilityIdentifier == model.accessibilityIdentifier
&& accessibilityTraits == model.accessibilityTraits
}
}

View File

@ -28,7 +28,9 @@ import VDS
//--------------------------------------------------
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
text = viewModel.text
subText = viewModel.subText
subTextRight = viewModel.subTextRight

View File

@ -8,47 +8,33 @@
import MVMCore
import VDS
@objcMembers public class RadioBoxModel: MoleculeModelProtocol, EnableableModelProtocol {
public class RadioBoxModel: FormFieldModel {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "radioBox"
public var id: String = UUID().uuidString
public override static var identifier: String { "radioBox" }
public var text: String
public var subText: String?
public var subTextRight: String?
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var selected: Bool = false
public var enabled: Bool = true
public var readOnly: Bool = false
public var strikethrough: Bool = false
public var fieldValue: String?
public var action: ActionModelProtocol?
public var inverted: Bool = false
public var surface: Surface { inverted ? .dark : .light }
public var fieldValue: String?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case text
case subText
case subTextRight
case backgroundColor
case accessibilityIdentifier
case selected
case enabled
case strikethrough
case fieldValue
case action
case readOnly
case inverted
case fieldValue
}
//--------------------------------------------------
@ -57,8 +43,19 @@ import VDS
public init(text: String) {
self.text = text
super.init()
}
//--------------------------------------------------
// MARK: - Form Validation
//--------------------------------------------------
/// Returns the fieldValue of the selected box, otherwise the text of the selected box.
public override func formFieldValue() -> AnyHashable? {
guard enabled else { return nil }
return fieldValue
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
@ -66,45 +63,42 @@ import VDS
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
text = try typeContainer.decode(String.self, forKey: .text)
subText = try typeContainer.decodeIfPresent(String.self, forKey: .subText)
subTextRight = try typeContainer.decodeIfPresent(String.self, forKey: .subTextRight)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) {
selected = isSelected
}
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
strikethrough = isStrikeTrough
}
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
try super.init(from: decoder)
}
public func encode(to encoder: Encoder) throws {
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(text, forKey: .text)
try container.encodeIfPresent(subText, forKey: .subText)
try container.encodeIfPresent(subTextRight, forKey: .subTextRight)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(selected, forKey: .selected)
try container.encode(enabled, forKey: .enabled)
try container.encode(readOnly, forKey: .readOnly)
try container.encode(strikethrough, forKey: .strikethrough)
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
try container.encodeModelIfPresent(action, forKey: .action)
try container.encode(inverted, forKey: .inverted)
}
open override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard super.isEqual(to: model), let model = model as? Self else { return false }
return text == model.text
&& subText == model.subText
&& subTextRight == model.subTextRight
&& selected == model.selected
&& strikethrough == model.strikethrough
&& fieldValue == model.fieldValue
&& action.isEqual(to: model.action)
}
}

View File

@ -9,10 +9,6 @@
import Foundation
import VDS
public protocol RadioBoxSelectionDelegate: AnyObject {
func selected(radioBox: RadioBoxModel)
}
open class RadioBoxes: VDS.RadioBoxGroup, VDSMoleculeViewProtocol {
//------------------------------------------------------
@ -29,13 +25,15 @@ open class RadioBoxes: VDS.RadioBoxGroup, VDSMoleculeViewProtocol {
/// The models for the molecules.
public var boxes: [RadioBoxModel]?
public weak var radioDelegate: RadioBoxSelectionDelegate?
// MARK: - MoleculeViewProtocol
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
boxes = viewModel.boxes
surface = viewModel.surface
selectorModels = viewModel.selectorModels
selectorModels = viewModel.boxes.convertToVDSRadioBoxModel(surface: surface)
FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate)
}
@ -50,7 +48,8 @@ open class RadioBoxes: VDS.RadioBoxGroup, VDSMoleculeViewProtocol {
boxes?.forEach { $0.selected = false }
selectedBox.selected = true
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
radioDelegate?.selected(radioBox: selectedBox)
}
}
}

View File

@ -8,7 +8,8 @@
import MVMCore
import VDS
@objcMembers public class RadioBoxesModel: FormFieldModel {
public class RadioBoxesModel: FormFieldModel, ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
@ -16,20 +17,9 @@ import VDS
public override static var identifier: String { "radioBoxes" }
public var boxes: [RadioBoxModel]
public var children: [any MoleculeModelProtocol] { boxes }
public var selectorModels: [VDS.RadioBoxGroup.RadioBoxItemModel] {
boxes.compactMap({ item in
var radioBox = RadioBoxGroup.RadioBoxItemModel()
radioBox.text = item.text
radioBox.subText = item.subText
radioBox.subTextRight = item.subTextRight
radioBox.surface = surface
radioBox.selected = item.selected
radioBox.strikethrough = item.strikethrough
radioBox.disabled = !(item.enabled && !item.readOnly)
return radioBox
})
}
//--------------------------------------------------
// MARK: - Form Validation
//--------------------------------------------------
@ -40,7 +30,7 @@ import VDS
let selectedBox = boxes.first { (box) -> Bool in
return box.selected
}
return selectedBox?.fieldValue ?? selectedBox?.text
return selectedBox?.formFieldValue() ?? selectedBox?.text
}
//--------------------------------------------------
@ -83,3 +73,19 @@ import VDS
try container.encode(boxes, forKey: .boxes)
}
}
extension Array where Element == RadioBoxModel {
internal func convertToVDSRadioBoxModel(surface: Surface) -> [RadioBoxGroup.RadioBoxItemModel] {
compactMap({ item in
var radioBox = RadioBoxGroup.RadioBoxItemModel()
radioBox.text = item.text
radioBox.subText = item.subText
radioBox.subTextRight = item.subTextRight
radioBox.surface = surface
radioBox.selected = item.selected
radioBox.strikethrough = item.strikethrough
radioBox.enabled = item.isEnabled
return radioBox
})
}
}

View File

@ -79,6 +79,11 @@ import VDS
//--------------------------------------------------
open override func setup() {
super.setup()
// Radio button should never be smaller that its content size.
setContentCompressionResistancePriority(.required, for: .vertical)
setContentCompressionResistancePriority(.required, for: .horizontal)
publisher(for: .valueChanged)
.sink { [weak self] control in
guard let self, isEnabled else { return }
@ -88,7 +93,9 @@ import VDS
}
open func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
//events
viewModel.updateUI = {
MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in
@ -101,7 +108,7 @@ import VDS
}
isSelected = viewModel.state
isEnabled = viewModel.enabled && !viewModel.readOnly
isEnabled = viewModel.isEnabled
RadioButtonSelectionHelper.setupForRadioButtonGroup(viewModel, self, delegateObject: delegateObject)
}
@ -144,11 +151,6 @@ import VDS
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
open func needsToBeConstrained() -> Bool { true }
public func horizontalAlignment() -> UIStackView.Alignment { .leading }
public func updateView(_ size: CGFloat) {}
}

View File

@ -83,4 +83,11 @@ open class RadioButtonModel: FormFieldModel {
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
try container.encodeModelIfPresent(action, forKey: .action)
}
open override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard super.isEqual(to: model), let model = model as? Self else { return false }
return state == model.state
&& fieldValue == model.fieldValue
&& action.isEqual(to: model.action)
}
}

View File

@ -0,0 +1,57 @@
//
// RadioButtons.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/20/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
open class RadioButtons: VDS.RadioButtonGroup, VDSMoleculeViewProtocol {
//------------------------------------------------------
// MARK: - Properties
//------------------------------------------------------
open var viewModel: RadioButtonsModel!
open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
// Form Validation
var fieldKey: String?
var fieldValue: JSONValue?
var groupName: String?
/// The models for the molecules.
public var radioButtons: [RadioButtonLabelModel]?
// MARK: - MoleculeViewProtocol
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
showError = viewModel.showError
isEnabled = viewModel.isEnabled
surface = viewModel.surface
radioButtons = viewModel.radioButtons
selectorModels = viewModel.radioButtons.convertToVDSRadioButtonItemModel(surface: surface,
delegateObject: delegateObject,
additionalData: additionalData)
FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate)
}
open func updateView(_ size: CGFloat) {}
open override func didSelect(_ selectedControl: RadioButtonItem) {
super.didSelect(selectedControl)
// since the radiobutton has the state being tracked, we need to update the values here.
if let index = items.firstIndex(where: {$0 === selectedControl}), let selected = radioButtons?[index] {
radioButtons?.forEach { $0.radioButton.state = false }
selected.radioButton.state = true
}
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
}
}

View File

@ -0,0 +1,74 @@
//
// RadioButtonsModel.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/20/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import MVMCore
import VDS
public class RadioButtonsModel: FormFieldModel, ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public override static var identifier: String { "radioButtons" }
public var radioButtons: [RadioButtonLabelModel]
public var children: [any MoleculeModelProtocol] { radioButtons }
//--------------------------------------------------
// MARK: - Form Validation
//--------------------------------------------------
/// Returns the fieldValue of the selected RadioButton.
public override func formFieldValue() -> AnyHashable? {
guard enabled else { return nil }
let selected = radioButtons.first { $0.radioButton.state }
return selected?.radioButton.formFieldValue()
}
//--------------------------------------------------
// MARK: - Server Value
//--------------------------------------------------
open override func formFieldServerValue() -> AnyHashable? {
return formFieldValue()
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case radioButtons
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(with radioButtons: [RadioButtonLabelModel]){
self.radioButtons = radioButtons
super.init()
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
radioButtons = try typeContainer.decode([RadioButtonLabelModel].self, forKey: .radioButtons)
try super.init(from: decoder)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(radioButtons, forKey: .radioButtons)
}
}

View File

@ -103,12 +103,15 @@ public typealias ActionBlockConfirmation = () -> (Bool)
}
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate)
isOn = viewModel.selected
surface = viewModel.surface
isAnimated = viewModel.animated
isEnabled = viewModel.enabled && !viewModel.readOnly
isEnabled = viewModel.isEnabled
showText = viewModel.showText
if let onText = viewModel.onText {
self.onText = onText

View File

@ -7,26 +7,18 @@
//
import VDS
public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
public class ToggleModel: FormFieldModel {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "toggle"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public override static var identifier: String { "toggle" }
public var selected: Bool = false
public var animated: Bool = true
public var enabled: Bool = true
public var readOnly: Bool = false
public var action: ActionModelProtocol?
public var alternateAction: ActionModelProtocol?
public var accessibilityText: String?
public var surface: Surface { inverted ? .dark : .light }
public var inverted: Bool = false
public var showText: Bool = false
public var onText: String?
public var offText: String?
@ -34,61 +26,41 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
public var textWeight: VDS.Toggle.TextWeight = .regular
public var textPosition: VDS.Toggle.TextPosition = .left
public var fieldKey: String?
public var groupName: String = FormValidator.defaultGroupName
public var baseValue: AnyHashable?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case state
case animated
case enabled
case readOnly
case action
case backgroundColor
case accessibilityIdentifier
case alternateAction
case accessibilityText
case inverted
case showText
case onText
case offText
case textSize
case textWeight
case textPosition
case fieldKey
case groupName
}
//--------------------------------------------------
// MARK: - Form Valdiation
//--------------------------------------------------
public func formFieldValue() -> AnyHashable? {
public override func formFieldValue() -> AnyHashable? {
guard enabled else { return nil }
return selected
}
//--------------------------------------------------
// MARK: - Server Value
//--------------------------------------------------
open func formFieldServerValue() -> AnyHashable? {
return formFieldValue()
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(_ state: Bool, id: String = UUID().uuidString) {
self.selected = state
selected = state
super.init()
baseValue = state
self.id = id
}
@ -100,8 +72,6 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) {
self.selected = state
}
@ -112,44 +82,28 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
baseValue = selected
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
self.groupName = groupName
}
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) ?? false
showText = try typeContainer.decodeIfPresent(Bool.self, forKey: .showText) ?? false
onText = try typeContainer.decodeIfPresent(String.self, forKey: .onText)
offText = try typeContainer.decodeIfPresent(String.self, forKey: .offText)
textSize = try typeContainer.decodeIfPresent(VDS.Toggle.TextSize.self, forKey: .textSize) ?? .small
textWeight = try typeContainer.decodeIfPresent(VDS.Toggle.TextWeight.self, forKey: .textWeight) ?? .regular
textPosition = try typeContainer.decodeIfPresent(VDS.Toggle.TextPosition.self, forKey: .textPosition) ?? .left
try super.init(from: decoder)
baseValue = selected
}
public func encode(to encoder: Encoder) throws {
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeModelIfPresent(action, forKey: .action)
try container.encodeModelIfPresent(alternateAction, forKey: .alternateAction)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(selected, forKey: .state)
try container.encode(animated, forKey: .animated)
try container.encode(enabled, forKey: .enabled)
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
try container.encodeIfPresent(groupName, forKey: .groupName)
try container.encode(readOnly, forKey: .readOnly)
try container.encode(inverted, forKey: .inverted)
try container.encode(showText, forKey: .showText)
try container.encodeIfPresent(onText, forKey: .onText)
try container.encodeIfPresent(offText, forKey: .offText)
@ -157,4 +111,19 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
try container.encode(textWeight, forKey: .textWeight)
try container.encode(textPosition, forKey: .textPosition)
}
open override func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard super.isEqual(to: model), let model = model as? Self else { return false }
return selected == model.selected
&& animated == model.animated
&& action.isEqual(to: model.action)
&& alternateAction.isEqual(to: model.alternateAction)
&& accessibilityText == model.accessibilityText
&& showText == model.showText
&& onText == model.onText
&& offText == model.offText
&& textSize == model.textSize
&& textWeight == model.textWeight
&& textPosition == model.textPosition
}
}

View File

@ -19,7 +19,8 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol {
}
public var moleculeName: String?
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var disabledColor: Color = Color(uiColor: .mvmCoolGray3)
public var color: Color = Color(uiColor: .mvmBlack)
@ -59,6 +60,7 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol {
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case backgroundColor
case disabledColor
@ -79,7 +81,8 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let disabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) {
self.disabledColor = disabledColor
}
@ -116,6 +119,7 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(disabledColor, forKey: .disabledColor)

View File

@ -27,10 +27,14 @@ open class Badge: VDS.Badge, VDSMoleculeViewProtocol {
//--------------------------------------------------
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
text = viewModel.text
textColor = viewModel.textColorStyle
maxWidth = viewModel.maxWidth
numberOfLines = viewModel.numberOfLines
fillColor = viewModel.fillColor
fillColor = viewModel.fillColorStyle
surface = viewModel.surface
}

View File

@ -25,6 +25,9 @@ open class BadgeIndicator: VDS.BadgeIndicator, VDSMoleculeViewProtocol {
//--------------------------------------------------
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
surface = viewModel.surface
number = viewModel.number
fillColor = viewModel.fillColor

View File

@ -17,7 +17,8 @@ open class BadgeIndicatorModel: MoleculeModelProtocol {
public static var identifier: String { "badgeIndicator" }
public var id: String = UUID().uuidString
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
//--------------------------------------------------
// MARK: - VDS Properties
//--------------------------------------------------
@ -43,6 +44,7 @@ open class BadgeIndicatorModel: MoleculeModelProtocol {
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case inverted
case accessibilityText
case number
@ -67,6 +69,7 @@ open class BadgeIndicatorModel: MoleculeModelProtocol {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.init()
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
inverted = try container.decodeIfPresent(Bool.self, forKey: .inverted) ?? false
accessibilityText = try container.decodeIfPresent(String.self, forKey: .accessibilityText)
number = try container.decodeIfPresent(Int.self, forKey: .number)
@ -91,6 +94,7 @@ open class BadgeIndicatorModel: MoleculeModelProtocol {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(inverted, forKey: .inverted)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
try container.encodeIfPresent(number, forKey: .number)
try container.encodeIfPresent(fillColor, forKey: .fillColor)

View File

@ -16,28 +16,46 @@ open class BadgeModel: MoleculeModelProtocol {
public static var identifier: String = "badge"
public var id: String = UUID().uuidString
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
//--------------------------------------------------
// MARK: - VDS Properties
//--------------------------------------------------
public var text: String = ""
public var textColorStyle: Badge.TextColor? = nil
public var accessibilityText: String?
public var maxWidth: CGFloat?
public var numberOfLines: Int = 1
public var fillColor = Badge.FillColor.red
public var fillColorStyle = Badge.FillColor.red
public var surface: Surface = .light
private enum CodingKeys: String, CodingKey {
case id, text, accessibilityText, fillColor, surface, numberOfLines, maxWidth
case id, accessibilityIdentifier, accessibilityText
case surface, numberOfLines, maxWidth
case text, textColor
case fillColor, fillColorStyle
}
required public convenience init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
text = try container.decode(String.self, forKey: .text)
accessibilityText = try container.decodeIfPresent(String.self, forKey: .accessibilityText)
fillColor = try container.decodeIfPresent(Badge.FillColor.self, forKey: .fillColor) ?? .red
//look for a textColor
if let textColor = try container.decodeIfPresent(Color.self, forKey: .textColor) {
textColorStyle = .custom(textColor.uiColor)
}
//look for a style
fillColorStyle = try container.decodeIfPresent(Badge.FillColor.self, forKey: .fillColorStyle) ?? .red
//look for a color and set the style
if let fillColor = try container.decodeIfPresent(Color.self, forKey: .fillColor) {
fillColorStyle = .custom(fillColor.uiColor)
}
surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .light
numberOfLines = try container.decodeIfPresent(Int.self, forKey: .numberOfLines) ?? 1
maxWidth = try container.decodeIfPresent(CGFloat.self, forKey: .maxWidth)
@ -48,16 +66,24 @@ open class BadgeModel: MoleculeModelProtocol {
try container.encode(id, forKey: .id)
try container.encode(text, forKey: .text)
try container.encode(accessibilityText, forKey: .accessibilityText)
try container.encode(fillColor, forKey: .fillColor)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(surface, forKey: .surface)
try container.encode(numberOfLines, forKey: .numberOfLines)
try container.encodeIfPresent(maxWidth, forKey: .maxWidth)
try container.encode(fillColorStyle, forKey: .fillColorStyle)
switch textColorStyle {
case .custom(let color):
try container.encode(Color(uiColor: color), forKey: .textColor)
default:
break
}
}
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? BadgeModel else { return false }
return self.backgroundColor == model.backgroundColor
&& self.fillColor == model.fillColor
&& self.fillColorStyle == model.fillColorStyle
&& self.textColorStyle == model.textColorStyle
&& self.numberOfLines == model.numberOfLines
&& self.text == model.text
&& self.surface == model.surface

View File

@ -25,6 +25,9 @@ open class ButtonIcon: VDS.ButtonIcon, VDSMoleculeViewProtocol {
//--------------------------------------------------
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
surface = viewModel.surface
onClick = { [weak self] control in

View File

@ -16,7 +16,8 @@ open class ButtonIconModel: ButtonModelProtocol, MoleculeModelProtocol {
public static var identifier: String = "buttonIcon"
public var id: String = UUID().uuidString
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
//--------------------------------------------------
// MARK: - VDS Properties
//--------------------------------------------------
@ -77,6 +78,7 @@ open class ButtonIconModel: ButtonModelProtocol, MoleculeModelProtocol {
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case inverted
case accessibilityText
case action
@ -105,6 +107,7 @@ open class ButtonIconModel: ButtonModelProtocol, MoleculeModelProtocol {
let container = try decoder.container(keyedBy: CodingKeys.self)
action = try container.decodeModel(codingKey: .action)
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
inverted = try container.decodeIfPresent(Bool.self, forKey: .inverted) ?? false
accessibilityText = try container.decodeIfPresent(String.self, forKey: .accessibilityText)
badgeIndicator = try container.decodeIfPresent(BadgeIndicatorModel.self, forKey: .badgeIndicator)
@ -128,6 +131,7 @@ open class ButtonIconModel: ButtonModelProtocol, MoleculeModelProtocol {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(inverted, forKey: .inverted)
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
try container.encodeIfPresent(badgeIndicator, forKey: .badgeIndicator)

View File

@ -0,0 +1,12 @@
//
// Calendar.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/20/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
open class CalendarView: VDS.CalendarBase, VDSMoleculeViewProtocol

View File

@ -0,0 +1,65 @@
//
// Calendar.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/20/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
open class CalendarView: VDS.CalendarBase, VDSMoleculeViewProtocol {
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
public var viewModel: CalendarViewModel!
public var delegateObject: MVMCoreUIDelegateObject?
public var additionalData: [AnyHashable : Any]?
//--------------------------------------------------
// MARK: - Public Methods
//--------------------------------------------------
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
if let _selectedDate = viewModel.selectedDate {
selectedDate = _selectedDate
}
if let _activeDates = viewModel.activeDates {
activeDates = _activeDates
}
if let _hideContainerBorder = viewModel.hideContainerBorder {
hideContainerBorder = _hideContainerBorder
}
if let _hideCurrentDateIndicator = viewModel.hideCurrentDateIndicator {
hideCurrentDateIndicator = _hideCurrentDateIndicator
}
if let _inactiveDates = viewModel.inactiveDates {
inactiveDates = _inactiveDates
}
if let _indicators = viewModel.indicators {
indicators = _indicators
}
if let _maxDate = viewModel.maxDate {
maxDate = _maxDate
}
if let _minDate = viewModel.minDate {
minDate = _minDate
}
surface = viewModel.surface
}
public func updateView(_ size: CGFloat) {}
}

View File

@ -0,0 +1,159 @@
//
// CalendarModel.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/20/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
open class CalendarViewModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "calendar"
public var id: String = UUID().uuidString
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeZone = NSTimeZone.system
formatter.locale = .current
formatter.formatterBehavior = .default
return formatter
}()
/// Update the property value to alter the format of how the date is presented.
public var dateFormat: String = "MMM d, y" {
didSet { dateFormatter.dateFormat = dateFormat }
}
public var hideContainerBorder: Bool?
public var hideCurrentDateIndicator: Bool?
public var activeDates: [Date]?
public var inactiveDates: [Date]?
public var selectedDate: Date?
public var minDate: Date?
public var maxDate: Date?
public var indicators: [CalendarBase.CalendarIndicatorModel]?
//--------------------------------------------------
// MARK: - VDS Properties
//--------------------------------------------------
public var surface: Surface { inverted ? .dark : .light }
public var inverted: Bool = false
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case inverted
case dateFormat
case hideContainerBorder
case hideCurrentDateIndicator
case activeDates
case inactiveDates
case selectedDate
case minDate
case maxDate
case indicators
}
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public init() {}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
inverted = try container.decodeIfPresent(Bool.self, forKey: .inverted) ?? false
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
hideContainerBorder = try container.decodeIfPresent(Bool.self, forKey: .hideContainerBorder)
hideCurrentDateIndicator = try container.decodeIfPresent(Bool.self, forKey: .hideCurrentDateIndicator)
if let dateFormat = try container.decodeIfPresent(String.self, forKey: .dateFormat) {
self.dateFormat = dateFormat
dateFormatter.dateFormat = dateFormat
}
if let dates = try container.decodeIfPresent([String].self, forKey: .activeDates) {
activeDates = dates.compactMap { dateFormatter.date(from: $0) }
}
if let dates = try container.decodeIfPresent([String].self, forKey: .inactiveDates) {
inactiveDates = dates.compactMap { dateFormatter.date(from: $0) }
}
if let date = try container.decodeIfPresent(String.self, forKey: .selectedDate) {
selectedDate = dateFormatter.date(from: date)
}
if let date = try container.decodeIfPresent(String.self, forKey: .minDate) {
minDate = dateFormatter.date(from: date)
}
if let date = try container.decodeIfPresent(String.self, forKey: .maxDate) {
maxDate = dateFormatter.date(from: date)
}
indicators = try container.decodeIfPresent([CalendarBase.CalendarIndicatorModel].self, forKey: .indicators)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(inverted, forKey: .inverted)
try container.encode(dateFormat, forKey: .dateFormat)
try container.encode(hideContainerBorder, forKey: .hideContainerBorder)
try container.encode(hideCurrentDateIndicator, forKey: .hideCurrentDateIndicator)
try container.encode(activeDates, forKey: .activeDates)
try container.encode(selectedDate, forKey: .selectedDate)
try container.encode(minDate, forKey: .minDate)
try container.encode(maxDate, forKey: .maxDate)
try container.encode(indicators, forKey: .indicators)
}
open func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return inverted == model.inverted
&& dateFormat == model.dateFormat
&& hideContainerBorder == model.hideContainerBorder
&& hideCurrentDateIndicator == model.hideCurrentDateIndicator
&& activeDates == model.activeDates
&& inactiveDates == model.inactiveDates
&& selectedDate == model.selectedDate
&& minDate == model.minDate
&& maxDate == model.maxDate
&& indicators == model.indicators
}
}
extension CalendarViewModel {
public func convertToVDSCalendarModel() -> DatePicker.CalendarModel {
let defaults = DatePicker.CalendarModel()
return .init(hideContainerBorder: hideContainerBorder ?? defaults.hideContainerBorder ,
hideCurrentDateIndicator: hideCurrentDateIndicator ?? defaults.hideCurrentDateIndicator,
activeDates: activeDates ?? defaults.activeDates,
inactiveDates: inactiveDates ?? defaults.inactiveDates,
selectedDate: selectedDate ?? defaults.selectedDate,
minDate: minDate ?? defaults.minDate,
maxDate: maxDate ?? defaults.maxDate,
indicators: indicators ?? defaults.indicators)
}
}

View File

@ -16,6 +16,7 @@ import MVMCore
public static var identifier: String = "caretView"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var strokeColor: Color = Color(uiColor: .mvmBlack)
public var strokeColor_inverted: Color = Color(uiColor: .mvmWhite)
@ -30,6 +31,7 @@ import MVMCore
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case backgroundColor
case strokeColor
@ -54,7 +56,8 @@ import MVMCore
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let strokeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .strokeColor) {
self.strokeColor = strokeColor
}
@ -84,6 +87,7 @@ import MVMCore
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(strokeColor, forKey: .strokeColor)
try container.encode(strokeColor_inverted, forKey: .strokeColor_inverted)
try container.encode(inverted, forKey: .inverted)

View File

@ -19,6 +19,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
}
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var moleculeName: String?
@ -48,6 +49,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case backgroundColor
case currentIndex
@ -70,6 +72,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
@ -118,6 +121,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(currentIndex, forKey: .currentIndex)
try container.encode(alwaysSendAction, forKey: .alwaysSendAction)

View File

@ -31,23 +31,20 @@ import VDS
// MARK: - Atomic
//--------------------------------------------------
open func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
surface = viewModel.surface
updateCheckbox()
//primary label
labelText = viewModel.label.text
if let attributes = viewModel.label.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData) {
labelTextAttributes = attributes
}
labelText = viewModel.label?.text
labelTextAttributes = viewModel.label?.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
//secondary label
if let subTitleModel = viewModel.subTitle {
childText = subTitleModel.text
if let attributes = subTitleModel.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData) {
childTextAttributes = attributes
}
}
childText = viewModel.subTitle?.text
childTextAttributes = viewModel.subTitle?.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
}
private func performCheckboxAction(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
@ -64,7 +61,7 @@ import VDS
//properties
isAnimated = viewModel.checkbox.animated
isEnabled = viewModel.checkbox.enabled && !viewModel.checkbox.readOnly
isEnabled = viewModel.checkbox.isEnabled
//call super here to go around the didSet
//in this class
@ -74,10 +71,11 @@ import VDS
viewModel.checkbox.updateUI = {
MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in
guard let self = self else { return }
let isValid = viewModel.checkbox.isValid ?? true
showError = !isValid
//let isValid = viewModel.checkbox.isValid ?? true
//TODO: Fix issue with default state
//showError = !isValid
errorText = viewModel.checkbox.errorMessage
isEnabled = viewModel.checkbox.enabled
isEnabled = viewModel.checkbox.isEnabled
})
}

View File

@ -14,17 +14,20 @@ import VDS
open class var identifier: String { "checkboxLabel" }
public var moleculeName: String = CheckboxLabelModel.identifier
@DecodableDefault.UUIDString public var id: String
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var checkbox: CheckboxModel
public var label: LabelModel
public var label: LabelModel?
public var subTitle: LabelModel?
public var inverted: Bool? = false
public var surface: Surface { inverted ?? false ? .dark : .light }
public var children: [MoleculeModelProtocol] {
guard let subTitle else { return [checkbox, label] }
return [checkbox, label, subTitle]
var values: [MoleculeModelProtocol] = [checkbox]
if let label { values.append(label) }
if let subTitle { values.append(subTitle) }
return values
}
//--------------------------------------------------
@ -36,5 +39,36 @@ import VDS
self.label = label
self.subTitle = subTitle
}
open func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return moleculeName == model.moleculeName
&& inverted == model.inverted
&& accessibilityText == model.accessibilityText
&& accessibilityIdentifier == model.accessibilityIdentifier
&& accessibilityTraits == model.accessibilityTraits
}
}
extension Array where Element == CheckboxLabelModel {
internal func convertToVDSCheckboxItemModel(surface: Surface,
delegateObject: MVMCoreUIDelegateObject?,
additionalData: [AnyHashable: Any]?) -> [CheckboxGroup.CheckboxItemModel] {
return compactMap({ model in
var item = CheckboxGroup.CheckboxItemModel()
item.inputId = model.checkbox.fieldKey
item.labelText = model.label?.text
if let attributes = model.label?.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData) {
item.labelTextAttributes = attributes
}
item.childText = model.subTitle?.text
if let attributes = model.subTitle?.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData) {
item.childTextAttributes = attributes
}
item.surface = surface
item.selected = model.checkbox.selected
item.enabled = model.checkbox.isEnabled
return item
})
}
}

View File

@ -107,15 +107,15 @@ import UIKit
// configure attributed string for progress percentage.
let attributedString = NSMutableAttributedString(string: String(percent) + "%")
// percent value
attributedString.setAttributes([NSAttributedString.Key.font: MFStyler.fontBoldTitleLarge()], range: NSMakeRange(0, percentLen))
attributedString.setAttributes([NSAttributedString.Key.font: Styler.Font.BoldTitleXLarge], range: NSMakeRange(0, percentLen))
// % symbol
attributedString.setAttributes([NSAttributedString.Key.font: MFStyler.fontBoldBodyLarge()], range: NSMakeRange(percentLen, 1))
attributedString.setAttributes([NSAttributedString.Key.font: Styler.Font.RegularMicro], range: NSMakeRange(percentLen, 1))
// show progress percentage in a text layer
let width = viewWidth
let height = width
labelLayer.string = attributedString
labelLayer.frame = CGRectMake((width - CGFloat(percentLen * 20))/2, (height - 30)/2, 60, 30)
labelLayer.frame = CGRectMake((width - CGFloat(percentLen * 20))/2, (height - 40)/2, 80, 40)
self.layer.addSublayer(labelLayer)
}

View File

@ -14,7 +14,8 @@ public class CircularProgressBarModel: GraphSizeBase, MoleculeModelProtocol {
public static var identifier: String = "circularProgress"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var percent: Int = 0
public var diameter: CGFloat? = 64
public var lineWidth: CGFloat? = 4
@ -31,6 +32,7 @@ public class CircularProgressBarModel: GraphSizeBase, MoleculeModelProtocol {
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case percent
case size
@ -48,7 +50,8 @@ public class CircularProgressBarModel: GraphSizeBase, MoleculeModelProtocol {
super.init()
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
percent = try typeContainer.decode(Int.self, forKey: .percent)
if let size = try typeContainer.decodeIfPresent(GraphSize.self, forKey: .size) {
@ -89,6 +92,7 @@ public class CircularProgressBarModel: GraphSizeBase, MoleculeModelProtocol {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(percent, forKey: .percent)
try container.encodeIfPresent(size, forKey: .size)
try container.encodeIfPresent(diameter, forKey: .diameter)

View File

@ -31,11 +31,15 @@ open class Icon: VDS.Icon, VDSMoleculeViewProtocol{
// MARK: - Public
//--------------------------------------------------
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
surface = viewModel.surface
color = viewModel.color.uiColor
size = viewModel.size
customSize = viewModel.customSize
name = viewModel.name
isAccessibilityElement = viewModel.isAccessibilityElement ?? true
}
//--------------------------------------------------

View File

@ -21,6 +21,8 @@ open class IconModel: MoleculeModelProtocol {
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
/// A representation that will be used to render the icon with corresponding name.
public var name: Icon.Name
@ -35,4 +37,6 @@ open class IconModel: MoleculeModelProtocol {
/// A custom size of the icon.
public var customSize: Int?
public var isAccessibilityElement: Bool?
}

View File

@ -18,6 +18,7 @@
public var backgroundColor: Color?
public var moleculeName: String = ImageViewModel.identifier
public var image: String
public var accessibilityIdentifier: String?
public var accessibilityText: String?
public var fallbackImage: String?
public var imageFormat: String?
@ -47,6 +48,7 @@
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case backgroundColor
case image

View File

@ -16,13 +16,15 @@ public class FormLabel: Label {
//public properties
public override var isEnabled: Bool {
didSet{
self.formModel.enabled = isEnabled
guard let formModel else { return }
formModel.enabled = isEnabled
self.set(with: isRequired ? formModel.model : formModel.requiredModel, delegateObject, additionalData)
}
}
public var isRequired: Bool = true {
didSet{
guard let formModel else { return }
self.set(with: isRequired ? formModel.model : formModel.requiredModel, delegateObject, additionalData)
}
}
@ -50,6 +52,7 @@ public class FormLabel: Label {
/// Text change that will update both enabledModel and disabledModel text values
/// - Parameter text: text you want to see
public func set(text: String?){
self.formModel.set(text: text ?? "")
guard let formModel else { return }
formModel.set(text: text ?? "")
}
}

View File

@ -182,6 +182,9 @@ public typealias ActionBlock = () -> ()
}
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
shouldMaskWhileRecording = viewModel.shouldMaskRecordedView ?? false
text = viewModel.text
hero = viewModel.hero

View File

@ -14,7 +14,8 @@ import VDS
open class var identifier: String { "label" }
public var id: String
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var text: String
public var accessibilityText: String?
@ -38,6 +39,7 @@ import VDS
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case text
case accessibilityText
@ -88,6 +90,7 @@ import VDS
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
text = try typeContainer.decode(String.self, forKey: .text)
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor)
@ -115,6 +118,7 @@ import VDS
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(moleculeName, forKey: .moleculeName)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(text, forKey: .text)
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
try container.encodeIfPresent(textColor, forKey: .textColor)

View File

@ -16,7 +16,8 @@ import UIKit
public static var identifier: String = "leftRightLabelView"
public var moleculeName: String = LeftRightLabelModel.identifier
@DecodableDefault.UUIDString public var id: String
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var leftText: LabelModel
public var rightText: LabelModel?

View File

@ -66,7 +66,7 @@ import VDS
}
open func setStyle(_ style: LineModel.Style) {
viewModel.type = style
viewModel?.type = style
update(viewModel: viewModel)
}
@ -85,7 +85,7 @@ import VDS
}
open override func draw(_ rect: CGRect) {
guard viewModel.type != .none else { return }
guard let viewModel, viewModel.type != .none else { return }
super.draw(rect)
}
@ -93,6 +93,9 @@ import VDS
// MARK: - VDSMoleculeViewProtocol
//--------------------------------------------------
open func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
surface = viewModel.surface
style = VDS.Line.Style(rawValue: viewModel.type.rawValue) ?? .primary
orientation = viewModel.orientation

View File

@ -55,6 +55,7 @@ public class LineModel: MoleculeModelProtocol, Invertable {
public static var identifier: String = "line"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var type: Style = .secondary
@ -83,6 +84,7 @@ public class LineModel: MoleculeModelProtocol, Invertable {
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case type
case frequency
@ -99,7 +101,8 @@ public class LineModel: MoleculeModelProtocol, Invertable {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let type = try typeContainer.decodeIfPresent(Style.self, forKey: .type) {
self.type = type
}
@ -124,6 +127,7 @@ public class LineModel: MoleculeModelProtocol, Invertable {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(type, forKey: .type)
try container.encode(inverted, forKey: .inverted)
try container.encodeIfPresent(frequency, forKey: .frequency)

View File

@ -22,6 +22,9 @@ open class LoadingSpinner: VDS.Loader, VDSMoleculeViewProtocol {
// MARK: - Public Functions
//--------------------------------------------------
open func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
size = Int(viewModel.diameter)
surface = viewModel.surface
}

View File

@ -16,7 +16,8 @@ open class LoadingSpinnerModel: MoleculeModelProtocol {
//--------------------------------------------------
public static var identifier: String = "loadingSpinner"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var inverted: Bool = false
public var diameter: CGFloat = 40
@ -27,6 +28,7 @@ open class LoadingSpinnerModel: MoleculeModelProtocol {
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case strokeColor
case diameter
@ -47,7 +49,8 @@ open class LoadingSpinnerModel: MoleculeModelProtocol {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let diameter = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .diameter) {
self.diameter = diameter
}
@ -65,6 +68,7 @@ open class LoadingSpinnerModel: MoleculeModelProtocol {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(diameter, forKey: .diameter)
try container.encodeIfPresent(inverted, forKey: .inverted)
}

View File

@ -22,7 +22,8 @@ import Foundation
public static var identifier: String = "multiProgressBar"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var progressList: [SingleProgressBarModel]
public var backgroundColor: Color?
public var thickness: CGFloat?
@ -30,6 +31,7 @@ import Foundation
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case progressList
case thickness
@ -44,6 +46,7 @@ import Foundation
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
progressList = try typeContainer.decode([SingleProgressBarModel].self, forKey: .progressList)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness)
@ -54,6 +57,7 @@ import Foundation
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(progressList, forKey: .progressList)
try container.encodeIfPresent(thickness, forKey: .thickness)
try container.encodeIfPresent(roundedCorners, forKey: .roundedCorners)

View File

@ -0,0 +1,60 @@
//
// Pagination.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/27/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
@objcMembers open class Pagination: VDS.Pagination, VDSMoleculeViewProtocol {
//------------------------------------------------------
// MARK: - Properties
//------------------------------------------------------
open var viewModel: PaginationModel!
open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
// Form Validation
open var fieldKey: String?
open var fieldValue: JSONValue?
open var groupName: String?
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public convenience required init() {
self.init(frame:.zero)
}
open override func setup() {
super.setup()
pageChangedPublisher
.sink { [weak self] control in
guard let self else { return }
viewModel?.selectedPage = control.selectedPage
}.store(in: &subscribers)
}
open func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
isEnabled = viewModel.enabled
surface = viewModel.surface
total = viewModel.totalPages
selectedPage = viewModel.selectedPage
}
//--------------------------------------------------
// MARK: - Actions
//--------------------------------------------------
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
public func updateView(_ size: CGFloat) {}
}

View File

@ -0,0 +1,76 @@
//
// PaginationModel.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/27/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
import MVMCore
open class PaginationModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
open class var identifier: String { "pagination" }
open var moleculeName: String { Self.identifier }
open var backgroundColor: Color?
open var id: String = UUID().uuidString
open var accessibilityIdentifier: String?
open var totalPages: Int = 0
open var selectedPage: Int = 0
open var enabled: Bool = true
open var inverted: Bool = false
open var surface: Surface { inverted ? .dark : .light }
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case accessibilityIdentifier
case totalPages
case selectedPage
case enabled
case inverted
}
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
totalPages = try container.decode(Int.self, forKey: .totalPages)
selectedPage = try container.decodeIfPresent(Int.self, forKey: .selectedPage) ?? 0
enabled = try container.decodeIfPresent(Bool.self, forKey: .enabled) ?? false
inverted = try container.decodeIfPresent(Bool.self, forKey: .inverted) ?? false
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(totalPages, forKey: .totalPages)
try container.encode(selectedPage, forKey: .selectedPage)
try container.encode(enabled, forKey: .enabled)
try container.encode(inverted, forKey: .inverted)
}
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return inverted == model.inverted
&& enabled == model.enabled
&& totalPages == model.totalPages
&& selectedPage == model.selectedPage
}
}

View File

@ -75,6 +75,9 @@ import Foundation
guard let progressBarModel = model as? ProgressBarModel else { return }
self.progressBarModel = progressBarModel
if let accessibilityIdentifier = model.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
thickness = progressBarModel.thickness ?? 8
progress = Float((progressBarModel.percent) / 100.0)
progressTintColor = progressBarModel.color.uiColor

View File

@ -11,7 +11,8 @@ import Foundation
@objcMembers open class ProgressBarModel: MoleculeModelProtocol {
open class var identifier: String { "progressBar" }
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
@Percent public var percent: CGFloat
public var color: Color = Color(uiColor: .mfCerulean())
public var backgroundColor: Color? = Color(uiColor: .mfLightSilver())
@ -20,6 +21,7 @@ import Foundation
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case roundedCorners
case thickness
@ -35,6 +37,7 @@ import Foundation
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
percent = try typeContainer.decode(CGFloat.self, forKey: .percent)
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) {
self.color = color
@ -50,6 +53,7 @@ import Foundation
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(percent, forKey: .percent)
try container.encode(color, forKey: .color)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)

View File

@ -14,7 +14,8 @@ open class StarModel: MoleculeModelProtocol {
//--------------------------------------------------
public static var identifier: String = "star"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
@Percent public var percent: CGFloat = 0
public var borderColor: Color?
@ -26,6 +27,7 @@ open class StarModel: MoleculeModelProtocol {
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case backgroundColor
case percent
@ -47,6 +49,7 @@ open class StarModel: MoleculeModelProtocol {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let percent = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .percent) {
self.percent = percent
}
@ -63,6 +66,7 @@ open class StarModel: MoleculeModelProtocol {
try container.encode(id, forKey: .id)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(percent, forKey: .percent)
try container.encodeIfPresent(borderColor, forKey: .borderColor)
try container.encodeIfPresent(fillColor, forKey: .fillColor)

View File

@ -14,7 +14,8 @@ import MVMCore
//--------------------------------------------------
public static var identifier: String = "stars"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var starBackgroundColor: Color?
public var stars: [StarModel]
@ -28,6 +29,7 @@ import MVMCore
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case backgroundColor
case starBackgroundColor
@ -53,6 +55,7 @@ import MVMCore
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
stars = try typeContainer.decode([StarModel].self, forKey: .stars)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
starBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .starBackgroundColor)
@ -70,6 +73,7 @@ import MVMCore
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(stars, forKey: .stars)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(starBackgroundColor, forKey: .starBackgroundColor)

View File

@ -40,7 +40,9 @@ open class TileContainer: VDS.TileContainer, VDSMoleculeViewProtocol{
// MARK: - Public
//--------------------------------------------------
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
if let moleculeModel = viewModel.molecule {
if let molecule,
moleculeModel.moleculeName == molecule.model?.moleculeName {
@ -99,7 +101,9 @@ open class TileContainer: VDS.TileContainer, VDSMoleculeViewProtocol{
//--------------------------------------------------
// MARK: - MVMCoreViewProtocol
//--------------------------------------------------
open func updateView(_ size: CGFloat) {}
open func updateView(_ size: CGFloat) {
(molecule as? MVMCoreViewProtocol)?.updateView(size)
}
//--------------------------------------------------
// MARK: - MoleculeViewProtocol

View File

@ -70,8 +70,10 @@ open class TileContainerBaseModel<PaddingType: DefaultValuing & Codable, TileCon
public var aspectRatio: TileContainerType.AspectRatio = .none
public var backgroundEffect: TileContainerType.BackgroundEffect = .none
public var surface: Surface { inverted ? .dark : .light }
public var accessibilityIdentifier: String?
private enum CodingKeys: String, CodingKey {
case accessibilityIdentifier
case inverted
case backgroundImage
case action
@ -88,6 +90,7 @@ open class TileContainerBaseModel<PaddingType: DefaultValuing & Codable, TileCon
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
inverted = try container.decodeIfPresent(Bool.self, forKey: .inverted) ?? false
backgroundImage = try container.decodeIfPresent(String.self, forKey: .backgroundImage)
action = try container.decodeModelIfPresent(codingKey: .action)
@ -104,6 +107,7 @@ open class TileContainerBaseModel<PaddingType: DefaultValuing & Codable, TileCon
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(backgroundImage, forKey: .backgroundImage)
try container.encodeModelIfPresent(action, forKey: .action)
try container.encodeIfPresent(imageFallbackColor, forKey: .imageFallbackColor)

View File

@ -39,6 +39,9 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{
// MARK: - Public
//--------------------------------------------------
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
//tilelet specific properties
if let value = viewModel.textWidth {
textWidth = .value(value)
@ -48,7 +51,7 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{
eyebrowModel = viewModel.eyebrowModel(delegateObject: delegateObject, additionalData: additionalData)
titleModel = viewModel.titleModel(delegateObject: delegateObject, additionalData: additionalData)
subTitleModel = viewModel.subTitleModel(delegateObject: delegateObject, additionalData: additionalData)
badgeModel = viewModel.badge
badgeModel = viewModel.badgeModel()
descriptiveIconModel = viewModel.descriptiveIcon
directionalIconModel = viewModel.directionalIcon
//setup action

View File

@ -18,7 +18,7 @@ open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, Molec
public var id: String = UUID().uuidString
public var backgroundColor: Color?
public var badge: Tilelet.BadgeModel?
public var badge: BadgeModel?
public var eyebrow: LabelModel?
public var eyebrowColor: TitleLockup.TextColor = .primary
public var title: LabelModel?
@ -49,7 +49,7 @@ open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, Molec
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
badge = try container.decodeIfPresent(Tilelet.BadgeModel.self, forKey: .badge)
badge = try container.decodeIfPresent(BadgeModel.self, forKey: .badge)
eyebrow = try container.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
title = try container.decodeIfPresent(LabelModel.self, forKey: .title)
subTitle = try container.decodeIfPresent(LabelModel.self, forKey: .subTitle)
@ -91,32 +91,48 @@ open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, Molec
try super.init(from: decoder)
}
public func badgeModel() -> Tilelet.BadgeModel? {
guard let badge else { return nil }
return .init(text: badge.text,
textColor: badge.textColorStyle,
fillColor: badge.fillColorStyle,
surface: badge.surface,
numberOfLines: badge.numberOfLines,
maxWidth: badge.maxWidth
)
}
public func eyebrowModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.EyebrowModel? {
guard let eyebrow else { return nil }
let attrs = eyebrow.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
var isBold: Bool = true
do {
if let style = eyebrow.fontStyle {
isBold = style.isBold()
return .init(text: eyebrow.text,
textColor: eyebrowColor,
textAttributes: attrs, isBold: style.isBold(),
textAttributes: attrs,
isBold: isBold,
standardStyle: try style.vdsSubsetStyle())
}
} catch MVMCoreError.errorObject(let object) {
MVMCoreLoggingHandler.shared()?.addError(toLog: object)
} catch { }
return .init(text: eyebrow.text, textColor: eyebrowColor, textAttributes: attrs)
return .init(text: eyebrow.text, textColor: eyebrowColor, textAttributes: attrs, isBold: isBold)
}
public func titleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.TitleModel? {
guard let title else { return nil }
let attrs = title.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
var isBold: Bool = true
do {
if let style = title.fontStyle {
isBold = style.isBold()
return .init(text: title.text,
textColor: titleColor,
textAttributes: attrs,
isBold: isBold,
standardStyle: try style.vdsSubsetStyle())
}
@ -124,7 +140,7 @@ open class TileletModel: TileContainerBaseModel<Tilelet.Padding, Tilelet>, Molec
MVMCoreLoggingHandler.shared()?.addError(toLog: object)
} catch { }
return .init(text: title.text, textColor: titleColor, textAttributes: attrs)
return .init(text: title.text, textColor: titleColor, textAttributes: attrs, isBold: isBold)
}
public func subTitleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.SubTitleModel? {

View File

@ -28,6 +28,9 @@ open class Tooltip: VDS.Tooltip, VDSMoleculeViewProtocol{
// MARK: - Public
//--------------------------------------------------
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
surface = viewModel.surface
fillColor = viewModel.fillColor
size = viewModel.size

View File

@ -22,6 +22,8 @@ open class TooltipModel: MoleculeModelProtocol {
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var size: VDS.Tooltip.Size = .medium
public var fillColor: VDS.Tooltip.FillColor = .primary
@ -39,6 +41,7 @@ open class TooltipModel: MoleculeModelProtocol {
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case backgroundColor
case closeButtonText
@ -52,13 +55,14 @@ open class TooltipModel: MoleculeModelProtocol {
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
self.backgroundColor = try container.decodeIfPresent(Color.self, forKey: .backgroundColor)
id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
backgroundColor = try container.decodeIfPresent(Color.self, forKey: .backgroundColor)
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
self.title = try container.decodeIfPresent(String.self, forKey: .title)
self.content = try container.decodeIfPresent(String.self, forKey: .content)
title = try container.decodeIfPresent(String.self, forKey: .title)
content = try container.decodeIfPresent(String.self, forKey: .content)
self.molecule = try container.decodeModelIfPresent(codingKey: .contentView)
molecule = try container.decodeModelIfPresent(codingKey: .contentView)
if let closeButtonText = try container.decodeIfPresent(String.self, forKey: .closeButtonText) {
self.closeButtonText = closeButtonText
@ -81,6 +85,7 @@ open class TooltipModel: MoleculeModelProtocol {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(surface, forKey: .surface)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
@ -98,7 +103,7 @@ open class TooltipModel: MoleculeModelProtocol {
}
extension TooltipModel {
public func toVDSTooltipModel() -> Tooltip.TooltipModel {
public func convertToVDSTooltipModel() -> Tooltip.TooltipModel {
var moleculeView: MoleculeViewProtocol?
if let molecule, let view = ModelRegistry.createMolecule(molecule) {
moleculeView = view

View File

@ -11,6 +11,7 @@ import Foundation
open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer {
public static var identifier = "video"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var video: String
public var showControls = false
@ -45,6 +46,7 @@ open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer {
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case moleculeName
case video
case showControls
@ -60,6 +62,7 @@ open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
video = try typeContainer.decode(String.self, forKey:.video)
if let showControls = try typeContainer.decodeIfPresent(Bool.self, forKey: .showControls) {
self.showControls = showControls
@ -76,6 +79,7 @@ open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer {
open func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(video, forKey: .video)
try container.encode(showControls, forKey: .showControls)

View File

@ -13,7 +13,8 @@ import MVMCore
public static var identifier: String = "webview"
public var moleculeName: String = WebViewModel.identifier
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var url: URL?
public var htmlString: String?
@ -26,6 +27,7 @@ import MVMCore
private enum CodingKeys: String, CodingKey{
case id
case accessibilityIdentifier
case moleculeName
case backgroundColor
case url
@ -43,6 +45,7 @@ import MVMCore
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
url = try typeContainer.decodeIfPresent(URL.self, forKey: .url)
htmlString = try typeContainer.decodeIfPresent(String.self, forKey: .htmlString)
@ -57,6 +60,7 @@ import MVMCore
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(url, forKey: .url)
try container.encodeIfPresent(htmlString, forKey: .htmlString)

View File

@ -16,7 +16,8 @@ public class WheelModel: GraphSizeBase, MoleculeModelProtocol {
public static var identifier: String = "wheel"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var style: GraphStyle = .unlimited {
didSet {
updateStyle()
@ -38,6 +39,7 @@ public class WheelModel: GraphSizeBase, MoleculeModelProtocol {
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case style
case size
case diameter
@ -53,7 +55,8 @@ public class WheelModel: GraphSizeBase, MoleculeModelProtocol {
super.init()
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
if let style = try typeContainer.decodeIfPresent(GraphStyle.self, forKey: .style) {
self.style = style
}
@ -84,6 +87,7 @@ public class WheelModel: GraphSizeBase, MoleculeModelProtocol {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(style, forKey: .style)
try container.encode(size, forKey: .size)
try container.encode(diameter, forKey: .diameter)

View File

@ -9,13 +9,13 @@
import Foundation
import VDS
import VDSCoreTokens
import MVMCore
//--------------------------------------------------
// MARK: - Codable Extensions
//--------------------------------------------------
extension VDS.Surface: Codable {}
extension VDS.Badge.FillColor: Codable {}
extension VDS.BadgeIndicator.FillColor: Codable {}
extension VDS.BadgeIndicator.Kind: Codable {}
extension VDS.BadgeIndicator.MaximumDigits: Codable {}
@ -57,6 +57,52 @@ extension VDS.Button.Size: RawRepresentableCodable {
public static var defaultValue: VDS.Button.Size? { nil }
}
extension VDS.CalendarBase.CalendarIndicatorModel: Codable, ModelComparisonProtocol, MoleculeModelComparisonProtocol {
enum CodingKeys: String, CodingKey {
case label
case date
case dateFormat
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let label = try container.decode(String.self, forKey: .label)
let formatter = Self.formatter()
formatter.dateFormat = try container.decodeIfPresent(String.self, forKey: .dateFormat) ?? "MMM d, y"
let foundDate = try container.decode(String.self, forKey: .date)
let date = formatter.date(from: foundDate)!
self = .init(label: label, date: date)
}
public func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(label, forKey: .label)
try container.encode(Self.formatter().string(from: date), forKey: .date)
}
static func formatter() -> DateFormatter {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeZone = NSTimeZone.system
formatter.locale = .current
formatter.formatterBehavior = .default
return formatter
}
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return label == model.label
&& date == model.date
}
public func isVisuallyEquivalent(to model: any MoleculeModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return label == model.label
&& date == model.date
}
}
//--------------------------------------------------
// MARK: - Decodable Defaults
//--------------------------------------------------
@ -247,6 +293,45 @@ extension VDS.TitleLockup.TextColor: Codable {
}
}
extension VDS.Badge.FillColor: Codable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let type = try container.decode(String.self)
switch type {
case "red":
self = .red
case "yellow":
self = .yellow
case "green":
self = .green
case "orange":
self = .orange
case "blue":
self = .blue
case "black":
self = .black
case "white":
self = .white
default:
if let color = try? Color(from: decoder) {
self = .custom(color.uiColor)
} else {
self = .custom(UIColor(hexString: type))
}
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .custom(let value):
try container.encode(Color(uiColor: value))
default:
try container.encode(String(reflecting: self))
}
}
}
extension VDS.TitleLockup.TitleTextColor: Codable {
enum CodingKeys: String, CodingKey {

View File

@ -16,7 +16,7 @@ extension Array where Element: MVMCoreUI.LabelAttributeModel {
var attributes: [any VDS.LabelAttributeModel] = []
forEach { atomicLabelAttribute in
if let attr = atomicLabelAttribute as? (any VDSLabelAttributeConvertable),
let vds = attr.convertToVDSLabelAttirbute(delegateObject: delegateObject,
let vds = attr.convertToVDSLabelAttribute(delegateObject: delegateObject,
additionalData: additionalData){
attributes.append(vds)
}
@ -28,12 +28,12 @@ extension Array where Element: MVMCoreUI.LabelAttributeModel {
//VDS Convertable Protocol and Extensions
public protocol VDSLabelAttributeConvertable<LabelAttributeType> {
associatedtype LabelAttributeType: VDS.LabelAttributeModel
func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> LabelAttributeType?
func convertToVDSLabelAttribute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> LabelAttributeType?
}
extension LabelAttributeUnderlineModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> UnderlineLabelAttribute? {
public func convertToVDSLabelAttribute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> UnderlineLabelAttribute? {
guard let style = UnderlineLabelAttribute.Style(rawValue: style.rawValue) else { return nil }
var pattern: UnderlineLabelAttribute.Pattern?
@ -50,7 +50,7 @@ extension LabelAttributeUnderlineModel: VDSLabelAttributeConvertable {
}
extension LabelAttributeActionModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> ActionLabelAttribute? {
public func convertToVDSLabelAttribute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> ActionLabelAttribute? {
var vdsAttribute = VDS.ActionLabelAttribute(location: location, length: length)
vdsAttribute.subscriber = vdsAttribute.action.sink { [weak self] in
guard let self else { return }
@ -64,11 +64,13 @@ extension LabelAttributeActionModel: VDSLabelAttributeConvertable {
}
extension LabelAttributeFontModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> TextStyleLabelAttribute? {
public func convertToVDSLabelAttribute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> TextStyleLabelAttribute? {
var textStyle: TextStyle?
if let found = style?.vdsTextStyle() {
textStyle = found
} else if let name, let size, let font = UIFont(name: name, size: size) {
textStyle = TextStyle.convert(font: font)
} else if let name, let found = TextStyle(rawValue: name) {
textStyle = found
}
@ -82,7 +84,7 @@ extension LabelAttributeFontModel: VDSLabelAttributeConvertable {
}
extension LabelAttributeColorModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> ColorLabelAttribute? {
public func convertToVDSLabelAttribute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> ColorLabelAttribute? {
guard let textColor else { return nil }
return ColorLabelAttribute(location: location,
length: length,
@ -91,14 +93,14 @@ extension LabelAttributeColorModel: VDSLabelAttributeConvertable {
}
extension LabelAttributeStrikeThroughModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> StrikeThroughLabelAttribute? {
public func convertToVDSLabelAttribute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> StrikeThroughLabelAttribute? {
return StrikeThroughLabelAttribute(location: location,
length: length)
}
}
extension LabelAttributeImageModel: VDSLabelAttributeConvertable {
public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> AtomicImageLabelAttribute? {
public func convertToVDSLabelAttribute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> AtomicImageLabelAttribute? {
var frame: CGRect?
if let size {
frame = CGRect(x: 0, y: 0, width: size, height: size)

View File

@ -0,0 +1,59 @@
//
// Breadcrumbs.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/26/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
@objcMembers open class Breadcrumbs: VDS.Breadcrumbs, VDSMoleculeViewProtocol {
//------------------------------------------------------
// MARK: - Properties
//------------------------------------------------------
open var viewModel: BreadcrumbsModel!
open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
// Form Validation
open var fieldKey: String?
open var fieldValue: JSONValue?
open var groupName: String?
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public convenience required init() {
self.init(frame:.zero)
}
open func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
isEnabled = viewModel.enabled
surface = viewModel.surface
breadcrumbModels = viewModel.breadcrumbs.compactMap { [unowned self] breadcrumb in
return .init(text: breadcrumb.text,
selected: breadcrumb.selected,
onClick: { _ in
MVMCoreUIActionHandler.performActionUnstructured(with: breadcrumb.action,
sourceModel: breadcrumb,
additionalData: self.additionalData,
delegateObject: self.delegateObject)
})
}
}
//--------------------------------------------------
// MARK: - Actions
//--------------------------------------------------
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
public func updateView(_ size: CGFloat) {}
}

View File

@ -0,0 +1,124 @@
//
// BreadCrumbs.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/26/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
import MVMCore
open class BreadcrumbsModel: MoleculeModelProtocol, ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
open class var identifier: String { "breadcrumbs" }
open var moleculeName: String { Self.identifier }
open var backgroundColor: Color?
open var id: String = UUID().uuidString
open var accessibilityIdentifier: String?
open var children: [any MoleculeModelProtocol] { breadcrumbs }
open var breadcrumbs: [BreadcrumbModel] = []
open var enabled: Bool = true
open var inverted: Bool = false
open var surface: Surface { inverted ? .dark : .light }
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case accessibilityIdentifier
case moleculeName
case breadcrumbs
case enabled
case inverted
}
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
breadcrumbs = try container.decode([BreadcrumbModel].self, forKey: .breadcrumbs)
enabled = try container.decodeIfPresent(Bool.self, forKey: .enabled) ?? false
inverted = try container.decodeIfPresent(Bool.self, forKey: .inverted) ?? false
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(breadcrumbs, forKey: .breadcrumbs)
try container.encode(enabled, forKey: .enabled)
try container.encode(inverted, forKey: .inverted)
}
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return inverted == model.inverted
&& enabled == model.enabled
}
}
open class BreadcrumbModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
open class var identifier: String { "breadcrumb" }
open var moleculeName: String { Self.identifier }
open var backgroundColor: Color?
open var id: String = UUID().uuidString
open var accessibilityIdentifier: String?
open var text: String = ""
open var selected: Bool = false
open var action: ActionModelProtocol
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case accessibilityIdentifier
case text
case selected
case action
}
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
accessibilityIdentifier = try container.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
text = try container.decode(String.self, forKey: .text)
selected = try container.decodeIfPresent(Bool.self, forKey: .selected) ?? false
action = try container.decodeModel(codingKey: .action)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(text, forKey: .text)
try container.encode(selected, forKey: .selected)
try container.encodeModelIfPresent(action, forKey: .action)
}
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return text == model.text
&& selected == model.selected
&& action.isEqual(to: model.action)
}
}

View File

@ -52,6 +52,9 @@ public class HeadersH1ButtonModel: HeaderModel, MoleculeModelProtocol, ParentMol
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
}
//--------------------------------------------------

View File

@ -31,6 +31,9 @@ public class HeadersH1NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
}
//--------------------------------------------------

View File

@ -47,18 +47,15 @@ public class HeadersH2ButtonsModel: HeaderModel, MoleculeModelProtocol, ParentMo
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if titleLockup.title.fontStyle == nil {
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
}
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -42,18 +42,15 @@ public class HeadersH2CaretLinkModel: HeaderModel, MoleculeModelProtocol, Parent
// MARK: - Methods
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if titleLockup.title.fontStyle == nil {
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
}
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -46,18 +46,15 @@ public class HeadersH2LinkModel: HeaderModel, ParentMoleculeModelProtocol {
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if titleLockup.title.fontStyle == nil {
if titleLockup.title.fontStyle == nil {
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
}
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -36,18 +36,15 @@ public class HeadersH2NoButtonsBodyTextModel: HeaderModel, MoleculeModelProtocol
}
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if titleLockup.title.fontStyle == nil {
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
}
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -57,12 +57,6 @@ public class HeadersH2PricingTwoRowsModel: HeaderModel, MoleculeModelProtocol, P
// MARK: - Methods
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if headline.accessibilityTraits == nil {
headline.accessibilityTraits = .header
}

View File

@ -47,18 +47,15 @@ public class HeadersH2TinyButtonModel: HeaderModel, MoleculeModelProtocol, Paren
//--------------------------------------------------
public override func setDefaults() {
if topPadding == nil {
topPadding = Padding.Component.VerticalMarginSpacing
}
if bottomPadding == nil {
bottomPadding = Padding.Component.VerticalMarginSpacing
}
if titleLockup.title.fontStyle == nil {
titleLockup.title.fontStyle = Styler.Font.RegularTitleXLarge
}
if titleLockup.subTitle?.fontStyle == nil {
titleLockup.subTitle?.fontStyle = Styler.Font.RegularTitleMedium
}
if titleLockup.title.accessibilityTraits == nil {
titleLockup.title.accessibilityTraits = [.header]
}
super.setDefaults()
button.style = .secondary
button.size = .small

View File

@ -14,7 +14,8 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol {
//--------------------------------------------------
public static var identifier: String = "planNamesLockup"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var headline: LabelModel
public var subHeadline: LabelModel
@ -35,6 +36,7 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol {
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case accessibilityIdentifier
case backgroundColor
case headline
case subHeadline
@ -47,6 +49,7 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
headline = try typeContainer.decode(LabelModel.self, forKey: .headline)
subHeadline = try typeContainer.decode(LabelModel.self, forKey: .subHeadline)
@ -57,6 +60,7 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(headline, forKey: .headline)
try container.encode(subHeadline, forKey: .subHeadline)

View File

@ -15,7 +15,8 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol {
public static var identifier: String = "planLockup"
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var planLabel : LabelModel
public var headline : LabelModel
@ -47,6 +48,7 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol {
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case accessibilityIdentifier
case backgroundColor
case planLabel
case headline
@ -61,6 +63,7 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
planLabel = try typeContainer.decode(LabelModel.self, forKey: .planLabel)
headline = try typeContainer.decode(LabelModel.self, forKey: .headline)
@ -73,6 +76,7 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(planLabel, forKey: .planLabel)
try container.encode(headline, forKey: .headline)

View File

@ -20,6 +20,9 @@ import VDS
// MARK: - Public Functions
//--------------------------------------------------
open func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
surface = viewModel.surface
textAlignment = viewModel.textAlignment
eyebrowModel = viewModel.eyebrowModel(delegateObject: delegateObject, additionalData: additionalData)

View File

@ -18,7 +18,8 @@ public class TitleLockupModel: ParentMoleculeModelProtocol {
public static var identifier: String = "titleLockup"
public var moleculeName: String = TitleLockupModel.identifier
public var id: String = UUID().uuidString
public var accessibilityIdentifier: String?
public var textAlignment: TitleLockup.TextAlignment = .left
public var eyebrow: LabelModel?
public var eyebrowColor: TitleLockup.TextColor = .primary
@ -26,8 +27,6 @@ public class TitleLockupModel: ParentMoleculeModelProtocol {
public var titleColor: TitleLockup.TitleTextColor = .primary
public var subTitle: LabelModel?
public var subTitleColor: TitleLockup.TextColor = .primary
public var alignment: VDS.TitleLockup.TextAlignment = .left
public var inverted: Bool = false
public var backgroundColor: Color?
@ -49,7 +48,6 @@ public class TitleLockupModel: ParentMoleculeModelProtocol {
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return textAlignment == model.textAlignment
&& alignment == model.alignment
&& titleColor == model.titleColor
&& subTitleColor == model.subTitleColor
&& inverted == model.inverted
@ -75,6 +73,7 @@ public class TitleLockupModel: ParentMoleculeModelProtocol {
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case accessibilityIdentifier
case textAlignment
case eyebrow
case eyebrowColor
@ -83,7 +82,6 @@ public class TitleLockupModel: ParentMoleculeModelProtocol {
case subTitle
case subTitleColor
case inverted
case alignment
}
//--------------------------------------------------
@ -93,6 +91,7 @@ public class TitleLockupModel: ParentMoleculeModelProtocol {
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
textAlignment = try typeContainer.decodeIfPresent(TitleLockup.TextAlignment.self, forKey: .textAlignment) ?? .left
title = try typeContainer.decodeMolecule(codingKey: .title)
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
@ -128,10 +127,6 @@ public class TitleLockupModel: ParentMoleculeModelProtocol {
subTitleColor = .primary
}
if let newAlignment = try typeContainer.decodeIfPresent(VDS.TitleLockup.TextAlignment.self, forKey: .alignment) {
alignment = newAlignment
}
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
} else {
@ -144,6 +139,7 @@ public class TitleLockupModel: ParentMoleculeModelProtocol {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(textAlignment, forKey: .textAlignment)
try container.encodeIfPresent(eyebrow, forKey: .eyebrow)
try container.encode(eyebrowColor, forKey: .eyebrowColor)
@ -151,7 +147,6 @@ public class TitleLockupModel: ParentMoleculeModelProtocol {
try container.encode(titleColor, forKey: .titleColor)
try container.encodeIfPresent(subTitle, forKey: .subTitle)
try container.encode(subTitleColor, forKey: .subTitleColor)
try container.encode(alignment, forKey: .alignment)
try container.encode(inverted, forKey: .inverted)
}

View File

@ -15,7 +15,7 @@ import Foundation
//-----------------------------------------------------
public var stack: Stack<StackModel>
public let headline = Label(fontStyle: .BoldTitleMedium)
public let headline = Label(fontStyle: .BoldTitleLarge)
public let body = Label(fontStyle: .RegularBodySmall)
//--------------------------------------------------
@ -24,7 +24,7 @@ import Foundation
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
(view: body, model: StackItemModel(spacing: 0, horizontalAlignment: .leading))],
(view: body, model: StackItemModel(spacing: 8, horizontalAlignment: .leading))],
axis: .vertical)
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
@ -63,7 +63,7 @@ import Foundation
open override func reset() {
super.reset()
headline.setFontStyle(.BoldTitleMedium)
headline.setFontStyle(.BoldTitleLarge)
body.setFontStyle(.RegularBodySmall)
}

View File

@ -47,6 +47,9 @@ public class ListOneColumnTextWithWhitespaceDividerShortModel: ListItemModel, Mo
override public func setDefaults() {
style = .shortDivider
if headline.accessibilityTraits == nil {
headline.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -15,7 +15,7 @@ import Foundation
//-----------------------------------------------------
public var stack: Stack<StackModel>
public let headline = Label(fontStyle: .BoldTitleMedium)
public let headline = Label(fontStyle: .BoldTitleLarge)
public let body = Label(fontStyle: .RegularBodySmall)
//--------------------------------------------------
@ -24,7 +24,7 @@ import Foundation
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
stack = Stack<StackModel>.createStack(with: [(view: headline, model: StackItemModel(horizontalAlignment: .leading)),
(view: body, model: StackItemModel(spacing: 0, horizontalAlignment: .leading))],
(view: body, model: StackItemModel(spacing: 8, horizontalAlignment: .leading))],
axis: .vertical)
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
@ -62,7 +62,7 @@ import Foundation
open override func reset() {
super.reset()
headline.setFontStyle(.BoldTitleMedium)
headline.setFontStyle(.BoldTitleLarge)
body.setFontStyle(.RegularBodySmall)
accessibilityLabel = nil
}

View File

@ -47,6 +47,9 @@ public class ListOneColumnTextWithWhitespaceDividerTallModel: ListItemModel, Mol
override public func setDefaults() {
style = .tallDivider
if headline.accessibilityTraits == nil {
headline.accessibilityTraits = [.header]
}
super.setDefaults()
}

View File

@ -17,7 +17,8 @@ import Foundation
public static var identifier: String = "doughnutChartItem"
public var moleculeName: String = DoughnutChartItemModel.identifier
@DecodableDefault.UUIDString public var id: String
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var label: LabelModel
@Percent public var percent: CGFloat
@ -28,6 +29,8 @@ import Foundation
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case accessibilityIdentifier
case backgroundColor
case label
case percent

View File

@ -17,7 +17,8 @@ import Foundation
public static var identifier: String = "doughnutChart"
public var moleculeName: String = DoughnutChartModel.identifier
@DecodableDefault.UUIDString public var id: String
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var title: LabelModel?
public var subtitle: LabelModel?

View File

@ -16,7 +16,8 @@ public class ImageHeadlineBodyModel: MoleculeModelProtocol {
public static var identifier: String = "imageHeadlineBody"
public var moleculeName: String = ImageHeadlineBodyModel.identifier
@DecodableDefault.UUIDString public var id: String
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var image: ImageViewModel
public var headlineBody: HeadlineBodyModel

View File

@ -80,6 +80,10 @@ import VDS
// MARK: - Atomic
//--------------------------------------------------
public func viewModelDidUpdate() {
if let accessibilityIdentifier = viewModel.accessibilityIdentifier {
self.accessibilityIdentifier = accessibilityIdentifier
}
surface = viewModel.surface
updateRadioButton()
@ -106,7 +110,7 @@ import VDS
}
//properties
isEnabled = viewModel.radioButton.enabled && !viewModel.radioButton.readOnly
isEnabled = viewModel.radioButton.isEnabled
isSelected = viewModel.radioButton.state
//forms

View File

@ -10,14 +10,15 @@ import Foundation
import MVMCore
import VDS
@objcMembers public class RadioButtonLabelModel: MoleculeModelProtocol, ParentMoleculeModelProtocol {
public class RadioButtonLabelModel: MoleculeModelProtocol, ParentMoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "radioButtonLabel"
@DecodableDefault.UUIDString public var id: String
public var accessibilityIdentifier: String?
public var backgroundColor: Color?
public var moleculeName: String = RadioButtonLabelModel.identifier
public var radioButton: RadioButtonModel
@ -40,5 +41,36 @@ import VDS
self.label = label
self.subTitle = subTitle
}
open func isEqual(to model: any ModelComparisonProtocol) -> Bool {
guard let model = model as? Self else { return false }
return moleculeName == model.moleculeName
&& inverted == model.inverted
&& accessibilityText == model.accessibilityText
&& accessibilityIdentifier == model.accessibilityIdentifier
&& accessibilityTraits == model.accessibilityTraits
}
}
extension Array where Element == RadioButtonLabelModel {
internal func convertToVDSRadioButtonItemModel(surface: Surface,
delegateObject: MVMCoreUIDelegateObject?,
additionalData: [AnyHashable: Any]?) -> [RadioButtonGroup.RadioButtonItemModel] {
return compactMap({ model in
var item = RadioButtonGroup.RadioButtonItemModel()
item.inputId = model.radioButton.fieldKey
item.labelText = model.label.text
if let attributes = model.label.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData) {
item.labelTextAttributes = attributes
}
item.childText = model.subTitle?.text
if let attributes = model.subTitle?.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData) {
item.childTextAttributes = attributes
}
item.surface = surface
item.selected = model.radioButton.state
item.enabled = model.radioButton.isEnabled
return item
})
}
}

Some files were not shown because too many files have changed in this diff Show More