Skip to content

Commit

Permalink
Merge branch 'appsmithorg:release' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
hajrezvan authored Jan 26, 2025
2 parents 4c75d46 + da449ee commit bbcc8a0
Show file tree
Hide file tree
Showing 136 changed files with 2,121 additions and 838 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* eslint-disable no-console */
import type { Meta, StoryObj } from "@storybook/react";

import { DismissibleTab } from ".";

const meta: Meta<typeof DismissibleTab> = {
title: "ADS/Components/Dismissible Tab",
component: DismissibleTab,
};

export default meta;

type Story = StoryObj<typeof DismissibleTab>;

export const Basic: Story = {
args: {
isActive: true,
dataTestId: "t--dismissible-tab",
children: "Dismissible tab",
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import styled from "styled-components";

import { Button as ADSButton } from "..";

export const Tab = styled.div`
position: relative;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
gap: var(--ads-v2-spaces-2);
height: 100%;
font-size: 12px;
color: var(--ads-v2-color-fg);
cursor: pointer;
border-top-left-radius: var(--ads-v2-border-radius);
border-top-right-radius: var(--ads-v2-border-radius);
border-left: 1px solid transparent;
border-right: 1px solid transparent;
border-top: 3px solid transparent;
padding: var(--ads-v2-spaces-3);
padding-top: 6px;
&.active {
background: var(--ads-v2-colors-control-field-default-bg);
border-top-color: var(--ads-v2-color-bg-brand);
border-left-color: var(--ads-v2-color-border-muted);
border-right-color: var(--ads-v2-color-border-muted);
span {
font-weight: var(--ads-v2-font-weight-bold);
}
}
& > .tab-close {
opacity: 0;
transition: opacity 0.2s ease;
}
&:hover > .tab-close,
&:focus-within > .tab-close,
&.active > .tab-close {
opacity: 1;
}
`;

export const CloseButton = styled(ADSButton)`
border-radius: 2px;
cursor: pointer;
padding: var(--ads-v2-spaces-1);
max-width: 16px;
max-height: 16px;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from "react";

import clsx from "classnames";

import { Icon } from "..";

import * as Styled from "./DismissibleTab.styles";
import { DATA_TEST_ID } from "./constants";

import type { DismissibleTabProps } from "./DismissibleTab.types";

export const DismissibleTab = ({
children,
dataTestId,
isActive,
onClick,
onClose,
onDoubleClick,
}: DismissibleTabProps) => {
return (
<Styled.Tab
className={clsx("editor-tab", isActive && "active")}
data-testid={dataTestId}
onClick={onClick}
onDoubleClick={onDoubleClick}
>
{children}
<Styled.CloseButton
aria-label="Close tab"
className="tab-close"
data-testid={DATA_TEST_ID.CLOSE_BUTTON}
isIconButton
kind="tertiary"
onClick={onClose}
role="tab"
size="sm"
tabIndex={0}
>
<Icon name="close-line" />
</Styled.CloseButton>
</Styled.Tab>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type React from "react";

export interface DismissibleTabProps {
children: React.ReactNode;
dataTestId?: string;
isActive: boolean;
onClick: () => void;
onClose: (e: React.MouseEvent) => void;
onDoubleClick?: () => void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const DATA_TEST_ID = {
CLOSE_BUTTON: "t--tab-close-btn",
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { DismissibleTab } from "./DismissibleTab";
export type { DismissibleTabProps } from "./DismissibleTab.types";
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-disable no-console */
import React from "react";
import type { Meta, StoryObj } from "@storybook/react";

import { EditableDismissibleTab } from ".";
import styled from "styled-components";

import { Icon } from "../..";

const meta: Meta<typeof EditableDismissibleTab> = {
title: "ADS/Templates/Editable Dismissible Tab",
component: EditableDismissibleTab,
};

const EntityIcon = styled.div`
height: 18px;
width: 18px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
svg,
img {
height: 100%;
width: 100%;
}
`;

const JSIcon = () => {
return (
<EntityIcon>
<Icon name="js-yellow" size="md" />
</EntityIcon>
);
};

export default meta;

type Story = StoryObj<typeof EditableDismissibleTab>;

export const Basic: Story = {
args: {
isActive: true,
dataTestId: "t--dismissible-tab",
icon: JSIcon(),
name: "Hello",

onNameSave: console.log,
validateName: (name: string) =>
name.length < 3 ? "Name must be at least 3 characters" : null,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from "react";
import { noop } from "lodash";
import { useBoolean } from "usehooks-ts";

import { DismissibleTab } from "../..";
import { EditableEntityName } from "..";

import type { EditableDismissibleTabProps } from "./EditableDismissibleTab.types";

export const EditableDismissibleTab = (props: EditableDismissibleTabProps) => {
const {
dataTestId,
icon,
isActive,
isEditable = true,
isLoading,
name,
onClick,
onClose,
onNameSave,
validateName,
} = props;

const {
setFalse: exitEditMode,
setTrue: enterEditMode,
value: isEditing,
} = useBoolean(false);

const handleDoubleClick = isEditable ? enterEditMode : noop;

return (
<DismissibleTab
dataTestId={dataTestId}
isActive={isActive}
onClick={onClick}
onClose={onClose}
onDoubleClick={handleDoubleClick}
>
<EditableEntityName
icon={icon}
isEditing={isEditing}
isLoading={isLoading}
name={name}
onExitEditing={exitEditMode}
onNameSave={onNameSave}
validateName={validateName}
/>
</DismissibleTab>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type React from "react";

export interface EditableDismissibleTabProps {
dataTestId?: string;
icon: React.ReactNode;
isActive: boolean;
isEditable?: boolean;
isLoading: boolean;
name: string;
onClick: () => void;
onClose: () => void;
onNameSave: (name: string) => void;
validateName: (name: string) => string | null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { EditableDismissibleTab } from "./EditableDismissibleTab";
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-disable no-console */
import React from "react";
import type { Meta, StoryObj } from "@storybook/react";
import styled from "styled-components";

import { Icon } from "../..";
import { EditableEntityName } from ".";

const EntityIcon = styled.div`
height: 18px;
width: 18px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
svg,
img {
height: 100%;
width: 100%;
}
`;

const JSIcon = () => {
return (
<EntityIcon>
<Icon name="js-yellow" size="md" />
</EntityIcon>
);
};

const meta: Meta<typeof EditableEntityName> = {
title: "ADS/Templates/Editable Entity Name",
component: EditableEntityName,
};

export default meta;

type Story = StoryObj<typeof EditableEntityName>;

export const Basic: Story = {
args: {
name: "Hello",
onNameSave: console.log,
onExitEditing: console.log,
icon: JSIcon(),
inputTestId: "t--editable-name",
isEditing: true,
isLoading: false,
validateName: (name: string) =>
name.length < 3 ? "Name must be at least 3 characters" : null,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import styled from "styled-components";
import { Text as ADSText } from "../../Text";

export const Root = styled.div`
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: start;
align-items: center;
gap: var(--ads-v2-spaces-2);
`;

export const Text = styled(ADSText)`
min-width: 3ch;
bottom: -0.5px;
`;

export const IconContainer = styled.div`
height: 12px;
width: 12px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
img {
width: 12px;
}
`;
Loading

0 comments on commit bbcc8a0

Please sign in to comment.