Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions packages/pluggableWidgets/switch-web/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Fixed

- Improved accessibility and input handling. Clicking the label now toggles the switch.

## [4.2.2] - 2024-08-28

### Changed
Expand Down
2 changes: 1 addition & 1 deletion packages/pluggableWidgets/switch-web/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@mendix/switch-web",
"widgetName": "Switch",
"version": "4.2.2",
"version": "4.3.0",
"description": "Toggle a boolean attribute",
"copyright": "© Mendix Technology BV 2025. All rights reserved.",
"license": "Apache-2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { Switch } from "../Switch";

describe("Switch", () => {
const renderSwitch = (props: SwitchContainerProps) => {

Check warning on line 9 in packages/pluggableWidgets/switch-web/src/__tests__/Switch.spec.tsx

View workflow job for this annotation

GitHub Actions / Run code quality check

Missing return type on function
return render(<Switch {...props} />);
};
const createProps = (props?: Partial<SwitchContainerProps>): SwitchContainerProps => {
Expand Down Expand Up @@ -99,7 +99,7 @@
const { container } = renderSwitch(props);
const wrapper = container.querySelector(".widget-switch-btn-wrapper");
expect(wrapper?.classList.contains("disabled")).toBe(false);
expect(wrapper?.getAttribute("aria-readonly")).toBe("false");
expect(wrapper?.getAttribute("aria-disabled")).toBe("false");
});

it("invokes action on click", () => {
Expand Down Expand Up @@ -173,7 +173,7 @@
const { container } = renderSwitch(props);
const wrapper = container.querySelector(".widget-switch-btn-wrapper");
expect(wrapper?.classList.contains("disabled")).toBe(true);
expect(wrapper?.getAttribute("aria-readonly")).toBe("true");
expect(wrapper?.getAttribute("aria-disabled")).toBe("true");
});

it("shouldn't invoke action", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@ exports[`Switch with editable value renders the structure correctly 1`] = `
<div
class="widget-switch"
>
<input
aria-checked="false"
aria-hidden="true"
class="sr-only"
id="com.mendix.widgets.custom.switch1"
readonly=""
tabindex="-1"
type="checkbox"
/>
<div
aria-checked="false"
aria-disabled="false"
aria-labelledby="com.mendix.widgets.custom.switch1-label"
aria-readonly="false"
class="widget-switch-btn-wrapper widget-switch-btn-wrapper-default un-checked"
id="com.mendix.widgets.custom.switch1"
role="switch"
tabindex="0"
>
Expand All @@ -27,12 +35,21 @@ exports[`Switch with readonly value renders the structure correctly 1`] = `
<div
class="widget-switch"
>
<input
aria-checked="false"
aria-hidden="true"
class="sr-only"
disabled=""
id="com.mendix.widgets.custom.switch1"
readonly=""
tabindex="-1"
type="checkbox"
/>
<div
aria-checked="false"
aria-disabled="true"
aria-labelledby="com.mendix.widgets.custom.switch1-label"
aria-readonly="true"
class="widget-switch-btn-wrapper widget-switch-btn-wrapper-default disabled un-checked"
id="com.mendix.widgets.custom.switch1"
role="switch"
tabindex="0"
>
Expand Down
15 changes: 13 additions & 2 deletions packages/pluggableWidgets/switch-web/src/components/Switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,19 @@ export interface SwitchProps extends Pick<SwitchContainerProps, "id" | "tabIndex
export default function Switch(props: SwitchProps): ReactElement {
return (
<div className="widget-switch">
<div
<input
type="checkbox"
id={props.id}
onClick={props.onClick}
checked={props.isChecked}
aria-checked={props.isChecked}
readOnly
className="sr-only"
disabled={!props.editable}
tabIndex={-1}
aria-hidden="true"
/>
<div
className={classNames("widget-switch-btn-wrapper", "widget-switch-btn-wrapper-default", {
checked: props.isChecked,
disabled: !props.editable,
Expand All @@ -27,7 +38,7 @@ export default function Switch(props: SwitchProps): ReactElement {
role="switch"
aria-checked={props.isChecked}
aria-labelledby={`${props.id}-label`}
aria-readonly={!props.editable}
aria-disabled={!props.editable}
>
<div
className={classNames("widget-switch-btn", {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
validation: undefined
};

function renderSwitch(props: Partial<SwitchProps> = {}) {

Check warning on line 16 in packages/pluggableWidgets/switch-web/src/components/__tests__/Switch.spec.tsx

View workflow job for this annotation

GitHub Actions / Run code quality check

Missing return type on function
return render(<Switch {...{ ...defaultProps, ...props }} />);
}

Expand All @@ -21,7 +21,7 @@
renderSwitch();
expect(screen.getByRole("switch")).toBeInTheDocument();
expect(screen.getByRole("switch")).toHaveAttribute("aria-checked", "false");
expect(screen.getByRole("switch")).toHaveAttribute("aria-readonly", "false");
expect(screen.getByRole("switch")).toHaveAttribute("aria-disabled", "false");
});

it("shows checked state", () => {
Expand All @@ -32,7 +32,7 @@
it("shows disabled state", () => {
renderSwitch({ editable: false });
expect(screen.getByRole("switch")).toHaveClass("disabled");
expect(screen.getByRole("switch")).toHaveAttribute("aria-readonly", "true");
expect(screen.getByRole("switch")).toHaveAttribute("aria-disabled", "true");
});

it("calls onClick when clicked", async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/pluggableWidgets/switch-web/src/package.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<package xmlns="http://www.mendix.com/package/1.0/">
<clientModule name="Switch" version="4.2.2" xmlns="http://www.mendix.com/clientModule/1.0/">
<clientModule name="Switch" version="4.3.0" xmlns="http://www.mendix.com/clientModule/1.0/">
<widgetFiles>
<widgetFile path="Switch.xml" />
</widgetFiles>
Expand Down
Loading