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.

98 lines (97 loc) 5.87 kB
'use client'; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import React, { useContext, useState } from 'react'; import { VisibilityStyle } from '../../styling/visibility-style'; import { StylingConfig } from '../../styling/styling-config'; import { classNames } from '../../../editor/utils/classNames'; import { FormContext } from '../../form/form-context'; import { getUniqueId } from '../../../editor/utils/getUniqueId'; import { AffixType } from './interfaces/affix-type'; export function NumberFieldClient(props) { const numberFieldUniqueId = props.widgetContext.model.Properties.SfFieldName; const numberFieldErrorMessageId = getUniqueId('NumberFieldErrorMessage', props.widgetContext.model.Id); const numberFieldInfoMessageId = getUniqueId('NumberFieldInfo', props.widgetContext.model.Id); let ariaDescribedByAttribute = props.hasDescription ? `${numberFieldUniqueId} ${numberFieldErrorMessageId}` : numberFieldErrorMessageId; const hasAffix = props.affixType !== AffixType.none && props.affixText; let affixId; if (hasAffix) { affixId = getUniqueId('NumberAffix', props.widgetContext.model.Id); ariaDescribedByAttribute = `${ariaDescribedByAttribute} ${affixId}`; } const inputRef = React.useRef(null); const [inputValue, setInputValue] = React.useState(props.predefinedValue || ''); const { formViewProps, sfFormValueChanged, hiddenInputs, skippedInputs, registerFieldValidator } = useContext(FormContext); const isHidden = hiddenInputs[numberFieldUniqueId]; const isSkipped = skippedInputs[numberFieldUniqueId]; const [errorMessageText, setErrorMessageText] = useState(''); let delayTimer; function dispatchValueChanged() { clearTimeout(delayTimer); delayTimer = setTimeout(function () { sfFormValueChanged(); }, 300); } function setErrorMessage(_input, message) { if (message) { setErrorMessageText(message); } } function clearErrorMessage() { setErrorMessageText(''); } const handleNumberValidation = () => { const target = inputRef.current; const validationMessages = props.violationRestrictionsMessages; const validationRestrictions = props.violationRestrictionsJson; setInputValue(target.value); if (validationRestrictions) { let isValidRange = true; if (validationRestrictions.minValue || validationRestrictions.minValue === 0) { isValidRange = +target.value >= validationRestrictions.minValue; } if (isValidRange && (validationRestrictions.maxValue || validationRestrictions.maxValue === 0)) { isValidRange = +target.value <= validationRestrictions.maxValue; } if (!isValidRange) { setErrorMessage(target, validationMessages.invalidRange); return false; } } if (target.required && target.validity.valueMissing) { setErrorMessage(target, validationMessages.required); return false; } else if (target.validity.stepMismatch && validationMessages.step) { setErrorMessage(target, validationMessages.step); return false; } else if (!target.validity.valid) { setErrorMessage(target, validationMessages.invalid); return false; } else { clearErrorMessage(); return true; } }; const handleInputEvent = (e) => { setInputValue(e.currentTarget.value); handleNumberValidation(); dispatchValueChanged(); }; React.useEffect(() => { registerFieldValidator(numberFieldUniqueId, handleNumberValidation); }, []); const rootClass = classNames('mb-3', props.cssClass, isHidden ? StylingConfig.VisibilityClasses[VisibilityStyle.Hidden] : StylingConfig.VisibilityClasses[VisibilityStyle.Visible]); let prefixEl = props.affixType === AffixType.prefix ? (_jsx("span", { className: "input-group-text", id: affixId, children: props.affixText })) : null; let suffixEl = props.affixType === AffixType.suffix ? (_jsx("span", { className: "input-group-text", id: affixId, children: props.affixText })) : null; const inputElementCssClass = props.affixType === AffixType.none ? props.inputCssClass : ''; const inputEl = (_jsxs(_Fragment, { children: [prefixEl, _jsx("input", { id: numberFieldUniqueId, type: "number", className: classNames('form-control', inputElementCssClass, { [formViewProps.invalidClass]: formViewProps.invalidClass && errorMessageText }), ref: inputRef, name: props.fieldName, placeholder: props.placeholderText || '', value: inputValue, "data-sf-role": "number-field-input", disabled: isHidden || isSkipped, "aria-describedby": ariaDescribedByAttribute, onChange: handleNumberValidation, onInput: handleInputEvent, onInvalid: handleNumberValidation, ...props.validationAttributes }), suffixEl] })); return (_jsxs("div", { className: rootClass, "data-sf-role": "number-field-container", children: [_jsx("label", { className: "h6", htmlFor: numberFieldUniqueId, children: props.label }), hasAffix ? _jsx("div", { className: classNames('input-group', props.inputCssClass), children: inputEl }) : inputEl, props.instructionalText && _jsx("div", { id: numberFieldInfoMessageId, className: "form-text", children: props.instructionalText }), errorMessageText && _jsx("div", { id: numberFieldErrorMessageId, "data-sf-role": "error-message", role: "alert", "aria-live": "assertive", className: classNames('invalid-feedback', { [StylingConfig.VisibilityClasses[VisibilityStyle.Visible]]: true }), children: errorMessageText })] })); }