@servicetitan/form 16.1.0 → 17.1.1
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/color-picker/color-palette.js +1 -1
- package/dist/color-picker/color-palette.js.map +1 -1
- package/dist/color-picker/color-picker.js +5 -5
- package/dist/color-picker/color-picker.js.map +1 -1
- package/dist/date-range-picker/date-range-picker.js +5 -5
- package/dist/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/date-range-picker/date-range-picker.module.css +2 -2
- package/dist/demo/color-picker.js +5 -5
- package/dist/demo/color-picker.js.map +1 -1
- package/dist/demo/date-range-picker.js +3 -3
- package/dist/demo/date-range-picker.js.map +1 -1
- package/dist/demo/dropdown-state.js +7 -7
- package/dist/demo/dropdown-state.js.map +1 -1
- package/dist/demo/file-uploader.js +4 -4
- package/dist/demo/file-uploader.js.map +1 -1
- package/dist/demo/input-date-mask.js +3 -3
- package/dist/demo/input-date-mask.js.map +1 -1
- package/dist/demo/number-input.js +3 -3
- package/dist/demo/number-input.js.map +1 -1
- package/dist/demo/original-number-input.js +3 -3
- package/dist/demo/original-number-input.js.map +1 -1
- package/dist/demo/phone-number-input.js +1 -1
- package/dist/demo/phone-number-input.js.map +1 -1
- package/dist/dropdown-state.d.ts.map +1 -1
- package/dist/dropdown-state.js +6 -5
- package/dist/dropdown-state.js.map +1 -1
- package/dist/file-uploader/config.js +2 -2
- package/dist/file-uploader/config.js.map +1 -1
- package/dist/file-uploader/file-uploader.js +6 -6
- package/dist/file-uploader/file-uploader.js.map +1 -1
- package/dist/file-uploader/uploader.js +1 -1
- package/dist/file-uploader/uploader.js.map +1 -1
- package/dist/form-helpers.js +9 -9
- package/dist/form-helpers.js.map +1 -1
- package/dist/form-state-error-banner/form-state-error-banner.js +4 -4
- package/dist/form-state-error-banner/form-state-error-banner.js.map +1 -1
- package/dist/form-validators.js +1 -1
- package/dist/form-validators.js.map +1 -1
- package/dist/input-date-mask/input-date-mask.js +10 -10
- package/dist/input-date-mask/input-date-mask.js.map +1 -1
- package/dist/label/label.js +1 -1
- package/dist/label/label.js.map +1 -1
- package/dist/masked-input.js +1 -1
- package/dist/masked-input.js.map +1 -1
- package/dist/number-input/number-input.d.ts.map +1 -1
- package/dist/number-input/number-input.js +58 -12
- package/dist/number-input/number-input.js.map +1 -1
- package/dist/original-number-input/ordinal-number-input.js +2 -2
- package/dist/original-number-input/ordinal-number-input.js.map +1 -1
- package/dist/persistent-form-state/persistent-form-state.js +3 -3
- package/dist/persistent-form-state/persistent-form-state.js.map +1 -1
- package/dist/phone-number-input/phone-number-input.d.ts +1 -1
- package/dist/phone-number-input/phone-number-input.d.ts.map +1 -1
- package/dist/phone-number-input/phone-number-input.js +2 -2
- package/dist/phone-number-input/phone-number-input.js.map +1 -1
- package/package.json +11 -11
- package/src/date-range-picker/date-range-picker.module.css +2 -2
- package/src/dropdown-state.ts +3 -1
- package/src/number-input/number-input.tsx +69 -6
@@ -3,5 +3,5 @@ import { FormInputProps } from '@servicetitan/design-system';
|
|
3
3
|
export interface PhoneNumberInputProps extends FormInputProps {
|
4
4
|
sip?: boolean;
|
5
5
|
}
|
6
|
-
export declare const PhoneNumberInput: import("react").ForwardRefExoticComponent<Pick<PhoneNumberInputProps,
|
6
|
+
export declare const PhoneNumberInput: import("react").ForwardRefExoticComponent<Pick<PhoneNumberInputProps, keyof PhoneNumberInputProps> & import("react").RefAttributes<HTMLInputElement>>;
|
7
7
|
//# sourceMappingURL=phone-number-input.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"phone-number-input.d.ts","sourceRoot":"","sources":["../../src/phone-number-input/phone-number-input.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAQ,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAEnE,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IACzD,GAAG,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,eAAO,MAAM,gBAAgB,
|
1
|
+
{"version":3,"file":"phone-number-input.d.ts","sourceRoot":"","sources":["../../src/phone-number-input/phone-number-input.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAQ,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAEnE,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IACzD,GAAG,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,eAAO,MAAM,gBAAgB,uJAS5B,CAAC"}
|
@@ -19,8 +19,8 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
19
19
|
const react_1 = require("react");
|
20
20
|
const react_input_mask_1 = __importDefault(require("react-input-mask"));
|
21
21
|
const design_system_1 = require("@servicetitan/design-system");
|
22
|
-
exports.PhoneNumberInput = react_1.forwardRef((_a, ref) => {
|
22
|
+
exports.PhoneNumberInput = (0, react_1.forwardRef)((_a, ref) => {
|
23
23
|
var { sip } = _a, props = __rest(_a, ["sip"]);
|
24
|
-
return sip ? (jsx_runtime_1.jsx(design_system_1.Form.Input, Object.assign({}, props, { ref: ref }), void 0)) : (jsx_runtime_1.jsx(react_input_mask_1.default, Object.assign({ maskChar: null, mask: "(999) 999-9999" }, props, { children: () => jsx_runtime_1.jsx(design_system_1.Form.Input, Object.assign({ ref: ref }, props), void 0) }), void 0));
|
24
|
+
return sip ? ((0, jsx_runtime_1.jsx)(design_system_1.Form.Input, Object.assign({}, props, { ref: ref }), void 0)) : ((0, jsx_runtime_1.jsx)(react_input_mask_1.default, Object.assign({ maskChar: null, mask: "(999) 999-9999" }, props, { children: () => (0, jsx_runtime_1.jsx)(design_system_1.Form.Input, Object.assign({ ref: ref }, props), void 0) }), void 0));
|
25
25
|
});
|
26
26
|
//# sourceMappingURL=phone-number-input.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"phone-number-input.js","sourceRoot":"","sources":["../../src/phone-number-input/phone-number-input.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,iCAAmC;AACnC,wEAAyC;AAEzC,+DAAmE;AAMtD,QAAA,gBAAgB,GAAG,kBAAU,
|
1
|
+
{"version":3,"file":"phone-number-input.js","sourceRoot":"","sources":["../../src/phone-number-input/phone-number-input.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,iCAAmC;AACnC,wEAAyC;AAEzC,+DAAmE;AAMtD,QAAA,gBAAgB,GAAG,IAAA,kBAAU,EACtC,CAAC,EAAiB,EAAE,GAAG,EAAE,EAAE;QAA1B,EAAE,GAAG,OAAY,EAAP,KAAK,cAAf,OAAiB,CAAF;IACZ,OAAA,GAAG,CAAC,CAAC,CAAC,CACF,uBAAC,oBAAI,CAAC,KAAK,oBAAK,KAAK,IAAE,GAAG,EAAE,GAAG,YAAI,CACtC,CAAC,CAAC,CAAC,CACA,uBAAC,0BAAS,kBAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAC,gBAAgB,IAAK,KAAK,cACrD,GAAG,EAAE,CAAC,uBAAC,oBAAI,CAAC,KAAK,kBAAC,GAAG,EAAE,GAAG,IAAM,KAAK,UAAI,YAClC,CACf,CAAA;CAAA,CACR,CAAC"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@servicetitan/form",
|
3
|
-
"version": "
|
3
|
+
"version": "17.1.1",
|
4
4
|
"description": "",
|
5
5
|
"homepage": "https://docs.st.dev/docs/frontend/form",
|
6
6
|
"repository": {
|
@@ -15,14 +15,14 @@
|
|
15
15
|
"src"
|
16
16
|
],
|
17
17
|
"devDependencies": {
|
18
|
-
"@servicetitan/confirm": "^
|
19
|
-
"@servicetitan/culture": "^
|
20
|
-
"@servicetitan/data-query": "^
|
21
|
-
"@servicetitan/design-system": "~10.
|
22
|
-
"@servicetitan/react-ioc": "^
|
23
|
-
"@servicetitan/tokens": "~10.
|
18
|
+
"@servicetitan/confirm": "^17.1.1",
|
19
|
+
"@servicetitan/culture": "^17.1.1",
|
20
|
+
"@servicetitan/data-query": "^17.1.1",
|
21
|
+
"@servicetitan/design-system": "~10.3.3",
|
22
|
+
"@servicetitan/react-ioc": "^17.1.1",
|
23
|
+
"@servicetitan/tokens": "~10.3.3",
|
24
24
|
"@types/debounce": "~1.2.1",
|
25
|
-
"@types/react": "~17.0.
|
25
|
+
"@types/react": "~17.0.27",
|
26
26
|
"@types/react-input-mask": "~2.0.5",
|
27
27
|
"@types/uuid": "~8.3.1",
|
28
28
|
"accounting": "~0.4.1",
|
@@ -38,9 +38,9 @@
|
|
38
38
|
"@servicetitan/confirm": "^14.0.0",
|
39
39
|
"@servicetitan/culture": "^14.0.0",
|
40
40
|
"@servicetitan/data-query": "^14.0.0",
|
41
|
-
"@servicetitan/design-system": "~10.
|
41
|
+
"@servicetitan/design-system": "~10.3.3",
|
42
42
|
"@servicetitan/react-ioc": "^14.0.0",
|
43
|
-
"@servicetitan/tokens": "~10.
|
43
|
+
"@servicetitan/tokens": "~10.3.3",
|
44
44
|
"accounting": "~0.4.1",
|
45
45
|
"formstate": "~2.0.0",
|
46
46
|
"mobx": "~6.3.3",
|
@@ -65,5 +65,5 @@
|
|
65
65
|
"cli": {
|
66
66
|
"webpack": false
|
67
67
|
},
|
68
|
-
"gitHead": "
|
68
|
+
"gitHead": "01f27439e67c569dd6534738dfba79d6dbbb41a5"
|
69
69
|
}
|
@@ -10,7 +10,7 @@
|
|
10
10
|
overflow: hidden;
|
11
11
|
}
|
12
12
|
.date-range-picker .date-range-picker-kendo :global(.k-textbox-container) {
|
13
|
-
padding-top: 0;
|
13
|
+
padding-top: var(--spacing-0);
|
14
14
|
height: var(--spacing-4);
|
15
15
|
}
|
16
16
|
|
@@ -30,7 +30,7 @@
|
|
30
30
|
}
|
31
31
|
|
32
32
|
.end-label {
|
33
|
-
margin: 0 var(--spacing-half);
|
33
|
+
margin: var(--spacing-0) var(--spacing-half);
|
34
34
|
color: var(--color-neutral-80);
|
35
35
|
font-size: var(--typescale-4);
|
36
36
|
width: var(--spacing-3);
|
package/src/dropdown-state.ts
CHANGED
@@ -84,7 +84,9 @@ export class DropdownState<T extends DropdownOption<any>> {
|
|
84
84
|
}
|
85
85
|
|
86
86
|
@computed private get searchFilter() {
|
87
|
-
if (!this.search)
|
87
|
+
if (!this.search) {
|
88
|
+
return undefined;
|
89
|
+
}
|
88
90
|
|
89
91
|
const filter = { operator: 'contains', value: this.search, ignoreCase: true };
|
90
92
|
|
@@ -1,4 +1,12 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
useCallback,
|
3
|
+
useState,
|
4
|
+
useEffect,
|
5
|
+
useRef,
|
6
|
+
SyntheticEvent,
|
7
|
+
KeyboardEvent,
|
8
|
+
FocusEvent,
|
9
|
+
} from 'react';
|
2
10
|
|
3
11
|
import { useOptionalDependencies } from '@servicetitan/react-ioc';
|
4
12
|
|
@@ -10,8 +18,11 @@ import { FormatNumber, getFormattedString } from './get-formatted-string';
|
|
10
18
|
import { EmptyValue, NumberValue } from './common-interfaces';
|
11
19
|
import { formatNumber as formatNumberDefault } from 'accounting';
|
12
20
|
|
21
|
+
import debounce from 'debounce';
|
22
|
+
|
13
23
|
const ARROW_UP_KEY = 38;
|
14
24
|
const ARROW_DOWN_KEY = 40;
|
25
|
+
const DEBOUNCE_WAIT = 300;
|
15
26
|
|
16
27
|
export interface NumberInputProps<TEmpty extends EmptyValue>
|
17
28
|
extends Omit<InputProps, 'value' | 'onChange'> {
|
@@ -104,7 +115,13 @@ export const NumberInput = <TEmpty extends EmptyValue>({
|
|
104
115
|
}
|
105
116
|
};
|
106
117
|
|
107
|
-
|
118
|
+
/*
|
119
|
+
** "updateImmediateValue" updates the value immediately without clamping min/max,
|
120
|
+
** then "updateClampedValueDebounced" updates applying the min/max after debounce delay
|
121
|
+
**
|
122
|
+
** Example: User can type "100" if min is "5" without the "1" immediately being clamped
|
123
|
+
*/
|
124
|
+
const updateImmediateValue = (value: string, silent = false) => {
|
108
125
|
const newState = processValue(
|
109
126
|
value,
|
110
127
|
{
|
@@ -114,10 +131,6 @@ export const NumberInput = <TEmpty extends EmptyValue>({
|
|
114
131
|
thousand: thousandsSeparator,
|
115
132
|
decimal: decimalSeparator,
|
116
133
|
},
|
117
|
-
range: {
|
118
|
-
min,
|
119
|
-
max,
|
120
|
-
},
|
121
134
|
},
|
122
135
|
formatNumber
|
123
136
|
);
|
@@ -129,6 +142,56 @@ export const NumberInput = <TEmpty extends EmptyValue>({
|
|
129
142
|
}
|
130
143
|
};
|
131
144
|
|
145
|
+
const updateClampedValueDebounced = useRef<(value: string, silent: boolean) => void>();
|
146
|
+
|
147
|
+
useEffect(() => {
|
148
|
+
let isCurrent = true;
|
149
|
+
|
150
|
+
const updateClampedValue = (value: string, silent = false) => {
|
151
|
+
if (isCurrent) {
|
152
|
+
const newState = processValue(
|
153
|
+
value,
|
154
|
+
{
|
155
|
+
emptyValue,
|
156
|
+
precision: decimalPlaces,
|
157
|
+
separators: {
|
158
|
+
thousand: thousandsSeparator,
|
159
|
+
decimal: decimalSeparator,
|
160
|
+
},
|
161
|
+
range: { min, max },
|
162
|
+
},
|
163
|
+
formatNumber
|
164
|
+
);
|
165
|
+
|
166
|
+
setState(newState);
|
167
|
+
|
168
|
+
if (!silent) {
|
169
|
+
onChange(newState.numberValue);
|
170
|
+
}
|
171
|
+
}
|
172
|
+
};
|
173
|
+
|
174
|
+
updateClampedValueDebounced.current = debounce(updateClampedValue, DEBOUNCE_WAIT);
|
175
|
+
|
176
|
+
return () => {
|
177
|
+
isCurrent = false;
|
178
|
+
};
|
179
|
+
}, [
|
180
|
+
emptyValue,
|
181
|
+
decimalPlaces,
|
182
|
+
thousandsSeparator,
|
183
|
+
decimalSeparator,
|
184
|
+
min,
|
185
|
+
max,
|
186
|
+
formatNumber,
|
187
|
+
onChange,
|
188
|
+
]);
|
189
|
+
|
190
|
+
const updateValue = (value: string, silent = false) => {
|
191
|
+
updateImmediateValue(value, silent);
|
192
|
+
updateClampedValueDebounced.current?.(value, silent);
|
193
|
+
};
|
194
|
+
|
132
195
|
const handleFocus = (event: FocusEvent<HTMLInputElement>) => {
|
133
196
|
if (state.numberValue !== undefined) {
|
134
197
|
updateValue(String(state.numberValue), true);
|