feat(core): add template mark on detail page header (#9764)
close AF-2136
This commit is contained in:
@@ -13,6 +13,8 @@ export const header = style({
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
gap: 12,
|
gap: 12,
|
||||||
|
containerName: 'detail-page-header',
|
||||||
|
containerType: 'inline-size',
|
||||||
});
|
});
|
||||||
export const spacer = style({
|
export const spacer = style({
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
@@ -56,3 +58,21 @@ export const dragPreview = style({
|
|||||||
backgroundColor: cssVarV2('layer/background/primary'),
|
backgroundColor: cssVarV2('layer/background/primary'),
|
||||||
borderRadius: '12px',
|
borderRadius: '12px',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const templateMark = style({
|
||||||
|
backgroundColor: cssVarV2.button.templateLabelBackground,
|
||||||
|
color: cssVarV2.button.primary,
|
||||||
|
borderRadius: 4,
|
||||||
|
padding: '2px 8px',
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: 500,
|
||||||
|
lineHeight: '20px',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const journalTemplateMark = style({
|
||||||
|
'@container': {
|
||||||
|
'(width <= 400px)': {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
@@ -16,9 +16,11 @@ import { BlocksuiteHeaderTitle } from '@affine/core/components/blocksuite/block-
|
|||||||
import { EditorModeSwitch } from '@affine/core/components/blocksuite/block-suite-mode-switch';
|
import { EditorModeSwitch } from '@affine/core/components/blocksuite/block-suite-mode-switch';
|
||||||
import { useRegisterCopyLinkCommands } from '@affine/core/components/hooks/affine/use-register-copy-link-commands';
|
import { useRegisterCopyLinkCommands } from '@affine/core/components/hooks/affine/use-register-copy-link-commands';
|
||||||
import { HeaderDivider } from '@affine/core/components/pure/header';
|
import { HeaderDivider } from '@affine/core/components/pure/header';
|
||||||
|
import { DocService } from '@affine/core/modules/doc';
|
||||||
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
|
import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
|
||||||
import { EditorService } from '@affine/core/modules/editor';
|
import { EditorService } from '@affine/core/modules/editor';
|
||||||
import { JournalService } from '@affine/core/modules/journal';
|
import { JournalService } from '@affine/core/modules/journal';
|
||||||
|
import { TemplateDocService } from '@affine/core/modules/template-doc';
|
||||||
import { ViewIcon, ViewTitle } from '@affine/core/modules/workbench';
|
import { ViewIcon, ViewTitle } from '@affine/core/modules/workbench';
|
||||||
import type { Workspace } from '@affine/core/modules/workspace';
|
import type { Workspace } from '@affine/core/modules/workspace';
|
||||||
import type { AffineDNDData } from '@affine/core/types/dnd';
|
import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||||
@@ -26,7 +28,16 @@ import { useI18n } from '@affine/i18n';
|
|||||||
import { track } from '@affine/track';
|
import { track } from '@affine/track';
|
||||||
import type { Store } from '@blocksuite/affine/store';
|
import type { Store } from '@blocksuite/affine/store';
|
||||||
import { useLiveData, useService } from '@toeverything/infra';
|
import { useLiveData, useService } from '@toeverything/infra';
|
||||||
import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
|
import clsx from 'clsx';
|
||||||
|
import {
|
||||||
|
forwardRef,
|
||||||
|
type HTMLAttributes,
|
||||||
|
memo,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
|
|
||||||
import * as styles from './detail-page-header.css';
|
import * as styles from './detail-page-header.css';
|
||||||
import { useDetailPageHeaderResponsive } from './use-header-responsive';
|
import { useDetailPageHeaderResponsive } from './use-header-responsive';
|
||||||
@@ -48,6 +59,24 @@ const Header = forwardRef<
|
|||||||
|
|
||||||
Header.displayName = 'forwardRef(Header)';
|
Header.displayName = 'forwardRef(Header)';
|
||||||
|
|
||||||
|
const TemplateMark = memo(function TemplateMark({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: HTMLAttributes<HTMLDivElement>) {
|
||||||
|
const t = useI18n();
|
||||||
|
const doc = useService(DocService).doc;
|
||||||
|
const templateDocService = useService(TemplateDocService);
|
||||||
|
const isTemplate = useLiveData(templateDocService.list.isTemplate$(doc.id));
|
||||||
|
|
||||||
|
if (!isTemplate) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={clsx(styles.templateMark, className)} {...props}>
|
||||||
|
{t['Template']()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
interface PageHeaderProps {
|
interface PageHeaderProps {
|
||||||
page: Store;
|
page: Store;
|
||||||
workspace: Workspace;
|
workspace: Workspace;
|
||||||
@@ -79,6 +108,7 @@ export function JournalPageHeader({ page, workspace }: PageHeaderProps) {
|
|||||||
<div className={styles.journalWeekPicker}>
|
<div className={styles.journalWeekPicker}>
|
||||||
<JournalWeekDatePicker page={page} />
|
<JournalWeekDatePicker page={page} />
|
||||||
</div>
|
</div>
|
||||||
|
<TemplateMark className={styles.journalTemplateMark} />
|
||||||
{hideToday ? null : <JournalTodayButton />}
|
{hideToday ? null : <JournalTodayButton />}
|
||||||
<HeaderDivider />
|
<HeaderDivider />
|
||||||
<PageHeaderMenuButton
|
<PageHeaderMenuButton
|
||||||
@@ -132,6 +162,7 @@ export function NormalPageHeader({ page, workspace }: PageHeaderProps) {
|
|||||||
docId={page.id}
|
docId={page.id}
|
||||||
inputHandleRef={titleInputHandleRef}
|
inputHandleRef={titleInputHandleRef}
|
||||||
/>
|
/>
|
||||||
|
<TemplateMark />
|
||||||
<div className={styles.iconButtonContainer}>
|
<div className={styles.iconButtonContainer}>
|
||||||
{hideCollect ? null : (
|
{hideCollect ? null : (
|
||||||
<>
|
<>
|
||||||
|
|||||||
Reference in New Issue
Block a user