7.3-35. Botón flotante personalizado

 

Creando un Botón Flotante Personalizado (FAB) en React Native

Uno de los principios fundamentales en React Native es la reutilización de componentes. En este post, aprenderemos a crear un Floating Action Button (FAB) personalizado y completamente reutilizable.

🛠 Por qué crear un componente FAB

  • Evita duplicación de código

  • Centraliza la lógica de estilos

  • Facilita el mantenimiento

  • Mejora la consistencia visual

📦 Estructura Básica del Componente

typescript
// components/FAB.tsx
import React from 'react';
import { Pressable, StyleSheet, Text, ViewStyle } from 'react-native';

interface FABProps {
  label: string;
  onPress?: () => void;
  onLongPress?: () => void;
  position?: 'left' | 'right';
}

export const FAB = ({
  label = '+1',
  onPress,
  onLongPress,
  position = 'right'
}: FABProps) => {
  return (
    <Pressable
      style={[
        styles.button,
        position === 'right' ? styles.positionRight : styles.positionLeft
      ]}
      onPress={onPress}
      onLongPress={onLongPress}
    >
      <Text style={styles.label}>{label}</Text>
    </Pressable>
  );
};

const styles = StyleSheet.create({
  button: {
    position: 'absolute',
    bottom: 20,
    backgroundColor: '#65558F',
    padding: 20,
    borderRadius: 15,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 4 },
    shadowOpacity: 0.3,
    shadowRadius: 4,
    elevation: 5,
  },
  positionRight: {
    right: 20,
  },
  positionLeft: {
    left: 20,
  },
  label: {
    color: 'white',
    fontSize: 20,
    fontWeight: 'bold',
  },
});

🔍 Explicación de las Props

PropTipoDescripciónObligatorio
labelstringTexto que muestra el botón✅ Sí
onPress() => voidFunción al hacer clic normal❌ No
onLongPress() => voidFunción al mantener presionado❌ No
position`'left''right'`Posición horizontal (default: 'right')❌ No

🎨 Personalización Avanzada

1. Añadir más posiciones

typescript
type Position = 'left' | 'right' | 'top' | 'bottom';

interface FABProps {
  // ...
  position?: Position;
}

2. Estilos dinámicos con StyleProp

typescript
import { ViewStyle } from 'react-native';

interface FABProps {
  // ...
  style?: ViewStyle;
}

// Uso en el componente:
<Pressable style={[styles.button, positionStyle, props.style]}>

3. Feedback visual mejorado

typescript
<Pressable
  style={({ pressed }) => [
    styles.button,
    positionStyle,
    { opacity: pressed ? 0.6 : 1 },
    props.style
  ]}
>

🚀 Implementación en la App

typescript
// App.tsx
import { FAB } from './components/FAB';

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <View style={styles.container}>
      <Text style={styles.counter}>{count}</Text>
      
      <FAB
        label="+1"
        position="right"
        onPress={() => setCount(c => c + 1)}
        onLongPress={() => setCount(0)}
      />
      
      <FAB
        label="Reset"
        position="left"
        onPress={() => setCount(0)}
        style={{ backgroundColor: '#E74C3C' }}
      />
    </View>
  );
}

💡 Mejores Prácticas

  1. Documenta tus componentes: Usa JSDoc para explicar las props

    typescript
    /**
     * Botón de acción flotante (FAB) personalizable
     * @param label - Texto a mostrar en el botón
     * @param position - Posición horizontal ('left' | 'right')
     */
  2. Pruebas unitarias: Verifica el comportamiento del componente

  3. Historias en Storybook: Crea documentación visual

  4. Accesibilidad: Añade propiedades como accessibilityLabel

📌 Conclusión

Crear componentes reutilizables como nuestro FAB:

  • Reduce errores al centralizar la lógica

  • Acelera desarrollo en proyectos grandes

  • Facilita mantenimiento al tener una única fuente de verdad

  • Mejora consistencia en la UI

¿Qué otras personalizaciones añadirías a este componente? ¡Compártelo en los comentarios!

Comentarios

Entradas más populares de este blog

4.2-12. Componentes esenciales

7.5-10. ¿Como funcionan los estilos en React Native?

7.1-19. Creación de estilos