Skip to content
This repository has been archived by the owner on Jul 31, 2024. It is now read-only.

Commit

Permalink
FDS-658 form builder object validation (#254)
Browse files Browse the repository at this point in the history
* FDS-658 object validation

* FDS-658 help and validaiton message toggle

* FDS-658 help slot manupulation logic updated

* FDS-658 validation support for array and object fields
  • Loading branch information
vikas-cldcvr authored Mar 27, 2024
1 parent 19ef80a commit a29cba9
Show file tree
Hide file tree
Showing 14 changed files with 132 additions and 60 deletions.
19 changes: 10 additions & 9 deletions packages/flow-core/src/components/f-form-group/f-form-group.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { html, unsafeCSS } from "lit";
import { html, nothing, unsafeCSS } from "lit";
import { property } from "lit/decorators.js";
import { FRoot } from "../../mixins/components/f-root/f-root";
import { FDiv } from "../f-div/f-div";
Expand All @@ -8,6 +8,7 @@ import globalStyle from "./f-form-group-global.scss?inline";
import { flowElement } from "./../../utils";

import { injectCss } from "@ollion/flow-core-config";
import { ifDefined } from "lit-html/directives/if-defined.js";
injectCss("f-form-group", globalStyle);

export type FGroupLabel = {
Expand Down Expand Up @@ -131,7 +132,7 @@ export class FFormGroup extends FRoot {
variant="heading"
size="small"
weight="regular"
data-qa-label-for=${this.dataset["qaId"]}
data-qa-label-for=${ifDefined(this.dataset["qaId"])}
.state=${this.collapse === "text" ? "primary" : "default"}
>
${this.collapse === "text"
Expand All @@ -153,19 +154,19 @@ export class FFormGroup extends FRoot {
source="i-question-filled"
size="small"
state="default"
data-qa-info-icon-for=${this.dataset["qaId"]}
data-qa-info-icon-for=${ifDefined(this.dataset["qaId"])}
.tooltip="${this.label?.iconTooltip}"
clickable
></f-icon>`
: ""}
: nothing}
</f-div>
${this.label?.description
? html` <f-div height="hug-content" width="hug-content">
<f-text variant="para" size="small" weight="regular">
${this.label.description}
</f-text>
</f-div>`
: ""}
: nothing}
</f-div>
<f-div
direction="row"
Expand All @@ -182,19 +183,19 @@ export class FFormGroup extends FRoot {
clickable
@click=${this.duplicationClick}
></f-icon>`
: ""}
: nothing}
${this.collapse === "accordion"
? html` <f-icon
.source=${!this.isCollapsed ? "i-chevron-up" : "i-chevron-down"}
size="small"
state="default"
clickable
></f-icon>`
: ""}
: nothing}
</f-div>
</f-div>
`
: ""}
: nothing}
${!this.isCollapsed || this.collapse === "none"
? html`
<f-div gap="small">
Expand All @@ -210,7 +211,7 @@ export class FFormGroup extends FRoot {
<slot name="action"></slot>
</f-div>
`
: ""}
: nothing}
</f-div>`;
}
}
Expand Down
6 changes: 6 additions & 0 deletions packages/flow-form-builder/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

# Change Log

## [2.4.0] - 2024-03-27

### Features

- validation support for `array` and `object` field

## [2.3.1] - 2024-03-12

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion packages/flow-form-builder/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ollion/flow-form-builder",
"version": "2.3.1",
"version": "2.4.0",
"description": "Form builder for the flow design system",
"module": "dist/flow-form-builder.es.js",
"main": "dist/flow-form-builder.cjs.js",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
f-form-array {
> [slot="help"] {
display: contents;
}
&[state="default"] {
--color-help-text: var(--color-state-secondary);
}

&[state="danger"] {
padding: 8px;
border-radius: 4px;
border: 1px solid var(--color-danger-default);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { html, PropertyValueMap, unsafeCSS } from "lit";
import { html, nothing, PropertyValueMap, unsafeCSS } from "lit";
import { customElement, property, queryAll } from "lit/decorators.js";
import { FDiv, FRoot } from "@ollion/flow-core";
import { FDiv, FRoot, injectCss } from "@ollion/flow-core";
import eleStyle from "./f-form-array.scss?inline";
import {
CanValidateFields,
Expand All @@ -20,7 +20,9 @@ import { getEssentialFlowCoreStyles, propogateProperties } from "../../modules/h
import { FFormObject } from "../f-form-object/f-form-object";
import { FIconButton } from "@ollion/flow-core";
import { ifDefined } from "lit/directives/if-defined.js";
import globalStyle from "./f-form-array-global.scss?inline";

injectCss("f-form-array", globalStyle);
export type ArrayValueType = (
| string
| string[]
Expand All @@ -36,7 +38,7 @@ export class FFormArray extends FRoot {
/**
* css loaded from scss file
*/
static styles = [unsafeCSS(eleStyle), ...getEssentialFlowCoreStyles()];
static styles = [unsafeCSS(eleStyle), unsafeCSS(globalStyle), ...getEssentialFlowCoreStyles()];

/**
* @attribute comments baout title
Expand Down Expand Up @@ -196,16 +198,18 @@ export class FFormArray extends FRoot {
${fieldTemplates.length > 0
? html`<f-div .gap=${this.gap} direction="column"> ${fieldTemplates} </f-div>`
: ``}
${this.config.helperText
? html`<f-text
variant="para"
data-qa-help-for=${ifDefined(this.config.qaId || this.config.id)}
size="small"
weight="regular"
.state=${this.config.state}
>${this.config?.helperText}</f-text
>`
: html`<slot name="help"></slot>`}
<slot name="help">
${this.config.helperText
? html`<f-text
variant="para"
data-qa-help-for=${ifDefined(this.config.qaId || this.config.id)}
size="small"
weight="regular"
.state=${this.config.state}
>${this.config?.helperText}</f-text
>`
: nothing}
</slot>
</f-div>`;
}

Expand All @@ -217,6 +221,7 @@ export class FFormArray extends FRoot {
this.fieldRefs.forEach(fieldRef => {
if ((fieldConfig.type === "object" || fieldConfig.type === "array") && fieldRef.value) {
allValidations.push(fieldRef.value.validate(silent));
allValidations.push(validateField(fieldConfig, fieldRef.value, silent));
} else {
allValidations.push(
validateField(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { getEssentialFlowCoreStyles, propogateProperties } from "../../modules/h
import { cloneDeep, isEqual } from "lodash-es";
import { injectCss } from "@ollion/flow-core-config";
import { ifDefined } from "lit/directives/if-defined.js";
import formArrayGlobalStyles from "./../f-form-array/f-form-array-global.scss?inline";

injectCss("f-form-builder", globalStyle);

Expand All @@ -36,7 +37,12 @@ export class FFormBuilder extends FRoot {
/**
* css loaded from scss file
*/
static styles = [unsafeCSS(eleStyle), unsafeCSS(globalStyle), ...getEssentialFlowCoreStyles()];
static styles = [
unsafeCSS(eleStyle),
unsafeCSS(formArrayGlobalStyles),
unsafeCSS(globalStyle),
...getEssentialFlowCoreStyles()
];

/**
* @attribute formbuilder name
Expand Down Expand Up @@ -352,6 +358,9 @@ export class FFormBuilder extends FRoot {
this.fieldRef.value
) {
allValidations.push(this.fieldRef.value.validate(silent));
allValidations.push(
validateField(this.field as CanValidateFields, this.fieldRef.value, silent)
);
} else if (this.field) {
allValidations.push(
validateField(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,19 @@ f-form-group[direction="horizontal"] {
flex: 1 1 auto !important;
}
}

f-form-object {
> [slot="help"] {
display: contents;
}

&[state="default"] {
--color-help-text: var(--color-state-secondary);
}

&[state="danger"] {
padding: 8px;
border-radius: 4px;
border: 1px solid var(--color-danger-default);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { html, PropertyValueMap, TemplateResult, unsafeCSS } from "lit";
import { html, nothing, PropertyValueMap, TemplateResult, unsafeCSS } from "lit";
import { customElement, property, query } from "lit/decorators.js";
import { FDiv, FRoot } from "@ollion/flow-core";
import eleStyle from "./f-form-object.scss?inline";
Expand Down Expand Up @@ -139,16 +139,18 @@ export class FFormObject extends FRoot {
${fieldTemplates}
</f-form-group>
${this.config.helperText
? html`<f-text
variant="para"
size="small"
weight="regular"
data-qa-help-for=${ifDefined(this.config.qaId || this.config.id)}
.state=${this.config.state}
>${this.config?.helperText}</f-text
>`
: ""}
<slot name="help">
${this.config.helperText
? html`<f-text
variant="para"
size="small"
weight="regular"
data-qa-help-for=${ifDefined(this.config.qaId || this.config.id)}
.state=${this.config.state ?? "secondary"}
>${this.config?.helperText}</f-text
>`
: nothing}
</slot>
</f-div>`;
}

Expand All @@ -163,6 +165,7 @@ export class FFormObject extends FRoot {
allValidations.push(
(this.fieldRefs[fieldname].value as FFormInputElements).validate(silent)
);
allValidations.push(validateField(fieldConfig, this.fieldRefs[fieldname].value, silent));
} else {
if (this.fieldRefs[fieldname]) {
allValidations.push(
Expand Down
1 change: 1 addition & 0 deletions packages/flow-form-builder/src/modules/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import checkboxGroupGlobalStyles from "./../components/f-checkbox-group/f-checkb
import radioGroupGlobalStyles from "./../components/f-radio-group/f-radio-group-global.scss?inline";
import fieldSeparatorGlobalStyles from "./../components/f-field-separator/f-field-separator-global.scss?inline";
import formObjectGlobalStyles from "./../components/f-form-object/f-form-object-global.scss?inline";

import { ifDefined } from "lit/directives/if-defined.js";

export async function propogateProperties(element: FFormArray | FFormObject | FFormBuilder) {
Expand Down
15 changes: 6 additions & 9 deletions packages/flow-form-builder/src/modules/validation/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,16 +207,13 @@ function updateMessage(
const helpSlot = element.querySelector<HTMLSlotElement>("[slot='help']");
if (helpSlot) {
helpSlot.remove();
element.insertAdjacentHTML(
"beforeend",
`<f-div slot="help" ${qaAttribute}=${field.qaId || field.id || ""}>${message}</f-div>`
);
} else {
element.insertAdjacentHTML(
"beforeend",
`<f-div slot="help" ${qaAttribute}=${field.qaId || field.id || ""}>${message}</f-div>`
);
}

const newHelpSlot = document.createElement("f-div");
newHelpSlot.setAttribute("slot", "help");
newHelpSlot.setAttribute(qaAttribute, field.qaId || field.id || "");
newHelpSlot.innerText = message;
element.appendChild(newHelpSlot);
}

export function extractValidationState(allResults: ValidationResults) {
Expand Down
2 changes: 1 addition & 1 deletion stories/flow-core/f-search.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const Playground = {
.variant=${args.variant}
.category=${args.category}
.placeholder=${args.placeholder}
.result=${[]}
.result=${args.result}
.scope=${args.scope}
@input=${handleInput}
.state=${args.state}
Expand Down
13 changes: 12 additions & 1 deletion stories/flow-form-builder/array-field.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,23 @@ const sampleFormBuilder: SampleFormBuilder = {
field: {
type: "array",
allowEmpty: true,
helperText: `Array help`,
label: {
title: "Text array"
},
field: {
type: "text"
}
},
validationRules: [
{
name: "custom",
message: "Values must start with `array` prefix",
validate: values => {
const arrayValues = values as string[];
return arrayValues.every(v => v.startsWith("array"));
}
}
]
}
};

Expand Down
2 changes: 1 addition & 1 deletion stories/flow-form-builder/f-form-builder.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const Playground = {
event.stopImmediatePropagation();
};

return html` <f-div padding="medium" gap="medium" height="100%" overflow="scroll">
return html`<f-div padding="medium" gap="medium" height="100%" overflow="scroll">
<f-div>
<f-form-builder
${ref(formRef)}
Expand Down
Loading

0 comments on commit a29cba9

Please sign in to comment.