chore: Updating List item and List components in ADS to start using it in Entity explorer (#38344)
This commit is contained in:
parent
aaabb154f8
commit
2246bde9bb
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { List, ListItem, Icon } from "@appsmith/ads";
|
||||
import { List, ListItem, Icon, Button } from "@appsmith/ads";
|
||||
import type { StoryObj } from "@storybook/react";
|
||||
import type { ListItemProps, ListProps } from "@appsmith/ads";
|
||||
|
||||
|
|
@ -79,15 +79,21 @@ const ListItemArgTypes = {
|
|||
},
|
||||
},
|
||||
},
|
||||
endIcon: {
|
||||
control: "text",
|
||||
description: "The icon to display at the end of the list item",
|
||||
rightControl: {
|
||||
description: "The control to display at the end of the list item",
|
||||
table: {
|
||||
type: {
|
||||
summary: "string",
|
||||
summary: "ReactNode",
|
||||
},
|
||||
},
|
||||
},
|
||||
rightControlVisibility: {
|
||||
description:
|
||||
"`always` type will show the right control always. `hover` type will show the right control only when the list item is hovered.",
|
||||
control: "radio",
|
||||
options: ["always", "hover"],
|
||||
defaultValue: "always",
|
||||
},
|
||||
description: {
|
||||
control: "text",
|
||||
description: "Description text to be shown alongside the title",
|
||||
|
|
@ -140,11 +146,12 @@ const ListItemArgTypes = {
|
|||
},
|
||||
},
|
||||
},
|
||||
onEndIconClick: {
|
||||
description: "callback for when the end icon is clicked",
|
||||
customTitleComponent: {
|
||||
description:
|
||||
"A custom title component for the list item to use input component for name editing",
|
||||
table: {
|
||||
type: {
|
||||
summary: "() => void",
|
||||
summary: "ReactNode",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -163,7 +170,7 @@ ListItemLargeStory.args = {
|
|||
description: "inline",
|
||||
descriptionType: "inline",
|
||||
size: "lg",
|
||||
endIcon: "add-more",
|
||||
rightControl: <Icon name="add-more" size={"md"} />,
|
||||
};
|
||||
|
||||
export const ListItemErrorStory = ListItemTemplate.bind({}) as StoryObj;
|
||||
|
|
@ -215,10 +222,12 @@ ListItemOverflowStory.args = {
|
|||
title: "Action item 1 Action item 1 Action item 1 Action item 1",
|
||||
};
|
||||
|
||||
export const ListItemEndIconStory = ListItemTemplate.bind({}) as StoryObj;
|
||||
ListItemEndIconStory.storyName = "List item end icon";
|
||||
ListItemEndIconStory.argTypes = ListItemArgTypes;
|
||||
ListItemEndIconStory.args = {
|
||||
export const ListItemRightControlStory = ListItemTemplate.bind({}) as StoryObj;
|
||||
ListItemRightControlStory.storyName = "List item right control";
|
||||
ListItemRightControlStory.argTypes = ListItemArgTypes;
|
||||
ListItemRightControlStory.args = {
|
||||
title: "Action item 1",
|
||||
endIcon: "add-more",
|
||||
rightControl: (
|
||||
<Button isIconButton kind="tertiary" size={"sm"} startIcon="add-more" />
|
||||
),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,47 +26,15 @@ const Sizes = {
|
|||
`,
|
||||
};
|
||||
|
||||
export const StyledList = styled.div`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding: var(--ads-v2-spaces-1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--ads-v2-spaces-2);
|
||||
`;
|
||||
|
||||
export const Wrapper = styled.div`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
gap: var(--ads-v2-spaces-3);
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
export const TooltipTextWrapper = styled.div`
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
`;
|
||||
|
||||
export const ContentWrapper = styled.div`
|
||||
display: flex;
|
||||
gap: var(--ads-v2-spaces-3);
|
||||
`;
|
||||
|
||||
export const ContentTextWrapper = styled.div`
|
||||
display: flex;
|
||||
gap: var(--ads-v2-spaces-3);
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
`;
|
||||
|
||||
export const DescriptionWrapper = styled.div`
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
gap: var(--ads-v2-spaces-3);
|
||||
gap: var(--ads-v2-spaces-2);
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
|
|
@ -74,34 +42,24 @@ export const InlineDescriptionWrapper = styled.div`
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
gap: var(--ads-v2-spaces-3);
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
`;
|
||||
|
||||
export const EndIconWrapper = styled.div`
|
||||
position: absolute;
|
||||
right: var(--ads-v2-spaces-3);
|
||||
export const RightControlWrapper = styled.div`
|
||||
height: 100%;
|
||||
line-height: normal;
|
||||
`;
|
||||
|
||||
export const StyledListItem = styled.div<{
|
||||
size: ListSizes;
|
||||
endIcon?: string;
|
||||
isBlockDescription: boolean;
|
||||
}>`
|
||||
${Variables};
|
||||
|
||||
export const ContentTextWrapper = styled.div`
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
border-radius: var(--ads-v2-border-radius);
|
||||
padding: var(--ads-v2-spaces-3);
|
||||
box-sizing: border-box;
|
||||
// 40px is the offset to make it look like the end icon is part of this div
|
||||
${(props) => !!props.endIcon && `padding: 8px 40px 8px 8px;`}}
|
||||
|
||||
${({ size }) => Sizes[size]}
|
||||
|
||||
gap: var(--ads-v2-spaces-3);
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
& .${ListItemTextOverflowClassName} {
|
||||
overflow: hidden;
|
||||
|
|
@ -115,7 +73,7 @@ export const StyledListItem = styled.div<{
|
|||
}
|
||||
|
||||
& .${ListItemBDescClassName} {
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-line-clamp: 1;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
text-overflow: initial;
|
||||
|
|
@ -126,14 +84,53 @@ export const StyledListItem = styled.div<{
|
|||
|
||||
& .${ListItemIDescClassName} {
|
||||
font-size: var(--listitem-idescription-font-size);
|
||||
line-height: 16px;
|
||||
padding-right: var(--ads-v2-spaces-2);
|
||||
}
|
||||
`;
|
||||
|
||||
export const StyledList = styled.div`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
padding: var(--ads-v2-spaces-1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--ads-v2-spaces-2);
|
||||
`;
|
||||
|
||||
export const StyledListItem = styled.div<{
|
||||
size: ListSizes;
|
||||
}>`
|
||||
${Variables};
|
||||
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
border-radius: var(--ads-v2-border-radius);
|
||||
padding: var(--ads-v2-spaces-2);
|
||||
padding-left: var(--ads-v2-spaces-3);
|
||||
|
||||
${({ size }) => Sizes[size]}
|
||||
|
||||
&[data-isblockdescription="true"] {
|
||||
height: 54px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--ads-v2-colors-content-surface-hover-bg);
|
||||
&[data-isblockdescription="false"] {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--ads-v2-colors-content-surface-active-bg);
|
||||
&[data-rightcontrolvisibility="hover"] {
|
||||
${RightControlWrapper} {
|
||||
display: none;
|
||||
}
|
||||
&:hover ${RightControlWrapper} {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&[data-selected="true"] {
|
||||
|
|
@ -144,6 +141,15 @@ export const StyledListItem = styled.div<{
|
|||
&[data-disabled="true"] {
|
||||
cursor: not-allowed;
|
||||
opacity: var(--ads-v2-opacity-disabled);
|
||||
background-color: var(--ads-v2-colors-content-surface-default-bg);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--ads-v2-colors-content-surface-hover-bg);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--ads-v2-colors-content-surface-active-bg);
|
||||
}
|
||||
|
||||
/* Focus styles */
|
||||
|
|
|
|||
|
|
@ -5,16 +5,14 @@ import type { ListItemProps, ListProps } from "./List.types";
|
|||
import {
|
||||
ContentTextWrapper,
|
||||
DescriptionWrapper,
|
||||
EndIconWrapper,
|
||||
InlineDescriptionWrapper,
|
||||
RightControlWrapper,
|
||||
StyledList,
|
||||
StyledListItem,
|
||||
TooltipTextWrapper,
|
||||
Wrapper,
|
||||
} from "./List.styles";
|
||||
import type { TextProps } from "../Text";
|
||||
import { Text } from "../Text";
|
||||
import { Button } from "../Button";
|
||||
import { Tooltip } from "../Tooltip";
|
||||
import {
|
||||
ListClassName,
|
||||
|
|
@ -23,7 +21,6 @@ import {
|
|||
ListItemIDescClassName,
|
||||
ListItemTextOverflowClassName,
|
||||
ListItemTitleClassName,
|
||||
ListItemWrapperClassName,
|
||||
} from "./List.constants";
|
||||
|
||||
function List({ className, items, ...rest }: ListProps) {
|
||||
|
|
@ -85,8 +82,9 @@ function ListItem(props: ListItemProps) {
|
|||
const {
|
||||
description,
|
||||
descriptionType = "inline",
|
||||
endIcon,
|
||||
hasError,
|
||||
rightControl,
|
||||
rightControlVisibility = "always",
|
||||
size = "md",
|
||||
startIcon,
|
||||
title,
|
||||
|
|
@ -104,27 +102,6 @@ function ListItem(props: ListItemProps) {
|
|||
}
|
||||
};
|
||||
|
||||
const endIconhandleKeyDown = (e: React.KeyboardEvent) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (!props.isDisabled && props.onEndIconClick) {
|
||||
switch (e.key) {
|
||||
case "Enter":
|
||||
case " ":
|
||||
props.onEndIconClick();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const endIconOnClick = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (!props.isDisabled && props.onEndIconClick) {
|
||||
props.onEndIconClick();
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnClick = () => {
|
||||
if (!props.isDisabled && props.onClick) {
|
||||
props.onClick();
|
||||
|
|
@ -132,20 +109,23 @@ function ListItem(props: ListItemProps) {
|
|||
};
|
||||
|
||||
return (
|
||||
<Wrapper className={clsx(ListItemWrapperClassName, props.wrapperClassName)}>
|
||||
<StyledListItem
|
||||
className={clsx(ListItemClassName, props.className)}
|
||||
data-disabled={props.isDisabled || false}
|
||||
data-isblockdescription={isBlockDescription}
|
||||
data-rightcontrolvisibility={rightControlVisibility}
|
||||
data-selected={props.isSelected}
|
||||
endIcon={props.endIcon}
|
||||
isBlockDescription={isBlockDescription}
|
||||
onClick={handleOnClick}
|
||||
onKeyDown={listItemhandleKeyDown}
|
||||
size={size}
|
||||
tabIndex={props.isDisabled ? -1 : 0}
|
||||
>
|
||||
<ContentTextWrapper>
|
||||
<ContentTextWrapper
|
||||
onClick={handleOnClick}
|
||||
onKeyDown={listItemhandleKeyDown}
|
||||
>
|
||||
{startIcon}
|
||||
{props.customTitleComponent ? (
|
||||
props.customTitleComponent
|
||||
) : (
|
||||
<InlineDescriptionWrapper>
|
||||
<DescriptionWrapper>
|
||||
<TextWithTooltip
|
||||
|
|
@ -175,22 +155,12 @@ function ListItem(props: ListItemProps) {
|
|||
</TextWithTooltip>
|
||||
)}
|
||||
</InlineDescriptionWrapper>
|
||||
</ContentTextWrapper>
|
||||
</StyledListItem>
|
||||
{endIcon && (
|
||||
<EndIconWrapper>
|
||||
<Button
|
||||
isDisabled={props.isDisabled}
|
||||
isIconButton
|
||||
kind="tertiary"
|
||||
onClick={endIconOnClick}
|
||||
onKeyDown={endIconhandleKeyDown}
|
||||
size={"sm"}
|
||||
startIcon={endIcon}
|
||||
/>
|
||||
</EndIconWrapper>
|
||||
)}
|
||||
</Wrapper>
|
||||
</ContentTextWrapper>
|
||||
{rightControl && (
|
||||
<RightControlWrapper>{rightControl}</RightControlWrapper>
|
||||
)}
|
||||
</StyledListItem>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ export type ListSizes = Extract<Sizes, "md" | "lg">;
|
|||
export interface ListItemProps {
|
||||
/** The icon to display before the list item title. */
|
||||
startIcon?: ReactNode;
|
||||
/** The icon to display at the end. Pass name of the icon from remix-icon library(eg: home-2-line) or an svg icon. */
|
||||
endIcon?: string;
|
||||
/** callback for when the endIcon is clicked */
|
||||
onEndIconClick?: () => void;
|
||||
/** The control to display at the end. */
|
||||
rightControl?: ReactNode;
|
||||
/** */
|
||||
rightControlVisibility?: "hover" | "always";
|
||||
/** callback for when the list item is clicked */
|
||||
onClick: () => void;
|
||||
/** Whether the list item is disabled. */
|
||||
|
|
@ -23,17 +23,17 @@ export interface ListItemProps {
|
|||
/** The title/label of the list item */
|
||||
title: string;
|
||||
/** Description text to be shown alongside the title */
|
||||
description: string;
|
||||
description?: string;
|
||||
/** `inline` type will show the description beside the title. `block` type will show the description
|
||||
* below the title.
|
||||
*/
|
||||
descriptionType: "inline" | "block";
|
||||
descriptionType?: "inline" | "block";
|
||||
/** class names for the list item */
|
||||
className?: string;
|
||||
/** class names for the wrapper */
|
||||
wrapperClassName?: string;
|
||||
/** id for the list item */
|
||||
id?: string;
|
||||
/** customTitleComponent for the list item to use input component for name editing */
|
||||
customTitleComponent?: ReactNode | ReactNode[];
|
||||
}
|
||||
|
||||
export interface ListProps {
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ export const useAddQueryListItems = () => {
|
|||
|
||||
return {
|
||||
startIcon: icon,
|
||||
wrapperClassName: className,
|
||||
className: className,
|
||||
title,
|
||||
description:
|
||||
fileOperation.focusEntityType === FocusEntity.QUERY_MODULE_INSTANCE
|
||||
|
|
|
|||
|
|
@ -266,8 +266,8 @@ export { EntityIcon };
|
|||
// fontSize is set to 56% by default.
|
||||
export function ApiMethodIcon(
|
||||
type: keyof typeof HTTP_METHOD,
|
||||
height = "18px",
|
||||
width = "36px",
|
||||
height = "16px",
|
||||
width = "34px",
|
||||
fontSize = 52,
|
||||
) {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ const AddJS = () => {
|
|||
: "",
|
||||
descriptionType: "inline",
|
||||
onClick: onCreateItemClick.bind(null, data),
|
||||
wrapperClassName: createAddClassName(title),
|
||||
className: createAddClassName(title),
|
||||
} as ListItemProps;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ const StyledList = styled(List)`
|
|||
& .ds-load-more .ads-v2-listitem__title {
|
||||
--color: var(--ads-v2-color-fg-subtle);
|
||||
}
|
||||
& .ads-v2-listitem__wrapper .ads-v2-listitem__idesc {
|
||||
& .ads-v2-listitem .ads-v2-listitem__idesc {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
& .ads-v2-listitem__wrapper:hover .ads-v2-listitem__idesc {
|
||||
& .ads-v2-listitem:hover .ads-v2-listitem__idesc {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user