diff --git a/JSONCreator_iOS/JSONCreator/AppDelegate.swift b/JSONCreator_iOS/JSONCreator/AppDelegate.swift index 3947db5..25cebc6 100644 --- a/JSONCreator_iOS/JSONCreator/AppDelegate.swift +++ b/JSONCreator_iOS/JSONCreator/AppDelegate.swift @@ -132,9 +132,9 @@ extension AppDelegate { ModelRegistry.register(TestModel.self) ModelRegistry.register(handler: TestLabelToggle.self, for: TestLabelToggleModel.self) ModelRegistry.register(handler: TestToggle.self, for: TestToggleModel.self) + ModelRegistry.register(handler: TestToggle2.self, for: TestToggleModel2.self) ModelRegistry.register(handler: TextEntryField.self, for: TextEntryField64Model.self) ModelRegistry.register(handler: EmailVerifyField.self, for: EmailVerifyModel.self) - ModelRegistry.register(handler: WifiWidget.self, for: WifiWidgetModel.self) ModelRegistry.register(handler: ToggleWifiActionHandler.self, for: ToggleWifiActionModel.self) guard let model = try? TestModel.decode(fileName: "/JSON/Samples/Wifi/TestModel") else { return } @@ -266,11 +266,9 @@ class ToggleWifiActionModel: ActionModelProtocol { class ToggleWifiActionHandler: MVMCoreActionHandlerProtocol { required public init() {} - func handleAction(_ model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) { + func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { guard let action = model as? ToggleWifiActionModel else { return } - print("Wi-Fi Id: \(action.wifiId)") - } } diff --git a/JSONCreator_iOS/JSONCreator/JSON/Samples/FormContactInfo.json b/JSONCreator_iOS/JSONCreator/JSON/Samples/FormContactInfo.json index 6918dfb..d0acf0a 100644 --- a/JSONCreator_iOS/JSONCreator/JSON/Samples/FormContactInfo.json +++ b/JSONCreator_iOS/JSONCreator/JSON/Samples/FormContactInfo.json @@ -22,8 +22,14 @@ { "moleculeName": "stackItem", "molecule": { - "moleculeName": "testToggle", - "fieldKey": "isActive" + "moleculeName": "testLabelToggle", + "label": { + "text": "isActive" + }, + "toggle": { + "moleculeName": "testToggle1", + "fieldKey": "isActive" + } } }, { diff --git a/JSONCreator_iOS/JSONCreator/MF/JSONCreatorActionHandler.swift b/JSONCreator_iOS/JSONCreator/MF/JSONCreatorActionHandler.swift index 77e25b0..378af3c 100644 --- a/JSONCreator_iOS/JSONCreator/MF/JSONCreatorActionHandler.swift +++ b/JSONCreator_iOS/JSONCreator/MF/JSONCreatorActionHandler.swift @@ -22,17 +22,7 @@ import MVMCoreUI } public class JSONCreatorActionHandler: MVMCoreUIActionHandler { - public override func handleOtherActions(_ actionType: String?, actionInformation: [AnyHashable : Any]?, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) -> Bool { - if actionType == "print" { - if actionInformation?.boolForKey("delay") ?? false { - sleep(2) - } - print(actionInformation?.stringForkey("text") ?? "fail") - return true - } - return super.handleOtherActions(actionType, actionInformation: actionInformation, additionalData: additionalData, delegateObject: delegateObject) - } - + public static func doStuff() { MVMCoreObject.sharedInstance()?.actionHandler = JSONCreatorActionHandler() ModelRegistry.register(ActionPrintModel.self) diff --git a/JSONCreator_iOS/JSONCreator/TestLabelToggle.swift b/JSONCreator_iOS/JSONCreator/TestLabelToggle.swift index e3d2a6d..c885083 100644 --- a/JSONCreator_iOS/JSONCreator/TestLabelToggle.swift +++ b/JSONCreator_iOS/JSONCreator/TestLabelToggle.swift @@ -14,8 +14,6 @@ import MVMCoreUI //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - - public let label = Label(fontStyle: .BoldBodySmall) public let toggle = TestToggle() //-------------------------------------------------- @@ -24,42 +22,34 @@ import MVMCoreUI open override func updateView(_ size: CGFloat) { super.updateView(size) - label.updateView(size) toggle.updateView(size) } open override func setupView() { super.setupView() - - addSubview(label) addSubview(toggle) - label.setContentHuggingPriority(.required, for: .vertical) - NSLayoutConstraint.pinViews(leftView: label, rightView: toggle, alignTop: false) - } - - open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - guard let model = model as? TestLabelToggleModel, - let toggleHeight = Toggle.estimatedHeight(with: model.toggle, delegateObject), - let labelHeight = Label.estimatedHeight(with: model.label, delegateObject) - else { return nil } - - return max(toggleHeight, labelHeight) + toggle.topAnchor.constraint(equalTo: topAnchor).isActive = true + toggle.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true + toggle.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - guard let labelToggleModel = model as? TestLabelToggleModel else { return } - - label.set(with: labelToggleModel.label, delegateObject, additionalData) + toggle.set(with: labelToggleModel.toggle, delegateObject, additionalData) + + let text = labelToggleModel.label.text + toggle.showText = true + toggle.onText = text + toggle.offText = text + toggle.textSize = .small + toggle.textWeight = .bold } // MARK: - MoleculeViewProtocol open override func reset() { super.reset() - label.reset() toggle.reset() - label.setFontStyle(.BoldBodySmall) } } diff --git a/JSONCreator_iOS/JSONCreator/TestToggle.swift b/JSONCreator_iOS/JSONCreator/TestToggle.swift index 32aaa8a..e68a22f 100644 --- a/JSONCreator_iOS/JSONCreator/TestToggle.swift +++ b/JSONCreator_iOS/JSONCreator/TestToggle.swift @@ -11,97 +11,120 @@ import MVMCoreUI import UIKit import VDS -extension MoleculeViewProtocol { - public func onModelChange(model: MoleculeModelProtocol) { - if let backgroundColor = model.backgroundColor { - self.backgroundColor = backgroundColor.uiColor - } - - if let accessibilityIdentifier = model.accessibilityIdentifier { - self.accessibilityIdentifier = accessibilityIdentifier - } - } +public protocol VDSMoleculeViewProtocol: MoleculeViewProtocol, MVMCoreViewProtocol { + associatedtype ViewModel: MoleculeModelProtocol + var viewModel: ViewModel! { get set } + var delegateObject: MVMCoreUIDelegateObject? { get set } + var additionalData: [AnyHashable: Any]? { get set } + func viewModelDidUpdate() } -extension ModelHandlerable where Self: MoleculeViewProtocol { - public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { - self.init(with: model as! ModelType) - self.set(with: model, delegateObject, additionalData) - } -} - -open class TestToggle: ToggleBase, MoleculeViewProtocol, MVMCoreViewProtocol { - - /// The state on the toggle. Default value: false. - open override var isOn: Bool { - didSet { - _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) - } - } - - open override var isEnabled: Bool { - didSet { - model.enabled = isEnabled && !model.readOnly - } - } - - //-------------------------------------------------- - // MARK: - Delegate - //-------------------------------------------------- - - private var delegateObject: MVMCoreUIDelegateObject? - - //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - open override func updateView(viewModel: ModelType) { - super.updateView(viewModel: viewModel) - onModelChange(model: viewModel) - } - - override open func setup() { - super.setup() - self.setupView() - } - - // MARK:- MVMCoreViewProtocol - public func updateView(_ size: CGFloat) {} - public func setupView() {} - - open override func toggle() { - super.toggle() - } - - // MARK:- MoleculeViewProtocol +extension VDSMoleculeViewProtocol { public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - - guard let castedModel = model as? ModelType else { return } - set(with: castedModel) - + guard let castedModel = model as? ViewModel else { return } self.delegateObject = delegateObject - - guard let formFieldProtocol = model as? FormFieldProtocol else { return } - FormValidator.setupValidation(for: formFieldProtocol, delegate: delegateObject?.formHolderDelegate) + viewModel = castedModel + viewModelDidUpdate() + } +} - let additionalDataWithSource = additionalData.dictionaryAdding(key: KeySourceModel, value: model) - if castedModel.action != nil || castedModel.alternateAction != nil { - onChange = { [weak self] in - guard let self = self else { return } - if self.isOn { - if let action = castedModel.action { - MVMCoreActionHandler.shared()?.asyncHandleAction(with: action, additionalData: additionalDataWithSource, delegateObject: delegateObject) - } - } else { - if let action = castedModel.alternateAction ?? castedModel.action { - MVMCoreActionHandler.shared()?.asyncHandleAction(with: action, additionalData: additionalDataWithSource, delegateObject: delegateObject) - } - } +extension TestToggleModel { + public func getVDSModel() -> DefaultToggleModel { + return DefaultToggleModel().copyWith { + $0.disabled = !enabled && readOnly + $0.on = selected + if let accessibilityText = accessibilityText { + $0.accessibilityLabelEnabled = accessibilityText + $0.accessibilityLabelDisabled = accessibilityText } } } - +} + +open class TestToggle: ToggleBase, VDSMoleculeViewProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public var viewModel: TestToggleModel! + public var delegateObject: MVMCoreUIDelegateObject? + public var additionalData: [AnyHashable: Any]? + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + public override func initialSetup() { + super.initialSetup() + + publisher(for: .touchUpInside) + .sink {[weak self] toggle in + guard let self = self else { return } + self.toggle() + }.store(in: &subscribers) + + publisher(for: .valueChanged) + .sink {[weak self] toggle in + guard let self = self else { return } + self.valueChanged(isOn: toggle.isOn) + }.store(in: &subscribers) + + model.accessibilityLabelEnabled = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel") + model.accessibilityLabelDisabled = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel") + model.accessibilityHintEnabled = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint") + model.accessibilityHintDisabled = MVMCoreUIUtility.hardcodedString(withKey: "AccDisabled") + model.accessibilityValueEnabled = MVMCoreUIUtility.hardcodedString(withKey: "AccOn") + model.accessibilityValueDisabled = MVMCoreUIUtility.hardcodedString(withKey: "AccOff") + } + + // MARK:- MVMCoreViewProtocol + open func updateView(_ size: CGFloat) {} + + open func viewModelDidUpdate() { + guard let viewModel else { return } + + FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate) + additionalData = additionalData.dictionaryAdding(key: KeySourceModel, value: viewModel) + set(with: viewModel.getVDSModel()) + } + + private func valueChanged(isOn: Bool){ + guard let viewModel else { return } + //sync the value on the viewModel + viewModel.selected = isOn + + //tell the form you changed + _ = FormValidator.validate(delegate: self.delegateObject?.formHolderDelegate) + + if viewModel.action != nil || viewModel.alternateAction != nil { + var action: ActionModelProtocol? + if isOn { + action = viewModel.action + } else { + action = viewModel.alternateAction ?? viewModel.action + } + if let action { + MVMCoreUIActionHandler.performActionUnstructured(with: action, + sourceModel: viewModel, + additionalData: additionalData, + delegateObject: delegateObject) + } + } + + print("toggle value changed to: \(isOn)") + print("viewModel server value: \(viewModel.formFieldServerValue()!)") + } + public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return 24 + return 44 + } + + private typealias ActionDefinition = (model: ActionModelProtocol, + sourceModel: MoleculeModelProtocol?) + + private func performActionUnstructured(definition: ActionDefinition) { + MVMCoreUIActionHandler.performActionUnstructured(with: definition.model, + sourceModel: definition.sourceModel, + additionalData: additionalData, + delegateObject: delegateObject) } } @@ -112,3 +135,70 @@ extension TestToggle: MVMCoreUIViewConstrainingProtocol { public func horizontalAlignment() -> UIStackView.Alignment { .trailing } } + +open class TestToggle2: GenericMolecule, MVMCoreUIViewConstrainingProtocol { + + private var toggle = Toggle() + + open override func initialSetup() { + super.initialSetup() + + //handle valueChanged + toggle.publisher(for: .valueChanged) + .sink { [weak self] control in + self?.valueDidChange(isOn: control.isOn) + }.store(in: &toggle.subscribers) + + } + + @Proxy(\.toggle.isOn) + open var isOn: Bool + + @Proxy(\.toggle.isEnabled) + open var isEnabled: Bool + + open override func setupView(){ + super.setupView() + addSubview(toggle) + NSLayoutConstraint.constraintPinSubview(toSuperview: toggle) + } + + open override func viewModelUpdate(model: TestToggleModel2) { + toggle.isEnabled = model.enabled + toggle.isOn = model.selected + + isUserInteractionEnabled = model.enabled && !model.readOnly + additionalData = additionalData.dictionaryAdding(key: KeySourceModel, value: model) + FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) + } + + open func valueDidChange(isOn: Bool) { + print("Toggle valueDidChange: \(isOn)") + + if model.action != nil || model.alternateAction != nil { + var action: ActionModelProtocol? + if isOn { + action = model.action + } else { + action = model.alternateAction ?? model.action + } + if let action { + MVMCoreUIActionHandler.performActionUnstructured(with: action, + sourceModel: model, + additionalData: additionalData, + delegateObject: delegateObject) + } + } + } + + //MARK - MoleculeViewProtocol + public override static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 44 + } + + //MARK - MVMCoreUIViewConstrainingProtocol + public func needsToBeConstrained() -> Bool { true } + + public func horizontalAlignment() -> UIStackView.Alignment { .trailing } +} + diff --git a/JSONCreator_iOS/JSONCreator/TestToggleModel.swift b/JSONCreator_iOS/JSONCreator/TestToggleModel.swift index ac8af65..995e5f6 100644 --- a/JSONCreator_iOS/JSONCreator/TestToggleModel.swift +++ b/JSONCreator_iOS/JSONCreator/TestToggleModel.swift @@ -11,186 +11,196 @@ import MVMCore import MVMCoreUI import VDS -//MARK: - Model -public class TestToggleModel: MoleculeModelProtocol, FormFieldProtocol, VDS.ToggleModel { - +public class TestToggleModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public static var identifier: String = "testToggle" - public var moleculeName: String = TestToggleModel.identifier - + public static var identifier: String = "testToggle1" + public var backgroundColor: Color? //not used + + public var selected: Bool = false + public var enabled: Bool = true + public var readOnly: Bool = false public var action: ActionModelProtocol? public var alternateAction: ActionModelProtocol? - public var accessibilityIdentifier: String? - public var backgroundColor: MVMCoreUI.Color? - - //FormFieldProtocol + public var accessibilityText: String? public var fieldKey: String? public var groupName: String = FormValidator.defaultGroupName public var baseValue: AnyHashable? - public var readOnly: Bool = false - public var enabled: Bool = true - //ToggleModelProtocol - public var id = UUID() - public var showText: Bool = false - public var on: Bool = false - public var surface: Surface = .light - public var inputId: String? - public var value: AnyHashable? - public var dataAnalyticsTrack: String? - public var dataClickStream: String? - public var dataTrack: String? - public var disabled: Bool = false - public var accessibilityHintEnabled: String? - public var accessibilityHintDisabled: String? - public var accessibilityValueEnabled: String? - public var accessibilityValueDisabled: String? - public var accessibilityLabelEnabled: String? - public var accessibilityLabelDisabled: String? - public var typograpicalStyle: VDS.TypographicalStyle = .BodyLarge - public var textPosition: TextPosition = .left - public var offText: String = "Off" - public var onText: String = "On" //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- - + private enum CodingKeys: String, CodingKey { case moleculeName + case state + case enabled + case readOnly case action - case alternateAction case accessibilityIdentifier + case alternateAction + case accessibilityText case fieldKey case groupName - case readOnly - case enabled //which to use - - case id - case showText - case on - case surface - case inputId - case value - case dataAnalyticsTrack - case dataClickStream - case dataTrack - case disabled //which to use - case typograpicalStyle - case textPosition - case offText - case onText } //-------------------------------------------------- // MARK: - Form Valdiation //-------------------------------------------------- - + public func formFieldValue() -> AnyHashable? { guard enabled else { return nil } - if let value = value { - return value - } else { - return on - } + return selected } - + //-------------------------------------------------- // MARK: - Server Value //-------------------------------------------------- open func formFieldServerValue() -> AnyHashable? { return formFieldValue() } - + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- - required public convenience init(){ - self.init(false) - } public init(_ state: Bool) { - self.on = state + selected = state baseValue = state } - + //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- - + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - //molecule + if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) { + selected = state + } action = try typeContainer.decodeModelIfPresent(codingKey: .action) alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction) - accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) - - //formField + accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) + baseValue = selected fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + if let gName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + groupName = gName + } + enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false - if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { - self.groupName = groupName - } - //vds toggle - showText = try typeContainer.decodeIfPresent(Bool.self, forKey: .showText) ?? false - on = try typeContainer.decodeIfPresent(Bool.self, forKey: .on) ?? false - - surface = try typeContainer.decodeIfPresent(Surface.self, forKey: .surface) ?? .light - dataAnalyticsTrack = try typeContainer.decodeIfPresent(String.self, forKey: .dataAnalyticsTrack) - dataClickStream = try typeContainer.decodeIfPresent(String.self, forKey: .dataClickStream) - dataTrack = try typeContainer.decodeIfPresent(String.self, forKey: .dataTrack) - typograpicalStyle = try typeContainer.decodeIfPresent(TypographicalStyle.self, forKey: .typograpicalStyle) ?? .BodyLarge - textPosition = try typeContainer.decodeIfPresent(TextPosition.self, forKey: .textPosition) ?? .left - offText = try typeContainer.decodeIfPresent(String.self, forKey: .offText) ?? "Off" - onText = try typeContainer.decodeIfPresent(String.self, forKey: .onText) ?? "On" - accessibilityHintEnabled = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint") - accessibilityHintDisabled = MVMCoreUIUtility.hardcodedString(withKey: "AccDisabled") - accessibilityValueEnabled = MVMCoreUIUtility.hardcodedString(withKey: "AccOn") - accessibilityValueDisabled = MVMCoreUIUtility.hardcodedString(withKey: "AccOff") - accessibilityLabelEnabled = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel") - accessibilityLabelDisabled = accessibilityLabelEnabled - - if let _enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { - enabled = _enabled && !readOnly - disabled = !_enabled && readOnly - } else if let _disabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .disabled) { - enabled = !_disabled && !readOnly - disabled = _disabled && readOnly - } - - baseValue = on } - + public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - //molecule - try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) try container.encodeModelIfPresent(action, forKey: .action) try container.encodeModelIfPresent(alternateAction, forKey: .alternateAction) - try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) - //formField + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(selected, forKey: .state) + try container.encode(enabled, forKey: .enabled) + try container.encodeIfPresent(fieldKey, forKey: .fieldKey) + try container.encodeIfPresent(groupName, forKey: .groupName) + try container.encode(readOnly, forKey: .readOnly) + } +} + + +public class TestToggleModel2: MoleculeModelProtocol, FormFieldProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public static var identifier: String = "testToggle2" + public var backgroundColor: Color? //not used + + public var selected: 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 fieldKey: String? + public var groupName: String = FormValidator.defaultGroupName + public var baseValue: AnyHashable? + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { + case moleculeName + case state + case enabled + case readOnly + case action + case accessibilityIdentifier + case alternateAction + case accessibilityText + case fieldKey + case groupName + } + + //-------------------------------------------------- + // MARK: - Form Valdiation + //-------------------------------------------------- + + public 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) { + selected = state + baseValue = state + } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + + if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) { + selected = state + } + action = try typeContainer.decodeModelIfPresent(codingKey: .action) + alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction) + accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) + baseValue = selected + fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + if let gName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + groupName = gName + } + enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true + readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + 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(enabled, forKey: .enabled) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(groupName, forKey: .groupName) try container.encode(readOnly, forKey: .readOnly) - try container.encode(enabled, forKey: .enabled) - //vds toggle - try container.encodeIfPresent(id, forKey: .id) - try container.encode(showText, forKey: .showText) - try container.encode(on, forKey: .on) - try container.encodeIfPresent(surface, forKey: .surface) - try container.encodeIfPresent(inputId, forKey: .inputId) - try container.encode(dataAnalyticsTrack, forKey: .dataAnalyticsTrack) - try container.encode(dataClickStream, forKey: .dataClickStream) - try container.encode(dataTrack, forKey: .dataTrack) - try container.encode(disabled, forKey: .disabled) - try container.encodeIfPresent(typograpicalStyle, forKey: .typograpicalStyle) - try container.encodeIfPresent(textPosition, forKey: .textPosition) - try container.encodeIfPresent(offText, forKey: .offText) - try container.encodeIfPresent(onText, forKey: .onText) } }