@fortawesome/free-solid-svg-icons#faCopy JavaScript Examples
The following examples show how to use
@fortawesome/free-solid-svg-icons#faCopy.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: App.js From lrc-staking-dapp with MIT License | 6 votes |
library.add( far, fas, faBookReader, faArrowLeft, faArrowRight, faQuestionCircle, faCopy, faSignOutAlt, faEdit, faAngleDown, faExternalLinkAlt, fab, faEthereum, faTwitter, faDiscord, faUnlink, faSearch, faFortAwesome, faExchangeAlt, faChartPie, faGlobe, faDonate, faDollarSign, );
Example #2
Source File: activitycarddropdown.js From ActiveLearningStudio-react-client with GNU Affero General Public License v3.0 | 5 votes |
ActivityCardDropDown = ({ iconColor }) => {
const IconColor = iconColor ? iconColor : "#084892";
const dispatch = useDispatch();
return (
<div className="curriki-utility-activity-dropdown">
<Dropdown className="activity-dropdown check ">
<Dropdown.Toggle className="activity-dropdown-btn">
<FontAwesomeIcon
icon={faEllipsisV}
style={{ fontSize: "13px", color: IconColor, marginLeft: "5px" }}
/>
{/* <span>EditActivity</span> */}
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item
onClick={() => {
dispatch({
type: "SET_ACTIVE_ACTIVITY_SCREEN",
payload: "addactivity",
});
}}
>
<FontAwesomeIcon icon={faEdit} className="mr-2" />
Edit
</Dropdown.Item>
<Dropdown.Item>
<FontAwesomeIcon icon={faCopy} className="mr-2" />
Duplicate
</Dropdown.Item>
<Dropdown.Item>
<FontAwesomeIcon icon={faTrash} className="mr-2" />
Delete
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</div>
);
}
Example #3
Source File: dropdownedit.js From ActiveLearningStudio-react-client with GNU Affero General Public License v3.0 | 5 votes |
DropDownEdit = ({ iconColor, data }) => {
const IconColor = iconColor ? iconColor : '#084892';
const dispatch = useDispatch();
return (
<div className="curriki-utility-activity-dropdown">
<Dropdown className="activity-dropdown check ">
<Dropdown.Toggle className="activity-dropdown-btn">
<FontAwesomeIcon icon={faEllipsisV} style={{ fontSize: '13px', color: IconColor, marginLeft: '5px' }} />
{/* <span>EditActivity</span> */}
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item
onClick={async () => {
toast.info('Duplicating project...', {
className: 'project-loading',
closeOnClick: false,
closeButton: false,
position: toast.POSITION.BOTTOM_RIGHT,
autoClose: 10000,
icon: '',
});
const result = await dispatch(cloneh5pvideo(data.id));
toast.dismiss();
Swal.fire({
html: result.message,
icon: 'success',
});
}}
>
<FontAwesomeIcon icon={faCopy} className="mr-2" />
Duplicate
</Dropdown.Item>
<Dropdown.Item
className
onClick={() => {
Swal.fire({
title: 'Are you sure you want to delete this activity?',
showDenyButton: true,
showCancelButton: true,
confirmButtonText: 'Yes',
denyButtonText: 'No',
}).then((result) => {
if (result.isConfirmed) {
dispatch(deleteVideo(data.id));
}
});
}}
>
<FontAwesomeIcon icon={faTrash} className="mr-2" />
Delete
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
</div>
);
}
Example #4
Source File: icon.js From uptime-kuma with MIT License | 5 votes |
library.add( faArrowAltCircleUp, faCog, faEdit, faEye, faEyeSlash, faList, faPause, faPlay, faPlus, faSearch, faTachometerAlt, faTimes, faTimesCircle, faTrash, faCheckCircle, faStream, faSave, faExclamationCircle, faBullhorn, faArrowsAltV, faUnlink, faQuestionCircle, faImages, faUpload, faCopy, faCheck, faFile, faAward, faLink, faChevronDown, faSignOutAlt, faPen, faExternalLinkSquareAlt, faSpinner, faUndo, faPlusCircle, faAngleDown, faLink, );
Example #5
Source File: fontawesome.js From xmrig-workers with GNU General Public License v3.0 | 5 votes |
export default function () {
library.add(faGithub, faWindows, faLinux, faTwitter, faReddit, faTelegram, faCheckCircle, faMicrochip, faTrashAlt,
faPaperPlane, faSpinner, faFlask, faInfoCircle, faPen, faTools, faCheck, faPlus, faCog, faExclamationTriangle,
faQuestionCircle, faSyncAlt, faInfinity, faDownload, faCopy, faPlug, faTimesCircle);
}
Example #6
Source File: PlayerStats.jsx From ashteki with GNU Affero General Public License v3.0 | 4 votes |
render() {
let t = this.props.t;
let userStyle = {};
if (this.props.user?.faveColor) {
userStyle.color = this.props.user.faveColor;
}
let userClass = 'username' + (this.props.user.role ? ` ${this.props.user.role.toLowerCase()}-role` : '');
let playerAvatar = (
<div className='state'>
<Avatar imgPath={this.props.user?.avatar} />
<b className={userClass} style={userStyle}>{this.props.user?.username || t('Noone')}</b>
</div>
);
let statsClass = classNames('panel player-stats', {
'active-player': this.props.activePlayer
});
let firstPlayerToken = this.props.firstPlayer ? (
<div className='state'>
<img src={FirstPlayerImage} title='First Player' />
</div>
) : (
''
);
return (
<div className={statsClass}>
{playerAvatar}
{this.renderLifeRemaining()}
{this.renderActions()}
{firstPlayerToken}
{this.props.activePlayer && (
<div className='state first-player-state'>
<Trans>Active Player</Trans>
</div>
)}
{this.props.showMessages && (
<div className='state chat-status'>
<div className='state'>
<a href='#' className='pr-1 pl-1' title='Show dice/card history'>
<FontAwesomeIcon
icon={faHistory}
onClick={this.props.onDiceHistoryClick}
></FontAwesomeIcon>
</a>
</div>
<div className='state'>
<a href='#' className='pr-1 pl-1' title='Mute spectators'>
<FontAwesomeIcon
icon={this.props.muteSpectators ? faEyeSlash : faEye}
onClick={this.props.onMuteClick}
></FontAwesomeIcon>
</a>
</div>
{this.props.showManualMode && (
<div className='state'>
<a
href='#'
className={this.props.manualModeEnabled ? 'text-danger' : ''}
onClick={this.props.onManualModeClick}
>
<FontAwesomeIcon icon={faWrench}></FontAwesomeIcon>
<span className='ml-1'>
<Trans>Manual Mode</Trans>
</span>
</a>
<a href='#' className='pr-1 pl-1' title='Show manual command list'>
<FontAwesomeIcon
icon={faList}
onClick={this.props.onManualCommandsClick}
/>
</a>
</div>
)}
<div className='state'>
<a
href='#'
onClick={this.onSettingsClick.bind(this)}
className='pr-1 pl-1'
>
<FontAwesomeIcon icon={faCogs}></FontAwesomeIcon>
<span className='ml-1'>
<Trans>Settings</Trans>
</span>
</a>
</div>
<div className='state'>
<a href='#' className='pr-1 pl-1' title='Copy chat to clipboard'>
<FontAwesomeIcon
icon={faCopy}
onClick={this.writeChatToClipboard.bind(this)}
></FontAwesomeIcon>
</a>
</div>
<div>
<a
href='#'
onClick={this.props.onMessagesClick}
className='pl-1'
title='Toggle chat'
>
<FontAwesomeIcon icon={faComment}></FontAwesomeIcon>
{this.props.numMessages > 0 && (
<Badge variant='danger'>{this.props.numMessages}</Badge>
)}
</a>
</div>
</div>
)}
</div>
);
}
Example #7
Source File: File.jsx From UniDrive with GNU General Public License v2.0 | 4 votes |
// export default function File(props) {
render() {
const {
data, email, moveWithin, oId, openFolder, shareFile, userId,
} = this.props;
const {
id, webViewLink, iconLink, name, mimeType, starred,
} = data;
const copyFunc = loadAuthParam(email, this.copy);
const deleteFunc = loadAuthParam(email, this.delete);
const renameFunc = loadAuthParam(email, this.rename);
const starFunc = loadAuthParam(email, this.star);
const findPermissionFunc = loadAuthParam(email, this.findPermission);
const findFilePermissionFunc = loadAuthParam(email, this.findFilePermission);
const deletePermissionFunc = loadAuthParam(email, this.deletePermission);
if (mimeType !== 'application/vnd.google-apps.folder') {
// if file
return (
<div>
<ContextMenuTrigger id={id + userId.toString() + oId.toString()}>
<a href={webViewLink} target="blank">
<div className="file-container">
<div className="file-image-container">
<img className="file-img" src={iconLink} alt="File icon" />
</div>
<div className="file-name">
{name}
</div>
</div>
</a>
</ContextMenuTrigger>
<ContextMenu className="context-menu" id={id + userId.toString() + oId.toString()}>
<MenuItem className="menu-item" onClick={() => window.open(webViewLink, 'blank')}>
<FontAwesomeIcon className="faOpen menu-icon" icon={faFolderOpen} />
Open
</MenuItem>
<hr className="divider" />
<MenuItem className="menu-item" onClick={() => shareFile(id, window.prompt('Email Address of sharee: '))}>
<FontAwesomeIcon className="faShare menu-icon" icon={faShare} />
Share
</MenuItem>
<MenuItem className="menu-item" onClick={() => moveWithin(userId, data, 'root')}>
<FontAwesomeIcon className="faArrowRight menu-icon" icon={faArrowRight} />
Move to Root
</MenuItem>
<MenuItem className="menu-item" onClick={() => renameFunc()}>
<FontAwesomeIcon className="faPencil menu-icon" icon={faPencilAlt} />
Rename
</MenuItem>
<MenuItem className="menu-item" onClick={() => copyFunc()}>
<FontAwesomeIcon className="faCopy menu-icon" icon={faCopy} />
Make a copy
</MenuItem>
<MenuItem className="menu-item" onClick={() => starFunc()}>
<FontAwesomeIcon className="faStar menu-icon" icon={faStar} />
{ (starred) ? 'Remove From Starred' : 'Add to Starred' }
</MenuItem>
<hr className="divider" />
<MenuItem className="menu-item" onClick={() => { if (window.confirm('This item will be placed in the trash. Proceed?')) { deleteFunc(findPermissionFunc, findFilePermissionFunc, deletePermissionFunc); } }}>
<FontAwesomeIcon className="menu-icon" icon={faTrash} />
Delete
</MenuItem>
</ContextMenu>
</div>
);
}
// if folder
return (
<div>
<ContextMenuTrigger id={id + userId.toString() + oId.toString()}>
<div className="folder-container" onClick={() => openFolder(userId, oId, data)}>
<div className="folder-content-container">
<img className="folder-img" src={iconLink} alt="File icon" />
<p className="folder-name">{name}</p>
</div>
</div>
</ContextMenuTrigger>
<ContextMenu className="context-menu" id={id + userId.toString() + oId.toString()}>
<MenuItem className="menu-item" onClick={() => window.open(webViewLink, 'blank')}>
<FontAwesomeIcon className="faGoogle menu-icon" icon={faGoogleDrive} />
View on Google Drive
</MenuItem>
<hr className="divider" />
<MenuItem className="menu-item" onClick={() => shareFile(id, window.prompt('Email Address of sharee: '))}>
<FontAwesomeIcon className="faShare menu-icon" icon={faShare} />
Share
</MenuItem>
<MenuItem className="menu-item" onClick={() => moveWithin(userId, data, 'root')}>
<FontAwesomeIcon className="faArrowRight menu-icon" icon={faArrowRight} />
Move to Root
</MenuItem>
<MenuItem className="menu-item" onClick={() => renameFunc(userId, id)}>
<FontAwesomeIcon className="faPencil menu-icon" icon={faPencilAlt} />
Rename
</MenuItem>
<MenuItem className="menu-item" onClick={() => starFunc()}>
<FontAwesomeIcon className="faStar menu-icon" icon={faStar} />
{ (starred) ? 'Remove From Starred' : 'Add to Starred' }
</MenuItem>
<hr className="divider" />
<MenuItem className="menu-item" onClick={() => { if (window.confirm('This item will become unrecoverable. Proceed?')) { deleteFunc(findPermissionFunc, findFilePermissionFunc, deletePermissionFunc); } }}>
<FontAwesomeIcon className="menu-icon" icon={faTrash} />
Delete
</MenuItem>
</ContextMenu>
</div>
);
}
Example #8
Source File: DemoSidebar.jsx From react-lte with MIT License | 4 votes |
export default function DemoSidebar() {
return (
<MainSidebar logo={logo} brandName='AdminLTE 3'>
<SidebarUser avatar={user2} href='#' name='Alexander Pierce' />
<NavSidebar>
<NavItem>
<NavLink tag={Link} to='/'>
<FontAwesomeIcon icon={faTachometerAlt} className='nav-icon' />
<p>Dashboard</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='/widgets'>
<FontAwesomeIcon icon={faTh} className='nav-icon' />
<p>
Widgets
<Badge color='danger' className='right'>
New
</Badge>
</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink href='#'>
<FontAwesomeIcon icon={faCopy} className='nav-icon' />
<p>
Layout Options
<FontAwesomeIcon icon={faAngleLeft} className='right' />
<Badge color='info' className='right'>
6
</Badge>
</p>
</NavLink>
<ul className='nav nav-treeview'>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Top Navigation</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<small>Top Navigation + Sidebar</small>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Boxed</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Fixed Sidebar</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<small>Fixed Sidebar + Custom Area</small>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Fixed Navbar</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Fixed Footer</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Collapsed Sidebar</p>
</NavLink>
</NavItem>
</ul>
</NavItem>
<NavItem>
<NavLink href='#'>
<FontAwesomeIcon icon={faChartPie} className='nav-icon' />
<p>
Charts
<FontAwesomeIcon icon={faAngleLeft} className='right' />
</p>
</NavLink>
<ul className='nav nav-treeview'>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>ChartJS</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Flot</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Inline</p>
</NavLink>
</NavItem>
</ul>
</NavItem>
<NavItem>
<NavLink href='#'>
<FontAwesomeIcon icon={faTree} className='nav-icon' />
<p>
UI Elements
<FontAwesomeIcon icon={faAngleLeft} className='right' />
</p>
</NavLink>
<ul className='nav nav-treeview'>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>General</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Icons</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Buttons</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Sliders</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Modals & Alerts</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Navbar & Tabs</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Timeline</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Ribbons</p>
</NavLink>
</NavItem>
</ul>
</NavItem>
<NavItem>
<NavLink href='#'>
<FontAwesomeIcon icon={faEdit} className='nav-icon' />
<p>
Forms
<FontAwesomeIcon icon={faAngleLeft} className='right' />
</p>
</NavLink>
<ul className='nav nav-treeview'>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>General Elements</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Advanced Elements</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Editors</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Validation</p>
</NavLink>
</NavItem>
</ul>
</NavItem>
<NavItem>
<NavLink href='#'>
<FontAwesomeIcon icon={faTable} className='nav-icon' />
<p>
Tables
<FontAwesomeIcon icon={faAngleLeft} className='right' />
</p>
</NavLink>
<ul className='nav nav-treeview'>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>Simple Tables</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>DataTables</p>
</NavLink>
</NavItem>
<NavItem>
<NavLink tag={Link} to='#'>
<FontAwesomeIcon icon={farCircle} className='nav-icon' />
<p>jsGrid</p>
</NavLink>
</NavItem>
</ul>
</NavItem>
</NavSidebar>
</MainSidebar>
);
}
Example #9
Source File: Builder.js From saltcorn with MIT License | 4 votes |
SettingsPanel = () => {
const { actions, selected, query } = useEditor((state, query) => {
const currentNodeId = state.events.selected;
let selected;
if (currentNodeId) {
selected = {
id: currentNodeId,
name: state.nodes[currentNodeId].data.name,
parent: state.nodes[currentNodeId].data.parent,
displayName:
state.nodes[currentNodeId].data &&
state.nodes[currentNodeId].data.displayName,
settings:
state.nodes[currentNodeId].related &&
state.nodes[currentNodeId].related.settings,
isDeletable: query.node(currentNodeId).isDeletable(),
children:
state.nodes[currentNodeId].data &&
state.nodes[currentNodeId].data.nodes,
};
}
return {
selected,
};
});
/** */
const deleteThis = () => {
actions.delete(selected.id);
};
/**
* @param {number} offset
* @returns {NodeId}
*/
const otherSibling = (offset) => {
const siblings = query.node(selected.parent).childNodes();
const sibIx = siblings.findIndex((sib) => sib === selected.id);
return siblings[sibIx + offset];
};
/**
* @param {object} event
*/
const handleUserKeyPress = (event) => {
const { keyCode, target } = event;
if (target.tagName.toLowerCase() === "body" && selected) {
//8 backsp, 46 del
if ((keyCode === 8 || keyCode === 46) && selected.id === "ROOT") {
deleteChildren();
}
if (keyCode === 8) {
//backspace
const prevSib = otherSibling(-1);
const parent = selected.parent;
deleteThis();
if (prevSib) actions.selectNode(prevSib);
else actions.selectNode(parent);
}
if (keyCode === 46) {
//del
const nextSib = otherSibling(1);
deleteThis();
if (nextSib) actions.selectNode(nextSib);
}
if (keyCode === 37 && selected.parent)
//left
actions.selectNode(selected.parent);
if (keyCode === 39) {
//right
if (selected.children && selected.children.length > 0) {
actions.selectNode(selected.children[0]);
} else if (selected.displayName === "Columns") {
const node = query.node(selected.id).get();
const child = node?.data?.linkedNodes?.Col0;
if (child) actions.selectNode(child);
}
}
if (keyCode === 38 && selected.parent) {
//up
const prevSib = otherSibling(-1);
if (prevSib) actions.selectNode(prevSib);
event.preventDefault();
}
if (keyCode === 40 && selected.parent) {
//down
const nextSib = otherSibling(1);
if (nextSib) actions.selectNode(nextSib);
event.preventDefault();
}
}
};
useEffect(() => {
window.addEventListener("keydown", handleUserKeyPress);
return () => {
window.removeEventListener("keydown", handleUserKeyPress);
};
}, [handleUserKeyPress]);
const hasChildren =
selected && selected.children && selected.children.length > 0;
/**
* @returns {void}
*/
const deleteChildren = () => {
selected.children.forEach((child) => {
actions.delete(child);
});
};
/**
* @returns {void}
*/
const duplicate = () => {
const {
data: { parent },
} = query.node(selected.id).get();
const siblings = query.node(selected.parent).childNodes();
const sibIx = siblings.findIndex((sib) => sib === selected.id);
const elem = recursivelyCloneToElems(query)(selected.id);
//console.log(elem);
actions.addNodeTree(
query.parseReactElement(elem).toNodeTree(),
parent || "ROOT",
sibIx + 1
);
};
return (
<div className="settings-panel card mt-1">
<div className="card-header px-2 py-1">
{selected && selected.displayName ? (
<Fragment>
<b>{selected.displayName}</b> settings
</Fragment>
) : (
"Settings"
)}
</div>
<div className="card-body p-2">
{selected ? (
<Fragment>
{selected.isDeletable && (
<button className="btn btn-sm btn-danger" onClick={deleteThis}>
<FontAwesomeIcon icon={faTrashAlt} className="me-1" />
Delete
</button>
)}
{hasChildren && !selected.isDeletable ? (
<button
className="btn btn-sm btn-danger"
onClick={deleteChildren}
>
<FontAwesomeIcon icon={faTrashAlt} className="me-1" />
Delete contents
</button>
) : (
<button
title="Duplicate element with its children"
className="btn btn-sm btn-secondary ms-2"
onClick={duplicate}
>
<FontAwesomeIcon icon={faCopy} className="me-1" />
Clone
</button>
)}
<hr className="my-2" />
{selected.settings && React.createElement(selected.settings)}
</Fragment>
) : (
"No element selected"
)}
</div>
</div>
);
}
Example #10
Source File: RenderNode.js From saltcorn with MIT License | 4 votes |
RenderNode = ({ render }) => {
const { id } = useNode();
const { actions, query, isActive } = useEditor((state) => ({
isActive: state.nodes[id].events.selected,
}));
const {
isHover,
dom,
name,
moveable,
deletable,
connectors: { drag },
parent,
} = useNode((node) => ({
isHover: node.events.hovered,
dom: node.dom,
name: node.data.custom.displayName || node.data.displayName,
moveable: query.node(node.id).isDraggable(),
deletable: query.node(node.id).isDeletable(),
parent: node.data.parent,
props: node.data.props,
}));
const currentRef = useRef();
const getPos = useCallback((dom) => {
const { top, left, bottom, height, width, right } = dom
? dom.getBoundingClientRect()
: { top: 0, left: 0, bottom: 0, right: 0, height: 0, width: 0 };
return {
top: `${top > 0 ? top : bottom}px`,
left: `${left}px`,
topn: top,
leftn: left,
height,
width,
right,
bottom,
};
}, []);
const scroll = useCallback(() => {
const { current: currentDOM } = currentRef;
if (!currentDOM) return;
const { top, left } = getPos(dom);
currentDOM.style.top = top;
currentDOM.style.left = left;
}, [dom, getPos]);
useEffect(() => {
document
.getElementById("builder-main-canvas")
.addEventListener("scroll", scroll);
document.addEventListener("scroll", scroll);
return () => {
document
.getElementById("builder-main-canvas")
.removeEventListener("scroll", scroll);
document.removeEventListener("scroll", scroll);
};
}, [scroll]);
/**
* @returns {void}
*/
const duplicate = () => {
const {
data: { parent },
} = query.node(id).get();
const siblings = query.node(parent).childNodes();
const sibIx = siblings.findIndex((sib) => sib === id);
const elem = recursivelyCloneToElems(query)(id);
actions.addNodeTree(
query.parseReactElement(elem).toNodeTree(),
parent || "ROOT",
sibIx + 1
);
};
return (
<>
{(isActive || isHover) &&
id !== "ROOT" &&
!(name === "Column" && !isActive)
? ReactDOM.createPortal(
<div
ref={currentRef}
className={`selected-indicator ${
isActive ? "activeind" : "hoverind"
} px-1 text-white`}
style={{
left: getPos(dom).left,
top: getPos(dom).top,
zIndex: 9999,
}}
>
<div className="dispname me-3">{name}</div>{" "}
{moveable && isActive && (
<button
className="btn btn-link btn-builder-move p-0"
ref={drag}
>
<FontAwesomeIcon icon={faArrowsAlt} className="me-2" />
</button>
)}
{isActive && parent && parent !== "ROOT" ? (
<FontAwesomeIcon
icon={faArrowUp}
className="me-2"
onClick={() => {
actions.selectNode(parent);
}}
/>
) : null}
{deletable && isActive
? [
<FontAwesomeIcon
key={1}
icon={faCopy}
onClick={duplicate}
className="me-2"
/>,
<FontAwesomeIcon
key={2}
icon={faTrashAlt}
className="me-2"
onMouseDown={(e) => {
e.stopPropagation();
actions.delete(id);
setTimeout(() => actions.selectNode(parent), 0);
}}
/>,
]
: null}
</div>,
document.querySelector("#builder-main-canvas")
)
: null}
{render}
</>
);
}