feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
.favorite-btn {
|
||||
color: #1D1C23;
|
||||
|
||||
:global(.semi-button-content-right) {
|
||||
margin-left: 4px;
|
||||
color: #1D1C23;
|
||||
}
|
||||
|
||||
&.dark {
|
||||
.un-collected {
|
||||
path {
|
||||
fill: #1D1C23
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, {
|
||||
useRef,
|
||||
useState,
|
||||
forwardRef,
|
||||
useImperativeHandle,
|
||||
type MouseEvent,
|
||||
} from 'react';
|
||||
|
||||
import cls from 'classnames';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
import { Button } from '@coze-arch/coze-design';
|
||||
import { UIButton } from '@coze-arch/bot-semi';
|
||||
|
||||
import { type FavoriteIconBtnRef, FavoriteIconBtn } from '../favorite-icon-btn';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
interface HeaderProps {
|
||||
favoriteCount?: number;
|
||||
productId?: string;
|
||||
entityType?: number;
|
||||
isFavorite?: boolean;
|
||||
svgColor?: 'default' | 'dark';
|
||||
onReportFavorite: (action) => void;
|
||||
disabled?: boolean;
|
||||
isMobile?: boolean;
|
||||
unCollectedIconCls?: string;
|
||||
collectedIconCls?: string;
|
||||
onClickBefore?: (
|
||||
action: 'cancel' | 'add',
|
||||
event?: MouseEvent<HTMLDivElement, globalThis.MouseEvent>,
|
||||
) => boolean | Promise<boolean>;
|
||||
/**兼容UI1.0&2.0 全部替换后去除 */
|
||||
isNewStyle?: boolean;
|
||||
isForbiddenIconClick?: boolean;
|
||||
}
|
||||
|
||||
/* Plugin header */
|
||||
|
||||
export const FavoriteBtn = forwardRef((props: HeaderProps, ref) => {
|
||||
const {
|
||||
favoriteCount,
|
||||
onReportFavorite,
|
||||
productId,
|
||||
entityType,
|
||||
isFavorite,
|
||||
svgColor,
|
||||
disabled,
|
||||
isMobile,
|
||||
isNewStyle,
|
||||
collectedIconCls,
|
||||
unCollectedIconCls,
|
||||
onClickBefore,
|
||||
isForbiddenIconClick,
|
||||
} = props;
|
||||
const refFavoriteBtn = useRef<FavoriteIconBtnRef>(null);
|
||||
const [favoriteNumberAdd, setFavoriteNumberAdd] = useState(0);
|
||||
|
||||
// 该数字不能小于0, 防止出现异常数字
|
||||
const favoriteNum = Math.max(
|
||||
0,
|
||||
(Number(favoriteCount) || 0) + (Number(favoriteNumberAdd) || 0),
|
||||
);
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => ({
|
||||
favorite: (event?: MouseEvent<HTMLDivElement, globalThis.MouseEvent>) =>
|
||||
refFavoriteBtn.current?.favorite(event),
|
||||
}),
|
||||
[],
|
||||
);
|
||||
const favoriteIconButton = (
|
||||
<FavoriteIconBtn
|
||||
ref={refFavoriteBtn}
|
||||
productId={productId}
|
||||
entityType={entityType}
|
||||
isFavorite={isFavorite}
|
||||
onClickBefore={onClickBefore}
|
||||
isVisible={true}
|
||||
onReportTea={onReportFavorite}
|
||||
className={collectedIconCls}
|
||||
unCollectedIconCls={cls(styles['un-collected'], unCollectedIconCls)}
|
||||
isForbiddenClick={isForbiddenIconClick}
|
||||
onChange={value => {
|
||||
setFavoriteNumberAdd(prevNumber =>
|
||||
//该值再 1和 -1 之间。
|
||||
Math.min(Math.max(prevNumber + (Number(value) || 0), -1), 1),
|
||||
);
|
||||
}}
|
||||
isMobile={isMobile}
|
||||
/>
|
||||
);
|
||||
return isMobile ? (
|
||||
<div
|
||||
onClick={event => {
|
||||
if (!isForbiddenIconClick) {
|
||||
refFavoriteBtn.current?.favorite(event);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{favoriteIconButton}
|
||||
</div>
|
||||
) : isNewStyle ? (
|
||||
<Button
|
||||
size="large"
|
||||
color="primary"
|
||||
icon={favoriteIconButton}
|
||||
onClick={event => {
|
||||
refFavoriteBtn.current?.favorite(event);
|
||||
}}
|
||||
disabled={disabled}
|
||||
>
|
||||
{favoriteNum > 0
|
||||
? `${I18n.t('mkpl_num_favorites')}(${favoriteNum})`
|
||||
: I18n.t('mkpl_num_favorites')}
|
||||
</Button>
|
||||
) : (
|
||||
<UIButton
|
||||
theme={'light'}
|
||||
// @ts-expect-error -- linter-disable-autofix
|
||||
className={cls(styles['favorite-btn'], styles[svgColor])}
|
||||
icon={favoriteIconButton}
|
||||
onClick={event => {
|
||||
refFavoriteBtn.current?.favorite(event);
|
||||
}}
|
||||
disabled={disabled}
|
||||
>
|
||||
{favoriteNum > 0 ? favoriteNum : I18n.t('mkpl_favorite')}
|
||||
</UIButton>
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user