diff --git a/lib/src/accordion/Accordion.stories.tsx b/lib/src/accordion/Accordion.stories.tsx index df374b27a..f9870b9c3 100644 --- a/lib/src/accordion/Accordion.stories.tsx +++ b/lib/src/accordion/Accordion.stories.tsx @@ -30,10 +30,33 @@ const folderIcon = ( ); -const thumbIcon = ( - - - +const smallIcon = ( + + + +); + +const facebookIcon = ( + + + + ); @@ -78,8 +101,30 @@ export const Chromatic = () => ( - - + + +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo + lobortis eget. +
+ + + + + <DxcAccordion label="Accordion" assistiveText="Assistive text" icon={facebookIcon}> + <div> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo + lobortis eget. + </div> + </DxcAccordion> + </ExampleContainer> + <ExampleContainer> + <Title title="With bigger icon (image)" theme="light" level={4} /> + <DxcAccordion + label="Accordion" + assistiveText="Assistive text" + icon="https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons/images/icon-and-image-large-icon-settings_2x.png" + > <div> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget. @@ -134,12 +179,7 @@ export const Chromatic = () => ( padding="medium" > <div style={{ display: "flex", flexDirection: "column", gap: "36px" }}> - <DxcTextInput - label="Label" - helperText="HelperText" - placeholder="Placeholder" - size="fillParent" - /> + <DxcTextInput label="Label" helperText="HelperText" placeholder="Placeholder" size="fillParent" /> <DxcButton label="Submit" size="medium" /> </div> </DxcAccordion> diff --git a/lib/src/accordion/Accordion.tsx b/lib/src/accordion/Accordion.tsx index 456dd3f54..4ebf1927b 100644 --- a/lib/src/accordion/Accordion.tsx +++ b/lib/src/accordion/Accordion.tsx @@ -59,7 +59,7 @@ const DxcAccordion = ({ <AccordionLabel> {icon && ( <IconContainer disabled={disabled}> - {typeof icon === "string" ? <IconImg src={icon} /> : icon} + {typeof icon === "string" ? <img src={icon} /> : icon} </IconContainer> )} <DxcTypography @@ -193,18 +193,15 @@ const AccordionLabel = styled.span` const IconContainer = styled.span<{ disabled: boolean }>` display: flex; - flex-wrap: wrap; - align-content: center; - height: ${(props) => props.theme.iconSize}; - width: ${(props) => props.theme.iconSize}; margin-left: ${(props) => props.theme.iconMarginLeft}; margin-right: ${(props) => props.theme.iconMarginRigth}; color: ${(props) => (props.disabled ? props.theme.disabledIconColor : props.theme.iconColor)}; -`; -const IconImg = styled.img` - height: ${(props) => props.theme.iconSize}; - width: ${(props) => props.theme.iconSize}; + svg, + img { + height: ${(props) => props.theme.iconSize}; + width: ${(props) => props.theme.iconSize}; + } `; const AccordionAssistiveText = styled.span<{ disabled: boolean }>` diff --git a/lib/src/button/Button.stories.tsx b/lib/src/button/Button.stories.tsx index b26eaaf45..d78e4d594 100644 --- a/lib/src/button/Button.stories.tsx +++ b/lib/src/button/Button.stories.tsx @@ -12,11 +12,42 @@ export default { }; const iconSVG = ( - <svg viewBox="0 0 24 24" fill="currentColor"> + <svg width="24px" height="24px" viewBox="0 0 24 24" fill="currentColor"> <path d="M0 0h24v24H0z" fill="none" /> <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" /> </svg> ); + +const facebookIcon = ( + <svg + version="1.1" + id="Capa_1" + x="0px" + y="0px" + width="438.536px" + height="438.536px" + viewBox="0 0 438.536 438.536" + fill="currentColor" + > + <g> + <path + d="M414.41,24.123C398.333,8.042,378.963,0,356.315,0H82.228C59.58,0,40.21,8.042,24.126,24.123 + C8.045,40.207,0.003,59.576,0.003,82.225v274.084c0,22.647,8.042,42.018,24.123,58.102c16.084,16.084,35.454,24.126,58.102,24.126 + h274.084c22.648,0,42.018-8.042,58.095-24.126c16.084-16.084,24.126-35.454,24.126-58.102V82.225 + C438.532,59.576,430.49,40.204,414.41,24.123z M373.155,225.548h-49.963V406.84h-74.802V225.548H210.99V163.02h37.401v-37.402 + c0-26.838,6.283-47.107,18.843-60.813c12.559-13.706,33.304-20.555,62.242-20.555h49.963v62.526h-31.401 + c-10.663,0-17.467,1.853-20.417,5.568c-2.949,3.711-4.428,10.23-4.428,19.558v31.119h56.534L373.155,225.548z" + /> + </g> + </svg> +); + +const smallIcon = ( + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" height="20" width="20" fill="currentColor"> + <path d="m7.646 18.333-.313-2.625q-.208-.125-.458-.27-.25-.146-.458-.271l-2.438 1.021-2.354-4.063 2.083-1.583V9.458L1.625 7.875l2.354-4.063 2.438 1.021q.208-.125.458-.27.25-.146.458-.271l.313-2.625h4.708l.313 2.625q.208.125.458.271.25.145.458.27l2.438-1.021 2.354 4.063-2.063 1.583v1.084l2.063 1.583-2.354 4.063-2.438-1.021q-.208.125-.458.271-.25.145-.458.27l-.313 2.625ZM10 12.979q1.229 0 2.104-.875T12.979 10q0-1.229-.875-2.104T10 7.021q-1.229 0-2.104.875T7.021 10q0 1.229.875 2.104t2.104.875Zm0-1.75q-.5 0-.865-.364-.364-.365-.364-.865t.364-.865q.365-.364.865-.364t.865.364q.364.365.364.865t-.364.865q-.365.364-.865.364ZM10.021 10Zm-.854 6.583h1.666l.25-2.166q.605-.167 1.167-.5.562-.334 1.021-.792l2.021.854.833-1.375-1.771-1.354q.104-.292.146-.604.042-.313.042-.646 0-.292-.042-.594t-.125-.635l1.771-1.375-.834-1.375-2.02.875q-.48-.479-1.032-.802-.552-.323-1.156-.49l-.271-2.187H9.167l-.271 2.187q-.604.167-1.156.49-.552.323-1.011.781l-2.021-.854-.833 1.375 1.75 1.354q-.083.333-.125.646-.042.312-.042.604t.042.594q.042.302.125.635l-1.75 1.375.833 1.375 2.021-.854q.459.458 1.011.781.552.323 1.156.49Z" /> + </svg> +); + export const Chromatic = () => ( <> <Title title="Primary" theme="light" level={2} /> @@ -52,6 +83,18 @@ export const Chromatic = () => ( <Title title="Only icon" theme="light" level={4} /> <DxcButton icon={iconSVG} /> </ExampleContainer> + <ExampleContainer> + <Title title="Big icon (SVG)" theme="light" level={4} /> + <DxcButton icon={facebookIcon} /> + </ExampleContainer> + <ExampleContainer> + <Title title="Big icon (image)" theme="light" level={4} /> + <DxcButton icon="https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons/images/icon-and-image-large-icon-settings_2x.png" /> + </ExampleContainer> + <ExampleContainer> + <Title title="Small icon" theme="light" level={4} /> + <DxcButton icon={smallIcon} /> + </ExampleContainer> <Title title="Secondary" theme="light" level={2} /> <ExampleContainer> <Title title="Enabled" theme="light" level={4} /> @@ -77,6 +120,10 @@ export const Chromatic = () => ( <Title title="With icon" theme="light" level={4} /> <DxcButton mode="secondary" label="Secondary" icon={iconSVG} /> </ExampleContainer> + <ExampleContainer> + <Title title="Only icon (image)" theme="light" level={4} /> + <DxcButton mode="secondary" icon="https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons/images/icon-and-image-large-icon-settings_2x.png" /> + </ExampleContainer> <Title title="Text" theme="light" level={2} /> <ExampleContainer> <Title title="Enabled" theme="light" level={4} /> @@ -102,6 +149,10 @@ export const Chromatic = () => ( <Title title="With icon" theme="light" level={4} /> <DxcButton label="Text" mode="text" icon={iconSVG} /> </ExampleContainer> + <ExampleContainer> + <Title title="Only icon (image)" theme="light" level={4} /> + <DxcButton mode="text" icon="https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons/images/icon-and-image-large-icon-settings_2x.png" /> + </ExampleContainer> <BackgroundColorProvider color="#333333"> <DarkContainer> <Title title="Primary" theme="dark" level={2} /> diff --git a/lib/src/button/Button.tsx b/lib/src/button/Button.tsx index a4689966c..974ab4e51 100644 --- a/lib/src/button/Button.tsx +++ b/lib/src/button/Button.tsx @@ -36,12 +36,6 @@ const DxcButton = ({ const colorsTheme = useTheme(); const backgroundType = useContext(BackgroundColorContext); - const labelComponent = ( - <LabelContainer icon={icon} iconPosition={iconPosition}> - {label} - </LabelContainer> - ); - return ( <ThemeProvider theme={colorsTheme.button}> <Button @@ -57,13 +51,21 @@ const DxcButton = ({ onClick(); }} > - {label && iconPosition === "after" && labelComponent} + {label && iconPosition === "after" && ( + <LabelContainer icon={icon} iconPosition={iconPosition}> + {label} + </LabelContainer> + )} {icon && ( <IconContainer label={label} iconPosition={iconPosition}> - {typeof icon === "string" ? <ButtonIcon src={icon} /> : icon} + {typeof icon === "string" ? <img src={icon} /> : icon} </IconContainer> )} - {label && iconPosition === "before" && labelComponent} + {label && iconPosition === "before" && ( + <LabelContainer icon={icon} iconPosition={iconPosition}> + {label} + </LabelContainer> + )} </Button> </ThemeProvider> ); @@ -303,26 +305,16 @@ type IconPropsType = { }; const IconContainer = styled.div<IconPropsType>` - max-height: 24px; - max-width: 24px; + display: flex; margin-left: ${(props) => !props.label ? "0px" : (props.iconPosition === "after" && props.label !== "" && "8px") || "8px"}; margin-right: ${(props) => !props.label ? "0px" : (props.iconPosition === "before" && props.label !== "" && "8px") || "8px"}; - overflow: hidden; - display: flex; - img, - svg { - height: 100%; - width: 100%; - } -`; -const ButtonIcon = styled.img` img, svg { - height: 100%; - width: 100%; + height: 24px; + width: 24px; } `; diff --git a/lib/src/chip/Chip.stories.tsx b/lib/src/chip/Chip.stories.tsx index 84e41bac5..8e22a4b01 100644 --- a/lib/src/chip/Chip.stories.tsx +++ b/lib/src/chip/Chip.stories.tsx @@ -10,9 +10,32 @@ export default { }; const iconSVG = ( - <svg viewBox="0 0 24 24" fill="currentColor"> - <path d="M0 0h24v24H0z" fill="none" /> - <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" /> + <svg + version="1.1" + id="Capa_1" + x="0px" + y="0px" + width="438.536px" + height="438.536px" + viewBox="0 0 438.536 438.536" + fill="currentColor" + > + <g> + <path + d="M414.41,24.123C398.333,8.042,378.963,0,356.315,0H82.228C59.58,0,40.21,8.042,24.126,24.123 +C8.045,40.207,0.003,59.576,0.003,82.225v274.084c0,22.647,8.042,42.018,24.123,58.102c16.084,16.084,35.454,24.126,58.102,24.126 +h274.084c22.648,0,42.018-8.042,58.095-24.126c16.084-16.084,24.126-35.454,24.126-58.102V82.225 +C438.532,59.576,430.49,40.204,414.41,24.123z M373.155,225.548h-49.963V406.84h-74.802V225.548H210.99V163.02h37.401v-37.402 +c0-26.838,6.283-47.107,18.843-60.813c12.559-13.706,33.304-20.555,62.242-20.555h49.963v62.526h-31.401 +c-10.663,0-17.467,1.853-20.417,5.568c-2.949,3.711-4.428,10.23-4.428,19.558v31.119h56.534L373.155,225.548z" + /> + </g> + </svg> +); + +const smallIconSVG = ( + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" height="20" width="20"> + <path d="m10 17-1.042-.938q-2.083-1.854-3.437-3.177-1.354-1.323-2.136-2.354Q2.604 9.5 2.302 8.646 2 7.792 2 6.896q0-1.854 1.271-3.125T6.396 2.5q1.021 0 1.979.438.958.437 1.625 1.229.667-.792 1.625-1.229.958-.438 1.979-.438 1.854 0 3.125 1.271T18 6.896q0 .896-.292 1.729-.291.833-1.073 1.854-.781 1.021-2.145 2.365-1.365 1.344-3.49 3.26Zm0-2.021q1.938-1.729 3.188-2.948 1.25-1.219 1.989-2.125.74-.906 1.031-1.614.292-.709.292-1.396 0-1.229-.833-2.063Q14.833 4 13.604 4q-.729 0-1.364.302-.636.302-1.094.844L10.417 6h-.834l-.729-.854q-.458-.542-1.114-.844Q7.083 4 6.396 4q-1.229 0-2.063.833-.833.834-.833 2.063 0 .687.271 1.364.271.678.989 1.573.719.896 1.98 2.125Q8 13.188 10 14.979Zm0-5.5Z" /> </svg> ); @@ -23,20 +46,29 @@ export const Chromatic = () => ( <DxcChip label="Default Chip" /> </ExampleContainer> <ExampleContainer> - <Title title="Chip with prefix" theme="light" level={4} /> - <DxcChip label="Chip with prefix" prefixIcon={iconSVG} /> + <Title title="Chip with prefix SVG (small icon)" theme="light" level={4} /> + <DxcChip label="Chip with prefix" prefixIcon={smallIconSVG} /> </ExampleContainer> <ExampleContainer> - <Title title="Chip with suffix" theme="light" level={4} /> + <Title title="Chip with suffix SVG (large icon)" theme="light" level={4} /> <DxcChip label="Chip with suffix" suffixIcon={iconSVG} /> </ExampleContainer> <ExampleContainer> - <Title title="Chip with prefix and suffix" theme="light" level={4} /> - <DxcChip label="Chip with prefix and suffix" prefixIcon={iconSVG} suffixIcon={iconSVG} /> + <Title title="Chip with prefix (SVG) and suffix (URL)" theme="light" level={4} /> + <DxcChip + label="Chip with prefix and suffix" + prefixIcon={iconSVG} + suffixIcon="https://upload.wikimedia.org/wikipedia/commons/e/e0/Check_green_icon.svg" + /> </ExampleContainer> <ExampleContainer> <Title title="Disabled chip" theme="light" level={4} /> - <DxcChip label="Disabled" disabled prefixIcon={iconSVG} suffixIcon={iconSVG} /> + <DxcChip + label="Disabled" + disabled + prefixIcon={iconSVG} + suffixIcon="https://upload.wikimedia.org/wikipedia/commons/e/e0/Check_green_icon.svg" + /> </ExampleContainer> <ExampleContainer> <Title title="Chip with ellipsis" theme="light" level={4} /> diff --git a/lib/src/chip/Chip.tsx b/lib/src/chip/Chip.tsx index ac097cb1a..32a4ac347 100644 --- a/lib/src/chip/Chip.tsx +++ b/lib/src/chip/Chip.tsx @@ -32,7 +32,7 @@ const DxcChip = ({ onClick={() => onClickPrefix && !disabled && onClickPrefix()} interactuable={typeof onClickPrefix === "function" && !disabled} > - {typeof prefixIcon === "string" ? <PrefixIconContainer src={prefixIcon} /> : prefixIcon} + {typeof prefixIcon === "string" ? <img src={prefixIcon} /> : prefixIcon} </IconContainer> )} {label && <ChipTextContainer disabled={disabled}>{label}</ChipTextContainer>} @@ -46,7 +46,7 @@ const DxcChip = ({ onClick={() => onClickSuffix && !disabled && onClickSuffix()} interactuable={typeof onClickSuffix === "function" && !disabled} > - {typeof suffixIcon === "string" ? <SuffixIconContainer src={suffixIcon} /> : suffixIcon} + {typeof suffixIcon === "string" ? <img src={suffixIcon} /> : suffixIcon} </IconContainer> )} </StyledDxcChip> @@ -55,13 +55,9 @@ const DxcChip = ({ }; const getCursor = (interactuable, disabled) => { - if (disabled) { - return "cursor:not-allowed;"; - } - if (interactuable) { - return "cursor:pointer;"; - } - return "cursor:default; outline:none;"; + if (disabled) return "cursor: not-allowed;"; + else if (interactuable) return "cursor: pointer;"; + else return "cursor: default; outline:none;"; }; const StyledDxcChip = styled.div` @@ -104,31 +100,25 @@ const ChipTextContainer = styled.span` overflow: hidden; `; -const SuffixIconContainer = styled.img``; - -const PrefixIconContainer = styled.img``; - const IconContainer = styled.div` - color: ${(props) => (props.disabled ? props.theme.disabledIconColor : props.theme.iconColor)}; + display: flex; ${(props) => props.prefixIcon ? `margin-right: ${((props.label || props.suffixIcon) && props.theme.iconSpacing) || (props.prefixIcon && "0")};` : `margin-left: ${((props.label || props.prefixIcon) && props.theme.iconSpacing) || (props.prefixIcon && "0")};`} + color: ${(props) => (props.disabled ? props.theme.disabledIconColor : props.theme.iconColor)}; ${(props) => getCursor(props.interactuable, props.disabled)} - width: ${(props) => props.theme.iconSize}; - height: ${(props) => props.theme.iconSize}; - overflow: hidden; - img, - svg { - height: 100%; - width: 100%; - } &:focus { outline-color: ${(props) => props.theme.focusColor}; outline-width: 2px; ${(props) => props.disabled && "outline: none;"} } + img, + svg { + width: ${(props) => props.theme.iconSize}; + height: ${(props) => props.theme.iconSize}; + } `; export default DxcChip; diff --git a/lib/src/dropdown/Dropdown.stories.tsx b/lib/src/dropdown/Dropdown.stories.tsx index 9d1a7b8a3..bce2d601e 100644 --- a/lib/src/dropdown/Dropdown.stories.tsx +++ b/lib/src/dropdown/Dropdown.stories.tsx @@ -8,7 +8,6 @@ import DxcCheckbox from "../checkbox/Checkbox"; import DxcTextInput from "../text-input/TextInput"; import { Option } from "./types"; - export default { title: "Dropdown", component: DxcDropdown, @@ -134,9 +133,18 @@ export const Chromatic = () => ( <DxcDropdown options={options} onSelectOption={(value) => {}} icon={hamburguerIcon} caretHidden /> </ExampleContainer> <ExampleContainer> - <Title title="Large icon" theme="light" level={4} /> + <Title title="Large icon (SVG)" theme="light" level={4} /> <DxcDropdown label="Large icon" options={options} onSelectOption={(value) => {}} icon={iconSVGLarge} /> </ExampleContainer> + <ExampleContainer> + <Title title="Large icon (image)" theme="light" level={4} /> + <DxcDropdown + label="Large icon" + options={options} + onSelectOption={(value) => {}} + icon="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Hamburger_icon.svg/2048px-Hamburger_icon.svg.png" + /> + </ExampleContainer> <ExampleContainer> <Title title="Disabled with icon" theme="light" level={4} /> <DxcDropdown @@ -242,10 +250,10 @@ const DropdownListStates = () => ( <Title title="Hovered option" theme="light" level={4} /> <DropdownMenu id="x" - dropdownId="dX" + dropdownTriggerId="dtx" iconsPosition="before" visualFocusIndex={-1} - optionOnClick={(option) => {}} + menuItemOnClick={(value) => {}} onKeyDown={(e) => {}} options={optionWithIcon} styles={{ width: 240 }} @@ -255,10 +263,10 @@ const DropdownListStates = () => ( <Title title="Active option" theme="light" level={4} /> <DropdownMenu id="x" - dropdownId="dX" + dropdownTriggerId="dtx" iconsPosition="before" visualFocusIndex={-1} - optionOnClick={(option) => {}} + menuItemOnClick={(value) => {}} onKeyDown={(e) => {}} options={optionWithIcon} styles={{ width: 240 }} @@ -268,10 +276,10 @@ const DropdownListStates = () => ( <Title title="Focused option" theme="light" level={4} /> <DropdownMenu id="x" - dropdownId="dX" + dropdownTriggerId="dtx" iconsPosition="before" visualFocusIndex={0} - optionOnClick={(option) => {}} + menuItemOnClick={(value) => {}} onKeyDown={(e) => {}} options={options} styles={{ width: 240 }} @@ -282,10 +290,10 @@ const DropdownListStates = () => ( <Title title="Before" theme="light" level={4} /> <DropdownMenu id="x" - dropdownId="dX" + dropdownTriggerId="dtx" iconsPosition="before" visualFocusIndex={-1} - optionOnClick={(option) => {}} + menuItemOnClick={(value) => {}} onKeyDown={(e) => {}} options={optionsIcon} styles={{ width: 240 }} @@ -293,10 +301,10 @@ const DropdownListStates = () => ( <Title title="After" theme="light" level={4} /> <DropdownMenu id="x" - dropdownId="dX" + dropdownTriggerId="dtx" iconsPosition="after" visualFocusIndex={-1} - optionOnClick={(option) => {}} + menuItemOnClick={(value) => {}} onKeyDown={(e) => {}} options={optionsIcon} styles={{ width: 240 }} diff --git a/lib/src/dropdown/Dropdown.tsx b/lib/src/dropdown/Dropdown.tsx index 99c386fa0..354851a2f 100644 --- a/lib/src/dropdown/Dropdown.tsx +++ b/lib/src/dropdown/Dropdown.tsx @@ -199,12 +199,7 @@ const DxcDropdown = ({ <DropdownTriggerContent> {label && iconPosition === "after" && <DropdownTriggerLabel>{label}</DropdownTriggerLabel>} {icon && ( - <DropdownTriggerIcon - label={label} - iconPosition={iconPosition} - disabled={disabled} - role={typeof icon === "string" ? undefined : "img"} - > + <DropdownTriggerIcon disabled={disabled} role={typeof icon === "string" ? undefined : "img"}> {typeof icon === "string" ? <img src={icon} /> : icon} </DropdownTriggerIcon> )} @@ -328,20 +323,14 @@ const DropdownTriggerLabel = styled.span` overflow: hidden; `; -type DropdownTriggerIconProps = { - iconPosition: "before" | "after"; - disabled: boolean; - label: string; -}; -const DropdownTriggerIcon = styled.div<DropdownTriggerIconProps>` - width: ${(props) => props.theme.buttonIconSize}; - height: ${(props) => props.theme.buttonIconSize}; +const DropdownTriggerIcon = styled.span<{ disabled: boolean }>` + display: flex; color: ${(props) => (props.disabled ? props.theme.disabledColor : props.theme.buttonIconColor)}; img, svg { - height: 100%; - width: 100%; + width: ${(props) => props.theme.buttonIconSize}; + height: ${(props) => props.theme.buttonIconSize}; } `; diff --git a/lib/src/paginator/Icons.jsx b/lib/src/paginator/Icons.jsx deleted file mode 100644 index 62ccaf29e..000000000 --- a/lib/src/paginator/Icons.jsx +++ /dev/null @@ -1,45 +0,0 @@ -import React from "react"; - -export const firstIcon = ( - <svg xmlns="http://www.w3.org/2000/svg" width="12.41" height="12" viewBox="0 0 12.41 12"> - <path - id="Path_2463" - data-name="Path 2463" - d="M18.41,16.59,13.82,12l4.59-4.59L17,6l-6,6,6,6ZM6,6H8V18H6Z" - transform="translate(-6 -6)" - /> - </svg> -); - -export const previousIcon = ( - <svg xmlns="http://www.w3.org/2000/svg" width="7.41" height="12" viewBox="0 0 7.41 12"> - <path - id="Path_2459" - data-name="Path 2459" - d="M15.41,7.41,14,6,8,12l6,6,1.41-1.41L10.83,12Z" - transform="translate(-8 -6)" - /> - </svg> -); - -export const nextIcon = ( - <svg xmlns="http://www.w3.org/2000/svg" width="7.41" height="12" viewBox="0 0 7.41 12"> - <path - id="Path_2461" - data-name="Path 2461" - d="M10,6,8.59,7.41,13.17,12,8.59,16.59,10,18l6-6Z" - transform="translate(-8.59 -6)" - /> - </svg> -); - -export const lastIcon = ( - <svg xmlns="http://www.w3.org/2000/svg" width="12.41" height="12" viewBox="0 0 12.41 12"> - <path - id="Path_2465" - data-name="Path 2465" - d="M5.59,7.41,10.18,12,5.59,16.59,7,18l6-6L7,6ZM16,6h2V18H16Z" - transform="translate(-5.59 -6)" - /> - </svg> -); diff --git a/lib/src/paginator/Icons.tsx b/lib/src/paginator/Icons.tsx new file mode 100644 index 000000000..d36b783e1 --- /dev/null +++ b/lib/src/paginator/Icons.tsx @@ -0,0 +1,25 @@ +import React from "react"; + +export const firstIcon = ( + <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" fill="currentColor"> + <path d="M6 18V6h2v12Zm11 0-6-6 6-6 1.4 1.4-4.6 4.6 4.6 4.6Z" /> + </svg> +); + +export const previousIcon = ( + <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" fill="currentColor"> + <path d="m14 18-6-6 6-6 1.4 1.4-4.6 4.6 4.6 4.6Z" /> + </svg> +); + +export const nextIcon = ( + <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" fill="currentColor"> + <path d="M9.4 18 8 16.6l4.6-4.6L8 7.4 9.4 6l6 6Z" /> + </svg> +); + +export const lastIcon = ( + <svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" fill="currentColor"> + <path d="m7 18-1.4-1.4 4.6-4.6-4.6-4.6L7 6l6 6Zm9 0V6h2v12Z" /> + </svg> +); diff --git a/lib/src/paginator/Paginator.tsx b/lib/src/paginator/Paginator.tsx index 723378a75..ce86e379a 100644 --- a/lib/src/paginator/Paginator.tsx +++ b/lib/src/paginator/Paginator.tsx @@ -57,7 +57,6 @@ const DxcPaginator = ({ </TotalItemsContainer> {onPageChange && ( <DxcButton - size="small" mode="secondary" disabled={currentPageInternal === 1 || currentPageInternal === 0} icon={firstIcon} @@ -69,7 +68,6 @@ const DxcPaginator = ({ )} {onPageChange && ( <DxcButton - size="small" mode="secondary" disabled={currentPageInternal === 1 || currentPageInternal === 0} icon={previousIcon} @@ -79,7 +77,7 @@ const DxcPaginator = ({ }} /> )} - {(showGoToPage && ( + {showGoToPage ? ( <PageToSelectContainer> <GoToLabel>{translatedLabels.paginator.goToPageText} </GoToLabel> <SelectContainer> @@ -97,12 +95,11 @@ const DxcPaginator = ({ /> </SelectContainer> </PageToSelectContainer> - )) || ( - <TextContainer>{translatedLabels.paginator.pageOfText(currentPageInternal, totalPages)}</TextContainer> + ) : ( + <span>{translatedLabels.paginator.pageOfText(currentPageInternal, totalPages)}</span> )} {onPageChange && ( <DxcButton - size="small" mode="secondary" disabled={currentPageInternal === totalPages} icon={nextIcon} @@ -114,7 +111,6 @@ const DxcPaginator = ({ )} {onPageChange && ( <DxcButton - size="small" mode="secondary" disabled={currentPageInternal === totalPages} icon={lastIcon} @@ -159,13 +155,6 @@ const ItemsPageContainer = styled.span` align-items: center; margin-right: ${(props) => props.theme.itemsPerPageSelectorMarginRight}; margin-left: ${(props) => props.theme.itemsPerPageSelectorMarginLeft}; - - label { - height: 0px; - } - label + .MuiInput-formControl { - margin-top: 0px; - } `; const ItemsLabel = styled.span` @@ -194,14 +183,6 @@ const PageToSelectContainer = styled.span` display: flex; align-items: center; margin-right: 0.5rem; - - label { - height: 0px; - } - label + .MuiInput-formControl { - margin-top: 0px; - } `; -const TextContainer = styled.span``; export default DxcPaginator; diff --git a/lib/src/select/Option.tsx b/lib/src/select/Option.tsx index ca3b550e0..b3d875a53 100644 --- a/lib/src/select/Option.tsx +++ b/lib/src/select/Option.tsx @@ -43,7 +43,7 @@ const Option = ({ multiple={multiple} role={!(typeof option.icon === "string") ? "img" : undefined} > - {typeof option.icon === "string" ? <OptionIconImg src={option.icon}></OptionIconImg> : option.icon} + {typeof option.icon === "string" ? <img src={option.icon} /> : option.icon} </OptionIcon> )} <OptionContent grouped={isGroupedOption} hasIcon={option.icon ? true : false} multiple={multiple}> @@ -106,12 +106,15 @@ type OptionIconProps = { }; const OptionIcon = styled.span<OptionIconProps>` display: flex; - flex-wrap: wrap; - align-content: center; - height: 24px; - width: 24px; - ${(props) => (props.grouped && !props.multiple ? "padding-left: 16px;" : "padding-left: 8px;")} + padding: 0.125rem; + margin-left: ${(props) => (props.grouped && !props.multiple ? "16px" : "8px")}; color: ${(props) => props.theme.listOptionIconColor}; + + svg, + img { + height: 20px; + width: 20px; + } `; type OptionContentProps = { @@ -122,14 +125,10 @@ type OptionContentProps = { const OptionContent = styled.span<OptionContentProps>` display: flex; justify-content: space-between; + gap: 0.25rem; width: 100%; overflow: hidden; - ${(props) => (props.grouped && !props.multiple && !props.hasIcon ? "padding-left: 16px;" : "padding-left: 8px;")} -`; - -const OptionIconImg = styled.img` - width: 16px; - height: 16px; + margin-left: ${(props) => (props.grouped && !props.multiple && !props.hasIcon ? "16px" : "8px")}; `; const OptionLabel = styled.span` @@ -140,10 +139,13 @@ const OptionLabel = styled.span` const OptionSelectedIndicator = styled.span` display: flex; - height: 16px; - width: 16px; - margin-left: 4px; + align-items: center; color: ${(props) => props.theme.selectedListOptionIconColor}; + + svg { + width: 16px; + height: 16px; + } `; export default React.memo(Option); diff --git a/lib/src/select/Select.stories.tsx b/lib/src/select/Select.stories.tsx index 0e4987e27..0d3c0597d 100644 --- a/lib/src/select/Select.stories.tsx +++ b/lib/src/select/Select.stories.tsx @@ -189,7 +189,29 @@ const url_options = [ { label: "Facebook", value: "facebook", - icon: "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b8/2021_Facebook_icon.svg/2048px-2021_Facebook_icon.svg.png", + icon: ( + <svg + version="1.1" + id="Capa_1" + x="0px" + y="0px" + width="438.536px" + height="438.536px" + viewBox="0 0 438.536 438.536" + fill="#4267B2" + > + <g> + <path + d="M414.41,24.123C398.333,8.042,378.963,0,356.315,0H82.228C59.58,0,40.21,8.042,24.126,24.123 + C8.045,40.207,0.003,59.576,0.003,82.225v274.084c0,22.647,8.042,42.018,24.123,58.102c16.084,16.084,35.454,24.126,58.102,24.126 + h274.084c22.648,0,42.018-8.042,58.095-24.126c16.084-16.084,24.126-35.454,24.126-58.102V82.225 + C438.532,59.576,430.49,40.204,414.41,24.123z M373.155,225.548h-49.963V406.84h-74.802V225.548H210.99V163.02h37.401v-37.402 + c0-26.838,6.283-47.107,18.843-60.813c12.559-13.706,33.304-20.555,62.242-20.555h49.963v62.526h-31.401 + c-10.663,0-17.467,1.853-20.417,5.568c-2.949,3.711-4.428,10.23-4.428,19.558v31.119h56.534L373.155,225.548z" + /> + </g> + </svg> + ), }, { label: "Pinterest", @@ -353,16 +375,29 @@ const Select = () => ( const SelectListbox = () => ( <> <Title title="Listbox" theme="light" level={2} /> - <Title title="Default with opened listbox" theme="light" level={3} /> <ExampleContainer> - <div style={{ display: "flex", gap: "30px", flexDirection: "column", marginBottom: "80px" }}> + <Title + title="List dialog uses a Radix Popover to appear over elements with a certain z-index" + theme="light" + level={3} + /> + <div + style={{ + display: "flex", + flexDirection: "column", + gap: "20px", + height: "150px", + width: "min-content", + marginBottom: "100px", + padding: "20px", + border: "1px solid black", + borderRadius: "4px", + overflow: "auto", + zIndex: "1300", + }} + > <DxcSelect label="Label" options={single_options} optional placeholder="Choose an option" /> - <DxcCheckbox - label="You understand the selection and give your consent" - onChange={() => {}} - labelPosition="after" - /> - <DxcButton label="Submit" onClick={() => {}} size="medium" /> + <button style={{ zIndex: "1", width: "100px" }}>Submit</button> </div> </ExampleContainer> <Title title="Listbox option states" theme="light" level={3} /> @@ -396,7 +431,6 @@ const SelectListbox = () => ( searchable={false} handleOptionOnClick={() => {}} getSelectWidth={() => 360} - /> </ExampleContainer> <ExampleContainer> @@ -447,6 +481,71 @@ const SelectListbox = () => ( getSelectWidth={() => 360} /> </ExampleContainer> + <Title title="Listbox with icons" theme="light" level={3} /> + <ExampleContainer> + <Title title="Icons (SVGs)" theme="light" level={4} /> + <Listbox + id="x" + currentValue="3" + options={icon_options} + visualFocusIndex={-1} + lastOptionIndex={3} + multiple={false} + optional={false} + optionalItem={{ label: "Empty", value: "" }} + searchable={false} + handleOptionOnClick={() => {}} + getSelectWidth={() => 360} + /> + </ExampleContainer> + <ExampleContainer> + <Title title="Icons (Images)" theme="light" level={4} /> + <Listbox + id="x" + currentValue="facebook" + options={url_options} + visualFocusIndex={-1} + lastOptionIndex={6} + multiple={false} + optional={false} + optionalItem={{ label: "Empty", value: "" }} + searchable={false} + handleOptionOnClick={() => {}} + getSelectWidth={() => 360} + /> + </ExampleContainer> + <ExampleContainer> + <Title title="Grouped icons (SVGs)" theme="light" level={4} /> + <Listbox + id="x" + currentValue={["0", "3"]} + options={icon_options_grouped} + visualFocusIndex={-1} + lastOptionIndex={3} + multiple={false} + optional={false} + optionalItem={{ label: "Empty", value: "" }} + searchable={false} + handleOptionOnClick={() => {}} + getSelectWidth={() => 360} + /> + </ExampleContainer> + <ExampleContainer> + <Title title="Grouped icons (Images)" theme="light" level={4} /> + <Listbox + id="x" + currentValue={["facebook", "figma"]} + options={url_options} + visualFocusIndex={-1} + lastOptionIndex={6} + multiple={true} + optional={false} + optionalItem={{ label: "Empty", value: "" }} + searchable={false} + handleOptionOnClick={() => {}} + getSelectWidth={() => 360} + /> + </ExampleContainer> </> ); const SearchableSelect = () => ( @@ -499,18 +598,6 @@ const MultipleGroupedOptionsSelect = () => ( /> </ExampleContainer> ); -const RescaledIcons = () => ( - <ExampleContainer expanded> - <Title title="Rescaled icons displayed" theme="light" level={4} /> - <DxcSelect label="Label" options={url_options} defaultValue="facebook" placeholder="Choose an option" /> - </ExampleContainer> -); -const SelectWithIcons = () => ( - <ExampleContainer expanded> - <Title title="Normal icons displayed" theme="light" level={4} /> - <DxcSelect label="Label" options={icon_options} defaultValue="3" placeholder="Choose an option" /> - </ExampleContainer> -); const SelectMultipleWithIcons = () => ( <ExampleContainer expanded> <Title title="Multiple select with icons" theme="light" level={4} /> @@ -594,31 +681,3 @@ MultipleGroupedOptionsDisplayed.play = async ({ canvasElement }) => { const select = canvas.getByRole("combobox"); await userEvent.click(select); }; - -export const WithIconsDisplayed = SelectWithIcons.bind({}); -WithIconsDisplayed.play = async ({ canvasElement }) => { - const canvas = within(canvasElement); - const select = canvas.getByRole("combobox"); - await userEvent.click(select); -}; - -export const WithRescaledIconsDisplayed = RescaledIcons.bind({}); -WithRescaledIconsDisplayed.play = async ({ canvasElement }) => { - const canvas = within(canvasElement); - const select = canvas.getByRole("combobox"); - await userEvent.click(select); -}; - -export const MultipleWithIconsDisplayed = SelectMultipleWithIcons.bind({}); -MultipleWithIconsDisplayed.play = async ({ canvasElement }) => { - const canvas = within(canvasElement); - const select = canvas.getByRole("combobox"); - await userEvent.click(select); -}; - -export const MultipleGroupedWithIconsDisplayed = MultipleGroupedOptionsSelectWithIcons.bind({}); -MultipleGroupedWithIconsDisplayed.play = async ({ canvasElement }) => { - const canvas = within(canvasElement); - const select = canvas.getByRole("combobox"); - await userEvent.click(select); -}; diff --git a/lib/src/sidenav/Sidenav.stories.tsx b/lib/src/sidenav/Sidenav.stories.tsx index f3ea4d0d0..343aefe33 100644 --- a/lib/src/sidenav/Sidenav.stories.tsx +++ b/lib/src/sidenav/Sidenav.stories.tsx @@ -10,21 +10,34 @@ export default { }; const iconSVG = ( - <svg viewBox="0 0 24 24" fill="currentColor"> - <path d="M0 0h24v24H0z" fill="none" /> - <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" /> + <svg + version="1.1" + id="Capa_1" + x="0px" + y="0px" + width="438.536px" + height="438.536px" + viewBox="0 0 438.536 438.536" + fill="currentColor" + > + <g> + <path + d="M414.41,24.123C398.333,8.042,378.963,0,356.315,0H82.228C59.58,0,40.21,8.042,24.126,24.123 +C8.045,40.207,0.003,59.576,0.003,82.225v274.084c0,22.647,8.042,42.018,24.123,58.102c16.084,16.084,35.454,24.126,58.102,24.126 +h274.084c22.648,0,42.018-8.042,58.095-24.126c16.084-16.084,24.126-35.454,24.126-58.102V82.225 +C438.532,59.576,430.49,40.204,414.41,24.123z M373.155,225.548h-49.963V406.84h-74.802V225.548H210.99V163.02h37.401v-37.402 +c0-26.838,6.283-47.107,18.843-60.813c12.559-13.706,33.304-20.555,62.242-20.555h49.963v62.526h-31.401 +c-10.663,0-17.467,1.853-20.417,5.568c-2.949,3.711-4.428,10.23-4.428,19.558v31.119h56.534L373.155,225.548z" + /> + </g> </svg> ); -const TitleComponent = () => { - return <DxcSidenav.Title>Dxc technology</DxcSidenav.Title>; -}; - export const Chromatic = () => ( <> <ExampleContainer> <Title title="Default sidenav" theme="light" level={4} /> - <DxcSidenav title={<TitleComponent />}> + <DxcSidenav title={<DxcSidenav.Title>Dxc technology</DxcSidenav.Title>}> <DxcSidenav.Section> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ullamcorper consectetur mollis. Suspendisse @@ -41,12 +54,18 @@ export const Chromatic = () => ( </DxcSidenav.Group> </DxcSidenav.Section> <DxcSidenav.Section> - <DxcSidenav.Group collapsable={true} title="Section Group" icon={iconSVG}> + <DxcSidenav.Group + collapsable={true} + title="Section Group" + icon="https://cdn-icons-png.flaticon.com/512/5039/5039041.png" + > <DxcSidenav.Link selected>Group Link</DxcSidenav.Link> <DxcSidenav.Link icon={iconSVG}>Group Link</DxcSidenav.Link> </DxcSidenav.Group> - <DxcSidenav.Link icon={iconSVG}>Single Link</DxcSidenav.Link> - <DxcSidenav.Link>Single Link</DxcSidenav.Link> + <DxcSidenav.Link icon="https://upload.wikimedia.org/wikipedia/commons/7/73/Flat_tick_icon.svg" newWindow> + Single Link + </DxcSidenav.Link> + <DxcSidenav.Link newWindow>Single Link</DxcSidenav.Link> <DxcSidenav.Group collapsable={false} title="Section Group"> <DxcSidenav.Link>Group Link</DxcSidenav.Link> <DxcSidenav.Link>Group Link</DxcSidenav.Link> @@ -55,51 +74,41 @@ export const Chromatic = () => ( </DxcSidenav.Section> </DxcSidenav> </ExampleContainer> + <ExampleContainer pseudoState="pseudo-focus"> + <Title title="Focused options sidenav" theme="light" level={4} /> + <DxcSidenav title={<DxcSidenav.Title>Dxc technology</DxcSidenav.Title>}> + <DxcSidenav.Section> + <p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ullamcorper consectetur mollis. Suspendisse + vitae lacinia libero. + </p> + </DxcSidenav.Section> + <DxcSidenav.Section> + <DxcSidenav.Link>Single Link</DxcSidenav.Link> + <DxcSidenav.Group collapsable={true} title="Collapsable Group"> + <DxcSidenav.Link icon="https://cdn-icons-png.flaticon.com/512/5039/5039041.png">Group Link</DxcSidenav.Link> + </DxcSidenav.Group> + </DxcSidenav.Section> + <DxcSidenav.Section> + <DxcSidenav.Group collapsable={true} title="Collapsable Group"> + <DxcSidenav.Link selected icon={iconSVG}> + Group Link + </DxcSidenav.Link> + </DxcSidenav.Group> + <DxcSidenav.Group collapsable={false} title="Section Group"> + <DxcSidenav.Link>Group Link</DxcSidenav.Link> + </DxcSidenav.Group> + </DxcSidenav.Section> + </DxcSidenav> + </ExampleContainer> </> ); -export const FocusedSidenav = () => ( - <ExampleContainer pseudoState="pseudo-focus"> - <Title title="Default sidenav" theme="light" level={4} /> - <DxcSidenav title={<TitleComponent />}> - <DxcSidenav.Section> - <p> - Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ullamcorper consectetur mollis. Suspendisse vitae - lacinia libero. - </p> - </DxcSidenav.Section> - <DxcSidenav.Section> - <DxcSidenav.Link>Single Link</DxcSidenav.Link> - <DxcSidenav.Link>Single Link</DxcSidenav.Link> - <DxcSidenav.Group collapsable={true} title="Collapsable Group"> - <DxcSidenav.Link>Group Link</DxcSidenav.Link> - <DxcSidenav.Link>Group Link</DxcSidenav.Link> - <DxcSidenav.Link>Group Link</DxcSidenav.Link> - <DxcSidenav.Link>Group Link</DxcSidenav.Link> - </DxcSidenav.Group> - </DxcSidenav.Section> - <DxcSidenav.Section> - <DxcSidenav.Group collapsable={true} title="Collapsable Group"> - <DxcSidenav.Link selected>Group Link</DxcSidenav.Link> - <DxcSidenav.Link>Group Link</DxcSidenav.Link> - </DxcSidenav.Group> - <DxcSidenav.Link>Single Link</DxcSidenav.Link> - <DxcSidenav.Link>Single Link</DxcSidenav.Link> - <DxcSidenav.Group collapsable={false} title="Section Group"> - <DxcSidenav.Link>Group Link</DxcSidenav.Link> - <DxcSidenav.Link>Group Link</DxcSidenav.Link> - <DxcSidenav.Link>Group Link</DxcSidenav.Link> - </DxcSidenav.Group> - </DxcSidenav.Section> - </DxcSidenav> - </ExampleContainer> -); - const CollapsedGroup = () => ( <> <ExampleContainer> <Title title="Default sidenav" theme="light" level={4} /> - <DxcSidenav title={<TitleComponent />}> + <DxcSidenav title={<DxcSidenav.Title>Dxc technology</DxcSidenav.Title>}> <DxcSidenav.Section> <DxcSidenav.Group collapsable={true} title="Collapsable Group" icon={iconSVG}> <DxcSidenav.Link>Group Link</DxcSidenav.Link> @@ -127,7 +136,7 @@ const CollapsedGroup = () => ( const HoverSidenav = () => ( <ExampleContainer pseudoState="pseudo-hover"> <Title title="Default sidenav" theme="light" level={4} /> - <DxcSidenav title={<TitleComponent />}> + <DxcSidenav title={<DxcSidenav.Title>Dxc technology</DxcSidenav.Title>}> <DxcSidenav.Section> <DxcSidenav.Link>Single Link</DxcSidenav.Link> <DxcSidenav.Link>Single Link</DxcSidenav.Link> diff --git a/lib/src/sidenav/Sidenav.tsx b/lib/src/sidenav/Sidenav.tsx index 8eb161a91..b6ce3749a 100644 --- a/lib/src/sidenav/Sidenav.tsx +++ b/lib/src/sidenav/Sidenav.tsx @@ -2,7 +2,6 @@ import React, { forwardRef, Ref, useMemo, useState } from "react"; import styled, { ThemeProvider } from "styled-components"; import { responsiveSizes } from "../common/variables.js"; import { useResponsiveSidenavVisibility } from "../layout/SidenavContext"; - import useTheme from "../useTheme"; import { BackgroundColorProvider } from "../BackgroundColorContext"; import SidenavPropsType, { @@ -85,7 +84,7 @@ const Group = ({ children, title, collapsable = false, icon }: SidenavGroupProps selectedGroup={selectedGroup} > <SidenavContent> - {typeof icon === "string" ? <SidenavIcon src={icon} /> : icon} + {typeof icon === "string" ? <img src={icon} /> : icon} {title} </SidenavContent> {collapsed ? collapsedIcon : collapsableIcon} @@ -93,7 +92,7 @@ const Group = ({ children, title, collapsable = false, icon }: SidenavGroupProps ) : ( title && ( <SidenavGroupTitle> - {typeof icon === "string" ? <SidenavIcon src={icon} /> : icon} + {typeof icon === "string" ? <img src={icon} /> : icon} {title} </SidenavGroupTitle> ) @@ -133,7 +132,7 @@ const Link = forwardRef( {...otherProps} > <SidenavContent> - {typeof icon === "string" ? <SidenavIcon src={icon} /> : icon} + {typeof icon === "string" ? <img src={icon} /> : icon} {children} </SidenavContent> {newWindow && externalLinkIcon} @@ -202,31 +201,33 @@ const SidenavGroup = styled.div` `; const SidenavGroupTitle = styled.span` - svg { - width: 16px; - margin-right: 0.5rem; - } box-sizing: border-box; + display: flex; + align-items: center; + gap: 0.5rem; width: 100%; - + padding: 0.5rem 1.2rem; font-family: ${(props) => props.theme.groupTitleFontFamily}; font-style: ${(props) => props.theme.groupTitleFontStyle}; font-weight: ${(props) => props.theme.groupTitleFontWeight}; font-size: ${(props) => props.theme.groupTitleFontSize}; line-height: 18px; - display: flex; - align-items: center; - margin: 0px; - padding: 0.5rem 1.2rem; + img, + svg { + height: 16px; + width: 16px; + } `; const SidenavGroupTitleButton = styled.button<{ selectedGroup: boolean }>` all: unset; - cursor: pointer; - justify-content: space-between; box-sizing: border-box; + display: flex; + align-items: center; + justify-content: space-between; width: 100%; + padding: 0.5rem 1.2rem; font-family: ${(props) => props.theme.groupTitleFontFamily}; font-style: ${(props) => props.theme.groupTitleFontStyle}; @@ -234,10 +235,8 @@ const SidenavGroupTitleButton = styled.button<{ selectedGroup: boolean }>` font-size: ${(props) => props.theme.groupTitleFontSize}; line-height: 19px; - display: flex; - align-items: center; - margin: 0px; - padding: 0.5rem 1.2rem; + cursor: pointer; + &:focus-visible { outline: 2px solid ${(props) => props.theme.linkFocusColor}; outline-offset: -2px; @@ -256,18 +255,23 @@ const SidenavGroupTitleButton = styled.button<{ selectedGroup: boolean }>` props.selectedGroup ? `color: ${props.theme.groupTitleSelectedFontColor}; background: ${props.theme.groupTitleSelectedBackgroundColor};` : `color: ${props.theme.groupTitleFontColor}; background: transparent;`} + svg { - width: 18px; - height: auto; + height: 16px; + width: 16px; } `; const SidenavLink = styled.a<{ selected: boolean }>` + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + padding: 0.5rem 1.2rem; + box-shadow: 0 0 0 2px transparent; letter-spacing: ${(props) => props.theme.linkFontLetterSpacing}; - text-transform: ${(props) => props.theme.linkFontTextTransform}; text-decoration: ${(props) => props.theme.linkTextDecoration}; - font-family: ${(props) => props.theme.linkFontFamily}; font-style: ${(props) => props.theme.linkFontStyle}; font-weight: ${(props) => props.theme.linkFontWeight}; @@ -279,19 +283,7 @@ const SidenavLink = styled.a<{ selected: boolean }>` ? `color: ${props.theme.linkSelectedFontColor}; background: ${props.theme.linkSelectedBackgroundColor};` : `color: ${props.theme.linkFontColor}; background: transparent;`} - display: flex; - align-items: center; - justify-content: space-between; - - box-shadow: 0 0 0 2px transparent; - - padding: 0.5rem 1.2rem; - cursor: pointer; - svg { - width: 16px; - margin-right: 0.5rem; - } &:hover { ${(props) => @@ -299,35 +291,35 @@ const SidenavLink = styled.a<{ selected: boolean }>` ? `color: ${props.theme.linkSelectedHoverFontColor}; background: ${props.theme.linkSelectedHoverBackgroundColor};` : `color: ${props.theme.linkFontColor}; background: ${props.theme.linkHoverBackgroundColor};`} } - &:focus { outline: 2px solid ${(props) => props.theme.linkFocusColor}; outline-offset: -2px; } - &:active { color: #ffffff; background: #4d4d4d; outline: 2px solid #0095ff; outline-offset: -2px; } + + svg { + height: 16px; + width: 16px; + } `; const SidenavContent = styled.span` display: flex; align-items: center; + gap: 0.5rem; + img, svg { + height: 16px; width: 16px; - margin-right: 0.5rem; } `; -const SidenavIcon = styled.img` - width: 16px; - margin-right: 0.5rem; -`; - DxcSidenav.Section = Section; DxcSidenav.Group = Group; DxcSidenav.Link = Link; diff --git a/lib/src/tabs-nav/NavTabs.stories.tsx b/lib/src/tabs-nav/NavTabs.stories.tsx index 574df92cd..cf03eea53 100644 --- a/lib/src/tabs-nav/NavTabs.stories.tsx +++ b/lib/src/tabs-nav/NavTabs.stories.tsx @@ -15,6 +15,8 @@ const iconSVG = ( </svg> ); +const largeIcon = "https://www.iconpacks.net/icons/1/free-pin-icon-48-thumb.png" + export const Chromatic = () => ( <> <ExampleContainer> @@ -93,10 +95,10 @@ export const Chromatic = () => ( <DxcNavTabs.Tab href="#" disabled icon={iconSVG}> Tab 2 </DxcNavTabs.Tab> - <DxcNavTabs.Tab href="#" icon={iconSVG}> + <DxcNavTabs.Tab href="#" icon={largeIcon}> Tab 3 </DxcNavTabs.Tab> - <DxcNavTabs.Tab href="#" icon={iconSVG}> + <DxcNavTabs.Tab href="#" icon={largeIcon}> Tab 4 </DxcNavTabs.Tab> </DxcNavTabs> @@ -104,7 +106,7 @@ export const Chromatic = () => ( <ExampleContainer> <Title title="With icon position left" theme="light" level={4} /> <DxcNavTabs iconPosition="left"> - <DxcNavTabs.Tab href="#" active icon={iconSVG}> + <DxcNavTabs.Tab href="#" active icon={largeIcon}> Tab 1 </DxcNavTabs.Tab> <DxcNavTabs.Tab href="#" disabled icon={iconSVG}> @@ -121,7 +123,7 @@ export const Chromatic = () => ( <ExampleContainer> <Title title="With icon and notification number" theme="light" level={4} /> <DxcNavTabs> - <DxcNavTabs.Tab href="#" active icon={iconSVG} notificationNumber> + <DxcNavTabs.Tab href="#" active icon={largeIcon} notificationNumber> Tab 1 </DxcNavTabs.Tab> <DxcNavTabs.Tab href="#" disabled icon={iconSVG} notificationNumber={5}> @@ -130,7 +132,7 @@ export const Chromatic = () => ( <DxcNavTabs.Tab href="#" icon={iconSVG} notificationNumber={120}> Tab 3 </DxcNavTabs.Tab> - <DxcNavTabs.Tab href="#" icon={iconSVG}> + <DxcNavTabs.Tab href="#" icon={largeIcon}> Tab 4 </DxcNavTabs.Tab> </DxcNavTabs> @@ -144,7 +146,7 @@ export const Chromatic = () => ( <DxcNavTabs.Tab href="#" disabled icon={iconSVG} notificationNumber={5}> Tab 2 </DxcNavTabs.Tab> - <DxcNavTabs.Tab href="#" icon={iconSVG} notificationNumber={120}> + <DxcNavTabs.Tab href="#" icon={largeIcon} notificationNumber={120}> Tab 3 </DxcNavTabs.Tab> <DxcNavTabs.Tab href="#" icon={iconSVG}> diff --git a/lib/src/tabs-nav/Tab.tsx b/lib/src/tabs-nav/Tab.tsx index 6a05cd8f7..7ccfec128 100644 --- a/lib/src/tabs-nav/Tab.tsx +++ b/lib/src/tabs-nav/Tab.tsx @@ -50,7 +50,7 @@ const DxcTab = forwardRef( > {icon && ( <TabIconContainer iconPosition={iconPosition}> - {typeof icon === "string" ? <TabIcon src={icon} /> : icon} + {typeof icon === "string" ? <img src={icon} /> : icon} </TabIconContainer> )} <LabelContainer> @@ -116,23 +116,18 @@ const Tab = styled.a<TabStyleProps>` }`} `; -const TabIcon = styled.img``; - type TabIconContainerProps = { iconPosition?: "top" | "left"; }; const TabIconContainer = styled.div<TabIconContainerProps>` - max-height: 24px; - max-width: 24px; + display: flex; margin-bottom: ${(props) => props.iconPosition === "top" && "0.375rem"}; margin-right: ${(props) => props.iconPosition === "left" && "0.625rem"}; - overflow: hidden; - display: flex; - align-items: center; + img, svg { - height: 100%; - width: 100%; + height: 24px; + width: 24px; } `; diff --git a/lib/src/tabs/Tab.tsx b/lib/src/tabs/Tab.tsx index cae1719a7..faaf005d1 100644 --- a/lib/src/tabs/Tab.tsx +++ b/lib/src/tabs/Tab.tsx @@ -40,7 +40,7 @@ const Tab = forwardRef( > {tab.icon && ( <TabIconContainer hasLabelAndIcon={hasLabelAndIcon} iconPosition={iconPosition}> - {typeof tab.icon === "string" ? <TabIcon src={tab.icon} /> : tab.icon} + {typeof tab.icon === "string" ? <img src={tab.icon} /> : tab.icon} </TabIconContainer> )} <DxcTypography @@ -163,26 +163,15 @@ const MainLabelContainer = styled.div<MainLabelContainerProps>` `; const TabIconContainer = styled.div<IconProps>` - max-height: 22px; - max-width: 22px; + display: flex; margin-bottom: ${(props) => (props.hasLabelAndIcon && props.iconPosition === "top" && "8px") || ""}; margin-right: ${(props) => (props.hasLabelAndIcon && props.iconPosition === "left" && "12px") || ""}; - overflow: hidden; - display: flex; - align-items: center; + img, svg { - height: 100%; - width: 100%; + height: 22px; + width: 22px; } `; -const TabIcon = styled.img` - width: 100%; - display: inline-flex; - align-items: center; - flex-direction: column; - justify-content: center; -`; - export default React.memo(Tab); diff --git a/lib/src/tabs/Tabs.stories.tsx b/lib/src/tabs/Tabs.stories.tsx index 8bcba64d8..558a02252 100644 --- a/lib/src/tabs/Tabs.stories.tsx +++ b/lib/src/tabs/Tabs.stories.tsx @@ -9,9 +9,8 @@ export default { }; const iconSVG = ( - <svg viewBox="0 0 24 24" fill="currentColor"> - <path d="M0 0h24v24H0z" fill="none" /> - <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" /> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" height="20" width="20" fill="currentColor"> + <path d="m10 17-1.042-.938q-2.083-1.854-3.437-3.177-1.354-1.323-2.136-2.354Q2.604 9.5 2.302 8.646 2 7.792 2 6.896q0-1.854 1.271-3.125T6.396 2.5q1.021 0 1.979.438.958.437 1.625 1.229.667-.792 1.625-1.229.958-.438 1.979-.438 1.854 0 3.125 1.271T18 6.896q0 .896-.292 1.729-.291.833-1.073 1.854-.781 1.021-2.145 2.365-1.365 1.344-3.49 3.26Zm0-2.021q1.938-1.729 3.188-2.948 1.25-1.219 1.989-2.125.74-.906 1.031-1.614.292-.709.292-1.396 0-1.229-.833-2.063Q14.833 4 13.604 4q-.729 0-1.364.302-.636.302-1.094.844L10.417 6h-.834l-.729-.854q-.458-.542-1.114-.844Q7.083 4 6.396 4q-1.229 0-2.063.833-.833.834-.833 2.063 0 .687.271 1.364.271.678.989 1.573.719.896 1.98 2.125Q8 13.188 10 14.979Zm0-5.5Z" /> </svg> ); @@ -74,7 +73,11 @@ const tabsNotification = tabs.map((tab, index) => ({ notificationNumber: (index === 0 && true) || (index === 1 && 5) || (index === 2 && 200), })); -const tabsIcon = tabs.map((tab) => ({ ...tab, icon: iconSVG })); +const tabsIcon = tabs.map((tab, index) => + index <= tabs.length / 2 + ? { ...tab, icon: "https://cdn-icons-png.flaticon.com/512/5039/5039041.png" } + : { ...tab, icon: iconSVG } +); const tabsNotificationIcon = tabsNotification.map((tab) => ({ ...tab, icon: iconSVG })); diff --git a/lib/src/text-input/TextInput.stories.tsx b/lib/src/text-input/TextInput.stories.tsx index 883407545..f1a483237 100644 --- a/lib/src/text-input/TextInput.stories.tsx +++ b/lib/src/text-input/TextInput.stories.tsx @@ -27,7 +27,7 @@ const action = { ), }; -const actionLargeIcon = { +const actionLargeIconSVG = { onClick: () => {}, icon: ( <svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 0 24 24" width="48px" fill="currentColor"> @@ -37,6 +37,11 @@ const actionLargeIcon = { ), }; +const actionLargeIconURL = { + onClick: () => {}, + icon: "https://iconape.com/wp-content/files/yd/367773/svg/logo-linkedin-logo-icon-png-svg.png", +}; + const country = ["Afghanistan"]; const countries = [ "Afghanistan", @@ -99,12 +104,21 @@ export const Chromatic = () => ( <DxcTextInput label="Text input" clearable defaultValue="Text" helperText="Help message" optional /> </ExampleContainer> <ExampleContainer> - <Title title="Clearable and large icon action" theme="light" level={4} /> + <Title title="Clearable and large icon action (SVG)" theme="light" level={4} /> + <DxcTextInput + label="Text input" + defaultValue="Text text text text text text text text text text" + clearable + action={actionLargeIconSVG} + /> + </ExampleContainer> + <ExampleContainer> + <Title title="Clearable and large icon action (URL)" theme="light" level={4} /> <DxcTextInput label="Text input" defaultValue="Text text text text text text text text text text" clearable - action={actionLargeIcon} + action={actionLargeIconURL} /> </ExampleContainer> <ExampleContainer> diff --git a/lib/src/text-input/TextInput.tsx b/lib/src/text-input/TextInput.tsx index c0dc353ac..22aff3531 100644 --- a/lib/src/text-input/TextInput.tsx +++ b/lib/src/text-input/TextInput.tsx @@ -516,7 +516,7 @@ const DxcTextInput = React.forwardRef<RefType, TextInputPropsType>( tabIndex={tabIndex} type="button" > - {typeof action.icon === "string" ? <ActionIcon src={action.icon}></ActionIcon> : action.icon} + {typeof action.icon === "string" ? <img src={action.icon} /> : action.icon} </Action> )} {suffix && ( @@ -703,21 +703,15 @@ const Input = styled.input<CommonBackgroundTypeProps>` } `; -const ActionIcon = styled.img` - width: 16px; - height: 16px; -`; - const Action = styled.button<CommonBackgroundTypeProps>` display: flex; - flex-wrap: wrap; - align-content: center; - height: 24px; - width: 24px; - font-size: 1rem; - font-family: ${(props) => props.theme.fontFamily}; + align-items: center; + justify-content: center; + flex-shrink: 0; border: 1px solid transparent; border-radius: 2px; + width: 24px; + height: 24px; padding: 3px; margin-left: 0.25rem; ${(props) => (props.disabled ? `cursor: not-allowed;` : `cursor: pointer;`)} @@ -788,8 +782,9 @@ const Action = styled.button<CommonBackgroundTypeProps>` } `} - svg { - line-height: 18px; + img, svg { + width: 16px; + height: 16px; } `; diff --git a/website/screens/components/select/code/SelectCodePage.tsx b/website/screens/components/select/code/SelectCodePage.tsx index 2396cd9a1..8f97138a0 100644 --- a/website/screens/components/select/code/SelectCodePage.tsx +++ b/website/screens/components/select/code/SelectCodePage.tsx @@ -76,7 +76,7 @@ const sections = [ <li> <b>Icon: string | SVGSVGElement</b>: Element used as the icon that will be placed before the option label. It can be a url - of an image or an inline SVG. If the url option is the chosen + of an image or an inline SVG. If the URL option is the chosen one, take into account that the component's color styling tokens will not be applied to the image. </li> diff --git a/website/screens/components/text-input/code/TextInputCodePage.tsx b/website/screens/components/text-input/code/TextInputCodePage.tsx index 838ba6958..30662f075 100644 --- a/website/screens/components/text-input/code/TextInputCodePage.tsx +++ b/website/screens/components/text-input/code/TextInputCodePage.tsx @@ -71,7 +71,8 @@ const sections = [ <Code> onClick: function, icon: string | svgIcon, title: string </Code> - {" }"}. + {" }"}. Note that if the icon is an URL (string), the component's + color styling tokens will not be applied to the image. </td> </tr> <tr>