From f0985ee98212ee0ecd69b1b46127dde7de9c160f Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Tue, 4 Feb 2025 15:52:18 +0100 Subject: [PATCH 01/12] Reimplementation of the Checkbox component with new CSS variables --- packages/lib/src/checkbox/Checkbox.tsx | 337 +++++++++++++------------ packages/lib/src/index.ts | 2 +- 2 files changed, 182 insertions(+), 157 deletions(-) diff --git a/packages/lib/src/checkbox/Checkbox.tsx b/packages/lib/src/checkbox/Checkbox.tsx index a7c6a730a5..08b37b02dd 100644 --- a/packages/lib/src/checkbox/Checkbox.tsx +++ b/packages/lib/src/checkbox/Checkbox.tsx @@ -1,115 +1,9 @@ import { useContext, useState, useRef, useId, forwardRef, KeyboardEvent } from "react"; import styled, { ThemeProvider } from "styled-components"; -import { AdvancedTheme, spaces } from "../common/variables"; import { getMargin } from "../common/utils"; import HalstackContext, { HalstackLanguageContext } from "../HalstackContext"; import CheckboxPropsType, { RefType } from "./types"; -const checkedIcon = ( - - - -); - -const DxcCheckbox = forwardRef( - ( - { - checked, - defaultChecked = false, - value, - label = "", - labelPosition = "before", - name = "", - disabled = false, - optional = false, - readOnly = false, - onChange, - margin, - size = "fitContent", - tabIndex = 0, - ariaLabel = "Checkbox", - }, - ref - ): JSX.Element => { - const labelId = `label-checkbox-${useId()}`; - const [innerChecked, setInnerChecked] = useState(defaultChecked); - const checkboxRef = useRef(null); - const colorsTheme = useContext(HalstackContext); - const translatedLabels = useContext(HalstackLanguageContext); - - const handleCheckboxChange = () => { - if (!disabled && !readOnly) { - if (document.activeElement !== checkboxRef.current) { - checkboxRef.current?.focus(); - } - if (checked == null) { - setInnerChecked((innerCurrentlyChecked) => !innerCurrentlyChecked); - } - onChange?.(!(checked ?? innerChecked)); - } - }; - - const handleKeyboard = (event: KeyboardEvent) => { - switch (event.key) { - case " ": - event.preventDefault(); - handleCheckboxChange(); - break; - default: - break; - } - }; - - return ( - - - {label && ( - - {label} - {optional && ` ${translatedLabels.formFields.optionalLabel}`} - - )} - - - - {(checked ?? innerChecked) && checkedIcon} - - - - - ); - } -); - const sizes = { small: "120px", medium: "240px", @@ -118,57 +12,75 @@ const sizes = { fitContent: "fit-content", }; +const spaces = { + xxsmall: "var(--spacing-padding-xxs)", + xsmall: "var(--spacing-padding-xs)", + small: "var(--spacing-padding-s)", + medium: "var(--spacing-padding-m)", + large: "var(--spacing-padding-l)", + xlarge: "var(--spacing-padding-xl)", + xxlarge: "var(--spacing-padding-xxl)", +}; + const calculateWidth = (margin: CheckboxPropsType["margin"], size: CheckboxPropsType["size"]) => size === "fillParent" ? `calc(${sizes[size]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` : size && sizes[size]; -const getDisabledColor = (theme: AdvancedTheme["checkbox"], element: string) => { +const getDisabledColor = (element: string) => { switch (element) { case "check": - return theme.disabledCheckColor; + return "var(--color-fg-neutral-bright)"; case "background": - return theme.disabledBackgroundColorChecked; + return "var(--color-fg-neutral-medium)"; case "border": - return theme.disabledBorderColor; + return "var(--border-color-neutral-medium)"; case "label": - return theme.disabledFontColor; + return "var(--color-fg-neutral-medium)"; default: return undefined; } }; -const getReadOnlyColor = (theme: AdvancedTheme["checkbox"], element: string) => { +const getReadOnlyColor = (element: string) => { switch (element) { case "check": - return theme.readOnlyCheckColor; + return "var(--color-fg-neutral-bright)"; case "background": - return theme.readOnlyBackgroundColorChecked; + return "var(--color-fg-neutral-medium)"; case "hoverBackground": - return theme.hoverReadOnlyBackgroundColorChecked; + return "var(--color-bg-neutral-stronger)"; case "border": - return theme.readOnlyBorderColor; + return "var(--border-color-neutral-strong)"; case "hoverBorder": - return theme.hoverReadOnlyBorderColor; + return "var(--border-color-neutral-stronger)"; + case "activeBorder": + return "var(--border-color-neutral-strongest)"; + case "activeBackground": + return "var(--color-bg-neutral-strongest)"; default: return undefined; } }; -const getEnabledColor = (theme: AdvancedTheme["checkbox"], element: string) => { +const getEnabledColor = (element: string) => { switch (element) { case "check": - return theme.checkColor; + return "var(--color-fg-neutral-bright)"; case "background": - return theme.backgroundColorChecked; + return "var(--color-bg-secondary-strong)"; case "hoverBackground": - return theme.hoverBackgroundColorChecked; + return "var(--color-bg-secondary-stronger)"; case "border": - return theme.borderColor; + return "var(--border-color-secondary-strong)"; case "hoverBorder": - return theme.hoverBorderColor; + return "var(--border-color-secondary-stronger)"; case "label": - return theme.fontColor; + return "var(--color-fg-neutral-dark)"; + case "activeBorder": + return "var(--border-color-secondary-strongest)"; + case "activeBackground": + return "var(--color-bg-secondary-strongest)"; default: return undefined; } @@ -179,11 +91,10 @@ const LabelContainer = styled.span<{ labelPosition: CheckboxPropsType["labelPosition"]; }>` order: ${(props) => (props.labelPosition === "before" ? 0 : 1)}; - color: ${(props) => - props.disabled ? getDisabledColor(props.theme, "label") : getEnabledColor(props.theme, "label")}; - font-family: ${(props) => props.theme.fontFamily}; - font-size: ${(props) => props.theme.fontSize}; - font-weight: ${(props) => props.theme.fontWeight}; + color: ${(props) => (props.disabled ? getDisabledColor("label") : getEnabledColor("label"))}; + font-family: var(--typography-font-family); + font-size: var(--typography-label-m); + font-weight: var(--typography-label-regular); `; const ValueInput = styled.input` @@ -195,7 +106,7 @@ const CheckboxContainer = styled.span` align-items: center; justify-content: center; height: 24px; - width: 24px; + width: var(--height-s); `; const Checkbox = styled.span<{ @@ -208,39 +119,39 @@ const Checkbox = styled.span<{ display: flex; align-items: center; justify-content: center; - height: 18px; - width: 18px; - border: 2px solid + height: 18px; // This does not have an apropiate alias + width: 18px; // This does not have an apropiate alias + border: var(--border-width-m) solid ${(props) => props.disabled - ? getDisabledColor(props.theme, "border") + ? getDisabledColor("border") : props.readOnly - ? getReadOnlyColor(props.theme, "border") - : getEnabledColor(props.theme, "border")}; + ? getReadOnlyColor("border") + : getEnabledColor("border")}; border-radius: 2px; background-color: ${(props) => props.checked ? props.disabled - ? getDisabledColor(props.theme, "check") + ? getDisabledColor("check") : props.readOnly - ? getReadOnlyColor(props.theme, "check") - : getEnabledColor(props.theme, "check") + ? getReadOnlyColor("check") + : getEnabledColor("check") : "transparent"}; color: ${(props) => props.disabled - ? getDisabledColor(props.theme, "background") + ? getDisabledColor("background") : props.readOnly - ? getReadOnlyColor(props.theme, "background") - : getEnabledColor(props.theme, "background")}; + ? getReadOnlyColor("background") + : getEnabledColor("background")}; &:focus { - outline: 2px solid ${(props) => props.theme.focusColor}; - outline-offset: 2px; + outline: var(--border-width-m) solid var(--border-color-secondary-medium); + outline-offset: 1px; // This does not have an apropiate alias } svg { position: absolute; - width: 22px; - height: 22px; + width: 24px; + height: var(--height-s); } ${(props) => props.disabled && "pointer-events: none;"} `; @@ -252,9 +163,9 @@ const MainContainer = styled.div<{ readOnly: CheckboxPropsType["readOnly"]; checked: CheckboxPropsType["checked"]; }>` - display: inline-flex; + display: flex; align-items: center; - gap: ${(props) => props.theme.checkLabelSpacing}; + gap: var(--spacing-gap-s); width: ${(props) => calculateWidth(props.margin, props.size)}; margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")}; margin-top: ${(props) => @@ -268,20 +179,134 @@ const MainContainer = styled.div<{ cursor: ${(props) => (props.disabled ? "not-allowed" : props.readOnly ? "default" : "pointer")}; &:hover ${Checkbox} { - border: 2px solid + border: var(--border-width-m) solid ${(props) => { - if (!props.disabled) - return props.readOnly - ? getReadOnlyColor(props.theme, "hoverBorder") - : getEnabledColor(props.theme, "hoverBorder"); + if (!props.disabled) return props.readOnly ? getReadOnlyColor("hoverBorder") : getEnabledColor("hoverBorder"); }}; color: ${(props) => { if (!props.disabled) - return props.readOnly - ? getReadOnlyColor(props.theme, "hoverBackground") - : getEnabledColor(props.theme, "hoverBackground"); + return props.readOnly ? getReadOnlyColor("hoverBackground") : getEnabledColor("hoverBackground"); + }}; + } + + &:active ${Checkbox} { + border: var(--border-width-m) solid + ${(props) => { + if (!props.disabled) return props.readOnly ? getReadOnlyColor("activeBorder") : getEnabledColor("activeBorder"); + }}; + color: ${(props) => { + if (!props.disabled) + return props.readOnly ? getReadOnlyColor("activeBackground") : getEnabledColor("activeBackground"); }}; } `; +const checkedIcon = ( + + + +); + +const DxcCheckbox = forwardRef( + ( + { + checked, + defaultChecked = false, + value, + label = "", + labelPosition = "before", + name = "", + disabled = false, + optional = false, + readOnly = false, + onChange, + margin, + size = "fitContent", + tabIndex = 0, + ariaLabel = "Checkbox", + }, + ref + ): JSX.Element => { + const labelId = `label-checkbox-${useId()}`; + const [innerChecked, setInnerChecked] = useState(defaultChecked); + const checkboxRef = useRef(null); + const colorsTheme = useContext(HalstackContext); + const translatedLabels = useContext(HalstackLanguageContext); + + const handleCheckboxChange = () => { + if (!disabled && !readOnly) { + if (document.activeElement !== checkboxRef.current) { + checkboxRef.current?.focus(); + } + if (checked == null) { + setInnerChecked((innerCurrentlyChecked) => !innerCurrentlyChecked); + } + onChange?.(!(checked ?? innerChecked)); + } + }; + + const handleKeyboard = (event: KeyboardEvent) => { + switch (event.key) { + case " ": + event.preventDefault(); + handleCheckboxChange(); + break; + default: + break; + } + }; + + return ( + + + {label && ( + + {label} + {optional && ` ${translatedLabels.formFields.optionalLabel}`} + + )} + + + + {(checked ?? innerChecked) && checkedIcon} + + + + + ); + } +); + export default DxcCheckbox; diff --git a/packages/lib/src/index.ts b/packages/lib/src/index.ts index fd0fc86ca5..3ded437d20 100644 --- a/packages/lib/src/index.ts +++ b/packages/lib/src/index.ts @@ -1,5 +1,5 @@ import "./styles/fonts.css"; -// import "./styles/variables.css"; +import "./styles/variables.css"; export { default as DxcAccordion } from "./accordion/Accordion"; export { default as DxcAccordionGroup } from "./accordion-group/AccordionGroup"; From fccb5410ef28776f3ab45c987cc65e4981bf0485 Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Thu, 6 Feb 2025 11:43:22 +0100 Subject: [PATCH 02/12] Changed check color to transparent --- packages/lib/src/checkbox/Checkbox.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/lib/src/checkbox/Checkbox.tsx b/packages/lib/src/checkbox/Checkbox.tsx index 08b37b02dd..5e3389f97b 100644 --- a/packages/lib/src/checkbox/Checkbox.tsx +++ b/packages/lib/src/checkbox/Checkbox.tsx @@ -30,7 +30,7 @@ const calculateWidth = (margin: CheckboxPropsType["margin"], size: CheckboxProps const getDisabledColor = (element: string) => { switch (element) { case "check": - return "var(--color-fg-neutral-bright)"; + return "transparent"; case "background": return "var(--color-fg-neutral-medium)"; case "border": @@ -45,7 +45,7 @@ const getDisabledColor = (element: string) => { const getReadOnlyColor = (element: string) => { switch (element) { case "check": - return "var(--color-fg-neutral-bright)"; + return "transparent"; case "background": return "var(--color-fg-neutral-medium)"; case "hoverBackground": @@ -66,7 +66,7 @@ const getReadOnlyColor = (element: string) => { const getEnabledColor = (element: string) => { switch (element) { case "check": - return "var(--color-fg-neutral-bright)"; + return "transparent"; case "background": return "var(--color-bg-secondary-strong)"; case "hoverBackground": From 730f68b2f7db1eb4385f2a18bc3acdd1c2ab9c91 Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Wed, 19 Feb 2025 16:40:39 +0100 Subject: [PATCH 03/12] Removed comments --- packages/lib/src/checkbox/Checkbox.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/lib/src/checkbox/Checkbox.tsx b/packages/lib/src/checkbox/Checkbox.tsx index 5e3389f97b..0d94f12310 100644 --- a/packages/lib/src/checkbox/Checkbox.tsx +++ b/packages/lib/src/checkbox/Checkbox.tsx @@ -119,8 +119,8 @@ const Checkbox = styled.span<{ display: flex; align-items: center; justify-content: center; - height: 18px; // This does not have an apropiate alias - width: 18px; // This does not have an apropiate alias + height: 18px; + width: 18px; border: var(--border-width-m) solid ${(props) => props.disabled @@ -146,7 +146,7 @@ const Checkbox = styled.span<{ &:focus { outline: var(--border-width-m) solid var(--border-color-secondary-medium); - outline-offset: 1px; // This does not have an apropiate alias + outline-offset: 1px; } svg { position: absolute; From b2cfc462143395e25142d76401540f20fbb6b8b1 Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Wed, 19 Feb 2025 17:05:01 +0100 Subject: [PATCH 04/12] Added documentation with the new structure --- .../pages/components/checkbox/code.tsx | 19 + .../pages/components/checkbox/index.tsx | 8 +- .../components/checkbox/specifications.tsx | 21 - .../pages/components/checkbox/usage.tsx | 21 - .../checkbox/CheckboxPageLayout.tsx | 10 +- .../checkbox/code/CheckboxCodePage.tsx | 84 ++- .../overview/CheckboxOverviewPage.tsx | 128 +++++ .../{usage => overview}/examples/stacking.ts | 0 .../overview/images/checkbox_anatomy.png | Bin 0 -> 12531 bytes .../checkbox/specs/CheckboxSpecsPage.tsx | 497 ------------------ .../specs/images/checkbox_anatomy.png | Bin 11379 -> 0 bytes .../checkbox/specs/images/checkbox_specs.png | Bin 20208 -> 0 bytes .../checkbox/specs/images/checkbox_states.png | Bin 19117 -> 0 bytes .../checkbox/usage/CheckboxUsagePage.tsx | 72 --- 14 files changed, 195 insertions(+), 665 deletions(-) create mode 100644 apps/website/pages/components/checkbox/code.tsx delete mode 100644 apps/website/pages/components/checkbox/specifications.tsx delete mode 100644 apps/website/pages/components/checkbox/usage.tsx create mode 100644 apps/website/screens/components/checkbox/overview/CheckboxOverviewPage.tsx rename apps/website/screens/components/checkbox/{usage => overview}/examples/stacking.ts (100%) create mode 100644 apps/website/screens/components/checkbox/overview/images/checkbox_anatomy.png delete mode 100644 apps/website/screens/components/checkbox/specs/CheckboxSpecsPage.tsx delete mode 100644 apps/website/screens/components/checkbox/specs/images/checkbox_anatomy.png delete mode 100644 apps/website/screens/components/checkbox/specs/images/checkbox_specs.png delete mode 100644 apps/website/screens/components/checkbox/specs/images/checkbox_states.png delete mode 100644 apps/website/screens/components/checkbox/usage/CheckboxUsagePage.tsx diff --git a/apps/website/pages/components/checkbox/code.tsx b/apps/website/pages/components/checkbox/code.tsx new file mode 100644 index 0000000000..71acfdb6cf --- /dev/null +++ b/apps/website/pages/components/checkbox/code.tsx @@ -0,0 +1,19 @@ +import Head from "next/head"; +import type { ReactElement } from "react"; +import CheckboxPageLayout from "screens/components/checkbox/CheckboxPageLayout"; +import CheckboxCodePage from "screens/components/checkbox/code/CheckboxCodePage"; + +const Code = () => { + return ( + <> + + Checkbox Code — Halstack Design System + + + + ); +}; + +Code.getLayout = (page: ReactElement) => {page}; + +export default Code; diff --git a/apps/website/pages/components/checkbox/index.tsx b/apps/website/pages/components/checkbox/index.tsx index 0d1de85a5f..f39c26d2d6 100644 --- a/apps/website/pages/components/checkbox/index.tsx +++ b/apps/website/pages/components/checkbox/index.tsx @@ -1,6 +1,6 @@ import Head from "next/head"; import type { ReactElement } from "react"; -import CheckboxCodePage from "screens/components/checkbox/code/CheckboxCodePage"; +import CheckboxOverviewPage from "screens/components/checkbox/overview/CheckboxOverviewPage"; import CheckboxPageLayout from "screens/components/checkbox/CheckboxPageLayout"; const Usage = () => { @@ -9,13 +9,11 @@ const Usage = () => { Checkbox — Halstack Design System - + ); }; -Usage.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; +Usage.getLayout = (page: ReactElement) => {page}; export default Usage; diff --git a/apps/website/pages/components/checkbox/specifications.tsx b/apps/website/pages/components/checkbox/specifications.tsx deleted file mode 100644 index b131a0af96..0000000000 --- a/apps/website/pages/components/checkbox/specifications.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Head from "next/head"; -import type { ReactElement } from "react"; -import CheckboxSpecsPage from "screens/components/checkbox/specs/CheckboxSpecsPage"; -import CheckboxPageLayout from "screens/components/checkbox/CheckboxPageLayout"; - -const Specifications = () => { - return ( - <> - - Checkbox Specs — Halstack Design System - - - - ); -}; - -Specifications.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; - -export default Specifications; diff --git a/apps/website/pages/components/checkbox/usage.tsx b/apps/website/pages/components/checkbox/usage.tsx deleted file mode 100644 index 1052a89dd2..0000000000 --- a/apps/website/pages/components/checkbox/usage.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Head from "next/head"; -import type { ReactElement } from "react"; -import CheckboxPageLayout from "screens/components/checkbox/CheckboxPageLayout"; -import CheckboxUsagePage from "screens/components/checkbox/usage/CheckboxUsagePage"; - -const Usage = () => { - return ( - <> - - Checkbox Usage — Halstack Design System - - - - ); -}; - -Usage.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; - -export default Usage; diff --git a/apps/website/screens/components/checkbox/CheckboxPageLayout.tsx b/apps/website/screens/components/checkbox/CheckboxPageLayout.tsx index 7044bc1192..af9d9ad8c5 100644 --- a/apps/website/screens/components/checkbox/CheckboxPageLayout.tsx +++ b/apps/website/screens/components/checkbox/CheckboxPageLayout.tsx @@ -6,9 +6,8 @@ import { ReactNode } from "react"; const CheckboxPageHeading = ({ children }: { children: ReactNode }) => { const tabs = [ - { label: "Code", path: "/components/checkbox" }, - { label: "Usage", path: "/components/checkbox/usage" }, - { label: "Specifications", path: "/components/checkbox/specifications" }, + { label: "Overview", path: "/components/checkbox" }, + { label: "Code", path: "/components/checkbox/code" }, ]; return ( @@ -17,10 +16,9 @@ const CheckboxPageHeading = ({ children }: { children: ReactNode }) => { - Checkboxes are inputs that offer to the user the possibility to select one or more options from a range of - attributes. + Checkboxes are inputs that allow the user to select one or more options from a range of attributes. - + {children} diff --git a/apps/website/screens/components/checkbox/code/CheckboxCodePage.tsx b/apps/website/screens/components/checkbox/code/CheckboxCodePage.tsx index 71d37db836..3ddffd77e4 100644 --- a/apps/website/screens/components/checkbox/code/CheckboxCodePage.tsx +++ b/apps/website/screens/components/checkbox/code/CheckboxCodePage.tsx @@ -23,14 +23,14 @@ const sections = [ - defaultChecked + ariaLabel - boolean + string - Initial state of the checkbox, only when it is uncontrolled. - false + Specifies a string to be used as the name for the checkbox element when no label is provided. + 'Checkbox' checked @@ -41,20 +41,27 @@ const sections = [ If true, the component is checked. If undefined the component will be uncontrolled and the value will be managed internally by the component. + - + + + defaultChecked + + boolean + + Initial state of the checkbox, only when it is uncontrolled. - - + false - value + disabled - string + boolean + If true, the component will be disabled. - Will be passed to the value attribute of the HTML input element. When inside a form, this - value will be only submitted if the checkbox is checked. + false - - label @@ -74,6 +81,17 @@ const sections = [ 'before' + + margin + + 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | Margin + + + 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. + + - + name @@ -83,14 +101,15 @@ const sections = [ - - disabled + onChange - boolean + {"(value: boolean) => void"} - If true, the component will be disabled. - false + This function will be called when the user clicks the checkbox. The new value will be passed as a + parameter. + - optional @@ -113,25 +132,11 @@ const sections = [ - onChange - - {"(value: boolean) => void"} - - - This function will be called when the user clicks the checkbox. The new value will be passed as a - parameter. - - - - - - margin - - 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge' | Margin - + ref - 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. + {"React.Ref"} + Reference to the component. - @@ -157,22 +162,15 @@ const sections = [ - ref - - {"React.Ref"} - - Reference to the component. - - - - - ariaLabel + value string - Specifies a string to be used as the name for the checkbox element when no label is provided. + Will be passed to the value attribute of the HTML input element. When inside a form, this + value will be only submitted if the checkbox is checked. - 'Checkbox' + - @@ -197,7 +195,7 @@ const CheckboxCodePage = () => { return ( - + diff --git a/apps/website/screens/components/checkbox/overview/CheckboxOverviewPage.tsx b/apps/website/screens/components/checkbox/overview/CheckboxOverviewPage.tsx new file mode 100644 index 0000000000..ae983eda69 --- /dev/null +++ b/apps/website/screens/components/checkbox/overview/CheckboxOverviewPage.tsx @@ -0,0 +1,128 @@ +import { DxcParagraph, DxcBulletedList, DxcFlex, DxcTable } from "@dxc-technology/halstack-react"; +import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; +import QuickNavContainer from "@/common/QuickNavContainer"; +import DocFooter from "@/common/DocFooter"; +import Example from "@/common/example/Example"; +import stacking from "./examples/stacking"; +import Image from "@/common/Image"; +import anatomy from "./images/checkbox_anatomy.png"; + +const sections = [ + { + title: "Introduction", + content: ( + <> + + Checkboxes support different states, including checked, unchecked, and indeterminate, providing clear visual + feedback. Checkboxes should be used when multiple selections are needed, unlike radio buttons, which are for + single-choice scenarios. Proper spacing and alignment help maintain clarity, and labels should be concise and + descriptive to enhance usability. + + + ), + }, + { + title: "Anatomy", + content: ( + <> + Checkbox's anatomy + + + Checkbox input: the interactive element that allows users to toggle between checked, + unchecked, and indeterminate states. It provides visual feedback based on user selection and supports + accessibility attributes for better usability. + + + Label: descriptive text associated with the checkbox, helping users understand the option + they select. It should be concise and placed close to the checkbox for clear association. + + + + ), + }, + { + title: "Stacking checkboxes", + content: ( + <> + Checkboxes can be stacked vertically or horizontally, depending on the use case. + + + ), + subSections: [ + { + title: "Vertical stacking", + content: ( + + To improve readability and scalability, checkboxes can be stacked vertically, especially in forms or + settings panels, allowing users to process options more efficiently without excessive eye movement. Leave + 8px of spacing between vertically stacked checkboxes. + + ), + }, + { + title: "Horizontal stacking", + content: ( + + Used in scenarios with limited vertical space, checkboxes can be stacked horizontally, along with a + consistent spacing and alignment, to maintain a structured and organized layout. If a set of checkboxes is + related to a single category, consider using a group label to provide context as this will enhance usability + and help users make informed selections. Horizontally stacked checkboxes maintain a separation of, minimum, + 32px. + + ), + }, + ], + }, + { + title: "Best practices", + content: ( + <> + + + Use for multiple selections: checkboxes should be used when users can select multiple + options independently. If only one selection is allowed, use radio buttons instead. + + + Ensure clear labels: each checkbox should have a clear, concise label that accurately + describes the option. Avoid ambiguous wording that might confuse users. + + + Group related options: when checkboxes are part of a related set, use a group label to + provide context. This improves readability and helps users understand the available choices. + + + Prioritize vertical stacking: for better readability and usability, stack checkboxes + vertically, especially when dealing with multiple options. Horizontal stacking should be reserved for short + lists with clear, non-wrapping labels. + + + Use the indeterminate state properly: the indeterminate state should only be used when a + parent checkbox controls multiple sub-options. This visually indicates that some but not all child options + are selected. + + + Maintain sufficient spacing: provide adequate spacing between checkboxes to prevent + misclicks and ensure a clean, organized layout. + + + Ensure accessibility: make checkboxes large enough to be easily clickable and ensure they + are keyboard-navigable. Labels should be linked correctly for screen readers to interpret them properly. + + + + ), + }, +]; + +const CheckboxInputOverviewPage = () => { + return ( + + + + + + + ); +}; + +export default CheckboxInputOverviewPage; diff --git a/apps/website/screens/components/checkbox/usage/examples/stacking.ts b/apps/website/screens/components/checkbox/overview/examples/stacking.ts similarity index 100% rename from apps/website/screens/components/checkbox/usage/examples/stacking.ts rename to apps/website/screens/components/checkbox/overview/examples/stacking.ts diff --git a/apps/website/screens/components/checkbox/overview/images/checkbox_anatomy.png b/apps/website/screens/components/checkbox/overview/images/checkbox_anatomy.png new file mode 100644 index 0000000000000000000000000000000000000000..ff4051b3d0528f6a9de33d6bc11f4eeab8a88059 GIT binary patch literal 12531 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 - Checkbox design specifications - - ), - }, - { - title: "States", - content: ( - <> - - The following states are defined in the life cycle of the component: unselected enabled,{" "} - unselected hover, unselected focus, unselected disabled,{" "} - selected enabled, selected hover, selected focus and{" "} - selected disabled. - -
- Checkbox states -
- - ), - }, - { - title: "Anatomy", - content: ( - <> - Checkbox anatomy - - Checkbox input - Label - - - ), - }, - { - title: "Design tokens", - subSections: [ - { - title: "Color", - content: ( - - - - Component token - Element - Core token - Value - - - - - - backgroundColorChecked - - Fill - - color-blue-800 - - #0067b3 - - - - hoverBackgroundColorChecked - - Fill:hover - - color-blue-900 - - #003c66 - - - - disabledBackgroundColorChecked - - Fill:disabled - - color-grey-500 - - #999999 - - - - readOnlyBackgroundColorChecked - - Fill:readonly - - color-grey-500 - - #999999 - - - - hoverReadOnlyBackgroundColorChecked - - Fill:readonly:hover - - color-grey-600 - - #808080 - - - - borderColor - - Border - - color-blue-800 - - #0067b3 - - - - hoverBorderColor - - Border:hover - - color-blue-900 - - #003c66 - - - - disabledBorderColor - - Border:disabled - - color-grey-500 - - #999999 - - - - readOnlyBorderColor - - Border:readonly - - color-grey-500 - - #999999 - - - - hoverReadOnlyBorderColor - - Border:readonly:hover - - color-grey-600 - - #808080 - - - - checkColor - - Check mark - - color-white - - #ffffff - - - - disabledCheckColor - - Check mark:disabled - - color-white - - #ffffff - - - - readOnlyCheckColor - - Check mark:readonly - - color-white - - #ffffff - - - - fontColor - - Label - - color-black - - #000000 - - - - disabledFontColor - - Label:disabled - - color-grey-500 - - #999999 - - - - focusColor - - Outline:focus - - color-blue-600 - - #0095ff - - - - ), - }, - { - title: "Spacing", - content: ( - - - - Component token - Element - Core token - Value - - - - - - inputMargin - - Checkbox input - - spacing-8 - - 0.5rem / 8px - - - - ), - }, - { - title: "Typography", - content: ( - - - - Component token - Element - Core token - Value - - - - - - fontFamily - - Label - - font-family-sans - - 'Open Sans', sans-serif - - - - fontSize - - Label - - font-scale-02 - - 0.875rem / 14px - - - - fontWeight - - Label - - font-weight-regular - - 400 - - - - ), - }, - { - title: "Border", - content: ( - - - - Property - Element - Core token - Value - - - - - - border-width - - Checkbox input - - border-width-2 - - 2px - - - - border-style - - Checkbox input - - border-style-solid - - solid - - - - border-radius - - Checkbox input - - border-radius-small - - 0.125rem / 2px - - - - 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: "Margin", - content: ( - <> - - Margin can be set independently for top, right, bottom,{" "} - left. - - - - - Margin - Value - - - - - - xxsmall - - 6px - - - - xsmall - - 16px - - - - small - - 24px - - - - medium - - 36px - - - - large - - 48px - - - - xlarge - - 64px - - - - xxlarge - - 100px - - - - - ), - }, - ], - }, - { - title: "Accessibility", - subSections: [ - { - title: "WCAG 2.2", - content: ( - <> - - - Understanding WCAG 2.2 -{" "} - - SC 1.3.1: Info and Relationships - - - - Understanding WCAG 2.2 -{" "} - - SC 4.1.2: Name, Role, Value - - - - - ), - }, - { - title: "WAI-ARIA 1.2", - content: ( - - - WAI-ARIA Authoring Practices 1.2 -{" "} - - 3.7 Checkbox - - - - ), - }, - ], - }, -]; - -const CheckboxSpecsPage = () => { - return ( - - - - - - - ); -}; - -export default CheckboxSpecsPage; diff --git a/apps/website/screens/components/checkbox/specs/images/checkbox_anatomy.png b/apps/website/screens/components/checkbox/specs/images/checkbox_anatomy.png deleted file mode 100644 index 40c875b6feb689f538a98dedf981882539ca3e46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11379 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 b*!KztZxAF8l^b|85f<)?*DjNbe|(Q*iK diff --git a/apps/website/screens/components/checkbox/specs/images/checkbox_states.png b/apps/website/screens/components/checkbox/specs/images/checkbox_states.png deleted file mode 100644 index 505cc4e15be0ae23b9548b9dfce73875d22d9d7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19117 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 Q{wa{MyvCy - Use the checkbox when: - - Multiple choices offered. - Binary response are requested (yes/no). - Accepting conditions and additional features. - - - ), - }, - { - title: "Stacking", - content: ( - <> - Checkbox may be either vertically or horizontally stacked. - - - - - Type - Usage - - - - - - Vertical - - - Related checkboxes that belong to the same category. The horizontal spacing between horizontally stacked - checkboxes should be 8px. - - - - - Horizontal - - - Checkboxes are independent of a category*. The vertical spacing between stacked checkboxes should be - 32px. Don't stack more than 3 options - - - - - - ), - }, -]; - -const CheckboxInputUsagePage = () => { - return ( - - - - - - - ); -}; - -export default CheckboxInputUsagePage; From 7498897def06100e66092960db24ea1ef01d7b9f Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Mon, 10 Mar 2025 15:09:23 +0100 Subject: [PATCH 05/12] Minor fixes for checkbox doc --- .../checkbox/code/CheckboxCodePage.tsx | 22 ++++++++--------- .../overview/CheckboxOverviewPage.tsx | 24 +++++++++---------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/apps/website/screens/components/checkbox/code/CheckboxCodePage.tsx b/apps/website/screens/components/checkbox/code/CheckboxCodePage.tsx index 3ddffd77e4..ce33c37237 100644 --- a/apps/website/screens/components/checkbox/code/CheckboxCodePage.tsx +++ b/apps/website/screens/components/checkbox/code/CheckboxCodePage.tsx @@ -30,7 +30,9 @@ const sections = [ Specifies a string to be used as the name for the checkbox element when no label is provided. - 'Checkbox' + + 'Checkbox' + checked @@ -191,15 +193,13 @@ const sections = [ }, ]; -const CheckboxCodePage = () => { - return ( - - - - - - - ); -}; +const CheckboxCodePage = () => ( + + + + + + +); export default CheckboxCodePage; diff --git a/apps/website/screens/components/checkbox/overview/CheckboxOverviewPage.tsx b/apps/website/screens/components/checkbox/overview/CheckboxOverviewPage.tsx index ae983eda69..b525ce0e1a 100644 --- a/apps/website/screens/components/checkbox/overview/CheckboxOverviewPage.tsx +++ b/apps/website/screens/components/checkbox/overview/CheckboxOverviewPage.tsx @@ -14,9 +14,9 @@ const sections = [ <> Checkboxes support different states, including checked, unchecked, and indeterminate, providing clear visual - feedback. Checkboxes should be used when multiple selections are needed, unlike radio buttons, which are for - single-choice scenarios. Proper spacing and alignment help maintain clarity, and labels should be concise and - descriptive to enhance usability. + feedback. Checkboxes should be used when multiple selections are needed, unlike radio + buttons, which are for single-choice scenarios. Proper spacing and alignment help maintain clarity, and labels + should be concise and descriptive to enhance usability. ), @@ -114,15 +114,13 @@ const sections = [ }, ]; -const CheckboxInputOverviewPage = () => { - return ( - - - - - - - ); -}; +const CheckboxInputOverviewPage = () => ( + + + + + + +); export default CheckboxInputOverviewPage; From c03d9df60fac6b25052e43a87837adab1d3c1d0a Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Mon, 10 Mar 2025 15:13:32 +0100 Subject: [PATCH 06/12] Small refactoring to checkbox --- packages/lib/src/checkbox/Checkbox.tsx | 96 ++------------------------ packages/lib/src/checkbox/utils.ts | 84 ++++++++++++++++++++++ 2 files changed, 91 insertions(+), 89 deletions(-) create mode 100644 packages/lib/src/checkbox/utils.ts diff --git a/packages/lib/src/checkbox/Checkbox.tsx b/packages/lib/src/checkbox/Checkbox.tsx index 0d94f12310..17c22595b2 100644 --- a/packages/lib/src/checkbox/Checkbox.tsx +++ b/packages/lib/src/checkbox/Checkbox.tsx @@ -1,90 +1,8 @@ import { useContext, useState, useRef, useId, forwardRef, KeyboardEvent } from "react"; import styled, { ThemeProvider } from "styled-components"; -import { getMargin } from "../common/utils"; import HalstackContext, { HalstackLanguageContext } from "../HalstackContext"; import CheckboxPropsType, { RefType } from "./types"; - -const sizes = { - small: "120px", - medium: "240px", - large: "480px", - fillParent: "100%", - fitContent: "fit-content", -}; - -const spaces = { - xxsmall: "var(--spacing-padding-xxs)", - xsmall: "var(--spacing-padding-xs)", - small: "var(--spacing-padding-s)", - medium: "var(--spacing-padding-m)", - large: "var(--spacing-padding-l)", - xlarge: "var(--spacing-padding-xl)", - xxlarge: "var(--spacing-padding-xxl)", -}; - -const calculateWidth = (margin: CheckboxPropsType["margin"], size: CheckboxPropsType["size"]) => - size === "fillParent" - ? `calc(${sizes[size]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` - : size && sizes[size]; - -const getDisabledColor = (element: string) => { - switch (element) { - case "check": - return "transparent"; - case "background": - return "var(--color-fg-neutral-medium)"; - case "border": - return "var(--border-color-neutral-medium)"; - case "label": - return "var(--color-fg-neutral-medium)"; - default: - return undefined; - } -}; - -const getReadOnlyColor = (element: string) => { - switch (element) { - case "check": - return "transparent"; - case "background": - return "var(--color-fg-neutral-medium)"; - case "hoverBackground": - return "var(--color-bg-neutral-stronger)"; - case "border": - return "var(--border-color-neutral-strong)"; - case "hoverBorder": - return "var(--border-color-neutral-stronger)"; - case "activeBorder": - return "var(--border-color-neutral-strongest)"; - case "activeBackground": - return "var(--color-bg-neutral-strongest)"; - default: - return undefined; - } -}; - -const getEnabledColor = (element: string) => { - switch (element) { - case "check": - return "transparent"; - case "background": - return "var(--color-bg-secondary-strong)"; - case "hoverBackground": - return "var(--color-bg-secondary-stronger)"; - case "border": - return "var(--border-color-secondary-strong)"; - case "hoverBorder": - return "var(--border-color-secondary-stronger)"; - case "label": - return "var(--color-fg-neutral-dark)"; - case "activeBorder": - return "var(--border-color-secondary-strongest)"; - case "activeBackground": - return "var(--color-bg-secondary-strongest)"; - default: - return undefined; - } -}; +import { calculateWidth, getDisabledColor, getEnabledColor, getReadOnlyColor, spaces } from "./utils"; const LabelContainer = styled.span<{ disabled: CheckboxPropsType["disabled"]; @@ -105,8 +23,8 @@ const CheckboxContainer = styled.span` display: flex; align-items: center; justify-content: center; - height: 24px; - width: var(--height-s); + height: var(--height-s); + width: 24px; `; const Checkbox = styled.span<{ @@ -128,7 +46,7 @@ const Checkbox = styled.span<{ : props.readOnly ? getReadOnlyColor("border") : getEnabledColor("border")}; - border-radius: 2px; + border-radius: var(--border-radius-xs); background-color: ${(props) => props.checked ? props.disabled @@ -179,7 +97,7 @@ const MainContainer = styled.div<{ cursor: ${(props) => (props.disabled ? "not-allowed" : props.readOnly ? "default" : "pointer")}; &:hover ${Checkbox} { - border: var(--border-width-m) solid + border: var(--border-width-m) var(--border-style-default) ${(props) => { if (!props.disabled) return props.readOnly ? getReadOnlyColor("hoverBorder") : getEnabledColor("hoverBorder"); }}; @@ -190,7 +108,7 @@ const MainContainer = styled.div<{ } &:active ${Checkbox} { - border: var(--border-width-m) solid + border: var(--border-width-m) var(--border-style-default) ${(props) => { if (!props.disabled) return props.readOnly ? getReadOnlyColor("activeBorder") : getEnabledColor("activeBorder"); }}; @@ -229,7 +147,7 @@ const DxcCheckbox = forwardRef( ariaLabel = "Checkbox", }, ref - ): JSX.Element => { + ) => { const labelId = `label-checkbox-${useId()}`; const [innerChecked, setInnerChecked] = useState(defaultChecked); const checkboxRef = useRef(null); diff --git a/packages/lib/src/checkbox/utils.ts b/packages/lib/src/checkbox/utils.ts new file mode 100644 index 0000000000..f0fb97df23 --- /dev/null +++ b/packages/lib/src/checkbox/utils.ts @@ -0,0 +1,84 @@ +import { getMargin } from "../common/utils"; +import CheckboxPropsType from "./types"; + +const sizes = { + small: "120px", + medium: "240px", + large: "480px", + fillParent: "100%", + fitContent: "fit-content", +}; + +export const spaces = { + xxsmall: "var(--spacing-padding-xxs)", + xsmall: "var(--spacing-padding-xs)", + small: "var(--spacing-padding-s)", + medium: "var(--spacing-padding-m)", + large: "var(--spacing-padding-l)", + xlarge: "var(--spacing-padding-xl)", + xxlarge: "var(--spacing-padding-xxl)", +}; + +export const calculateWidth = (margin: CheckboxPropsType["margin"], size: CheckboxPropsType["size"]) => + size === "fillParent" + ? `calc(${sizes[size]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` + : size && sizes[size]; + +export const getDisabledColor = (element: string) => { + switch (element) { + case "check": + return "transparent"; + case "background": + return "var(--color-fg-neutral-medium)"; + case "border": + return "var(--border-color-neutral-medium)"; + case "label": + return "var(--color-fg-neutral-medium)"; + default: + return undefined; + } +}; + +export const getReadOnlyColor = (element: string) => { + switch (element) { + case "check": + return "transparent"; + case "background": + return "var(--color-fg-neutral-medium)"; + case "hoverBackground": + return "var(--color-bg-neutral-stronger)"; + case "border": + return "var(--border-color-neutral-strong)"; + case "hoverBorder": + return "var(--border-color-neutral-stronger)"; + case "activeBorder": + return "var(--border-color-neutral-strongest)"; + case "activeBackground": + return "var(--color-bg-neutral-strongest)"; + default: + return undefined; + } +}; + +export const getEnabledColor = (element: string) => { + switch (element) { + case "check": + return "transparent"; + case "background": + return "var(--color-bg-secondary-strong)"; + case "hoverBackground": + return "var(--color-bg-secondary-stronger)"; + case "border": + return "var(--border-color-secondary-strong)"; + case "hoverBorder": + return "var(--border-color-secondary-stronger)"; + case "label": + return "var(--color-fg-neutral-dark)"; + case "activeBorder": + return "var(--border-color-secondary-strongest)"; + case "activeBackground": + return "var(--color-bg-secondary-strongest)"; + default: + return undefined; + } +}; From 7ac5a19061a58e821625811903abaa51026f6172 Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Fri, 14 Mar 2025 14:05:16 +0100 Subject: [PATCH 07/12] Changed checkbox logic to prevent outline bug --- packages/lib/src/checkbox/Checkbox.tsx | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/lib/src/checkbox/Checkbox.tsx b/packages/lib/src/checkbox/Checkbox.tsx index 17c22595b2..74f1e735e7 100644 --- a/packages/lib/src/checkbox/Checkbox.tsx +++ b/packages/lib/src/checkbox/Checkbox.tsx @@ -28,7 +28,6 @@ const CheckboxContainer = styled.span` `; const Checkbox = styled.span<{ - checked: CheckboxPropsType["checked"]; disabled: CheckboxPropsType["disabled"]; readOnly: CheckboxPropsType["readOnly"]; }>` @@ -48,13 +47,7 @@ const Checkbox = styled.span<{ : getEnabledColor("border")}; border-radius: var(--border-radius-xs); background-color: ${(props) => - props.checked - ? props.disabled - ? getDisabledColor("check") - : props.readOnly - ? getReadOnlyColor("check") - : getEnabledColor("check") - : "transparent"}; + props.disabled ? getDisabledColor("check") : props.readOnly ? getReadOnlyColor("check") : getEnabledColor("check")}; color: ${(props) => props.disabled ? getDisabledColor("background") @@ -79,7 +72,6 @@ const MainContainer = styled.div<{ size: CheckboxPropsType["size"]; disabled: CheckboxPropsType["disabled"]; readOnly: CheckboxPropsType["readOnly"]; - checked: CheckboxPropsType["checked"]; }>` display: flex; align-items: center; @@ -128,6 +120,15 @@ const checkedIcon = ( ); +const unCheckedIcon = ( + + + +); + const DxcCheckbox = forwardRef( ( { @@ -185,7 +186,6 @@ const DxcCheckbox = forwardRef( onClick={handleCheckboxChange} margin={margin} size={size} - checked={checked ?? innerChecked} ref={ref} > {label && ( @@ -196,7 +196,6 @@ const DxcCheckbox = forwardRef( )} ( aria-required={!disabled && !optional} aria-labelledby={label ? labelId : undefined} aria-label={label ? undefined : ariaLabel} - checked={checked ?? innerChecked} disabled={disabled} readOnly={readOnly} ref={checkboxRef} > - {(checked ?? innerChecked) && checkedIcon} + {(checked ?? innerChecked) ? checkedIcon : unCheckedIcon} From 28a5f02abd4acae1262579391ddc00645da7ec76 Mon Sep 17 00:00:00 2001 From: Enrique Moreno Date: Fri, 14 Mar 2025 14:18:23 +0100 Subject: [PATCH 08/12] Solved problem with checked state --- packages/lib/src/checkbox/Checkbox.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/lib/src/checkbox/Checkbox.tsx b/packages/lib/src/checkbox/Checkbox.tsx index 74f1e735e7..a7753875bc 100644 --- a/packages/lib/src/checkbox/Checkbox.tsx +++ b/packages/lib/src/checkbox/Checkbox.tsx @@ -72,6 +72,7 @@ const MainContainer = styled.div<{ size: CheckboxPropsType["size"]; disabled: CheckboxPropsType["disabled"]; readOnly: CheckboxPropsType["readOnly"]; + checked: CheckboxPropsType["checked"]; }>` display: flex; align-items: center; @@ -196,6 +197,7 @@ const DxcCheckbox = forwardRef( )} Date: Fri, 14 Mar 2025 14:22:21 +0100 Subject: [PATCH 09/12] Solved problem with checked state --- packages/lib/src/checkbox/Checkbox.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/lib/src/checkbox/Checkbox.tsx b/packages/lib/src/checkbox/Checkbox.tsx index a7753875bc..c62a94cce8 100644 --- a/packages/lib/src/checkbox/Checkbox.tsx +++ b/packages/lib/src/checkbox/Checkbox.tsx @@ -72,7 +72,6 @@ const MainContainer = styled.div<{ size: CheckboxPropsType["size"]; disabled: CheckboxPropsType["disabled"]; readOnly: CheckboxPropsType["readOnly"]; - checked: CheckboxPropsType["checked"]; }>` display: flex; align-items: center; From 0cd3b78aa1aa90e88822f61bed3db2aad0b1056a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Tue, 18 Mar 2025 17:09:30 +0100 Subject: [PATCH 10/12] Checkbox updates --- .../lib/src/checkbox/Checkbox.stories.tsx | 117 ++++------ packages/lib/src/checkbox/Checkbox.tsx | 210 ++++++------------ packages/lib/src/checkbox/types.ts | 42 ++-- packages/lib/src/checkbox/utils.ts | 84 ------- packages/lib/src/checkbox/utils.tsx | 44 ++++ 5 files changed, 182 insertions(+), 315 deletions(-) delete mode 100644 packages/lib/src/checkbox/utils.ts create mode 100644 packages/lib/src/checkbox/utils.tsx diff --git a/packages/lib/src/checkbox/Checkbox.stories.tsx b/packages/lib/src/checkbox/Checkbox.stories.tsx index 3214db89de..307126e281 100644 --- a/packages/lib/src/checkbox/Checkbox.stories.tsx +++ b/packages/lib/src/checkbox/Checkbox.stories.tsx @@ -1,7 +1,6 @@ import styled from "styled-components"; import ExampleContainer from "../../.storybook/components/ExampleContainer"; import Title from "../../.storybook/components/Title"; -import { HalstackProvider } from "../HalstackContext"; import DxcCheckbox from "./Checkbox"; import { Meta, StoryObj } from "@storybook/react"; @@ -10,14 +9,6 @@ export default { component: DxcCheckbox, } as Meta; -const opinionatedTheme = { - checkbox: { - baseColor: "#0067b3", - checkColor: "#ffffff", - fontColor: "#000000", - }, -}; - const ScrollableContainer = styled.div` display: flex; flex-direction: column; @@ -39,6 +30,7 @@ const SmallContainer = styled.div` const Checkbox = () => ( <> + <ExampleContainer> <Title title="Default" theme="light" level={4} /> <DxcCheckbox label="Checkbox" /> @@ -47,6 +39,31 @@ const Checkbox = () => ( <Title title="Checked" theme="light" level={4} /> <DxcCheckbox label="Checkbox" defaultChecked /> </ExampleContainer> + <ExampleContainer pseudoState="pseudo-focus"> + <Title title="Focused" theme="light" level={4} /> + <DxcCheckbox label="Focused" /> + </ExampleContainer> + <ExampleContainer pseudoState="pseudo-hover"> + <Title title="Hovered" theme="light" level={4} /> + <DxcCheckbox label="Hovered" /> + </ExampleContainer> + <ExampleContainer pseudoState="pseudo-hover"> + <Title title="Hovered and checked" theme="light" level={4} /> + <DxcCheckbox label="Hovered" defaultChecked /> + </ExampleContainer> + <ExampleContainer pseudoState={["pseudo-focus", "pseudo-active"]}> + <Title title="Active" theme="light" level={4} /> + <DxcCheckbox label="Active" /> + </ExampleContainer> + <ExampleContainer pseudoState={["pseudo-focus", "pseudo-active"]}> + <Title title="Active and checked" theme="light" level={4} /> + <DxcCheckbox label="Active" defaultChecked /> + </ExampleContainer> + <ExampleContainer> + <Title title="Optional" theme="light" level={4} /> + <DxcCheckbox label="Checkbox" optional /> + </ExampleContainer> + <Title title="Disabled" theme="light" level={2} /> <ExampleContainer> <Title title="Disabled" theme="light" level={4} /> <DxcCheckbox label="Checkbox" disabled /> @@ -55,37 +72,38 @@ const Checkbox = () => ( <Title title="Disabled, checked and optional" theme="light" level={4} /> <DxcCheckbox label="Checkbox" disabled defaultChecked optional /> </ExampleContainer> + <Title title="Read only" theme="light" level={2} /> <ExampleContainer> <Title title="Read-only" theme="light" level={4} /> <DxcCheckbox label="Checkbox" readOnly /> </ExampleContainer> - <ExampleContainer pseudoState="pseudo-hover"> - <Title title="Hovered read-only" theme="light" level={4} /> - <DxcCheckbox label="Checkbox" readOnly /> - </ExampleContainer> <ExampleContainer> - <Title title="Read-only, checked and optional" theme="light" level={4} /> - <DxcCheckbox label="Checkbox" readOnly defaultChecked optional /> - </ExampleContainer> - <ExampleContainer pseudoState="pseudo-hover"> - <Title title="Hovered read-only and checked" theme="light" level={4} /> - <DxcCheckbox label="Checkbox" readOnly defaultChecked optional /> + <Title title="Read-only and optional" theme="light" level={4} /> + <DxcCheckbox label="Checkbox" readOnly optional /> </ExampleContainer> <ExampleContainer pseudoState="pseudo-focus"> - <Title title="Focused" theme="light" level={4} /> - <DxcCheckbox label="Focused" /> + <Title title="Read-only and focused" theme="light" level={4} /> + <DxcCheckbox label="Checkbox" readOnly optional /> + </ExampleContainer> + <ExampleContainer> + <Title title="Read-only and checked" theme="light" level={4} /> + <DxcCheckbox label="Checkbox" readOnly defaultChecked /> </ExampleContainer> <ExampleContainer pseudoState="pseudo-hover"> - <Title title="Hovered" theme="light" level={4} /> - <DxcCheckbox label="Hovered" /> + <Title title="Hovered and read-only" theme="light" level={4} /> + <DxcCheckbox label="Checkbox" readOnly /> + </ExampleContainer> + <ExampleContainer pseudoState={["pseudo-active", "pseudo-focus"]}> + <Title title="Active and read-only" theme="light" level={4} /> + <DxcCheckbox label="Checkbox" readOnly /> </ExampleContainer> <ExampleContainer pseudoState="pseudo-hover"> - <Title title="Hovered and checked" theme="light" level={4} /> - <DxcCheckbox label="Hovered" defaultChecked /> + <Title title="Hovered, read-only and checked" theme="light" level={4} /> + <DxcCheckbox label="Checkbox" readOnly defaultChecked /> </ExampleContainer> - <ExampleContainer> - <Title title="Optional" theme="light" level={4} /> - <DxcCheckbox label="Checkbox" optional /> + <ExampleContainer pseudoState={["pseudo-active", "pseudo-focus"]}> + <Title title="Active, read-only and checked" theme="light" level={4} /> + <DxcCheckbox label="Checkbox" readOnly defaultChecked /> </ExampleContainer> <ExampleContainer> <Title title="Label after" theme="light" level={4} /> @@ -168,49 +186,6 @@ const Checkbox = () => ( <DxcCheckbox label="Very long label to check its overflowing" labelPosition="after" /> </SmallContainer> </ExampleContainer> - <Title title="Opinionated theme" theme="light" level={2} /> - <ExampleContainer> - <Title title="Default" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcCheckbox label="Checkbox" /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer> - <Title title="Checked" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcCheckbox label="Checkbox" defaultChecked /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer> - <Title title="Disabled" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcCheckbox label="Checkbox" disabled /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer> - <Title title="Disabled checked" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcCheckbox label="Checkbox" defaultChecked disabled /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer pseudoState="pseudo-focus"> - <Title title="Focused" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcCheckbox label="Focused" /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer pseudoState="pseudo-hover"> - <Title title="Hovered" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcCheckbox label="Hovered" /> - </HalstackProvider> - </ExampleContainer> - <ExampleContainer pseudoState="pseudo-hover"> - <Title title="Hovered and checked" theme="light" level={4} /> - <HalstackProvider theme={opinionatedTheme}> - <DxcCheckbox label="Hovered" defaultChecked /> - </HalstackProvider> - </ExampleContainer> </> ); diff --git a/packages/lib/src/checkbox/Checkbox.tsx b/packages/lib/src/checkbox/Checkbox.tsx index c62a94cce8..471992656d 100644 --- a/packages/lib/src/checkbox/Checkbox.tsx +++ b/packages/lib/src/checkbox/Checkbox.tsx @@ -1,80 +1,51 @@ import { useContext, useState, useRef, useId, forwardRef, KeyboardEvent } from "react"; -import styled, { ThemeProvider } from "styled-components"; -import HalstackContext, { HalstackLanguageContext } from "../HalstackContext"; +import styled from "styled-components"; +import { HalstackLanguageContext } from "../HalstackContext"; import CheckboxPropsType, { RefType } from "./types"; -import { calculateWidth, getDisabledColor, getEnabledColor, getReadOnlyColor, spaces } from "./utils"; +import { calculateWidth, icons, spaces } from "./utils"; -const LabelContainer = styled.span<{ +const Label = styled.span<{ disabled: CheckboxPropsType["disabled"]; - labelPosition: CheckboxPropsType["labelPosition"]; }>` - order: ${(props) => (props.labelPosition === "before" ? 0 : 1)}; - color: ${(props) => (props.disabled ? getDisabledColor("label") : getEnabledColor("label"))}; + color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-dark)")}; font-family: var(--typography-font-family); font-size: var(--typography-label-m); font-weight: var(--typography-label-regular); -`; - -const ValueInput = styled.input` - display: none; -`; - -const CheckboxContainer = styled.span` - display: flex; - align-items: center; - justify-content: center; - height: var(--height-s); - width: 24px; + span { + color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; + } `; const Checkbox = styled.span<{ disabled: CheckboxPropsType["disabled"]; readOnly: CheckboxPropsType["readOnly"]; }>` - position: relative; - box-sizing: border-box; display: flex; - align-items: center; - justify-content: center; - height: 18px; - width: 18px; - border: var(--border-width-m) solid - ${(props) => - props.disabled - ? getDisabledColor("border") - : props.readOnly - ? getReadOnlyColor("border") - : getEnabledColor("border")}; - border-radius: var(--border-radius-xs); - background-color: ${(props) => - props.disabled ? getDisabledColor("check") : props.readOnly ? getReadOnlyColor("check") : getEnabledColor("check")}; - color: ${(props) => - props.disabled - ? getDisabledColor("background") - : props.readOnly - ? getReadOnlyColor("background") - : getEnabledColor("background")}; + border-radius: var(--border-radius-s); + color: ${({ disabled, readOnly }) => + disabled || readOnly ? "var(--color-fg-neutral-medium)" : "var(--color-fg-secondary-medium)"}; + ${({ disabled }) => disabled && "pointer-events: none;"} &:focus { - outline: var(--border-width-m) solid var(--border-color-secondary-medium); - outline-offset: 1px; + outline: var(--border-width-m) var(--border-style-default) var(--border-color-secondary-medium); + outline-offset: -2px; } svg { - position: absolute; width: 24px; height: var(--height-s); } - ${(props) => props.disabled && "pointer-events: none;"} `; -const MainContainer = styled.div<{ - margin: CheckboxPropsType["margin"]; - size: CheckboxPropsType["size"]; +const CheckboxContainer = styled.div<{ disabled: CheckboxPropsType["disabled"]; + labelPosition: CheckboxPropsType["labelPosition"]; + margin: CheckboxPropsType["margin"]; readOnly: CheckboxPropsType["readOnly"]; + size: CheckboxPropsType["size"]; }>` display: flex; align-items: center; + flex-direction: ${({ labelPosition }) => (labelPosition === "before" ? "row" : "row-reverse")}; gap: var(--spacing-gap-s); width: ${(props) => calculateWidth(props.margin, props.size)}; margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")}; @@ -86,92 +57,56 @@ const MainContainer = styled.div<{ props.margin && typeof props.margin === "object" && props.margin.bottom ? spaces[props.margin.bottom] : ""}; margin-left: ${(props) => props.margin && typeof props.margin === "object" && props.margin.left ? spaces[props.margin.left] : ""}; - cursor: ${(props) => (props.disabled ? "not-allowed" : props.readOnly ? "default" : "pointer")}; + cursor: ${({ disabled, readOnly }) => (disabled ? "not-allowed" : readOnly ? "default" : "pointer")}; &:hover ${Checkbox} { - border: var(--border-width-m) var(--border-style-default) - ${(props) => { - if (!props.disabled) return props.readOnly ? getReadOnlyColor("hoverBorder") : getEnabledColor("hoverBorder"); - }}; - color: ${(props) => { - if (!props.disabled) - return props.readOnly ? getReadOnlyColor("hoverBackground") : getEnabledColor("hoverBackground"); - }}; + ${({ disabled, readOnly }) => + !disabled && `color: ${readOnly ? "var(--color-fg-neutral-strong)" : "var(--color-fg-secondary-strong)"}`}; } - &:active ${Checkbox} { - border: var(--border-width-m) var(--border-style-default) - ${(props) => { - if (!props.disabled) return props.readOnly ? getReadOnlyColor("activeBorder") : getEnabledColor("activeBorder"); - }}; - color: ${(props) => { - if (!props.disabled) - return props.readOnly ? getReadOnlyColor("activeBackground") : getEnabledColor("activeBackground"); - }}; + ${({ disabled, readOnly }) => + !disabled && `color: ${readOnly ? "var(--color-fg-neutral-strong)" : "var(--color-fg-secondary-strong)"}`}; } `; -const checkedIcon = ( - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"> - <path - d="M19 3H5C3.89 3 3 3.9 3 5V19C3 20.1 3.89 21 5 21H19C20.11 21 21 20.1 21 19V5C21 3.9 20.11 3 19 3ZM10 17L5 12L6.41 10.59L10 14.17L17.59 6.58L19 8L10 17Z" - fill="currentColor" - /> - </svg> -); - -const unCheckedIcon = ( - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"> - <path - d="M19 5V19H5V5H19ZM19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3Z" - fill="currentColor" - /> - </svg> -); - const DxcCheckbox = forwardRef<RefType, CheckboxPropsType>( ( { + ariaLabel = "Checkbox", checked, defaultChecked = false, - value, + disabled = false, label = "", labelPosition = "before", + margin, name = "", - disabled = false, + onChange, optional = false, readOnly = false, - onChange, - margin, size = "fitContent", tabIndex = 0, - ariaLabel = "Checkbox", + value, }, ref ) => { const labelId = `label-checkbox-${useId()}`; const [innerChecked, setInnerChecked] = useState(defaultChecked); const checkboxRef = useRef<HTMLSpanElement | null>(null); - const colorsTheme = useContext(HalstackContext); const translatedLabels = useContext(HalstackLanguageContext); - const handleCheckboxChange = () => { + const handleOnChange = () => { if (!disabled && !readOnly) { - if (document.activeElement !== checkboxRef.current) { - checkboxRef.current?.focus(); - } - if (checked == null) { - setInnerChecked((innerCurrentlyChecked) => !innerCurrentlyChecked); - } + if (document.activeElement !== checkboxRef.current) checkboxRef.current?.focus(); + if (checked == null) setInnerChecked((innerCurrentlyChecked) => !innerCurrentlyChecked); onChange?.(!(checked ?? innerChecked)); } }; - const handleKeyboard = (event: KeyboardEvent<HTMLSpanElement>) => { + const handleOnKeyDown = (event: KeyboardEvent<HTMLSpanElement>) => { switch (event.key) { case " ": event.preventDefault(); - handleCheckboxChange(); + handleOnChange(); break; default: break; @@ -179,49 +114,46 @@ const DxcCheckbox = forwardRef<RefType, CheckboxPropsType>( }; return ( - <ThemeProvider theme={colorsTheme.checkbox}> - <MainContainer + <CheckboxContainer + disabled={disabled} + labelPosition={labelPosition} + margin={margin} + onClick={handleOnChange} + readOnly={readOnly} + ref={ref} + size={size} + > + {label && ( + <Label aria-label={label} disabled={disabled} id={labelId}> + {label} {optional && <span>{translatedLabels.formFields.optionalLabel}</span>} + </Label> + )} + <Checkbox + aria-checked={checked ?? innerChecked} + aria-disabled={disabled} + aria-label={label ? undefined : ariaLabel} + aria-labelledby={label ? labelId : undefined} + aria-readonly={readOnly} + aria-required={!disabled && !optional} disabled={disabled} + onKeyDown={handleOnKeyDown} readOnly={readOnly} - onClick={handleCheckboxChange} - margin={margin} - size={size} - ref={ref} + role="checkbox" + ref={checkboxRef} + tabIndex={disabled ? -1 : tabIndex} > - {label && ( - <LabelContainer id={labelId} disabled={disabled} labelPosition={labelPosition} aria-label={label}> - {label} - {optional && ` ${translatedLabels.formFields.optionalLabel}`} - </LabelContainer> - )} - <ValueInput - type="checkbox" - checked={checked ?? innerChecked} - name={name} - value={value} - disabled={disabled} - readOnly - /> - <CheckboxContainer> - <Checkbox - onKeyDown={handleKeyboard} - role="checkbox" - tabIndex={disabled ? -1 : tabIndex} - aria-checked={checked ?? innerChecked} - aria-disabled={disabled} - aria-readonly={readOnly} - aria-required={!disabled && !optional} - aria-labelledby={label ? labelId : undefined} - aria-label={label ? undefined : ariaLabel} - disabled={disabled} - readOnly={readOnly} - ref={checkboxRef} - > - {(checked ?? innerChecked) ? checkedIcon : unCheckedIcon} - </Checkbox> - </CheckboxContainer> - </MainContainer> - </ThemeProvider> + {(checked ?? innerChecked) ? icons.checked : icons.unchecked} + </Checkbox> + <input + checked={checked ?? innerChecked} + disabled={disabled} + name={name} + readOnly + style={{ display: "none" }} + type="checkbox" + value={value} + /> + </CheckboxContainer> ); } ); diff --git a/packages/lib/src/checkbox/types.ts b/packages/lib/src/checkbox/types.ts index 1559591832..2558af5cbc 100644 --- a/packages/lib/src/checkbox/types.ts +++ b/packages/lib/src/checkbox/types.ts @@ -2,19 +2,22 @@ import { Margin, Space } from "../common/utils"; type Props = { /** - * Initial state of the checkbox, only when it is uncontrolled. + * Specifies a string to be used as the name for the checkbox element when no `label` is provided. */ - defaultChecked?: boolean; + ariaLabel?: string; /** * If true, the component is checked. If undefined the component will be * uncontrolled and the value will be managed internally by the component. */ checked?: boolean; /** - * Will be passed to the value attribute of the html input element. - * When inside a form, this value will be only submitted if the checkbox is checked. + * Initial state of the checkbox, only when it is uncontrolled. */ - value?: string; + defaultChecked?: boolean; + /** + * If true, the component will be disabled. + */ + disabled?: boolean; /** * Text to be placed next to the checkbox. */ @@ -23,14 +26,22 @@ type Props = { * Whether the label should appear after or before the checkbox. */ labelPosition?: "before" | "after"; + /** + * Size of the margin to be applied to the component + * ('xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge'). + * You can pass an object with 'top', 'bottom', 'left' and 'right' properties + * in order to specify different margin sizes. + */ + margin?: Space | Margin; /** * Name attribute of the input element. */ name?: string; /** - * If true, the component will be disabled. + * This function will be called when the user clicks the checkbox. + * The new value will be passed as a parameter. */ - disabled?: boolean; + onChange?: (value: boolean) => void; /** * If true, the component will display '(Optional)' next to the label. */ @@ -39,18 +50,6 @@ type Props = { * If true, the component will not be mutable, meaning the user can not edit the control. */ readOnly?: boolean; - /** - * This function will be called when the user clicks the checkbox. - * The new value will be passed as a parameter. - */ - onChange?: (value: boolean) => void; - /** - * Size of the margin to be applied to the component - * ('xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge'). - * You can pass an object with 'top', 'bottom', 'left' and 'right' properties - * in order to specify different margin sizes. - */ - margin?: Space | Margin; /** * Size of the component. */ @@ -60,9 +59,10 @@ type Props = { */ tabIndex?: number; /** - * Specifies a string to be used as the name for the checkbox element when no `label` is provided. + * Will be passed to the value attribute of the html input element. + * When inside a form, this value will be only submitted if the checkbox is checked. */ - ariaLabel?: string; + value?: string; }; /** diff --git a/packages/lib/src/checkbox/utils.ts b/packages/lib/src/checkbox/utils.ts deleted file mode 100644 index f0fb97df23..0000000000 --- a/packages/lib/src/checkbox/utils.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { getMargin } from "../common/utils"; -import CheckboxPropsType from "./types"; - -const sizes = { - small: "120px", - medium: "240px", - large: "480px", - fillParent: "100%", - fitContent: "fit-content", -}; - -export const spaces = { - xxsmall: "var(--spacing-padding-xxs)", - xsmall: "var(--spacing-padding-xs)", - small: "var(--spacing-padding-s)", - medium: "var(--spacing-padding-m)", - large: "var(--spacing-padding-l)", - xlarge: "var(--spacing-padding-xl)", - xxlarge: "var(--spacing-padding-xxl)", -}; - -export const calculateWidth = (margin: CheckboxPropsType["margin"], size: CheckboxPropsType["size"]) => - size === "fillParent" - ? `calc(${sizes[size]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` - : size && sizes[size]; - -export const getDisabledColor = (element: string) => { - switch (element) { - case "check": - return "transparent"; - case "background": - return "var(--color-fg-neutral-medium)"; - case "border": - return "var(--border-color-neutral-medium)"; - case "label": - return "var(--color-fg-neutral-medium)"; - default: - return undefined; - } -}; - -export const getReadOnlyColor = (element: string) => { - switch (element) { - case "check": - return "transparent"; - case "background": - return "var(--color-fg-neutral-medium)"; - case "hoverBackground": - return "var(--color-bg-neutral-stronger)"; - case "border": - return "var(--border-color-neutral-strong)"; - case "hoverBorder": - return "var(--border-color-neutral-stronger)"; - case "activeBorder": - return "var(--border-color-neutral-strongest)"; - case "activeBackground": - return "var(--color-bg-neutral-strongest)"; - default: - return undefined; - } -}; - -export const getEnabledColor = (element: string) => { - switch (element) { - case "check": - return "transparent"; - case "background": - return "var(--color-bg-secondary-strong)"; - case "hoverBackground": - return "var(--color-bg-secondary-stronger)"; - case "border": - return "var(--border-color-secondary-strong)"; - case "hoverBorder": - return "var(--border-color-secondary-stronger)"; - case "label": - return "var(--color-fg-neutral-dark)"; - case "activeBorder": - return "var(--border-color-secondary-strongest)"; - case "activeBackground": - return "var(--color-bg-secondary-strongest)"; - default: - return undefined; - } -}; diff --git a/packages/lib/src/checkbox/utils.tsx b/packages/lib/src/checkbox/utils.tsx new file mode 100644 index 0000000000..a112847d1c --- /dev/null +++ b/packages/lib/src/checkbox/utils.tsx @@ -0,0 +1,44 @@ +import { getMargin } from "../common/utils"; +import CheckboxPropsType from "./types"; + +const sizes = { + small: "120px", + medium: "240px", + large: "480px", + fillParent: "100%", + fitContent: "fit-content", +}; + +export const spaces = { + xxsmall: "var(--spacing-padding-xxs)", + xsmall: "var(--spacing-padding-xs)", + small: "var(--spacing-padding-s)", + medium: "var(--spacing-padding-m)", + large: "var(--spacing-padding-l)", + xlarge: "var(--spacing-padding-xl)", + xxlarge: "var(--spacing-padding-xxl)", +}; + +export const calculateWidth = (margin: CheckboxPropsType["margin"], size: CheckboxPropsType["size"]) => + size === "fillParent" + ? `calc(${sizes[size]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` + : size && sizes[size]; + +export const icons = { + checked: ( + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"> + <path + d="M19 3H5C3.89 3 3 3.9 3 5V19C3 20.1 3.89 21 5 21H19C20.11 21 21 20.1 21 19V5C21 3.9 20.11 3 19 3ZM10 17L5 12L6.41 10.59L10 14.17L17.59 6.58L19 8L10 17Z" + fill="currentColor" + /> + </svg> + ), + unchecked: ( + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"> + <path + d="M19 5V19H5V5H19ZM19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V5C21 3.9 20.1 3 19 3Z" + fill="currentColor" + /> + </svg> + ), +}; From ffa49d5224e8b475b442318acc4ebb1bc16694c4 Mon Sep 17 00:00:00 2001 From: Enrique Moreno <enrique.moreno@dxc.com> Date: Wed, 19 Mar 2025 11:44:22 +0100 Subject: [PATCH 11/12] Small fix for doc title --- apps/website/pages/components/checkbox/code.tsx | 2 +- apps/website/pages/components/checkbox/index.tsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/website/pages/components/checkbox/code.tsx b/apps/website/pages/components/checkbox/code.tsx index 71acfdb6cf..4a880336ce 100644 --- a/apps/website/pages/components/checkbox/code.tsx +++ b/apps/website/pages/components/checkbox/code.tsx @@ -7,7 +7,7 @@ const Code = () => { return ( <> <Head> - <title>Checkbox Code — Halstack Design System + Checkbox code — Halstack Design System diff --git a/apps/website/pages/components/checkbox/index.tsx b/apps/website/pages/components/checkbox/index.tsx index f39c26d2d6..c3b5922b15 100644 --- a/apps/website/pages/components/checkbox/index.tsx +++ b/apps/website/pages/components/checkbox/index.tsx @@ -3,7 +3,7 @@ import type { ReactElement } from "react"; import CheckboxOverviewPage from "screens/components/checkbox/overview/CheckboxOverviewPage"; import CheckboxPageLayout from "screens/components/checkbox/CheckboxPageLayout"; -const Usage = () => { +const Index = () => { return ( <> @@ -14,6 +14,6 @@ const Usage = () => { ); }; -Usage.getLayout = (page: ReactElement) => {page}; +Index.getLayout = (page: ReactElement) => {page}; -export default Usage; +export default Index; From 818ed6c1000bc17787e5941c26737150189a10fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Wed, 19 Mar 2025 12:11:20 +0100 Subject: [PATCH 12/12] Return statements removed --- .../website/pages/components/checkbox/code.tsx | 18 ++++++++---------- .../pages/components/checkbox/index.tsx | 18 ++++++++---------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/apps/website/pages/components/checkbox/code.tsx b/apps/website/pages/components/checkbox/code.tsx index 4a880336ce..5041cb1fde 100644 --- a/apps/website/pages/components/checkbox/code.tsx +++ b/apps/website/pages/components/checkbox/code.tsx @@ -3,16 +3,14 @@ import type { ReactElement } from "react"; import CheckboxPageLayout from "screens/components/checkbox/CheckboxPageLayout"; import CheckboxCodePage from "screens/components/checkbox/code/CheckboxCodePage"; -const Code = () => { - return ( - <> - - Checkbox code — Halstack Design System - - - - ); -}; +const Code = () => ( + <> + + Checkbox code — Halstack Design System + + + +); Code.getLayout = (page: ReactElement) => {page}; diff --git a/apps/website/pages/components/checkbox/index.tsx b/apps/website/pages/components/checkbox/index.tsx index c3b5922b15..60b254d22c 100644 --- a/apps/website/pages/components/checkbox/index.tsx +++ b/apps/website/pages/components/checkbox/index.tsx @@ -3,16 +3,14 @@ import type { ReactElement } from "react"; import CheckboxOverviewPage from "screens/components/checkbox/overview/CheckboxOverviewPage"; import CheckboxPageLayout from "screens/components/checkbox/CheckboxPageLayout"; -const Index = () => { - return ( - <> - - Checkbox — Halstack Design System - - - - ); -}; +const Index = () => ( + <> + + Checkbox — Halstack Design System + + + +); Index.getLayout = (page: ReactElement) => {page};