Pārlūkot izejas kodu

chore : option card (#6800)

Joel 8 mēneši atpakaļ
vecāks
revīzija
53a89bbbc7

+ 62 - 0
web/app/components/workflow/nodes/_base/components/option-card.tsx

@@ -0,0 +1,62 @@
+'use client'
+import type { FC } from 'react'
+import React, { useCallback } from 'react'
+import type { VariantProps } from 'class-variance-authority'
+import { cva } from 'class-variance-authority'
+import cn from '@/utils/classnames'
+
+const variants = cva([], {
+  variants: {
+    align: {
+      left: 'justify-start',
+      center: 'justify-center',
+      right: 'justify-end',
+    },
+  },
+  defaultVariants: {
+    align: 'center',
+  },
+},
+)
+
+type Props = {
+  className?: string
+  title: string
+  onSelect: () => void
+  selected: boolean
+  disabled?: boolean
+  align?: 'left' | 'center' | 'right'
+} & VariantProps<typeof variants>
+
+const OptionCard: FC<Props> = ({
+  className,
+  title,
+  onSelect,
+  selected,
+  disabled,
+  align = 'center',
+}) => {
+  const handleSelect = useCallback(() => {
+    if (selected || disabled)
+      return
+    onSelect()
+  }, [onSelect, selected, disabled])
+
+  return (
+    <div
+      className={cn(
+        'flex items-center px-2 h-8 rounded-md system-sm-regular bg-components-option-card-option-bg border border-components-option-card-option-bg text-text-secondary cursor-default',
+        (!selected && !disabled) && 'hover:bg-components-option-card-option-bg-hover hover:border-components-option-card-option-border-hover hover:shadow-xs cursor-pointer',
+        selected && 'bg-components-option-card-option-selected-bg border-[1.5px] border-components-option-card-option-selected-border system-sm-medium shadow-xs',
+        disabled && 'text-text-disabled',
+        variants({ align }),
+        className,
+      )}
+      onClick={handleSelect}
+    >
+      {title}
+    </div>
+  )
+}
+
+export default React.memo(OptionCard)

+ 12 - 33
web/app/components/workflow/nodes/llm/components/resolution-picker.tsx

@@ -2,35 +2,11 @@
 import type { FC } from 'react'
 import React, { useCallback } from 'react'
 import { useTranslation } from 'react-i18next'
-import cn from '@/utils/classnames'
+import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card'
 import { Resolution } from '@/types/app'
 
 const i18nPrefix = 'workflow.nodes.llm'
 
-type ItemProps = {
-  title: string
-  value: Resolution
-  onSelect: (value: Resolution) => void
-  isSelected: boolean
-}
-
-const Item: FC<ItemProps> = ({ title, value, onSelect, isSelected }) => {
-  const handleSelect = useCallback(() => {
-    if (isSelected)
-      return
-    onSelect(value)
-  }, [value, onSelect, isSelected])
-
-  return (
-    <div
-      className={cn(isSelected ? 'bg-white border-[2px] border-primary-400  shadow-xs' : 'bg-gray-25 border border-gray-100', 'flex items-center h-8 px-3 rounded-lg text-[13px] font-normal text-gray-900 cursor-pointer')}
-      onClick={handleSelect}
-    >
-      {title}
-    </div>
-  )
-}
-
 type Props = {
   value: Resolution
   onChange: (value: Resolution) => void
@@ -42,21 +18,24 @@ const ResolutionPicker: FC<Props> = ({
 }) => {
   const { t } = useTranslation()
 
+  const handleOnChange = useCallback((value: Resolution) => {
+    return () => {
+      onChange(value)
+    }
+  }, [onChange])
   return (
     <div className='flex items-center justify-between'>
       <div className='mr-2 text-xs font-medium text-gray-500 uppercase'>{t(`${i18nPrefix}.resolution.name`)}</div>
       <div className='flex items-center space-x-1'>
-        <Item
+        <OptionCard
           title={t(`${i18nPrefix}.resolution.high`)}
-          value={Resolution.high}
-          onSelect={onChange}
-          isSelected={value === Resolution.high}
+          onSelect={handleOnChange(Resolution.high)}
+          selected={value === Resolution.high}
         />
-        <Item
+        <OptionCard
           title={t(`${i18nPrefix}.resolution.low`)}
-          value={Resolution.low}
-          onSelect={onChange}
-          isSelected={value === Resolution.low}
+          onSelect={handleOnChange(Resolution.low)}
+          selected={value === Resolution.low}
         />
       </div>
     </div>