Skip to main content

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:

  1. 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.

  2. Indicadores de Corrección: Muestra visualmente si una respuesta seleccionada es correcta o incorrecta, facilitando el feedback inmediato al usuario.

  3. Renderizado Personalizado: Permite definir un componente de botón personalizado (renderButton), brindando control total sobre la apariencia y comportamiento de cada botón.

  4. Temas de Colores: Soporte para combinaciones de colores personalizables, que se adaptan automáticamente para indicar respuestas correctas e incorrectas.

  5. 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 📜

PropTipoDescripción
answersT[]Arreglo de elementos de respuesta que serán renderizados como botones.
isCorrectIndexnumber or nullÍndice de la respuesta seleccionada, o null si no se ha seleccionado ninguna.
isCorrectboolean or nullEstado de corrección de la respuesta seleccionada (true si es correcta, false si es incorrecta, null si no se ha verificado).
checkAnswer(index: number) => voidFunción de callback que se ejecuta al seleccionar una respuesta, pasando el índice de la respuesta seleccionada.
colorCombinationthemesVariants or ThemeTemplateDefine la combinación de colores a aplicar en los botones. Puede ser un tema predefinido o una plantilla personalizada.
correctIndexnumberÍndice de la respuesta correcta para mostrar retroalimentación visual si la selección fue incorrecta.
renderButton(params) => React.ReactNodeFunció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.
itemsPerRownumberNúmero de elementos que se muestran por fila. Valor predeterminado: 2.
containerStyleStyleProp<ViewStyle>Estilos personalizados para el contenedor principal del grupo de botones.
answerContainerStyleStyleProp<ViewStyle>Estilos personalizados para el contenedor de cada fila de respuestas.
answerItemContentStyleStyleProp<ViewStyle>Estilos personalizados para el contenedor individual de cada respuesta.
textStyleStyleProp<TextStyle>Estilos personalizados para el texto dentro de cada botón, permitiendo ajuste de fuente, tamaño y color.
buttonOuterContainerStyleStyleProp<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 🎨

Imagen 1Imagen 2