From 8c90edf4624996749e28132584d91116aa49e560 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 28 Jan 2021 08:47:44 +0000 Subject: [PATCH] Add more functionality to core SpectrumField component to simplify other form components --- .../PropertyControls/FormFieldSelect.svelte | 2 +- .../standard-components/src/forms/Form.svelte | 16 +-- .../src/forms/OptionsField.svelte | 111 +++++++++--------- .../src/forms/SpectrumField.svelte | 19 ++- .../src/forms/StringField.svelte | 46 ++++---- 5 files changed, 102 insertions(+), 92 deletions(-) diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FormFieldSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FormFieldSelect.svelte index ca40946bcb..2c6119eb00 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FormFieldSelect.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/FormFieldSelect.svelte @@ -22,7 +22,7 @@ $: options = getOptions(schema, type) const getOptions = (schema, fieldType) => { - let entries = Object.entries(schema) + let entries = Object.entries(schema ?? {}) if (fieldType) { entries = entries.filter(entry => entry[1].type === fieldType) } diff --git a/packages/standard-components/src/forms/Form.svelte b/packages/standard-components/src/forms/Form.svelte index 21e2ece4df..268b3f8aed 100644 --- a/packages/standard-components/src/forms/Form.svelte +++ b/packages/standard-components/src/forms/Form.svelte @@ -8,7 +8,7 @@ export let theme export let size - const { styleable, API } = getContext("sdk") + const { styleable, API, setBindableValue } = getContext("sdk") const component = getContext("component") let loaded = false @@ -24,7 +24,7 @@ // Form API contains functions to control the form const formApi = { - registerField: field => { + registerField: (field, componentId) => { if (!field) { return } @@ -38,11 +38,8 @@ fieldMap[field] = { fieldState: makeFieldState(field), - fieldApi: makeFieldApi(field, validate), + fieldApi: makeFieldApi(field, componentId, validate), fieldSchema: schema?.[field] ?? {}, - fieldId: `${Math.random() - .toString(32) - .substr(2)}/${field}`, } fieldMap = fieldMap return fieldMap[field] @@ -53,9 +50,11 @@ setContext("form", { formApi, formState }) // Creates an API for a specific field - const makeFieldApi = (field, validate) => { + const makeFieldApi = (field, componentId, validate) => { return { setValue: value => { + console.log("setting " + componentId + " to " + value) + setBindableValue(value, componentId) const { fieldState } = fieldMap[field] fieldState.update(state => { state.value = value @@ -72,6 +71,9 @@ const makeFieldState = field => { return writable({ field, + fieldId: `${Math.random() + .toString(32) + .substr(2)}/${field}`, value: null, error: null, valid: true, diff --git a/packages/standard-components/src/forms/OptionsField.svelte b/packages/standard-components/src/forms/OptionsField.svelte index 4c7f29f046..bdfb1664cc 100644 --- a/packages/standard-components/src/forms/OptionsField.svelte +++ b/packages/standard-components/src/forms/OptionsField.svelte @@ -2,17 +2,15 @@ import "@spectrum-css/picker/dist/index-vars.css" import "@spectrum-css/popover/dist/index-vars.css" import "@spectrum-css/menu/dist/index-vars.css" - import { getContext } from "svelte" import SpectrumField from "./SpectrumField.svelte" export let field export let label export let placeholder - // Register this field with its form - const { formApi } = getContext("form") ?? {} - const formField = formApi?.registerField(field) ?? {} - const { fieldApi, fieldState, fieldSchema } = formField + let fieldState + let fieldApi + let fieldSchema // Picker state let open = false @@ -20,68 +18,52 @@ $: placeholderText = placeholder || "Choose an option" $: isNull = $fieldState?.value == null || $fieldState?.value === "" - // Update value on blur only const selectOption = value => { fieldApi.setValue(value) open = false } - - -
-
    -
  • selectOption(null)}> - {placeholderText} + + {#if fieldState} +
  • - {#each options as option} + {/if} + + +
    +
    • selectOption(option)}> - {option} + on:click={() => selectOption(null)}> + {placeholderText}
    • - {/each} -
    -
    + {#each options as option} +
  • selectOption(option)}> + {option} + +
  • + {/each} +
+
+ {/if}
diff --git a/packages/standard-components/src/forms/SpectrumField.svelte b/packages/standard-components/src/forms/SpectrumField.svelte index 418b04371c..0c7b826f9f 100644 --- a/packages/standard-components/src/forms/SpectrumField.svelte +++ b/packages/standard-components/src/forms/SpectrumField.svelte @@ -5,21 +5,32 @@ export let label export let field + export let fieldState + export let fieldApi + export let fieldSchema + // Get contexts const formContext = getContext("form") const fieldGroupContext = getContext("fieldGroup") const { styleable } = getContext("sdk") const component = getContext("component") + + // Register field with form const { formApi } = formContext || {} const labelPosition = fieldGroupContext?.labelPosition || "above" - const formField = formApi?.registerField(field) ?? {} - const { fieldId, fieldState } = formField + const formField = formApi?.registerField(field, $component.id) + // Expose field properties to parent component + fieldState = formField?.fieldState + fieldApi = formField?.fieldApi + fieldSchema = formField?.fieldSchema + + // Extract label position from field group context $: labelPositionClass = labelPosition === "above" ? "" : `spectrum-FieldLabel--${labelPosition}` -{#if !fieldId} +{#if !fieldState} Add the Field setting to start using your component {:else if !formContext} Form components need to be wrapped in a Form @@ -28,7 +39,7 @@
{#if label} diff --git a/packages/standard-components/src/forms/StringField.svelte b/packages/standard-components/src/forms/StringField.svelte index 14ead3b367..c0a5684eae 100644 --- a/packages/standard-components/src/forms/StringField.svelte +++ b/packages/standard-components/src/forms/StringField.svelte @@ -1,6 +1,5 @@ - -
- {#if !$fieldState.valid} - - {/if} - -
+ + {#if fieldState} +
+ {#if !$fieldState.valid} + + {/if} + +
+ {/if}