Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use HTML Drag and Drop API [WIP] #771

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c14a0f6
Use 'draggable' attribute to indicate allowable drag targets.
PerBothner Nov 1, 2021
397afe7
Merge branch 'master' into draggable-attr
PerBothner Jan 16, 2022
39a7a04
Implement 'TitleRenderer' hook for tab titles.
PerBothner Jan 16, 2022
c21f827
Fixes to shut up lint:ts
PerBothner Jan 17, 2022
39e9d77
Tweaks and improvements to renderer-based tab layout.
PerBothner Jan 21, 2022
c563877
Use requestAnimationFrame to reduce updateTabSizes redundancy.
PerBothner Jan 24, 2022
2e8cea9
Fix two lint complaints
PerBothner Jan 24, 2022
de08994
Fix 'draggable' attribute to use true/false, not yes/no.
PerBothner Jan 31, 2022
6b0b6d9
Update drags-tests.ts for previous change.
PerBothner Jan 31, 2022
37cfe50
In tryUpdateTabSizes update _lastVisibleTabIndex.
PerBothner Feb 2, 2022
4278be8
Initial support for using browser's Drag-and-Drop API
PerBothner Feb 2, 2022
54648fc
Update _lastVisibleTabIndex when a tab is removed.
PerBothner Feb 5, 2022
de52a1d
Small drag-and-drop improvements.
PerBothner Feb 17, 2022
0681ecb
Catch iframe pointer-events in other top-level windows
PerBothner Feb 23, 2022
e2a9bb3
Add events to support drag to decktop (i.e. popout).
PerBothner Mar 25, 2022
d42455a
Implement cancel of drag
PerBothner Apr 12, 2022
64a0aab
Update README.ms with notes specific for d-n-d-api branch
PerBothner Apr 12, 2022
c62722f
Fix some lint problems
PerBothner Apr 12, 2022
27454a6
D-n-D improvements - more robust cancel, drag to desktop.
PerBothner Apr 20, 2022
194f00a
Pass extra DragEvent parameter to "dragExported" event
PerBothner Apr 25, 2022
30423b4
Update webpack dependencies to avoid openssl issue
PerBothner May 28, 2022
0f537e8
Change/simplify "virtual" bindings (in-progress).
PerBothner May 28, 2022
995f84e
Changes mostly relating to headers
PerBothner Jun 18, 2022
7f2502e
Btter border handling when using virtual components. Other changes.
PerBothner Jun 21, 2022
e818016
Remove some old commented-out code.
PerBothner Jun 21, 2022
0e0aba6
Fix some lint complaints.
PerBothner Jun 21, 2022
f291f25
Changes to splitter to work better for transparent windows
PerBothner Jun 23, 2022
e16d316
Make element visible before emitting 'dragExported'.
PerBothner Jun 25, 2022
be4a682
Fix/add some comments.
PerBothner Jul 23, 2022
a5bca25
Some tweaks for better focus behavior
PerBothner Jul 23, 2022
dcd1c55
Fix race condition between requestAnimationFrame and dragenter.
PerBothner Aug 10, 2022
c580de7
Remove deprecated transition-indicator
PerBothner Aug 10, 2022
42c6f25
New constructor GoldenLayout(config, container, position)
PerBothner Aug 10, 2022
6195d2f
Add new containerWidthAndHeight hook.
PerBothner Aug 11, 2022
5efae74
Fix lint:ts warnings
PerBothner Aug 11, 2022
a13de43
Improve cursor style for splitter
PerBothner Aug 27, 2022
37ec5ad
dark-theme: Changes for border and splitter like for light-theme
PerBothner Oct 5, 2022
2954170
Styling (light/dark): Make splitter color more distictive
PerBothner Nov 6, 2022
afd9a09
make drag-end work better using timing heuristics.
PerBothner Feb 2, 2023
0c9382d
Do drop after deferred deletions
PerBothner Feb 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ Golden Layout is a Javascript layout manager which enables you to layout compone
* Works in modern browsers (Firefox, Chrome)
* Reponsive design

The 'd-n-d-api' branch is an experimental fork making use
of the [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API).
This enables:

* Drag from one window and drop to another.
* Drag from one window and drop to desktop as new window (popout).
* Cancel a drag (usually by typing Escape before releasing mouse).

*This is experimental with an unstable API and known issues.*
It is used in the`drag-drop` branch of [DomTerm](https://github.com/PerBothner/DomTerm/).

The 'd-n-d-api' branch builds on the 'tab-renderer' branch,
which is part of [GL pull request #759](https://github.com/golden-layout/golden-layout/pull/759).

## Installation
The library can be installed into an application package with the npm command:\
`npm i golden-layout`
Expand Down
106 changes: 99 additions & 7 deletions etc/golden-layout.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ export class ComponentContainer extends EventEmitter {
_config: ResolvedComponentItemConfig,
_parent: ComponentItem,
_layoutManager: LayoutManager,
_element: HTMLElement,
_element: HTMLElement | undefined,
_updateItemConfigEvent: ComponentContainer.UpdateItemConfigEventHandler,
_showEvent: ComponentContainer.ShowEventHandler,
_hideEvent: ComponentContainer.HideEventHandler,
_focusEvent: ComponentContainer.FocusEventHandler,
_blurEvent: ComponentContainer.BlurEventHandler);
// @internal (undocumented)
addVirtualSizedContainerToLayoutManager(): void;
blur(suppressEvent?: boolean): void;
close(): void;
// (undocumented)
Expand All @@ -72,7 +74,7 @@ export class ComponentContainer extends EventEmitter {
destroy(): void;
// @internal (undocumented)
drag(): void;
get element(): HTMLElement;
get element(): HTMLElement | undefined;
// @internal
enterDragMode(width: number, height: number): void;
// @internal (undocumented)
Expand All @@ -85,7 +87,7 @@ export class ComponentContainer extends EventEmitter {
extendState(state: Record<string, unknown>): void;
focus(suppressEvent?: boolean): void;
// @deprecated (undocumented)
getElement(): HTMLElement;
getElement(): HTMLElement | undefined;
// @deprecated
getState(): JsonValue | undefined;
// (undocumented)
Expand All @@ -96,6 +98,8 @@ export class ComponentContainer extends EventEmitter {
get isHidden(): boolean;
// (undocumented)
get layoutManager(): LayoutManager;
// (undocumented)
notifyResize: ComponentContainer.NotifyResizeHandler | undefined;
// @internal (undocumented)
notifyVirtualRectingRequired(): void;
// (undocumented)
Expand All @@ -107,13 +111,13 @@ export class ComponentContainer extends EventEmitter {
setLogicalZIndex(logicalZIndex: LogicalZIndex): void;
// @internal
setSize(width: number, height: number): boolean;
// @internal
setSizeToNodeSize(width: number, height: number, force: boolean): void;
// @deprecated
setState(state: JsonValue): void;
// @internal (undocumented)
setTab(tab: Tab): void;
setTitle(title: string): void;
// (undocumented)
setTitleRenderer(renderer: Tab.TitleRenderer | undefined): void;
// @internal (undocumented)
setVisibility(value: boolean): void;
show(): void;
Expand Down Expand Up @@ -156,6 +160,8 @@ export namespace ComponentContainer {
export type FocusEventHandler = (this: void, suppressEvent: boolean) => void;
// @internal (undocumented)
export type HideEventHandler = (this: void) => void;
// (undocumented)
export type NotifyResizeHandler = (this: void, container: ComponentContainer, left: number, top: number, width: number, height: number) => void;
// @internal (undocumented)
export type ShowEventHandler = (this: void) => void;
// (undocumented)
Expand Down Expand Up @@ -226,15 +232,21 @@ export class ComponentItem extends ContentItem {
// (undocumented)
setTab(tab: Tab): void;
setTitle(title: string): void;
// (undocumented)
setTitleRenderer(renderer: Tab.TitleRenderer | undefined): void;
// @internal (undocumented)
show(): void;
// (undocumented)
get tab(): Tab;
// (undocumented)
get title(): string;
// (undocumented)
get titleRenderer(): Tab.TitleRenderer | undefined;
// (undocumented)
toConfig(): ResolvedComponentItemConfig;
// @internal (undocumented)
updateNodeSize(): void;
// @internal (undocumented)
updateSize(): void;
}

Expand Down Expand Up @@ -304,6 +316,10 @@ export abstract class ContentItem extends EventEmitter {
// (undocumented)
get id(): string;
set id(value: string);
// (undocumented)
ignoring: boolean;
// (undocumented)
ignoringChild: boolean;
// @internal
init(): void;
// @internal (undocumented)
Expand Down Expand Up @@ -380,7 +396,6 @@ export class DragSource {
constructor(
_layoutManager: LayoutManager,
_element: HTMLElement,
_extraAllowableChildTargets: HTMLElement[],
_componentTypeOrFtn: JsonValue | (() => DragSource.ComponentItemConfig),
_componentState: JsonValue | undefined,
_title: string | undefined);
Expand Down Expand Up @@ -465,13 +480,21 @@ export namespace EventEmitter {
// (undocumented)
export type ComponentItemParam = [ComponentItem];
// (undocumented)
export type DragComponentParams = [event: DragEvent, component: ComponentItem];
// (undocumented)
export type DragEventParams = [event: DragEvent];
// (undocumented)
export type DragParams = [offsetX: number, offsetY: number, event: PointerEvent];
// (undocumented)
export type DragStartParams = [originalX: number, originalY: number];
// (undocumented)
export type DragStopParams = [event: PointerEvent | undefined];
// (undocumented)
export interface EventParamsMap {
// (undocumented)
"drag-enter-window": DragEventParams;
// (undocumented)
"drag-leave-window": DragEventParams;
// (undocumented)
"__all": UnknownParams;
// (undocumented)
Expand All @@ -491,8 +514,14 @@ export namespace EventEmitter {
// (undocumented)
"drag": DragParams;
// (undocumented)
"dragend": DragEventParams;
// (undocumented)
"dragExported": DragComponentParams;
// (undocumented)
"dragStart": DragStartParams;
// (undocumented)
"dragstart": DragComponentParams;
// (undocumented)
"dragStop": DragStopParams;
// (undocumented)
"focus": BubblingEventParam;
Expand Down Expand Up @@ -663,6 +692,8 @@ export class Header extends EventEmitter {
// @internal (undocumented)
applyFocusedValue(value: boolean): void;
// (undocumented)
availableTabsSize(): number;
// (undocumented)
get controlsContainerElement(): HTMLElement;
// @internal
createTab(componentItem: ComponentItem, index: number): void;
Expand Down Expand Up @@ -921,6 +952,7 @@ export namespace LayoutConfig {
export interface Dimensions {
borderGrabWidth?: number;
borderWidth?: number;
contentInset: number;
dragProxyHeight?: number;
dragProxyWidth?: number;
headerHeight?: number;
Expand Down Expand Up @@ -975,8 +1007,11 @@ export namespace LayoutConfig {
// (undocumented)
export interface Settings {
blockedPopoutsThrowError?: boolean;
checkGlWindowKey?: boolean;
closePopoutsOnUnload?: boolean;
constrainDragToContainer?: boolean;
// (undocumented)
dragDataMimetype?: string;
// @deprecated (undocumented)
hasHeaders?: boolean;
popInOnClose?: boolean;
Expand All @@ -992,6 +1027,8 @@ export namespace LayoutConfig {
showPopoutIcon?: boolean;
tabControlOffset?: number;
tabOverlapAllowance?: number;
// (undocumented)
useDragAndDrop?: boolean;
}
// (undocumented)
export namespace Settings {
Expand Down Expand Up @@ -1032,16 +1069,30 @@ export abstract class LayoutManager extends EventEmitter {
get container(): HTMLElement;
// (undocumented)
createAndInitContentItem(config: ResolvedItemConfig, parent: ContentItem): ContentItem;
// (undocumented)
createContainerElement: (lm: LayoutManager, config: ResolvedComponentItemConfig) => HTMLElement | undefined;
// @internal
createContentItem(config: ResolvedItemConfig, parent: ContentItem): ContentItem;
createPopout(itemConfigOrContentItem: ContentItem | ResolvedRootItemConfig, positionAndSize: ResolvedPopoutLayoutConfig.Window, parentId: string | null, indexInParent: number | null): BrowserPopout;
// @internal (undocumented)
createPopoutFromContentItem(item: ContentItem, window: ResolvedPopoutLayoutConfig.Window | undefined, parentId: string | null, indexInParent: number | null | undefined): BrowserPopout;
// @internal (undocumented)
createPopoutFromPopoutLayoutConfig(config: ResolvedPopoutLayoutConfig): BrowserPopout;
// (undocumented)
_currentlyDragging: boolean;
// (undocumented)
deferIfDragging(action: (cancel: boolean) => void): void;
// @deprecated (undocumented)
get deprecatedConstructor(): boolean;
destroy(): void;
// (undocumented)
doDeferredActions(cancel: boolean): void;
// (undocumented)
dragDataMimetype(): string;
// (undocumented)
_draggedComponentItem: ComponentItem | undefined;
// (undocumented)
draggingInOtherWindow(ending: boolean): void;
// Warning: (ae-forgotten-export) The symbol "DropTargetIndicator" needs to be exported by the entry point index.d.ts
//
// @internal (undocumented)
Expand All @@ -1065,10 +1116,16 @@ export abstract class LayoutManager extends EventEmitter {
// @internal (undocumented)
get groundItem(): GroundItem | undefined;
// (undocumented)
get headersContainerElement(): HTMLElement;
// (undocumented)
get height(): number | null;
// (undocumented)
_hideTargetIndicator(): void;
// @internal
init(): void;
// (undocumented)
inSomeWindow: boolean;
// (undocumented)
get isInitialised(): boolean;
// (undocumented)
readonly isSubWindow: boolean;
Expand All @@ -1089,7 +1146,11 @@ export abstract class LayoutManager extends EventEmitter {
newItemAtLocation(itemConfig: RowOrColumnItemConfig | StackItemConfig | ComponentItemConfig, locationSelectors?: readonly LayoutManager.LocationSelector[]): ContentItem | undefined;
// (undocumented)
get openPopouts(): BrowserPopout[];
// (undocumented)
popoutClickHandler: (item: Stack, ev: Event) => boolean;
removeDragSource(dragSource: DragSource): void;
// (undocumented)
removeElementEventually(element: HTMLElement): void;
// @internal @deprecated (undocumented)
get root(): GroundItem | undefined;
// (undocumented)
Expand All @@ -1101,7 +1162,9 @@ export abstract class LayoutManager extends EventEmitter {
setMaximisedStack(stack: Stack | undefined): void;
setSize(width: number, height: number): void;
// @internal (undocumented)
startComponentDrag(x: number, y: number, dragListener: DragListener, componentItem: ComponentItem, stack: Stack): void;
startComponentDrag(ev: DragEvent, componentItem: ComponentItem): void;
// @internal (undocumented)
startComponentDragOld(x: number, y: number, dragListener: DragListener, componentItem: ComponentItem, stack: Stack): void;
// @internal (undocumented)
get tabDropPlaceholder(): HTMLElement;
// @deprecated (undocumented)
Expand All @@ -1120,6 +1183,10 @@ export abstract class LayoutManager extends EventEmitter {
// @internal (undocumented)
updateSizeFromContainer(): void;
// (undocumented)
useNativeDragAndDrop(): boolean;
// (undocumented)
validDragEvent(e: DragEvent): boolean;
// (undocumented)
get width(): number | null;
}

Expand All @@ -1129,6 +1196,8 @@ export namespace LayoutManager {
export type AfterVirtualRectingEvent = (this: void) => void;
// (undocumented)
export type BeforeVirtualRectingEvent = (this: void, count: number) => void;
const // (undocumented)
VIRTUAL_ELEMENT_DUMMY: HTMLDivElement;
// @internal (undocumented)
export interface ConstructorParameters {
// (undocumented)
Expand Down Expand Up @@ -1422,6 +1491,8 @@ export namespace ResolvedLayoutConfig {
// (undocumented)
readonly borderWidth: number;
// (undocumented)
readonly contentInset: number;
// (undocumented)
readonly dragProxyHeight: number;
// (undocumented)
readonly dragProxyWidth: number;
Expand Down Expand Up @@ -1471,10 +1542,14 @@ export namespace ResolvedLayoutConfig {
// (undocumented)
readonly blockedPopoutsThrowError: boolean;
// (undocumented)
readonly checkGlWindowKey: boolean;
// (undocumented)
readonly closePopoutsOnUnload: boolean;
// (undocumented)
readonly constrainDragToContainer: boolean;
// (undocumented)
readonly dragDataMimetype: string;
// (undocumented)
readonly popInOnClose: boolean;
// (undocumented)
readonly popoutWholeStack: boolean;
Expand All @@ -1488,6 +1563,8 @@ export namespace ResolvedLayoutConfig {
readonly tabControlOffset: number;
// (undocumented)
readonly tabOverlapAllowance: number;
// (undocumented)
readonly useDragAndDrop: boolean;
}
// (undocumented)
export namespace Settings {
Expand Down Expand Up @@ -1749,6 +1826,8 @@ export class Stack extends ComponentParentableItem {
toggleMaximise(): void;
// @internal (undocumented)
updateSize(): void;
// (undocumented)
updateTabSizes(): void;
}

// @public (undocumented)
Expand Down Expand Up @@ -1841,6 +1920,8 @@ export class Tab {
setFocused(): void;
setTitle(title: string): void;
// (undocumented)
readonly tabClickListener: (ev: MouseEvent) => void;
// (undocumented)
get titleElement(): HTMLElement;
}

Expand All @@ -1852,6 +1933,17 @@ export namespace Tab {
export type DragStartEvent = (x: number, y: number, dragListener: DragListener, componentItem: ComponentItem) => void;
// @internal (undocumented)
export type FocusEvent = (componentItem: ComponentItem) => void;
// (undocumented)
export enum RenderFlags {
// (undocumented)
DropdownActive = 1,
// (undocumented)
InDropdownMenu = 2,
// (undocumented)
IsActiveTab = 4
}
// (undocumented)
export type TitleRenderer = (component: ComponentContainer, target: HTMLElement, availableWidth: number, flags: RenderFlags) => void;
}

// @public (undocumented)
Expand Down