chore: bump toolchain & fix lint

This commit is contained in:
DarkSky
2026-05-24 06:47:17 +08:00
parent adfa51a372
commit 2aa56cbccd
39 changed files with 151 additions and 130 deletions
@@ -117,7 +117,7 @@ export class EmbedGithubBlockComponent extends EmbedBlockComponent<
override renderBlock() { override renderBlock() {
const { const {
title = 'GitHub', title,
githubType, githubType,
status, status,
statusReason, statusReason,
@@ -139,7 +139,7 @@ export class EmbedGithubBlockComponent extends EmbedBlockComponent<
? getGithubStatusIcon(githubType, status, statusReason) ? getGithubStatusIcon(githubType, status, statusReason)
: nothing; : nothing;
const statusText = loading ? '' : status; const statusText = loading ? '' : status;
const titleText = loading ? 'Loading...' : title; const titleText = loading ? 'Loading...' : title || 'GitHub';
const descriptionText = loading ? '' : description; const descriptionText = loading ? '' : description;
const bannerImage = const bannerImage =
!loading && image !loading && image
@@ -89,14 +89,14 @@ export class EmbedLoomBlockComponent extends EmbedBlockComponent<
} }
override renderBlock() { override renderBlock() {
const { image, title = 'Loom', description, videoId } = this.model.props; const { image, title, description, videoId } = this.model.props;
const loading = this.loading; const loading = this.loading;
const theme = this.std.get(ThemeProvider).theme; const theme = this.std.get(ThemeProvider).theme;
const imageProxyService = this.store.get(ImageProxyService); const imageProxyService = this.store.get(ImageProxyService);
const { EmbedCardBannerIcon } = getEmbedCardIcons(theme); const { EmbedCardBannerIcon } = getEmbedCardIcons(theme);
const titleIcon = loading ? LoadingIcon() : LoomIcon; const titleIcon = loading ? LoadingIcon() : LoomIcon;
const titleText = loading ? 'Loading...' : title; const titleText = loading ? 'Loading...' : title || 'Loom';
const descriptionText = loading ? '' : description; const descriptionText = loading ? '' : description;
const bannerImage = const bannerImage =
!loading && image !loading && image
@@ -96,21 +96,15 @@ export class EmbedYoutubeBlockComponent extends EmbedBlockComponent<
} }
override renderBlock() { override renderBlock() {
const { const { image, title, description, creator, creatorImage, videoId } =
image, this.model.props;
title = 'YouTube',
description,
creator,
creatorImage,
videoId,
} = this.model.props;
const loading = this.loading; const loading = this.loading;
const theme = this.std.get(ThemeProvider).theme; const theme = this.std.get(ThemeProvider).theme;
const imageProxyService = this.store.get(ImageProxyService); const imageProxyService = this.store.get(ImageProxyService);
const { EmbedCardBannerIcon } = getEmbedCardIcons(theme); const { EmbedCardBannerIcon } = getEmbedCardIcons(theme);
const titleIcon = loading ? LoadingIcon() : YoutubeIcon; const titleIcon = loading ? LoadingIcon() : YoutubeIcon;
const titleText = loading ? 'Loading...' : title; const titleText = loading ? 'Loading...' : title || 'YouTube';
const descriptionText = loading ? null : description; const descriptionText = loading ? null : description;
const bannerImage = const bannerImage =
!loading && image !loading && image
@@ -276,7 +276,8 @@ export class ImageEdgelessBlockComponent extends GfxBlockComponent<ImageBlockMod
override renderGfxBlock() { override renderGfxBlock() {
const blobUrl = this.blobUrl; const blobUrl = this.blobUrl;
const { rotate = 0, size = 0, caption = 'Image' } = this.model.props; const { rotate, size: rawSize, caption = 'Image' } = this.model.props;
const size = rawSize ?? 0;
this._resetLodSource(blobUrl); this._resetLodSource(blobUrl);
const containerStyleMap = styleMap({ const containerStyleMap = styleMap({
+11 -11
View File
@@ -119,15 +119,14 @@ export class MindMapView extends GfxElementModelView<MindmapElementModel> {
private _setLayoutMethod() { private _setLayoutMethod() {
this.model.setLayoutMethod(function ( this.model.setLayoutMethod(function (
this: MindmapElementModel, this: MindmapElementModel,
tree: MindmapNode | MindmapRoot = this.tree, tree: MindmapNode | MindmapRoot | undefined,
options: { options:
applyStyle?: boolean; | {
layoutType?: LayoutType; applyStyle?: boolean;
stashed?: boolean; layoutType?: LayoutType;
} = { stashed?: boolean;
applyStyle: true, }
stashed: true, | undefined
}
) { ) {
const { stashed, applyStyle, layoutType } = Object.assign( const { stashed, applyStyle, layoutType } = Object.assign(
{ {
@@ -137,9 +136,10 @@ export class MindMapView extends GfxElementModelView<MindmapElementModel> {
}, },
options options
); );
const targetTree = tree ?? this.tree;
const pop = stashed ? this.stashTree(tree) : null; const pop = stashed ? this.stashTree(targetTree) : null;
handleLayout(this, tree, applyStyle, layoutType); handleLayout(this, targetTree, applyStyle, layoutType);
pop?.(); pop?.();
}); });
} }
@@ -58,8 +58,7 @@ export const getSelectedModelsCommand: Command<
]) ])
.pipe(getSelectedBlocksCommand, { types, mode }) .pipe(getSelectedBlocksCommand, { types, mode })
.pipe(ctx => { .pipe(ctx => {
const { selectedBlocks = [] } = ctx; selectedModels.push(...ctx.selectedBlocks.map(el => el.model));
selectedModels.push(...selectedBlocks.map(el => el.model));
}) })
.run(); .run();
@@ -374,10 +374,10 @@ export class CopilotEmbeddingJob {
const docContent = await this.doc.getFullDocContent(workspaceId, docId); const docContent = await this.doc.getFullDocContent(workspaceId, docId);
const authors = await this.models.doc.getAuthors(workspaceId, docId); const authors = await this.models.doc.getAuthors(workspaceId, docId);
if (docContent && authors) { if (docContent && authors) {
const { title = 'Untitled', summary } = docContent; const { title, summary } = docContent;
const { createdAt, updatedAt, createdByUser, updatedByUser } = authors; const { createdAt, updatedAt, createdByUser, updatedByUser } = authors;
return { return {
title, title: title || 'Untitled',
summary, summary,
createdAt: createdAt.toDateString(), createdAt: createdAt.toDateString(),
updatedAt: updatedAt.toDateString(), updatedAt: updatedAt.toDateString(),
@@ -255,9 +255,7 @@ export class LiveData<T = unknown>
constructor( constructor(
initialValue: T, initialValue: T,
upstream: upstream?: (upstream: Observable<LiveDataOperation>) => Observable<T>
| ((upstream: Observable<LiveDataOperation>) => Observable<T>)
| undefined = undefined
) { ) {
super(); super();
this.raw$ = new BehaviorSubject(initialValue); this.raw$ = new BehaviorSubject(initialValue);
@@ -37,6 +37,8 @@ impl PartialEq for Item {
} }
} }
impl Eq for Item {}
impl std::fmt::Debug for Item { impl std::fmt::Debug for Item {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut dbg = f.debug_struct("Item"); let mut dbg = f.debug_struct("Item");
@@ -44,9 +44,7 @@ impl PartialEq for Node {
} }
} }
impl Eq for Node { impl Eq for Node {}
fn assert_receiver_is_total_eq(&self) {}
}
impl From<Item> for Node { impl From<Item> for Node {
fn from(value: Item) -> Self { fn from(value: Item) -> Self {
@@ -299,9 +299,7 @@ impl<T: PartialEq> PartialEq for SomrInner<T> {
} }
} }
impl<T: PartialEq> Eq for Somr<T> { impl<T: Eq> Eq for Somr<T> {}
fn assert_receiver_is_total_eq(&self) {}
}
impl<T: PartialOrd> PartialOrd for Somr<T> { impl<T: PartialOrd> PartialOrd for Somr<T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
@@ -64,7 +64,7 @@ impl StoreHistory {
// make items as reference // make items as reference
let mut store_items = store_items.iter().collect::<Vec<_>>(); let mut store_items = store_items.iter().collect::<Vec<_>>();
store_items.sort_by(|a, b| a.id.clock.cmp(&b.id.clock)); store_items.sort_by_key(|item| item.id.clock);
self.parse_items(store_items) self.parse_items(store_items)
} }
@@ -126,7 +126,7 @@ impl StoreHistory {
// make items as reference // make items as reference
let mut store_items = store_items.iter().collect::<Vec<_>>(); let mut store_items = store_items.iter().collect::<Vec<_>>();
store_items.sort_by(|a, b| a.id.clock.cmp(&b.id.clock)); store_items.sort_by_key(|item| item.id.clock);
self.parse_items(store_items) self.parse_items(store_items)
} }
@@ -266,11 +266,7 @@ fn advance_text_position(store: &mut DocStore, pos: &mut TextPosition, mut remai
} }
fn minimize_attribute_changes(pos: &mut TextPosition, attrs: &TextAttributes) { fn minimize_attribute_changes(pos: &mut TextPosition, attrs: &TextAttributes) {
loop { while let Some(item) = pos.right.get() {
let Some(item) = pos.right.get() else {
break;
};
if item.deleted() { if item.deleted() {
pos.forward(); pos.forward();
continue; continue;
@@ -345,11 +341,7 @@ fn insert_negated_attributes(
pos: &mut TextPosition, pos: &mut TextPosition,
mut negated: TextAttributes, mut negated: TextAttributes,
) -> JwstCodecResult { ) -> JwstCodecResult {
loop { while let Some(item) = pos.right.get() {
let Some(item) = pos.right.get() else {
break;
};
if item.deleted() { if item.deleted() {
pos.forward(); pos.forward();
continue; continue;
@@ -61,6 +61,11 @@ export type AvatarProps = {
removeButtonProps?: HTMLAttributes<HTMLButtonElement>; removeButtonProps?: HTMLAttributes<HTMLButtonElement>;
} & HTMLAttributes<HTMLSpanElement>; } & HTMLAttributes<HTMLSpanElement>;
const EMPTY_STYLE: CSSProperties = {};
const EMPTY_FALLBACK_PROPS: AvatarFallbackProps = {};
const EMPTY_HOVER_WRAPPER_PROPS: HTMLAttributes<HTMLDivElement> = {};
const EMPTY_REMOVE_BUTTON_PROPS: HTMLAttributes<HTMLButtonElement> = {};
function drawImageFit( function drawImageFit(
img: ImageBitmap, img: ImageBitmap,
ctx: CanvasRenderingContext2D, ctx: CanvasRenderingContext2D,
@@ -88,32 +93,32 @@ export const Avatar = forwardRef<HTMLSpanElement, AvatarProps>(
( (
{ {
size = 20, size = 20,
style: propsStyles = {}, style: propsStyles = EMPTY_STYLE,
url, url,
image, image,
name, name,
className, className,
colorfulFallback = false, colorfulFallback = false,
hoverIcon, hoverIcon,
fallbackProps: { className: fallbackClassName, ...fallbackProps } = {}, fallbackProps = EMPTY_FALLBACK_PROPS,
imageProps, imageProps,
avatarProps, avatarProps,
rounded = '50%', rounded = '50%',
onRemove, onRemove,
hoverWrapperProps: { hoverWrapperProps = EMPTY_HOVER_WRAPPER_PROPS,
className: hoverWrapperClassName,
...hoverWrapperProps
} = {},
avatarTooltipOptions, avatarTooltipOptions,
removeTooltipOptions, removeTooltipOptions,
removeButtonProps: { removeButtonProps = EMPTY_REMOVE_BUTTON_PROPS,
className: removeButtonClassName,
...removeButtonProps
} = {},
...props ...props
}, },
ref ref
) => { ) => {
const { className: fallbackClassName, ...otherFallbackProps } =
fallbackProps;
const { className: hoverWrapperClassName, ...otherHoverWrapperProps } =
hoverWrapperProps;
const { className: removeButtonClassName, ...otherRemoveButtonProps } =
removeButtonProps;
const firstCharOfName = useMemo(() => { const firstCharOfName = useMemo(() => {
return name?.slice(0, 1); return name?.slice(0, 1);
}, [name]); }, [name]);
@@ -180,7 +185,7 @@ export const Avatar = forwardRef<HTMLSpanElement, AvatarProps>(
<AvatarFallback <AvatarFallback
className={clsx(style.avatarFallback, fallbackClassName)} className={clsx(style.avatarFallback, fallbackClassName)}
delayMs={url ? 600 : undefined} delayMs={url ? 600 : undefined}
{...fallbackProps} {...otherFallbackProps}
> >
{colorfulFallback ? ( {colorfulFallback ? (
<ColorfulFallback char={firstCharOfName} /> <ColorfulFallback char={firstCharOfName} />
@@ -196,7 +201,7 @@ export const Avatar = forwardRef<HTMLSpanElement, AvatarProps>(
fallbackClassName fallbackClassName
)} )}
delayMs={url ? 600 : undefined} delayMs={url ? 600 : undefined}
{...fallbackProps} {...otherFallbackProps}
> >
<DefaultFallbackSvg /> <DefaultFallbackSvg />
</AvatarFallback> </AvatarFallback>
@@ -204,7 +209,7 @@ export const Avatar = forwardRef<HTMLSpanElement, AvatarProps>(
{hoverIcon ? ( {hoverIcon ? (
<div <div
className={clsx(style.hoverWrapper, hoverWrapperClassName)} className={clsx(style.hoverWrapper, hoverWrapperClassName)}
{...hoverWrapperProps} {...otherHoverWrapperProps}
> >
{hoverIcon} {hoverIcon}
</div> </div>
@@ -223,7 +228,7 @@ export const Avatar = forwardRef<HTMLSpanElement, AvatarProps>(
className={clsx(style.removeButton, removeButtonClassName)} className={clsx(style.removeButton, removeButtonClassName)}
onClick={onRemove} onClick={onRemove}
ref={setRemoveButtonDom} ref={setRemoveButtonDom}
{...removeButtonProps} {...otherRemoveButtonProps}
> >
<CloseIcon /> <CloseIcon />
</IconButton> </IconButton>
@@ -27,6 +27,8 @@ export type InputProps = {
onEnter?: (value: string) => void; onEnter?: (value: string) => void;
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'size' | 'onBlur'>; } & Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'size' | 'onBlur'>;
const EMPTY_STYLE: CSSProperties = {};
export const Input = forwardRef<HTMLInputElement, InputProps>(function Input( export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
{ {
disabled, disabled,
@@ -34,8 +36,8 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
noBorder = false, noBorder = false,
className, className,
status = 'default', status = 'default',
style = {}, style = EMPTY_STYLE,
inputStyle = {}, inputStyle = EMPTY_STYLE,
size = 'default', size = 'default',
preFix, preFix,
endFix, endFix,
@@ -25,6 +25,8 @@ export type RowInputProps = {
debounce?: number; debounce?: number;
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'size' | 'onBlur'>; } & Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'size' | 'onBlur'>;
const EMPTY_STYLE: CSSProperties = {};
// RowInput component that is used in the selector layout for search input // RowInput component that is used in the selector layout for search input
// handles composition events and enter key press // handles composition events and enter key press
export const RowInput = forwardRef<HTMLInputElement, RowInputProps>( export const RowInput = forwardRef<HTMLInputElement, RowInputProps>(
@@ -33,7 +35,7 @@ export const RowInput = forwardRef<HTMLInputElement, RowInputProps>(
disabled, disabled,
onChange: propsOnChange, onChange: propsOnChange,
className, className,
style = {}, style = EMPTY_STYLE,
onEnter, onEnter,
onKeyDown, onKeyDown,
onBlur, onBlur,
@@ -11,26 +11,26 @@ const MenuContextValue = {
type: 'dropdown-menu', type: 'dropdown-menu',
} as const; } as const;
const EMPTY_ROOT_OPTIONS: NonNullable<MenuProps['rootOptions']> = {};
const EMPTY_CONTENT_OPTIONS: NonNullable<MenuProps['contentOptions']> = {};
const EMPTY_CONTENT_STYLE: React.CSSProperties = {};
export const DesktopMenu = ({ export const DesktopMenu = ({
children, children,
items, items,
noPortal, noPortal,
portalOptions, portalOptions,
rootOptions: { rootOptions: rawRootOptions,
defaultOpen, contentOptions: rawContentOptions,
modal,
open,
onOpenChange,
onClose,
...rootOptions
} = {},
contentOptions: {
className = '',
style: contentStyle = {},
...otherContentOptions
} = {},
ref, ref,
}: MenuProps) => { }: MenuProps) => {
const { defaultOpen, modal, open, onOpenChange, onClose, ...rootOptions } =
rawRootOptions ?? EMPTY_ROOT_OPTIONS;
const {
className = '',
style: contentStyle = EMPTY_CONTENT_STYLE,
...otherContentOptions
} = rawContentOptions ?? EMPTY_CONTENT_OPTIONS;
const [innerOpen, setInnerOpen] = useState(defaultOpen); const [innerOpen, setInnerOpen] = useState(defaultOpen);
const finalOpen = open ?? innerOpen; const finalOpen = open ?? innerOpen;
@@ -9,18 +9,25 @@ import * as styles from '../styles.css';
import { useMenuItem } from '../use-menu-item'; import { useMenuItem } from '../use-menu-item';
import { DesktopMenuContext } from './context'; import { DesktopMenuContext } from './context';
const EMPTY_SUB_OPTIONS: NonNullable<MenuSubProps['subOptions']> = {};
const EMPTY_SUB_CONTENT_OPTIONS: NonNullable<
MenuSubProps['subContentOptions']
> = {};
export const DesktopMenuSub = ({ export const DesktopMenuSub = ({
children: propsChildren, children: propsChildren,
items, items,
portalOptions, portalOptions,
subOptions: { defaultOpen, ...otherSubOptions } = {}, subOptions,
triggerOptions, triggerOptions,
subContentOptions: { subContentOptions,
}: MenuSubProps) => {
const { defaultOpen, ...otherSubOptions } = subOptions ?? EMPTY_SUB_OPTIONS;
const {
className: subContentClassName = '', className: subContentClassName = '',
style: contentStyle, style: contentStyle,
...otherSubContentOptions ...otherSubContentOptions
} = {}, } = subContentOptions ?? EMPTY_SUB_CONTENT_OPTIONS;
}: MenuSubProps) => {
const { type } = useContext(DesktopMenuContext); const { type } = useContext(DesktopMenuContext);
const { className, children, otherProps } = useMenuItem({ const { className, children, otherProps } = useMenuItem({
children: propsChildren, children: propsChildren,
@@ -24,11 +24,18 @@ import {
import * as styles from './styles.css'; import * as styles from './styles.css';
import { MobileMenuSubRaw } from './sub'; import { MobileMenuSubRaw } from './sub';
const EMPTY_CONTENT_OPTIONS: NonNullable<MenuProps['contentOptions']> = {};
export const MobileMenu = ({ export const MobileMenu = ({
children, children,
items, items,
title, title,
contentOptions: { contentOptions,
contentWrapperStyle,
rootOptions,
ref,
}: MenuProps) => {
const {
className, className,
onPointerDownOutside, onPointerDownOutside,
onInteractOutside, onInteractOutside,
@@ -38,11 +45,7 @@ export const MobileMenu = ({
align: _align, align: _align,
...otherContentOptions ...otherContentOptions
} = {}, } = contentOptions ?? EMPTY_CONTENT_OPTIONS;
contentWrapperStyle,
rootOptions,
ref,
}: MenuProps) => {
const [subMenus, setSubMenus] = useState<SubMenuContent[]>([]); const [subMenus, setSubMenus] = useState<SubMenuContent[]>([]);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const mobileContextValue = useMemo( const mobileContextValue = useMemo(
@@ -6,13 +6,18 @@ import type { MenuSubProps } from '../menu.types';
import { useMenuItem } from '../use-menu-item'; import { useMenuItem } from '../use-menu-item';
import { useMobileSubMenuHelper } from './context'; import { useMobileSubMenuHelper } from './context';
const EMPTY_SUB_CONTENT_OPTIONS: NonNullable<
MenuSubProps['subContentOptions']
> = {};
export const MobileMenuSub = ({ export const MobileMenuSub = ({
title, title,
children: propsChildren, children: propsChildren,
items, items,
triggerOptions, triggerOptions,
subContentOptions: contentOptions = {}, subContentOptions,
}: MenuSubProps & { title?: string }) => { }: MenuSubProps & { title?: string }) => {
const contentOptions = subContentOptions ?? EMPTY_SUB_CONTENT_OPTIONS;
const { const {
className, className,
children, children,
@@ -43,11 +48,12 @@ export const MobileMenuSubRaw = ({
children, children,
items, items,
subOptions, subOptions,
subContentOptions: contentOptions = {}, subContentOptions,
}: MenuSubProps & { }: MenuSubProps & {
onClick?: (e: MouseEvent<HTMLDivElement>) => void; onClick?: (e: MouseEvent<HTMLDivElement>) => void;
title?: string; title?: string;
}) => { }) => {
const contentOptions = subContentOptions ?? EMPTY_SUB_CONTENT_OPTIONS;
const id = useId(); const id = useId();
const { addSubMenu } = useMobileSubMenuHelper(); const { addSubMenu } = useMobileSubMenuHelper();
@@ -15,17 +15,21 @@ export interface PopoverProps extends PopoverPrimitiveProps {
portalOptions?: PopoverPortalProps; portalOptions?: PopoverPortalProps;
contentOptions?: PopoverContentProps; contentOptions?: PopoverContentProps;
} }
const EMPTY_CONTENT_OPTIONS: NonNullable<PopoverProps['contentOptions']> = {};
export const Popover = ({ export const Popover = ({
content, content,
children, children,
portalOptions, portalOptions,
contentOptions: { contentOptions,
...props
}: PopoverProps) => {
const {
className: contentClassName, className: contentClassName,
style: contentStyle, style: contentStyle,
...otherContentOptions ...otherContentOptions
} = {}, } = contentOptions ?? EMPTY_CONTENT_OPTIONS;
...props
}: PopoverProps) => {
return ( return (
<PopoverPrimitive.Root {...props}> <PopoverPrimitive.Root {...props}>
<PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger> <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>
@@ -428,13 +428,8 @@ export class AIChatComposer extends SignalWatcher(
}; };
private readonly addSelectedContextChip = async () => { private readonly addSelectedContextChip = async () => {
const { const { attachments, snapshot, combinedElementsMarkdown, docs, html } =
attachments = [], this.chatContextValue;
snapshot,
combinedElementsMarkdown,
docs = [],
html,
} = this.chatContextValue;
await this.removeSelectedContextChip(); await this.removeSelectedContextChip();
const chip: SelectedContextChip = { const chip: SelectedContextChip = {
uuid: uuidv4(), uuid: uuidv4(),
@@ -23,7 +23,7 @@ export interface AIPanelErrorConfig {
} }
export interface AIPanelGeneratingConfig { export interface AIPanelGeneratingConfig {
generatingIcon: TemplateResult<1>; generatingIcon?: TemplateResult<1>;
height?: number; height?: number;
stages?: string[]; stages?: string[];
} }
@@ -67,11 +67,14 @@ interface ErrorBaseProps {
buttons?: ReactElement[]; buttons?: ReactElement[];
} }
const DEFAULT_ICON = <FileIcon />;
const EMPTY_BUTTONS: ReactElement[] = [];
const ErrorBase = ({ const ErrorBase = ({
title, title,
subtitle, subtitle,
icon = <FileIcon />, icon = DEFAULT_ICON,
buttons = [], buttons = EMPTY_BUTTONS,
}: ErrorBaseProps) => { }: ErrorBaseProps) => {
return ( return (
<div className={clsx([styles.viewer, styles.error])}> <div className={clsx([styles.viewer, styles.error])}>
@@ -20,8 +20,10 @@ import { AffineShapeIcon } from '..';
import { SelectorLayout } from '../selector/selector-layout'; import { SelectorLayout } from '../selector/selector-layout';
import * as styles from './select-page.css'; import * as styles from './select-page.css';
const EMPTY_INIT: string[] = [];
export const SelectPage = memo(function SelectPage({ export const SelectPage = memo(function SelectPage({
init = [], init = EMPTY_INIT,
onConfirm, onConfirm,
onCancel, onCancel,
onChange: propsOnChange, onChange: propsOnChange,
@@ -48,6 +48,8 @@ import { DropEffect } from './drop-effect';
import * as styles from './node.css'; import * as styles from './node.css';
import type { NodeOperation } from './types'; import type { NodeOperation } from './types';
const EMPTY_OPERATIONS: NodeOperation[] = [];
export type NavigationPanelTreeNodeDropEffectData = { export type NavigationPanelTreeNodeDropEffectData = {
source: { data: AffineDNDData['draggable'] }; source: { data: AffineDNDData['draggable'] };
treeInstruction: DropTargetTreeInstruction | null; treeInstruction: DropTargetTreeInstruction | null;
@@ -190,9 +192,9 @@ export const NavigationPanelTreeNode = ({
collapsible = true, collapsible = true,
canDrop, canDrop,
reorderable = true, reorderable = true,
operations = [], operations = EMPTY_OPERATIONS,
postfix, postfix,
childrenOperations = [], childrenOperations = EMPTY_OPERATIONS,
childrenPlaceholder, childrenPlaceholder,
linkComponent: LinkComponent = WorkbenchLink, linkComponent: LinkComponent = WorkbenchLink,
dndData, dndData,
@@ -4,9 +4,11 @@ import { NavigationPanelTreeContext } from './context';
import * as styles from './root.css'; import * as styles from './root.css';
import type { NodeOperation } from './types'; import type { NodeOperation } from './types';
const EMPTY_OPERATIONS: NodeOperation[] = [];
export const NavigationPanelTreeRoot = ({ export const NavigationPanelTreeRoot = ({
children, children,
childrenOperations = [], childrenOperations = EMPTY_OPERATIONS,
placeholder, placeholder,
}: { }: {
children?: React.ReactNode; children?: React.ReactNode;
@@ -1,4 +1,4 @@
export function BulledListIcon({ color = 'currentColor' }: { color: string }) { export function BulledListIcon({ color = 'currentColor' }: { color?: string }) {
return ( return (
<svg <svg
width="16" width="16"
@@ -13,10 +13,12 @@ export interface AddItemPlaceholderProps extends HTMLAttributes<HTMLDivElement>
icon?: React.ReactNode; icon?: React.ReactNode;
} }
const DEFAULT_ICON = <PlusIcon />;
export const AddItemPlaceholder = ({ export const AddItemPlaceholder = ({
onClick, onClick,
label = 'Add Item', label = 'Add Item',
icon = <PlusIcon />, icon = DEFAULT_ICON,
className, className,
...attrs ...attrs
}: AddItemPlaceholderProps) => { }: AddItemPlaceholderProps) => {
@@ -22,6 +22,8 @@ import * as styles from './node.css';
interface NavigationPanelTreeNodeProps extends BaseNavigationPanelTreeNodeProps {} interface NavigationPanelTreeNodeProps extends BaseNavigationPanelTreeNodeProps {}
const EMPTY_OPERATIONS: BaseNavigationPanelTreeNodeProps['operations'] = [];
export const NavigationPanelTreeNode = ({ export const NavigationPanelTreeNode = ({
children, children,
icon: Icon, icon: Icon,
@@ -33,9 +35,9 @@ export const NavigationPanelTreeNode = ({
collapsed, collapsed,
extractEmojiAsIcon, extractEmojiAsIcon,
setCollapsed, setCollapsed,
operations = [], operations = EMPTY_OPERATIONS,
postfix, postfix,
childrenOperations = [], childrenOperations = EMPTY_OPERATIONS,
childrenPlaceholder, childrenPlaceholder,
linkComponent: LinkComponent = WorkbenchLink, linkComponent: LinkComponent = WorkbenchLink,
...otherProps ...otherProps
@@ -6,9 +6,11 @@ import { useMemo, useState } from 'react';
import * as styles from './root.css'; import * as styles from './root.css';
const EMPTY_OPERATIONS: NodeOperation[] = [];
export const NavigationPanelTreeRoot = ({ export const NavigationPanelTreeRoot = ({
children, children,
childrenOperations = [], childrenOperations = EMPTY_OPERATIONS,
placeholder, placeholder,
}: { }: {
children?: React.ReactNode; children?: React.ReactNode;
@@ -33,11 +33,13 @@ export interface SettingDropdownSelectProps<
native?: boolean; native?: boolean;
} }
const EMPTY_OPTIONS: DropdownItem<string>[] = [];
export const SettingDropdownSelect = < export const SettingDropdownSelect = <
V extends string = string, V extends string = string,
E extends boolean | undefined = true, E extends boolean | undefined = true,
>({ >({
options = [], options = EMPTY_OPTIONS as DropdownItem<V>[],
value, value,
emitValue = true, emitValue = true,
onChange, onChange,
@@ -98,7 +100,7 @@ export const NativeSettingDropdownSelect = <
V extends string = string, V extends string = string,
E extends boolean | undefined = true, E extends boolean | undefined = true,
>({ >({
options = [], options = EMPTY_OPTIONS as DropdownItem<V>[],
value, value,
emitValue = true, emitValue = true,
onChange, onChange,
@@ -85,7 +85,7 @@ const DatabaseBacklinkRow = ({
row$, row$,
onChange, onChange,
}: { }: {
defaultOpen: boolean; defaultOpen?: boolean;
row$: Observable<DatabaseRow | undefined>; row$: Observable<DatabaseRow | undefined>;
onChange?: ( onChange?: (
row: DatabaseRow, row: DatabaseRow,
@@ -20,10 +20,12 @@ import { HighlightText } from './highlight-text';
type Groups = { group?: QuickSearchGroup; items: QuickSearchItem[] }[]; type Groups = { group?: QuickSearchGroup; items: QuickSearchItem[] }[];
const EMPTY_GROUPS: Groups = [];
export const CMDK = ({ export const CMDK = ({
className, className,
query, query,
groups: newGroups = [], groups: newGroups = EMPTY_GROUPS,
error, error,
inputLabel, inputLabel,
placeholder, placeholder,
@@ -3,7 +3,7 @@ import { Fragment, useMemo } from 'react';
import * as styles from './highlight-text.css'; import * as styles from './highlight-text.css';
type HighlightProps = { type HighlightProps = {
text: string; text?: string;
start: string; start: string;
end: string; end: string;
}; };
@@ -192,5 +192,5 @@ export const SUPPORTED_LANGUAGES: Record<
originalName: 'Türkçe', originalName: 'Türkçe',
flagEmoji: '🇹🇷', flagEmoji: '🇹🇷',
resource: () => import('./tr.json'), resource: () => import('./tr.json'),
} },
}; };
+1 -1
View File
@@ -1584,7 +1584,7 @@
"com.affine.settings.workspace.experimental-features.enable-mind-map-import.name": "Zihin Haritası İçe Aktarımı", "com.affine.settings.workspace.experimental-features.enable-mind-map-import.name": "Zihin Haritası İçe Aktarımı",
"com.affine.settings.workspace.experimental-features.enable-mind-map-import.description": "Zihin haritasının içe aktarılmasını etkinleştirir.", "com.affine.settings.workspace.experimental-features.enable-mind-map-import.description": "Zihin haritasının içe aktarılmasını etkinleştirir.",
"com.affine.settings.workspace.experimental-features.enable-block-meta.name": "Blok Metaverisi", "com.affine.settings.workspace.experimental-features.enable-block-meta.name": "Blok Metaverisi",
"com.affine.settings.workspace.experimental-features.enable-block-meta.description": "Etkinleştirildiğinde, tüm bloklar için oluşturulma zamanı, güncellenme zamanı ile oluşturan ve güncelleyen bilgileri gösterilir.", "com.affine.settings.workspace.experimental-features.enable-block-meta.description": "Etkinleştirildiğinde, tüm bloklar için oluşturulma zamanı, güncellenme zamanı ile oluşturan ve güncelleyen bilgileri gösterilir.",
"com.affine.settings.workspace.experimental-features.enable-callout.name": "Belirtme çizgisi", "com.affine.settings.workspace.experimental-features.enable-callout.name": "Belirtme çizgisi",
"com.affine.settings.workspace.experimental-features.enable-callout.description": "Sözleriniz öne çıksın. Bu aynı zamanda transkripsiyon bloğundaki belirtme çizgisini de içerir.", "com.affine.settings.workspace.experimental-features.enable-callout.description": "Sözleriniz öne çıksın. Bu aynı zamanda transkripsiyon bloğundaki belirtme çizgisini de içerir.",
"com.affine.settings.workspace.experimental-features.enable-embed-iframe-block.name": "Iframe Bloğunu Göm", "com.affine.settings.workspace.experimental-features.enable-embed-iframe-block.name": "Iframe Bloğunu Göm",
@@ -1,8 +1,8 @@
export function createWavBuffer( export function createWavBuffer(
samples: Float32Array, samples: Float32Array,
options: { options: {
sampleRate: number; sampleRate?: number;
numChannels: number; numChannels?: number;
} }
) { ) {
const { sampleRate = 44100, numChannels = 1 } = options; const { sampleRate = 44100, numChannels = 1 } = options;
@@ -273,9 +273,7 @@ export class ChatPanelUtils {
await expect(async () => { await expect(async () => {
const states = await page const states = await page
.getByTestId('chat-panel-chip') .getByTestId('chat-panel-chip')
.evaluateAll(elements => .evaluateAll(elements => elements.map(el => el.dataset.state));
elements.map(el => el.getAttribute('data-state'))
);
expect(states.every(state => state === 'finished')).toBe(true); expect(states.every(state => state === 'finished')).toBe(true);
}).toPass({ timeout: 20000 }); }).toPass({ timeout: 20000 });
@@ -283,9 +281,7 @@ export class ChatPanelUtils {
await expect(async () => { await expect(async () => {
const states = await page const states = await page
.getByTestId('chat-panel-chip') .getByTestId('chat-panel-chip')
.evaluateAll(elements => .evaluateAll(elements => elements.map(el => el.dataset.state));
elements.map(el => el.getAttribute('data-state'))
);
expect(states).toHaveLength(attachments.length); expect(states).toHaveLength(attachments.length);
expect(states.every(state => state === 'finished')).toBe(true); expect(states.every(state => state === 'finished')).toBe(true);
}).toPass({ timeout: 20000 }); }).toPass({ timeout: 20000 });