Memoise field registration to improve performance and avoid loops

This commit is contained in:
Andrew Kingston 2024-11-08 11:05:22 +00:00
parent c4b597488e
commit a00bcea2f7
No known key found for this signature in database
1 changed files with 35 additions and 11 deletions

View File

@ -1,10 +1,10 @@
<script> <script>
import Placeholder from "../Placeholder.svelte"
import { getContext, onDestroy } from "svelte" import { getContext, onDestroy } from "svelte"
import { Icon } from "@budibase/bbui"
import InnerForm from "./InnerForm.svelte"
import { writable } from "svelte/store" import { writable } from "svelte/store"
import Provider from "components/context/Provider.svelte" import { Icon } from "@budibase/bbui"
import { memo } from "@budibase/frontend-core"
import Placeholder from "../Placeholder.svelte"
import InnerForm from "./InnerForm.svelte"
export let label export let label
export let field export let field
@ -23,26 +23,39 @@
const formContext = getContext("form") const formContext = getContext("form")
const formStepContext = getContext("form-step") const formStepContext = getContext("form-step")
const fieldGroupContext = getContext("field-group") const fieldGroupContext = getContext("field-group")
const { styleable, builderStore } = getContext("sdk") const { styleable, builderStore, Provider } = getContext("sdk")
const component = getContext("component") const component = getContext("component")
// Register field with form // Register field with form
const formApi = formContext?.formApi const formApi = formContext?.formApi
const labelPos = fieldGroupContext?.labelPosition || "above" const labelPos = fieldGroupContext?.labelPosition || "above"
let formField
let touched = false let touched = false
let labelNode let labelNode
$: formStep = formStepContext ? $formStepContext || 1 : 1 // Memoize values required to register the field to avoid loops
$: formField = formApi?.registerField( const formStep = formStepContext || writable(1)
field || $component.name, const fieldInfo = memo({
field: field || $component.name,
type, type,
defaultValue, defaultValue,
disabled, disabled,
readonly, readonly,
validation, validation,
formStep formStep: $formStep || 1,
) })
$: fieldInfo.set({
field: field || $component.name,
type,
defaultValue,
disabled,
readonly,
validation,
formStep: $formStep || 1,
})
$: registerField($fieldInfo)
$: schemaType = $: schemaType =
fieldSchema?.type !== "formula" && fieldSchema?.type !== "bigint" fieldSchema?.type !== "formula" && fieldSchema?.type !== "bigint"
? fieldSchema?.type ? fieldSchema?.type
@ -61,6 +74,18 @@
// Determine label class from position // Determine label class from position
$: labelClass = labelPos === "above" ? "" : `spectrum-FieldLabel--${labelPos}` $: labelClass = labelPos === "above" ? "" : `spectrum-FieldLabel--${labelPos}`
const registerField = info => {
formField = formApi?.registerField(
info.field,
info.type,
info.defaultValue,
info.disabled,
info.readonly,
info.validation,
info.formStep
)
}
const updateLabel = e => { const updateLabel = e => {
if (touched) { if (touched) {
builderStore.actions.updateProp("label", e.target.textContent) builderStore.actions.updateProp("label", e.target.textContent)
@ -75,7 +100,6 @@
</script> </script>
{#if !formContext} {#if !formContext}
<!-- Cant support attachments -->
<Provider data={{ value: fieldState?.value }}> <Provider data={{ value: fieldState?.value }}>
<InnerForm <InnerForm
{disabled} {disabled}