mirror of
https://github.com/mathuo/dockview
synced 2025-02-02 06:25:44 +00:00
Merge pull request #411 from NaNgets/388-rtl-support-gpgsigned
RTL support.
This commit is contained in:
commit
c2d65db045
@ -3,10 +3,10 @@
|
||||
|
||||
> .drop-target-dropzone {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
|
||||
@ -17,8 +17,8 @@
|
||||
width: 100%;
|
||||
background-color: var(--dv-drag-over-background-color);
|
||||
transition: top 70ms ease-out, left 70ms ease-out,
|
||||
width 70ms ease-out, height 70ms ease-out,
|
||||
opacity 0.15s ease-out;
|
||||
right 70ms ease-out, width 70ms ease-out,
|
||||
height 70ms ease-out, opacity 0.15s ease-out;
|
||||
will-change: transform;
|
||||
pointer-events: none;
|
||||
|
||||
|
@ -42,8 +42,8 @@
|
||||
|
||||
.dv-resize-handle-top {
|
||||
height: 4px;
|
||||
width: calc(100% - 8px);
|
||||
left: 4px;
|
||||
right: 4px;
|
||||
top: -2px;
|
||||
z-index: 999;
|
||||
position: absolute;
|
||||
@ -52,8 +52,8 @@
|
||||
|
||||
.dv-resize-handle-bottom {
|
||||
height: 4px;
|
||||
width: calc(100% - 8px);
|
||||
left: 4px;
|
||||
right: 4px;
|
||||
bottom: -2px;
|
||||
z-index: 999;
|
||||
position: absolute;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { DragAndDropObserver } from '../../dnd/dnd';
|
||||
import { Droptarget } from '../../dnd/droptarget';
|
||||
import { getDomNodePagePosition, toggleClass } from '../../dom';
|
||||
import { getDomNodePagePosition, hasClassInTree, toggleClass } from '../../dom';
|
||||
import { CompositeDisposable, Disposable, IDisposable } from '../../lifecycle';
|
||||
import { IDockviewPanel } from '../dockviewPanel';
|
||||
|
||||
@ -77,7 +77,9 @@ export class GreadyRenderContainer extends CompositeDisposable {
|
||||
// TODO propagate position to avoid getDomNodePagePosition calls
|
||||
const box = getDomNodePagePosition(referenceContainer.element);
|
||||
const box2 = getDomNodePagePosition(this.element);
|
||||
focusContainer.style.left = `${box.left - box2.left}px`;
|
||||
const isRtl = hasClassInTree(this.element, 'dv-rtl');
|
||||
focusContainer.style.left = isRtl ? '' : `${(box.left || 0) - (box2.left || 0)}px`;
|
||||
focusContainer.style.right = isRtl ? `${(box.right || 0) - (box2.right || 0)}px` : '';
|
||||
focusContainer.style.top = `${box.top - box2.top}px`;
|
||||
focusContainer.style.width = `${box.width}px`;
|
||||
focusContainer.style.height = `${box.height}px`;
|
||||
|
@ -63,12 +63,19 @@
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
pointer-events: none;
|
||||
background-color: var(--dv-tab-divider-color);
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
|
||||
.dv-ltr & {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.dv-rtl & {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,15 +251,15 @@ export class TabsContainer
|
||||
) {
|
||||
event.preventDefault();
|
||||
|
||||
const { top, left } =
|
||||
const { top, left, right } =
|
||||
this.element.getBoundingClientRect();
|
||||
const { top: rootTop, left: rootLeft } =
|
||||
const { top: rootTop, left: rootLeft, right: rootRight } =
|
||||
this.accessor.element.getBoundingClientRect();
|
||||
|
||||
this.accessor.addFloatingGroup(
|
||||
this.group,
|
||||
{
|
||||
x: left - rootLeft + 20,
|
||||
x: (this.accessor.options.isRtl ? (right - rootRight) : (left - rootLeft)) + 20,
|
||||
y: top - rootTop + 20,
|
||||
},
|
||||
{ inDragMode: true }
|
||||
@ -361,14 +361,14 @@ export class TabsContainer
|
||||
|
||||
const panel = this.accessor.getGroupPanel(tab.panel.id);
|
||||
|
||||
const { top, left } = tab.element.getBoundingClientRect();
|
||||
const { top: rootTop, left: rootLeft } =
|
||||
const { top, left, right } = tab.element.getBoundingClientRect();
|
||||
const { top: rootTop, left: rootLeft, right: rootRight } =
|
||||
this.accessor.element.getBoundingClientRect();
|
||||
|
||||
this.accessor.addFloatingGroup(
|
||||
panel as DockviewPanel,
|
||||
{
|
||||
x: left - rootLeft,
|
||||
x: (this.accessor.options.isRtl ? (right - rootRight) : (left - rootLeft)) + 20,
|
||||
y: top - rootTop,
|
||||
},
|
||||
{ inDragMode: true }
|
||||
|
@ -2,12 +2,20 @@
|
||||
position: relative;
|
||||
background-color: var(--dv-group-view-background-color);
|
||||
|
||||
&.dv-ltr {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
&.dv-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.dv-watermark-container {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
@ -316,6 +316,7 @@ export class DockviewComponent
|
||||
styles: options.styles,
|
||||
parentElement: options.parentElement,
|
||||
disableAutoResizing: options.disableAutoResizing,
|
||||
isRtl: options.isRtl,
|
||||
});
|
||||
|
||||
const gready = document.createElement('div');
|
||||
@ -1007,7 +1008,8 @@ export class DockviewComponent
|
||||
const relativeLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
location,
|
||||
target
|
||||
target,
|
||||
this.options.isRtl
|
||||
);
|
||||
const group = this.createGroupAtLocation(relativeLocation);
|
||||
panel = this.createPanel(options, group);
|
||||
@ -1155,7 +1157,8 @@ export class DockviewComponent
|
||||
const relativeLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
location,
|
||||
target
|
||||
target,
|
||||
this.options.isRtl
|
||||
);
|
||||
this.doAddGroup(group, relativeLocation);
|
||||
return group;
|
||||
@ -1270,7 +1273,8 @@ export class DockviewComponent
|
||||
const targetLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
referenceLocation,
|
||||
destinationTarget
|
||||
destinationTarget,
|
||||
this.options.isRtl
|
||||
);
|
||||
|
||||
if (sourceGroup && sourceGroup.size < 2) {
|
||||
@ -1310,7 +1314,8 @@ export class DockviewComponent
|
||||
const location = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
updatedReferenceLocation,
|
||||
destinationTarget
|
||||
destinationTarget,
|
||||
this.options.isRtl
|
||||
);
|
||||
this.doAddGroup(targetGroup, location);
|
||||
} else {
|
||||
@ -1325,7 +1330,8 @@ export class DockviewComponent
|
||||
const dropLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
referenceLocation,
|
||||
destinationTarget
|
||||
destinationTarget,
|
||||
this.options.isRtl
|
||||
);
|
||||
|
||||
const group = this.createGroupAtLocation(dropLocation);
|
||||
@ -1374,7 +1380,8 @@ export class DockviewComponent
|
||||
const dropLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
referenceLocation,
|
||||
target
|
||||
target,
|
||||
this.options.isRtl
|
||||
);
|
||||
|
||||
this.gridview.addView(
|
||||
|
@ -7,7 +7,7 @@ export interface IDockviewFloatingGroupPanel {
|
||||
position(
|
||||
bounds: Partial<{
|
||||
top: number;
|
||||
left: number;
|
||||
side: number;
|
||||
height: number;
|
||||
width: number;
|
||||
}>
|
||||
@ -27,7 +27,7 @@ export class DockviewFloatingGroupPanel
|
||||
position(
|
||||
bounds: Partial<{
|
||||
top: number;
|
||||
left: number;
|
||||
side: number;
|
||||
height: number;
|
||||
width: number;
|
||||
}>
|
||||
|
@ -98,6 +98,7 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions {
|
||||
minimumWidthWithinViewport?: number;
|
||||
};
|
||||
defaultRenderer?: DockviewPanelRenderer;
|
||||
isRtl?: boolean;
|
||||
debug?: boolean;
|
||||
}
|
||||
|
||||
|
@ -186,15 +186,29 @@ export function quasiDefaultPrevented(event: Event): boolean {
|
||||
return (event as any)[QUASI_PREVENT_DEFAULT_KEY];
|
||||
}
|
||||
|
||||
// Gets whether the given class exists in the element or its parent tree
|
||||
export function hasClassInTree(domNode: Element, className: string): boolean {
|
||||
if (domNode.classList.contains(className)) {
|
||||
return true;
|
||||
}
|
||||
if (domNode.parentElement) {
|
||||
return hasClassInTree(domNode.parentElement, className);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getDomNodePagePosition(domNode: Element): {
|
||||
left: number;
|
||||
left?: number;
|
||||
right?: number;
|
||||
top: number;
|
||||
width: number;
|
||||
height: number;
|
||||
} {
|
||||
const { left, top, width, height } = domNode.getBoundingClientRect();
|
||||
const isRtl = hasClassInTree(domNode, 'dv-rtl');
|
||||
const { left, right, top, width, height } = domNode.getBoundingClientRect();
|
||||
return {
|
||||
left: left + window.scrollX,
|
||||
left: isRtl ? undefined : left + window.scrollX,
|
||||
right: isRtl ? right + window.scrollX : undefined,
|
||||
top: top + window.scrollY,
|
||||
width: width,
|
||||
height: height,
|
||||
|
@ -7,6 +7,7 @@ import { ISplitviewStyles, Orientation, Sizing } from '../splitview/splitview';
|
||||
import { IPanel } from '../panel/types';
|
||||
import { MovementOptions2 } from '../dockview/options';
|
||||
import { Resizable } from '../resizable';
|
||||
import { toggleClass } from '../dom';
|
||||
|
||||
const nextLayoutId = sequentialNumberGenerator();
|
||||
|
||||
@ -34,6 +35,7 @@ export interface BaseGridOptions {
|
||||
readonly styles?: ISplitviewStyles;
|
||||
readonly parentElement?: HTMLElement;
|
||||
readonly disableAutoResizing?: boolean;
|
||||
readonly isRtl?: boolean;
|
||||
}
|
||||
|
||||
export interface IGridPanelView extends IGridView, IPanel {
|
||||
@ -137,6 +139,9 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
||||
options.orientation
|
||||
);
|
||||
|
||||
toggleClass(this.gridview.element, 'dv-rtl', options.isRtl === true);
|
||||
toggleClass(this.gridview.element, 'dv-ltr', options.isRtl === false);
|
||||
|
||||
this.element.appendChild(this.gridview.element);
|
||||
|
||||
this.layout(0, 0, true); // set some elements height/widths
|
||||
|
@ -2,4 +2,12 @@
|
||||
.branch-node {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
&.dv-ltr {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
&.dv-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +123,8 @@ export function getGridLocation(element: HTMLElement): number[] {
|
||||
export function getRelativeLocation(
|
||||
rootOrientation: Orientation,
|
||||
location: number[],
|
||||
direction: Position
|
||||
direction: Position,
|
||||
isRtl?: boolean
|
||||
): number[] {
|
||||
const orientation = getLocationOrientation(rootOrientation, location);
|
||||
const directionOrientation = getDirectionOrientation(direction);
|
||||
@ -132,13 +133,13 @@ export function getRelativeLocation(
|
||||
const [rest, _index] = tail(location);
|
||||
let index = _index;
|
||||
|
||||
if (direction === 'right' || direction === 'bottom') {
|
||||
if ((isRtl ? direction === 'left' : direction === 'right') || direction === 'bottom') {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
return [...rest, index];
|
||||
} else {
|
||||
const index = direction === 'right' || direction === 'bottom' ? 1 : 0;
|
||||
const index = (isRtl ? direction === 'left' : direction === 'right') || direction === 'bottom' ? 1 : 0;
|
||||
return [...location, index];
|
||||
}
|
||||
}
|
||||
|
@ -110,6 +110,7 @@ export class GridviewComponent
|
||||
orientation: options.orientation,
|
||||
styles: options.styles,
|
||||
disableAutoResizing: options.disableAutoResizing,
|
||||
isRtl: options.isRtl,
|
||||
});
|
||||
|
||||
this._options = options;
|
||||
@ -299,7 +300,8 @@ export class GridviewComponent
|
||||
relativeLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
location,
|
||||
target
|
||||
target,
|
||||
this.options.isRtl
|
||||
);
|
||||
}
|
||||
|
||||
@ -330,7 +332,8 @@ export class GridviewComponent
|
||||
relativeLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
location,
|
||||
target
|
||||
target,
|
||||
this.options.isRtl
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -406,7 +409,8 @@ export class GridviewComponent
|
||||
const targetLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
referenceLocation,
|
||||
target
|
||||
target,
|
||||
this.options.isRtl
|
||||
);
|
||||
|
||||
const [targetParentLocation, to] = tail(targetLocation);
|
||||
@ -435,7 +439,8 @@ export class GridviewComponent
|
||||
const location = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
updatedReferenceLocation,
|
||||
target
|
||||
target,
|
||||
this.options.isRtl
|
||||
);
|
||||
this.doAddGroup(targetGroup, location);
|
||||
}
|
||||
|
@ -17,5 +17,6 @@ export interface GridviewComponentOptions {
|
||||
};
|
||||
frameworkComponentFactory?: FrameworkFactory<GridviewPanel>;
|
||||
styles?: ISplitviewStyles;
|
||||
isRtl?: boolean;
|
||||
parentElement?: HTMLElement;
|
||||
}
|
||||
|
@ -146,14 +146,29 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
|
||||
const fromIndex = allPanels.indexOf(existingPanel);
|
||||
let toIndex = containerApi.panels.indexOf(this);
|
||||
|
||||
console.log('onDrop', this.accessor.options.isRtl, fromIndex, toIndex, event.position);
|
||||
|
||||
if (event.position === 'left' || event.position === 'top') {
|
||||
toIndex = Math.max(0, toIndex - 1);
|
||||
if (this.accessor.options.isRtl) {
|
||||
if (fromIndex > toIndex) {
|
||||
toIndex++;
|
||||
}
|
||||
toIndex = Math.min(allPanels.length - 1, toIndex);
|
||||
}
|
||||
else {
|
||||
toIndex = Math.max(0, toIndex - 1);
|
||||
}
|
||||
}
|
||||
if (event.position === 'right' || event.position === 'bottom') {
|
||||
if (fromIndex > toIndex) {
|
||||
toIndex++;
|
||||
if (this.accessor.options.isRtl) {
|
||||
toIndex = Math.max(0, toIndex - 1);
|
||||
}
|
||||
else {
|
||||
if (fromIndex > toIndex) {
|
||||
toIndex++;
|
||||
}
|
||||
toIndex = Math.min(allPanels.length - 1, toIndex);
|
||||
}
|
||||
toIndex = Math.min(allPanels.length - 1, toIndex);
|
||||
}
|
||||
|
||||
containerApi.movePanel(fromIndex, toIndex);
|
||||
|
@ -26,4 +26,5 @@ export interface PaneviewComponentOptions {
|
||||
disableDnd?: boolean;
|
||||
showDndOverlay?: (event: PaneviewDndOverlayEvent) => boolean;
|
||||
parentElement?: HTMLElement;
|
||||
isRtl?: boolean;
|
||||
}
|
||||
|
@ -2,6 +2,18 @@
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
&.dv-ltr {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
&.dv-rtl {
|
||||
direction: rtl;
|
||||
|
||||
.view .default-header .dockview-pane-header-icon {
|
||||
transform: scale(-1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
&.animated {
|
||||
.view {
|
||||
transition-duration: 0.15s;
|
||||
@ -38,8 +50,8 @@
|
||||
}
|
||||
|
||||
> span {
|
||||
padding-left: 8px;
|
||||
flex-grow: 1;
|
||||
padding-inline-start: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,7 +82,7 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
z-index: 5;
|
||||
content: '';
|
||||
@ -96,7 +108,7 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
z-index: 5;
|
||||
content: '';
|
||||
|
@ -6,7 +6,7 @@ import {
|
||||
} from '../splitview/splitview';
|
||||
import { CompositeDisposable, IDisposable } from '../lifecycle';
|
||||
import { Emitter, Event } from '../events';
|
||||
import { addClasses, removeClasses } from '../dom';
|
||||
import { addClasses, removeClasses, toggleClass } from '../dom';
|
||||
import { PaneviewPanel } from './paneviewPanel';
|
||||
|
||||
interface PaneItem {
|
||||
@ -54,7 +54,7 @@ export class Paneview extends CompositeDisposable implements IDisposable {
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
options: { orientation: Orientation; descriptor?: ISplitViewDescriptor }
|
||||
options: { orientation: Orientation; isRtl?: boolean; descriptor?: ISplitViewDescriptor }
|
||||
) {
|
||||
super();
|
||||
|
||||
@ -63,12 +63,16 @@ export class Paneview extends CompositeDisposable implements IDisposable {
|
||||
this.element = document.createElement('div');
|
||||
this.element.className = 'pane-container';
|
||||
|
||||
toggleClass(this.element, 'dv-rtl', options.isRtl === true);
|
||||
toggleClass(this.element, 'dv-ltr', options.isRtl === false);
|
||||
|
||||
container.appendChild(this.element);
|
||||
|
||||
this.splitview = new Splitview(this.element, {
|
||||
orientation: this._orientation,
|
||||
proportionalLayout: false,
|
||||
descriptor: options.descriptor,
|
||||
isRtl: options.isRtl,
|
||||
});
|
||||
|
||||
// if we've added views from the descriptor we need to
|
||||
|
@ -24,6 +24,7 @@ import { sequentialNumberGenerator } from '../math';
|
||||
import { PaneTransfer } from '../dnd/dataTransfer';
|
||||
import { Resizable } from '../resizable';
|
||||
import { Parameters } from '../panel/types';
|
||||
import { toggleClass } from '../dom';
|
||||
|
||||
const nextLayoutId = sequentialNumberGenerator();
|
||||
|
||||
@ -221,6 +222,7 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
|
||||
this.paneview = new Paneview(this.element, {
|
||||
// only allow paneview in the vertical orientation for now
|
||||
orientation: Orientation.VERTICAL,
|
||||
isRtl: options.isRtl,
|
||||
});
|
||||
|
||||
this.addDisposables(this._disposable);
|
||||
@ -369,6 +371,7 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
|
||||
|
||||
this.paneview = new Paneview(this.element, {
|
||||
orientation: Orientation.VERTICAL,
|
||||
isRtl: this.options.isRtl,
|
||||
descriptor: {
|
||||
size,
|
||||
views: views.map((view) => {
|
||||
|
@ -25,6 +25,22 @@
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
&.dv-ltr {
|
||||
direction: ltr;
|
||||
|
||||
&.separator-border .view:not(:first-child)::before {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.dv-rtl {
|
||||
direction: rtl;
|
||||
|
||||
&.separator-border .view:not(:first-child)::before {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.animation {
|
||||
.view,
|
||||
.sash {
|
||||
@ -145,7 +161,6 @@
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
pointer-events: none;
|
||||
background-color: var(--dv-separator-border);
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
addClasses,
|
||||
toggleClass,
|
||||
getElementsByTagName,
|
||||
hasClassInTree,
|
||||
} from '../dom';
|
||||
import { Event, Emitter } from '../events';
|
||||
import { pushToStart, pushToEnd, firstIndex } from '../array';
|
||||
@ -36,6 +37,7 @@ export interface SplitViewOptions {
|
||||
readonly descriptor?: ISplitViewDescriptor;
|
||||
readonly proportionalLayout?: boolean;
|
||||
readonly styles?: ISplitviewStyles;
|
||||
readonly isRtl?: boolean;
|
||||
}
|
||||
|
||||
export enum LayoutPriority {
|
||||
@ -201,7 +203,7 @@ export class Splitview {
|
||||
options: SplitViewOptions
|
||||
) {
|
||||
this._orientation = options.orientation;
|
||||
this.element = this.createContainer();
|
||||
this.element = this.createContainer(options.isRtl);
|
||||
|
||||
this.proportionalLayout =
|
||||
options.proportionalLayout === undefined
|
||||
@ -756,6 +758,7 @@ export class Splitview {
|
||||
|
||||
private layoutViews(): void {
|
||||
this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
|
||||
const isRtl = hasClassInTree(this.element, 'dv-rtl');
|
||||
let sum = 0;
|
||||
const x: number[] = [];
|
||||
|
||||
@ -768,18 +771,21 @@ export class Splitview {
|
||||
const offset = Math.min(Math.max(0, sum - 2), this.size - 4);
|
||||
|
||||
if (this._orientation === Orientation.HORIZONTAL) {
|
||||
this.sashes[i].container.style.left = `${offset}px`;
|
||||
this.sashes[i].container.style.left = isRtl ? '' : `${offset}px`;
|
||||
this.sashes[i].container.style.right = isRtl ? `${offset}px` : '';
|
||||
this.sashes[i].container.style.top = `0px`;
|
||||
}
|
||||
if (this._orientation === Orientation.VERTICAL) {
|
||||
this.sashes[i].container.style.left = `0px`;
|
||||
this.sashes[i].container.style.left = isRtl ? '' : `0px`;
|
||||
this.sashes[i].container.style.right = isRtl ? `0px` : '';
|
||||
this.sashes[i].container.style.top = `${offset}px`;
|
||||
}
|
||||
}
|
||||
this.viewItems.forEach((view, i) => {
|
||||
if (this._orientation === Orientation.HORIZONTAL) {
|
||||
view.container.style.width = `${view.size}px`;
|
||||
view.container.style.left = i == 0 ? '0px' : `${x[i - 1]}px`;
|
||||
view.container.style.left = isRtl ? '' : (i == 0 ? '0px' : `${x[i - 1]}px`);
|
||||
view.container.style.right = isRtl ? (i == 0 ? '0px' : `${x[i - 1]}px`) : '';
|
||||
view.container.style.top = '';
|
||||
view.container.style.height = '';
|
||||
}
|
||||
@ -788,6 +794,7 @@ export class Splitview {
|
||||
view.container.style.top = i == 0 ? '0px' : `${x[i - 1]}px`;
|
||||
view.container.style.width = '';
|
||||
view.container.style.left = '';
|
||||
view.container.style.right = '';
|
||||
}
|
||||
|
||||
view.view.layout(view.size, this._orthogonalSize);
|
||||
@ -918,8 +925,10 @@ export class Splitview {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const upIndexes = range(index, -1);
|
||||
const downIndexes = range(index + 1, this.viewItems.length);
|
||||
const isHorizontal = this._orientation === Orientation.HORIZONTAL;
|
||||
const isRtl = hasClassInTree(this.element, 'dv-rtl');
|
||||
const upIndexes = isHorizontal && isRtl && this.viewItems.length > 1 ? range(index + 1, this.viewItems.length) : range(index, -1);
|
||||
const downIndexes = isHorizontal && isRtl && this.viewItems.length > 1 ? range(index, -1) : range(index + 1, this.viewItems.length);
|
||||
//
|
||||
if (highPriorityIndexes) {
|
||||
for (const i of highPriorityIndexes) {
|
||||
@ -955,7 +964,6 @@ export class Splitview {
|
||||
? Number.POSITIVE_INFINITY
|
||||
: downIndexes.reduce(
|
||||
(_, i) => _ + sizes[i] - this.viewItems[i].minimumSize,
|
||||
|
||||
0
|
||||
);
|
||||
const minDeltaDown =
|
||||
@ -1044,13 +1052,15 @@ export class Splitview {
|
||||
return element;
|
||||
}
|
||||
|
||||
private createContainer(): HTMLElement {
|
||||
private createContainer(isRtl?: boolean): HTMLElement {
|
||||
const element = document.createElement('div');
|
||||
const orientationClassname =
|
||||
this._orientation === Orientation.HORIZONTAL
|
||||
? 'horizontal'
|
||||
: 'vertical';
|
||||
element.className = `split-view-container ${orientationClassname}`;
|
||||
toggleClass(element, 'dv-rtl', isRtl === true);
|
||||
toggleClass(element, 'dv-ltr', isRtl === false);
|
||||
return element;
|
||||
}
|
||||
|
||||
|
@ -349,6 +349,7 @@ export class SplitviewComponent
|
||||
this.splitview = new Splitview(this.element, {
|
||||
orientation,
|
||||
proportionalLayout: this.options.proportionalLayout,
|
||||
isRtl: this.options.isRtl,
|
||||
descriptor: {
|
||||
size,
|
||||
views: views.map((view) => {
|
||||
|
@ -185,9 +185,9 @@
|
||||
&::after {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
content: '';
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #94527e;
|
||||
z-index: 999;
|
||||
@ -205,9 +205,9 @@
|
||||
&::after {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
content: '';
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #5e3d5a;
|
||||
z-index: 999;
|
||||
|
@ -77,6 +77,7 @@ export interface IDockviewReactProps {
|
||||
minimumHeightWithinViewport?: number;
|
||||
minimumWidthWithinViewport?: number;
|
||||
};
|
||||
isRtl?: boolean;
|
||||
debug?: boolean;
|
||||
defaultRenderer?: DockviewPanelRenderer;
|
||||
}
|
||||
@ -179,6 +180,7 @@ export const DockviewReact = React.forwardRef(
|
||||
disableFloatingGroups: props.disableFloatingGroups,
|
||||
floatingGroupBounds: props.floatingGroupBounds,
|
||||
defaultRenderer: props.defaultRenderer,
|
||||
isRtl: props.isRtl,
|
||||
debug: props.debug,
|
||||
});
|
||||
|
||||
|
@ -28,6 +28,7 @@ export interface IGridviewReactProps {
|
||||
className?: string;
|
||||
proportionalLayout?: boolean;
|
||||
disableAutoResizing?: boolean;
|
||||
isRtl?: boolean;
|
||||
}
|
||||
|
||||
export const GridviewReact = React.forwardRef(
|
||||
@ -69,6 +70,7 @@ export const GridviewReact = React.forwardRef(
|
||||
styles: props.hideBorders
|
||||
? { separatorBorder: 'transparent' }
|
||||
: undefined,
|
||||
isRtl: props.isRtl,
|
||||
});
|
||||
|
||||
const { clientWidth, clientHeight } = domRef.current;
|
||||
|
@ -27,6 +27,7 @@ export interface IPaneviewReactProps {
|
||||
components: PanelCollection<IPaneviewPanelProps>;
|
||||
headerComponents?: PanelCollection<IPaneviewPanelProps>;
|
||||
className?: string;
|
||||
isRtl?: boolean;
|
||||
disableAutoResizing?: boolean;
|
||||
disableDnd?: boolean;
|
||||
showDndOverlay?: (event: PaneviewDndOverlayEvent) => boolean;
|
||||
@ -68,6 +69,7 @@ export const PaneviewReact = React.forwardRef(
|
||||
},
|
||||
},
|
||||
showDndOverlay: props.showDndOverlay,
|
||||
isRtl: props.isRtl,
|
||||
});
|
||||
|
||||
const api = new PaneviewApi(paneview);
|
||||
|
@ -27,6 +27,7 @@ export interface ISplitviewReactProps {
|
||||
proportionalLayout?: boolean;
|
||||
hideBorders?: boolean;
|
||||
className?: string;
|
||||
isRtl?: boolean;
|
||||
disableAutoResizing?: boolean;
|
||||
}
|
||||
|
||||
@ -62,6 +63,7 @@ export const SplitviewReact = React.forwardRef(
|
||||
styles: props.hideBorders
|
||||
? { separatorBorder: 'transparent' }
|
||||
: undefined,
|
||||
isRtl: props.isRtl,
|
||||
});
|
||||
|
||||
const { clientWidth, clientHeight } = domRef.current!;
|
||||
|
@ -890,3 +890,34 @@ If you wish to interact with the drop event from one dockview instance in anothe
|
||||
### Window-like mananger with tabs
|
||||
|
||||
<DockviewNative2 />
|
||||
|
||||
## RTL support
|
||||
|
||||
You can set the dockview to RTL using the `isRtl` property.
|
||||
|
||||
<MultiFrameworkContainer
|
||||
sandboxId="simple-dockview"
|
||||
react={SimpleDockview}
|
||||
isRtl={true}
|
||||
/>
|
||||
|
||||
<MultiFrameworkContainer
|
||||
sandboxId="watermark-dockview"
|
||||
react={DockviewWatermark}
|
||||
isRtl={true}
|
||||
/>
|
||||
|
||||
<MultiFrameworkContainer
|
||||
height={600}
|
||||
sandboxId="floatinggroup-dockview"
|
||||
react={DockviewFloating}
|
||||
isRtl={true}
|
||||
/>
|
||||
|
||||
<MultiFrameworkContainer
|
||||
sandboxId="groupcontrol-dockview"
|
||||
react={DockviewGroupControl}
|
||||
isRtl={true}
|
||||
/>
|
||||
|
||||
<DockviewNative2 isRtl={true} />
|
||||
|
@ -27,7 +27,7 @@ Gridview serves a purpose when you want only the nested splitviews with no tabs
|
||||
## GridviewReact Component
|
||||
|
||||
```tsx
|
||||
import { ReactGridview } from 'dockview';
|
||||
import { GridviewReact } from 'dockview';
|
||||
```
|
||||
|
||||
<DocRef declaration="IGridviewReactProps" />
|
||||
@ -233,3 +233,14 @@ You can find more details on theming <Link to="../theme">here</Link>.
|
||||
react={EditorGridview}
|
||||
hideThemePicker={true}
|
||||
/>
|
||||
|
||||
## RTL support
|
||||
|
||||
You can set the gridview to RTL using the `isRtl` property.
|
||||
|
||||
<MultiFrameworkContainer
|
||||
height={600}
|
||||
sandboxId="simple-gridview"
|
||||
react={SimpleGridview}
|
||||
isRtl={true}
|
||||
/>
|
||||
|
@ -93,10 +93,10 @@ SimplePaneview = () => {
|
||||
|
||||
## PaneviewReact Component
|
||||
|
||||
You can create a Paneview through the use of the `ReactPaneview` component.
|
||||
You can create a Paneview through the use of the `PaneviewReact` component.
|
||||
|
||||
```tsx
|
||||
import { ReactPaneview } from 'dockview';
|
||||
import { PaneviewReact } from 'dockview';
|
||||
```
|
||||
|
||||
<DocRef declaration="IPaneviewReactProps" />
|
||||
@ -167,7 +167,7 @@ const onReady = (event: PaneviewReadyEvent) => {
|
||||
};
|
||||
```
|
||||
|
||||
This header must be defined in the collection of components provided to the `headerComponents` props for `ReactPaneivew`
|
||||
This header must be defined in the collection of components provided to the `headerComponents` props for `PaneviewReact`
|
||||
|
||||
```tsx
|
||||
import { IPaneviewPanelProps } from 'dockview';
|
||||
@ -226,3 +226,9 @@ If you wish to interact with the drop event from one paneview instance in anothe
|
||||
As an example see how dragging a header from one control to another will only trigger an interactable event for the developer if the checkbox is enabled.
|
||||
|
||||
<SideBySidePaneview />
|
||||
|
||||
## RTL support
|
||||
|
||||
You can set the paneview to RTL using the `isRtl` property.
|
||||
|
||||
<MultiFrameworkContainer sandboxId="simple-paneview" react={SimplePaneview} isRtl={true} />
|
||||
|
@ -194,3 +194,18 @@ api.setConstraints({
|
||||
minimumSize: 400,
|
||||
});
|
||||
```
|
||||
|
||||
## RTL support
|
||||
|
||||
You can set the splitview to RTL using the `isRtl` property.
|
||||
|
||||
<div
|
||||
style={{
|
||||
height: '100px',
|
||||
backgroundColor: 'rgb(30,30,30)',
|
||||
color: 'white',
|
||||
margin: '20px 0px',
|
||||
}}
|
||||
>
|
||||
<SimpleSplitview isRtl={true} />
|
||||
</div>
|
||||
|
@ -127,7 +127,7 @@ const useLocalStorage = <T,>(
|
||||
];
|
||||
};
|
||||
|
||||
export const DockviewPersistance = (props: { theme?: string }) => {
|
||||
export const DockviewPersistance = (props: { isRtl?: boolean; theme?: string; }) => {
|
||||
const [api, setApi] = React.useState<DockviewApi>();
|
||||
const [layout, setLayout] =
|
||||
useLocalStorage<SerializedDockview>('floating.layout');
|
||||
@ -235,6 +235,7 @@ export const DockviewPersistance = (props: { theme?: string }) => {
|
||||
rightHeaderActionsComponent={RightComponent}
|
||||
disableFloatingGroups={disableFloatingGroups}
|
||||
floatingGroupBounds={options}
|
||||
isRtl={props.isRtl}
|
||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
||||
/>
|
||||
</div>
|
||||
|
@ -55,7 +55,7 @@ const LeftHeaderActions = (props: IDockviewHeaderActionsProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const DockviewGroupControl = (props: { theme: string }) => {
|
||||
const DockviewGroupControl = (props: { isRtl?: boolean; theme: string; }) => {
|
||||
const onReady = (event: DockviewReadyEvent) => {
|
||||
const panel1 = event.api.addPanel({
|
||||
id: 'panel_1',
|
||||
@ -97,6 +97,7 @@ const DockviewGroupControl = (props: { theme: string }) => {
|
||||
components={components}
|
||||
leftHeaderActionsComponent={LeftHeaderActions}
|
||||
rightHeaderActionsComponent={RightHeaderActions}
|
||||
isRtl={props.isRtl}
|
||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
||||
/>
|
||||
);
|
||||
|
@ -25,7 +25,7 @@ const components = {
|
||||
);
|
||||
},
|
||||
isolatedApp: (
|
||||
props: IDockviewPanelProps<{ title: string; x?: number }>
|
||||
props: IDockviewPanelProps<{ title: string; isRtl?: boolean; x?: number }>
|
||||
) => {
|
||||
const onReady = (event: DockviewReadyEvent) => {
|
||||
const panel1 = event.api.addPanel({
|
||||
@ -55,6 +55,7 @@ const components = {
|
||||
onReady={onReady}
|
||||
components={components}
|
||||
tabComponents={tabComponents}
|
||||
isRtl={props.params.isRtl}
|
||||
className="dockview-theme-abyss"
|
||||
/>
|
||||
);
|
||||
@ -82,7 +83,7 @@ const tabComponents = {
|
||||
},
|
||||
};
|
||||
|
||||
const DockviewNative2 = (props: { theme?: string }) => {
|
||||
const DockviewNative2 = (props: { isRtl?: boolean; theme?: string; }) => {
|
||||
const onReady = (event: DockviewReadyEvent) => {
|
||||
const panel1 = event.api.addPanel({
|
||||
id: 'panel_1',
|
||||
@ -90,6 +91,7 @@ const DockviewNative2 = (props: { theme?: string }) => {
|
||||
tabComponent: 'default',
|
||||
params: {
|
||||
title: 'Window 1',
|
||||
isRtl: props.isRtl,
|
||||
},
|
||||
});
|
||||
panel1.group.locked = true;
|
||||
@ -100,6 +102,7 @@ const DockviewNative2 = (props: { theme?: string }) => {
|
||||
tabComponent: 'default',
|
||||
params: {
|
||||
title: 'Window 2',
|
||||
isRtl: props.isRtl,
|
||||
},
|
||||
position: {
|
||||
direction: 'right',
|
||||
@ -113,6 +116,7 @@ const DockviewNative2 = (props: { theme?: string }) => {
|
||||
tabComponent: 'default',
|
||||
params: {
|
||||
title: 'Window 3',
|
||||
isRtl: props.isRtl,
|
||||
},
|
||||
position: {
|
||||
direction: 'below',
|
||||
@ -133,6 +137,7 @@ const DockviewNative2 = (props: { theme?: string }) => {
|
||||
onReady={onReady}
|
||||
components={components}
|
||||
tabComponents={tabComponents}
|
||||
isRtl={props.isRtl}
|
||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
||||
singleTabMode="fullwidth"
|
||||
/>
|
||||
|
@ -15,7 +15,7 @@ const components = {
|
||||
},
|
||||
};
|
||||
|
||||
export const App: React.FC = (props: { theme?: string }) => {
|
||||
export const App: React.FC = (props: { isRtl?: boolean; theme?: string; }) => {
|
||||
const onReady = (event: DockviewReadyEvent) => {
|
||||
const panel = event.api.addPanel({
|
||||
id: 'panel_1',
|
||||
@ -87,6 +87,7 @@ export const App: React.FC = (props: { theme?: string }) => {
|
||||
return (
|
||||
<DockviewReact
|
||||
components={components}
|
||||
isRtl={props.isRtl}
|
||||
onReady={onReady}
|
||||
className={props.theme || 'dockview-theme-abyss'}
|
||||
/>
|
||||
|
@ -18,7 +18,7 @@ const components = {
|
||||
},
|
||||
};
|
||||
|
||||
export const App: React.FC = (props: { theme?: string }) => {
|
||||
export const App: React.FC = (props: { isRtl?: boolean; theme?: string; }) => {
|
||||
const [api, setApi] = React.useState<GridviewApi>();
|
||||
|
||||
const onReady = (event: GridviewReadyEvent) => {
|
||||
@ -135,6 +135,7 @@ export const App: React.FC = (props: { theme?: string }) => {
|
||||
onReady={onReady}
|
||||
// proportionalLayout={false}
|
||||
orientation={Orientation.VERTICAL}
|
||||
isRtl={props.isRtl}
|
||||
className={props.theme || 'dockview-theme-abyss'}
|
||||
/>
|
||||
</div>
|
||||
|
@ -61,7 +61,7 @@ const headerComponents = {
|
||||
myHeaderComponent: MyHeaderComponent,
|
||||
};
|
||||
|
||||
export const App: React.FC = (props: { theme?: string }) => {
|
||||
export const App: React.FC = (props: { isRtl?: boolean; theme?: string; }) => {
|
||||
const onReady = (event: PaneviewReadyEvent) => {
|
||||
event.api.addPanel({
|
||||
id: 'panel_1',
|
||||
@ -96,6 +96,7 @@ export const App: React.FC = (props: { theme?: string }) => {
|
||||
components={components}
|
||||
headerComponents={headerComponents}
|
||||
onReady={onReady}
|
||||
isRtl={props.isRtl}
|
||||
className={props.theme || 'dockview-theme-abyss'}
|
||||
/>
|
||||
);
|
||||
|
@ -81,7 +81,7 @@ const Watermark = (props: IWatermarkPanelProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const DockviewWatermark = (props: { theme?: string }) => {
|
||||
const DockviewWatermark = (props: { isRtl?: boolean; theme?: string; }) => {
|
||||
const [api, setApi] = React.useState<DockviewApi>();
|
||||
|
||||
const onReady = (event: DockviewReadyEvent) => {
|
||||
@ -126,6 +126,7 @@ const DockviewWatermark = (props: { theme?: string }) => {
|
||||
onReady={onReady}
|
||||
components={components}
|
||||
watermarkComponent={Watermark}
|
||||
isRtl={props.isRtl}
|
||||
className={`${props.theme || 'dockview-theme-abyss'}`}
|
||||
/>
|
||||
</div>
|
||||
|
@ -12,7 +12,7 @@ const components = {
|
||||
},
|
||||
};
|
||||
|
||||
export const SimpleSplitview = (props: { proportional?: boolean }) => {
|
||||
export const SimpleSplitview = (props: { isRtl?: boolean; proportional?: boolean }) => {
|
||||
const onReady = (event: SplitviewReadyEvent) => {
|
||||
event.api.addPanel({
|
||||
id: 'panel_1',
|
||||
@ -48,6 +48,7 @@ export const SimpleSplitview = (props: { proportional?: boolean }) => {
|
||||
proportionalLayout={props.proportional}
|
||||
onReady={onReady}
|
||||
orientation={Orientation.HORIZONTAL}
|
||||
isRtl={props.isRtl}
|
||||
className="dockview-theme-abyss"
|
||||
/>
|
||||
);
|
||||
|
@ -149,6 +149,7 @@ export const MultiFrameworkContainer2 = (props: {
|
||||
typescript?: (parent: HTMLElement) => { dispose: () => void };
|
||||
sandboxId: string;
|
||||
height?: number;
|
||||
isRtl?: boolean;
|
||||
hideThemePicker?: boolean;
|
||||
}) => {
|
||||
const ref = React.useRef<HTMLDivElement>(null);
|
||||
@ -220,7 +221,7 @@ export const MultiFrameworkContainer2 = (props: {
|
||||
<Spinner />
|
||||
</div>
|
||||
)}
|
||||
{framework === 'React' && <props.react theme={theme} />}
|
||||
{framework === 'React' && <props.react isRtl={props.isRtl} theme={theme} />}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
@ -281,6 +282,7 @@ export const MultiFrameworkContainer = (props: {
|
||||
typescript?: (parent: HTMLElement) => { dispose: () => void };
|
||||
sandboxId: string;
|
||||
height?: number;
|
||||
isRtl?: boolean;
|
||||
hideThemePicker?: boolean;
|
||||
}) => {
|
||||
return (
|
||||
|
@ -2074,6 +2074,11 @@
|
||||
"name": "watermarkComponent",
|
||||
"signature": "FunctionComponent<IWatermarkPanelProps>",
|
||||
"type": "property"
|
||||
},
|
||||
{
|
||||
"name": "isRtl",
|
||||
"signature": "boolean",
|
||||
"type": "property"
|
||||
}
|
||||
],
|
||||
"IGridviewReactProps": [
|
||||
@ -2111,6 +2116,11 @@
|
||||
"name": "proportionalLayout",
|
||||
"signature": "boolean",
|
||||
"type": "property"
|
||||
},
|
||||
{
|
||||
"name": "isRtl",
|
||||
"signature": "boolean",
|
||||
"type": "property"
|
||||
}
|
||||
],
|
||||
"IPaneviewReactProps": [
|
||||
@ -2153,6 +2163,11 @@
|
||||
"name": "onDidDrop",
|
||||
"signature": "(event: PaneviewDropEvent): void",
|
||||
"type": "method"
|
||||
},
|
||||
{
|
||||
"name": "isRtl",
|
||||
"signature": "boolean",
|
||||
"type": "property"
|
||||
}
|
||||
],
|
||||
"ISplitviewReactProps": [
|
||||
@ -2192,4 +2207,4 @@
|
||||
"type": "property"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user