@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.
Files changed (59) hide show
  1. package/dist/color-picker/color-palette.js +1 -1
  2. package/dist/color-picker/color-palette.js.map +1 -1
  3. package/dist/color-picker/color-picker.js +5 -5
  4. package/dist/color-picker/color-picker.js.map +1 -1
  5. package/dist/date-range-picker/date-range-picker.js +5 -5
  6. package/dist/date-range-picker/date-range-picker.js.map +1 -1
  7. package/dist/date-range-picker/date-range-picker.module.css +2 -2
  8. package/dist/demo/color-picker.js +5 -5
  9. package/dist/demo/color-picker.js.map +1 -1
  10. package/dist/demo/date-range-picker.js +3 -3
  11. package/dist/demo/date-range-picker.js.map +1 -1
  12. package/dist/demo/dropdown-state.js +7 -7
  13. package/dist/demo/dropdown-state.js.map +1 -1
  14. package/dist/demo/file-uploader.js +4 -4
  15. package/dist/demo/file-uploader.js.map +1 -1
  16. package/dist/demo/input-date-mask.js +3 -3
  17. package/dist/demo/input-date-mask.js.map +1 -1
  18. package/dist/demo/number-input.js +3 -3
  19. package/dist/demo/number-input.js.map +1 -1
  20. package/dist/demo/original-number-input.js +3 -3
  21. package/dist/demo/original-number-input.js.map +1 -1
  22. package/dist/demo/phone-number-input.js +1 -1
  23. package/dist/demo/phone-number-input.js.map +1 -1
  24. package/dist/dropdown-state.d.ts.map +1 -1
  25. package/dist/dropdown-state.js +6 -5
  26. package/dist/dropdown-state.js.map +1 -1
  27. package/dist/file-uploader/config.js +2 -2
  28. package/dist/file-uploader/config.js.map +1 -1
  29. package/dist/file-uploader/file-uploader.js +6 -6
  30. package/dist/file-uploader/file-uploader.js.map +1 -1
  31. package/dist/file-uploader/uploader.js +1 -1
  32. package/dist/file-uploader/uploader.js.map +1 -1
  33. package/dist/form-helpers.js +9 -9
  34. package/dist/form-helpers.js.map +1 -1
  35. package/dist/form-state-error-banner/form-state-error-banner.js +4 -4
  36. package/dist/form-state-error-banner/form-state-error-banner.js.map +1 -1
  37. package/dist/form-validators.js +1 -1
  38. package/dist/form-validators.js.map +1 -1
  39. package/dist/input-date-mask/input-date-mask.js +10 -10
  40. package/dist/input-date-mask/input-date-mask.js.map +1 -1
  41. package/dist/label/label.js +1 -1
  42. package/dist/label/label.js.map +1 -1
  43. package/dist/masked-input.js +1 -1
  44. package/dist/masked-input.js.map +1 -1
  45. package/dist/number-input/number-input.d.ts.map +1 -1
  46. package/dist/number-input/number-input.js +58 -12
  47. package/dist/number-input/number-input.js.map +1 -1
  48. package/dist/original-number-input/ordinal-number-input.js +2 -2
  49. package/dist/original-number-input/ordinal-number-input.js.map +1 -1
  50. package/dist/persistent-form-state/persistent-form-state.js +3 -3
  51. package/dist/persistent-form-state/persistent-form-state.js.map +1 -1
  52. package/dist/phone-number-input/phone-number-input.d.ts +1 -1
  53. package/dist/phone-number-input/phone-number-input.d.ts.map +1 -1
  54. package/dist/phone-number-input/phone-number-input.js +2 -2
  55. package/dist/phone-number-input/phone-number-input.js.map +1 -1
  56. package/package.json +11 -11
  57. package/src/date-range-picker/date-range-picker.module.css +2 -2
  58. package/src/dropdown-state.ts +3 -1
  59. 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, string | number> & import("react").RefAttributes<HTMLInputElement>>;
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,2IAS5B,CAAC"}
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,CACtC,CAAC,EAAiB,EAAE,GAAG,EAAE,EAAE;QAA1B,EAAE,GAAG,OAAY,EAAP,KAAK,cAAf,OAAiB,CAAF;IACZ,OAAA,GAAG,CAAC,CAAC,CAAC,CACF,kBAAC,oBAAI,CAAC,KAAK,oBAAK,KAAK,IAAE,GAAG,EAAE,GAAG,YAAI,CACtC,CAAC,CAAC,CAAC,CACA,kBAAC,0BAAS,kBAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAC,gBAAgB,IAAK,KAAK,cACrD,GAAG,EAAE,CAAC,kBAAC,oBAAI,CAAC,KAAK,kBAAC,GAAG,EAAE,GAAG,IAAM,KAAK,UAAI,YAClC,CACf,CAAA;CAAA,CACR,CAAC"}
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": "16.1.0",
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": "^16.1.0",
19
- "@servicetitan/culture": "^16.1.0",
20
- "@servicetitan/data-query": "^16.1.0",
21
- "@servicetitan/design-system": "~10.2.1",
22
- "@servicetitan/react-ioc": "^16.1.0",
23
- "@servicetitan/tokens": "~10.2.1",
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.24",
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.2.1",
41
+ "@servicetitan/design-system": "~10.3.3",
42
42
  "@servicetitan/react-ioc": "^14.0.0",
43
- "@servicetitan/tokens": "~10.2.1",
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": "3790506ef903e0e9bf129dcf4d2ed352f42b007d"
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);
@@ -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) return undefined;
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 { useCallback, useState, useEffect, SyntheticEvent, KeyboardEvent, FocusEvent } from 'react';
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
- const updateValue = (value: string, silent = false) => {
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);