UNPKG

@fluentui/react-northstar

Version:
284 lines (282 loc) 10.6 kB
import _get from "lodash/get"; import _invoke from "lodash/invoke"; import _isNil from "lodash/isNil"; import { inputBehavior } from '@fluentui/accessibility'; import { handleRef, Ref } from '@fluentui/react-component-ref'; import * as customPropTypes from '@fluentui/react-proptypes'; import * as React from 'react'; import * as PropTypes from 'prop-types'; import { partitionHTMLProps, commonPropTypes, createShorthandFactory, createShorthand, getOrGenerateIdFromShorthand } from '../../utils'; import { Box } from '../Box/Box'; import { useAutoControlled, getElementType, useUnhandledProps, useTelemetry, useFluentContext, useStyles, useAccessibility, compose } from '@fluentui/react-bindings'; import { ExclamationCircleIcon, CheckmarkCircleIcon, CloseIcon } from '@fluentui/react-icons-northstar'; import { InputLabel } from './InputLabel'; import { FormFieldBaseContext } from '../Form/utils/formFieldBaseContext'; export var inputClassName = 'ui-input'; export var inputSlotClassNames = { input: inputClassName + "__input", icon: inputClassName + "__icon" }; /** * An Input is a field used to elicit an input from a user. * * @accessibility * For good screen reader experience set `aria-label` or `aria-labelledby` attribute for input. */ export var Input = /*#__PURE__*/function () { var Input = compose(function (props, ref, composeOptions) { var context = useFluentContext(); var _useTelemetry = useTelemetry(composeOptions.displayName, context.telemetry), setStart = _useTelemetry.setStart, setEnd = _useTelemetry.setEnd; setStart(); var className = props.className, input = props.input, type = props.type, wrapper = props.wrapper, disabled = props.disabled, fluid = props.fluid, inverted = props.inverted, inline = props.inline, clearable = props.clearable, icon = props.icon, iconPosition = props.iconPosition, design = props.design, styles = props.styles, variables = props.variables, required = props.required, successIndicator = props.successIndicator, error = props.error, errorIndicator = props.errorIndicator, showSuccessIndicator = props.showSuccessIndicator, label = props.label, labelPosition = props.labelPosition; var inputRef = React.useRef(); var _React$useContext = React.useContext(FormFieldBaseContext), labelId = _React$useContext.labelId; var inputId = React.useRef(); inputId.current = props.id || getOrGenerateIdFromShorthand('ui-input-', '', inputId.current); var ElementType = getElementType(props); var unhandledProps = useUnhandledProps(composeOptions.handledProps, props); var _partitionHTMLProps = partitionHTMLProps(unhandledProps), htmlInputProps = _partitionHTMLProps[0], restProps = _partitionHTMLProps[1]; var _useAutoControlled = useAutoControlled({ defaultValue: props.defaultValue, value: props.value, initialValue: '' }), value = _useAutoControlled[0], setValue = _useAutoControlled[1]; var hasValue = !!value && (value == null ? void 0 : value.length) !== 0; var isShowSuccessIndicatorUndefined = typeof showSuccessIndicator === 'undefined'; var requiredAndSuccessful = isShowSuccessIndicatorUndefined ? (required && hasValue || showSuccessIndicator) && !error : showSuccessIndicator; var hasIcon = !!icon || showSuccessIndicator || required && isShowSuccessIndicatorUndefined || !_isNil(error); var _useStyles = useStyles(composeOptions.displayName, { className: inputClassName, mapPropsToStyles: function mapPropsToStyles() { return { fluid: fluid, inverted: inverted, inline: inline, disabled: disabled, clearable: clearable, hasIcon: hasIcon, requiredAndSuccessful: requiredAndSuccessful, iconPosition: iconPosition, hasValue: hasValue, labelPosition: labelPosition, error: error }; }, mapPropsToInlineStyles: function mapPropsToInlineStyles() { return { className: className, design: design, styles: styles, variables: variables }; }, rtl: context.rtl, composeOptions: composeOptions, unstable_props: props }), classes = _useStyles.classes, resolvedStyles = _useStyles.styles; var getA11yProps = useAccessibility(props.accessibility, { debugName: composeOptions.displayName, actionHandlers: { clear: function clear(e) { if (clearable && value !== '') { e.stopPropagation(); e.nativeEvent && e.nativeEvent.stopPropagation(); handleOnClear(e); } } }, mapPropsToBehavior: function mapPropsToBehavior() { return { disabled: disabled, required: required, error: error }; }, rtl: context.rtl }); var handleIconOverrides = function handleIconOverrides(predefinedProps) { return { onClick: function onClick(e) { if (!disabled) { handleOnClear(e); inputRef.current.focus(); } _invoke(predefinedProps, 'onClick', e, props); } }; }; var handleChange = function handleChange(e) { if (disabled) { return; } var newValue = _get(e, 'target.value'); _invoke(props, 'onChange', e, Object.assign({}, props, { value: newValue })); setValue(newValue); }; var handleOnClear = function handleOnClear(e) { if (clearable) { _invoke(props, 'onChange', e, Object.assign({}, props, { value: '' })); setValue(''); } }; var computeIcon = function computeIcon() { if (clearable && (value == null ? void 0 : value.length) !== 0) { return /*#__PURE__*/React.createElement(CloseIcon, { outline: true }); } if (requiredAndSuccessful) { return successIndicator; } if (error) { return errorIndicator; } return icon || null; }; var labelElement = createShorthand(composeOptions.slots.label, label, { defaultProps: function defaultProps() { return { labelPosition: labelPosition, label: label, required: required, htmlFor: inputId.current, hasValue: hasValue, id: labelId }; } }); var inputElement = Box.create({}, { defaultProps: function defaultProps() { return { children: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Ref, { innerRef: function innerRef(inputElement) { handleRef(inputRef, inputElement); handleRef(props.inputRef, inputElement); handleRef(ref, inputElement); } }, createShorthand(composeOptions.slots.control, input || type, { defaultProps: function defaultProps() { return getA11yProps('input', Object.assign({}, htmlInputProps, { as: 'input', disabled: disabled, type: type, required: required, value: value || '', id: inputId.current, className: inputSlotClassNames.input, styles: resolvedStyles.input, onChange: handleChange })); } })), createShorthand(composeOptions.slots.icon, computeIcon(), { defaultProps: function defaultProps() { return getA11yProps('icon', { className: inputSlotClassNames.icon, styles: resolvedStyles.icon }); }, overrideProps: handleIconOverrides })), styles: resolvedStyles.inputContainer }; } }); var element = Box.create(wrapper, { defaultProps: function defaultProps() { return getA11yProps('root', Object.assign({ className: classes.root, children: /*#__PURE__*/React.createElement(React.Fragment, null, labelElement, inputElement), styles: resolvedStyles.root }, restProps)); }, overrideProps: { as: wrapper && wrapper.as || ElementType } }); setEnd(); return element; }, { className: inputClassName, displayName: 'Input', slots: { control: Box, icon: Box, label: InputLabel }, handledProps: ['accessibility', 'as', 'children', 'className', 'design', 'styles', 'variables', 'clearable', 'defaultValue', 'disabled', 'fluid', 'icon', 'iconPosition', 'input', 'inputRef', 'inline', 'inverted', 'onChange', 'type', 'value', 'wrapper', 'required', 'successIndicator', 'error', 'errorIndicator', 'showSuccessIndicator', 'label', 'labelPosition'] }); Input.propTypes = Object.assign({}, commonPropTypes.createCommon({ content: false }), { clearable: PropTypes.bool, defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), disabled: PropTypes.bool, fluid: PropTypes.bool, label: customPropTypes.itemShorthand, labelPosition: PropTypes.oneOf(['inline', 'above', 'inside']), icon: customPropTypes.shorthandAllowingChildren, iconPosition: PropTypes.oneOf(['start', 'end']), input: customPropTypes.itemShorthand, inputRef: customPropTypes.ref, inline: PropTypes.bool, inverted: PropTypes.bool, onChange: PropTypes.func, type: PropTypes.string, value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), wrapper: customPropTypes.wrapperShorthand, required: PropTypes.bool, successIndicator: customPropTypes.shorthandAllowingChildren, error: PropTypes.bool, errorIndicator: customPropTypes.shorthandAllowingChildren, showSuccessIndicator: PropTypes.bool }); Input.defaultProps = { accessibility: inputBehavior, type: 'text', wrapper: {}, iconPosition: 'end', errorIndicator: /*#__PURE__*/React.createElement(ExclamationCircleIcon, null), successIndicator: /*#__PURE__*/React.createElement(CheckmarkCircleIcon, { outline: true }) }; Input.Label = InputLabel; Input.create = createShorthandFactory({ Component: Input }); return Input; }(); //# sourceMappingURL=Input.js.map