saagie-ui
Version:
Saagie UI from Saagie Design System
80 lines (67 loc) • 2.1 kB
JavaScript
import React, { useEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { PipelineConnectors } from './PipelineConnectors';
const propTypes = {
children: PropTypes.node.isRequired,
defaultClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
className: PropTypes.string,
showConnectors: PropTypes.bool,
};
const defaultProps = {
defaultClassName: 'sui-prj-pipeline',
className: '',
showConnectors: false,
};
export const Pipeline = ({
children,
defaultClassName,
className,
showConnectors,
...attributes
}) => {
const pipelineId = useMemo(() => Math.random().toString(36).substr(2, 9), []);
const classes = useMemo(() => classnames(
defaultClassName,
className
), [defaultClassName, className]);
const [connectorsKey, setConnectorsKey] = useState(0);
// Refresh Connectors when pipeline content change
useEffect(() => {
if (!showConnectors) {
return () => {};
}
const debounceTime = 50;
const updateConnectors = () => {
setConnectorsKey((k) => k + 1);
};
let debounce = setTimeout(updateConnectors, debounceTime);
const observer = new MutationObserver(() => {
clearTimeout(debounce);
debounce = setTimeout(updateConnectors, debounceTime);
});
const pipelineNode = document.getElementById(pipelineId);
const pipelineItems = pipelineNode.querySelector('.sui-prj-pipeline__items');
observer.observe(pipelineItems, {
subtree: true,
childList: true,
characterData: true,
});
return () => {
observer.disconnect();
clearTimeout(debounce);
};
}, [pipelineId, showConnectors]);
return (
<div className={classes} {...attributes} id={pipelineId}>
<div className="sui-prj-pipeline__items">
{children}
</div>
{showConnectors && (
<PipelineConnectors key={connectorsKey} containerId={pipelineId} />
)}
</div>
);
};
Pipeline.propTypes = propTypes;
Pipeline.defaultProps = defaultProps;