Skip to content

Commit c3aaa2e

Browse files
authored
Moo/moo 2018/improve existing switch component functionality for mx10 (#436)
2 parents 66425a1 + ac38298 commit c3aaa2e

11 files changed

Lines changed: 181 additions & 130 deletions

File tree

packages/pluggableWidgets/switch-native/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- Added the ability to change the position of the label in horizontal view from the left side of the switch to the right side.
12+
13+
### Fixed
14+
15+
- We fixed an issue where the validation message was rendered inside the view container of the switch, which caused incorrect styling of the switch.
16+
- Fixed an issue where two overlapping tracks were seen in IOS, giving a inconsistent look to switch.
17+
18+
919
## [1.1.0] - 2024-12-3
1020

1121
### Changed

packages/pluggableWidgets/switch-native/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "switch-native",
33
"widgetName": "Switch",
4-
"version": "1.1.0",
4+
"version": "1.1.1",
55
"license": "Apache-2.0",
66
"repository": {
77
"type": "git",

packages/pluggableWidgets/switch-native/src/Switch.tsx

Lines changed: 80 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { flattenStyles } from "@mendix/piw-native-utils-internal";
2-
import { createElement, ReactElement, useCallback } from "react";
3-
import { View, Text, Switch as SwitchComponent, Platform } from "react-native";
2+
import React, { createElement, ReactElement, useCallback, Fragment } from "react";
3+
import { View, Text, Switch as SwitchComponent } from "react-native";
44
import { executeAction } from "@mendix/piw-utils-internal";
55
import { extractStyles } from "@mendix/pluggable-widgets-tools";
66

@@ -10,7 +10,7 @@ import { SwitchStyle, defaultSwitchStyle, CheckBoxInputType } from "./ui/Styles"
1010
export type Props = SwitchProps<SwitchStyle>;
1111

1212
export function Switch(props: Props): ReactElement {
13-
const { label, labelOrientation, showLabel, name, onChange, booleanAttribute } = props;
13+
const { label, labelOrientation, showLabel, name, onChange, booleanAttribute, labelPosition } = props;
1414
const combinedStyles = flattenStyles(defaultSwitchStyle, props.style);
1515
const styles = processStyles(combinedStyles);
1616
const horizontalOrientation = showLabel && labelOrientation === "horizontal";
@@ -39,36 +39,87 @@ export function Switch(props: Props): ReactElement {
3939

4040
const labelValue = label?.status === "available" ? label.value : "";
4141

42+
const switchElement = (
43+
<SwitchComponent
44+
disabled={!editable}
45+
testID={name}
46+
style={inputStyle}
47+
onValueChange={editable ? onChangeCallback : undefined}
48+
value={booleanAttribute.value}
49+
trackColor={{
50+
true: inputProps.trackColorOn,
51+
false: inputProps.trackColorOff
52+
}}
53+
thumbColor={booleanAttribute.value ? inputProps.thumbColorOn : inputProps.thumbColorOff}
54+
/>
55+
);
56+
57+
const labelElement = showLabel ? (
58+
<Text testID={`${name}$label`} style={[labelStyles]}>
59+
{labelValue}
60+
</Text>
61+
) : null;
62+
63+
const validationMessage = hasValidationMessage ? (
64+
<Text testID={`${name}$alert`} style={styles.validationMessage}>
65+
{booleanAttribute.validation}
66+
</Text>
67+
) : null;
68+
4269
return (
4370
<View
4471
testID={`${name}$wrapper`}
45-
style={[containerStyles, horizontalOrientation ? { flexDirection: "row", alignItems: "center" } : null]}
72+
style={[containerStyles, { flexDirection: "column", alignItems: "flex-start" }]}
4673
>
47-
{showLabel ? (
48-
<Text testID={`${name}$label`} style={[labelStyles, horizontalOrientation ? { flex: 1 } : null]}>
49-
{labelValue}
50-
</Text>
51-
) : null}
52-
<View style={[horizontalOrientation ? { flex: 1, alignItems: "flex-end" } : { alignItems: "flex-start" }]}>
53-
<SwitchComponent
54-
disabled={!editable}
55-
testID={name}
56-
style={inputStyle}
57-
onValueChange={editable ? onChangeCallback : undefined}
58-
value={booleanAttribute.value}
59-
trackColor={{
60-
true: inputProps.trackColorOn,
61-
false: inputProps.trackColorOff
62-
}}
63-
thumbColor={booleanAttribute.value ? inputProps.thumbColorOn : inputProps.thumbColorOff}
64-
{...(Platform.OS === "ios" ? { ios_backgroundColor: inputProps.trackColorOff } : {})}
65-
/>
66-
{hasValidationMessage ? (
67-
<Text testID={`${name}$alert`} style={styles.validationMessage}>
68-
{booleanAttribute.validation}
69-
</Text>
70-
) : null}
71-
</View>
74+
{horizontalOrientation ? (
75+
// Horizontal layout: label and switch in a row, validation message below
76+
<>
77+
<View
78+
testID={`${name}$horizontalContainer`}
79+
style={{
80+
flexDirection: "row",
81+
alignItems: "center",
82+
width: "100%",
83+
justifyContent: "space-between"
84+
}}
85+
>
86+
{labelPosition === "right" ? (
87+
<>
88+
{React.cloneElement(switchElement, { key: "switch" })}
89+
<View
90+
style={{
91+
flexDirection: "column",
92+
alignItems: "flex-end"
93+
}}
94+
>
95+
{labelElement && React.cloneElement(labelElement, { key: "label" })}
96+
{validationMessage}
97+
</View>
98+
</>
99+
) : (
100+
<>
101+
<View
102+
style={{
103+
flexDirection: "column",
104+
alignItems: "flex-start"
105+
}}
106+
>
107+
{labelElement && React.cloneElement(labelElement, { key: "label" })}
108+
{validationMessage}
109+
</View>
110+
{React.cloneElement(switchElement, { key: "switch" })}
111+
</>
112+
)}
113+
</View>
114+
</>
115+
) : (
116+
// Vertical layout: label, switch, and validation message all in a column
117+
<>
118+
{labelElement && React.cloneElement(labelElement, { key: "label" })}
119+
{React.cloneElement(switchElement, { key: "switch" })}
120+
{validationMessage}
121+
</>
122+
)}
72123
</View>
73124
);
74125
}

packages/pluggableWidgets/switch-native/src/Switch.xml

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
<?xml version="1.0" encoding="utf-8"?>
2-
<widget id="com.mendix.widget.native.switch.Switch" supportedPlatform="Native" needsEntityContext="true" offlineCapable="true"
3-
pluginWidget="true" xmlns="http://www.mendix.com/widget/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../../../node_modules/mendix/custom_widget.xsd">
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<widget id="com.mendix.widget.native.switch.Switch" supportedPlatform="Native" needsEntityContext="true" offlineCapable="true" pluginWidget="true" xmlns="http://www.mendix.com/widget/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../../../node_modules/mendix/custom_widget.xsd">
53
<name>Switch</name>
64
<description>Toggle a boolean attribute.</description>
75
<studioProCategory>Display</studioProCategory>
@@ -11,44 +9,52 @@
119
<propertyGroup caption="Data source">
1210
<property key="booleanAttribute" type="attribute">
1311
<caption>Attribute</caption>
14-
<description/>
12+
<description />
1513
<attributeTypes>
16-
<attributeType name="Boolean"/>
14+
<attributeType name="Boolean" />
1715
</attributeTypes>
1816
</property>
1917
</propertyGroup>
2018
<propertyGroup caption="Events">
2119
<property key="onChange" type="action" required="false">
2220
<caption>On change</caption>
23-
<description/>
21+
<description />
2422
</property>
2523
</propertyGroup>
2624
<propertyGroup caption="Label">
2725
<property key="showLabel" type="boolean" defaultValue="false">
2826
<caption>Show label</caption>
29-
<description/>
27+
<description />
3028
</property>
3129
<property key="label" type="textTemplate" required="false">
3230
<caption>Label</caption>
33-
<description/>
31+
<description />
3432
</property>
3533
<property key="labelOrientation" type="enumeration" defaultValue="horizontal">
3634
<caption>Label orientation</caption>
37-
<description/>
35+
<description />
3836
<enumerationValues>
3937
<enumerationValue key="horizontal">Horizontal</enumerationValue>
4038
<enumerationValue key="vertical">Vertical</enumerationValue>
4139
</enumerationValues>
4240
</property>
41+
<property key="labelPosition" type="enumeration" defaultValue="left">
42+
<caption>Label position</caption>
43+
<description>The position of the label relative to the switch</description>
44+
<enumerationValues>
45+
<enumerationValue key="left">Left</enumerationValue>
46+
<enumerationValue key="right">Right</enumerationValue>
47+
</enumerationValues>
48+
</property>
4349
</propertyGroup>
4450
<propertyGroup caption="Editability">
45-
<systemProperty key="Editability"/>
51+
<systemProperty key="Editability" />
4652
</propertyGroup>
4753
<propertyGroup caption="Visibility">
48-
<systemProperty key="Visibility"/>
54+
<systemProperty key="Visibility" />
4955
</propertyGroup>
5056
<propertyGroup caption="Common">
51-
<systemProperty key="Name"/>
57+
<systemProperty key="Name" />
5258
</propertyGroup>
5359
</propertyGroup>
5460
</properties>

0 commit comments

Comments
 (0)