{options.map((optionId, index) => {
const isSelected = currentIds.includes(optionId);
diff --git a/packages/pluggableWidgets/checkbox-radio-selection-web/src/components/RadioSelection/RadioSelection.tsx b/packages/pluggableWidgets/checkbox-radio-selection-web/src/components/RadioSelection/RadioSelection.tsx
index 930f79da82..7e7c9ea095 100644
--- a/packages/pluggableWidgets/checkbox-radio-selection-web/src/components/RadioSelection/RadioSelection.tsx
+++ b/packages/pluggableWidgets/checkbox-radio-selection-web/src/components/RadioSelection/RadioSelection.tsx
@@ -1,17 +1,19 @@
+import { If } from "@mendix/widget-plugin-component-kit/If";
import classNames from "classnames";
import { ChangeEvent, MouseEvent, ReactElement } from "react";
import { SelectionBaseProps, SingleSelector } from "../../helpers/types";
import { getValidationErrorId } from "../../helpers/utils";
+import { useWrapperProps } from "../../hooks/useWrapperProps";
import { CaptionContent } from "../CaptionContent";
import { ValidationAlert } from "@mendix/widget-plugin-component-kit/Alert";
import { Placeholder } from "../Placeholder";
-import { If } from "@mendix/widget-plugin-component-kit/If";
export function RadioSelection({
selector,
tabIndex = 0,
inputId,
ariaRequired,
+ ariaLabel,
readOnlyStyle,
groupName,
noOptionsText
@@ -43,15 +45,14 @@ export function RadioSelection({
return (
{options.map((optionId, index) => {
const isSelected = currentId === optionId;
diff --git a/packages/pluggableWidgets/checkbox-radio-selection-web/src/helpers/types.ts b/packages/pluggableWidgets/checkbox-radio-selection-web/src/helpers/types.ts
index f2a9aa7a31..505ed7556a 100644
--- a/packages/pluggableWidgets/checkbox-radio-selection-web/src/helpers/types.ts
+++ b/packages/pluggableWidgets/checkbox-radio-selection-web/src/helpers/types.ts
@@ -84,6 +84,7 @@ export interface SelectionBaseProps
{
selector: Selector;
tabIndex: number;
ariaRequired: DynamicValue;
+ ariaLabel: DynamicValue | undefined;
groupName: DynamicValue | undefined;
noOptionsText: string;
}
diff --git a/packages/pluggableWidgets/checkbox-radio-selection-web/src/helpers/utils.ts b/packages/pluggableWidgets/checkbox-radio-selection-web/src/helpers/utils.ts
index c05390081e..646a20a472 100644
--- a/packages/pluggableWidgets/checkbox-radio-selection-web/src/helpers/utils.ts
+++ b/packages/pluggableWidgets/checkbox-radio-selection-web/src/helpers/utils.ts
@@ -59,3 +59,7 @@ export function getCustomCaption(values: CheckboxRadioSelectionPreviewProps): st
export function getValidationErrorId(inputId?: string): string | undefined {
return inputId ? inputId + "-validation-message" : undefined;
}
+
+export function getInputLabel(inputId: string): Element | null {
+ return document.querySelector(`label[for="${inputId}"]`);
+}
diff --git a/packages/pluggableWidgets/checkbox-radio-selection-web/src/hooks/useWrapperProps.ts b/packages/pluggableWidgets/checkbox-radio-selection-web/src/hooks/useWrapperProps.ts
new file mode 100644
index 0000000000..2dcc1bf792
--- /dev/null
+++ b/packages/pluggableWidgets/checkbox-radio-selection-web/src/hooks/useWrapperProps.ts
@@ -0,0 +1,34 @@
+import { useMemo } from "react";
+import { getInputLabel } from "../helpers/utils";
+import classNames from "classnames";
+import { ReadOnlyStyleEnum } from "../../typings/CheckboxRadioSelectionProps";
+import { DynamicValue } from "mendix";
+
+interface WrapperProps {
+ inputId: string;
+ isReadOnly: boolean;
+ isCheckbox: boolean;
+ readOnlyStyle: ReadOnlyStyleEnum;
+ ariaRequired: DynamicValue;
+ ariaLabel: DynamicValue | undefined;
+}
+
+export function useWrapperProps(props: WrapperProps): any {
+ const { inputId, isReadOnly, isCheckbox, readOnlyStyle, ariaRequired, ariaLabel } = props;
+
+ const inputLabel = getInputLabel(inputId);
+ const hasLabel = useMemo(() => Boolean(inputLabel), [inputLabel]);
+ const hasAriaLabel = useMemo(() => Boolean(ariaLabel && ariaLabel.value), [ariaLabel]);
+
+ return {
+ className: classNames("widget-checkbox-radio-selection-list", {
+ "widget-checkbox-radio-selection-readonly": isReadOnly,
+ [`widget-checkbox-radio-selection-readonly-${readOnlyStyle}`]: isReadOnly
+ }),
+ id: inputId,
+ role: isCheckbox ? "group" : "radiogroup",
+ "aria-labelledby": hasLabel ? `${inputId}-label` : undefined,
+ "aria-required": ariaRequired ? ariaRequired.value : undefined,
+ "aria-label": hasAriaLabel ? ariaLabel?.value : undefined
+ };
+}
diff --git a/packages/pluggableWidgets/checkbox-radio-selection-web/src/package.xml b/packages/pluggableWidgets/checkbox-radio-selection-web/src/package.xml
index 2d81ae1635..794be0ced8 100644
--- a/packages/pluggableWidgets/checkbox-radio-selection-web/src/package.xml
+++ b/packages/pluggableWidgets/checkbox-radio-selection-web/src/package.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/packages/pluggableWidgets/checkbox-radio-selection-web/typings/CheckboxRadioSelectionProps.d.ts b/packages/pluggableWidgets/checkbox-radio-selection-web/typings/CheckboxRadioSelectionProps.d.ts
index 73d66d4f20..d7cadccba5 100644
--- a/packages/pluggableWidgets/checkbox-radio-selection-web/typings/CheckboxRadioSelectionProps.d.ts
+++ b/packages/pluggableWidgets/checkbox-radio-selection-web/typings/CheckboxRadioSelectionProps.d.ts
@@ -45,16 +45,16 @@ export interface CheckboxRadioSelectionContainerProps {
attributeBoolean: EditableValue;
optionsSourceDatabaseDataSource?: ListValue;
optionsSourceDatabaseItemSelection?: SelectionSingleValue | SelectionMultiValue;
+ optionsSourceDatabaseValueAttribute?: ListAttributeValue;
+ databaseAttributeString?: EditableValue;
+ attributeAssociation: ReferenceValue | ReferenceSetValue;
+ optionsSourceAssociationDataSource?: ListValue;
optionsSourceAssociationCaptionType: OptionsSourceAssociationCaptionTypeEnum;
optionsSourceDatabaseCaptionType: OptionsSourceDatabaseCaptionTypeEnum;
optionsSourceAssociationCaptionAttribute?: ListAttributeValue;
optionsSourceDatabaseCaptionAttribute?: ListAttributeValue;
optionsSourceAssociationCaptionExpression?: ListExpressionValue;
optionsSourceDatabaseCaptionExpression?: ListExpressionValue;
- optionsSourceDatabaseValueAttribute?: ListAttributeValue;
- databaseAttributeString?: EditableValue;
- attributeAssociation: ReferenceValue | ReferenceSetValue;
- optionsSourceAssociationDataSource?: ListValue;
staticAttribute: EditableValue;
optionsSourceStaticDataSource: OptionsSourceStaticDataSourceType[];
noOptionsText?: DynamicValue;
@@ -62,12 +62,13 @@ export interface CheckboxRadioSelectionContainerProps {
optionsSourceAssociationCustomContent?: ListWidgetValue;
optionsSourceDatabaseCustomContent?: ListWidgetValue;
controlType: ControlTypeEnum;
+ groupName?: DynamicValue;
customEditability: CustomEditabilityEnum;
customEditabilityExpression: DynamicValue;
readOnlyStyle: ReadOnlyStyleEnum;
onChangeEvent?: ActionValue;
ariaRequired: DynamicValue;
- groupName?: DynamicValue;
+ ariaLabel?: DynamicValue;
}
export interface CheckboxRadioSelectionPreviewProps {
@@ -80,16 +81,16 @@ export interface CheckboxRadioSelectionPreviewProps {
attributeBoolean: string;
optionsSourceDatabaseDataSource: {} | { caption: string } | { type: string } | null;
optionsSourceDatabaseItemSelection: "Single" | "Multi" | "None";
+ optionsSourceDatabaseValueAttribute: string;
+ databaseAttributeString: string;
+ attributeAssociation: string;
+ optionsSourceAssociationDataSource: {} | { caption: string } | { type: string } | null;
optionsSourceAssociationCaptionType: OptionsSourceAssociationCaptionTypeEnum;
optionsSourceDatabaseCaptionType: OptionsSourceDatabaseCaptionTypeEnum;
optionsSourceAssociationCaptionAttribute: string;
optionsSourceDatabaseCaptionAttribute: string;
optionsSourceAssociationCaptionExpression: string;
optionsSourceDatabaseCaptionExpression: string;
- optionsSourceDatabaseValueAttribute: string;
- databaseAttributeString: string;
- attributeAssociation: string;
- optionsSourceAssociationDataSource: {} | { caption: string } | { type: string } | null;
staticAttribute: string;
optionsSourceStaticDataSource: OptionsSourceStaticDataSourcePreviewType[];
noOptionsText: string;
@@ -97,11 +98,12 @@ export interface CheckboxRadioSelectionPreviewProps {
optionsSourceAssociationCustomContent: { widgetCount: number; renderer: ComponentType<{ children: ReactNode; caption?: string }> };
optionsSourceDatabaseCustomContent: { widgetCount: number; renderer: ComponentType<{ children: ReactNode; caption?: string }> };
controlType: ControlTypeEnum;
+ groupName: string;
customEditability: CustomEditabilityEnum;
customEditabilityExpression: string;
readOnlyStyle: ReadOnlyStyleEnum;
onChangeEvent: {} | null;
onChangeDatabaseEvent: {} | null;
ariaRequired: string;
- groupName: string;
+ ariaLabel: string;
}