react-native-leader-line
Version:
React Native port of leader-line library for drawing arrow lines and connectors
238 lines • 8.21 kB
JavaScript
/**
* @fileoverview Imperative API Wrapper for Leader Line
* @description Provides a leader-line compatible imperative API for backward compatibility
* @version 1.2.0
* @author Federico Garcia
*
* @example Basic Usage (leader-line compatibility)
* ```tsx
* import { LeaderLineImperative } from 'react-native-leader-line';
*
* // Create a new leader line (similar to original leader-line)
* const line = new LeaderLineImperative(startRef, endRef, {
* color: 'coral',
* size: 4,
* path: 'straight',
* endPlug: 'arrow1'
* });
*
* // Show the line
* line.show();
*
* // Update properties
* line.setOptions({ color: 'blue', size: 6 });
*
* // Hide and remove
* line.hide();
* line.remove();
* ```
*/
import React from 'react';
/**
* @class LeaderLineImperative
* @description Imperative API wrapper that mimics the original leader-line library
*
* This class provides backward compatibility with the original leader-line API
* while using React Native Leader Line components under the hood.
*/
export class LeaderLineImperative {
/**
* @constructor
* @param {React.RefObject<any> | Point} start - Start element ref or point
* @param {React.RefObject<any> | Point} end - End element ref or point
* @param {ImperativeLeaderLineOptions} options - Configuration options
* @param {Function} renderCallback - Callback to render the component
*/
constructor(start, end, options = {}, renderCallback) {
this.isVisible = false;
this.componentRef = null;
this.startElement = start;
this.endElement = end;
this.options = { ...options };
this.renderCallback = renderCallback;
// Auto-show by default (like original leader-line)
if (this.renderCallback) {
this.show();
}
}
/**
* @method show
* @description Show the leader line with optional effect
* @param {string} [effectName] - Show effect name
* @param {ImperativeLeaderLineOptions} [animOptions] - Animation options
* @returns {LeaderLineImperative} This instance for chaining
*/
show(effectName, animOptions) {
if (!this.renderCallback) {
console.warn('LeaderLineImperative: No render callback provided');
return this;
}
this.isVisible = true;
const component = this.createComponent({
...this.options,
...animOptions,
showEffectName: effectName || this.options.showEffectName,
visible: true
});
this.renderCallback(component);
return this;
}
/**
* @method hide
* @description Hide the leader line with optional effect
* @param {string} [effectName] - Hide effect name
* @param {ImperativeLeaderLineOptions} [animOptions] - Animation options
* @returns {LeaderLineImperative} This instance for chaining
*/
hide(effectName, animOptions) {
if (!this.renderCallback) {
return this;
}
this.isVisible = false;
const component = this.createComponent({
...this.options,
...animOptions,
hideEffectName: effectName || this.options.hideEffectName,
visible: false
});
this.renderCallback(component);
return this;
}
/**
* @method setOptions
* @description Update leader line options
* @param {ImperativeLeaderLineOptions} newOptions - New options to apply
* @returns {LeaderLineImperative} This instance for chaining
*/
setOptions(newOptions) {
this.options = { ...this.options, ...newOptions };
if (this.isVisible && this.renderCallback) {
const component = this.createComponent(this.options);
this.renderCallback(component);
}
return this;
}
/**
* @method position
* @description Update line position (recalculate attachment points)
* @returns {LeaderLineImperative} This instance for chaining
*/
position() {
if (this.isVisible && this.renderCallback) {
const component = this.createComponent(this.options);
this.renderCallback(component);
}
return this;
}
/**
* @method remove
* @description Remove the leader line completely
* @returns {void}
*/
remove() {
this.isVisible = false;
if (this.renderCallback) {
this.renderCallback(React.createElement('div', { style: { display: 'none' } }));
}
this.renderCallback = undefined;
}
/**
* @method getOptions
* @description Get current options
* @returns {ImperativeLeaderLineOptions} Current options
*/
getOptions() {
return { ...this.options };
}
/**
* @method isShown
* @description Check if line is currently visible
* @returns {boolean} True if visible
*/
isShown() {
return this.isVisible;
}
/**
* @private
* @method createComponent
* @description Create the React component with current options
* @param {ImperativeLeaderLineOptions} opts - Options to use
* @returns {React.ReactElement} LeaderLine component
*/
createComponent(opts) {
// Import dynamically to avoid circular dependencies
const LeaderLine = require('./LeaderLine').LeaderLine;
// Convert start/end to attachment format
const startAttachment = this.isPoint(this.startElement)
? { point: this.startElement }
: { element: this.startElement };
const endAttachment = this.isPoint(this.endElement)
? { point: this.endElement }
: { element: this.endElement };
// Map leader-line options to React Native Leader Line props
const props = {
start: startAttachment,
end: endAttachment,
color: opts.color,
strokeWidth: opts.size || opts.strokeWidth,
opacity: opts.visible === false ? 0 : 1,
path: opts.path,
curvature: opts.curvature,
startPlug: opts.startPlug,
endPlug: opts.endPlug,
startPlugColor: opts.startPlugColor,
endPlugColor: opts.endPlugColor,
startSocket: opts.startSocket,
endSocket: opts.endSocket,
outline: opts.outline,
dropShadow: opts.dropShadow,
dash: opts.dash,
animation: opts.showEffectName || opts.hideEffectName,
animationDuration: opts.duration,
startLabel: opts.startLabel,
endLabel: opts.endLabel,
middleLabel: opts.middleLabel,
ref: this.componentRef
};
return React.createElement(LeaderLine, props);
}
/**
* @private
* @method isPoint
* @description Check if value is a Point
* @param {any} value - Value to check
* @returns {boolean} True if value is a Point
*/
isPoint(value) {
return value && typeof value.x === 'number' && typeof value.y === 'number';
}
}
/**
* @function createLeaderLine
* @description Factory function for creating leader lines (leader-line compatibility)
* @param {React.RefObject<any> | Point} start - Start element or point
* @param {React.RefObject<any> | Point} end - End element or point
* @param {ImperativeLeaderLineOptions} options - Configuration options
* @param {Function} renderCallback - Callback to render the component
* @returns {LeaderLineImperative} New leader line instance
*
* @example
* ```tsx
* const line = createLeaderLine(startRef, endRef, {
* color: 'red',
* size: 3,
* endPlug: 'arrow1'
* }, renderComponent);
* ```
*/
export function createLeaderLine(start, end, options = {}, renderCallback) {
return new LeaderLineImperative(start, end, options, renderCallback);
}
/**
* @constant LEADER_LINE_VERSION
* @description Version compatibility with original leader-line
*/
export const LEADER_LINE_VERSION = '1.0.7-react-native';
// Export class as default for ES6 import compatibility
export default LeaderLineImperative;
//# sourceMappingURL=LeaderLineImperative.js.map