UNPKG

@progress/sitefinity-nextjs-sdk

Version:

Provides OOB widgets developed using the Next.js framework, which includes an abstraction layer for Sitefinity communication. Additionally, it offers an expanded API, typings, and tools for further development and integration.

113 lines (112 loc) 6.88 kB
'use client'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import React, { useContext, useState } from 'react'; import { StylingConfig } from '../../styling/styling-config'; import { VisibilityStyle } from '../../styling/visibility-style'; import { classNames } from '../../../editor/utils/classNames'; import { FormContext } from '../../form/form-context'; import { getUniqueId } from '../../../editor/utils/getUniqueId'; export function CheckboxesClient(props) { let layoutClass = ''; let innerColumnClass = ''; const parsed = parseInt(props.columnsNumber.toString(), 10); switch (parsed) { case 0: layoutClass = 'd-flex flex-wrap'; innerColumnClass = 'me-2'; break; case 2: layoutClass = 'row m-0'; innerColumnClass = 'col-6'; break; case 3: layoutClass = 'row m-0'; innerColumnClass = 'col-4'; break; default: break; } const checkboxUniqueId = props.sfFieldName; const inputCheckboxUniqueId = getUniqueId(checkboxUniqueId, props.widgetContext.model.Id); const otherChoiceOptionId = getUniqueId(`choiceOption-other-${checkboxUniqueId}`, props.widgetContext.model.Id); const otherChoiceInputRef = React.useRef(null); const [inputValues, setInputValues] = React.useState(props.choices); const { formViewProps, sfFormValueChanged, dispatchValidity, hiddenInputs, skippedInputs, formSubmitted } = useContext(FormContext); const isHidden = hiddenInputs[checkboxUniqueId]; const isSkipped = skippedInputs[checkboxUniqueId]; const [errorMessageText, setErrorMessageText] = useState(''); const [otherInputText, setOtherInputText] = useState(''); const [showOtherInput, setShowOtherInput] = useState(false); let delayTimer; function dispatchValueChanged() { clearTimeout(delayTimer); delayTimer = setTimeout(function () { sfFormValueChanged(); }, 300); } function clearErrorMessage() { setErrorMessageText(''); } const handleChange = (event) => { clearErrorMessage(); const newInputValues = [...inputValues].map((input) => { return { ...input, Selected: event.target.value.toString() === input.Value?.toString() ? event.target.checked : input.Selected }; }); setInputValues(newInputValues); dispatchValueChanged(); }; function handleOtherChange(event) { setShowOtherInput(event.target.checked); dispatchValueChanged(); } function handleOtherInputChange(event) { if (event.target.value) { clearErrorMessage(); } else { setErrorMessageText(props.requiredErrorMessage.replace('{0}', props.label)); } dispatchValueChanged(); } function handleOtherInputInput(event) { setOtherInputText(event.target.value); } const hasValueSelected = React.useMemo(() => { return inputValues.some((i) => i.Selected); }, [inputValues]); const handleChoiceValidation = () => { const otherChoiceInput = otherChoiceInputRef.current; if ((props.required && !hasValueSelected) && !(otherChoiceInput && otherChoiceInput.required)) { setErrorMessageText(props.requiredErrorMessage.replace('{0}', props.label)); return false; } if (otherChoiceInput && otherChoiceInput.required && otherChoiceInput.validity.valueMissing) { setErrorMessageText(props.requiredErrorMessage.replace('{0}', props.label)); return false; } return true; }; React.useEffect(() => { let isValid = false; if (formSubmitted) { isValid = handleChoiceValidation(); } dispatchValidity(checkboxUniqueId, isValid); // eslint-disable-next-line react-hooks/exhaustive-deps }, [formSubmitted]); return (_jsxs("fieldset", { "data-sf-role": "checkboxes-field-container", className: classNames('mb-3', props.cssClass, isHidden ? StylingConfig.VisibilityClasses[VisibilityStyle.Hidden] : StylingConfig.VisibilityClasses[VisibilityStyle.Visible]), "aria-labelledby": `choice-field-label-${checkboxUniqueId} choice-field-description-${checkboxUniqueId}`, children: [_jsx("input", { type: "hidden", "data-sf-role": "required-validator", value: props.required.toString() }), _jsx("legend", { className: "h6", id: `choice-field-label-${checkboxUniqueId}`, children: props.label }), props.instructionalText && _jsx("p", { className: "text-muted small", id: `choice-field-description-${checkboxUniqueId}`, children: props.instructionalText }), _jsxs("div", { className: layoutClass, children: [inputValues.map((choiceOption, idx) => { const choiceOptionId = `choiceOption-${idx}-${inputCheckboxUniqueId}`; return (_jsxs("div", { className: `form-check ${innerColumnClass}`, children: [_jsx("input", { className: "form-check-input", type: "checkbox", name: checkboxUniqueId, id: choiceOptionId, value: choiceOption.Value || '', "data-sf-role": "checkboxes-field-input", required: props.required && !hasValueSelected, checked: !!choiceOption.Selected, disabled: isHidden || isSkipped, onChange: handleChange }), _jsx("label", { className: "form-check-label", htmlFor: choiceOptionId, children: choiceOption.Name })] }, idx)); }), props.hasAdditionalChoice && _jsxs("div", { className: `form-check ${innerColumnClass}`, children: [_jsx("input", { className: "form-check-input mt-1", type: "checkbox", name: checkboxUniqueId, id: otherChoiceOptionId, "data-sf-role": "checkboxes-field-input", required: props.required && !hasValueSelected, checked: showOtherInput, value: otherInputText, onChange: handleOtherChange }), _jsx("label", { className: "form-check-label", htmlFor: otherChoiceOptionId, children: "Other" }), showOtherInput && _jsx("input", { type: "text", ref: otherChoiceInputRef, className: classNames('form-control', { [formViewProps.invalidClass]: formViewProps.invalidClass && props.required && !otherInputText && !hasValueSelected }), "data-sf-role": "choice-other-input", value: otherInputText, required: props.required, disabled: isHidden || isSkipped, onChange: handleOtherInputChange, onInput: handleOtherInputInput })] })] }), props.required && errorMessageText && _jsx("div", { "data-sf-role": "error-message", role: "alert", "aria-live": "assertive", className: classNames('invalid-feedback', { [StylingConfig.VisibilityClasses[VisibilityStyle.Visible]]: true }), children: errorMessageText })] })); }