UNPKG

@appbuckets/react-ui

Version:
343 lines (340 loc) 9.84 kB
import { __rest, __read, __assign } from 'tslib'; import * as React from 'react'; import clsx from 'clsx'; import { useAutoControlledValue, useForkRef } from '@appbuckets/react-ui-core'; import ReactInputMask from 'react-input-mask'; import TextareaAutosize from 'react-textarea-autosize'; import { useSharedClassName, useSplitStateClassName, } from '../utils/customHook.js'; import { useTabIndex } from '../hooks/useTabIndex.js'; import '../BucketTheme/BucketTheme.js'; import { useWithDefaultProps } from '../BucketTheme/BucketContext.js'; import Field from '../Field/Field.js'; /* -------- * Component Render * -------- */ var Input = React.forwardRef(function (receivedProps, ref) { var props = useWithDefaultProps('input', receivedProps); var _a = useSharedClassName(props), className = _a.className, _b = _a.rest, /** Strict Input Props */ clearable = _b.clearable, masked = _b.masked, textarea = _b.textarea, type = _b.type, userDefinedTabIndex = _b.tabIndex, selectAllOnClick = _b.selectAllOnClick, userDefinedValue = _b.value, userDefinedDefaultValue = _b.defaultValue, textareaProps = _b.textareaProps, /** Overridden Input Handlers */ userDefinedOnClick = _b.onClick, userDefinedOnClear = _b.onClear, userDefinedOnChange = _b.onChange, userDefinedOnBlur = _b.onBlur, userDefinedOnFocus = _b.onFocus, userDefinedOnSubmit = _b.onInputSubmit, userDefinedOnKeyDown = _b.onKeyDown, /** Shared Input/Field Props */ disabled = _b.disabled, required = _b.required, readOnly = _b.readOnly, /** Strict Field Props */ actions = _b.actions, actionsPosition = _b.actionsPosition, contentClassName = _b.contentClassName, hint = _b.hint, hintClassName = _b.hintClassName, icon = _b.icon, iconPosition = _b.iconPosition, label = _b.label, /** All other input Props */ rawRest = __rest(_b, [ 'clearable', 'masked', 'textarea', 'type', 'tabIndex', 'selectAllOnClick', 'value', 'defaultValue', 'textareaProps', 'onClick', 'onClear', 'onChange', 'onBlur', 'onFocus', 'onInputSubmit', 'onKeyDown', 'disabled', 'required', 'readOnly', 'actions', 'actionsPosition', 'contentClassName', 'hint', 'hintClassName', 'icon', 'iconPosition', 'label', ]); var _c = __read(useSplitStateClassName(rawRest), 2), stateClassName = _c[0], rest = _c[1]; /* -------- * Auto Controlled Component Value * -------- */ var _d = __read( useAutoControlledValue('', { prop: userDefinedValue, defaultProp: userDefinedDefaultValue, }), 2 ), value = _d[0], trySetValue = _d[1]; /* -------- * Internal Component Ref * -------- */ var fieldRef = React.useRef(null); var inputRef = React.useRef(null); var handleRef = useForkRef(ref, inputRef); /* -------- * Component Classes * -------- */ var classes = clsx( { required: required, disabled: disabled, clearable: clearable }, 'text', stateClassName, className ); /* -------- * Class list Controller * -------- */ var addClassesToRef = React.useCallback(function () { var classesToAdd = []; for (var _i = 0; _i < arguments.length; _i++) { classesToAdd[_i] = arguments[_i]; } classesToAdd.forEach(function (cx) { if (fieldRef.current) { fieldRef.current.classList.add(cx); } if (inputRef.current) { inputRef.current.classList.add(cx); } }); }, []); var removeClassesFromRef = React.useCallback(function () { var classesToRemove = []; for (var _i = 0; _i < arguments.length; _i++) { classesToRemove[_i] = arguments[_i]; } classesToRemove.forEach(function (cx) { if (fieldRef.current) { fieldRef.current.classList.remove(cx); } if (inputRef.current) { inputRef.current.classList.remove(cx); } }); }, []); /* -------- * Input Handlers * -------- */ var handleInputBlur = function (e) { /** Abort if Disabled or Readonly */ if (disabled || readOnly) { return; } /** Remove classes from reference */ removeClassesFromRef('focused'); /** Call user defined handler */ if (userDefinedOnBlur) { userDefinedOnBlur(e, __assign(__assign({}, props), { value: value })); } }; var handleInputChange = function (e) { /** Add class to reference */ addClassesToRef('dirty'); /** Call user defined handler */ if (userDefinedOnChange) { userDefinedOnChange( e, __assign(__assign({}, props), { value: e.target.value }) ); } /** Try to change local input state value */ trySetValue(e.target.value); }; var handleInputClick = function (e) { /** Abort if Disabled or Readonly */ if (disabled || readOnly) { return; } /** Add classes to reference */ addClassesToRef('touched'); if (inputRef.current && selectAllOnClick) { inputRef.current.setSelectionRange(0, inputRef.current.value.length); } e.stopPropagation(); if (userDefinedOnClick) { userDefinedOnClick(e, __assign(__assign({}, props), { value: value })); } }; var handleInputFocus = function (e) { /** Abort if Disabled or Readonly */ if (disabled || readOnly) { return; } /** Add classes to reference */ addClassesToRef('touched', 'focused'); /** Call user defined handler */ if (userDefinedOnFocus) { userDefinedOnFocus(e, __assign(__assign({}, props), { value: value })); } }; var handleInputKeyDown = function (e) { /** Abort if Disabled or Readonly */ if (disabled || readOnly) { return; } /** Call user defined handler */ if (userDefinedOnKeyDown) { userDefinedOnKeyDown(e); } /** If enter has been pressed */ if ((e.key === 'Enter' || e.key === 'NumpadEnter') && userDefinedOnSubmit) { userDefinedOnSubmit( null, __assign(__assign({}, props), { value: value }) ); } }; var handleInputClear = React.useCallback( function (e) { var _a, _b; /** Manually set the input value, and after trigger the change event */ if (inputRef.current) { /** Get the right value setter function from element */ var valueSetter = (_a = Object.getOwnPropertyDescriptor(inputRef.current, 'value')) === null || _a === void 0 ? void 0 : _a.set; var prototype = Object.getPrototypeOf(inputRef.current); var prototypeValueSetter = (_b = Object.getOwnPropertyDescriptor(prototype, 'value')) === null || _b === void 0 ? void 0 : _b.set; /** Create the Event */ var event_1 = new Event('input', { bubbles: true }); event_1.simulated = true; /** Call the Value Setter Function */ if (valueSetter !== prototypeValueSetter && prototypeValueSetter) { prototypeValueSetter.call(inputRef.current, ''); } else if (valueSetter) { valueSetter.call(inputRef.current, ''); } /** Dispatch the event */ inputRef.current.dispatchEvent(event_1); /** Call user defined handler */ if (userDefinedOnClear) { userDefinedOnClear(e); } /** Focus the input element */ inputRef.current.focus(); } }, [userDefinedOnClear] ); /* -------- * Input Computed Properties * -------- */ var tabIndex = useTabIndex({ disabled: disabled, readOnly: readOnly, prop: userDefinedTabIndex, }); /* -------- * Input Render * -------- */ var renderInputElement = function () { var baseProps = { value: value, disabled: disabled, required: required, tabIndex: tabIndex, readOnly: readOnly, className: classes, autoComplete: 'off', type: type || 'text', onBlur: handleInputBlur, onChange: handleInputChange, onClick: handleInputClick, onFocus: handleInputFocus, onKeyDown: handleInputKeyDown, }; if (masked) { return React.createElement( ReactInputMask, __assign({}, baseProps, masked), function (inputProps) { inputProps.maskPlaceholder; var restInputProps = __rest(inputProps, ['maskPlaceholder']); return React.createElement( 'input', __assign({}, restInputProps, rest, { ref: handleRef }, baseProps) ); } ); } if (textarea) { return React.createElement( TextareaAutosize, __assign({}, rest, { ref: handleRef }, textareaProps, baseProps) ); } return React.createElement( 'input', __assign({}, rest, { ref: handleRef }, baseProps) ); }; /* -------- * Component Render * -------- */ return React.createElement( Field, { ref: fieldRef, disabled: disabled, required: required, actions: actions, actionsPosition: actionsPosition, contentClassName: contentClassName, hint: hint, hintClassName: hintClassName, icon: icon, iconPosition: iconPosition, label: label, readOnly: readOnly, clearable: clearable, onClear: handleInputClear, appearance: rawRest.appearance, danger: rawRest.danger, info: rawRest.info, primary: rawRest.primary, secondary: rawRest.secondary, success: rawRest.success, warning: rawRest.warning, contentType: 'input', }, renderInputElement() ); }); Input.displayName = 'Input'; export { Input as default };