增加一个悬浮Color Picker组件
This commit is contained in:
		
							
								
								
									
										38
									
								
								src/components/FloatColorPicker.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/components/FloatColorPicker.module.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| @layer components { | ||||
|   .float_color_picker { | ||||
|     position: relative; | ||||
|     height: 32px; | ||||
|     .preview { | ||||
|       height: 100%; | ||||
|       display: flex; | ||||
|       flex-direction: row; | ||||
|       align-items: center; | ||||
|       gap: var(--spacing-xs); | ||||
|       .preview_block { | ||||
|         height: 100%; | ||||
|         aspect-ratio: 16 / 9; | ||||
|         border-radius: var(--border-radius-xxs); | ||||
|         border: 1px solid var(--color-border); | ||||
|         cursor: pointer; | ||||
|       } | ||||
|     } | ||||
|     .picker { | ||||
|       position: absolute; | ||||
|       top: calc(100% + 4px); | ||||
|       padding: var(--spacing-s) var(--spacing-s); | ||||
|       border-radius: var(--border-radius-xxs); | ||||
|       border: 1px solid var(--color-border); | ||||
|       background-color: var(--color-bg); | ||||
|       box-shadow: 2px 0 8px oklch(from var(--color-black) l c h / 65%); | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       align-items: stretch; | ||||
|       gap: var(--spacing-s); | ||||
|       .btns { | ||||
|         display: flex; | ||||
|         flex-direction: row-reverse; | ||||
|         gap: var(--spacing-xs); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										54
									
								
								src/components/FloatColorPicker.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/components/FloatColorPicker.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| import { isEqual, isNil } from 'lodash-es'; | ||||
| import { useCallback, useEffect, useState } from 'react'; | ||||
| import { ActionIcon } from './ActionIcon'; | ||||
| import { ColorPicker } from './ColorPicker'; | ||||
| import styles from './FloatColorPicker.module.css'; | ||||
|  | ||||
| type FloatColorPickerProps = { | ||||
|   name?: string; | ||||
|   color?: string; | ||||
|   onPick?: (color: string) => void; | ||||
| }; | ||||
|  | ||||
| export function FloatColorPicker({ name, color, onPick }: FloatColorPickerProps) { | ||||
|   const [pickedColor, setPicked] = useState<string | null>(color ?? null); | ||||
|   const [showPicker, setPickerShow] = useState(false); | ||||
|   const handlePickAction = useCallback( | ||||
|     (value: string | null) => { | ||||
|       setPicked(value); | ||||
|       onPick?.(value); | ||||
|     }, | ||||
|     [onPick], | ||||
|   ); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     if (!isEqual(pickedColor, color)) { | ||||
|       setPicked(color); | ||||
|     } | ||||
|   }, [color]); | ||||
|  | ||||
|   return ( | ||||
|     <div className={styles.float_color_picker}> | ||||
|       <div className={styles.preview}> | ||||
|         <div | ||||
|           className={styles.preview_block} | ||||
|           onClick={() => setPickerShow(true)} | ||||
|           style={{ | ||||
|             backgroundColor: isNil(pickedColor) ? 'rgba(0, 0, 0, 0)' : `#${pickedColor}`, | ||||
|           }}></div> | ||||
|         <ActionIcon icon="tabler:x" onClick={() => handlePickAction(null)} /> | ||||
|       </div> | ||||
|       {showPicker && ( | ||||
|         <div className={styles.picker}> | ||||
|           <ColorPicker color={pickedColor} onSelect={handlePickAction} /> | ||||
|           <div className={styles.btns}> | ||||
|             <button type="button" className="primary" onClick={() => setPickerShow(false)}> | ||||
|               Done | ||||
|             </button> | ||||
|           </div> | ||||
|         </div> | ||||
|       )} | ||||
|       {!isNil(name) && <input type="hidden" name={name} value={pickedColor} />} | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user