diff --git a/apps/website/pages/components/chip/code.tsx b/apps/website/pages/components/chip/code.tsx new file mode 100644 index 0000000000..edcba505f0 --- /dev/null +++ b/apps/website/pages/components/chip/code.tsx @@ -0,0 +1,19 @@ +import Head from "next/head"; +import type { ReactElement } from "react"; +import ChipCodePage from "screens/components/chip/code/ChipCodePage"; +import ChipPageLayout from "screens/components/chip/ChipPageLayout"; + +const Code = () => { + return ( + <> + + Chip Code — Halstack Design System + + + + ); +}; + +Code.getLayout = (page: ReactElement) => {page}; + +export default Code; diff --git a/apps/website/pages/components/chip/index.tsx b/apps/website/pages/components/chip/index.tsx index 99f10ff97c..147b709d5e 100644 --- a/apps/website/pages/components/chip/index.tsx +++ b/apps/website/pages/components/chip/index.tsx @@ -1,6 +1,6 @@ import Head from "next/head"; import type { ReactElement } from "react"; -import ChipCodePage from "screens/components/chip/code/ChipCodePage"; +import ChipOverviewPage from "screens/components/chip/overview/ChipOverviewPage"; import ChipPageLayout from "screens/components/chip/ChipPageLayout"; const Index = () => { @@ -9,13 +9,11 @@ const Index = () => { Chip — 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/chip/specifications.tsx b/apps/website/pages/components/chip/specifications.tsx deleted file mode 100644 index fea0962888..0000000000 --- a/apps/website/pages/components/chip/specifications.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Head from "next/head"; -import type { ReactElement } from "react"; -import ChipSpecsPage from "screens/components/chip/specs/ChipSpecsPage"; -import ChipPageLayout from "screens/components/chip/ChipPageLayout"; - -const Specifications = () => { - return ( - <> - - Chip Specs — Halstack Design System - - - - ); -}; - -Specifications.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; - -export default Specifications; diff --git a/apps/website/pages/components/chip/usage.tsx b/apps/website/pages/components/chip/usage.tsx deleted file mode 100644 index 98f85c4e95..0000000000 --- a/apps/website/pages/components/chip/usage.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Head from "next/head"; -import type { ReactElement } from "react"; -import ChipUsagePage from "screens/components/chip/usage/ChipUsagePage"; -import ChipPageLayout from "screens/components/chip/ChipPageLayout"; - -const Usage = () => { - return ( - <> - - Chip Usage — Halstack Design System - - - - ); -}; - -Usage.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; - -export default Usage; diff --git a/apps/website/screens/components/chip/ChipPageLayout.tsx b/apps/website/screens/components/chip/ChipPageLayout.tsx index cf36827872..dc88a9d4ef 100644 --- a/apps/website/screens/components/chip/ChipPageLayout.tsx +++ b/apps/website/screens/components/chip/ChipPageLayout.tsx @@ -6,9 +6,8 @@ import { ReactNode } from "react"; const ChipPageHeading = ({ children }: { children: ReactNode }) => { const tabs = [ - { label: "Code", path: "/components/chip" }, - { label: "Usage", path: "/components/chip/usage" }, - { label: "Specifications", path: "/components/chip/specifications" }, + { label: "Overview", path: "/components/chip" }, + { label: "Code", path: "/components/chip/code" }, ]; return ( @@ -17,9 +16,10 @@ const ChipPageHeading = ({ children }: { children: ReactNode }) => { - Chips are elements that represent status, complementary information, or association between elements. + A chip is a compact, interactive UI element used to represent small pieces of information, actions, or + selections. - + {children} diff --git a/apps/website/screens/components/chip/code/ChipCodePage.tsx b/apps/website/screens/components/chip/code/ChipCodePage.tsx index a6b77e3424..1810934198 100644 --- a/apps/website/screens/components/chip/code/ChipCodePage.tsx +++ b/apps/website/screens/components/chip/code/ChipCodePage.tsx @@ -23,40 +23,31 @@ const sections = [ - label + disabled - string + boolean - Text to be placed on the chip. - - - - - prefixIcon + If true, the component will be disabled. - string | {"(React.ReactNode & React.SVGProps )"} + false + + + label - - Material Symbol - {" "} - name or SVG element as the icon that will be placed before the chip label. When using Material Symbols, - replace spaces with underscores. By default they are outlined if you want it to be filled prefix the - symbol name with "filled_". + string + Text to be placed on the chip. - - suffixIcon + margin - string | {"(React.ReactNode & React.SVGProps )"} + 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | Margin - - Material Symbol - {" "} - name or SVG element as the icon that will be placed after the chip label. When using Material Symbols, - replace spaces with underscores. By default they are outlined if you want it to be filled prefix the - symbol name with "filled_". + 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. - @@ -83,23 +74,32 @@ const sections = [ - - disabled + prefixIcon - boolean + string | {"(React.ReactNode & React.SVGProps )"} - If true, the component will be disabled. - false + + Material Symbol + {" "} + name or SVG element as the icon that will be placed before the chip label. When using Material Symbols, + replace spaces with underscores. By default they are outlined if you want it to be filled prefix the + symbol name with "filled_". + - - margin + suffixIcon - 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | Margin + string | {"(React.ReactNode & React.SVGProps )"} - 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. + + Material Symbol + {" "} + name or SVG element as the icon that will be placed after the chip label. When using Material Symbols, + replace spaces with underscores. By default they are outlined if you want it to be filled prefix the + symbol name with "filled_". - @@ -143,7 +143,7 @@ const ChipCodePage = () => { return ( - + diff --git a/apps/website/screens/components/chip/overview/ChipOverviewPage.tsx b/apps/website/screens/components/chip/overview/ChipOverviewPage.tsx new file mode 100644 index 0000000000..9d198e64b0 --- /dev/null +++ b/apps/website/screens/components/chip/overview/ChipOverviewPage.tsx @@ -0,0 +1,214 @@ +import { DxcBulletedList, DxcFlex, DxcLink, DxcParagraph, DxcTable } from "@dxc-technology/halstack-react"; +import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; +import QuickNavContainer from "@/common/QuickNavContainer"; +import DocFooter from "@/common/DocFooter"; +import anatomy from "./images/chip-anatomy.png"; +import Example from "@/common/example/Example"; +import categorization from "./examples/categorization"; +import filter from "./examples/filter"; +import spacing from "./images/chip-spacing.png"; +import Image from "@/common/Image"; +import Link from "next/link"; + +const sections = [ + { + title: "Introduction", + content: ( + + Chips are versatile components that allow users to display and manage information in a compact format. They are + commonly used to represent selected options, tags, filters, or interactive elements within an interface. Their + lightweight and flexible design makes them ideal for enhancing user experience by enabling quick and organized + interactions. + + ), + }, + { + title: "Anatomy", + content: ( + <> + Chip's anatomy + + + Prefix (Optional): the prefix can be an icon or an action icon that provides + additional context or functionality. + + + Label: the primary text that conveys the chip's meaning, such as a tag name or a selected + option. It should be concise, clear, and relevant to the chip's function. + + + Suffix (Optional): the suffix can be an icon or an action icon that enhances + interactivity. + + + + ), + }, + { + title: "Using chips", + subSections: [ + { + title: "Categorization", + content: ( + <> + + Chips are commonly used to organize content by grouping related topics, products, or subjects. They often + serve as a summary of the page's content. When using chips for categorization, ensure that they are + relevant to the displayed information to maintain clarity and usability. + + + + ), + }, + { + title: "Faceted search filters", + content: ( + <> + + When used alongside the select component, chips serve as effective filter facets, allowing users to refine + search results by choosing and removing specific attributes. This combination enables users to include or + exclude preferences directly from their queries. For faceted filtering, chips should be dismissible, + ensuring effortless adjustments and a more intuitive selection experience. + + + + ), + }, + { + title: "Chips vs. Badges", + content: ( + <> + + While{" "} + + badges + {" "} + and chips share a similar visual style, they serve different purposes in a user interface:{" "} + chips are interactive, while badges are static indicators. + + + + + Component + Use case + + + + + + Chip + + + Chips help users categorize, filter, or organize information. They often include keywords or + metadata, providing quick access to related content and aiding navigation. + + + + + Badge + + + Badges function as visual indicators, displaying status or contextual information. They are + non-interactive and rely on color and text to communicate meaning. + + + + + + ), + }, + ], + }, + { + title: "Best practices", + subSections: [ + { + title: "Keep labels concise and meaningful", + content: ( + + + Labels should be short and clear, ideally one or two words. + + + Avoid long text that may cause truncation or wrapping issues. + + + Use sentence case for readability (e.g., "New York" instead of "NEW YORK"). + + + ), + }, + { + title: "Avoid overloading the UI with too many chips", + content: ( + <> + + + Use chips only when necessary to avoid clutter. + + + Group related chips logically and consider collapsible chip groups if the list becomes + too long. + + + Chip's spacing + + ), + }, + { + title: "Ensure icons are contextually relevant and avoid redundancy", + content: ( + <> + + While the component configuration is flexible enough to allow multiple icons or action icons, it is{" "} + not recommended to use two icons or two action icons within the same chip. Instead, a{" "} + balanced approach should be followed: pairing one icon (to provide + context) with one action icon (to enable an interaction). + + + + Icons should add value to the chip, not just be decorative. + + + Ensure that icons are easy to recognize and understand within the chip's context. The + selected icon should accurately represent the chip's purpose, while the action icon should clearly + indicate the interaction it triggers. + + + Icons should not compete for attention or convey conflicting messages. Instead, they + should complement each other to enhance usability. + + + Follow the guideline: one informational icon + one action icon (if needed)—avoid using + two icons of the same type. + + + + ), + }, + { + title: "Manage chip overflow gracefully", + content: ( + + + If there are too many chips in a row, consider horizontal scrolling or wrapping. + + + For dynamic content, provide a "Show more" option to avoid overwhelming the user. + + + ), + }, + ], + }, +]; + +const ChipOverviewPage = () => ( + + + + + + +); +export default ChipOverviewPage; diff --git a/apps/website/screens/components/chip/overview/examples/categorization.ts b/apps/website/screens/components/chip/overview/examples/categorization.ts new file mode 100644 index 0000000000..d2dd832054 --- /dev/null +++ b/apps/website/screens/components/chip/overview/examples/categorization.ts @@ -0,0 +1,21 @@ +import { DxcChip, DxcInset, DxcFlex } from "@dxc-technology/halstack-react"; + +const code = `() => { + return ( + + + {}} /> + {}} /> + {}} /> + + + ); +}`; + +const scope = { + DxcChip, + DxcInset, + DxcFlex, +}; + +export default { code, scope }; diff --git a/apps/website/screens/components/chip/overview/examples/filter.ts b/apps/website/screens/components/chip/overview/examples/filter.ts new file mode 100644 index 0000000000..39fd2e7951 --- /dev/null +++ b/apps/website/screens/components/chip/overview/examples/filter.ts @@ -0,0 +1,54 @@ +import { DxcChip, DxcInset, DxcFlex, DxcSelect, DxcHeading } from "@dxc-technology/halstack-react"; +import { useState } from "react"; + +const code = `() => { +const roles = ["Admin", "Security Analyst", "Auditor", "Read-Only User"]; + const [selectedRoles, setSelectedRoles] = useState([roles[0]]); + + const handleSelectChange = ({value}) => { + setSelectedRoles(value); + }; + const handleRemoveRole = (roleToRemove) => { + setSelectedRoles(selectedRoles.filter((role) => role !== roleToRemove)); + }; + + return ( + + + ({ label: role, value: role }))} + onChange={handleSelectChange} + value={selectedRoles} + multiple + /> + + + + {selectedRoles.map((role) => ( + handleRemoveRole(role)} + /> + ))} + + + + + ); +}`; + +const scope = { + DxcChip, + DxcFlex, + DxcHeading, + DxcInset, + DxcSelect, + useState +}; + +export default { code, scope }; diff --git a/apps/website/screens/components/chip/overview/images/chip-anatomy.png b/apps/website/screens/components/chip/overview/images/chip-anatomy.png new file mode 100644 index 0000000000..ef136349cb Binary files /dev/null and b/apps/website/screens/components/chip/overview/images/chip-anatomy.png differ diff --git a/apps/website/screens/components/chip/overview/images/chip-spacing.png b/apps/website/screens/components/chip/overview/images/chip-spacing.png new file mode 100644 index 0000000000..960982e926 Binary files /dev/null and b/apps/website/screens/components/chip/overview/images/chip-spacing.png differ diff --git a/apps/website/screens/components/chip/specs/ChipSpecsPage.tsx b/apps/website/screens/components/chip/specs/ChipSpecsPage.tsx deleted file mode 100644 index c82afaf2b0..0000000000 --- a/apps/website/screens/components/chip/specs/ChipSpecsPage.tsx +++ /dev/null @@ -1,423 +0,0 @@ -import { DxcBulletedList, DxcFlex, DxcTable, DxcParagraph } from "@dxc-technology/halstack-react"; -import QuickNavContainer from "@/common/QuickNavContainer"; -import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; -import DocFooter from "@/common/DocFooter"; -import Figure from "@/common/Figure"; -import Image from "@/common/Image"; -import Code from "@/common/Code"; -import specsImage from "./images/chip_specs.png"; -import statesImage from "./images/chip_states_container.png"; -import prefixSuffixStatesImage from "./images/chip_states_action.png"; -import anatomyImage from "./images/chip_anatomy.png"; - -const sections = [ - { - title: "Specifications", - content: ( -
- Chip design specifications -
- ), - }, - { - title: "States", - content: ( - <> - - The chip component container states are enabled and disabled: - -
- Chip states -
- - The chip action item has the following states: enabled, hover,{" "} - focus, active and disabled: - -
- Chip prefix and suffix states -
- - ), - }, - { - title: "Anatomy", - content: ( - <> - Chip anatomy - - Container - - Prefix (Optional) - - Label - - Suffix (Optional) - - - - ), - }, - { - title: "Design tokens", - subSections: [ - { - title: "Color", - content: ( - - - - Component token - Element - Core token - Value - - - - - - activeIconColor - - Container:active - - color-black - - #000000 - - - - backgroundColor - - Container - - color-grey-200 - - #e6e6e6 - - - - borderColor - - Container:border - - color-transparent - - transparent - - - - disabledBackgroundColor - - Container:disabled - - color-grey-100 - - #f2f2f2 - - - - disabledFontcolor - - Label:disabled - - color-grey-500 - - #999999 - - - - disabledIconColor - - Icon:disabled - - color-grey-500 - - #999999 - - - - focusColor - - Focus outline - - color-blue-600 - - #0095ff - - - - fontColor - - Label - - color-black - - #000000 - - - - hoverIconColor - - Container:hover - - color-grey-900 - - #333333 - - - - iconColor - - Icon - - color-grey-800 - - #4d4d4d - - - - ), - }, - { - title: "Typography", - content: ( - - - - Component token - Element - Core token - Value - - - - - - fontFamily - - Label - - font-family-sans - - 'Open Sans', sans-serif - - - - fontSize - - Label - - font-scale-03 - - 1rem / 16px - - - - fontStyle - - Label - - font-style-normal - - normal - - - - fontWeight - - Label - - font-weight-regular - - 400 - - - - ), - }, - { - title: "Spacing", - content: ( - - - - Component token - Element - Core token - Value - - - - - - contentPaddingLeft - - Container - - spacing-16 - - 1rem / 16px - - - - contentPaddingRight - - Container - - spacing-16 - - 1rem / 16px - - - - contentPaddingTop - - Container - - spacing-0 - - 0rem / 0px - - - - contentPaddingBottom - - Container - - spacing-0 - - 0rem / 0px - - - - iconSpacing - - Icon - - spacing-8 - - 0.5rem / 8px - - - - ), - }, - { - title: "Border", - content: ( - - - - Property - Element - Core token - Value - - - - - - border-width - - Chip container - - border-width-0 - - 0rem / 0px - - - - border-style - - Chip container - - border-style-none - - none - - - - border-radius - - Chip container - - border-radius-full - - 9999px - - - - border-width - - Focus border - - border-width-2 - - 2px - - - - border-style - - Focus border - - border-style-solid - - solid - - - - border-radius - - Focus border - - border-radius-medium - - 0.25rem / 4px - - - - ), - }, - { - title: "Size", - content: ( - - - - Component token - Element - Core token - Value - - - - - - iconSize - - Prefix/Suffix - - size-icon-large - - 24x24px - - - - ), - }, - ], - }, -]; - -const ChipSpecsPage = () => { - return ( - - - - - - - ); -}; - -export default ChipSpecsPage; diff --git a/apps/website/screens/components/chip/specs/images/chip_anatomy.png b/apps/website/screens/components/chip/specs/images/chip_anatomy.png deleted file mode 100644 index 33ababa249..0000000000 Binary files a/apps/website/screens/components/chip/specs/images/chip_anatomy.png and /dev/null differ diff --git a/apps/website/screens/components/chip/specs/images/chip_specs.png b/apps/website/screens/components/chip/specs/images/chip_specs.png deleted file mode 100644 index eb805bc760..0000000000 Binary files a/apps/website/screens/components/chip/specs/images/chip_specs.png and /dev/null differ diff --git a/apps/website/screens/components/chip/specs/images/chip_states_action.png b/apps/website/screens/components/chip/specs/images/chip_states_action.png deleted file mode 100644 index 6e37083ab4..0000000000 Binary files a/apps/website/screens/components/chip/specs/images/chip_states_action.png and /dev/null differ diff --git a/apps/website/screens/components/chip/specs/images/chip_states_container.png b/apps/website/screens/components/chip/specs/images/chip_states_container.png deleted file mode 100644 index 961986709c..0000000000 Binary files a/apps/website/screens/components/chip/specs/images/chip_states_container.png and /dev/null differ diff --git a/apps/website/screens/components/chip/usage/ChipUsagePage.tsx b/apps/website/screens/components/chip/usage/ChipUsagePage.tsx deleted file mode 100644 index eadf79c656..0000000000 --- a/apps/website/screens/components/chip/usage/ChipUsagePage.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { DxcBulletedList, DxcFlex } from "@dxc-technology/halstack-react"; -import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; -import QuickNavContainer from "@/common/QuickNavContainer"; -import DocFooter from "@/common/DocFooter"; - -const sections = [ - { - title: "Usage", - content: ( - - - Do not use chips instead of buttons since they have a total different aim in the UI. - - Make the content of the label clear and simple. - Use chips to make tasks easier for the user. - - ), - }, -]; - -const ChipUsagePage = () => { - return ( - - - - - - - ); -}; - -export default ChipUsagePage; diff --git a/packages/lib/src/chip/Chip.stories.tsx b/packages/lib/src/chip/Chip.stories.tsx index 0950b12fe9..c9edd3e333 100644 --- a/packages/lib/src/chip/Chip.stories.tsx +++ b/packages/lib/src/chip/Chip.stories.tsx @@ -1,7 +1,6 @@ import { userEvent } from "@storybook/test"; import ExampleContainer from "../../.storybook/components/ExampleContainer"; import Title from "../../.storybook/components/Title"; -import { HalstackProvider } from "../HalstackContext"; import DxcChip from "./Chip"; import { Meta, StoryObj } from "@storybook/react"; @@ -39,14 +38,6 @@ const smallIconSVG = ( ); -const opinionatedTheme = { - chip: { - baseColor: "#e6e6e6", - fontColor: "#000000", - iconColor: "#4d4d4d", - }, -}; - const Chip = () => ( <> @@ -132,43 +123,6 @@ const Chip = () => ( <DxcChip label="xxlarge" margin="xxlarge" /> </ExampleContainer> - <Title title="Opinionated theme" theme="light" level={2} /> - <ExampleContainer> - <Title title="Chip with prefix and suffix" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcChip label="Chip" prefixIcon={iconSVG} suffixIcon="filled_check_circle" /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer> - <Title title="Chip with prefix and suffix" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcChip label="Chip" disabled prefixIcon={iconSVG} suffixIcon="filled_check_circle" /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer pseudoState="pseudo-hover"> - <Title title="Hovered" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcChip - label="Chip" - prefixIcon={iconSVG} - suffixIcon={iconSVG} - onClickPrefix={() => {}} - onClickSuffix={() => {}} - /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer pseudoState="pseudo-active"> - <Title title="Actived" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcChip - label="Chip" - prefixIcon={iconSVG} - suffixIcon={iconSVG} - onClickPrefix={() => {}} - onClickSuffix={() => {}} - /> - </HalstackProvider> - </ExampleContainer> </> ); diff --git a/packages/lib/src/chip/Chip.tsx b/packages/lib/src/chip/Chip.tsx index b5434cef32..6ee1113cd6 100644 --- a/packages/lib/src/chip/Chip.tsx +++ b/packages/lib/src/chip/Chip.tsx @@ -1,55 +1,9 @@ -import { useContext } from "react"; -import styled, { ThemeProvider } from "styled-components"; +import styled from "styled-components"; import { getMargin } from "../common/utils"; import { spaces } from "../common/variables"; import DxcIcon from "../icon/Icon"; -import HalstackContext from "../HalstackContext"; import ChipPropsType from "./types"; - -const DxcChip = ({ - label, - suffixIcon, - prefixIcon, - onClickSuffix, - onClickPrefix, - disabled, - margin, - tabIndex = 0, -}: ChipPropsType): JSX.Element => { - const colorsTheme = useContext(HalstackContext); - - return ( - <ThemeProvider theme={colorsTheme.chip}> - <Chip disabled={disabled} margin={margin}> - {prefixIcon && ( - <IconContainer - role={typeof onClickPrefix === "function" ? "button" : undefined} - aria-label={typeof onClickPrefix === "function" ? "Prefix Action" : undefined} - disabled={disabled} - interactive={typeof onClickPrefix === "function" && !disabled} - tabIndex={typeof onClickPrefix === "function" && !disabled ? tabIndex : -1} - onClick={() => onClickPrefix && !disabled && onClickPrefix()} - > - {typeof prefixIcon === "string" ? <DxcIcon icon={prefixIcon} /> : prefixIcon} - </IconContainer> - )} - {label && <LabelContainer disabled={disabled}>{label}</LabelContainer>} - {suffixIcon && ( - <IconContainer - role={typeof onClickSuffix === "function" ? "button" : undefined} - aria-label={typeof onClickSuffix === "function" ? "Suffix Action" : undefined} - disabled={disabled} - interactive={typeof onClickSuffix === "function" && !disabled} - tabIndex={typeof onClickSuffix === "function" && !disabled ? tabIndex : -1} - onClick={() => !disabled && onClickSuffix?.()} - > - {typeof suffixIcon === "string" ? <DxcIcon icon={suffixIcon} /> : suffixIcon} - </IconContainer> - )} - </Chip> - </ThemeProvider> - ); -}; +import ActionIcon from "../action-icon/ActionIcon"; const calculateWidth = (margin: ChipPropsType["margin"]) => `calc(100% - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})`; @@ -58,20 +12,12 @@ const Chip = styled.div<{ margin: ChipPropsType["margin"]; disabled: ChipPropsTy box-sizing: border-box; display: inline-flex; align-items: center; - gap: ${(props) => props.theme.iconSpacing}; - min-height: 40px; + gap: var(--spacing-gap-s); + min-height: var(--height-xl); max-width: ${(props) => calculateWidth(props.margin)}; - background-color: ${(props) => - (props.disabled && props.theme.disabledBackgroundColor) || props.theme.backgroundColor}; - border-radius: ${(props) => props.theme.borderRadius}; - border-width: ${(props) => props.theme.borderThickness}; - border-style: ${(props) => props.theme.borderStyle}; - border-color: ${(props) => props.theme.borderColor}; - - padding-top: ${(props) => props.theme.contentPaddingTop}; - padding-bottom: ${(props) => props.theme.contentPaddingBottom}; - padding-left: ${(props) => props.theme.contentPaddingLeft}; - padding-right: ${(props) => props.theme.contentPaddingRight}; + background-color: var(--color-bg-neutral-light); + border-radius: var(--border-radius-xl); + padding: var(--spacing-padding-none) var(--spacing-padding-m); margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")}; margin-top: ${(props) => props.margin && typeof props.margin === "object" && props.margin.top ? spaces[props.margin.top] : ""}; @@ -85,11 +31,10 @@ const Chip = styled.div<{ margin: ChipPropsType["margin"]; disabled: ChipPropsTy `; const LabelContainer = styled.span<{ disabled: ChipPropsType["disabled"] }>` - font-size: ${(props) => props.theme.fontSize}; - font-family: ${(props) => props.theme.fontFamily}; - font-weight: ${(props) => props.theme.fontWeight}; - font-style: ${(props) => props.theme.fontStyle}; - color: ${(props) => (props.disabled ? props.theme.disabledFontColor : props.theme.fontColor)}; + font-size: var(--typography-label-l); + font-family: var(--typography-font-family); + font-weight: var(--typography-label-regular); + color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-dark)")}; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; @@ -97,33 +42,58 @@ const LabelContainer = styled.span<{ disabled: ChipPropsType["disabled"] }>` const IconContainer = styled.div<{ disabled: ChipPropsType["disabled"]; - interactive: boolean; }>` display: flex; - border-radius: 0.25rem; - color: ${(props) => (props.disabled ? props.theme.disabledIconColor : props.theme.iconColor)}; - ${({ interactive }) => interactive && "cursor: pointer;"} - - ${(props) => - props.interactive && - ` - &:hover { - color: ${props.theme.hoverIconColor}; - } - &:focus, - &:focus-visible { - outline: ${props.theme.focusBorderThickness} ${props.theme.focusBorderStyle} ${props.theme.focusColor}; - } - &:active { - color: ${props.theme.activeIconColor}; - } - `} - - font-size: ${(props) => props.theme.iconSize}; + border-radius: var(--border-radius-xs); + color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-dark)")}; + font-size: var(--height-s); svg { - width: ${(props) => props.theme.iconSize}; - height: ${(props) => props.theme.iconSize}; + width: 24px; + height: var(--height-s); } `; +const DxcChip = ({ + label, + suffixIcon, + prefixIcon, + onClickSuffix, + onClickPrefix, + disabled, + margin, + tabIndex = 0, +}: ChipPropsType) => ( + <Chip disabled={disabled} margin={margin}> + {prefixIcon && + (typeof onClickPrefix === "function" ? ( + <ActionIcon + disabled={disabled} + icon={prefixIcon} + onClick={onClickPrefix} + tabIndex={tabIndex} + title="Prefix Action" + /> + ) : ( + <IconContainer disabled={disabled}> + {typeof prefixIcon === "string" ? <DxcIcon icon={prefixIcon} /> : prefixIcon} + </IconContainer> + ))} + {label && <LabelContainer disabled={disabled}>{label}</LabelContainer>} + {suffixIcon && + (typeof onClickSuffix === "function" ? ( + <ActionIcon + disabled={disabled} + icon={suffixIcon} + onClick={onClickSuffix} + tabIndex={tabIndex} + title="Suffix Action" + /> + ) : ( + <IconContainer disabled={disabled}> + {typeof suffixIcon === "string" ? <DxcIcon icon={suffixIcon} /> : suffixIcon} + </IconContainer> + ))} + </Chip> +); + export default DxcChip;