diff --git a/packages/pluggableWidgets/checkbox-radio-selection-web/CHANGELOG.md b/packages/pluggableWidgets/checkbox-radio-selection-web/CHANGELOG.md index 6c69019ea9..ea02bac76c 100644 --- a/packages/pluggableWidgets/checkbox-radio-selection-web/CHANGELOG.md +++ b/packages/pluggableWidgets/checkbox-radio-selection-web/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Fixed + +- We fixed an issue where checkboxes remained visible in read-only "Content only" mode. Now only selected items are displayed as text, consistent with radio button behavior. + ## [1.1.1] - 2026-02-24 ### Fixed diff --git a/packages/pluggableWidgets/checkbox-radio-selection-web/src/__tests__/CheckboxRadioSelection.spec.tsx b/packages/pluggableWidgets/checkbox-radio-selection-web/src/__tests__/CheckboxRadioSelection.spec.tsx index 517ef3f6d1..691a8a513f 100644 --- a/packages/pluggableWidgets/checkbox-radio-selection-web/src/__tests__/CheckboxRadioSelection.spec.tsx +++ b/packages/pluggableWidgets/checkbox-radio-selection-web/src/__tests__/CheckboxRadioSelection.spec.tsx @@ -1,6 +1,8 @@ import { render } from "@testing-library/react"; import { CheckboxRadioSelectionContainerProps } from "../../typings/CheckboxRadioSelectionProps"; import CheckboxRadioSelection from "../CheckboxRadioSelection"; +import { CheckboxSelection } from "../components/CheckboxSelection/CheckboxSelection"; +import { MultiSelector } from "../helpers/types"; // Mock the selector to avoid implementation dependencies for basic tests jest.mock("../helpers/getSelector", () => ({ @@ -89,3 +91,94 @@ describe("CheckboxRadioSelection", () => { expect(widget?.className).toContain("widget-checkbox-radio-selection"); }); }); + +function makeMultiSelector(overrides: Partial = {}): MultiSelector { + return { + type: "multi", + status: "available", + readOnly: false, + currentId: [], + clearable: false, + customContentType: "no", + validation: undefined, + updateProps: jest.fn(), + setValue: jest.fn(), + getOptions: jest.fn(() => ["option1", "option2", "option3"]), + options: { + status: "available", + searchTerm: "", + isLoading: false, + getAll: jest.fn(() => ["option1", "option2", "option3"]), + setSearchTerm: jest.fn(), + onAfterSearchTermChange: jest.fn(), + _updateProps: jest.fn(), + _optionToValue: jest.fn(), + _valueToOption: jest.fn() + }, + caption: { + get: jest.fn((v: string) => `Caption ${v}`), + render: jest.fn((v: string | null | number | null) => `Caption ${v}`), + emptyCaption: "Select an option", + formatter: undefined + }, + ...overrides + }; +} + +const baseCheckboxProps = { + inputId: "test-checkbox", + tabIndex: 0, + ariaRequired: { status: "available" as const, value: false } as any, + ariaLabel: undefined, + groupName: undefined, + noOptionsText: "No options" +}; + +describe("CheckboxSelection – read-only text mode", () => { + it("hides unselected options and their inputs", () => { + const selector = makeMultiSelector({ readOnly: true, currentId: ["option1"] }); + const { queryByDisplayValue } = render( + + ); + + // unselected options should not appear at all + expect(queryByDisplayValue("option2")).toBeNull(); + expect(queryByDisplayValue("option3")).toBeNull(); + }); + + it("renders no for the selected option in text mode", () => { + const selector = makeMultiSelector({ readOnly: true, currentId: ["option1"] }); + const { queryAllByRole } = render( + + ); + + expect(queryAllByRole("checkbox")).toHaveLength(0); + }); + + it("renders selected option caption text", () => { + const selector = makeMultiSelector({ readOnly: true, currentId: ["option1"] }); + const { getByText } = render( + + ); + + expect(getByText("Caption option1")).toBeTruthy(); + }); + + it("renders all inputs when not read-only", () => { + const selector = makeMultiSelector({ readOnly: false, currentId: ["option1"] }); + const { getAllByRole } = render( + + ); + + expect(getAllByRole("checkbox")).toHaveLength(3); + }); + + it("renders inputs in bordered read-only mode", () => { + const selector = makeMultiSelector({ readOnly: true, currentId: ["option1"] }); + const { getAllByRole } = render( + + ); + + expect(getAllByRole("checkbox")).toHaveLength(3); + }); +}); diff --git a/packages/pluggableWidgets/checkbox-radio-selection-web/src/components/CheckboxSelection/CheckboxSelection.tsx b/packages/pluggableWidgets/checkbox-radio-selection-web/src/components/CheckboxSelection/CheckboxSelection.tsx index ec3604ee93..e48918ca5f 100644 --- a/packages/pluggableWidgets/checkbox-radio-selection-web/src/components/CheckboxSelection/CheckboxSelection.tsx +++ b/packages/pluggableWidgets/checkbox-radio-selection-web/src/components/CheckboxSelection/CheckboxSelection.tsx @@ -1,3 +1,4 @@ +import { If } from "@mendix/widget-plugin-component-kit/If"; import classNames from "classnames"; import { MouseEvent, ReactElement } from "react"; import { MultiSelector, SelectionBaseProps } from "../../helpers/types"; @@ -48,6 +49,9 @@ export function CheckboxSelection({ {options.map((optionId, index) => { const isSelected = currentIds.includes(optionId); const checkboxId = `${inputId}-checkbox-${index}`; + if (isReadOnly && !isSelected && readOnlyStyle === "text") { + return null; + } return (
- handleChange(optionId, e.target.checked)} - aria-describedby={isSingleCheckbox && selector.validation ? errorId : undefined} - aria-invalid={isSingleCheckbox && selector.validation ? true : undefined} - /> + + handleChange(optionId, e.target.checked)} + aria-describedby={isSingleCheckbox && selector.validation ? errorId : undefined} + aria-invalid={isSingleCheckbox && selector.validation ? true : undefined} + /> + ) => { e.preventDefault(); diff --git a/packages/pluggableWidgets/checkbox-radio-selection-web/src/ui/CheckboxRadioSelection.scss b/packages/pluggableWidgets/checkbox-radio-selection-web/src/ui/CheckboxRadioSelection.scss index 34b6148712..c8cf1eca26 100644 --- a/packages/pluggableWidgets/checkbox-radio-selection-web/src/ui/CheckboxRadioSelection.scss +++ b/packages/pluggableWidgets/checkbox-radio-selection-web/src/ui/CheckboxRadioSelection.scss @@ -6,7 +6,8 @@ &-readonly { &.widget-checkbox-radio-selection-readonly-text { - .radio-item { + .radio-item, + .checkbox-item { display: none; &.widget-checkbox-radio-selection-item-selected {