UNPKG

@carbon/react

Version:

React components for the Carbon Design System

210 lines (208 loc) 9.6 kB
/** * Copyright IBM Corp. 2016, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ const require_runtime = require("../../_virtual/_rolldown/runtime.js"); const require_usePrefix = require("../../internal/usePrefix.js"); const require_deprecate = require("../../prop-types/deprecate.js"); const require_Tooltip = require("../Tooltip/Tooltip.js"); const require_useNormalizedInputProps = require("../../internal/useNormalizedInputProps.js"); const require_FormContext = require("../FluidForm/FormContext.js"); const require_util = require("./util.js"); let classnames = require("classnames"); classnames = require_runtime.__toESM(classnames); let react = require("react"); react = require_runtime.__toESM(react); let prop_types = require("prop-types"); prop_types = require_runtime.__toESM(prop_types); let react_jsx_runtime = require("react/jsx-runtime"); let _carbon_icons_react = require("@carbon/icons-react"); //#region src/components/TextInput/PasswordInput.tsx /** * Copyright IBM Corp. 2023, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ const PasswordInput = (0, react.forwardRef)(({ className, disabled = false, helperText, hideLabel, hidePasswordLabel = "Hide password", id, inline, invalid = false, invalidText, labelText, light, onChange = () => {}, onClick = () => {}, onTogglePasswordVisibility, placeholder, readOnly, size = "md", showPasswordLabel = "Show password", tooltipPosition = "bottom", tooltipAlignment = "end", type = "password", warn = false, warnText, ...rest }, ref) => { const [inputType, setInputType] = (0, react.useState)(type); const prefix = require_usePrefix.usePrefix(); const normalizedProps = require_useNormalizedInputProps.useNormalizedInputProps({ id, invalid, invalidText, warn, warnText, readOnly, disabled }); const { isFluid } = (0, react.useContext)(require_FormContext.FormContext); const handleTogglePasswordVisibility = (event) => { setInputType(inputType === "password" ? "text" : "password"); onTogglePasswordVisibility?.(event); }; const sharedTextInputProps = { id, onChange: (evt) => { if (!disabled) onChange(evt); }, onClick: (evt) => { if (!disabled) onClick(evt); }, placeholder, type: inputType, className: (0, classnames.default)(`${prefix}--text-input`, `${prefix}--password-input`, className, { [`${prefix}--text-input--light`]: light, [`${prefix}--text-input--invalid`]: normalizedProps.invalid, [`${prefix}--text-input--warning`]: normalizedProps.warn, [`${prefix}--text-input--${size}`]: size, [`${prefix}--layout--size-${size}`]: size }), readOnly, ref, ...rest }; const inputWrapperClasses = (0, classnames.default)(`${prefix}--form-item`, `${prefix}--text-input-wrapper`, `${prefix}--password-input-wrapper`, { [`${prefix}--text-input-wrapper--readonly`]: readOnly, [`${prefix}--text-input-wrapper--light`]: light, [`${prefix}--text-input-wrapper--inline`]: inline, [`${prefix}--text-input--fluid`]: isFluid }); const labelClasses = (0, classnames.default)(`${prefix}--label`, { [`${prefix}--visually-hidden`]: hideLabel, [`${prefix}--label--disabled`]: disabled, [`${prefix}--label--inline`]: inline, [`${prefix}--label--inline--${size}`]: inline && !!size }); const helperTextClasses = (0, classnames.default)(`${prefix}--form__helper-text`, { [`${prefix}--form__helper-text--disabled`]: disabled, [`${prefix}--form__helper-text--inline`]: inline }); const fieldOuterWrapperClasses = (0, classnames.default)(`${prefix}--text-input__field-outer-wrapper`, { [`${prefix}--text-input__field-outer-wrapper--inline`]: inline }); const fieldWrapperClasses = (0, classnames.default)(`${prefix}--text-input__field-wrapper`, { [`${prefix}--text-input__field-wrapper--warning`]: normalizedProps.warn }); const iconClasses = (0, classnames.default)({ [`${prefix}--text-input__invalid-icon`]: normalizedProps.invalid || normalizedProps.warn, [`${prefix}--text-input__invalid-icon--warning`]: normalizedProps.warn }); const label = typeof labelText !== "undefined" && labelText !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", { htmlFor: id, className: labelClasses, children: labelText }); const helper = typeof helperText !== "undefined" && helperText !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { id: normalizedProps.helperId, className: helperTextClasses, children: helperText }); const passwordIsVisible = inputType === "text"; const passwordVisibilityIcon = passwordIsVisible ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_carbon_icons_react.ViewOff, { className: `${prefix}--icon-visibility-off` }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_carbon_icons_react.View, { className: `${prefix}--icon-visibility-on` }); const passwordVisibilityToggleClasses = (0, classnames.default)(`${prefix}--text-input--password__visibility__toggle`, `${prefix}--btn`, `${prefix}--tooltip__trigger`, `${prefix}--tooltip--a11y`, { [`${prefix}--tooltip--${tooltipPosition}`]: tooltipPosition, [`${prefix}--tooltip--align-${tooltipAlignment}`]: tooltipAlignment }); const tooltipClasses = (0, classnames.default)(`${prefix}--toggle-password-tooltip`, `${prefix}--icon-tooltip`); let align = void 0; if (tooltipPosition === "top" || tooltipPosition === "bottom") { if (tooltipAlignment === "center") align = tooltipPosition; if (tooltipAlignment === "end") align = `${tooltipPosition}-end`; if (tooltipAlignment === "start") align = `${tooltipPosition}-start`; } if (tooltipPosition === "right" || tooltipPosition === "left") align = tooltipPosition; if (!hidePasswordLabel || hidePasswordLabel.trim() === "") console.warn("Warning: The \"hidePasswordLabel\" should not be blank."); else if (!showPasswordLabel || showPasswordLabel.trim() === "") console.warn("Warning: The \"showPasswordLabel\" should not be blank."); const input = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", { ...require_util.getTextInputProps({ sharedTextInputProps, invalid: normalizedProps.invalid, invalidId: normalizedProps.invalidId, warn: normalizedProps.warn, warnId: normalizedProps.warnId, hasHelper: Boolean(helperText && !isFluid && (inline || !inline && !normalizedProps.validation)), helperId: normalizedProps.helperId }), disabled, "data-toggle-password-visibility": inputType === "password" }), isFluid && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("hr", { className: `${prefix}--text-input__divider` }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Tooltip.Tooltip, { align, className: tooltipClasses, label: passwordIsVisible ? hidePasswordLabel : showPasswordLabel, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", { type: "button", className: passwordVisibilityToggleClasses, disabled, onClick: handleTogglePasswordVisibility, children: passwordVisibilityIcon }) }) ] }); (0, react.useEffect)(() => { setInputType(type); }, [type]); const Icon = normalizedProps.icon; return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { className: inputWrapperClasses, children: [!inline ? label : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { className: `${prefix}--text-input__label-helper-wrapper`, children: [label, !isFluid && helper] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { className: fieldOuterWrapperClasses, children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { className: fieldWrapperClasses, "data-invalid": normalizedProps.invalid || null, children: [ Icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: iconClasses }), input, isFluid && !inline && normalizedProps.validation ] }), !isFluid && !inline && (normalizedProps.validation || helper)] })] }); }); PasswordInput.displayName = "PasswordInput"; PasswordInput.propTypes = { className: prop_types.default.string, defaultValue: prop_types.default.oneOfType([prop_types.default.string, prop_types.default.number]), disabled: prop_types.default.bool, helperText: prop_types.default.node, hideLabel: prop_types.default.bool, hidePasswordLabel: prop_types.default.string, id: prop_types.default.string.isRequired, inline: prop_types.default.bool, invalid: prop_types.default.bool, readOnly: prop_types.default.bool, invalidText: prop_types.default.node, labelText: prop_types.default.node.isRequired, light: require_deprecate.deprecate(prop_types.default.bool, "The `light` prop for `PasswordInput` has been deprecated in favor of the new `Layer` component. It will be removed in the next major release."), onChange: prop_types.default.func, onClick: prop_types.default.func, onTogglePasswordVisibility: prop_types.default.func, placeholder: prop_types.default.string, showPasswordLabel: prop_types.default.string, size: prop_types.default.oneOf([ "sm", "md", "lg" ]), tooltipAlignment: prop_types.default.oneOf([ "start", "center", "end" ]), tooltipPosition: prop_types.default.oneOf([ "top", "right", "bottom", "left" ]), type: prop_types.default.oneOf(["password", "text"]), value: prop_types.default.oneOfType([prop_types.default.string, prop_types.default.number]), warn: prop_types.default.bool, warnText: prop_types.default.node }; //#endregion exports.default = PasswordInput;