Skip to content

Commit

Permalink
v0.7.12
Browse files Browse the repository at this point in the history
  • Loading branch information
nealus committed Sep 30, 2023
1 parent 82ce11c commit 2e469d1
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 110 deletions.
4 changes: 4 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
0.7.12
Action.setActiveTabset can now take undefined to unset the active tabset.
Added Tab attribute contentClassName to add a class to the tab content.

0.7.11
Added ITabSetRenderValues.overflowPosition to allow overflow button position to be
specified, if left undefined, position will be after sticky buttons as before.
Expand Down
111 changes: 21 additions & 90 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,16 @@ Features:

## Installation

FlexLayout is in the npm repository. Simply install React and FlexLayout from npm:
FlexLayout is in the npm repository. install using:

```
npm install react
npm install react-dom
npm install flexlayout-react
```

Import React and FlexLayout in your modules:
Import FlexLayout in your modules:

```
import * as React from "react";
import { createRoot } from "react-dom/client";
import * as FlexLayout from "flexlayout-react";
import {Layout, Model} from 'flexlayout-react';
```

Include the light, underline, gray or dark theme by either:
Expand Down Expand Up @@ -93,14 +89,6 @@ The factory is a function that takes a Node object and returns a React component

The model can be created using the Model.fromJson(jsonObject) static method, and can be saved using the model.toJson() method.

```javascript
this.state = {model: FlexLayout.Model.fromJson(json)};

render() {
<FlexLayout.Layout model={this.state.model} factory={factory}/>
}
```

## Example Configuration:

```javascript
Expand Down Expand Up @@ -140,34 +128,25 @@ var json = {

## Example Code

```
import * as React from "react";
import { createRoot } from "react-dom/client";
import * as FlexLayout from "flexlayout-react";
```javascript
const model = Model.fromJson(json);

class Main extends React.Component {
function App() {

constructor(props) {
super(props);
this.state = {model: FlexLayout.Model.fromJson(json)};
}
const factory = (node) => {
var component = node.getComponent();

factory = (node) => {
var component = node.getComponent();
if (component === "button") {
return <button>{node.getName()}</button>;
}
if (component === "button") {
return <button>{node.getName()}</button>;
}
}

render() {
return (
<FlexLayout.Layout model={this.state.model} factory={this.factory}/>
)
}
return (
<Layout
model={model}
factory={factory} />
);
}
const root = createRoot(document.getElementById("container"));
root.render(<Main/>);
```

The above code would render two tabsets horizontally each containing a single tab that hosts a button component. The tabs could be moved and resized by dragging and dropping. Additional grids could be added to the layout by sending actions to the model.
Expand Down Expand Up @@ -203,63 +182,14 @@ Weights on rows and tabsets specify the relative weight of these nodes within th
NOTE: the easiest way to create your initial layout JSON is to use the [demo](https://rawgit.com/caplin/FlexLayout/demos/demos/v0.7/demo/index.html) app, modify one of the
existing layouts by dragging/dropping and adding nodes then press the 'Show Layout JSON in console' button to print the JSON to the browser developer console.


example borders section:
```
borders: [
{
type: "border",
location: "left",
children: [
{
type: "tab",
enableClose: false,
name: "Navigation",
component: "grid",
}
]
},
{
type: "border",
location: "right",
children: [
{
type: "tab",
enableClose: false,
name: "Options",
component: "grid",
}
]
},
{
type: "border",
location: "bottom",
children: [
{
type: "tab",
enableClose: false,
name: "Activity Blotter",
component: "grid",
},
{
type: "tab",
enableClose: false,
name: "Execution Blotter",
component: "grid",
}
]
}
]
```

To control where nodes can be dropped you can add a callback function to the model:

```
model.setOnAllowDrop(this.allowDrop);
```

example:
```
```javascript
allowDrop(dragNode, dropInfo) {
let dropNode = dropInfo.node;

Expand Down Expand Up @@ -355,6 +285,7 @@ Attributes allowed in the 'global' element
| tabEnableRename | true | allow user to rename all tabs by double clicking |
| tabEnableFloat | false | enable popouts in all tabs (in popout capable browser) |
| tabClassName | null | |
| tabContentClassName | null | |
| tabIcon | null | |
| tabEnableRenderOnDemand | true | whether to avoid rendering component until tab is visible |
| tabDragSpeed | 0.3 | CSS transition speed of drag outlines (in seconds) |
Expand Down Expand Up @@ -420,7 +351,8 @@ Inherited defaults will take their value from the associated global attributes (
| enableRename | *inherited* | allow user to rename tabs by double clicking |
| enableFloat | *inherited* | enable popout (in popout capable browser) |
| floating | false | |
| className | *inherited* | |
| className | *inherited* | class applied to tab button |
| contentClassName | *inherited* | class applied to tab content |
| icon | *inherited* | |
| enableRenderOnDemand | *inherited* | whether to avoid rendering component until tab is visible |
| borderWidth | *inherited* | width when added to border, -1 will use border size |
Expand Down Expand Up @@ -489,8 +421,7 @@ Inherited defaults will take their value from the associated global attributes (
| enableDrop | *inherited* | |
| autoSelectTabWhenOpen | *inherited* | whether to select new/moved tabs in border when the border is already open |
| autoSelectTabWhenClosed | *inherited* | whether to select new/moved tabs in border when the border is currently closed |
| className | *inherited* | |

| className | *inherited* | class applied to tab button |

## Model Actions

Expand Down
23 changes: 9 additions & 14 deletions examples/simple/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,27 +44,22 @@ var json = {
}
};

class Main extends React.Component {
const model = FlexLayout.Model.fromJson(json);

constructor(props) {
super(props);
this.state = {model: FlexLayout.Model.fromJson(json)};
}
function Main(props) {

factory = (node) => {
const factory = (node) => {
var component = node.getComponent();
if (component === "panel") {
return <div className="tab_content">{node.getName()}</div>;
}
}

render() {
return (
<FlexLayout.Layout
model={this.state.model}
factory={this.factory}/>
);
}

return (
<FlexLayout.Layout
model={model}
factory={factory}/>
);
}

ReactDOM.createRoot(document.getElementById("container")).render(<Main/>);
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "flexlayout-react",
"version": "0.7.11",
"version": "0.7.12",
"description": "A multi-tab docking layout manager",
"main": "lib/index.js",
"types": "./declarations/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion src/model/Actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export class Actions {
* @param tabsetNodeId the id of the tabset node to set as active
* @returns {Action} the action
*/
static setActiveTabset(tabsetNodeId: string): Action {
static setActiveTabset(tabsetNodeId: string | undefined): Action {
return new Action(Actions.SET_ACTIVE_TABSET, { tabsetNode: tabsetNodeId });
}

Expand Down
4 changes: 3 additions & 1 deletion src/model/IJsonModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ export interface IGlobalAttributes {
borderMinSize?: number; // default: 0
borderSize?: number; // default: 200
enableEdgeDock?: boolean; // default: true
enableUseVisibility?: boolean; // default: false
enableRotateBorderIcons?: boolean; // default: true
enableUseVisibility?: boolean; // default: false
legacyOverflowMenu?: boolean; // default: false
marginInsets?: IInsets; // default: {"top":0,"right":0,"bottom":0,"left":0}
rootOrientationVertical?: boolean; // default: false
Expand All @@ -51,6 +51,7 @@ export interface IGlobalAttributes {
tabBorderWidth?: number; // default: -1
tabClassName?: string;
tabCloseType?: ICloseType; // default: 1
tabContentClassName?: string;
tabDragSpeed?: number; // default: 0.3
tabEnableClose?: boolean; // default: true
tabEnableDrag?: boolean; // default: true
Expand Down Expand Up @@ -122,6 +123,7 @@ export interface ITabAttributes {
closeType?: ICloseType; // default: 1 - inherited from global tabCloseType
component?: string;
config?: any;
contentClassName?: string;
enableClose?: boolean; // default: true - inherited from global tabEnableClose
enableDrag?: boolean; // default: true - inherited from global tabEnableDrag
enableFloat?: boolean; // default: false - inherited from global tabEnableFloat
Expand Down
11 changes: 8 additions & 3 deletions src/model/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export class Model {
attributeDefinitions.add("tabEnableFloat", false).setType(Attribute.BOOLEAN);
attributeDefinitions.add("tabEnableDrag", true).setType(Attribute.BOOLEAN);
attributeDefinitions.add("tabEnableRename", true).setType(Attribute.BOOLEAN);
attributeDefinitions.add("tabContentClassName", undefined).setType(Attribute.STRING);
attributeDefinitions.add("tabClassName", undefined).setType(Attribute.STRING);
attributeDefinitions.add("tabIcon", undefined).setType(Attribute.STRING);
attributeDefinitions.add("tabEnableRenderOnDemand", true).setType(Attribute.BOOLEAN);
Expand Down Expand Up @@ -371,9 +372,13 @@ export class Model {
break;
}
case Actions.SET_ACTIVE_TABSET: {
const tabsetNode = this._idMap[action.data.tabsetNode];
if (tabsetNode instanceof TabSetNode) {
this._activeTabSet = tabsetNode;
if (action.data.tabsetNode === undefined) {
this._activeTabSet = undefined;
} else {
const tabsetNode = this._idMap[action.data.tabsetNode];
if (tabsetNode instanceof TabSetNode) {
this._activeTabSet = tabsetNode;
}
}
break;
}
Expand Down
5 changes: 5 additions & 0 deletions src/model/TabNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class TabNode extends Node implements IDraggable {
attributeDefinitions.addInherited("enableDrag", "tabEnableDrag").setType(Attribute.BOOLEAN);
attributeDefinitions.addInherited("enableRename", "tabEnableRename").setType(Attribute.BOOLEAN);
attributeDefinitions.addInherited("className", "tabClassName").setType(Attribute.STRING);
attributeDefinitions.addInherited("contentClassName", "tabContentClassName").setType(Attribute.STRING);
attributeDefinitions.addInherited("icon", "tabIcon").setType(Attribute.STRING);
attributeDefinitions.addInherited("enableRenderOnDemand", "tabEnableRenderOnDemand").setType(Attribute.BOOLEAN);
attributeDefinitions.addInherited("enableFloat", "tabEnableFloat").setType(Attribute.BOOLEAN);
Expand Down Expand Up @@ -155,6 +156,10 @@ export class TabNode extends Node implements IDraggable {
getClassName() {
return this._getAttr("className") as string | undefined;
}

getContentClassName() {
return this._getAttr("contentClassName") as string | undefined;
}

isEnableRenderOnDemand() {
return this._getAttr("enableRenderOnDemand") as boolean;
Expand Down
4 changes: 4 additions & 0 deletions src/view/Tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ export const Tab = (props: ITabProps) => {
className += " " + cm(CLASSES.FLEXLAYOUT__TAB_BORDER);
className += " " + cm(CLASSES.FLEXLAYOUT__TAB_BORDER_ + parentNode.getLocation().getName());
}

if (node.getContentClassName() !== undefined) {
className += " " + node.getContentClassName();
}

return (
<div
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5246,6 +5246,7 @@ html-minifier-terser@^6.0.2:
util.promisify "1.0.0"

"html-webpack-plugin-5@npm:html-webpack-plugin@^5", html-webpack-plugin@^5.5.0:
name html-webpack-plugin-5
version "5.5.1"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz#826838e31b427f5f7f30971f8d8fa2422dfa6763"
integrity sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA==
Expand Down

0 comments on commit 2e469d1

Please sign in to comment.