diff --git a/packages/flow-form-builder/CHANGELOG.md b/packages/flow-form-builder/CHANGELOG.md index 34b393b5d..314e1598c 100644 --- a/packages/flow-form-builder/CHANGELOG.md +++ b/packages/flow-form-builder/CHANGELOG.md @@ -2,6 +2,13 @@ # Change Log +## [2.3.1] - 2024-03-12 + +### Bug Fixes + +- `showWhen` not working for `layout:'label-left'` fields. +- `layout:'label-left'` fields alignment fixed when used in object in horizontal direction. + ## [2.3.0] - 2024-03-01 ### Features diff --git a/packages/flow-form-builder/package.json b/packages/flow-form-builder/package.json index c891b48a6..16f0cb4b6 100644 --- a/packages/flow-form-builder/package.json +++ b/packages/flow-form-builder/package.json @@ -1,6 +1,6 @@ { "name": "@ollion/flow-form-builder", - "version": "2.3.0", + "version": "2.3.1", "description": "Form builder for the flow design system", "module": "dist/flow-form-builder.es.js", "main": "dist/flow-form-builder.cjs.js", diff --git a/packages/flow-form-builder/src/components/f-form-array/f-form-array.ts b/packages/flow-form-builder/src/components/f-form-array/f-form-array.ts index cc3c74724..16bb6eb70 100644 --- a/packages/flow-form-builder/src/components/f-form-array/f-form-array.ts +++ b/packages/flow-form-builder/src/components/f-form-array/f-form-array.ts @@ -1,12 +1,13 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { html, PropertyValueMap, unsafeCSS } from "lit"; import { customElement, property, queryAll } from "lit/decorators.js"; -import { FRoot } from "@ollion/flow-core"; +import { FDiv, FRoot } from "@ollion/flow-core"; import eleStyle from "./f-form-array.scss?inline"; import { CanValidateFields, FFormInputElements, FormBuilderArrayField, + FormBuilderBaseField, FormBuilderValidationPromise, FormBuilderValues } from "../../types"; @@ -18,6 +19,7 @@ import { Subject } from "rxjs"; import { getEssentialFlowCoreStyles, propogateProperties } from "../../modules/helpers"; import { FFormObject } from "../f-form-object/f-form-object"; import { FIconButton } from "@ollion/flow-core"; +import { ifDefined } from "lit/directives/if-defined.js"; export type ArrayValueType = ( | string @@ -118,7 +120,7 @@ export class FFormArray extends FRoot { ${i === 0 && this.isRequired ? html` ` : html` ` @@ -175,7 +177,7 @@ export class FFormArray extends FRoot { ${!this.isRequired ? html`(".label-left-layout"); + if (wrapper) { + wrapper.dataset.hidden = "true"; + } + } } else { ref.value.dataset.hidden = "false"; + if ((fieldConfig as FormBuilderBaseField).layout === "label-left") { + const wrapper = ref.value.closest(".label-left-layout"); + if (wrapper) { + wrapper.dataset.hidden = "false"; + } + } } this.dispatchShowWhenExeEvent(); } diff --git a/packages/flow-form-builder/src/components/f-form-builder/f-form-builder.ts b/packages/flow-form-builder/src/components/f-form-builder/f-form-builder.ts index 9c7fa9e95..65243c05d 100644 --- a/packages/flow-form-builder/src/components/f-form-builder/f-form-builder.ts +++ b/packages/flow-form-builder/src/components/f-form-builder/f-form-builder.ts @@ -12,12 +12,13 @@ import { FormBuilderGap, FormBuilderSize, FormBuilderVariant, - CanValidateFields + CanValidateFields, + FormBuilderBaseField } from "../../types"; import eleStyle from "./f-form-builder.scss?inline"; import globalStyle from "./f-form-builder-global.scss?inline"; -import { FRoot } from "@ollion/flow-core"; +import { FDiv, FRoot } from "@ollion/flow-core"; import { Ref, createRef } from "lit/directives/ref.js"; import fieldRenderer from "./fields"; import { extractValidationState, validateField } from "../../modules/validation/validator"; @@ -26,6 +27,7 @@ import { Subject } from "rxjs"; import { getEssentialFlowCoreStyles, propogateProperties } from "../../modules/helpers"; import { cloneDeep, isEqual } from "lodash-es"; import { injectCss } from "@ollion/flow-core-config"; +import { ifDefined } from "lit/directives/if-defined.js"; injectCss("f-form-builder", globalStyle); @@ -120,7 +122,7 @@ export class FFormBuilder extends FRoot { @show-when=${this.onShowWhen} @show-when-exe=${this.onShowWhenExecution} ?separator=${this.separator} - gap=${this.gap} + gap=${ifDefined(this.gap)} @keyup=${this.handleKeyUp} > ${this.label @@ -288,8 +290,20 @@ export class FFormBuilder extends FRoot { const showField = this.field.showWhen(values); if (!showField) { ref.value.dataset.hidden = "true"; + if ((this.field as FormBuilderBaseField).layout === "label-left") { + const wrapper = ref.value.closest(".label-left-layout"); + if (wrapper) { + wrapper.dataset.hidden = "true"; + } + } } else { ref.value.dataset.hidden = "false"; + if ((this.field as FormBuilderBaseField).layout === "label-left") { + const wrapper = ref.value.closest(".label-left-layout"); + if (wrapper) { + wrapper.dataset.hidden = "false"; + } + } } this.onShowWhenExecution(); } diff --git a/packages/flow-form-builder/src/components/f-form-builder/fields/text.ts b/packages/flow-form-builder/src/components/f-form-builder/fields/text.ts index bded0afde..2581025c8 100644 --- a/packages/flow-form-builder/src/components/f-form-builder/fields/text.ts +++ b/packages/flow-form-builder/src/components/f-form-builder/fields/text.ts @@ -21,7 +21,7 @@ export default function ( ${ref(fieldRef)} .placeholder=${field.placeholder} .value=${value} - data-qa-element-id=${field.qaId || field.id} + data-qa-element-id=${ifDefined(field.qaId || field.id)} icon-left=${ifDefined(field.iconLeft)} icon-right=${ifDefined(field.iconRight)} prefix=${ifDefined(field.prefix)} @@ -33,13 +33,13 @@ export default function ( ?disabled=${field.disabled ?? false} ?clear=${field.clear ?? true} ?read-only=${field.readonly ?? false} - @click=${ifDefined(field.onClick)} - @focus=${ifDefined(field.onFocus)} - @input=${ifDefined(field.onInput)} - @keypress=${ifDefined(field.onKeyPress)} - @keydown=${ifDefined(field.onKeyDown)} - @keyup=${ifDefined(field.onKeyUp)} - @mouseover=${ifDefined(field.onMouseOver)} + @click=${field.onClick} + @focus=${field.onFocus} + @input=${field.onInput} + @keypress=${field.onKeyPress} + @keydown=${field.onKeyDown} + @keyup=${field.onKeyUp} + @mouseover=${field.onMouseOver} autofocus=${ifDefined(field.autofocus)} autocomplete=${ifDefined(field.autocomplete)} > diff --git a/packages/flow-form-builder/src/components/f-form-object/f-form-object-global.scss b/packages/flow-form-builder/src/components/f-form-object/f-form-object-global.scss index d3ae6ef00..f593e262f 100644 --- a/packages/flow-form-builder/src/components/f-form-object/f-form-object-global.scss +++ b/packages/flow-form-builder/src/components/f-form-object/f-form-object-global.scss @@ -40,4 +40,8 @@ f-form-group[direction="horizontal"] { width: 100%; flex: initial; } + > .label-left-layout { + width: auto !important; + flex: 1 1 auto !important; + } } diff --git a/packages/flow-form-builder/src/components/f-form-object/f-form-object.ts b/packages/flow-form-builder/src/components/f-form-object/f-form-object.ts index f38437742..d7464757f 100644 --- a/packages/flow-form-builder/src/components/f-form-object/f-form-object.ts +++ b/packages/flow-form-builder/src/components/f-form-object/f-form-object.ts @@ -1,6 +1,6 @@ import { html, PropertyValueMap, TemplateResult, unsafeCSS } from "lit"; import { customElement, property, query } from "lit/decorators.js"; -import { FRoot } from "@ollion/flow-core"; +import { FDiv, FRoot } from "@ollion/flow-core"; import eleStyle from "./f-form-object.scss?inline"; import globalStyle from "./f-form-object-global.scss?inline"; @@ -9,6 +9,7 @@ import { createRef, Ref } from "lit/directives/ref.js"; import { CanValidateFields, FFormInputElements, + FormBuilderBaseField, FormBuilderObjectField, FormBuilderValidationPromise, FormBuilderValues @@ -20,6 +21,7 @@ import { FFormGroup } from "@ollion/flow-core"; import { FFieldSeparator } from "../f-field-separator/f-field-separator"; import { radioGroupStyles } from "../f-radio-group/f-radio-group"; import { checkboxGroupStyles } from "../f-checkbox-group/f-checkbox-group"; +import { ifDefined } from "lit/directives/if-defined.js"; export type ObjectValueType = Record< string, @@ -130,8 +132,8 @@ export class FFormObject extends FRoot { .direction=${this.config.direction ?? "horizontal"} .variant=${this.config.variant} .label=${this.config.label} - gap=${this.config.gap ?? this.gap} - data-qa-id=${this.config.qaId || this.config.id} + gap=${ifDefined(this.config.gap ?? this.gap)} + data-qa-id=${ifDefined(this.config.qaId || this.config.id)} .collapse=${this.config.isCollapsible ? "accordion" : "none"} > ${fieldTemplates} @@ -142,7 +144,7 @@ export class FFormObject extends FRoot { variant="para" size="small" weight="regular" - data-qa-help-for=${this.config.qaId || this.config.id} + data-qa-help-for=${ifDefined(this.config.qaId || this.config.id)} .state=${this.config.state} >${this.config?.helperText}` @@ -223,6 +225,13 @@ export class FFormObject extends FRoot { if (divider) { divider.dataset.hidden = "true"; } + + if ((fieldConfig as FormBuilderBaseField).layout === "label-left") { + const wrapper = ref.value.closest(".label-left-layout"); + if (wrapper) { + wrapper.dataset.hidden = "true"; + } + } } else { ref.value.dataset.hidden = "false"; const divider = this.shadowRoot?.querySelector( @@ -231,6 +240,13 @@ export class FFormObject extends FRoot { if (divider) { divider.dataset.hidden = "false"; } + + if ((fieldConfig as FormBuilderBaseField).layout === "label-left") { + const wrapper = ref.value.closest(".label-left-layout"); + if (wrapper) { + wrapper.dataset.hidden = "false"; + } + } } this.dispatchShowWhenExeEvent(); } diff --git a/packages/flow-form-builder/src/modules/helpers.ts b/packages/flow-form-builder/src/modules/helpers.ts index 271ca58f6..ff5ba11b4 100644 --- a/packages/flow-form-builder/src/modules/helpers.ts +++ b/packages/flow-form-builder/src/modules/helpers.ts @@ -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) { const inputElements = element.shadowRoot?.querySelectorAll( @@ -88,7 +89,7 @@ export function getSubTitle( return html` ${subTitle} + ${subTitle} `; } @@ -116,11 +119,15 @@ export function getSlots( slot="label" padding="none" gap="none" - data-qa-label-for=${field.qaId || field.id} + data-qa-label-for=${ifDefined(field.qaId || field.id)} >${field.label.title}` : name - ? html`${name}` : nothing; @@ -135,7 +142,7 @@ export function getSlots( source="i-question-filled" size="small" state="subtle" - data-qa-info-icon-for=${field.qaId || field.id} + data-qa-info-icon-for=${ifDefined(field.qaId || field.id)} .tooltip="${field.label?.iconTooltip}" clickable > @@ -148,7 +155,7 @@ export function getSlots( } return html` ${label}${subTitle} ${field.helperText - ? html`${field.helperText} ` : nothing}`; @@ -170,7 +177,7 @@ export function getLabelLeftLayout( source="i-question-filled" size="small" state="subtle" - data-qa-info-icon-for=${field.qaId || field.id} + data-qa-info-icon-for=${ifDefined(field.qaId || field.id)} .tooltip="${field.label?.iconTooltip}" clickable > @@ -180,14 +187,16 @@ export function getLabelLeftLayout( typeof field.label?.title === "object" ? field.label?.title : html` - ${field.label?.title} + ${field.label?.title} `; const label = html` ${title}${iconTooltip} ${description} `; - return html` + return html` ${label} ${fieldHtml} `; diff --git a/stories/flow-form-builder/show-when-with-layout.stories.ts b/stories/flow-form-builder/show-when-with-layout.stories.ts new file mode 100644 index 000000000..3613a8366 --- /dev/null +++ b/stories/flow-form-builder/show-when-with-layout.stories.ts @@ -0,0 +1,110 @@ +import { Story, Meta } from "@storybook/web-components"; +import { html } from "lit-html"; +import { FormBuilderField, FormBuilderValues } from "@ollion/flow-form-builder"; +import { createRef, Ref, ref } from "lit/directives/ref.js"; + +export default { + title: "@ollion/flow-form-builder/Examples/Show When With Layout", + argTypes: { + field: { + control: false + } + } +} as Meta; + +type SampleFormBuilder = { + field: FormBuilderField; +}; + +const sampleFormBuilder: SampleFormBuilder = { + field: { + type: "object", + direction: "vertical", + label: { + title: "Label left Layout fields" + }, + fields: { + first: { + type: "text", + label: { + title: "First" + }, + layout: "label-left" + }, + second: { + type: "text", + label: { + title: "Second" + }, + layout: "label-left", + showWhen(values) { + console.log((values as Record).first === "xyz"); + return (values as Record).first === "xyz"; + } + }, + thirdWithIcon: { + type: "object", + label: { + title: "Icon is added after field" + }, + gap: "x-small", + fields: { + third: { + type: "text", + label: { + title: "Third" + }, + layout: "label-left" + }, + icon: { + type: "icon-button", + icon: "i-close", + category: "transparent", + variant: "block", + state: "neutral" + } + } + } + } + } +}; + +const Template: Story = (args: any) => { + const handleKeydown = (event: Event) => { + event.stopPropagation(); + event.stopImmediatePropagation(); + }; + const fieldRef: Ref = createRef(); + const handleInput = (event: CustomEvent) => { + if (fieldRef.value) { + fieldRef.value.innerHTML = JSON.stringify(event.detail, undefined, 8); + } + }; + return html` + + + + + + + +
${JSON.stringify(args.values, undefined, 8)}
+
+
+ `; +}; + +export const basic = Template.bind({}); + +basic.args = { + field: sampleFormBuilder.field, + values: { + first: "Tony", + second: "Stark" + } +};