Merge branch '504-bug-updating-panel-parameters-does-not-trigger-ondidlayoutchange' into master

This commit is contained in:
mathuo 2024-03-11 20:02:08 +00:00 committed by GitHub
commit 258be8594d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
83 changed files with 32304 additions and 4964 deletions

View File

@ -2,7 +2,7 @@
"packages": [
"packages/*"
],
"version": "1.10.0",
"version": "1.10.1",
"npmClient": "yarn",
"command": {
"publish": {

View File

@ -1,6 +1,6 @@
{
"name": "dockview-core",
"version": "1.10.0",
"version": "1.10.1",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"keywords": [
"splitview",

View File

@ -2,6 +2,7 @@ import { DockviewPanelApiImpl } from '../../api/dockviewPanelApi';
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { DockviewPanel, IDockviewPanel } from '../../dockview/dockviewPanel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import { fromPartial } from '@total-typescript/shoehorn';
describe('groupPanelApi', () => {
test('title', () => {
@ -17,12 +18,15 @@ describe('groupPanelApi', () => {
setTitle: jest.fn(),
} as any;
});
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {} as any;
});
const panel = new panelMock();
const group = new groupMock();
const group = fromPartial<DockviewGroupPanel>({
api: {
onDidVisibilityChange: jest.fn(),
onDidLocationChange: jest.fn(),
onDidActiveChange: jest.fn(),
},
});
const cut = new DockviewPanelApiImpl(
panel,

View File

@ -17,6 +17,7 @@ import {
TabDragEvent,
} from '../../dockview/components/titlebar/tabsContainer';
import { fromPartial } from '@total-typescript/shoehorn';
import { DockviewApi } from '../../api/component.api';
class PanelContentPartTest implements IContentRenderer {
element: HTMLElement = document.createElement('div');
@ -4670,4 +4671,113 @@ describe('dockviewComponent', () => {
disposeDidLayoutChangeHandler();
});
});
test('that setVisible toggles visiblity', () => {
const container = document.createElement('div');
const dockview = new DockviewComponent({
parentElement: container,
components: {
default: PanelContentPartTest,
},
tabComponents: {
test_tab_id: PanelTabPartTest,
},
orientation: Orientation.HORIZONTAL,
});
const api = new DockviewApi(dockview);
dockview.layout(1000, 1000);
const panel1 = api.addPanel({
id: 'panel1',
component: 'default',
});
const panel2 = api.addPanel({
id: 'panel2',
component: 'default',
position: { referencePanel: panel1, direction: 'within' },
});
const panel3 = api.addPanel({
id: 'panel3',
component: 'default',
position: { referencePanel: panel1, direction: 'right' },
});
const panel4 = api.addPanel({
id: 'panel4',
component: 'default',
position: { referencePanel: panel3, direction: 'within' },
});
expect(api.groups.length).toBe(2);
expect(panel1.group).toBe(panel2.group);
expect(panel3.group).toBe(panel4.group);
expect(panel1.group.api.isVisible).toBeTruthy();
expect(panel2.group.api.isVisible).toBeTruthy();
expect(panel3.group.api.isVisible).toBeTruthy();
expect(panel4.group.api.isVisible).toBeTruthy();
expect(panel1.api.isVisible).toBeFalsy();
expect(panel2.api.isVisible).toBeTruthy();
expect(panel3.api.isVisible).toBeFalsy();
expect(panel4.api.isVisible).toBeTruthy();
// case #1
panel1.group.api.setVisible(false);
expect(panel1.group.api.isVisible).toBeFalsy();
expect(panel2.group.api.isVisible).toBeFalsy();
expect(panel3.group.api.isVisible).toBeTruthy();
expect(panel4.group.api.isVisible).toBeTruthy();
expect(panel1.api.isVisible).toBeFalsy();
expect(panel2.api.isVisible).toBeFalsy();
expect(panel3.api.isVisible).toBeFalsy();
expect(panel4.api.isVisible).toBeTruthy();
// case #2
panel3.group.api.setVisible(false);
expect(panel1.group.api.isVisible).toBeFalsy();
expect(panel2.group.api.isVisible).toBeFalsy();
expect(panel3.group.api.isVisible).toBeFalsy();
expect(panel4.group.api.isVisible).toBeFalsy();
expect(panel1.api.isVisible).toBeFalsy();
expect(panel2.api.isVisible).toBeFalsy();
expect(panel3.api.isVisible).toBeFalsy();
expect(panel4.api.isVisible).toBeFalsy();
// case #2
panel3.group.api.setVisible(true);
expect(panel1.group.api.isVisible).toBeFalsy();
expect(panel2.group.api.isVisible).toBeFalsy();
expect(panel3.group.api.isVisible).toBeTruthy();
expect(panel4.group.api.isVisible).toBeTruthy();
expect(panel1.api.isVisible).toBeFalsy();
expect(panel2.api.isVisible).toBeFalsy();
expect(panel3.api.isVisible).toBeFalsy();
expect(panel4.api.isVisible).toBeTruthy();
// case #2
panel1.group.api.setVisible(true);
expect(panel1.group.api.isVisible).toBeTruthy();
expect(panel2.group.api.isVisible).toBeTruthy();
expect(panel3.group.api.isVisible).toBeTruthy();
expect(panel4.group.api.isVisible).toBeTruthy();
expect(panel1.api.isVisible).toBeFalsy();
expect(panel2.api.isVisible).toBeTruthy();
expect(panel3.api.isVisible).toBeFalsy();
expect(panel4.api.isVisible).toBeTruthy();
});
});

View File

@ -3,6 +3,7 @@ import { DockviewApi } from '../../api/component.api';
import { DockviewPanel } from '../../dockview/dockviewPanel';
import { IDockviewPanelModel } from '../../dockview/dockviewPanelModel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import { fromPartial } from '@total-typescript/shoehorn';
describe('dockviewPanel', () => {
test('update title', () => {
@ -14,9 +15,7 @@ describe('dockviewPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {} as any;
});
const panelModelMock = jest.fn<Partial<IDockviewPanelModel>, []>(() => {
return {
update: jest.fn(),
@ -26,7 +25,13 @@ describe('dockviewPanel', () => {
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const group = fromPartial<DockviewGroupPanel>({
api: {
onDidVisibilityChange: jest.fn(),
onDidLocationChange: jest.fn(),
onDidActiveChange: jest.fn(),
},
});
const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, {
@ -61,9 +66,6 @@ describe('dockviewPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {} as any;
});
const panelModelMock = jest.fn<Partial<IDockviewPanelModel>, []>(() => {
return {
update: jest.fn(),
@ -73,7 +75,13 @@ describe('dockviewPanel', () => {
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const group = fromPartial<DockviewGroupPanel>({
api: {
onDidVisibilityChange: jest.fn(),
onDidLocationChange: jest.fn(),
onDidActiveChange: jest.fn(),
},
});
const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, {
@ -97,9 +105,6 @@ describe('dockviewPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {} as any;
});
const panelModelMock = jest.fn<Partial<IDockviewPanelModel>, []>(() => {
return {
update: jest.fn(),
@ -110,7 +115,19 @@ describe('dockviewPanel', () => {
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const group = fromPartial<DockviewGroupPanel>({
api: {
onDidVisibilityChange: jest
.fn()
.mockReturnValue({ dispose: jest.fn() }),
onDidLocationChange: jest
.fn()
.mockReturnValue({ dispose: jest.fn() }),
onDidActiveChange: jest
.fn()
.mockReturnValue({ dispose: jest.fn() }),
},
});
const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, {
@ -131,9 +148,6 @@ describe('dockviewPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {} as any;
});
const panelModelMock = jest.fn<Partial<IDockviewPanelModel>, []>(() => {
return {
update: jest.fn(),
@ -144,7 +158,13 @@ describe('dockviewPanel', () => {
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const group = fromPartial<DockviewGroupPanel>({
api: {
onDidVisibilityChange: jest.fn(),
onDidLocationChange: jest.fn(),
onDidActiveChange: jest.fn(),
},
});
const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, {
@ -165,13 +185,6 @@ describe('dockviewPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {
api: {
setSize: jest.fn(),
},
} as any;
});
const panelModelMock = jest.fn<Partial<IDockviewPanelModel>, []>(() => {
return {
update: jest.fn(),
@ -182,7 +195,14 @@ describe('dockviewPanel', () => {
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const group = fromPartial<DockviewGroupPanel>({
api: {
onDidVisibilityChange: jest.fn(),
onDidLocationChange: jest.fn(),
onDidActiveChange: jest.fn(),
setSize: jest.fn(),
},
});
const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, {
@ -202,9 +222,6 @@ describe('dockviewPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<DockviewGroupPanel, []>(() => {
return {} as any;
});
const panelModelMock = jest.fn<Partial<IDockviewPanelModel>, []>(() => {
return {
update: jest.fn(),
@ -215,7 +232,13 @@ describe('dockviewPanel', () => {
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const group = fromPartial<DockviewGroupPanel>({
api: {
onDidVisibilityChange: jest.fn(),
onDidLocationChange: jest.fn(),
onDidActiveChange: jest.fn(),
},
});
const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, {

View File

@ -2700,4 +2700,35 @@ describe('gridview', () => {
expect(gridview.disableResizing).toBeTruthy();
});
test('that setVisible toggles visiblity', () => {
const gridview = new GridviewComponent({
parentElement: container,
proportionalLayout: true,
orientation: Orientation.HORIZONTAL,
components: { default: TestGridview },
disableAutoResizing: true,
});
gridview.layout(1000, 1000);
const panel1 = gridview.addPanel({
id: 'panel1',
component: 'default',
});
const panel2 = gridview.addPanel({
id: 'panel2',
component: 'default',
});
expect(panel1.api.isVisible).toBeTruthy();
expect(panel2.api.isVisible).toBeTruthy();
panel1.api.setVisible(false);
expect(panel1.api.isVisible).toBeFalsy();
expect(panel2.api.isVisible).toBeTruthy();
panel1.api.setVisible(true);
expect(panel1.api.isVisible).toBeTruthy();
expect(panel2.api.isVisible).toBeTruthy();
});
});

View File

@ -514,4 +514,38 @@ describe('componentPaneview', () => {
expect(paneview.disableResizing).toBeTruthy();
});
test('that setVisible toggles visiblity', () => {
const paneview = new PaneviewComponent({
parentElement: container,
components: {
default: TestPanel,
},
disableAutoResizing: true,
});
paneview.layout(1000, 1000);
const panel1 = paneview.addPanel({
id: 'panel1',
component: 'default',
title: 'panel1',
});
const panel2 = paneview.addPanel({
id: 'panel2',
component: 'default',
title: 'panel2',
});
expect(panel1.api.isVisible).toBeTruthy();
expect(panel2.api.isVisible).toBeTruthy();
panel1.api.setVisible(false);
expect(panel1.api.isVisible).toBeFalsy();
expect(panel2.api.isVisible).toBeTruthy();
panel1.api.setVisible(true);
expect(panel1.api.isVisible).toBeTruthy();
expect(panel2.api.isVisible).toBeTruthy();
});
});

View File

@ -617,4 +617,36 @@ describe('componentSplitview', () => {
expect(splitview.disableResizing).toBeTruthy();
});
test('that setVisible toggles visiblity', () => {
const splitview = new SplitviewComponent({
parentElement: container,
orientation: Orientation.HORIZONTAL,
components: {
default: TestPanel,
},
});
splitview.layout(1000, 1000);
const panel1 = splitview.addPanel({
id: 'panel1',
component: 'default',
});
const panel2 = splitview.addPanel({
id: 'panel2',
component: 'default',
});
expect(panel1.api.isVisible).toBeTruthy();
expect(panel2.api.isVisible).toBeTruthy();
panel1.api.setVisible(false);
expect(panel1.api.isVisible).toBeFalsy();
expect(panel2.api.isVisible).toBeTruthy();
panel1.api.setVisible(true);
expect(panel1.api.isVisible).toBeTruthy();
expect(panel2.api.isVisible).toBeTruthy();
});
});

View File

@ -667,21 +667,29 @@ export class DockviewApi implements CommonApi<SerializedDockview> {
}
/**
* Invoked before an overlay is shown indicating a drop target.
*
* Calling `event.preventDefault()` will prevent the overlay being shown and prevent
* the any subsequent drop event.
*/
get onWillShowOverlay(): Event<WillShowOverlayLocationEvent> {
return this.component.onWillShowOverlay;
}
/**
* Invoked before a group is dragged. Exposed for custom Drag'n'Drop functionality.
* Invoked before a group is dragged.
*
* Calling `event.nativeEvent.preventDefault()` will prevent the group drag starting.
*
*/
get onWillDragGroup(): Event<GroupDragEvent> {
return this.component.onWillDragGroup;
}
/**
* Invoked before a panel is dragged. Exposed for custom Drag'n'Drop functionality.
* Invoked before a panel is dragged.
*
* Calling `event.nativeEvent.preventDefault()` will prevent the panel drag starting.
*/
get onWillDragPanel(): Event<TabDragEvent> {
return this.component.onWillDragPanel;

View File

@ -100,41 +100,14 @@ export class DockviewPanelApiImpl
}
set group(value: DockviewGroupPanel) {
const isOldGroupActive = this.isGroupActive;
const oldGroup = this._group;
if (this._group !== value) {
this._group = value;
this._onDidGroupChange.fire({});
let _trackGroupActive = isOldGroupActive; // prevent duplicate events with same state
this.groupEventsDisposable.value = new CompositeDisposable(
this.group.api.onDidLocationChange((event) => {
if (this.group !== this.panel.group) {
return;
}
this._onDidLocationChange.fire(event);
}),
this.group.api.onDidActiveChange(() => {
if (this.group !== this.panel.group) {
return;
}
if (_trackGroupActive !== this.isGroupActive) {
_trackGroupActive = this.isGroupActive;
this._onDidActiveGroupChange.fire({
isActive: this.isGroupActive,
});
}
})
);
// if (this.isGroupActive !== isOldGroupActive) {
// this._onDidActiveGroupChange.fire({
// isActive: this.isGroupActive,
// });
// }
this.setupGroupEventListeners(oldGroup);
this._onDidLocationChange.fire({
location: this.group.api.location,
@ -156,6 +129,7 @@ export class DockviewPanelApiImpl
this.initialize(panel);
this._group = group;
this.setupGroupEventListeners();
this.addDisposables(
this.groupEventsDisposable,
@ -209,4 +183,40 @@ export class DockviewPanelApiImpl
exitMaximized(): void {
this.group.api.exitMaximized();
}
private setupGroupEventListeners(previousGroup?: DockviewGroupPanel) {
let _trackGroupActive = previousGroup?.isActive ?? false; // prevent duplicate events with same state
this.groupEventsDisposable.value = new CompositeDisposable(
this.group.api.onDidVisibilityChange((event) => {
if (!event.isVisible && this.isVisible) {
this._onDidVisibilityChange.fire(event);
} else if (
event.isVisible &&
!this.isVisible &&
this.group.model.isPanelActive(this.panel)
) {
this._onDidVisibilityChange.fire(event);
}
}),
this.group.api.onDidLocationChange((event) => {
if (this.group !== this.panel.group) {
return;
}
this._onDidLocationChange.fire(event);
}),
this.group.api.onDidActiveChange(() => {
if (this.group !== this.panel.group) {
return;
}
if (_trackGroupActive !== this.isGroupActive) {
_trackGroupActive = this.isGroupActive;
this._onDidActiveGroupChange.fire({
isActive: this.isGroupActive,
});
}
})
);
}
}

View File

@ -14,10 +14,6 @@ export interface VisibilityEvent {
readonly isVisible: boolean;
}
export interface HiddenEvent {
readonly isHidden: boolean;
}
export interface ActiveEvent {
readonly isActive: boolean;
}
@ -31,6 +27,7 @@ export interface PanelApi {
readonly onDidHiddenChange: Event<HiddenEvent>;
readonly onUpdateParameters: Event<Parameters>;
setActive(): void;
setVisible(isVisible: boolean): void;
updateParameters(parameters: Parameters): void;
/**
* The id of the panel that would have been assigned when the panel was created
@ -48,10 +45,6 @@ export interface PanelApi {
* Whether the panel is visible
*/
readonly isVisible: boolean;
/**
* Whether the panel is hidden
*/
readonly isHidden: boolean;
/**
* The panel width in pixels
*/
@ -77,7 +70,6 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
private _isFocused = false;
private _isActive = false;
private _isVisible = true;
private _isHidden = false;
private _width = 0;
private _height = 0;
@ -96,9 +88,9 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
readonly onDidVisibilityChange: Event<VisibilityEvent> =
this._onDidVisibilityChange.event;
readonly _onDidHiddenChange = new Emitter<HiddenEvent>();
readonly onDidHiddenChange: Event<HiddenEvent> =
this._onDidHiddenChange.event;
readonly _onWillVisibilityChange = new Emitter<VisibilityEvent>();
readonly onWillVisibilityChange: Event<VisibilityEvent> =
this._onWillVisibilityChange.event;
readonly _onDidActiveChange = new Emitter<ActiveEvent>();
readonly onDidActiveChange: Event<ActiveEvent> =
@ -123,10 +115,6 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
return this._isVisible;
}
get isHidden(): boolean {
return this._isHidden;
}
get width(): number {
return this._width;
}
@ -148,9 +136,6 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
this.onDidVisibilityChange((event) => {
this._isVisible = event.isVisible;
}),
this.onDidHiddenChange((event) => {
this._isHidden = event.isHidden;
}),
this.onDidDimensionsChange((event) => {
this._width = event.width;
this._height = event.height;
@ -163,7 +148,7 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
this._onWillFocus,
this._onActiveChange,
this._onWillFocus,
this._onDidHiddenChange,
this._onWillVisibilityChange,
this._onUpdateParameters
);
}
@ -178,8 +163,8 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
);
}
setHidden(isHidden: boolean): void {
this._onDidHiddenChange.fire({ isHidden });
setVisible(isVisible: boolean): void {
this._onWillVisibilityChange.fire({ isVisible });
}
setActive(): void {

View File

@ -685,7 +685,7 @@ export class DockviewComponent
options?.overridePopoutGroup?.id ?? this.getNextGroupId(); //item.id;
if (itemToPopout.api.location.type === 'grid') {
itemToPopout.api.setHidden(true);
itemToPopout.api.setVisible(false);
}
const _window = new PopoutWindow(
@ -760,7 +760,7 @@ export class DockviewComponent
switch (referenceLocation) {
case 'grid':
referenceGroup.api.setHidden(true);
referenceGroup.api.setVisible(false);
break;
case 'floating':
case 'popout':
@ -832,8 +832,8 @@ export class DockviewComponent
})
);
if (referenceGroup.api.isHidden) {
referenceGroup.api.setHidden(false);
if (!referenceGroup.api.isVisible) {
referenceGroup.api.setVisible(true);
}
if (this.getPanel(group.id)) {
@ -1607,7 +1607,7 @@ export class DockviewComponent
private updateWatermark(): void {
if (
this.groups.filter(
(x) => x.api.location.type === 'grid' && !x.api.isHidden
(x) => x.api.location.type === 'grid' && x.api.isVisible
).length === 0
) {
if (!this.watermark) {

View File

@ -158,11 +158,11 @@ export abstract class GridviewPanel<
this.api.initialize(this); // TODO: required to by-pass 'super before this' requirement
this.addDisposables(
this.api.onDidHiddenChange((event) => {
const { isHidden } = event;
this.api.onWillVisibilityChange((event) => {
const { isVisible } = event;
const { accessor } = this._params as GridviewInitParameters;
accessor.setVisible(this, !isHidden);
accessor.setVisible(this, isVisible);
}),
this.api.onActiveChange(() => {
const { accessor } = this._params as GridviewInitParameters;

View File

@ -1,5 +1,5 @@
export interface IDisposable {
dispose: () => void;
dispose(): void;
}
export interface IValueDisposable<T> {

View File

@ -108,6 +108,10 @@ export class Paneview extends CompositeDisposable implements IDisposable {
);
}
setViewVisible(index: number, visible: boolean) {
this.splitview.setViewVisible(index, visible);
}
public addPane(
pane: PaneviewPanel,
size?: number | Sizing,

View File

@ -125,6 +125,7 @@ export interface IPaneviewComponent extends IDisposable {
getPanel(id: string): IPaneviewPanel | undefined;
movePanel(from: number, to: number): void;
updateOptions(options: Partial<PaneviewComponentOptions>): void;
setVisible(panel: IPaneviewPanel, visible: boolean): void;
clear(): void;
}
@ -226,6 +227,11 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
this.addDisposables(this._disposable);
}
setVisible(panel: PaneviewPanel, visible: boolean): void {
const index = this.panels.indexOf(panel);
this.paneview.setViewVisible(index, visible);
}
focus(): void {
//noop
}
@ -296,6 +302,7 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
isExpanded: options.isExpanded,
title: options.title,
containerApi: new PaneviewApi(this),
accessor: this,
});
this.paneview.addPane(view, size, index);
@ -430,6 +437,7 @@ export class PaneviewComponent extends Resizable implements IPaneviewComponent {
title: data.title,
isExpanded: !!view.expanded,
containerApi: new PaneviewApi(this),
accessor: this,
});
panel.orientation = this.paneview.orientation;
});

View File

@ -15,6 +15,7 @@ import {
Parameters,
} from '../panel/types';
import { IView, Orientation } from '../splitview/splitview';
import { PaneviewComponent } from './paneviewComponent';
export interface PanePanelViewState extends BasePanelViewState {
headerComponent?: string;
@ -27,6 +28,7 @@ export interface PanePanelInitParameter extends PanelInitParameters {
isExpanded?: boolean;
title: string;
containerApi: PaneviewApi;
accessor: PaneviewComponent;
}
export interface PanePanelComponentInitParameter
@ -176,6 +178,11 @@ export abstract class PaneviewPanel
this.element.classList.add('pane');
this.addDisposables(
this.api.onWillVisibilityChange((event) => {
const { isVisible } = event;
const { accessor } = this._params as PanePanelInitParameter;
accessor.setVisible(this, isVisible);
}),
this.api.onDidSizeChange((event) => {
this._onDidChange.fire({ size: event.size });
}),

View File

@ -209,20 +209,20 @@ export class SplitviewComponent
this.splitview.setViewVisible(index, visible);
}
setActive(view: SplitviewPanel, skipFocus?: boolean): void {
this._activePanel = view;
setActive(panel: SplitviewPanel, skipFocus?: boolean): void {
this._activePanel = panel;
this.panels
.filter((v) => v !== view)
.filter((v) => v !== panel)
.forEach((v) => {
v.api._onDidActiveChange.fire({ isActive: false });
if (!skipFocus) {
v.focus();
}
});
view.api._onDidActiveChange.fire({ isActive: true });
panel.api._onDidActiveChange.fire({ isActive: true });
if (!skipFocus) {
view.focus();
panel.focus();
}
}

View File

@ -89,10 +89,10 @@ export abstract class SplitviewPanel
this.addDisposables(
this._onDidChange,
this.api.onDidHiddenChange((event) => {
const { isHidden } = event;
this.api.onWillVisibilityChange((event) => {
const { isVisible } = event;
const { accessor } = this._params as PanelViewInitParameters;
accessor.setVisible(this, !isHidden);
accessor.setVisible(this, isVisible);
}),
this.api.onActiveChange(() => {
const { accessor } = this._params as PanelViewInitParameters;

View File

@ -1,6 +1,6 @@
{
"name": "dockview",
"version": "1.10.0",
"version": "1.10.1",
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support",
"keywords": [
"splitview",
@ -54,6 +54,6 @@
"test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview --coverage"
},
"dependencies": {
"dockview-core": "^1.10.0"
"dockview-core": "^1.10.1"
}
}

View File

@ -0,0 +1,19 @@
---
slug: dockview-1.10.1-release
title: Dockview 1.10.1
tags: [release]
---
# Release Notes
Please reference to docs @ [dockview.dev](https://dockview.dev).
## 🚀 Features
- `onWillShowOverlay` handles 'edge' drops [#526](https://github.com/mathuo/dockview/pull/526)
## 🛠 Miscs
- regression: add `setVisible` to public panel api [#535](https://github.com/mathuo/dockview/pull/535)
- remove unintended public api methods `isHidden`, `onDidHiddenChange`
- reinstate `setVisible` after mistaken removal

View File

@ -6,6 +6,10 @@ sidebar_position: 3
import { DocRef } from '@site/src/components/ui/reference/docRef';
:::info
You may want to combine this with `locked={true}` to provide a locked grid with no dnd funtionality. See [Locked](/docs/core/locked) for more.
:::
<FrameworkSpecific framework="JavaScript">
<DocRef declaration="DockviewComponentOptions" methods={["disableDnd"]} />
</FrameworkSpecific>

View File

@ -5,7 +5,6 @@ sidebar_position: 1
import useBaseUrl from '@docusaurus/useBaseUrl';
import { MultiFrameworkContainer } from '@site/src/components/ui/container';
import DndDockview from '@site/sandboxes/dnd-dockview/src/app';
import DockviewExternalDnd from '@site/sandboxes/externaldnd-dockview/src/app';
import LiveExample from '@site/src/components/ui/exampleFrame';
@ -16,7 +15,7 @@ The dock makes heavy use of drag and drop functionalities.
<DocRef declaration="DockviewApi"
methods={[
'onWillDragPanel', 'onWillDragGroup',
'onWillDrop', 'onDidDrop', 'onWillShowOverlay'
'onWillDrop', 'onWillShowOverlay'
]}
/>
@ -79,12 +78,6 @@ return (
);
```
## Intercepting Drag Events
You can intercept drag events to attach your own metadata using the `onWillDragPanel` and `onWillDragGroup` api methods.
<MultiFrameworkContainer sandboxId="dnd-dockview" react={DndDockview} />
## Third Party Dnd Libraries
This shows a simple example of a third-party library used inside a panel that relies on drag

View File

@ -0,0 +1,31 @@
---
title: 'External Dnd Events'
sidebar_position: 3
---
External Dnd events can be intercepted through a number of utilities.
import { DocRef } from '@site/src/components/ui/reference/docRef';
import LiveExample from '@site/src/components/ui/exampleFrame';
<DocRef declaration="DockviewApi"
methods={['onDidDrop']}
/>
<FrameworkSpecific framework='React'>
<DocRef declaration="IDockviewReactProps" methods={['showDndOverlay']} />
</FrameworkSpecific>
<FrameworkSpecific framework='JavaScript'>
<DocRef declaration="DockviewComponentOptions"
methods={['showDndOverlay']}
/>
</FrameworkSpecific>
## Intercepting Drag Events
You can intercept drag events to attach your own metadata using the `onWillDragPanel` and `onWillDragGroup` api methods.
<LiveExample framework='react' id="dockview/dnd-external" />

View File

@ -4,11 +4,6 @@ sidebar_position: 0
---
import useBaseUrl from '@docusaurus/useBaseUrl';
import { MultiFrameworkContainer } from '@site/src/components/ui/container';
import DndDockview from '@site/sandboxes/dnd-dockview/src/app';
import DockviewExternalDnd from '@site/sandboxes/externaldnd-dockview/src/app';
import { DocRef } from '@site/src/components/ui/reference/docRef';
Dockview supports a wide variety of built-in Drag and Drop possibilities.

View File

@ -9,4 +9,8 @@ import LiveExample from '@site/src/components/ui/exampleFrame';
This section describes how to lock the dock to prevent movement.
:::info
You may want to combine this with `disableDnd={true}` to provide a locked grid with no dnd funtionality. See [Disable Dnd](/docs/core/dnd/disable) for more.
:::
<LiveExample framework='react' id='dockview/locked'/>

View File

@ -3,5 +3,15 @@ title: Overview
sidebar_position: 0
---
import LiveExample from '@site/src/components/ui/exampleFrame';
import { DocRef } from '@site/src/components/ui/reference/docRef';
The implementation of the dock is a collection of nested *splitview* controls forming a *gridview*
which is exposed as a seperate component to be used independantly.
<DocRef declaration="IGridviewReactProps"/>
## Live Example
<LiveExample framework='react' id='gridview/simple' />

View File

@ -2,5 +2,13 @@
title: Overview
sidebar_position: 0
---
import LiveExample from '@site/src/components/ui/exampleFrame';
import { DocRef } from '@site/src/components/ui/reference/docRef';
A *splitview* control where each panel contains a header and collapsable content.
<DocRef declaration="IPaneviewReactProps"/>
## Live Example
<LiveExample framework='react' id='paneview/simple' />

View File

@ -5,3 +5,12 @@ sidebar_position: 0
The implementation of the dock is a collection of nested *splitview* controls
which is exposed as a seperate component to be used independantly.
import LiveExample from '@site/src/components/ui/exampleFrame';
import { DocRef } from '@site/src/components/ui/reference/docRef';
<DocRef declaration="ISplitviewReactProps"/>
## Live Example
<LiveExample framework='react' id='splitview/simple' height={200} />

View File

@ -0,0 +1,10 @@
---
title: Tabview
sidebar_position: 3
---
A *tabview* can be created using a dock and preventing some default behaviours.
import LiveExample from '@site/src/components/ui/exampleFrame';
<LiveExample framework='react' id='dockview/tabview' />

View File

@ -1,6 +1,6 @@
{
"name": "dockview-docs",
"version": "1.10.0",
"version": "1.10.1",
"private": true,
"scripts": {
"build": "docusaurus build",
@ -34,7 +34,7 @@
"ag-grid-react": "^31.0.2",
"axios": "^1.6.3",
"clsx": "^2.1.0",
"dockview": "^1.10.0",
"dockview": "^1.10.1",
"prism-react-renderer": "^2.3.1",
"react-dnd": "^16.0.1",
"react-laag": "^2.0.5",

View File

@ -35,6 +35,7 @@
align-items: center;
justify-content: center;
background-color: #1c254a;
color: white;
border: none;
cursor: pointer;
outline: 1px solid #4c65d4;

View File

@ -28,7 +28,7 @@ const components = {
position: 'relative',
}}
>
<Table data={metadata} />
{/* <Table data={metadata} /> */}
<span
style={{
position: 'absolute',
@ -68,8 +68,20 @@ const headerComponents = {
},
};
const colors = [
'rgba(255,0,0,0.2)',
'rgba(0,255,0,0.2)',
'rgba(0,0,255,0.2)',
'rgba(255,255,0,0.2)',
'rgba(0,255,255,0.2)',
'rgba(255,0,255,0.2)',
];
let count = 0;
const DockviewDemo = (props: { theme?: string }) => {
const [logLines, setLogLines] = React.useState<any[]>([]);
const [logLines, setLogLines] = React.useState<
{ text: string; timestamp?: Date; backgroundColor?: string }[]
>([]);
const [panels, setPanels] = React.useState<string[]>([]);
const [groups, setGroups] = React.useState<string[]>([]);
@ -78,16 +90,39 @@ const DockviewDemo = (props: { theme?: string }) => {
const [activePanel, setActivePanel] = React.useState<string>();
const [activeGroup, setActiveGroup] = React.useState<string>();
const [pending, setPending] = React.useState<
{ text: string; timestamp?: Date }[]
>([]);
const addLogLine = (message: string) => {
setPending((line) => [
{ text: message, timestamp: new Date() },
...line,
]);
};
React.useLayoutEffect(() => {
if (pending.length === 0) {
return;
}
const color = colors[count++ % colors.length];
setLogLines((lines) => [
...pending.map((_) => ({ ..._, backgroundColor: color })),
...lines,
]);
setPending([]);
}, [pending]);
const onReady = (event: DockviewReadyEvent) => {
setApi(event.api);
event.api.onDidAddPanel((event) => {
setPanels((_) => [..._, event.id]);
setLogLines((line) => [`Panel Added ${event.id}`, ...line]);
addLogLine(`Panel Added ${event.id}`);
});
event.api.onDidActivePanelChange((event) => {
setActivePanel(event?.id);
setLogLines((line) => [`Panel Activated ${event?.id}`, ...line]);
addLogLine(`Panel Activated ${event?.id}`);
});
event.api.onDidRemovePanel((event) => {
setPanels((_) => {
@ -99,12 +134,12 @@ const DockviewDemo = (props: { theme?: string }) => {
return next;
});
setLogLines((line) => [`Panel Removed ${event.id}`, ...line]);
addLogLine(`Panel Removed ${event.id}`);
});
event.api.onDidAddGroup((event) => {
setGroups((_) => [..._, event.id]);
setLogLines((line) => [`Group Added ${event.id}`, ...line]);
addLogLine(`Group Added ${event.id}`);
});
event.api.onDidRemoveGroup((event) => {
@ -117,12 +152,12 @@ const DockviewDemo = (props: { theme?: string }) => {
return next;
});
setLogLines((line) => [`Group Removed ${event.id}`, ...line]);
addLogLine(`Group Removed ${event.id}`);
});
event.api.onDidActiveGroupChange((event) => {
setActiveGroup(event?.id);
setLogLines((line) => [`Group Activated ${event?.id}`, ...line]);
addLogLine(`Group Activated ${event?.id}`);
});
const state = localStorage.getItem('dv-demo-state');
@ -146,6 +181,9 @@ const DockviewDemo = (props: { theme?: string }) => {
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
padding: '8px',
backgroundColor: 'rgba(0,0,50,0.25)',
borderRadius: '8px',
}}
>
<div>
@ -167,6 +205,7 @@ const DockviewDemo = (props: { theme?: string }) => {
overflow: 'hidden',
// flexBasis: 0
height: 0,
display: 'flex',
}}
>
<DockviewReact
@ -178,33 +217,62 @@ const DockviewDemo = (props: { theme?: string }) => {
onReady={onReady}
className={props.theme || 'dockview-theme-abyss'}
/>
</div>
<div
style={{
height: '200px',
backgroundColor: 'black',
color: 'white',
overflow: 'auto',
}}
>
{logLines.map((line, i) => {
return (
<div key={i}>
<span
<div
style={{
// height: '200px',
width: '300px',
backgroundColor: 'black',
color: 'white',
overflow: 'auto',
}}
>
{logLines.map((line, i) => {
return (
<div
style={{
display: 'inline-block',
width: '30px',
color: 'gray',
borderRight: '1px solid gray',
marginRight: '4px',
height: '30px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
fontSize: '13px',
display: 'flex',
alignItems: 'center',
backgroundColor: line.backgroundColor,
}}
key={i}
>
{logLines.length - i}
</span>
<span>{line}</span>
</div>
);
})}
<span
style={{
display: 'inline-block',
width: '20px',
color: 'gray',
borderRight: '1px solid gray',
marginRight: '4px',
paddingLeft: '2px',
height: '100%',
}}
>
{logLines.length - i}
</span>
<span>
{line.timestamp && (
<span
style={{
fontSize: '0.7em',
padding: '0px 2px',
}}
>
{line.timestamp
.toISOString()
.substring(11, 23)}
</span>
)}
<span>{line.text}</span>
</span>
</div>
);
})}
</div>
</div>
</div>
);

View File

@ -14,10 +14,6 @@ export interface PanelApiMetadata {
value: boolean;
count: number;
};
isHidden: {
value: boolean;
count: number;
};
renderer: {
value: DockviewPanelRenderer;
count: number;
@ -69,7 +65,6 @@ export function usePanelApiMetadata(api: DockviewPanelApi): PanelApiMetadata {
const [state, setState] = React.useState<PanelApiMetadata>({
isActive: { value: api.isActive, count: 0 },
isVisible: { value: api.isVisible, count: 0 },
isHidden: { value: api.isHidden, count: 0 },
renderer: { value: api.renderer, count: 0 },
isGroupActive: { value: api.isGroupActive, count: 0 },
groupChanged: { count: 0 },
@ -125,15 +120,6 @@ export function usePanelApiMetadata(api: DockviewPanelApi): PanelApiMetadata {
},
}));
});
const d6 = api.onDidHiddenChange((event) => {
setState((_) => ({
..._,
isHidden: {
value: event.isHidden,
count: _.isHidden.count + 1,
},
}));
});
const d7 = api.onDidLocationChange((event) => {
setState((_) => ({
..._,
@ -168,7 +154,6 @@ export function usePanelApiMetadata(api: DockviewPanelApi): PanelApiMetadata {
d3.dispose();
d4.dispose();
d5.dispose();
d6.dispose();
d7.dispose();
d8.dispose();
d9.dispose();

View File

@ -11,7 +11,7 @@ export const nextId = (() => {
export function defaultConfig(api: DockviewApi) {
const panel1 = api.addPanel({
id: 'panel_1',
component: 'iframe',
component: 'default',
renderer: 'always',
title: 'Panel 1',
});

View File

@ -0,0 +1,32 @@
{
"name": "dockview.dnd-external",
"description": "",
"keywords": [
"dockview"
],
"version": "1.0.0",
"main": "src/index.tsx",
"dependencies": {
"dockview": "*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"typescript": "^4.9.5",
"react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}

View File

@ -1,7 +1,7 @@
import {
DockviewApi,
DockviewDndOverlayEvent,
DockviewDropEvent,
DockviewDidDropEvent,
DockviewReact,
DockviewReadyEvent,
IDockviewPanelProps,
@ -123,7 +123,7 @@ const DndDockview = (props: { renderVisibleOnly: boolean; theme?: string }) => {
setApi(event.api);
};
const onDidDrop = (event: DockviewDropEvent) => {
const onDidDrop = (event: DockviewDidDropEvent) => {
event.api.addPanel({
id: 'test',
component: 'default',

View File

@ -1,5 +1,5 @@
{
"name": "dnd-dockview",
"name": "dockview.tabview",
"description": "",
"keywords": [
"dockview"
@ -29,4 +29,4 @@
"not ie <= 11",
"not op_mini all"
]
}
}

View File

@ -0,0 +1,82 @@
import {
DockviewApi,
DockviewReact,
DockviewReadyEvent,
IDockviewPanelProps,
} from 'dockview';
import * as React from 'react';
const Default = (props: IDockviewPanelProps) => {
return (
<div style={{ height: '100%' }}>
<div>{props.api.title}</div>
</div>
);
};
const components = {
default: Default,
};
const Component = (props: { theme?: string }) => {
const [api, setApi] = React.useState<DockviewApi>();
React.useEffect(() => {
if (!api) {
return;
}
const disposables = [
api.onWillShowOverlay((e) => {
if (e.kind === 'header_space' || e.kind === 'tab') {
return;
}
e.preventDefault();
}),
];
return () => {
disposables.forEach((disposable) => {
disposable.dispose();
});
};
}, [api]);
const onReady = (event: DockviewReadyEvent) => {
setApi(event.api);
event.api.addPanel({
id: 'panel_1',
component: 'default',
});
event.api.addPanel({
id: 'panel_2',
component: 'default',
});
event.api.addPanel({
id: 'panel_3',
component: 'default',
});
event.api.addPanel({
id: 'panel_4',
component: 'default',
});
event.api.addPanel({
id: 'panel_5',
component: 'default',
});
};
return (
<DockviewReact
className={`${props.theme || 'dockview-theme-abyss'}`}
onReady={onReady}
components={components}
disableFloatingGroups={true}
/>
);
};
export default Component;

View File

@ -1,5 +1,5 @@
{
"name": "simple-gridview",
"name": "gridview.simple",
"description": "",
"keywords": [
"dockview"

View File

@ -1,5 +1,5 @@
{
"name": "simple-paneview",
"name": "paneview.simple",
"description": "",
"keywords": [
"dockview"

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View File

@ -0,0 +1,20 @@
import { StrictMode } from 'react';
import * as ReactDOMClient from 'react-dom/client';
import './styles.css';
import 'dockview/dist/styles/dockview.css';
import App from './app';
const rootElement = document.getElementById('root');
if (rootElement) {
const root = ReactDOMClient.createRoot(rootElement);
root.render(
<StrictMode>
<div className="app">
<App />
</div>
</StrictMode>
);
}

View File

@ -0,0 +1,16 @@
body {
margin: 0px;
color: white;
font-family: sans-serif;
text-align: center;
}
#root {
height: 100vh;
width: 100vw;
}
.app {
height: 100%;
}

View File

@ -0,0 +1,18 @@
{
"compilerOptions": {
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true
}
}

View File

@ -0,0 +1,32 @@
{
"name": "splitview.simple",
"description": "",
"keywords": [
"dockview"
],
"version": "1.0.0",
"main": "src/index.tsx",
"dependencies": {
"dockview": "*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"typescript": "^4.9.5",
"react-scripts": "*"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View File

@ -0,0 +1,59 @@
import {
SplitviewReact,
SplitviewReadyEvent,
ISplitviewPanelProps,
} from 'dockview';
import * as React from 'react';
const components = {
default: (props: ISplitviewPanelProps<{ title: string }>) => {
return (
<div
style={{
padding: '10px',
height: '100%',
}}
>
{props.params.title}
</div>
);
},
};
export const App: React.FC = (props: { theme?: string }) => {
const onReady = (event: SplitviewReadyEvent) => {
event.api.addPanel({
id: 'panel_1',
component: 'default',
params: {
title: 'Panel 1',
},
});
event.api.addPanel({
id: 'panel_2',
component: 'default',
params: {
title: 'Panel 2',
},
});
event.api.addPanel({
id: 'panel_3',
component: 'default',
params: {
title: 'Panel 3',
},
});
};
return (
<SplitviewReact
components={components}
onReady={onReady}
className={props.theme || 'dockview-theme-abyss'}
/>
);
};
export default App;

View File

@ -0,0 +1,20 @@
import { StrictMode } from 'react';
import * as ReactDOMClient from 'react-dom/client';
import './styles.css';
import 'dockview/dist/styles/dockview.css';
import App from './app';
const rootElement = document.getElementById('root');
if (rootElement) {
const root = ReactDOMClient.createRoot(rootElement);
root.render(
<StrictMode>
<div className="app">
<App />
</div>
</StrictMode>
);
}

View File

@ -0,0 +1,16 @@
body {
margin: 0px;
color: white;
font-family: sans-serif;
text-align: center;
}
#root {
height: 100vh;
width: 100vw;
}
.app {
height: 100%;
}

View File

@ -0,0 +1,18 @@
{
"compilerOptions": {
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true
}
}

View File

@ -1,6 +1,7 @@
import BrowserOnly from '@docusaurus/BrowserOnly';
import { DockviewEmitter } from 'dockview';
import * as React from 'react';
import { IS_PROD } from '../flags';
const frameworks = [
{ value: 'JavaScript', label: 'JavaScript' },
@ -35,7 +36,7 @@ function useActiveFramework(): [string, (value: string) => void] {
activeFrameworkGlobal.fire(value);
}, []);
return [value, setter];
return [IS_PROD ? frameworks[1].value : value, setter];
}
const FrameworkSelector1 = () => {
@ -45,6 +46,10 @@ const FrameworkSelector1 = () => {
setActiveFramework(event.target.value),
];
if (IS_PROD) {
return null;
}
return (
<select onChange={onChange} value={activeFramework}>
{frameworks.map((framework) => {

View File

@ -8,6 +8,7 @@ export interface DocRefProps {
}
import docsJson_ from '../../../generated/api.output.json';
import { ExportedTypeFile, TypeSystem, codify, firstLevel } from './types';
const docsJson = docsJson_ as any as DocsJson;
type DocsContent = { kind: string; text: string; tag?: string };
@ -16,19 +17,57 @@ type DocsComment = {
summary?: DocsContent[];
blockTags?: DocsTag[];
};
type Piece = {
kind: 'return' | 'paramter' | 'signature' | 'typearg' | 'typearg_default';
value: string;
};
type Doc = {
name: string;
code: string;
comment?: DocsComment;
kind: 'accessor' | 'property' | 'method';
pieces: string[];
pieces: Piece[];
};
type DocJson = {
kind: string;
metadata?: Doc;
children: Doc[];
};
type DocsJson = {
[index: string]: {
kind: string;
metadata?: Doc;
children: Doc[];
};
[index: string]: DocJson;
};
const newJson = docsJson_ as ExportedTypeFile;
export const DocumentRef = (props: { value: TypeSystem.Type }) => {
const code = React.useMemo(() => {
if (!props.value) {
return null;
}
switch (props.value.kind) {
case 'typeAlias':
return codify(props.value);
case 'interface':
return codify(props.value);
case 'class':
return codify(props.value);
case 'function':
return codify(props.value);
default:
return null;
}
}, [props.value]);
if (!code) {
return null;
}
return <CodeBlock language="tsx">{code}</CodeBlock>;
};
export const Text = (props: { content: DocsContent[] }) => {
@ -81,25 +120,11 @@ export const Markdown = (props: { children: string }) => {
return <span>{props.children}</span>;
};
const Piece = (props: { piece: string }) => {
const item = docsJson[props.piece];
if (!item) {
return;
}
if (item.kind === 'interface') {
return;
}
if (!item.metadata?.code) {
return;
}
return <CodeBlock language="tsx">{item.metadata.code}</CodeBlock>;
};
const Row = (props: { doc: Doc }) => {
const Row = (props: { doc: TypeSystem.Type }) => {
const comment =
props.doc.kind === 'accessor'
? props.doc.value.comment
: props.doc.comment;
return (
<tr>
<th
@ -151,12 +176,8 @@ const Row = (props: { doc: Doc }) => {
<th style={{ width: '60%' }}>
{/* <div>{'-'}</div> */}
<div>
<div>
{props.doc.comment && (
<Summary summary={props.doc.comment} />
)}
</div>
<CodeBlock language="tsx">{props.doc.code}</CodeBlock>
<div>{comment && <Summary summary={comment} />}</div>
<CodeBlock language="tsx">{codify(props.doc)}</CodeBlock>
</div>
</th>
</tr>
@ -165,18 +186,23 @@ const Row = (props: { doc: Doc }) => {
export const DocRef = (props: DocRefProps) => {
const docs = React.useMemo(
() => (docsJson as DocsJson)[props.declaration],
() => newJson[props.declaration],
[props.declaration]
);
const filteredDocs = React.useMemo(
() =>
docs?.children?.filter((child) => {
if (props.methods && !props.methods.includes(child.name)) {
return false;
}
return true;
}),
docs.kind === 'class' || docs.kind === 'interface'
? docs.children.filter((child) => {
if (
props.methods &&
!props.methods.includes(child.name)
) {
return false;
}
return true;
})
: [],
[docs]
);
@ -191,6 +217,13 @@ export const DocRef = (props: DocRefProps) => {
return (
<>
<Row key={i} doc={doc} />
{/* <th colSpan={2}>
{firstLevel(doc).map((x) => (
<span style={{ padding: '0px 2px' }}>
<DocumentRef value={newJson[x]} />
</span>
))}
</th> */}
{/* {doc.pieces?.map((piece) => (
<tr>
<th colSpan={2}>

View File

@ -0,0 +1,446 @@
export type ExportedTypeFile = Record<string, TypeSystem.Type>;
export function firstLevelTypes(value: TypeDescriptor.Type | null) {
if (!value) {
return null;
}
switch (value.type) {
case 'array':
return firstLevelTypes(value.value);
case 'literal':
return [];
case 'intrinsic':
return [];
case 'or':
return value.values.flatMap(firstLevelTypes);
case 'intersection':
return value.values.flatMap(firstLevelTypes);
case 'predicate':
return [];
case 'reference': {
const result = [];
if (
value.source.startsWith('dockview') &&
!value.refersToTypeParameter
) {
result.push(value.value);
}
if (value.typeArguments) {
result.push(...value.typeArguments.flatMap(firstLevelTypes));
}
return result;
}
case 'reflection':
return firstLevel(value.value);
case 'tuple':
return value.value.map(codifyType);
default:
throw new Error('unreachable');
}
}
export function firstLevel(value: TypeSystem.Type | null) {
const results: string[] = [];
switch (value.kind) {
case null:
break;
case 'property':
results.push(...firstLevelTypes(value.type));
break;
case 'accessor':
results.push(...firstLevelTypes(value.value.returnType));
break;
case 'method':
results.push(...value.signature.flatMap(firstLevel));
break;
case 'constructor':
break;
case 'typeLiteral':
if (value.properties) {
results.push(...value.properties.flatMap(firstLevel));
}
if (value.signatures) {
results.push(...value.signatures.flatMap(firstLevel));
}
break;
case 'callSignature':
results.push(
...firstLevelTypes(value.returnType),
...value.typeParameters.flatMap((_) => {
return [...firstLevelTypes(_.extends)];
}),
...value.parameters.flatMap(firstLevel)
);
break;
case 'parameter':
results.push(...firstLevelTypes(value.type));
break;
default:
console.log('test', value);
throw new Error('unreachable');
}
return Array.from(new Set(results));
}
export function codifyType(value: TypeDescriptor.Type | null, tabs = 0) {
if (!value) {
return null;
}
switch (value.type) {
case 'array':
return `${codifyType(value.value)}[]`;
case 'literal':
return `'${value.value}'`;
case 'intrinsic':
return value.value;
case 'or':
return `${value.values
.map((_) => {
const isComparator =
_.type === 'or' || _.type === 'intersection';
const code = codifyType(_);
return isComparator ? `(${code})` : code;
})
.join(' | ')}`;
case 'intersection':
return `${value.values
.map((_) => {
const isComparator =
_.type === 'or' || _.type === 'intersection';
const code = codifyType(_);
return isComparator ? `(${code})` : code;
})
.join(' & ')}`;
case 'predicate':
return `${value.lhs} is ${value.rhs}`;
case 'reference': {
if (value.typeArguments) {
return `${value.value}<${value.typeArguments.map(codifyType)}>`;
}
return `${value.value}`;
}
case 'reflection':
return codify(value.value, tabs);
case 'tuple':
return `[${value.value.map(codifyType).join(', ')}]`;
default:
throw new Error('unreachable');
}
}
export function codify(value: TypeSystem.Type | null, tabs = 0) {
if (!value) {
return null;
}
if (value.kind === 'accessor') {
const signature = value.value;
return `${'\t'.repeat(tabs)}${signature.name}: ${codifyType(
signature.returnType
)}`;
}
if (value.kind === 'property') {
let code = '\t'.repeat(tabs);
if (value.flags.isProtected) {
code += 'protected ';
}
if (value.flags.isReadonly) {
code += 'readonly ';
}
code += value.name;
if (value.flags.isOptional) {
code += '?';
}
code += `: ${codifyType(value.type, tabs + 1)}`;
return code;
}
if (value.kind === 'method') {
return `${'\t'.repeat(tabs)}${value.name}${value.signature
.map(codify)
.join('\n')}`;
}
if (value.kind === 'callSignature') {
let code = ``;
if (value.typeParameters.length > 0) {
code += '<';
code += value.typeParameters.map((typeParameter) => {
let typeCode = `${typeParameter.name}`;
if (typeParameter.extends) {
typeCode += ' extends';
typeCode += ` ${codifyType(typeParameter.extends)}`;
}
if (typeParameter.default) {
typeCode += ' =';
typeCode += ` ${typeParameter.default}`;
}
return typeCode;
});
code += '>';
}
code += '(';
code += value.parameters
.map((parameter) => {
return codify(parameter, tabs + 1);
})
.join(', ');
code += `): ${codifyType(value.returnType)}`;
return code;
}
if (value.kind === 'parameter') {
return `${value.name}: ${codifyType(value.type, tabs + 1)}`;
}
if (value.kind === 'typeLiteral') {
if (value.properties) {
return `{\n${value.properties
.map((_) => codify(_, tabs))
.join(',\n')}\n${'\t'.repeat(Math.max(0, tabs - 1))}}`;
}
if (value.signatures) {
return value.signatures.map(codify).join('\n');
}
}
if (value.kind === 'constructor') {
return '';
}
if (value.kind === 'interface') {
return `interface ${value.name} {\n${value.children
.map((_) => codify(_, tabs + 1))
.join(';\n')};\n}`;
}
if (value.kind === 'class') {
return `interface ${value.name} {\n${value.children
.filter((_) => _.kind !== 'constructor')
.map((_) => codify(_, tabs + 1))
.join(';\n')};\n}`;
}
if (value.kind === 'typeAlias') {
return `type ${value.name} = ${codifyType(value.type)}`;
}
console.log('unreachable', value);
throw new Error(`unreachable`);
}
export namespace TypeSystem {
export type Comment = any;
export type TypeParameter = {
name: string;
extends: TypeDescriptor.Type;
default: string;
comment?: Comment;
};
export type Accessor = {
name: string;
kind: 'accessor';
comment?: Comment;
value: TypeSystem.GetSignature;
};
export type GetSignature = {
kind: 'getSignature';
name: string;
returnType: TypeDescriptor.Type;
comment?: Comment;
};
export type CallSignature = {
kind: 'callSignature';
typeParameters: TypeSystem.TypeParameter[];
parameters: TypeSystem.Type[];
returnType: TypeDescriptor.Type;
name: string;
comment?: Comment;
};
export type Method = {
name: string;
kind: 'method';
signature: TypeSystem.CallSignature[];
comment?: Comment;
};
export type Function = {
name: string;
kind: 'function';
signature: TypeSystem.CallSignature;
comment?: Comment;
};
export type Property = {
kind: 'property';
name: string;
type: TypeDescriptor.Type;
flags: TypeDescriptor.Flags;
comment?: Comment;
};
export type TypeAlias = {
name: string;
kind: 'typeAlias';
typeParameters: TypeSystem.TypeParameter[];
type: TypeDescriptor.Type;
comment?: Comment;
};
export type Enum = {
name: string;
kind: 'enum';
children: TypeSystem.EnumMember[];
comment?: Comment;
};
export type EnumMember = {
kind: 'enumMember';
name: string;
comment?: Comment;
};
export type Class = {
name: string;
kind: 'class';
children: TypeSystem.Type[];
comment?: Comment;
};
export type Interface = {
name: string;
kind: 'interface';
children: TypeSystem.Type[];
comment?: Comment;
};
export type Parameter = {
name: string;
kind: 'parameter';
type: TypeDescriptor.Type;
comment?: Comment;
};
export type Constructor = {
kind: 'constructor';
name: string;
comment?: Comment;
};
export type ConstructorSignature = {
kind: 'constructorSignature';
name: string;
comment?: Comment;
};
export type TypeLiteral = {
kind: 'typeLiteral';
name: string;
signatures?: (ConstructorSignature | TypeSystem.CallSignature)[];
properties?: TypeSystem.Property[];
comment?: Comment;
};
export type Type =
| TypeSystem.Accessor
| TypeSystem.GetSignature
| TypeSystem.CallSignature
| TypeSystem.Method
| TypeSystem.Property
| TypeSystem.TypeAlias
| TypeSystem.Enum
| TypeSystem.EnumMember
| TypeSystem.Class
| TypeSystem.Constructor
| TypeSystem.ConstructorSignature
| TypeSystem.TypeLiteral
| TypeSystem.Parameter
| TypeSystem.Interface
| TypeSystem.Function;
}
export namespace TypeDescriptor {
export interface Union {
type: 'or';
values: TypeDescriptor.Type[];
}
export interface Intrinsic {
type: 'intrinsic';
value: string;
}
export interface Literal {
type: 'literal';
value: string;
}
export type Reflection = { type: 'reflection'; value: TypeSystem.Type };
export interface Reference {
type: 'reference';
value: string;
source: string;
typeArguments?: TypeDescriptor.Type[];
refersToTypeParameter?: boolean;
}
export interface Array {
type: 'array';
value: TypeDescriptor.Type;
}
export interface Intersection {
type: 'intersection';
values: TypeDescriptor.Type[];
}
export interface Predicate {
type: 'predicate';
lhs: string;
rhs: TypeDescriptor.Type;
}
export interface Tuple {
type: 'tuple';
value: TypeDescriptor.Type[];
}
export type Type =
| TypeDescriptor.Union
| TypeDescriptor.Intrinsic
| TypeDescriptor.Literal
| TypeDescriptor.Reflection
| TypeDescriptor.Reference
| TypeDescriptor.Array
| TypeDescriptor.Intersection
| TypeDescriptor.Predicate
| TypeDescriptor.Tuple;
export type Flags = {
isReadonly?: boolean;
isProtected?: boolean;
isOptional?: boolean;
};
}

View File

@ -154,6 +154,7 @@
}
code {
// white-space: pre-wrap;
.token {
&.maybe-class-name {
color: #cf8cff;

View File

@ -0,0 +1 @@
export const IS_PROD = true;

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -2,12 +2,46 @@ import React from 'react';
import Layout from '@theme/Layout';
import { themeConfig } from '../config/theme.config';
import ExampleFrame from '../components/ui/exampleFrame';
import BrowserOnly from '@docusaurus/BrowserOnly';
const ThemeToggle: React.FC = () => {
const [theme, setTheme] = React.useState<string>(
new URLSearchParams(location.search).get('theme') ?? themeConfig[3].id
);
return (
<>
<div
style={{
height: '40px',
display: 'flex',
alignItems: 'center',
}}
>
<select
onChange={(event) => {
const url = new URL(window.location.href);
url.searchParams.set('theme', event.target.value);
window.location.href = url.toString();
}}
value={theme}
>
{themeConfig.map((theme) => {
return <option>{theme.id}</option>;
})}
</select>
</div>
<ExampleFrame
theme={theme}
framework="react"
height="100%"
id="dockview/demo-dockview"
/>
</>
);
};
export default function Popout() {
// const [theme, setTheme] = React.useState<string>(
// new URLSearchParams(location.search).get('theme') ?? themeConfig[3].id
// );
return (
<Layout noFooter={true}>
<div
@ -19,33 +53,7 @@ export default function Popout() {
flexDirection: 'column',
}}
>
<div
style={{
height: '40px',
display: 'flex',
alignItems: 'center',
}}
>
<select
onChange={(event) => {
const url = new URL(window.location.href);
url.searchParams.set('theme', event.target.value);
window.location.href = url.toString();
}}
// value={theme}
>
{themeConfig.map((theme) => {
return <option>{theme.id}</option>;
})}
</select>
</div>
<ExampleFrame
// theme={theme}
framework="react"
height="100%"
id="dockview/demo-dockview"
/>
<BrowserOnly>{() => <ThemeToggle />}</BrowserOnly>
</div>
</Layout>
);

View File

@ -1,20 +1 @@
<svg width="156" height="18" viewBox="0 0 156 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect y="4" width="156" height="14" fill="#1C1C2A"/>
<rect y="4" width="30" height="14" fill="#10192C"/>
<rect x="31" y="4" width="30" height="14" fill="#10192C"/>
<rect x="62" y="4" width="30" height="14" fill="#000C18"/>
<rect x="30" y="4" width="1" height="14" fill="#2B2B4A"/>
<rect x="61" y="4" width="1" height="14" fill="#2B2B4A"/>
<rect x="92" y="4" width="1" height="14" fill="#2B2B4A"/>
<rect x="66" y="9" width="7" height="4" rx="2" fill="white"/>
<rect x="76" y="9" width="12" height="4" rx="2" fill="white"/>
<rect x="33" y="9" width="15" height="4" rx="2" fill="#777777"/>
<rect x="2" y="9" width="6" height="4" rx="2" fill="#777777"/>
<rect x="10" y="9" width="18" height="4" rx="2" fill="#777777"/>
<rect x="93" y="4" width="63" height="14" fill="#E1E1E1" fill-opacity="0.25"/>
<rect x="111.5" y="0.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/>
<rect x="115" y="5" width="7" height="4" rx="2" fill="white"/>
<rect x="126" y="5" width="12" height="4" rx="2" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M128.344 13.2654C128.52 13.1426 128.51 12.8799 128.327 12.77L124.18 10.2905C123.961 10.1595 123.691 10.3492 123.739 10.5997L124.651 15.344C124.691 15.5542 124.935 15.653 125.11 15.5302L125.772 15.067C125.867 15.0002 125.914 14.8836 125.892 14.7693L125.602 13.2612C125.554 13.0106 125.825 12.821 126.044 12.952L127.362 13.7401C127.462 13.7999 127.588 13.7954 127.683 13.7286L128.344 13.2654Z" fill="white"/>
<rect x="127.5" y="14.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="156" height="18" fill="none" viewBox="0 0 156 18"><rect width="156" height="14" y="4" fill="#1C1C2A"/><rect width="30" height="14" y="4" fill="#10192C"/><rect width="30" height="14" x="31" y="4" fill="#10192C"/><rect width="30" height="14" x="62" y="4" fill="#000C18"/><rect width="1" height="14" x="30" y="4" fill="#2B2B4A"/><rect width="1" height="14" x="61" y="4" fill="#2B2B4A"/><rect width="1" height="14" x="92" y="4" fill="#2B2B4A"/><rect width="7" height="4" x="66" y="9" fill="#fff" rx="2"/><rect width="12" height="4" x="76" y="9" fill="#fff" rx="2"/><rect width="15" height="4" x="33" y="9" fill="#777" rx="2"/><rect width="6" height="4" x="2" y="9" fill="#777" rx="2"/><rect width="18" height="4" x="10" y="9" fill="#777" rx="2"/><rect width="63" height="14" x="93" y="4" fill="#E1E1E1" fill-opacity=".25"/><rect width="29" height="13" x="111.5" y=".5" fill="#000C18" stroke="#2B2B4A"/><rect width="7" height="4" x="115" y="5" fill="#fff" rx="2"/><rect width="12" height="4" x="126" y="5" fill="#fff" rx="2"/><path fill="#fff" fill-rule="evenodd" d="M128.344 13.2654C128.52 13.1426 128.51 12.8799 128.327 12.77L124.18 10.2905C123.961 10.1595 123.691 10.3492 123.739 10.5997L124.651 15.344C124.691 15.5542 124.935 15.653 125.11 15.5302L125.772 15.067C125.867 15.0002 125.914 14.8836 125.892 14.7693L125.602 13.2612C125.554 13.0106 125.825 12.821 126.044 12.952L127.362 13.7401C127.462 13.7999 127.588 13.7954 127.683 13.7286L128.344 13.2654Z" clip-rule="evenodd"/><rect width="4" height="2" x="127.5" y="14.5" stroke="#fff" stroke-dasharray=".25 .25"/></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,45 +1 @@
<svg width="312" height="200" viewBox="0 0 312 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="311.504" height="200" rx="5" fill="white"/>
<path d="M0 5C0 2.23858 2.23858 0 5 0H307C309.761 0 312 2.23858 312 5V11H0V5Z" fill="#DCDCDC"/>
<rect y="10" width="312" height="1" fill="#BABABA"/>
<rect y="11" width="156" height="189" fill="#A8A8A8"/>
<rect x="156" y="11" width="156" height="91" fill="#000C18"/>
<rect x="234" y="102" width="78" height="98" fill="#000C18"/>
<rect x="156" y="102" width="78" height="98" fill="#000C18"/>
<rect y="24" width="156" height="176" fill="#000C18"/>
<rect x="157" y="102" width="155" height="1" fill="#2B2B4A"/>
<rect width="1" height="189" transform="matrix(-1 0 0 1 157 11)" fill="#2B2B4A"/>
<path d="M234 103H233V200H234V103Z" fill="#2B2B4A"/>
<rect y="11" width="156" height="14" fill="#1C1C2A"/>
<rect y="11" width="30" height="14" fill="#10192C"/>
<rect x="31" y="11" width="30" height="14" fill="#10192C"/>
<rect x="62" y="11" width="30" height="14" fill="#000C18"/>
<rect x="30" y="11" width="1" height="14" fill="#2B2B4A"/>
<rect x="61" y="11" width="1" height="14" fill="#2B2B4A"/>
<rect x="92" y="11" width="1" height="14" fill="#2B2B4A"/>
<rect x="157" y="11" width="155" height="14" fill="#1C1C2A"/>
<rect x="157" y="11" width="30" height="14" fill="#10192C"/>
<rect x="188" y="11" width="30" height="14" fill="#000C18"/>
<rect x="187" y="11" width="1" height="14" fill="#2B2B4A"/>
<rect x="218" y="11" width="1" height="14" fill="#2B2B4A"/>
<rect x="234" y="103" width="78" height="14" fill="#1C1C2A"/>
<rect x="234" y="103" width="24" height="14" fill="#10192C"/>
<rect x="258" y="103" width="24" height="14" fill="#000C18"/>
<rect x="258" y="103" width="0.503226" height="14" fill="#2B2B4A"/>
<rect x="282" y="103" width="0.503226" height="14" fill="#2B2B4A"/>
<rect x="66" y="16" width="7" height="4" rx="2" fill="white"/>
<rect x="76" y="16" width="12" height="4" rx="2" fill="white"/>
<rect x="191" y="16" width="12" height="4" rx="2" fill="#777777"/>
<rect x="260" y="108" width="7" height="4" rx="2" fill="#777777"/>
<rect x="268" y="108" width="11" height="4" rx="2" fill="#777777"/>
<rect x="206" y="16" width="4" height="4" rx="2" fill="#777777"/>
<rect x="160" y="16" width="5" height="4" rx="2" fill="#282828"/>
<rect x="166" y="16" width="16" height="4" rx="2" fill="#282828"/>
<rect x="237" y="108" width="16" height="4" rx="2" fill="#282828"/>
<rect x="33" y="16" width="15" height="4" rx="2" fill="#777777"/>
<rect x="4" y="3" width="4" height="4" rx="2" fill="#FD605E"/>
<rect x="10" y="3" width="4" height="4" rx="2" fill="#FBBC3F"/>
<rect x="16" y="3" width="4" height="4" rx="2" fill="#34C942"/>
<rect x="2" y="16" width="6" height="4" rx="2" fill="#777777"/>
<rect x="10" y="16" width="18" height="4" rx="2" fill="#777777"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="312" height="200" fill="none" viewBox="0 0 312 200"><rect width="311.504" height="200" fill="#fff" rx="5"/><path fill="#DCDCDC" d="M0 5C0 2.23858 2.23858 0 5 0H307C309.761 0 312 2.23858 312 5V11H0V5Z"/><rect width="312" height="1" y="10" fill="#BABABA"/><rect width="156" height="189" y="11" fill="#A8A8A8"/><rect width="156" height="91" x="156" y="11" fill="#000C18"/><rect width="78" height="98" x="234" y="102" fill="#000C18"/><rect width="78" height="98" x="156" y="102" fill="#000C18"/><rect width="156" height="176" y="24" fill="#000C18"/><rect width="155" height="1" x="157" y="102" fill="#2B2B4A"/><rect width="1" height="189" fill="#2B2B4A" transform="matrix(-1 0 0 1 157 11)"/><path fill="#2B2B4A" d="M234 103H233V200H234V103Z"/><rect width="156" height="14" y="11" fill="#1C1C2A"/><rect width="30" height="14" y="11" fill="#10192C"/><rect width="30" height="14" x="31" y="11" fill="#10192C"/><rect width="30" height="14" x="62" y="11" fill="#000C18"/><rect width="1" height="14" x="30" y="11" fill="#2B2B4A"/><rect width="1" height="14" x="61" y="11" fill="#2B2B4A"/><rect width="1" height="14" x="92" y="11" fill="#2B2B4A"/><rect width="155" height="14" x="157" y="11" fill="#1C1C2A"/><rect width="30" height="14" x="157" y="11" fill="#10192C"/><rect width="30" height="14" x="188" y="11" fill="#000C18"/><rect width="1" height="14" x="187" y="11" fill="#2B2B4A"/><rect width="1" height="14" x="218" y="11" fill="#2B2B4A"/><rect width="78" height="14" x="234" y="103" fill="#1C1C2A"/><rect width="24" height="14" x="234" y="103" fill="#10192C"/><rect width="24" height="14" x="258" y="103" fill="#000C18"/><rect width=".503" height="14" x="258" y="103" fill="#2B2B4A"/><rect width=".503" height="14" x="282" y="103" fill="#2B2B4A"/><rect width="7" height="4" x="66" y="16" fill="#fff" rx="2"/><rect width="12" height="4" x="76" y="16" fill="#fff" rx="2"/><rect width="12" height="4" x="191" y="16" fill="#777" rx="2"/><rect width="7" height="4" x="260" y="108" fill="#777" rx="2"/><rect width="11" height="4" x="268" y="108" fill="#777" rx="2"/><rect width="4" height="4" x="206" y="16" fill="#777" rx="2"/><rect width="5" height="4" x="160" y="16" fill="#282828" rx="2"/><rect width="16" height="4" x="166" y="16" fill="#282828" rx="2"/><rect width="16" height="4" x="237" y="108" fill="#282828" rx="2"/><rect width="15" height="4" x="33" y="16" fill="#777" rx="2"/><rect width="4" height="4" x="4" y="3" fill="#FD605E" rx="2"/><rect width="4" height="4" x="10" y="3" fill="#FBBC3F" rx="2"/><rect width="4" height="4" x="16" y="3" fill="#34C942" rx="2"/><rect width="6" height="4" x="2" y="16" fill="#777" rx="2"/><rect width="18" height="4" x="10" y="16" fill="#777" rx="2"/></svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -1,51 +1 @@
<svg width="312" height="200" viewBox="0 0 312 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="311.504" height="200" rx="5" fill="white"/>
<path d="M0 5C0 2.23858 2.23858 0 5 0H307C309.761 0 312 2.23858 312 5V11H0V5Z" fill="#DCDCDC"/>
<rect y="10" width="312" height="1" fill="#BABABA"/>
<rect y="11" width="156" height="189" fill="#A8A8A8"/>
<rect x="156" y="11" width="156" height="91" fill="#000C18"/>
<rect x="234" y="102" width="78" height="98" fill="#000C18"/>
<rect x="156" y="102" width="78" height="98" fill="#000C18"/>
<rect y="24" width="156" height="176" fill="#000C18"/>
<rect x="157" y="102" width="155" height="1" fill="#2B2B4A"/>
<rect width="1" height="189" transform="matrix(-1 0 0 1 157 11)" fill="#2B2B4A"/>
<path d="M234 103H233V200H234V103Z" fill="#2B2B4A"/>
<rect y="11" width="156" height="14" fill="#1C1C2A"/>
<rect y="11" width="30" height="14" fill="#10192C"/>
<rect x="31" y="11" width="30" height="14" fill="#10192C"/>
<rect x="62" y="11" width="30" height="14" fill="#000C18"/>
<rect x="30" y="11" width="1" height="14" fill="#2B2B4A"/>
<rect x="61" y="11" width="1" height="14" fill="#2B2B4A"/>
<rect x="92" y="11" width="1" height="14" fill="#2B2B4A"/>
<rect x="157" y="11" width="155" height="14" fill="#1C1C2A"/>
<rect x="157" y="11" width="30" height="14" fill="#10192C"/>
<rect x="188" y="11" width="30" height="14" fill="#000C18"/>
<rect x="187" y="11" width="1" height="14" fill="#2B2B4A"/>
<rect x="218" y="11" width="1" height="14" fill="#2B2B4A"/>
<rect x="234" y="103" width="78" height="14" fill="#1C1C2A"/>
<rect x="234" y="103" width="24" height="14" fill="#10192C"/>
<rect x="258" y="103" width="24" height="14" fill="#000C18"/>
<rect x="258" y="103" width="0.503226" height="14" fill="#2B2B4A"/>
<rect x="282" y="103" width="0.503226" height="14" fill="#2B2B4A"/>
<rect x="66" y="16" width="7" height="4" rx="2" fill="white"/>
<rect x="76" y="16" width="12" height="4" rx="2" fill="white"/>
<rect x="191" y="16" width="12" height="4" rx="2" fill="#777777"/>
<rect x="260" y="108" width="7" height="4" rx="2" fill="#777777"/>
<rect x="268" y="108" width="11" height="4" rx="2" fill="#777777"/>
<rect x="206" y="16" width="4" height="4" rx="2" fill="#777777"/>
<rect x="160" y="16" width="5" height="4" rx="2" fill="#282828"/>
<rect x="166" y="16" width="16" height="4" rx="2" fill="#282828"/>
<rect x="237" y="108" width="16" height="4" rx="2" fill="#282828"/>
<rect x="33" y="16" width="15" height="4" rx="2" fill="#777777"/>
<rect x="4" y="3" width="4" height="4" rx="2" fill="#FD605E"/>
<rect x="10" y="3" width="4" height="4" rx="2" fill="#FBBC3F"/>
<rect x="16" y="3" width="4" height="4" rx="2" fill="#34C942"/>
<rect x="2" y="16" width="6" height="4" rx="2" fill="#777777"/>
<rect x="10" y="16" width="18" height="4" rx="2" fill="#777777"/>
<rect x="157" y="61" width="155" height="41" fill="#E1E1E1" fill-opacity="0.25"/>
<rect x="172.5" y="68.5" width="29" height="13" fill="#000C18" stroke="#2B2B4A"/>
<rect x="176" y="73" width="7" height="4" rx="2" fill="white"/>
<rect x="187" y="73" width="12" height="4" rx="2" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M201.344 83.2654C201.52 83.1426 201.51 82.8799 201.327 82.77L197.18 80.2905C196.961 80.1595 196.691 80.3492 196.739 80.5997L197.651 85.344C197.691 85.5542 197.935 85.653 198.11 85.5302L198.772 85.067C198.867 85.0002 198.914 84.8836 198.892 84.7693L198.602 83.2612C198.554 83.0106 198.825 82.821 199.044 82.952L200.362 83.7401C200.462 83.7999 200.588 83.7954 200.683 83.7286L201.344 83.2654Z" fill="white"/>
<rect x="200.5" y="84.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="312" height="200" fill="none" viewBox="0 0 312 200"><rect width="311.504" height="200" fill="#fff" rx="5"/><path fill="#DCDCDC" d="M0 5C0 2.23858 2.23858 0 5 0H307C309.761 0 312 2.23858 312 5V11H0V5Z"/><rect width="312" height="1" y="10" fill="#BABABA"/><rect width="156" height="189" y="11" fill="#A8A8A8"/><rect width="156" height="91" x="156" y="11" fill="#000C18"/><rect width="78" height="98" x="234" y="102" fill="#000C18"/><rect width="78" height="98" x="156" y="102" fill="#000C18"/><rect width="156" height="176" y="24" fill="#000C18"/><rect width="155" height="1" x="157" y="102" fill="#2B2B4A"/><rect width="1" height="189" fill="#2B2B4A" transform="matrix(-1 0 0 1 157 11)"/><path fill="#2B2B4A" d="M234 103H233V200H234V103Z"/><rect width="156" height="14" y="11" fill="#1C1C2A"/><rect width="30" height="14" y="11" fill="#10192C"/><rect width="30" height="14" x="31" y="11" fill="#10192C"/><rect width="30" height="14" x="62" y="11" fill="#000C18"/><rect width="1" height="14" x="30" y="11" fill="#2B2B4A"/><rect width="1" height="14" x="61" y="11" fill="#2B2B4A"/><rect width="1" height="14" x="92" y="11" fill="#2B2B4A"/><rect width="155" height="14" x="157" y="11" fill="#1C1C2A"/><rect width="30" height="14" x="157" y="11" fill="#10192C"/><rect width="30" height="14" x="188" y="11" fill="#000C18"/><rect width="1" height="14" x="187" y="11" fill="#2B2B4A"/><rect width="1" height="14" x="218" y="11" fill="#2B2B4A"/><rect width="78" height="14" x="234" y="103" fill="#1C1C2A"/><rect width="24" height="14" x="234" y="103" fill="#10192C"/><rect width="24" height="14" x="258" y="103" fill="#000C18"/><rect width=".503" height="14" x="258" y="103" fill="#2B2B4A"/><rect width=".503" height="14" x="282" y="103" fill="#2B2B4A"/><rect width="7" height="4" x="66" y="16" fill="#fff" rx="2"/><rect width="12" height="4" x="76" y="16" fill="#fff" rx="2"/><rect width="12" height="4" x="191" y="16" fill="#777" rx="2"/><rect width="7" height="4" x="260" y="108" fill="#777" rx="2"/><rect width="11" height="4" x="268" y="108" fill="#777" rx="2"/><rect width="4" height="4" x="206" y="16" fill="#777" rx="2"/><rect width="5" height="4" x="160" y="16" fill="#282828" rx="2"/><rect width="16" height="4" x="166" y="16" fill="#282828" rx="2"/><rect width="16" height="4" x="237" y="108" fill="#282828" rx="2"/><rect width="15" height="4" x="33" y="16" fill="#777" rx="2"/><rect width="4" height="4" x="4" y="3" fill="#FD605E" rx="2"/><rect width="4" height="4" x="10" y="3" fill="#FBBC3F" rx="2"/><rect width="4" height="4" x="16" y="3" fill="#34C942" rx="2"/><rect width="6" height="4" x="2" y="16" fill="#777" rx="2"/><rect width="18" height="4" x="10" y="16" fill="#777" rx="2"/><rect width="155" height="41" x="157" y="61" fill="#E1E1E1" fill-opacity=".25"/><rect width="29" height="13" x="172.5" y="68.5" fill="#000C18" stroke="#2B2B4A"/><rect width="7" height="4" x="176" y="73" fill="#fff" rx="2"/><rect width="12" height="4" x="187" y="73" fill="#fff" rx="2"/><path fill="#fff" fill-rule="evenodd" d="M201.344 83.2654C201.52 83.1426 201.51 82.8799 201.327 82.77L197.18 80.2905C196.961 80.1595 196.691 80.3492 196.739 80.5997L197.651 85.344C197.691 85.5542 197.935 85.653 198.11 85.5302L198.772 85.067C198.867 85.0002 198.914 84.8836 198.892 84.7693L198.602 83.2612C198.554 83.0106 198.825 82.821 199.044 82.952L200.362 83.7401C200.462 83.7999 200.588 83.7954 200.683 83.7286L201.344 83.2654Z" clip-rule="evenodd"/><rect width="4" height="2" x="200.5" y="84.5" stroke="#fff" stroke-dasharray=".25 .25"/></svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -1,45 +1 @@
<svg width="312" height="200" viewBox="0 0 312 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 5C0 2.23858 2.23858 0 5 0H307C309.761 0 312 2.23858 312 5V11H0V5Z" fill="#DCDCDC"/>
<rect y="10" width="312" height="1" fill="#BABABA"/>
<rect x="4" y="3" width="4" height="4" rx="2" fill="#FD605E"/>
<rect x="10" y="3" width="4" height="4" rx="2" fill="#FBBC3F"/>
<rect x="16" y="3" width="4" height="4" rx="2" fill="#34C942"/>
<rect y="11" width="312" height="189" fill="#D9D9D9"/>
<rect y="11" width="166" height="189" fill="#000C18"/>
<rect x="167" y="11" width="145" height="189" fill="#000C18"/>
<rect x="166" y="11" width="1" height="189" fill="#2B2B4A"/>
<rect x="167" y="56" width="145" height="1" fill="#2B2B4A"/>
<rect x="167" y="112" width="145" height="1" fill="#2B2B4A"/>
<rect y="11" width="166" height="10" fill="#1C1C2A"/>
<rect y="22" width="166" height="10" fill="#1C1C2A"/>
<rect y="94" width="166" height="10" fill="#1C1C2A"/>
<rect y="190" width="166" height="10" fill="#1C1C2A"/>
<rect y="21" width="166" height="1" fill="#2B2B4A"/>
<rect x="11" y="14" width="21" height="4" rx="2" fill="white"/>
<rect x="34" y="14" width="11" height="4" rx="2" fill="white"/>
<rect x="11" y="25" width="6" height="4" rx="2" fill="white"/>
<rect x="19" y="25" width="11" height="4" rx="2" fill="white"/>
<rect x="11" y="97" width="16" height="4" rx="2" fill="white"/>
<rect x="29" y="97" width="5" height="4" rx="2" fill="white"/>
<rect x="11" y="193" width="14" height="4" rx="2" fill="white"/>
<path d="M5 29L2 25.6078L2.5375 25L5 27.7986L7.4625 25.0141L8 25.6219L5 29Z" fill="white"/>
<path d="M5 101L2 97.6078L2.5375 97L5 99.7986L7.4625 97.0141L8 97.6219L5 101Z" fill="white"/>
<path d="M6 16L2.60777 19L2 18.4625L4.79859 16L2.01413 13.5375L2.62191 13L6 16Z" fill="white"/>
<path d="M6 195L2.60777 198L2 197.463L4.79859 195L2.01413 192.538L2.62191 192L6 195Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M212.674 111C212.91 111 213.068 110.779 212.971 110.584L210.797 106.175C210.682 105.942 210.318 105.942 210.203 106.175L208.029 110.584C207.932 110.779 208.09 111 208.326 111H209.215C209.343 111 209.46 110.932 209.512 110.825L210.203 109.424C210.318 109.191 210.682 109.191 210.797 109.424L211.488 110.825C211.54 110.932 211.657 111 211.785 111H212.674Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M208.326 114C208.09 114 207.932 114.221 208.029 114.416L210.203 118.825C210.318 119.058 210.682 119.058 210.797 118.825L212.971 114.416C213.068 114.221 212.91 114 212.674 114H211.785C211.657 114 211.54 114.068 211.488 114.175L210.797 115.576C210.682 115.809 210.318 115.809 210.203 115.576L209.512 114.175C209.46 114.068 209.343 114 209.215 114H208.326Z" fill="white"/>
<line x1="210.5" y1="116" x2="210.5" y2="109" stroke="white"/>
<rect x="175" y="18" width="20" height="19" rx="2" fill="#777777"/>
<rect x="198" y="18" width="5" height="5" rx="2" fill="#777777"/>
<rect x="206" y="18" width="26" height="5" rx="2" fill="#777777"/>
<rect x="203" y="71" width="44" height="5" rx="2" fill="#777777"/>
<rect x="228" y="78" width="44" height="14" rx="2" fill="#777777"/>
<rect x="250" y="71" width="22" height="5" rx="2" fill="#777777"/>
<rect x="239" y="95" width="33" height="5" rx="2" fill="#777777"/>
<rect x="272" y="117" width="33" height="5" rx="2" fill="#777777"/>
<rect x="259" y="117" width="7" height="5" rx="2" fill="#777777"/>
<rect x="213" y="95" width="23" height="5" rx="2" fill="#777777"/>
<rect x="203" y="95" width="8" height="5" rx="2" fill="#777777"/>
<rect x="198" y="25" width="15" height="5" rx="2" fill="#777777"/>
<rect x="215" y="25" width="18" height="5" rx="2" fill="#777777"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="312" height="200" fill="none" viewBox="0 0 312 200"><path fill="#DCDCDC" d="M0 5C0 2.23858 2.23858 0 5 0H307C309.761 0 312 2.23858 312 5V11H0V5Z"/><rect width="312" height="1" y="10" fill="#BABABA"/><rect width="4" height="4" x="4" y="3" fill="#FD605E" rx="2"/><rect width="4" height="4" x="10" y="3" fill="#FBBC3F" rx="2"/><rect width="4" height="4" x="16" y="3" fill="#34C942" rx="2"/><rect width="312" height="189" y="11" fill="#D9D9D9"/><rect width="166" height="189" y="11" fill="#000C18"/><rect width="145" height="189" x="167" y="11" fill="#000C18"/><rect width="1" height="189" x="166" y="11" fill="#2B2B4A"/><rect width="145" height="1" x="167" y="56" fill="#2B2B4A"/><rect width="145" height="1" x="167" y="112" fill="#2B2B4A"/><rect width="166" height="10" y="11" fill="#1C1C2A"/><rect width="166" height="10" y="22" fill="#1C1C2A"/><rect width="166" height="10" y="94" fill="#1C1C2A"/><rect width="166" height="10" y="190" fill="#1C1C2A"/><rect width="166" height="1" y="21" fill="#2B2B4A"/><rect width="21" height="4" x="11" y="14" fill="#fff" rx="2"/><rect width="11" height="4" x="34" y="14" fill="#fff" rx="2"/><rect width="6" height="4" x="11" y="25" fill="#fff" rx="2"/><rect width="11" height="4" x="19" y="25" fill="#fff" rx="2"/><rect width="16" height="4" x="11" y="97" fill="#fff" rx="2"/><rect width="5" height="4" x="29" y="97" fill="#fff" rx="2"/><rect width="14" height="4" x="11" y="193" fill="#fff" rx="2"/><path fill="#fff" d="M5 29L2 25.6078L2.5375 25L5 27.7986L7.4625 25.0141L8 25.6219L5 29Z"/><path fill="#fff" d="M5 101L2 97.6078L2.5375 97L5 99.7986L7.4625 97.0141L8 97.6219L5 101Z"/><path fill="#fff" d="M6 16L2.60777 19L2 18.4625L4.79859 16L2.01413 13.5375L2.62191 13L6 16Z"/><path fill="#fff" d="M6 195L2.60777 198L2 197.463L4.79859 195L2.01413 192.538L2.62191 192L6 195Z"/><path fill="#fff" fill-rule="evenodd" d="M212.674 111C212.91 111 213.068 110.779 212.971 110.584L210.797 106.175C210.682 105.942 210.318 105.942 210.203 106.175L208.029 110.584C207.932 110.779 208.09 111 208.326 111H209.215C209.343 111 209.46 110.932 209.512 110.825L210.203 109.424C210.318 109.191 210.682 109.191 210.797 109.424L211.488 110.825C211.54 110.932 211.657 111 211.785 111H212.674Z" clip-rule="evenodd"/><path fill="#fff" fill-rule="evenodd" d="M208.326 114C208.09 114 207.932 114.221 208.029 114.416L210.203 118.825C210.318 119.058 210.682 119.058 210.797 118.825L212.971 114.416C213.068 114.221 212.91 114 212.674 114H211.785C211.657 114 211.54 114.068 211.488 114.175L210.797 115.576C210.682 115.809 210.318 115.809 210.203 115.576L209.512 114.175C209.46 114.068 209.343 114 209.215 114H208.326Z" clip-rule="evenodd"/><line x1="210.5" x2="210.5" y1="116" y2="109" stroke="#fff"/><rect width="20" height="19" x="175" y="18" fill="#777" rx="2"/><rect width="5" height="5" x="198" y="18" fill="#777" rx="2"/><rect width="26" height="5" x="206" y="18" fill="#777" rx="2"/><rect width="44" height="5" x="203" y="71" fill="#777" rx="2"/><rect width="44" height="14" x="228" y="78" fill="#777" rx="2"/><rect width="22" height="5" x="250" y="71" fill="#777" rx="2"/><rect width="33" height="5" x="239" y="95" fill="#777" rx="2"/><rect width="33" height="5" x="272" y="117" fill="#777" rx="2"/><rect width="7" height="5" x="259" y="117" fill="#777" rx="2"/><rect width="23" height="5" x="213" y="95" fill="#777" rx="2"/><rect width="8" height="5" x="203" y="95" fill="#777" rx="2"/><rect width="15" height="5" x="198" y="25" fill="#777" rx="2"/><rect width="18" height="5" x="215" y="25" fill="#777" rx="2"/></svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -1,20 +1 @@
<svg width="156" height="76" viewBox="0 0 156 76" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect y="14" width="156" height="62" fill="#000C18"/>
<rect width="156" height="14" fill="#1C1C2A"/>
<rect width="30" height="14" fill="#10192C"/>
<rect x="31" width="30" height="14" fill="#10192C"/>
<rect x="30" width="1" height="14" fill="#2B2B4A"/>
<rect x="61" width="1" height="14" fill="#2B2B4A"/>
<rect x="41" y="54" width="30" height="14" fill="#000C18"/>
<rect x="33" y="5" width="15" height="4" rx="2" fill="#777777"/>
<rect x="2" y="5" width="6" height="4" rx="2" fill="#777777"/>
<rect x="10" y="5" width="18" height="4" rx="2" fill="#777777"/>
<rect x="68.5" y="7.5" width="83" height="60" fill="#000C18" stroke="#2B2B4A"/>
<rect x="100" y="8" width="51" height="14" fill="#1C1C2A"/>
<rect x="83" y="13" width="12" height="4" rx="2" fill="white"/>
<rect x="73" y="13" width="7" height="4" rx="2" fill="white"/>
<rect x="99" y="8" width="1" height="14" fill="#2B2B4A"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.3445 8.26544C70.5198 8.14263 70.5104 7.87986 70.3266 7.76998L66.1804 5.29049C65.9614 5.15953 65.6906 5.34916 65.7388 5.59974L66.6506 10.344C66.691 10.5542 66.9347 10.653 67.1101 10.5302L67.7716 10.067C67.8669 10.0002 67.9142 9.88362 67.8922 9.76929L67.6024 8.26123C67.5542 8.01064 67.825 7.82101 68.044 7.95197L69.362 8.74015C69.4619 8.79989 69.5876 8.79538 69.683 8.7286L70.3445 8.26544Z" fill="white"/>
<rect x="69.5" y="9.5" width="4" height="2" stroke="white" stroke-dasharray="0.25 0.25"/>
<path d="M70.9414 4.47461V4.81445H68.9922V4.47461H70.9414ZM70.1484 3.64453V5.71484H69.7871V3.64453H70.1484ZM73.9473 5.28125C73.9473 5.21484 73.9368 5.15625 73.916 5.10547C73.8965 5.05339 73.8613 5.00651 73.8105 4.96484C73.7611 4.92318 73.6921 4.88346 73.6035 4.8457C73.5163 4.80794 73.4056 4.76953 73.2715 4.73047C73.1309 4.6888 73.0039 4.64258 72.8906 4.5918C72.7773 4.53971 72.6803 4.48047 72.5996 4.41406C72.5189 4.34766 72.457 4.27148 72.4141 4.18555C72.3711 4.09961 72.3496 4.0013 72.3496 3.89062C72.3496 3.77995 72.3724 3.67773 72.418 3.58398C72.4635 3.49023 72.5286 3.40885 72.6133 3.33984C72.6992 3.26953 72.8014 3.21484 72.9199 3.17578C73.0384 3.13672 73.1706 3.11719 73.3164 3.11719C73.5299 3.11719 73.7109 3.1582 73.8594 3.24023C74.0091 3.32096 74.123 3.42708 74.2012 3.55859C74.2793 3.6888 74.3184 3.82812 74.3184 3.97656H73.9434C73.9434 3.86979 73.9206 3.77539 73.875 3.69336C73.8294 3.61003 73.7604 3.54492 73.668 3.49805C73.5755 3.44987 73.4583 3.42578 73.3164 3.42578C73.1823 3.42578 73.0716 3.44596 72.9844 3.48633C72.8971 3.52669 72.832 3.58138 72.7891 3.65039C72.7474 3.7194 72.7266 3.79818 72.7266 3.88672C72.7266 3.94661 72.7389 4.0013 72.7637 4.05078C72.7897 4.09896 72.8294 4.14388 72.8828 4.18555C72.9375 4.22721 73.0065 4.26562 73.0898 4.30078C73.1745 4.33594 73.2754 4.36979 73.3926 4.40234C73.554 4.44792 73.6934 4.4987 73.8105 4.55469C73.9277 4.61068 74.0241 4.67383 74.0996 4.74414C74.1764 4.81315 74.2331 4.89193 74.2695 4.98047C74.3073 5.06771 74.3262 5.16667 74.3262 5.27734C74.3262 5.39323 74.3027 5.49805 74.2559 5.5918C74.209 5.68555 74.1419 5.76562 74.0547 5.83203C73.9674 5.89844 73.8626 5.94987 73.7402 5.98633C73.6191 6.02148 73.4837 6.03906 73.334 6.03906C73.2025 6.03906 73.0729 6.02083 72.9453 5.98438C72.819 5.94792 72.7038 5.89323 72.5996 5.82031C72.4967 5.7474 72.4141 5.65755 72.3516 5.55078C72.2904 5.44271 72.2598 5.31771 72.2598 5.17578H72.6348C72.6348 5.27344 72.6536 5.35742 72.6914 5.42773C72.7292 5.49674 72.7806 5.55404 72.8457 5.59961C72.9121 5.64518 72.987 5.67904 73.0703 5.70117C73.1549 5.72201 73.2428 5.73242 73.334 5.73242C73.4655 5.73242 73.5768 5.71419 73.668 5.67773C73.7591 5.64128 73.8281 5.58919 73.875 5.52148C73.9232 5.45378 73.9473 5.3737 73.9473 5.28125ZM76.6641 4.37891V4.68555H75.125V4.37891H76.6641ZM75.1836 3.15625V6H74.8066V3.15625H75.1836ZM76.9922 3.15625V6H76.6172V3.15625H76.9922ZM78.0664 3.15625V6H77.6895V3.15625H78.0664ZM79.1289 3.15625V6H78.752V3.15625H79.1289ZM80.3203 4.43555V4.74414H79.0469V4.43555H80.3203ZM80.5137 3.15625V3.46484H79.0469V3.15625H80.5137ZM82.0527 3.15625V6H81.6816V3.15625H82.0527ZM82.9668 3.15625V3.46484H80.7695V3.15625H82.9668ZM84.6797 3.15625V6H84.3027V3.15625H84.6797ZM86.3965 3.15625L85.2148 4.48242L84.5508 5.17188L84.4883 4.76953L84.9883 4.21875L85.9434 3.15625H86.3965ZM86.0332 6L84.9805 4.61328L85.2051 4.31445L86.4824 6H86.0332ZM88.6211 5.69336V6H87.1152V5.69336H88.6211ZM87.1914 3.15625V6H86.8145V3.15625H87.1914ZM88.4219 4.37891V4.68555H87.1152V4.37891H88.4219ZM88.6016 3.15625V3.46484H87.1152V3.15625H88.6016ZM89.2188 3.15625L89.957 4.58398L90.6973 3.15625H91.125L90.1445 4.9375V6H89.7676V4.9375L88.7871 3.15625H89.2188Z" fill="white"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="156" height="76" fill="none" viewBox="0 0 156 76"><rect width="156" height="62" y="14" fill="#000C18"/><rect width="156" height="14" fill="#1C1C2A"/><rect width="30" height="14" fill="#10192C"/><rect width="30" height="14" x="31" fill="#10192C"/><rect width="1" height="14" x="30" fill="#2B2B4A"/><rect width="1" height="14" x="61" fill="#2B2B4A"/><rect width="30" height="14" x="41" y="54" fill="#000C18"/><rect width="15" height="4" x="33" y="5" fill="#777" rx="2"/><rect width="6" height="4" x="2" y="5" fill="#777" rx="2"/><rect width="18" height="4" x="10" y="5" fill="#777" rx="2"/><rect width="83" height="60" x="68.5" y="7.5" fill="#000C18" stroke="#2B2B4A"/><rect width="51" height="14" x="100" y="8" fill="#1C1C2A"/><rect width="12" height="4" x="83" y="13" fill="#fff" rx="2"/><rect width="7" height="4" x="73" y="13" fill="#fff" rx="2"/><rect width="1" height="14" x="99" y="8" fill="#2B2B4A"/><path fill="#fff" fill-rule="evenodd" d="M70.3445 8.26544C70.5198 8.14263 70.5104 7.87986 70.3266 7.76998L66.1804 5.29049C65.9614 5.15953 65.6906 5.34916 65.7388 5.59974L66.6506 10.344C66.691 10.5542 66.9347 10.653 67.1101 10.5302L67.7716 10.067C67.8669 10.0002 67.9142 9.88362 67.8922 9.76929L67.6024 8.26123C67.5542 8.01064 67.825 7.82101 68.044 7.95197L69.362 8.74015C69.4619 8.79989 69.5876 8.79538 69.683 8.7286L70.3445 8.26544Z" clip-rule="evenodd"/><rect width="4" height="2" x="69.5" y="9.5" stroke="#fff" stroke-dasharray=".25 .25"/><path fill="#fff" d="M70.9414 4.47461V4.81445H68.9922V4.47461H70.9414ZM70.1484 3.64453V5.71484H69.7871V3.64453H70.1484ZM73.9473 5.28125C73.9473 5.21484 73.9368 5.15625 73.916 5.10547C73.8965 5.05339 73.8613 5.00651 73.8105 4.96484C73.7611 4.92318 73.6921 4.88346 73.6035 4.8457C73.5163 4.80794 73.4056 4.76953 73.2715 4.73047C73.1309 4.6888 73.0039 4.64258 72.8906 4.5918C72.7773 4.53971 72.6803 4.48047 72.5996 4.41406C72.5189 4.34766 72.457 4.27148 72.4141 4.18555C72.3711 4.09961 72.3496 4.0013 72.3496 3.89062C72.3496 3.77995 72.3724 3.67773 72.418 3.58398C72.4635 3.49023 72.5286 3.40885 72.6133 3.33984C72.6992 3.26953 72.8014 3.21484 72.9199 3.17578C73.0384 3.13672 73.1706 3.11719 73.3164 3.11719C73.5299 3.11719 73.7109 3.1582 73.8594 3.24023C74.0091 3.32096 74.123 3.42708 74.2012 3.55859C74.2793 3.6888 74.3184 3.82812 74.3184 3.97656H73.9434C73.9434 3.86979 73.9206 3.77539 73.875 3.69336C73.8294 3.61003 73.7604 3.54492 73.668 3.49805C73.5755 3.44987 73.4583 3.42578 73.3164 3.42578C73.1823 3.42578 73.0716 3.44596 72.9844 3.48633C72.8971 3.52669 72.832 3.58138 72.7891 3.65039C72.7474 3.7194 72.7266 3.79818 72.7266 3.88672C72.7266 3.94661 72.7389 4.0013 72.7637 4.05078C72.7897 4.09896 72.8294 4.14388 72.8828 4.18555C72.9375 4.22721 73.0065 4.26562 73.0898 4.30078C73.1745 4.33594 73.2754 4.36979 73.3926 4.40234C73.554 4.44792 73.6934 4.4987 73.8105 4.55469C73.9277 4.61068 74.0241 4.67383 74.0996 4.74414C74.1764 4.81315 74.2331 4.89193 74.2695 4.98047C74.3073 5.06771 74.3262 5.16667 74.3262 5.27734C74.3262 5.39323 74.3027 5.49805 74.2559 5.5918C74.209 5.68555 74.1419 5.76562 74.0547 5.83203C73.9674 5.89844 73.8626 5.94987 73.7402 5.98633C73.6191 6.02148 73.4837 6.03906 73.334 6.03906C73.2025 6.03906 73.0729 6.02083 72.9453 5.98438C72.819 5.94792 72.7038 5.89323 72.5996 5.82031C72.4967 5.7474 72.4141 5.65755 72.3516 5.55078C72.2904 5.44271 72.2598 5.31771 72.2598 5.17578H72.6348C72.6348 5.27344 72.6536 5.35742 72.6914 5.42773C72.7292 5.49674 72.7806 5.55404 72.8457 5.59961C72.9121 5.64518 72.987 5.67904 73.0703 5.70117C73.1549 5.72201 73.2428 5.73242 73.334 5.73242C73.4655 5.73242 73.5768 5.71419 73.668 5.67773C73.7591 5.64128 73.8281 5.58919 73.875 5.52148C73.9232 5.45378 73.9473 5.3737 73.9473 5.28125ZM76.6641 4.37891V4.68555H75.125V4.37891H76.6641ZM75.1836 3.15625V6H74.8066V3.15625H75.1836ZM76.9922 3.15625V6H76.6172V3.15625H76.9922ZM78.0664 3.15625V6H77.6895V3.15625H78.0664ZM79.1289 3.15625V6H78.752V3.15625H79.1289ZM80.3203 4.43555V4.74414H79.0469V4.43555H80.3203ZM80.5137 3.15625V3.46484H79.0469V3.15625H80.5137ZM82.0527 3.15625V6H81.6816V3.15625H82.0527ZM82.9668 3.15625V3.46484H80.7695V3.15625H82.9668ZM84.6797 3.15625V6H84.3027V3.15625H84.6797ZM86.3965 3.15625L85.2148 4.48242L84.5508 5.17188L84.4883 4.76953L84.9883 4.21875L85.9434 3.15625H86.3965ZM86.0332 6L84.9805 4.61328L85.2051 4.31445L86.4824 6H86.0332ZM88.6211 5.69336V6H87.1152V5.69336H88.6211ZM87.1914 3.15625V6H86.8145V3.15625H87.1914ZM88.4219 4.37891V4.68555H87.1152V4.37891H88.4219ZM88.6016 3.15625V3.46484H87.1152V3.15625H88.6016ZM89.2188 3.15625L89.957 4.58398L90.6973 3.15625H91.125L90.1445 4.9375V6H89.7676V4.9375L88.7871 3.15625H89.2188Z"/></svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 KiB

After

Width:  |  Height:  |  Size: 515 KiB

View File

@ -105,9 +105,89 @@ function parseType(obj) {
}
}
function parseComplexType(obj) {
switch (obj.type) {
case 'union':
return {
type: 'or',
values: obj.types.map(parseComplexType).reverse(),
};
case 'intrinsic':
return { type: obj.type, value: obj.name };
case 'literal':
return { type: obj.type, value: obj.value };
case 'reflection':
return { type: obj.type, value: parse(obj.declaration) };
case 'reference': {
if (obj.refersToTypeParameter) {
return {
type: obj.type,
value: obj.name,
source: obj.package,
refersToTypeParameter: true,
};
}
if (obj.qualifiedName) {
return {
type: obj.type,
value: obj.qualifiedName,
source: obj.sourceFileName
? obj.sourceFileName.startsWith('packages/dockview')
? 'dockview'
: 'external'
: obj.package,
typeArguments: obj.typeArguments?.map(parseComplexType),
};
}
return {
type: obj.type,
value: obj.name,
source: obj.package,
typeArguments: obj.typeArguments?.map(parseComplexType),
};
}
case 'array':
return {
type: obj.type,
value: parseComplexType(obj.elementType),
};
case 'intersection':
return {
type: obj.type,
values: obj.types.map(parseComplexType).reverse(),
};
case 'predicate':
return {
type: obj.type,
lhs: obj.name,
rhs: parseComplexType(obj.targetType),
};
case 'tuple':
return {
type: obj.type,
values: obj.elements.map(parseComplexType),
};
default:
throw new Error(`unhandled type ${obj.type}`);
}
}
function extractPiecesFromType(obj) {
if (obj.type === 'reference' && obj.package?.startsWith('dockview-')) {
return obj.name;
let result = { name: obj.name };
if (Array.isArray(obj.typeArguments)) {
const typeArgs = obj.typeArguments
.map(extractPiecesFromType)
.filter(Boolean);
if (typeArgs.length > 0) {
result.typeArgs = typeArgs;
}
}
return result;
}
return null;
}
@ -126,14 +206,15 @@ function parse(data) {
const getSignature = parse(data.getSignature);
code += getSignature.code;
pieces.push(...getSignature.pieces);
// pieces.push(...getSignature.pieces);
return {
name,
code,
kind: 'accessor',
value: getSignature,
comment: getSignature.comment,
pieces,
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.Method: // 2048
const methodSignature = data.signatures.map((signature) =>
@ -149,20 +230,25 @@ function parse(data) {
name,
code,
kind: 'method',
signature: methodSignature,
comment: data.signatures[0].comment,
pieces,
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.Property: // 1024
code += parseType(data.type);
pieces.push(extractPiecesFromType(data.type));
pieces.push({
kind: 'property',
value: extractPiecesFromType(data.type),
});
return {
name,
code,
kind: 'property',
type: parseComplexType(data.type),
flags,
comment,
pieces,
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.Parameter: // 32768
@ -174,14 +260,21 @@ function parse(data) {
code += ': ';
code += parseType(data.type);
pieces.push(extractPiecesFromType(data.type));
pieces.push({
kind: 'parameter',
value: extractPiecesFromType(data.type),
});
return {
name,
code,
pieces,
type: parseComplexType(data.type),
kind: 'parameter',
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.TypeLiteral: // 65536
let result = {};
if (Array.isArray(data.children)) {
code += `{ `;
code += data.children
@ -192,46 +285,91 @@ function parse(data) {
code += '?';
}
const childData = parse(child);
pieces.push(...childData.pieces);
// pieces.push(...childData.pieces);
code += `: ${childData.code}`;
return code;
})
.join(', ');
code += ` }`;
result.properties = data.children.map((_) => {
const result = parse(_);
if (result.kind !== 'property') {
throw new Error(`invalid ${result.kind}`);
}
return result;
});
}
if (Array.isArray(data.signatures)) {
const signatures = data.signatures.map((signature) =>
parse(signature)
);
const signatures = data.signatures.map((signature) => {
const result = parse(signature);
if (
result.kind !== 'callSignature' &&
result.kind !== 'constructorSignature'
) {
throw new Error(`invalid ${result.kind}`);
}
return result;
});
code += signatures
.map((signature) => signature.code)
.join(', ');
pieces.push(...signatures.flatMap((_) => _.pieces));
// pieces.push(...signatures.flatMap((_) => _.pieces));
if (result.type) {
throw new Error('anc');
}
result.signatures = signatures;
}
return { name, code, pieces };
return {
name,
code,
// pieces,
kind: 'typeLiteral',
properties: result.properties,
signatures: result.signatures,
};
case ReflectionKind.CallSignature: // 4096
// don't care for constrcutors
const typeParameters = [];
let _parameters = [];
if (Array.isArray(data.typeParameter)) {
code += `<${data.typeParameter.map((typeParameter) => {
let type = `${typeParameter.name}`;
const result = { name: type };
if (typeParameter.type) {
type += ` extends ${parseType(typeParameter.type)}`;
pieces.push(extractPiecesFromType(typeParameter.type));
result.extends = parseComplexType(typeParameter.type);
pieces.push({
kind: 'typearg',
value: extractPiecesFromType(typeParameter.type),
});
}
if (typeParameter.default) {
type += ` = ${typeParameter.default.name}`;
pieces.push(
extractPiecesFromType(typeParameter.default)
);
pieces.push({
kind: 'typearg_default',
value: extractPiecesFromType(typeParameter.default),
});
result.default = typeParameter.default.name;
}
typeParameters.push(result);
return type;
})}>`;
}
@ -242,113 +380,155 @@ function parse(data) {
const parameters = data.parameters.map((parameter) =>
parse(parameter)
);
_parameters = parameters;
code += `${parameters
.map((parameter) => parameter.code)
.join(', ')}`;
pieces.push(...parameters.flatMap((_) => _.pieces));
// pieces.push(...parameters.flatMap((_) => _.pieces));
}
code += '): ';
code += parseType(data.type);
pieces.push(extractPiecesFromType(data.type));
pieces.push({
kind: 'return',
value: extractPiecesFromType(data.type),
});
return {
name,
comment,
typeParameters,
parameters: _parameters,
returnType: parseComplexType(data.type),
code,
pieces,
kind: 'callSignature',
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.GetSignature: // 524288
code += parseType(data.type);
pieces.push(extractPiecesFromType(data.type));
pieces.push({
kind: 'signature',
value: extractPiecesFromType(data.type),
});
return {
name,
comment,
code,
pieces,
kind: 'getSignature',
returnType: parseComplexType(data.type),
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.Function: // 64
if (data.signatures.length > 1) {
throw new Error('unhandled');
}
const functionSignature = parse(data.signatures[0]);
pieces.push(...functionSignature.pieces);
// pieces.push(...functionSignature.pieces);
code += functionSignature.code;
return {
name,
comment,
code,
pieces,
signature: parse(data.signatures[0]),
kind: 'function',
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.Variable: // 32
return {
name,
comment,
code,
pieces,
kind: 'variable',
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.EnumMember: // 16
return {
name,
comment,
code,
pieces,
kind: 'enumMember',
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.Interface: // 16
return {
name,
comment,
code,
pieces,
kind: 'interface',
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.ConstructorSignature: // 16384
return {
name,
comment,
code,
pieces,
kind: 'constructorSignature',
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.Constructor: // 512
// don't care for constrcutors
return {
name,
comment,
kind: 'constructor',
code,
pieces,
// pieces: pieces.filter((_) => _.value !== null),
};
case ReflectionKind.TypeAlias: // 2097152
const typeParameters1 = [];
if (Array.isArray(data.typeParameter)) {
code += `<${data.typeParameter.map((typeParameter) => {
let type = `${typeParameter.name}`;
const result = { name: typeParameter.name };
if (typeParameter.type) {
type += ` extends ${parseType(typeParameter.type)}`;
pieces.push(extractPiecesFromType(typeParameter.type));
result.extends = parseComplexType(typeParameter.type);
pieces.push({
kind: 'typearg',
value: extractPiecesFromType(typeParameter.type),
});
}
if (typeParameter.default) {
type += ` = ${typeParameter.default.name}`;
pieces.push(
extractPiecesFromType(typeParameter.default)
);
pieces.push({
kind: 'typearg_default',
value: extractPiecesFromType(typeParameter.default),
});
result.default = typeParameter.default.name;
}
typeParameters1.push(result);
return type;
})}>`;
}
code += parseType(data.type);
pieces.push(extractPiecesFromType(data.type));
pieces.push({
kind: 'typearg',
value: extractPiecesFromType(data.type),
});
return {
name,
comment,
code,
pieces,
typeParameters: typeParameters1,
type: parseComplexType(data.type),
kind: 'typeAlias',
// pieces: pieces.filter((_) => _.value !== null),
};
default:
throw new Error(`unhandled kind ${data.kind}`);
@ -395,11 +575,15 @@ function createDocument(declarations) {
documentation[name] = {
...metadata,
name,
children: [],
};
if (!children) {
documentation[name].metadata = parse(declaration);
documentation[name] = {
...parse(declaration),
};
// documentation[name].metadata = parse(declaration);
}
if (children) {
@ -417,6 +601,8 @@ function createDocument(declarations) {
output.pieces = Array.from(new Set(output.pieces))
.filter(Boolean)
.sort();
delete output.pieces;
// delete output.comment;
documentation[name].children.push(output);
}