Files
AFFiNE-Mirror/packages/frontend/component/src/ui/dnd/drop-indicator.tsx
T
EYHN 24e0c5797c refactor(core): doc property (#8465)
doc property upgraded to use orm.

The visibility of the property are simplified to three types: `always show`, `always hide`, `hide when empty`, and the default is `always show`.

![CleanShot 2024-10-14 at 15 34 52](https://github.com/user-attachments/assets/748b8b80-061f-4d6a-8579-52e59df717c2)

Added a sidebar view to manage properties
![CleanShot 2024-10-14 at 15 35 58](https://github.com/user-attachments/assets/bffa9b1a-a1a5-4708-b2e8-4963120f3af9)

new property ui in workspace settings
![CleanShot 2024-10-14 at 15 36 44](https://github.com/user-attachments/assets/572d8dcc-9b3d-462a-9bcc-5f5fa8e622da)

Property lists can be collapsed
![CleanShot 2024-10-14 at 15 37 59](https://github.com/user-attachments/assets/2b20be1a-8141-478a-8fe7-405aff6d04fd)
2024-10-15 10:17:12 +00:00

135 lines
3.3 KiB
TypeScript

import type { Edge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
import type { Instruction } from '@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item';
import { cssVar } from '@toeverything/theme';
import { assignInlineVars } from '@vanilla-extract/dynamic';
import clsx from 'clsx';
import { type ReactElement } from 'react';
import * as styles from './drop-indicator.css';
export type DropIndicatorProps = {
instruction?: Instruction | null;
edge?: Edge | null;
noTerminal?: boolean;
};
function getTreeElement({
instruction,
isBlocked,
noTerminal,
}: {
instruction: Exclude<Instruction, { type: 'instruction-blocked' }>;
isBlocked: boolean;
noTerminal?: boolean;
}): ReactElement | null {
const style = {
[styles.horizontalIndent]: `${instruction.currentLevel * instruction.indentPerLevel}px`,
[styles.indicatorColor]: !isBlocked
? cssVar('--affine-primary-color')
: cssVar('--affine-warning-color'),
};
if (instruction.type === 'reorder-above') {
return (
<div
className={clsx(styles.treeLine, styles.lineAboveStyles)}
style={assignInlineVars(style)}
data-no-terminal={noTerminal}
/>
);
}
if (instruction.type === 'reorder-below') {
return (
<div
className={clsx(styles.treeLine, styles.lineBelowStyles)}
style={assignInlineVars(style)}
data-no-terminal={noTerminal}
/>
);
}
if (instruction.type === 'make-child') {
return (
<div
className={clsx(styles.outlineStyles)}
style={assignInlineVars(style)}
data-no-terminal={noTerminal}
/>
);
}
if (instruction.type === 'reparent') {
style[styles.horizontalIndent] = `${
instruction.desiredLevel * instruction.indentPerLevel
}px`;
return (
<div
className={clsx(styles.treeLine, styles.lineBelowStyles)}
style={assignInlineVars(style)}
data-no-terminal={noTerminal}
/>
);
}
return null;
}
type Orientation = 'horizontal' | 'vertical';
const edgeToOrientationMap: Record<Edge, Orientation> = {
top: 'horizontal',
bottom: 'horizontal',
left: 'vertical',
right: 'vertical',
};
const orientationStyles: Record<Orientation, string> = {
horizontal: styles.horizontal,
vertical: styles.vertical,
};
const edgeStyles: Record<Edge, string> = {
top: styles.top,
bottom: styles.bottom,
left: styles.left,
right: styles.right,
};
function getEdgeElement(edge: Edge, gap: number = 0, noTerminal?: boolean) {
const lineOffset = `calc(-0.5 * (${gap}px + 2px))`;
const orientation = edgeToOrientationMap[edge];
return (
<div
data-no-terminal={noTerminal}
className={clsx([
styles.edgeLine,
orientationStyles[orientation],
edgeStyles[edge],
])}
style={assignInlineVars({ [styles.localLineOffset]: lineOffset })}
/>
);
}
export function DropIndicator({
instruction,
edge,
noTerminal,
}: DropIndicatorProps) {
if (edge) {
return getEdgeElement(edge, 0, noTerminal);
}
if (instruction) {
if (instruction.type === 'instruction-blocked') {
return getTreeElement({
instruction: instruction.desired,
isBlocked: true,
});
}
return getTreeElement({ instruction, isBlocked: false });
}
return;
}