import type { FormStyleSettings } from '@/types/form-style' import { resolveBorderStyle } from '@/utils/styleUtils' export interface FieldStateVariantStyleParams { baseSelector: string styleSettings: FormStyleSettings fieldBorderWidth: string fieldTextColor?: string fieldFontSize?: string fieldFontWeight?: string fieldFontStyle?: string } export function applyFieldStateVariantStyles( css: string[], { baseSelector, styleSettings, fieldBorderWidth, fieldTextColor, fieldFontSize, fieldFontWeight, fieldFontStyle, }: FieldStateVariantStyleParams, ): void { const activeStateBackground = styleSettings.advancedMode?.fieldStates?.active?.background const activeStateBorderColor = styleSettings.advancedMode?.fieldStates?.active?.borderColor const activeStateTextColor = styleSettings.advancedMode?.fieldStates?.active?.textColor const activeStateDescriptionColor = styleSettings.advancedMode?.fieldStates?.active?.descriptionColor const hasActiveBorderStyle = styleSettings.advancedMode?.fieldStates?.active?.borderStyle != null const activeStateBorderStyle = hasActiveBorderStyle ? resolveBorderStyle(styleSettings.advancedMode?.fieldStates?.active?.borderStyle) : undefined if (activeStateBackground || activeStateBorderColor || hasActiveBorderStyle) { const activeBorderSelectors = [ `${baseSelector} .ivyforms-input.el-input:focus-within .el-input__wrapper`, `${baseSelector} .ivyforms-field__text:focus-within .el-input__wrapper`, `${baseSelector} .ivyforms-field__email:focus-within .el-input__wrapper`, `${baseSelector} .ivyforms-field__website:focus-within .el-input__wrapper`, `${baseSelector} .ivyforms-field__textarea:focus-within .el-textarea__inner`, `${baseSelector} .ivyforms-phone-input:focus-within .el-input__wrapper`, `${baseSelector} .ivyforms-field__phone:focus-within .vue-tel-input`, `${baseSelector} .ivyforms-field__select:focus-within .el-input__wrapper`, `${baseSelector} .ivyforms-field__select:focus-within .el-select__wrapper`, `${baseSelector} .el-select:focus-within .el-select__wrapper`, `${baseSelector} .ivyforms-field__date:focus-within .el-input__wrapper`, `${baseSelector} .ivyforms-field__time:focus-within .el-input__wrapper`, `${baseSelector} .ivyforms-field__address .el-input:focus-within .el-input__wrapper`, `${baseSelector} .ivyforms-field__address .el-select:focus-within .el-select__wrapper`, `${baseSelector} .ivyforms-name-field .el-input:focus-within .el-input__wrapper`, ] css.push(activeBorderSelectors.join(',') + ' {') if (activeStateBackground) { css.push(` background-color: ${activeStateBackground} !important;`) } if (activeStateBorderColor) { css.push(` border-width: ${fieldBorderWidth} !important;`) css.push(` border-color: ${activeStateBorderColor} !important;`) } if (hasActiveBorderStyle && activeStateBorderStyle) { css.push(` border-style: ${activeStateBorderStyle} !important;`) } css.push('}') if (activeStateBackground) { const activePhoneInnerSelectors = [ `${baseSelector} .ivyforms-field__phone:focus-within .vti__input`, ] css.push(activePhoneInnerSelectors.join(',') + ' {') css.push(` background-color: ${activeStateBackground} !important;`) css.push('}') } } if (activeStateDescriptionColor) { css.push(`${baseSelector} .ivyforms-form-item:focus-within .ivyforms-form-item__info-text,`) css.push(`${baseSelector} .el-form-item:focus-within .ivyforms-form-item__info-text {`) css.push(` color: ${activeStateDescriptionColor} !important;`) css.push(` --ivyforms-info-color: ${activeStateDescriptionColor} !important;`) css.push('}') } if (activeStateTextColor) { const activeTextSelectors = [ `${baseSelector} .ivyforms-field__textarea:focus-within .el-textarea__inner`, `${baseSelector} .ivyforms-field__textarea:focus-within textarea`, `${baseSelector} .ivyforms-field__select:focus-within .el-select__selected-item`, `${baseSelector} .el-select:focus-within .el-select__selected-item`, `${baseSelector} .ivyforms-field__phone:focus-within .vti__input`, `${baseSelector} .ivyforms-field__phone:focus-within .vue-tel-input input`, `${baseSelector} .ivyforms-field__phone:focus-within input.vti__input`, `${baseSelector} .ivyforms-field__phone:focus-within input.iti__input`, `${baseSelector} .ivyforms-field__phone:focus-within .vti__input.vti__phone`, ] css.push(activeTextSelectors.join(',') + ' {') css.push(` color: ${activeStateTextColor} !important;`) css.push(` -webkit-text-fill-color: ${activeStateTextColor} !important;`) css.push('}') } const readOnlyExplicitTextColor = styleSettings.advancedMode?.fieldStates?.readOnly?.textColor const fieldPlaceholderFontColor = styleSettings.advancedMode?.fieldPlaceholder?.fontColor const readOnlyResolvedFieldTextColor = readOnlyExplicitTextColor || fieldPlaceholderFontColor || fieldTextColor if (readOnlyResolvedFieldTextColor || fieldFontSize || fieldFontWeight || fieldFontStyle) { const alwaysDisabledTextSelectors = [ `${baseSelector} .ivyforms-field.is-readonly .el-input__inner`, `${baseSelector} .ivyforms-field.is-disabled .el-input__inner`, `${baseSelector} .ivyforms-field.is-readonly input`, `${baseSelector} .ivyforms-field.is-disabled input`, `${baseSelector} .ivyforms-field.is-readonly .el-textarea__inner`, `${baseSelector} .ivyforms-field.is-disabled .el-textarea__inner`, `${baseSelector} .ivyforms-field.is-readonly textarea`, `${baseSelector} .ivyforms-field.is-disabled textarea`, `${baseSelector} .el-input.is-disabled .el-input__inner`, `${baseSelector} .el-textarea.is-disabled .el-textarea__inner`, ] css.push(alwaysDisabledTextSelectors.join(',') + ' {') if (readOnlyResolvedFieldTextColor) { css.push(` color: ${readOnlyResolvedFieldTextColor} !important;`) css.push(` -webkit-text-fill-color: ${readOnlyResolvedFieldTextColor} !important;`) css.push(' opacity: 1 !important;') } if (fieldFontSize) { css.push(` font-size: ${fieldFontSize} !important;`) } if (fieldFontWeight) { css.push(` font-weight: ${fieldFontWeight} !important;`) } if (fieldFontStyle) { css.push(` font-style: ${fieldFontStyle} !important;`) } css.push('}') } const readOnlyBackground = styleSettings.advancedMode?.fieldStates?.readOnly?.background const readOnlyBorderColor = styleSettings.advancedMode?.fieldStates?.readOnly?.borderColor const readOnlyDescriptionColor = styleSettings.advancedMode?.fieldStates?.readOnly?.descriptionColor const hasReadOnlyBorderStyle = styleSettings.advancedMode?.fieldStates?.readOnly?.borderStyle != null const readOnlyBorderStyle = hasReadOnlyBorderStyle ? resolveBorderStyle(styleSettings.advancedMode?.fieldStates?.readOnly?.borderStyle) : undefined if ( readOnlyBackground || readOnlyBorderColor || hasReadOnlyBorderStyle || readOnlyExplicitTextColor ) { const disabledSelectors = [ `${baseSelector} .ivyforms-input.el-input:disabled .el-input__wrapper`, `${baseSelector} .ivyforms-input.el-input.is-disabled .el-input__wrapper`, `${baseSelector} .ivyforms-field:disabled .el-input__wrapper`, `${baseSelector} .ivyforms-field.is-disabled .el-input__wrapper`, `${baseSelector} .ivyforms-field.is-readonly .el-input__wrapper`, `${baseSelector} .el-input-number.is-disabled .el-input__wrapper`, `${baseSelector} .ivyforms-field.is-readonly .el-input-number .el-input__wrapper`, `${baseSelector} .el-input-number.is-disabled`, `${baseSelector} .el-input-number.is-disabled .el-input__inner`, `${baseSelector} .ivyforms-field.is-readonly .el-input-number`, `${baseSelector} .ivyforms-field.is-readonly .el-input-number .el-input__inner`, `${baseSelector} .ivyforms-text-number[readonly] .el-input__wrapper`, `${baseSelector} .ivyforms-field.is-readonly .ivyforms-text-number__input .el-input__wrapper`, `${baseSelector} .ivyforms-field:disabled .el-textarea__inner`, `${baseSelector} .ivyforms-field.is-disabled .el-textarea__inner`, `${baseSelector} .ivyforms-field.is-readonly .el-textarea__inner`, `${baseSelector} .ivyforms-field.is-readonly .el-input__inner`, `${baseSelector} .el-input.is-disabled .el-input__wrapper`, `${baseSelector} .el-textarea.is-disabled .el-textarea__inner`, `${baseSelector} .ivyforms-field.is-readonly .el-select__wrapper`, `${baseSelector} .ivyforms-field.is-readonly .el-input__wrapper:has(input[readonly])`, `${baseSelector} .ivyforms-field.is-readonly .el-textarea__inner[readonly]`, `${baseSelector} .ivyforms-field.is-readonly .vue-tel-input`, ] css.push(disabledSelectors.join(',') + ' {') if (readOnlyBackground) { css.push(` background-color: ${readOnlyBackground} !important;`) } if (readOnlyBorderColor) { css.push(` border-width: ${fieldBorderWidth} !important;`) css.push(` border-color: ${readOnlyBorderColor} !important;`) } if (hasReadOnlyBorderStyle && readOnlyBorderStyle) { css.push(` border-style: ${readOnlyBorderStyle} !important;`) } css.push('}') const readOnlyAppearanceSelectors = [ `${baseSelector} .ivyforms-field.is-readonly`, `${baseSelector} .ivyforms-field.is-disabled`, `${baseSelector} .ivyforms-field.is-readonly .el-input__wrapper`, `${baseSelector} .ivyforms-field.is-disabled .el-input__wrapper`, `${baseSelector} .ivyforms-field.is-readonly .el-input__inner`, `${baseSelector} .ivyforms-field.is-disabled .el-input__inner`, `${baseSelector} .ivyforms-field.is-readonly input`, `${baseSelector} .ivyforms-field.is-disabled input`, `${baseSelector} .ivyforms-field.is-readonly .el-textarea__inner`, `${baseSelector} .ivyforms-field.is-disabled .el-textarea__inner`, `${baseSelector} .ivyforms-field.is-readonly textarea`, `${baseSelector} .ivyforms-field.is-disabled textarea`, `${baseSelector} .ivyforms-field.is-readonly .el-select__wrapper`, `${baseSelector} .ivyforms-field.is-disabled .el-select__wrapper`, `${baseSelector} .ivyforms-field.is-readonly .vue-tel-input`, `${baseSelector} .ivyforms-field.is-disabled .vue-tel-input`, `${baseSelector} .ivyforms-field.is-readonly .vti__input`, `${baseSelector} .ivyforms-field.is-disabled .vti__input`, `${baseSelector} .ivyforms-field.is-readonly .ivyforms-text-number`, `${baseSelector} .ivyforms-field.is-disabled .ivyforms-text-number`, `${baseSelector} .ivyforms-field.is-readonly .ivyforms-text-number__btn:disabled`, `${baseSelector} .ivyforms-field.is-disabled .ivyforms-text-number__btn:disabled`, ] css.push(readOnlyAppearanceSelectors.join(',') + ' {') css.push(' opacity: 1 !important;') css.push('}') if (readOnlyResolvedFieldTextColor) { const readOnlyTextAppearanceSelectors = [ `${baseSelector} .ivyforms-field.is-readonly .el-input__inner`, `${baseSelector} .ivyforms-field.is-disabled .el-input__inner`, `${baseSelector} .ivyforms-field.is-readonly input`, `${baseSelector} .ivyforms-field.is-disabled input`, `${baseSelector} .ivyforms-field.is-readonly .el-textarea__inner`, `${baseSelector} .ivyforms-field.is-disabled .el-textarea__inner`, `${baseSelector} .ivyforms-field.is-readonly textarea`, `${baseSelector} .ivyforms-field.is-disabled textarea`, `${baseSelector} .ivyforms-field.is-readonly .vti__input`, `${baseSelector} .ivyforms-field.is-disabled .vti__input`, `${baseSelector} .ivyforms-field.is-readonly .ivyforms-text-number__btn`, `${baseSelector} .ivyforms-field.is-disabled .ivyforms-text-number__btn`, ] css.push(readOnlyTextAppearanceSelectors.join(',') + ' {') css.push(` color: ${readOnlyResolvedFieldTextColor} !important;`) css.push(` -webkit-text-fill-color: ${readOnlyResolvedFieldTextColor} !important;`) css.push(' opacity: 1 !important;') css.push('}') } css.push(`${baseSelector} .ivyforms-field.is-readonly .ivyforms-text-number,`) css.push(`${baseSelector} .ivyforms-field.is-disabled .ivyforms-text-number {`) css.push(' border: none !important;') css.push(' box-shadow: none !important;') css.push(' background: transparent !important;') css.push('}') const readOnlyOpacitySelectors = [ `${baseSelector} .ivyforms-field.is-readonly .vue-tel-input`, `${baseSelector} .ivyforms-field.is-disabled .vue-tel-input`, ] css.push(readOnlyOpacitySelectors.join(',') + ' {') css.push(' opacity: 1 !important;') css.push('}') css.push(`${baseSelector} .ivyforms-field.is-readonly .el-input__inner,`) css.push(`${baseSelector} .ivyforms-field.is-disabled .el-input__inner,`) css.push(`${baseSelector} .ivyforms-field.is-readonly .vti__input,`) css.push(`${baseSelector} .ivyforms-field.is-disabled .vti__input {`) css.push(' border: none !important;') css.push(' outline: none !important;') css.push(' box-shadow: none !important;') css.push(' -webkit-appearance: none !important;') css.push(' appearance: none !important;') css.push('}') css.push( `${baseSelector} .ivyforms-field.ivyforms-field__phone.is-readonly .ivyforms-phone-input .vue-tel-input.disabled .vti__input.vti__phone,`, ) css.push( `${baseSelector} .ivyforms-field.ivyforms-field__phone.is-readonly .ivyforms-phone-input .vue-tel-input.disabled .vti__input:disabled,`, ) css.push( `${baseSelector} .ivyforms-field.ivyforms-field__phone.is-readonly:focus-within .ivyforms-phone-input .vue-tel-input .vti__input,`, ) css.push( `${baseSelector} .ivyforms-field.ivyforms-field__phone.is-disabled .ivyforms-phone-input .vue-tel-input.disabled .vti__input:disabled {`, ) css.push(' border: none !important;') css.push(' outline: none !important;') css.push(' box-shadow: none !important;') css.push(' background: transparent !important;') css.push(' background-color: transparent !important;') css.push('}') const readOnlyPhoneSelectors = [ `${baseSelector} .ivyforms-field.is-readonly .vue-tel-input`, `${baseSelector} .ivyforms-field.is-disabled .vue-tel-input`, ] css.push(readOnlyPhoneSelectors.join(',') + ' {') if (readOnlyBackground) { css.push(` background-color: ${readOnlyBackground} !important;`) } if (readOnlyBorderColor) { css.push(` border-color: ${readOnlyBorderColor} !important;`) } css.push('}') } if (readOnlyDescriptionColor) { css.push(`${baseSelector} .ivyforms-field.is-readonly .ivyforms-form-item__info-text,`) css.push(`${baseSelector} .ivyforms-field.is-disabled .ivyforms-form-item__info-text,`) css.push( `${baseSelector} .ivyforms-field.is-readonly .el-form-item .ivyforms-form-item__info-text,`, ) css.push( `${baseSelector} .ivyforms-field.is-disabled .el-form-item .ivyforms-form-item__info-text {`, ) css.push(` color: ${readOnlyDescriptionColor} !important;`) css.push(` --ivyforms-info-color: ${readOnlyDescriptionColor} !important;`) css.push('}') } const errorBackground = styleSettings.advancedMode?.fieldStates?.error?.background const errorBorderColor = styleSettings.advancedMode?.fieldStates?.error?.borderColor const errorTextColor = styleSettings.advancedMode?.fieldStates?.error?.textColor const errorDescriptionColor = styleSettings.advancedMode?.fieldStates?.error?.descriptionColor const hasErrorBorderStyle = styleSettings.advancedMode?.fieldStates?.error?.borderStyle != null const errorBorderStyle = hasErrorBorderStyle ? resolveBorderStyle(styleSettings.advancedMode?.fieldStates?.error?.borderStyle) : undefined if (errorBackground || errorBorderColor || hasErrorBorderStyle) { const errorSelectors = [ `${baseSelector} .ivyforms-form-item.is-error .ivyforms-input.el-input .el-input__wrapper`, `${baseSelector} .ivyforms-form-item.is-error .ivyforms-field .el-input__wrapper`, `${baseSelector} .ivyforms-form-item.is-error .el-input__wrapper`, `${baseSelector} .ivyforms-form-item.is-error .el-textarea__inner`, `${baseSelector} .ivyforms-form-item.is-error .el-select__wrapper`, `${baseSelector} .ivyforms-form-item.is-error .vue-tel-input`, `${baseSelector} .el-form-item.is-error .ivyforms-input.el-input .el-input__wrapper`, `${baseSelector} .el-form-item.is-error .ivyforms-field .el-input__wrapper`, `${baseSelector} .el-form-item.is-error .el-input__wrapper`, `${baseSelector} .el-form-item.is-error .el-textarea__inner`, `${baseSelector} .el-form-item.is-error .el-select__wrapper`, `${baseSelector} .el-form-item.is-error .vue-tel-input`, ] css.push(errorSelectors.join(',') + ' {') if (errorBackground) { css.push(` background-color: ${errorBackground} !important;`) } if (errorBorderColor) { css.push(` border-width: ${fieldBorderWidth} !important;`) css.push(` border-color: ${errorBorderColor} !important;`) } if (hasErrorBorderStyle && errorBorderStyle) { css.push(` border-style: ${errorBorderStyle} !important;`) } css.push('}') } if (errorDescriptionColor) { css.push(`${baseSelector} .ivyforms-form-item.is-error .ivyforms-form-item__info-text,`) css.push(`${baseSelector} .el-form-item.is-error .ivyforms-form-item__info-text {`) css.push(` color: ${errorDescriptionColor} !important;`) css.push(` --ivyforms-info-color: ${errorDescriptionColor} !important;`) css.push('}') } if (errorTextColor) { const errorTextSelectors = [ `${baseSelector} .ivyforms-form-item.is-error .ivyforms-input.el-input input`, `${baseSelector} .ivyforms-form-item.is-error .ivyforms-field input`, `${baseSelector} .ivyforms-form-item.is-error input`, `${baseSelector} .ivyforms-form-item.is-error textarea`, `${baseSelector} .ivyforms-form-item.is-error .el-input__inner`, `${baseSelector} .ivyforms-form-item.is-error .el-textarea__inner`, `${baseSelector} .ivyforms-form-item.is-error .vti__input`, `${baseSelector} .ivyforms-form-item.is-error .el-input__prefix`, `${baseSelector} .ivyforms-form-item.is-error .el-input__suffix`, `${baseSelector} .ivyforms-form-item.is-error .el-input__prefix .el-icon`, `${baseSelector} .ivyforms-form-item.is-error .el-input__suffix .el-icon`, `${baseSelector} .el-form-item.is-error .ivyforms-input.el-input input`, `${baseSelector} .el-form-item.is-error .ivyforms-field input`, `${baseSelector} .el-form-item.is-error input`, `${baseSelector} .el-form-item.is-error textarea`, `${baseSelector} .el-form-item.is-error .el-input__inner`, `${baseSelector} .el-form-item.is-error .el-textarea__inner`, `${baseSelector} .el-form-item.is-error .vti__input`, `${baseSelector} .el-form-item.is-error .el-input__prefix`, `${baseSelector} .el-form-item.is-error .el-input__suffix`, `${baseSelector} .el-form-item.is-error .el-input__prefix .el-icon`, `${baseSelector} .el-form-item.is-error .el-input__suffix .el-icon`, ] css.push(errorTextSelectors.join(',') + ' {') css.push(` color: ${errorTextColor} !important;`) css.push('}') const errorIconSelectors = [ `${baseSelector} .ivyforms-form-item.is-error .ivyforms-icon`, `${baseSelector} .el-form-item.is-error .ivyforms-icon`, ] css.push(errorIconSelectors.join(',') + ' {') css.push(` --map-status-error-symbol-0: ${errorTextColor} !important;`) css.push('}') const errorSvgSelectors = [ `${baseSelector} .ivyforms-form-item.is-error .ivyforms-icon svg path`, `${baseSelector} .el-form-item.is-error .ivyforms-icon svg path`, ] css.push(errorSvgSelectors.join(',') + ' {') css.push(` fill: ${errorTextColor} !important;`) css.push('}') } }