fix(editor): loading style (#12537)

Closes: [BS-3555](https://linear.app/affine-design/issue/BS-3555/ui-attachment-loading-变量更新)
Closes: [BS-3559](https://linear.app/affine-design/issue/BS-3559/ui-图片-loading-变量更新)

### Dark
<img width="625" alt="Screenshot 2025-05-26 at 20 32 36" src="https://github.com/user-attachments/assets/93501e3d-8fc6-45f9-84a0-ac147e5c5f9f" />

### Light
<img width="623" alt="Screenshot 2025-05-26 at 20 32 25" src="https://github.com/user-attachments/assets/7d5bc128-6667-45b5-982d-dab3a22706a7" />

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Loading icons are now invoked as functions, allowing for more flexible and customizable rendering with parameters like size and progress.

- **Refactor**
  - Replaced theme-dependent and static loading icon references with a unified `LoadingIcon()` component across multiple components and blocks.
  - Removed legacy icon variants and simplified icon import statements, centralizing icon rendering logic.

- **Style**
  - Updated styles for loading and reload buttons to use theme-aware CSS variables.
  - Enlarged and repositioned loading indicators in image blocks for better visibility.

- **Bug Fixes**
  - Achieved consistent loading icon rendering across various blocks and components by standardizing icon invocation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
fundon
2025-05-27 05:10:27 +00:00
parent 1b715e588c
commit 9465d0dc73
27 changed files with 103 additions and 166 deletions

View File

@@ -4,7 +4,7 @@ import {
} from '@blocksuite/affine-components/caption';
import {
getAttachmentFileIcon,
getLoadingIconWith,
LoadingIcon,
} from '@blocksuite/affine-components/icons';
import { Peekable } from '@blocksuite/affine-components/peek';
import {
@@ -20,7 +20,6 @@ import {
DocModeProvider,
FileSizeLimitProvider,
TelemetryProvider,
ThemeProvider,
} from '@blocksuite/affine-shared/services';
import { formatSize } from '@blocksuite/affine-shared/utils';
import {
@@ -304,15 +303,12 @@ export class AttachmentBlockComponent extends CaptionedBlockComponent<Attachment
}
protected resolvedState$ = computed<AttachmentResolvedStateInfo>(() => {
const theme = this.std.get(ThemeProvider).theme$.value;
const loadingIcon = getLoadingIconWith(theme);
const size = this.model.props.size;
const name = this.model.props.name$.value;
const kind = getAttachmentFileIcon(name.split('.').pop() ?? '');
const resolvedState = this.resourceController.resolveStateWith({
loadingIcon,
loadingIcon: LoadingIcon(),
errorIcon: WarningIcon(),
icon: AttachmentIcon(),
title: name,

View File

@@ -47,11 +47,10 @@ export const styles = css`
.affine-attachment-content-title-icon {
display: flex;
width: 16px;
height: 16px;
align-items: center;
justify-content: center;
color: var(--affine-text-primary-color);
font-size: 16px;
}
.affine-attachment-content-title-text {
@@ -107,7 +106,7 @@ export const styles = css`
.affine-attachment-card.loading {
.affine-attachment-content-title-text {
color: var(--affine-placeholder-color);
color: ${unsafeCSSVarV2('text/placeholder')};
}
}

View File

@@ -1,5 +1,5 @@
import { getEmbedCardIcons } from '@blocksuite/affine-block-embed';
import { WebIcon16 } from '@blocksuite/affine-components/icons';
import { LoadingIcon, WebIcon16 } from '@blocksuite/affine-components/icons';
import { ImageProxyService } from '@blocksuite/affine-shared/adapters';
import { ThemeProvider } from '@blocksuite/affine-shared/services';
import { getHostName } from '@blocksuite/affine-shared/utils';
@@ -60,11 +60,11 @@ export class BookmarkCard extends SignalWatcher(
: title;
const theme = this.bookmark.std.get(ThemeProvider).theme;
const { LoadingIcon, EmbedCardBannerIcon } = getEmbedCardIcons(theme);
const { EmbedCardBannerIcon } = getEmbedCardIcons(theme);
const imageProxyService = this.bookmark.store.get(ImageProxyService);
const titleIcon = this.loading
? LoadingIcon
? LoadingIcon()
: icon
? html`<img src=${imageProxyService.buildUrl(icon)} alt="icon" />`
: WebIcon16;

View File

@@ -3,6 +3,7 @@ import {
RENDER_CARD_THROTTLE_MS,
} from '@blocksuite/affine-block-embed';
import { SurfaceBlockModel } from '@blocksuite/affine-block-surface';
import { LoadingIcon } from '@blocksuite/affine-components/icons';
import { isPeekable, Peekable } from '@blocksuite/affine-components/peek';
import { RefNodeSlotsProvider } from '@blocksuite/affine-inline-reference';
import type {
@@ -31,6 +32,7 @@ import {
referenceToNode,
} from '@blocksuite/affine-shared/utils';
import { Bound } from '@blocksuite/global/gfx';
import { ResetIcon } from '@blocksuite/icons/lit';
import { BlockSelection } from '@blocksuite/std';
import { Text } from '@blocksuite/store';
import { computed } from '@preact/signals-core';
@@ -337,8 +339,6 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
const theme = this.std.get(ThemeProvider).theme;
const {
LoadingIcon,
ReloadIcon,
LinkedDocDeletedBanner,
LinkedDocEmptyBanner,
SyncedDocErrorBanner,
@@ -347,7 +347,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
const icon = isError
? SyncedDocErrorIcon
: isLoading
? LoadingIcon
? LoadingIcon()
: this.icon$.value;
const title = isLoading ? 'Loading...' : this.title$;
const description = this.model.props.description$;
@@ -429,7 +429,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
class="affine-embed-linked-doc-card-content-reload-button"
@click=${this.refreshData}
>
${ReloadIcon} <span>Reload</span>
${ResetIcon()} <span>Reload</span>
</div>
</div>
`

View File

@@ -124,11 +124,11 @@ export const styles = css`
align-items: center;
gap: 4px;
cursor: pointer;
color: ${unsafeCSSVarV2('button/primary')};
}
.affine-embed-linked-doc-card-content-reload-button svg {
width: 12px;
height: 12px;
fill: var(--affine-background-primary-color);
}
.affine-embed-linked-doc-card-content-reload-button > span {
display: -webkit-box;
@@ -138,7 +138,6 @@ export const styles = css`
white-space: normal;
overflow: hidden;
text-overflow: ellipsis;
color: var(--affine-brand-color);
font-family: var(--affine-font-family);
font-size: var(--affine-font-xs);
font-style: normal;

View File

@@ -1,8 +1,6 @@
import {
EmbedEdgelessIcon,
EmbedPageIcon,
getLoadingIconWith,
ReloadIcon,
} from '@blocksuite/affine-components/icons';
import {
ColorScheme,
@@ -35,8 +33,6 @@ import {
} from './styles.js';
type EmbedCardImages = {
LoadingIcon: TemplateResult<1>;
ReloadIcon: TemplateResult<1>;
LinkedDocIcon: TemplateResult<1>;
LinkedDocDeletedIcon: TemplateResult<1>;
LinkedDocEmptyBanner: TemplateResult<1>;
@@ -50,12 +46,9 @@ export function getEmbedLinkedDocIcons(
style: (typeof EmbedLinkedDocStyles)[number]
): EmbedCardImages {
const small = style !== 'vertical';
const LoadingIcon = getLoadingIconWith(theme);
if (editorMode === 'page') {
if (theme === ColorScheme.Light) {
return {
LoadingIcon,
ReloadIcon,
LinkedDocIcon: EmbedPageIcon,
LinkedDocDeletedIcon,
LinkedDocEmptyBanner: small
@@ -68,8 +61,6 @@ export function getEmbedLinkedDocIcons(
};
} else {
return {
ReloadIcon,
LoadingIcon,
LinkedDocIcon: EmbedPageIcon,
LinkedDocDeletedIcon,
LinkedDocEmptyBanner: small
@@ -84,8 +75,6 @@ export function getEmbedLinkedDocIcons(
} else {
if (theme === ColorScheme.Light) {
return {
ReloadIcon,
LoadingIcon,
LinkedDocIcon: EmbedEdgelessIcon,
LinkedDocDeletedIcon,
LinkedDocEmptyBanner: small
@@ -98,8 +87,6 @@ export function getEmbedLinkedDocIcons(
};
} else {
return {
ReloadIcon,
LoadingIcon,
LinkedDocIcon: EmbedEdgelessIcon,
LinkedDocDeletedIcon,
LinkedDocEmptyBanner: small

View File

@@ -1,6 +1,8 @@
import { RENDER_CARD_THROTTLE_MS } from '@blocksuite/affine-block-embed';
import { LoadingIcon } from '@blocksuite/affine-components/icons';
import { ThemeProvider } from '@blocksuite/affine-shared/services';
import { WithDisposable } from '@blocksuite/global/lit';
import { ResetIcon } from '@blocksuite/icons/lit';
import {
BlockSelection,
isGfxBlockComponent,
@@ -148,9 +150,7 @@ export class EmbedSyncedDocCard extends WithDisposable(ShadowlessElement) {
const theme = this.std.get(ThemeProvider).theme;
const {
LoadingIcon,
SyncedDocErrorIcon,
ReloadIcon,
SyncedDocEmptyBanner,
SyncedDocErrorBanner,
SyncedDocDeletedBanner,
@@ -159,7 +159,7 @@ export class EmbedSyncedDocCard extends WithDisposable(ShadowlessElement) {
const icon = error
? SyncedDocErrorIcon
: isLoading
? LoadingIcon
? LoadingIcon()
: this.block.icon$.value;
const title = isLoading ? 'Loading...' : this.block.title$;
@@ -216,7 +216,7 @@ export class EmbedSyncedDocCard extends WithDisposable(ShadowlessElement) {
class="affine-embed-synced-doc-card-content-reload-button"
@click=${() => this.block.refreshData()}
>
${ReloadIcon} <span>Reload</span>
${ResetIcon()} <span>Reload</span>
</div>
</div>
`

View File

@@ -303,11 +303,11 @@ export const cardStyles = css`
align-items: center;
gap: 4px;
cursor: pointer;
color: ${unsafeCSSVarV2('button/primary')};
}
.affine-embed-synced-doc-card-content-reload-button svg {
width: 12px;
height: 12px;
fill: var(--affine-background-primary-color);
}
.affine-embed-synced-doc-card-content-reload-button > span {
display: -webkit-box;
@@ -317,7 +317,6 @@ export const cardStyles = css`
white-space: normal;
overflow: hidden;
text-overflow: ellipsis;
color: var(--affine-brand-color);
font-family: var(--affine-font-family);
font-size: var(--affine-font-xs);
font-style: normal;

View File

@@ -1,8 +1,6 @@
import {
EmbedEdgelessIcon,
EmbedPageIcon,
getLoadingIconWith,
ReloadIcon,
} from '@blocksuite/affine-components/icons';
import { ColorScheme } from '@blocksuite/affine-model';
import type { BlockComponent } from '@blocksuite/std';
@@ -21,11 +19,9 @@ import {
} from './styles.js';
type SyncedCardImages = {
LoadingIcon: TemplateResult<1>;
SyncedDocIcon: TemplateResult<1>;
SyncedDocErrorIcon: TemplateResult<1>;
SyncedDocDeletedIcon: TemplateResult<1>;
ReloadIcon: TemplateResult<1>;
SyncedDocEmptyBanner: TemplateResult<1>;
SyncedDocErrorBanner: TemplateResult<1>;
SyncedDocDeletedBanner: TemplateResult<1>;
@@ -35,25 +31,20 @@ export function getSyncedDocIcons(
theme: ColorScheme,
editorMode: 'page' | 'edgeless'
): SyncedCardImages {
const LoadingIcon = getLoadingIconWith(theme);
if (theme === ColorScheme.Light) {
return {
LoadingIcon,
SyncedDocIcon: editorMode === 'page' ? EmbedPageIcon : EmbedEdgelessIcon,
SyncedDocErrorIcon,
SyncedDocDeletedIcon,
ReloadIcon,
SyncedDocEmptyBanner: LightSyncedDocEmptyBanner,
SyncedDocErrorBanner: LightSyncedDocErrorBanner,
SyncedDocDeletedBanner: LightSyncedDocDeletedBanner,
};
} else {
return {
LoadingIcon,
SyncedDocIcon: editorMode === 'page' ? EmbedPageIcon : EmbedEdgelessIcon,
SyncedDocErrorIcon,
SyncedDocDeletedIcon,
ReloadIcon,
SyncedDocEmptyBanner: DarkSyncedDocEmptyBanner,
SyncedDocErrorBanner: DarkSyncedDocErrorBanner,
SyncedDocDeletedBanner: DarkSyncedDocDeletedBanner,

View File

@@ -9,13 +9,11 @@ import {
EmbedCardLightHorizontalIcon,
EmbedCardLightListIcon,
EmbedCardLightVerticalIcon,
getLoadingIconWith,
} from '@blocksuite/affine-components/icons';
import { ColorScheme } from '@blocksuite/affine-model';
import type { TemplateResult } from 'lit';
type EmbedCardIcons = {
LoadingIcon: TemplateResult<1>;
EmbedCardBannerIcon: TemplateResult<1>;
EmbedCardHorizontalIcon: TemplateResult<1>;
EmbedCardListIcon: TemplateResult<1>;
@@ -24,11 +22,8 @@ type EmbedCardIcons = {
};
export function getEmbedCardIcons(theme: ColorScheme): EmbedCardIcons {
const LoadingIcon = getLoadingIconWith(theme);
if (theme === ColorScheme.Light) {
return {
LoadingIcon,
EmbedCardBannerIcon: EmbedCardLightBannerIcon,
EmbedCardHorizontalIcon: EmbedCardLightHorizontalIcon,
EmbedCardListIcon: EmbedCardLightListIcon,
@@ -37,7 +32,6 @@ export function getEmbedCardIcons(theme: ColorScheme): EmbedCardIcons {
};
} else {
return {
LoadingIcon,
EmbedCardBannerIcon: EmbedCardDarkBannerIcon,
EmbedCardHorizontalIcon: EmbedCardDarkHorizontalIcon,
EmbedCardListIcon: EmbedCardDarkListIcon,

View File

@@ -1,4 +1,4 @@
import { OpenIcon } from '@blocksuite/affine-components/icons';
import { LoadingIcon, OpenIcon } from '@blocksuite/affine-components/icons';
import type {
EmbedGithubModel,
EmbedGithubStyles,
@@ -133,8 +133,8 @@ export class EmbedGithubBlockComponent extends EmbedBlockComponent<
const loading = this.loading;
const theme = this.std.get(ThemeProvider).theme;
const imageProxyService = this.store.get(ImageProxyService);
const { LoadingIcon, EmbedCardBannerIcon } = getEmbedCardIcons(theme);
const titleIcon = loading ? LoadingIcon : GithubIcon;
const { EmbedCardBannerIcon } = getEmbedCardIcons(theme);
const titleIcon = loading ? LoadingIcon() : GithubIcon;
const statusIcon = status
? getGithubStatusIcon(githubType, status, statusReason)
: nothing;

View File

@@ -1,4 +1,4 @@
import { ThemeProvider } from '@blocksuite/affine-shared/services';
import { LoadingIcon } from '@blocksuite/affine-components/icons';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { EmbedIcon } from '@blocksuite/icons/lit';
import { type BlockStdScope } from '@blocksuite/std';
@@ -7,7 +7,6 @@ import { property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { styleMap } from 'lit/directives/style-map.js';
import { getEmbedCardIcons } from '../../common/utils';
import { LOADING_CARD_DEFAULT_HEIGHT } from '../consts';
import type { EmbedIframeStatusCardOptions } from '../types';
@@ -156,9 +155,6 @@ export class EmbedIframeLoadingCard extends LitElement {
`;
override render() {
const theme = this.std.get(ThemeProvider).theme;
const { LoadingIcon } = getEmbedCardIcons(theme);
const { layout, width, height } = this.options;
const cardClasses = classMap({
'affine-embed-iframe-loading-card': true,
@@ -176,7 +172,7 @@ export class EmbedIframeLoadingCard extends LitElement {
return html`
<div class=${cardClasses} style=${cardStyle}>
<div class="loading-content">
<div class="loading-spinner">${LoadingIcon}</div>
<div class="loading-spinner">${LoadingIcon()}</div>
<div class="loading-text">Loading...</div>
</div>
<div class="loading-banner">

View File

@@ -1,4 +1,4 @@
import { OpenIcon } from '@blocksuite/affine-components/icons';
import { LoadingIcon, OpenIcon } from '@blocksuite/affine-components/icons';
import type { EmbedLoomModel, EmbedLoomStyles } from '@blocksuite/affine-model';
import { ImageProxyService } from '@blocksuite/affine-shared/adapters';
import { ThemeProvider } from '@blocksuite/affine-shared/services';
@@ -94,8 +94,8 @@ export class EmbedLoomBlockComponent extends EmbedBlockComponent<
const loading = this.loading;
const theme = this.std.get(ThemeProvider).theme;
const imageProxyService = this.store.get(ImageProxyService);
const { LoadingIcon, EmbedCardBannerIcon } = getEmbedCardIcons(theme);
const titleIcon = loading ? LoadingIcon : LoomIcon;
const { EmbedCardBannerIcon } = getEmbedCardIcons(theme);
const titleIcon = loading ? LoadingIcon() : LoomIcon;
const titleText = loading ? 'Loading...' : title;
const descriptionText = loading ? '' : description;
const bannerImage =

View File

@@ -1,4 +1,4 @@
import { OpenIcon } from '@blocksuite/affine-components/icons';
import { LoadingIcon, OpenIcon } from '@blocksuite/affine-components/icons';
import type {
EmbedYoutubeModel,
EmbedYoutubeStyles,
@@ -108,8 +108,8 @@ export class EmbedYoutubeBlockComponent extends EmbedBlockComponent<
const loading = this.loading;
const theme = this.std.get(ThemeProvider).theme;
const imageProxyService = this.store.get(ImageProxyService);
const { LoadingIcon, EmbedCardBannerIcon } = getEmbedCardIcons(theme);
const titleIcon = loading ? LoadingIcon : YoutubeIcon;
const { EmbedCardBannerIcon } = getEmbedCardIcons(theme);
const titleIcon = loading ? LoadingIcon() : YoutubeIcon;
const titleText = loading ? 'Loading...' : title;
const descriptionText = loading ? null : description;
const bannerImage =

View File

@@ -46,12 +46,16 @@ export class ImageBlockPageComponent extends SignalWatcher(
justify-content: center;
position: absolute;
top: 4px;
right: 4px;
width: 20px;
height: 20px;
padding: 4px;
border-radius: 4px;
left: 4px;
width: 36px;
height: 36px;
padding: 5px;
border-radius: 8px;
background: ${unsafeCSSVarV2('loading/backgroundLayer')};
& > svg {
font-size: 25.71px;
}
}
affine-page-image .affine-image-status {

View File

@@ -1,19 +1,17 @@
import { CaptionedBlockComponent } from '@blocksuite/affine-components/caption';
import { whenHover } from '@blocksuite/affine-components/hover';
import { getLoadingIconWith } from '@blocksuite/affine-components/icons';
import { LoadingIcon } from '@blocksuite/affine-components/icons';
import { Peekable } from '@blocksuite/affine-components/peek';
import { ResourceController } from '@blocksuite/affine-components/resource';
import type { ImageBlockModel } from '@blocksuite/affine-model';
import { ImageSelection } from '@blocksuite/affine-shared/selection';
import {
ThemeProvider,
ToolbarRegistryIdentifier,
} from '@blocksuite/affine-shared/services';
import { ToolbarRegistryIdentifier } from '@blocksuite/affine-shared/services';
import { formatSize } from '@blocksuite/affine-shared/utils';
import { IS_MOBILE } from '@blocksuite/global/env';
import { BrokenImageIcon, ImageIcon } from '@blocksuite/icons/lit';
import { BlockSelection } from '@blocksuite/std';
import { computed } from '@preact/signals-core';
import { cssVarV2 } from '@toeverything/theme/v2';
import { html } from 'lit';
import { query } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
@@ -126,9 +124,6 @@ export class ImageBlockComponent extends CaptionedBlockComponent<ImageBlockModel
}
override renderBlock() {
const theme = this.std.get(ThemeProvider).theme$.value;
const loadingIcon = getLoadingIconWith(theme);
const blobUrl = this.blobUrl;
const { size = 0 } = this.model.props;
@@ -138,7 +133,9 @@ export class ImageBlockComponent extends CaptionedBlockComponent<ImageBlockModel
});
const resovledState = this.resourceController.resolveStateWith({
loadingIcon,
loadingIcon: LoadingIcon({
strokeColor: cssVarV2('button/pureWhiteText'),
}),
errorIcon: BrokenImageIcon(),
icon: ImageIcon(),
title: 'Image',

View File

@@ -1,13 +1,12 @@
import type { BlockCaptionEditor } from '@blocksuite/affine-components/caption';
import { getLoadingIconWith } from '@blocksuite/affine-components/icons';
import { LoadingIcon } from '@blocksuite/affine-components/icons';
import { Peekable } from '@blocksuite/affine-components/peek';
import { ResourceController } from '@blocksuite/affine-components/resource';
import {
type ImageBlockModel,
ImageBlockSchema,
} from '@blocksuite/affine-model';
import { ThemeProvider } from '@blocksuite/affine-shared/services';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { cssVarV2, unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { formatSize } from '@blocksuite/affine-shared/utils';
import { BrokenImageIcon, ImageIcon } from '@blocksuite/icons/lit';
import { GfxBlockComponent } from '@blocksuite/std';
@@ -39,11 +38,15 @@ export class ImageEdgelessBlockComponent extends GfxBlockComponent<ImageBlockMod
position: absolute;
top: 4px;
right: 4px;
width: 20px;
height: 20px;
padding: 4px;
border-radius: 4px;
width: 36px;
height: 36px;
padding: 5px;
border-radius: 8px;
background: ${unsafeCSSVarV2('loading/backgroundLayer')};
& > svg {
font-size: 25.71px;
}
}
affine-edgeless-image .affine-image-status {
@@ -108,9 +111,6 @@ export class ImageEdgelessBlockComponent extends GfxBlockComponent<ImageBlockMod
}
override renderGfxBlock() {
const theme = this.std.get(ThemeProvider).theme$.value;
const loadingIcon = getLoadingIconWith(theme);
const blobUrl = this.blobUrl;
const { rotate = 0, size = 0, caption = 'Image' } = this.model.props;
@@ -124,7 +124,9 @@ export class ImageEdgelessBlockComponent extends GfxBlockComponent<ImageBlockMod
});
const resovledState = this.resourceController.resolveStateWith({
loadingIcon,
loadingIcon: LoadingIcon({
strokeColor: cssVarV2('button/pureWhiteText'),
}),
errorIcon: BrokenImageIcon(),
icon: ImageIcon(),
title: 'Image',
@@ -148,7 +150,7 @@ export class ImageEdgelessBlockComponent extends GfxBlockComponent<ImageBlockMod
</div>
${when(
resovledState.loading,
() => html`<div class="loading">${loadingIcon}</div>`
() => html`<div class="loading">${resovledState.icon}</div>`
)}
${when(
resovledState.error && resovledState.description,

View File

@@ -1,14 +1,23 @@
import { ColorScheme } from '@blocksuite/affine-model';
import { cssVarV2 } from '@toeverything/theme/v2';
import { html } from 'lit';
const LoadingIcon = (color: string) =>
export const LoadingIcon = ({
size = '1em',
progress = 0.2,
strokeColor = cssVarV2('loading/foreground'),
}: {
size?: string;
progress?: number;
strokeColor?: string;
} = {}) =>
html`<svg
width="16"
height="16"
viewBox="0 0 16 16"
width="${size}"
height="${size}"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
fill="none"
>
<style xmlns="http://www.w3.org/2000/svg">
<style>
.spinner {
transform-origin: center;
animation: spinner_animate 0.75s infinite linear;
@@ -19,21 +28,24 @@ const LoadingIcon = (color: string) =>
}
}
</style>
<path
d="M14.6666 8.00004C14.6666 11.6819 11.6818 14.6667 7.99992 14.6667C4.31802 14.6667 1.33325 11.6819 1.33325 8.00004C1.33325 4.31814 4.31802 1.33337 7.99992 1.33337C11.6818 1.33337 14.6666 4.31814 14.6666 8.00004ZM3.30003 8.00004C3.30003 10.5957 5.40424 12.6999 7.99992 12.6999C10.5956 12.6999 12.6998 10.5957 12.6998 8.00004C12.6998 5.40436 10.5956 3.30015 7.99992 3.30015C5.40424 3.30015 3.30003 5.40436 3.30003 8.00004Z"
fill="${color}"
fill-opacity="0.1"
<circle
cx="12"
cy="12"
r="8"
stroke="${cssVarV2('loading/background')}"
stroke-width="4"
/>
<path
d="M13.6833 8.00004C14.2263 8.00004 14.674 7.55745 14.5942 7.02026C14.5142 6.48183 14.3684 5.954 14.1591 5.44882C13.8241 4.63998 13.333 3.90505 12.714 3.286C12.0949 2.66694 11.36 2.17588 10.5511 1.84084C10.046 1.63159 9.51812 1.48576 8.9797 1.40576C8.44251 1.32595 7.99992 1.77363 7.99992 2.31671C7.99992 2.85979 8.44486 3.28974 8.9761 3.40253C9.25681 3.46214 9.53214 3.54746 9.79853 3.65781C10.3688 3.894 10.8869 4.2402 11.3233 4.67664C11.7598 5.11307 12.106 5.6312 12.3422 6.20143C12.4525 6.46782 12.5378 6.74315 12.5974 7.02386C12.7102 7.5551 13.1402 8.00004 13.6833 8.00004Z"
fill="#1C9EE4"
<circle
class="spinner"
cx="12"
cy="12"
r="8"
stroke="${strokeColor}"
stroke-width="4"
stroke-linecap="round"
stroke-dasharray="${2 * Math.PI * 8 * progress} ${2 *
Math.PI *
8 *
(1 - progress)}"
/>
</svg>`;
export const LightLoadingIcon = LoadingIcon('black');
export const DarkLoadingIcon = LoadingIcon('white');
export const getLoadingIconWith = (theme: ColorScheme = ColorScheme.Light) =>
theme === ColorScheme.Light ? LightLoadingIcon : DarkLoadingIcon;

View File

@@ -840,28 +840,6 @@ export const EmbedCardDarkCubeIcon = html`
</svg>
`;
export const ReloadIcon = html`<svg
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_6505_24239)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M1.625 6C1.625 3.58375 3.58375 1.625 6 1.625C7.12028 1.625 8.14299 2.04656 8.91676 2.7391L8.91796 2.74017L9.625 3.37847V2C9.625 1.79289 9.79289 1.625 10 1.625C10.2071 1.625 10.375 1.79289 10.375 2V4.22222C10.375 4.42933 10.2071 4.59722 10 4.59722H7.77778C7.57067 4.59722 7.40278 4.42933 7.40278 4.22222C7.40278 4.01512 7.57067 3.84722 7.77778 3.84722H9.025L8.41657 3.29795C8.41637 3.29777 8.41617 3.29759 8.41597 3.29741C7.77447 2.7235 6.92838 2.375 6 2.375C3.99797 2.375 2.375 3.99797 2.375 6C2.375 8.00203 3.99797 9.625 6 9.625C7.72469 9.625 9.16888 8.42017 9.53518 6.80591C9.58101 6.60393 9.78189 6.47736 9.98386 6.52319C10.1858 6.56902 10.3124 6.7699 10.2666 6.97187C9.82447 8.92025 8.08257 10.375 6 10.375C3.58375 10.375 1.625 8.41625 1.625 6Z"
fill="#1E96EB"
/>
</g>
<defs>
<clipPath id="clip0_6505_24239">
<rect width="12" height="12" fill="white" />
</clipPath>
</defs>
</svg>`;
export const EmbedPageIcon = icons.LinkedPageIcon({
width: '16',
height: '16',

View File

@@ -1,4 +1,4 @@
import { LightLoadingIcon } from '@blocksuite/affine-components/icons';
import { LoadingIcon } from '@blocksuite/affine-components/icons';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { ShadowlessElement } from '@blocksuite/std';
import { css, html } from 'lit';
@@ -46,7 +46,7 @@ export class MindMapPlaceholder extends ShadowlessElement {
return html`<div class="placeholder-container">
<div class="preview-icon">${importMindMapIcon}</div>
<div class="description">
${LightLoadingIcon}
${LoadingIcon()}
<span>Importing mind map...</span>
</div>
</div>`;

View File

@@ -1,6 +1,6 @@
import {
getAttachmentFileIcon,
getLoadingIconWith,
LoadingIcon,
WebIcon16,
} from '@blocksuite/affine-components/icons';
import type { FootNote } from '@blocksuite/affine-model';
@@ -8,7 +8,6 @@ import { ImageProxyService } from '@blocksuite/affine-shared/adapters';
import {
DocDisplayMetaProvider,
LinkPreviewServiceIdentifier,
ThemeProvider,
} from '@blocksuite/affine-shared/services';
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
@@ -77,7 +76,7 @@ export class FootNotePopup extends SignalWatcher(WithDisposable(LitElement)) {
return getAttachmentFileIcon(fileType);
} else if (referenceType === 'url') {
if (this._isLoading$.value) {
return this._LoadingIcon();
return LoadingIcon();
}
const favicon = this._linkPreview$.value?.favicon;
@@ -126,11 +125,6 @@ export class FootNotePopup extends SignalWatcher(WithDisposable(LitElement)) {
return this._popupLabel$.value;
});
private readonly _LoadingIcon = () => {
const theme = this.std.get(ThemeProvider).theme;
return getLoadingIconWith(theme);
};
private readonly _onClick = () => {
this.onPopupClick(this.footnote, this.abortController);
this.abortController.abort();

View File

@@ -1,10 +1,9 @@
import type { IconButton } from '@blocksuite/affine-components/icon-button';
import { getLoadingIconWith } from '@blocksuite/affine-components/icons';
import { LoadingIcon } from '@blocksuite/affine-components/icons';
import {
cleanSpecifiedTail,
getTextContentFromInlineRange,
} from '@blocksuite/affine-rich-text';
import { ThemeProvider } from '@blocksuite/affine-shared/services';
import { unsafeCSSVar } from '@blocksuite/affine-shared/theme';
import {
createKeydownObserver,
@@ -128,10 +127,6 @@ export class LinkedDocPopover extends SignalWatcher(
);
}
private get _loadingIcon() {
return getLoadingIconWith(this.context.std.get(ThemeProvider).theme$.value);
}
private _getActionItems(group: LinkedMenuGroup) {
const isExpanded = !!this._expanded.get(group.name);
let items = resolveSignal(group.items);
@@ -291,7 +286,7 @@ export class LinkedDocPopover extends SignalWatcher(
<div class="group-title">
<div class="group-title-text">${group.name}</div>
${group.isLoading
? html`<span class="loading-icon">${this._loadingIcon}</span>`
? html`<span class="loading-icon">${LoadingIcon()}</span>`
: nothing}
</div>
<div class="group" style=${group.styles ?? ''}>