mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-14 06:05:51 +08:00
feat: added ActionButton component (#6631)
This commit is contained in:
parent
5af2df0cd5
commit
c112188207
49
web/app/components/base/action-button/index.css
Normal file
49
web/app/components/base/action-button/index.css
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
@tailwind components;
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
.action-btn {
|
||||||
|
@apply inline-flex justify-center items-center cursor-pointer text-text-tertiary
|
||||||
|
hover:text-text-secondary
|
||||||
|
hover:bg-state-base-hover
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn-disabled {
|
||||||
|
@apply cursor-not-allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn-xl {
|
||||||
|
@apply p-2 w-9 h-9 rounded-lg
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn-l {
|
||||||
|
@apply p-1.5 w-[34px] h-[34px] rounded-lg
|
||||||
|
}
|
||||||
|
|
||||||
|
/* m is for the regular button */
|
||||||
|
.action-btn-m {
|
||||||
|
@apply p-0.5 w-6 h-6 rounded-lg
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn-xs {
|
||||||
|
@apply p-0 w-5 h-5 rounded
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.action-btn-active {
|
||||||
|
@apply
|
||||||
|
text-text-accent
|
||||||
|
bg-state-accent-active
|
||||||
|
hover:bg-state-accent-active-alt
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.action-btn-disabled {
|
||||||
|
@apply
|
||||||
|
text-text-disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.action-btn-destructive {
|
||||||
|
@apply
|
||||||
|
text-text-destructive
|
||||||
|
bg-state-destructive-hover
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
70
web/app/components/base/action-button/index.tsx
Normal file
70
web/app/components/base/action-button/index.tsx
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import type { CSSProperties } from 'react'
|
||||||
|
import React from 'react'
|
||||||
|
import { type VariantProps, cva } from 'class-variance-authority'
|
||||||
|
import classNames from '@/utils/classnames'
|
||||||
|
|
||||||
|
enum ActionButtonState {
|
||||||
|
Destructive = 'destructive',
|
||||||
|
Active = 'active',
|
||||||
|
Disabled = 'disabled',
|
||||||
|
Default = '',
|
||||||
|
}
|
||||||
|
|
||||||
|
const actionButtonVariants = cva(
|
||||||
|
'action-btn',
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
size: {
|
||||||
|
xs: 'action-btn-xs',
|
||||||
|
m: 'action-btn-m',
|
||||||
|
l: 'action-btn-l',
|
||||||
|
xl: 'action-btn-xl',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
size: 'm',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
export type ActionButtonProps = {
|
||||||
|
size?: 'xs' | 'm' | 'l' | 'xl'
|
||||||
|
state?: ActionButtonState
|
||||||
|
styleCss?: CSSProperties
|
||||||
|
} & React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof actionButtonVariants>
|
||||||
|
|
||||||
|
function getActionButtonState(state: ActionButtonState) {
|
||||||
|
switch (state) {
|
||||||
|
case ActionButtonState.Destructive:
|
||||||
|
return 'action-btn-destructive'
|
||||||
|
case ActionButtonState.Active:
|
||||||
|
return 'action-btn-active'
|
||||||
|
case ActionButtonState.Disabled:
|
||||||
|
return 'action-btn-disabled'
|
||||||
|
default:
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ActionButton = React.forwardRef<HTMLButtonElement, ActionButtonProps>(
|
||||||
|
({ className, size, state = ActionButtonState.Default, styleCss, children, ...props }, ref) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className={classNames(
|
||||||
|
actionButtonVariants({ className, size }),
|
||||||
|
getActionButtonState(state),
|
||||||
|
)}
|
||||||
|
ref={ref}
|
||||||
|
style={styleCss}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
ActionButton.displayName = 'ActionButton'
|
||||||
|
|
||||||
|
export default ActionButton
|
||||||
|
export { ActionButton, ActionButtonState, actionButtonVariants }
|
@ -13,6 +13,7 @@ export type TooltipProps = {
|
|||||||
hideArrow?: boolean
|
hideArrow?: boolean
|
||||||
popupClassName?: string
|
popupClassName?: string
|
||||||
offset?: OffsetOptions
|
offset?: OffsetOptions
|
||||||
|
asChild?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const arrow = (
|
const arrow = (
|
||||||
@ -27,6 +28,7 @@ const Tooltip: FC<TooltipProps> = ({
|
|||||||
hideArrow,
|
hideArrow,
|
||||||
popupClassName,
|
popupClassName,
|
||||||
offset,
|
offset,
|
||||||
|
asChild,
|
||||||
}) => {
|
}) => {
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const [isHoverPopup, {
|
const [isHoverPopup, {
|
||||||
@ -79,6 +81,7 @@ const Tooltip: FC<TooltipProps> = ({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onMouseLeave={() => triggerMethod === 'hover' && handleLeave(true)}
|
onMouseLeave={() => triggerMethod === 'hover' && handleLeave(true)}
|
||||||
|
asChild={asChild}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</PortalToFollowElemTrigger>
|
</PortalToFollowElemTrigger>
|
||||||
|
@ -45,7 +45,7 @@ export default function AccountAbout({
|
|||||||
IS_CE_EDITION
|
IS_CE_EDITION
|
||||||
? <Link href={'https://github.com/langgenius/dify/blob/main/LICENSE'} target='_blank' rel='noopener noreferrer'>Open Source License</Link>
|
? <Link href={'https://github.com/langgenius/dify/blob/main/LICENSE'} target='_blank' rel='noopener noreferrer'>Open Source License</Link>
|
||||||
: <>
|
: <>
|
||||||
<Link href='https://dify.ai/privacy' target='_blank' rel='noopener noreferrer'>Privacy Policy</Link>,
|
<Link href='https://dify.ai/privacy' target='_blank' rel='noopener noreferrer'>Privacy Policy</Link>,<span> </span>
|
||||||
<Link href='https://dify.ai/terms' target='_blank' rel='noopener noreferrer'>Terms of Service</Link>
|
<Link href='https://dify.ai/terms' target='_blank' rel='noopener noreferrer'>Terms of Service</Link>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import s from '@/app/components/app/configuration/config-prompt/style.module.css
|
|||||||
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
import { useEventEmitterContextContext } from '@/context/event-emitter'
|
||||||
import { PROMPT_EDITOR_INSERT_QUICKLY } from '@/app/components/base/prompt-editor/plugins/update-block'
|
import { PROMPT_EDITOR_INSERT_QUICKLY } from '@/app/components/base/prompt-editor/plugins/update-block'
|
||||||
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
|
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
|
||||||
|
import ActionButton from '@/app/components/base/action-button'
|
||||||
import TooltipPlus from '@/app/components/base/tooltip-plus'
|
import TooltipPlus from '@/app/components/base/tooltip-plus'
|
||||||
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor/editor-support-vars'
|
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor/editor-support-vars'
|
||||||
import Switch from '@/app/components/base/switch'
|
import Switch from '@/app/components/base/switch'
|
||||||
@ -128,7 +129,7 @@ const Editor: FC<Props> = ({
|
|||||||
<Wrap className={cn(className, wrapClassName)} style={wrapStyle} isInNode isExpand={isExpand}>
|
<Wrap className={cn(className, wrapClassName)} style={wrapStyle} isInNode isExpand={isExpand}>
|
||||||
<div ref={ref} className={cn(isFocus ? s.gradientBorder : 'bg-gray-100', isExpand && 'h-full', '!rounded-[9px] p-0.5')}>
|
<div ref={ref} className={cn(isFocus ? s.gradientBorder : 'bg-gray-100', isExpand && 'h-full', '!rounded-[9px] p-0.5')}>
|
||||||
<div className={cn(isFocus ? 'bg-gray-50' : 'bg-gray-100', isExpand && 'h-full flex flex-col', 'rounded-lg')}>
|
<div className={cn(isFocus ? 'bg-gray-50' : 'bg-gray-100', isExpand && 'h-full flex flex-col', 'rounded-lg')}>
|
||||||
<div className={cn(headerClassName, 'pt-1 pl-3 pr-2 flex justify-between h-6 items-center')}>
|
<div className={cn(headerClassName, 'pt-1 pl-3 pr-2 flex justify-between items-center')}>
|
||||||
<div className='leading-4 text-xs font-semibold text-gray-700 uppercase'>{title}</div>
|
<div className='leading-4 text-xs font-semibold text-gray-700 uppercase'>{title}</div>
|
||||||
<div className='flex items-center'>
|
<div className='flex items-center'>
|
||||||
<div className='leading-[18px] text-xs font-medium text-gray-500'>{value?.length || 0}</div>
|
<div className='leading-[18px] text-xs font-medium text-gray-500'>{value?.length || 0}</div>
|
||||||
@ -138,7 +139,7 @@ const Editor: FC<Props> = ({
|
|||||||
|
|
||||||
<div className='w-px h-3 ml-2 mr-2 bg-gray-200'></div>
|
<div className='w-px h-3 ml-2 mr-2 bg-gray-200'></div>
|
||||||
{/* Operations */}
|
{/* Operations */}
|
||||||
<div className='flex items-center space-x-2'>
|
<div className='flex items-center space-x-[2px]'>
|
||||||
{isSupportJinja && (
|
{isSupportJinja && (
|
||||||
<TooltipPlus
|
<TooltipPlus
|
||||||
popupContent={
|
popupContent={
|
||||||
@ -165,19 +166,28 @@ const Editor: FC<Props> = ({
|
|||||||
{!readOnly && (
|
{!readOnly && (
|
||||||
<TooltipPlus
|
<TooltipPlus
|
||||||
popupContent={`${t('workflow.common.insertVarTip')}`}
|
popupContent={`${t('workflow.common.insertVarTip')}`}
|
||||||
|
asChild
|
||||||
>
|
>
|
||||||
<Variable02 className='w-3.5 h-3.5 text-gray-500 cursor-pointer' onClick={handleInsertVariable} />
|
<ActionButton onClick={handleInsertVariable}>
|
||||||
|
<Variable02 className='w-4 h-4' />
|
||||||
|
</ActionButton>
|
||||||
</TooltipPlus>
|
</TooltipPlus>
|
||||||
)}
|
)}
|
||||||
{showRemove && (
|
{showRemove && (
|
||||||
<RiDeleteBinLine className='w-3.5 h-3.5 text-gray-500 cursor-pointer' onClick={onRemove} />
|
<ActionButton onClick={onRemove}>
|
||||||
|
<RiDeleteBinLine className='w-4 h-4' />
|
||||||
|
</ActionButton>
|
||||||
)}
|
)}
|
||||||
{!isCopied
|
{!isCopied
|
||||||
? (
|
? (
|
||||||
<Clipboard className='w-3.5 h-3.5 text-gray-500 cursor-pointer' onClick={handleCopy} />
|
<ActionButton onClick={handleCopy}>
|
||||||
|
<Clipboard className='w-4 h-4' />
|
||||||
|
</ActionButton>
|
||||||
)
|
)
|
||||||
: (
|
: (
|
||||||
<ClipboardCheck className='mx-1 w-3.5 h-3.5 text-gray-500' />
|
<ActionButton>
|
||||||
|
<ClipboardCheck className='w-4 h-4' />
|
||||||
|
</ActionButton>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<ToggleExpandBtn isExpand={isExpand} onExpandChange={setIsExpand} />
|
<ToggleExpandBtn isExpand={isExpand} onExpandChange={setIsExpand} />
|
||||||
|
@ -63,7 +63,7 @@ const TypeSelector: FC<Props> = ({
|
|||||||
<div
|
<div
|
||||||
onClick={toggleShow}
|
onClick={toggleShow}
|
||||||
className={cn(showOption && 'bg-black/5', 'flex items-center h-5 pl-1 pr-0.5 rounded-md text-xs font-semibold text-gray-700 cursor-pointer hover:bg-black/5')}>
|
className={cn(showOption && 'bg-black/5', 'flex items-center h-5 pl-1 pr-0.5 rounded-md text-xs font-semibold text-gray-700 cursor-pointer hover:bg-black/5')}>
|
||||||
<div className={cn(triggerClassName, 'text-sm font-semibold', uppercase && 'uppercase', noValue && 'text-gray-400')}>{!noValue ? item?.label : placeholder}</div>
|
<div className={cn(triggerClassName, 'text-xs font-semibold', uppercase && 'uppercase', noValue && 'text-gray-400')}>{!noValue ? item?.label : placeholder}</div>
|
||||||
{!readonly && <DropDownIcon className='w-3 h-3 ' />}
|
{!readonly && <DropDownIcon className='w-3 h-3 ' />}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
RiCollapseDiagonalLine,
|
RiCollapseDiagonalLine,
|
||||||
RiExpandDiagonalLine,
|
RiExpandDiagonalLine,
|
||||||
} from '@remixicon/react'
|
} from '@remixicon/react'
|
||||||
|
import ActionButton from '@/app/components/base/action-button'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isExpand: boolean
|
isExpand: boolean
|
||||||
@ -21,7 +22,9 @@ const ExpandBtn: FC<Props> = ({
|
|||||||
|
|
||||||
const Icon = isExpand ? RiCollapseDiagonalLine : RiExpandDiagonalLine
|
const Icon = isExpand ? RiCollapseDiagonalLine : RiExpandDiagonalLine
|
||||||
return (
|
return (
|
||||||
<Icon className='w-3.5 h-3.5 text-gray-500 cursor-pointer' onClick={handleToggle} />
|
<ActionButton onClick={handleToggle}>
|
||||||
|
<Icon className='w-4 h-4' />
|
||||||
|
</ActionButton>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
export default React.memo(ExpandBtn)
|
export default React.memo(ExpandBtn)
|
||||||
|
@ -4,6 +4,7 @@ import React, { useCallback } from 'react'
|
|||||||
import { useBoolean } from 'ahooks'
|
import { useBoolean } from 'ahooks'
|
||||||
import cn from 'classnames'
|
import cn from 'classnames'
|
||||||
import { Generator } from '@/app/components/base/icons/src/vender/other'
|
import { Generator } from '@/app/components/base/icons/src/vender/other'
|
||||||
|
import { ActionButton } from '@/app/components/base/action-button'
|
||||||
import GetAutomaticResModal from '@/app/components/app/configuration/config/automatic/get-automatic-res'
|
import GetAutomaticResModal from '@/app/components/app/configuration/config/automatic/get-automatic-res'
|
||||||
import { AppType } from '@/types/app'
|
import { AppType } from '@/types/app'
|
||||||
import type { AutomaticRes } from '@/service/debug'
|
import type { AutomaticRes } from '@/service/debug'
|
||||||
@ -28,9 +29,11 @@ const PromptGeneratorBtn: FC<Props> = ({
|
|||||||
}, [onGenerated, showAutomaticFalse])
|
}, [onGenerated, showAutomaticFalse])
|
||||||
return (
|
return (
|
||||||
<div className={cn(className)}>
|
<div className={cn(className)}>
|
||||||
<div className='p-[5px] rounded-md hover:bg-[#155EEF]/8 cursor-pointer' onClick={showAutomaticTrue}>
|
<ActionButton
|
||||||
<Generator className='w-3.5 h-3.5 text-primary-600' />
|
className='hover:bg-[#155EFF]/8'
|
||||||
</div>
|
onClick={showAutomaticTrue}>
|
||||||
|
<Generator className='w-4 h-4 text-primary-600' />
|
||||||
|
</ActionButton>
|
||||||
{showAutomatic && (
|
{showAutomatic && (
|
||||||
<GetAutomaticResModal
|
<GetAutomaticResModal
|
||||||
mode={AppType.chat}
|
mode={AppType.chat}
|
||||||
|
@ -660,6 +660,7 @@ button:focus-within {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@import '../components/base/button/index.css';
|
@import '../components/base/button/index.css';
|
||||||
|
@import '../components/base/action-button/index.css';
|
||||||
@import '../components/base/modal/index.css';
|
@import '../components/base/modal/index.css';
|
||||||
|
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
Loading…
x
Reference in New Issue
Block a user