diff --git a/.mapping.json b/.mapping.json index b102db490..94ad48e34 100644 --- a/.mapping.json +++ b/.mapping.json @@ -11464,6 +11464,7 @@ "client/ios/DivKit/Extensions/DivSizeUnitExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivSizeUnitExtensions.swift", "client/ios/DivKit/Extensions/DivSliderExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivSliderExtensions.swift", "client/ios/DivKit/Extensions/DivStateExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivStateExtensions.swift", + "client/ios/DivKit/Extensions/DivSwitchExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivSwitchExtensions.swift", "client/ios/DivKit/Extensions/DivTabsExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivTabsExtensions.swift", "client/ios/DivKit/Extensions/DivTextExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivTextExtensions.swift", "client/ios/DivKit/Extensions/DivTooltipExtensions.swift":"divkit/public/client/ios/DivKit/Extensions/DivTooltipExtensions.swift", @@ -11795,6 +11796,8 @@ "client/ios/DivKit/generated_sources/DivStretchIndicatorItemPlacementTemplate.swift":"divkit/public/client/ios/DivKit/generated_sources/DivStretchIndicatorItemPlacementTemplate.swift", "client/ios/DivKit/generated_sources/DivStroke.swift":"divkit/public/client/ios/DivKit/generated_sources/DivStroke.swift", "client/ios/DivKit/generated_sources/DivStrokeTemplate.swift":"divkit/public/client/ios/DivKit/generated_sources/DivStrokeTemplate.swift", + "client/ios/DivKit/generated_sources/DivSwitch.swift":"divkit/public/client/ios/DivKit/generated_sources/DivSwitch.swift", + "client/ios/DivKit/generated_sources/DivSwitchTemplate.swift":"divkit/public/client/ios/DivKit/generated_sources/DivSwitchTemplate.swift", "client/ios/DivKit/generated_sources/DivTabs.swift":"divkit/public/client/ios/DivKit/generated_sources/DivTabs.swift", "client/ios/DivKit/generated_sources/DivTabsTemplate.swift":"divkit/public/client/ios/DivKit/generated_sources/DivTabsTemplate.swift", "client/ios/DivKit/generated_sources/DivTemplate.swift":"divkit/public/client/ios/DivKit/generated_sources/DivTemplate.swift", @@ -13917,6 +13920,30 @@ "client/ios/Tests/reference_snapshots/div-states/borders_414@3x.png":"divkit/public/client/ios/Tests/reference_snapshots/div-states/borders_414@3x.png", "client/ios/Tests/reference_snapshots/div-states/default-state_375@2x.png":"divkit/public/client/ios/Tests/reference_snapshots/div-states/default-state_375@2x.png", "client/ios/Tests/reference_snapshots/div-states/default-state_414@3x.png":"divkit/public/client/ios/Tests/reference_snapshots/div-states/default-state_414@3x.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step0.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step0.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step1.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step1.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step2.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step2.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step3.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step3.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step4.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step4.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step5.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step5.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step6.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step6.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step7.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step7.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step0.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step0.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step1.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step1.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step2.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step2.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step3.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step3.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step4.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step4.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step5.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step5.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step6.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step6.png", + "client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step7.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step7.png", + "client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step0.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step0.png", + "client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step1.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step1.png", + "client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step2.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step2.png", + "client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step3.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step3.png", + "client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step0.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step0.png", + "client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step1.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step1.png", + "client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step2.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step2.png", + "client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step3.png":"divkit/public/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step3.png", "client/ios/Tests/reference_snapshots/div-tabs/corners_radius_375@2x.png":"divkit/public/client/ios/Tests/reference_snapshots/div-tabs/corners_radius_375@2x.png", "client/ios/Tests/reference_snapshots/div-tabs/corners_radius_414@3x.png":"divkit/public/client/ios/Tests/reference_snapshots/div-tabs/corners_radius_414@3x.png", "client/ios/Tests/reference_snapshots/div-tabs/custom-background-border_375@2x.png":"divkit/public/client/ios/Tests/reference_snapshots/div-tabs/custom-background-border_375@2x.png", @@ -17471,6 +17498,7 @@ "schema/div-state.json":"divkit/public/schema/div-state.json", "schema/div-stretch-indicator-item-placement.json":"divkit/public/schema/div-stretch-indicator-item-placement.json", "schema/div-stroke.json":"divkit/public/schema/div-stroke.json", + "schema/div-switch.json":"divkit/public/schema/div-switch.json", "schema/div-tabs.json":"divkit/public/schema/div-tabs.json", "schema/div-text-alignment-vertical.json":"divkit/public/schema/div-text-alignment-vertical.json", "schema/div-text-gradient.json":"divkit/public/schema/div-text-gradient.json", @@ -17725,6 +17753,8 @@ "test_data/interactive_snapshot_test_data/div-slider/visibility.json":"divkit/public/test_data/interactive_snapshot_test_data/div-slider/visibility.json", "test_data/interactive_snapshot_test_data/div-state/base-properties.json":"divkit/public/test_data/interactive_snapshot_test_data/div-state/base-properties.json", "test_data/interactive_snapshot_test_data/div-state/visibility.json":"divkit/public/test_data/interactive_snapshot_test_data/div-state/visibility.json", + "test_data/interactive_snapshot_test_data/div-switch/base-properties.json":"divkit/public/test_data/interactive_snapshot_test_data/div-switch/base-properties.json", + "test_data/interactive_snapshot_test_data/div-switch/switch-properties.json":"divkit/public/test_data/interactive_snapshot_test_data/div-switch/switch-properties.json", "test_data/interactive_snapshot_test_data/div-tabs/select-elements.json":"divkit/public/test_data/interactive_snapshot_test_data/div-tabs/select-elements.json", "test_data/interactive_snapshot_test_data/div-text/background-image-blur.json":"divkit/public/test_data/interactive_snapshot_test_data/div-text/background-image-blur.json", "test_data/interactive_snapshot_test_data/div-text/text-properties.json":"divkit/public/test_data/interactive_snapshot_test_data/div-text/text-properties.json", diff --git a/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt b/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt index 67e78f24f..cdab0640c 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/state/DivPathUtils.kt @@ -121,6 +121,7 @@ internal object DivPathUtils { is Div.Separator -> null is Div.Select -> null is Div.Video -> null + is Div.Switch -> null } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt b/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt index c0d7841a7..c6f8003ae 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/util/DivTreeWalk.kt @@ -172,6 +172,7 @@ private fun Div.getItems(resolver: ExpressionResolver): List emptyList() is Div.Select -> emptyList() is Div.Video -> emptyList() + is Div.Switch -> emptyList() is Div.Container -> value.buildItems(resolver) is Div.Grid -> value.itemsToDivItemBuilderResult(resolver) is Div.Gallery -> value.buildItems(resolver) diff --git a/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt b/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt index 6f64d7c9e..3a46389c5 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/util/DivUtil.kt @@ -35,6 +35,7 @@ import com.yandex.div2.DivSelect import com.yandex.div2.DivSeparator import com.yandex.div2.DivSlider import com.yandex.div2.DivState +import com.yandex.div2.DivSwitch import com.yandex.div2.DivTabs import com.yandex.div2.DivText import com.yandex.div2.DivVariable @@ -60,6 +61,7 @@ internal val Div.type: String is Div.Tabs -> DivTabs.TYPE is Div.Custom -> DivCustom.TYPE is Div.Select -> DivSelect.TYPE + is Div.Switch -> DivSwitch.TYPE } } @@ -176,6 +178,7 @@ internal fun Div.containsStateInnerTransitions(resolver: ExpressionResolver): Bo is Div.Slider -> false is Div.Video -> false is Div.Input -> false + is Div.Switch -> false } } @@ -197,6 +200,7 @@ internal val Div.isBranch: Boolean is Div.Custom -> false is Div.Select -> false is Div.Video -> false + is Div.Switch -> false is Div.Container -> true is Div.Grid -> true is Div.Gallery -> true diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivBinder.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivBinder.kt index 1d716da17..e68e3487e 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivBinder.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivBinder.kt @@ -124,6 +124,7 @@ internal class DivBinder @Inject constructor( is Div.Input -> bindInput(context, view, div.value, path) is Div.Select -> bindSelect(context, view, div.value, path) is Div.Video -> bindVideo(context, view, div.value, path) + is Div.Switch -> Unit }.also { // extensionController bound new CustomView in DivCustomBinder after replacing in parent if (div !is Div.Custom) { @@ -222,6 +223,7 @@ internal class DivBinder @Inject constructor( is Div.Input -> (view as DivInputView).setDataWithoutBinding(context, div.value) is Div.Select -> (view as DivSelectView).setDataWithoutBinding(context, div.value) is Div.Video -> (view as DivVideoView).setDataWithoutBinding(context, div.value) + is Div.Switch -> Unit } private fun DivHolderView.setDataWithoutBinding(context: BindingContext, newDiv: T) { diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt index 1fc9ff7a8..019970ff5 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/DivViewCreator.kt @@ -152,6 +152,7 @@ internal class DivViewCreator @Inject constructor( const val TAG_SLIDER = "DIV2.SLIDER" const val TAG_INPUT = "DIV2.INPUT" const val TAG_SELECT = "DIV2.SELECT" + const val TAG_SWITCH = "DIV2.SWITCH" const val TAG_VIDEO = "DIV2.VIDEO" val TAGS = arrayOf( @@ -191,6 +192,7 @@ internal class DivViewCreator @Inject constructor( is Div.Pager -> TAG_PAGER is Div.Select -> TAG_SELECT is Div.Slider -> TAG_SLIDER + is Div.Switch -> TAG_SWITCH is Div.State -> TAG_STATE is Div.Tabs -> TAG_TABS is Div.Text -> TAG_TEXT diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt index b1644d9c3..381476695 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/animations/DivComparator.kt @@ -123,6 +123,7 @@ internal object DivComparator { is Div.Indicator -> emptyList() is Div.Slider -> emptyList() is Div.Video -> emptyList() + is Div.Switch -> emptyList() } } diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/ExistingToken.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/ExistingToken.kt index 3bb6e94cb..0b07b1340 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/ExistingToken.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/ExistingToken.kt @@ -40,6 +40,7 @@ internal class ExistingToken( is Div.Input -> emptyList() is Div.Select -> emptyList() is Div.Video -> emptyList() + is Div.Switch -> emptyList() is Div.Container -> div.value.itemsToExistingTokenList(item.expressionResolver, parentToken) is Div.Custom -> div.value.itemsToExistingTokenList(item.expressionResolver, parentToken) is Div.Grid -> div.value.itemsToExistingTokenList(item.expressionResolver, parentToken) diff --git a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/NewToken.kt b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/NewToken.kt index ba0b1eb21..05a75f7b6 100644 --- a/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/NewToken.kt +++ b/client/android/div/src/main/java/com/yandex/div/core/view2/reuse/NewToken.kt @@ -27,6 +27,7 @@ internal class NewToken( is Div.Input -> listOf() is Div.Select -> listOf() is Div.Video -> listOf() + is Div.Switch -> listOf() is Div.Container -> div.value.buildItems(resolver).itemsToNewTokenList() is Div.Custom -> div.value.nonNullItems.toDivItemBuilderResult(resolver).itemsToNewTokenList() is Div.Grid -> div.value.itemsToDivItemBuilderResult(resolver).itemsToNewTokenList() diff --git a/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt b/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt index 74ccaf6f3..7ca7c9f3c 100644 --- a/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt +++ b/client/android/div/src/main/java/com/yandex/div/internal/core/DivCollectionExtensions.kt @@ -109,6 +109,7 @@ private fun Div.copy(id: String? = value().id): Div { is Div.Input -> Div.Input(value.copy(id = id)) is Div.Select -> Div.Select(value.copy(id = id)) is Div.Video -> Div.Video(value.copy(id = id)) + is Div.Switch -> Div.Switch(value.copy(id = id)) } } diff --git a/client/android/div/src/main/java/com/yandex/div/internal/core/DivVisitor.kt b/client/android/div/src/main/java/com/yandex/div/internal/core/DivVisitor.kt index ed28acb9b..dd62f8023 100644 --- a/client/android/div/src/main/java/com/yandex/div/internal/core/DivVisitor.kt +++ b/client/android/div/src/main/java/com/yandex/div/internal/core/DivVisitor.kt @@ -22,6 +22,7 @@ abstract class DivVisitor { is Div.Input -> visit(div, resolver) is Div.Select -> visit(div, resolver) is Div.Video -> visit(div, resolver) + is Div.Switch -> visit(div, resolver) } } diff --git a/client/ios/DivKit/Extensions/DivContainer/DivContainer+Accessibility.swift b/client/ios/DivKit/Extensions/DivContainer/DivContainer+Accessibility.swift index 927f81679..e5413d635 100644 --- a/client/ios/DivKit/Extensions/DivContainer/DivContainer+Accessibility.swift +++ b/client/ios/DivKit/Extensions/DivContainer/DivContainer+Accessibility.swift @@ -56,6 +56,7 @@ extension Div { .divSeparator, .divSlider, .divState, + .divSwitch, .divTabs, .divVideo: return accessibility?.resolveDescription(expressionResolver) diff --git a/client/ios/DivKit/Extensions/DivData/DivDataPatchExtensions.swift b/client/ios/DivKit/Extensions/DivData/DivDataPatchExtensions.swift index bd3ea16a7..2647eed7b 100644 --- a/client/ios/DivKit/Extensions/DivData/DivDataPatchExtensions.swift +++ b/client/ios/DivKit/Extensions/DivData/DivDataPatchExtensions.swift @@ -81,6 +81,7 @@ extension Div { .divSelect, .divSeparator, .divSlider, + .divSwitch, .divVideo, .divText: // no children diff --git a/client/ios/DivKit/Extensions/DivExtensions.swift b/client/ios/DivKit/Extensions/DivExtensions.swift index db80b328f..5c9a462ab 100644 --- a/client/ios/DivKit/Extensions/DivExtensions.swift +++ b/client/ios/DivKit/Extensions/DivExtensions.swift @@ -17,6 +17,7 @@ extension Div { .divSelect, .divSeparator, .divSlider, + .divSwitch, .divVideo, .divText: [] diff --git a/client/ios/DivKit/Extensions/DivSwitchExtensions.swift b/client/ios/DivKit/Extensions/DivSwitchExtensions.swift new file mode 100644 index 000000000..f9510274f --- /dev/null +++ b/client/ios/DivKit/Extensions/DivSwitchExtensions.swift @@ -0,0 +1,29 @@ +import LayoutKit + +extension DivSwitch: DivBlockModeling { + public func makeBlock(context: DivBlockModelingContext) throws -> Block { + let resolver = context.expressionResolver + let switchVariable = context.makeBinding( + variableName: isOnVariable, + defaultValue: false + ) + + return try applyBaseProperties( + to: { + SwitchBlock( + on: switchVariable, + enabled: resolveIsEnabled(resolver), + action: nil, + onTintColor: resolveOnColor(resolver) + ) + }, + context: context, + actionsHolder: nil, + customAccessibilityParams: CustomAccessibilityParams( + defaultTraits: .switchButton + ) { [unowned self] in + accessibility?.resolveDescription(resolver) + } + ) + } +} diff --git a/client/ios/DivKit/generated_sources/Div.swift b/client/ios/DivKit/generated_sources/Div.swift index da5700688..754816ac2 100644 --- a/client/ios/DivKit/generated_sources/Div.swift +++ b/client/ios/DivKit/generated_sources/Div.swift @@ -19,6 +19,7 @@ public enum Div { case divCustom(DivCustom) case divIndicator(DivIndicator) case divSlider(DivSlider) + case divSwitch(DivSwitch) case divInput(DivInput) case divSelect(DivSelect) case divVideo(DivVideo) @@ -51,6 +52,8 @@ public enum Div { return value case let .divSlider(value): return value + case let .divSwitch(value): + return value case let .divInput(value): return value case let .divSelect(value): @@ -88,6 +91,8 @@ public enum Div { return value.id case let .divSlider(value): return value.id + case let .divSwitch(value): + return value.id case let .divInput(value): return value.id case let .divSelect(value): @@ -128,6 +133,8 @@ extension Div: Equatable { return l == r case let (.divSlider(l), .divSlider(r)): return l == r + case let (.divSwitch(l), .divSwitch(r)): + return l == r case let (.divInput(l), .divInput(r)): return l == r case let (.divSelect(l), .divSelect(r)): diff --git a/client/ios/DivKit/generated_sources/DivSwitch.swift b/client/ios/DivKit/generated_sources/DivSwitch.swift new file mode 100644 index 000000000..8963c13de --- /dev/null +++ b/client/ios/DivKit/generated_sources/DivSwitch.swift @@ -0,0 +1,300 @@ +// Generated code. Do not modify. + +import Foundation +import Serialization +import VGSL + +public final class DivSwitch: DivBase { + public static let type: String = "switch" + public let accessibility: DivAccessibility? + public let alignmentHorizontal: Expression? + public let alignmentVertical: Expression? + public let alpha: Expression // constraint: number >= 0.0 && number <= 1.0; default value: 1.0 + public let animators: [DivAnimator]? + public let background: [DivBackground]? + public let border: DivBorder? + public let columnSpan: Expression? // constraint: number >= 0 + public let disappearActions: [DivDisappearAction]? + public let extensions: [DivExtension]? + public let focus: DivFocus? + public let functions: [DivFunction]? + public let height: DivSize // default value: .divWrapContentSize(DivWrapContentSize()) + public let id: String? + public let isEnabled: Expression // default value: true + public let isOnVariable: String + public let layoutProvider: DivLayoutProvider? + public let margins: DivEdgeInsets? + public let onColor: Expression? + public let paddings: DivEdgeInsets? + public let reuseId: Expression? + public let rowSpan: Expression? // constraint: number >= 0 + public let selectedActions: [DivAction]? + public let tooltips: [DivTooltip]? + public let transform: DivTransform? + public let transitionChange: DivChangeTransition? + public let transitionIn: DivAppearanceTransition? + public let transitionOut: DivAppearanceTransition? + public let transitionTriggers: [DivTransitionTrigger]? // at least 1 elements + public let variableTriggers: [DivTrigger]? + public let variables: [DivVariable]? + public let visibility: Expression // default value: visible + public let visibilityAction: DivVisibilityAction? + public let visibilityActions: [DivVisibilityAction]? + public let width: DivSize // default value: .divMatchParentSize(DivMatchParentSize()) + + public func resolveAlignmentHorizontal(_ resolver: ExpressionResolver) -> DivAlignmentHorizontal? { + resolver.resolveEnum(alignmentHorizontal) + } + + public func resolveAlignmentVertical(_ resolver: ExpressionResolver) -> DivAlignmentVertical? { + resolver.resolveEnum(alignmentVertical) + } + + public func resolveAlpha(_ resolver: ExpressionResolver) -> Double { + resolver.resolveNumeric(alpha) ?? 1.0 + } + + public func resolveColumnSpan(_ resolver: ExpressionResolver) -> Int? { + resolver.resolveNumeric(columnSpan) + } + + public func resolveIsEnabled(_ resolver: ExpressionResolver) -> Bool { + resolver.resolveNumeric(isEnabled) ?? true + } + + public func resolveOnColor(_ resolver: ExpressionResolver) -> Color? { + resolver.resolveColor(onColor) + } + + public func resolveReuseId(_ resolver: ExpressionResolver) -> String? { + resolver.resolveString(reuseId) + } + + public func resolveRowSpan(_ resolver: ExpressionResolver) -> Int? { + resolver.resolveNumeric(rowSpan) + } + + public func resolveVisibility(_ resolver: ExpressionResolver) -> DivVisibility { + resolver.resolveEnum(visibility) ?? DivVisibility.visible + } + + static let alphaValidator: AnyValueValidator = + makeValueValidator(valueValidator: { $0 >= 0.0 && $0 <= 1.0 }) + + static let columnSpanValidator: AnyValueValidator = + makeValueValidator(valueValidator: { $0 >= 0 }) + + static let rowSpanValidator: AnyValueValidator = + makeValueValidator(valueValidator: { $0 >= 0 }) + + static let transitionTriggersValidator: AnyArrayValueValidator = + makeArrayValidator(minItems: 1) + + init( + accessibility: DivAccessibility? = nil, + alignmentHorizontal: Expression? = nil, + alignmentVertical: Expression? = nil, + alpha: Expression? = nil, + animators: [DivAnimator]? = nil, + background: [DivBackground]? = nil, + border: DivBorder? = nil, + columnSpan: Expression? = nil, + disappearActions: [DivDisappearAction]? = nil, + extensions: [DivExtension]? = nil, + focus: DivFocus? = nil, + functions: [DivFunction]? = nil, + height: DivSize? = nil, + id: String? = nil, + isEnabled: Expression? = nil, + isOnVariable: String, + layoutProvider: DivLayoutProvider? = nil, + margins: DivEdgeInsets? = nil, + onColor: Expression? = nil, + paddings: DivEdgeInsets? = nil, + reuseId: Expression? = nil, + rowSpan: Expression? = nil, + selectedActions: [DivAction]? = nil, + tooltips: [DivTooltip]? = nil, + transform: DivTransform? = nil, + transitionChange: DivChangeTransition? = nil, + transitionIn: DivAppearanceTransition? = nil, + transitionOut: DivAppearanceTransition? = nil, + transitionTriggers: [DivTransitionTrigger]? = nil, + variableTriggers: [DivTrigger]? = nil, + variables: [DivVariable]? = nil, + visibility: Expression? = nil, + visibilityAction: DivVisibilityAction? = nil, + visibilityActions: [DivVisibilityAction]? = nil, + width: DivSize? = nil + ) { + self.accessibility = accessibility + self.alignmentHorizontal = alignmentHorizontal + self.alignmentVertical = alignmentVertical + self.alpha = alpha ?? .value(1.0) + self.animators = animators + self.background = background + self.border = border + self.columnSpan = columnSpan + self.disappearActions = disappearActions + self.extensions = extensions + self.focus = focus + self.functions = functions + self.height = height ?? .divWrapContentSize(DivWrapContentSize()) + self.id = id + self.isEnabled = isEnabled ?? .value(true) + self.isOnVariable = isOnVariable + self.layoutProvider = layoutProvider + self.margins = margins + self.onColor = onColor + self.paddings = paddings + self.reuseId = reuseId + self.rowSpan = rowSpan + self.selectedActions = selectedActions + self.tooltips = tooltips + self.transform = transform + self.transitionChange = transitionChange + self.transitionIn = transitionIn + self.transitionOut = transitionOut + self.transitionTriggers = transitionTriggers + self.variableTriggers = variableTriggers + self.variables = variables + self.visibility = visibility ?? .value(.visible) + self.visibilityAction = visibilityAction + self.visibilityActions = visibilityActions + self.width = width ?? .divMatchParentSize(DivMatchParentSize()) + } +} + +#if DEBUG +extension DivSwitch: Equatable { + public static func ==(lhs: DivSwitch, rhs: DivSwitch) -> Bool { + guard + lhs.accessibility == rhs.accessibility, + lhs.alignmentHorizontal == rhs.alignmentHorizontal, + lhs.alignmentVertical == rhs.alignmentVertical + else { + return false + } + guard + lhs.alpha == rhs.alpha, + lhs.animators == rhs.animators, + lhs.background == rhs.background + else { + return false + } + guard + lhs.border == rhs.border, + lhs.columnSpan == rhs.columnSpan, + lhs.disappearActions == rhs.disappearActions + else { + return false + } + guard + lhs.extensions == rhs.extensions, + lhs.focus == rhs.focus, + lhs.functions == rhs.functions + else { + return false + } + guard + lhs.height == rhs.height, + lhs.id == rhs.id, + lhs.isEnabled == rhs.isEnabled + else { + return false + } + guard + lhs.isOnVariable == rhs.isOnVariable, + lhs.layoutProvider == rhs.layoutProvider, + lhs.margins == rhs.margins + else { + return false + } + guard + lhs.onColor == rhs.onColor, + lhs.paddings == rhs.paddings, + lhs.reuseId == rhs.reuseId + else { + return false + } + guard + lhs.rowSpan == rhs.rowSpan, + lhs.selectedActions == rhs.selectedActions, + lhs.tooltips == rhs.tooltips + else { + return false + } + guard + lhs.transform == rhs.transform, + lhs.transitionChange == rhs.transitionChange, + lhs.transitionIn == rhs.transitionIn + else { + return false + } + guard + lhs.transitionOut == rhs.transitionOut, + lhs.transitionTriggers == rhs.transitionTriggers, + lhs.variableTriggers == rhs.variableTriggers + else { + return false + } + guard + lhs.variables == rhs.variables, + lhs.visibility == rhs.visibility, + lhs.visibilityAction == rhs.visibilityAction + else { + return false + } + guard + lhs.visibilityActions == rhs.visibilityActions, + lhs.width == rhs.width + else { + return false + } + return true + } +} +#endif + +extension DivSwitch: Serializable { + public func toDictionary() -> [String: ValidSerializationValue] { + var result: [String: ValidSerializationValue] = [:] + result["type"] = Self.type + result["accessibility"] = accessibility?.toDictionary() + result["alignment_horizontal"] = alignmentHorizontal?.toValidSerializationValue() + result["alignment_vertical"] = alignmentVertical?.toValidSerializationValue() + result["alpha"] = alpha.toValidSerializationValue() + result["animators"] = animators?.map { $0.toDictionary() } + result["background"] = background?.map { $0.toDictionary() } + result["border"] = border?.toDictionary() + result["column_span"] = columnSpan?.toValidSerializationValue() + result["disappear_actions"] = disappearActions?.map { $0.toDictionary() } + result["extensions"] = extensions?.map { $0.toDictionary() } + result["focus"] = focus?.toDictionary() + result["functions"] = functions?.map { $0.toDictionary() } + result["height"] = height.toDictionary() + result["id"] = id + result["is_enabled"] = isEnabled.toValidSerializationValue() + result["is_on_variable"] = isOnVariable + result["layout_provider"] = layoutProvider?.toDictionary() + result["margins"] = margins?.toDictionary() + result["on_color"] = onColor?.toValidSerializationValue() + result["paddings"] = paddings?.toDictionary() + result["reuse_id"] = reuseId?.toValidSerializationValue() + result["row_span"] = rowSpan?.toValidSerializationValue() + result["selected_actions"] = selectedActions?.map { $0.toDictionary() } + result["tooltips"] = tooltips?.map { $0.toDictionary() } + result["transform"] = transform?.toDictionary() + result["transition_change"] = transitionChange?.toDictionary() + result["transition_in"] = transitionIn?.toDictionary() + result["transition_out"] = transitionOut?.toDictionary() + result["transition_triggers"] = transitionTriggers?.map { $0.rawValue } + result["variable_triggers"] = variableTriggers?.map { $0.toDictionary() } + result["variables"] = variables?.map { $0.toDictionary() } + result["visibility"] = visibility.toValidSerializationValue() + result["visibility_action"] = visibilityAction?.toDictionary() + result["visibility_actions"] = visibilityActions?.map { $0.toDictionary() } + result["width"] = width.toDictionary() + return result + } +} diff --git a/client/ios/DivKit/generated_sources/DivSwitchTemplate.swift b/client/ios/DivKit/generated_sources/DivSwitchTemplate.swift new file mode 100644 index 000000000..fe9729484 --- /dev/null +++ b/client/ios/DivKit/generated_sources/DivSwitchTemplate.swift @@ -0,0 +1,879 @@ +// Generated code. Do not modify. + +import Foundation +import Serialization +import VGSL + +public final class DivSwitchTemplate: TemplateValue { + public static let type: String = "switch" + public let parent: String? + public let accessibility: Field? + public let alignmentHorizontal: Field>? + public let alignmentVertical: Field>? + public let alpha: Field>? // constraint: number >= 0.0 && number <= 1.0; default value: 1.0 + public let animators: Field<[DivAnimatorTemplate]>? + public let background: Field<[DivBackgroundTemplate]>? + public let border: Field? + public let columnSpan: Field>? // constraint: number >= 0 + public let disappearActions: Field<[DivDisappearActionTemplate]>? + public let extensions: Field<[DivExtensionTemplate]>? + public let focus: Field? + public let functions: Field<[DivFunctionTemplate]>? + public let height: Field? // default value: .divWrapContentSize(DivWrapContentSize()) + public let id: Field? + public let isEnabled: Field>? // default value: true + public let isOnVariable: Field? + public let layoutProvider: Field? + public let margins: Field? + public let onColor: Field>? + public let paddings: Field? + public let reuseId: Field>? + public let rowSpan: Field>? // constraint: number >= 0 + public let selectedActions: Field<[DivActionTemplate]>? + public let tooltips: Field<[DivTooltipTemplate]>? + public let transform: Field? + public let transitionChange: Field? + public let transitionIn: Field? + public let transitionOut: Field? + public let transitionTriggers: Field<[DivTransitionTrigger]>? // at least 1 elements + public let variableTriggers: Field<[DivTriggerTemplate]>? + public let variables: Field<[DivVariableTemplate]>? + public let visibility: Field>? // default value: visible + public let visibilityAction: Field? + public let visibilityActions: Field<[DivVisibilityActionTemplate]>? + public let width: Field? // default value: .divMatchParentSize(DivMatchParentSize()) + + public convenience init(dictionary: [String: Any], templateToType: [TemplateName: String]) throws { + self.init( + parent: dictionary["type"] as? String, + accessibility: dictionary.getOptionalField("accessibility", templateToType: templateToType), + alignmentHorizontal: dictionary.getOptionalExpressionField("alignment_horizontal"), + alignmentVertical: dictionary.getOptionalExpressionField("alignment_vertical"), + alpha: dictionary.getOptionalExpressionField("alpha"), + animators: dictionary.getOptionalArray("animators", templateToType: templateToType), + background: dictionary.getOptionalArray("background", templateToType: templateToType), + border: dictionary.getOptionalField("border", templateToType: templateToType), + columnSpan: dictionary.getOptionalExpressionField("column_span"), + disappearActions: dictionary.getOptionalArray("disappear_actions", templateToType: templateToType), + extensions: dictionary.getOptionalArray("extensions", templateToType: templateToType), + focus: dictionary.getOptionalField("focus", templateToType: templateToType), + functions: dictionary.getOptionalArray("functions", templateToType: templateToType), + height: dictionary.getOptionalField("height", templateToType: templateToType), + id: dictionary.getOptionalField("id"), + isEnabled: dictionary.getOptionalExpressionField("is_enabled"), + isOnVariable: dictionary.getOptionalField("is_on_variable"), + layoutProvider: dictionary.getOptionalField("layout_provider", templateToType: templateToType), + margins: dictionary.getOptionalField("margins", templateToType: templateToType), + onColor: dictionary.getOptionalExpressionField("on_color", transform: Color.color(withHexString:)), + paddings: dictionary.getOptionalField("paddings", templateToType: templateToType), + reuseId: dictionary.getOptionalExpressionField("reuse_id"), + rowSpan: dictionary.getOptionalExpressionField("row_span"), + selectedActions: dictionary.getOptionalArray("selected_actions", templateToType: templateToType), + tooltips: dictionary.getOptionalArray("tooltips", templateToType: templateToType), + transform: dictionary.getOptionalField("transform", templateToType: templateToType), + transitionChange: dictionary.getOptionalField("transition_change", templateToType: templateToType), + transitionIn: dictionary.getOptionalField("transition_in", templateToType: templateToType), + transitionOut: dictionary.getOptionalField("transition_out", templateToType: templateToType), + transitionTriggers: dictionary.getOptionalArray("transition_triggers"), + variableTriggers: dictionary.getOptionalArray("variable_triggers", templateToType: templateToType), + variables: dictionary.getOptionalArray("variables", templateToType: templateToType), + visibility: dictionary.getOptionalExpressionField("visibility"), + visibilityAction: dictionary.getOptionalField("visibility_action", templateToType: templateToType), + visibilityActions: dictionary.getOptionalArray("visibility_actions", templateToType: templateToType), + width: dictionary.getOptionalField("width", templateToType: templateToType) + ) + } + + init( + parent: String?, + accessibility: Field? = nil, + alignmentHorizontal: Field>? = nil, + alignmentVertical: Field>? = nil, + alpha: Field>? = nil, + animators: Field<[DivAnimatorTemplate]>? = nil, + background: Field<[DivBackgroundTemplate]>? = nil, + border: Field? = nil, + columnSpan: Field>? = nil, + disappearActions: Field<[DivDisappearActionTemplate]>? = nil, + extensions: Field<[DivExtensionTemplate]>? = nil, + focus: Field? = nil, + functions: Field<[DivFunctionTemplate]>? = nil, + height: Field? = nil, + id: Field? = nil, + isEnabled: Field>? = nil, + isOnVariable: Field? = nil, + layoutProvider: Field? = nil, + margins: Field? = nil, + onColor: Field>? = nil, + paddings: Field? = nil, + reuseId: Field>? = nil, + rowSpan: Field>? = nil, + selectedActions: Field<[DivActionTemplate]>? = nil, + tooltips: Field<[DivTooltipTemplate]>? = nil, + transform: Field? = nil, + transitionChange: Field? = nil, + transitionIn: Field? = nil, + transitionOut: Field? = nil, + transitionTriggers: Field<[DivTransitionTrigger]>? = nil, + variableTriggers: Field<[DivTriggerTemplate]>? = nil, + variables: Field<[DivVariableTemplate]>? = nil, + visibility: Field>? = nil, + visibilityAction: Field? = nil, + visibilityActions: Field<[DivVisibilityActionTemplate]>? = nil, + width: Field? = nil + ) { + self.parent = parent + self.accessibility = accessibility + self.alignmentHorizontal = alignmentHorizontal + self.alignmentVertical = alignmentVertical + self.alpha = alpha + self.animators = animators + self.background = background + self.border = border + self.columnSpan = columnSpan + self.disappearActions = disappearActions + self.extensions = extensions + self.focus = focus + self.functions = functions + self.height = height + self.id = id + self.isEnabled = isEnabled + self.isOnVariable = isOnVariable + self.layoutProvider = layoutProvider + self.margins = margins + self.onColor = onColor + self.paddings = paddings + self.reuseId = reuseId + self.rowSpan = rowSpan + self.selectedActions = selectedActions + self.tooltips = tooltips + self.transform = transform + self.transitionChange = transitionChange + self.transitionIn = transitionIn + self.transitionOut = transitionOut + self.transitionTriggers = transitionTriggers + self.variableTriggers = variableTriggers + self.variables = variables + self.visibility = visibility + self.visibilityAction = visibilityAction + self.visibilityActions = visibilityActions + self.width = width + } + + private static func resolveOnlyLinks(context: TemplatesContext, parent: DivSwitchTemplate?) -> DeserializationResult { + let accessibilityValue = { parent?.accessibility?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let alignmentHorizontalValue = { parent?.alignmentHorizontal?.resolveOptionalValue(context: context) ?? .noValue }() + let alignmentVerticalValue = { parent?.alignmentVertical?.resolveOptionalValue(context: context) ?? .noValue }() + let alphaValue = { parent?.alpha?.resolveOptionalValue(context: context, validator: ResolvedValue.alphaValidator) ?? .noValue }() + let animatorsValue = { parent?.animators?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let backgroundValue = { parent?.background?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let borderValue = { parent?.border?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let columnSpanValue = { parent?.columnSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.columnSpanValidator) ?? .noValue }() + let disappearActionsValue = { parent?.disappearActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let extensionsValue = { parent?.extensions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let focusValue = { parent?.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let functionsValue = { parent?.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let heightValue = { parent?.height?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let idValue = { parent?.id?.resolveOptionalValue(context: context) ?? .noValue }() + let isEnabledValue = { parent?.isEnabled?.resolveOptionalValue(context: context) ?? .noValue }() + let isOnVariableValue = { parent?.isOnVariable?.resolveValue(context: context) ?? .noValue }() + let layoutProviderValue = { parent?.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let marginsValue = { parent?.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let onColorValue = { parent?.onColor?.resolveOptionalValue(context: context, transform: Color.color(withHexString:)) ?? .noValue }() + let paddingsValue = { parent?.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let reuseIdValue = { parent?.reuseId?.resolveOptionalValue(context: context) ?? .noValue }() + let rowSpanValue = { parent?.rowSpan?.resolveOptionalValue(context: context, validator: ResolvedValue.rowSpanValidator) ?? .noValue }() + let selectedActionsValue = { parent?.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let tooltipsValue = { parent?.tooltips?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let transformValue = { parent?.transform?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let transitionChangeValue = { parent?.transitionChange?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let transitionInValue = { parent?.transitionIn?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let transitionOutValue = { parent?.transitionOut?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let transitionTriggersValue = { parent?.transitionTriggers?.resolveOptionalValue(context: context, validator: ResolvedValue.transitionTriggersValidator) ?? .noValue }() + let variableTriggersValue = { parent?.variableTriggers?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let variablesValue = { parent?.variables?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let visibilityValue = { parent?.visibility?.resolveOptionalValue(context: context) ?? .noValue }() + let visibilityActionValue = { parent?.visibilityAction?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let visibilityActionsValue = { parent?.visibilityActions?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + let widthValue = { parent?.width?.resolveOptionalValue(context: context, useOnlyLinks: true) ?? .noValue }() + var errors = mergeErrors( + accessibilityValue.errorsOrWarnings?.map { .nestedObjectError(field: "accessibility", error: $0) }, + alignmentHorizontalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_horizontal", error: $0) }, + alignmentVerticalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_vertical", error: $0) }, + alphaValue.errorsOrWarnings?.map { .nestedObjectError(field: "alpha", error: $0) }, + animatorsValue.errorsOrWarnings?.map { .nestedObjectError(field: "animators", error: $0) }, + backgroundValue.errorsOrWarnings?.map { .nestedObjectError(field: "background", error: $0) }, + borderValue.errorsOrWarnings?.map { .nestedObjectError(field: "border", error: $0) }, + columnSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "column_span", error: $0) }, + disappearActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "disappear_actions", error: $0) }, + extensionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "extensions", error: $0) }, + focusValue.errorsOrWarnings?.map { .nestedObjectError(field: "focus", error: $0) }, + functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, + heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, + isEnabledValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_enabled", error: $0) }, + isOnVariableValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_on_variable", error: $0) }, + layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, + marginsValue.errorsOrWarnings?.map { .nestedObjectError(field: "margins", error: $0) }, + onColorValue.errorsOrWarnings?.map { .nestedObjectError(field: "on_color", error: $0) }, + paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, + reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, + rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, + selectedActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "selected_actions", error: $0) }, + tooltipsValue.errorsOrWarnings?.map { .nestedObjectError(field: "tooltips", error: $0) }, + transformValue.errorsOrWarnings?.map { .nestedObjectError(field: "transform", error: $0) }, + transitionChangeValue.errorsOrWarnings?.map { .nestedObjectError(field: "transition_change", error: $0) }, + transitionInValue.errorsOrWarnings?.map { .nestedObjectError(field: "transition_in", error: $0) }, + transitionOutValue.errorsOrWarnings?.map { .nestedObjectError(field: "transition_out", error: $0) }, + transitionTriggersValue.errorsOrWarnings?.map { .nestedObjectError(field: "transition_triggers", error: $0) }, + variableTriggersValue.errorsOrWarnings?.map { .nestedObjectError(field: "variable_triggers", error: $0) }, + variablesValue.errorsOrWarnings?.map { .nestedObjectError(field: "variables", error: $0) }, + visibilityValue.errorsOrWarnings?.map { .nestedObjectError(field: "visibility", error: $0) }, + visibilityActionValue.errorsOrWarnings?.map { .nestedObjectError(field: "visibility_action", error: $0) }, + visibilityActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "visibility_actions", error: $0) }, + widthValue.errorsOrWarnings?.map { .nestedObjectError(field: "width", error: $0) } + ) + if case .noValue = isOnVariableValue { + errors.append(.requiredFieldIsMissing(field: "is_on_variable")) + } + guard + let isOnVariableNonNil = isOnVariableValue.value + else { + return .failure(NonEmptyArray(errors)!) + } + let result = DivSwitch( + accessibility: { accessibilityValue.value }(), + alignmentHorizontal: { alignmentHorizontalValue.value }(), + alignmentVertical: { alignmentVerticalValue.value }(), + alpha: { alphaValue.value }(), + animators: { animatorsValue.value }(), + background: { backgroundValue.value }(), + border: { borderValue.value }(), + columnSpan: { columnSpanValue.value }(), + disappearActions: { disappearActionsValue.value }(), + extensions: { extensionsValue.value }(), + focus: { focusValue.value }(), + functions: { functionsValue.value }(), + height: { heightValue.value }(), + id: { idValue.value }(), + isEnabled: { isEnabledValue.value }(), + isOnVariable: { isOnVariableNonNil }(), + layoutProvider: { layoutProviderValue.value }(), + margins: { marginsValue.value }(), + onColor: { onColorValue.value }(), + paddings: { paddingsValue.value }(), + reuseId: { reuseIdValue.value }(), + rowSpan: { rowSpanValue.value }(), + selectedActions: { selectedActionsValue.value }(), + tooltips: { tooltipsValue.value }(), + transform: { transformValue.value }(), + transitionChange: { transitionChangeValue.value }(), + transitionIn: { transitionInValue.value }(), + transitionOut: { transitionOutValue.value }(), + transitionTriggers: { transitionTriggersValue.value }(), + variableTriggers: { variableTriggersValue.value }(), + variables: { variablesValue.value }(), + visibility: { visibilityValue.value }(), + visibilityAction: { visibilityActionValue.value }(), + visibilityActions: { visibilityActionsValue.value }(), + width: { widthValue.value }() + ) + return errors.isEmpty ? .success(result) : .partialSuccess(result, warnings: NonEmptyArray(errors)!) + } + + public static func resolveValue(context: TemplatesContext, parent: DivSwitchTemplate?, useOnlyLinks: Bool) -> DeserializationResult { + if useOnlyLinks { + return resolveOnlyLinks(context: context, parent: parent) + } + var accessibilityValue: DeserializationResult = .noValue + var alignmentHorizontalValue: DeserializationResult> = { parent?.alignmentHorizontal?.value() ?? .noValue }() + var alignmentVerticalValue: DeserializationResult> = { parent?.alignmentVertical?.value() ?? .noValue }() + var alphaValue: DeserializationResult> = { parent?.alpha?.value() ?? .noValue }() + var animatorsValue: DeserializationResult<[DivAnimator]> = .noValue + var backgroundValue: DeserializationResult<[DivBackground]> = .noValue + var borderValue: DeserializationResult = .noValue + var columnSpanValue: DeserializationResult> = { parent?.columnSpan?.value() ?? .noValue }() + var disappearActionsValue: DeserializationResult<[DivDisappearAction]> = .noValue + var extensionsValue: DeserializationResult<[DivExtension]> = .noValue + var focusValue: DeserializationResult = .noValue + var functionsValue: DeserializationResult<[DivFunction]> = .noValue + var heightValue: DeserializationResult = .noValue + var idValue: DeserializationResult = { parent?.id?.value() ?? .noValue }() + var isEnabledValue: DeserializationResult> = { parent?.isEnabled?.value() ?? .noValue }() + var isOnVariableValue: DeserializationResult = { parent?.isOnVariable?.value() ?? .noValue }() + var layoutProviderValue: DeserializationResult = .noValue + var marginsValue: DeserializationResult = .noValue + var onColorValue: DeserializationResult> = { parent?.onColor?.value() ?? .noValue }() + var paddingsValue: DeserializationResult = .noValue + var reuseIdValue: DeserializationResult> = { parent?.reuseId?.value() ?? .noValue }() + var rowSpanValue: DeserializationResult> = { parent?.rowSpan?.value() ?? .noValue }() + var selectedActionsValue: DeserializationResult<[DivAction]> = .noValue + var tooltipsValue: DeserializationResult<[DivTooltip]> = .noValue + var transformValue: DeserializationResult = .noValue + var transitionChangeValue: DeserializationResult = .noValue + var transitionInValue: DeserializationResult = .noValue + var transitionOutValue: DeserializationResult = .noValue + var transitionTriggersValue: DeserializationResult<[DivTransitionTrigger]> = { parent?.transitionTriggers?.value(validatedBy: ResolvedValue.transitionTriggersValidator) ?? .noValue }() + var variableTriggersValue: DeserializationResult<[DivTrigger]> = .noValue + var variablesValue: DeserializationResult<[DivVariable]> = .noValue + var visibilityValue: DeserializationResult> = { parent?.visibility?.value() ?? .noValue }() + var visibilityActionValue: DeserializationResult = .noValue + var visibilityActionsValue: DeserializationResult<[DivVisibilityAction]> = .noValue + var widthValue: DeserializationResult = .noValue + _ = { + // Each field is parsed in its own lambda to keep the stack size managable + // Otherwise the compiler will allocate stack for each intermediate variable + // upfront even when we don't actually visit a relevant branch + for (key, __dictValue) in context.templateData { + _ = { + if key == "accessibility" { + accessibilityValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivAccessibilityTemplate.self).merged(with: accessibilityValue) + } + }() + _ = { + if key == "alignment_horizontal" { + alignmentHorizontalValue = deserialize(__dictValue).merged(with: alignmentHorizontalValue) + } + }() + _ = { + if key == "alignment_vertical" { + alignmentVerticalValue = deserialize(__dictValue).merged(with: alignmentVerticalValue) + } + }() + _ = { + if key == "alpha" { + alphaValue = deserialize(__dictValue, validator: ResolvedValue.alphaValidator).merged(with: alphaValue) + } + }() + _ = { + if key == "animators" { + animatorsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivAnimatorTemplate.self).merged(with: animatorsValue) + } + }() + _ = { + if key == "background" { + backgroundValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivBackgroundTemplate.self).merged(with: backgroundValue) + } + }() + _ = { + if key == "border" { + borderValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivBorderTemplate.self).merged(with: borderValue) + } + }() + _ = { + if key == "column_span" { + columnSpanValue = deserialize(__dictValue, validator: ResolvedValue.columnSpanValidator).merged(with: columnSpanValue) + } + }() + _ = { + if key == "disappear_actions" { + disappearActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivDisappearActionTemplate.self).merged(with: disappearActionsValue) + } + }() + _ = { + if key == "extensions" { + extensionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivExtensionTemplate.self).merged(with: extensionsValue) + } + }() + _ = { + if key == "focus" { + focusValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFocusTemplate.self).merged(with: focusValue) + } + }() + _ = { + if key == "functions" { + functionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFunctionTemplate.self).merged(with: functionsValue) + } + }() + _ = { + if key == "height" { + heightValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self).merged(with: heightValue) + } + }() + _ = { + if key == "id" { + idValue = deserialize(__dictValue).merged(with: idValue) + } + }() + _ = { + if key == "is_enabled" { + isEnabledValue = deserialize(__dictValue).merged(with: isEnabledValue) + } + }() + _ = { + if key == "is_on_variable" { + isOnVariableValue = deserialize(__dictValue).merged(with: isOnVariableValue) + } + }() + _ = { + if key == "layout_provider" { + layoutProviderValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivLayoutProviderTemplate.self).merged(with: layoutProviderValue) + } + }() + _ = { + if key == "margins" { + marginsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self).merged(with: marginsValue) + } + }() + _ = { + if key == "on_color" { + onColorValue = deserialize(__dictValue, transform: Color.color(withHexString:)).merged(with: onColorValue) + } + }() + _ = { + if key == "paddings" { + paddingsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self).merged(with: paddingsValue) + } + }() + _ = { + if key == "reuse_id" { + reuseIdValue = deserialize(__dictValue).merged(with: reuseIdValue) + } + }() + _ = { + if key == "row_span" { + rowSpanValue = deserialize(__dictValue, validator: ResolvedValue.rowSpanValidator).merged(with: rowSpanValue) + } + }() + _ = { + if key == "selected_actions" { + selectedActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self).merged(with: selectedActionsValue) + } + }() + _ = { + if key == "tooltips" { + tooltipsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTooltipTemplate.self).merged(with: tooltipsValue) + } + }() + _ = { + if key == "transform" { + transformValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTransformTemplate.self).merged(with: transformValue) + } + }() + _ = { + if key == "transition_change" { + transitionChangeValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivChangeTransitionTemplate.self).merged(with: transitionChangeValue) + } + }() + _ = { + if key == "transition_in" { + transitionInValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivAppearanceTransitionTemplate.self).merged(with: transitionInValue) + } + }() + _ = { + if key == "transition_out" { + transitionOutValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivAppearanceTransitionTemplate.self).merged(with: transitionOutValue) + } + }() + _ = { + if key == "transition_triggers" { + transitionTriggersValue = deserialize(__dictValue, validator: ResolvedValue.transitionTriggersValidator).merged(with: transitionTriggersValue) + } + }() + _ = { + if key == "variable_triggers" { + variableTriggersValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTriggerTemplate.self).merged(with: variableTriggersValue) + } + }() + _ = { + if key == "variables" { + variablesValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivVariableTemplate.self).merged(with: variablesValue) + } + }() + _ = { + if key == "visibility" { + visibilityValue = deserialize(__dictValue).merged(with: visibilityValue) + } + }() + _ = { + if key == "visibility_action" { + visibilityActionValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivVisibilityActionTemplate.self).merged(with: visibilityActionValue) + } + }() + _ = { + if key == "visibility_actions" { + visibilityActionsValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivVisibilityActionTemplate.self).merged(with: visibilityActionsValue) + } + }() + _ = { + if key == "width" { + widthValue = deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self).merged(with: widthValue) + } + }() + _ = { + if key == parent?.accessibility?.link { + accessibilityValue = accessibilityValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivAccessibilityTemplate.self) }) + } + }() + _ = { + if key == parent?.alignmentHorizontal?.link { + alignmentHorizontalValue = alignmentHorizontalValue.merged(with: { deserialize(__dictValue) }) + } + }() + _ = { + if key == parent?.alignmentVertical?.link { + alignmentVerticalValue = alignmentVerticalValue.merged(with: { deserialize(__dictValue) }) + } + }() + _ = { + if key == parent?.alpha?.link { + alphaValue = alphaValue.merged(with: { deserialize(__dictValue, validator: ResolvedValue.alphaValidator) }) + } + }() + _ = { + if key == parent?.animators?.link { + animatorsValue = animatorsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivAnimatorTemplate.self) }) + } + }() + _ = { + if key == parent?.background?.link { + backgroundValue = backgroundValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivBackgroundTemplate.self) }) + } + }() + _ = { + if key == parent?.border?.link { + borderValue = borderValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivBorderTemplate.self) }) + } + }() + _ = { + if key == parent?.columnSpan?.link { + columnSpanValue = columnSpanValue.merged(with: { deserialize(__dictValue, validator: ResolvedValue.columnSpanValidator) }) + } + }() + _ = { + if key == parent?.disappearActions?.link { + disappearActionsValue = disappearActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivDisappearActionTemplate.self) }) + } + }() + _ = { + if key == parent?.extensions?.link { + extensionsValue = extensionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivExtensionTemplate.self) }) + } + }() + _ = { + if key == parent?.focus?.link { + focusValue = focusValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFocusTemplate.self) }) + } + }() + _ = { + if key == parent?.functions?.link { + functionsValue = functionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivFunctionTemplate.self) }) + } + }() + _ = { + if key == parent?.height?.link { + heightValue = heightValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self) }) + } + }() + _ = { + if key == parent?.id?.link { + idValue = idValue.merged(with: { deserialize(__dictValue) }) + } + }() + _ = { + if key == parent?.isEnabled?.link { + isEnabledValue = isEnabledValue.merged(with: { deserialize(__dictValue) }) + } + }() + _ = { + if key == parent?.isOnVariable?.link { + isOnVariableValue = isOnVariableValue.merged(with: { deserialize(__dictValue) }) + } + }() + _ = { + if key == parent?.layoutProvider?.link { + layoutProviderValue = layoutProviderValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivLayoutProviderTemplate.self) }) + } + }() + _ = { + if key == parent?.margins?.link { + marginsValue = marginsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self) }) + } + }() + _ = { + if key == parent?.onColor?.link { + onColorValue = onColorValue.merged(with: { deserialize(__dictValue, transform: Color.color(withHexString:)) }) + } + }() + _ = { + if key == parent?.paddings?.link { + paddingsValue = paddingsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivEdgeInsetsTemplate.self) }) + } + }() + _ = { + if key == parent?.reuseId?.link { + reuseIdValue = reuseIdValue.merged(with: { deserialize(__dictValue) }) + } + }() + _ = { + if key == parent?.rowSpan?.link { + rowSpanValue = rowSpanValue.merged(with: { deserialize(__dictValue, validator: ResolvedValue.rowSpanValidator) }) + } + }() + _ = { + if key == parent?.selectedActions?.link { + selectedActionsValue = selectedActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivActionTemplate.self) }) + } + }() + _ = { + if key == parent?.tooltips?.link { + tooltipsValue = tooltipsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTooltipTemplate.self) }) + } + }() + _ = { + if key == parent?.transform?.link { + transformValue = transformValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTransformTemplate.self) }) + } + }() + _ = { + if key == parent?.transitionChange?.link { + transitionChangeValue = transitionChangeValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivChangeTransitionTemplate.self) }) + } + }() + _ = { + if key == parent?.transitionIn?.link { + transitionInValue = transitionInValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivAppearanceTransitionTemplate.self) }) + } + }() + _ = { + if key == parent?.transitionOut?.link { + transitionOutValue = transitionOutValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivAppearanceTransitionTemplate.self) }) + } + }() + _ = { + if key == parent?.transitionTriggers?.link { + transitionTriggersValue = transitionTriggersValue.merged(with: { deserialize(__dictValue, validator: ResolvedValue.transitionTriggersValidator) }) + } + }() + _ = { + if key == parent?.variableTriggers?.link { + variableTriggersValue = variableTriggersValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivTriggerTemplate.self) }) + } + }() + _ = { + if key == parent?.variables?.link { + variablesValue = variablesValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivVariableTemplate.self) }) + } + }() + _ = { + if key == parent?.visibility?.link { + visibilityValue = visibilityValue.merged(with: { deserialize(__dictValue) }) + } + }() + _ = { + if key == parent?.visibilityAction?.link { + visibilityActionValue = visibilityActionValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivVisibilityActionTemplate.self) }) + } + }() + _ = { + if key == parent?.visibilityActions?.link { + visibilityActionsValue = visibilityActionsValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivVisibilityActionTemplate.self) }) + } + }() + _ = { + if key == parent?.width?.link { + widthValue = widthValue.merged(with: { deserialize(__dictValue, templates: context.templates, templateToType: context.templateToType, type: DivSizeTemplate.self) }) + } + }() + } + }() + if let parent = parent { + _ = { accessibilityValue = accessibilityValue.merged(with: { parent.accessibility?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { animatorsValue = animatorsValue.merged(with: { parent.animators?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { backgroundValue = backgroundValue.merged(with: { parent.background?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { borderValue = borderValue.merged(with: { parent.border?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { disappearActionsValue = disappearActionsValue.merged(with: { parent.disappearActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { extensionsValue = extensionsValue.merged(with: { parent.extensions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { focusValue = focusValue.merged(with: { parent.focus?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { functionsValue = functionsValue.merged(with: { parent.functions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { heightValue = heightValue.merged(with: { parent.height?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { layoutProviderValue = layoutProviderValue.merged(with: { parent.layoutProvider?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { marginsValue = marginsValue.merged(with: { parent.margins?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { paddingsValue = paddingsValue.merged(with: { parent.paddings?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { selectedActionsValue = selectedActionsValue.merged(with: { parent.selectedActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { tooltipsValue = tooltipsValue.merged(with: { parent.tooltips?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { transformValue = transformValue.merged(with: { parent.transform?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { transitionChangeValue = transitionChangeValue.merged(with: { parent.transitionChange?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { transitionInValue = transitionInValue.merged(with: { parent.transitionIn?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { transitionOutValue = transitionOutValue.merged(with: { parent.transitionOut?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { variableTriggersValue = variableTriggersValue.merged(with: { parent.variableTriggers?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { variablesValue = variablesValue.merged(with: { parent.variables?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { visibilityActionValue = visibilityActionValue.merged(with: { parent.visibilityAction?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { visibilityActionsValue = visibilityActionsValue.merged(with: { parent.visibilityActions?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + _ = { widthValue = widthValue.merged(with: { parent.width?.resolveOptionalValue(context: context, useOnlyLinks: true) }) }() + } + var errors = mergeErrors( + accessibilityValue.errorsOrWarnings?.map { .nestedObjectError(field: "accessibility", error: $0) }, + alignmentHorizontalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_horizontal", error: $0) }, + alignmentVerticalValue.errorsOrWarnings?.map { .nestedObjectError(field: "alignment_vertical", error: $0) }, + alphaValue.errorsOrWarnings?.map { .nestedObjectError(field: "alpha", error: $0) }, + animatorsValue.errorsOrWarnings?.map { .nestedObjectError(field: "animators", error: $0) }, + backgroundValue.errorsOrWarnings?.map { .nestedObjectError(field: "background", error: $0) }, + borderValue.errorsOrWarnings?.map { .nestedObjectError(field: "border", error: $0) }, + columnSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "column_span", error: $0) }, + disappearActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "disappear_actions", error: $0) }, + extensionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "extensions", error: $0) }, + focusValue.errorsOrWarnings?.map { .nestedObjectError(field: "focus", error: $0) }, + functionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "functions", error: $0) }, + heightValue.errorsOrWarnings?.map { .nestedObjectError(field: "height", error: $0) }, + idValue.errorsOrWarnings?.map { .nestedObjectError(field: "id", error: $0) }, + isEnabledValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_enabled", error: $0) }, + isOnVariableValue.errorsOrWarnings?.map { .nestedObjectError(field: "is_on_variable", error: $0) }, + layoutProviderValue.errorsOrWarnings?.map { .nestedObjectError(field: "layout_provider", error: $0) }, + marginsValue.errorsOrWarnings?.map { .nestedObjectError(field: "margins", error: $0) }, + onColorValue.errorsOrWarnings?.map { .nestedObjectError(field: "on_color", error: $0) }, + paddingsValue.errorsOrWarnings?.map { .nestedObjectError(field: "paddings", error: $0) }, + reuseIdValue.errorsOrWarnings?.map { .nestedObjectError(field: "reuse_id", error: $0) }, + rowSpanValue.errorsOrWarnings?.map { .nestedObjectError(field: "row_span", error: $0) }, + selectedActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "selected_actions", error: $0) }, + tooltipsValue.errorsOrWarnings?.map { .nestedObjectError(field: "tooltips", error: $0) }, + transformValue.errorsOrWarnings?.map { .nestedObjectError(field: "transform", error: $0) }, + transitionChangeValue.errorsOrWarnings?.map { .nestedObjectError(field: "transition_change", error: $0) }, + transitionInValue.errorsOrWarnings?.map { .nestedObjectError(field: "transition_in", error: $0) }, + transitionOutValue.errorsOrWarnings?.map { .nestedObjectError(field: "transition_out", error: $0) }, + transitionTriggersValue.errorsOrWarnings?.map { .nestedObjectError(field: "transition_triggers", error: $0) }, + variableTriggersValue.errorsOrWarnings?.map { .nestedObjectError(field: "variable_triggers", error: $0) }, + variablesValue.errorsOrWarnings?.map { .nestedObjectError(field: "variables", error: $0) }, + visibilityValue.errorsOrWarnings?.map { .nestedObjectError(field: "visibility", error: $0) }, + visibilityActionValue.errorsOrWarnings?.map { .nestedObjectError(field: "visibility_action", error: $0) }, + visibilityActionsValue.errorsOrWarnings?.map { .nestedObjectError(field: "visibility_actions", error: $0) }, + widthValue.errorsOrWarnings?.map { .nestedObjectError(field: "width", error: $0) } + ) + if case .noValue = isOnVariableValue { + errors.append(.requiredFieldIsMissing(field: "is_on_variable")) + } + guard + let isOnVariableNonNil = isOnVariableValue.value + else { + return .failure(NonEmptyArray(errors)!) + } + let result = DivSwitch( + accessibility: { accessibilityValue.value }(), + alignmentHorizontal: { alignmentHorizontalValue.value }(), + alignmentVertical: { alignmentVerticalValue.value }(), + alpha: { alphaValue.value }(), + animators: { animatorsValue.value }(), + background: { backgroundValue.value }(), + border: { borderValue.value }(), + columnSpan: { columnSpanValue.value }(), + disappearActions: { disappearActionsValue.value }(), + extensions: { extensionsValue.value }(), + focus: { focusValue.value }(), + functions: { functionsValue.value }(), + height: { heightValue.value }(), + id: { idValue.value }(), + isEnabled: { isEnabledValue.value }(), + isOnVariable: { isOnVariableNonNil }(), + layoutProvider: { layoutProviderValue.value }(), + margins: { marginsValue.value }(), + onColor: { onColorValue.value }(), + paddings: { paddingsValue.value }(), + reuseId: { reuseIdValue.value }(), + rowSpan: { rowSpanValue.value }(), + selectedActions: { selectedActionsValue.value }(), + tooltips: { tooltipsValue.value }(), + transform: { transformValue.value }(), + transitionChange: { transitionChangeValue.value }(), + transitionIn: { transitionInValue.value }(), + transitionOut: { transitionOutValue.value }(), + transitionTriggers: { transitionTriggersValue.value }(), + variableTriggers: { variableTriggersValue.value }(), + variables: { variablesValue.value }(), + visibility: { visibilityValue.value }(), + visibilityAction: { visibilityActionValue.value }(), + visibilityActions: { visibilityActionsValue.value }(), + width: { widthValue.value }() + ) + return errors.isEmpty ? .success(result) : .partialSuccess(result, warnings: NonEmptyArray(errors)!) + } + + private func mergedWithParent(templates: [TemplateName: Any]) throws -> DivSwitchTemplate { + guard let parent = parent, parent != Self.type else { return self } + guard let parentTemplate = templates[parent] as? DivSwitchTemplate else { + throw DeserializationError.unknownType(type: parent) + } + let mergedParent = try parentTemplate.mergedWithParent(templates: templates) + + return DivSwitchTemplate( + parent: nil, + accessibility: accessibility ?? mergedParent.accessibility, + alignmentHorizontal: alignmentHorizontal ?? mergedParent.alignmentHorizontal, + alignmentVertical: alignmentVertical ?? mergedParent.alignmentVertical, + alpha: alpha ?? mergedParent.alpha, + animators: animators ?? mergedParent.animators, + background: background ?? mergedParent.background, + border: border ?? mergedParent.border, + columnSpan: columnSpan ?? mergedParent.columnSpan, + disappearActions: disappearActions ?? mergedParent.disappearActions, + extensions: extensions ?? mergedParent.extensions, + focus: focus ?? mergedParent.focus, + functions: functions ?? mergedParent.functions, + height: height ?? mergedParent.height, + id: id ?? mergedParent.id, + isEnabled: isEnabled ?? mergedParent.isEnabled, + isOnVariable: isOnVariable ?? mergedParent.isOnVariable, + layoutProvider: layoutProvider ?? mergedParent.layoutProvider, + margins: margins ?? mergedParent.margins, + onColor: onColor ?? mergedParent.onColor, + paddings: paddings ?? mergedParent.paddings, + reuseId: reuseId ?? mergedParent.reuseId, + rowSpan: rowSpan ?? mergedParent.rowSpan, + selectedActions: selectedActions ?? mergedParent.selectedActions, + tooltips: tooltips ?? mergedParent.tooltips, + transform: transform ?? mergedParent.transform, + transitionChange: transitionChange ?? mergedParent.transitionChange, + transitionIn: transitionIn ?? mergedParent.transitionIn, + transitionOut: transitionOut ?? mergedParent.transitionOut, + transitionTriggers: transitionTriggers ?? mergedParent.transitionTriggers, + variableTriggers: variableTriggers ?? mergedParent.variableTriggers, + variables: variables ?? mergedParent.variables, + visibility: visibility ?? mergedParent.visibility, + visibilityAction: visibilityAction ?? mergedParent.visibilityAction, + visibilityActions: visibilityActions ?? mergedParent.visibilityActions, + width: width ?? mergedParent.width + ) + } + + public func resolveParent(templates: [TemplateName: Any]) throws -> DivSwitchTemplate { + let merged = try mergedWithParent(templates: templates) + + return DivSwitchTemplate( + parent: nil, + accessibility: merged.accessibility?.tryResolveParent(templates: templates), + alignmentHorizontal: merged.alignmentHorizontal, + alignmentVertical: merged.alignmentVertical, + alpha: merged.alpha, + animators: merged.animators?.tryResolveParent(templates: templates), + background: merged.background?.tryResolveParent(templates: templates), + border: merged.border?.tryResolveParent(templates: templates), + columnSpan: merged.columnSpan, + disappearActions: merged.disappearActions?.tryResolveParent(templates: templates), + extensions: merged.extensions?.tryResolveParent(templates: templates), + focus: merged.focus?.tryResolveParent(templates: templates), + functions: merged.functions?.tryResolveParent(templates: templates), + height: merged.height?.tryResolveParent(templates: templates), + id: merged.id, + isEnabled: merged.isEnabled, + isOnVariable: merged.isOnVariable, + layoutProvider: merged.layoutProvider?.tryResolveParent(templates: templates), + margins: merged.margins?.tryResolveParent(templates: templates), + onColor: merged.onColor, + paddings: merged.paddings?.tryResolveParent(templates: templates), + reuseId: merged.reuseId, + rowSpan: merged.rowSpan, + selectedActions: merged.selectedActions?.tryResolveParent(templates: templates), + tooltips: merged.tooltips?.tryResolveParent(templates: templates), + transform: merged.transform?.tryResolveParent(templates: templates), + transitionChange: merged.transitionChange?.tryResolveParent(templates: templates), + transitionIn: merged.transitionIn?.tryResolveParent(templates: templates), + transitionOut: merged.transitionOut?.tryResolveParent(templates: templates), + transitionTriggers: merged.transitionTriggers, + variableTriggers: merged.variableTriggers?.tryResolveParent(templates: templates), + variables: merged.variables?.tryResolveParent(templates: templates), + visibility: merged.visibility, + visibilityAction: merged.visibilityAction?.tryResolveParent(templates: templates), + visibilityActions: merged.visibilityActions?.tryResolveParent(templates: templates), + width: merged.width?.tryResolveParent(templates: templates) + ) + } +} diff --git a/client/ios/DivKit/generated_sources/DivTemplate.swift b/client/ios/DivKit/generated_sources/DivTemplate.swift index 16dbc4f78..56f4425f3 100644 --- a/client/ios/DivKit/generated_sources/DivTemplate.swift +++ b/client/ios/DivKit/generated_sources/DivTemplate.swift @@ -19,6 +19,7 @@ public enum DivTemplate: TemplateValue { case divCustomTemplate(DivCustomTemplate) case divIndicatorTemplate(DivIndicatorTemplate) case divSliderTemplate(DivSliderTemplate) + case divSwitchTemplate(DivSwitchTemplate) case divInputTemplate(DivInputTemplate) case divSelectTemplate(DivSelectTemplate) case divVideoTemplate(DivVideoTemplate) @@ -51,6 +52,8 @@ public enum DivTemplate: TemplateValue { return value case let .divSliderTemplate(value): return value + case let .divSwitchTemplate(value): + return value case let .divInputTemplate(value): return value case let .divSelectTemplate(value): @@ -88,6 +91,8 @@ public enum DivTemplate: TemplateValue { return .divIndicatorTemplate(try value.resolveParent(templates: templates)) case let .divSliderTemplate(value): return .divSliderTemplate(try value.resolveParent(templates: templates)) + case let .divSwitchTemplate(value): + return .divSwitchTemplate(try value.resolveParent(templates: templates)) case let .divInputTemplate(value): return .divInputTemplate(try value.resolveParent(templates: templates)) case let .divSelectTemplate(value): @@ -251,6 +256,17 @@ public enum DivTemplate: TemplateValue { } } else { return nil } }() + result = result ?? { + if case let .divSwitchTemplate(value) = parent { + let result = value.resolveValue(context: context, useOnlyLinks: useOnlyLinks) + switch result { + case let .success(value): return .success(.divSwitch(value)) + case let .partialSuccess(value, warnings): return .partialSuccess(.divSwitch(value), warnings: warnings) + case let .failure(errors): return .failure(errors) + case .noValue: return .noValue + } + } else { return nil } + }() result = result ?? { if case let .divInputTemplate(value) = parent { let result = value.resolveValue(context: context, useOnlyLinks: useOnlyLinks) @@ -412,6 +428,15 @@ public enum DivTemplate: TemplateValue { case .noValue: return .noValue } } else { return nil } }() + result = result ?? { if type == DivSwitch.type { + let result = { DivSwitchTemplate.resolveValue(context: context, useOnlyLinks: useOnlyLinks) }() + switch result { + case let .success(value): return .success(.divSwitch(value)) + case let .partialSuccess(value, warnings): return .partialSuccess(.divSwitch(value), warnings: warnings) + case let .failure(errors): return .failure(errors) + case .noValue: return .noValue + } + } else { return nil } }() result = result ?? { if type == DivInput.type { let result = { DivInputTemplate.resolveValue(context: context, useOnlyLinks: useOnlyLinks) }() switch result { @@ -475,6 +500,8 @@ extension DivTemplate { self = .divIndicatorTemplate(try DivIndicatorTemplate(dictionary: dictionary, templateToType: templateToType)) case DivSliderTemplate.type: self = .divSliderTemplate(try DivSliderTemplate(dictionary: dictionary, templateToType: templateToType)) + case DivSwitchTemplate.type: + self = .divSwitchTemplate(try DivSwitchTemplate(dictionary: dictionary, templateToType: templateToType)) case DivInputTemplate.type: self = .divInputTemplate(try DivInputTemplate(dictionary: dictionary, templateToType: templateToType)) case DivSelectTemplate.type: diff --git a/client/ios/DivKitExtensions/DivExtensions.swift b/client/ios/DivKitExtensions/DivExtensions.swift index e22bda4ac..f5814fdb9 100644 --- a/client/ios/DivKitExtensions/DivExtensions.swift +++ b/client/ios/DivKitExtensions/DivExtensions.swift @@ -35,6 +35,7 @@ extension Div { .divSeparator, .divSlider, .divState, + .divSwitch, .divVideo, .divTabs: break diff --git a/client/ios/LayoutKit/LayoutKit/Blocks/SwitchBlock.swift b/client/ios/LayoutKit/LayoutKit/Blocks/SwitchBlock.swift index 1f2c50567..c0276660c 100644 --- a/client/ios/LayoutKit/LayoutKit/Blocks/SwitchBlock.swift +++ b/client/ios/LayoutKit/LayoutKit/Blocks/SwitchBlock.swift @@ -4,7 +4,7 @@ import Foundation import VGSL public final class SwitchBlock: Block { - public let on: Bool + public let on: Binding public let enabled: Bool public let action: UserInterfaceAction? public let onTintColor: Color? @@ -16,6 +16,20 @@ public final class SwitchBlock: Block { action: UserInterfaceAction?, onTintColor: Color? = nil, accessibilityElement: AccessibilityElement? = nil + ) { + self.on = Binding(name: "", value: Property(booleanLiteral: on)) + self.enabled = enabled + self.action = action + self.onTintColor = onTintColor + self.accessibilityElement = accessibilityElement + } + + public init( + on: Binding, + enabled: Bool, + action: UserInterfaceAction?, + onTintColor: Color? = nil, + accessibilityElement: AccessibilityElement? = nil ) { self.on = on self.enabled = enabled @@ -65,7 +79,7 @@ public final class SwitchBlock: Block { } public func ==(lhs: SwitchBlock, rhs: SwitchBlock) -> Bool { - lhs.on == rhs.on && + lhs.on.value == rhs.on.value && lhs.enabled == rhs.enabled && lhs.action == rhs.action && lhs.onTintColor == rhs.onTintColor && diff --git a/client/ios/LayoutKit/LayoutKit/UI/Blocks/SwitchBlock+UIViewRenderableBlock.swift b/client/ios/LayoutKit/LayoutKit/UI/Blocks/SwitchBlock+UIViewRenderableBlock.swift index 901d0c254..d2dc0c7b4 100644 --- a/client/ios/LayoutKit/LayoutKit/UI/Blocks/SwitchBlock+UIViewRenderableBlock.swift +++ b/client/ios/LayoutKit/LayoutKit/UI/Blocks/SwitchBlock+UIViewRenderableBlock.swift @@ -28,7 +28,7 @@ extension SwitchBlock { private final class SwitchBlockView: BlockView, VisibleBoundsTrackingLeaf { struct Model { - let on: Bool + let on: Binding let enabled: Bool let action: UserInterfaceAction? let onTintColor: Color? @@ -37,7 +37,7 @@ private final class SwitchBlockView: BlockView, VisibleBoundsTrackingLeaf { var model: Model! { didSet { - aSwitch.isOn = model.on + aSwitch.isOn = model.on.value aSwitch.isEnabled = model.enabled aSwitch.onTintColor = model.onTintColor?.systemColor applyAccessibility(model.accessibility) @@ -73,5 +73,6 @@ private final class SwitchBlockView: BlockView, VisibleBoundsTrackingLeaf { if let action = model.action { action.perform(sendingFrom: self) } + model.on.value = aSwitch.isOn } } diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step0.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step0.png new file mode 100644 index 000000000..cb883ae9b Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step0.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step1.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step1.png new file mode 100644 index 000000000..9fe076f5e Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step1.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step2.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step2.png new file mode 100644 index 000000000..c09623c4b Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step2.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step3.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step3.png new file mode 100644 index 000000000..2bee6e300 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step3.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step4.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step4.png new file mode 100644 index 000000000..2bee6e300 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step4.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step5.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step5.png new file mode 100644 index 000000000..2bee6e300 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step5.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step6.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step6.png new file mode 100644 index 000000000..b73d208fa Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step6.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step7.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step7.png new file mode 100644 index 000000000..b7aa7909a Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_375@2x_step7.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step0.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step0.png new file mode 100644 index 000000000..e68462fc0 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step0.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step1.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step1.png new file mode 100644 index 000000000..e20f35a78 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step1.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step2.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step2.png new file mode 100644 index 000000000..7759de2b7 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step2.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step3.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step3.png new file mode 100644 index 000000000..7f966fcc2 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step3.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step4.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step4.png new file mode 100644 index 000000000..7f966fcc2 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step4.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step5.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step5.png new file mode 100644 index 000000000..7f966fcc2 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step5.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step6.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step6.png new file mode 100644 index 000000000..5869ec3df Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step6.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step7.png b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step7.png new file mode 100644 index 000000000..b33ecfc21 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/base-properties_414@3x_step7.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step0.png b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step0.png new file mode 100644 index 000000000..bea9a0d5c Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step0.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step1.png b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step1.png new file mode 100644 index 000000000..b5058ba8c Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step1.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step2.png b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step2.png new file mode 100644 index 000000000..16a4828b2 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step2.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step3.png b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step3.png new file mode 100644 index 000000000..929218cbe Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_375@2x_step3.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step0.png b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step0.png new file mode 100644 index 000000000..f4573af35 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step0.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step1.png b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step1.png new file mode 100644 index 000000000..31983c0c1 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step1.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step2.png b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step2.png new file mode 100644 index 000000000..dcb496ba5 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step2.png differ diff --git a/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step3.png b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step3.png new file mode 100644 index 000000000..285299a14 Binary files /dev/null and b/client/ios/Tests/reference_snapshots/div-switch/switch-properties_414@3x_step3.png differ diff --git a/schema/div-switch.json b/schema/div-switch.json new file mode 100644 index 000000000..9f066837e --- /dev/null +++ b/schema/div-switch.json @@ -0,0 +1,38 @@ +{ + "$description": "translations.json#/div_switch", + "allOf": [ + { + "$ref": "div-base.json" + }, + { + "properties": { + "type": { + "type": "string", + "enum": [ + "switch" + ] + }, + "is_on_variable": { + "$ref": "div-variable-name.json", + "$description": "translations.json#/div_switch_is_on_variable" + }, + "is_enabled": { + "$ref": "common.json#/boolean_int", + "default_value": "true", + "$description": "translations.json#/div_switch_is_enabled" + }, + "on_color": { + "$ref": "common.json#/color", + "$description": "translations.json#/div_switch_on_color" + } + } + } + ], + "platforms": [ + "ios" + ], + "required": [ + "type", + "is_on_variable" + ] +} diff --git a/schema/div.json b/schema/div.json index 588350f7b..ad774a29d 100644 --- a/schema/div.json +++ b/schema/div.json @@ -54,6 +54,10 @@ "$ref": "div-slider.json", "$description": "translations.json#/div_slider_short" }, + { + "$ref": "div-switch.json", + "$description": "translations.json#/div_switch_short" + }, { "$ref": "div-input.json", "$description": "translations.json#/div_input_short" diff --git a/schema/translations.json b/schema/translations.json index 8f3d736b0..8a74c46c4 100644 --- a/schema/translations.json +++ b/schema/translations.json @@ -2071,6 +2071,26 @@ "en": "Stroke width.", "ru": "Толщина рамки." }, + "div_switch": { + "en": "A two-state switch that allows user to toggle a boolean variable. The element has a different appearance depending on the platform. On iOS, the switch size is fixed.", + "ru": "Переключатель с двумя состояниями, который позволяет пользователю переключать булевую переменную. Элемент имеет разный вид в зависимости от платформы. На iOS размер переключателя фиксированный." + }, + "div_switch_short": { + "en": "Switch.", + "ru": "Переключатель." + }, + "div_switch_is_on_variable": { + "en": "The name of the boolean variable for the switch.", + "ru": "Название булевой переменной для переключателя." + }, + "div_switch_is_enabled": { + "en": "Enables or disables the ability to switch an element.", + "ru": "Включает или отключает возможность переключения элемента." + }, + "div_switch_on_color": { + "en": "The color of the switch when it is on. If no color is specified, the default system color is used on iOS, and the color specified in `Div2Context` is used on Android.", + "ru": "Цвет переключателя во включенном состоянии. Если цвет не указан, то на iOS используется стандартный системный цвет, на Android используется цвет, указанный в `Div2Context`." + }, "div_tabs": { "en": "Tabs. Height of the first tab is determined by its contents, and height of the remaining [depends on the platform](../../location#tabs).", "ru": "Табы. Высота первого таба определяется его содержимым, а высота остальных [зависит от платформы](../../location#tabs)." diff --git a/test_data/interactive_snapshot_test_data/div-switch/base-properties.json b/test_data/interactive_snapshot_test_data/div-switch/base-properties.json new file mode 100644 index 000000000..051a45691 --- /dev/null +++ b/test_data/interactive_snapshot_test_data/div-switch/base-properties.json @@ -0,0 +1,244 @@ +{ + "description": "Switch with base properties", + "platforms": [ + "ios" + ], + "div_data": { + "card": { + "log_id": "tests", + "variables": [ + { + "name": "alpha", + "type": "number", + "value": 1.0 + }, + { + "name": "background_color", + "type": "color", + "value": "#FFFFCC" + }, + { + "name": "border_corner_radius", + "type": "integer", + "value": 0 + }, + { + "name": "border_stroke_color", + "type": "color", + "value": "#0000FF" + }, + { + "name": "border_stroke_width", + "type": "number", + "value": 1 + }, + { + "name": "margins", + "type": "integer", + "value": 0 + }, + { + "name": "paddings", + "type": "integer", + "value": 0 + }, + { + "name": "height_value", + "type": "integer", + "value": 250 + }, + { + "name": "width_value", + "type": "integer", + "value": 300 + }, + { + "name": "alignment_horizontal", + "type": "string", + "value": "left" + }, + { + "name": "alignment_vertical", + "type": "string", + "value": "top" + }, + { + "name": "switch_value", + "type": "boolean", + "value": false + } + ], + "states": [ + { + "state_id": 0, + "div": { + "type": "switch", + "is_on_variable": "switch_value", + "alpha": "@{alpha}", + "alignment_horizontal": "@{alignment_horizontal}", + "alignment_vertical": "@{alignment_vertical}", + "background": [ + { + "type": "solid", + "color": "@{background_color}" + } + ], + "border": { + "corner_radius": "@{border_corner_radius}", + "stroke": { + "color": "@{border_stroke_color}", + "width": "@{border_stroke_width}" + } + }, + "paddings": { + "left": "@{paddings}", + "top": "@{paddings}", + "right": "@{paddings}", + "bottom": "@{paddings}" + }, + "margins": { + "left": "@{margins}", + "top": "@{margins}", + "right": "@{margins}", + "bottom": "@{margins}" + }, + "width": { + "type": "fixed", + "value": "@{width_value}" + }, + "height": { + "type": "fixed", + "value": "@{height_value}" + } + } + } + ] + } + }, + "steps": [ + { + "expected_screenshot": "step0.png" + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=background_color&value=%2370A1A1A1", + "log_id": "background_color" + } + ] + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=margins&value=15", + "log_id": "margins" + } + ] + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=paddings&value=15", + "log_id": "paddings" + } + ] + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=width_value&value=150", + "log_id": "width" + }, + { + "url": "div-action://set_variable?name=height_value&value=100", + "log_id": "height" + } + ] + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=alignment_vertical&value=bottom", + "log_id": "alignment_vertical" + }, + { + "url": "div-action://set_variable?name=alignment_horizontal&value=right", + "log_id": "alignment_horizontal" + } + ] + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=border_corner_radius&value=15", + "log_id": "border_corner_radius" + }, + { + "url": "div-action://set_variable?name=border_stroke_color&value=%237000FF00", + "log_id": "border_stroke_color" + }, + { + "url": "div-action://set_variable?name=border_stroke_width&value=3", + "log_id": "border_stroke_width" + } + ] + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=alpha&value=0.2", + "log_id": "alpha" + } + ] + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=alpha&value=1.0", + "log_id": "restore: alpha" + }, + { + "url": "div-action://set_variable?name=background_color&value=%23FFFFCC", + "log_id": "restore: background_color" + }, + { + "url": "div-action://set_variable?name=border_corner_radius&value=0", + "log_id": "restore: border_corner_radius" + }, + { + "url": "div-action://set_variable?name=border_stroke_color&value=%230000FF", + "log_id": "restore: border_stroke_color" + }, + { + "url": "div-action://set_variable?name=border_stroke_width&value=1", + "log_id": "restore: border_stroke_width" + }, + { + "url": "div-action://set_variable?name=margins&value=0", + "log_id": "restore: margins" + }, + { + "url": "div-action://set_variable?name=paddings&value=0", + "log_id": "restore: paddings" + }, + { + "url": "div-action://set_variable?name=height_value&value=250", + "log_id": "restore: height_value" + }, + { + "url": "div-action://set_variable?name=width_value&value=300", + "log_id": "restore: width_value" + }, + { + "url": "div-action://set_variable?name=alignment_horizontal&value=left", + "log_id": "restore: alignment_horizontal" + }, + { + "url": "div-action://set_variable?name=alignment_vertical&value=top", + "log_id": "restore: alignment_vertical" + } + ], + "expected_screenshot": "step0.png" + } + ] +} diff --git a/test_data/interactive_snapshot_test_data/div-switch/switch-properties.json b/test_data/interactive_snapshot_test_data/div-switch/switch-properties.json new file mode 100644 index 000000000..f162fcd30 --- /dev/null +++ b/test_data/interactive_snapshot_test_data/div-switch/switch-properties.json @@ -0,0 +1,68 @@ +{ + "description": "Switch properties", + "platforms": [ + "ios" + ], + "div_data": { + "card": { + "log_id": "tests", + "variables": [ + { + "name": "switch_value", + "type": "boolean", + "value": false + }, + { + "name": "on_color_var", + "type": "color", + "value": "#FFFFFF" + }, + { + "name": "switch_enabled", + "type": "boolean", + "value": true + } + ], + "states": [ + { + "state_id": 0, + "div": { + "type": "switch", + "is_on_variable": "switch_value", + "is_enabled": "@{switch_enabled}", + "on_color": "@{on_color_var}" + } + } + ] + } + }, + "steps": [ + { + "expected_screenshot": "step0.png" + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=switch_value&value=true", + "log_id": "switch_value" + } + ] + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=on_color_var&value=%232a35ad", + "log_id": "change_color" + } + ] + }, + { + "div_actions": [ + { + "url": "div-action://set_variable?name=switch_enabled&value=false", + "log_id": "disable_switch" + } + ] + } + ] +}