From 4fa2aca3e93cf6deea7fe5345fb1da2c22bab23f Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Fri, 15 Nov 2024 14:27:33 +0530 Subject: [PATCH 01/15] chore: Transfer IDE components --- app/client/src/IDE/Components/HeaderTitle.tsx | 17 ------------- app/client/src/IDE/index.ts | 25 ------------------- app/client/src/ce/constants/messages.ts | 3 ++- .../src/pages/AdminSettings/components.tsx | 3 +-- .../pages/AppViewer/Navigation/Sidebar.tsx | 2 +- .../src/pages/Editor/EditorName/components.ts | 3 +-- .../Editor/IDE/EditorPane/PagesSection.tsx | 3 +-- .../pages/Editor/IDE/Header/EditorTitle.tsx | 12 ++++++--- .../src/pages/Editor/IDE/Header/index.tsx | 6 +++-- .../pages/Editor/JSEditor/styledComponents.ts | 2 +- .../WidgetsEditor/WidgetEditorContainer.tsx | 2 +- .../Editor/commons/EditorHeaderComponents.tsx | 2 +- .../Editor/commons/EditorWrapperContainer.tsx | 2 +- .../src/pages/Editor/commons/Omnibar.tsx | 2 +- app/client/src/pages/Editor/index.tsx | 2 +- 15 files changed, 24 insertions(+), 62 deletions(-) delete mode 100644 app/client/src/IDE/Components/HeaderTitle.tsx diff --git a/app/client/src/IDE/Components/HeaderTitle.tsx b/app/client/src/IDE/Components/HeaderTitle.tsx deleted file mode 100644 index 7423cb338ed6..000000000000 --- a/app/client/src/IDE/Components/HeaderTitle.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react"; -import { Flex, Text } from "@appsmith/ads"; - -/** - * Handy little styled component that can be used to render the title in the IDEHeader component - * **/ -const HeaderTitle = ({ title }: { title: string }) => { - return ( - - - {title} - - - ); -}; - -export default HeaderTitle; diff --git a/app/client/src/IDE/index.ts b/app/client/src/IDE/index.ts index cc69383fab62..a151c77f1b75 100644 --- a/app/client/src/IDE/index.ts +++ b/app/client/src/IDE/index.ts @@ -3,15 +3,6 @@ Components that are part of the main structure of the IDE experience ====================================================**/ -/** - * The IDEHeader gets exported with 3 layout subsections. - * IDEHeader.Left, IDEHeader.Center, IDEHeader.Right - * These are composable components that you can use to spread the content of the header - * It is possible to use the IDE Header without using these subsections - */ -export { IDE_HEADER_HEIGHT } from "./Structure/constants"; -export { default as IDEHeader } from "./Structure/Header"; - /** * The IDEToolbar gets exported with 2 layout subsections. * IDEToolbar.Left and IDEToolbar.Right @@ -25,22 +16,6 @@ export { default as IDEToolbar } from "./Structure/Toolbar"; Components that are smaller UI abstractions for easy use and standardisation within the IDE =======================================================**/ -/** - * IDEHeaderTitle is a small text styled wrapper that is suitable to be used inside IDEHeader - */ -export { default as IDEHeaderTitle } from "./Components/HeaderTitle"; -/** - * IDEHeaderEditorSwitcher can be used for a trigger component to show a dropdown for pages, modules - * or any list of elements in the header E.g., Pages / Page 1 - */ -export { default as IDEHeaderEditorSwitcher } from "./Components/HeaderEditorSwitcher"; -/** - * The IDEHeaderDropdown gets exported with 2 layout subsections. - * IDEHeaderDropdown.Header, IDEHeaderDropdown.Body - * These are composable components that you can use to spread the content of the header - * It is possible to use the IDE Header without using these subsections - */ -export { default as IDEHeaderDropdown } from "./Components/HeaderDropdown"; /** * IDEBottomView is a versatile view meant to be at the bottom of the screen. * It is resizable and can be hidden or collapsed based on the behavior configured diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts index b5a102028ede..6916b5373dd7 100644 --- a/app/client/src/ce/constants/messages.ts +++ b/app/client/src/ce/constants/messages.ts @@ -2472,7 +2472,8 @@ export const ADD_PAGE_FROM_TEMPLATE_MODAL = { export const HEADER_TITLES = { DATA: () => "Data", - EDITOR: () => "Pages", + PAGES: () => "Pages", + EDITOR: () => "Editor", SETTINGS: () => "Settings", LIBRARIES: () => "Libraries", }; diff --git a/app/client/src/pages/AdminSettings/components.tsx b/app/client/src/pages/AdminSettings/components.tsx index d2ef42475856..791cdf4fb3cc 100644 --- a/app/client/src/pages/AdminSettings/components.tsx +++ b/app/client/src/pages/AdminSettings/components.tsx @@ -1,7 +1,6 @@ import styled from "styled-components"; import { Classes } from "@blueprintjs/core"; -import { Link, Text } from "@appsmith/ads"; -import { IDE_HEADER_HEIGHT } from "IDE"; +import { Link, Text, IDE_HEADER_HEIGHT } from "@appsmith/ads"; export const Wrapper = styled.div` flex-basis: calc(100% - ${(props) => props.theme.homePage.leftPane.width}px); diff --git a/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx b/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx index 95903b915ca6..3b6b80aa7328 100644 --- a/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx +++ b/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx @@ -34,7 +34,7 @@ import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettings import NavigationLogo from "ee/pages/AppViewer/NavigationLogo"; import MenuItemContainer from "./components/MenuItemContainer"; import BackToAppsButton from "./components/BackToAppsButton"; -import { IDE_HEADER_HEIGHT } from "IDE"; +import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; import { BOTTOM_BAR_HEIGHT } from "components/BottomBar/constants"; interface SidebarProps { diff --git a/app/client/src/pages/Editor/EditorName/components.ts b/app/client/src/pages/Editor/EditorName/components.ts index 8aaa930f461f..a1499635bd75 100644 --- a/app/client/src/pages/Editor/EditorName/components.ts +++ b/app/client/src/pages/Editor/EditorName/components.ts @@ -1,8 +1,7 @@ import styled from "styled-components"; import { Classes } from "@blueprintjs/core"; import { getTypographyByKey } from "@appsmith/ads-old"; -import { Icon } from "@appsmith/ads"; -import { IDE_HEADER_HEIGHT } from "IDE"; +import { Icon, IDE_HEADER_HEIGHT } from "@appsmith/ads"; export const Container = styled.div` display: flex; diff --git a/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx b/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx index 0b94703f2532..96393d1643d2 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useMemo, useState } from "react"; -import { Text } from "@appsmith/ads"; +import { Text, IDEHeaderDropdown } from "@appsmith/ads"; import { useDispatch, useSelector } from "react-redux"; import { useLocation } from "react-router"; @@ -18,7 +18,6 @@ import { getNextEntityName } from "utils/AppsmithUtils"; import { getCurrentWorkspaceId } from "ee/selectors/selectedWorkspaceSelectors"; import { getInstanceId } from "ee/selectors/tenantSelectors"; import { PageElement } from "pages/Editor/IDE/EditorPane/components/PageElement"; -import { IDEHeaderDropdown } from "IDE"; import { PAGE_ENTITY_NAME } from "ee/constants/messages"; const PagesSection = ({ onItemSelected }: { onItemSelected: () => void }) => { diff --git a/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx b/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx index 47ef1030766c..c1db625a89cf 100644 --- a/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx +++ b/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx @@ -1,9 +1,13 @@ import React, { useState } from "react"; -import { Popover, PopoverTrigger, PopoverContent } from "@appsmith/ads"; +import { + Popover, + PopoverTrigger, + PopoverContent, + IDEHeaderSwitcher, +} from "@appsmith/ads"; import { createMessage, HEADER_TITLES } from "ee/constants/messages"; import { PagesSection } from "../EditorPane/PagesSection"; -import { IDEHeaderEditorSwitcher } from "IDE"; const EditorTitle = ({ title }: { title: string }) => { const [active, setActive] = useState(false); @@ -15,9 +19,9 @@ const EditorTitle = ({ title }: { title: string }) => { return ( - diff --git a/app/client/src/pages/Editor/IDE/Header/index.tsx b/app/client/src/pages/Editor/IDE/Header/index.tsx index ee4365196a5c..de4701c0dfef 100644 --- a/app/client/src/pages/Editor/IDE/Header/index.tsx +++ b/app/client/src/pages/Editor/IDE/Header/index.tsx @@ -13,6 +13,8 @@ import { TabPanel, Button, Link, + IDEHeader, + IDEHeaderTitle, } from "@appsmith/ads"; import { useDispatch, useSelector } from "react-redux"; import { EditInteractionKind, SavingState } from "@appsmith/ads-old"; @@ -74,10 +76,10 @@ import { useCurrentAppState } from "../hooks/useCurrentAppState"; import { EditorState } from "ee/entities/IDE/constants"; import { EditorSaveIndicator } from "pages/Editor/EditorSaveIndicator"; import type { Page } from "entities/Page"; -import { IDEHeader, IDEHeaderTitle } from "IDE"; import { APPLICATIONS_URL } from "constants/routes"; import { useNavigationMenuData } from "../../EditorName/useNavigationMenuData"; import useLibraryHeaderTitle from "ee/pages/Editor/IDE/Header/useLibraryHeaderTitle"; +import { AppsmithLink } from "pages/Editor/AppsmithLink"; const StyledDivider = styled(Divider)` height: 50%; @@ -218,7 +220,7 @@ const Header = () => { return ( <> - + }> diff --git a/app/client/src/pages/Editor/JSEditor/styledComponents.ts b/app/client/src/pages/Editor/JSEditor/styledComponents.ts index f84f96e2a064..0358ce19f101 100644 --- a/app/client/src/pages/Editor/JSEditor/styledComponents.ts +++ b/app/client/src/pages/Editor/JSEditor/styledComponents.ts @@ -6,7 +6,7 @@ import { RUN_GUTTER_ID, } from "./constants"; import { thinScrollbar } from "constants/DefaultTheme"; -import { IDE_HEADER_HEIGHT } from "IDE"; +import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; export const CodeEditorWithGutterStyles = css` .${RUN_GUTTER_ID} { diff --git a/app/client/src/pages/Editor/WidgetsEditor/WidgetEditorContainer.tsx b/app/client/src/pages/Editor/WidgetsEditor/WidgetEditorContainer.tsx index 1bdf176c3748..cad110052fd0 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/WidgetEditorContainer.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/WidgetEditorContainer.tsx @@ -8,7 +8,7 @@ import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettings import { EditorState } from "ee/entities/IDE/constants"; import { RenderModes } from "constants/WidgetConstants"; import styled from "styled-components"; -import { IDE_HEADER_HEIGHT } from "IDE"; +import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; import { BOTTOM_BAR_HEIGHT } from "components/BottomBar/constants"; const Container = styled.div` diff --git a/app/client/src/pages/Editor/commons/EditorHeaderComponents.tsx b/app/client/src/pages/Editor/commons/EditorHeaderComponents.tsx index cdaaa0859f32..dd758e54326f 100644 --- a/app/client/src/pages/Editor/commons/EditorHeaderComponents.tsx +++ b/app/client/src/pages/Editor/commons/EditorHeaderComponents.tsx @@ -1,7 +1,7 @@ import styled from "styled-components"; import { Profile } from "pages/common/ProfileImage"; import { getTypographyByKey } from "@appsmith/ads-old"; -import { IDE_HEADER_HEIGHT } from "IDE"; +import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; export const HeaderWrapper = styled.div` width: 100%; diff --git a/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx b/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx index 4ed87816a8d5..990004cbbec5 100644 --- a/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx +++ b/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx @@ -4,7 +4,7 @@ import classNames from "classnames"; import { useSelector } from "react-redux"; import { combinedPreviewModeSelector } from "../../../selectors/editorSelectors"; import { protectedModeSelector } from "selectors/gitSyncSelectors"; -import { IDE_HEADER_HEIGHT } from "../../../IDE"; +import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; import { BOTTOM_BAR_HEIGHT } from "../../../components/BottomBar/constants"; import { PROTECTED_CALLOUT_HEIGHT } from "../IDE/ProtectedCallout"; diff --git a/app/client/src/pages/Editor/commons/Omnibar.tsx b/app/client/src/pages/Editor/commons/Omnibar.tsx index d9226faf000f..bf4d06e0494b 100644 --- a/app/client/src/pages/Editor/commons/Omnibar.tsx +++ b/app/client/src/pages/Editor/commons/Omnibar.tsx @@ -3,7 +3,7 @@ import styled from "styled-components"; import { snipingModeSelector } from "selectors/editorSelectors"; import { retryPromise } from "utils/AppsmithUtils"; import { useSelector } from "react-redux"; -import { IDE_HEADER_HEIGHT } from "IDE"; +import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; const BindingBanner = styled.div` position: fixed; diff --git a/app/client/src/pages/Editor/index.tsx b/app/client/src/pages/Editor/index.tsx index b42f724b6c2e..dbb5f8790a06 100644 --- a/app/client/src/pages/Editor/index.tsx +++ b/app/client/src/pages/Editor/index.tsx @@ -50,7 +50,7 @@ import { PartialExportModal } from "components/editorComponents/PartialImportExp import { PartialImportModal } from "components/editorComponents/PartialImportExport/PartialImportModal"; import type { Page } from "entities/Page"; import { AppCURLImportModal } from "ee/pages/Editor/CurlImport"; -import { IDE_HEADER_HEIGHT } from "IDE"; +import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; interface EditorProps { currentApplicationId?: string; From 8940eca9528329df2a7c1a5354d0d6ca1c7b36d7 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Fri, 15 Nov 2024 14:43:36 +0530 Subject: [PATCH 02/15] ADS changes --- .../ads/src/IDEHeader/HeaderDropdown.test.tsx | 41 +++++++ .../ads/src/IDEHeader/HeaderDropdown.tsx | 77 +++++++++++++ .../IDEHeader/HeaderEditorSwitcher.test.tsx | 104 ++++++++++++++++++ .../ads/src/IDEHeader/IDEHeader.constants.ts | 2 + .../ads/src/IDEHeader/IDEHeader.tsx | 79 +++++++++++++ .../ads/src/IDEHeader/IDEHeaderSwitcher.tsx | 71 ++++++++++++ .../ads/src/IDEHeader/IDEHeaderTitle.tsx | 16 +++ .../design-system/ads/src/IDEHeader/index.ts | 27 +++++ .../packages/design-system/ads/src/index.ts | 1 + 9 files changed, 418 insertions(+) create mode 100644 app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.test.tsx create mode 100644 app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.tsx create mode 100644 app/client/packages/design-system/ads/src/IDEHeader/HeaderEditorSwitcher.test.tsx create mode 100644 app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.constants.ts create mode 100644 app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.tsx create mode 100644 app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderSwitcher.tsx create mode 100644 app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderTitle.tsx create mode 100644 app/client/packages/design-system/ads/src/IDEHeader/index.ts diff --git a/app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.test.tsx b/app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.test.tsx new file mode 100644 index 000000000000..2085669f4cfa --- /dev/null +++ b/app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.test.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import { IDEHeaderDropdown } from "./HeaderDropdown"; +import "@testing-library/jest-dom"; + +describe("HeaderDropdown", () => { + it("renders children components correctly", () => { + render( + + + Header + + + Body + + , + ); + + expect(screen.getByText("Header")).toBeInTheDocument(); + expect(screen.getByText("Body")).toBeInTheDocument(); + }); + + it("applies custom className to the header", () => { + const customClass = "my-custom-class"; + const { container } = render( + + + Header + + + Body + + , + ); + + // eslint-disable-next-line testing-library/no-node-access,testing-library/no-container + const headerElement = container.querySelector(`.${customClass}`); + + expect(headerElement).toBeInTheDocument(); + }); +}); diff --git a/app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.tsx b/app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.tsx new file mode 100644 index 000000000000..538633f979be --- /dev/null +++ b/app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.tsx @@ -0,0 +1,77 @@ +import { Flex } from "../Flex"; +import React from "react"; +import styled from "styled-components"; + +const Container = styled(Flex)` + & .t--entity-item { + grid-template-columns: 0 auto 1fr auto auto auto auto auto; + height: 32px; + + & .t--entity-name { + padding-left: var(--ads-v2-spaces-3); + } + } +`; + +const HeaderWrapper = styled.div` + padding: var(--ads-v2-spaces-3); + padding-right: var(--ads-v2-spaces-2); + display: flex; + justify-content: space-between; + align-items: center; + height: 40px; + span { + line-height: 20px; + } +`; + +interface EditorHeaderDropdown { + children: React.ReactNode; +} + +interface EditorHeaderDropdownHeader { + children: React.ReactNode; + className?: string; +} + +interface EditorHeaderDropdownBody { + children: React.ReactNode; +} + +export function IDEHeaderDropdown({ children }: EditorHeaderDropdown) { + return ( + + {children} + + ); +} + +function IDEHeaderDropdownHeader({ + children, + className, +}: EditorHeaderDropdownHeader) { + return {children}; +} + +function IDEHeaderDropdownBody({ children }: EditorHeaderDropdownBody) { + return ( + + {children} + + ); +} + +IDEHeaderDropdown.Header = IDEHeaderDropdownHeader; +IDEHeaderDropdown.Body = IDEHeaderDropdownBody; diff --git a/app/client/packages/design-system/ads/src/IDEHeader/HeaderEditorSwitcher.test.tsx b/app/client/packages/design-system/ads/src/IDEHeader/HeaderEditorSwitcher.test.tsx new file mode 100644 index 000000000000..2663d7e15bf9 --- /dev/null +++ b/app/client/packages/design-system/ads/src/IDEHeader/HeaderEditorSwitcher.test.tsx @@ -0,0 +1,104 @@ +import React from "react"; +import { render, fireEvent, screen } from "@testing-library/react"; +import { IDEHeaderSwitcher } from "./IDEHeaderSwitcher"; +import "@testing-library/jest-dom"; + +describe("HeaderEditorSwitcher", () => { + const mockOnClick = jest.fn(); + const defaultProps = { + prefix: "Prefix", + title: "Title", + titleTestId: "titleTestId", + active: false, + onClick: mockOnClick, + }; + + it("renders with correct props", () => { + render(); + + // eslint-disable-next-line testing-library/no-node-access + const testIdElement = document.getElementsByClassName( + defaultProps.titleTestId, + ); + + expect(screen.getByText("Prefix /")).toBeInTheDocument(); + expect(screen.getByText(defaultProps.title)).toBeInTheDocument(); + expect(testIdElement).toBeDefined(); + }); + + it("renders active state correctly", () => { + render(); + + expect(screen.getByText("Prefix /")).toHaveStyle( + "background-color: var(--ads-v2-color-bg-subtle)", + ); + }); + + it("calls onClick handler when clicked", () => { + render(); + + fireEvent.click(screen.getByText("Title")); + + expect(mockOnClick).toHaveBeenCalled(); + }); + + it("forwards ref correctly", () => { + const ref = React.createRef(); + + render(); + expect(ref.current).toBeTruthy(); + }); + + it("does not crash when onClick is not provided", () => { + render(); + + fireEvent.click(screen.getByText("Title")); // Should not throw error + }); + + it("does not show separator and applies different inactive color to icon", () => { + const ref = React.createRef(); + const { container } = render( + , + ); + + // eslint-disable-next-line testing-library/no-container,testing-library/no-node-access + const icon = container.querySelector(".remixicon-icon"); // Get chevron icon + + expect(screen.getByTestId("root-div")).toHaveTextContent("Prefix"); + expect(icon).toHaveAttribute( + "fill", + "var(--ads-v2-colors-content-label-inactive-fg)", + ); + }); + + it("forwards additional props correctly", () => { + const testId = "test-id"; + const className = "custom-class"; + + const { container } = render( + , + ); + + // eslint-disable-next-line testing-library/no-container,testing-library/no-node-access + const firstDiv = container.querySelector("div"); // Get the first div element + const classNames = firstDiv?.getAttribute("class")?.split(" ") || []; + + expect(firstDiv).toHaveAttribute("data-testid", testId); // Check if data-testid prop is applied + expect(classNames).toContain(className); // Check if className prop is applied + expect(classNames).toContain("flex"); // Check if internal classes still exists + expect(classNames).toContain("align-center"); // Check if internal classes still exists + expect(classNames).toContain("justify-center"); // Check if internal classes still exists + }); +}); diff --git a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.constants.ts b/app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.constants.ts new file mode 100644 index 000000000000..6307b9c5b692 --- /dev/null +++ b/app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.constants.ts @@ -0,0 +1,2 @@ +export const IDE_HEADER_HEIGHT = 40; +export const LOGO_WIDTH = 50; diff --git a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.tsx b/app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.tsx new file mode 100644 index 000000000000..1cd52ca2faf2 --- /dev/null +++ b/app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.tsx @@ -0,0 +1,79 @@ +import React from "react"; +import { Flex } from "../Flex"; +import { IDE_HEADER_HEIGHT, LOGO_WIDTH } from "./IDEHeader.constants"; + +interface ChildrenProps { + children: React.ReactNode | React.ReactNode[]; +} + +const Left = (props: ChildrenProps & { logo: React.ReactNode }) => { + return ( + + + {props.logo} + + {props.children} + + ); +}; + +const Center = (props: ChildrenProps) => { + return ( + + {props.children} + + ); +}; + +const Right = (props: ChildrenProps) => { + return ( + + {props.children} + + ); +}; + +export const IDEHeader = (props: ChildrenProps) => { + return ( + + {props.children} + + ); +}; + +IDEHeader.Left = Left; +IDEHeader.Center = Center; +IDEHeader.Right = Right; diff --git a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderSwitcher.tsx b/app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderSwitcher.tsx new file mode 100644 index 000000000000..714e68ff21e4 --- /dev/null +++ b/app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderSwitcher.tsx @@ -0,0 +1,71 @@ +import { Flex, Icon, Text } from ".."; +import React, { type ForwardedRef } from "react"; +import styled from "styled-components"; + +interface Props { + prefix: string; + title?: string; + titleTestId: string; + active: boolean; + onClick?: React.MouseEventHandler; + className?: string; +} + +const SwitchTrigger = styled.div<{ active: boolean }>` + border-radius: var(--ads-v2-border-radius); + background-color: ${(props) => + props.active ? `var(--ads-v2-color-bg-subtle)` : "unset"}; + cursor: pointer; + padding: var(--ads-v2-spaces-2); + :hover { + background-color: var(--ads-v2-color-bg-subtle); + } +`; + +export const IDEHeaderSwitcher = React.forwardRef( + (props: Props, ref: ForwardedRef) => { + const { active, className, prefix, title, titleTestId, ...rest } = props; + + const separator = title ? " /" : ""; + + return ( + + + {prefix + separator} + + + + {title} + + + + + ); + }, +); + +IDEHeaderSwitcher.displayName = "IDEHeaderSwitcher"; diff --git a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderTitle.tsx b/app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderTitle.tsx new file mode 100644 index 000000000000..e31bcfe27d78 --- /dev/null +++ b/app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderTitle.tsx @@ -0,0 +1,16 @@ +import React from "react"; +import { Flex } from "../Flex"; +import { Text } from "../Text"; + +/** + * Handy little styled component that can be used to render the title in the IDEHeader component + * **/ +export const IDEHeaderTitle = ({ title }: { title: string }) => { + return ( + + + {title} + + + ); +}; diff --git a/app/client/packages/design-system/ads/src/IDEHeader/index.ts b/app/client/packages/design-system/ads/src/IDEHeader/index.ts new file mode 100644 index 000000000000..9fd6d10262f1 --- /dev/null +++ b/app/client/packages/design-system/ads/src/IDEHeader/index.ts @@ -0,0 +1,27 @@ +/** + * The IDEHeader gets exported with 3 layout subsections. + * IDEHeader.Left, IDEHeader.Center, IDEHeader.Right + * These are composable components that you can use to spread the content of the header + * It is possible to use the IDE Header without using these subsections + */ +export { IDEHeader } from "./IDEHeader"; +export { IDE_HEADER_HEIGHT, LOGO_WIDTH } from "./IDEHeader.constants"; + +/** + * IDEHeaderSwitcher can be used for a trigger component to show a dropdown for pages, modules + * or any list of elements in the header E.g., Pages / Page 1 + */ +export { IDEHeaderSwitcher } from "./IDEHeaderSwitcher"; + +/** + * IDEHeaderTitle is a small text styled wrapper that is suitable to be used inside IDEHeader + */ +export { IDEHeaderTitle } from "./IDEHeaderTitle"; + +/** + * The IDEHeaderDropdown gets exported with 2 layout subsections. + * IDEHeaderDropdown.Header, IDEHeaderDropdown.Body + * These are composable components that you can use to spread the content of the header + * It is possible to use the IDE Header without using these subsections + */ +export { IDEHeaderDropdown } from "./HeaderDropdown"; diff --git a/app/client/packages/design-system/ads/src/index.ts b/app/client/packages/design-system/ads/src/index.ts index 173d119074e6..4e2c665df632 100644 --- a/app/client/packages/design-system/ads/src/index.ts +++ b/app/client/packages/design-system/ads/src/index.ts @@ -36,3 +36,4 @@ export * from "./Toast"; export * from "./ToggleButton"; export * from "./Tooltip"; export * from "./ToggleButtonGroup"; +export * from "./IDEHeader"; From 7df7ad010ab3c0432af3696aecdba990aafe99a1 Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Mon, 18 Nov 2024 16:06:26 +0530 Subject: [PATCH 03/15] folder changes --- .../ads/src/Layout/EntityExplorer/index.ts | 1 + .../ads/src/Layout/EntityExplorer/styles.ts | 13 +++++++ .../HeaderDropdown/HeaderDropdown.styles.ts | 13 +++++++ .../HeaderDropdown}/HeaderDropdown.test.tsx | 0 .../HeaderDropdown}/HeaderDropdown.tsx | 37 +++++-------------- .../Layout/IDEHeader/HeaderDropdown/index.ts | 1 + .../HeaderEditorSwitcher.test.tsx | 0 .../HeaderSwitcher/HeaderSwitcher.styles.ts | 12 ++++++ .../HeaderSwitcher}/IDEHeaderSwitcher.tsx | 19 ++-------- .../Layout/IDEHeader/HeaderSwitcher/index.ts | 1 + .../IDEHeader/IDEHeader.constants.ts | 0 .../src/{ => Layout}/IDEHeader/IDEHeader.tsx | 2 +- .../{ => Layout}/IDEHeader/IDEHeaderTitle.tsx | 4 +- .../ads/src/{ => Layout}/IDEHeader/index.ts | 2 +- .../design-system/ads/src/Layout/index.ts | 2 + .../packages/design-system/ads/src/index.ts | 2 +- .../Editor/IDE/EditorPane/PagesSection.tsx | 6 ++- 17 files changed, 65 insertions(+), 50 deletions(-) create mode 100644 app/client/packages/design-system/ads/src/Layout/EntityExplorer/index.ts create mode 100644 app/client/packages/design-system/ads/src/Layout/EntityExplorer/styles.ts create mode 100644 app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.styles.ts rename app/client/packages/design-system/ads/src/{IDEHeader => Layout/IDEHeader/HeaderDropdown}/HeaderDropdown.test.tsx (100%) rename app/client/packages/design-system/ads/src/{IDEHeader => Layout/IDEHeader/HeaderDropdown}/HeaderDropdown.tsx (59%) create mode 100644 app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/index.ts rename app/client/packages/design-system/ads/src/{IDEHeader => Layout/IDEHeader/HeaderSwitcher}/HeaderEditorSwitcher.test.tsx (100%) create mode 100644 app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.styles.ts rename app/client/packages/design-system/ads/src/{IDEHeader => Layout/IDEHeader/HeaderSwitcher}/IDEHeaderSwitcher.tsx (76%) create mode 100644 app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/index.ts rename app/client/packages/design-system/ads/src/{ => Layout}/IDEHeader/IDEHeader.constants.ts (100%) rename app/client/packages/design-system/ads/src/{ => Layout}/IDEHeader/IDEHeader.tsx (97%) rename app/client/packages/design-system/ads/src/{ => Layout}/IDEHeader/IDEHeaderTitle.tsx (83%) rename app/client/packages/design-system/ads/src/{ => Layout}/IDEHeader/index.ts (94%) create mode 100644 app/client/packages/design-system/ads/src/Layout/index.ts diff --git a/app/client/packages/design-system/ads/src/Layout/EntityExplorer/index.ts b/app/client/packages/design-system/ads/src/Layout/EntityExplorer/index.ts new file mode 100644 index 000000000000..b560fb716f49 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Layout/EntityExplorer/index.ts @@ -0,0 +1 @@ +export { ListItemContainer } from "./styles"; diff --git a/app/client/packages/design-system/ads/src/Layout/EntityExplorer/styles.ts b/app/client/packages/design-system/ads/src/Layout/EntityExplorer/styles.ts new file mode 100644 index 000000000000..0b2455da723b --- /dev/null +++ b/app/client/packages/design-system/ads/src/Layout/EntityExplorer/styles.ts @@ -0,0 +1,13 @@ +import styled from "styled-components"; +import { Flex } from "../../Flex"; + +export const ListItemContainer = styled(Flex)` + & .t--entity-item { + grid-template-columns: 0 auto 1fr auto auto auto auto auto; + height: 32px; + + & .t--entity-name { + padding-left: var(--ads-v2-spaces-3); + } + } +`; diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.styles.ts b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.styles.ts new file mode 100644 index 000000000000..27b2927809d2 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.styles.ts @@ -0,0 +1,13 @@ +import styled from "styled-components"; + +export const HeaderWrapper = styled.div` + padding: var(--ads-v2-spaces-3); + padding-right: var(--ads-v2-spaces-2); + display: flex; + justify-content: space-between; + align-items: center; + height: 40px; + span { + line-height: 20px; + } +`; diff --git a/app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.test.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.test.tsx similarity index 100% rename from app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.test.tsx rename to app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.test.tsx diff --git a/app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.tsx similarity index 59% rename from app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.tsx rename to app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.tsx index 538633f979be..9978edca6883 100644 --- a/app/client/packages/design-system/ads/src/IDEHeader/HeaderDropdown.tsx +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.tsx @@ -1,29 +1,6 @@ -import { Flex } from "../Flex"; +import { Flex } from "../../../Flex"; import React from "react"; -import styled from "styled-components"; - -const Container = styled(Flex)` - & .t--entity-item { - grid-template-columns: 0 auto 1fr auto auto auto auto auto; - height: 32px; - - & .t--entity-name { - padding-left: var(--ads-v2-spaces-3); - } - } -`; - -const HeaderWrapper = styled.div` - padding: var(--ads-v2-spaces-3); - padding-right: var(--ads-v2-spaces-2); - display: flex; - justify-content: space-between; - align-items: center; - height: 40px; - span { - line-height: 20px; - } -`; +import * as Styled from "./styles"; interface EditorHeaderDropdown { children: React.ReactNode; @@ -40,14 +17,14 @@ interface EditorHeaderDropdownBody { export function IDEHeaderDropdown({ children }: EditorHeaderDropdown) { return ( - {children} - + ); } @@ -55,7 +32,11 @@ function IDEHeaderDropdownHeader({ children, className, }: EditorHeaderDropdownHeader) { - return {children}; + return ( + + {children} + + ); } function IDEHeaderDropdownBody({ children }: EditorHeaderDropdownBody) { diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/index.ts b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/index.ts new file mode 100644 index 000000000000..07bf361f42e0 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/index.ts @@ -0,0 +1 @@ +export { IDEHeaderDropdown } from "./HeaderDropdown"; diff --git a/app/client/packages/design-system/ads/src/IDEHeader/HeaderEditorSwitcher.test.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderEditorSwitcher.test.tsx similarity index 100% rename from app/client/packages/design-system/ads/src/IDEHeader/HeaderEditorSwitcher.test.tsx rename to app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderEditorSwitcher.test.tsx diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.styles.ts b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.styles.ts new file mode 100644 index 000000000000..e9a73e15b4a8 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.styles.ts @@ -0,0 +1,12 @@ +import styled from "styled-components"; + +export const SwitchTrigger = styled.div<{ active: boolean }>` + border-radius: var(--ads-v2-border-radius); + background-color: ${(props) => + props.active ? `var(--ads-v2-color-bg-subtle)` : "unset"}; + cursor: pointer; + padding: var(--ads-v2-spaces-2); + :hover { + background-color: var(--ads-v2-color-bg-subtle); + } +`; diff --git a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderSwitcher.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/IDEHeaderSwitcher.tsx similarity index 76% rename from app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderSwitcher.tsx rename to app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/IDEHeaderSwitcher.tsx index 714e68ff21e4..34e6e8c1f921 100644 --- a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderSwitcher.tsx +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/IDEHeaderSwitcher.tsx @@ -1,6 +1,6 @@ -import { Flex, Icon, Text } from ".."; +import { Flex, Icon, Text } from "../../../index"; import React, { type ForwardedRef } from "react"; -import styled from "styled-components"; +import * as Styled from "./styles"; interface Props { prefix: string; @@ -11,17 +11,6 @@ interface Props { className?: string; } -const SwitchTrigger = styled.div<{ active: boolean }>` - border-radius: var(--ads-v2-border-radius); - background-color: ${(props) => - props.active ? `var(--ads-v2-color-bg-subtle)` : "unset"}; - cursor: pointer; - padding: var(--ads-v2-spaces-2); - :hover { - background-color: var(--ads-v2-color-bg-subtle); - } -`; - export const IDEHeaderSwitcher = React.forwardRef( (props: Props, ref: ForwardedRef) => { const { active, className, prefix, title, titleTestId, ...rest } = props; @@ -29,7 +18,7 @@ export const IDEHeaderSwitcher = React.forwardRef( const separator = title ? " /" : ""; return ( - - + ); }, ); diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/index.ts b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/index.ts new file mode 100644 index 000000000000..1580b3834c63 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/index.ts @@ -0,0 +1 @@ +export { IDEHeaderSwitcher } from "./IDEHeaderSwitcher"; diff --git a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.constants.ts b/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.constants.ts similarity index 100% rename from app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.constants.ts rename to app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.constants.ts diff --git a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.tsx similarity index 97% rename from app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.tsx rename to app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.tsx index 1cd52ca2faf2..f006421b30f4 100644 --- a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeader.tsx +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { Flex } from "../Flex"; +import { Flex } from "../../Flex"; import { IDE_HEADER_HEIGHT, LOGO_WIDTH } from "./IDEHeader.constants"; interface ChildrenProps { diff --git a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderTitle.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeaderTitle.tsx similarity index 83% rename from app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderTitle.tsx rename to app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeaderTitle.tsx index e31bcfe27d78..cfa626f95910 100644 --- a/app/client/packages/design-system/ads/src/IDEHeader/IDEHeaderTitle.tsx +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeaderTitle.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { Flex } from "../Flex"; -import { Text } from "../Text"; +import { Flex } from "../../Flex"; +import { Text } from "../../Text"; /** * Handy little styled component that can be used to render the title in the IDEHeader component diff --git a/app/client/packages/design-system/ads/src/IDEHeader/index.ts b/app/client/packages/design-system/ads/src/Layout/IDEHeader/index.ts similarity index 94% rename from app/client/packages/design-system/ads/src/IDEHeader/index.ts rename to app/client/packages/design-system/ads/src/Layout/IDEHeader/index.ts index 9fd6d10262f1..3a8c4d389008 100644 --- a/app/client/packages/design-system/ads/src/IDEHeader/index.ts +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/index.ts @@ -11,7 +11,7 @@ export { IDE_HEADER_HEIGHT, LOGO_WIDTH } from "./IDEHeader.constants"; * IDEHeaderSwitcher can be used for a trigger component to show a dropdown for pages, modules * or any list of elements in the header E.g., Pages / Page 1 */ -export { IDEHeaderSwitcher } from "./IDEHeaderSwitcher"; +export { IDEHeaderSwitcher } from "./HeaderSwitcher"; /** * IDEHeaderTitle is a small text styled wrapper that is suitable to be used inside IDEHeader diff --git a/app/client/packages/design-system/ads/src/Layout/index.ts b/app/client/packages/design-system/ads/src/Layout/index.ts new file mode 100644 index 000000000000..283192812370 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Layout/index.ts @@ -0,0 +1,2 @@ +export * from "./IDEHeader"; +export * from "./EntityExplorer"; diff --git a/app/client/packages/design-system/ads/src/index.ts b/app/client/packages/design-system/ads/src/index.ts index 4e2c665df632..a62cbcb01a6d 100644 --- a/app/client/packages/design-system/ads/src/index.ts +++ b/app/client/packages/design-system/ads/src/index.ts @@ -36,4 +36,4 @@ export * from "./Toast"; export * from "./ToggleButton"; export * from "./Tooltip"; export * from "./ToggleButtonGroup"; -export * from "./IDEHeader"; +export * from "./Layout"; diff --git a/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx b/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx index 96393d1643d2..da2e5fe03533 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useMemo, useState } from "react"; -import { Text, IDEHeaderDropdown } from "@appsmith/ads"; +import { Text, IDEHeaderDropdown, ListItemContainer } from "@appsmith/ads"; import { useDispatch, useSelector } from "react-redux"; import { useLocation } from "react-router"; @@ -76,7 +76,9 @@ const PagesSection = ({ onItemSelected }: { onItemSelected: () => void }) => { /> ) : null} - {pageElements} + + {pageElements} + ); }; From 8d78cf88f4946632ff4d0dca54c1ebe20c73469d Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Mon, 18 Nov 2024 16:07:55 +0530 Subject: [PATCH 04/15] remove old files --- .../IDE/Components/HeaderDropdown.test.tsx | 40 ------- .../src/IDE/Components/HeaderDropdown.tsx | 79 ------------- .../Components/HeaderEditorSwitcher.test.tsx | 105 ------------------ .../IDE/Components/HeaderEditorSwitcher.tsx | 73 ------------ 4 files changed, 297 deletions(-) delete mode 100644 app/client/src/IDE/Components/HeaderDropdown.test.tsx delete mode 100644 app/client/src/IDE/Components/HeaderDropdown.tsx delete mode 100644 app/client/src/IDE/Components/HeaderEditorSwitcher.test.tsx delete mode 100644 app/client/src/IDE/Components/HeaderEditorSwitcher.tsx diff --git a/app/client/src/IDE/Components/HeaderDropdown.test.tsx b/app/client/src/IDE/Components/HeaderDropdown.test.tsx deleted file mode 100644 index 647e2e7be5d9..000000000000 --- a/app/client/src/IDE/Components/HeaderDropdown.test.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React from "react"; -import { render } from "@testing-library/react"; -import HeaderDropdown from "./HeaderDropdown"; -import "@testing-library/jest-dom"; - -describe("HeaderDropdown", () => { - it("renders children components correctly", () => { - const { getByText } = render( - - - Header - - - Body - - , - ); - - expect(getByText("Header")).toBeInTheDocument(); - expect(getByText("Body")).toBeInTheDocument(); - }); - - it("applies custom className to the header", () => { - const customClass = "my-custom-class"; - const { container } = render( - - - Header - - - Body - - , - ); - - const headerElement = container.querySelector(`.${customClass}`); - - expect(headerElement).toBeInTheDocument(); - }); -}); diff --git a/app/client/src/IDE/Components/HeaderDropdown.tsx b/app/client/src/IDE/Components/HeaderDropdown.tsx deleted file mode 100644 index 28777fc3f80d..000000000000 --- a/app/client/src/IDE/Components/HeaderDropdown.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { Flex } from "@appsmith/ads"; -import React from "react"; -import styled from "styled-components"; - -const Container = styled(Flex)` - & .t--entity-item { - grid-template-columns: 0 auto 1fr auto auto auto auto auto; - height: 32px; - - & .t--entity-name { - padding-left: var(--ads-v2-spaces-3); - } - } -`; - -const HeaderWrapper = styled.div` - padding: var(--ads-v2-spaces-3); - padding-right: var(--ads-v2-spaces-2); - display: flex; - justify-content: space-between; - align-items: center; - height: 40px; - span { - line-height: 20px; - } -`; - -interface EditorHeaderDropdown { - children: React.ReactNode; -} - -interface EditorHeaderDropdownHeader { - children: React.ReactNode; - className?: string; -} - -interface EditorHeaderDropdownBody { - children: React.ReactNode; -} - -function EditorHeaderDropdown({ children }: EditorHeaderDropdown) { - return ( - - {children} - - ); -} - -function EditorHeaderDropdownHeader({ - children, - className, -}: EditorHeaderDropdownHeader) { - return {children}; -} - -function EditorHeaderDropdownBody({ children }: EditorHeaderDropdownBody) { - return ( - - {children} - - ); -} - -EditorHeaderDropdown.Header = EditorHeaderDropdownHeader; -EditorHeaderDropdown.Body = EditorHeaderDropdownBody; - -export default EditorHeaderDropdown; diff --git a/app/client/src/IDE/Components/HeaderEditorSwitcher.test.tsx b/app/client/src/IDE/Components/HeaderEditorSwitcher.test.tsx deleted file mode 100644 index e9bb49738823..000000000000 --- a/app/client/src/IDE/Components/HeaderEditorSwitcher.test.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import React from "react"; -import { render, fireEvent } from "@testing-library/react"; -import HeaderEditorSwitcher from "./HeaderEditorSwitcher"; -import "@testing-library/jest-dom"; - -describe("HeaderEditorSwitcher", () => { - const mockOnClick = jest.fn(); - const defaultProps = { - prefix: "Prefix", - title: "Title", - titleTestId: "titleTestId", - active: false, - onClick: mockOnClick, - }; - - it("renders with correct props", () => { - const { getByText } = render(); - - const testIdElement = document.getElementsByClassName( - defaultProps.titleTestId, - ); - - expect(getByText("Prefix /")).toBeInTheDocument(); - expect(getByText(defaultProps.title)).toBeInTheDocument(); - expect(testIdElement).toBeDefined(); - }); - - it("renders active state correctly", () => { - const { getByText } = render( - , - ); - - expect(getByText("Prefix /")).toHaveStyle( - "background-color: var(--ads-v2-color-bg-subtle)", - ); - }); - - it("calls onClick handler when clicked", () => { - const { getByText } = render(); - - fireEvent.click(getByText("Title")); - - expect(mockOnClick).toHaveBeenCalled(); - }); - - it("forwards ref correctly", () => { - const ref = React.createRef(); - - render(); - expect(ref.current).toBeTruthy(); - }); - - it("does not crash when onClick is not provided", () => { - const { getByText } = render( - , - ); - - fireEvent.click(getByText("Title")); // Should not throw error - }); - - it("does not show separator and applies different inactive color to icon", () => { - const ref = React.createRef(); - const { container, getByTestId } = render( - , - ); - - const icon = container.querySelector(".remixicon-icon"); // Get chevron icon - - expect(getByTestId("root-div")).toHaveTextContent("Prefix"); - expect(icon).toHaveAttribute( - "fill", - "var(--ads-v2-colors-content-label-inactive-fg)", - ); - }); - - it("forwards additional props correctly", () => { - const testId = "test-id"; - const className = "custom-class"; - - const { container } = render( - , - ); - - const firstDiv = container.querySelector("div"); // Get the first div element - const classNames = firstDiv?.getAttribute("class")?.split(" ") || []; - - expect(firstDiv).toHaveAttribute("data-testid", testId); // Check if data-testid prop is applied - expect(classNames).toContain(className); // Check if className prop is applied - expect(classNames).toContain("flex"); // Check if internal classes still exists - expect(classNames).toContain("align-center"); // Check if internal classes still exists - expect(classNames).toContain("justify-center"); // Check if internal classes still exists - }); -}); diff --git a/app/client/src/IDE/Components/HeaderEditorSwitcher.tsx b/app/client/src/IDE/Components/HeaderEditorSwitcher.tsx deleted file mode 100644 index a7baa0744264..000000000000 --- a/app/client/src/IDE/Components/HeaderEditorSwitcher.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { Flex, Icon, Text } from "@appsmith/ads"; -import React from "react"; -import styled from "styled-components"; - -interface HeaderEditorSwitcherProps { - prefix: string; - title?: string; - titleTestId: string; - active: boolean; - onClick?: React.MouseEventHandler; - className?: string; -} - -const SwitchTrigger = styled.div<{ active: boolean }>` - border-radius: var(--ads-v2-border-radius); - background-color: ${(props) => - props.active ? `var(--ads-v2-color-bg-subtle)` : "unset"}; - cursor: pointer; - padding: var(--ads-v2-spaces-2); - :hover { - background-color: var(--ads-v2-color-bg-subtle); - } -`; - -const HeaderEditorSwitcher = React.forwardRef( - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (props: HeaderEditorSwitcherProps, ref: any) => { - const { active, className, prefix, title, titleTestId, ...rest } = props; - - const separator = title ? " /" : ""; - - return ( - - - {prefix + separator} - - - - {title} - - - - - ); - }, -); - -export default HeaderEditorSwitcher; From 40775919a5d93d99ffcf55b29754e25b255229de Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Wed, 20 Nov 2024 18:33:39 +0530 Subject: [PATCH 05/15] Create story --- .../ads/src/Layout/EntityExplorer/index.ts | 2 +- .../ads/src/Layout/EntityExplorer/styles.ts | 13 +++ .../HeaderDropdown/HeaderDropdown.styles.ts | 13 --- .../HeaderDropdown/HeaderDropdown.test.tsx | 41 ------- .../HeaderDropdown/HeaderDropdown.tsx | 58 ---------- .../Layout/IDEHeader/HeaderDropdown/index.ts | 1 - .../HeaderSwitcher/HeaderSwitcher.styles.ts | 8 ++ ...tcher.test.tsx => HeaderSwitcher.test.tsx} | 5 +- .../HeaderSwitcher/IDEHeaderSwitcher.tsx | 103 +++++++++++------- .../ads/src/Layout/IDEHeader/IDEHeader.mdx | 28 +++++ .../Layout/IDEHeader/IDEHeader.stories.tsx | 101 +++++++++++++++++ .../ads/src/Layout/IDEHeader/IDEHeader.tsx | 5 +- .../ads/src/Layout/IDEHeader/index.ts | 8 -- .../Editor/IDE/EditorPane/PagesSection.tsx | 35 ++++-- .../pages/Editor/IDE/Header/EditorTitle.tsx | 39 +++---- 15 files changed, 262 insertions(+), 198 deletions(-) delete mode 100644 app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.styles.ts delete mode 100644 app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.test.tsx delete mode 100644 app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.tsx delete mode 100644 app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/index.ts rename app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/{HeaderEditorSwitcher.test.tsx => HeaderSwitcher.test.tsx} (96%) create mode 100644 app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.mdx create mode 100644 app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.stories.tsx diff --git a/app/client/packages/design-system/ads/src/Layout/EntityExplorer/index.ts b/app/client/packages/design-system/ads/src/Layout/EntityExplorer/index.ts index b560fb716f49..a0696c71028e 100644 --- a/app/client/packages/design-system/ads/src/Layout/EntityExplorer/index.ts +++ b/app/client/packages/design-system/ads/src/Layout/EntityExplorer/index.ts @@ -1 +1 @@ -export { ListItemContainer } from "./styles"; +export { ListItemContainer, ListHeaderContainer } from "./styles"; diff --git a/app/client/packages/design-system/ads/src/Layout/EntityExplorer/styles.ts b/app/client/packages/design-system/ads/src/Layout/EntityExplorer/styles.ts index 0b2455da723b..235f18bbe26b 100644 --- a/app/client/packages/design-system/ads/src/Layout/EntityExplorer/styles.ts +++ b/app/client/packages/design-system/ads/src/Layout/EntityExplorer/styles.ts @@ -11,3 +11,16 @@ export const ListItemContainer = styled(Flex)` } } `; + +export const ListHeaderContainer = styled.div` + padding: var(--ads-v2-spaces-3); + padding-right: var(--ads-v2-spaces-2); + display: flex; + justify-content: space-between; + align-items: center; + height: 40px; + + span { + line-height: 20px; + } +`; diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.styles.ts b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.styles.ts deleted file mode 100644 index 27b2927809d2..000000000000 --- a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.styles.ts +++ /dev/null @@ -1,13 +0,0 @@ -import styled from "styled-components"; - -export const HeaderWrapper = styled.div` - padding: var(--ads-v2-spaces-3); - padding-right: var(--ads-v2-spaces-2); - display: flex; - justify-content: space-between; - align-items: center; - height: 40px; - span { - line-height: 20px; - } -`; diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.test.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.test.tsx deleted file mode 100644 index 2085669f4cfa..000000000000 --- a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.test.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React from "react"; -import { render, screen } from "@testing-library/react"; -import { IDEHeaderDropdown } from "./HeaderDropdown"; -import "@testing-library/jest-dom"; - -describe("HeaderDropdown", () => { - it("renders children components correctly", () => { - render( - - - Header - - - Body - - , - ); - - expect(screen.getByText("Header")).toBeInTheDocument(); - expect(screen.getByText("Body")).toBeInTheDocument(); - }); - - it("applies custom className to the header", () => { - const customClass = "my-custom-class"; - const { container } = render( - - - Header - - - Body - - , - ); - - // eslint-disable-next-line testing-library/no-node-access,testing-library/no-container - const headerElement = container.querySelector(`.${customClass}`); - - expect(headerElement).toBeInTheDocument(); - }); -}); diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.tsx deleted file mode 100644 index 9978edca6883..000000000000 --- a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/HeaderDropdown.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Flex } from "../../../Flex"; -import React from "react"; -import * as Styled from "./styles"; - -interface EditorHeaderDropdown { - children: React.ReactNode; -} - -interface EditorHeaderDropdownHeader { - children: React.ReactNode; - className?: string; -} - -interface EditorHeaderDropdownBody { - children: React.ReactNode; -} - -export function IDEHeaderDropdown({ children }: EditorHeaderDropdown) { - return ( - - {children} - - ); -} - -function IDEHeaderDropdownHeader({ - children, - className, -}: EditorHeaderDropdownHeader) { - return ( - - {children} - - ); -} - -function IDEHeaderDropdownBody({ children }: EditorHeaderDropdownBody) { - return ( - - {children} - - ); -} - -IDEHeaderDropdown.Header = IDEHeaderDropdownHeader; -IDEHeaderDropdown.Body = IDEHeaderDropdownBody; diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/index.ts b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/index.ts deleted file mode 100644 index 07bf361f42e0..000000000000 --- a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderDropdown/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { IDEHeaderDropdown } from "./HeaderDropdown"; diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.styles.ts b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.styles.ts index e9a73e15b4a8..06309d2d20cf 100644 --- a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.styles.ts +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.styles.ts @@ -1,12 +1,20 @@ import styled from "styled-components"; +import { PopoverContent } from "../../../Popover"; export const SwitchTrigger = styled.div<{ active: boolean }>` + display: flex; border-radius: var(--ads-v2-border-radius); background-color: ${(props) => props.active ? `var(--ads-v2-color-bg-subtle)` : "unset"}; cursor: pointer; padding: var(--ads-v2-spaces-2); + :hover { background-color: var(--ads-v2-color-bg-subtle); } `; + +export const ContentContainer = styled(PopoverContent)` + padding: 0; + padding-bottom: 0.25em; +`; diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderEditorSwitcher.test.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.test.tsx similarity index 96% rename from app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderEditorSwitcher.test.tsx rename to app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.test.tsx index 2663d7e15bf9..fbc180b6b5a9 100644 --- a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderEditorSwitcher.test.tsx +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/HeaderSwitcher.test.tsx @@ -3,14 +3,16 @@ import { render, fireEvent, screen } from "@testing-library/react"; import { IDEHeaderSwitcher } from "./IDEHeaderSwitcher"; import "@testing-library/jest-dom"; -describe("HeaderEditorSwitcher", () => { +describe("HeaderSwitcher", () => { const mockOnClick = jest.fn(); + const mockSetActive = jest.fn(); const defaultProps = { prefix: "Prefix", title: "Title", titleTestId: "titleTestId", active: false, onClick: mockOnClick, + setActive: mockSetActive, }; it("renders with correct props", () => { @@ -86,6 +88,7 @@ describe("HeaderEditorSwitcher", () => { className={className} data-testid={testId} // Additional prop prefix="Prefix" + setActive={mockSetActive} title="Title" titleTestId="titleTestId" />, diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/IDEHeaderSwitcher.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/IDEHeaderSwitcher.tsx index 34e6e8c1f921..9efeeb5dbc46 100644 --- a/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/IDEHeaderSwitcher.tsx +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/HeaderSwitcher/IDEHeaderSwitcher.tsx @@ -1,58 +1,83 @@ -import { Flex, Icon, Text } from "../../../index"; -import React, { type ForwardedRef } from "react"; -import * as Styled from "./styles"; +import React, { type ForwardedRef, useCallback } from "react"; +import { Flex } from "../../../Flex"; +import { Icon } from "../../../Icon"; +import { Popover, PopoverTrigger } from "../../../Popover"; +import { Text } from "../../../Text"; +import * as Styled from "./HeaderSwitcher.styles"; interface Props { prefix: string; title?: string; titleTestId: string; active: boolean; + setActive: (active: boolean) => void; onClick?: React.MouseEventHandler; className?: string; + children: React.ReactNode; } export const IDEHeaderSwitcher = React.forwardRef( (props: Props, ref: ForwardedRef) => { - const { active, className, prefix, title, titleTestId, ...rest } = props; + const { + active, + children, + className, + onClick, + prefix, + setActive, + title, + titleTestId, + } = props; const separator = title ? " /" : ""; + const closeSwitcher = useCallback(() => { + return setActive(false); + }, [setActive]); + return ( - - - {prefix + separator} - - - - {title} - - - - + + + + + {prefix + separator} + + + + {title} + + + + + + + {children} + + ); }, ); diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.mdx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.mdx new file mode 100644 index 000000000000..37c3900615a3 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.mdx @@ -0,0 +1,28 @@ +import { Canvas, Meta } from "@storybook/blocks"; +import * as IDEHeaderStories from "./IDEHeader.stories"; + + + +# IDEHeader + +IDEHeader sets the stage for the IDE experience. It is the topmost section of the IDE that contains the Appsmith logo, the app name, and the user profile. + + + +## Anatomy + +### Left Section options + +The local title + +#### Header Title + +A title that is specific to the app state. It is displayed on the left side of the header. + + + +#### Header Dropdown + +A dropdown that allows the user to switch between different pages. + + diff --git a/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.stories.tsx b/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.stories.tsx new file mode 100644 index 000000000000..df32e4991ff3 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Layout/IDEHeader/IDEHeader.stories.tsx @@ -0,0 +1,101 @@ +import React from "react"; +import type { Meta } from "@storybook/react"; +import { IDEHeader } from "./IDEHeader"; +import { IDEHeaderTitle } from "./IDEHeaderTitle"; +import { IDEHeaderSwitcher } from "./HeaderSwitcher"; +import { noop } from "lodash"; +import { Icon } from "../../Icon"; +import { Button } from "../../Button"; +import { List } from "../../List"; +import { Flex } from "../../Flex"; +import { Text } from "../../Text"; +import { ListHeaderContainer } from "../EntityExplorer/styles"; + +const meta: Meta = { + title: "ADS/Templates/IDEHeader", + component: IDEHeader, + parameters: { + layout: "fullscreen", + }, + decorators: [ + (Story: () => React.ReactNode) => ( +
{Story()}
+ ), + ], +}; + +export default meta; + +export const Default = () => ( + + }> + Left Content + + + Center Content + + + Right Content + + +); + +export const WithHeaderTitle = () => { + return ( + + }> + + + + + + ); +}; + +export const WithHeaderDropdown = () => { + const [open, setOpen] = React.useState(false); + + return ( + + }> + + + + Pages +