FlexLayout icon indicating copy to clipboard operation
FlexLayout copied to clipboard

Config TypeScript Types

Open Vampiro opened this issue 5 years ago • 7 comments

The layout model's json is a very large object with many well defined attributes that could benefit from being exported as TypeScript types so that downstream devs can take advantage of code completion when creating this object.

To be clear, I am talking about this object:

const json = {
  global: {},
  borders: [],
  layout: {}
}

This could use TypeScript types for:

  • The top-most level (containing global, borders, and layout).
  • The top level elements: global, borders, and layout.
  • The four "nodes": border, row, tabset, and tab.

Vampiro avatar Jan 26 '21 14:01 Vampiro

Thanks, that's a good idea

nealus avatar Feb 16 '21 09:02 nealus

If its of any use to anyone, I've tried to map out the json types based on the documentation. I'm not 100% certain about this though, but it works for my configs:

IModelData.ts
-----
// Taken from flexlayout-react/declarations/model/ICloseType.d.ts
enum ICloseType {
 Visible = 1,
 Always = 2,
 Selected = 3,
}

type TabLocationVertical = "top" | "bottom";
type TabLocationHorizontal = "left" | "right";
type TabLocation = TabLocationHorizontal | TabLocationVertical;

interface IModelGlobalSettings {
 splitterSize?: number; // default:  8  width in pixels of all splitters between tabsets/borders
 enableEdgeDock?: boolean; // default:  true
 tabEnableClose?: boolean; // default:  true  allow user to close all tabs via close button
 tabCloseType?: ICloseType; // default:  1  see values in ICloseType
 tabEnableDrag?: boolean; // default:  true  allow user to drag all tabs to new location
 tabEnableRename?: boolean; // default:  true  allow user to rename all tabs by double clicking
 tabEnableFloat?: boolean; // default:  false  enable popouts in all tabs (in popout capable browser)
 tabClassName?: string | null; // default:  null
 tabIcon?: string | null; // default:  null
 tabEnableRenderOnDemand?: boolean; // default:  true  whether to avoid rendering component until tab is visible
 tabDragSpeed?: number; // default:  0.3  CSS transition speed of drag outlines (in seconds)
 tabSetEnableDeleteWhenEmpty?: boolean; // default:  true
 tabSetEnableDrop?: boolean; // default:  true  allow user to drag tabs into all tabsets
 tabSetEnableDrag?: boolean; // default:  true  allow user to drag tabs out of all tabsets
 tabSetEnableDivide?: boolean; // default:  true  allow user to drag tabs to region of all tabsets, splitting into new tabset
 tabSetEnableMaximize?: boolean; // default:  true  allow user to maximize all tabsets to fill view via maximize button
 tabSetAutoSelectTab?: boolean; // default:  true  whether to select new/moved tabs in all tabsets
 tabSetClassNameTabStrip?: string | null; // default:  null  height in pixels of tab strips in all tabsets
 tabSetClassNameHeader?: string | null; // default:  null
 tabSetEnableTabStrip?: boolean; // default:  true  enable tab strip and allow multiple tabs in all tabsets
 tabSetHeaderHeight?: number; // default:  0  height of tabset header in pixels; if left as 0 then the value will be calculated from the current fontSize
 tabSetTabStripHeight?: number; // default:  0  height of tabset tab bar in pixels; if left as 0 then the value will be calculated from the current fontSize
 borderBarSize?: number; // default:  0  size of the border bars in pixels; if left as 0 then the value will be calculated from the current fontSize
 borderEnableDrop?: boolean; // default:  true  allow user to drag tabs into this border
 borderAutoSelectTabWhenOpen?: boolean; // default:  true  whether to select new/moved tabs in border when the border is already open
 borderAutoSelectTabWhenClosed?: boolean; // default:  false  whether to select new/moved tabs in border when the border is curently closed
 borderClassName?: string | null; // default:  null
 borderSize?: number; // default:  200  initial width in pixels for left/right borders, height for top/bottom borders
 borderMinSize?: number; // default:  0  minimum width in pixels for left/right borders, height for top/bottom borders
 tabSetMinHeight?: number; // default:  0  minimum width (in px) for all tabsets
 tabSetMinWidth?: number; // default:  0  minimum height (in px) for all tabsets
 tabSetTabLocation?: TabLocationVertical; // default:  top  show tabs in location top or bottom
}

interface IModelTabNode {
 type: "tab";
 name: string; //  required  internal unique string identifying tab (for factory)
 component: string; //  required  string identifying which component to run (for factory)
 config?: Record<string, any> | null; //  default: null  a place to hold json config for the hosted component
 id?: string; //  default: auto generated
 enableClose?: boolean; //  default: inherited  allow user to close tab via close button
 closeType?: ICloseType; //  default: inherited  see values in ICloseType
 enableDrag?: boolean; //  default: inherited  allow user to drag tab to new location
 enableRename?: boolean; //  default: inherited  allow user to rename tabs by double clicking
 enableFloat?: boolean; //  default: inherited  enable popout (in popout capable browser)
 floating?: boolean; //  default: false
 className?: string; //  default: inherited
 icon?: string; //  default: inherited
 enableRenderOnDemand?: boolean; //  default: inherited  whether to avoid rendering component until tab is visible
}

interface IModelDividerNode {
 type: "row" | "column";
 weight?: number; // default: 100
 width?: number | null; // default: null  preferred width in pixels
 height?: number | null; // default: null  preferred height in pixels
 children: (IModelDividerNode | IModelTabNode | IModelTabSetNode)[];
}

interface IModelTabSetNode {
 type: "tabset";
 active?: boolean;
 weight?: number; // default: 100  	relative weight for sizing of this tabset in parent row
 width?: number | null; // default: null  	preferred pixel width
 height?: number | null; // default: null  	preferred pixel height
 name?: string | null; // default: null  	named tabsets will show a header bar above the tabs
 selected?: number; // default: 0  	index of selected/visible tab in tabset
 maximized?: boolean; // default: false  	whether tabset is currently maximized to fill view
 id?: string; // default: auto generated
 children: IModelTabNode[]; // required  	a list of tab nodes
 enableDeleteWhenEmpty?: boolean; // default: inherited
 enableDrop?: boolean; // default: inherited  	allow user to drag tabs into this tabset
 enableDrag?: boolean; // default: inherited  	allow user to drag tabs out this tabset
 enableDivide?: boolean; // default: inherited  	allow user to drag tabs to region of this tabset, splitting into new tabset
 enableMaximize?: boolean; // default: inherited  	allow user to maximize tabset to fill view via maximize button
 autoSelectTab?: boolean; // default: inherited  	whether to select new/moved tabs in tabset
 classNameTabStrip?: string; // default: inherited
 classNameHeader?: string; // default: inherited
 enableTabStrip?: boolean; // default: inherited  	enable tab strip and allow multiple tabs in this tabset
 headerHeight?: number; // default: inherited
 tabStripHeight?: number; // default: inherited  	height in pixels of tab strip
 tabLocation?: TabLocationVertical; // default: inherited  	show tabs in location top or bottom
 minHeight?: number; // default: inherited  	minimum width (in px) for this tabset
 minWidth?: number; // default: inherited  	minimum height (in px) for this tabset
}

interface IModelBorderNode {
 type: "border";
 location: TabLocation;
 children: IModelTabNode[];
}

interface IModelData {
 global?: IModelGlobalSettings;
 borders?: IModelBorderNode[];
 layout: IModelTabNode | IModelDividerNode | IModelTabSetNode;
}

export default IModelData;

EricPolman avatar Apr 26 '21 12:04 EricPolman

If you import FlexLayout from 'flexlayout-react/src/index then you should get the types defined automatically, because FlexLayout is written in TypeScript.

edemaine avatar Apr 26 '21 13:04 edemaine

FlexLayout.Model.fromJson accepts input of type any and FlexLayout.Model.toJson outputs an object of type any, these definitions attempt to clarify those types. Or is there a definition for those JSON objects already?

EricPolman avatar Apr 26 '21 14:04 EricPolman

Sorry, got it. That does seem like it would be a useful addition!

Maybe you should write a PR adding them to the source?

edemaine avatar Apr 26 '21 14:04 edemaine

I've added the PR: https://github.com/caplin/FlexLayout/pull/209

EricPolman avatar Apr 26 '21 14:04 EricPolman

that's a good idea, need to check it covers all the attributes, I know there are some that are not in the readme (the readme tables of attributes were originally generated from the attributes in the code, but have since been manually updated)

nealus avatar May 02 '21 09:05 nealus