/
githubmirror
/
react-beautiful-dnd
Обзор
Документация
Войти
/
githubmirror
/
react-beautiful-dnd
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/types.js
485 строк
12 KB
Alex Reardon
its alive
29 ноя 2019, 05:53
29 ноя 2019, 05:53
9a35d65
Код
Авторство
О чём код?
// @flow import type { BoxModel, Rect, Position } from 'css-box-model'; export type Id = string; export type DraggableId = Id; export type DroppableId = Id; export type TypeId = Id; export type ContextId = Id; export type ElementId = Id; export type DroppableMode = 'standard' | 'virtual'; export type DroppableDescriptor = {| id: DroppableId, type: TypeId, mode: DroppableMode, |}; export type DraggableDescriptor = {| id: DraggableId, index: number, // Inherited from Droppable droppableId: DroppableId, // This is technically redundant but it avoids // needing to look up a parent droppable just to get its type type: TypeId, |}; export type DraggableOptions = {| canDragInteractiveElements: boolean, shouldRespectForcePress: boolean, isEnabled: boolean, |}; export type Direction = 'horizontal' | 'vertical'; export type VerticalAxis = {| direction: 'vertical', line: 'y', start: 'top', end: 'bottom', size: 'height', crossAxisLine: 'x', crossAxisStart: 'left', crossAxisEnd: 'right', crossAxisSize: 'width', |}; export type HorizontalAxis = {| direction: 'horizontal', line: 'x', start: 'left', end: 'right', size: 'width', crossAxisLine: 'y', crossAxisStart: 'top', crossAxisEnd: 'bottom', crossAxisSize: 'height', |}; export type Axis = VerticalAxis | HorizontalAxis; export type ScrollSize = {| scrollHeight: number, scrollWidth: number, |}; export type ScrollDetails = {| initial: Position, current: Position, // the maximum allowable scroll for the frame max: Position, diff: {| value: Position, // The actual displacement as a result of a scroll is in the opposite // direction to the scroll itself. When scrolling down items are displaced // upwards. This value is the negated version of the 'value' displacement: Position, |}, |}; export type Placeholder = {| client: BoxModel, tagName: string, display: string, |}; export type DraggableDimension = {| descriptor: DraggableDescriptor, // the placeholder for the draggable placeholder: Placeholder, // relative to the viewport when the drag started client: BoxModel, // relative to the whole page page: BoxModel, // how much displacement the draggable causes // this is the size of the marginBox displaceBy: Position, |}; export type Scrollable = {| // This is the window through which the droppable is observed // It does not change during a drag pageMarginBox: Rect, // Used for comparision with dynamic recollecting frameClient: BoxModel, scrollSize: ScrollSize, // Whether or not we should clip the subject by the frame // Is controlled by the ignoreContainerClipping prop shouldClipSubject: boolean, scroll: ScrollDetails, |}; export type PlaceholderInSubject = {| // might not actually be increased by // placeholder if there is no required space increasedBy: ?Position, placeholderSize: Position, // max scroll before placeholder added // will be null if there was no frame oldFrameMaxScroll: ?Position, |}; export type DroppableSubject = {| // raw, unchanging page: BoxModel, withPlaceholder: ?PlaceholderInSubject, // The hitbox for a droppable // - page margin box // - with scroll changes // - with any additional droppable placeholder // - clipped by frame // The subject will be null if the hit area is completely empty active: ?Rect, |}; export type DroppableDimension = {| descriptor: DroppableDescriptor, axis: Axis, isEnabled: boolean, isCombineEnabled: boolean, // relative to the current viewport client: BoxModel, // relative to the whole page isFixedOnPage: boolean, // relative to the page page: BoxModel, // The container of the droppable frame: ?Scrollable, // what is visible through the frame subject: DroppableSubject, |}; export type DraggableLocation = {| droppableId: DroppableId, index: number, |}; export type DraggableIdMap = { [id: DraggableId]: true, }; export type DroppableIdMap = { [id: DroppableId]: true, }; export type DraggableDimensionMap = { [key: DraggableId]: DraggableDimension }; export type DroppableDimensionMap = { [key: DroppableId]: DroppableDimension }; export type Displacement = {| draggableId: DraggableId, shouldAnimate: boolean, |}; export type DisplacementMap = { [key: DraggableId]: Displacement }; export type DisplacedBy = {| value: number, point: Position, |}; export type Combine = {| draggableId: DraggableId, droppableId: DroppableId, |}; export type DisplacementGroups = {| all: DraggableId[], visible: DisplacementMap, invisible: DraggableIdMap, |}; export type ReorderImpact = {| type: 'REORDER', destination: DraggableLocation, |}; export type CombineImpact = {| type: 'COMBINE', combine: Combine, |}; export type ImpactLocation = ReorderImpact | CombineImpact; export type Displaced = {| forwards: DisplacementGroups, backwards: DisplacementGroups, |}; export type DragImpact = {| displaced: DisplacementGroups, displacedBy: DisplacedBy, at: ?ImpactLocation, |}; export type ClientPositions = {| // where the user initially selected // This point is not used to calculate the impact of a dragging item // It is used to calculate the offset from the initial selection point selection: Position, // the current center of the item borderBoxCenter: Position, // how far the item has moved from its original position offset: Position, |}; export type PagePositions = {| selection: Position, borderBoxCenter: Position, // how much the page position has changed from the initial offset: Position, |}; // There are two seperate modes that a drag can be in // FLUID: everything is done in response to highly granular input (eg mouse) // SNAP: items move in response to commands (eg keyboard); export type MovementMode = 'FLUID' | 'SNAP'; export type DragPositions = {| client: ClientPositions, page: PagePositions, |}; export type DraggableRubric = {| draggableId: DraggableId, type: TypeId, source: DraggableLocation, |}; // Published in onBeforeCapture // We cannot give more information as things might change in the // onBeforeCapture responder! export type BeforeCapture = {| draggableId: DraggableId, mode: MovementMode, |}; // published when a drag starts export type DragStart = {| ...DraggableRubric, mode: MovementMode, |}; export type DragUpdate = {| ...DragStart, // may not have any destination (drag to nowhere) destination: ?DraggableLocation, // populated when a draggable is dragging over another in combine mode combine: ?Combine, |}; export type DropReason = 'DROP' | 'CANCEL'; // published when a drag finishes export type DropResult = {| ...DragUpdate, reason: DropReason, |}; export type ScrollOptions = {| shouldPublishImmediately: boolean, |}; // using the draggable id rather than the descriptor as the descriptor // may change as a result of the initial flush. This means that the lift // descriptor may not be the same as the actual descriptor. To avoid // confusion the request is just an id which is looked up // in the dimension-marshal post-flush // Not including droppableId as it might change in a drop flush export type LiftRequest = {| draggableId: DraggableId, scrollOptions: ScrollOptions, |}; export type Critical = {| draggable: DraggableDescriptor, droppable: DroppableDescriptor, |}; export type Viewport = {| // live updates with the latest values frame: Rect, scroll: ScrollDetails, |}; export type LiftEffect = {| inVirtualList: boolean, effected: DraggableIdMap, displacedBy: DisplacedBy, |}; export type DimensionMap = {| draggables: DraggableDimensionMap, droppables: DroppableDimensionMap, |}; export type DroppablePublish = {| droppableId: DroppableId, scroll: Position, |}; export type Published = {| additions: DraggableDimension[], removals: DraggableId[], modified: DroppablePublish[], |}; export type CompletedDrag = {| critical: Critical, result: DropResult, impact: DragImpact, afterCritical: LiftEffect, |}; export type IdleState = {| phase: 'IDLE', completed: ?CompletedDrag, shouldFlush: boolean, |}; export type DraggingState = {| phase: 'DRAGGING', isDragging: true, critical: Critical, movementMode: MovementMode, dimensions: DimensionMap, initial: DragPositions, current: DragPositions, impact: DragImpact, viewport: Viewport, afterCritical: LiftEffect, onLiftImpact: DragImpact, // when there is a fixed list we want to opt out of this behaviour isWindowScrollAllowed: boolean, // if we need to jump the scroll (keyboard dragging) scrollJumpRequest: ?Position, // whether or not draggable movements should be animated forceShouldAnimate: ?boolean, |}; // While dragging we can enter into a bulk collection phase // During this phase no drag updates are permitted. // If a drop occurs during this phase, it must wait until it is // completed before continuing with the drop // TODO: rename to BulkCollectingState export type CollectingState = {| ...DraggingState, phase: 'COLLECTING', |}; // If a drop action occurs during a bulk collection we need to // wait for the collection to finish before performing the drop. // This is to ensure that everything has the correct index after // a drop export type DropPendingState = {| ...DraggingState, phase: 'DROP_PENDING', isWaiting: boolean, reason: DropReason, |}; // An optional phase for animating the drop / cancel if it is needed export type DropAnimatingState = {| phase: 'DROP_ANIMATING', completed: CompletedDrag, newHomeClientOffset: Position, dropDuration: number, // We still need to render placeholders and fix the dimensions of the dragging item dimensions: DimensionMap, |}; export type State = | IdleState | DraggingState | CollectingState | DropPendingState | DropAnimatingState; export type StateWhenUpdatesAllowed = DraggingState | CollectingState; export type Announce = (message: string) => void; export type InOutAnimationMode = 'none' | 'open' | 'close'; export type ResponderProvided = {| announce: Announce, |}; export type OnBeforeCaptureResponder = (before: BeforeCapture) => mixed; export type OnBeforeDragStartResponder = (start: DragStart) => mixed; export type OnDragStartResponder = ( start: DragStart, provided: ResponderProvided, ) => mixed; export type OnDragUpdateResponder = ( update: DragUpdate, provided: ResponderProvided, ) => mixed; export type OnDragEndResponder = ( result: DropResult, provided: ResponderProvided, ) => mixed; export type Responders = {| onBeforeCapture?: OnBeforeCaptureResponder, onBeforeDragStart?: OnBeforeDragStartResponder, onDragStart?: OnDragStartResponder, onDragUpdate?: OnDragUpdateResponder, // always required onDragEnd: OnDragEndResponder, |}; // ## Sensors export type StopDragOptions = {| shouldBlockNextClick: boolean, |}; type DragActions = {| drop: (args?: StopDragOptions) => void, cancel: (args?: StopDragOptions) => void, isActive: () => boolean, shouldRespectForcePress: () => boolean, |}; export type FluidDragActions = {| ...DragActions, move: (clientSelection: Position) => void, |}; export type SnapDragActions = {| ...DragActions, moveUp: () => void, moveDown: () => void, moveRight: () => void, moveLeft: () => void, |}; export type PreDragActions = {| // discover if the lock is still active isActive: () => boolean, // whether it has been indicated if force press should be respected shouldRespectForcePress: () => boolean, // lift the current item fluidLift: (clientSelection: Position) => FluidDragActions, snapLift: () => SnapDragActions, // cancel the pre drag without starting a drag. Releases the lock abort: () => void, |}; export type TryGetLockOptions = { sourceEvent?: Event, }; export type TryGetLock = ( draggableId: DraggableId, forceStop?: () => void, options?: TryGetLockOptions, ) => ?PreDragActions; export type SensorAPI = {| tryGetLock: TryGetLock, canGetLock: (id: DraggableId) => boolean, isLockClaimed: () => boolean, tryReleaseLock: () => void, findClosestDraggableId: (event: Event) => ?DraggableId, findOptionsForDraggable: (id: DraggableId) => ?DraggableOptions, |}; export type Sensor = (api: SensorAPI) => void;