11import { 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" ;
44import { executeAction } from "@mendix/piw-utils-internal" ;
55import { extractStyles } from "@mendix/pluggable-widgets-tools" ;
66
@@ -10,7 +10,7 @@ import { SwitchStyle, defaultSwitchStyle, CheckBoxInputType } from "./ui/Styles"
1010export type Props = SwitchProps < SwitchStyle > ;
1111
1212export 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}
0 commit comments