diff --git a/.changeset/drop-animation-refactor.md b/.changeset/drop-animation-refactor.md index 4681188e1..70d0f09c3 100644 --- a/.changeset/drop-animation-refactor.md +++ b/.changeset/drop-animation-refactor.md @@ -108,7 +108,7 @@ For even more advanced use-cases, consumers may also provide a function to the ` ```ts interface DropAnimationFunctionArguments { active: { - id: string; + id: UniqueIdentifier; data: DataRef; node: HTMLElement; rect: ClientRect; diff --git a/.changeset/number-unique-id.md b/.changeset/number-unique-id.md new file mode 100644 index 000000000..dfbed9c07 --- /dev/null +++ b/.changeset/number-unique-id.md @@ -0,0 +1,28 @@ +--- +'@dnd-kit/core': major +'@dnd-kit/sortable': major +--- + +The `UniqueIdentifier` type has been updated to now accept either `string` or `number` identifiers. As a result, the `id` property of `useDraggable`, `useDroppable` and `useSortable` and the `items` prop of `` now all accept either `string` or `number` identifiers. + +#### Migration steps + +For consumers that are using TypeScript, import the `UniqueIdentifier` type to have strongly typed local state: + +```diff ++ import type {UniqueIdentifier} from '@dnd-kit/core'; + +function MyComponent() { +- const [items, setItems] = useState(['A', 'B', 'C']); ++ const [items, setItems] = useState(['A', 'B', 'C']); +} +``` + +Alternatively, consumers can cast or convert the `id` property to a `string` when reading the `id` property of interfaces such as `Active`, `Over`, `DroppableContainer` and `DraggableNode`. + +The `draggableNodes` object has also been converted to a map. Consumers that were reading from the `draggableNodes` property that is available on the public context of `` should follow these migration steps: + +```diff +- draggableNodes[someId]; ++ draggableNodes.get(someId); +``` diff --git a/packages/core/src/components/Accessibility/Accessibility.tsx b/packages/core/src/components/Accessibility/Accessibility.tsx index 91fa8e02a..2e8520cec 100644 --- a/packages/core/src/components/Accessibility/Accessibility.tsx +++ b/packages/core/src/components/Accessibility/Accessibility.tsx @@ -3,7 +3,6 @@ import {createPortal} from 'react-dom'; import {useUniqueId} from '@dnd-kit/utilities'; import {HiddenText, LiveRegion, useAnnouncement} from '@dnd-kit/accessibility'; -import type {UniqueIdentifier} from '../../types'; import {DndMonitorListener, useDndMonitor} from '../DndMonitor'; import type {Announcements, ScreenReaderInstructions} from './types'; @@ -16,7 +15,7 @@ interface Props { announcements?: Announcements; container?: Element; screenReaderInstructions?: ScreenReaderInstructions; - hiddenTextDescribedById: UniqueIdentifier; + hiddenTextDescribedById: string; } export function Accessibility({ diff --git a/packages/core/src/components/Accessibility/components/RestoreFocus.tsx b/packages/core/src/components/Accessibility/components/RestoreFocus.tsx index 3b87b8982..928f248c0 100644 --- a/packages/core/src/components/Accessibility/components/RestoreFocus.tsx +++ b/packages/core/src/components/Accessibility/components/RestoreFocus.tsx @@ -32,7 +32,7 @@ export function RestoreFocus({disabled}: Props) { return; } - const draggableNode = draggableNodes[previousActiveId]; + const draggableNode = draggableNodes.get(previousActiveId); if (!draggableNode) { return; diff --git a/packages/core/src/components/DndContext/DndContext.tsx b/packages/core/src/components/DndContext/DndContext.tsx index a241dfddd..4e7b34c9c 100644 --- a/packages/core/src/components/DndContext/DndContext.tsx +++ b/packages/core/src/components/DndContext/DndContext.tsx @@ -154,7 +154,7 @@ export const DndContext = memo(function DndContext({ draggable: {active: activeId, nodes: draggableNodes, translate}, droppable: {containers: droppableContainers}, } = state; - const node = activeId ? draggableNodes[activeId] : null; + const node = activeId ? draggableNodes.get(activeId) : null; const activeRects = useRef({ initial: null, translated: null, @@ -202,7 +202,7 @@ export const DndContext = memo(function DndContext({ ); useLayoutShiftScrollCompensation({ - activeNode: activeId ? draggableNodes[activeId] : null, + activeNode: activeId ? draggableNodes.get(activeId) : null, config: autoScrollOptions.layoutShiftCompensation, initialRect: initialActiveNodeRect, measure: measuringConfiguration.draggable.measure, @@ -329,11 +329,11 @@ export const DndContext = memo(function DndContext({ event: React.SyntheticEvent, {sensor: Sensor, options}: SensorDescriptor ) => { - if (!activeRef.current) { + if (activeRef.current == null) { return; } - const activeNode = draggableNodes[activeRef.current]; + const activeNode = draggableNodes.get(activeRef.current); if (!activeNode) { return; @@ -356,7 +356,7 @@ export const DndContext = memo(function DndContext({ return; } - const draggableNode = draggableNodes[id]; + const draggableNode = draggableNodes.get(id); if (!draggableNode) { return; @@ -456,7 +456,7 @@ export const DndContext = memo(function DndContext({ ): SyntheticListener['handler'] => { return (event, active) => { const nativeEvent = event.nativeEvent as DndEvent; - const activeDraggableNode = draggableNodes[active]; + const activeDraggableNode = draggableNodes.get(active); if ( // Another sensor is already instantiating diff --git a/packages/core/src/components/DragOverlay/DragOverlay.tsx b/packages/core/src/components/DragOverlay/DragOverlay.tsx index 3fde6e90a..39c6b6e73 100644 --- a/packages/core/src/components/DragOverlay/DragOverlay.tsx +++ b/packages/core/src/components/DragOverlay/DragOverlay.tsx @@ -84,6 +84,7 @@ export const DragOverlay = React.memo( {active && key ? ( Promise | void; @@ -29,15 +31,13 @@ export function AnimationManager({animation, children}: Props) { } const key = clonedChildren?.key; + const id = clonedChildren?.props.id; - if (typeof key !== 'string') { + if (key == null || id == null) { setClonedChildren(null); return; } - const [prefix] = key.split('-', 1); - const id = key.substring(prefix.length + 1); - Promise.resolve(animation(id, element)).then(() => { setClonedChildren(null); }); diff --git a/packages/core/src/components/DragOverlay/components/PositionedOverlay/PositionedOverlay.tsx b/packages/core/src/components/DragOverlay/components/PositionedOverlay/PositionedOverlay.tsx index e795265ed..1b7e2e394 100644 --- a/packages/core/src/components/DragOverlay/components/PositionedOverlay/PositionedOverlay.tsx +++ b/packages/core/src/components/DragOverlay/components/PositionedOverlay/PositionedOverlay.tsx @@ -4,7 +4,7 @@ import {CSS, isKeyboardEvent} from '@dnd-kit/utilities'; import type {Transform} from '@dnd-kit/utilities'; import {getRelativeTransformOrigin} from '../../../../utilities'; -import type {ClientRect} from '../../../../types'; +import type {ClientRect, UniqueIdentifier} from '../../../../types'; type TransitionGetter = ( activatorEvent: Event | null @@ -16,6 +16,7 @@ export interface Props { adjustScale?: boolean; children?: React.ReactNode; className?: string; + id: UniqueIdentifier; rect: ClientRect | null; style?: React.CSSProperties; transition?: string | TransitionGetter; diff --git a/packages/core/src/components/DragOverlay/hooks/useDropAnimation.ts b/packages/core/src/components/DragOverlay/hooks/useDropAnimation.ts index a9b4ff01c..94ba8fac8 100644 --- a/packages/core/src/components/DragOverlay/hooks/useDropAnimation.ts +++ b/packages/core/src/components/DragOverlay/hooks/useDropAnimation.ts @@ -7,7 +7,7 @@ import type { DraggableNodes, DroppableContainers, } from '../../../store'; -import type {ClientRect} from '../../../types'; +import type {ClientRect, UniqueIdentifier} from '../../../types'; import {getMeasurableNode} from '../../../utilities/nodes'; import {scrollIntoViewIfNeeded} from '../../../utilities/scroll'; import {parseTransform} from '../../../utilities/transform'; @@ -16,7 +16,7 @@ import type {Animation} from '../components'; interface SharedParameters { active: { - id: string; + id: UniqueIdentifier; data: Active['data']; node: HTMLElement; rect: ClientRect; @@ -171,7 +171,7 @@ export function useDropAnimation({ return; } - const activeDraggable: DraggableNode | undefined = draggableNodes[id]; + const activeDraggable: DraggableNode | undefined = draggableNodes.get(id); if (!activeDraggable) { return; diff --git a/packages/core/src/components/DragOverlay/hooks/useKey.ts b/packages/core/src/components/DragOverlay/hooks/useKey.ts index 8af0dc399..b801922b0 100644 --- a/packages/core/src/components/DragOverlay/hooks/useKey.ts +++ b/packages/core/src/components/DragOverlay/hooks/useKey.ts @@ -1,8 +1,10 @@ import {useMemo} from 'react'; +import type {UniqueIdentifier} from '../../../types'; + let key = 0; -export function useKey(id: string | undefined) { +export function useKey(id: UniqueIdentifier | undefined) { return useMemo(() => { if (id == null) { return; diff --git a/packages/core/src/hooks/useDraggable.ts b/packages/core/src/hooks/useDraggable.ts index a6e59724e..f0f5c9495 100644 --- a/packages/core/src/hooks/useDraggable.ts +++ b/packages/core/src/hooks/useDraggable.ts @@ -8,11 +8,12 @@ import { } from '@dnd-kit/utilities'; import {InternalContext, Data} from '../store'; +import type {UniqueIdentifier} from '../types'; import {ActiveDraggableContext} from '../components/DndContext'; import {useSyntheticListeners, SyntheticListenerMap} from './utilities'; export interface UseDraggableArguments { - id: string; + id: UniqueIdentifier; data?: Data; disabled?: boolean; attributes?: { @@ -68,13 +69,13 @@ export function useDraggable({ useIsomorphicLayoutEffect( () => { - draggableNodes[id] = {id, key, node, activatorNode, data: dataRef}; + draggableNodes.set(id, {id, key, node, activatorNode, data: dataRef}); return () => { - const node = draggableNodes[id]; + const node = draggableNodes.get(id); if (node && node.key === key) { - delete draggableNodes[id]; + draggableNodes.delete(id); } }; }, diff --git a/packages/core/src/hooks/useDroppable.ts b/packages/core/src/hooks/useDroppable.ts index e2e404733..7939f15db 100644 --- a/packages/core/src/hooks/useDroppable.ts +++ b/packages/core/src/hooks/useDroppable.ts @@ -74,7 +74,7 @@ export function useDroppable({ callbackId.current = setTimeout(() => { measureDroppableContainers( - typeof ids.current === 'string' ? [ids.current] : ids.current + Array.isArray(ids.current) ? ids.current : [ids.current] ); callbackId.current = null; }, resizeObserverTimeout); diff --git a/packages/core/src/hooks/utilities/useCachedNode.ts b/packages/core/src/hooks/utilities/useCachedNode.ts index 5c7c195d0..c010d5514 100644 --- a/packages/core/src/hooks/utilities/useCachedNode.ts +++ b/packages/core/src/hooks/utilities/useCachedNode.ts @@ -7,7 +7,7 @@ export function useCachedNode( draggableNodes: DraggableNodes, id: UniqueIdentifier | null ): DraggableNode['node']['current'] { - const draggableNode = id !== null ? draggableNodes[id] : undefined; + const draggableNode = id !== null ? draggableNodes.get(id) : undefined; const node = draggableNode ? draggableNode.node.current : null; return useLazyMemo( diff --git a/packages/core/src/hooks/utilities/useSyntheticListeners.ts b/packages/core/src/hooks/utilities/useSyntheticListeners.ts index 9ce09314b..03c6ce027 100644 --- a/packages/core/src/hooks/utilities/useSyntheticListeners.ts +++ b/packages/core/src/hooks/utilities/useSyntheticListeners.ts @@ -13,7 +13,7 @@ export type SyntheticListenerMap = Record; export function useSyntheticListeners( listeners: SyntheticListeners, - id: string + id: UniqueIdentifier ): SyntheticListenerMap { return useMemo(() => { return listeners.reduce( diff --git a/packages/core/src/store/context.ts b/packages/core/src/store/context.ts index e1829310b..bb624ec83 100644 --- a/packages/core/src/store/context.ts +++ b/packages/core/src/store/context.ts @@ -12,7 +12,7 @@ export const defaultPublicContext: PublicContextDescriptor = { activeNodeRect: null, collisions: null, containerNodeRect: null, - draggableNodes: {}, + draggableNodes: new Map(), droppableRects: new Map(), droppableContainers: new DroppableContainersMap(), over: null, @@ -40,7 +40,7 @@ export const defaultInternalContext: InternalContextDescriptor = { draggable: '', }, dispatch: noop, - draggableNodes: {}, + draggableNodes: new Map(), over: null, measureDroppableContainers: noop, }; diff --git a/packages/core/src/store/reducer.ts b/packages/core/src/store/reducer.ts index c43d7247a..fa34ba9ef 100644 --- a/packages/core/src/store/reducer.ts +++ b/packages/core/src/store/reducer.ts @@ -7,7 +7,7 @@ export function getInitialState(): State { draggable: { active: null, initialCoordinates: {x: 0, y: 0}, - nodes: {}, + nodes: new Map(), translate: {x: 0, y: 0}, }, droppable: { diff --git a/packages/core/src/store/types.ts b/packages/core/src/store/types.ts index 61ff78acc..b9b21f918 100644 --- a/packages/core/src/store/types.ts +++ b/packages/core/src/store/types.ts @@ -56,10 +56,7 @@ export type DraggableNode = { data: DataRef; }; -export type DraggableNodes = Record< - UniqueIdentifier, - DraggableNode | undefined ->; +export type DraggableNodes = Map; export type DroppableContainers = DroppableContainersMap; @@ -107,7 +104,7 @@ export interface InternalContextDescriptor { active: Active | null; activeNodeRect: ClientRect | null; ariaDescribedById: { - draggable: UniqueIdentifier; + draggable: string; }; dispatch: React.Dispatch; draggableNodes: DraggableNodes; diff --git a/packages/core/src/types/other.ts b/packages/core/src/types/other.ts index 412568bf8..04bb8adfc 100644 --- a/packages/core/src/types/other.ts +++ b/packages/core/src/types/other.ts @@ -1 +1 @@ -export type UniqueIdentifier = string; +export type UniqueIdentifier = string | number; diff --git a/packages/sortable/src/components/SortableContext.tsx b/packages/sortable/src/components/SortableContext.tsx index 9a1891e02..4720b562e 100644 --- a/packages/sortable/src/components/SortableContext.tsx +++ b/packages/sortable/src/components/SortableContext.tsx @@ -60,10 +60,10 @@ export function SortableContext({ } = useDndContext(); const containerId = useUniqueId(ID_PREFIX, id); const useDragOverlay = Boolean(dragOverlay.rect !== null); - const items = useMemo( + const items = useMemo( () => userDefinedItems.map((item) => - typeof item === 'string' ? item : item.id + typeof item === 'object' && 'id' in item ? item.id : item ), [userDefinedItems] ); diff --git a/stories/2 - Presets/Sortable/1-Vertical.story.tsx b/stories/2 - Presets/Sortable/1-Vertical.story.tsx index 6e729d88a..f3254429e 100644 --- a/stories/2 - Presets/Sortable/1-Vertical.story.tsx +++ b/stories/2 - Presets/Sortable/1-Vertical.story.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {MeasuringStrategy} from '@dnd-kit/core'; +import {MeasuringStrategy, UniqueIdentifier} from '@dnd-kit/core'; import {restrictToWindowEdges} from '@dnd-kit/modifiers'; import { AnimateLayoutChanges, @@ -102,12 +102,15 @@ export const VariableHeights = () => { ); }; -export const DisabledItems = () => ( - ['1', '5', '8', '13', '20'].includes(value)} - /> -); +export const DisabledItems = () => { + const disabledItems: UniqueIdentifier[] = ['1', '5', '8', '13', '20']; + return ( + disabledItems.includes(value)} + /> + ); +}; export const MarginBetweenItems = () => { const getMargin = (index: number) => { diff --git a/stories/2 - Presets/Sortable/4-MultipleContainers.story.tsx b/stories/2 - Presets/Sortable/4-MultipleContainers.story.tsx index 20601f06f..6b8780f7d 100644 --- a/stories/2 - Presets/Sortable/4-MultipleContainers.story.tsx +++ b/stories/2 - Presets/Sortable/4-MultipleContainers.story.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import type {CancelDrop} from '@dnd-kit/core'; +import type {CancelDrop, UniqueIdentifier} from '@dnd-kit/core'; import {rectSortingStrategy} from '@dnd-kit/sortable'; import {MultipleContainers, TRASH_ID} from './MultipleContainers'; @@ -27,7 +27,7 @@ export const ManyItems = () => ( export const Vertical = () => ; export const TrashableItems = ({confirmDrop}: {confirmDrop: boolean}) => { - const [activeId, setActiveId] = React.useState(null); + const [activeId, setActiveId] = React.useState(null); const resolveRef = React.useRef<(value: boolean) => void>(); const cancelDrop: CancelDrop = async ({active, over}) => { diff --git a/stories/2 - Presets/Sortable/5-Virtualized.story.tsx b/stories/2 - Presets/Sortable/5-Virtualized.story.tsx index 8676188a7..89bd81262 100644 --- a/stories/2 - Presets/Sortable/5-Virtualized.story.tsx +++ b/stories/2 - Presets/Sortable/5-Virtualized.story.tsx @@ -10,6 +10,7 @@ import { KeyboardSensor, useSensor, useSensors, + UniqueIdentifier, } from '@dnd-kit/core'; import { arrayMove, @@ -37,9 +38,9 @@ function Sortable({ modifiers, }: Props) { const [items, setItems] = useState(() => - createRange(itemCount, (index) => `${index + 1}`) + createRange(itemCount, (index) => `${index + 1}`) ); - const [activeId, setActiveId] = useState(null); + const [activeId, setActiveId] = useState(null); const sensors = useSensors( useSensor(PointerSensor), useSensor(KeyboardSensor, { @@ -48,7 +49,7 @@ function Sortable({ coordinateGetter: sortableKeyboardCoordinates, }) ); - const getIndex: (id: string) => number = items.indexOf.bind(items); + const getIndex = (id: UniqueIdentifier) => items.indexOf(id); const activeIndex = activeId ? getIndex(activeId) : -1; return ( diff --git a/stories/2 - Presets/Sortable/FramerMotion.tsx b/stories/2 - Presets/Sortable/FramerMotion.tsx index 849b2e922..0dc0f88f3 100644 --- a/stories/2 - Presets/Sortable/FramerMotion.tsx +++ b/stories/2 - Presets/Sortable/FramerMotion.tsx @@ -8,6 +8,7 @@ import { KeyboardSensor, useSensor, useSensors, + UniqueIdentifier, } from '@dnd-kit/core'; import { SortableContext, @@ -24,9 +25,8 @@ import styles from '../../components/Item/Item.module.css'; export function FramerMotion() { const [items, setItems] = useState(() => - createRange(16, (index) => (index + 1).toString()) + createRange(16, (index) => index + 1) ); - const [activeId, setActiveId] = useState(null); const sensors = useSensors( useSensor(PointerSensor), useSensor(KeyboardSensor, { @@ -39,7 +39,6 @@ export function FramerMotion() { @@ -53,15 +52,14 @@ export function FramerMotion() { ); - function handleDragStart({active}) { - setActiveId(active.id); - } + function handleDragEnd({active, over}: DragEndEvent) { + if (!over) { + return; + } - function handleDragEnd({over}: DragEndEvent) { setItems((items) => - arrayMove(items, items.indexOf(activeId), items.indexOf(over.id)) + arrayMove(items, items.indexOf(active.id), items.indexOf(over.id)) ); - setActiveId(null); } } @@ -77,7 +75,7 @@ const initialStyles = { scale: 1, }; -function Item({id}) { +function Item({id}: {id: UniqueIdentifier}) { const { attributes, setNodeRef, @@ -94,8 +92,7 @@ function Item({id}) { className={styles.Item} style={baseStyles} ref={setNodeRef} - tabIndex={0} - layoutId={id} + layoutId={String(id)} animate={ transform ? { diff --git a/stories/2 - Presets/Sortable/MultipleContainers.tsx b/stories/2 - Presets/Sortable/MultipleContainers.tsx index 02bb4395a..926fda55b 100644 --- a/stories/2 - Presets/Sortable/MultipleContainers.tsx +++ b/stories/2 - Presets/Sortable/MultipleContainers.tsx @@ -56,8 +56,8 @@ function DroppableContainer({ ...props }: ContainerProps & { disabled?: boolean; - id: string; - items: string[]; + id: UniqueIdentifier; + items: UniqueIdentifier[]; style?: React.CSSProperties; }) { const { @@ -114,7 +114,7 @@ const dropAnimation: DropAnimation = { }), }; -type Items = Record; +type Items = Record; interface Props { adjustScale?: boolean; @@ -176,8 +176,10 @@ export function MultipleContainers({ D: createRange(itemCount, (index) => `D${index + 1}`), } ); - const [containers, setContainers] = useState(Object.keys(items)); - const [activeId, setActiveId] = useState(null); + const [containers, setContainers] = useState( + Object.keys(items) as UniqueIdentifier[] + ); + const [activeId, setActiveId] = useState(null); const lastOverId = useRef(null); const recentlyMovedToNewContainer = useRef(false); const isSortingContainer = activeId ? containers.includes(activeId) : false; @@ -260,7 +262,7 @@ export function MultipleContainers({ coordinateGetter, }) ); - const findContainer = (id: string) => { + const findContainer = (id: UniqueIdentifier) => { if (id in items) { return id; } @@ -268,7 +270,7 @@ export function MultipleContainers({ return Object.keys(items).find((key) => items[key].includes(id)); }; - const getIndex = (id: string) => { + const getIndex = (id: UniqueIdentifier) => { const container = findContainer(id); if (!container) { @@ -520,13 +522,13 @@ export function MultipleContainers({ ); - function renderSortableItemDragOverlay(id: string) { + function renderSortableItemDragOverlay(id: UniqueIdentifier) { return ( | null; index: number; isDragging: boolean; - id: string; + id: UniqueIdentifier; }): React.CSSProperties; isDisabled?(id: UniqueIdentifier): boolean; } @@ -115,12 +115,12 @@ export function Sortable({ useDragOverlay = true, wrapperStyle = () => ({}), }: Props) { - const [items, setItems] = useState( + const [items, setItems] = useState( () => initialItems ?? - createRange(itemCount, (index) => (index + 1).toString()) + createRange(itemCount, (index) => index + 1) ); - const [activeId, setActiveId] = useState(null); + const [activeId, setActiveId] = useState(null); const sensors = useSensors( useSensor(MouseSensor, { activationConstraint, @@ -135,17 +135,20 @@ export function Sortable({ }) ); const isFirstAnnouncement = useRef(true); - const getIndex = items.indexOf.bind(items); - const getPosition = (id: string) => getIndex(id) + 1; + const getIndex = (id: UniqueIdentifier) => items.indexOf(id); + const getPosition = (id: UniqueIdentifier) => getIndex(id) + 1; const activeIndex = activeId ? getIndex(activeId) : -1; const handleRemove = removable - ? (id: string) => setItems((items) => items.filter((item) => item !== id)) + ? (id: UniqueIdentifier) => + setItems((items) => items.filter((item) => item !== id)) : undefined; const announcements: Announcements = { onDragStart({active: {id}}) { - return `Picked up sortable item ${id}. Sortable item ${id} is in position ${getPosition( + return `Picked up sortable item ${String( id - )} of ${items.length}`; + )}. Sortable item ${id} is in position ${getPosition(id)} of ${ + items.length + }`; }, onDragOver({active, over}) { // In this specific use-case, the picked up item's `id` is always the same as the first `over` id. @@ -277,11 +280,11 @@ interface SortableItemProps { animateLayoutChanges?: AnimateLayoutChanges; disabled?: boolean; getNewIndex?: NewIndexGetter; - id: string; + id: UniqueIdentifier; index: number; handle: boolean; useDragOverlay?: boolean; - onRemove?(id: string): void; + onRemove?(id: UniqueIdentifier): void; style(values: any): React.CSSProperties; renderItem?(args: any): React.ReactElement; wrapperStyle: Props['wrapperStyle']; diff --git a/stories/3 - Examples/Advanced/Pages/Page.tsx b/stories/3 - Examples/Advanced/Pages/Page.tsx index f1a5a41a2..c7ab3cf02 100644 --- a/stories/3 - Examples/Advanced/Pages/Page.tsx +++ b/stories/3 - Examples/Advanced/Pages/Page.tsx @@ -1,4 +1,5 @@ import React, {forwardRef, HTMLAttributes} from 'react'; +import type {UniqueIdentifier} from '@dnd-kit/core'; import classNames from 'classnames'; import {removeIcon} from './icons'; @@ -15,11 +16,11 @@ export enum Layout { Grid = 'grid', } -export interface Props extends HTMLAttributes { +export interface Props extends Omit, 'id'> { active?: boolean; clone?: boolean; insertPosition?: Position; - id: string; + id: UniqueIdentifier; index?: number; layout: Layout; onRemove?(): void; @@ -42,7 +43,7 @@ export const Page = forwardRef(function Page( style={style} ref={ref} > -