@trackunit/react-form-components 1.22.26 → 1.22.27
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 +18 -10
- package/index.esm.js +18 -12
- package/package.json +1 -1
- package/src/index.d.ts +2 -0
- package/src/utilities/useCreateInputChangeEvent.d.ts +11 -0
- package/src/utilities/createInputChangeEvent.d.ts +0 -7
package/index.cjs.js
CHANGED
|
@@ -107,12 +107,7 @@ const setupLibraryTranslations = () => {
|
|
|
107
107
|
i18nLibraryTranslation.registerTranslations(translations);
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
* Builds a synthetic change event for an input with a given value.
|
|
112
|
-
* Use when calling onChange from code (e.g. clear, apply, clamped value) so consumers
|
|
113
|
-
* that use `onChange={e => setValue(e.target.value)}` still receive the expected shape.
|
|
114
|
-
*/
|
|
115
|
-
function createInputChangeEvent(value, sourceInput) {
|
|
110
|
+
const createSyntheticInputChangeEvent = (value, sourceInput) => {
|
|
116
111
|
const target = document.createElement("input");
|
|
117
112
|
target.value = value;
|
|
118
113
|
if (sourceInput) {
|
|
@@ -139,7 +134,17 @@ function createInputChangeEvent(value, sourceInput) {
|
|
|
139
134
|
isDefaultPrevented: () => native.defaultPrevented,
|
|
140
135
|
isPropagationStopped: () => false,
|
|
141
136
|
};
|
|
142
|
-
}
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Returns a stable function that builds a synthetic change event for an input with a given value.
|
|
140
|
+
* Use when calling onChange from code (e.g. clear, apply, clamped value) so consumers
|
|
141
|
+
* that use `onChange={e => setValue(e.target.value)}` still receive the expected shape.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* const createInputChangeEvent = useCreateInputChangeEvent();
|
|
145
|
+
* onChange?.(createInputChangeEvent(str, inputRef.current));
|
|
146
|
+
*/
|
|
147
|
+
const useCreateInputChangeEvent = () => react.useCallback((value, sourceInput) => createSyntheticInputChangeEvent(value, sourceInput), []);
|
|
143
148
|
|
|
144
149
|
const cvaInputBase = cssClassVarianceUtilities.cvaMerge([
|
|
145
150
|
"component-baseInput-shadow",
|
|
@@ -708,6 +713,7 @@ const DateBaseInput = ({ min, max, defaultValue, value, ref, onChange, suffix: s
|
|
|
708
713
|
? (dateAndTimeUtils.parseYYYYMMDDUtil(value) ?? undefined)
|
|
709
714
|
: parseToDate(isControlled ? value : internalValue);
|
|
710
715
|
const inputRef = react.useRef(null);
|
|
716
|
+
const createInputChangeEvent = useCreateInputChangeEvent();
|
|
711
717
|
react.useImperativeHandle(ref, () => inputRef.current ?? document.createElement("input"), []);
|
|
712
718
|
const syncPendingFromValue = react.useCallback(() => {
|
|
713
719
|
setPendingDate(selectedDate ?? null);
|
|
@@ -728,7 +734,7 @@ const DateBaseInput = ({ min, max, defaultValue, value, ref, onChange, suffix: s
|
|
|
728
734
|
setInternalValue("");
|
|
729
735
|
onChange?.(createInputChangeEvent("", inputRef.current));
|
|
730
736
|
closePopover();
|
|
731
|
-
}, [isControlled, onChange]);
|
|
737
|
+
}, [createInputChangeEvent, isControlled, onChange]);
|
|
732
738
|
const handleCancel = react.useCallback((closePopover) => {
|
|
733
739
|
closePopover();
|
|
734
740
|
}, []);
|
|
@@ -741,7 +747,7 @@ const DateBaseInput = ({ min, max, defaultValue, value, ref, onChange, suffix: s
|
|
|
741
747
|
setInternalValue(str);
|
|
742
748
|
onChange?.(createInputChangeEvent(str, inputRef.current));
|
|
743
749
|
closePopover();
|
|
744
|
-
}, [isControlled, min, max, onChange, pendingDate, timeZoneId]);
|
|
750
|
+
}, [createInputChangeEvent, isControlled, min, max, onChange, pendingDate, timeZoneId]);
|
|
745
751
|
const handleInputChange = react.useCallback((e) => {
|
|
746
752
|
const raw = e.target.value;
|
|
747
753
|
const parsed = parseDateFieldInputForChange(raw, locale);
|
|
@@ -759,7 +765,7 @@ const DateBaseInput = ({ min, max, defaultValue, value, ref, onChange, suffix: s
|
|
|
759
765
|
setInternalValue(raw);
|
|
760
766
|
onChange?.(e);
|
|
761
767
|
}
|
|
762
|
-
}, [isControlled, locale, min, max, onChange, timeZoneId]);
|
|
768
|
+
}, [createInputChangeEvent, isControlled, locale, min, max, onChange, timeZoneId]);
|
|
763
769
|
return (jsxRuntime.jsxs(reactComponents.Popover, { onOpenStateChange: open => open && syncPendingFromValue(), placement: "bottom-start", children: [jsxRuntime.jsx(reactComponents.PopoverTrigger, { children: jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex w-full min-w-0 cursor-pointer items-center", (Boolean(rest.disabled) || Boolean(rest.readOnly)) && "pointer-events-none"), children: jsxRuntime.jsx(BaseInput, { ...rest, "aria-readonly": true, className: tailwindMerge.twMerge("w-full min-w-0", rest.className), "data-testid": dataTestId ? `${dataTestId}-input` : undefined, onChange: handleInputChange, placeholder: rest.placeholder ?? t("dateField.placeholder"), ref: inputRef, suffix: suffixProp ?? (jsxRuntime.jsx(reactComponents.Icon, { "aria-label": undefined, className: Boolean(rest.disabled) || Boolean(rest.readOnly) ? "text-neutral-500" : undefined, "data-testid": dataTestId ? `${dataTestId}-calendar` : "calendar", name: "Calendar", size: "medium", type: "solid" })), type: "text", value: resolvedValue }) }) }), jsxRuntime.jsx(reactComponents.PopoverContent, { children: closePopover => {
|
|
764
770
|
const displayDate = pendingDate ?? selectedDate ?? null;
|
|
765
771
|
return (jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("flex w-min flex-col overflow-hidden rounded-md border border-neutral-300 bg-white p-0"), children: [jsxRuntime.jsx(ReactCalendar, { allowPartialRange: true, className: tailwindMerge.twMerge("custom-day-picker", "range-picker", "p-0"), defaultActiveStartDate: displayDate ?? undefined, defaultView: "month", locale: locale, onChange: val => {
|
|
@@ -5007,6 +5013,7 @@ exports.PhoneBaseInput = PhoneBaseInput;
|
|
|
5007
5013
|
exports.PhoneField = PhoneField;
|
|
5008
5014
|
exports.PhoneFieldWithController = PhoneFieldWithController;
|
|
5009
5015
|
exports.RadioGroup = RadioGroup;
|
|
5016
|
+
exports.RadioGroupContext = RadioGroupContext;
|
|
5010
5017
|
exports.RadioItem = RadioItem;
|
|
5011
5018
|
exports.Schedule = Schedule;
|
|
5012
5019
|
exports.Search = Search;
|
|
@@ -5065,6 +5072,7 @@ exports.parseSchedule = parseSchedule;
|
|
|
5065
5072
|
exports.phoneErrorMessage = phoneErrorMessage;
|
|
5066
5073
|
exports.serializeSchedule = serializeSchedule;
|
|
5067
5074
|
exports.useCreatableSelect = useCreatableSelect;
|
|
5075
|
+
exports.useCreateInputChangeEvent = useCreateInputChangeEvent;
|
|
5068
5076
|
exports.useCustomComponents = useCustomComponents;
|
|
5069
5077
|
exports.useGetPhoneValidationRules = useGetPhoneValidationRules;
|
|
5070
5078
|
exports.usePhoneInput = usePhoneInput;
|
package/index.esm.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import { registerTranslations, useNamespaceTranslation, NamespaceTrans } from '@trackunit/i18n-library-translation';
|
|
3
3
|
import { parseYYYYMMDDUtil, formatShortDateUtil, parseValidDate, toDateUtil, startOfDayUtil, toZonedDateTimeUtil } from '@trackunit/date-and-time-utils';
|
|
4
4
|
import { IconButton, Icon, Tooltip, Popover, PopoverTrigger, PopoverContent, Button, cvaMenu, cvaMenuList, Tag, useIsTextTruncated, ZStack, MenuItem, useMeasure, useDebounce, useMergeRefs, Spinner, useScrollBlock, Text, Heading, useIsFirstRender } from '@trackunit/react-components';
|
|
5
|
-
import { useRef, useEffect, useImperativeHandle, useState,
|
|
5
|
+
import { useCallback, useRef, useEffect, useImperativeHandle, useState, cloneElement, isValidElement, useLayoutEffect, useMemo, useReducer, createContext, useContext, useId } from 'react';
|
|
6
6
|
import ReactCalendar from 'react-calendar';
|
|
7
7
|
import { twMerge } from 'tailwind-merge';
|
|
8
8
|
import { themeSpacing } from '@trackunit/ui-design-tokens';
|
|
@@ -106,12 +106,7 @@ const setupLibraryTranslations = () => {
|
|
|
106
106
|
registerTranslations(translations);
|
|
107
107
|
};
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
* Builds a synthetic change event for an input with a given value.
|
|
111
|
-
* Use when calling onChange from code (e.g. clear, apply, clamped value) so consumers
|
|
112
|
-
* that use `onChange={e => setValue(e.target.value)}` still receive the expected shape.
|
|
113
|
-
*/
|
|
114
|
-
function createInputChangeEvent(value, sourceInput) {
|
|
109
|
+
const createSyntheticInputChangeEvent = (value, sourceInput) => {
|
|
115
110
|
const target = document.createElement("input");
|
|
116
111
|
target.value = value;
|
|
117
112
|
if (sourceInput) {
|
|
@@ -138,7 +133,17 @@ function createInputChangeEvent(value, sourceInput) {
|
|
|
138
133
|
isDefaultPrevented: () => native.defaultPrevented,
|
|
139
134
|
isPropagationStopped: () => false,
|
|
140
135
|
};
|
|
141
|
-
}
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Returns a stable function that builds a synthetic change event for an input with a given value.
|
|
139
|
+
* Use when calling onChange from code (e.g. clear, apply, clamped value) so consumers
|
|
140
|
+
* that use `onChange={e => setValue(e.target.value)}` still receive the expected shape.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* const createInputChangeEvent = useCreateInputChangeEvent();
|
|
144
|
+
* onChange?.(createInputChangeEvent(str, inputRef.current));
|
|
145
|
+
*/
|
|
146
|
+
const useCreateInputChangeEvent = () => useCallback((value, sourceInput) => createSyntheticInputChangeEvent(value, sourceInput), []);
|
|
142
147
|
|
|
143
148
|
const cvaInputBase = cvaMerge([
|
|
144
149
|
"component-baseInput-shadow",
|
|
@@ -707,6 +712,7 @@ const DateBaseInput = ({ min, max, defaultValue, value, ref, onChange, suffix: s
|
|
|
707
712
|
? (parseYYYYMMDDUtil(value) ?? undefined)
|
|
708
713
|
: parseToDate(isControlled ? value : internalValue);
|
|
709
714
|
const inputRef = useRef(null);
|
|
715
|
+
const createInputChangeEvent = useCreateInputChangeEvent();
|
|
710
716
|
useImperativeHandle(ref, () => inputRef.current ?? document.createElement("input"), []);
|
|
711
717
|
const syncPendingFromValue = useCallback(() => {
|
|
712
718
|
setPendingDate(selectedDate ?? null);
|
|
@@ -727,7 +733,7 @@ const DateBaseInput = ({ min, max, defaultValue, value, ref, onChange, suffix: s
|
|
|
727
733
|
setInternalValue("");
|
|
728
734
|
onChange?.(createInputChangeEvent("", inputRef.current));
|
|
729
735
|
closePopover();
|
|
730
|
-
}, [isControlled, onChange]);
|
|
736
|
+
}, [createInputChangeEvent, isControlled, onChange]);
|
|
731
737
|
const handleCancel = useCallback((closePopover) => {
|
|
732
738
|
closePopover();
|
|
733
739
|
}, []);
|
|
@@ -740,7 +746,7 @@ const DateBaseInput = ({ min, max, defaultValue, value, ref, onChange, suffix: s
|
|
|
740
746
|
setInternalValue(str);
|
|
741
747
|
onChange?.(createInputChangeEvent(str, inputRef.current));
|
|
742
748
|
closePopover();
|
|
743
|
-
}, [isControlled, min, max, onChange, pendingDate, timeZoneId]);
|
|
749
|
+
}, [createInputChangeEvent, isControlled, min, max, onChange, pendingDate, timeZoneId]);
|
|
744
750
|
const handleInputChange = useCallback((e) => {
|
|
745
751
|
const raw = e.target.value;
|
|
746
752
|
const parsed = parseDateFieldInputForChange(raw, locale);
|
|
@@ -758,7 +764,7 @@ const DateBaseInput = ({ min, max, defaultValue, value, ref, onChange, suffix: s
|
|
|
758
764
|
setInternalValue(raw);
|
|
759
765
|
onChange?.(e);
|
|
760
766
|
}
|
|
761
|
-
}, [isControlled, locale, min, max, onChange, timeZoneId]);
|
|
767
|
+
}, [createInputChangeEvent, isControlled, locale, min, max, onChange, timeZoneId]);
|
|
762
768
|
return (jsxs(Popover, { onOpenStateChange: open => open && syncPendingFromValue(), placement: "bottom-start", children: [jsx(PopoverTrigger, { children: jsx("div", { className: twMerge("flex w-full min-w-0 cursor-pointer items-center", (Boolean(rest.disabled) || Boolean(rest.readOnly)) && "pointer-events-none"), children: jsx(BaseInput, { ...rest, "aria-readonly": true, className: twMerge("w-full min-w-0", rest.className), "data-testid": dataTestId ? `${dataTestId}-input` : undefined, onChange: handleInputChange, placeholder: rest.placeholder ?? t("dateField.placeholder"), ref: inputRef, suffix: suffixProp ?? (jsx(Icon, { "aria-label": undefined, className: Boolean(rest.disabled) || Boolean(rest.readOnly) ? "text-neutral-500" : undefined, "data-testid": dataTestId ? `${dataTestId}-calendar` : "calendar", name: "Calendar", size: "medium", type: "solid" })), type: "text", value: resolvedValue }) }) }), jsx(PopoverContent, { children: closePopover => {
|
|
763
769
|
const displayDate = pendingDate ?? selectedDate ?? null;
|
|
764
770
|
return (jsxs("div", { className: twMerge("flex w-min flex-col overflow-hidden rounded-md border border-neutral-300 bg-white p-0"), children: [jsx(ReactCalendar, { allowPartialRange: true, className: twMerge("custom-day-picker", "range-picker", "p-0"), defaultActiveStartDate: displayDate ?? undefined, defaultView: "month", locale: locale, onChange: val => {
|
|
@@ -4977,4 +4983,4 @@ const useZodValidators = () => {
|
|
|
4977
4983
|
*/
|
|
4978
4984
|
setupLibraryTranslations();
|
|
4979
4985
|
|
|
4980
|
-
export { ActionButton, BaseInput, BaseSelect, Checkbox, CheckboxField, ColorField, CreatableSelect, CreatableSelectField, DEFAULT_TIME, DateBaseInput, DateField, DropZone, DropZoneDefaultLabel, EMAIL_REGEX, EmailField, FormFieldSelectAdapter, FormGroup, Label, MultiSelectField, NumberBaseInput, NumberField, OptionCard, PasswordBaseInput, PasswordField, PhoneBaseInput, PhoneField, PhoneFieldWithController, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, SelectField, TextAreaBaseInput, TextAreaField, TextBaseInput, TextField, TimeRange, TimeRangeField, ToggleSwitch, ToggleSwitchOption, UploadField, UploadInput, UrlField, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaAccessoriesContainer, cvaActionButton, cvaActionContainer, cvaInput$1 as cvaInput, cvaInputAddon, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputBaseReadOnly, cvaInputBaseSize, cvaInputElement, cvaInputGroup, cvaInputItemPlacementManager, cvaInputPrefix, cvaInputSuffix, cvaLabel, cvaRadioItem, cvaSelectClearIndicator, cvaSelectContainer, cvaSelectControl, cvaSelectDropdownIconContainer, cvaSelectDropdownIndicator, cvaSelectIndicatorsContainer, cvaSelectLoadingMessage, cvaSelectMenu, cvaSelectMenuList, cvaSelectMultiValue, cvaSelectNoOptionsMessage, cvaSelectPlaceholder, cvaSelectPrefixSuffix, cvaSelectSingleValue, cvaSelectValueContainer, getCountryAbbreviation, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isValidHEXColor, parseSchedule, phoneErrorMessage, serializeSchedule, useCreatableSelect, useCustomComponents, useGetPhoneValidationRules, usePhoneInput, useRadioItemChecked, useSelect, useZodValidators, validateEmailAddress, validatePhoneNumber, weekDay };
|
|
4986
|
+
export { ActionButton, BaseInput, BaseSelect, Checkbox, CheckboxField, ColorField, CreatableSelect, CreatableSelectField, DEFAULT_TIME, DateBaseInput, DateField, DropZone, DropZoneDefaultLabel, EMAIL_REGEX, EmailField, FormFieldSelectAdapter, FormGroup, Label, MultiSelectField, NumberBaseInput, NumberField, OptionCard, PasswordBaseInput, PasswordField, PhoneBaseInput, PhoneField, PhoneFieldWithController, RadioGroup, RadioGroupContext, RadioItem, Schedule, ScheduleVariant, Search, SelectField, TextAreaBaseInput, TextAreaField, TextBaseInput, TextField, TimeRange, TimeRangeField, ToggleSwitch, ToggleSwitchOption, UploadField, UploadInput, UrlField, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaAccessoriesContainer, cvaActionButton, cvaActionContainer, cvaInput$1 as cvaInput, cvaInputAddon, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputBaseReadOnly, cvaInputBaseSize, cvaInputElement, cvaInputGroup, cvaInputItemPlacementManager, cvaInputPrefix, cvaInputSuffix, cvaLabel, cvaRadioItem, cvaSelectClearIndicator, cvaSelectContainer, cvaSelectControl, cvaSelectDropdownIconContainer, cvaSelectDropdownIndicator, cvaSelectIndicatorsContainer, cvaSelectLoadingMessage, cvaSelectMenu, cvaSelectMenuList, cvaSelectMultiValue, cvaSelectNoOptionsMessage, cvaSelectPlaceholder, cvaSelectPrefixSuffix, cvaSelectSingleValue, cvaSelectValueContainer, getCountryAbbreviation, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isValidHEXColor, parseSchedule, phoneErrorMessage, serializeSchedule, useCreatableSelect, useCreateInputChangeEvent, useCustomComponents, useGetPhoneValidationRules, usePhoneInput, useRadioItemChecked, useSelect, useZodValidators, validateEmailAddress, validatePhoneNumber, weekDay };
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export * from "./components/PhoneField/PhoneField";
|
|
|
35
35
|
export * from "./components/PhoneFieldWithController/PhoneFieldWithController";
|
|
36
36
|
export * from "./components/RadioGroup/RadioGroup";
|
|
37
37
|
export * from "./components/RadioGroup/RadioGroup.variants";
|
|
38
|
+
export * from "./components/RadioGroup/RadioGroupContext";
|
|
38
39
|
export * from "./components/RadioGroup/RadioItem";
|
|
39
40
|
export * from "./components/RadioGroup/useRadioItemChecked";
|
|
40
41
|
export * from "./components/Schedule/Schedule";
|
|
@@ -53,6 +54,7 @@ export * from "./components/UploadField/UploadField";
|
|
|
53
54
|
export * from "./components/UploadInput/UploadInput";
|
|
54
55
|
export * from "./components/UrlField/UrlField";
|
|
55
56
|
export * from "./utilities/emailUtils";
|
|
57
|
+
export * from "./utilities/useCreateInputChangeEvent";
|
|
56
58
|
export * from "./utilities/useGetPhoneValidationRules";
|
|
57
59
|
export * from "./utilities/usePhoneInput";
|
|
58
60
|
export * from "./utilities/useZodValidators";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ChangeEvent } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Returns a stable function that builds a synthetic change event for an input with a given value.
|
|
4
|
+
* Use when calling onChange from code (e.g. clear, apply, clamped value) so consumers
|
|
5
|
+
* that use `onChange={e => setValue(e.target.value)}` still receive the expected shape.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const createInputChangeEvent = useCreateInputChangeEvent();
|
|
9
|
+
* onChange?.(createInputChangeEvent(str, inputRef.current));
|
|
10
|
+
*/
|
|
11
|
+
export declare const useCreateInputChangeEvent: () => ((value: string, sourceInput: HTMLInputElement | null) => ChangeEvent<HTMLInputElement>);
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type ChangeEvent } from "react";
|
|
2
|
-
/**
|
|
3
|
-
* Builds a synthetic change event for an input with a given value.
|
|
4
|
-
* Use when calling onChange from code (e.g. clear, apply, clamped value) so consumers
|
|
5
|
-
* that use `onChange={e => setValue(e.target.value)}` still receive the expected shape.
|
|
6
|
-
*/
|
|
7
|
-
export declare function createInputChangeEvent(value: string, sourceInput: HTMLInputElement | null): ChangeEvent<HTMLInputElement>;
|