{"version":3,"names":["componentsWithInputEvent","getClearValidationEventName","componentTag","componentTagCamelCase","split","map","part","index","toUpperCase","slice","join","clearValidationEvent","includes","hiddenFormInputSlotName","isCheckable","component","onFormResetMap","WeakMap","formComponentSet","WeakSet","hasRegisteredFormComponentParent","form","formComponentEl","hasParentComponentWithFormIdSet","closestElementCrossShadowBoundary","parentElement","formComponentRegisterEventName","addEventListener","event","composedPath","some","element","has","stopPropagation","once","dispatchEvent","CustomEvent","bubbles","composed","displayValidationMessage","status","message","icon","validationIcon","validationMessage","getValidationComponent","el","nodeName","invalidEvent","invalidHandler","hiddenInput","target","hiddenInputMessage","formComponent","toLowerCase","componentTagParts","length","preventDefault","validity","submitForm","formEl","requestSubmit","removeEventListener","requestAnimationFrame","invalidEls","querySelectorAll","setFocus","resetForm","reset","connectForm","value","associatedForm","findAssociatedForm","defaultValue","defaultChecked","checked","boundOnFormReset","onFormReset","bind","set","add","queryElementRoots","id","this","disconnectForm","get","delete","afterConnectDefaultValueSet","internalHiddenInputInputEvent","hiddenInputInputHandler","removeHiddenInputChangeEventListener","input","syncHiddenFormInput","name","ownerDocument","inputs","forEach","remove","values","Array","isArray","extra","seen","Set","valueMatch","find","val","defaultSyncHiddenFormInput","push","docFrag","pop","createElement","slot","createDocumentFragment","append","disabled","required","tabIndex","setAttribute","removeAttribute","validationComponent","key","HiddenFormInputSlot","h"],"sources":["src/utils/form.tsx"],"sourcesContent":["import { FunctionalComponent, h, VNode } from \"@stencil/core\";\nimport { Writable } from \"type-fest\";\nimport { Status } from \"../components/interfaces\";\nimport type { IconNameOrString } from \"../components/icon/interfaces\";\nimport { closestElementCrossShadowBoundary, queryElementRoots } from \"./dom\";\n\n/**\n * Any form with a `calciteInput` event needs to be included in this array.\n */\nexport const componentsWithInputEvent = [\n \"calcite-input\",\n \"calcite-input-number\",\n \"calcite-input-text\",\n \"calcite-text-area\",\n];\n\n/**\n * Get the event name to listen for that, when emitted, will clear the\n * validation message that displays after form submission. Only validation\n * messages that are set by the browser will be cleared. If a user sets\n * validationMessage to a custom value, they are responsible for clearing it.\n *\n * Exported for testing purposes.\n *\n * @param componentTag the tag of the component, e.g. \"calcite-input\"\n * @returns the event name\n */\nexport function getClearValidationEventName(componentTag: string): string {\n const componentTagCamelCase = componentTag\n .split(\"-\")\n .map((part: string, index: number) =>\n index === 0 ? part : `${part[0].toUpperCase()}${part.slice(1)}`,\n )\n .join(\"\");\n\n const clearValidationEvent = `${componentTagCamelCase}${\n componentsWithInputEvent.includes(componentTag) ? \"Input\" : \"Change\"\n }`;\n\n return clearValidationEvent;\n}\n\nexport type MutableValidityState = Writable;\n\n/**\n * Exported for testing purposes.\n */\nexport const hiddenFormInputSlotName = \"hidden-form-input\";\n\n/**\n * Defines interface for form owning components.\n *\n * Allows calling submit/reset methods on the form.\n */\nexport interface FormOwner {\n /**\n * The host element.\n */\n readonly el: HTMLElement;\n\n /**\n * The ID of the form to associate with the component.\n *\n * When not set, the component will be associated with its ancestor form element, if any.\n *\n * Note that this prop should use the @Prop decorator.\n */\n form: string;\n\n /**\n * The form this component is associated with.\n *\n * @internal\n */\n formEl: HTMLFormElement;\n}\n\n/**\n * Defines interface for form-associated components.\n *\n * Along with the interface, use the matching form utils to help set up the component behavior.\n */\nexport interface FormComponent extends FormOwner {\n /**\n * When true, this component's value will not be submitted in the form.\n */\n disabled: boolean;\n\n /**\n * When true, form submit requests will enforce field requirement.\n *\n * @todo remove optional in follow-up PR\n */\n required?: boolean;\n\n /**\n * The name used to submit the value to the associated form.\n *\n * Note that this prop should use the @Prop decorator.\n */\n name: string;\n\n /**\n * This form component's value.\n *\n * Note that this prop should use the @Prop decorator.\n */\n value: T;\n\n /**\n * The initial value for this form component.\n *\n * When the form is reset, the value will be set to this property.\n */\n defaultValue: T;\n\n /** The validation icon to display. */\n validationIcon?: string | boolean;\n\n /** The validation message to display. */\n validationMessage?: string;\n\n /** The validity state of the form component. */\n validity?: MutableValidityState;\n\n /**\n * Hook for components to provide custom form reset behavior.\n */\n onFormReset?: () => void;\n\n /**\n * Hook for components to sync _extra_ props on the hidden input form element used for form-submitting.\n *\n * Note: The following props are set by default: disabled, hidden, name, required, value.\n */\n syncHiddenFormInput?: (input: HTMLInputElement) => void;\n}\n\n/**\n * Defines interface for checkable form-associated components.\n *\n * Along with the interface, use the matching form utils to help set up the component behavior.\n */\nexport interface CheckableFormComponent extends FormComponent {\n /**\n * For boolean-valued components, this property defines whether the associated value is submitted to the form or not.\n */\n checked: boolean;\n\n /**\n * The initial checked value for this form component.\n *\n * When the form is reset, the checked property will be set to this value.\n */\n defaultChecked: boolean;\n}\n\nfunction isCheckable(component: FormComponent): component is CheckableFormComponent {\n return \"checked\" in component;\n}\n\nconst onFormResetMap = new WeakMap();\nconst formComponentSet = new WeakSet();\n\n/**\n * This helps determine if our form component is part of a composite form-associated component.\n *\n * @param form\n * @param formComponentEl\n */\nfunction hasRegisteredFormComponentParent(\n form: HTMLFormElement,\n formComponentEl: HTMLElement,\n): boolean {\n // if we have a parent component using the form ID attribute, we assume it is form-associated\n const hasParentComponentWithFormIdSet = closestElementCrossShadowBoundary(\n formComponentEl.parentElement,\n \"[form]\",\n );\n\n if (hasParentComponentWithFormIdSet) {\n return true;\n }\n\n // we use events as a way to test for nested form-associated components across shadow bounds\n const formComponentRegisterEventName = \"calciteInternalFormComponentRegister\";\n\n let hasRegisteredFormComponentParent = false;\n\n form.addEventListener(\n formComponentRegisterEventName,\n (event) => {\n hasRegisteredFormComponentParent = event\n .composedPath()\n .some((element) => formComponentSet.has(element as HTMLElement));\n event.stopPropagation();\n },\n { once: true },\n );\n\n formComponentEl.dispatchEvent(\n new CustomEvent(formComponentRegisterEventName, {\n bubbles: true,\n composed: true,\n }),\n );\n\n return hasRegisteredFormComponentParent;\n}\n\n// exported for test purposes only\nexport interface ValidationProps {\n status: Status;\n message: string;\n icon: IconNameOrString | boolean | \"\";\n}\n\nfunction displayValidationMessage(\n component: HTMLCalciteInputElement | FormComponent,\n { status, message, icon }: ValidationProps,\n): void {\n if (\"status\" in component) {\n component.status = status;\n }\n\n if (\"validationIcon\" in component && typeof component.validationIcon !== \"string\") {\n component.validationIcon = icon;\n }\n\n if (\"validationMessage\" in component && !component.validationMessage) {\n component.validationMessage = message;\n }\n}\n\nfunction getValidationComponent(\n el: HTMLCalciteInputElement,\n // TODO: create an HTMLCalciteFormAssociatedElement base type\n): HTMLCalciteInputElement | HTMLCalciteRadioButtonGroupElement {\n // radio-button is formAssociated, but the validation props are on the parent group\n if (el.nodeName === \"CALCITE-RADIO-BUTTON\") {\n return closestElementCrossShadowBoundary(el, \"calcite-radio-button-group\");\n }\n return el;\n}\n\nconst invalidEvent = new CustomEvent(\"calciteInvalid\", { bubbles: true, composed: true });\n\nfunction invalidHandler(event: Event) {\n // target is the hidden input, which is slotted in the actual form component\n const hiddenInput = event?.target as HTMLInputElement;\n const hiddenInputMessage = hiddenInput?.validationMessage;\n\n // not necessarily a calcite-input, but we don't have an HTMLCalciteFormAssociatedElement type\n const formComponent = getValidationComponent(\n hiddenInput?.parentElement as HTMLCalciteInputElement,\n ) as HTMLCalciteInputElement;\n\n if (!formComponent) {\n return;\n }\n\n const componentTag = formComponent?.nodeName?.toLowerCase();\n const componentTagParts = componentTag?.split(\"-\");\n\n if (componentTagParts.length < 2 || componentTagParts[0] !== \"calcite\") {\n return;\n }\n\n // prevent the browser from showing the native validation popover\n event?.preventDefault();\n\n if (\"validity\" in formComponent) {\n formComponent.validity = hiddenInput?.validity;\n }\n\n // dispatch a \"calciteInvalid\" so users can set custom validation messages\n formComponent.dispatchEvent(invalidEvent);\n\n displayValidationMessage(formComponent, {\n message: hiddenInputMessage,\n icon: true,\n status: \"invalid\",\n });\n\n const clearValidationEvent = getClearValidationEventName(componentTag);\n formComponent.addEventListener(\n clearValidationEvent,\n () => {\n if (\"status\" in formComponent) {\n formComponent.status = \"idle\";\n }\n\n if (\"validationIcon\" in formComponent && !formComponent.validationIcon) {\n formComponent.validationIcon = false;\n }\n\n if (\n \"validationMessage\" in formComponent &&\n formComponent.validationMessage === hiddenInputMessage\n ) {\n formComponent.validationMessage = \"\";\n }\n\n if (\"validity\" in formComponent) {\n formComponent.validity = hiddenInput?.validity;\n }\n },\n { once: true },\n );\n}\n\n/**\n * Helper to submit a form.\n *\n * @param component\n * @returns true if its associated form was submitted, false otherwise.\n */\nexport function submitForm(component: FormOwner): boolean {\n const { formEl } = component;\n\n if (!formEl) {\n return false;\n }\n\n formEl.addEventListener(\"invalid\", invalidHandler, true);\n formEl.requestSubmit();\n formEl.removeEventListener(\"invalid\", invalidHandler, true);\n\n requestAnimationFrame(() => {\n const invalidEls = formEl.querySelectorAll(\"[status=invalid]\");\n\n // focus the first invalid element that has a validation message\n for (const el of invalidEls) {\n if (el?.validationMessage) {\n el?.setFocus();\n break;\n }\n }\n });\n\n return true;\n}\n\n/**\n * Helper to reset a form.\n *\n * @param component\n */\nexport function resetForm(component: FormOwner): void {\n component.formEl?.reset();\n}\n\n/**\n * Helper to set up form interactions on connectedCallback.\n *\n * @param component\n */\nexport function connectForm(component: FormComponent): void {\n const { el, value } = component;\n const associatedForm = findAssociatedForm(component);\n\n if (!associatedForm || hasRegisteredFormComponentParent(associatedForm, el)) {\n return;\n }\n\n component.formEl = associatedForm;\n component.defaultValue = value;\n\n if (isCheckable(component)) {\n component.defaultChecked = component.checked;\n }\n\n const boundOnFormReset = (component.onFormReset || onFormReset).bind(component);\n associatedForm.addEventListener(\"reset\", boundOnFormReset);\n onFormResetMap.set(component.el, boundOnFormReset);\n formComponentSet.add(el);\n}\n\n/**\n * Utility method to find a form-component's associated form element.\n *\n * @param component\n */\nexport function findAssociatedForm(component: FormOwner): HTMLFormElement | null {\n const { el, form } = component;\n\n return form\n ? queryElementRoots(el, { id: form })\n : closestElementCrossShadowBoundary(el, \"form\");\n}\n\nfunction onFormReset(this: FormComponent): void {\n if (\"status\" in this) {\n this.status = \"idle\";\n }\n\n if (\"validationIcon\" in this) {\n this.validationIcon = false;\n }\n\n if (\"validationMessage\" in this) {\n this.validationMessage = \"\";\n }\n\n if (isCheckable(this)) {\n this.checked = this.defaultChecked;\n return;\n }\n\n this.value = this.defaultValue;\n}\n\n/**\n * Helper to tear down form interactions on disconnectedCallback.\n *\n * @param component\n */\nexport function disconnectForm(component: FormComponent): void {\n const { el, formEl } = component;\n\n if (!formEl) {\n return;\n }\n\n const boundOnFormReset = onFormResetMap.get(el);\n formEl.removeEventListener(\"reset\", boundOnFormReset);\n onFormResetMap.delete(el);\n component.formEl = null;\n formComponentSet.delete(el);\n}\n\n/**\n * Helper for setting the default value on initialization after connectedCallback.\n *\n * Note that this is only needed if the default value cannot be determined on connectedCallback.\n *\n * @param component\n * @param value\n */\nexport function afterConnectDefaultValueSet(component: FormComponent, value: any): void {\n component.defaultValue = value;\n}\n\nexport const internalHiddenInputInputEvent = \"calciteInternalHiddenInputInput\";\n\nconst hiddenInputInputHandler = (event: Event) => {\n event.target.dispatchEvent(new CustomEvent(internalHiddenInputInputEvent, { bubbles: true }));\n};\n\nconst removeHiddenInputChangeEventListener = (input: HTMLInputElement) =>\n input.removeEventListener(\"input\", hiddenInputInputHandler);\n\n/**\n * Helper for maintaining a form-associated's hidden input in sync with the component.\n *\n * Based on Ionic's approach: https://github.com/ionic-team/ionic-framework/blob/e4bf052794af9aac07f887013b9250d2a045eba3/core/src/utils/helpers.ts#L198\n *\n * @param component\n */\nfunction syncHiddenFormInput(component: FormComponent): void {\n const { el, formEl, name, value } = component;\n const { ownerDocument } = el;\n\n const inputs = el.querySelectorAll(`input[slot=\"${hiddenFormInputSlotName}\"]`);\n\n if (!formEl || !name) {\n inputs.forEach((input) => {\n removeHiddenInputChangeEventListener(input);\n input.remove();\n });\n return;\n }\n\n const values = Array.isArray(value) ? value : [value];\n const extra: any[] = [];\n const seen = new Set();\n\n inputs.forEach((input) => {\n const valueMatch = values.find(\n (val) =>\n /* intentional non-strict equality check */\n val == input.value,\n );\n\n if (valueMatch != null) {\n seen.add(valueMatch);\n defaultSyncHiddenFormInput(component, input, valueMatch);\n } else {\n extra.push(input);\n }\n });\n\n let docFrag: DocumentFragment;\n\n values.forEach((value) => {\n if (seen.has(value)) {\n return;\n }\n\n let input = extra.pop();\n\n if (!input) {\n input = ownerDocument.createElement(\"input\");\n input.slot = hiddenFormInputSlotName;\n }\n\n if (!docFrag) {\n docFrag = ownerDocument.createDocumentFragment();\n }\n\n docFrag.append(input);\n\n // emits when hidden input is autofilled\n input.addEventListener(\"input\", hiddenInputInputHandler);\n\n defaultSyncHiddenFormInput(component, input, value);\n });\n\n if (docFrag) {\n el.append(docFrag);\n }\n extra.forEach((input) => {\n removeHiddenInputChangeEventListener(input);\n input.remove();\n });\n}\n\nfunction defaultSyncHiddenFormInput(\n component: FormComponent,\n input: HTMLInputElement,\n value: string,\n): void {\n const { defaultValue, disabled, form, name, required } = component;\n\n // keep in sync to prevent losing reset value\n input.defaultValue = defaultValue;\n input.disabled = disabled;\n input.name = name;\n input.required = required;\n input.tabIndex = -1;\n\n // we set the attr as the prop is read-only\n if (form) {\n input.setAttribute(\"form\", form);\n } else {\n input.removeAttribute(\"form\");\n }\n\n if (isCheckable(component)) {\n input.checked = component.checked;\n\n // keep in sync to prevent losing reset value\n input.defaultChecked = component.defaultChecked;\n // heuristic to support default/on mode from https://html.spec.whatwg.org/multipage/input.html#dom-input-value-default-on\n input.value = component.checked ? value || \"on\" : \"\";\n } else {\n input.value = value || \"\";\n }\n\n component.syncHiddenFormInput?.(input);\n\n const validationComponent = getValidationComponent(component.el as HTMLCalciteInputElement);\n\n if (validationComponent && \"validity\" in validationComponent) {\n // mutate the component's validity object to prevent a rerender\n // https://stenciljs.com/docs/properties#mutable-arrays-and-objects\n for (const key in { ...input?.validity }) {\n validationComponent.validity[key] = input.validity[key];\n }\n }\n}\n\ninterface HiddenFormInputSlotProps {\n component: FormComponent;\n}\n\n/**\n * Helper to render the slot for form-associated component's hidden input.\n *\n * If the component has a default slot, this must be placed at the bottom of the component's root container to ensure it is the last child.\n *\n * render(): VNode {\n * \n *
\n * // ...\n * \n *
\n *
\n * }\n *\n * Note that the hidden-form-input Sass mixin must be added to the component's style to apply specific styles.\n *\n * @param root0\n * @param root0.component\n */\nexport const HiddenFormInputSlot: FunctionalComponent = ({\n component,\n}): VNode => {\n syncHiddenFormInput(component);\n\n return ;\n};\n"],"mappings":"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","ignoreList":[]}