Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
cc2364e
feat: initial selection controls version
gjulivan Jul 10, 2025
751c92a
feat: initial update
gjulivan Jul 11, 2025
b28c57c
feat: update dropzone for custom content
gjulivan Jul 11, 2025
98b60bd
chore: updating code for selection controls for cleaner caption
gjulivan Jul 11, 2025
b95183a
chore: removing onleave and onenter event
gjulivan Jul 11, 2025
d0a275d
chore: update preview
gjulivan Jul 14, 2025
53881a3
chore: rename selection controls to checkbox radio selection
gjulivan Jul 14, 2025
67139dd
chore: update lock file
gjulivan Jul 14, 2025
50ca448
fix: lint and build
gjulivan Jul 15, 2025
895c604
fix: update test
gjulivan Jul 15, 2025
4ef22ee
fix: allow group name and fix onclick label
gjulivan Jul 15, 2025
d3957b1
test(checkbox-radio-selection-web): update e2e test with new naming
rahmanunver Jul 18, 2025
66e8e80
chore: update checkbox radio icon
gjulivan Jul 23, 2025
c5bd170
feat: allow boolean to choose for checkbox type
gjulivan Jul 23, 2025
31f71eb
chore: update styling
gjulivan Jul 24, 2025
4d8956c
feat(checkbox-radio-selection-web): add new icons
rahmanunver Aug 5, 2025
8e0775b
feat(checkbox-radio-selection-web): add checkbox for booleans
rahmanunver Aug 5, 2025
cd1bf36
test(checkbox-radio-selection-web): update test
rahmanunver Aug 5, 2025
7ab5b36
test(checkbox-radio-selection-web): fix e2e tests
rahmanunver Aug 6, 2025
acd5502
chore: update rollup config and e2e
gjulivan Aug 7, 2025
1fcdffa
feat: no options text
gjulivan Aug 14, 2025
313480d
feat: no options text readonly style
gjulivan Aug 15, 2025
3f8b4cc
fix: update based on testing
gjulivan Aug 18, 2025
08e3dce
test(checkbox-radio-selection-web): update e2e spec
leonardomendix Aug 19, 2025
f633e38
test(checkbox-radio-selection-web): update e2e screenshots
leonardomendix Aug 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified automation/utils/bin/rui-prepare-release.ts
100644 → 100755
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("@mendix/prettier-config-web-widgets");
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

All notable changes to this widget will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Initial release of Checkbox Radio Selection widget
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Checkbox Radio Selection

A widget for displaying radio button lists (single selection) and checkbox lists (multiple selection) based on different data sources.

## Features

- **Single Selection**: Radio button list for exclusive selection
- **Multiple Selection**: Checkbox list for multiple selection
- **Data Sources**: Support for context (association), database, and static data
- **Custom Content**: Ability to add custom content for options
- **Accessibility**: Full accessibility support with ARIA labels and keyboard navigation

## Configuration

The widget supports various data source types:

- **Context**: Use associations from your entity
- **Database**: Query database for selectable objects
- **Static**: Define static values directly in the widget

## Usage

1. Add the Checkbox Radio Selection widget to your page
2. Configure the data source (Context, Database, or Static)
3. Set up caption and value attributes
4. Configure selection method (single or multiple)
5. Customize styling and accessibility options

For detailed configuration options, please refer to the widget properties in Studio Pro.

## Browser Support

- Modern browsers supporting ES6+
- Internet Explorer 11+ (with polyfills)

## Development

This widget is built using:

- React 18+
- TypeScript
- Mendix Pluggable Widgets API
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { test, expect } from "@playwright/test";

test.afterEach("Cleanup session", async ({ page }) => {
// Because the test isolation that will open a new session for every test executed, and that exceeds Mendix's license limit of 5 sessions, so we need to force logout after each test.
await page.evaluate(() => window.mx.session.logout());
});

test.describe("checkbox-radio-selection-web", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/p/checkboxradioselection");
await page.waitForLoadState("networkidle");
await page.click(".mx-name-actionButton1");
});

test.describe("data source types", () => {
test("renders checkbox radio selection using association", async ({ page }) => {
const selectionControls = page.locator(".mx-name-checkboxRadioSelection1");
await expect(selectionControls).toBeVisible({ timeout: 10000 });
await expect(selectionControls).toHaveScreenshot(`checkboxRadioSelectionAssociation.png`);
});

test("renders checkbox radio selection using enum", async ({ page }) => {
const selectionControls = page.locator(".mx-name-checkboxRadioSelection2");
await expect(selectionControls).toBeVisible({ timeout: 10000 });
await expect(selectionControls).toHaveScreenshot(`checkboxRadioSelectionEnum.png`);
});

test("renders checkbox radio selection using boolean", async ({ page }) => {
const selectionControls = page.locator(".mx-name-checkboxRadioSelection3");
await expect(selectionControls).toBeVisible({ timeout: 10000 });
await expect(selectionControls).toHaveScreenshot(`checkboxRadioSelectionBoolean.png`);
});

test("renders checkbox radio selection using static values", async ({ page }) => {
await page.reload();
await page.click(".mx-name-actionButton1", { timeout: 10000 });
await page.waitForLoadState("networkidle", { timeout: 10000 });
const tabPage2 = page.getByRole("tab", { name: "Page 2" });
await expect(tabPage2).toBeVisible({ timeout: 10000 });
await tabPage2.click();
const selectionControls = page.locator(".mx-name-checkboxRadioSelection4");
await expect(selectionControls).toBeVisible({ timeout: 10000 });
await expect(selectionControls).toHaveScreenshot(`checkboxRadioSelectionStatic.png`);
});

test("renders checkbox radio selection using database", async ({ page }) => {
await page.reload();
await page.click(".mx-name-actionButton1", { timeout: 10000 });
await page.waitForLoadState("networkidle", { timeout: 10000 });
const tabPage2 = page.getByRole("tab", { name: "Page 2" });
await expect(tabPage2).toBeVisible({ timeout: 10000 });
await tabPage2.click();
const selectionControls = page.locator(".mx-name-checkboxRadioSelection5");
await expect(selectionControls).toBeVisible({ timeout: 10000 });
await expect(selectionControls).toHaveScreenshot(`checkboxRadioSelectionDatabase.png`);
});

test.describe("selection behavior", () => {
test("handles radio button selection", async ({ page }) => {
await page.reload();
await page.click(".mx-name-actionButton1", { timeout: 10000 });
await page.waitForLoadState("networkidle", { timeout: 10000 });
const tabPage2 = page.getByRole("tab", { name: "Page 2" });
await expect(tabPage2).toBeVisible({ timeout: 10000 });
await tabPage2.click();
const selectionControls = page.locator(".mx-name-checkboxRadioSelection5");
await expect(selectionControls).toBeVisible({ timeout: 10000 });

const radioOption = selectionControls.locator('input[type="radio"]').first();
await radioOption.click();
await expect(radioOption).toBeChecked();
});

test("handles checkbox selection", async ({ page }) => {
const selectionControls = page.locator(".mx-name-checkboxRadioSelection1"); // multi selection
await expect(selectionControls).toBeVisible({ timeout: 10000 });

const checkboxOption = selectionControls.locator('input[type="checkbox"]').first();
await checkboxOption.click();
await expect(checkboxOption).toBeChecked();
});
});
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import config from "@mendix/eslint-config-web-widgets/widget-ts.mjs";

export default config;
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"name": "@mendix/checkbox-radio-selection-web",
"widgetName": "CheckboxRadioSelection",
"version": "1.0.0",
"description": "Configurable radio buttons and check box widget",
"copyright": "© Mendix Technology BV 2025. All rights reserved.",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/mendix/web-widgets.git"
},
"config": {
"developmentPort": 3000,
"mendixHost": "http://localhost:8080"
},
"mxpackage": {
"name": "CheckboxRadioSelection",
"type": "widget",
"mpkName": "com.mendix.widget.web.CheckboxRadioSelection.mpk"
},
"packagePath": "com.mendix.widget.web",
"marketplace": {
"minimumMXVersion": "10.7.0",
"appNumber": 219304,
"appName": "Checkbox Radio Selection",
"reactReady": true
},
"testProject": {
"githubUrl": "https://github.com/mendix/testProjects",
"branchName": "checkbox-radio-selection-web"
},
"scripts": {
"prebuild": "rui-create-translation",
"build": "pluggable-widgets-tools build:web",
"create-gh-release": "rui-create-gh-release",
"create-translation": "rui-create-translation",
"dev": "pluggable-widgets-tools start:web",
"e2e": "run-e2e ci",
"e2edev": "run-e2e dev --with-preps",
"format": "prettier --ignore-path ./node_modules/@mendix/prettier-config-web-widgets/global-prettierignore --write .",
"lint": "eslint src/ package.json",
"publish-marketplace": "rui-publish-marketplace",
"release": "pluggable-widgets-tools release:web",
"start": "pluggable-widgets-tools start:server",
"test": "pluggable-widgets-tools test:unit:web:enzyme-free",
"update-changelog": "rui-update-changelog-widget",
"verify": "rui-verify-package-format"
},
"dependencies": {
"classnames": "^2.3.2"
},
"devDependencies": {
"@mendix/automation-utils": "workspace:*",
"@mendix/eslint-config-web-widgets": "workspace:*",
"@mendix/pluggable-widgets-tools": "*",
"@mendix/prettier-config-web-widgets": "workspace:*",
"@mendix/rollup-web-widgets": "workspace:*",
"@mendix/run-e2e": "workspace:^*",
"@mendix/widget-plugin-component-kit": "workspace:*",
"@mendix/widget-plugin-grid": "workspace:*",
"@mendix/widget-plugin-hooks": "workspace:*",
"@mendix/widget-plugin-platform": "workspace:*",
"@mendix/widget-plugin-test-utils": "workspace:*",
"cross-env": "^7.0.3"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("@mendix/run-e2e/playwright.config.cjs");
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import copyFiles from "@mendix/rollup-web-widgets/copyFiles.mjs";

export default args => {
return copyFiles(args);
};
Loading
Loading