@trackunit/react-form-components 0.0.262 → 0.0.265

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs.js CHANGED
@@ -695,7 +695,7 @@ const EmailInput = React__namespace.forwardRef((_a, ref) => {
695
695
  return window.open(`mailto:${email}`);
696
696
  };
697
697
  const renderAsInvalid = (email && !validateEmailAddress(email)) || isInvalid;
698
- return (jsxRuntime.jsx(BaseInput, Object.assign({ dataTestId: dataTestId, ref: ref, type: "email", placeholder: rest.placeholder || "mail@example.com", onChange: e => setEmail(e.target.value), isInvalid: renderAsInvalid }, rest, { actions: jsxRuntime.jsx(ActionButton, { disabled: disabled, value: email, type: "EMAIL", onClick: sendEmail, dataTestId: dataTestId && `${dataTestId}-emailIcon`, iconSize: fieldSize }) })));
698
+ return (jsxRuntime.jsx(BaseInput, Object.assign({ dataTestId: dataTestId, ref: ref, type: "email", placeholder: rest.placeholder || "mail@example.com", onChange: e => setEmail(e.target.value), isInvalid: renderAsInvalid, actions: jsxRuntime.jsx(ActionButton, { disabled: disabled, value: email, type: "EMAIL", onClick: sendEmail, dataTestId: dataTestId && `${dataTestId}-emailIcon`, iconSize: fieldSize }) }, rest)));
699
699
  });
700
700
 
701
701
  /**
@@ -773,6 +773,31 @@ const OptionCard = React.forwardRef((_a, ref) => {
773
773
  return (jsxRuntime.jsxs("div", { "data-testid": dataTestId, className: cvaOptionCardContainer(), children: [jsxRuntime.jsx("input", Object.assign({ ref: ref, id: htmlForId, type: "radio", value: value, className: "peer hidden" }, rest)), jsxRuntime.jsxs("label", { htmlFor: htmlForId, className: cvaOptionCardLabel({ className, disabled }), children: [disabled && icon && React.cloneElement(icon, { className: `${icon.props.className} text-secondary-400` }), !disabled && icon, heading && (jsxRuntime.jsx(reactComponents.Heading, { variant: "secondary", subtle: disabled, children: heading })), (subheading || description) && (jsxRuntime.jsxs("div", { className: cvaOptionCardContent(), children: [subheading && (jsxRuntime.jsx(reactComponents.Text, { type: "span", weight: "thick", align: "center", subtle: disabled, children: subheading })), description && (jsxRuntime.jsx(reactComponents.Text, { type: "span", subtle: true, align: "center", children: description }))] }))] })] }));
774
774
  });
775
775
 
776
+ /**
777
+ * A thin wrapper around the `BaseInput` component for password input fields.
778
+ *
779
+ * NOTE: If shown with a label, please use the `PasswordField` component instead.
780
+ */
781
+ const PasswordInput = React.forwardRef((props, ref) => (jsxRuntime.jsx(BaseInput, Object.assign({ ref: ref, type: props.obfuscate ? "text" : "password" }, props))));
782
+
783
+ /**
784
+ * Password fields enter a password or other confidential information. Characters are masked as they are typed.
785
+ *
786
+ * _**Do use** when the user has to input a password or something that needs to be obfuscated_
787
+ *
788
+ * _**Do not use** to confirm user actions, such as deleting. Use a checkbox for such flows._
789
+ */
790
+ const PasswordField = React.forwardRef((_a, ref) => {
791
+ var { id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, dataTestId } = _a, rest = __rest(_a, ["id", "label", "tip", "helpText", "helpAddon", "errorMessage", "isInvalid", "maxLength", "onChange", "className", "value", "dataTestId"]);
792
+ const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
793
+ const htmlFor = id ? id : "passwordField-" + uuid.v4();
794
+ const [showPassword, setShowPassword] = React.useState(false);
795
+ const handleChange = React.useCallback((event) => {
796
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
797
+ }, [onChange]);
798
+ return (jsxRuntime.jsx(FormGroup, { htmlFor: htmlFor, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && errorMessage) || helpText, helpAddon: helpAddon, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsxRuntime.jsx(PasswordInput, Object.assign({}, rest, { obfuscate: showPassword, disabled: rest.readOnly, id: htmlFor, "aria-labelledby": htmlFor + "-label", ref: ref, maxLength: maxLength, value: value, isInvalid: renderAsInvalid, className: className, onChange: handleChange, dataTestId: dataTestId, actions: jsxRuntime.jsx(reactComponents.Icon, { className: "absolute top-0 bottom-0 right-2 h-full content-center", name: showPassword ? "EyeSlash" : "Eye", size: "small", color: "neutral", onClick: () => setShowPassword(prevState => !prevState) }) })) }));
799
+ });
800
+
776
801
  /**
777
802
  * @param phoneNumber - a phone number as a string
778
803
  * @returns {boolean} true if the phone number starts with a plus sign
@@ -2181,6 +2206,8 @@ exports.MultiSelectMenuItem = MultiSelectMenuItem;
2181
2206
  exports.NumberField = NumberField;
2182
2207
  exports.NumberInput = NumberInput;
2183
2208
  exports.OptionCard = OptionCard;
2209
+ exports.PasswordField = PasswordField;
2210
+ exports.PasswordInput = PasswordInput;
2184
2211
  exports.PhoneField = PhoneField;
2185
2212
  exports.PhoneInput = PhoneInput;
2186
2213
  exports.RadioGroup = RadioGroup;
package/index.esm.js CHANGED
@@ -3,7 +3,7 @@ import { useNamespaceTranslation, registerTranslations } from '@trackunit/i18n-l
3
3
  import { IconButton, Icon, Tip, Heading, Text, MenuItem, Tag, Spinner } from '@trackunit/react-components';
4
4
  import { cvaMerge } from '@trackunit/css-class-variance-utilities';
5
5
  import * as React from 'react';
6
- import React__default, { useMemo, forwardRef, useState, cloneElement, useEffect, useRef } from 'react';
6
+ import React__default, { useMemo, forwardRef, useState, cloneElement, useCallback, useEffect, useRef } from 'react';
7
7
  import { v4 } from 'uuid';
8
8
  import { format } from 'date-fns';
9
9
  import parsePhoneNumberFromString, { getCountries, getCountryCallingCode, isValidPhoneNumber, parsePhoneNumberFromString as parsePhoneNumberFromString$1 } from 'libphonenumber-js';
@@ -665,7 +665,7 @@ const EmailInput = React.forwardRef((_a, ref) => {
665
665
  return window.open(`mailto:${email}`);
666
666
  };
667
667
  const renderAsInvalid = (email && !validateEmailAddress(email)) || isInvalid;
668
- return (jsx(BaseInput, Object.assign({ dataTestId: dataTestId, ref: ref, type: "email", placeholder: rest.placeholder || "mail@example.com", onChange: e => setEmail(e.target.value), isInvalid: renderAsInvalid }, rest, { actions: jsx(ActionButton, { disabled: disabled, value: email, type: "EMAIL", onClick: sendEmail, dataTestId: dataTestId && `${dataTestId}-emailIcon`, iconSize: fieldSize }) })));
668
+ return (jsx(BaseInput, Object.assign({ dataTestId: dataTestId, ref: ref, type: "email", placeholder: rest.placeholder || "mail@example.com", onChange: e => setEmail(e.target.value), isInvalid: renderAsInvalid, actions: jsx(ActionButton, { disabled: disabled, value: email, type: "EMAIL", onClick: sendEmail, dataTestId: dataTestId && `${dataTestId}-emailIcon`, iconSize: fieldSize }) }, rest)));
669
669
  });
670
670
 
671
671
  /**
@@ -743,6 +743,31 @@ const OptionCard = forwardRef((_a, ref) => {
743
743
  return (jsxs("div", { "data-testid": dataTestId, className: cvaOptionCardContainer(), children: [jsx("input", Object.assign({ ref: ref, id: htmlForId, type: "radio", value: value, className: "peer hidden" }, rest)), jsxs("label", { htmlFor: htmlForId, className: cvaOptionCardLabel({ className, disabled }), children: [disabled && icon && cloneElement(icon, { className: `${icon.props.className} text-secondary-400` }), !disabled && icon, heading && (jsx(Heading, { variant: "secondary", subtle: disabled, children: heading })), (subheading || description) && (jsxs("div", { className: cvaOptionCardContent(), children: [subheading && (jsx(Text, { type: "span", weight: "thick", align: "center", subtle: disabled, children: subheading })), description && (jsx(Text, { type: "span", subtle: true, align: "center", children: description }))] }))] })] }));
744
744
  });
745
745
 
746
+ /**
747
+ * A thin wrapper around the `BaseInput` component for password input fields.
748
+ *
749
+ * NOTE: If shown with a label, please use the `PasswordField` component instead.
750
+ */
751
+ const PasswordInput = forwardRef((props, ref) => (jsx(BaseInput, Object.assign({ ref: ref, type: props.obfuscate ? "text" : "password" }, props))));
752
+
753
+ /**
754
+ * Password fields enter a password or other confidential information. Characters are masked as they are typed.
755
+ *
756
+ * _**Do use** when the user has to input a password or something that needs to be obfuscated_
757
+ *
758
+ * _**Do not use** to confirm user actions, such as deleting. Use a checkbox for such flows._
759
+ */
760
+ const PasswordField = forwardRef((_a, ref) => {
761
+ var { id, label, tip, helpText, helpAddon, errorMessage, isInvalid, maxLength, onChange, className, value, dataTestId } = _a, rest = __rest(_a, ["id", "label", "tip", "helpText", "helpAddon", "errorMessage", "isInvalid", "maxLength", "onChange", "className", "value", "dataTestId"]);
762
+ const renderAsInvalid = isInvalid === undefined ? Boolean(errorMessage) : isInvalid;
763
+ const htmlFor = id ? id : "passwordField-" + v4();
764
+ const [showPassword, setShowPassword] = useState(false);
765
+ const handleChange = useCallback((event) => {
766
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
767
+ }, [onChange]);
768
+ return (jsx(FormGroup, { htmlFor: htmlFor, label: label, tip: tip, isInvalid: renderAsInvalid, helpText: (renderAsInvalid && errorMessage) || helpText, helpAddon: helpAddon, dataTestId: dataTestId && `${dataTestId}-FormGroup`, children: jsx(PasswordInput, Object.assign({}, rest, { obfuscate: showPassword, disabled: rest.readOnly, id: htmlFor, "aria-labelledby": htmlFor + "-label", ref: ref, maxLength: maxLength, value: value, isInvalid: renderAsInvalid, className: className, onChange: handleChange, dataTestId: dataTestId, actions: jsx(Icon, { className: "absolute top-0 bottom-0 right-2 h-full content-center", name: showPassword ? "EyeSlash" : "Eye", size: "small", color: "neutral", onClick: () => setShowPassword(prevState => !prevState) }) })) }));
769
+ });
770
+
746
771
  /**
747
772
  * @param phoneNumber - a phone number as a string
748
773
  * @returns {boolean} true if the phone number starts with a plus sign
@@ -2132,4 +2157,4 @@ const UploadField = forwardRef((_a, ref) => {
2132
2157
  */
2133
2158
  setupLibraryTranslations();
2134
2159
 
2135
- export { ActionButton, BaseInput, Checkbox, CreatableSelect, DateField, DateInput, DropZone, EmailField, EmailInput, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PhoneField, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, Toggle, UploadField, UploadInput, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaInput, cvaInputAddon, cvaInputAddonAfter, cvaInputAddonBefore, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputPrefix, cvaInputSuffix, cvaSelect, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefix, cvaSelectXIcon, getCountryAbbreviation, getOrderedOptions, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isMultiValue, parseSchedule, serializeSchedule, useCustomComponents, usePhoneInput, validateEmailAddress, validatePhoneNumber, weekDay };
2160
+ export { ActionButton, BaseInput, Checkbox, CreatableSelect, DateField, DateInput, DropZone, EmailField, EmailInput, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PasswordField, PasswordInput, PhoneField, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, Toggle, UploadField, UploadInput, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaInput, cvaInputAddon, cvaInputAddonAfter, cvaInputAddonBefore, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputPrefix, cvaInputSuffix, cvaSelect, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefix, cvaSelectXIcon, getCountryAbbreviation, getOrderedOptions, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isMultiValue, parseSchedule, serializeSchedule, useCustomComponents, usePhoneInput, validateEmailAddress, validatePhoneNumber, weekDay };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-form-components",
3
- "version": "0.0.262",
3
+ "version": "0.0.265",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -0,0 +1,19 @@
1
+ /// <reference types="react" />
2
+ import { FormGroupProps } from "../FormGroup/FormGroup";
3
+ import { PasswordInputProps } from "../PasswordInput/PasswordInput";
4
+ type FormGroupExposedProps = Pick<FormGroupProps, "label" | "tip" | "helpText" | "helpAddon">;
5
+ export interface PasswordFieldProps extends Omit<PasswordInputProps, "obfuscate" | "actions">, FormGroupExposedProps {
6
+ /**
7
+ * If a value is set, the field is rendered in its invalid state.
8
+ */
9
+ errorMessage?: string;
10
+ }
11
+ /**
12
+ * Password fields enter a password or other confidential information. Characters are masked as they are typed.
13
+ *
14
+ * _**Do use** when the user has to input a password or something that needs to be obfuscated_
15
+ *
16
+ * _**Do not use** to confirm user actions, such as deleting. Use a checkbox for such flows._
17
+ */
18
+ export declare const PasswordField: import("react").ForwardRefExoticComponent<PasswordFieldProps & import("react").RefAttributes<HTMLInputElement>>;
19
+ export {};
@@ -0,0 +1 @@
1
+ export * from "./PasswordField";
@@ -0,0 +1,16 @@
1
+ /// <reference types="react" />
2
+ import { BaseInputProps } from "../BaseInput/BaseInput";
3
+ type BaseInputExposedProps = Omit<BaseInputProps, "type">;
4
+ export interface PasswordInputProps extends BaseInputExposedProps {
5
+ /**
6
+ * If false the field will show password as plain text.
7
+ */
8
+ obfuscate?: boolean;
9
+ }
10
+ /**
11
+ * A thin wrapper around the `BaseInput` component for password input fields.
12
+ *
13
+ * NOTE: If shown with a label, please use the `PasswordField` component instead.
14
+ */
15
+ export declare const PasswordInput: import("react").ForwardRefExoticComponent<PasswordInputProps & import("react").RefAttributes<HTMLInputElement>>;
16
+ export {};
@@ -42,6 +42,11 @@ export interface PhoneInputProps extends BaseInputExposedProps {
42
42
  */
43
43
  onChangeValue?: ({ phone, national, countryCode }: PhoneNumberValue) => void;
44
44
  isCountryCodeClearable?: boolean;
45
+ /**
46
+ * A ReactNode to render at the end of the input field before the addonAfter.
47
+ * Mainly meant for the icon button actions for special input types.
48
+ */
49
+ actions?: React.ReactNode;
45
50
  }
46
51
  /**
47
52
  * A component for inputting phone numbers with an optional action button for initiating a phone call.
package/src/index.d.ts CHANGED
@@ -11,6 +11,8 @@ export * from "./components/Label/Label";
11
11
  export * from "./components/NumberField/NumberField";
12
12
  export * from "./components/NumberInput/NumberInput";
13
13
  export * from "./components/OptionCard/OptionCard";
14
+ export * from "./components/PasswordField";
15
+ export * from "./components/PasswordInput/PasswordInput";
14
16
  export * from "./components/PhoneField/PhoneField";
15
17
  export * from "./components/PhoneInput/PhoneInput";
16
18
  export * from "./components/PhoneInput/PhoneInputValidationUtils";