Add more functionality to core SpectrumField component to simplify other form components
This commit is contained in:
parent
734e341ebb
commit
32ad2b6a08
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,14 +18,14 @@
|
|||
$: placeholderText = placeholder || "Choose an option"
|
||||
$: isNull = $fieldState?.value == null || $fieldState?.value === ""
|
||||
|
||||
// Update value on blur only
|
||||
const selectOption = value => {
|
||||
fieldApi.setValue(value)
|
||||
open = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<SpectrumField {field} {label}>
|
||||
<SpectrumField {field} {label} bind:fieldState bind:fieldApi bind:fieldSchema>
|
||||
{#if fieldState}
|
||||
<button
|
||||
id={$fieldState.fieldId}
|
||||
class="spectrum-Picker"
|
||||
|
@ -92,4 +90,5 @@
|
|||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
</SpectrumField>
|
||||
|
|
|
@ -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}`
|
||||
</script>
|
||||
|
||||
{#if !fieldId}
|
||||
{#if !fieldState}
|
||||
<Placeholder>Add the Field setting to start using your component</Placeholder>
|
||||
{:else if !formContext}
|
||||
<Placeholder>Form components need to be wrapped in a Form</Placeholder>
|
||||
|
@ -28,7 +39,7 @@
|
|||
<div class="spectrum-Form-item" use:styleable={$component.styles}>
|
||||
{#if label}
|
||||
<label
|
||||
for={fieldId}
|
||||
for={$fieldState.fieldId}
|
||||
class={`spectrum-FieldLabel spectrum-FieldLabel--sizeM spectrum-Form-itemLabel ${labelPositionClass}`}>
|
||||
{label}
|
||||
</label>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<script>
|
||||
import "@spectrum-css/textfield/dist/index-vars.css"
|
||||
import { getContext } from "svelte"
|
||||
import SpectrumField from "./SpectrumField.svelte"
|
||||
|
||||
export let field
|
||||
|
@ -8,18 +7,16 @@
|
|||
export let placeholder
|
||||
export let type = "text"
|
||||
|
||||
// Register this field with its form
|
||||
const { formApi } = getContext("form") ?? {}
|
||||
const formField = formApi?.registerField(field) ?? {}
|
||||
const { fieldApi, fieldState } = formField
|
||||
let fieldState
|
||||
let fieldApi
|
||||
|
||||
// Update value on blur only
|
||||
const onBlur = event => {
|
||||
fieldApi.setValue(event.target.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<SpectrumField {label} {field}>
|
||||
<SpectrumField {label} {field} bind:fieldState bind:fieldApi>
|
||||
{#if fieldState}
|
||||
<div class="spectrum-Textfield" class:is-invalid={!$fieldState.valid}>
|
||||
{#if !$fieldState.valid}
|
||||
<svg
|
||||
|
@ -37,4 +34,5 @@
|
|||
{type}
|
||||
class="spectrum-Textfield-input" />
|
||||
</div>
|
||||
{/if}
|
||||
</SpectrumField>
|
||||
|
|
Loading…
Reference in New Issue