Merge branch 'release' of https://github.com/appsmithorg/appsmith into release

This commit is contained in:
Automated Github Action 2020-08-13 09:05:18 +00:00
commit b8d1d56310
5 changed files with 40 additions and 187 deletions

View File

@ -1,108 +1,3 @@
import React from "react"; import { CommonComponentProps } from "./common";
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
import "react-tabs/style/react-tabs.css";
import styled from "styled-components";
import { Icon, IconName } from "./Icon";
import { Size } from "./Button";
const TabsWrapper = styled.div<{ shouldOverflow?: boolean }>` // Create a wrapper around react-tabs
font-family: ${props => props.theme.fonts.main};
user-select: none;
border-radius: 0px;
height: 100%;
span {
margin-right: ${props => props.theme.spaces[2] - 1}px;
}
.react-tabs {
height: 100%;
}
.react-tabs__tab-panel {
height: calc(100% - 32px);
overflow: scroll;
}
.react-tabs__tab-list {
border-bottom: 2px solid ${props => props.theme.colors.blackShades[3]};
color: ${props => props.theme.colors.blackShades[6]};
${props =>
props.shouldOverflow &&
`
overflow-y: hidden;
overflow-x: auto;
white-space: nowrap;
`}
}
.react-tabs__tab {
padding: ${props => props.theme.space[7]}px 0;
margin-right: ${props => props.theme.space[15]}px;
text-align: center;
display: inline-flex;
align-items: center;
justify-content: center;
}
.react-tabs__tab:hover {
color: ${props => props.theme.colors.blackShades[9]};
path {
fill: ${props => props.theme.colors.blackShades[9]};
}
}
.react-tabs__tab:focus {
box-shadow: none;
border-bottom: ${props => props.theme.colors.info.main}
${props => props.theme.space[16]}px solid;
path {
fill: ${props => props.theme.colors.blackShades[9]};
}
}
.react-tabs__tab--selected {
color: ${props => props.theme.colors.blackShades[9]};
border: 0px solid;
border-bottom: ${props => props.theme.colors.info.main}
${props => props.theme.space[16]}px solid;
background-color: transparent;
path {
fill: ${props => props.theme.colors.blackShades[9]};
}
}
.react-tabs__tab:focus:after {
content: none;
height: ${props => props.theme.space[16]}px;
background: ${props => props.theme.colors.info.main};
}
`;
type TabbedViewComponentType = {
tabs: Array<{
key: string;
title: string;
panelComponent: JSX.Element;
icon?: IconName;
}>;
selectedIndex?: number;
setSelectedIndex?: Function;
overflow?: boolean;
};
export const AdsTabComponent = (props: TabbedViewComponentType) => {
return (
<TabsWrapper shouldOverflow={props.overflow}>
<Tabs
selectedIndex={props.selectedIndex}
onSelect={(index: number) => {
props.setSelectedIndex && props.setSelectedIndex(index);
}}
>
<TabList>
{props.tabs.map(tab => (
<Tab key={tab.key}>
{tab.icon ? <Icon name={tab.icon} size={Size.large} /> : null}
{tab.title}
</Tab>
))}
</TabList>
{props.tabs.map(tab => (
<TabPanel key={tab.key}>{tab.panelComponent}</TabPanel>
))}
</Tabs>
</TabsWrapper>
);
};

View File

@ -103,6 +103,7 @@ const StyledText = styled.div<TabProps>`
`; `;
const TabsComponent = (props: TabsComponentProps) => { const TabsComponent = (props: TabsComponentProps) => {
const { onTabChange, ...remainingProps } = props;
const tabContainerRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>( const tabContainerRef: RefObject<HTMLDivElement> = useRef<HTMLDivElement>(
null, null,
); );
@ -135,7 +136,7 @@ const TabsComponent = (props: TabsComponentProps) => {
)} )}
<ChildrenWrapper> <ChildrenWrapper>
<ScrollableCanvasWrapper <ScrollableCanvasWrapper
{...props} {...remainingProps}
className={`${ className={`${
props.shouldScrollContents ? getCanvasClassName() : "" props.shouldScrollContents ? getCanvasClassName() : ""
} ${generateClassName(props.widgetId)}`} } ${generateClassName(props.widgetId)}`}

View File

@ -7,6 +7,7 @@ import { ControlIcons } from "icons/ControlIcons";
import { AnyStyledComponent } from "styled-components"; import { AnyStyledComponent } from "styled-components";
import { generateReactKey } from "utils/generators"; import { generateReactKey } from "utils/generators";
import { DroppableComponent } from "../designSystems/appsmith/DraggableListComponent"; import { DroppableComponent } from "../designSystems/appsmith/DraggableListComponent";
import { getNextEntityName } from "utils/AppsmithUtils";
import _ from "lodash"; import _ from "lodash";
const StyledDeleteIcon = styled(FormIcons.DELETE_ICON as AnyStyledComponent)` const StyledDeleteIcon = styled(FormIcons.DELETE_ICON as AnyStyledComponent)`
@ -161,7 +162,11 @@ class TabControl extends BaseControl<ControlProps> {
? JSON.parse(this.props.propertyValue) ? JSON.parse(this.props.propertyValue)
: this.props.propertyValue; : this.props.propertyValue;
const newTabId = generateReactKey({ prefix: "tab" }); const newTabId = generateReactKey({ prefix: "tab" });
tabs.push({ id: newTabId, label: `Tab ${tabs.length + 1}` }); const newTabLabel = getNextEntityName(
"Tab ",
tabs.map(tab => tab.label),
);
tabs.push({ id: newTabId, label: newTabLabel });
this.updateProperty(this.props.propertyName, JSON.stringify(tabs)); this.updateProperty(this.props.propertyName, JSON.stringify(tabs));
}; };

View File

@ -1,68 +0,0 @@
import React from "react";
import { AdsTabComponent } from "components/ads/Tabs";
import { withKnobs } from "@storybook/addon-knobs";
import { withDesign } from "storybook-addon-designs";
import { ThemeProvider } from "styled-components";
import { adsTheme } from "../ads/baseTheme";
import { IconName } from "../ads/Icon";
export default {
title: "tabs",
component: AdsTabComponent,
decorators: [withKnobs, withDesign],
};
type tabSingle = {
key: string;
title: string;
panelComponent: JSX.Element;
icon: IconName;
};
const tabArr: tabSingle[] = [
{
key: "r",
title: "Tab one",
panelComponent: (
<div
style={{ backgroundColor: "#CB4810", width: "100%", height: "100%" }}
></div>
),
icon: "delete",
},
{
key: "r",
title: "Tab two",
panelComponent: (
<div
style={{ backgroundColor: "#218358", width: "100%", height: "100%" }}
></div>
),
icon: "delete",
},
{
key: "r",
title: "Tab three",
panelComponent: (
<div
style={{ backgroundColor: "#457AE6", width: "100%", height: "100%" }}
></div>
),
icon: "delete",
},
];
export const withDynamicProps = () => (
<div
style={{
width: "100%",
height: "600px",
backgroundColor: "#1A191C",
padding: "100px",
}}
>
<ThemeProvider theme={adsTheme}>
<AdsTabComponent tabs={tabArr}></AdsTabComponent>
</ThemeProvider>
</div>
);

View File

@ -8,6 +8,7 @@ import { WidgetPropertyValidationType } from "utils/ValidationFactory";
import { VALIDATION_TYPES } from "constants/WidgetValidation"; import { VALIDATION_TYPES } from "constants/WidgetValidation";
import _ from "lodash"; import _ from "lodash";
import { EventType } from "constants/ActionConstants"; import { EventType } from "constants/ActionConstants";
import { WidgetOperations } from "widgets/BaseWidget";
class TabsWidget extends BaseWidget< class TabsWidget extends BaseWidget<
TabsWidgetProps<TabContainerWidgetProps>, TabsWidgetProps<TabContainerWidgetProps>,
@ -60,21 +61,26 @@ class TabsWidget extends BaseWidget<
renderComponent = () => { renderComponent = () => {
const selectedTabId = this.props.selectedTabId; const selectedTabId = this.props.selectedTabId;
const children = this.props.children.filter(item => { const childWidgetData: TabContainerWidgetProps = this.props.children.filter(
item => {
return selectedTabId === item.tabId; return selectedTabId === item.tabId;
})[0]; },
const childWidgetData: TabContainerWidgetProps = children; )[0];
if (!childWidgetData) { if (!childWidgetData) {
return <div></div>; return null;
} }
childWidgetData.shouldScrollContents = false; childWidgetData.shouldScrollContents = false;
childWidgetData.canExtend = this.props.shouldScrollContents; childWidgetData.canExtend = this.props.shouldScrollContents;
const { componentWidth, componentHeight } = this.getComponentDimensions(); const { componentWidth, componentHeight } = this.getComponentDimensions();
childWidgetData.rightColumn = componentWidth; childWidgetData.rightColumn = componentWidth;
childWidgetData.isVisible = this.props.isVisible;
childWidgetData.bottomRow = this.props.shouldScrollContents childWidgetData.bottomRow = this.props.shouldScrollContents
? (this.props.bottomRow - this.props.topRow - 1) * ? childWidgetData.bottomRow
this.props.parentRowSpace : componentHeight - 1;
: componentHeight; childWidgetData.parentId = this.props.widgetId;
childWidgetData.minHeight = componentHeight;
return WidgetFactory.createWidget(childWidgetData, this.props.renderMode); return WidgetFactory.createWidget(childWidgetData, this.props.renderMode);
}; };
@ -117,11 +123,12 @@ class TabsWidget extends BaseWidget<
children: [], children: [],
}, },
}; };
this.updateWidget("ADD_CHILD", this.props.widgetId, config); this.updateWidget(WidgetOperations.ADD_CHILD, this.props.widgetId, config);
}; };
removeTabContainer = () => { removeTabContainer = () => {
let removedContainerWidgetId = ""; let removedContainerWidgetId = "";
let removedTabId = "";
const tabIds: string[] = this.props.tabs.map(tab => { const tabIds: string[] = this.props.tabs.map(tab => {
return tab.id; return tab.id;
}); });
@ -129,9 +136,22 @@ class TabsWidget extends BaseWidget<
const children = this.props.children[index]; const children = this.props.children[index];
if (!tabIds.includes(children.tabId)) { if (!tabIds.includes(children.tabId)) {
removedContainerWidgetId = children.widgetId; removedContainerWidgetId = children.widgetId;
removedTabId = children.tabId;
} }
} }
this.updateWidget("REMOVE_CHILD", removedContainerWidgetId, { /* Selecting first tab as default tab when no tab is selected */
if (
this.props.tabs.length > 1 &&
removedTabId === this.props.selectedTabId
) {
setTimeout(() => {
this.updateWidgetProperty(
"defaultTab",
this.props.tabs.filter(tab => tab.id !== removedTabId)[0].label,
);
}, 0);
}
this.updateWidget(WidgetOperations.DELETE, removedContainerWidgetId, {
parentId: this.props.widgetId, parentId: this.props.widgetId,
}); });
}; };