@rehagro/ui 1.0.30 → 1.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/native.js CHANGED
@@ -937,6 +937,557 @@ var Card2 = Object.assign(CardRoot, {
937
937
  Content: CardContent,
938
938
  Footer: CardFooter
939
939
  });
940
+ var ChevronIcon = ({ size, color, open }) => /* @__PURE__ */ jsxRuntime.jsx(
941
+ reactNative.View,
942
+ {
943
+ style: {
944
+ width: size,
945
+ height: size,
946
+ alignItems: "center",
947
+ justifyContent: "center"
948
+ },
949
+ children: /* @__PURE__ */ jsxRuntime.jsx(
950
+ reactNative.View,
951
+ {
952
+ style: {
953
+ width: size * 0.5,
954
+ height: size * 0.5,
955
+ borderRightWidth: 2,
956
+ borderBottomWidth: 2,
957
+ borderColor: color,
958
+ transform: [
959
+ { rotate: open ? "225deg" : "45deg" },
960
+ { translateY: open ? size * 0.1 : -size * 0.1 }
961
+ ]
962
+ }
963
+ }
964
+ )
965
+ }
966
+ );
967
+ var CheckIcon2 = ({ size, color }) => /* @__PURE__ */ jsxRuntime.jsx(
968
+ reactNative.View,
969
+ {
970
+ style: {
971
+ width: size,
972
+ height: size,
973
+ alignItems: "center",
974
+ justifyContent: "center"
975
+ },
976
+ children: /* @__PURE__ */ jsxRuntime.jsx(
977
+ reactNative.View,
978
+ {
979
+ style: {
980
+ position: "absolute",
981
+ width: size * 0.55,
982
+ height: size * 0.3,
983
+ borderLeftWidth: 2,
984
+ borderBottomWidth: 2,
985
+ borderColor: color,
986
+ transform: [{ rotate: "-45deg" }, { translateY: -size * 0.05 }]
987
+ }
988
+ }
989
+ )
990
+ }
991
+ );
992
+ var Select = react.forwardRef(function Select2(props, ref) {
993
+ const {
994
+ options,
995
+ label,
996
+ subtitle,
997
+ placeholder = "Selecione",
998
+ status = "default",
999
+ size = "md",
1000
+ radius = "xs",
1001
+ helperText,
1002
+ disabled = false,
1003
+ style,
1004
+ wrapperStyle,
1005
+ accessibilityLabel,
1006
+ multiple = false
1007
+ } = props;
1008
+ const theme = useRehagroTheme();
1009
+ const triggerRef = react.useRef(null);
1010
+ const [isOpen, setIsOpen] = react.useState(false);
1011
+ const [triggerLayout, setTriggerLayout] = react.useState(null);
1012
+ const [internalValue, setInternalValue] = react.useState(() => {
1013
+ if (props.defaultValue !== void 0) {
1014
+ return Array.isArray(props.defaultValue) ? props.defaultValue : [props.defaultValue];
1015
+ }
1016
+ return [];
1017
+ });
1018
+ const isControlled = props.value !== void 0;
1019
+ const selectedValues = isControlled ? Array.isArray(props.value) ? props.value : props.value !== void 0 ? [props.value] : [] : internalValue;
1020
+ const heightMap = {
1021
+ sm: theme.inputHeightSm ?? 36,
1022
+ md: theme.inputHeightMd ?? 44,
1023
+ lg: theme.inputHeightLg ?? 52
1024
+ };
1025
+ const paddingMap2 = {
1026
+ sm: 12,
1027
+ md: 14,
1028
+ lg: 16
1029
+ };
1030
+ const fontSizeMap = {
1031
+ sm: 14,
1032
+ md: 14,
1033
+ lg: 16
1034
+ };
1035
+ const optionPaddingMap = {
1036
+ sm: 8,
1037
+ md: 10,
1038
+ lg: 12
1039
+ };
1040
+ const radiusMap2 = {
1041
+ none: 0,
1042
+ xxs: theme.radiusXxs ?? 4,
1043
+ xs: theme.radiusXs ?? 8,
1044
+ sm: theme.radiusSm ?? 12,
1045
+ md: theme.radiusMd ?? 16,
1046
+ lg: theme.radiusLg ?? 24,
1047
+ xl: theme.radiusXl ?? 32,
1048
+ full: 9999
1049
+ };
1050
+ const dropdownRadiusMap = {
1051
+ none: 0,
1052
+ xxs: theme.radiusXxs ?? 4,
1053
+ xs: theme.radiusXs ?? 8,
1054
+ sm: theme.radiusXs ?? 8,
1055
+ md: theme.radiusXs ?? 8,
1056
+ lg: theme.radiusXs ?? 8,
1057
+ xl: theme.radiusXs ?? 8,
1058
+ full: theme.radiusXs ?? 8
1059
+ };
1060
+ const hasError = status === "error";
1061
+ const borderColor = hasError ? theme.danger : isOpen ? theme.primary : theme.border;
1062
+ const containerStyle = {
1063
+ height: heightMap[size],
1064
+ paddingHorizontal: paddingMap2[size],
1065
+ borderRadius: radiusMap2[radius],
1066
+ borderWidth: theme.borderWidthSm,
1067
+ borderColor,
1068
+ backgroundColor: disabled ? theme.background : theme.surface,
1069
+ flexDirection: "row",
1070
+ alignItems: "center",
1071
+ justifyContent: "space-between",
1072
+ gap: 8,
1073
+ opacity: disabled ? 0.5 : 1
1074
+ };
1075
+ const displayText = react.useMemo(() => {
1076
+ if (selectedValues.length === 0) return null;
1077
+ if (!multiple) {
1078
+ return options.find((o) => o.value === selectedValues[0])?.label ?? null;
1079
+ }
1080
+ const selectedLabels = selectedValues.map((v) => options.find((o) => o.value === v)?.label).filter(Boolean);
1081
+ if (selectedLabels.length === 0) return null;
1082
+ if (selectedLabels.length === 1) return selectedLabels[0];
1083
+ return `${selectedLabels.length} selecionados`;
1084
+ }, [selectedValues, options, multiple]);
1085
+ const handleSelect = react.useCallback(
1086
+ (optionValue) => {
1087
+ if (multiple) {
1088
+ const next = selectedValues.includes(optionValue) ? selectedValues.filter((v) => v !== optionValue) : [...selectedValues, optionValue];
1089
+ if (!isControlled) setInternalValue(next);
1090
+ props.onChange?.(next);
1091
+ } else {
1092
+ const next = [optionValue];
1093
+ if (!isControlled) setInternalValue(next);
1094
+ props.onChange?.(optionValue);
1095
+ setIsOpen(false);
1096
+ }
1097
+ },
1098
+ [multiple, selectedValues, isControlled, props]
1099
+ );
1100
+ const openDropdown = react.useCallback(() => {
1101
+ if (disabled) return;
1102
+ triggerRef.current?.measureInWindow((x, y, width, height) => {
1103
+ setTriggerLayout({ x, y, width, height });
1104
+ setIsOpen(true);
1105
+ });
1106
+ }, [disabled]);
1107
+ const closeDropdown = react.useCallback(() => {
1108
+ setIsOpen(false);
1109
+ }, []);
1110
+ const handleTriggerLayout = (_e) => {
1111
+ if (isOpen) {
1112
+ triggerRef.current?.measureInWindow((x, y, width, height) => {
1113
+ setTriggerLayout({ x, y, width, height });
1114
+ });
1115
+ }
1116
+ };
1117
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [{ gap: 4 }, wrapperStyle], children: [
1118
+ label && /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flexDirection: "row", alignItems: "baseline", gap: 4 }, children: [
1119
+ /* @__PURE__ */ jsxRuntime.jsx(
1120
+ reactNative.Text,
1121
+ {
1122
+ style: {
1123
+ fontSize: 14,
1124
+ fontWeight: "500",
1125
+ color: theme.text,
1126
+ ...theme.fontFamilyBody ? { fontFamily: theme.fontFamilyBody } : {}
1127
+ },
1128
+ children: label
1129
+ }
1130
+ ),
1131
+ subtitle && /* @__PURE__ */ jsxRuntime.jsx(
1132
+ reactNative.Text,
1133
+ {
1134
+ style: {
1135
+ fontSize: 14,
1136
+ color: theme.textMuted,
1137
+ ...theme.fontFamilyBody ? { fontFamily: theme.fontFamilyBody } : {}
1138
+ },
1139
+ children: subtitle
1140
+ }
1141
+ )
1142
+ ] }),
1143
+ /* @__PURE__ */ jsxRuntime.jsxs(
1144
+ reactNative.Pressable,
1145
+ {
1146
+ ref: (node) => {
1147
+ triggerRef.current = node;
1148
+ if (typeof ref === "function") ref(node);
1149
+ else if (ref) ref.current = node;
1150
+ },
1151
+ onPress: openDropdown,
1152
+ onLayout: handleTriggerLayout,
1153
+ disabled,
1154
+ accessibilityRole: "combobox",
1155
+ accessibilityState: { disabled, expanded: isOpen },
1156
+ accessibilityLabel: accessibilityLabel ?? label,
1157
+ style: [containerStyle, style],
1158
+ children: [
1159
+ /* @__PURE__ */ jsxRuntime.jsx(
1160
+ reactNative.Text,
1161
+ {
1162
+ numberOfLines: 1,
1163
+ style: {
1164
+ flex: 1,
1165
+ fontSize: fontSizeMap[size],
1166
+ color: displayText ? theme.text : theme.textMuted,
1167
+ ...theme.fontFamilyBody ? { fontFamily: theme.fontFamilyBody } : {}
1168
+ },
1169
+ children: displayText ?? placeholder
1170
+ }
1171
+ ),
1172
+ /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon, { size: 18, color: theme.textMuted ?? "#6b7280", open: isOpen })
1173
+ ]
1174
+ }
1175
+ ),
1176
+ helperText && /* @__PURE__ */ jsxRuntime.jsx(
1177
+ reactNative.Text,
1178
+ {
1179
+ style: {
1180
+ fontSize: 12,
1181
+ color: hasError ? theme.danger : theme.textMuted,
1182
+ ...theme.fontFamilyBody ? { fontFamily: theme.fontFamilyBody } : {}
1183
+ },
1184
+ children: helperText
1185
+ }
1186
+ ),
1187
+ /* @__PURE__ */ jsxRuntime.jsx(
1188
+ reactNative.Modal,
1189
+ {
1190
+ visible: isOpen,
1191
+ transparent: true,
1192
+ animationType: "fade",
1193
+ onRequestClose: closeDropdown,
1194
+ statusBarTranslucent: true,
1195
+ children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { style: { flex: 1, backgroundColor: "transparent" }, onPress: closeDropdown, children: triggerLayout && /* @__PURE__ */ jsxRuntime.jsx(
1196
+ reactNative.View,
1197
+ {
1198
+ style: {
1199
+ position: "absolute",
1200
+ top: triggerLayout.y + triggerLayout.height + 36,
1201
+ left: triggerLayout.x,
1202
+ width: triggerLayout.width,
1203
+ maxHeight: 240,
1204
+ borderRadius: dropdownRadiusMap[radius],
1205
+ borderWidth: theme.borderWidthSm,
1206
+ borderColor: theme.border,
1207
+ backgroundColor: theme.surface,
1208
+ shadowColor: "#000",
1209
+ shadowOffset: { width: 0, height: 2 },
1210
+ shadowOpacity: 0.1,
1211
+ shadowRadius: 8,
1212
+ elevation: 4,
1213
+ overflow: "hidden"
1214
+ },
1215
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1216
+ reactNative.FlatList,
1217
+ {
1218
+ data: options,
1219
+ keyExtractor: (item) => item.value,
1220
+ keyboardShouldPersistTaps: "handled",
1221
+ renderItem: ({ item }) => {
1222
+ const isSelected = selectedValues.includes(item.value);
1223
+ const isDisabled = !!item.disabled;
1224
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1225
+ reactNative.Pressable,
1226
+ {
1227
+ onPress: () => {
1228
+ if (!isDisabled) handleSelect(item.value);
1229
+ },
1230
+ disabled: isDisabled,
1231
+ accessibilityRole: "menuitem",
1232
+ accessibilityState: { selected: isSelected, disabled: isDisabled },
1233
+ style: ({ pressed }) => ({
1234
+ paddingHorizontal: paddingMap2[size],
1235
+ paddingVertical: optionPaddingMap[size],
1236
+ flexDirection: "row",
1237
+ alignItems: "center",
1238
+ justifyContent: "space-between",
1239
+ gap: 8,
1240
+ backgroundColor: pressed && !isDisabled ? theme.background : "transparent",
1241
+ opacity: isDisabled ? 0.5 : 1
1242
+ }),
1243
+ children: [
1244
+ /* @__PURE__ */ jsxRuntime.jsx(
1245
+ reactNative.Text,
1246
+ {
1247
+ numberOfLines: 1,
1248
+ style: {
1249
+ flex: 1,
1250
+ fontSize: fontSizeMap[size],
1251
+ color: theme.text,
1252
+ ...theme.fontFamilyBody ? { fontFamily: theme.fontFamilyBody } : {}
1253
+ },
1254
+ children: item.label
1255
+ }
1256
+ ),
1257
+ multiple ? /* @__PURE__ */ jsxRuntime.jsx(
1258
+ reactNative.View,
1259
+ {
1260
+ style: {
1261
+ width: 18,
1262
+ height: 18,
1263
+ borderRadius: theme.radiusXxs,
1264
+ borderWidth: theme.borderWidthSm,
1265
+ borderColor: isSelected ? theme.primary : theme.border,
1266
+ backgroundColor: isSelected ? theme.primary : theme.surface,
1267
+ alignItems: "center",
1268
+ justifyContent: "center"
1269
+ },
1270
+ children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(CheckIcon2, { size: 12, color: theme.surface ?? "#ffffff" })
1271
+ }
1272
+ ) : isSelected && /* @__PURE__ */ jsxRuntime.jsx(CheckIcon2, { size: 14, color: theme.primary ?? "#16a34a" })
1273
+ ]
1274
+ }
1275
+ );
1276
+ }
1277
+ }
1278
+ )
1279
+ }
1280
+ ) })
1281
+ }
1282
+ )
1283
+ ] });
1284
+ });
1285
+ var RadioGroupContext = react.createContext(null);
1286
+ var useRadioGroup = () => react.useContext(RadioGroupContext);
1287
+ var PRESET_COLORS4 = /* @__PURE__ */ new Set([
1288
+ "primary",
1289
+ "secondary",
1290
+ "danger",
1291
+ "warning",
1292
+ "success",
1293
+ "info"
1294
+ ]);
1295
+ var isPresetColor4 = (color) => PRESET_COLORS4.has(color);
1296
+ var resolveColor = (color, theme) => {
1297
+ if (isPresetColor4(color)) {
1298
+ return theme[color] ?? "#16a34a";
1299
+ }
1300
+ return color;
1301
+ };
1302
+ var outerSizeMap = {
1303
+ sm: 16,
1304
+ md: 20,
1305
+ lg: 24
1306
+ };
1307
+ var innerSizeMap = {
1308
+ sm: 8,
1309
+ md: 10,
1310
+ lg: 12
1311
+ };
1312
+ var labelSizeMap = {
1313
+ sm: 14,
1314
+ md: 14,
1315
+ lg: 16
1316
+ };
1317
+ var descriptionSizeMap = {
1318
+ sm: 12,
1319
+ md: 12,
1320
+ lg: 14
1321
+ };
1322
+ var gapMap = {
1323
+ sm: 8,
1324
+ md: 12,
1325
+ lg: 16
1326
+ };
1327
+ var Radio = react.forwardRef(function Radio2({
1328
+ size = "md",
1329
+ label,
1330
+ description,
1331
+ color = "primary",
1332
+ disabled,
1333
+ checked: controlledChecked,
1334
+ defaultChecked = false,
1335
+ onChange,
1336
+ style,
1337
+ accessibilityLabel,
1338
+ ...rest
1339
+ }, ref) {
1340
+ const theme = useRehagroTheme();
1341
+ const isControlled = controlledChecked !== void 0;
1342
+ const [internalChecked, setInternalChecked] = react.useState(defaultChecked);
1343
+ const isChecked = isControlled ? controlledChecked : internalChecked;
1344
+ const resolvedColor = resolveColor(color, theme);
1345
+ const handlePress = react.useCallback(() => {
1346
+ if (disabled) return;
1347
+ if (!isControlled) setInternalChecked(true);
1348
+ onChange?.(true);
1349
+ }, [disabled, isControlled, onChange]);
1350
+ const outerSize = outerSizeMap[size];
1351
+ const innerSize = innerSizeMap[size];
1352
+ const outerStyle = {
1353
+ width: outerSize,
1354
+ height: outerSize,
1355
+ borderRadius: outerSize / 2,
1356
+ borderWidth: theme.borderWidthSm ?? 1,
1357
+ borderColor: isChecked ? resolvedColor : theme.border ?? "#d1d5db",
1358
+ backgroundColor: theme.surface ?? "#ffffff",
1359
+ alignItems: "center",
1360
+ justifyContent: "center"
1361
+ };
1362
+ const innerStyle = {
1363
+ width: innerSize,
1364
+ height: innerSize,
1365
+ borderRadius: innerSize / 2,
1366
+ backgroundColor: resolvedColor
1367
+ };
1368
+ const accessibilityText = accessibilityLabel ?? (typeof label === "string" ? label : void 0);
1369
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1370
+ reactNative.Pressable,
1371
+ {
1372
+ ref,
1373
+ onPress: handlePress,
1374
+ disabled,
1375
+ accessibilityRole: "radio",
1376
+ accessibilityState: { checked: isChecked, disabled: !!disabled },
1377
+ accessibilityLabel: accessibilityText,
1378
+ style: [
1379
+ {
1380
+ flexDirection: "row",
1381
+ alignItems: "flex-start",
1382
+ gap: 8,
1383
+ opacity: disabled ? 0.5 : 1
1384
+ },
1385
+ style
1386
+ ],
1387
+ ...rest,
1388
+ children: [
1389
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: outerStyle, children: isChecked && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: innerStyle }) }),
1390
+ (label || description) && /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: { flex: 1, gap: 2 }, children: [
1391
+ label && /* @__PURE__ */ jsxRuntime.jsx(
1392
+ reactNative.Text,
1393
+ {
1394
+ style: {
1395
+ fontSize: labelSizeMap[size],
1396
+ color: theme.text,
1397
+ ...theme.fontFamilyBody ? { fontFamily: theme.fontFamilyBody } : {}
1398
+ },
1399
+ children: label
1400
+ }
1401
+ ),
1402
+ description && /* @__PURE__ */ jsxRuntime.jsx(
1403
+ reactNative.Text,
1404
+ {
1405
+ style: {
1406
+ fontSize: descriptionSizeMap[size],
1407
+ color: theme.textMuted,
1408
+ ...theme.fontFamilyBody ? { fontFamily: theme.fontFamilyBody } : {}
1409
+ },
1410
+ children: description
1411
+ }
1412
+ )
1413
+ ] })
1414
+ ]
1415
+ }
1416
+ );
1417
+ });
1418
+ var RadioOption = react.forwardRef(function RadioOption2({ value, size, color, disabled, ...rest }, ref) {
1419
+ const group = useRadioGroup();
1420
+ const mergedSize = size ?? group?.size ?? "md";
1421
+ const mergedColor = color ?? group?.color ?? "primary";
1422
+ const mergedDisabled = disabled ?? group?.disabled ?? false;
1423
+ const isChecked = group?.value === value;
1424
+ const handleChange = () => {
1425
+ group?.onChange?.(value);
1426
+ };
1427
+ return /* @__PURE__ */ jsxRuntime.jsx(
1428
+ Radio,
1429
+ {
1430
+ ref,
1431
+ size: mergedSize,
1432
+ color: mergedColor,
1433
+ disabled: mergedDisabled,
1434
+ checked: isChecked,
1435
+ onChange: handleChange,
1436
+ ...rest
1437
+ }
1438
+ );
1439
+ });
1440
+ var RadioGroup = react.forwardRef(function RadioGroup2({
1441
+ children,
1442
+ value,
1443
+ defaultValue,
1444
+ onChange,
1445
+ size = "md",
1446
+ orientation = "vertical",
1447
+ color = "primary",
1448
+ disabled = false,
1449
+ gap = "md",
1450
+ style
1451
+ }, ref) {
1452
+ const [internalValue, setInternalValue] = react.useState(defaultValue);
1453
+ const isControlled = value !== void 0;
1454
+ const currentValue = isControlled ? value : internalValue;
1455
+ const handleChange = react.useCallback(
1456
+ (newValue) => {
1457
+ if (!isControlled) setInternalValue(newValue);
1458
+ onChange?.(newValue);
1459
+ },
1460
+ [isControlled, onChange]
1461
+ );
1462
+ return /* @__PURE__ */ jsxRuntime.jsx(
1463
+ RadioGroupContext.Provider,
1464
+ {
1465
+ value: {
1466
+ value: currentValue,
1467
+ onChange: handleChange,
1468
+ size,
1469
+ color,
1470
+ disabled
1471
+ },
1472
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1473
+ reactNative.View,
1474
+ {
1475
+ ref,
1476
+ accessibilityRole: "radiogroup",
1477
+ style: [
1478
+ {
1479
+ flexDirection: orientation === "vertical" ? "column" : "row",
1480
+ flexWrap: orientation === "horizontal" ? "wrap" : "nowrap",
1481
+ gap: gapMap[gap]
1482
+ },
1483
+ style
1484
+ ],
1485
+ children
1486
+ }
1487
+ )
1488
+ }
1489
+ );
1490
+ });
940
1491
 
941
1492
  exports.ActivityIndicator = ActivityIndicator3;
942
1493
  exports.Avatar = Avatar;
@@ -947,7 +1498,11 @@ exports.CardFooter = CardFooter;
947
1498
  exports.CardHeader = CardHeader;
948
1499
  exports.Checkbox = Checkbox;
949
1500
  exports.IconButton = IconButton;
1501
+ exports.Radio = Radio;
1502
+ exports.RadioGroup = RadioGroup;
1503
+ exports.RadioOption = RadioOption;
950
1504
  exports.RehagroNativeProvider = RehagroNativeProvider;
1505
+ exports.Select = Select;
951
1506
  exports.Tag = Tag;
952
1507
  exports.Text = Text5;
953
1508
  exports.TextInput = TextInput;