Resolve errors and pass tests

This commit is contained in:
adilallo
2026-02-04 14:15:22 -07:00
parent 0ebad759f9
commit 97e2680c57
7 changed files with 15 additions and 36 deletions
@@ -1,6 +1,6 @@
"use client"; "use client";
import { memo, useCallback, useId, useState, useEffect } from "react"; import { memo, useCallback, useId, useState } from "react";
import { CheckboxGroupView } from "./CheckboxGroup.view"; import { CheckboxGroupView } from "./CheckboxGroup.view";
import type { CheckboxGroupProps } from "./CheckboxGroup.types"; import type { CheckboxGroupProps } from "./CheckboxGroup.types";
@@ -18,15 +18,11 @@ const CheckboxGroupContainer = ({
const generatedId = useId(); const generatedId = useId();
const groupId = name || `checkbox-group-${generatedId}`; const groupId = name || `checkbox-group-${generatedId}`;
// Internal state to track checked values // Internal state to track checked values (only used if value prop is not provided)
const [checkedValues, setCheckedValues] = useState<string[]>(value || []); const [internalCheckedValues, setInternalCheckedValues] = useState<string[]>([]);
// Sync internal state with external value prop // Use controlled value if provided, otherwise use internal state
useEffect(() => { const checkedValues = value !== undefined ? value : internalCheckedValues;
if (value !== undefined) {
setCheckedValues(value);
}
}, [value]);
const handleOptionChange = useCallback( const handleOptionChange = useCallback(
(optionValue: string, checked: boolean) => { (optionValue: string, checked: boolean) => {
@@ -36,13 +32,16 @@ const CheckboxGroupContainer = ({
? [...checkedValues, optionValue] ? [...checkedValues, optionValue]
: checkedValues.filter((v) => v !== optionValue); : checkedValues.filter((v) => v !== optionValue);
setCheckedValues(newCheckedValues); // Only update internal state if uncontrolled
if (value === undefined) {
setInternalCheckedValues(newCheckedValues);
}
if (onChange) { if (onChange) {
onChange({ value: newCheckedValues }); onChange({ value: newCheckedValues });
} }
}, },
[disabled, checkedValues, onChange], [disabled, checkedValues, onChange, value],
); );
return ( return (
@@ -16,7 +16,6 @@ const RadioButtonContainer = ({
value, value,
ariaLabel, ariaLabel,
className = "", className = "",
...props
}: RadioButtonProps) => { }: RadioButtonProps) => {
const isInverse = mode === "inverse"; const isInverse = mode === "inverse";
const isStandard = mode === "standard"; const isStandard = mode === "standard";
@@ -82,23 +81,6 @@ const RadioButtonContainer = ({
const combinedBoxStyles = getBoxStyles(); const combinedBoxStyles = getBoxStyles();
// Dot color per Figma
// Selected state: light cream/yellow (#fefcc9)
// Selected hover state: darker yellow/brown (#333000 or rgba(51, 48, 0, 1))
const getDotColor = (): string => {
if (!checked) return "transparent";
if (isStandard) {
// Use CSS to handle hover state - default is light cream, hover is darker
return "var(--color-content-default-brand-primary, #fefcc9)";
}
// Inverse mode: black dot
return "var(--color-content-default-primary, #000000)";
};
const dotColor = getDotColor();
// Label color // Label color
const labelColor = isInverse const labelColor = isInverse
? "var(--color-content-inverse-primary)" ? "var(--color-content-inverse-primary)"
@@ -139,7 +121,6 @@ const RadioButtonContainer = ({
ariaLabel={ariaLabel} ariaLabel={ariaLabel}
className={className} className={className}
combinedBoxStyles={combinedBoxStyles} combinedBoxStyles={combinedBoxStyles}
dotColor={dotColor}
labelColor={labelColor} labelColor={labelColor}
onToggle={handleToggle} onToggle={handleToggle}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
@@ -24,7 +24,6 @@ export interface RadioButtonViewProps {
ariaLabel?: string; ariaLabel?: string;
className: string; className: string;
combinedBoxStyles: string; combinedBoxStyles: string;
dotColor: string;
labelColor: string; labelColor: string;
onToggle: (_e: React.MouseEvent | React.KeyboardEvent) => void; onToggle: (_e: React.MouseEvent | React.KeyboardEvent) => void;
onKeyDown: (_e: React.KeyboardEvent<HTMLSpanElement>) => void; onKeyDown: (_e: React.KeyboardEvent<HTMLSpanElement>) => void;
@@ -11,7 +11,6 @@ export function RadioButtonView({
ariaLabel, ariaLabel,
className, className,
combinedBoxStyles, combinedBoxStyles,
dotColor,
labelColor, labelColor,
onToggle, onToggle,
onKeyDown, onKeyDown,
@@ -59,7 +59,6 @@ export function SelectInputView({
menuRef, menuRef,
ariaLabelledby, ariaLabelledby,
ariaInvalid, ariaInvalid,
...props
}: SelectInputViewProps) { }: SelectInputViewProps) {
// Styles based on Figma design // Styles based on Figma design
const containerClasses = "flex flex-col gap-[8px]"; const containerClasses = "flex flex-col gap-[8px]";
+1 -1
View File
@@ -99,7 +99,7 @@ Step2.args = {
description: "You can also combine or add new approaches to the list", description: "You can also combine or add new approaches to the list",
children: ( children: (
<div className="space-y-4"> <div className="space-y-4">
<Input label="Label" placeholder="Enter text" value="" /> <TextInput label="Label" placeholder="Enter text" value="" />
</div> </div>
), ),
showBackButton: true, showBackButton: true,
+3 -1
View File
@@ -188,9 +188,10 @@ describe("NumberCard Component", () => {
it("applies Small size variant correctly", () => { it("applies Small size variant correctly", () => {
render(<NumberCard {...defaultProps} size="Small" />); render(<NumberCard {...defaultProps} size="Small" />);
// For Small size, text is directly in card div (no wrapper), so use closest("div")
const card = screen const card = screen
.getByText("Test Card Text") .getByText("Test Card Text")
.closest("div").parentElement; .closest("div");
expect(card).toHaveClass( expect(card).toHaveClass(
"flex", "flex",
"flex-col", "flex-col",
@@ -198,6 +199,7 @@ describe("NumberCard Component", () => {
"justify-center", "justify-center",
"gap-4", "gap-4",
"p-5", "p-5",
"relative",
); );
const textElement = screen.getByText("Test Card Text"); const textElement = screen.getByText("Test Card Text");