diff --git a/apps/website/screens/components/dropdown/code/DropdownCodePage.tsx b/apps/website/screens/components/dropdown/code/DropdownCodePage.tsx
index 919696722..db39ff7f6 100644
--- a/apps/website/screens/components/dropdown/code/DropdownCodePage.tsx
+++ b/apps/website/screens/components/dropdown/code/DropdownCodePage.tsx
@@ -184,6 +184,17 @@ const sections = [
0
+
+ title
+
+ string
+
+
+ Text representing advisory information related to the dropdown's trigger action. Under the hood, this
+ prop also serves as an accessible label for the component.
+
+ -
+
>
diff --git a/apps/website/screens/components/heading/usage/HeadingUsagePage.tsx b/apps/website/screens/components/heading/usage/HeadingUsagePage.tsx
index 8fc8359fe..93e8fcd15 100644
--- a/apps/website/screens/components/heading/usage/HeadingUsagePage.tsx
+++ b/apps/website/screens/components/heading/usage/HeadingUsagePage.tsx
@@ -39,7 +39,7 @@ const sections = [
<>
- Use Heading componments from H1 to H5 when creating content
+ Use Heading components from H1 to H5 when creating content
hierarchy in the page.
diff --git a/apps/website/screens/principles/themes/ThemesPage.tsx b/apps/website/screens/principles/themes/ThemesPage.tsx
index d01a1c452..52ef41982 100644
--- a/apps/website/screens/principles/themes/ThemesPage.tsx
+++ b/apps/website/screens/principles/themes/ThemesPage.tsx
@@ -978,6 +978,9 @@ const sections = [
Option font color
listOptionFontColor
+
+
+ listOptionIconColor
diff --git a/packages/lib/src/HalstackContext.tsx b/packages/lib/src/HalstackContext.tsx
index a326b9f80..d99ade814 100644
--- a/packages/lib/src/HalstackContext.tsx
+++ b/packages/lib/src/HalstackContext.tsx
@@ -255,6 +255,7 @@ const parseTheme = (theme: DeepPartial): AdvancedTheme => {
selectTokens.labelFontColor = theme?.select?.fontColor ?? selectTokens.labelFontColor;
selectTokens.helperTextFontColor = theme?.select?.fontColor ?? selectTokens.helperTextFontColor;
selectTokens.listOptionFontColor = theme?.select?.optionFontColor ?? selectTokens.listOptionFontColor;
+ selectTokens.listOptionIconColor = theme?.select?.optionFontColor ?? selectTokens.listOptionIconColor;
selectTokens.placeholderFontColor = addLightness(30, theme?.select?.fontColor) ?? selectTokens.placeholderFontColor;
selectTokens.collapseIndicatorColor = theme?.select?.fontColor ?? selectTokens.collapseIndicatorColor;
selectTokens.hoverInputBorderColor = theme?.select?.hoverBorderColor ?? selectTokens.hoverInputBorderColor;
diff --git a/packages/lib/src/action-icon/ActionIcon.tsx b/packages/lib/src/action-icon/ActionIcon.tsx
index df0da9a91..dcbbb7726 100644
--- a/packages/lib/src/action-icon/ActionIcon.tsx
+++ b/packages/lib/src/action-icon/ActionIcon.tsx
@@ -3,28 +3,26 @@ import ActionIconPropsTypes, { RefType } from "./types";
import styled from "styled-components";
import CoreTokens from "../common/coreTokens";
import DxcIcon from "../icon/Icon";
-import DxcTooltip from "../tooltip/Tooltip";
+import { Tooltip } from "../tooltip/Tooltip";
const DxcActionIcon = forwardRef(
- ({ disabled = false, title, icon, onClick, tabIndex }, ref): JSX.Element => {
- return (
-
- {
- event.stopPropagation();
- }}
- tabIndex={tabIndex}
- type="button"
- ref={ref}
- >
- {typeof icon === "string" ? : icon}
-
-
- );
- }
+ ({ disabled = false, title, icon, onClick, tabIndex }, ref): JSX.Element => (
+
+ {
+ event.stopPropagation();
+ }}
+ tabIndex={tabIndex}
+ type="button"
+ ref={ref}
+ >
+ {typeof icon === "string" ? : icon}
+
+
+ )
);
const ActionIcon = styled.button`
diff --git a/packages/lib/src/badge/Badge.tsx b/packages/lib/src/badge/Badge.tsx
index 937c421ab..64895758f 100644
--- a/packages/lib/src/badge/Badge.tsx
+++ b/packages/lib/src/badge/Badge.tsx
@@ -1,9 +1,8 @@
import styled from "styled-components";
import BadgePropsType from "./types";
-import DxcFlex from "../flex/Flex";
import CoreTokens from "../common/coreTokens";
import DxcIcon from "../icon/Icon";
-import DxcTooltip from "../tooltip/Tooltip";
+import { Tooltip } from "../tooltip/Tooltip";
const contextualColorMap = {
grey: {
@@ -75,14 +74,6 @@ const sizeMap = {
},
};
-const Label = ({ label, notificationLimit, size }) => {
- return (
-
- {typeof label === "number" ? (label > notificationLimit ? "+" + notificationLimit : label) : label}
-
- );
-};
-
const DxcBadge = ({
label,
title,
@@ -91,28 +82,26 @@ const DxcBadge = ({
icon,
notificationLimit = 99,
size = "medium",
-}: BadgePropsType): JSX.Element => {
- return (
-
-
- {(mode === "contextual" && (
-
- {icon && (
- {typeof icon === "string" ? : icon}
- )}
-
-
- )) || }
-
-
- );
-};
+}: BadgePropsType): JSX.Element => (
+
+
+ {mode === "contextual" && icon && (
+ {typeof icon === "string" ? : icon}
+ )}
+ {label && (
+
+ {typeof label === "number" ? (label > notificationLimit ? "+" + notificationLimit : label) : label}
+
+ )}
+
+
+);
const getColor = (mode, color) => (mode === "contextual" ? contextualColorMap[color].text : CoreTokens.color_white);
@@ -128,17 +117,18 @@ const BadgeContainer = styled.div<{
color: BadgePropsType["color"];
size: BadgePropsType["size"];
}>`
- display: flex;
- color: ${(props) => getColor(props.mode, props.color)};
- background-color: ${(props) => getBackgroundColor(props.mode, props.color)};
+ box-sizing: border-box;
border-radius: ${(props) => sizeMap[props.size].borderRadius};
+ padding: ${(props) => (props.label ? getPadding(props.mode, props.size) : "")};
width: ${(props) => (!props.label && props.mode === "notification" ? sizeMap[props.size].width : "fit-content")};
min-width: ${(props) => props.mode === "notification" && sizeMap[props.size].minWidth};
height: ${(props) => sizeMap[props.size].height};
- padding: ${(props) => (props.label ? getPadding(props.mode, props.size) : "")};
+ display: flex;
align-items: center;
+ gap: ${CoreTokens.spacing_2};
justify-content: center;
- box-sizing: border-box;
+ background-color: ${(props) => getBackgroundColor(props.mode, props.color)};
+ color: ${(props) => getColor(props.mode, props.color)};
`;
const IconContainer = styled.div<{ size: BadgePropsType["size"] }>`
@@ -151,7 +141,7 @@ const IconContainer = styled.div<{ size: BadgePropsType["size"] }>`
}
`;
-const LabelContainer = styled.span<{ size: BadgePropsType["size"] }>`
+const Label = styled.span<{ size: BadgePropsType["size"] }>`
font-family: ${CoreTokens.type_sans};
font-size: ${(props) => sizeMap[props.size].fontSize};
font-weight: ${CoreTokens.type_semibold};
diff --git a/packages/lib/src/button/Button.tsx b/packages/lib/src/button/Button.tsx
index 95829d765..54a51db86 100644
--- a/packages/lib/src/button/Button.tsx
+++ b/packages/lib/src/button/Button.tsx
@@ -4,7 +4,7 @@ import { getMargin } from "../common/utils";
import useTheme from "../useTheme";
import ButtonPropsType from "./types";
import DxcIcon from "../icon/Icon";
-import DxcTooltip from "../tooltip/Tooltip";
+import { Tooltip } from "../tooltip/Tooltip";
const DxcButton = ({
label = "",
@@ -24,7 +24,7 @@ const DxcButton = ({
return (
-
+
{typeof icon === "string" ? : icon}
)}
-
+
);
};
diff --git a/packages/lib/src/contextual-menu/ContextualMenu.stories.tsx b/packages/lib/src/contextual-menu/ContextualMenu.stories.tsx
index 3716725a2..dc8b6904e 100644
--- a/packages/lib/src/contextual-menu/ContextualMenu.stories.tsx
+++ b/packages/lib/src/contextual-menu/ContextualMenu.stories.tsx
@@ -6,6 +6,7 @@ import DxcContainer from "../container/Container";
import useTheme from "../useTheme";
import DxcContextualMenu, { ContextualMenuContext } from "./ContextualMenu";
import SingleItem from "./SingleItem";
+import { userEvent, within } from "@storybook/test";
export default {
title: "Contextual Menu",
@@ -215,3 +216,19 @@ export const SingleItemStates = () => {
);
};
+
+const ItemWithEllipsis = () => (
+
+
+
+
+
+
+);
+
+export const ContextualMenuTooltip = ItemWithEllipsis.bind({});
+ContextualMenuTooltip.play = async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+ await userEvent.hover(canvas.getByText("Item with a very long label that should be truncated"));
+ await userEvent.hover(canvas.getByText("Item with a very long label that should be truncated"));
+};
diff --git a/packages/lib/src/contextual-menu/ItemAction.tsx b/packages/lib/src/contextual-menu/ItemAction.tsx
index ed488074d..d16921a3a 100644
--- a/packages/lib/src/contextual-menu/ItemAction.tsx
+++ b/packages/lib/src/contextual-menu/ItemAction.tsx
@@ -3,18 +3,7 @@ import styled from "styled-components";
import CoreTokens from "../common/coreTokens";
import { ItemActionProps } from "./types";
import DxcIcon from "../icon/Icon";
-import DxcTooltip from "../tooltip/Tooltip";
-
-// TODO: The tooltip is not working fine, text-overflow is not ellipsis due to wrapper container.
-const TooltipWrapper = ({
- condition,
- children,
- label,
-}: {
- condition: boolean;
- children: React.ReactNode;
- label: string;
-}) => (condition ? {children} : <>{children}>);
+import { TooltipWrapper } from "../tooltip/Tooltip";
const ItemAction = ({ badge, collapseIcon, icon, label, depthLevel, ...props }: ItemActionProps) => {
const [hasTooltip, setHasTooltip] = useState(false);
@@ -28,10 +17,10 @@ const ItemAction = ({ badge, collapseIcon, icon, label, depthLevel, ...props }:
{icon && depthLevel === 0 && {typeof icon === "string" ? : icon} }
) => {
- // const text = event.currentTarget;
- // if (text.title === "" && text.scrollWidth > text.clientWidth) setHasTooltip(true);
- // }}
+ onMouseEnter={(event: React.MouseEvent) => {
+ const text = event.currentTarget;
+ setHasTooltip(text.scrollWidth > text.clientWidth);
+ }}
>
{label}
diff --git a/packages/lib/src/date-input/DatePicker.tsx b/packages/lib/src/date-input/DatePicker.tsx
index bc799140a..a10f389f0 100644
--- a/packages/lib/src/date-input/DatePicker.tsx
+++ b/packages/lib/src/date-input/DatePicker.tsx
@@ -7,7 +7,7 @@ import Calendar from "./Calendar";
import YearPicker from "./YearPicker";
import useTranslatedLabels from "../useTranslatedLabels";
import DxcIcon from "../icon/Icon";
-import DxcTooltip from "../tooltip/Tooltip";
+import {Tooltip} from "../tooltip/Tooltip";
const today = dayjs();
@@ -34,14 +34,14 @@ const DatePicker = ({ date, onDateSelect, id }: DatePickerPropsType): JSX.Elemen
return (
-
+
handleMonthChange(innerDate.set("month", innerDate.get("month") - 1))}
>
-
+
setContent((content) => (content === "yearPicker" ? "calendar" : "yearPicker"))}
@@ -51,14 +51,14 @@ const DatePicker = ({ date, onDateSelect, id }: DatePickerPropsType): JSX.Elemen
-
+
handleMonthChange(innerDate.set("month", innerDate.get("month") + 1))}
>
-
+
{content === "calendar" && (
({ ...op, icon: icons[i] }));
const opinionatedTheme = {
dropdown: {
- baseColor: "#ffffff",
- fontColor: "#000000",
- optionFontColor: "#000000",
+ baseColor: "#fabada",
+ fontColor: "#fff",
+ optionFontColor: "#0095ff",
},
};
@@ -346,32 +346,7 @@ const DropdownListStates = () => {
);
};
-const DropdownRightAlignment = () => (
-
-
-
- {}} />
-
-
-);
-
-const DropdownCenterAlignment = () => (
-
-
-
- {}} margin="small" />
-
-
-);
-
-export const Chromatic = Dropdown.bind({});
-Chromatic.play = async ({ canvasElement }) => {
- const canvas = within(canvasElement);
- const buttonList = canvas.getAllByRole("button");
- await userEvent.click(buttonList[buttonList.length - 1]);
-};
-
-export const OpinionatedTheme = () => (
+const OpinionatedTheme = () => (
<>
@@ -387,9 +362,9 @@ export const OpinionatedTheme = () => (
-
+
- {}} icon={iconSVG} />
+ {}} icon={iconSVG} />
@@ -404,23 +379,51 @@ export const OpinionatedTheme = () => (
{}} icon={iconSVG} disabled />
+
+
+
+ {}} icon={iconSVG} />
+
+
>
);
-export const DropdownMenuStates = DropdownListStates.bind({});
-DropdownMenuStates.play = async ({ canvasElement }) => {
+const TooltipTitle = () => (
+
+
+ {}}
+ icon="menu"
+ caretHidden
+ margin="large"
+ />
+
+);
+
+export const Chromatic = Dropdown.bind({});
+Chromatic.play = async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+ const buttonList = canvas.getAllByRole("button");
+ await userEvent.click(buttonList[buttonList.length - 1]);
+};
+
+export const OpinionatedThemed = OpinionatedTheme.bind({});
+OpinionatedThemed.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
- await userEvent.click(canvas.getAllByRole("button")[0]);
+ const buttonList = canvas.getAllByRole("button");
+ await userEvent.click(buttonList[buttonList.length - 1]);
};
-export const DropdownMenuAlignedRight = DropdownRightAlignment.bind({});
-DropdownMenuAlignedRight.play = async ({ canvasElement }) => {
+export const MenuStates = DropdownListStates.bind({});
+MenuStates.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
- await userEvent.click(canvas.getByRole("button"));
+ await userEvent.click(canvas.getAllByRole("button")[0]);
};
-export const DropdownMenuAlignedCenter = DropdownCenterAlignment.bind({});
-DropdownMenuAlignedCenter.play = async ({ canvasElement }) => {
+export const MenuTooltip = TooltipTitle.bind({});
+MenuTooltip.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
- await userEvent.click(canvas.getByRole("button"));
+ await userEvent.hover(canvas.getByRole("button"));
};
diff --git a/packages/lib/src/dropdown/Dropdown.tsx b/packages/lib/src/dropdown/Dropdown.tsx
index e40104dc2..ad36a565e 100644
--- a/packages/lib/src/dropdown/Dropdown.tsx
+++ b/packages/lib/src/dropdown/Dropdown.tsx
@@ -8,6 +8,7 @@ import useTheme from "../useTheme";
import useWidth from "../utils/useWidth";
import DropdownMenu from "./DropdownMenu";
import DropdownPropsType from "./types";
+import { Tooltip } from "../tooltip/Tooltip";
const DxcDropdown = ({
options,
@@ -22,6 +23,7 @@ const DxcDropdown = ({
margin,
size = "fitContent",
tabIndex = 0,
+ title,
}: DropdownPropsType): JSX.Element => {
const id = useId();
const triggerId = `trigger-${id}`;
@@ -145,45 +147,47 @@ const DxcDropdown = ({
size={size}
>
-
- {
- event.stopPropagation();
- }}
- disabled={disabled}
- label={label}
- margin={margin}
- size={size}
- id={triggerId}
- aria-haspopup="true"
- aria-controls={isOpen ? menuId : undefined}
- aria-expanded={isOpen ? true : undefined}
- aria-label="Show options"
- tabIndex={tabIndex}
- ref={triggerRef}
- >
-
- {label && iconPosition === "after" && {label} }
- {icon && (
-
- {typeof icon === "string" ? : icon}
-
+
+
+ {
+ event.stopPropagation();
+ }}
+ disabled={disabled}
+ label={label}
+ margin={margin}
+ size={size}
+ id={triggerId}
+ aria-haspopup="true"
+ aria-controls={isOpen ? menuId : undefined}
+ aria-expanded={isOpen ? true : undefined}
+ aria-label="Show options"
+ tabIndex={tabIndex}
+ ref={triggerRef}
+ >
+
+ {label && iconPosition === "after" && {label} }
+ {icon && (
+
+ {typeof icon === "string" ? : icon}
+
+ )}
+ {label && iconPosition === "before" && {label} }
+
+ {!caretHidden && (
+
+ {" "}
+
)}
- {label && iconPosition === "before" && {label} }
-
- {!caretHidden && (
-
- {" "}
-
- )}
-
-
+
+
+
{socialLinks?.map((link, index) => (
-
+
: link.logo}
-
+
))}
)}
diff --git a/packages/lib/src/header/Header.tsx b/packages/lib/src/header/Header.tsx
index d7be0086a..a79d5f796 100644
--- a/packages/lib/src/header/Header.tsx
+++ b/packages/lib/src/header/Header.tsx
@@ -6,7 +6,7 @@ import DxcIcon from "../icon/Icon";
import useTheme from "../useTheme";
import useTranslatedLabels from "../useTranslatedLabels";
import HeaderPropsType from "./types";
-import DxcTooltip from "../tooltip/Tooltip";
+import { Tooltip } from "../tooltip/Tooltip";
import DxcFlex from "../flex/Flex";
const Dropdown = (props: ComponentProps) => (
@@ -119,11 +119,11 @@ const DxcHeader = ({
{headerResponsiveLogo}
-
+
-
+
{headerContent}
{sidenav && isResponsive && (
-
+
{visibilityToggleLabel}
-
+
)}
diff --git a/packages/lib/src/select/ListOption.tsx b/packages/lib/src/select/ListOption.tsx
index bdf43dd51..3f2b82ce2 100644
--- a/packages/lib/src/select/ListOption.tsx
+++ b/packages/lib/src/select/ListOption.tsx
@@ -2,6 +2,8 @@ import styled from "styled-components";
import { OptionProps } from "./types";
import DxcCheckbox from "../checkbox/Checkbox";
import DxcIcon from "../icon/Icon";
+import { useState } from "react";
+import { TooltipWrapper } from "../tooltip/Tooltip";
const ListOption = ({
id,
@@ -13,50 +15,53 @@ const ListOption = ({
isLastOption,
isSelected,
}: OptionProps): JSX.Element => {
- const handleOnMouseEnter = (event: React.MouseEvent) => {
- const label = event.currentTarget;
- const optionElement = document.getElementById(id);
- if (optionElement.title === "" && label.scrollWidth > label.clientWidth) optionElement.title = option.label;
+ const [hasTooltip, setHasTooltip] = useState(false);
+
+ const handleOnMouseEnter = (event: React.MouseEvent) => {
+ const text = event.currentTarget;
+ setHasTooltip(text.scrollWidth > text.clientWidth);
};
return (
- {
- onClick(option);
- }}
- visualFocused={visualFocused}
- selected={isSelected}
- role="option"
- aria-selected={!multiple ? isSelected : undefined}
- >
-
+ {
+ onClick(option);
+ }}
visualFocused={visualFocused}
selected={isSelected}
- last={isLastOption}
- grouped={isGroupedOption}
- multiple={multiple}
+ role="option"
+ aria-selected={!multiple ? isSelected : undefined}
>
- {multiple && (
-
-
-
- )}
- {option.icon && (
-
- {typeof option.icon === "string" ? : option.icon}
-
- )}
-
- {option.label}
- {!multiple && isSelected && (
-
-
-
+
+ {multiple && (
+
+
+
+ )}
+ {option.icon && (
+
+ {typeof option.icon === "string" ? : option.icon}
+
)}
-
-
-
+
+ {option.label}
+ {!multiple && isSelected && (
+
+
+
+ )}
+
+
+
+
);
};
diff --git a/packages/lib/src/select/Select.stories.tsx b/packages/lib/src/select/Select.stories.tsx
index da4896e08..8c098379c 100644
--- a/packages/lib/src/select/Select.stories.tsx
+++ b/packages/lib/src/select/Select.stories.tsx
@@ -212,7 +212,7 @@ const options_material = [
},
];
-const optionsWithEllipsisMedium = [
+const optionsWithEllipsis = [
{ label: "Optiond1234567890123456789012345678901234", value: "1" },
{ label: "Optiond12345678901234567890123456789012345", value: "2" },
{ label: "Option 031111111111111111111111111111222", value: "3" },
@@ -220,10 +220,10 @@ const optionsWithEllipsisMedium = [
const opinionatedTheme = {
select: {
- selectedOptionBackgroundColor: "#e6f4ff",
- fontColor: "#000000",
- optionFontColor: "#000000",
- hoverBorderColor: "#a46ede",
+ selectedOptionBackgroundColor: "#fabada",
+ fontColor: "#333",
+ optionFontColor: "#a46ede",
+ hoverBorderColor: "#0095ff",
},
};
@@ -347,63 +347,44 @@ const Select = () => (
-
+
+ >
+);
+
+const Opinionated = () => (
+ <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
>
@@ -413,279 +394,165 @@ const SelectListbox = () => {
const colorsTheme = useTheme();
return (
- <>
-
-
-
-
-
-
- Submit
-
-
-
-
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
-
-
-
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- {" "}
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- {" "}
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- {" "}
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- {" "}
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
-
- {" "}
-
- {}}
- styles={{ width: 360 }}
- />
-
-
-
- >
+
+
+
+
+
+
+ Submit
+
+
+
+
+
+ {}}
+ styles={{ width: 360 }}
+ />
+
+
+
+ {}}
+ styles={{ width: 360 }}
+ />
+
+
+
+ {}}
+ styles={{ width: 360 }}
+ />
+
+
+
+ {}}
+ styles={{ width: 360 }}
+ />
+
+
+
+ {}}
+ styles={{ width: 360 }}
+ />
+
+
+
+
+ {}}
+ styles={{ width: 360 }}
+ />
+
+
+
+ {}}
+ styles={{ width: 360 }}
+ />
+
+
+
+ {}}
+ styles={{ width: 360 }}
+ />
+
+
);
};
@@ -696,15 +563,6 @@ const SearchableSelect = () => (
);
-const SearchableSelectOpinionated = () => (
-
-
-
-
-
-
-);
-
const SearchValue = () => (
@@ -718,21 +576,6 @@ const SearchValue = () => (
);
-const SearchValueOpinionated = () => (
-
-
-
-
-
-
-);
-
const MultipleSelect = () => (
<>
@@ -748,21 +591,6 @@ const MultipleSelect = () => (
>
);
-const MultipleSelectOpinionated = () => (
-
-
-
-
-
-
-);
-
const DefaultGroupedOptionsSelect = () => (
@@ -792,21 +620,6 @@ const MultipleGroupedOptionsSelect = () => (
);
-const MultipleGroupedOptionsSelectOpinionated = () => (
-
-
-
-
-
-
-);
-
const MultipleSearchable = () => (
@@ -821,19 +634,42 @@ const MultipleSearchable = () => (
);
-const MultipleSearchableOpinionated = () => (
+const TooltipValue = () => (
-
-
-
-
+
+
+
+);
+
+const TooltipOption = () => {
+ const colorsTheme = useTheme();
+
+ return (
+
+
+ {" "}
+ {}}
+ styles={{ width: 360 }}
+ />
+
+
+ );
+};
+
+const TooltipClear = () => (
+
+
+
);
@@ -843,6 +679,12 @@ Chromatic.play = async ({ canvasElement }) => {
await userEvent.click(canvas.getAllByRole("combobox")[24]);
};
+export const OpinionatedTheme = Opinionated.bind({});
+OpinionatedTheme.play = async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+ await userEvent.click(canvas.getAllByRole("combobox")[2]);
+};
+
export const ListboxStates = SelectListbox.bind({});
ListboxStates.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
@@ -856,36 +698,18 @@ Searchable.play = async ({ canvasElement }) => {
await userEvent.type(canvas.getByRole("combobox"), "r");
};
-export const SearchableOpinionated = SearchableSelectOpinionated.bind({});
-SearchableOpinionated.play = async ({ canvasElement }) => {
- const canvas = within(canvasElement);
- await userEvent.type(canvas.getByRole("combobox"), "r");
-};
-
export const SearchableWithValue = SearchValue.bind({});
SearchableWithValue.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.click(canvas.getByRole("combobox"));
};
-export const SearchableWithValueOpinionated = SearchValueOpinionated.bind({});
-SearchableWithValueOpinionated.play = async ({ canvasElement }) => {
- const canvas = within(canvasElement);
- await userEvent.click(canvas.getByRole("combobox"));
-};
-
export const MultipleSearchableWithValue = MultipleSearchable.bind({});
MultipleSearchableWithValue.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
await userEvent.click(canvas.getAllByRole("combobox")[0]);
};
-export const MultipleSearchableWithValueOpinionated = MultipleSearchableOpinionated.bind({});
-MultipleSearchableWithValueOpinionated.play = async ({ canvasElement }) => {
- const canvas = within(canvasElement);
- await userEvent.click(canvas.getAllByRole("combobox")[0]);
-};
-
export const GroupOptionsDisplayed = DefaultGroupedOptionsSelect.bind({});
GroupOptionsDisplayed.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
@@ -906,12 +730,6 @@ MultipleOptionsDisplayed.play = async ({ canvasElement }) => {
await userEvent.click(canvas.getAllByRole("combobox")[0]);
};
-export const MultipleOptionsDisplayedOpinionated = MultipleSelectOpinionated.bind({});
-MultipleOptionsDisplayedOpinionated.play = async ({ canvasElement }) => {
- const canvas = within(canvasElement);
- await userEvent.click(canvas.getAllByRole("combobox")[0]);
-};
-
export const MultipleGroupedOptionsDisplayed = MultipleGroupedOptionsSelect.bind({});
MultipleGroupedOptionsDisplayed.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
@@ -919,28 +737,31 @@ MultipleGroupedOptionsDisplayed.play = async ({ canvasElement }) => {
await userEvent.click(select);
};
-export const MultipleGroupedOptionsDisplayedOpinionated = MultipleGroupedOptionsSelectOpinionated.bind({});
-MultipleGroupedOptionsDisplayedOpinionated.play = async ({ canvasElement }) => {
+export const ValueWithEllipsisTooltip = TooltipValue.bind({});
+ValueWithEllipsisTooltip.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
- const select = canvas.getByRole("combobox");
- await userEvent.click(select);
+ await userEvent.hover(canvas.getByText("Option 01, Option 02, Option 03, Option 04"));
+ await userEvent.hover(canvas.getByText("Option 01, Option 02, Option 03, Option 04"));
};
-const Tooltip = () => {
- const colorsTheme: any = useTheme();
- return (
-
-
-
-
-
-
- );
+export const ListboxOptionWithEllipsisTooltip = TooltipOption.bind({});
+ListboxOptionWithEllipsisTooltip.play = async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+ await userEvent.hover(canvas.getByText("Optiond12345678901234567890123456789012345"));
+ await userEvent.hover(canvas.getByText("Optiond12345678901234567890123456789012345"));
};
-export const SelectTooltip = Tooltip.bind({});
-SelectTooltip.play = async ({ canvasElement }) => {
+export const ClearActionTooltip = TooltipClear.bind({});
+ClearActionTooltip.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
const clearSelectionButton = canvas.getByRole("button");
await userEvent.hover(clearSelectionButton);
};
+
+export const SearchableClearActionTooltip = SearchableSelect.bind({});
+SearchableClearActionTooltip.play = async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+ await userEvent.type(canvas.getByRole("combobox"), "r");
+ const clearSelectionButton = canvas.getByRole("button");
+ await userEvent.hover(clearSelectionButton);
+};
diff --git a/packages/lib/src/select/Select.tsx b/packages/lib/src/select/Select.tsx
index f3eb96e16..a211d9d2e 100644
--- a/packages/lib/src/select/Select.tsx
+++ b/packages/lib/src/select/Select.tsx
@@ -1,10 +1,10 @@
import * as Popover from "@radix-ui/react-popover";
-import { forwardRef, useCallback, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
+import { forwardRef, useCallback, useId, useMemo, useRef, useState } from "react";
import styled, { ThemeProvider } from "styled-components";
import { getMargin } from "../common/utils";
import { spaces } from "../common/variables";
import DxcIcon from "../icon/Icon";
-import DxcTooltip from "../tooltip/Tooltip";
+import { Tooltip, TooltipWrapper } from "../tooltip/Tooltip";
import useTheme from "../useTheme";
import useTranslatedLabels from "../useTranslatedLabels";
import useWidth from "../utils/useWidth";
@@ -52,10 +52,9 @@ const DxcSelect = forwardRef(
const [searchValue, setSearchValue] = useState("");
const [visualFocusIndex, changeVisualFocusIndex] = useState(-1);
const [isOpen, changeIsOpen] = useState(false);
-
+ const [hasTooltip, setHasTooltip] = useState(false);
const selectRef = useRef(null);
const selectSearchInputRef = useRef(null);
- const selectedOptionLabelRef = useRef(null);
const width = useWidth(selectRef.current);
const colorsTheme = useTheme();
@@ -229,13 +228,10 @@ const DxcSelect = forwardRef(
[handleSelectChangeValue, closeListbox, multiple]
);
- useLayoutEffect(() => {
- if (selectedOptionLabelRef?.current != null) {
- if (selectedOptionLabelRef?.current.scrollWidth > selectedOptionLabelRef?.current.clientWidth)
- selectedOptionLabelRef.current.title = getSelectedOptionLabel(placeholder, selectedOption);
- else selectedOptionLabelRef.current.title = "";
- }
- }, [placeholder, selectedOption]);
+ const handleOnMouseEnter = (event: React.MouseEvent) => {
+ const text = event.currentTarget;
+ setHasTooltip(text.scrollWidth > text.clientWidth);
+ };
return (
@@ -279,7 +275,7 @@ const DxcSelect = forwardRef(
{multiple && Array.isArray(selectedOption) && selectedOption.length > 0 && (
{selectedOption.length}
-
+
{
@@ -292,58 +288,60 @@ const DxcSelect = forwardRef(
>
-
+
)}
-
-
- {searchable && (
-
- )}
- {(!searchable || searchValue === "") && (
-
+
+
-
- {getSelectedOptionLabel(placeholder, selectedOption)}
-
-
- )}
-
+ readOnly
+ aria-hidden="true"
+ />
+ {searchable && (
+
+ )}
+ {(!searchable || searchValue === "") && (
+
+
+ {getSelectedOptionLabel(placeholder, selectedOption)}
+
+
+ )}
+
+
{!disabled && error && (
)}
{searchable && searchValue.length > 0 && (
-
+
{
// Avoid input to lose focus
@@ -355,7 +353,7 @@ const DxcSelect = forwardRef(
>
-
+
)}
diff --git a/packages/lib/src/select/selectUtils.ts b/packages/lib/src/select/selectUtils.ts
index 8f549dc14..d0840beb2 100644
--- a/packages/lib/src/select/selectUtils.ts
+++ b/packages/lib/src/select/selectUtils.ts
@@ -130,7 +130,7 @@ const getSelectedOption = (
};
/**
- * Return the label or labels of the selected option(s) for the internal input.
+ * Return the label or labels of the selected option(s), separated by commas.
*/
const getSelectedOptionLabel = (placeholder: string, selectedOption: ListOptionType | ListOptionType[]) =>
Array.isArray(selectedOption)
diff --git a/packages/lib/src/tabs/Tab.tsx b/packages/lib/src/tabs/Tab.tsx
index 1cd4abd0d..a355e9565 100644
--- a/packages/lib/src/tabs/Tab.tsx
+++ b/packages/lib/src/tabs/Tab.tsx
@@ -2,7 +2,7 @@ import { forwardRef, Ref, useContext, useEffect, useRef } from "react";
import styled from "styled-components";
import DxcBadge from "../badge/Badge";
import DxcIcon from "../icon/Icon";
-import DxcTooltip from "../tooltip/Tooltip";
+import { Tooltip } from "../tooltip/Tooltip";
import useTheme from "../useTheme";
import BaseTypography from "../utils/BaseTypography";
import { TabsContext } from "./TabsContext";
@@ -64,7 +64,7 @@ const DxcTab = forwardRef(
};
return (
-
+
)}
-
+
);
}
);
diff --git a/packages/lib/src/toggle-group/ToggleGroup.tsx b/packages/lib/src/toggle-group/ToggleGroup.tsx
index 30853f117..91206df98 100644
--- a/packages/lib/src/toggle-group/ToggleGroup.tsx
+++ b/packages/lib/src/toggle-group/ToggleGroup.tsx
@@ -3,7 +3,7 @@ import styled, { ThemeProvider } from "styled-components";
import { spaces } from "../common/variables";
import DxcFlex from "../flex/Flex";
import DxcIcon from "../icon/Icon";
-import DxcTooltip from "../tooltip/Tooltip";
+import { Tooltip } from "../tooltip/Tooltip";
import useTheme from "../useTheme";
import ToggleGroupPropsType, { OptionLabel } from "./types";
@@ -67,7 +67,7 @@ const DxcToggleGroup = ({
{helperText}
{options.map((option, i) => (
-
+
{option.label}}
-
+
))}
diff --git a/packages/lib/src/tooltip/Tooltip.tsx b/packages/lib/src/tooltip/Tooltip.tsx
index 8881ae6a4..ae46bfdc0 100644
--- a/packages/lib/src/tooltip/Tooltip.tsx
+++ b/packages/lib/src/tooltip/Tooltip.tsx
@@ -1,60 +1,16 @@
-import * as Tooltip from "@radix-ui/react-tooltip";
import styled from "styled-components";
import CoreTokens from "../common/coreTokens";
-import TooltipPropsType from "./types";
-import { TooltipContext } from "./TooltipContext";
-import { useContext } from "react";
-
-const triangleIcon = (
-
-
-
-);
-
-const DxcTooltip = ({ position = "bottom", label, children }: TooltipPropsType): JSX.Element => {
- const hasTooltip = useContext(TooltipContext);
-
- return (
-
- {label && !hasTooltip ? (
-
-
-
- {children}
-
-
-
- {label}
-
- {triangleIcon}
-
-
-
-
-
- ) : (
- children
- )}
-
- );
-};
+import TooltipPropsType, { TooltipWrapperProps } from "./types";
+import { createContext, useContext } from "react";
+import { Root, Trigger, Portal, Arrow, Content } from "@radix-ui/react-tooltip";
+import { Provider } from "@radix-ui/react-tooltip";
const TooltipTriggerContainer = styled.div`
- display: inline-flex;
position: relative;
+ display: inline-flex;
`;
-const StyledTooltipContent = styled(Tooltip.Content)`
+const StyledTooltipContent = styled(Content)`
z-index: 2147483647;
animation-duration: 0.2s;
@@ -120,14 +76,71 @@ const StyledTooltipContent = styled(Tooltip.Content)`
const TooltipContainer = styled.div`
box-sizing: border-box;
- padding: 8px 12px;
+ max-width: 242px;
border-radius: 4px;
+ border-color: ${CoreTokens.color_grey_800};
+ padding: 8px 12px;
font-size: ${CoreTokens.type_scale_01};
font-family: ${CoreTokens.type_sans};
- max-width: 242px;
color: ${CoreTokens.color_white};
background-color: ${CoreTokens.color_grey_800};
- border-color: ${CoreTokens.color_grey_800};
+ overflow-wrap: break-word;
`;
-export default DxcTooltip;
+const triangleIcon = (
+
+
+
+);
+
+const TooltipContext = createContext(false);
+
+export const Tooltip = ({
+ label,
+ hasAdditionalContainer = false,
+ position = "bottom",
+ children,
+}: { hasAdditionalContainer?: boolean } & TooltipPropsType): JSX.Element => {
+ const hasTooltip = useContext(TooltipContext);
+
+ return (
+
+ {label && !hasTooltip ? (
+
+
+
+ {hasAdditionalContainer ? {children} : children}
+
+
+
+ {label}
+
+ {triangleIcon}
+
+
+
+
+
+ ) : (
+ children
+ )}
+
+ );
+};
+
+export const TooltipWrapper = ({ condition, children, label }: TooltipWrapperProps) =>
+ condition ? {children} : <>{children}>;
+
+export default function DxcTooltip(props: TooltipPropsType) {
+ return ;
+}
diff --git a/packages/lib/src/tooltip/TooltipContext.tsx b/packages/lib/src/tooltip/TooltipContext.tsx
deleted file mode 100644
index 5ac842bf3..000000000
--- a/packages/lib/src/tooltip/TooltipContext.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-import { createContext } from "react";
-
-export const TooltipContext = createContext(false);
diff --git a/packages/lib/src/tooltip/types.tsx b/packages/lib/src/tooltip/types.tsx
index 25a4a996a..a61ae9491 100644
--- a/packages/lib/src/tooltip/types.tsx
+++ b/packages/lib/src/tooltip/types.tsx
@@ -13,4 +13,10 @@ type Props = {
children: React.ReactNode;
};
+export type TooltipWrapperProps = {
+ condition?: boolean;
+ children: React.ReactNode;
+ label?: string;
+};
+
export default Props;