Draggable
Descripción
El componente draggable esta creado con una arquitectura strategy junto con una Decorator. Es el encargado de crear los objetos con la propiedad de draggable usando la libreria react-dnd. Este objeto Renderizar n cantidad de draggables. Todos los objetos draggable son renderizados un flex-Direction: "row" y flexWrap, por lo que si se quiere modificar la alineacion de estos solo se tiene solo se tiene que modificar el contenedor.
Importante: Para que los draggable puedan mostrar texto, asegurarse que a la data que se le pase a dragAndDropProvider tenga el elemento value: string. Ademas, cada data tiene que tener id: string | number para que el draggable sea unico
{
...
id: string | number
value: string
...
}
Props
| Propiedad | Tipo | Descripción |
|---|---|---|
quantity | number | Opcional. Por defecto tiene un valor de 5. Si a dragAndDropProvider no se le pasa el prop de data, se renderizará la cantidad de droppables que indique este prop. |
onDrag | () => void | Opcional. Se dispara cuando un draggable es arrastrado. |
onStopDrag | () => void | Opcional. Se ejecuta cuando un objeto que está siendo arrastrado es soltado. Esta función se dispara al finalizar la acción de "drag". |
configuration | Configuration | Opcional. Tiene configuraciones por defecto. Es el prop más importante, aquí se envían todas las configuraciones a los objetos draggable para ser creados. |
onDrop | () => void | Opcional. Se dispara cuando un elemento arrastrado se deja caer en un droppable. |
disabledDraggable | boolean | Opcional. Por defecto está en false. Este prop deshabilita todos los draggables. |
Configuration
El prop Configurations permite personalizar el comportamiento de los elementos draggable globalmente.
Nota: Estas configuraciones se pueden asignar individualmente a cada elemento, no necesariamente se tiene que aplicar el mismo estilo para todos (es decir, en el componente). Mas adelante se entrara en mas detalle. Por el momento hay que conocer con exactitud que hace cada cosa individualmente.
| Propiedad | Tipo | Descripción breve |
|---|---|---|
id | number | Identificador único, generalmente asignado automáticamente. |
value | string | Contenido que el draggable debe renderizar. |
renderElement | () => React.ReactNode | Renderiza contenido personalizado. Prefiere value cuando sea posible. |
image | ImageSourcePropType[] | Imagen de fondo para el draggable. |
onCorrectImage | ImageSourcePropType | Imagen a mostrar cuando es correcto. |
onIncorrectImage | ImageSourcePropType | Imagen a mostrar cuando es incorrecto. |
opacity | number | Controla la opacidad del draggable. |
singleDrop | boolean | Define si el draggable puede soltarse una vez en el droppable. |
hideOnDrop | boolean | Oculta el draggable después de ser soltado en el droppable. |
showCorrectIncorrectIndicator | boolean | Habilita el indicador de correcto/incorrecto. |
multipleDraggables | boolean | Permite usar el draggable múltiples veces, aún con indicador activo. |
alreadyDropValues | string[] | Define los valores ya colocados en el droppable. |
correctValue | string | Valor considerado correcto, muestra indicador de estado. |
showIndicatorValue | string[] | Orden correcto para los elementos. |
animation | object | Configura animaciones del draggable. Utiliza framer-motion |
outerStyle, innerStyle, textStyles | StyleProp | Estilos personalizados para el contenedor externo, interno y el texto. |
droppedStyle | StyleProp<ViewStyle> | Estilos aplicados al soltarse el draggable. |
Detalle de cada configuracion
A continuación se explica en mayor detalle cada propiedad de Configuration y cómo se comporta:
id
- Tipo:
number - Descripción: Identificador único que se asigna automáticamente en
droppable. Se recomienda nunca asignarlo manualmente.
value
- Tipo:
string - Descripción: Siempre que se quiera que un elemento draggable renderize algo en el Se le tiene que mandar por medio de este valor para que el draggable lo reconozca y lo despliegue
- Ejemplo de uso:
<Draggable
configuration={{
value: "Chanin",
textStyles: { fontSize: 20 },
}}
/>

renderElement
- Tipo:
() => React.ReactNode - Descripción: Alternativa a
valuepara renderizar un contenido personalizado. Esta configuracion es solo si no se puede usarvalue, usar solo cuando sea necesario para casos específicos. Como renderizar fracciones o elemento dentro de otro elemento - TODO: Aun no se ha implementado para el boton solo cuando el draggable es imagen
- Ejemplo de uso:
<Draggable
configuration={{
image: require("@assets/images/intergalactic-route/mission2/asteroids/asteroide1.png"),
renderElement: () => <AtomicFraction numerator={5} denominator={10} />,
}}
/>

image
- Tipo:
ImageSourcePropType | ImageSourcePropType[] - Descripción: Asigna una imagen de fondo para el
draggable. Se le puede pasar una sola imagen o un array de imagenes. Este asigna por si solo un modulo por si se le pasan solo 2 imagenes y son varios elementos este va ir alternando. Puede personalizarse conouterStyle. - Ejemplo de uso:
- Una sola imagen:
<Draggable
configuration={{
image: require("@assets/images/intergalactic-route/mission2/asteroids/asteroide1.png"),
}}
/>

- Array imagenes:
<Draggable
configuration={{
image: [
require("@assets/images/intergalactic-route/mission2/asteroids/asteroide1.png"),
require("@assets/images/common/agujero_negro.png"),
],
}}
/>

onCorrectImage
- Tipo:
ImageSourcePropType - Descripción: Imagen a mostrar cuando esta tirado en un droppable y la respuesta es correcta. Esto solo es para cuando se renderiza una imagen. Un caso de esto son los meteoritos.
- Dependiente: Este elemento se coloca automaticamente con el isCorrect que se le pasa al dragAndDropProvider.
- Ejemplo de uso:
<Draggable
configuration={{
image: require("@assets/images/intergalactic-route/mission2/asteroids/asteroide1.png"),
onCorrectImage: require("@assets/images/intergalactic-route/mission2/asteroids/asteroideCorrecta.png"),
}}
/>

onIncorrectImage
- Tipo:
ImageSourcePropType - Descripción: Imagen a mostrar cuando esta tirado en un droppable y la respuesta es incorrecta. Esto solo es para cuando se renderiza una imagen. Un caso de esto son los meteoritos.
- Dependiente: Este elemento se coloca automaticamente con el isCorrect que se le pasa al dragAndDropProvider.
- Ejemplo de uso:
<Draggable
configuration={{
image: require("@assets/images/intergalactic-route/mission2/asteroids/asteroide1.png"),
onIncorrectImage: require("@assets/images/intergalactic-route/mission2/asteroids/asteroideIncorrecta.png"),
}}
/>

opacity
- Tipo:
number - Descripción: Controla la opacidad del
draggable. - Ejemplo de uso:
<Draggable
configuration={{
opacity: 0.5,
}}
/>

singleDrop
- Tipo:
boolean - Descripción: Si SingleDrop es true el
draggablese esconde pero regresa a su posicion original si le cae encima otro draggable. Asi se puede lograr un que se arrastre multiples veces por si se confundio el usuario. - Dependiente: Para que este elemento funcione correctamente la cada data individualemente tiene que llevar id.
- Ejemplo de uso:
<Draggable configuration={{ singleDrop: true }} />
hideOnDrop
- Tipo:
boolean - Descripción: Si hideOnDrop es true el
draggableel draggable se esconde y ya no regresa a su posicion original. Al contrario que singleDrop este tiene como objetivo que a un droppable le puedan caer muchos draggables. No solo uno. - Ejemplo de uso:
<Draggable
configuration={{
hideOnDrop: true,
}}
/>
showCorrectIncorrectIndicator
- Tipo:
boolean - Descripción: Este elemento es para habilitar el indicador de correcto/incorrecto. El que tiene forma de cheque o cruz. y una vez se coloca el cheque o cruz ya no se puede arrastrar el objeto. Internamente el objeto que fue droppeado guarda que paso cuando el fue droppeado, es decir, si es correcto o incorrecto. asi que el solo se colocara. Si se quiere saber cual fue la respuesta correcta se tiene que usar
correctValue(ir a la seccion de este para saber como usarlo). - Combinaciones: Este elemento se puede combinar con
multipleDraggablesyalreadyDropValuesocorrectValue. ir a la seccion respectiva de cada uno para saber como utilizarlo - TODO: Por el momento solo esta aplicado para cuando el draggable es una imagen. Porque el momento de hacerse este dnd nunca fue necesario el cheque en los botones normales.
- Ejemplo de uso:
<Draggable
configuration={{
showCorrectIncorrectIndicator: true,
outerStyle: {
width: 90,
height: 90,
},
}}
/>
multipleDraggables
- Tipo:
boolean - Descripción: Este elemento es para habilitar que un draggable se pueda usar multiples veces aun teniendo el cheque activo. Solo hay una caso de uso para esto y es en la balanza de Bioaventura-Choza de la materia y energia-m2-OBS
- Dependiente: Este elemento va de la mano con
showCorrectIncorrectIndicatoryalreadyDropValues. Para colocarle cheques a los que ya fueron tirados. - Ejemplo de uso:
const [viewItems, setViewItems] = useState<string[]>([]);
<Draggable
configuration={{
outerStyle: { width: 100, height: 100 },
showCorrectIncorrectIndicator: true,
multipleDraggables: true,
alreadyDropValues: viewItems,
}}
/>
alreadyDropValues
- Tipo:
string[] - Descripción: Este elemento es para saber a que elemento colocarle el cheque de correcto. Va de la mano con
multipleDraggablesyshowCorrectIncorrectIndicator. Este funciona con el id de los elementos, con este detecta que elemento fue el que ya fue arrastrado y lo marca con el cheque. El unico caso de uso que tiene por el momento es en la balanza de Bioaventura-Choza de la materia y energia-m2- OBS o EXP - Ejemplo de uso:
const [viewItems, setViewItems] = useState<string[]>([]);
<Draggable
configuration={{
outerStyle: { width: 100, height: 100 },
showCorrectIncorrectIndicator: true,
multipleDraggables: true,
alreadyDropValues: viewItems,
}}
/>
correctValue
- Tipo:
string - Descripción: Este elemento es para indicar que valor es el correcto. Va de la mano con
showCorrectIncorrectIndicator. Este elemento usa elvaluede las answers para saber cual es el correcto y a este ponerle el cheque. - Ejemplo de uso:
<DragnDropProvider data={data} isCorrect={false}>
{({ dropState }) => (
<View style={styles.testStyle}>
<Dropppable quantity={1} />
<Draggable
configuration={{
image: require("@assets/images/intergalactic-route/mission2/asteroids/asteroide1.png"),
hideOnDrop: true,
showCorrectIncorrectIndicator: true,
correctValue: "hola",
}}
/>
</View>
)}
</DragnDropProvider>

showIndicatorValue
- Tipo:
string[] - Descripción: Este elemento es para indicar el orden de colocacion correcto de los objetos. Se le tiene que pasar un array de string en el orden en el que se despligan los droppable para asi asignale a ese respectivamente en que posicion "iba".
- TODO: Por el momento solo esta aplicado para cuando el draggable es una boton.
- Ejemplo de uso:
const data = [
{ id: 0, value: "a", position: 1 },
{ id: 1, value: "b", position: 2 },
{ id: 2, value: "c", position: 3 },
];
const dataShuffle = shuffleArray(data);
const correctAnswerPosition = dataShuffle.map((item) =>
item.position.toString()
);
<Draggable
configuration={{
hideOnDrop: true,
showCorrectIncorrectIndicator: true,
showIndicatorValue: correctAnswerPosition,
}}
/>;

animation
- Tipo:
animation: { initial?: Variant; animate?: Variant; transition?: Transition; exit?: Variant; } - Descripción: Esta animacion se aplica con
framer-motion. Este elemento es para agregar animaciones a los objetos draggable. Esta animacion es solo para el objeto y no para el droppable. Si se quiere que se anime cuando se tira es el droppable que tiene que ir esta animacion. - Ejemplo de uso:
<Draggable
configuration={{
animation: {
initial: { scale: 1, x: 0, y: 0 },
animate: {
scale: [1, 1.2, 1],
x: [0, 30, 0, -30, 0],
y: [0, 30, 60, 30, 0],
},
transition: {
duration: 2,
repeat: Infinity,
ease: "linear",
},
exit: { scale: 0.8 },
},
}}
/>
outerStyle
- Tipo:
StyleProp<ViewStyle> - Descripción: Este elemento es para agregar estilos al contenedor del draggable por la parte de afuera.
innerStyle
- Tipo:
StyleProp<ViewStyle> - Descripción: Este elemento es para agregar estilos al contenedor del draggable por la parte de adentro.
textStyles
- Tipo:
StyleProp<TextStyle> - Descripción: Este elemento es para agregar estilos al texto que se despliega en el draggable.
indicatorStyle
- Tipo:
StyleProp<ViewStyle> - Descripción: Este elemento es para agregar estilos al contenedor del indicador de correcto/incorrecto.
droppedStyle
- Tipo:
StyleProp<ViewStyle> - Descripción: Este elemento es para agregar estilos al contenedor del draggable cuando este fue tirado en un droppable.
Configuraciones individuales
Para aplicar configuraciones individuales a cada draggable, se deben agregar elementos de configuración directamente en los datos. Los draggable se generan según la cantidad de elementos en el array de datos, por lo que cualquier configuración añadida a un elemento del array se aplicará a ese draggable específico.
Es importante que la data siempre tenga id para que sea unico, por eso en las condiguraciones globales no tiene que estar
Todo elemento de configuracion se puede asignar a una elemento dentro de la data, ya sea una imagen, un texto o un estilo distinto. Este va a responder a esto.
data = [
{
id: 0,
value: "a",
outerStyle: {
height: 100,
width: 100
}
},
{
id: 1,
image: require("./assets/chanin.png")
}
]
<DragnDropProvider data={data} isCorrect={isCorrect}>
{({ dropState }) => {
useEffect(() => {}, [dropState.DroppedItems]);
return (
<View style={{ display: "flex", gap: 15, flexDirection: "column" }}>
<Dropppable />
<Draggable />
</View>
);
}}
</DragnDropProvider>
Aqui se le aplican configuraciones sin necesariamente aplicarlas al componente.
Renderiza esto:

Configuraciones Especiales
Existen dos Configuraciones que no estan en la interfaz pero son permitidas.
Primera Configuración
filled: boolean: Esta configuracion funciona para que un draggable ya aparezca puesto en los droppable.
data = [
{
id: 0,
value: "-",
filled: false
},
{
id: 1
value: "x",
filled: true
},
{
id: 2,
value: "x",
filled: false,
},
{
id: 3,
value: "+",
filled: false,
}
]
Renderizara:

Un ejemplo de esto es Ruta Intergalactica-Planeta Aritmetica-m2-AP04
Segunda Configuración
disabled: boolean: Este elemento deshabilita el respectivo draggable al que se le activa. A diferencia del prop disabledDraggable que deshabilita todos este solo deshabilita uno especifico.
data = [
{
id: 0,
image: require(./img1),
disabled: false
},
{
id: 1
image: require(./img2),
disabled: false
},
{
id: 2,
image: require(./Distractor),
disabled: true,
},
{
id: 3,
image: require(./img2),
disabled: false,
}
]
Un ejemplo de esto se encuentra en Bioavntura-Choza de la materia y energia-m1-CP02
Aqui existen Distractores los cuales no se pueden arrastrar que son las hojas
