From 108e309cd74ad774592788dcd55a33e132814af6 Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Tue, 25 Mar 2025 12:11:53 +0100 Subject: [PATCH 01/12] Reimplemented component using new tokens --- packages/lib/src/accordion/Accordion.tsx | 45 ++-- packages/lib/src/accordion/AccordionItem.tsx | 212 +++++++++---------- 2 files changed, 120 insertions(+), 137 deletions(-) diff --git a/packages/lib/src/accordion/Accordion.tsx b/packages/lib/src/accordion/Accordion.tsx index 180777ce19..a5918795aa 100644 --- a/packages/lib/src/accordion/Accordion.tsx +++ b/packages/lib/src/accordion/Accordion.tsx @@ -70,7 +70,7 @@ const AccordionContainer = styled.div<{ margin: AccordionPropsType["margin"]; }>` width: ${(props) => calculateWidth(props.margin)}; - margin: ${({ margin }) => (margin && typeof margin !== "object" ? spaces[margin] : "0px")}; + margin: ${({ margin }) => (margin && typeof margin !== "object" ? spaces[margin] : "var(--spacing-padding-none)")}; margin-top: ${({ margin }) => (margin && typeof margin === "object" && margin.top ? spaces[margin.top] : "")}; margin-right: ${({ margin }) => (margin && typeof margin === "object" && margin.right ? spaces[margin.right] : "")}; margin-bottom: ${({ margin }) => @@ -78,68 +78,61 @@ const AccordionContainer = styled.div<{ margin-left: ${({ margin }) => (margin && typeof margin === "object" && margin.left ? spaces[margin.left] : "")}; cursor: "pointer"; - // first and middle accordions (separator) - > div:not(:last-of-type):not(:only-of-type) { - border-bottom: ${(props) => - `${props.theme.accordionSeparatorBorderThickness} ${props.theme.accordionSeparatorBorderStyle}`}; - border-color: ${(props) => props.theme.accordionSeparatorBorderColor}; - } - // first accordion > div:first-of-type:not(:only-of-type) { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - border-top-left-radius: ${(props) => props.theme.borderRadius}; - border-top-right-radius: ${(props) => props.theme.borderRadius}; + border-bottom-left-radius: var(--border-radius-none); + border-bottom-right-radius: var(--border-radius-none); + border-top-left-radius: var(--border-radius-s); + border-top-right-radius: var(--border-radius-s); } // first accordion: hover, focus and active > div:first-of-type:not(:only-of-type) button:hover, div:first-of-type:not(:only-of-type) button:focus, div:first-of-type:not(:only-of-type) button:active { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; + border-bottom-left-radius: var(--border-radius-none); + border-bottom-right-radius: var(--border-radius-none); } // middle accordions > div:not(:first-of-type):not(:last-of-type):not(:only-of-type) { - border-radius: 0; + border-radius: var(--border-radius-none); } // middle accordions: hover, focus and active > div:not(:first-of-type):not(:last-of-type):not(:only-of-type) button:hover, div:not(:first-of-type):not(:last-of-type):not(:only-of-type) button:focus, div:not(:first-of-type):not(:last-of-type):not(:only-of-type) button:active { - border-radius: 0; + border-radius: var(--border-radius-none); } // last accordion > div:last-of-type:not(:only-of-type) { - border-top-left-radius: 0; - border-top-right-radius: 0; - border-bottom-left-radius: ${(props) => props.theme.borderRadius}; - border-bottom-right-radius: ${(props) => props.theme.borderRadius}; + border-top-left-radius: var(--border-radius-none); + border-top-right-radius: var(--border-radius-none); + border-bottom-left-radius: var(--border-radius-s); + border-bottom-right-radius: var(--border-radius-s); } // last accordion: hover, focus and active > div:last-of-type:not(:only-of-type) button:hover, div:last-of-type:not(:only-of-type) button:focus, div:last-of-type:not(:only-of-type) button:active { - border-top-left-radius: 0; - border-top-right-radius: 0; - border-bottom-left-radius: ${(props) => props.theme.borderRadius}; - border-bottom-right-radius: ${(props) => props.theme.borderRadius}; + border-top-left-radius: var(--border-radius-none); + border-top-right-radius: var(--border-radius-none); + border-bottom-left-radius: var(--border-radius-s); + border-bottom-right-radius: var(--border-radius-s); } // last expanded accordion > div:last-of-type:not(:only-of-type) > button[aria-expanded="true"] { - border-radius: 0; + border-radius: var(--border-radius-none); } // last expanded accordion: hover, focus and active > div:last-of-type:not(:only-of-type) > button[aria-expanded="true"]:hover, div:last-of-type:not(:only-of-type) > button[aria-expanded="true"]:focus, div:last-of-type:not(:only-of-type) > button[aria-expanded="true"]:active { - border-radius: 0; + border-radius: var(--border-radius-none); } `; diff --git a/packages/lib/src/accordion/AccordionItem.tsx b/packages/lib/src/accordion/AccordionItem.tsx index c2ce6a448b..4c579e6cc2 100644 --- a/packages/lib/src/accordion/AccordionItem.tsx +++ b/packages/lib/src/accordion/AccordionItem.tsx @@ -1,5 +1,5 @@ import { ReactElement, useContext, useId, cloneElement, useMemo } from "react"; -import styled, { ThemeProvider } from "styled-components"; +import styled from "styled-components"; import HalstackContext from "../HalstackContext"; import { AccordionItemProps } from "./types"; import DxcIcon from "../icon/Icon"; @@ -20,7 +20,6 @@ const AccordionItem = ({ tabIndex = 0, }: AccordionItemProps): JSX.Element => { const id = useId(); - const colorsTheme = useContext(HalstackContext); const { activeIndex, handlerActiveChange, index, independent } = useContext(AccordionContext) ?? {}; const isItemExpanded = useMemo(() => { return independent @@ -33,79 +32,75 @@ const AccordionItem = ({ }; return ( - - - - - - - - {(icon || badge?.position === "before") && ( - - {icon ? ( - - {typeof icon === "string" ? : icon} - - ) : ( - - {disabled ? cloneElement(badge?.element as ReactElement, { color: "grey" }) : badge?.element} - - )} - + + + + + + {(icon || badge?.position === "before") && ( + + {icon ? ( + + {typeof icon === "string" ? : icon} + + ) : ( + + {disabled ? cloneElement(badge?.element as ReactElement, { color: "grey" }) : badge?.element} + )} - - {label} - {subLabel && {subLabel}} - - - - - {assistiveText && ( - - {assistiveText} - - )} - {badge && badge?.position === "after" && !assistiveText && ( - - {disabled ? React.cloneElement(badge.element as ReactElement, { color: "grey" }) : badge.element} - - )} - {badge?.position !== "after" && statusLight && !assistiveText && ( - - {disabled ? React.cloneElement(statusLight as ReactElement, { mode: "default" }) : statusLight} - - )} - - - - - - - - {isItemExpanded && ( - - {children} - - )} - - + + )} + + {label} + {subLabel && {subLabel}} + + + + {assistiveText && ( + + {assistiveText} + + )} + {badge && badge?.position === "after" && !assistiveText && ( + + {disabled ? React.cloneElement(badge.element as ReactElement, { color: "grey" }) : badge.element} + + )} + {badge?.position !== "after" && statusLight && !assistiveText && ( + + {disabled ? React.cloneElement(statusLight as ReactElement, { mode: "default" }) : statusLight} + + )} + + + + + + + + {isItemExpanded && ( + + {children} + + )} + ); }; const AccordionContainer = styled.div` display: flex; flex-direction: column; - background-color: ${(props) => props.theme.backgroundColor}; - border-radius: ${(props) => props.theme.borderRadius}; - box-shadow: ${(props) => - `${props.theme.boxShadowOffsetX} ${props.theme.boxShadowOffsetY} ${props.theme.boxShadowBlur} ${props.theme.boxShadowSpread} ${props.theme.boxShadowColor}`}; + background-color: var(--color-bg-neutral-lightest); + border-radius: var(--border-radius-s); + box-shadow: var(--shadow-mid-x-position) var(--shadow-mid-y-position) var(--shadow-mid-blur) var(--shadow-mid-spread) + var(--shadow-light); min-width: 280px; width: 100%; `; @@ -113,40 +108,39 @@ const AccordionContainer = styled.div` const AccordionTrigger = styled.button` display: flex; justify-content: space-between; - gap: 1.5rem; + gap: var(--spacing-gap-l); width: 100%; background-color: transparent; border: none; - border-radius: ${(props) => props.theme.borderRadius}; - padding: 8px 16px; + border-radius: var(--border-radius-s); + padding: var(--spacing-padding-xs) var(--spacing-padding-m); cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; :focus { - background-color: ${(props) => `${props.theme.focusBackgroundColor}`}; - box-shadow: inset 0 0 0 ${(props) => props.theme.focusBorderThickness} ${(props) => props.theme.focusBorderColor}; + outline: var(--border-width-m) solid var(--border-color-secondary-medium); } :focus-visible { - background-color: ${(props) => `${props.theme.focusBackgroundColor}`}; - box-shadow: inset 0 0 0 ${(props) => props.theme.focusBorderThickness} ${(props) => props.theme.focusBorderColor}; - outline: none; + outline: var(--border-width-m) solid var(--border-color-secondary-medium); } :active:enabled { - background-color: ${(props) => `${props.theme.activeBackgroundColor}`}; - box-shadow: inset 0 0 0 ${(props) => props.theme.focusBorderThickness} ${(props) => props.theme.focusBorderColor}; + background-color: var(--color-bg-primary-lighter); + outline: var(--border-width-m) solid var(--border-color-secondary-medium); } :hover:enabled { - background-color: ${(props) => `${props.theme.hoverBackgroundColor}`}; + background-color: var(--color-bg-neutral-lightest); } `; const LeftSideContainer = styled.div` flex: 1; overflow: hidden; + display: flex; + gap: var(--spacing-gap-m); `; const RightSideContainer = styled.div` display: flex; overflow: hidden; justify-content: flex-end; - gap: 0.5rem; + gap: var(--spacing-gap-s); max-width: 30%; flex-shrink: 0; `; @@ -165,39 +159,36 @@ const LabelsContainer = styled.div` const StatusContainer = styled.div<{ subLabel: AccordionItemProps["subLabel"] }>` display: flex; align-items: ${(props) => (props.subLabel ? "flex-start" : "center")}; - margin-top: ${(props) => props.subLabel && "4px"}; + /* TODO: Check why this was used */ + /* margin-top: ${(props) => props.subLabel && "4px"}; */ `; const IconContainer = styled.span<{ disabled: AccordionItemProps["disabled"] }>` display: flex; - color: ${(props) => (props.disabled ? props.theme.disabledIconColor : props.theme.iconColor)}; - font-size: ${(props) => props.theme.iconSize}; + color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-primary-strong)")}; + font-size: var(--height-s); svg { - height: ${(props) => props.theme.iconSize}; - width: ${(props) => props.theme.iconSize}; + height: var(--height-s); + width: 24px; } `; const AccordionLabel = styled.span<{ disabled: AccordionItemProps["disabled"] }>` - color: ${(props) => (props.disabled ? props.theme.disabledTitleLabelFontColor : props.theme.titleLabelFontColor)}; - font-family: ${(props) => props.theme.titleLabelFontFamily}; - font-size: ${(props) => props.theme.titleLabelFontSize}; - font-style: ${(props) => props.theme.titleLabelFontStyle}; - font-weight: ${(props) => props.theme.titleLabelFontWeight}; - line-height: 1.5em; + color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-dark)")}; + font-family: var(--typography-font-family); + font-size: var(--typography-label-l); + font-weight: var(--typography-label-regular); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; `; const SubLabel = styled.span<{ disabled: AccordionItemProps["disabled"] }>` - height: 20px; - color: ${(props) => (props.disabled ? props.theme.disabledSubLabelFontColor : props.theme.subLabelFontColor)}; - font-family: ${(props) => props.theme.subLabelFontFamily}; - font-size: ${(props) => props.theme.subLabelFontSize}; - font-style: ${(props) => props.theme.subLabelFontStyle}; - font-weight: ${(props) => props.theme.subLabelFontWeight}; - line-height: 1.5em; + height: 22px; /* TODO: Ask designers if this is correct */ + color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; + font-family: var(--typography-font-family); + font-size: var(--typography-helper-text-s); + font-weight: var(--typography-helper-text-regular); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -208,18 +199,16 @@ const AssistiveText = styled.span<{ disabled: AccordionItemProps["disabled"]; subLabel: AccordionItemProps["subLabel"]; }>` - color: ${(props) => - props.disabled ? props.theme.disabledAssistiveTextFontColor : props.theme.assistiveTextFontColor}; - font-family: ${(props) => props.theme.assistiveTextFontFamily}; - font-size: ${(props) => props.theme.assistiveTextFontSize}; - font-style: ${(props) => props.theme.assistiveTextFontStyle}; - font-weight: ${(props) => props.theme.assistiveTextFontWeight}; - line-height: 1.5em; + color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; + font-family: var(--typography-font-family); + font-size: var(--typography-helper-text-s); + font-weight: var(--typography-helper-text-regular); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; align-content: ${(props) => !props.subLabel && "center"}; - margin-top: ${(props) => props.subLabel && "4px"}; + /* TODO: Check why this was used */ + /* margin-top: ${(props) => props.subLabel && "4px"}; */ `; const CollapseIndicator = styled.span<{ @@ -228,16 +217,17 @@ const CollapseIndicator = styled.span<{ display: flex; flex-wrap: wrap; font-size: 24px; - color: ${(props) => (props.disabled ? props.theme.disabledArrowColor : props.theme.arrowColor)}; + color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-primary-strong)")}; svg { - height: ${(props) => props.theme.iconSize}; - width: ${(props) => props.theme.iconSize}; + height: var(--height-s); + width: 24px; } `; const AccordionPanel = styled.div` - border-bottom-left-radius: ${(props) => props.theme.borderRadius}; - border-bottom-right-radius: ${(props) => props.theme.borderRadius}; + border-bottom-left-radius: var(--border-radius-s); + border-bottom-right-radius: var(--border-radius-s); + padding: var(--spacing-padding-m); `; export default AccordionItem; From 18159d03dc454d9e5400bc8e157ac556f90a920d Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Wed, 26 Mar 2025 15:34:47 +0100 Subject: [PATCH 02/12] Changed styled-components order --- packages/lib/src/accordion/Accordion.tsx | 112 ++++++------ packages/lib/src/accordion/AccordionItem.tsx | 173 ++++++++++--------- 2 files changed, 143 insertions(+), 142 deletions(-) diff --git a/packages/lib/src/accordion/Accordion.tsx b/packages/lib/src/accordion/Accordion.tsx index a5918795aa..d29e7ff674 100644 --- a/packages/lib/src/accordion/Accordion.tsx +++ b/packages/lib/src/accordion/Accordion.tsx @@ -7,62 +7,6 @@ import AccordionContext from "./AccordionContext"; import HalstackContext from "../HalstackContext"; import AccordionItem from "./AccordionItem"; -const DxcAccordion = (props: AccordionPropsType): JSX.Element => { - const { children, margin, onActiveChange } = props; - const colorsTheme = useContext(HalstackContext); - - const [innerIndexActive, setInnerIndexActive] = useState( - props.independent - ? (props.defaultIndexActive ?? -1) - : Array.isArray(props.defaultIndexActive) - ? props.defaultIndexActive.filter((i) => i !== undefined) - : [] - ); - - const handlerActiveChange = useCallback( - (index: number | number[]) => { - if (props.indexActive == null) { - setInnerIndexActive((prev) => { - if (props.independent) return typeof index === "number" ? (index === prev ? -1 : index) : prev; - else { - const prevArray = Array.isArray(prev) ? prev : []; - return Array.isArray(index) - ? index - : prevArray.includes(index) - ? prevArray.filter((i) => i !== index) - : [...prevArray, index]; - } - }); - } - onActiveChange?.(index as number & number[]); - }, - [props.indexActive, props.independent, onActiveChange, innerIndexActive] - ); - - const contextValue = useMemo( - () => ({ - activeIndex: props.indexActive ?? innerIndexActive, - handlerActiveChange, - independent: props.independent, - }), - [props.indexActive, innerIndexActive, handlerActiveChange, props.independent] - ); - - return ( - - - {Children.map(children, (accordion, index) => ( - - {accordion} - - ))} - - - ); -}; - -DxcAccordion.AccordionItem = AccordionItem; - const calculateWidth = (margin: AccordionPropsType["margin"]) => `calc(100% - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})`; @@ -136,4 +80,60 @@ const AccordionContainer = styled.div<{ } `; +const DxcAccordion = (props: AccordionPropsType): JSX.Element => { + const { children, margin, onActiveChange } = props; + const colorsTheme = useContext(HalstackContext); + + const [innerIndexActive, setInnerIndexActive] = useState( + props.independent + ? (props.defaultIndexActive ?? -1) + : Array.isArray(props.defaultIndexActive) + ? props.defaultIndexActive.filter((i) => i !== undefined) + : [] + ); + + const handlerActiveChange = useCallback( + (index: number | number[]) => { + if (props.indexActive == null) { + setInnerIndexActive((prev) => { + if (props.independent) return typeof index === "number" ? (index === prev ? -1 : index) : prev; + else { + const prevArray = Array.isArray(prev) ? prev : []; + return Array.isArray(index) + ? index + : prevArray.includes(index) + ? prevArray.filter((i) => i !== index) + : [...prevArray, index]; + } + }); + } + onActiveChange?.(index as number & number[]); + }, + [props.indexActive, props.independent, onActiveChange, innerIndexActive] + ); + + const contextValue = useMemo( + () => ({ + activeIndex: props.indexActive ?? innerIndexActive, + handlerActiveChange, + independent: props.independent, + }), + [props.indexActive, innerIndexActive, handlerActiveChange, props.independent] + ); + + return ( + + + {Children.map(children, (accordion, index) => ( + + {accordion} + + ))} + + + ); +}; + +DxcAccordion.AccordionItem = AccordionItem; + export default DxcAccordion; diff --git a/packages/lib/src/accordion/AccordionItem.tsx b/packages/lib/src/accordion/AccordionItem.tsx index 4c579e6cc2..0e2c91e743 100644 --- a/packages/lib/src/accordion/AccordionItem.tsx +++ b/packages/lib/src/accordion/AccordionItem.tsx @@ -8,92 +8,6 @@ import DxcContainer from "../container/Container"; import React from "react"; import AccordionContext from "./AccordionContext"; -const AccordionItem = ({ - label = "", - subLabel = "", - badge, - statusLight, - icon, - assistiveText = "", - disabled = false, - children, - tabIndex = 0, -}: AccordionItemProps): JSX.Element => { - const id = useId(); - const { activeIndex, handlerActiveChange, index, independent } = useContext(AccordionContext) ?? {}; - const isItemExpanded = useMemo(() => { - return independent - ? activeIndex === index - : Array.isArray(activeIndex) && index !== undefined && activeIndex.includes(index); - }, [independent, activeIndex, index]); - - const handleAccordionState = () => { - if (index !== undefined) handlerActiveChange?.(index); - }; - - return ( - - - - - - {(icon || badge?.position === "before") && ( - - {icon ? ( - - {typeof icon === "string" ? : icon} - - ) : ( - - {disabled ? cloneElement(badge?.element as ReactElement, { color: "grey" }) : badge?.element} - - )} - - )} - - {label} - {subLabel && {subLabel}} - - - - {assistiveText && ( - - {assistiveText} - - )} - {badge && badge?.position === "after" && !assistiveText && ( - - {disabled ? React.cloneElement(badge.element as ReactElement, { color: "grey" }) : badge.element} - - )} - {badge?.position !== "after" && statusLight && !assistiveText && ( - - {disabled ? React.cloneElement(statusLight as ReactElement, { mode: "default" }) : statusLight} - - )} - - - - - - - - {isItemExpanded && ( - - {children} - - )} - - ); -}; - const AccordionContainer = styled.div` display: flex; flex-direction: column; @@ -129,6 +43,7 @@ const AccordionTrigger = styled.button` background-color: var(--color-bg-neutral-lightest); } `; + const LeftSideContainer = styled.div` flex: 1; overflow: hidden; @@ -230,4 +145,90 @@ const AccordionPanel = styled.div` padding: var(--spacing-padding-m); `; +const AccordionItem = ({ + label = "", + subLabel = "", + badge, + statusLight, + icon, + assistiveText = "", + disabled = false, + children, + tabIndex = 0, +}: AccordionItemProps): JSX.Element => { + const id = useId(); + const { activeIndex, handlerActiveChange, index, independent } = useContext(AccordionContext) ?? {}; + const isItemExpanded = useMemo(() => { + return independent + ? activeIndex === index + : Array.isArray(activeIndex) && index !== undefined && activeIndex.includes(index); + }, [independent, activeIndex, index]); + + const handleAccordionState = () => { + if (index !== undefined) handlerActiveChange?.(index); + }; + + return ( + + + + + + {(icon || badge?.position === "before") && ( + + {icon ? ( + + {typeof icon === "string" ? : icon} + + ) : ( + + {disabled ? cloneElement(badge?.element as ReactElement, { color: "grey" }) : badge?.element} + + )} + + )} + + {label} + {subLabel && {subLabel}} + + + + {assistiveText && ( + + {assistiveText} + + )} + {badge && badge?.position === "after" && !assistiveText && ( + + {disabled ? React.cloneElement(badge.element as ReactElement, { color: "grey" }) : badge.element} + + )} + {badge?.position !== "after" && statusLight && !assistiveText && ( + + {disabled ? React.cloneElement(statusLight as ReactElement, { mode: "default" }) : statusLight} + + )} + + + + + + + + {isItemExpanded && ( + + {children} + + )} + + ); +}; + export default AccordionItem; From bd71ede6487d4afc988d6fb512805823ec167d35 Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Wed, 26 Mar 2025 17:10:47 +0100 Subject: [PATCH 03/12] Reimplemented component --- packages/lib/src/progress-bar/ProgressBar.tsx | 106 ++++++++---------- 1 file changed, 48 insertions(+), 58 deletions(-) diff --git a/packages/lib/src/progress-bar/ProgressBar.tsx b/packages/lib/src/progress-bar/ProgressBar.tsx index c6124c7e90..e40bf1a402 100644 --- a/packages/lib/src/progress-bar/ProgressBar.tsx +++ b/packages/lib/src/progress-bar/ProgressBar.tsx @@ -1,17 +1,15 @@ -import { useContext, useEffect, useId, useState } from "react"; -import styled, { ThemeProvider } from "styled-components"; +import { useEffect, useId, useState } from "react"; +import styled from "styled-components"; import { spaces } from "../common/variables"; -import HalstackContext from "../HalstackContext"; import ProgressBarPropsType from "./types"; import DxcFlex from "../flex/Flex"; const Overlay = styled.div<{ overlay: ProgressBarPropsType["overlay"]; }>` - ${({ overlay, theme }) => + ${({ overlay }) => overlay - ? `background-color: ${theme.overlayColor}; - width: 100%; + ? `background-color: var(--color-bg-alpha-medium); justify-content: center; height: 100vh; align-items: center; @@ -45,19 +43,17 @@ const MainContainer = styled.div<{ props.margin && typeof props.margin === "object" && props.margin.left ? spaces[props.margin.left] : ""}; display: flex; flex-direction: column; - gap: 0.5rem; z-index: ${(props) => (props.overlay ? "100" : "0")}; + gap: var(--spacing-gap-s); `; const ProgressBarLabel = styled.div<{ overlay: ProgressBarPropsType["overlay"]; }>` - font-family: ${(props) => props.theme.labelFontFamily}; - font-style: ${(props) => props.theme.labelFontStyle}; - font-size: ${(props) => props.theme.labelFontSize}; - font-weight: ${(props) => props.theme.labelFontWeight}; - text-transform: ${(props) => props.theme.labelFontTextTransform}; - color: ${(props) => (props.overlay ? props.theme.overlayFontColor : props.theme.labelFontColor)}; + font-family: var(--typography-font-family); + font-size: var(--typography-label-m); + font-weight: var(--typography-label-semibold); + color: var(--color-fg-neutral-dark); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -68,30 +64,27 @@ const ProgressBarProgress = styled.div<{ overlay: ProgressBarPropsType["overlay"]; }>` flex-shrink: 0; - color: ${(props) => (props.overlay ? props.theme.overlayFontColor : props.theme.valueFontColor)}; - font-family: ${(props) => props.theme.valueFontFamily}; - font-style: ${(props) => props.theme.valueFontStyle}; - font-size: ${(props) => props.theme.valueFontSize}; - font-weight: ${(props) => props.theme.valueFontWeight}; - text-transform: ${(props) => props.theme.valueFontTextTransform}; + color: var(--color-fg-neutral-dark); + font-family: var(--typography-font-family); + font-size: var(--typography-helper-text-s); + font-weight: var(--typography-helper-text-regular); + /* text-transform: ${(props) => props.theme.valueFontTextTransform}; */ `; const HelperText = styled.span<{ overlay: ProgressBarPropsType["overlay"] }>` - color: ${(props) => (props.overlay ? props.theme.overlayFontColor : props.theme.helperTextFontColor)}; - font-family: ${(props) => props.theme.helperTextFontFamily}; - font-size: ${(props) => props.theme.helperTextFontSize}; - font-style: ${(props) => props.theme.helperTextFontStyle}; - font-weight: ${(props) => props.theme.helperTextFontWeight}; - line-height: 1.5em; + color: var(--color-fg-neutral-dark); + font-family: var(--typography-font-family); + font-size: var(--typography-helper-text-s); + font-weight: var(--typography-helper-text-regular, 400); `; const LinearProgress = styled.div<{ helperText: ProgressBarPropsType["helperText"]; }>` position: relative; - border-radius: ${(props) => props.theme.borderRadius}; - height: ${(props) => props.theme.thickness}; - background-color: ${(props) => props.theme.totalLineColor}; + border-radius: var(--border-radius-m); + height: 8px; + background-color: var(--color-bg-neutral-light); overflow: hidden; `; @@ -107,7 +100,7 @@ const LinearProgressBar = styled.span<{ transform: ${(props) => `translateX(-${props.variant === "determinate" ? 100 - (props.value ?? 0) : 0}%)`}; transition: ${(props) => (props.variant === "determinate" ? "transform .4s linear" : "transform 0.2s linear")}; transform-origin: left; - background-color: ${(props) => props.theme.trackLineColor}; + background-color: var(--color-fg-primary-strong); ${(props) => props.variant === "indeterminate" ? "animation: keyframes-indeterminate-first 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;" @@ -153,7 +146,6 @@ const DxcProgressBar = ({ margin, ariaLabel = "Progress bar", }: ProgressBarPropsType): JSX.Element => { - const colorsTheme = useContext(HalstackContext); const labelId = `label-${useId()}`; const [innerValue, setInnerValue] = useState(); @@ -162,34 +154,32 @@ const DxcProgressBar = ({ }, [value]); return ( - - - - - {label && ( - - {label} - - )} - {innerValue != null && showValue && ( - {innerValue} % - )} - - - - - {helperText && {helperText}} - - - + + + + {label && ( + + {label} + + )} + {innerValue != null && showValue && ( + {innerValue} % + )} + + + + + {helperText && {helperText}} + + ); }; From 3a5fb6010aff905bfccb9c679c600e04dd99b3ba Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Wed, 26 Mar 2025 17:11:43 +0100 Subject: [PATCH 04/12] Removed dead code --- packages/lib/src/progress-bar/ProgressBar.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/lib/src/progress-bar/ProgressBar.tsx b/packages/lib/src/progress-bar/ProgressBar.tsx index e40bf1a402..2a3cabfa64 100644 --- a/packages/lib/src/progress-bar/ProgressBar.tsx +++ b/packages/lib/src/progress-bar/ProgressBar.tsx @@ -68,7 +68,6 @@ const ProgressBarProgress = styled.div<{ font-family: var(--typography-font-family); font-size: var(--typography-helper-text-s); font-weight: var(--typography-helper-text-regular); - /* text-transform: ${(props) => props.theme.valueFontTextTransform}; */ `; const HelperText = styled.span<{ overlay: ProgressBarPropsType["overlay"] }>` @@ -156,7 +155,7 @@ const DxcProgressBar = ({ return ( - + {label && ( {label} From 894fa04acbf62c9e2565691a49582a4243d22f1e Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Mon, 31 Mar 2025 13:20:48 +0200 Subject: [PATCH 05/12] Refactoring and fixed colors for overlay --- .../src/progress-bar/ProgressBar.stories.tsx | 36 ------------------- packages/lib/src/progress-bar/ProgressBar.tsx | 36 ++++++++++--------- packages/lib/src/progress-bar/utils.ts | 12 +++++++ 3 files changed, 31 insertions(+), 53 deletions(-) create mode 100644 packages/lib/src/progress-bar/utils.ts diff --git a/packages/lib/src/progress-bar/ProgressBar.stories.tsx b/packages/lib/src/progress-bar/ProgressBar.stories.tsx index 60e9f7feec..4d93a68630 100644 --- a/packages/lib/src/progress-bar/ProgressBar.stories.tsx +++ b/packages/lib/src/progress-bar/ProgressBar.stories.tsx @@ -9,16 +9,6 @@ export default { component: DxcProgressBar, } as Meta; -const opinionatedTheme = { - progressBar: { - accentColor: "#5f249f", - baseColor: "#e6e6e6", - fontColor: "#000000", - overlayColor: "#000000b3", - overlayFontColor: "#ffffff", - }, -}; - const ProgressBar = () => ( <> @@ -62,19 +52,6 @@ const ProgressBar = () => ( <DxcProgressBar label="Margin xxlarge" margin="xxlarge" value={50} showValue /> </ExampleContainer> - <Title title="Opinionated theme" theme="light" level={2} /> - <ExampleContainer> - <Title title="Label and helper text" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcProgressBar label="Loading..." helperText="Helper text" value={24} showValue /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer> - <Title title="Without default value" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcProgressBar label="Loading..." helperText="Helper text" showValue /> - </HalstackProvider> - </ExampleContainer> </> ); @@ -85,15 +62,6 @@ const ProgressBarWithOverlay = () => ( </ExampleContainer> ); -const ProgressBarWithOverlayOpinionated = () => ( - <ExampleContainer> - <Title title="Overlay" theme="dark" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcProgressBar label="Overlay" helperText="Helper text" overlay showValue value={50} /> - </HalstackProvider> - </ExampleContainer> -); - type Story = StoryObj<typeof DxcProgressBar>; export const Chromatic: Story = { @@ -103,7 +71,3 @@ export const Chromatic: Story = { export const ProgressBarOverlay: Story = { render: ProgressBarWithOverlay, }; - -export const ProgressBarOverlayOpinionated: Story = { - render: ProgressBarWithOverlayOpinionated, -}; diff --git a/packages/lib/src/progress-bar/ProgressBar.tsx b/packages/lib/src/progress-bar/ProgressBar.tsx index 2a3cabfa64..6321ef333b 100644 --- a/packages/lib/src/progress-bar/ProgressBar.tsx +++ b/packages/lib/src/progress-bar/ProgressBar.tsx @@ -3,6 +3,7 @@ import styled from "styled-components"; import { spaces } from "../common/variables"; import ProgressBarPropsType from "./types"; import DxcFlex from "../flex/Flex"; +import { getAuxTextStyle, getLabelTextStyle, getTextColor } from "./utils"; const Overlay = styled.div<{ overlay: ProgressBarPropsType["overlay"]; @@ -50,10 +51,8 @@ const MainContainer = styled.div<{ const ProgressBarLabel = styled.div<{ overlay: ProgressBarPropsType["overlay"]; }>` - font-family: var(--typography-font-family); - font-size: var(--typography-label-m); - font-weight: var(--typography-label-semibold); - color: var(--color-fg-neutral-dark); + ${getLabelTextStyle()}; + ${(props) => getTextColor(props.overlay)}; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -63,31 +62,29 @@ const ProgressBarLabel = styled.div<{ const ProgressBarProgress = styled.div<{ overlay: ProgressBarPropsType["overlay"]; }>` + ${getAuxTextStyle()}; + ${(props) => getTextColor(props.overlay)}; flex-shrink: 0; - color: var(--color-fg-neutral-dark); - font-family: var(--typography-font-family); - font-size: var(--typography-helper-text-s); - font-weight: var(--typography-helper-text-regular); `; const HelperText = styled.span<{ overlay: ProgressBarPropsType["overlay"] }>` - color: var(--color-fg-neutral-dark); - font-family: var(--typography-font-family); - font-size: var(--typography-helper-text-s); - font-weight: var(--typography-helper-text-regular, 400); + ${(props) => getTextColor(props.overlay)}; + ${getAuxTextStyle()}; `; const LinearProgress = styled.div<{ helperText: ProgressBarPropsType["helperText"]; + overlay: ProgressBarPropsType["overlay"]; }>` position: relative; border-radius: var(--border-radius-m); height: 8px; - background-color: var(--color-bg-neutral-light); + background-color: ${(props) => (props.overlay ? "var(--color-bg-neutral-lighter)" : "var(--color-bg-neutral-light)")}; overflow: hidden; `; const LinearProgressBar = styled.span<{ + overlay: ProgressBarPropsType["overlay"]; variant: "determinate" | "indeterminate"; value: ProgressBarPropsType["value"]; }>` @@ -99,7 +96,7 @@ const LinearProgressBar = styled.span<{ transform: ${(props) => `translateX(-${props.variant === "determinate" ? 100 - (props.value ?? 0) : 0}%)`}; transition: ${(props) => (props.variant === "determinate" ? "transform .4s linear" : "transform 0.2s linear")}; transform-origin: left; - background-color: var(--color-fg-primary-strong); + background-color: ${(props) => (props.overlay ? "var(--color-fg-primary-medium)" : "var(--color-fg-primary-strong)")}; ${(props) => props.variant === "indeterminate" ? "animation: keyframes-indeterminate-first 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;" @@ -166,15 +163,20 @@ const DxcProgressBar = ({ )} </DxcFlex> <LinearProgress - role="progressbar" - helperText={helperText} aria-label={label ? undefined : ariaLabel} aria-labelledby={label ? labelId : undefined} aria-valuenow={innerValue} aria-valuemin={0} aria-valuemax={100} + helperText={helperText} + role="progressbar" + overlay={overlay} > - <LinearProgressBar variant={innerValue == null ? "indeterminate" : "determinate"} value={innerValue} /> + <LinearProgressBar + overlay={overlay} + variant={innerValue == null ? "indeterminate" : "determinate"} + value={innerValue} + /> </LinearProgress> {helperText && <HelperText overlay={overlay}>{helperText}</HelperText>} </MainContainer> diff --git a/packages/lib/src/progress-bar/utils.ts b/packages/lib/src/progress-bar/utils.ts new file mode 100644 index 0000000000..acd89b37bb --- /dev/null +++ b/packages/lib/src/progress-bar/utils.ts @@ -0,0 +1,12 @@ +export const getTextColor = (overlay?: boolean) => + `color: ${overlay ? "var(--color-fg-neutral-bright)" : "var(--color-fg-neutral-dark)"}`; + +export const getLabelTextStyle = () => + `font-family: var(--typography-font-family); + font-size: var(--typography-label-m); + font-weight: var(--typography-label-semibold);`; + +export const getAuxTextStyle = () => + `font-family: var(--typography-font-family); + font-size: var(--typography-helper-text-s); + font-weight: var(--typography-helper-text-regular);`; From 48132b4b851c830d7d17f4f61104f6501ab730df Mon Sep 17 00:00:00 2001 From: Enrique Moreno <enrique.moreno@dxc.com> Date: Mon, 31 Mar 2025 13:26:51 +0200 Subject: [PATCH 06/12] Removed ThemeProvider import --- packages/lib/src/progress-bar/ProgressBar.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/lib/src/progress-bar/ProgressBar.stories.tsx b/packages/lib/src/progress-bar/ProgressBar.stories.tsx index 4d93a68630..bf87f7dc02 100644 --- a/packages/lib/src/progress-bar/ProgressBar.stories.tsx +++ b/packages/lib/src/progress-bar/ProgressBar.stories.tsx @@ -1,7 +1,6 @@ import { Meta, StoryObj } from "@storybook/react"; import ExampleContainer from "../../.storybook/components/ExampleContainer"; import Title from "../../.storybook/components/Title"; -import { HalstackProvider } from "../HalstackContext"; import DxcProgressBar from "./ProgressBar"; export default { From ece8ed07fb5912681c2ae21c4f27bc8a668260d8 Mon Sep 17 00:00:00 2001 From: Enrique Moreno <enrique.moreno@dxc.com> Date: Tue, 1 Apr 2025 15:04:57 +0200 Subject: [PATCH 07/12] Revert "Changed styled-components order" This reverts commit 18159d03dc454d9e5400bc8e157ac556f90a920d. --- packages/lib/src/accordion/Accordion.tsx | 112 ++++++------ packages/lib/src/accordion/AccordionItem.tsx | 173 +++++++++---------- 2 files changed, 142 insertions(+), 143 deletions(-) diff --git a/packages/lib/src/accordion/Accordion.tsx b/packages/lib/src/accordion/Accordion.tsx index d29e7ff674..a5918795aa 100644 --- a/packages/lib/src/accordion/Accordion.tsx +++ b/packages/lib/src/accordion/Accordion.tsx @@ -7,6 +7,62 @@ import AccordionContext from "./AccordionContext"; import HalstackContext from "../HalstackContext"; import AccordionItem from "./AccordionItem"; +const DxcAccordion = (props: AccordionPropsType): JSX.Element => { + const { children, margin, onActiveChange } = props; + const colorsTheme = useContext(HalstackContext); + + const [innerIndexActive, setInnerIndexActive] = useState( + props.independent + ? (props.defaultIndexActive ?? -1) + : Array.isArray(props.defaultIndexActive) + ? props.defaultIndexActive.filter((i) => i !== undefined) + : [] + ); + + const handlerActiveChange = useCallback( + (index: number | number[]) => { + if (props.indexActive == null) { + setInnerIndexActive((prev) => { + if (props.independent) return typeof index === "number" ? (index === prev ? -1 : index) : prev; + else { + const prevArray = Array.isArray(prev) ? prev : []; + return Array.isArray(index) + ? index + : prevArray.includes(index) + ? prevArray.filter((i) => i !== index) + : [...prevArray, index]; + } + }); + } + onActiveChange?.(index as number & number[]); + }, + [props.indexActive, props.independent, onActiveChange, innerIndexActive] + ); + + const contextValue = useMemo( + () => ({ + activeIndex: props.indexActive ?? innerIndexActive, + handlerActiveChange, + independent: props.independent, + }), + [props.indexActive, innerIndexActive, handlerActiveChange, props.independent] + ); + + return ( + <ThemeProvider theme={colorsTheme.accordion}> + <AccordionContainer margin={margin}> + {Children.map(children, (accordion, index) => ( + <AccordionContext.Provider key={`accordion-${index}`} value={{ index, ...contextValue }}> + {accordion} + </AccordionContext.Provider> + ))} + </AccordionContainer> + </ThemeProvider> + ); +}; + +DxcAccordion.AccordionItem = AccordionItem; + const calculateWidth = (margin: AccordionPropsType["margin"]) => `calc(100% - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})`; @@ -80,60 +136,4 @@ const AccordionContainer = styled.div<{ } `; -const DxcAccordion = (props: AccordionPropsType): JSX.Element => { - const { children, margin, onActiveChange } = props; - const colorsTheme = useContext(HalstackContext); - - const [innerIndexActive, setInnerIndexActive] = useState( - props.independent - ? (props.defaultIndexActive ?? -1) - : Array.isArray(props.defaultIndexActive) - ? props.defaultIndexActive.filter((i) => i !== undefined) - : [] - ); - - const handlerActiveChange = useCallback( - (index: number | number[]) => { - if (props.indexActive == null) { - setInnerIndexActive((prev) => { - if (props.independent) return typeof index === "number" ? (index === prev ? -1 : index) : prev; - else { - const prevArray = Array.isArray(prev) ? prev : []; - return Array.isArray(index) - ? index - : prevArray.includes(index) - ? prevArray.filter((i) => i !== index) - : [...prevArray, index]; - } - }); - } - onActiveChange?.(index as number & number[]); - }, - [props.indexActive, props.independent, onActiveChange, innerIndexActive] - ); - - const contextValue = useMemo( - () => ({ - activeIndex: props.indexActive ?? innerIndexActive, - handlerActiveChange, - independent: props.independent, - }), - [props.indexActive, innerIndexActive, handlerActiveChange, props.independent] - ); - - return ( - <ThemeProvider theme={colorsTheme.accordion}> - <AccordionContainer margin={margin}> - {Children.map(children, (accordion, index) => ( - <AccordionContext.Provider key={`accordion-${index}`} value={{ index, ...contextValue }}> - {accordion} - </AccordionContext.Provider> - ))} - </AccordionContainer> - </ThemeProvider> - ); -}; - -DxcAccordion.AccordionItem = AccordionItem; - export default DxcAccordion; diff --git a/packages/lib/src/accordion/AccordionItem.tsx b/packages/lib/src/accordion/AccordionItem.tsx index 0e2c91e743..4c579e6cc2 100644 --- a/packages/lib/src/accordion/AccordionItem.tsx +++ b/packages/lib/src/accordion/AccordionItem.tsx @@ -8,6 +8,92 @@ import DxcContainer from "../container/Container"; import React from "react"; import AccordionContext from "./AccordionContext"; +const AccordionItem = ({ + label = "", + subLabel = "", + badge, + statusLight, + icon, + assistiveText = "", + disabled = false, + children, + tabIndex = 0, +}: AccordionItemProps): JSX.Element => { + const id = useId(); + const { activeIndex, handlerActiveChange, index, independent } = useContext(AccordionContext) ?? {}; + const isItemExpanded = useMemo(() => { + return independent + ? activeIndex === index + : Array.isArray(activeIndex) && index !== undefined && activeIndex.includes(index); + }, [independent, activeIndex, index]); + + const handleAccordionState = () => { + if (index !== undefined) handlerActiveChange?.(index); + }; + + return ( + <AccordionContainer> + <AccordionTrigger + id={`accordion-${id}`} + onClick={disabled ? undefined : handleAccordionState} + disabled={disabled} + tabIndex={disabled ? -1 : tabIndex} + aria-expanded={isItemExpanded} + aria-controls={`accordion-panel-${id}`} + > + <DxcContainer width="100%" height="100%"> + <DxcFlex> + <LeftSideContainer> + {(icon || badge?.position === "before") && ( + <OptionalElement> + {icon ? ( + <IconContainer disabled={disabled}> + {typeof icon === "string" ? <DxcIcon icon={icon} /> : icon} + </IconContainer> + ) : ( + <StatusContainer subLabel={subLabel}> + {disabled ? cloneElement(badge?.element as ReactElement, { color: "grey" }) : badge?.element} + </StatusContainer> + )} + </OptionalElement> + )} + <LabelsContainer> + <AccordionLabel disabled={disabled}>{label}</AccordionLabel> + {subLabel && <SubLabel disabled={disabled}>{subLabel}</SubLabel>} + </LabelsContainer> + </LeftSideContainer> + <RightSideContainer> + {assistiveText && ( + <AssistiveText disabled={disabled} subLabel={subLabel}> + {assistiveText} + </AssistiveText> + )} + {badge && badge?.position === "after" && !assistiveText && ( + <StatusContainer subLabel={subLabel}> + {disabled ? React.cloneElement(badge.element as ReactElement, { color: "grey" }) : badge.element} + </StatusContainer> + )} + {badge?.position !== "after" && statusLight && !assistiveText && ( + <StatusContainer subLabel={subLabel}> + {disabled ? React.cloneElement(statusLight as ReactElement, { mode: "default" }) : statusLight} + </StatusContainer> + )} + <CollapseIndicator disabled={disabled}> + <DxcIcon icon={isItemExpanded ? "expand_less" : "expand_more"} /> + </CollapseIndicator> + </RightSideContainer> + </DxcFlex> + </DxcContainer> + </AccordionTrigger> + {isItemExpanded && ( + <AccordionPanel id={`accordion-panel-${id}`} role="region" aria-labelledby={`accordion-${id}`}> + {children} + </AccordionPanel> + )} + </AccordionContainer> + ); +}; + const AccordionContainer = styled.div` display: flex; flex-direction: column; @@ -43,7 +129,6 @@ const AccordionTrigger = styled.button` background-color: var(--color-bg-neutral-lightest); } `; - const LeftSideContainer = styled.div` flex: 1; overflow: hidden; @@ -145,90 +230,4 @@ const AccordionPanel = styled.div` padding: var(--spacing-padding-m); `; -const AccordionItem = ({ - label = "", - subLabel = "", - badge, - statusLight, - icon, - assistiveText = "", - disabled = false, - children, - tabIndex = 0, -}: AccordionItemProps): JSX.Element => { - const id = useId(); - const { activeIndex, handlerActiveChange, index, independent } = useContext(AccordionContext) ?? {}; - const isItemExpanded = useMemo(() => { - return independent - ? activeIndex === index - : Array.isArray(activeIndex) && index !== undefined && activeIndex.includes(index); - }, [independent, activeIndex, index]); - - const handleAccordionState = () => { - if (index !== undefined) handlerActiveChange?.(index); - }; - - return ( - <AccordionContainer> - <AccordionTrigger - id={`accordion-${id}`} - onClick={disabled ? undefined : handleAccordionState} - disabled={disabled} - tabIndex={disabled ? -1 : tabIndex} - aria-expanded={isItemExpanded} - aria-controls={`accordion-panel-${id}`} - > - <DxcContainer width="100%" height="100%"> - <DxcFlex> - <LeftSideContainer> - {(icon || badge?.position === "before") && ( - <OptionalElement> - {icon ? ( - <IconContainer disabled={disabled}> - {typeof icon === "string" ? <DxcIcon icon={icon} /> : icon} - </IconContainer> - ) : ( - <StatusContainer subLabel={subLabel}> - {disabled ? cloneElement(badge?.element as ReactElement, { color: "grey" }) : badge?.element} - </StatusContainer> - )} - </OptionalElement> - )} - <LabelsContainer> - <AccordionLabel disabled={disabled}>{label}</AccordionLabel> - {subLabel && <SubLabel disabled={disabled}>{subLabel}</SubLabel>} - </LabelsContainer> - </LeftSideContainer> - <RightSideContainer> - {assistiveText && ( - <AssistiveText disabled={disabled} subLabel={subLabel}> - {assistiveText} - </AssistiveText> - )} - {badge && badge?.position === "after" && !assistiveText && ( - <StatusContainer subLabel={subLabel}> - {disabled ? React.cloneElement(badge.element as ReactElement, { color: "grey" }) : badge.element} - </StatusContainer> - )} - {badge?.position !== "after" && statusLight && !assistiveText && ( - <StatusContainer subLabel={subLabel}> - {disabled ? React.cloneElement(statusLight as ReactElement, { mode: "default" }) : statusLight} - </StatusContainer> - )} - <CollapseIndicator disabled={disabled}> - <DxcIcon icon={isItemExpanded ? "expand_less" : "expand_more"} /> - </CollapseIndicator> - </RightSideContainer> - </DxcFlex> - </DxcContainer> - </AccordionTrigger> - {isItemExpanded && ( - <AccordionPanel id={`accordion-panel-${id}`} role="region" aria-labelledby={`accordion-${id}`}> - {children} - </AccordionPanel> - )} - </AccordionContainer> - ); -}; - export default AccordionItem; From 3df69d9eefd3ea70b35a91ee7fa23758b9408664 Mon Sep 17 00:00:00 2001 From: Enrique Moreno <enrique.moreno@dxc.com> Date: Tue, 1 Apr 2025 15:07:35 +0200 Subject: [PATCH 08/12] Restored accordion --- packages/lib/src/accordion/Accordion.tsx | 45 ++-- packages/lib/src/accordion/AccordionItem.tsx | 212 ++++++++++--------- 2 files changed, 137 insertions(+), 120 deletions(-) diff --git a/packages/lib/src/accordion/Accordion.tsx b/packages/lib/src/accordion/Accordion.tsx index a5918795aa..180777ce19 100644 --- a/packages/lib/src/accordion/Accordion.tsx +++ b/packages/lib/src/accordion/Accordion.tsx @@ -70,7 +70,7 @@ const AccordionContainer = styled.div<{ margin: AccordionPropsType["margin"]; }>` width: ${(props) => calculateWidth(props.margin)}; - margin: ${({ margin }) => (margin && typeof margin !== "object" ? spaces[margin] : "var(--spacing-padding-none)")}; + margin: ${({ margin }) => (margin && typeof margin !== "object" ? spaces[margin] : "0px")}; margin-top: ${({ margin }) => (margin && typeof margin === "object" && margin.top ? spaces[margin.top] : "")}; margin-right: ${({ margin }) => (margin && typeof margin === "object" && margin.right ? spaces[margin.right] : "")}; margin-bottom: ${({ margin }) => @@ -78,61 +78,68 @@ const AccordionContainer = styled.div<{ margin-left: ${({ margin }) => (margin && typeof margin === "object" && margin.left ? spaces[margin.left] : "")}; cursor: "pointer"; + // first and middle accordions (separator) + > div:not(:last-of-type):not(:only-of-type) { + border-bottom: ${(props) => + `${props.theme.accordionSeparatorBorderThickness} ${props.theme.accordionSeparatorBorderStyle}`}; + border-color: ${(props) => props.theme.accordionSeparatorBorderColor}; + } + // first accordion > div:first-of-type:not(:only-of-type) { - border-bottom-left-radius: var(--border-radius-none); - border-bottom-right-radius: var(--border-radius-none); - border-top-left-radius: var(--border-radius-s); - border-top-right-radius: var(--border-radius-s); + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-top-left-radius: ${(props) => props.theme.borderRadius}; + border-top-right-radius: ${(props) => props.theme.borderRadius}; } // first accordion: hover, focus and active > div:first-of-type:not(:only-of-type) button:hover, div:first-of-type:not(:only-of-type) button:focus, div:first-of-type:not(:only-of-type) button:active { - border-bottom-left-radius: var(--border-radius-none); - border-bottom-right-radius: var(--border-radius-none); + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } // middle accordions > div:not(:first-of-type):not(:last-of-type):not(:only-of-type) { - border-radius: var(--border-radius-none); + border-radius: 0; } // middle accordions: hover, focus and active > div:not(:first-of-type):not(:last-of-type):not(:only-of-type) button:hover, div:not(:first-of-type):not(:last-of-type):not(:only-of-type) button:focus, div:not(:first-of-type):not(:last-of-type):not(:only-of-type) button:active { - border-radius: var(--border-radius-none); + border-radius: 0; } // last accordion > div:last-of-type:not(:only-of-type) { - border-top-left-radius: var(--border-radius-none); - border-top-right-radius: var(--border-radius-none); - border-bottom-left-radius: var(--border-radius-s); - border-bottom-right-radius: var(--border-radius-s); + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: ${(props) => props.theme.borderRadius}; + border-bottom-right-radius: ${(props) => props.theme.borderRadius}; } // last accordion: hover, focus and active > div:last-of-type:not(:only-of-type) button:hover, div:last-of-type:not(:only-of-type) button:focus, div:last-of-type:not(:only-of-type) button:active { - border-top-left-radius: var(--border-radius-none); - border-top-right-radius: var(--border-radius-none); - border-bottom-left-radius: var(--border-radius-s); - border-bottom-right-radius: var(--border-radius-s); + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: ${(props) => props.theme.borderRadius}; + border-bottom-right-radius: ${(props) => props.theme.borderRadius}; } // last expanded accordion > div:last-of-type:not(:only-of-type) > button[aria-expanded="true"] { - border-radius: var(--border-radius-none); + border-radius: 0; } // last expanded accordion: hover, focus and active > div:last-of-type:not(:only-of-type) > button[aria-expanded="true"]:hover, div:last-of-type:not(:only-of-type) > button[aria-expanded="true"]:focus, div:last-of-type:not(:only-of-type) > button[aria-expanded="true"]:active { - border-radius: var(--border-radius-none); + border-radius: 0; } `; diff --git a/packages/lib/src/accordion/AccordionItem.tsx b/packages/lib/src/accordion/AccordionItem.tsx index 4c579e6cc2..c2ce6a448b 100644 --- a/packages/lib/src/accordion/AccordionItem.tsx +++ b/packages/lib/src/accordion/AccordionItem.tsx @@ -1,5 +1,5 @@ import { ReactElement, useContext, useId, cloneElement, useMemo } from "react"; -import styled from "styled-components"; +import styled, { ThemeProvider } from "styled-components"; import HalstackContext from "../HalstackContext"; import { AccordionItemProps } from "./types"; import DxcIcon from "../icon/Icon"; @@ -20,6 +20,7 @@ const AccordionItem = ({ tabIndex = 0, }: AccordionItemProps): JSX.Element => { const id = useId(); + const colorsTheme = useContext(HalstackContext); const { activeIndex, handlerActiveChange, index, independent } = useContext(AccordionContext) ?? {}; const isItemExpanded = useMemo(() => { return independent @@ -32,75 +33,79 @@ const AccordionItem = ({ }; return ( - <AccordionContainer> - <AccordionTrigger - id={`accordion-${id}`} - onClick={disabled ? undefined : handleAccordionState} - disabled={disabled} - tabIndex={disabled ? -1 : tabIndex} - aria-expanded={isItemExpanded} - aria-controls={`accordion-panel-${id}`} - > - <DxcContainer width="100%" height="100%"> - <DxcFlex> - <LeftSideContainer> - {(icon || badge?.position === "before") && ( - <OptionalElement> - {icon ? ( - <IconContainer disabled={disabled}> - {typeof icon === "string" ? <DxcIcon icon={icon} /> : icon} - </IconContainer> - ) : ( - <StatusContainer subLabel={subLabel}> - {disabled ? cloneElement(badge?.element as ReactElement, { color: "grey" }) : badge?.element} - </StatusContainer> + <ThemeProvider theme={colorsTheme.accordion}> + <AccordionContainer> + <AccordionTrigger + id={`accordion-${id}`} + onClick={disabled ? undefined : handleAccordionState} + disabled={disabled} + tabIndex={disabled ? -1 : tabIndex} + aria-expanded={isItemExpanded} + aria-controls={`accordion-panel-${id}`} + > + <DxcContainer width="100%" height="100%"> + <DxcFlex gap="1.5rem"> + <LeftSideContainer> + <DxcFlex gap="0.75rem"> + {(icon || badge?.position === "before") && ( + <OptionalElement> + {icon ? ( + <IconContainer disabled={disabled}> + {typeof icon === "string" ? <DxcIcon icon={icon} /> : icon} + </IconContainer> + ) : ( + <StatusContainer subLabel={subLabel}> + {disabled ? cloneElement(badge?.element as ReactElement, { color: "grey" }) : badge?.element} + </StatusContainer> + )} + </OptionalElement> )} - </OptionalElement> - )} - <LabelsContainer> - <AccordionLabel disabled={disabled}>{label}</AccordionLabel> - {subLabel && <SubLabel disabled={disabled}>{subLabel}</SubLabel>} - </LabelsContainer> - </LeftSideContainer> - <RightSideContainer> - {assistiveText && ( - <AssistiveText disabled={disabled} subLabel={subLabel}> - {assistiveText} - </AssistiveText> - )} - {badge && badge?.position === "after" && !assistiveText && ( - <StatusContainer subLabel={subLabel}> - {disabled ? React.cloneElement(badge.element as ReactElement, { color: "grey" }) : badge.element} - </StatusContainer> - )} - {badge?.position !== "after" && statusLight && !assistiveText && ( - <StatusContainer subLabel={subLabel}> - {disabled ? React.cloneElement(statusLight as ReactElement, { mode: "default" }) : statusLight} - </StatusContainer> - )} - <CollapseIndicator disabled={disabled}> - <DxcIcon icon={isItemExpanded ? "expand_less" : "expand_more"} /> - </CollapseIndicator> - </RightSideContainer> - </DxcFlex> - </DxcContainer> - </AccordionTrigger> - {isItemExpanded && ( - <AccordionPanel id={`accordion-panel-${id}`} role="region" aria-labelledby={`accordion-${id}`}> - {children} - </AccordionPanel> - )} - </AccordionContainer> + <LabelsContainer> + <AccordionLabel disabled={disabled}>{label}</AccordionLabel> + {subLabel && <SubLabel disabled={disabled}>{subLabel}</SubLabel>} + </LabelsContainer> + </DxcFlex> + </LeftSideContainer> + <RightSideContainer> + {assistiveText && ( + <AssistiveText disabled={disabled} subLabel={subLabel}> + {assistiveText} + </AssistiveText> + )} + {badge && badge?.position === "after" && !assistiveText && ( + <StatusContainer subLabel={subLabel}> + {disabled ? React.cloneElement(badge.element as ReactElement, { color: "grey" }) : badge.element} + </StatusContainer> + )} + {badge?.position !== "after" && statusLight && !assistiveText && ( + <StatusContainer subLabel={subLabel}> + {disabled ? React.cloneElement(statusLight as ReactElement, { mode: "default" }) : statusLight} + </StatusContainer> + )} + <CollapseIndicator disabled={disabled}> + <DxcIcon icon={isItemExpanded ? "expand_less" : "expand_more"} /> + </CollapseIndicator> + </RightSideContainer> + </DxcFlex> + </DxcContainer> + </AccordionTrigger> + {isItemExpanded && ( + <AccordionPanel id={`accordion-panel-${id}`} role="region" aria-labelledby={`accordion-${id}`}> + {children} + </AccordionPanel> + )} + </AccordionContainer> + </ThemeProvider> ); }; const AccordionContainer = styled.div` display: flex; flex-direction: column; - background-color: var(--color-bg-neutral-lightest); - border-radius: var(--border-radius-s); - box-shadow: var(--shadow-mid-x-position) var(--shadow-mid-y-position) var(--shadow-mid-blur) var(--shadow-mid-spread) - var(--shadow-light); + background-color: ${(props) => props.theme.backgroundColor}; + border-radius: ${(props) => props.theme.borderRadius}; + box-shadow: ${(props) => + `${props.theme.boxShadowOffsetX} ${props.theme.boxShadowOffsetY} ${props.theme.boxShadowBlur} ${props.theme.boxShadowSpread} ${props.theme.boxShadowColor}`}; min-width: 280px; width: 100%; `; @@ -108,39 +113,40 @@ const AccordionContainer = styled.div` const AccordionTrigger = styled.button` display: flex; justify-content: space-between; - gap: var(--spacing-gap-l); + gap: 1.5rem; width: 100%; background-color: transparent; border: none; - border-radius: var(--border-radius-s); - padding: var(--spacing-padding-xs) var(--spacing-padding-m); + border-radius: ${(props) => props.theme.borderRadius}; + padding: 8px 16px; cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; :focus { - outline: var(--border-width-m) solid var(--border-color-secondary-medium); + background-color: ${(props) => `${props.theme.focusBackgroundColor}`}; + box-shadow: inset 0 0 0 ${(props) => props.theme.focusBorderThickness} ${(props) => props.theme.focusBorderColor}; } :focus-visible { - outline: var(--border-width-m) solid var(--border-color-secondary-medium); + background-color: ${(props) => `${props.theme.focusBackgroundColor}`}; + box-shadow: inset 0 0 0 ${(props) => props.theme.focusBorderThickness} ${(props) => props.theme.focusBorderColor}; + outline: none; } :active:enabled { - background-color: var(--color-bg-primary-lighter); - outline: var(--border-width-m) solid var(--border-color-secondary-medium); + background-color: ${(props) => `${props.theme.activeBackgroundColor}`}; + box-shadow: inset 0 0 0 ${(props) => props.theme.focusBorderThickness} ${(props) => props.theme.focusBorderColor}; } :hover:enabled { - background-color: var(--color-bg-neutral-lightest); + background-color: ${(props) => `${props.theme.hoverBackgroundColor}`}; } `; const LeftSideContainer = styled.div` flex: 1; overflow: hidden; - display: flex; - gap: var(--spacing-gap-m); `; const RightSideContainer = styled.div` display: flex; overflow: hidden; justify-content: flex-end; - gap: var(--spacing-gap-s); + gap: 0.5rem; max-width: 30%; flex-shrink: 0; `; @@ -159,36 +165,39 @@ const LabelsContainer = styled.div` const StatusContainer = styled.div<{ subLabel: AccordionItemProps["subLabel"] }>` display: flex; align-items: ${(props) => (props.subLabel ? "flex-start" : "center")}; - /* TODO: Check why this was used */ - /* margin-top: ${(props) => props.subLabel && "4px"}; */ + margin-top: ${(props) => props.subLabel && "4px"}; `; const IconContainer = styled.span<{ disabled: AccordionItemProps["disabled"] }>` display: flex; - color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-primary-strong)")}; - font-size: var(--height-s); + color: ${(props) => (props.disabled ? props.theme.disabledIconColor : props.theme.iconColor)}; + font-size: ${(props) => props.theme.iconSize}; svg { - height: var(--height-s); - width: 24px; + height: ${(props) => props.theme.iconSize}; + width: ${(props) => props.theme.iconSize}; } `; const AccordionLabel = styled.span<{ disabled: AccordionItemProps["disabled"] }>` - color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-dark)")}; - font-family: var(--typography-font-family); - font-size: var(--typography-label-l); - font-weight: var(--typography-label-regular); + color: ${(props) => (props.disabled ? props.theme.disabledTitleLabelFontColor : props.theme.titleLabelFontColor)}; + font-family: ${(props) => props.theme.titleLabelFontFamily}; + font-size: ${(props) => props.theme.titleLabelFontSize}; + font-style: ${(props) => props.theme.titleLabelFontStyle}; + font-weight: ${(props) => props.theme.titleLabelFontWeight}; + line-height: 1.5em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; `; const SubLabel = styled.span<{ disabled: AccordionItemProps["disabled"] }>` - height: 22px; /* TODO: Ask designers if this is correct */ - color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; - font-family: var(--typography-font-family); - font-size: var(--typography-helper-text-s); - font-weight: var(--typography-helper-text-regular); + height: 20px; + color: ${(props) => (props.disabled ? props.theme.disabledSubLabelFontColor : props.theme.subLabelFontColor)}; + font-family: ${(props) => props.theme.subLabelFontFamily}; + font-size: ${(props) => props.theme.subLabelFontSize}; + font-style: ${(props) => props.theme.subLabelFontStyle}; + font-weight: ${(props) => props.theme.subLabelFontWeight}; + line-height: 1.5em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -199,16 +208,18 @@ const AssistiveText = styled.span<{ disabled: AccordionItemProps["disabled"]; subLabel: AccordionItemProps["subLabel"]; }>` - color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; - font-family: var(--typography-font-family); - font-size: var(--typography-helper-text-s); - font-weight: var(--typography-helper-text-regular); + color: ${(props) => + props.disabled ? props.theme.disabledAssistiveTextFontColor : props.theme.assistiveTextFontColor}; + font-family: ${(props) => props.theme.assistiveTextFontFamily}; + font-size: ${(props) => props.theme.assistiveTextFontSize}; + font-style: ${(props) => props.theme.assistiveTextFontStyle}; + font-weight: ${(props) => props.theme.assistiveTextFontWeight}; + line-height: 1.5em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; align-content: ${(props) => !props.subLabel && "center"}; - /* TODO: Check why this was used */ - /* margin-top: ${(props) => props.subLabel && "4px"}; */ + margin-top: ${(props) => props.subLabel && "4px"}; `; const CollapseIndicator = styled.span<{ @@ -217,17 +228,16 @@ const CollapseIndicator = styled.span<{ display: flex; flex-wrap: wrap; font-size: 24px; - color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-primary-strong)")}; + color: ${(props) => (props.disabled ? props.theme.disabledArrowColor : props.theme.arrowColor)}; svg { - height: var(--height-s); - width: 24px; + height: ${(props) => props.theme.iconSize}; + width: ${(props) => props.theme.iconSize}; } `; const AccordionPanel = styled.div` - border-bottom-left-radius: var(--border-radius-s); - border-bottom-right-radius: var(--border-radius-s); - padding: var(--spacing-padding-m); + border-bottom-left-radius: ${(props) => props.theme.borderRadius}; + border-bottom-right-radius: ${(props) => props.theme.borderRadius}; `; export default AccordionItem; From 526eb0dea6fe0a6faf7eb690c1a19029efec74b9 Mon Sep 17 00:00:00 2001 From: Enrique Moreno <enrique.moreno@dxc.com> Date: Wed, 2 Apr 2025 14:08:59 +0200 Subject: [PATCH 09/12] Changed ProgressBar component structure --- packages/lib/src/progress-bar/ProgressBar.tsx | 44 ++++++++----------- packages/lib/src/progress-bar/utils.ts | 21 +++++---- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/packages/lib/src/progress-bar/ProgressBar.tsx b/packages/lib/src/progress-bar/ProgressBar.tsx index 6321ef333b..7693d42fb6 100644 --- a/packages/lib/src/progress-bar/ProgressBar.tsx +++ b/packages/lib/src/progress-bar/ProgressBar.tsx @@ -3,31 +3,22 @@ import styled from "styled-components"; import { spaces } from "../common/variables"; import ProgressBarPropsType from "./types"; import DxcFlex from "../flex/Flex"; -import { getAuxTextStyle, getLabelTextStyle, getTextColor } from "./utils"; +import { auxTextStyles, labelTextStyles, textColorStyles } from "./utils"; -const Overlay = styled.div<{ - overlay: ProgressBarPropsType["overlay"]; -}>` - ${({ overlay }) => - overlay - ? `background-color: var(--color-bg-alpha-medium); - justify-content: center; - height: 100vh; - align-items: center; - max-width: 100%; - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: 1300;` - : `background-color: transparent;`} +const ProgressBarContainer = styled.div` display: flex; flex-wrap: wrap; min-width: 100px; width: 100%; `; +const Overlay = styled.div` + background-color: var(--color-bg-alpha-medium); + height: 100%; + inset: 0; + position: fixed; +`; + const MainContainer = styled.div<{ overlay: ProgressBarPropsType["overlay"]; margin: ProgressBarPropsType["margin"]; @@ -51,8 +42,8 @@ const MainContainer = styled.div<{ const ProgressBarLabel = styled.div<{ overlay: ProgressBarPropsType["overlay"]; }>` - ${getLabelTextStyle()}; - ${(props) => getTextColor(props.overlay)}; + ${labelTextStyles}; + ${(props) => textColorStyles(props.overlay)}; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -62,14 +53,14 @@ const ProgressBarLabel = styled.div<{ const ProgressBarProgress = styled.div<{ overlay: ProgressBarPropsType["overlay"]; }>` - ${getAuxTextStyle()}; - ${(props) => getTextColor(props.overlay)}; + ${auxTextStyles}; + ${(props) => textColorStyles(props.overlay)}; flex-shrink: 0; `; const HelperText = styled.span<{ overlay: ProgressBarPropsType["overlay"] }>` - ${(props) => getTextColor(props.overlay)}; - ${getAuxTextStyle()}; + ${(props) => textColorStyles(props.overlay)}; + ${auxTextStyles}; `; const LinearProgress = styled.div<{ @@ -150,7 +141,8 @@ const DxcProgressBar = ({ }, [value]); return ( - <Overlay overlay={overlay}> + <ProgressBarContainer> + {overlay && <Overlay />} <MainContainer overlay={overlay} margin={margin}> <DxcFlex justifyContent="space-between"> {label && ( @@ -180,7 +172,7 @@ const DxcProgressBar = ({ </LinearProgress> {helperText && <HelperText overlay={overlay}>{helperText}</HelperText>} </MainContainer> - </Overlay> + </ProgressBarContainer> ); }; diff --git a/packages/lib/src/progress-bar/utils.ts b/packages/lib/src/progress-bar/utils.ts index acd89b37bb..e9401dcac1 100644 --- a/packages/lib/src/progress-bar/utils.ts +++ b/packages/lib/src/progress-bar/utils.ts @@ -1,12 +1,17 @@ -export const getTextColor = (overlay?: boolean) => - `color: ${overlay ? "var(--color-fg-neutral-bright)" : "var(--color-fg-neutral-dark)"}`; +import { css } from "styled-components"; -export const getLabelTextStyle = () => - `font-family: var(--typography-font-family); +export const textColorStyles = (overlay = false) => css` + color: ${overlay ? "var(--color-fg-neutral-bright)" : "var(--color-fg-neutral-dark)"}; +`; + +export const labelTextStyles = css` + font-family: var(--typography-font-family); font-size: var(--typography-label-m); - font-weight: var(--typography-label-semibold);`; + font-weight: var(--typography-label-semibold); +`; -export const getAuxTextStyle = () => - `font-family: var(--typography-font-family); +export const auxTextStyles = css` + font-family: var(--typography-font-family); font-size: var(--typography-helper-text-s); - font-weight: var(--typography-helper-text-regular);`; + font-weight: var(--typography-helper-text-regular); +`; From ca1e01b952cee53f732de46b7d99b573d38c624b Mon Sep 17 00:00:00 2001 From: Enrique Moreno <enrique.moreno@dxc.com> Date: Wed, 9 Apr 2025 16:55:14 +0200 Subject: [PATCH 10/12] Added documentation --- .../pages/components/progress-bar/code.tsx | 19 + .../pages/components/progress-bar/index.tsx | 24 +- .../progress-bar/specifications.tsx | 21 - .../pages/components/progress-bar/usage.tsx | 21 - .../progress-bar/ProgressBarPageLayout.tsx | 18 +- .../progress-bar/code/ProgressBarCodePage.tsx | 68 ++- .../overview/ProgressBarOverviewPage.tsx | 146 ++++++ .../examples/determinate_undeterminate.ts | 0 .../overview/images/default_overlay.png | Bin 0 -> 30587 bytes .../overview/images/progress_bar_anatomy.png | Bin 0 -> 31638 bytes .../specs/ProgressBarSpecsPage.tsx | 436 ------------------ .../specs/images/progress_anatomy.png | Bin 13179 -> 0 bytes .../specs/images/progress_specs.png | Bin 8660 -> 0 bytes .../usage/ProgressBarUsagePage.tsx | 97 ---- .../usage/images/progress_variants.png | Bin 14896 -> 0 bytes 15 files changed, 212 insertions(+), 638 deletions(-) create mode 100644 apps/website/pages/components/progress-bar/code.tsx delete mode 100644 apps/website/pages/components/progress-bar/specifications.tsx delete mode 100644 apps/website/pages/components/progress-bar/usage.tsx create mode 100644 apps/website/screens/components/progress-bar/overview/ProgressBarOverviewPage.tsx rename apps/website/screens/components/progress-bar/{usage => overview}/examples/determinate_undeterminate.ts (100%) create mode 100644 apps/website/screens/components/progress-bar/overview/images/default_overlay.png create mode 100644 apps/website/screens/components/progress-bar/overview/images/progress_bar_anatomy.png delete mode 100644 apps/website/screens/components/progress-bar/specs/ProgressBarSpecsPage.tsx delete mode 100644 apps/website/screens/components/progress-bar/specs/images/progress_anatomy.png delete mode 100644 apps/website/screens/components/progress-bar/specs/images/progress_specs.png delete mode 100644 apps/website/screens/components/progress-bar/usage/ProgressBarUsagePage.tsx delete mode 100644 apps/website/screens/components/progress-bar/usage/images/progress_variants.png diff --git a/apps/website/pages/components/progress-bar/code.tsx b/apps/website/pages/components/progress-bar/code.tsx new file mode 100644 index 0000000000..bfca7215ed --- /dev/null +++ b/apps/website/pages/components/progress-bar/code.tsx @@ -0,0 +1,19 @@ +import Head from "next/head"; +import type { ReactElement } from "react"; +import ProgressBarPageLayout from "screens/components/progress-bar/ProgressBarPageLayout"; +import ProgressBarCodePage from "screens/components/progress-bar/overview/ProgressBarOverviewPage"; + +const Code = () => { + return ( + <> + <Head> + <title>Progress bar code — Halstack Design System + + + + ); +}; + +Code.getLayout = (page: ReactElement) => {page}; + +export default Code; diff --git a/apps/website/pages/components/progress-bar/index.tsx b/apps/website/pages/components/progress-bar/index.tsx index 600ea58ee7..ee8797d07d 100644 --- a/apps/website/pages/components/progress-bar/index.tsx +++ b/apps/website/pages/components/progress-bar/index.tsx @@ -1,21 +1,17 @@ import Head from "next/head"; import type { ReactElement } from "react"; -import ProgressBarCodePage from "screens/components/progress-bar/code/ProgressBarCodePage"; +import ProgressBarOverviewPage from "screens/components/progress-bar/overview/ProgressBarOverviewPage"; import ProgressBarPageLayout from "screens/components/progress-bar/ProgressBarPageLayout"; -const Index = () => { - return ( - <> - - Progress Bar — Halstack Design System - - - - ); -}; +const Index = () => ( + <> + + Progress Bar — Halstack Design System + + + +); -Index.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; +Index.getLayout = (page: ReactElement) => {page}; export default Index; diff --git a/apps/website/pages/components/progress-bar/specifications.tsx b/apps/website/pages/components/progress-bar/specifications.tsx deleted file mode 100644 index a2710b01b9..0000000000 --- a/apps/website/pages/components/progress-bar/specifications.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Head from "next/head"; -import type { ReactElement } from "react"; -import ProgressBarSpecsPage from "screens/components/progress-bar/specs/ProgressBarSpecsPage"; -import ProgressBarPageLayout from "screens/components/progress-bar/ProgressBarPageLayout"; - -const Specifications = () => { - return ( - <> - - Progress Bar Specs — Halstack Design System - - - - ); -}; - -Specifications.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; - -export default Specifications; diff --git a/apps/website/pages/components/progress-bar/usage.tsx b/apps/website/pages/components/progress-bar/usage.tsx deleted file mode 100644 index 4b7598d75f..0000000000 --- a/apps/website/pages/components/progress-bar/usage.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Head from "next/head"; -import type { ReactElement } from "react"; -import ProgressBarPageLayout from "screens/components/progress-bar/ProgressBarPageLayout"; -import ProgressBarUsagePage from "screens/components/progress-bar/usage/ProgressBarUsagePage"; - -const Usage = () => { - return ( - <> - - Progress Bar Usage — Halstack Design System - - - - ); -}; - -Usage.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; - -export default Usage; diff --git a/apps/website/screens/components/progress-bar/ProgressBarPageLayout.tsx b/apps/website/screens/components/progress-bar/ProgressBarPageLayout.tsx index 231fd62ee8..1d03fb3701 100644 --- a/apps/website/screens/components/progress-bar/ProgressBarPageLayout.tsx +++ b/apps/website/screens/components/progress-bar/ProgressBarPageLayout.tsx @@ -6,12 +6,8 @@ import { ReactNode } from "react"; const ProgressBarPageHeading = ({ children }: { children: ReactNode }) => { const tabs = [ - { label: "Code", path: "/components/progress-bar" }, - { label: "Usage", path: "/components/progress-bar/usage" }, - { - label: "Specifications", - path: "/components/progress-bar/specifications", - }, + { label: "Overview", path: "/components/progress-bar" }, + { label: "Code", path: "/components/progress-bar/code" }, ]; return ( @@ -19,14 +15,8 @@ const ProgressBarPageHeading = ({ children }: { children: ReactNode }) => { - - Progress indicators offer visibility of system status to the user, giving feedback to indicate that the - application is taking some time to processing data. The main aim of these components is to reduce the - user's uncertainty about offering something to look at while the user is waiting for the end. A progress - bar should be used in any scenario that will take more than 1 second in performing the action, for anything - that takes less than that time, it will be distracting for the user. - - + A progress bar visually indicates the completion status of a task or process. + {children} diff --git a/apps/website/screens/components/progress-bar/code/ProgressBarCodePage.tsx b/apps/website/screens/components/progress-bar/code/ProgressBarCodePage.tsx index 52c1910f63..4e8139785c 100644 --- a/apps/website/screens/components/progress-bar/code/ProgressBarCodePage.tsx +++ b/apps/website/screens/components/progress-bar/code/ProgressBarCodePage.tsx @@ -23,12 +23,15 @@ const sections = [ - label + ariaLabel string - Text to be placed above the progress bar. - - + + Specifies a string to be used as the name for the progress bar element when no label is + provided. + + 'Progress bar' helperText @@ -39,57 +42,54 @@ const sections = [ - - overlay - - boolean - - If true, the progress bar will be displayed as a modal. + label - false + string + Text to be placed above the progress bar. + - - value + margin - number + 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | Margin - The value of the progress indicator. If it's received the component is determinate otherwise is - indeterminate. + Size of the margin to be applied to the component. You can pass an object with 'top', 'bottom', 'left' and + 'right' properties in order to specify different margin sizes. - - showValue + overlay boolean - If true, the determined value is displayed above the progress bar. + If true, the progress bar will be displayed as a modal. false - margin + showValue - 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | Margin + boolean + If true, the determined value is displayed above the progress bar. - Size of the margin to be applied to the component. You can pass an object with 'top', 'bottom', 'left' and - 'right' properties in order to specify different margin sizes. + false - - - ariaLabel + value - string + number - Specifies a string to be used as the name for the progress bar element when no label is - provided. + The value of the progress indicator. If it's received the component is determinate otherwise is + indeterminate. - 'Progress bar' + - @@ -110,15 +110,13 @@ const sections = [ }, ]; -const ProgressBarCodePage = () => { - return ( - - - - - - - ); -}; +const ProgressBarCodePage = () => ( + + + + + + +); export default ProgressBarCodePage; diff --git a/apps/website/screens/components/progress-bar/overview/ProgressBarOverviewPage.tsx b/apps/website/screens/components/progress-bar/overview/ProgressBarOverviewPage.tsx new file mode 100644 index 0000000000..7d1eb144d5 --- /dev/null +++ b/apps/website/screens/components/progress-bar/overview/ProgressBarOverviewPage.tsx @@ -0,0 +1,146 @@ +import { DxcParagraph, DxcBulletedList, DxcFlex } from "@dxc-technology/halstack-react"; +import QuickNavContainer from "@/common/QuickNavContainer"; +import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; +import DocFooter from "@/common/DocFooter"; +import Image from "@/common/Image"; +import Example from "@/common/example/Example"; +import default_overlay from "./images/default_overlay.png"; +import anatomy from "./images/progress_bar_anatomy.png"; +import determinate_undeterminate from "./examples/determinate_undeterminate"; + +const sections = [ + { + title: "Introduction", + content: ( + + Progress bars are used to show the progression of a task over time. They provide users with immediate visual + feedback about the current state of an operation, such as loading content, uploading a file, or completing a + form. + + ), + }, + { + title: "Anatomy", + content: ( + <> + Progress bar's anatomy + + + Label (Optional): text element that describes the purpose or context of the + progress bar (e.g., "Uploading file…"). + + + Helper text (Optional): provides additional information or clarification related + to the progress, such as status messages or expected duration. + + + Progress track line: the filled portion of the bar showing completed progress. + + + Progress total line: the background bar representing the total task to be completed. + + + Progress indicator (Optional): highlights the current progress value within the + bar. + + + + ), + }, + { + title: "Variants", + content: ( + <> + Progress bars come in different styles based on task nature and UI context. + + ), + subSections: [ + { + title: "Default or overlay", + content: ( + <> + + + Default: displays the progress bar inline, directly within the page or component + layout. This is the most commonly used style, suitable for non-blocking tasks that allow the user to + continue interacting with the UI. + + + Overlay: displays the progress with a background overlay, temporarily blocking + interaction with the UI. It's used for tasks that require user attention or when interaction must be + paused until the task is complete. + + + Default mode and overlay mode example + + ), + }, + { + title: "Determinate or indeterminate", + content: ( + <> + + + Determinate: are used when the system can calculate the percentage of work completed. + + + Indeterminate: are used when the duration of the task is unknown or unpredictable. + + + + + ), + }, + ], + }, + { + title: "Best practices", + content: ( + <> + + + Provide clear feedback: always display a progress bar when the task takes longer than a few + seconds. This reassures users that the system is processing and gives them a sense of control. If possible, + include a label or percentage to indicate how much of the task is completed. + + + Avoid overuse: Don't show a progress bar for tasks shorter than 1 second — use a spinner or + no feedback instead. Don't use a progress bar just for decoration; it should always reflect a real process. + + + Provide contextual information: whenever possible, provide additional information like + "Starting," "Halfway," or "Almost Done" to help users gauge the task status. If applicable, show what the + task involves, especially when the user is waiting for something critical (e.g., "Updating to the latest + version..."). + + + Use the right variant: use determinate when the completion percentage is known (e.g., file + uploads, task completion). Use indeterminate when the system can’t predict the time or progress (e.g., + loading content, waiting for server responses). + + + Avoid blocking the UI: when progress is happening in the background, place the progress bar + in a non-intrusive area, like near the top of the page or inside a specific section. Use overlay variant + only when necessary, as it blocks user interaction. Make sure to include a clear indication of what the user + is waiting for and an estimated time if possible. + + + Combine with other feedback: pair with success, warning, or info toasts or alerts when + appropriate to give users closure after completion. + + + + ), + }, +]; + +const ProgressBarOverviewPage = () => ( + + + + + + +); + +export default ProgressBarOverviewPage; diff --git a/apps/website/screens/components/progress-bar/usage/examples/determinate_undeterminate.ts b/apps/website/screens/components/progress-bar/overview/examples/determinate_undeterminate.ts similarity index 100% rename from apps/website/screens/components/progress-bar/usage/examples/determinate_undeterminate.ts rename to apps/website/screens/components/progress-bar/overview/examples/determinate_undeterminate.ts diff --git a/apps/website/screens/components/progress-bar/overview/images/default_overlay.png b/apps/website/screens/components/progress-bar/overview/images/default_overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..e15db544ada27ccbc30baca5d9f6700dd2cd3389 GIT binary patch literal 30587 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 z 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 - Progress bar design specifications - - ), - }, - - { - title: "Anatomy", - content: ( - <> - Progress bar anatomy - - - Label (Optional) - - Progress track line - - Helper text (Optional) - - Progress total line - - Progress indicator (Optional){" "} - - - - ), - }, - { - title: "Design tokens", - subSections: [ - { - title: "Color", - content: ( - - - - Component token - Element - Core token - Value - - - - - - trackLineColor - - Track line - - color-purple-700 - - #5f249f - - - - totalLineColor - - Total line - - color-grey-200 - - #e6e6e6 - - - - labelFontColor - - Label - - color-black - - #000000 - - - - labelFontColor - - Label - - color-black - - #000000 - - - - indicatorFontColor - - Indicator - - color-black - - #000000 - - - - helperFontColor - - Helper text - - color-black - - #000000 - - - - overlayColor - - Overlay - - color-grey-800-a - - #000000b3 - - - - overlayFontColor - - Overlay font color - - color-white - - #ffffff - - - - ), - }, - { - title: "Size", - content: ( - - - - Property - Element - Core token - Value - - - - - - height - - Track line - - - 8px - - - - height - - Total line - - - 8px - - - - max-width - - Overlay - - - 100vw - - - - max-height - - Overlay - - - 100vh - - - - ), - }, - { - title: "Internal spacing", - content: ( - - - - Property - Element - Core token - Value - - - - - - margin-bottom - - Label - - - 8px - - - - margin-top - - Helper text - - - 8px - - - - ), - }, - { - title: "Margin", - content: ( - <> - - - - Margin - Value - - - - - - xxsmall - - 6px - - - - xsmall - - 16px - - - - small - - 24px - - - - medium - - 36px - - - - large - - 48px - - - - xlarge - - 64px - - - - xxlarge - - 100px - - - - - And also apply different values to each side of the component: - top, bottom, left, right. - - - ), - }, - { - title: "Typography", - content: ( - - - - Property - Element - Core token - Value - - - - - - font-size - - Label - - font-scale-01 - - 12px - - - - font-weight - - Label - - font-regular - - 400 - - - - text-transform - - Label - - font-transform-uppercase - - uppercase - - - - font-size - - Indicator - - font-scale-02 - - 14px - - - - font-weight - - Indicator - - font-bold - - 600 - - - - font-size - - Helper text - - font-scale-01 - - 12px - - - - font-weight - - Helper text - - font-regular - - 400 - - - - ), - }, - { - title: "Border", - content: ( - - - - Property - Element - Core token - Value - - - - - - border-width - - Track line - - border-width-0 - - 0rem / 0px - - - - border-style - - Track line - - border-style-none - - none - - - - border-radius - - Track line - - border-radius-full - - 9999px - - - - ), - }, - ], - }, -]; - -const ProgressBarSpecsPage = () => { - return ( - - - - - - - ); -}; - -export default ProgressBarSpecsPage; diff --git a/apps/website/screens/components/progress-bar/specs/images/progress_anatomy.png b/apps/website/screens/components/progress-bar/specs/images/progress_anatomy.png deleted file mode 100644 index 090493057dd45e70a853661731b3f73c8161845d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13179 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 - - Use a progress bar when it needs to give feedback in a long-running process with continuous values. - - - Add additional information to clarify the user about the action it is waiting ("Sending - documents..."). - - - Use the determinate type whenever possible, the user can have an estimation on how long it is going take. - - - ), - }, - { - title: "Don'ts", - content: ( - - - For an unknown amount of time/progress, consider using a loading spinner instead. - - - Do not use this type of component in actions that will take less than 1 minute of processing. - - - ), - }, - ], - }, - { - title: "Variants", - content: ( - <> - - The component progress-bar has two variants: default and overlay. - -
- Progress bar variants -
- - ), - }, - { - title: "Determinate or indeterminate", - content: ( - <> - - - - Determinate indicators display how long a process will take. They should be used in longer processes. - - - - Indeterminate indicators express an unspecified amount of wait time. They should be used when: - - - The processing time is unknown. - - The wait time is expected to be short enough that it's not necessary to display. - - - - - - ), - }, -]; - -const ProgressBarUsagePage = () => { - return ( - - - - - - - ); -}; - -export default ProgressBarUsagePage; diff --git a/apps/website/screens/components/progress-bar/usage/images/progress_variants.png b/apps/website/screens/components/progress-bar/usage/images/progress_variants.png deleted file mode 100644 index 3d60e7328f61c22f7ed53796f5222fa71273414a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14896 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 iNhkk*vT5)>rE&|lP>2`F3;xR{L`MU5xm4Zu(f Date: Thu, 10 Apr 2025 11:34:32 +0200 Subject: [PATCH 11/12] Added fixes from review --- .../pages/components/progress-bar/code.tsx | 20 +++++++++---------- .../pages/components/progress-bar/index.tsx | 2 +- .../progress-bar/ProgressBarPageLayout.tsx | 2 +- .../progress-bar/code/ProgressBarCodePage.tsx | 4 +++- .../overview/ProgressBarOverviewPage.tsx | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/apps/website/pages/components/progress-bar/code.tsx b/apps/website/pages/components/progress-bar/code.tsx index bfca7215ed..875b2559de 100644 --- a/apps/website/pages/components/progress-bar/code.tsx +++ b/apps/website/pages/components/progress-bar/code.tsx @@ -1,18 +1,16 @@ import Head from "next/head"; import type { ReactElement } from "react"; import ProgressBarPageLayout from "screens/components/progress-bar/ProgressBarPageLayout"; -import ProgressBarCodePage from "screens/components/progress-bar/overview/ProgressBarOverviewPage"; +import ProgressBarCodePage from "screens/components/progress-bar/code/ProgressBarCodePage"; -const Code = () => { - return ( - <> - - Progress bar code — Halstack Design System - - - - ); -}; +const Code = () => ( + <> + + Progress bar code — Halstack Design System + + + +); Code.getLayout = (page: ReactElement) => {page}; diff --git a/apps/website/pages/components/progress-bar/index.tsx b/apps/website/pages/components/progress-bar/index.tsx index ee8797d07d..a6bcc21207 100644 --- a/apps/website/pages/components/progress-bar/index.tsx +++ b/apps/website/pages/components/progress-bar/index.tsx @@ -6,7 +6,7 @@ import ProgressBarPageLayout from "screens/components/progress-bar/ProgressBarPa const Index = () => ( <> - Progress Bar — Halstack Design System + Progress bar — Halstack Design System diff --git a/apps/website/screens/components/progress-bar/ProgressBarPageLayout.tsx b/apps/website/screens/components/progress-bar/ProgressBarPageLayout.tsx index 1d03fb3701..82aacea0db 100644 --- a/apps/website/screens/components/progress-bar/ProgressBarPageLayout.tsx +++ b/apps/website/screens/components/progress-bar/ProgressBarPageLayout.tsx @@ -14,7 +14,7 @@ const ProgressBarPageHeading = ({ children }: { children: ReactNode }) => { - + A progress bar visually indicates the completion status of a task or process. diff --git a/apps/website/screens/components/progress-bar/code/ProgressBarCodePage.tsx b/apps/website/screens/components/progress-bar/code/ProgressBarCodePage.tsx index 4e8139785c..a674f70551 100644 --- a/apps/website/screens/components/progress-bar/code/ProgressBarCodePage.tsx +++ b/apps/website/screens/components/progress-bar/code/ProgressBarCodePage.tsx @@ -31,7 +31,9 @@ const sections = [ Specifies a string to be used as the name for the progress bar element when no label is provided. - 'Progress bar' + + 'Progress bar' + helperText diff --git a/apps/website/screens/components/progress-bar/overview/ProgressBarOverviewPage.tsx b/apps/website/screens/components/progress-bar/overview/ProgressBarOverviewPage.tsx index 7d1eb144d5..b5943e7f9a 100644 --- a/apps/website/screens/components/progress-bar/overview/ProgressBarOverviewPage.tsx +++ b/apps/website/screens/components/progress-bar/overview/ProgressBarOverviewPage.tsx @@ -104,7 +104,7 @@ const sections = [ include a label or percentage to indicate how much of the task is completed. - Avoid overuse: Don't show a progress bar for tasks shorter than 1 second — use a spinner or + Avoid overuse: don't show a progress bar for tasks shorter than 1 second — use a spinner or no feedback instead. Don't use a progress bar just for decoration; it should always reflect a real process. From ad3b4f3c198e1920a5485d2e31d88150e692be3e Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Thu, 10 Apr 2025 12:14:03 +0200 Subject: [PATCH 12/12] Fixed problem with vertical alignment in overlay mode --- packages/lib/src/progress-bar/ProgressBar.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/lib/src/progress-bar/ProgressBar.tsx b/packages/lib/src/progress-bar/ProgressBar.tsx index 7693d42fb6..d8c99b8809 100644 --- a/packages/lib/src/progress-bar/ProgressBar.tsx +++ b/packages/lib/src/progress-bar/ProgressBar.tsx @@ -5,11 +5,24 @@ import ProgressBarPropsType from "./types"; import DxcFlex from "../flex/Flex"; import { auxTextStyles, labelTextStyles, textColorStyles } from "./utils"; -const ProgressBarContainer = styled.div` +const ProgressBarContainer = styled.div<{ + overlay: ProgressBarPropsType["overlay"]; +}>` display: flex; flex-wrap: wrap; min-width: 100px; width: 100%; + ${({ overlay }) => + overlay && + ` + position: fixed; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + height: 100%; + z-index: 1300; + `} `; const Overlay = styled.div` @@ -141,7 +154,7 @@ const DxcProgressBar = ({ }, [value]); return ( - + {overlay && }