mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
@@ -0,0 +1,25 @@
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import { cssVarV2 } from '@toeverything/theme/v2';
|
||||
import { fallbackVar, style } from '@vanilla-extract/css';
|
||||
|
||||
import { levelIndent } from '../tree/node.css';
|
||||
|
||||
export const emptyChildren = style({
|
||||
fontSize: cssVar('fontSm'),
|
||||
color: cssVarV2('text/disable'),
|
||||
textAlign: 'left',
|
||||
userSelect: 'none',
|
||||
lineHeight: '22px',
|
||||
padding: '4px 0px',
|
||||
marginTop: 2,
|
||||
// 48 = node.paddingLeft + node.collapsable.width + node.icon.width + node.icon.marginRight
|
||||
// = 4 + 16 + 20 + 8
|
||||
// to align with node's content
|
||||
paddingLeft: `calc(${fallbackVar(levelIndent, '20px')} + 48px)`,
|
||||
selectors: {
|
||||
'&[data-dragged-over="true"]': {
|
||||
background: cssVarV2('layer/background/hoverOverlay'),
|
||||
borderRadius: '4px',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import clsx from 'clsx';
|
||||
import { forwardRef, type HTMLAttributes, type Ref } from 'react';
|
||||
|
||||
import { emptyChildren } from './empty-node-children.css';
|
||||
|
||||
export const EmptyNodeChildren = forwardRef(function EmptyNodeChildren(
|
||||
{ children, className, ...attrs }: HTMLAttributes<HTMLDivElement>,
|
||||
ref: Ref<HTMLDivElement>
|
||||
) {
|
||||
return (
|
||||
<div className={clsx(emptyChildren, className)} ref={ref} {...attrs}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -7,9 +7,9 @@ import {
|
||||
type SVGProps,
|
||||
} from 'react';
|
||||
|
||||
import * as styles from './empty-layout.css';
|
||||
import * as styles from './empty-section.css';
|
||||
|
||||
interface ExplorerGroupEmptyProps extends HTMLAttributes<HTMLDivElement> {
|
||||
interface ExplorerEmptySectionProps extends HTMLAttributes<HTMLDivElement> {
|
||||
icon: (props: SVGProps<SVGSVGElement>) => JSX.Element;
|
||||
message: string;
|
||||
messageTestId?: string;
|
||||
@@ -17,7 +17,7 @@ interface ExplorerGroupEmptyProps extends HTMLAttributes<HTMLDivElement> {
|
||||
onActionClick?: () => void;
|
||||
}
|
||||
|
||||
export const ExplorerGroupEmpty = forwardRef(function ExplorerGroupEmpty(
|
||||
export const ExplorerEmptySection = forwardRef(function ExplorerEmptySection(
|
||||
{
|
||||
icon: Icon,
|
||||
message,
|
||||
@@ -27,7 +27,7 @@ export const ExplorerGroupEmpty = forwardRef(function ExplorerGroupEmpty(
|
||||
className,
|
||||
onActionClick,
|
||||
...attrs
|
||||
}: ExplorerGroupEmptyProps,
|
||||
}: ExplorerEmptySectionProps,
|
||||
ref: Ref<HTMLDivElement>
|
||||
) {
|
||||
return (
|
||||
@@ -1,19 +0,0 @@
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import { fallbackVar, style } from '@vanilla-extract/css';
|
||||
|
||||
import { levelIndent } from '../../tree/node.css';
|
||||
|
||||
export const noReferences = style({
|
||||
fontSize: cssVar('fontSm'),
|
||||
textAlign: 'left',
|
||||
padding: '4px 0 4px 32px',
|
||||
color: cssVar('black30'),
|
||||
userSelect: 'none',
|
||||
paddingLeft: `calc(${fallbackVar(levelIndent, '20px')} + 32px)`,
|
||||
selectors: {
|
||||
'&[data-dragged-over="true"]': {
|
||||
background: cssVar('--affine-hover-color'),
|
||||
borderRadius: '4px',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -2,7 +2,7 @@ import { type DropTargetDropEvent, useDropTarget } from '@affine/component';
|
||||
import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
|
||||
import * as styles from './empty.css';
|
||||
import { EmptyNodeChildren } from '../../layouts/empty-node-children';
|
||||
|
||||
export const Empty = ({
|
||||
onDrop,
|
||||
@@ -17,8 +17,8 @@ export const Empty = ({
|
||||
);
|
||||
const t = useI18n();
|
||||
return (
|
||||
<div className={styles.noReferences} ref={dropTargetRef}>
|
||||
<EmptyNodeChildren ref={dropTargetRef}>
|
||||
{t['com.affine.collection.emptyCollection']()}
|
||||
</div>
|
||||
</EmptyNodeChildren>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import { fallbackVar, style } from '@vanilla-extract/css';
|
||||
|
||||
import { levelIndent } from '../../tree/node.css';
|
||||
|
||||
export const noReferences = style({
|
||||
fontSize: cssVar('fontSm'),
|
||||
textAlign: 'left',
|
||||
padding: '4px 0 4px 32px',
|
||||
color: cssVar('black30'),
|
||||
userSelect: 'none',
|
||||
paddingLeft: `calc(${fallbackVar(levelIndent, '20px')} + 32px)`,
|
||||
selectors: {
|
||||
'&[data-dragged-over="true"]': {
|
||||
background: cssVar('--affine-hover-color'),
|
||||
borderRadius: '4px',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -2,7 +2,7 @@ import { type DropTargetDropEvent, useDropTarget } from '@affine/component';
|
||||
import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
|
||||
import * as styles from './empty.css';
|
||||
import { EmptyNodeChildren } from '../../layouts/empty-node-children';
|
||||
|
||||
export const Empty = ({
|
||||
onDrop,
|
||||
@@ -16,9 +16,10 @@ export const Empty = ({
|
||||
[onDrop]
|
||||
);
|
||||
const t = useI18n();
|
||||
|
||||
return (
|
||||
<div className={styles.noReferences} ref={dropTargetRef}>
|
||||
<EmptyNodeChildren ref={dropTargetRef}>
|
||||
{t['com.affine.rootAppSidebar.docs.no-subdoc']()}
|
||||
</div>
|
||||
</EmptyNodeChildren>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,22 +5,16 @@ import {
|
||||
} from '@affine/component';
|
||||
import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { FolderIcon } from '@blocksuite/icons/rc';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { ExplorerGroupEmpty } from '../../layouts/empty-layout';
|
||||
import * as styles from './empty.css';
|
||||
import { EmptyNodeChildren } from '../../layouts/empty-node-children';
|
||||
import { draggedOverHighlight } from './empty.css';
|
||||
|
||||
export const FolderEmpty = ({
|
||||
onClickCreate,
|
||||
className,
|
||||
canDrop,
|
||||
onDrop,
|
||||
}: {
|
||||
onClickCreate?: () => void;
|
||||
onDrop?: (data: DropTargetDropEvent<AffineDNDData>) => void;
|
||||
canDrop?: DropTargetOptions<AffineDNDData>['canDrop'];
|
||||
className?: string;
|
||||
}) => {
|
||||
const { dropTargetRef } = useDropTarget(
|
||||
() => ({
|
||||
@@ -32,16 +26,8 @@ export const FolderEmpty = ({
|
||||
|
||||
const t = useI18n();
|
||||
return (
|
||||
<ExplorerGroupEmpty
|
||||
className={clsx(styles.draggedOverHighlight, className)}
|
||||
ref={dropTargetRef}
|
||||
icon={FolderIcon}
|
||||
message={t['com.affine.rootAppSidebar.organize.empty-folder']()}
|
||||
messageTestId="slider-bar-organize-empty-message"
|
||||
actionText={t[
|
||||
'com.affine.rootAppSidebar.organize.empty-folder.add-pages'
|
||||
]()}
|
||||
onActionClick={onClickCreate}
|
||||
/>
|
||||
<EmptyNodeChildren ref={dropTargetRef} className={draggedOverHighlight}>
|
||||
{t['com.affine.rootAppSidebar.organize.empty-folder']()}
|
||||
</EmptyNodeChildren>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -814,11 +814,7 @@ export const ExplorerFolderNodeFolder = ({
|
||||
operations={finalOperations}
|
||||
canDrop={handleCanDrop}
|
||||
childrenPlaceholder={
|
||||
<FolderEmpty
|
||||
canDrop={handleCanDrop}
|
||||
onDrop={handleDropOnPlaceholder}
|
||||
onClickCreate={() => handleAddToFolder('doc')}
|
||||
/>
|
||||
<FolderEmpty canDrop={handleCanDrop} onDrop={handleDropOnPlaceholder} />
|
||||
}
|
||||
dropEffect={handleDropEffect}
|
||||
data-testid={`explorer-folder-${node.id}`}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import { fallbackVar, style } from '@vanilla-extract/css';
|
||||
|
||||
import { levelIndent } from '../../tree/node.css';
|
||||
|
||||
export const noReferences = style({
|
||||
fontSize: cssVar('fontSm'),
|
||||
textAlign: 'left',
|
||||
padding: '4px 0 4px 32px',
|
||||
color: cssVar('black30'),
|
||||
userSelect: 'none',
|
||||
paddingLeft: `calc(${fallbackVar(levelIndent, '20px')} + 32px)`,
|
||||
selectors: {
|
||||
'&[data-dragged-over="true"]': {
|
||||
background: cssVar('--affine-hover-color'),
|
||||
borderRadius: '4px',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -2,7 +2,7 @@ import { type DropTargetDropEvent, useDropTarget } from '@affine/component';
|
||||
import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
|
||||
import * as styles from './empty.css';
|
||||
import { EmptyNodeChildren } from '../../layouts/empty-node-children';
|
||||
|
||||
export const Empty = ({
|
||||
onDrop,
|
||||
@@ -17,8 +17,8 @@ export const Empty = ({
|
||||
);
|
||||
const t = useI18n();
|
||||
return (
|
||||
<div className={styles.noReferences} ref={dropTargetRef}>
|
||||
<EmptyNodeChildren ref={dropTargetRef}>
|
||||
{t['com.affine.rootAppSidebar.tags.no-doc']()}
|
||||
</div>
|
||||
</EmptyNodeChildren>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { ViewLayersIcon } from '@blocksuite/icons/rc';
|
||||
|
||||
import { ExplorerGroupEmpty } from '../../layouts/empty-layout';
|
||||
import { ExplorerEmptySection } from '../../layouts/empty-section';
|
||||
|
||||
export const RootEmpty = ({
|
||||
onClickCreate,
|
||||
@@ -11,7 +11,7 @@ export const RootEmpty = ({
|
||||
const t = useI18n();
|
||||
|
||||
return (
|
||||
<ExplorerGroupEmpty
|
||||
<ExplorerEmptySection
|
||||
icon={ViewLayersIcon}
|
||||
message={t['com.affine.collections.empty.message']()}
|
||||
messageTestId="slider-bar-collection-empty-message"
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { FavoriteIcon } from '@blocksuite/icons/rc';
|
||||
|
||||
import { ExplorerGroupEmpty } from '../../layouts/empty-layout';
|
||||
import { ExplorerEmptySection } from '../../layouts/empty-section';
|
||||
import { DropEffect, type ExplorerTreeNodeDropEffect } from '../../tree';
|
||||
|
||||
export const RootEmpty = ({
|
||||
@@ -34,7 +34,7 @@ export const RootEmpty = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<ExplorerGroupEmpty
|
||||
<ExplorerEmptySection
|
||||
ref={dropTargetRef}
|
||||
icon={FavoriteIcon}
|
||||
message={t['com.affine.rootAppSidebar.favorites.empty']()}
|
||||
@@ -52,6 +52,6 @@ export const RootEmpty = ({
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</ExplorerGroupEmpty>
|
||||
</ExplorerEmptySection>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { FolderIcon } from '@blocksuite/icons/rc';
|
||||
|
||||
import { ExplorerGroupEmpty } from '../../layouts/empty-layout';
|
||||
import { ExplorerEmptySection } from '../../layouts/empty-section';
|
||||
|
||||
export const RootEmpty = ({
|
||||
onClickCreate,
|
||||
@@ -11,7 +11,7 @@ export const RootEmpty = ({
|
||||
const t = useI18n();
|
||||
|
||||
return (
|
||||
<ExplorerGroupEmpty
|
||||
<ExplorerEmptySection
|
||||
icon={FolderIcon}
|
||||
message={t['com.affine.rootAppSidebar.organize.empty']()}
|
||||
messageTestId="slider-bar-organize-empty-message"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { TagIcon } from '@blocksuite/icons/rc';
|
||||
|
||||
import { ExplorerGroupEmpty } from '../../layouts/empty-layout';
|
||||
import { ExplorerEmptySection } from '../../layouts/empty-section';
|
||||
|
||||
export const RootEmpty = () => {
|
||||
const t = useI18n();
|
||||
|
||||
return (
|
||||
<ExplorerGroupEmpty
|
||||
<ExplorerEmptySection
|
||||
icon={TagIcon}
|
||||
message={t['com.affine.rootAppSidebar.tags.empty']()}
|
||||
messageTestId="slider-bar-tags-empty-message"
|
||||
|
||||
Reference in New Issue
Block a user