Skip to content

Commit

Permalink
v0.7.13
Browse files Browse the repository at this point in the history
  • Loading branch information
nealus committed Oct 22, 2023
1 parent cda1203 commit 4df024a
Show file tree
Hide file tree
Showing 21 changed files with 231 additions and 16 deletions.
8 changes: 8 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
0.7.13
New attribute on tabset: enableSingleTabStretch will stretch a single tab to take up
all the remaining space and change the style to look like a header, combined with enableDrop
this can be used to create a Mosaic style layout (headed panels without tabs), see the new
Mosaic Style layout in the Demo.
The layout methods addTabToTabSet and addTabToActiveTabSet now return the added TabNode.
Fixed #352 - Layout.getDomRect returning null.

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.
Expand Down
4 changes: 3 additions & 1 deletion examples/demo/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,11 @@ class App extends React.Component<any, { layoutFile: string | null, model: Model
}

onRenderTab = (node: TabNode, renderValues: ITabRenderValues) => {
// renderValues.content = (<InnerComponent/>);
// renderValues.content = (<div>hello</div>);
// 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(<div style={{flexGrow:1}}></div>);
// renderValues.buttons.push(<img style={{width:"1em", height:"1em"}} src="images/folder.svg"/>);
}

Expand Down Expand Up @@ -486,6 +487,7 @@ class App extends React.Component<any, { layoutFile: string | null, model: Model
<option value="default">Default</option>
<option value="newfeatures">New Features</option>
<option value="simple">Simple</option>
<option value="mosaic">Mosaic Style</option>
<option value="sub">SubLayout</option>
<option value="complex">Complex</option>
<option value="headers">Headers</option>
Expand Down
54 changes: 54 additions & 0 deletions examples/demo/layouts/mosaic.layout
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"global": {
"tabSetEnableDrop": false,
"tabSetEnableSingleTabStretch": true,
"tabSetMinWidth": 100,
"tabSetMinHeight": 100
},
"borders": [],
"layout": {
"type": "row",
"children": [
{
"type": "tabset",
"id": "2",
"weight": 25,
"children": [
{
"type": "tab",
"id": "3",
"name": "Layout JSON",
"component": "json"
}
],
"active": true
},
{
"type": "tabset",
"weight": 50,
"children": [
{
"type": "tab",
"name": "Wikipedia",
"component": "multitype",
"config": {
"type": "url",
"data": "https://en.wikipedia.org/wiki/Main_Page"
}
}
]
},
{
"type": "tabset",
"weight": 25,
"children": [
{
"type": "tab",
"name": "One",
"component": "grid"
}
]
}
]
}
}
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.12",
"version": "0.7.13",
"description": "A multi-tab docking layout manager",
"main": "lib/index.js",
"types": "./declarations/index.d.ts",
Expand Down
1 change: 1 addition & 0 deletions src/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export enum CLASSES {
FLEXLAYOUT__TAB_BORDER = "flexlayout__tab_border",
FLEXLAYOUT__TAB_BORDER_ = "flexlayout__tab_border_",
FLEXLAYOUT__TAB_BUTTON = "flexlayout__tab_button",
FLEXLAYOUT__TAB_BUTTON_STRETCH = "flexlayout__tab_button_stretch",
FLEXLAYOUT__TAB_BUTTON_CONTENT = "flexlayout__tab_button_content",
FLEXLAYOUT__TAB_BUTTON_LEADING = "flexlayout__tab_button_leading",
FLEXLAYOUT__TAB_BUTTON_OVERFLOW = "flexlayout__tab_button_overflow",
Expand Down
6 changes: 4 additions & 2 deletions src/model/IJsonModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export interface IGlobalAttributes {
tabSetEnableDrag?: boolean; // default: true
tabSetEnableDrop?: boolean; // default: true
tabSetEnableMaximize?: boolean; // default: true
tabSetEnableSingleTabStretch?: boolean; // default: false
tabSetEnableTabStrip?: boolean; // default: true
tabSetHeaderHeight?: number; // default: 0
tabSetMarginInsets?: IInsets; // default: {"top":0,"right":0,"bottom":0,"left":0}
Expand Down Expand Up @@ -96,6 +97,7 @@ export interface ITabSetAttributes {
enableDrag?: boolean; // default: true - inherited from global tabSetEnableDrag
enableDrop?: boolean; // default: true - inherited from global tabSetEnableDrop
enableMaximize?: boolean; // default: true - inherited from global tabSetEnableMaximize
enableSingleTabStretch?: boolean; // default: false - inherited from global tabSetEnableSingleTabStretch
enableTabStrip?: boolean; // default: true - inherited from global tabSetEnableTabStrip
headerHeight?: number; // default: 0 - inherited from global tabSetHeaderHeight
height?: number;
Expand All @@ -110,7 +112,7 @@ export interface ITabSetAttributes {
type: "tabset";
weight?: number; // default: 100
width?: number;

// special attributes are read from initial json but must subseqently be set on the model
maximized?: boolean; // default false
active?:boolean; // default false
Expand All @@ -123,7 +125,7 @@ export interface ITabAttributes {
closeType?: ICloseType; // default: 1 - inherited from global tabCloseType
component?: string;
config?: any;
contentClassName?: string;
contentClassName?: string; // - inherited from global tabContentClassName
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
1 change: 1 addition & 0 deletions src/model/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export class Model {
attributeDefinitions.add("tabSetEnableDivide", true).setType(Attribute.BOOLEAN);
attributeDefinitions.add("tabSetEnableMaximize", true).setType(Attribute.BOOLEAN);
attributeDefinitions.add("tabSetEnableClose", false).setType(Attribute.BOOLEAN);
attributeDefinitions.add("tabSetEnableSingleTabStretch", false).setType(Attribute.BOOLEAN);
attributeDefinitions.add("tabSetAutoSelectTab", true).setType(Attribute.BOOLEAN);
attributeDefinitions.add("tabSetClassNameTabStrip", undefined).setType(Attribute.STRING);
attributeDefinitions.add("tabSetClassNameHeader", undefined).setType(Attribute.STRING);
Expand Down
6 changes: 6 additions & 0 deletions src/model/TabSetNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export class TabSetNode extends Node implements IDraggable, IDropTarget {
attributeDefinitions.addInherited("enableDivide", "tabSetEnableDivide");
attributeDefinitions.addInherited("enableMaximize", "tabSetEnableMaximize");
attributeDefinitions.addInherited("enableClose", "tabSetEnableClose");
attributeDefinitions.addInherited("enableSingleTabStretch", "tabSetEnableSingleTabStretch");

attributeDefinitions.addInherited("classNameTabStrip", "tabSetClassNameTabStrip");
attributeDefinitions.addInherited("classNameHeader", "tabSetClassNameHeader");
attributeDefinitions.addInherited("enableTabStrip", "tabSetEnableTabStrip");
Expand Down Expand Up @@ -189,6 +191,10 @@ export class TabSetNode extends Node implements IDraggable, IDropTarget {
isEnableClose() {
return this._getAttr("enableClose") as boolean;
}

isEnableSingleTabStretch() {
return this._getAttr("enableSingleTabStretch") as boolean;
}

canMaximize() {
if (this.isEnableMaximize()) {
Expand Down
15 changes: 9 additions & 6 deletions src/view/TabButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,17 @@ export const TabButton = (props: ITabButtonProps) => {
const cm = layout.getClassName;
const parentNode = node.getParent() as TabSetNode;

let baseClassName = CLASSES.FLEXLAYOUT__TAB_BUTTON;
const isStretch = parentNode.isEnableSingleTabStretch() && parentNode.getChildren().length === 1;
let baseClassName = isStretch ? CLASSES.FLEXLAYOUT__TAB_BUTTON_STRETCH : CLASSES.FLEXLAYOUT__TAB_BUTTON;
let classNames = cm(baseClassName);
classNames += " " + cm(baseClassName + "_" + parentNode.getTabLocation());

if (selected) {
classNames += " " + cm(baseClassName + "--selected");
} else {
classNames += " " + cm(baseClassName + "--unselected");
if (!isStretch) {
if (selected) {
classNames += " " + cm(baseClassName + "--selected");
} else {
classNames += " " + cm(baseClassName + "--unselected");
}
}

if (node.getClassName() !== undefined) {
Expand Down Expand Up @@ -177,7 +180,7 @@ export const TabButton = (props: ITabButtonProps) => {
);
}

if (node.isEnableClose()) {
if (node.isEnableClose() && !isStretch) {
const closeTitle = layout.i18nName(I18nLabel.Close_Tab);
renderState.buttons.push(
<div
Expand Down
18 changes: 13 additions & 5 deletions src/view/TabSet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ export const TabSet = (props: ITabSetProps) => {
event.stopPropagation();
};

const onCloseTab = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
layout.doAction(Actions.deleteTab(node.getChildren()[0].getId()));
event.stopPropagation();
};

const onFloatTab = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
if (selectedTabNode !== undefined) {
layout.doAction(Actions.floatTab(selectedTabNode.getId()));
Expand Down Expand Up @@ -167,12 +172,15 @@ export const TabSet = (props: ITabSetProps) => {
buttons = renderState.buttons;
headerButtons = renderState.headerButtons;

const isTabStretch = node.isEnableSingleTabStretch() && node.getChildren().length === 1;
const showClose = (isTabStretch && ((node.getChildren()[0] as TabNode).isEnableClose())) || node.isEnableClose();

if (renderState.overflowPosition === undefined) {
renderState.overflowPosition = stickyButtons.length;
}

if (stickyButtons.length > 0) {
if (tabsTruncated) {
if (tabsTruncated || isTabStretch) {
buttons = [...stickyButtons, ...buttons];
} else {
tabs.push(<div
Expand Down Expand Up @@ -253,16 +261,16 @@ export const TabSet = (props: ITabSetProps) => {
);
}

if (!node.isMaximized() && node.isEnableClose()) {
const title = layout.i18nName(I18nLabel.Close_Tabset);
if (!node.isMaximized() && showClose) {
const title = isTabStretch ? layout.i18nName(I18nLabel.Close_Tab) : layout.i18nName(I18nLabel.Close_Tabset);
const btns = showHeader ? headerButtons : buttons;
btns.push(
<button
key="close"
data-layout-path={path + "/button/close"}
title={title}
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON_CLOSE)}
onClick={onClose}
onClick={isTabStretch ? onCloseTab : onClose}
onMouseDown={onInterceptMouseDown}
onTouchStart={onInterceptMouseDown}
>
Expand Down Expand Up @@ -348,7 +356,7 @@ export const TabSet = (props: ITabSetProps) => {
onTouchStart={onMouseDown}>
<div ref={tabbarInnerRef} className={cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER) + " " + cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_ + node.getTabLocation())}>
<div
style={{ left: position }}
style={{ left: position, width: (isTabStretch? "100%": "10000px")}}
className={cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_TAB_CONTAINER) + " " + cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_TAB_CONTAINER_ + node.getTabLocation())}
>
{tabs}
Expand Down
21 changes: 21 additions & 0 deletions style/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,27 @@
cursor: pointer;
@include tab_button_mixin;

&_stretch {
background-color: transparent;
color:var(--color-tab-selected);
width: 100%;
padding: 3px 0em;
text-wrap: nowrap;
display: flex;
gap: 0.3em;
align-items: center;
box-sizing: border-box;
cursor: pointer;
@include tab_button_stretch_mixin;

@media (hover: hover) {
&:hover {
color:var(--color-tab-selected);
@include tab_button_stretch_hovered_mixin;
}
}
}

&--selected {
background-color:var(--color-tab-selected-background);
color:var(--color-tab-selected);
Expand Down
17 changes: 17 additions & 0 deletions style/dark.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions style/dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ $font-family: Roboto, Arial, sans-serif !default;
@mixin tab_button_hovered_mixin {
}

@mixin tab_button_stretch_mixin {
}

@mixin tab_button_stretch_hovered_mixin {
}

@mixin border_mixin {
}

Expand Down
17 changes: 17 additions & 0 deletions style/gray.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions style/gray.scss
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ $font_family: Roboto, Arial, sans-serif !default;
@mixin border_button_hovered_mixin {
}

@mixin tab_button_stretch_mixin {
}

@mixin tab_button_stretch_hovered_mixin {
}

@mixin splitter_mixin {
}

Expand Down
17 changes: 17 additions & 0 deletions style/light.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions style/light.scss
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ $font-family: Roboto, Arial, sans-serif !default;
@mixin tab_button_hovered_mixin {
}

@mixin tab_button_stretch_mixin {
}

@mixin tab_button_stretch_hovered_mixin {
}

@mixin close_button_hovered_mixin {
background-color:var(--color-3);
}
Expand Down
Loading

0 comments on commit 4df024a

Please sign in to comment.