feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,52 @@
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
import * as React from 'react';
import { Platform } from 'react-native';
import RadioButtonAndroid from './RadioButtonAndroid';
import RadioButtonIOS from './RadioButtonIOS';
import { useInternalTheme } from '../../core/theming';
/**
* Radio buttons allow the selection a single option from a set.
*
* ## Usage
* ```js
* import * as React from 'react';
* import { View } from 'react-native';
* import { RadioButton } from 'react-native-paper';
*
* const MyComponent = () => {
* const [checked, setChecked] = React.useState('first');
*
* return (
* <View>
* <RadioButton
* value="first"
* status={ checked === 'first' ? 'checked' : 'unchecked' }
* onPress={() => setChecked('first')}
* />
* <RadioButton
* value="second"
* status={ checked === 'second' ? 'checked' : 'unchecked' }
* onPress={() => setChecked('second')}
* />
* </View>
* );
* };
*
* export default MyComponent;
* ```
*/
const RadioButton = ({
theme: themeOverrides,
...props
}) => {
const theme = useInternalTheme(themeOverrides);
const Button = Platform.select({
default: RadioButtonAndroid,
ios: RadioButtonIOS
});
return /*#__PURE__*/React.createElement(Button, _extends({}, props, {
theme: theme
}));
};
export default RadioButton;
//# sourceMappingURL=RadioButton.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","Platform","RadioButtonAndroid","RadioButtonIOS","useInternalTheme","RadioButton","theme","themeOverrides","props","Button","select","default","ios","createElement","_extends"],"sourceRoot":"../../../../src","sources":["components/RadioButton/RadioButton.tsx"],"mappings":";AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAAgCC,QAAQ,QAAQ,cAAc;AAE9D,OAAOC,kBAAkB,MAAM,sBAAsB;AACrD,OAAOC,cAAc,MAAM,kBAAkB;AAC7C,SAASC,gBAAgB,QAAQ,oBAAoB;AAsCrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,WAAW,GAAGA,CAAC;EAAEC,KAAK,EAAEC,cAAc;EAAE,GAAGC;AAAa,CAAC,KAAK;EAClE,MAAMF,KAAK,GAAGF,gBAAgB,CAACG,cAAc,CAAC;EAE9C,MAAME,MAAM,GAAGR,QAAQ,CAACS,MAAM,CAAC;IAC7BC,OAAO,EAAET,kBAAkB;IAC3BU,GAAG,EAAET;EACP,CAAC,CAAC;EAEF,oBAAOH,KAAA,CAAAa,aAAA,CAACJ,MAAM,EAAAK,QAAA,KAAKN,KAAK;IAAEF,KAAK,EAAEA;EAAM,EAAE,CAAC;AAC5C,CAAC;AAED,eAAeD,WAAW","ignoreList":[]}

View File

@@ -0,0 +1,138 @@
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
import * as React from 'react';
import { Animated, StyleSheet, View } from 'react-native';
import { RadioButtonContext } from './RadioButtonGroup';
import { handlePress, isChecked } from './utils';
import { useInternalTheme } from '../../core/theming';
import { getAndroidSelectionControlColor } from '../Checkbox/utils';
import TouchableRipple from '../TouchableRipple/TouchableRipple';
const BORDER_WIDTH = 2;
/**
* Radio buttons allow the selection a single option from a set.
* This component follows platform guidelines for Android, but can be used
* on any platform.
*
* @extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple
*/
const RadioButtonAndroid = ({
disabled,
onPress,
theme: themeOverrides,
value,
status,
testID,
...rest
}) => {
const theme = useInternalTheme(themeOverrides);
const {
current: borderAnim
} = React.useRef(new Animated.Value(BORDER_WIDTH));
const {
current: radioAnim
} = React.useRef(new Animated.Value(1));
const isFirstRendering = React.useRef(true);
const {
scale
} = theme.animation;
React.useEffect(() => {
// Do not run animation on very first rendering
if (isFirstRendering.current) {
isFirstRendering.current = false;
return;
}
if (status === 'checked') {
radioAnim.setValue(1.2);
Animated.timing(radioAnim, {
toValue: 1,
duration: 150 * scale,
useNativeDriver: true
}).start();
} else {
borderAnim.setValue(10);
Animated.timing(borderAnim, {
toValue: BORDER_WIDTH,
duration: 150 * scale,
useNativeDriver: false
}).start();
}
}, [status, borderAnim, radioAnim, scale]);
return /*#__PURE__*/React.createElement(RadioButtonContext.Consumer, null, context => {
const checked = isChecked({
contextValue: context === null || context === void 0 ? void 0 : context.value,
status,
value
}) === 'checked';
const {
rippleColor,
selectionControlColor
} = getAndroidSelectionControlColor({
theme,
disabled,
checked,
customColor: rest.color,
customUncheckedColor: rest.uncheckedColor
});
return /*#__PURE__*/React.createElement(TouchableRipple, _extends({}, rest, {
borderless: true,
rippleColor: rippleColor,
onPress: disabled ? undefined : event => {
handlePress({
onPress,
onValueChange: context === null || context === void 0 ? void 0 : context.onValueChange,
value,
event
});
},
accessibilityRole: "radio",
accessibilityState: {
disabled,
checked
},
accessibilityLiveRegion: "polite",
style: styles.container,
testID: testID,
theme: theme
}), /*#__PURE__*/React.createElement(Animated.View, {
style: [styles.radio, {
borderColor: selectionControlColor,
borderWidth: borderAnim
}]
}, checked ? /*#__PURE__*/React.createElement(View, {
style: [StyleSheet.absoluteFill, styles.radioContainer]
}, /*#__PURE__*/React.createElement(Animated.View, {
style: [styles.dot, {
backgroundColor: selectionControlColor,
transform: [{
scale: radioAnim
}]
}]
})) : null));
});
};
RadioButtonAndroid.displayName = 'RadioButton.Android';
const styles = StyleSheet.create({
container: {
borderRadius: 18
},
radioContainer: {
alignItems: 'center',
justifyContent: 'center'
},
radio: {
height: 20,
width: 20,
borderRadius: 10,
margin: 8
},
dot: {
height: 10,
width: 10,
borderRadius: 5
}
});
export default RadioButtonAndroid;
// @component-docs ignore-next-line
export { RadioButtonAndroid };
//# sourceMappingURL=RadioButtonAndroid.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","Animated","StyleSheet","View","RadioButtonContext","handlePress","isChecked","useInternalTheme","getAndroidSelectionControlColor","TouchableRipple","BORDER_WIDTH","RadioButtonAndroid","disabled","onPress","theme","themeOverrides","value","status","testID","rest","current","borderAnim","useRef","Value","radioAnim","isFirstRendering","scale","animation","useEffect","setValue","timing","toValue","duration","useNativeDriver","start","createElement","Consumer","context","checked","contextValue","rippleColor","selectionControlColor","customColor","color","customUncheckedColor","uncheckedColor","_extends","borderless","undefined","event","onValueChange","accessibilityRole","accessibilityState","accessibilityLiveRegion","style","styles","container","radio","borderColor","borderWidth","absoluteFill","radioContainer","dot","backgroundColor","transform","displayName","create","borderRadius","alignItems","justifyContent","height","width","margin"],"sourceRoot":"../../../../src","sources":["components/RadioButton/RadioButtonAndroid.tsx"],"mappings":"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","ignoreList":[]}

View File

@@ -0,0 +1,51 @@
import * as React from 'react';
import { View } from 'react-native';
export const RadioButtonContext = /*#__PURE__*/React.createContext(null);
/**
* Radio button group allows to control a group of radio buttons.
*
* ## Usage
* ```js
* import * as React from 'react';
* import { View } from 'react-native';
* import { RadioButton, Text } from 'react-native-paper';
*
* const MyComponent = () => {
* const [value, setValue] = React.useState('first');
*
* return (
* <RadioButton.Group onValueChange={newValue => setValue(newValue)} value={value}>
* <View>
* <Text>First</Text>
* <RadioButton value="first" />
* </View>
* <View>
* <Text>Second</Text>
* <RadioButton value="second" />
* </View>
* </RadioButton.Group>
* );
* };
*
* export default MyComponent;
*```
*/
const RadioButtonGroup = ({
value,
onValueChange,
children
}) => /*#__PURE__*/React.createElement(RadioButtonContext.Provider, {
value: {
value,
onValueChange
}
}, /*#__PURE__*/React.createElement(View, {
accessibilityRole: "radiogroup"
}, children));
RadioButtonGroup.displayName = 'RadioButton.Group';
export default RadioButtonGroup;
// @component-docs ignore-next-line
export { RadioButtonGroup };
//# sourceMappingURL=RadioButtonGroup.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","View","RadioButtonContext","createContext","RadioButtonGroup","value","onValueChange","children","createElement","Provider","accessibilityRole","displayName"],"sourceRoot":"../../../../src","sources":["components/RadioButton/RadioButtonGroup.tsx"],"mappings":"AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAASC,IAAI,QAAQ,cAAc;AAsBnC,OAAO,MAAMC,kBAAkB,gBAAGF,KAAK,CAACG,aAAa,CACnD,IACF,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,gBAAgB,GAAGA,CAAC;EAAEC,KAAK;EAAEC,aAAa;EAAEC;AAAgB,CAAC,kBACjEP,KAAA,CAAAQ,aAAA,CAACN,kBAAkB,CAACO,QAAQ;EAACJ,KAAK,EAAE;IAAEA,KAAK;IAAEC;EAAc;AAAE,gBAC3DN,KAAA,CAAAQ,aAAA,CAACP,IAAI;EAACS,iBAAiB,EAAC;AAAY,GAAEH,QAAe,CAC1B,CAC9B;AAEDH,gBAAgB,CAACO,WAAW,GAAG,mBAAmB;AAClD,eAAeP,gBAAgB;;AAE/B;AACA,SAASA,gBAAgB","ignoreList":[]}

View File

@@ -0,0 +1,86 @@
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
import { RadioButtonContext } from './RadioButtonGroup';
import { handlePress, isChecked } from './utils';
import { useInternalTheme } from '../../core/theming';
import { getSelectionControlIOSColor } from '../Checkbox/utils';
import MaterialCommunityIcon from '../MaterialCommunityIcon';
import TouchableRipple from '../TouchableRipple/TouchableRipple';
/**
* Radio buttons allow the selection a single option from a set.
* This component follows platform guidelines for iOS, but can be used
* on any platform.
*
* @extends TouchableRipple props https://callstack.github.io/react-native-paper/docs/components/TouchableRipple
*/
const RadioButtonIOS = ({
disabled,
onPress,
theme: themeOverrides,
status,
value,
testID,
...rest
}) => {
const theme = useInternalTheme(themeOverrides);
return /*#__PURE__*/React.createElement(RadioButtonContext.Consumer, null, context => {
const checked = isChecked({
contextValue: context === null || context === void 0 ? void 0 : context.value,
status,
value
}) === 'checked';
const {
checkedColor,
rippleColor
} = getSelectionControlIOSColor({
theme,
disabled,
customColor: rest.color
});
const opacity = checked ? 1 : 0;
return /*#__PURE__*/React.createElement(TouchableRipple, _extends({}, rest, {
borderless: true,
rippleColor: rippleColor,
onPress: disabled ? undefined : event => {
handlePress({
onPress,
value,
onValueChange: context === null || context === void 0 ? void 0 : context.onValueChange,
event
});
},
accessibilityRole: "radio",
accessibilityState: {
disabled,
checked
},
accessibilityLiveRegion: "polite",
style: styles.container,
testID: testID,
theme: theme
}), /*#__PURE__*/React.createElement(View, {
style: {
opacity
}
}, /*#__PURE__*/React.createElement(MaterialCommunityIcon, {
allowFontScaling: false,
name: "check",
size: 24,
color: checkedColor,
direction: "ltr"
})));
});
};
RadioButtonIOS.displayName = 'RadioButton.IOS';
const styles = StyleSheet.create({
container: {
borderRadius: 18,
padding: 6
}
});
export default RadioButtonIOS;
// @component-docs ignore-next-line
export { RadioButtonIOS };
//# sourceMappingURL=RadioButtonIOS.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","StyleSheet","View","RadioButtonContext","handlePress","isChecked","useInternalTheme","getSelectionControlIOSColor","MaterialCommunityIcon","TouchableRipple","RadioButtonIOS","disabled","onPress","theme","themeOverrides","status","value","testID","rest","createElement","Consumer","context","checked","contextValue","checkedColor","rippleColor","customColor","color","opacity","_extends","borderless","undefined","event","onValueChange","accessibilityRole","accessibilityState","accessibilityLiveRegion","style","styles","container","allowFontScaling","name","size","direction","displayName","create","borderRadius","padding"],"sourceRoot":"../../../../src","sources":["components/RadioButton/RadioButtonIOS.tsx"],"mappings":";AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAAgCC,UAAU,EAAEC,IAAI,QAAQ,cAAc;AAEtE,SAASC,kBAAkB,QAAgC,oBAAoB;AAC/E,SAASC,WAAW,EAAEC,SAAS,QAAQ,SAAS;AAChD,SAASC,gBAAgB,QAAQ,oBAAoB;AAErD,SAASC,2BAA2B,QAAQ,mBAAmB;AAC/D,OAAOC,qBAAqB,MAAM,0BAA0B;AAC5D,OAAOC,eAAe,MAAM,oCAAoC;AAiChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,cAAc,GAAGA,CAAC;EACtBC,QAAQ;EACRC,OAAO;EACPC,KAAK,EAAEC,cAAc;EACrBC,MAAM;EACNC,KAAK;EACLC,MAAM;EACN,GAAGC;AACE,CAAC,KAAK;EACX,MAAML,KAAK,GAAGP,gBAAgB,CAACQ,cAAc,CAAC;EAE9C,oBACEd,KAAA,CAAAmB,aAAA,CAAChB,kBAAkB,CAACiB,QAAQ,QACxBC,OAAgC,IAAK;IACrC,MAAMC,OAAO,GACXjB,SAAS,CAAC;MACRkB,YAAY,EAAEF,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEL,KAAK;MAC5BD,MAAM;MACNC;IACF,CAAC,CAAC,KAAK,SAAS;IAElB,MAAM;MAAEQ,YAAY;MAAEC;IAAY,CAAC,GAAGlB,2BAA2B,CAAC;MAChEM,KAAK;MACLF,QAAQ;MACRe,WAAW,EAAER,IAAI,CAACS;IACpB,CAAC,CAAC;IACF,MAAMC,OAAO,GAAGN,OAAO,GAAG,CAAC,GAAG,CAAC;IAE/B,oBACEtB,KAAA,CAAAmB,aAAA,CAACV,eAAe,EAAAoB,QAAA,KACVX,IAAI;MACRY,UAAU;MACVL,WAAW,EAAEA,WAAY;MACzBb,OAAO,EACLD,QAAQ,GACJoB,SAAS,GACRC,KAAK,IAAK;QACT5B,WAAW,CAAC;UACVQ,OAAO;UACPI,KAAK;UACLiB,aAAa,EAAEZ,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEY,aAAa;UACrCD;QACF,CAAC,CAAC;MACJ,CACL;MACDE,iBAAiB,EAAC,OAAO;MACzBC,kBAAkB,EAAE;QAAExB,QAAQ;QAAEW;MAAQ,CAAE;MAC1Cc,uBAAuB,EAAC,QAAQ;MAChCC,KAAK,EAAEC,MAAM,CAACC,SAAU;MACxBtB,MAAM,EAAEA,MAAO;MACfJ,KAAK,EAAEA;IAAM,iBAEbb,KAAA,CAAAmB,aAAA,CAACjB,IAAI;MAACmC,KAAK,EAAE;QAAET;MAAQ;IAAE,gBACvB5B,KAAA,CAAAmB,aAAA,CAACX,qBAAqB;MACpBgC,gBAAgB,EAAE,KAAM;MACxBC,IAAI,EAAC,OAAO;MACZC,IAAI,EAAE,EAAG;MACTf,KAAK,EAAEH,YAAa;MACpBmB,SAAS,EAAC;IAAK,CAChB,CACG,CACS,CAAC;EAEtB,CAC2B,CAAC;AAElC,CAAC;AAEDjC,cAAc,CAACkC,WAAW,GAAG,iBAAiB;AAE9C,MAAMN,MAAM,GAAGrC,UAAU,CAAC4C,MAAM,CAAC;EAC/BN,SAAS,EAAE;IACTO,YAAY,EAAE,EAAE;IAChBC,OAAO,EAAE;EACX;AACF,CAAC,CAAC;AAEF,eAAerC,cAAc;;AAE7B;AACA,SAASA,cAAc","ignoreList":[]}

View File

@@ -0,0 +1,137 @@
import * as React from 'react';
import { StyleSheet, View } from 'react-native';
import RadioButton from './RadioButton';
import RadioButtonAndroid from './RadioButtonAndroid';
import { RadioButtonContext } from './RadioButtonGroup';
import RadioButtonIOS from './RadioButtonIOS';
import { handlePress, isChecked } from './utils';
import { useInternalTheme } from '../../core/theming';
import TouchableRipple from '../TouchableRipple/TouchableRipple';
import Text from '../Typography/Text';
/**
* RadioButton.Item allows you to press the whole row (item) instead of only the RadioButton.
*
* ## Usage
* ```js
* import * as React from 'react';
* import { RadioButton } from 'react-native-paper';
*
* const MyComponent = () => {
* const [value, setValue] = React.useState('first');
*
* return (
* <RadioButton.Group onValueChange={value => setValue(value)} value={value}>
* <RadioButton.Item label="First item" value="first" />
* <RadioButton.Item label="Second item" value="second" />
* </RadioButton.Group>
* );
* };
*
* export default MyComponent;
*```
*/
const RadioButtonItem = ({
value,
label,
style,
labelStyle,
onPress,
onLongPress,
disabled,
color,
uncheckedColor,
rippleColor,
status,
theme: themeOverrides,
background,
accessibilityLabel = label,
testID,
mode,
position = 'trailing',
labelVariant = 'bodyLarge',
labelMaxFontSizeMultiplier,
hitSlop
}) => {
const theme = useInternalTheme(themeOverrides);
const radioButtonProps = {
value,
disabled,
status,
color,
theme,
uncheckedColor
};
const isLeading = position === 'leading';
let radioButton;
if (mode === 'android') {
radioButton = /*#__PURE__*/React.createElement(RadioButtonAndroid, radioButtonProps);
} else if (mode === 'ios') {
radioButton = /*#__PURE__*/React.createElement(RadioButtonIOS, radioButtonProps);
} else {
radioButton = /*#__PURE__*/React.createElement(RadioButton, radioButtonProps);
}
const textColor = theme.isV3 ? theme.colors.onSurface : theme.colors.text;
const disabledTextColor = theme.isV3 ? theme.colors.onSurfaceDisabled : theme.colors.disabled;
const textAlign = isLeading ? 'right' : 'left';
const computedStyle = {
color: disabled ? disabledTextColor : textColor,
textAlign
};
return /*#__PURE__*/React.createElement(RadioButtonContext.Consumer, null, context => {
const checked = isChecked({
contextValue: context === null || context === void 0 ? void 0 : context.value,
status,
value
}) === 'checked';
return /*#__PURE__*/React.createElement(TouchableRipple, {
onPress: event => handlePress({
onPress: onPress,
onValueChange: context === null || context === void 0 ? void 0 : context.onValueChange,
value,
event
}),
onLongPress: onLongPress,
accessibilityLabel: accessibilityLabel,
accessibilityRole: "radio",
accessibilityState: {
checked,
disabled
},
testID: testID,
disabled: disabled,
background: background,
theme: theme,
rippleColor: rippleColor,
hitSlop: hitSlop
}, /*#__PURE__*/React.createElement(View, {
style: [styles.container, style],
pointerEvents: "none"
}, isLeading && radioButton, /*#__PURE__*/React.createElement(Text, {
variant: labelVariant,
style: [styles.label, !theme.isV3 && styles.font, computedStyle, labelStyle],
maxFontSizeMultiplier: labelMaxFontSizeMultiplier
}, label), !isLeading && radioButton));
});
};
RadioButtonItem.displayName = 'RadioButton.Item';
export default RadioButtonItem;
// @component-docs ignore-next-line
export { RadioButtonItem };
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingVertical: 8,
paddingHorizontal: 16
},
label: {
flexShrink: 1,
flexGrow: 1
},
font: {
fontSize: 16
}
});
//# sourceMappingURL=RadioButtonItem.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","StyleSheet","View","RadioButton","RadioButtonAndroid","RadioButtonContext","RadioButtonIOS","handlePress","isChecked","useInternalTheme","TouchableRipple","Text","RadioButtonItem","value","label","style","labelStyle","onPress","onLongPress","disabled","color","uncheckedColor","rippleColor","status","theme","themeOverrides","background","accessibilityLabel","testID","mode","position","labelVariant","labelMaxFontSizeMultiplier","hitSlop","radioButtonProps","isLeading","radioButton","createElement","textColor","isV3","colors","onSurface","text","disabledTextColor","onSurfaceDisabled","textAlign","computedStyle","Consumer","context","checked","contextValue","event","onValueChange","accessibilityRole","accessibilityState","styles","container","pointerEvents","variant","font","maxFontSizeMultiplier","displayName","create","flexDirection","alignItems","justifyContent","paddingVertical","paddingHorizontal","flexShrink","flexGrow","fontSize"],"sourceRoot":"../../../../src","sources":["components/RadioButton/RadioButtonItem.tsx"],"mappings":"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","ignoreList":[]}

View File

@@ -0,0 +1,19 @@
import RadioButtonComponent from './RadioButton';
import RadioButtonAndroid from './RadioButtonAndroid';
import RadioButtonGroup from './RadioButtonGroup';
import RadioButtonIOS from './RadioButtonIOS';
import RadioButtonItem from './RadioButtonItem';
const RadioButton = Object.assign(
// @component ./RadioButton.tsx
RadioButtonComponent, {
// @component ./RadioButtonGroup.tsx
Group: RadioButtonGroup,
// @component ./RadioButtonAndroid.tsx
Android: RadioButtonAndroid,
// @component ./RadioButtonIOS.tsx
IOS: RadioButtonIOS,
// @component ./RadioButtonItem.tsx
Item: RadioButtonItem
});
export default RadioButton;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["RadioButtonComponent","RadioButtonAndroid","RadioButtonGroup","RadioButtonIOS","RadioButtonItem","RadioButton","Object","assign","Group","Android","IOS","Item"],"sourceRoot":"../../../../src","sources":["components/RadioButton/index.ts"],"mappings":"AAAA,OAAOA,oBAAoB,MAAM,eAAe;AAChD,OAAOC,kBAAkB,MAAM,sBAAsB;AACrD,OAAOC,gBAAgB,MAAM,oBAAoB;AACjD,OAAOC,cAAc,MAAM,kBAAkB;AAC7C,OAAOC,eAAe,MAAM,mBAAmB;AAE/C,MAAMC,WAAW,GAAGC,MAAM,CAACC,MAAM;AAC/B;AACAP,oBAAoB,EACpB;EACE;EACAQ,KAAK,EAAEN,gBAAgB;EACvB;EACAO,OAAO,EAAER,kBAAkB;EAC3B;EACAS,GAAG,EAAEP,cAAc;EACnB;EACAQ,IAAI,EAAEP;AACR,CACF,CAAC;AAED,eAAeC,WAAW","ignoreList":[]}

View File

@@ -0,0 +1,23 @@
export const handlePress = ({
onPress,
value,
onValueChange,
event
}) => {
if (onPress && onValueChange) {
console.warn(`onPress in the scope of RadioButtonGroup will not be executed, use onValueChange instead`);
}
onValueChange ? onValueChange(value) : onPress === null || onPress === void 0 ? void 0 : onPress(event);
};
export const isChecked = ({
value,
status,
contextValue
}) => {
if (contextValue !== undefined && contextValue !== null) {
return contextValue === value ? 'checked' : 'unchecked';
} else {
return status;
}
};
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["handlePress","onPress","value","onValueChange","event","console","warn","isChecked","status","contextValue","undefined"],"sourceRoot":"../../../../src","sources":["components/RadioButton/utils.ts"],"mappings":"AAEA,OAAO,MAAMA,WAAW,GAAGA,CAAC;EAC1BC,OAAO;EACPC,KAAK;EACLC,aAAa;EACbC;AAMF,CAAC,KAAK;EACJ,IAAIH,OAAO,IAAIE,aAAa,EAAE;IAC5BE,OAAO,CAACC,IAAI,CACV,0FACF,CAAC;EACH;EAEAH,aAAa,GAAGA,aAAa,CAACD,KAAK,CAAC,GAAGD,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAGG,KAAK,CAAC;AACzD,CAAC;AAED,OAAO,MAAMG,SAAS,GAAGA,CAAC;EACxBL,KAAK;EACLM,MAAM;EACNC;AAKF,CAAC,KAAK;EACJ,IAAIA,YAAY,KAAKC,SAAS,IAAID,YAAY,KAAK,IAAI,EAAE;IACvD,OAAOA,YAAY,KAAKP,KAAK,GAAG,SAAS,GAAG,WAAW;EACzD,CAAC,MAAM;IACL,OAAOM,MAAM;EACf;AACF,CAAC","ignoreList":[]}