mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
refactor(component): refactor the implementation of Button and IconButton (#7716)
## Button
- Remove props withoutHoverStyle
refactor hover impl with independent layer, so that hover-color won't affect the background even if is overridden outside
- Update `type` (renamed to `variant`):
- remove `processing` and `warning`
- rename `default` with `secondary`
- Remove `shape` props
- Remove `icon` and `iconPosition`, replaced with `prefix: ReactNode` and `suffix: ReactNode`
- Integrate tooltip for more convenient usage
- New Storybook document
- Focus style
## IconButton
- A Wrapper base on `<Button />`
- Override Button size and variant
- size: `'12' | '14' | '16' | '20' | '24' | number`
These presets size are referenced from the design system.
- variant: `'plain' | 'solid' | 'danger' | 'custom'`
- Inset icon via Button 's prefix
## Fix
- fix some button related issues
- close AF-1159, AF-1160, AF-1161, AF-1162, AF-1163, AF-1158, AF-1157
## Storybook

This commit is contained in:
@@ -32,7 +32,7 @@ export const AdminPanelHeader = ({
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
type="primary"
|
||||
variant="primary"
|
||||
disabled={modifiedValues.length === 0}
|
||||
onClick={() => {
|
||||
openConfirmModal({
|
||||
@@ -41,7 +41,7 @@ export const AdminPanelHeader = ({
|
||||
'Are you sure you want to save the following changes?',
|
||||
confirmText: 'Save',
|
||||
confirmButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
},
|
||||
onConfirm: onConfirm,
|
||||
children:
|
||||
|
||||
@@ -81,7 +81,7 @@ export const ErrorDetail: FC<ErrorDetailProps> = props => {
|
||||
))}
|
||||
<div className={styles.errorFooter}>
|
||||
<Button
|
||||
type="primary"
|
||||
variant="primary"
|
||||
onClick={onBtnClick}
|
||||
loading={isBtnLoading}
|
||||
size="extraLarge"
|
||||
|
||||
@@ -21,7 +21,6 @@ export const thumbContent = style({
|
||||
});
|
||||
|
||||
export const actionButton = style({
|
||||
fontWeight: 500,
|
||||
fontSize: cssVar('fontSm'),
|
||||
lineHeight: '22px',
|
||||
});
|
||||
|
||||
@@ -103,7 +103,7 @@ export const AIOnboardingEdgeless = () => {
|
||||
notify.dismiss(id);
|
||||
toggleEdgelessAIOnboarding(false);
|
||||
}}
|
||||
type="plain"
|
||||
variant="plain"
|
||||
className={styles.actionButton}
|
||||
>
|
||||
<span className={styles.getStartedButtonText}>
|
||||
@@ -113,7 +113,7 @@ export const AIOnboardingEdgeless = () => {
|
||||
{aiSubscription ? null : (
|
||||
<Button
|
||||
className={styles.actionButton}
|
||||
type="plain"
|
||||
variant="plain"
|
||||
onClick={() => {
|
||||
goToPricingPlans();
|
||||
notify.dismiss(id);
|
||||
|
||||
@@ -114,17 +114,3 @@ export const subscribeActions = style({
|
||||
gap: 12,
|
||||
alignItems: 'center',
|
||||
});
|
||||
export const baseActionButton = style({
|
||||
fontSize: cssVar('fontBase'),
|
||||
selectors: {
|
||||
'&.large': {
|
||||
fontWeight: 500,
|
||||
},
|
||||
},
|
||||
});
|
||||
export const transparentActionButton = style([
|
||||
baseActionButton,
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -243,36 +243,26 @@ export const AIOnboardingGeneral = () => {
|
||||
>
|
||||
{isLast ? (
|
||||
<>
|
||||
<IconButton
|
||||
size="default"
|
||||
icon={<ArrowLeftSmallIcon width={20} height={20} />}
|
||||
onClick={onPrev}
|
||||
type="plain"
|
||||
className={styles.baseActionButton}
|
||||
/>
|
||||
<IconButton size="20" onClick={onPrev}>
|
||||
<ArrowLeftSmallIcon />
|
||||
</IconButton>
|
||||
{aiSubscription ? (
|
||||
<Button
|
||||
className={styles.baseActionButton}
|
||||
size="large"
|
||||
onClick={closeAndDismiss}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
>
|
||||
{t['com.affine.ai-onboarding.general.get-started']()}
|
||||
</Button>
|
||||
) : (
|
||||
<div className={styles.subscribeActions}>
|
||||
<Button
|
||||
className={styles.baseActionButton}
|
||||
size="large"
|
||||
onClick={goToPricingPlans}
|
||||
>
|
||||
<Button size="large" onClick={goToPricingPlans}>
|
||||
{t['com.affine.ai-onboarding.general.purchase']()}
|
||||
</Button>
|
||||
<Button
|
||||
className={styles.baseActionButton}
|
||||
size="large"
|
||||
onClick={closeAndDismiss}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
>
|
||||
{t['com.affine.ai-onboarding.general.try-for-free']()}
|
||||
</Button>
|
||||
@@ -282,21 +272,15 @@ export const AIOnboardingGeneral = () => {
|
||||
) : (
|
||||
<>
|
||||
{isFirst ? (
|
||||
<Button
|
||||
className={styles.transparentActionButton}
|
||||
onClick={remindLater}
|
||||
size="large"
|
||||
type="default"
|
||||
>
|
||||
<Button onClick={remindLater} size="large">
|
||||
{t['com.affine.ai-onboarding.general.skip']()}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
icon={<ArrowLeftSmallIcon />}
|
||||
className={styles.baseActionButton}
|
||||
prefix={<ArrowLeftSmallIcon />}
|
||||
onClick={onPrev}
|
||||
type="plain"
|
||||
size="large"
|
||||
variant="plain"
|
||||
>
|
||||
{t['com.affine.ai-onboarding.general.prev']()}
|
||||
</Button>
|
||||
@@ -305,12 +289,7 @@ export const AIOnboardingGeneral = () => {
|
||||
<div>
|
||||
{index + 1} / {list.length}
|
||||
</div>
|
||||
<Button
|
||||
className={styles.baseActionButton}
|
||||
size="large"
|
||||
type="primary"
|
||||
onClick={onNext}
|
||||
>
|
||||
<Button size="large" variant="primary" onClick={onNext}>
|
||||
{t['com.affine.ai-onboarding.general.next']()}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@ const FooterActions = ({ onDismiss }: { onDismiss: () => void }) => {
|
||||
<a href="https://ai.affine.pro" target="_blank" rel="noreferrer">
|
||||
<Button
|
||||
className={styles.actionButton}
|
||||
type="plain"
|
||||
variant="plain"
|
||||
onClick={onDismiss}
|
||||
>
|
||||
{t['com.affine.ai-onboarding.local.action-learn-more']()}
|
||||
@@ -50,7 +50,7 @@ const FooterActions = ({ onDismiss }: { onDismiss: () => void }) => {
|
||||
{loggedIn ? null : (
|
||||
<Button
|
||||
className={styles.actionButton}
|
||||
type="plain"
|
||||
variant="plain"
|
||||
onClick={() => {
|
||||
onDismiss();
|
||||
jumpToSignIn('', RouteLogic.REPLACE, {}, { initCloud: 'true' });
|
||||
|
||||
@@ -99,7 +99,7 @@ export const AfterSignInSendEmail = ({
|
||||
<Button
|
||||
style={!verifyToken ? { cursor: 'not-allowed' } : {}}
|
||||
disabled={!verifyToken || isSending}
|
||||
type="plain"
|
||||
variant="plain"
|
||||
size="large"
|
||||
onClick={onResendClick}
|
||||
>
|
||||
|
||||
@@ -91,7 +91,7 @@ export const AfterSignUpSendEmail: FC<AuthPanelProps> = ({
|
||||
<Button
|
||||
style={!verifyToken ? { cursor: 'not-allowed' } : {}}
|
||||
disabled={!verifyToken || isSending}
|
||||
type="plain"
|
||||
variant="plain"
|
||||
size="large"
|
||||
onClick={onResendClick}
|
||||
>
|
||||
|
||||
@@ -27,7 +27,7 @@ export const AiLoginRequiredModal = () => {
|
||||
},
|
||||
confirmText: t['com.affine.ai.login-required.dialog-confirm'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
},
|
||||
cancelText: t['com.affine.ai.login-required.dialog-cancel'](),
|
||||
onOpenChange: setOpen,
|
||||
|
||||
@@ -82,11 +82,11 @@ function OAuthProvider({
|
||||
return (
|
||||
<Button
|
||||
key={provider}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
block
|
||||
size="extraLarge"
|
||||
style={{ marginTop: 30 }}
|
||||
icon={icon}
|
||||
style={{ marginTop: 30, width: '100%' }}
|
||||
prefix={icon}
|
||||
onClick={onClick}
|
||||
>
|
||||
Continue with {provider}
|
||||
|
||||
@@ -203,7 +203,7 @@ export const SendEmail = ({
|
||||
</Wrapper>
|
||||
|
||||
<Button
|
||||
type="primary"
|
||||
variant="primary"
|
||||
size="extraLarge"
|
||||
style={{ width: '100%' }}
|
||||
disabled={hasSentEmail}
|
||||
|
||||
@@ -129,7 +129,7 @@ export const SignInWithPassword: FC<AuthPanelProps> = ({
|
||||
</div>
|
||||
<Button
|
||||
data-testid="sign-in-button"
|
||||
type="primary"
|
||||
variant="primary"
|
||||
size="extraLarge"
|
||||
style={{ width: '100%' }}
|
||||
disabled={isLoading}
|
||||
|
||||
@@ -5,8 +5,9 @@ import { authAtom } from '@affine/core/atoms';
|
||||
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
|
||||
import { mixpanel } from '@affine/core/mixpanel';
|
||||
import { Trans, useI18n } from '@affine/i18n';
|
||||
import { ArrowDownBigIcon } from '@blocksuite/icons/rc';
|
||||
import { ArrowRightBigIcon } from '@blocksuite/icons/rc';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import type { FC } from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
@@ -149,21 +150,13 @@ export const SignIn: FC<AuthPanelProps> = ({
|
||||
|
||||
{verifyToken ? (
|
||||
<Button
|
||||
style={{ width: '100%' }}
|
||||
size="extraLarge"
|
||||
data-testid="continue-login-button"
|
||||
block
|
||||
loading={isMutating}
|
||||
icon={
|
||||
<ArrowDownBigIcon
|
||||
width={20}
|
||||
height={20}
|
||||
style={{
|
||||
transform: 'rotate(-90deg)',
|
||||
color: 'var(--affine-blue)',
|
||||
}}
|
||||
/>
|
||||
}
|
||||
iconPosition="end"
|
||||
suffix={<ArrowRightBigIcon />}
|
||||
suffixStyle={{ width: 20, height: 20, color: cssVar('blue') }}
|
||||
onClick={onContinue}
|
||||
>
|
||||
{t['com.affine.auth.sign.email.continue']()}
|
||||
|
||||
@@ -106,7 +106,7 @@ const NameWorkspaceContent = ({
|
||||
cancelText={t['com.affine.nameWorkspace.button.cancel']()}
|
||||
confirmText={t['com.affine.nameWorkspace.button.create']()}
|
||||
confirmButtonOptions={{
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
disabled: !workspaceName || loading,
|
||||
['data-testid' as string]: 'create-workspace-create-button',
|
||||
}}
|
||||
|
||||
@@ -28,7 +28,7 @@ export const HistoryTipsModal = () => {
|
||||
description={t['com.affine.history-vision.tips-modal.description']()}
|
||||
cancelText={t['com.affine.history-vision.tips-modal.cancel']()}
|
||||
confirmButtonOptions={{
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
}}
|
||||
onConfirm={handleConfirm}
|
||||
confirmText={t['com.affine.history-vision.tips-modal.confirm']()}
|
||||
|
||||
@@ -27,7 +27,7 @@ export const IssueFeedbackModal = () => {
|
||||
to={`${runtimeConfig.githubUrl}/issues/new/choose`}
|
||||
confirmText={t['com.affine.issue-feedback.confirm']()}
|
||||
confirmButtonOptions={{
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
}}
|
||||
external
|
||||
/>
|
||||
|
||||
@@ -19,7 +19,7 @@ export const AnimateInTooltip = ({
|
||||
</div>
|
||||
<div className={styles.next}>
|
||||
{visible ? (
|
||||
<Button type="primary" size="extraLarge" onClick={onNext}>
|
||||
<Button variant="primary" size="extraLarge" onClick={onNext}>
|
||||
Next
|
||||
</Button>
|
||||
) : null}
|
||||
|
||||
@@ -235,7 +235,7 @@ export const EdgelessSwitch = ({
|
||||
onSwitchToPageMode={onSwitchToPageMode}
|
||||
onSwitchToEdgelessMode={onSwitchToEdgelessMode}
|
||||
/>
|
||||
<Button size="extraLarge" type="primary" onClick={onNextClick}>
|
||||
<Button size="extraLarge" variant="primary" onClick={onNextClick}>
|
||||
Next
|
||||
</Button>
|
||||
</header>
|
||||
@@ -263,7 +263,7 @@ export const EdgelessSwitch = ({
|
||||
<Button
|
||||
className={styles.wellDoneEnterAnim}
|
||||
onClick={onNextClick}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
size="extraLarge"
|
||||
style={{ marginTop: 40 }}
|
||||
>
|
||||
|
||||
@@ -251,11 +251,9 @@ const PlanPrompt = () => {
|
||||
: '' /* TODO(@catsjuice): loading UI */
|
||||
}
|
||||
|
||||
<IconButton
|
||||
size="small"
|
||||
icon={<CloseIcon />}
|
||||
onClick={closeFreePlanPrompt}
|
||||
/>
|
||||
<IconButton onClick={closeFreePlanPrompt}>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
);
|
||||
}, [closeFreePlanPrompt, isProWorkspace, t]);
|
||||
@@ -393,7 +391,7 @@ const PageHistoryList = ({
|
||||
})}
|
||||
{onLoadMore ? (
|
||||
<Button
|
||||
type="plain"
|
||||
variant="plain"
|
||||
loading={loadingMore}
|
||||
disabled={loadingMore}
|
||||
className={styles.historyItemLoadMore}
|
||||
@@ -480,7 +478,7 @@ const PageHistoryManager = ({
|
||||
},
|
||||
confirmText: t['com.affine.history.confirm-restore-modal.restore'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
['data-testid' as string]: 'confirm-restore-history-button',
|
||||
},
|
||||
onConfirm: handleRestore,
|
||||
@@ -520,12 +518,12 @@ const PageHistoryManager = ({
|
||||
) : null}
|
||||
|
||||
<div className={styles.historyFooter}>
|
||||
<Button type="plain" onClick={onClose}>
|
||||
<Button onClick={onClose}>
|
||||
{t['com.affine.history.back-to-page']()}
|
||||
</Button>
|
||||
<div className={styles.spacer} />
|
||||
<Button
|
||||
type="primary"
|
||||
variant="primary"
|
||||
onClick={onConfirmRestore}
|
||||
disabled={isMutating || !activeVersion}
|
||||
>
|
||||
|
||||
@@ -50,7 +50,7 @@ export const ConfirmDeletePropertyModal = ({
|
||||
onClick: onCancel,
|
||||
}}
|
||||
confirmButtonOptions={{
|
||||
type: 'error',
|
||||
variant: 'error',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -117,22 +117,14 @@ export const tableBodySortable = style({
|
||||
});
|
||||
|
||||
export const addPropertyButton = style({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
alignSelf: 'flex-start',
|
||||
fontSize: cssVar('fontSm'),
|
||||
color: `${cssVar('textSecondaryColor')} !important`,
|
||||
color: `${cssVar('textSecondaryColor')}`,
|
||||
padding: '0 4px',
|
||||
height: 36,
|
||||
cursor: 'pointer',
|
||||
':hover': {
|
||||
color: cssVar('textPrimaryColor'),
|
||||
backgroundColor: cssVar('hoverColor'),
|
||||
},
|
||||
gap: 2,
|
||||
fontWeight: 400,
|
||||
gap: 6,
|
||||
});
|
||||
|
||||
globalStyle(`${addPropertyButton} svg`, {
|
||||
fontSize: 16,
|
||||
color: cssVar('iconSecondary'),
|
||||
|
||||
@@ -703,11 +703,9 @@ export const PagePropertiesTableHeader = ({
|
||||
</div>
|
||||
{properties.length === 0 || manager.readonly ? null : (
|
||||
<PagePropertiesSettingsPopup>
|
||||
<IconButton
|
||||
data-testid="page-info-show-more"
|
||||
type="plain"
|
||||
icon={<MoreHorizontalIcon />}
|
||||
/>
|
||||
<IconButton data-testid="page-info-show-more" size="20">
|
||||
<MoreHorizontalIcon />
|
||||
</IconButton>
|
||||
</PagePropertiesSettingsPopup>
|
||||
)}
|
||||
<Collapsible.Trigger asChild role="button" onClick={handleCollapse}>
|
||||
@@ -715,15 +713,12 @@ export const PagePropertiesTableHeader = ({
|
||||
className={styles.tableHeaderCollapseButtonWrapper}
|
||||
data-testid="page-info-collapse"
|
||||
>
|
||||
<IconButton
|
||||
type="plain"
|
||||
icon={
|
||||
<ToggleExpandIcon
|
||||
className={styles.collapsedIcon}
|
||||
data-collapsed={!open}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<IconButton size="20">
|
||||
<ToggleExpandIcon
|
||||
className={styles.collapsedIcon}
|
||||
data-collapsed={!open}
|
||||
/>
|
||||
</IconButton>
|
||||
</div>
|
||||
</Collapsible.Trigger>
|
||||
</div>
|
||||
@@ -1056,8 +1051,8 @@ export const PagePropertiesAddProperty = () => {
|
||||
return (
|
||||
<Menu {...menuOptions}>
|
||||
<Button
|
||||
type="plain"
|
||||
icon={<PlusIcon />}
|
||||
variant="plain"
|
||||
prefix={<PlusIcon />}
|
||||
className={styles.addPropertyButton}
|
||||
>
|
||||
{t['com.affine.page-properties.add-property']()}
|
||||
|
||||
@@ -405,11 +405,9 @@ export const TagsEditor = ({ pageId, readonly }: TagsEditorProps) => {
|
||||
<TagItem maxWidth="100%" tag={tag} mode="inline" />
|
||||
<div className={styles.spacer} />
|
||||
<EditTagMenu tagId={tag.id} onTagDelete={onTagDelete}>
|
||||
<IconButton
|
||||
className={styles.tagEditIcon}
|
||||
type="plain"
|
||||
icon={<MoreHorizontalIcon />}
|
||||
/>
|
||||
<IconButton className={styles.tagEditIcon}>
|
||||
<MoreHorizontalIcon />
|
||||
</IconButton>
|
||||
</EditTagMenu>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -112,7 +112,7 @@ export const CloudQuotaModal = () => {
|
||||
isFreePlanOwner ? t['com.affine.payment.upgrade']() : t['Got it']()
|
||||
}
|
||||
confirmButtonOptions={{
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -37,7 +37,7 @@ export const LocalQuotaModal = () => {
|
||||
onConfirm={onConfirm}
|
||||
confirmText={t['Got it']()}
|
||||
confirmButtonOptions={{
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -132,7 +132,7 @@ export const AIUsagePanel = () => {
|
||||
</div>
|
||||
|
||||
{hasPaymentFeature && (
|
||||
<AISubscribe type="primary" className={styles.storageButton}>
|
||||
<AISubscribe variant="primary">
|
||||
{t['com.affine.payment.ai.usage.purchase-button-label']()}
|
||||
</AISubscribe>
|
||||
)}
|
||||
|
||||
@@ -142,7 +142,6 @@ export const AvatarAndName = () => {
|
||||
<Button
|
||||
data-testid="save-user-name"
|
||||
onClick={handleUpdateUserName}
|
||||
className={styles.button}
|
||||
style={{
|
||||
marginLeft: '12px',
|
||||
}}
|
||||
@@ -234,7 +233,7 @@ export const AccountSetting: FC = () => {
|
||||
/>
|
||||
<AvatarAndName />
|
||||
<SettingRow name={t['com.affine.settings.email']()} desc={account.email}>
|
||||
<Button onClick={onChangeEmail} className={styles.button}>
|
||||
<Button onClick={onChangeEmail}>
|
||||
{account.info?.emailVerified
|
||||
? t['com.affine.settings.email.action.change']()
|
||||
: t['com.affine.settings.email.action.verify']()}
|
||||
@@ -244,7 +243,7 @@ export const AccountSetting: FC = () => {
|
||||
name={t['com.affine.settings.password']()}
|
||||
desc={t['com.affine.settings.password.message']()}
|
||||
>
|
||||
<Button onClick={onPasswordButtonClick} className={styles.button}>
|
||||
<Button onClick={onPasswordButtonClick}>
|
||||
{account.info?.hasPassword
|
||||
? t['com.affine.settings.password.action.change']()
|
||||
: t['com.affine.settings.password.action.set']()}
|
||||
|
||||
@@ -28,6 +28,3 @@ globalStyle(`${storageProgressWrapper} .storage-progress-bar-wrapper`, {
|
||||
export const storageProgressBar = style({
|
||||
height: '100%',
|
||||
});
|
||||
export const storageButton = style({
|
||||
padding: '4px 12px',
|
||||
});
|
||||
|
||||
@@ -18,7 +18,7 @@ export interface StorageProgressProgress {
|
||||
|
||||
enum ButtonType {
|
||||
Primary = 'primary',
|
||||
Default = 'default',
|
||||
Default = 'secondary',
|
||||
}
|
||||
|
||||
export const StorageProgress = ({ onUpgrade }: StorageProgressProgress) => {
|
||||
@@ -101,11 +101,7 @@ export const StorageProgress = ({ onUpgrade }: StorageProgressProgress) => {
|
||||
}
|
||||
>
|
||||
<span tabIndex={0}>
|
||||
<Button
|
||||
type={buttonType}
|
||||
onClick={onUpgrade}
|
||||
className={styles.storageButton}
|
||||
>
|
||||
<Button variant={buttonType} onClick={onUpgrade}>
|
||||
{isFreeUser
|
||||
? t['com.affine.storage.upgrade']()
|
||||
: t['com.affine.storage.change-plan']()}
|
||||
|
||||
@@ -39,6 +39,3 @@ globalStyle(`${avatarWrapper} .camera-icon-wrapper`, {
|
||||
color: cssVar('white'),
|
||||
fontSize: cssVar('fontH4'),
|
||||
});
|
||||
export const button = style({
|
||||
padding: '4px 12px',
|
||||
});
|
||||
|
||||
@@ -299,9 +299,7 @@ const TypeFormLink = () => {
|
||||
desc={t['com.affine.payment.billing-type-form.description']()}
|
||||
>
|
||||
<a target="_blank" href={link} rel="noreferrer">
|
||||
<Button style={{ padding: '4px 12px' }}>
|
||||
{t['com.affine.payment.billing-type-form.go']()}
|
||||
</Button>
|
||||
<Button>{t['com.affine.payment.billing-type-form.go']()}</Button>
|
||||
</a>
|
||||
</SettingRow>
|
||||
);
|
||||
@@ -435,7 +433,7 @@ const PlanAction = ({
|
||||
return (
|
||||
<Button
|
||||
className={styles.planAction}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
onClick={gotoPlansSetting}
|
||||
>
|
||||
{plan === SubscriptionPlan.Pro
|
||||
@@ -460,12 +458,7 @@ const PaymentMethodUpdater = () => {
|
||||
}, [trigger]);
|
||||
|
||||
return (
|
||||
<Button
|
||||
className={styles.button}
|
||||
onClick={update}
|
||||
loading={isMutating}
|
||||
disabled={isMutating}
|
||||
>
|
||||
<Button onClick={update} loading={isMutating} disabled={isMutating}>
|
||||
{t['com.affine.payment.billing-setting.update']()}
|
||||
</Button>
|
||||
);
|
||||
@@ -492,7 +485,7 @@ const ResumeSubscription = () => {
|
||||
|
||||
return (
|
||||
<ResumeAction open={open} onOpenChange={setOpen}>
|
||||
<Button className={styles.button} onClick={handleClick}>
|
||||
<Button onClick={handleClick}>
|
||||
{t['com.affine.payment.billing-setting.resume-subscription']()}
|
||||
</Button>
|
||||
</ResumeAction>
|
||||
@@ -503,10 +496,11 @@ const CancelSubscription = ({ loading }: { loading?: boolean }) => {
|
||||
return (
|
||||
<IconButton
|
||||
style={{ pointerEvents: 'none' }}
|
||||
icon={<ArrowRightSmallIcon />}
|
||||
disabled={loading}
|
||||
loading={loading}
|
||||
/>
|
||||
>
|
||||
<ArrowRightSmallIcon />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -583,7 +577,7 @@ const InvoiceLine = ({
|
||||
: ''
|
||||
} $${invoice.amount / 100} - ${planText}`}
|
||||
>
|
||||
<Button className={styles.button} onClick={open}>
|
||||
<Button onClick={open}>
|
||||
{t['com.affine.payment.billing-setting.view-invoice']()}
|
||||
</Button>
|
||||
</SettingRow>
|
||||
|
||||
@@ -46,9 +46,6 @@ export const currentPlanName = style({
|
||||
color: cssVar('textEmphasisColor'),
|
||||
cursor: 'pointer',
|
||||
});
|
||||
export const button = style({
|
||||
padding: '4px 12px',
|
||||
});
|
||||
export const subscriptionSettingSkeleton = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
@@ -63,7 +63,7 @@ const ExperimentalFeaturesPrompt = ({
|
||||
<Button
|
||||
disabled={!checked}
|
||||
onClick={onConfirm}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
data-testid="experimental-confirm-button"
|
||||
>
|
||||
{t[
|
||||
|
||||
@@ -43,12 +43,12 @@ export const AICancel = ({ module, ...btnProps }: AICancelProps) => {
|
||||
confirmText:
|
||||
t['com.affine.payment.ai.action.cancel.confirm.confirm-text'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'default',
|
||||
variant: 'secondary',
|
||||
},
|
||||
cancelText:
|
||||
t['com.affine.payment.ai.action.cancel.confirm.cancel-text'](),
|
||||
cancelButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
},
|
||||
onConfirm: async () => {
|
||||
try {
|
||||
@@ -92,7 +92,12 @@ export const AICancel = ({ module, ...btnProps }: AICancelProps) => {
|
||||
]);
|
||||
|
||||
return (
|
||||
<Button onClick={cancel} loading={isMutating} type="primary" {...btnProps}>
|
||||
<Button
|
||||
onClick={cancel}
|
||||
loading={isMutating}
|
||||
variant="primary"
|
||||
{...btnProps}
|
||||
>
|
||||
{t['com.affine.payment.ai.action.cancel.button-label']()}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@ export const AILogin = (btnProps: ButtonProps) => {
|
||||
}, [setOpen]);
|
||||
|
||||
return (
|
||||
<Button onClick={onClickSignIn} type="primary" {...btnProps}>
|
||||
<Button onClick={onClickSignIn} variant="primary" {...btnProps}>
|
||||
{t['com.affine.payment.ai.action.login.button-label']()}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -48,7 +48,7 @@ export const AIResume = ({ module, ...btnProps }: AIResumeProps) => {
|
||||
confirmText:
|
||||
t['com.affine.payment.ai.action.resume.confirm.confirm-text'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
},
|
||||
cancelText:
|
||||
t['com.affine.payment.ai.action.resume.confirm.cancel-text'](),
|
||||
@@ -79,7 +79,12 @@ export const AIResume = ({ module, ...btnProps }: AIResumeProps) => {
|
||||
}, [subscription, openConfirmModal, t, module, idempotencyKey]);
|
||||
|
||||
return (
|
||||
<Button loading={isMutating} onClick={resume} type="primary" {...btnProps}>
|
||||
<Button
|
||||
loading={isMutating}
|
||||
onClick={resume}
|
||||
variant="primary"
|
||||
{...btnProps}
|
||||
>
|
||||
{t['com.affine.payment.ai.action.resume.button-label']()}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -102,7 +102,7 @@ export const AISubscribe = ({
|
||||
<Button
|
||||
loading={isMutating}
|
||||
onClick={subscribe}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
{...btnProps}
|
||||
>
|
||||
{btnProps.children ?? `${priceReadable} / ${priceFrequency}`}
|
||||
|
||||
@@ -46,6 +46,7 @@ export const allPlansLink = style({
|
||||
|
||||
export const collapsibleHeader = style({
|
||||
display: 'flex',
|
||||
alignItems: 'start',
|
||||
marginBottom: 8,
|
||||
});
|
||||
export const collapsibleHeaderContent = style({
|
||||
|
||||
@@ -58,7 +58,7 @@ export const PricingCollapsible = ({
|
||||
<div className={styles.collapsibleHeaderTitle}>{title}</div>
|
||||
<div className={styles.collapsibleHeaderCaption}>{caption}</div>
|
||||
</div>
|
||||
<IconButton onClick={toggle}>
|
||||
<IconButton onClick={toggle} size="20">
|
||||
<ArrowUpSmallIcon
|
||||
style={{
|
||||
transform: open ? 'rotate(0deg)' : 'rotate(180deg)',
|
||||
@@ -163,7 +163,7 @@ export const PlanLayout = ({ cloud, ai, cloudTip }: PlanLayoutProps) => {
|
||||
</div>
|
||||
<Button
|
||||
onClick={() => scrollToAnchor('cloudPricingPlan')}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
>
|
||||
{t['com.affine.ai-scroll-tip.view']()}
|
||||
</Button>
|
||||
|
||||
@@ -48,7 +48,7 @@ export const ConfirmLoadingModal = ({
|
||||
cancelText={cancelText}
|
||||
confirmText={confirmText}
|
||||
confirmButtonOptions={{
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
loading,
|
||||
}}
|
||||
open={open}
|
||||
@@ -120,7 +120,7 @@ export const DowngradeModal = ({
|
||||
<Button
|
||||
disabled={loading}
|
||||
onClick={() => onOpenChange?.(false)}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
>
|
||||
{t['com.affine.payment.modal.downgrade.confirm']()}
|
||||
</Button>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button } from '@affine/component/ui/button';
|
||||
import { Button, type ButtonProps } from '@affine/component/ui/button';
|
||||
import { Tooltip } from '@affine/component/ui/tooltip';
|
||||
import { generateSubscriptionCallbackLink } from '@affine/core/hooks/affine/use-subscription-notify';
|
||||
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
|
||||
@@ -10,10 +10,11 @@ import { SubscriptionPlan, SubscriptionStatus } from '@affine/graphql';
|
||||
import { Trans, useI18n } from '@affine/i18n';
|
||||
import { DoneIcon } from '@blocksuite/icons/rc';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
import { assignInlineVars } from '@vanilla-extract/dynamic';
|
||||
import clsx from 'clsx';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { nanoid } from 'nanoid';
|
||||
import type { HTMLAttributes, PropsWithChildren } from 'react';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { authAtom } from '../../../../../atoms/index';
|
||||
@@ -194,7 +195,7 @@ const Downgrade = ({ disabled }: { disabled?: boolean }) => {
|
||||
<div className={styles.planAction}>
|
||||
<Button
|
||||
className={styles.planAction}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
onClick={handleClick}
|
||||
disabled={disabled}
|
||||
>
|
||||
@@ -232,7 +233,7 @@ const BookDemo = ({ plan }: { plan: SubscriptionPlan }) => {
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Button className={styles.planAction} type="primary">
|
||||
<Button className={styles.planAction} variant="primary">
|
||||
{t['com.affine.payment.tell-us-use-case']()}
|
||||
</Button>
|
||||
</a>
|
||||
@@ -243,8 +244,8 @@ export const Upgrade = ({
|
||||
className,
|
||||
recurring,
|
||||
children,
|
||||
...attrs
|
||||
}: HTMLAttributes<HTMLButtonElement> & {
|
||||
...btnProps
|
||||
}: ButtonProps & {
|
||||
recurring: SubscriptionRecurring;
|
||||
}) => {
|
||||
const [isMutating, setMutating] = useState(false);
|
||||
@@ -307,11 +308,11 @@ export const Upgrade = ({
|
||||
return (
|
||||
<Button
|
||||
className={clsx(styles.planAction, className)}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
onClick={upgrade}
|
||||
disabled={isMutating}
|
||||
loading={isMutating}
|
||||
{...attrs}
|
||||
{...btnProps}
|
||||
>
|
||||
{children ?? t['com.affine.payment.upgrade']()}
|
||||
</Button>
|
||||
@@ -371,7 +372,7 @@ const ChangeRecurring = ({
|
||||
<>
|
||||
<Button
|
||||
className={styles.planAction}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
onClick={onStartChange}
|
||||
disabled={disabled || isMutating}
|
||||
loading={isMutating}
|
||||
@@ -405,7 +406,7 @@ const SignUpAction = ({ children }: PropsWithChildren) => {
|
||||
<Button
|
||||
onClick={onClickSignIn}
|
||||
className={styles.planAction}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
@@ -415,7 +416,6 @@ const SignUpAction = ({ children }: PropsWithChildren) => {
|
||||
const ResumeButton = () => {
|
||||
const t = useI18n();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [hovered, setHovered] = useState(false);
|
||||
const subscription = useService(SubscriptionService).subscription;
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
@@ -435,14 +435,14 @@ const ResumeButton = () => {
|
||||
return (
|
||||
<ResumeAction open={open} onOpenChange={setOpen}>
|
||||
<Button
|
||||
className={styles.planAction}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
className={styles.resumeAction}
|
||||
onClick={handleClick}
|
||||
style={assignInlineVars({
|
||||
'--default-content': t['com.affine.payment.current-plan'](),
|
||||
'--hover-content': t['com.affine.payment.resume-renewal'](),
|
||||
})}
|
||||
>
|
||||
{hovered
|
||||
? t['com.affine.payment.resume-renewal']()
|
||||
: t['com.affine.payment.current-plan']()}
|
||||
<span className={styles.resumeActionContent} />
|
||||
</Button>
|
||||
</ResumeAction>
|
||||
);
|
||||
|
||||
@@ -177,7 +177,17 @@ export const planPriceDesc = style({
|
||||
});
|
||||
export const planAction = style({
|
||||
width: '100%',
|
||||
fontWeight: 500,
|
||||
});
|
||||
export const resumeAction = style([planAction, {}]);
|
||||
export const resumeActionContent = style({
|
||||
':after': {
|
||||
content: 'var(--default-content)',
|
||||
},
|
||||
selectors: {
|
||||
[`${resumeAction}:hover &:after`]: {
|
||||
content: 'var(--hover-content)',
|
||||
},
|
||||
},
|
||||
});
|
||||
export const planBenefits = style({
|
||||
fontSize: cssVar('fontXs'),
|
||||
|
||||
@@ -38,7 +38,7 @@ export const WorkspaceDeleteModal = ({
|
||||
cancelText={t['com.affine.workspaceDelete.button.cancel']()}
|
||||
confirmText={t['com.affine.workspaceDelete.button.delete']()}
|
||||
confirmButtonOptions={{
|
||||
type: 'error',
|
||||
variant: 'error',
|
||||
disabled: !allowDelete,
|
||||
['data-testid' as string]: 'delete-workspace-confirm-button',
|
||||
}}
|
||||
|
||||
@@ -136,7 +136,7 @@ export const DeleteLeaveWorkspace = () => {
|
||||
description={t['com.affine.deleteLeaveWorkspace.leaveDescription']()}
|
||||
confirmText={t['Leave']()}
|
||||
confirmButtonOptions={{
|
||||
type: 'warning',
|
||||
variant: 'error',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -56,7 +56,7 @@ export const EnableCloudPanel = () => {
|
||||
>
|
||||
<Button
|
||||
data-testid="publish-enable-affine-cloud-button"
|
||||
type="primary"
|
||||
variant="primary"
|
||||
onClick={confirmEnableCloudAndClose}
|
||||
style={{ marginTop: '12px' }}
|
||||
>
|
||||
|
||||
@@ -63,7 +63,7 @@ const MembersPanelLocal = () => {
|
||||
<Tooltip content={t['com.affine.settings.member-tooltip']()}>
|
||||
<div className={style.fakeWrapper}>
|
||||
<SettingRow name={`${t['Members']()} (0)`} desc={t['Members hint']()}>
|
||||
<Button size="large">{t['Invite Members']()}</Button>
|
||||
<Button>{t['Invite Members']()}</Button>
|
||||
</SettingRow>
|
||||
</div>
|
||||
</Tooltip>
|
||||
@@ -393,7 +393,6 @@ const MemberItem = ({
|
||||
>
|
||||
<IconButton
|
||||
disabled={!operationButtonInfo.show}
|
||||
type="plain"
|
||||
style={{
|
||||
visibility: operationButtonInfo.show ? 'visible' : 'hidden',
|
||||
flexShrink: 0,
|
||||
|
||||
@@ -173,11 +173,9 @@ const EditPropertyButton = ({
|
||||
}}
|
||||
items={editing ? editMenuItems : defaultMenuItems}
|
||||
>
|
||||
<IconButton
|
||||
onClick={() => setOpen(true)}
|
||||
type="plain"
|
||||
icon={<MoreHorizontalIcon />}
|
||||
/>
|
||||
<IconButton onClick={() => setOpen(true)} size="20">
|
||||
<MoreHorizontalIcon />
|
||||
</IconButton>
|
||||
</Menu>
|
||||
<ConfirmDeletePropertyModal
|
||||
onConfirm={() => {
|
||||
@@ -350,7 +348,7 @@ const WorkspaceSettingPropertiesMain = () => {
|
||||
<div className={styles.listHeader}>
|
||||
{properties.length > 0 ? (
|
||||
<Menu items={filterMenuItems}>
|
||||
<Button type="default" icon={<FilterIcon />}>
|
||||
<Button prefix={<FilterIcon />}>
|
||||
{filterMode === 'all'
|
||||
? t['com.affine.filter']()
|
||||
: t[`com.affine.settings.workspace.properties.${filterMode}`]()}
|
||||
@@ -365,7 +363,7 @@ const WorkspaceSettingPropertiesMain = () => {
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Button type="primary">
|
||||
<Button variant="primary">
|
||||
{t['com.affine.settings.workspace.properties.add_property']()}
|
||||
</Button>
|
||||
</Menu>
|
||||
|
||||
@@ -55,7 +55,7 @@ const DefaultShareButton = forwardRef(function DefaultShareButton(
|
||||
}, [shareService]);
|
||||
|
||||
return (
|
||||
<Button ref={ref} className={styles.shareButton} type="primary">
|
||||
<Button ref={ref} className={styles.shareButton} variant="primary">
|
||||
{shared
|
||||
? t['com.affine.share-menu.sharedButton']()
|
||||
: t['com.affine.share-menu.shareButton']()}
|
||||
|
||||
@@ -40,7 +40,7 @@ export const LocalSharePage = (props: ShareMenuProps) => {
|
||||
<div>
|
||||
<Button
|
||||
onClick={props.onEnableAffineCloud}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
data-testid="share-menu-enable-affine-cloud-button"
|
||||
>
|
||||
{t['Enable AFFiNE Cloud']()}
|
||||
@@ -256,7 +256,7 @@ export const AffineSharePage = (props: ShareMenuProps) => {
|
||||
) : (
|
||||
<Button
|
||||
onClick={onClickCreateLink}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
data-testid="share-menu-create-link-button"
|
||||
style={{ padding: '4px 12px', whiteSpace: 'nowrap' }}
|
||||
>
|
||||
|
||||
@@ -32,7 +32,7 @@ export const SignOutModal = ({ ...props }: ConfirmModalProps) => {
|
||||
cancelText={cancelText ?? defaultTexts.cancelText}
|
||||
confirmText={confirmText ?? defaultTexts.children}
|
||||
confirmButtonOptions={{
|
||||
type: 'error',
|
||||
variant: 'error',
|
||||
['data-testid' as string]: 'confirm-sign-out-button',
|
||||
}}
|
||||
contentOptions={{
|
||||
|
||||
@@ -26,7 +26,7 @@ export const StarAFFiNEModal = () => {
|
||||
cancelText={t['com.affine.star-affine.cancel']()}
|
||||
to={runtimeConfig.githubUrl}
|
||||
confirmButtonOptions={{
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
}}
|
||||
confirmText={t['com.affine.star-affine.confirm']()}
|
||||
external
|
||||
|
||||
@@ -48,7 +48,7 @@ const UpgradeSuccessLayout = ({
|
||||
|
||||
return (
|
||||
<AuthPageContainer title={title} subtitle={subtitle}>
|
||||
<Button type="primary" size="extraLarge" onClick={openAffine}>
|
||||
<Button variant="primary" size="extraLarge" onClick={openAffine}>
|
||||
{t['com.affine.other-page.nav.open-affine']()}
|
||||
</Button>
|
||||
</AuthPageContainer>
|
||||
|
||||
@@ -32,7 +32,7 @@ const SubscriptionChangedNotifyFooter = ({
|
||||
className={clsx(actionButton, cancelButton)}
|
||||
size={'default'}
|
||||
onClick={onCancel}
|
||||
type="plain"
|
||||
variant="plain"
|
||||
>
|
||||
{cancelText}
|
||||
</Button>
|
||||
@@ -40,7 +40,7 @@ const SubscriptionChangedNotifyFooter = ({
|
||||
<Button
|
||||
onClick={onConfirm}
|
||||
className={clsx(actionButton, confirmButton)}
|
||||
type="plain"
|
||||
variant="plain"
|
||||
>
|
||||
{okText}
|
||||
</Button>
|
||||
|
||||
@@ -6,11 +6,7 @@ export const root = style({
|
||||
height: 32,
|
||||
borderRadius: 8,
|
||||
boxShadow: '0px 1px 2px 0px rgba(0, 0, 0, 0.15)',
|
||||
border: `1px solid ${cssVarV2('layer/border')}`,
|
||||
borderWidth: 1,
|
||||
borderColor: cssVarV2('layer/border'),
|
||||
background: cssVarV2('button/siderbarPrimary/background'),
|
||||
});
|
||||
export const icon = style({
|
||||
color: cssVarV2('icon/primary'),
|
||||
fontSize: 20,
|
||||
display: 'block',
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Tooltip } from '@affine/component';
|
||||
import { IconButton } from '@affine/component';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { PlusIcon } from '@blocksuite/icons/rc';
|
||||
import clsx from 'clsx';
|
||||
@@ -12,6 +12,7 @@ interface AddPageButtonProps {
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
const sideBottom = { side: 'bottom' as const };
|
||||
export function AddPageButton({
|
||||
onClick,
|
||||
className,
|
||||
@@ -20,15 +21,15 @@ export function AddPageButton({
|
||||
const t = useI18n();
|
||||
|
||||
return (
|
||||
<Tooltip content={t['New Page']()} side="bottom">
|
||||
<Button
|
||||
data-testid="sidebar-new-page-button"
|
||||
style={style}
|
||||
className={clsx([styles.root, className])}
|
||||
onClick={onClick}
|
||||
>
|
||||
<PlusIcon className={styles.icon} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<IconButton
|
||||
tooltip={t['New Page']()}
|
||||
tooltipOptions={sideBottom}
|
||||
data-testid="sidebar-new-page-button"
|
||||
style={style}
|
||||
className={clsx([styles.root, className])}
|
||||
onClick={onClick}
|
||||
>
|
||||
<PlusIcon />
|
||||
</IconButton>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,25 +34,20 @@ export const label = style({
|
||||
lineHeight: '20px',
|
||||
flexGrow: '0',
|
||||
display: 'flex',
|
||||
gap: 2,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'start',
|
||||
cursor: 'pointer',
|
||||
});
|
||||
|
||||
export const collapseButton = style({
|
||||
selectors: {
|
||||
[`${label} > &`]: {
|
||||
color: cssVarV2('icon/tertiary'),
|
||||
transform: 'translateY(1px)',
|
||||
},
|
||||
},
|
||||
});
|
||||
export const collapseIcon = style({
|
||||
transform: 'rotate(90deg)',
|
||||
vars: { '--y': '1px', '--r': '90deg' },
|
||||
color: cssVarV2('icon/tertiary'),
|
||||
transform: 'translateY(var(--y)) rotate(var(--r))',
|
||||
transition: 'transform 0.2s',
|
||||
selectors: {
|
||||
[`${root}[data-collapsed="true"] &`]: {
|
||||
transform: 'rotate(0deg)',
|
||||
vars: { '--r': '0deg' },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { IconButton } from '@affine/component';
|
||||
import { ToggleCollapseIcon } from '@blocksuite/icons/rc';
|
||||
import clsx from 'clsx';
|
||||
import { type ForwardedRef, forwardRef, type PropsWithChildren } from 'react';
|
||||
@@ -42,14 +41,12 @@ export const CategoryDivider = forwardRef(
|
||||
<div className={styles.label}>
|
||||
{label}
|
||||
{collapsible ? (
|
||||
<IconButton
|
||||
withoutHoverStyle
|
||||
className={styles.collapseButton}
|
||||
size="small"
|
||||
<ToggleCollapseIcon
|
||||
width={16}
|
||||
height={16}
|
||||
data-testid="category-divider-collapse-button"
|
||||
>
|
||||
<ToggleCollapseIcon className={styles.collapseIcon} />
|
||||
</IconButton>
|
||||
className={styles.collapseIcon}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
<div className={styles.actions} onClick={e => e.stopPropagation()}>
|
||||
|
||||
@@ -1,23 +1,18 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const sidebarSwitch = style({
|
||||
opacity: 0,
|
||||
display: 'inline-flex',
|
||||
export const sidebarSwitchClip = style({
|
||||
flexShrink: 0,
|
||||
overflow: 'hidden',
|
||||
pointerEvents: 'none',
|
||||
transition: 'max-width 0.2s ease-in-out, margin 0.3s ease-in-out',
|
||||
transition:
|
||||
'max-width 0.2s ease-in-out, margin 0.3s ease-in-out, opacity 0.3s ease',
|
||||
selectors: {
|
||||
'&[data-show=true]': {
|
||||
maxWidth: '32px',
|
||||
opacity: 1,
|
||||
width: '32px',
|
||||
flexShrink: 0,
|
||||
fontSize: '24px',
|
||||
pointerEvents: 'auto',
|
||||
maxWidth: '60px',
|
||||
},
|
||||
'&[data-show=false]': {
|
||||
opacity: 0,
|
||||
maxWidth: 0,
|
||||
margin: '0 !important',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { IconButton, Tooltip } from '@affine/component';
|
||||
import { IconButton } from '@affine/component';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { SidebarIcon } from '@blocksuite/icons/rc';
|
||||
import clsx from 'clsx';
|
||||
import { useAtom } from 'jotai';
|
||||
|
||||
import { appSidebarOpenAtom } from '../index.jotai';
|
||||
@@ -19,19 +18,21 @@ export const SidebarSwitch = ({
|
||||
const tooltipContent = open
|
||||
? t['com.affine.sidebarSwitch.collapse']()
|
||||
: t['com.affine.sidebarSwitch.expand']();
|
||||
// TODO(@CatsJuice): Tooltip shortcut style
|
||||
const collapseKeyboardShortcuts =
|
||||
environment.isBrowser && environment.isMacOs ? ' ⌘+/' : ' Ctrl+/';
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={tooltipContent + ' ' + collapseKeyboardShortcuts}
|
||||
side={open ? 'bottom' : 'right'}
|
||||
<div
|
||||
data-show={show}
|
||||
className={styles.sidebarSwitchClip}
|
||||
data-testid={`app-sidebar-arrow-button-${open ? 'collapse' : 'expand'}`}
|
||||
>
|
||||
<IconButton
|
||||
className={clsx(styles.sidebarSwitch, className)}
|
||||
data-show={show}
|
||||
size="large"
|
||||
data-testid={`app-sidebar-arrow-button-${open ? 'collapse' : 'expand'}`}
|
||||
tooltip={tooltipContent + ' ' + collapseKeyboardShortcuts}
|
||||
tooltipOptions={{ side: open ? 'bottom' : 'right' }}
|
||||
className={className}
|
||||
size="24"
|
||||
style={{
|
||||
zIndex: 1,
|
||||
}}
|
||||
@@ -39,6 +40,6 @@ export const SidebarSwitch = ({
|
||||
>
|
||||
<SidebarIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -134,7 +134,7 @@ export function patchNotificationService(
|
||||
description: toReactNode(message),
|
||||
confirmText,
|
||||
confirmButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
},
|
||||
cancelText,
|
||||
onConfirm: () => {
|
||||
@@ -177,7 +177,7 @@ export function patchNotificationService(
|
||||
description: description,
|
||||
confirmText: confirmText ?? 'Confirm',
|
||||
confirmButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
},
|
||||
cancelText: cancelText ?? 'Cancel',
|
||||
onConfirm: () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IconButton, Tooltip } from '@affine/component';
|
||||
import { IconButton } from '@affine/component';
|
||||
import { openInfoModalAtom } from '@affine/core/atoms';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { InformationIcon } from '@blocksuite/icons/rc';
|
||||
@@ -11,12 +11,13 @@ export const InfoButton = () => {
|
||||
setOpenInfoModal(true);
|
||||
};
|
||||
return (
|
||||
<Tooltip content={t['com.affine.page-properties.page-info.view']()}>
|
||||
<IconButton
|
||||
data-testid="header-info-button"
|
||||
onClick={onOpenInfoModal}
|
||||
icon={<InformationIcon />}
|
||||
/>
|
||||
</Tooltip>
|
||||
<IconButton
|
||||
size="20"
|
||||
tooltip={t['com.affine.page-properties.page-info.view']()}
|
||||
data-testid="header-info-button"
|
||||
onClick={onOpenInfoModal}
|
||||
>
|
||||
<InformationIcon />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,9 +9,10 @@ export const DetailPageHeaderPresentButton = () => {
|
||||
return (
|
||||
<IconButton
|
||||
style={{ flexShrink: 0 }}
|
||||
size={'large'}
|
||||
icon={<PresentationIcon />}
|
||||
size="24"
|
||||
onClick={() => handlePresent(!isPresent)}
|
||||
></IconButton>
|
||||
>
|
||||
<PresentationIcon />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -11,11 +11,10 @@ export const PresentButton = () => {
|
||||
|
||||
return (
|
||||
<Button
|
||||
icon={<PresentationIcon />}
|
||||
prefix={<PresentationIcon />}
|
||||
className={styles.presentButton}
|
||||
onClick={() => handlePresent()}
|
||||
disabled={isPresent}
|
||||
withoutHoverStyle
|
||||
>
|
||||
{t['com.affine.share-page.header.present']()}
|
||||
</Button>
|
||||
|
||||
@@ -46,7 +46,6 @@ export const headerDivider = style({
|
||||
});
|
||||
|
||||
export const presentButton = style({
|
||||
gap: '4px',
|
||||
background: cssVar('black'),
|
||||
color: cssVar('white'),
|
||||
borderColor: cssVar('pureBlack10'),
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { IconButtonProps } from '@affine/component';
|
||||
import { IconButton, Tooltip } from '@affine/component';
|
||||
import { IconButton } from '@affine/component';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { FavoritedIcon, FavoriteIcon } from '@blocksuite/icons/rc';
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import Lottie from 'lottie-react';
|
||||
import { forwardRef, useCallback, useState } from 'react';
|
||||
|
||||
@@ -25,24 +26,32 @@ export const FavoriteTag = forwardRef<
|
||||
[active, onClick]
|
||||
);
|
||||
return (
|
||||
<Tooltip content={active ? t['Favorited']() : t['Favorite']()} side="top">
|
||||
<IconButton ref={ref} active={active} onClick={handleClick} {...props}>
|
||||
{active ? (
|
||||
playAnimation ? (
|
||||
<Lottie
|
||||
loop={false}
|
||||
animationData={favoritedAnimation}
|
||||
onComplete={() => setPlayAnimation(false)}
|
||||
style={{ width: '20px', height: '20px' }}
|
||||
/>
|
||||
) : (
|
||||
<FavoritedIcon data-testid="favorited-icon" />
|
||||
)
|
||||
<IconButton
|
||||
tooltip={active ? t['Favorited']() : t['Favorite']()}
|
||||
tooltipOptions={{ side: 'top' }}
|
||||
ref={ref}
|
||||
onClick={handleClick}
|
||||
size="20"
|
||||
{...props}
|
||||
>
|
||||
{active ? (
|
||||
playAnimation ? (
|
||||
<Lottie
|
||||
loop={false}
|
||||
animationData={favoritedAnimation}
|
||||
onComplete={() => setPlayAnimation(false)}
|
||||
style={{ width: '20px', height: '20px' }}
|
||||
/>
|
||||
) : (
|
||||
<FavoriteIcon />
|
||||
)}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<FavoritedIcon
|
||||
color={cssVar('primaryColor')}
|
||||
data-testid="favorited-icon"
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<FavoriteIcon />
|
||||
)}
|
||||
</IconButton>
|
||||
);
|
||||
});
|
||||
FavoriteTag.displayName = 'FavoriteTag';
|
||||
|
||||
@@ -5,12 +5,6 @@ export const menu = style({
|
||||
minWidth: '220px',
|
||||
});
|
||||
|
||||
export const arrowDownSmallIcon = style({
|
||||
width: '16px',
|
||||
height: '16px',
|
||||
color: cssVar('iconColor'),
|
||||
});
|
||||
|
||||
export const headerDisplayButton = style({
|
||||
marginLeft: '16px',
|
||||
['WebkitAppRegion' as string]: 'no-drag',
|
||||
|
||||
@@ -167,8 +167,7 @@ export const PageDisplayMenu = () => {
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
iconPosition="end"
|
||||
icon={<ArrowDownSmallIcon className={styles.arrowDownSmallIcon} />}
|
||||
suffix={<ArrowDownSmallIcon />}
|
||||
className={styles.headerDisplayButton}
|
||||
data-testid="page-display-menu-button"
|
||||
>
|
||||
|
||||
@@ -27,14 +27,6 @@ export const titleIcon = style({
|
||||
export const titleCollectionName = style({
|
||||
color: cssVar('textPrimaryColor'),
|
||||
});
|
||||
export const addPageButton = style({
|
||||
padding: '6px 10px',
|
||||
borderRadius: '8px',
|
||||
background: cssVar('backgroundPrimaryColor'),
|
||||
fontSize: cssVar('fontXs'),
|
||||
fontWeight: 500,
|
||||
height: '28px',
|
||||
});
|
||||
export const tagSticky = style({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
|
||||
@@ -125,7 +125,7 @@ export const CollectionPageListHeader = ({
|
||||
cancelText: t['Cancel'](),
|
||||
confirmText: t['Confirm'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
},
|
||||
onConfirm: () => createAndAddDocument(createDocumentFn),
|
||||
});
|
||||
@@ -156,9 +156,7 @@ export const CollectionPageListHeader = ({
|
||||
<div className={styles.titleCollectionName}>{collection.name}</div>
|
||||
</div>
|
||||
<div className={styles.rightButtonGroup}>
|
||||
<Button className={styles.addPageButton} onClick={handleEdit}>
|
||||
{t['Edit']()}
|
||||
</Button>
|
||||
<Button onClick={handleEdit}>{t['Edit']()}</Button>
|
||||
<PageListNewPageButton
|
||||
size="small"
|
||||
testId="new-page-button-trigger"
|
||||
@@ -253,7 +251,7 @@ export const TagPageListHeader = ({
|
||||
</div>
|
||||
</Menu>
|
||||
</div>
|
||||
<Button className={styles.addPageButton} onClick={handleClick}>
|
||||
<Button onClick={handleClick}>
|
||||
{t['com.affine.editCollection.saveCollection']()}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -59,15 +59,11 @@ export const FilterList = ({
|
||||
}
|
||||
>
|
||||
{value.length === 0 ? (
|
||||
<Button
|
||||
icon={<PlusIcon style={{ color: 'var(--affine-icon-color)' }} />}
|
||||
iconPosition="end"
|
||||
style={{ fontSize: 'var(--affine-font-xs)', padding: '0 8px' }}
|
||||
>
|
||||
<Button suffix={<PlusIcon />}>
|
||||
{t['com.affine.filterList.button.add']()}
|
||||
</Button>
|
||||
) : (
|
||||
<IconButton size="small">
|
||||
<IconButton size="16">
|
||||
<PlusIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
@@ -84,12 +84,16 @@ export const editTagWrapper = style({
|
||||
},
|
||||
});
|
||||
|
||||
export const deleteIcon = style({
|
||||
export const deleteButton = style({
|
||||
color: cssVar('iconColor'),
|
||||
':hover': {
|
||||
background: cssVar('backgroundErrorColor'),
|
||||
},
|
||||
});
|
||||
export const deleteIcon = style({
|
||||
selectors: {
|
||||
'&:not(.without-hover):hover': {
|
||||
[`${deleteButton}:hover &`]: {
|
||||
color: cssVar('errorColor'),
|
||||
background: cssVar('backgroundErrorColor'),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
MenuIcon,
|
||||
MenuItem,
|
||||
toast,
|
||||
Tooltip,
|
||||
useConfirmModal,
|
||||
} from '@affine/component';
|
||||
import { useAppSettingHelper } from '@affine/core/hooks/affine/use-app-setting-helper';
|
||||
@@ -53,6 +52,9 @@ import type { TagMeta } from './types';
|
||||
import { ColWrapper, stopPropagationWithoutPrevent } from './utils';
|
||||
import { useEditCollection, useEditCollectionName } from './view';
|
||||
|
||||
const tooltipSideTop = { side: 'top' as const };
|
||||
const tooltipSideTopAlignEnd = { side: 'top' as const, align: 'end' as const };
|
||||
|
||||
export interface PageOperationCellProps {
|
||||
page: DocMeta;
|
||||
isInAllowList?: boolean;
|
||||
@@ -238,7 +240,7 @@ export const PageOperationCell = ({
|
||||
align: 'end',
|
||||
}}
|
||||
>
|
||||
<IconButton type="plain" data-testid="page-list-operation-button">
|
||||
<IconButton data-testid="page-list-operation-button" size="20">
|
||||
<MoreVerticalIcon />
|
||||
</IconButton>
|
||||
</Menu>
|
||||
@@ -278,7 +280,7 @@ export const TrashOperationCell = ({
|
||||
cancelText: t['Cancel'](),
|
||||
confirmText: t['com.affine.trashOperation.delete'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'error',
|
||||
variant: 'error',
|
||||
},
|
||||
onConfirm: onPermanentlyDeletePage,
|
||||
});
|
||||
@@ -286,30 +288,29 @@ export const TrashOperationCell = ({
|
||||
|
||||
return (
|
||||
<ColWrapper flex={1}>
|
||||
<Tooltip content={t['com.affine.trashOperation.restoreIt']()} side="top">
|
||||
<IconButton
|
||||
data-testid="restore-page-button"
|
||||
style={{ marginRight: '12px' }}
|
||||
onClick={() => {
|
||||
onRestorePage();
|
||||
}}
|
||||
>
|
||||
<ResetIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
content={t['com.affine.trashOperation.deletePermanently']()}
|
||||
side="top"
|
||||
align="end"
|
||||
<IconButton
|
||||
tooltip={t['com.affine.trashOperation.restoreIt']()}
|
||||
tooltipOptions={tooltipSideTop}
|
||||
data-testid="restore-page-button"
|
||||
style={{ marginRight: '12px' }}
|
||||
onClick={() => {
|
||||
onRestorePage();
|
||||
}}
|
||||
size="20"
|
||||
>
|
||||
<IconButton
|
||||
data-testid="delete-page-button"
|
||||
onClick={onConfirmPermanentlyDelete}
|
||||
className={styles.deleteIcon}
|
||||
>
|
||||
<DeletePermanentlyIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<ResetIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
tooltip={t['com.affine.trashOperation.deletePermanently']()}
|
||||
tooltipOptions={tooltipSideTopAlignEnd}
|
||||
data-testid="delete-page-button"
|
||||
onClick={onConfirmPermanentlyDelete}
|
||||
className={styles.deleteButton}
|
||||
iconClassName={styles.deleteIcon}
|
||||
size="20"
|
||||
>
|
||||
<DeletePermanentlyIcon />
|
||||
</IconButton>
|
||||
</ColWrapper>
|
||||
);
|
||||
};
|
||||
@@ -393,7 +394,7 @@ export const CollectionOperationCell = ({
|
||||
cancelText: t['Cancel'](),
|
||||
confirmText: t['Confirm'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
},
|
||||
onConfirm: createAndAddDocument,
|
||||
});
|
||||
@@ -411,16 +412,20 @@ export const CollectionOperationCell = ({
|
||||
>
|
||||
<FavoriteTag onClick={onToggleFavoriteCollection} active={favourite} />
|
||||
</ColWrapper>
|
||||
<Tooltip content={t['com.affine.collection.menu.rename']()} side="top">
|
||||
<IconButton onClick={handleEditName}>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip content={t['com.affine.collection.menu.edit']()} side="top">
|
||||
<IconButton onClick={handleEdit}>
|
||||
<FilterIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<IconButton
|
||||
onClick={handleEditName}
|
||||
tooltip={t['com.affine.collection.menu.rename']()}
|
||||
tooltipOptions={tooltipSideTop}
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={handleEdit}
|
||||
tooltip={t['com.affine.collection.menu.edit']()}
|
||||
tooltipOptions={tooltipSideTop}
|
||||
>
|
||||
<FilterIcon />
|
||||
</IconButton>
|
||||
<ColWrapper alignment="start">
|
||||
<Menu
|
||||
items={
|
||||
@@ -470,7 +475,7 @@ export const CollectionOperationCell = ({
|
||||
align: 'end',
|
||||
}}
|
||||
>
|
||||
<IconButton type="plain">
|
||||
<IconButton>
|
||||
<MoreVerticalIcon />
|
||||
</IconButton>
|
||||
</Menu>
|
||||
@@ -521,11 +526,13 @@ export const TagOperationCell = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Tooltip content={t['Rename']()} side="top">
|
||||
<IconButton onClick={() => setOpen(true)}>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<IconButton
|
||||
tooltip={t['Rename']()}
|
||||
tooltipOptions={tooltipSideTop}
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
|
||||
<ColWrapper alignment="start">
|
||||
<Menu
|
||||
@@ -546,7 +553,7 @@ export const TagOperationCell = ({
|
||||
align: 'end',
|
||||
}}
|
||||
>
|
||||
<IconButton type="plain">
|
||||
<IconButton>
|
||||
<MoreVerticalIcon />
|
||||
</IconButton>
|
||||
</Menu>
|
||||
|
||||
@@ -49,7 +49,7 @@ const MoveToTrashConfirm = ({
|
||||
confirmText={t.Delete()}
|
||||
confirmButtonOptions={{
|
||||
['data-testid' as string]: 'confirm-delete-page',
|
||||
type: 'error',
|
||||
variant: 'error',
|
||||
}}
|
||||
{...confirmModalProps}
|
||||
/>
|
||||
|
||||
@@ -61,7 +61,11 @@ export const SelectorLayout = ({
|
||||
<span>{t['com.affine.selectPage.selected']()}</span>
|
||||
<span className={styles.selectedNum}>{selectedCount ?? 0}</span>
|
||||
</div>
|
||||
<Button type="plain" className={styles.clearButton} onClick={onClear}>
|
||||
<Button
|
||||
variant="plain"
|
||||
className={styles.clearButton}
|
||||
onClick={onClear}
|
||||
>
|
||||
{t['com.affine.editCollection.pages.clear']()}
|
||||
</Button>
|
||||
</div>
|
||||
@@ -75,7 +79,7 @@ export const SelectorLayout = ({
|
||||
<Button
|
||||
onClick={onConfirm}
|
||||
className={styles.actionButton}
|
||||
type="primary"
|
||||
variant="primary"
|
||||
>
|
||||
{t['Confirm']()}
|
||||
</Button>
|
||||
|
||||
@@ -158,7 +158,7 @@ export const CreateOrEditTag = ({
|
||||
<Button className={styles.cancelBtn} onClick={onClose}>
|
||||
{t['Cancel']()}
|
||||
</Button>
|
||||
<Button type="primary" onClick={onConfirm} disabled={!tagName}>
|
||||
<Button variant="primary" onClick={onConfirm} disabled={!tagName}>
|
||||
{tagMeta ? t['Save']() : t['Create']()}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -35,9 +35,6 @@ export const viewOption = style({
|
||||
});
|
||||
export const filterMenuTrigger = style({
|
||||
padding: '6px 8px',
|
||||
':hover': {
|
||||
backgroundColor: cssVar('hoverColor'),
|
||||
},
|
||||
selectors: {
|
||||
[`&[data-is-hidden="true"]`]: {
|
||||
display: 'none',
|
||||
|
||||
@@ -30,8 +30,7 @@ export const AllPageListOperationsMenu = ({
|
||||
>
|
||||
<Button
|
||||
className={styles.filterMenuTrigger}
|
||||
type="default"
|
||||
icon={<FilterIcon />}
|
||||
prefix={<FilterIcon />}
|
||||
data-testid="create-first-filter"
|
||||
>
|
||||
{t['com.affine.filter']()}
|
||||
|
||||
@@ -115,7 +115,7 @@ export const CreateCollection = ({
|
||||
<Button
|
||||
size="large"
|
||||
data-testid="save-collection"
|
||||
type="primary"
|
||||
variant="primary"
|
||||
disabled={isNameEmpty}
|
||||
onClick={save}
|
||||
>
|
||||
|
||||
@@ -146,21 +146,13 @@ export const rulesTitleHighlight = style({
|
||||
fontStyle: 'italic',
|
||||
fontWeight: 800,
|
||||
});
|
||||
export const icon = style({
|
||||
color: cssVar('iconColor'),
|
||||
});
|
||||
export const button = style({
|
||||
userSelect: 'none',
|
||||
borderRadius: 4,
|
||||
cursor: 'pointer',
|
||||
':hover': {
|
||||
backgroundColor: cssVar('hoverColor'),
|
||||
},
|
||||
});
|
||||
export const bottomButton = style({
|
||||
padding: '4px 12px',
|
||||
borderRadius: 8,
|
||||
});
|
||||
export const actionButton = style({
|
||||
minWidth: 80,
|
||||
});
|
||||
export const previewActive = style({
|
||||
backgroundColor: cssVar('hoverColorFilled'),
|
||||
});
|
||||
|
||||
@@ -119,13 +119,13 @@ export const EditCollection = ({
|
||||
const buttons = useMemo(
|
||||
() => (
|
||||
<>
|
||||
<Button size="large" onClick={onCancel}>
|
||||
<Button onClick={onCancel} className={styles.actionButton}>
|
||||
{t['com.affine.editCollection.button.cancel']()}
|
||||
</Button>
|
||||
<Button
|
||||
size="large"
|
||||
className={styles.actionButton}
|
||||
data-testid="save-collection"
|
||||
type="primary"
|
||||
variant="primary"
|
||||
disabled={isNameEmpty}
|
||||
onClick={onSaveCollection}
|
||||
>
|
||||
@@ -183,7 +183,7 @@ export const EditCollection = ({
|
||||
reset={reset}
|
||||
updateCollection={onChange}
|
||||
buttons={buttons}
|
||||
></RulesMode>
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Tooltip } from '@affine/component';
|
||||
import { Button, IconButton, Tooltip } from '@affine/component';
|
||||
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
|
||||
import type { Collection } from '@affine/env/filter';
|
||||
import { Trans, useI18n } from '@affine/i18n';
|
||||
@@ -125,14 +125,12 @@ export const RulesMode = ({
|
||||
<div className={styles.rulesContainerLeftContentInclude}>
|
||||
{collection.allowList.length > 0 ? (
|
||||
<div className={styles.includeTitle}>
|
||||
<ToggleCollapseIcon
|
||||
<IconButton
|
||||
onClick={() => setExpandInclude(!expandInclude)}
|
||||
className={styles.button}
|
||||
width={24}
|
||||
height={24}
|
||||
style={{
|
||||
iconStyle={{
|
||||
transform: expandInclude ? 'rotate(90deg)' : undefined,
|
||||
}}
|
||||
icon={<ToggleCollapseIcon />}
|
||||
/>
|
||||
<div style={{ color: cssVar('textSecondaryColor') }}>
|
||||
{t['com.affine.editCollection.rules.include.title']()}
|
||||
@@ -181,8 +179,9 @@ export const RulesMode = ({
|
||||
{page?.title || t['Untitled']()}
|
||||
</div>
|
||||
</div>
|
||||
<CloseIcon
|
||||
className={styles.button}
|
||||
<IconButton
|
||||
size="14"
|
||||
icon={<CloseIcon />}
|
||||
onClick={() => {
|
||||
updateCollection({
|
||||
...collection,
|
||||
@@ -191,7 +190,7 @@ export const RulesMode = ({
|
||||
),
|
||||
});
|
||||
}}
|
||||
></CloseIcon>
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
@@ -240,24 +239,16 @@ export const RulesMode = ({
|
||||
</div>
|
||||
<div className={styles.rulesBottom}>
|
||||
<div className={styles.bottomLeft}>
|
||||
<div
|
||||
className={clsx(
|
||||
styles.button,
|
||||
styles.bottomButton,
|
||||
showPreview && styles.previewActive
|
||||
)}
|
||||
<Button
|
||||
onClick={() => {
|
||||
setShowPreview(!showPreview);
|
||||
}}
|
||||
>
|
||||
{t['com.affine.editCollection.rules.preview']()}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(styles.button, styles.bottomButton)}
|
||||
onClick={reset}
|
||||
>
|
||||
</Button>
|
||||
<Button variant="plain" onClick={reset}>
|
||||
{t['com.affine.editCollection.rules.reset']()}
|
||||
</div>
|
||||
</Button>
|
||||
<div className={styles.previewCountTips}>
|
||||
<Trans
|
||||
i18nKey="com.affine.editCollection.rules.countTips"
|
||||
@@ -273,7 +264,9 @@ export const RulesMode = ({
|
||||
</Trans>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>{buttons}</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 20 }}>
|
||||
{buttons}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Menu, toast } from '@affine/component';
|
||||
import { IconButton, Menu, toast } from '@affine/component';
|
||||
import { useBlockSuiteDocMeta } from '@affine/core/hooks/use-block-suite-page-meta';
|
||||
import { CompatibleFavoriteItemsAdapter } from '@affine/core/modules/properties';
|
||||
import { ShareDocsService } from '@affine/core/modules/share-doc';
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
useServices,
|
||||
WorkspaceService,
|
||||
} from '@toeverything/infra';
|
||||
import clsx from 'clsx';
|
||||
import { type ReactNode, useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { FavoriteTag } from '../../components/favorite-tag';
|
||||
@@ -185,22 +184,10 @@ export const SelectPage = ({
|
||||
/>
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<FilterIcon
|
||||
className={clsx(styles.icon, styles.button)}
|
||||
onClick={clickFilter}
|
||||
width={24}
|
||||
height={24}
|
||||
></FilterIcon>
|
||||
</div>
|
||||
<IconButton icon={<FilterIcon />} onClick={clickFilter} />
|
||||
</Menu>
|
||||
) : (
|
||||
<FilterIcon
|
||||
className={clsx(styles.icon, styles.button)}
|
||||
onClick={clickFilter}
|
||||
width={24}
|
||||
height={24}
|
||||
></FilterIcon>
|
||||
<IconButton icon={<FilterIcon />} onClick={clickFilter} />
|
||||
)}
|
||||
</div>
|
||||
{showFilter ? (
|
||||
|
||||
@@ -35,7 +35,7 @@ export const SaveAsCollectionButton = ({
|
||||
<Button
|
||||
onClick={handleClick}
|
||||
data-testid="save-as-collection"
|
||||
icon={<SaveIcon />}
|
||||
prefix={<SaveIcon />}
|
||||
className={styles.button}
|
||||
>
|
||||
{t['com.affine.editCollection.saveCollection']()}
|
||||
|
||||
@@ -75,7 +75,7 @@ export const VirtualizedTrashList = () => {
|
||||
cancelText: t['Cancel'](),
|
||||
confirmText: t['com.affine.trashOperation.delete'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'error',
|
||||
variant: 'error',
|
||||
},
|
||||
onConfirm: handleMultiDelete,
|
||||
});
|
||||
|
||||
@@ -15,8 +15,6 @@ export const HeaderDropDownButton = forwardRef<
|
||||
{...props}
|
||||
data-testid="header-dropDownButton"
|
||||
className={headerMenuTrigger}
|
||||
withoutHoverStyle={true}
|
||||
type="plain"
|
||||
>
|
||||
<MoreHorizontalIcon />
|
||||
</IconButton>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { cssVar } from '@toeverything/theme';
|
||||
import { style } from '@vanilla-extract/css';
|
||||
export const headerMenuTrigger = style({
|
||||
selectors: {
|
||||
'&[data-state=open], &:hover': {
|
||||
'&[data-state=open]': {
|
||||
backgroundColor: cssVar('hoverColor'),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Button } from '@affine/component/ui/button';
|
||||
import { ConfirmModal } from '@affine/component/ui/modal';
|
||||
import { Tooltip } from '@affine/component/ui/tooltip';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { DeleteIcon, ResetIcon } from '@blocksuite/icons/rc';
|
||||
import { DocService, useService, WorkspaceService } from '@toeverything/infra';
|
||||
@@ -50,30 +49,23 @@ export const TrashPageFooter = () => {
|
||||
>
|
||||
<div className={styles.deleteHintText}>{hintText}</div>
|
||||
<div className={styles.group}>
|
||||
<Tooltip content={t['com.affine.trashOperation.restoreIt']()}>
|
||||
<Button
|
||||
data-testid="page-restore-button"
|
||||
type="primary"
|
||||
onClick={onRestore}
|
||||
className={styles.buttonContainer}
|
||||
>
|
||||
<div className={styles.icon}>
|
||||
<ResetIcon />
|
||||
</div>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip content={t['com.affine.trashOperation.deletePermanently']()}>
|
||||
<Button
|
||||
type="error"
|
||||
onClick={onDelete}
|
||||
style={{ color: 'var(--affine-pure-white)' }}
|
||||
className={styles.buttonContainer}
|
||||
>
|
||||
<div className={styles.icon}>
|
||||
<DeleteIcon />
|
||||
</div>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Button
|
||||
tooltip={t['com.affine.trashOperation.restoreIt']()}
|
||||
data-testid="page-restore-button"
|
||||
variant="primary"
|
||||
onClick={onRestore}
|
||||
className={styles.buttonContainer}
|
||||
prefix={<ResetIcon />}
|
||||
prefixClassName={styles.icon}
|
||||
/>
|
||||
<Button
|
||||
tooltip={t['com.affine.trashOperation.deletePermanently']()}
|
||||
variant="error"
|
||||
onClick={onDelete}
|
||||
className={styles.buttonContainer}
|
||||
prefix={<DeleteIcon />}
|
||||
prefixClassName={styles.icon}
|
||||
/>
|
||||
</div>
|
||||
<ConfirmModal
|
||||
title={t['com.affine.trashOperation.delete.title']()}
|
||||
@@ -81,7 +73,7 @@ export const TrashPageFooter = () => {
|
||||
description={t['com.affine.trashOperation.delete.description']()}
|
||||
confirmText={t['com.affine.trashOperation.delete']()}
|
||||
confirmButtonOptions={{
|
||||
type: 'error',
|
||||
variant: 'error',
|
||||
}}
|
||||
open={open}
|
||||
onConfirm={onConfirmDelete}
|
||||
|
||||
@@ -28,12 +28,10 @@ export const deleteHintText = style({
|
||||
overflow: 'hidden',
|
||||
});
|
||||
export const buttonContainer = style({
|
||||
color: cssVar('pureWhite'),
|
||||
padding: '8px 18px',
|
||||
fontSize: '20px',
|
||||
height: '36px',
|
||||
});
|
||||
export const icon = style({
|
||||
display: 'flex',
|
||||
alignContent: 'center',
|
||||
width: 20,
|
||||
height: 20,
|
||||
});
|
||||
|
||||
@@ -24,18 +24,6 @@ export const workspaceWrapper = style({
|
||||
flex: 1,
|
||||
});
|
||||
|
||||
export const userInfoWrapper = style({
|
||||
flexShrink: 0,
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
padding: '4px 0',
|
||||
});
|
||||
|
||||
// TODO(@catsjuice):
|
||||
globalStyle(`button.${userInfoWrapper} > span`, {
|
||||
lineHeight: 0,
|
||||
});
|
||||
|
||||
export const operationMenu = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
@@ -44,7 +44,7 @@ export const TrashButton = () => {
|
||||
),
|
||||
confirmText: t.Delete(),
|
||||
confirmButtonOptions: {
|
||||
type: 'error',
|
||||
variant: 'error',
|
||||
},
|
||||
onConfirm() {
|
||||
docRecord.moveToTrash();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
Divider,
|
||||
ErrorMessage,
|
||||
IconButton,
|
||||
Menu,
|
||||
MenuIcon,
|
||||
MenuItem,
|
||||
@@ -52,13 +52,9 @@ const menuContentOptions: MenuProps['contentOptions'] = {
|
||||
const AuthorizedUserInfo = ({ account }: { account: AuthAccountInfo }) => {
|
||||
return (
|
||||
<Menu items={<OperationMenu />} contentOptions={menuContentOptions}>
|
||||
<Button
|
||||
data-testid="sidebar-user-avatar"
|
||||
type="plain"
|
||||
className={styles.userInfoWrapper}
|
||||
>
|
||||
<IconButton data-testid="sidebar-user-avatar" variant="plain" size="24">
|
||||
<Avatar size={24} name={account.label} url={account.avatar} />
|
||||
</Button>
|
||||
</IconButton>
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
@@ -71,14 +67,14 @@ const UnauthorizedUserInfo = () => {
|
||||
}, [setOpen]);
|
||||
|
||||
return (
|
||||
<Button
|
||||
<IconButton
|
||||
onClick={openSignInModal}
|
||||
data-testid="sidebar-user-avatar"
|
||||
type="plain"
|
||||
className={styles.userInfoWrapper}
|
||||
variant="plain"
|
||||
size="24"
|
||||
>
|
||||
<UnknownUserIcon width={24} height={24} />
|
||||
</Button>
|
||||
<UnknownUserIcon />
|
||||
</IconButton>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { cssVar } from '@toeverything/theme';
|
||||
import { keyframes, style } from '@vanilla-extract/css';
|
||||
import { style } from '@vanilla-extract/css';
|
||||
export const layout = style({
|
||||
margin: '80px auto',
|
||||
maxWidth: '536px',
|
||||
@@ -19,17 +19,3 @@ export const upgradeTips = style({
|
||||
lineHeight: '20px',
|
||||
textAlign: 'center',
|
||||
});
|
||||
const rotate = keyframes({
|
||||
'0%': {
|
||||
transform: 'rotate(0deg)',
|
||||
},
|
||||
'50%': {
|
||||
transform: 'rotate(180deg)',
|
||||
},
|
||||
'100%': {
|
||||
transform: 'rotate(360deg)',
|
||||
},
|
||||
});
|
||||
export const loadingIcon = style({
|
||||
animation: `${rotate} 1.2s infinite linear`,
|
||||
});
|
||||
|
||||
@@ -54,16 +54,9 @@ export const WorkspaceUpgrade = function WorkspaceUpgrade() {
|
||||
data-testid="upgrade-workspace-button"
|
||||
onClick={onButtonClick}
|
||||
size="extraLarge"
|
||||
icon={
|
||||
error ? (
|
||||
<HeartBreakIcon />
|
||||
) : (
|
||||
<ArrowCircleIcon
|
||||
className={upgrading ? styles.loadingIcon : undefined}
|
||||
/>
|
||||
)
|
||||
}
|
||||
type={error ? 'error' : 'default'}
|
||||
loading={upgrading}
|
||||
prefix={error ? <HeartBreakIcon /> : <ArrowCircleIcon />}
|
||||
variant={error ? 'error' : 'secondary'}
|
||||
>
|
||||
{error
|
||||
? t['com.affine.upgrade.button-text.error']()
|
||||
|
||||
@@ -89,7 +89,7 @@ export const useEnableCloud = () => {
|
||||
? t['Enable']()
|
||||
: t['Sign in and Enable'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
['data-testid' as string]: 'confirm-enable-affine-cloud-button',
|
||||
},
|
||||
onConfirm: async () =>
|
||||
|
||||
@@ -362,11 +362,15 @@ export const AppTabsHeader = ({
|
||||
ref={spacerDropTargetRef}
|
||||
data-dragged-over={draggedOver}
|
||||
>
|
||||
<IconButton onClick={onAddTab} data-testid="add-tab-view-button">
|
||||
<PlusIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
size={22.86}
|
||||
onClick={onAddTab}
|
||||
data-testid="add-tab-view-button"
|
||||
style={{ width: 32, height: 32 }}
|
||||
icon={<PlusIcon />}
|
||||
/>
|
||||
</div>
|
||||
<IconButton size="large" onClick={onToggleRightSidebar}>
|
||||
<IconButton size="24" onClick={onToggleRightSidebar}>
|
||||
<RightSidebarIcon />
|
||||
</IconButton>
|
||||
{environment.isDesktop && environment.isWindows ? (
|
||||
|
||||
@@ -95,7 +95,7 @@ export const useExplorerCollectionNodeOperations = (
|
||||
cancelText: t['Cancel'](),
|
||||
confirmText: t['Confirm'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'primary',
|
||||
variant: 'primary',
|
||||
},
|
||||
onConfirm: createAndAddDocument,
|
||||
});
|
||||
@@ -129,11 +129,7 @@ export const useExplorerCollectionNodeOperations = (
|
||||
index: 0,
|
||||
inline: true,
|
||||
view: (
|
||||
<IconButton
|
||||
size="small"
|
||||
type="plain"
|
||||
onClick={handleAddDocToCollection}
|
||||
>
|
||||
<IconButton size="16" onClick={handleAddDocToCollection}>
|
||||
<PlusIcon />
|
||||
</IconButton>
|
||||
),
|
||||
|
||||
@@ -61,7 +61,7 @@ export const useExplorerDocNodeOperations = (
|
||||
confirmText: t['com.affine.moveToTrash.confirmModal.confirm'](),
|
||||
cancelText: t['com.affine.moveToTrash.confirmModal.cancel'](),
|
||||
confirmButtonOptions: {
|
||||
type: 'error',
|
||||
variant: 'error',
|
||||
},
|
||||
onConfirm() {
|
||||
docRecord.moveToTrash();
|
||||
|
||||
@@ -633,7 +633,7 @@ export const ExplorerFolderNodeFolder = ({
|
||||
index: 0,
|
||||
inline: true,
|
||||
view: (
|
||||
<IconButton size="small" type="plain" onClick={handleNewDoc}>
|
||||
<IconButton size="16" onClick={handleNewDoc}>
|
||||
<PlusIcon />
|
||||
</IconButton>
|
||||
),
|
||||
|
||||
@@ -103,7 +103,7 @@ export const useExplorerTagNodeOperations = (
|
||||
index: 0,
|
||||
inline: true,
|
||||
view: (
|
||||
<IconButton size="small" type="plain" onClick={handleNewDoc}>
|
||||
<IconButton size="16" onClick={handleNewDoc}>
|
||||
<PlusIcon />
|
||||
</IconButton>
|
||||
),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user