UNPKG

@kobalte/core

Version:

Unstyled components and primitives for building accessible web apps and design systems with SolidJS.

207 lines (202 loc) 6.93 kB
import { FORM_CONTROL_FIELD_PROP_NAMES, createFormControlField } from './HYP2U57X.js'; import { FormControlLabel } from './7ZHN3PYD.js'; import { createFormResetListener } from './ANN3A2QM.js'; import { FormControlErrorMessage } from './ICNSTULC.js'; import { FormControlDescription, useFormControlContext, FORM_CONTROL_PROP_NAMES, createFormControl, FormControlContext } from './YKGT7A57.js'; import { createControllableSignal } from './BLN63FDC.js'; import { Polymorphic } from './6Y7B2NEO.js'; import { __export } from './5ZKAE4VZ.js'; import { createComponent, mergeProps } from 'solid-js/web'; import { mergeDefaultProps, composeEventHandlers, createGenerateId, access, mergeRefs } from '@kobalte/utils'; import { createContext, useContext, splitProps, createUniqueId, createEffect, on } from 'solid-js'; // src/text-field/index.tsx var text_field_exports = {}; __export(text_field_exports, { Description: () => FormControlDescription, ErrorMessage: () => FormControlErrorMessage, Input: () => TextFieldInput, Label: () => FormControlLabel, Root: () => TextFieldRoot, TextArea: () => TextFieldTextArea, TextField: () => TextField, useTextFieldContext: () => useTextFieldContext }); var TextFieldContext = createContext(); function useTextFieldContext() { const context = useContext(TextFieldContext); if (context === void 0) { throw new Error("[kobalte]: `useTextFieldContext` must be used within a `TextField` component"); } return context; } // src/text-field/text-field-input.tsx function TextFieldInput(props) { return createComponent(TextFieldInputBase, mergeProps({ type: "text" }, props)); } function TextFieldInputBase(props) { const formControlContext = useFormControlContext(); const context = useTextFieldContext(); const mergedProps = mergeDefaultProps({ id: context.generateId("input") }, props); const [local, formControlFieldProps, others] = splitProps(mergedProps, ["onInput"], FORM_CONTROL_FIELD_PROP_NAMES); const { fieldProps } = createFormControlField(formControlFieldProps); return createComponent(Polymorphic, mergeProps({ as: "input", get id() { return fieldProps.id(); }, get name() { return formControlContext.name(); }, get value() { return context.value(); }, get required() { return formControlContext.isRequired(); }, get disabled() { return formControlContext.isDisabled(); }, get readonly() { return formControlContext.isReadOnly(); }, get ["aria-label"]() { return fieldProps.ariaLabel(); }, get ["aria-labelledby"]() { return fieldProps.ariaLabelledBy(); }, get ["aria-describedby"]() { return fieldProps.ariaDescribedBy(); }, get ["aria-invalid"]() { return formControlContext.validationState() === "invalid" || void 0; }, get ["aria-required"]() { return formControlContext.isRequired() || void 0; }, get ["aria-disabled"]() { return formControlContext.isDisabled() || void 0; }, get ["aria-readonly"]() { return formControlContext.isReadOnly() || void 0; }, get onInput() { return composeEventHandlers([local.onInput, context.onInput]); } }, () => formControlContext.dataset(), others)); } function TextFieldRoot(props) { let ref; const defaultId = `textfield-${createUniqueId()}`; const mergedProps = mergeDefaultProps({ id: defaultId }, props); const [local, formControlProps, others] = splitProps(mergedProps, ["ref", "value", "defaultValue", "onChange"], FORM_CONTROL_PROP_NAMES); const initialValue = local.value; const [value, setValue] = createControllableSignal({ value: () => initialValue === void 0 ? void 0 : local.value ?? "", defaultValue: () => local.defaultValue, onChange: (value2) => local.onChange?.(value2) }); const { formControlContext } = createFormControl(formControlProps); createFormResetListener(() => ref, () => setValue(local.defaultValue ?? "")); const onInput = (e) => { if (formControlContext.isReadOnly() || formControlContext.isDisabled()) { return; } const target = e.target; setValue(target.value); target.value = value() ?? ""; }; const context = { value, generateId: createGenerateId(() => access(formControlProps.id)), onInput }; return createComponent(FormControlContext.Provider, { value: formControlContext, get children() { return createComponent(TextFieldContext.Provider, { value: context, get children() { return createComponent(Polymorphic, mergeProps({ as: "div", ref(r$) { const _ref$ = mergeRefs((el) => ref = el, local.ref); typeof _ref$ === "function" && _ref$(r$); }, role: "group", get id() { return access(formControlProps.id); } }, () => formControlContext.dataset(), others)); } }); } }); } function TextFieldTextArea(props) { let ref; const context = useTextFieldContext(); const mergedProps = mergeDefaultProps({ id: context.generateId("textarea") }, props); const [local, others] = splitProps(mergedProps, ["ref", "autoResize", "submitOnEnter", "onKeyPress"]); createEffect(on([() => ref, () => local.autoResize, () => context.value()], ([ref2, autoResize]) => { if (!ref2 || !autoResize) { return; } adjustHeight(ref2); })); const onKeyPress = (event) => { if (ref && local.submitOnEnter && event.key === "Enter" && !event.shiftKey) { if (ref.form) { ref.form.requestSubmit(); event.preventDefault(); } } }; return createComponent(TextFieldInputBase, mergeProps({ as: "textarea", get ["aria-multiline"]() { return local.submitOnEnter ? "false" : void 0; }, get onKeyPress() { return composeEventHandlers([local.onKeyPress, onKeyPress]); }, ref(r$) { const _ref$ = mergeRefs((el) => ref = el, local.ref); typeof _ref$ === "function" && _ref$(r$); } }, others)); } function adjustHeight(el) { const prevAlignment = el.style.alignSelf; const prevOverflow = el.style.overflow; const isFirefox = "MozAppearance" in el.style; if (!isFirefox) { el.style.overflow = "hidden"; } el.style.alignSelf = "start"; el.style.height = "auto"; el.style.height = `${el.scrollHeight + (el.offsetHeight - el.clientHeight)}px`; el.style.overflow = prevOverflow; el.style.alignSelf = prevAlignment; } // src/text-field/index.tsx var TextField = Object.assign(TextFieldRoot, { Description: FormControlDescription, ErrorMessage: FormControlErrorMessage, Input: TextFieldInput, Label: FormControlLabel, TextArea: TextFieldTextArea }); export { TextField, TextFieldInput, TextFieldRoot, TextFieldTextArea, text_field_exports, useTextFieldContext };