SimpleChoiceButtonGroup 🟢🔴
SimpleChoiceButtonGroup es un componente que permite mostrar un grupo de botones de elección simple, organizados en filas. Este componente es altamente flexible, permitiendo personalizar la disposición, los estilos y la lógica de cada botón dentro del grupo. Ideal para actividades de selección con opciones correctas e incorrectas y retroalimentación visual.
Características
SimpleChoiceButtonGroup ofrece una estructura de botones que soporta:
-
Disposición en Filas: Organiza los botones en filas personalizables con un número variable de botones por fila, ajustándose a diferentes configuraciones de diseño.
-
Indicadores de Corrección: Muestra visualmente si una respuesta seleccionada es correcta o incorrecta, facilitando el feedback inmediato al usuario.
-
Renderizado Personalizado: Permite definir un componente de botón personalizado (
renderButton), brindando control total sobre la apariencia y comportamiento de cada botón. -
Temas de Colores: Soporte para combinaciones de colores personalizables, que se adaptan automáticamente para indicar respuestas correctas e incorrectas.
-
Estilos Personalizables:
- Estilo de Contenedor: Personalización completa del contenedor principal y el contenedor de cada respuesta.
- Estilo de Botones: Flexibilidad en los estilos individuales de cada botón, desde el contenedor externo hasta el texto.
Props 📜
| Prop | Tipo | Descripción |
|---|---|---|
answers | T[] | Arreglo de elementos de respuesta que serán renderizados como botones. |
isCorrectIndex | number or null | Índice de la respuesta seleccionada, o null si no se ha seleccionado ninguna. |
isCorrect | boolean or null | Estado de corrección de la respuesta seleccionada (true si es correcta, false si es incorrecta, null si no se ha verificado). |
checkAnswer | (index: number) => void | Función de callback que se ejecuta al seleccionar una respuesta, pasando el índice de la respuesta seleccionada. |
colorCombination | themesVariants or ThemeTemplate | Define la combinación de colores a aplicar en los botones. Puede ser un tema predefinido o una plantilla personalizada. |
correctIndex | number | Índice de la respuesta correcta para mostrar retroalimentación visual si la selección fue incorrecta. |
renderButton | (params) => React.ReactNode | Función de renderizado para personalizar el componente de cada botón. Recibe parámetros como el índice, el estado de selección, el estado de corrección, entre otros. |
itemsPerRow | number | Número de elementos que se muestran por fila. Valor predeterminado: 2. |
containerStyle | StyleProp<ViewStyle> | Estilos personalizados para el contenedor principal del grupo de botones. |
answerContainerStyle | StyleProp<ViewStyle> | Estilos personalizados para el contenedor de cada fila de respuestas. |
answerItemContentStyle | StyleProp<ViewStyle> | Estilos personalizados para el contenedor individual de cada respuesta. |
textStyle | StyleProp<TextStyle> | Estilos personalizados para el texto dentro de cada botón, permitiendo ajuste de fuente, tamaño y color. |
buttonOuterContainerStyle | StyleProp<ViewStyle> | Estilos adicionales para el contenedor externo de cada botón, útil para configurar márgenes, bordes, etc. |
Codigo de ejemplo 🕹️
Native Versión 📱: EmojiGridChoice
<SimpleChoiceButtonGroup
answers={options}
isCorrectIndex={null}
isCorrect={null}
checkAnswer={(index) => handleButtonPress(index)}
correctIndex={correctAnswerIndex}
itemsPerRow={2}
answerContainerStyle={{
paddingHorizontal: 40,
}}
renderButton={({ item, index, onPress }) => {
const isSelected = selectedButtonIndices.includes(index);
const isRemaining = remainingOption === index;
const buttonBackgroundSource = isRemaining
? remainingButtonBackground
: isSelected
? require("assets/images/metrobot/m1/CP01/05-btn-presionado.png")
: require("assets/images/metrobot/m1/CP01/02-btn-original.png");
const buttonImageStyle = isSelected
? [styles.imageBackgroundStyle, styles.selectedImageBackground]
: styles.imageBackgroundStyle;
return (
<ImageBackground
key={index}
source={buttonBackgroundSource}
style={styles.imageBackground}
imageStyle={buttonImageStyle}
>
<BaseButton
onPress={onPress}
isCorrect={item === correctAnswer}
containerStyles={styles.button}
colorCombination="none"
usePressAnimation={false}
lottiViewStyle={{
width: Dimensions.get("window").width * 0.4,
height: Dimensions.get("window").height * 0.25,
marginBottom: 50,
marginRight: 10,
}}
playBrillo={
isRemaining &&
remainingButtonBackground ===
require("assets/images/metrobot/m1/CP01/03-btn-correcto.png")
}
disabled={buttonsDisabled} // Deshabilitar el botón si `buttonsDisabled` es true
>
<Animated.View
style={{
transform: [{ translateY: animatedPositions[index] }],
}}
>
{typeof item === "string" ? (
<AtomText variant="textBold" style={styles.text}>
{item}
</AtomText>
) : (
<Animated.Image source={item} style={styles.icon} />
)}
</Animated.View>
</BaseButton>
{showCorrectOverlay && index === correctAnswerIndex && (
<View style={styles.overlayContainer}>
<ImageBackground
source={require("assets/images/metrobot/m1/CP01/50-cheque-correcto.png")}
style={styles.overlayImage}
/>
</View>
)}
</ImageBackground>
);
}}
/>
Web Versión 💻: EmojiGridChoice
<SimpleChoiceButtonGroup
answers={options}
isCorrectIndex={null}
isCorrect={null}
checkAnswer={(index) => handleButtonPress(index)}
correctIndex={correctAnswerIndex}
itemsPerRow={2}
answerContainerStyle={{
flex: 1,
paddingHorizontal: 110,
marginLeft: 5,
}}
renderButton={({ item, index, onPress }) => {
const isSelected = selectedButtonIndices.includes(index);
const isRemaining = remainingOption === index;
const buttonBackgroundSource = isRemaining
? remainingButtonBackground
: isSelected
? require("assets/images/metrobot/m1/CP01/05-btn-presionado.png")
: require("assets/images/metrobot/m1/CP01/02-btn-original.png");
const buttonImageStyle = isSelected
? [styles.imageBackgroundStyle, styles.selectedImageBackground]
: styles.imageBackgroundStyle;
return (
<ImageBackground
key={index}
source={buttonBackgroundSource}
style={styles.imageBackground}
imageStyle={buttonImageStyle}
>
<BaseButton
onPress={onPress}
isCorrect={item === correctAnswer}
containerStyles={styles.button}
colorCombination="none"
usePressAnimation={false}
lottiViewStyle={{
width: 300,
height: 300,
marginTop: 80,
}}
playBrillo={
isRemaining &&
remainingButtonBackground ===
require("assets/images/metrobot/m1/CP01/03-btn-correcto.png")
}
disabled={buttonsDisabled} // Deshabilitar el botón si `buttonsDisabled` es true
>
<Animated.View
style={{
transform: [{ translateY: animatedPositions[index] }],
}}
>
{typeof item === "string" ? (
<AtomText
variant="textBold"
style={[
styles.text,
{
fontSize: isSmallFontNeeded ? 15 : 17,
},
]}
>
{item}
</AtomText>
) : (
<Animated.Image source={item} style={styles.icon} />
)}
</Animated.View>
</BaseButton>
{showCorrectOverlay && index === correctAnswerIndex && (
<View style={styles.overlayContainer}>
<ImageBackground
source={require("assets/images/metrobot/m1/CP01/50-cheque-correcto.png")}
style={styles.overlayImage}
/>
</View>
)}
</ImageBackground>
);
}}
/>
Ejemplos de uso 🎨
![]() | ![]() |
|---|

