From a544a1e985c1615e21f4aa51a7667b3f2ff332c7 Mon Sep 17 00:00:00 2001
From: Maja Zarkova <60856270+MajaZarkova@users.noreply.github.com>
Date: Mon, 4 Nov 2024 14:47:45 +0100
Subject: [PATCH] feat(OnyxForm): Add successMessage to useCustomValidity
composable (#2031)
Relates to #573
Add successMessage prop to useCustomValidity composable. This property
will be provided in OnyxForm component and later injected by it's child
input components to represent the success state.
---
.../OnyxErrorTooltip/OnyxErrorTooltip.vue | 6 +--
.../src/components/OnyxFormElement/types.ts | 4 +-
.../src/components/OnyxInput/OnyxInput.ct.tsx | 4 +-
.../components/OnyxSelect/OnyxSelect.ct.tsx | 4 +-
.../components/OnyxStepper/OnyxStepper.ct.tsx | 4 +-
.../src/composables/useCustomValidity.ts | 53 ++++++++++++-------
6 files changed, 44 insertions(+), 31 deletions(-)
diff --git a/packages/sit-onyx/src/components/OnyxErrorTooltip/OnyxErrorTooltip.vue b/packages/sit-onyx/src/components/OnyxErrorTooltip/OnyxErrorTooltip.vue
index d819a65c68..158743db30 100644
--- a/packages/sit-onyx/src/components/OnyxErrorTooltip/OnyxErrorTooltip.vue
+++ b/packages/sit-onyx/src/components/OnyxErrorTooltip/OnyxErrorTooltip.vue
@@ -1,6 +1,6 @@
diff --git a/packages/sit-onyx/src/components/OnyxFormElement/types.ts b/packages/sit-onyx/src/components/OnyxFormElement/types.ts
index e7528184ed..55bd186f30 100644
--- a/packages/sit-onyx/src/components/OnyxFormElement/types.ts
+++ b/packages/sit-onyx/src/components/OnyxFormElement/types.ts
@@ -1,5 +1,5 @@
import type { RequiredMarkerProp } from "../../composables/required";
-import type { FormErrorMessages } from "../../composables/useCustomValidity";
+import type { FormMessages } from "../../composables/useCustomValidity";
export type OnyxFormElementProps = RequiredMarkerProp & {
/**
@@ -40,7 +40,7 @@ export type OnyxFormElementProps = RequiredMarkerProp & {
/**
* Error messages that inform about causes for invalidity of form components
*/
- errorMessages?: FormErrorMessages;
+ errorMessages?: FormMessages;
/**
* Maximum number of characters that are allowed to be entered.
* Warning: when the value is (pre)set programmatically,
diff --git a/packages/sit-onyx/src/components/OnyxInput/OnyxInput.ct.tsx b/packages/sit-onyx/src/components/OnyxInput/OnyxInput.ct.tsx
index 14e720caf0..a6730dbfb6 100644
--- a/packages/sit-onyx/src/components/OnyxInput/OnyxInput.ct.tsx
+++ b/packages/sit-onyx/src/components/OnyxInput/OnyxInput.ct.tsx
@@ -1,5 +1,5 @@
import { DENSITIES } from "../../composables/density";
-import type { FormErrorMessages } from "../../composables/useCustomValidity";
+import type { FormMessages } from "../../composables/useCustomValidity";
import { expect, test } from "../../playwright/a11y";
import { executeMatrixScreenshotTest } from "../../playwright/screenshots";
import { createFormElementUtils } from "../OnyxFormElement/OnyxFormElement.ct-utils";
@@ -108,7 +108,7 @@ test.describe("Screenshot tests", () => {
const message = showLongMessage
? "Very long message that should be truncated"
: "Test message";
- const errorMessages: FormErrorMessages = {
+ const errorMessages: FormMessages = {
shortMessage: showLongMessage
? "Very long error preview that should be truncated"
: "Test error",
diff --git a/packages/sit-onyx/src/components/OnyxSelect/OnyxSelect.ct.tsx b/packages/sit-onyx/src/components/OnyxSelect/OnyxSelect.ct.tsx
index 06202691a5..a86646fac8 100644
--- a/packages/sit-onyx/src/components/OnyxSelect/OnyxSelect.ct.tsx
+++ b/packages/sit-onyx/src/components/OnyxSelect/OnyxSelect.ct.tsx
@@ -1,7 +1,7 @@
import type { MountResultJsx } from "@playwright/experimental-ct-vue";
import { comboboxSelectOnlyTesting, comboboxTesting } from "@sit-onyx/headless/playwright";
import { DENSITIES } from "../../composables/density";
-import type { FormErrorMessages } from "../../composables/useCustomValidity";
+import type { FormMessages } from "../../composables/useCustomValidity";
import { expect, test } from "../../playwright/a11y";
import {
adjustAbsolutePositionScreenshot,
@@ -315,7 +315,7 @@ test.describe("Invalidity handling screenshots", () => {
const message = showLongMessage
? "Very long message that should be truncated"
: "Test message";
- const errorMessages: FormErrorMessages = {
+ const errorMessages: FormMessages = {
shortMessage: showLongMessage
? "Very long error preview that should be truncated"
: "Test error",
diff --git a/packages/sit-onyx/src/components/OnyxStepper/OnyxStepper.ct.tsx b/packages/sit-onyx/src/components/OnyxStepper/OnyxStepper.ct.tsx
index 2b66d28bad..4d1a6c56dd 100644
--- a/packages/sit-onyx/src/components/OnyxStepper/OnyxStepper.ct.tsx
+++ b/packages/sit-onyx/src/components/OnyxStepper/OnyxStepper.ct.tsx
@@ -1,5 +1,5 @@
import { DENSITIES } from "../../composables/density";
-import type { FormErrorMessages } from "../../composables/useCustomValidity";
+import type { FormMessages } from "../../composables/useCustomValidity";
import { expect, test } from "../../playwright/a11y";
import { executeMatrixScreenshotTest } from "../../playwright/screenshots";
import { createFormElementUtils } from "../OnyxFormElement/OnyxFormElement.ct-utils";
@@ -100,7 +100,7 @@ test.describe("Screenshot tests", () => {
const message = showLongMessage
? "Very long message that should be truncated"
: "Test message";
- const errorMessages: FormErrorMessages = {
+ const errorMessages: FormMessages = {
shortMessage: showLongMessage
? "Very long error preview that should be truncated"
: "Test error",
diff --git a/packages/sit-onyx/src/composables/useCustomValidity.ts b/packages/sit-onyx/src/composables/useCustomValidity.ts
index 7b70686bd6..1d49a38706 100644
--- a/packages/sit-onyx/src/composables/useCustomValidity.ts
+++ b/packages/sit-onyx/src/composables/useCustomValidity.ts
@@ -6,13 +6,17 @@ import type { BaseSelectOption } from "../types";
import { areObjectsFlatEqual } from "../utils/objects";
import { getFirstInvalidType, transformValidityStateToObject } from "../utils/validity";
-export type CustomErrorType = string | FormErrorMessages;
+export type CustomMessageType = string | FormMessages;
export type CustomValidityProp = {
/**
* Custom error message to show. Will only show up after the user has interacted with the input.
*/
- customError?: CustomErrorType;
+ customError?: CustomMessageType;
+ /**
+ * Success message to show. Will only show up after the user has interacted with the input.
+ */
+ successMessage?: CustomMessageType;
};
export type UseCustomValidityOptions = {
@@ -45,39 +49,38 @@ export const TRANSLATED_INPUT_TYPES = Object.keys(
export type TranslatedInputType = (typeof TRANSLATED_INPUT_TYPES)[number];
/**
- * Translated error messages that inform about causes for invalidity of form components
+ * Translated messages that inform about the validity state of form components
*/
-export type FormErrorMessages = {
+export type FormMessages = {
/**
- * A short error message preview to inform the user about the cause of the error
+ * A short message preview to inform the user about the validity state
*/
shortMessage: string;
/**
- * An extended informative error message to provide more info
- * how the error cause can be resolved
+ * An extended informative message to provide more info
*/
longMessage?: string;
};
/**
- * Transforms a customError into the format needed to display an error preview and extended message
+ * Transforms a customMessage into the format needed to display an error preview and extended message
*/
-export const getCustomErrors = (customError?: CustomErrorType): FormErrorMessages | undefined => {
- if (!customError) return;
- if (typeof customError === "string") {
- // we can't guarantee a custom error message will be short,
+export const getFormMessages = (customMessage?: CustomMessageType): FormMessages | undefined => {
+ if (!customMessage) return;
+ if (typeof customMessage === "string") {
+ // we can't guarantee a custom message will be short,
// so in case it overflows, by adding it to "longMessage",
// it will still be visible in a tooltip
- return { shortMessage: customError, longMessage: customError };
+ return { shortMessage: customMessage, longMessage: customMessage };
}
- return customError;
+ return customMessage;
};
/**
- * Returns a string combining short + long message or just the customError if it was provided as single string.
+ * Returns a string combining short + long message or just the customMessage if it was provided as single string.
* Will be used e.g. for customInvalidity and showing a tooltip e.g. in RadioButtons
*/
-export const getCustomErrorText = (customError?: CustomErrorType): string | undefined => {
+export const getFormMessageText = (customError?: CustomMessageType): string | undefined => {
if (!customError) return;
if (typeof customError === "string") {
return customError;
@@ -90,7 +93,7 @@ export const getCustomErrorText = (customError?: CustomErrorType): string | unde
};
/**
- * Composable for unified handling of custom error messages for form components.
+ * Composable for unified handling of custom messages for form components.
* Will call `setCustomValidity()` accordingly and emit the "validityChange" event
* whenever the input value / error changes.
*
@@ -128,7 +131,7 @@ export const useCustomValidity = (options: UseCustomValidityOptions) => {
/**
* Sync custom error with the native input validity.
*/
- watchEffect(() => el.setCustomValidity(getCustomErrorText(options.props.customError) ?? ""));
+ watchEffect(() => el.setCustomValidity(getFormMessageText(options.props.customError) ?? ""));
watch(
// we need to watch all props instead of only modelValue so the validity is re-checked
@@ -166,11 +169,11 @@ export const useCustomValidity = (options: UseCustomValidityOptions) => {
},
} satisfies Directive;
- const errorMessages = computed(() => {
+ const errorMessages = computed(() => {
if (!validityState.value || validityState.value.valid) return;
const errorType = getFirstInvalidType(validityState.value);
- const customErrors = getCustomErrors(options.props.customError);
+ const customErrors = getFormMessages(options.props.customError);
// a custom error message always is considered first
if (customErrors || errorType === "customError") {
if (!customErrors) return;
@@ -207,6 +210,12 @@ export const useCustomValidity = (options: UseCustomValidityOptions) => {
};
});
+ const successMessages = computed(() => {
+ if (validityState.value === undefined || !validityState.value.valid) return;
+
+ return getFormMessages(options.props.successMessage);
+ });
+
return {
/**
* Directive to set the custom error message and emit validityChange event.
@@ -216,5 +225,9 @@ export const useCustomValidity = (options: UseCustomValidityOptions) => {
* A custom error or the default translation of the first invalid state if one exists.
*/
errorMessages,
+ /**
+ * A custom success message if provided by the user.
+ */
+ successMessages,
};
};