/** @jsx jsx */ import { CSSProperties, ReactElement } from 'react'; import { css, jsx } from '@emotion/react'; import type { Instruction } from '@atlaskit/drag-and-drop-hitbox/experimental/tree-item'; import { token } from '@atlaskit/tokens'; import { line } from '../constants'; const lineStyles = css({ '--terminal-size': '8px', // To make things a bit clearer we are making the box that the indicator in as // big as the whole tree item position: 'absolute', top: 0, right: 0, left: 'var(--horizontal-indent)', bottom: 0, // We don't want to cause any additional 'dragenter' events pointerEvents: 'none', // Terminal '::before': { display: 'block', content: '""', position: 'absolute', zIndex: 2, boxSizing: 'border-box', width: 'var(--terminal-size)', height: 'var(--terminal-size)', left: 0, background: 'transparent', borderColor: 'var(--indicator-color)', borderWidth: line.thickness, borderRadius: '50%', borderStyle: 'solid', }, // Line '::after': { display: 'block', content: '""', position: 'absolute', zIndex: 1, background: 'var(--indicator-color)', left: 'calc(var(--terminal-size) / 2)', // putting the line to the right of the terminal height: line.thickness, right: 0, }, }); const lineAboveStyles = css({ // terminal '::before': { top: 0, // move to position to be a 'cap' on the line transform: `translate(calc(-0.5 * var(--terminal-size)), calc(-0.5 * var(--terminal-size)))`, }, // line '::after': { top: `${-0.5 * line.thickness}px`, }, }); const lineBelowStyles = css({ '::before': { bottom: 0, // move to position to be a 'cap' on the line transform: `translate(calc(-0.5 * var(--terminal-size)), calc(0.5 * var(--terminal-size)))`, }, // line '::after': { bottom: `${-0.5 * line.thickness}px`, }, }); const outlineStyles = css({ // To make things a bit clearer we are making the box that the indicator in as // big as the whole tree item position: 'absolute', top: 0, right: 0, left: 'var(--horizontal-indent)', bottom: 0, // We don't want to cause any additional 'dragenter' events pointerEvents: 'none', border: `${line.thickness}px solid var(--indicator-color)`, // TODO: make this a prop? // For now: matching the Confluence tree item border radius borderRadius: '3px', }); export type DropIndicatorProps = { instruction: Instruction; }; function getElement({ instruction, isBlocked, }: { instruction: Exclude; isBlocked: boolean; }): ReactElement | null { const style = { '--horizontal-indent': `${ instruction.currentLevel * instruction.indentPerLevel }px`, '--indicator-color': !isBlocked ? line.backgroundColor : token('color.border.warning', '#E34935'), } as CSSProperties; if (instruction.type === 'reorder-above') { return
; } if (instruction.type === 'reorder-below') { return
; } if (instruction.type === 'make-child') { return
; } if (instruction.type === 'reparent') { (style as any)['--horizontal-indent'] = `${ instruction.desiredLevel * instruction.indentPerLevel }px`; return
; } return null; } export function DropIndicator({ instruction }: DropIndicatorProps) { if (instruction.type === 'instruction-blocked') { return getElement({ instruction: instruction.desired, isBlocked: true }); } return getElement({ instruction, isBlocked: false }); }