From 7f655528c2efffbde8432e051e165253557c25ed Mon Sep 17 00:00:00 2001 From: Yordan Stoyanov Date: Thu, 30 Apr 2026 14:48:09 +0200 Subject: [PATCH 1/2] fix: show only selected items in readonly content-only mode --- .../checkbox-radio-selection-web/CHANGELOG.md | 4 ++++ .../src/components/CheckboxSelection/CheckboxSelection.tsx | 3 +++ .../src/ui/CheckboxRadioSelection.scss | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) 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/components/CheckboxSelection/CheckboxSelection.tsx b/packages/pluggableWidgets/checkbox-radio-selection-web/src/components/CheckboxSelection/CheckboxSelection.tsx index ec3604ee93..d62e240289 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 @@ -48,6 +48,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 (
Date: Tue, 26 May 2026 15:10:28 +0200 Subject: [PATCH 2/2] fix: remove hidden input from text read-only mode and add tests --- .../__tests__/CheckboxRadioSelection.spec.tsx | 93 +++++++++++++++++++ .../CheckboxSelection/CheckboxSelection.tsx | 27 +++--- 2 files changed, 108 insertions(+), 12 deletions(-) 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 d62e240289..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"; @@ -59,18 +60,20 @@ export function CheckboxSelection({ "widget-checkbox-radio-selection-item-selected": isSelected })} > - 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();