mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-04 14:22:11 +08:00
refactor: migrate to @dnd-kit/react and simplify sortable components (#7819)
* refactor: migrate to @dnd-kit/react and simplify sortable components * chore: enable css formatting in biome.json * refactor(profile): simplify icon rendering logic and add alt text * style(profiles): add overflow hidden to profile grid container * refactor(profile): add radix for parseInt and improve type safety in profiles * docs: update changelog with drag-and-drop styling improvements * refactor(profile): move hasValidName function out of ProxiesEditorViewer * refactor(proxy): refactor proxy chain into sortable components * feat(proxy): add drop state styling and arrow animations to proxy chain * style(profiles): reduce horizontal padding in profile grid * feat(profile): add vertical margin to editor viewer items * chore: refresh pnpm lockfile * fix: preserve drag and drop behavior --------- Co-authored-by: Tunglies <77394545+Tunglies@users.noreply.github.com>
This commit is contained in:
@@ -17,3 +17,4 @@ export {
|
||||
StickyVirtualList,
|
||||
type StickyVirtualListHandle,
|
||||
} from './sticky-virtual-list'
|
||||
export { SortableItem } from './sortable-item'
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { useSortable } from '@dnd-kit/react/sortable'
|
||||
import { useTheme } from '@mui/material'
|
||||
import { type CSSProperties, type ReactNode, useCallback } from 'react'
|
||||
|
||||
export interface SortableItemRenderProps {
|
||||
ref: (element: HTMLElement | null) => void
|
||||
handleRef: (element: HTMLElement | null) => void
|
||||
style: CSSProperties
|
||||
}
|
||||
|
||||
interface SortableItemProps {
|
||||
id: string
|
||||
index: number
|
||||
group?: string
|
||||
disabled?: boolean
|
||||
style?: CSSProperties
|
||||
children: ReactNode | ((props: SortableItemRenderProps) => ReactNode)
|
||||
}
|
||||
|
||||
export const SortableItem = (props: SortableItemProps) => {
|
||||
const { id, index, group, disabled, children, style } = props
|
||||
const { ref, handleRef, sortable, isDragging } = useSortable({
|
||||
id,
|
||||
index,
|
||||
group,
|
||||
disabled,
|
||||
})
|
||||
const theme = useTheme()
|
||||
const setRef = useCallback(
|
||||
(element: HTMLDivElement | null) => {
|
||||
handleRef(element?.querySelector('[data-sortable-handle]') ?? null)
|
||||
ref(element)
|
||||
},
|
||||
[handleRef, ref],
|
||||
)
|
||||
|
||||
const mergedStyle: CSSProperties = {
|
||||
position: 'relative',
|
||||
borderRadius: 8,
|
||||
...style,
|
||||
...(sortable.transition && {
|
||||
transition: `${sortable.transition.duration ?? 300}ms ${sortable.transition.easing ?? 'ease'} transform`,
|
||||
}),
|
||||
...(isDragging && {
|
||||
zIndex: 100,
|
||||
// 拖拽中的元素置为不透明背景,避免半透明卡片透出下层内容。 投影由全局 [data-dnd-dragging] 规则统一施加。
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
}),
|
||||
}
|
||||
|
||||
if (typeof children === 'function') {
|
||||
return children({ ref, handleRef, style: mergedStyle })
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref={setRef} style={mergedStyle}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user