Skip to content

Commit

Permalink
v0.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
nealus committed Nov 24, 2021
1 parent 199887d commit 1b31495
Show file tree
Hide file tree
Showing 20 changed files with 147 additions and 130 deletions.
8 changes: 5 additions & 3 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
Next Version
0.6.0
Changed icons to use svg images, these will now scale with the font size.
Improved element spacing, removed most margin/padding spacers.
Overflow menu will now show the tab icon and content as rendered in the tab.
The overflow menu and drag rectangle will now show the tab icon and content as rendered in the tab.
Added altName attribute to TabNode, this will be used as the name in the overflow menu if there is no
name attribute (e.g the tab has just an icon).
Changed drag rectangle default color from red/green to blue.
Changed the drag outline colors from red/green to light blue/green.
Removed closeIcon prop from Layout, use the icons property instead.
Changed onRenderDragRect callback to take a ReactElement rather than a string, the content now
contains the tabbutton as rendered.

0.5.21
Fixed copying stylesheet links for popout windows when cssRules throw exception.
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ FlexLayout is a layout manager that arranges React components in multiple tab se

![FlexLayout Demo Screenshot](/../screenshots/github_images/v0.5/demo1.png?raw=true "FlexLayout Demo Screenshot")

[Run the Demo](https://rawgit.com/caplin/FlexLayout/demos/demos/v0.5/demo/index.html)
[Run the Demo](https://rawgit.com/caplin/FlexLayout/demos/demos/v0.6/demo/index.html)

Try it now using [JSFiddle](https://jsfiddle.net/7oe4q2pc/)
Try it now using [JSFiddle](https://jsfiddle.net/18zfp0qm/)

<!-- [API Doc](./typedoc/index.html) -->

Expand Down Expand Up @@ -185,7 +185,7 @@ ReactDOM.render(<Main/>, document.getElementById("container"));

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.

Try it now using [JSFiddle](https://jsfiddle.net/7oe4q2pc/)
Try it now using [JSFiddle](https://jsfiddle.net/18zfp0qm/)

A simple Create React App (CRA) example (using typescript) can be found here:

Expand Down Expand Up @@ -213,7 +213,7 @@ The model json contains 3 top level elements:

Weights on rows and tabsets specify the relative weight of these nodes within the parent row, the actual values do not matter just their relative values (ie two tabsets of weights 30,70 would render the same if they had weights of 3,7).

NOTE: the easiest way to create your initial layout JSON is to use the [demo](https://rawgit.com/caplin/FlexLayout/demos/demos/v0.5/demo/index.html) app, modify one of the
NOTE: the easiest way to create your initial layout JSON is to use the [demo](https://rawgit.com/caplin/FlexLayout/demos/demos/v0.6/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.


Expand Down
27 changes: 16 additions & 11 deletions examples/demo/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ class App extends React.Component<any, { layoutFile: string | null, model: FlexL
let dropNode = dropInfo.node;

// prevent non-border tabs dropping into borders
if (dropNode.getType() == "border" && (dragNode.getParent() == null || dragNode.getParent()!.getType() != "border"))
if (dropNode.getType() === "border" && (dragNode.getParent() == null || dragNode.getParent()!.getType() != "border"))
return false;

// prevent border tabs dropping into main layout
if (dropNode.getType() != "border" && (dragNode.getParent() != null && dragNode.getParent()!.getType() == "border"))
if (dropNode.getType() !== "border" && (dragNode.getParent() != null && dragNode.getParent()!.getType() == "border"))
return false;

return true;
Expand All @@ -103,18 +103,20 @@ class App extends React.Component<any, { layoutFile: string | null, model: FlexL
event.stopPropagation();
event.preventDefault();
if (this.state.model!.getMaximizedTabset() == null) {
(this.refs.layout as FlexLayout.Layout).addTabWithDragAndDrop("Add grid\n(Drag to location)", {
(this.refs.layout as FlexLayout.Layout).addTabWithDragAndDrop(undefined, {
component: "grid",
icon: "images/article.svg",
name: "Grid " + this.nextGridIndex++
}, this.onAdded);
// this.setState({ adding: true });
}
}
}

onAddActiveClick = (event: React.MouseEvent) => {
if (this.state.model!.getMaximizedTabset() == null) {
(this.refs.layout as FlexLayout.Layout).addTabToActiveTabSet({
component: "grid",
icon: "images/article.svg",
name: "Grid " + this.nextGridIndex++
});
}
Expand Down Expand Up @@ -145,14 +147,16 @@ class App extends React.Component<any, { layoutFile: string | null, model: FlexL
});
}

onRenderDragRect = (text: String, node?: Node, json?: IJsonTabNode) => {
onRenderDragRect = (content: React.ReactElement | undefined, node?: Node, json?: IJsonTabNode) => {
if (this.state.layoutFile === "newfeatures") {
return (
<div style={{ whiteSpace: "pre" }}>{text}
<br /><br />
return (<>
{content}
<div style={{ whiteSpace: "pre" }}>
<br />
This is a customized<br />
drag rectangle
</div>
</>
);
} else {
return undefined; // use default rendering
Expand Down Expand Up @@ -371,14 +375,15 @@ class App extends React.Component<any, { layoutFile: string | null, model: FlexL

onRenderTab = (node: TabNode, renderValues: ITabRenderValues) => {
// renderValues.content += " *";
// renderValues.leading = <img style={{width:"1em", height:"1em"}}src="images/folder.svg"/>;
// renderValues.name = "tab " + node.getId(); // name used in overflow menu
// renderValues.buttons.push(<img src="images/folder.svg"/>);
// renderValues.buttons.push(<img style={{width:"1em", height:"1em"}} src="images/folder.svg"/>);
}

onRenderTabSet = (node: (TabSetNode | BorderNode), renderValues: ITabSetRenderValues) => {
if (this.state.layoutFile === "default") {
//renderValues.headerContent = "-- " + renderValues.headerContent + " --";
//renderValues.buttons.push(<img src="images/folder.svg"/>);
//renderValues.buttons.push(<img style={{width:"1em", height:"1em"}} src="images/folder.svg"/>);
renderValues.stickyButtons.push(
<img src="images/add.svg"
alt="Add"
Expand Down Expand Up @@ -450,7 +455,7 @@ class App extends React.Component<any, { layoutFile: string | null, model: FlexL
<option value="preferred">Using Preferred size</option>
<option value="trader">Trader</option>
</select>
<button className="toolbar_control" onClick={this.onReloadFromFile} style={{ marginLeft: 5 }}>reload from file</button>
<button className="toolbar_control" onClick={this.onReloadFromFile} style={{ marginLeft: 5 }}>Reload</button>
<div style={{ flexGrow: 1 }}></div>
<span style={{ fontSize: "14px" }}>Realtime resize</span>
<input
Expand Down
1 change: 1 addition & 0 deletions examples/demo/images/article.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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.5.21",
"version": "0.6.0",
"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/I18nLabel.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export enum I18nLabel {
Close_Tab = "Close",
Close_Tabset = "Close tabset",
Move_Tab = "Move: ",
Move_Tab = "Move: ", // no longer used
Move_Tabset = "Move tabset",
Maximize = "Maximize tabset",
Restore = "Restore tabset",
Expand Down
4 changes: 2 additions & 2 deletions src/PopupMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { DragDrop } from ".";
import TabNode from "./model/TabNode";
import { CLASSES } from "./Types";
import { ILayoutCallbacks } from "./view/Layout";
import { MenuTabButton } from "./view/MenuTabButton";
import { TabButtonStamp } from "./view/TabButtonStamp";

/** @hidden @internal */
export function showPopup(
Expand Down Expand Up @@ -100,7 +100,7 @@ const PopupMenu = (props: IPopupMenuProps) => {
title={item.node.getHelpText()} >
{item.node.getModel().isLegacyOverflowMenu() ?
item.node._getNameForOverflowMenu() :
<MenuTabButton
<TabButtonStamp
node={item.node}
layout={layout}
iconFactory={iconFactory}
Expand Down
2 changes: 1 addition & 1 deletion src/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export enum CLASSES {
FLEXLAYOUT__TAB_BUTTON_OVERFLOW = "flexlayout__tab_button_overflow",
FLEXLAYOUT__TAB_BUTTON_TEXTBOX = "flexlayout__tab_button_textbox",
FLEXLAYOUT__TAB_BUTTON_TRAILING = "flexlayout__tab_button_trailing",
FLEXLAYOUT__TAB_BUTTON_IN_OVERFLOW_MENU = "flexlayout__tab_button_in_overflow_menu",
FLEXLAYOUT__TAB_BUTTON_STAMP = "flexlayout__tab_button_stamp",

FLEXLAYOUT__TAB_FLOATING = "flexlayout__tab_floating",
FLEXLAYOUT__TAB_FLOATING_INNER = "flexlayout__tab_floating_inner",
Expand Down
3 changes: 1 addition & 2 deletions src/view/BorderButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ export const BorderButton = (props: IBorderButtonProps) => {

const onMouseDown = (event: React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement>) => {
if (!isAuxMouseEvent(event)) {
const message = layout.i18nName(I18nLabel.Move_Tab, node._getNameForOverflowMenu());
props.layout.dragStart(event, message, node, node.isEnableDrag(), onClick, (event2: Event) => undefined);
props.layout.dragStart(event, undefined, node, node.isEnableDrag(), onClick, (event2: Event) => undefined);
}
};

Expand Down
44 changes: 30 additions & 14 deletions src/view/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ import { TabFloating } from "./TabFloating";
import { IJsonTabNode } from "../model/IJsonModel";
import { Orientation } from "..";
import { CloseIcon, MaximizeIcon, OverflowIcon, PopoutIcon, RestoreIcon } from "./Icons";
import { TabButtonStamp } from "./TabButtonStamp";

export type CustomDragCallback = (dragging: TabNode | IJsonTabNode, over: TabNode, x: number, y: number, location: DockLocation) => void;
export type DragRectRenderCallback = (text: String, node?: Node, json?: IJsonTabNode) => React.ReactElement | undefined;
export type DragRectRenderCallback = (content: React.ReactElement | undefined, node?: Node, json?: IJsonTabNode) => React.ReactElement | undefined;
export type FloatingTabPlaceholderRenderCallback = (dockPopout: () => void, showPopout: () => void) => React.ReactElement | undefined;
export type NodeMouseEvent = (node: TabNode | TabSetNode | BorderNode, event: React.MouseEvent<HTMLElement, MouseEvent>) => void;

Expand Down Expand Up @@ -155,7 +156,7 @@ export interface ILayoutCallbacks {
getRootDiv(): HTMLDivElement;
dragStart(
event: Event | React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement> | React.DragEvent<HTMLDivElement> | undefined,
dragDivText: string,
dragDivText: string | undefined,
node: Node & IDraggable,
allowDrag: boolean,
onClick?: (event: Event) => void,
Expand Down Expand Up @@ -224,7 +225,7 @@ export class Layout extends React.Component<ILayoutProps, ILayoutState> {
/** @hidden @internal */
private dragRectRendered: boolean = true;
/** @hidden @internal */
private dragDivText: string = "";
private dragDivText: string | undefined = undefined;
/** @hidden @internal */
private dropInfo: DropInfo | undefined;
/** @hidden @internal */
Expand Down Expand Up @@ -291,11 +292,13 @@ export class Layout extends React.Component<ILayoutProps, ILayoutState> {
/** @hidden @internal */
styleFont(style: Record<string, string>): Record<string, string> {
if (this.props.font) {
if (this.props.font.size) {
style.fontSize = this.props.font.size;
}
if (this.props.font.family) {
style.fontFamily = this.props.font.family;
if (this.selfRef.current) {
if (this.props.font.size) {
this.selfRef.current.style.setProperty("--font-size", this.props.font.size);
}
if (this.props.font.family) {
this.selfRef.current.style.setProperty("--font-family", this.props.font.family);
}
}
if (this.props.font.style) {
style.fontStyle = this.props.font.style;
Expand Down Expand Up @@ -699,7 +702,7 @@ export class Layout extends React.Component<ILayoutProps, ILayoutState> {
* @param json the json for the new tab node
* @param onDrop a callback to call when the drag is complete (node and event will be undefined if the drag was cancelled)
*/
addTabWithDragAndDrop(dragText: string, json: IJsonTabNode, onDrop?: (node?: Node, event?: Event) => void) {
addTabWithDragAndDrop(dragText: string | undefined, json: IJsonTabNode, onDrop?: (node?: Node, event?: Event) => void) {
this.fnNewNodeDropped = onDrop;
this.newTabJson = json;
this.dragStart(undefined, dragText, TabNode._fromJson(json, this.props.model, false), true, undefined, undefined);
Expand All @@ -713,7 +716,7 @@ export class Layout extends React.Component<ILayoutProps, ILayoutState> {
* @param json the json for the new tab node
* @param onDrop a callback to call when the drag is complete (node and event will be undefined if the drag was cancelled)
*/
addTabWithDragAndDropIndirect(dragText: string, json: IJsonTabNode, onDrop?: (node?: Node, event?: Event) => void) {
addTabWithDragAndDropIndirect(dragText: string | undefined, json: IJsonTabNode, onDrop?: (node?: Node, event?: Event) => void) {
this.fnNewNodeDropped = onDrop;
this.newTabJson = json;

Expand Down Expand Up @@ -806,7 +809,7 @@ export class Layout extends React.Component<ILayoutProps, ILayoutState> {
/** @hidden @internal */
dragStart = (
event: Event | React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement> | React.DragEvent<HTMLDivElement> | undefined,
dragDivText: string,
dragDivText: string | undefined,
node: Node & IDraggable,
allowDrag: boolean,
onClick?: (event: Event) => void,
Expand All @@ -822,11 +825,24 @@ export class Layout extends React.Component<ILayoutProps, ILayoutState> {
};

/** @hidden @internal */
dragRectRender = (text: String, node?: Node, json?: IJsonTabNode, onRendered?: () => void) => {
let content: React.ReactElement | undefined = <div style={{ whiteSpace: "pre" }}>{text.replace("<br>", "\n")}</div>;
dragRectRender = (text: String | undefined, node?: Node, json?: IJsonTabNode, onRendered?: () => void) => {
let content: React.ReactElement | undefined;

if (text !== undefined) {
content = <div style={{ whiteSpace: "pre" }}>{text.replace("<br>", "\n")}</div>;
} else {
if (node && node instanceof TabNode) {
content = (<TabButtonStamp
node={node}
layout={this}
iconFactory={this.props.iconFactory}
titleFactory={this.props.titleFactory}
/>);
}
}

if (this.props.onRenderDragRect !== undefined) {
const customContent = this.props.onRenderDragRect(text, node, json);
const customContent = this.props.onRenderDragRect(content, node, json);
if (customContent !== undefined) {
content = customContent;
}
Expand Down
3 changes: 1 addition & 2 deletions src/view/TabButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ export const TabButton = (props: ITabButtonProps) => {
const onMouseDown = (event: React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement>) => {

if (!isAuxMouseEvent(event) && !layout.getEditingTab()) {
const message = layout.i18nName(I18nLabel.Move_Tab, node._getNameForOverflowMenu());
layout.dragStart(event, message, node, node.isEnableDrag(), onClick, onDoubleClick);
layout.dragStart(event, undefined, node, node.isEnableDrag(), onClick, onDoubleClick);
}
};

Expand Down
6 changes: 3 additions & 3 deletions src/view/MenuTabButton.tsx → src/view/TabButtonStamp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ import { CLASSES } from "../Types";
import { getRenderStateEx } from "./Utils";

/** @hidden @internal */
export interface IMenuTabButtonProps {
export interface ITabButtonStampProps {
node: TabNode;
layout: ILayoutCallbacks;
iconFactory?: (node: TabNode) => React.ReactNode | undefined;
titleFactory?: (node: TabNode) => React.ReactNode | undefined;
}

/** @hidden @internal */
export const MenuTabButton = (props: IMenuTabButtonProps) => {
export const TabButtonStamp = (props: ITabButtonStampProps) => {
const { layout, node, iconFactory, titleFactory } = props;
const selfRef = React.useRef<HTMLDivElement | null>(null);

const cm = layout.getClassName;

let classNames = cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_IN_OVERFLOW_MENU);
let classNames = cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_STAMP);

const renderState = getRenderStateEx(layout, node, iconFactory, titleFactory);

Expand Down
11 changes: 5 additions & 6 deletions style/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
justify-content: center;
flex-direction: column;
overflow: hidden;
padding: 10px;
padding: 0.5em 1em;
word-wrap: break-word;
font-size: var(--font-size);
font-family: var(--font-family);
Expand Down Expand Up @@ -187,12 +187,11 @@
}
}

&__tab_button_in_overflow_menu {
display: flex;
&__tab_button_stamp {
display: inline-flex;
align-items: center;
gap: 0.3em;
white-space: nowrap;
padding-left: 0.5em;
padding-right: 0.5em;
box-sizing: border-box;
}

Expand Down Expand Up @@ -529,7 +528,7 @@
font-family: var(--font-family);

&_item {
padding: 2px 2px;
padding: 2px 0.5em;
white-space: nowrap;
cursor: pointer;
border-radius: 2px;
Expand Down
Loading

0 comments on commit 1b31495

Please sign in to comment.