From 527bb5898a469d93f82b05f0d0e63cbb45f61cf6 Mon Sep 17 00:00:00 2001 From: vicky-primathon <67091118+vicky-primathon@users.noreply.github.com> Date: Wed, 29 Jul 2020 14:31:17 +0530 Subject: [PATCH] Fix-The tabs should scroll with the increase in the number of tabs. (#131) * Fixed tabs widget bugs and other updates: 1. Moved drag icon to the left of tab name field in the tabs widget property pane 2. Change drag icon 3. Add scroll when the tabs occupy more width than the width of tabs widget. 4. Add selected tab name validation. 5. Hide overflow tabs. 6. Avoid vertical scrollbars in tabs widget header --- app/client/src/assets/icons/control/drag.svg | 3 +++ .../designSystems/appsmith/Table.tsx | 2 +- .../designSystems/appsmith/TabsComponent.tsx | 8 ++++++- .../propertyControls/TabControl.tsx | 9 ++++---- app/client/src/constants/DefaultTheme.tsx | 18 ++++++++++++++++ app/client/src/constants/WidgetValidation.ts | 1 + app/client/src/icons/ControlIcons.tsx | 6 ++++++ app/client/src/utils/Validators.ts | 21 +++++++++++++++++++ app/client/src/widgets/TabsWidget.tsx | 1 + 9 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 app/client/src/assets/icons/control/drag.svg diff --git a/app/client/src/assets/icons/control/drag.svg b/app/client/src/assets/icons/control/drag.svg new file mode 100644 index 0000000000..a432baa4a2 --- /dev/null +++ b/app/client/src/assets/icons/control/drag.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/client/src/components/designSystems/appsmith/Table.tsx b/app/client/src/components/designSystems/appsmith/Table.tsx index 68da25e7e4..95dcef8f5c 100644 --- a/app/client/src/components/designSystems/appsmith/Table.tsx +++ b/app/client/src/components/designSystems/appsmith/Table.tsx @@ -69,7 +69,7 @@ export const Table = (props: TableProps) => { const data = React.useMemo(() => props.data, [JSON.stringify(props.data)]); const columns = React.useMemo(() => props.columns, [ JSON.stringify(props.columns), - props.columnActions, + JSON.stringify(props.columnActions), ]); const { getTableProps, diff --git a/app/client/src/components/designSystems/appsmith/TabsComponent.tsx b/app/client/src/components/designSystems/appsmith/TabsComponent.tsx index 069febc174..5ba211dec0 100644 --- a/app/client/src/components/designSystems/appsmith/TabsComponent.tsx +++ b/app/client/src/components/designSystems/appsmith/TabsComponent.tsx @@ -3,6 +3,7 @@ import styled, { css } from "styled-components"; import { ComponentProps } from "./BaseComponent"; import { TabsWidgetProps, TabContainerWidgetProps } from "widgets/TabsWidget"; import { generateClassName, getCanvasClassName } from "utils/generators"; +import { scrollbarLight } from "constants/DefaultTheme"; interface TabsComponentProps extends ComponentProps { children?: ReactNode; @@ -53,8 +54,13 @@ const ScrollableCanvasWrapper = styled.div< `; const TabsContainer = styled.div` + width: 100%; + overflow-x: auto; + overflow-y: hidden; + ${scrollbarLight}; + background: ${props => props.theme.colors.builderBodyBG}; && { - height: 32px; + height: 38px; width: 100%; display: flex; justify-content: flex-start; diff --git a/app/client/src/components/propertyControls/TabControl.tsx b/app/client/src/components/propertyControls/TabControl.tsx index 97197ef6ff..1b180b8fdd 100644 --- a/app/client/src/components/propertyControls/TabControl.tsx +++ b/app/client/src/components/propertyControls/TabControl.tsx @@ -16,12 +16,10 @@ const StyledDeleteIcon = styled(FormIcons.DELETE_ICON as AnyStyledComponent)` cursor: pointer; `; -const StyledDragIcon = styled( - ControlIcons.DRAGGABLE_CONTROL as AnyStyledComponent, -)` +const StyledDragIcon = styled(ControlIcons.DRAG_CONTROL as AnyStyledComponent)` padding: 0; position: relative; - margin-left: 15px; + margin-right: 15px; cursor: move; svg { path { @@ -40,6 +38,7 @@ const StyledPropertyPaneButtonWrapper = styled.div` const ItemWrapper = styled.div` display: flex; justify-content: flex-start; + align-items: center; `; const TabsWrapper = styled.div` @@ -77,6 +76,7 @@ function TabControlComponent(props: RenderComponentProps) { const { deleteOption, updateOption, item, index } = props; return ( + - ); } diff --git a/app/client/src/constants/DefaultTheme.tsx b/app/client/src/constants/DefaultTheme.tsx index 8805865b53..a3c316b48b 100644 --- a/app/client/src/constants/DefaultTheme.tsx +++ b/app/client/src/constants/DefaultTheme.tsx @@ -564,5 +564,23 @@ export const theme: Theme = { }, }; +export const scrollbarLight = css` + scrollbar-color: ${props => props.theme.colors.paneText} + + scrollbar-width: thin; + &::-webkit-scrollbar { + width: 6px; + height: 6px; + } + &::-webkit-scrollbar-track { + box-shadow: inset 0 0 6px + ${props => getColorWithOpacity(props.theme.colors.paneText, 0.3)}; + } + &::-webkit-scrollbar-thumb { + background-color: ${props => props.theme.colors.paneText}; + border-radius: ${props => props.theme.radii[1]}px; + } +`; + export { css, createGlobalStyle, keyframes, ThemeProvider }; export default styled; diff --git a/app/client/src/constants/WidgetValidation.ts b/app/client/src/constants/WidgetValidation.ts index 8dbc8b9ef0..9741656714 100644 --- a/app/client/src/constants/WidgetValidation.ts +++ b/app/client/src/constants/WidgetValidation.ts @@ -17,6 +17,7 @@ export const VALIDATION_TYPES = { MARKERS: "MARKERS", ACTION_SELECTOR: "ACTION_SELECTOR", ARRAY_ACTION_SELECTOR: "ARRAY_ACTION_SELECTOR", + SELECTED_TAB: "SELECTED_TAB", }; export type ValidationResponse = { diff --git a/app/client/src/icons/ControlIcons.tsx b/app/client/src/icons/ControlIcons.tsx index ddcd8199eb..455025cb07 100644 --- a/app/client/src/icons/ControlIcons.tsx +++ b/app/client/src/icons/ControlIcons.tsx @@ -15,6 +15,7 @@ import { ReactComponent as HelpIcon } from "assets/icons/control/help.svg"; import { ReactComponent as PickMyLocationSelectedIcon } from "assets/icons/control/pick-location-selected.svg"; import { ReactComponent as SettingsIcon } from "assets/icons/control/settings.svg"; +import { ReactComponent as DragIcon } from "assets/icons/control/drag.svg"; import PlayIcon from "assets/icons/control/play-icon.png"; /* eslint-disable react/display-name */ @@ -101,6 +102,11 @@ export const ControlIcons: { /> ), + DRAG_CONTROL: (props: IconProps) => ( + + + + ), }; export type ControlIconName = keyof typeof ControlIcons; diff --git a/app/client/src/utils/Validators.ts b/app/client/src/utils/Validators.ts index 3a1568c709..6bfbc6d4d3 100644 --- a/app/client/src/utils/Validators.ts +++ b/app/client/src/utils/Validators.ts @@ -499,4 +499,25 @@ export const VALIDATORS: Record = { message: message, }; }, + [VALIDATION_TYPES.SELECTED_TAB]: ( + value: any, + props: WidgetProps, + dataTree?: DataTree, + ): ValidationResponse => { + const tabs = + props.tabs && _.isString(props.tabs) + ? JSON.parse(props.tabs) + : props.tabs && Array.isArray(props.tabs) + ? props.tabs + : []; + const tabNames = tabs.map((i: { label: string; id: string }) => i.label); + const isValidTabName = tabNames.includes(value); + return { + isValid: isValidTabName, + parsed: value, + message: isValidTabName + ? "" + : `${WIDGET_TYPE_VALIDATION_ERROR}: Invalid tab name.`, + }; + }, }; diff --git a/app/client/src/widgets/TabsWidget.tsx b/app/client/src/widgets/TabsWidget.tsx index f52729f49e..1f10f6587a 100644 --- a/app/client/src/widgets/TabsWidget.tsx +++ b/app/client/src/widgets/TabsWidget.tsx @@ -14,6 +14,7 @@ class TabsWidget extends BaseWidget< static getPropertyValidationMap(): WidgetPropertyValidationType { return { tabs: VALIDATION_TYPES.TABS_DATA, + selectedTab: VALIDATION_TYPES.SELECTED_TAB, }; }