@servicetitan/form 38.0.0 → 38.2.0
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/dist/date-range-picker/date-range-picker.js +2 -2
- package/dist/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/file-uploader/file-uploader.js +2 -2
- package/dist/file-uploader/file-uploader.js.map +1 -1
- package/dist/number-input/number-input.d.ts.map +1 -1
- package/dist/number-input/number-input.js.map +1 -1
- package/package.json +11 -11
- package/src/number-input/number-input.tsx +4 -2
|
@@ -40,6 +40,7 @@ export class DateRangePicker extends Component {
|
|
|
40
40
|
window.removeEventListener('click', this.handleClickGlobal);
|
|
41
41
|
}
|
|
42
42
|
render() {
|
|
43
|
+
var _value_from, _value_to;
|
|
43
44
|
const { hasError } = this.props.field;
|
|
44
45
|
const { 'qa-testing': qaTestingLocator, placeHolder, inputFormat, className, calendarComponent, headerTitleComponent, cellComponent, minDate, maxDate, calendarMinDate, calendarMaxDate, topView, bottomView, horizontalAlign, disabled = false, small, maskChar } = this.props;
|
|
45
46
|
const value = this.props.field.value ? this.props.field.value : {};
|
|
@@ -47,7 +48,6 @@ export class DateRangePicker extends Component {
|
|
|
47
48
|
[Styles.popupCenter]: horizontalAlign === 'center',
|
|
48
49
|
[Styles.popupRight]: horizontalAlign === 'right'
|
|
49
50
|
});
|
|
50
|
-
var _value_from, _value_to;
|
|
51
51
|
return /*#__PURE__*/ _jsxs("div", {
|
|
52
52
|
className: classnames(Styles.dateRangePicker, className),
|
|
53
53
|
ref: this.handleRef,
|
|
@@ -204,6 +204,7 @@ export class DateRangePicker extends Component {
|
|
|
204
204
|
}
|
|
205
205
|
this.toggleShow();
|
|
206
206
|
}), _define_property(this, "handleChange", (event)=>{
|
|
207
|
+
var _value_start, _value_end;
|
|
207
208
|
const value = event.target.value;
|
|
208
209
|
if (value.start && value.end && value.start > value.end) {
|
|
209
210
|
[value.start, value.end] = [
|
|
@@ -211,7 +212,6 @@ export class DateRangePicker extends Component {
|
|
|
211
212
|
value.start
|
|
212
213
|
];
|
|
213
214
|
}
|
|
214
|
-
var _value_start, _value_end;
|
|
215
215
|
this.props.field.onChange({
|
|
216
216
|
from: (_value_start = value.start) !== null && _value_start !== void 0 ? _value_start : undefined,
|
|
217
217
|
to: (_value_end = value.end) !== null && _value_end !== void 0 ? _value_end : undefined
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/date-range-picker/date-range-picker.tsx"],"sourcesContent":["import { ComponentType, Component, SyntheticEvent } from 'react';\nimport {\n DateRangePicker as DateRangePickerKendo,\n DateRangePickerChangeEvent,\n CalendarHeaderTitleProps,\n MultiViewCalendarProps,\n CalendarCellProps,\n ActiveView,\n} from '@progress/kendo-react-dateinputs';\nimport { Icon, InputDateMask, Stack } from '@servicetitan/design-system';\nimport { DateRange } from '@servicetitan/form-state';\nimport { observable, action, makeObservable } from 'mobx';\nimport { observer } from 'mobx-react';\nimport classnames from 'classnames';\nimport moment from 'moment';\nimport * as Styles from './date-range-picker.module.css';\nimport { FieldState } from 'formstate';\n\nexport interface DateRangePickerProps {\n field: FieldState<DateRange | undefined>;\n ['qa-testing']: string;\n placeHolder?: string;\n minDate?: Date;\n maxDate?: Date;\n calendarMinDate?: Date;\n calendarMaxDate?: Date;\n topView?: ActiveView;\n bottomView?: ActiveView;\n className?: string;\n calendarComponent?: ComponentType<MultiViewCalendarProps>;\n headerTitleComponent?: ComponentType<CalendarHeaderTitleProps>;\n cellComponent?: ComponentType<CalendarCellProps>;\n inputFormat?: string;\n horizontalAlign?: 'left' | 'center' | 'right';\n disabled?: boolean;\n small?: boolean;\n disableRangeValidation?: boolean;\n maskChar?: string;\n}\n\n@observer\nexport class DateRangePicker extends Component<DateRangePickerProps> {\n // `HTMLDivElement` leads to issues with Node/SSR\n @observable wrapElem?: any /* HTMLDivElement */;\n isFocused = false;\n @observable showDatePicker = false;\n isIconClicked = false;\n isDateRangePickerClicked = false;\n\n constructor(props: DateRangePickerProps) {\n super(props);\n makeObservable(this);\n }\n\n @action\n handleRef = (wrapElem: HTMLDivElement) => {\n this.wrapElem = wrapElem;\n };\n\n @action\n toggleShow(show?: boolean) {\n this.showDatePicker = show !== undefined ? show : !this.showDatePicker;\n }\n\n handleClickGlobal = (evt: Event) => {\n if (!(evt.target instanceof Node)) {\n return;\n }\n\n const isPrevFocused = this.isFocused;\n\n this.isFocused = this.isDateRangePickerClicked;\n\n if (!this.isFocused && isPrevFocused) {\n // click outside\n this.props.field.enableAutoValidationAndValidate();\n\n this.toggleShow(false);\n } else if (this.isFocused && !isPrevFocused && !this.isIconClicked) {\n // click inside but outside icons\n this.props.field.disableAutoValidation();\n }\n\n this.isIconClicked = false;\n this.isDateRangePickerClicked = false;\n };\n\n handleClickDateRangePicker = () => {\n this.isDateRangePickerClicked = true;\n };\n\n handleClickIcon = () => {\n this.isIconClicked = true;\n\n if (this.showDatePicker) {\n this.props.field.enableAutoValidationAndValidate();\n } else {\n this.props.field.disableAutoValidation();\n }\n\n this.toggleShow();\n };\n\n componentDidMount() {\n window.addEventListener('click', this.handleClickGlobal);\n }\n\n componentWillUnmount() {\n window.removeEventListener('click', this.handleClickGlobal);\n }\n\n handleChange = (event: DateRangePickerChangeEvent) => {\n const value = event.target.value;\n\n if (value.start && value.end && value.start > value.end) {\n [value.start, value.end] = [value.end, value.start];\n }\n\n this.props.field.onChange({ from: value.start ?? undefined, to: value.end ?? undefined });\n };\n\n handleFromChange = (from?: Date) => {\n const to = this.props.field.value ? this.props.field.value.to : undefined;\n\n if (from || to) {\n this.props.field.onChange({ from, to });\n } else {\n this.props.field.onChange(undefined);\n }\n };\n\n handleToChange = (to?: Date) => {\n const from = this.props.field.value ? this.props.field.value.from : undefined;\n\n if (from || to) {\n this.props.field.onChange({ from, to });\n } else {\n this.props.field.onChange(undefined);\n }\n };\n\n render() {\n const { hasError } = this.props.field;\n const {\n 'qa-testing': qaTestingLocator,\n placeHolder,\n inputFormat,\n className,\n calendarComponent,\n headerTitleComponent,\n cellComponent,\n minDate,\n maxDate,\n calendarMinDate,\n calendarMaxDate,\n topView,\n bottomView,\n horizontalAlign,\n disabled = false,\n small,\n maskChar,\n } = this.props;\n\n const value = this.props.field.value ? this.props.field.value : {};\n\n const horizontalAlignClass = classnames({\n [Styles.popupCenter]: horizontalAlign === 'center',\n [Styles.popupRight]: horizontalAlign === 'right',\n });\n\n return (\n <div\n className={classnames(Styles.dateRangePicker, className)}\n ref={this.handleRef}\n onClick={this.handleClickDateRangePicker}\n >\n <DateRangePickerKendo\n className={Styles.dateRangePickerKendo}\n calendarSettings={{\n min: minDate ?? calendarMinDate,\n max: maxDate ?? calendarMaxDate,\n topView,\n bottomView,\n disabled,\n mode: 'range',\n headerTitle: headerTitleComponent,\n cell: cellComponent,\n }}\n popupSettings={{\n appendTo: this.wrapElem,\n className: horizontalAlignClass,\n }}\n startDateInputSettings={{\n tabIndex: -1,\n }}\n endDateInputSettings={{\n tabIndex: -1,\n }}\n show={this.showDatePicker}\n value={{ start: value.from ?? null, end: value.to ?? null }}\n onChange={this.handleChange}\n min={minDate}\n max={maxDate}\n calendar={calendarComponent}\n />\n <Stack alignItems=\"center\" className=\"flex-grow-1\">\n <Stack.Item fill>\n <InputDateMask\n shortLabel={\n <Icon\n name=\"today\"\n className={classnames(\n Styles.icon,\n `${qaTestingLocator}-icon-from`\n )}\n onClick={this.handleClickIcon}\n />\n }\n placeholder={placeHolder}\n value={value.from}\n onChange={this.handleFromChange}\n onBlur={this.handleFromChange}\n error={hasError}\n disabled={disabled}\n qa-testing={`${qaTestingLocator}-from`}\n dateFormat={inputFormat}\n minDate={minDate}\n maxDate={this.maxFromDate}\n small={small}\n maskChar={maskChar}\n />\n </Stack.Item>\n <Icon name=\"arrow_forward\" className={Styles.endLabel} />\n <Stack.Item fill>\n <InputDateMask\n shortLabel={\n <Icon\n name=\"today\"\n className={classnames(\n Styles.icon,\n `${qaTestingLocator}-icon-to`\n )}\n onClick={this.handleClickIcon}\n />\n }\n placeholder={placeHolder}\n value={value.to}\n onChange={this.handleToChange}\n onBlur={this.handleToChange}\n error={hasError}\n disabled={disabled}\n qa-testing={`${qaTestingLocator}-to`}\n dateFormat={inputFormat}\n minDate={this.minToDate}\n maxDate={maxDate}\n small={small}\n maskChar={maskChar}\n />\n </Stack.Item>\n </Stack>\n <input\n hidden\n // eslint-disable-next-line react/no-unknown-property\n qa-testing={qaTestingLocator}\n onChange={this.handleHiddenInputChange}\n />\n </div>\n );\n }\n\n formatDate(date?: Date, inputFormat = 'L') {\n return date ? moment(date).format(inputFormat) : '';\n }\n\n handleHiddenInputChange = (ev: SyntheticEvent<HTMLInputElement>) => {\n const values = ev.currentTarget.value.split('-').map(v => new Date(v));\n this.props.field.onChange({ from: values[0] || undefined, to: values[1] || undefined });\n };\n\n get maxFromDate() {\n const { disableRangeValidation, maxDate, field } = this.props;\n if (disableRangeValidation) {\n return maxDate;\n }\n\n const to = field.value ? field.value.to : undefined;\n\n if (maxDate && to) {\n return maxDate > to ? to : maxDate;\n }\n\n return maxDate ?? to;\n }\n\n get minToDate() {\n const { disableRangeValidation, minDate, field } = this.props;\n if (disableRangeValidation) {\n return minDate;\n }\n\n const from = field.value ? field.value.from : undefined;\n if (minDate && from) {\n return minDate < from ? from : minDate;\n }\n\n return minDate ?? from;\n }\n}\n"],"names":["Component","DateRangePicker","DateRangePickerKendo","Icon","InputDateMask","Stack","observable","action","makeObservable","observer","classnames","moment","Styles","toggleShow","show","showDatePicker","undefined","componentDidMount","window","addEventListener","handleClickGlobal","componentWillUnmount","removeEventListener","render","hasError","props","field","qaTestingLocator","placeHolder","inputFormat","className","calendarComponent","headerTitleComponent","cellComponent","minDate","maxDate","calendarMinDate","calendarMaxDate","topView","bottomView","horizontalAlign","disabled","small","maskChar","value","horizontalAlignClass","popupCenter","popupRight","div","dateRangePicker","ref","handleRef","onClick","handleClickDateRangePicker","dateRangePickerKendo","calendarSettings","min","max","mode","headerTitle","cell","popupSettings","appendTo","wrapElem","startDateInputSettings","tabIndex","endDateInputSettings","start","from","end","to","onChange","handleChange","calendar","alignItems","Item","fill","shortLabel","name","icon","handleClickIcon","placeholder","handleFromChange","onBlur","error","qa-testing","dateFormat","maxFromDate","endLabel","handleToChange","minToDate","input","hidden","handleHiddenInputChange","formatDate","date","format","disableRangeValidation","isFocused","isIconClicked","isDateRangePickerClicked","evt","target","Node","isPrevFocused","enableAutoValidationAndValidate","disableAutoValidation","event","ev","values","currentTarget","split","map","v","Date"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/date-range-picker/date-range-picker.tsx"],"sourcesContent":["import { ComponentType, Component, SyntheticEvent } from 'react';\nimport {\n DateRangePicker as DateRangePickerKendo,\n DateRangePickerChangeEvent,\n CalendarHeaderTitleProps,\n MultiViewCalendarProps,\n CalendarCellProps,\n ActiveView,\n} from '@progress/kendo-react-dateinputs';\nimport { Icon, InputDateMask, Stack } from '@servicetitan/design-system';\nimport { DateRange } from '@servicetitan/form-state';\nimport { observable, action, makeObservable } from 'mobx';\nimport { observer } from 'mobx-react';\nimport classnames from 'classnames';\nimport moment from 'moment';\nimport * as Styles from './date-range-picker.module.css';\nimport { FieldState } from 'formstate';\n\nexport interface DateRangePickerProps {\n field: FieldState<DateRange | undefined>;\n ['qa-testing']: string;\n placeHolder?: string;\n minDate?: Date;\n maxDate?: Date;\n calendarMinDate?: Date;\n calendarMaxDate?: Date;\n topView?: ActiveView;\n bottomView?: ActiveView;\n className?: string;\n calendarComponent?: ComponentType<MultiViewCalendarProps>;\n headerTitleComponent?: ComponentType<CalendarHeaderTitleProps>;\n cellComponent?: ComponentType<CalendarCellProps>;\n inputFormat?: string;\n horizontalAlign?: 'left' | 'center' | 'right';\n disabled?: boolean;\n small?: boolean;\n disableRangeValidation?: boolean;\n maskChar?: string;\n}\n\n@observer\nexport class DateRangePicker extends Component<DateRangePickerProps> {\n // `HTMLDivElement` leads to issues with Node/SSR\n @observable wrapElem?: any /* HTMLDivElement */;\n isFocused = false;\n @observable showDatePicker = false;\n isIconClicked = false;\n isDateRangePickerClicked = false;\n\n constructor(props: DateRangePickerProps) {\n super(props);\n makeObservable(this);\n }\n\n @action\n handleRef = (wrapElem: HTMLDivElement) => {\n this.wrapElem = wrapElem;\n };\n\n @action\n toggleShow(show?: boolean) {\n this.showDatePicker = show !== undefined ? show : !this.showDatePicker;\n }\n\n handleClickGlobal = (evt: Event) => {\n if (!(evt.target instanceof Node)) {\n return;\n }\n\n const isPrevFocused = this.isFocused;\n\n this.isFocused = this.isDateRangePickerClicked;\n\n if (!this.isFocused && isPrevFocused) {\n // click outside\n this.props.field.enableAutoValidationAndValidate();\n\n this.toggleShow(false);\n } else if (this.isFocused && !isPrevFocused && !this.isIconClicked) {\n // click inside but outside icons\n this.props.field.disableAutoValidation();\n }\n\n this.isIconClicked = false;\n this.isDateRangePickerClicked = false;\n };\n\n handleClickDateRangePicker = () => {\n this.isDateRangePickerClicked = true;\n };\n\n handleClickIcon = () => {\n this.isIconClicked = true;\n\n if (this.showDatePicker) {\n this.props.field.enableAutoValidationAndValidate();\n } else {\n this.props.field.disableAutoValidation();\n }\n\n this.toggleShow();\n };\n\n componentDidMount() {\n window.addEventListener('click', this.handleClickGlobal);\n }\n\n componentWillUnmount() {\n window.removeEventListener('click', this.handleClickGlobal);\n }\n\n handleChange = (event: DateRangePickerChangeEvent) => {\n const value = event.target.value;\n\n if (value.start && value.end && value.start > value.end) {\n [value.start, value.end] = [value.end, value.start];\n }\n\n this.props.field.onChange({ from: value.start ?? undefined, to: value.end ?? undefined });\n };\n\n handleFromChange = (from?: Date) => {\n const to = this.props.field.value ? this.props.field.value.to : undefined;\n\n if (from || to) {\n this.props.field.onChange({ from, to });\n } else {\n this.props.field.onChange(undefined);\n }\n };\n\n handleToChange = (to?: Date) => {\n const from = this.props.field.value ? this.props.field.value.from : undefined;\n\n if (from || to) {\n this.props.field.onChange({ from, to });\n } else {\n this.props.field.onChange(undefined);\n }\n };\n\n render() {\n const { hasError } = this.props.field;\n const {\n 'qa-testing': qaTestingLocator,\n placeHolder,\n inputFormat,\n className,\n calendarComponent,\n headerTitleComponent,\n cellComponent,\n minDate,\n maxDate,\n calendarMinDate,\n calendarMaxDate,\n topView,\n bottomView,\n horizontalAlign,\n disabled = false,\n small,\n maskChar,\n } = this.props;\n\n const value = this.props.field.value ? this.props.field.value : {};\n\n const horizontalAlignClass = classnames({\n [Styles.popupCenter]: horizontalAlign === 'center',\n [Styles.popupRight]: horizontalAlign === 'right',\n });\n\n return (\n <div\n className={classnames(Styles.dateRangePicker, className)}\n ref={this.handleRef}\n onClick={this.handleClickDateRangePicker}\n >\n <DateRangePickerKendo\n className={Styles.dateRangePickerKendo}\n calendarSettings={{\n min: minDate ?? calendarMinDate,\n max: maxDate ?? calendarMaxDate,\n topView,\n bottomView,\n disabled,\n mode: 'range',\n headerTitle: headerTitleComponent,\n cell: cellComponent,\n }}\n popupSettings={{\n appendTo: this.wrapElem,\n className: horizontalAlignClass,\n }}\n startDateInputSettings={{\n tabIndex: -1,\n }}\n endDateInputSettings={{\n tabIndex: -1,\n }}\n show={this.showDatePicker}\n value={{ start: value.from ?? null, end: value.to ?? null }}\n onChange={this.handleChange}\n min={minDate}\n max={maxDate}\n calendar={calendarComponent}\n />\n <Stack alignItems=\"center\" className=\"flex-grow-1\">\n <Stack.Item fill>\n <InputDateMask\n shortLabel={\n <Icon\n name=\"today\"\n className={classnames(\n Styles.icon,\n `${qaTestingLocator}-icon-from`\n )}\n onClick={this.handleClickIcon}\n />\n }\n placeholder={placeHolder}\n value={value.from}\n onChange={this.handleFromChange}\n onBlur={this.handleFromChange}\n error={hasError}\n disabled={disabled}\n qa-testing={`${qaTestingLocator}-from`}\n dateFormat={inputFormat}\n minDate={minDate}\n maxDate={this.maxFromDate}\n small={small}\n maskChar={maskChar}\n />\n </Stack.Item>\n <Icon name=\"arrow_forward\" className={Styles.endLabel} />\n <Stack.Item fill>\n <InputDateMask\n shortLabel={\n <Icon\n name=\"today\"\n className={classnames(\n Styles.icon,\n `${qaTestingLocator}-icon-to`\n )}\n onClick={this.handleClickIcon}\n />\n }\n placeholder={placeHolder}\n value={value.to}\n onChange={this.handleToChange}\n onBlur={this.handleToChange}\n error={hasError}\n disabled={disabled}\n qa-testing={`${qaTestingLocator}-to`}\n dateFormat={inputFormat}\n minDate={this.minToDate}\n maxDate={maxDate}\n small={small}\n maskChar={maskChar}\n />\n </Stack.Item>\n </Stack>\n <input\n hidden\n // eslint-disable-next-line react/no-unknown-property\n qa-testing={qaTestingLocator}\n onChange={this.handleHiddenInputChange}\n />\n </div>\n );\n }\n\n formatDate(date?: Date, inputFormat = 'L') {\n return date ? moment(date).format(inputFormat) : '';\n }\n\n handleHiddenInputChange = (ev: SyntheticEvent<HTMLInputElement>) => {\n const values = ev.currentTarget.value.split('-').map(v => new Date(v));\n this.props.field.onChange({ from: values[0] || undefined, to: values[1] || undefined });\n };\n\n get maxFromDate() {\n const { disableRangeValidation, maxDate, field } = this.props;\n if (disableRangeValidation) {\n return maxDate;\n }\n\n const to = field.value ? field.value.to : undefined;\n\n if (maxDate && to) {\n return maxDate > to ? to : maxDate;\n }\n\n return maxDate ?? to;\n }\n\n get minToDate() {\n const { disableRangeValidation, minDate, field } = this.props;\n if (disableRangeValidation) {\n return minDate;\n }\n\n const from = field.value ? field.value.from : undefined;\n if (minDate && from) {\n return minDate < from ? from : minDate;\n }\n\n return minDate ?? from;\n }\n}\n"],"names":["Component","DateRangePicker","DateRangePickerKendo","Icon","InputDateMask","Stack","observable","action","makeObservable","observer","classnames","moment","Styles","toggleShow","show","showDatePicker","undefined","componentDidMount","window","addEventListener","handleClickGlobal","componentWillUnmount","removeEventListener","render","value","hasError","props","field","qaTestingLocator","placeHolder","inputFormat","className","calendarComponent","headerTitleComponent","cellComponent","minDate","maxDate","calendarMinDate","calendarMaxDate","topView","bottomView","horizontalAlign","disabled","small","maskChar","horizontalAlignClass","popupCenter","popupRight","div","dateRangePicker","ref","handleRef","onClick","handleClickDateRangePicker","dateRangePickerKendo","calendarSettings","min","max","mode","headerTitle","cell","popupSettings","appendTo","wrapElem","startDateInputSettings","tabIndex","endDateInputSettings","start","from","end","to","onChange","handleChange","calendar","alignItems","Item","fill","shortLabel","name","icon","handleClickIcon","placeholder","handleFromChange","onBlur","error","qa-testing","dateFormat","maxFromDate","endLabel","handleToChange","minToDate","input","hidden","handleHiddenInputChange","formatDate","date","format","disableRangeValidation","isFocused","isIconClicked","isDateRangePickerClicked","evt","target","Node","isPrevFocused","enableAutoValidationAndValidate","disableAutoValidation","event","ev","values","currentTarget","split","map","v","Date"],"mappings":"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"}
|
|
@@ -158,12 +158,12 @@ export class FileUploader extends Component {
|
|
|
158
158
|
this.addError(file, message);
|
|
159
159
|
this.props.onChange(this.props.value.filter((fileDescriptor)=>fileDescriptor.file !== file));
|
|
160
160
|
}), _define_property(this, "handleDownload", (file)=>{
|
|
161
|
+
var _ref, _ref1;
|
|
161
162
|
var _this_props_config, _this_config;
|
|
162
163
|
if (!file.downloadLink) {
|
|
163
164
|
return;
|
|
164
165
|
}
|
|
165
|
-
|
|
166
|
-
const path = (_ref = (_this_props_config_downloadPath = (_this_props_config = this.props.config) === null || _this_props_config === void 0 ? void 0 : _this_props_config.downloadPath) !== null && _this_props_config_downloadPath !== void 0 ? _this_props_config_downloadPath : (_this_config = this.config) === null || _this_config === void 0 ? void 0 : _this_config.downloadPath) !== null && _ref !== void 0 ? _ref : `/app/api/fileuploader/folders/${this.props.folderName}/files/`;
|
|
166
|
+
const path = (_ref = (_ref1 = (_this_props_config = this.props.config) === null || _this_props_config === void 0 ? void 0 : _this_props_config.downloadPath) !== null && _ref1 !== void 0 ? _ref1 : (_this_config = this.config) === null || _this_config === void 0 ? void 0 : _this_config.downloadPath) !== null && _ref !== void 0 ? _ref : `/app/api/fileuploader/folders/${this.props.folderName}/files/`;
|
|
167
167
|
window.open(path + file.downloadLink);
|
|
168
168
|
}), _define_property(this, "handleSelected", (files)=>{
|
|
169
169
|
if (!this.props.onChange) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/file-uploader/file-uploader.tsx"],"sourcesContent":["import { Component, Fragment, FC } from 'react';\n\nimport { injectDependency, optional } from '@servicetitan/react-ioc';\n\nimport { observer } from 'mobx-react';\nimport { observable, action, makeObservable } from 'mobx';\n\nimport type { FileDescriptor, FilePickerProps } from '@servicetitan/design-system';\nimport { FilePicker, Banner } from '@servicetitan/design-system';\nimport { Confirm } from '@servicetitan/confirm';\n\nimport type { FileUploaderConfig } from './config';\nimport { FILE_UPLOADER_CONFIGURATION_TOKEN } from './config';\nimport { Uploader } from './uploader';\n\nimport { v4 as uuid } from 'uuid';\n\nfunction immutableSplice<T>(arr: T[], start: number, deleteCount: number, ...items: T[]) {\n return [...arr.slice(0, start), ...items, ...arr.slice(start + deleteCount)];\n}\n\ninterface UploadError {\n id: string;\n file: File;\n message?: string;\n}\n\ninterface UploadErrorsProps {\n errors: UploadError[];\n multiple?: boolean;\n className?: string;\n onClose(): void;\n}\n\nconst UploadErrors: FC<UploadErrorsProps> = ({ errors, className, onClose, multiple }) => {\n const title = multiple\n ? 'One or more files could not be uploaded:'\n : 'Your file could not be uploaded';\n\n return (\n <Banner icon status=\"critical\" title={title} className={className} onClose={onClose}>\n <ul className=\"p-x-0-i\">\n {errors.map(({ id, file, message }) => (\n <li key={id} style={!multiple ? { listStyle: 'none' } : {}}>\n {multiple && file.name}\n {message && (multiple ? ` (${message})` : message)}\n </li>\n ))}\n </ul>\n </Banner>\n );\n};\n\ntype ExcludedFilePickerProps = 'onDelete' | 'onDownload' | 'onReplace' | 'onSelected' | 'value';\n\ninterface FileUploaderProps extends Omit<FilePickerProps, ExcludedFilePickerProps> {\n config?: FileUploaderConfig;\n value: FileDescriptor[];\n folderName?: string;\n hideReplace?: boolean;\n hideDownload?: boolean;\n onChange?(value: FileDescriptor[]): void;\n}\n\n@observer\nexport class FileUploader extends Component<FileUploaderProps> {\n static defaultProps = {\n folderName: 'temp',\n };\n\n @injectDependency(FILE_UPLOADER_CONFIGURATION_TOKEN)\n @optional()\n declare config?: FileUploaderConfig;\n\n @observable errors: UploadError[] = [];\n\n uploader!: Uploader;\n\n constructor(props: FileUploaderProps) {\n super(props);\n makeObservable(this);\n }\n\n @action\n addError(file: File, message?: string) {\n this.errors.push({\n file,\n message,\n id: uuid(),\n });\n }\n\n @action\n clearErrors() {\n this.errors = [];\n }\n\n @action\n handleUploadProgress = (file: File, progress: number) => {\n if (!this.props.onChange) {\n return;\n }\n\n const index = this.props.value.findIndex(fileDescriptor => fileDescriptor.file === file);\n if (index !== -1) {\n this.props.onChange(\n immutableSplice(this.props.value, index, 1, {\n ...this.props.value[index],\n uploadProgress: progress,\n })\n );\n } else {\n this.uploader.cancel(file);\n }\n };\n\n @action\n handleUploadSuccess = (file: File, message?: string) => {\n if (!this.props.onChange) {\n return;\n }\n\n const index = this.props.value.findIndex(fileDescriptor => fileDescriptor.file === file);\n if (index !== -1) {\n this.props.onChange(\n immutableSplice(this.props.value, index, 1, {\n ...this.props.value[index],\n ...(message\n ? { file: message, displayName: file.name, downloadLink: message }\n : { file: file.name }),\n uploadProgress: undefined,\n })\n );\n }\n };\n\n @action\n handleUploadError = (file: File, message?: string) => {\n if (!this.props.onChange) {\n return;\n }\n\n this.addError(file, message);\n\n this.props.onChange(\n this.props.value.filter(fileDescriptor => fileDescriptor.file !== file)\n );\n };\n\n componentDidMount() {\n this.uploader = new Uploader(\n {\n ...this.config,\n ...this.props.config,\n },\n {\n progress: this.handleUploadProgress,\n success: this.handleUploadSuccess,\n error: this.handleUploadError,\n },\n this.props.folderName\n );\n }\n\n componentWillUnmount() {\n this.uploader.cancel();\n }\n\n handleDownload = (file: FileDescriptor) => {\n if (!file.downloadLink) {\n return;\n }\n\n const path =\n this.props.config?.downloadPath ??\n this.config?.downloadPath ??\n `/app/api/fileuploader/folders/${this.props.folderName}/files/`;\n\n window.open(path + file.downloadLink);\n };\n\n handleSelected = (files: FileList) => {\n if (!this.props.onChange) {\n return;\n }\n\n this.props.onChange([\n ...this.props.value,\n ...Array.from(files).map(file => ({\n file,\n uploadProgress: 0,\n })),\n ]);\n this.uploader.upload(files);\n };\n\n handleReplace = ({ file: { file }, newFile }: { file: FileDescriptor; newFile: File }) => {\n if (!this.props.onChange) {\n return;\n }\n\n const index = this.props.value.findIndex(fileDescriptor => fileDescriptor.file === file);\n if (index !== -1) {\n this.uploader.upload(newFile);\n\n this.props.onChange(\n immutableSplice(this.props.value, index, 1, {\n file: newFile,\n uploadProgress: 0,\n })\n );\n }\n };\n\n handleDelete = ({ file }: FileDescriptor) => {\n if (!this.props.onChange) {\n return;\n }\n\n this.props.onChange(\n this.props.value.filter(fileDescriptor => fileDescriptor.file !== file)\n );\n };\n\n handleErrorsClose = () => {\n this.clearErrors();\n };\n\n render() {\n const {\n value,\n onChange,\n hideReplace,\n hideDownload,\n limitReached,\n multiple,\n config,\n folderName,\n ...rest\n } = this.props;\n\n if (!onChange && !value.length) {\n return null;\n }\n\n const readonlyProps = onChange\n ? {}\n : {\n onReplace: undefined,\n onDelete: undefined,\n limitReached: true,\n };\n\n return (\n <Fragment>\n {!!this.errors.length && (\n <UploadErrors\n errors={this.errors}\n onClose={this.handleErrorsClose}\n className=\"m-b-2\"\n multiple={multiple}\n />\n )}\n <Confirm\n onConfirm={this.handleDelete}\n title=\"Are you sure you want to delete this file?\"\n >\n {onDelete => (\n <FilePicker\n value={value.length ? value : undefined}\n onReplace={!hideReplace ? this.handleReplace : undefined}\n onSelected={this.handleSelected}\n onDelete={onDelete}\n onDownload={!hideDownload ? this.handleDownload : undefined}\n limitReached={limitReached}\n multiple={multiple}\n {...rest}\n {...readonlyProps}\n />\n )}\n </Confirm>\n </Fragment>\n );\n }\n}\n"],"names":["Component","Fragment","injectDependency","optional","observer","observable","action","makeObservable","FilePicker","Banner","Confirm","FILE_UPLOADER_CONFIGURATION_TOKEN","Uploader","v4","uuid","immutableSplice","arr","start","deleteCount","items","slice","UploadErrors","errors","className","onClose","multiple","title","icon","status","ul","map","id","file","message","li","style","listStyle","name","FileUploader","addError","push","clearErrors","componentDidMount","uploader","config","props","progress","handleUploadProgress","success","handleUploadSuccess","error","handleUploadError","folderName","componentWillUnmount","cancel","render","value","onChange","hideReplace","hideDownload","limitReached","rest","length","readonlyProps","onReplace","undefined","onDelete","handleErrorsClose","onConfirm","handleDelete","handleReplace","onSelected","handleSelected","onDownload","handleDownload","index","findIndex","fileDescriptor","uploadProgress","displayName","downloadLink","filter","path","downloadPath","window","open","files","Array","from","upload","newFile","defaultProps"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/file-uploader/file-uploader.tsx"],"sourcesContent":["import { Component, Fragment, FC } from 'react';\n\nimport { injectDependency, optional } from '@servicetitan/react-ioc';\n\nimport { observer } from 'mobx-react';\nimport { observable, action, makeObservable } from 'mobx';\n\nimport type { FileDescriptor, FilePickerProps } from '@servicetitan/design-system';\nimport { FilePicker, Banner } from '@servicetitan/design-system';\nimport { Confirm } from '@servicetitan/confirm';\n\nimport type { FileUploaderConfig } from './config';\nimport { FILE_UPLOADER_CONFIGURATION_TOKEN } from './config';\nimport { Uploader } from './uploader';\n\nimport { v4 as uuid } from 'uuid';\n\nfunction immutableSplice<T>(arr: T[], start: number, deleteCount: number, ...items: T[]) {\n return [...arr.slice(0, start), ...items, ...arr.slice(start + deleteCount)];\n}\n\ninterface UploadError {\n id: string;\n file: File;\n message?: string;\n}\n\ninterface UploadErrorsProps {\n errors: UploadError[];\n multiple?: boolean;\n className?: string;\n onClose(): void;\n}\n\nconst UploadErrors: FC<UploadErrorsProps> = ({ errors, className, onClose, multiple }) => {\n const title = multiple\n ? 'One or more files could not be uploaded:'\n : 'Your file could not be uploaded';\n\n return (\n <Banner icon status=\"critical\" title={title} className={className} onClose={onClose}>\n <ul className=\"p-x-0-i\">\n {errors.map(({ id, file, message }) => (\n <li key={id} style={!multiple ? { listStyle: 'none' } : {}}>\n {multiple && file.name}\n {message && (multiple ? ` (${message})` : message)}\n </li>\n ))}\n </ul>\n </Banner>\n );\n};\n\ntype ExcludedFilePickerProps = 'onDelete' | 'onDownload' | 'onReplace' | 'onSelected' | 'value';\n\ninterface FileUploaderProps extends Omit<FilePickerProps, ExcludedFilePickerProps> {\n config?: FileUploaderConfig;\n value: FileDescriptor[];\n folderName?: string;\n hideReplace?: boolean;\n hideDownload?: boolean;\n onChange?(value: FileDescriptor[]): void;\n}\n\n@observer\nexport class FileUploader extends Component<FileUploaderProps> {\n static defaultProps = {\n folderName: 'temp',\n };\n\n @injectDependency(FILE_UPLOADER_CONFIGURATION_TOKEN)\n @optional()\n declare config?: FileUploaderConfig;\n\n @observable errors: UploadError[] = [];\n\n uploader!: Uploader;\n\n constructor(props: FileUploaderProps) {\n super(props);\n makeObservable(this);\n }\n\n @action\n addError(file: File, message?: string) {\n this.errors.push({\n file,\n message,\n id: uuid(),\n });\n }\n\n @action\n clearErrors() {\n this.errors = [];\n }\n\n @action\n handleUploadProgress = (file: File, progress: number) => {\n if (!this.props.onChange) {\n return;\n }\n\n const index = this.props.value.findIndex(fileDescriptor => fileDescriptor.file === file);\n if (index !== -1) {\n this.props.onChange(\n immutableSplice(this.props.value, index, 1, {\n ...this.props.value[index],\n uploadProgress: progress,\n })\n );\n } else {\n this.uploader.cancel(file);\n }\n };\n\n @action\n handleUploadSuccess = (file: File, message?: string) => {\n if (!this.props.onChange) {\n return;\n }\n\n const index = this.props.value.findIndex(fileDescriptor => fileDescriptor.file === file);\n if (index !== -1) {\n this.props.onChange(\n immutableSplice(this.props.value, index, 1, {\n ...this.props.value[index],\n ...(message\n ? { file: message, displayName: file.name, downloadLink: message }\n : { file: file.name }),\n uploadProgress: undefined,\n })\n );\n }\n };\n\n @action\n handleUploadError = (file: File, message?: string) => {\n if (!this.props.onChange) {\n return;\n }\n\n this.addError(file, message);\n\n this.props.onChange(\n this.props.value.filter(fileDescriptor => fileDescriptor.file !== file)\n );\n };\n\n componentDidMount() {\n this.uploader = new Uploader(\n {\n ...this.config,\n ...this.props.config,\n },\n {\n progress: this.handleUploadProgress,\n success: this.handleUploadSuccess,\n error: this.handleUploadError,\n },\n this.props.folderName\n );\n }\n\n componentWillUnmount() {\n this.uploader.cancel();\n }\n\n handleDownload = (file: FileDescriptor) => {\n if (!file.downloadLink) {\n return;\n }\n\n const path =\n this.props.config?.downloadPath ??\n this.config?.downloadPath ??\n `/app/api/fileuploader/folders/${this.props.folderName}/files/`;\n\n window.open(path + file.downloadLink);\n };\n\n handleSelected = (files: FileList) => {\n if (!this.props.onChange) {\n return;\n }\n\n this.props.onChange([\n ...this.props.value,\n ...Array.from(files).map(file => ({\n file,\n uploadProgress: 0,\n })),\n ]);\n this.uploader.upload(files);\n };\n\n handleReplace = ({ file: { file }, newFile }: { file: FileDescriptor; newFile: File }) => {\n if (!this.props.onChange) {\n return;\n }\n\n const index = this.props.value.findIndex(fileDescriptor => fileDescriptor.file === file);\n if (index !== -1) {\n this.uploader.upload(newFile);\n\n this.props.onChange(\n immutableSplice(this.props.value, index, 1, {\n file: newFile,\n uploadProgress: 0,\n })\n );\n }\n };\n\n handleDelete = ({ file }: FileDescriptor) => {\n if (!this.props.onChange) {\n return;\n }\n\n this.props.onChange(\n this.props.value.filter(fileDescriptor => fileDescriptor.file !== file)\n );\n };\n\n handleErrorsClose = () => {\n this.clearErrors();\n };\n\n render() {\n const {\n value,\n onChange,\n hideReplace,\n hideDownload,\n limitReached,\n multiple,\n config,\n folderName,\n ...rest\n } = this.props;\n\n if (!onChange && !value.length) {\n return null;\n }\n\n const readonlyProps = onChange\n ? {}\n : {\n onReplace: undefined,\n onDelete: undefined,\n limitReached: true,\n };\n\n return (\n <Fragment>\n {!!this.errors.length && (\n <UploadErrors\n errors={this.errors}\n onClose={this.handleErrorsClose}\n className=\"m-b-2\"\n multiple={multiple}\n />\n )}\n <Confirm\n onConfirm={this.handleDelete}\n title=\"Are you sure you want to delete this file?\"\n >\n {onDelete => (\n <FilePicker\n value={value.length ? value : undefined}\n onReplace={!hideReplace ? this.handleReplace : undefined}\n onSelected={this.handleSelected}\n onDelete={onDelete}\n onDownload={!hideDownload ? this.handleDownload : undefined}\n limitReached={limitReached}\n multiple={multiple}\n {...rest}\n {...readonlyProps}\n />\n )}\n </Confirm>\n </Fragment>\n );\n }\n}\n"],"names":["Component","Fragment","injectDependency","optional","observer","observable","action","makeObservable","FilePicker","Banner","Confirm","FILE_UPLOADER_CONFIGURATION_TOKEN","Uploader","v4","uuid","immutableSplice","arr","start","deleteCount","items","slice","UploadErrors","errors","className","onClose","multiple","title","icon","status","ul","map","id","file","message","li","style","listStyle","name","FileUploader","addError","push","clearErrors","componentDidMount","uploader","config","props","progress","handleUploadProgress","success","handleUploadSuccess","error","handleUploadError","folderName","componentWillUnmount","cancel","render","value","onChange","hideReplace","hideDownload","limitReached","rest","length","readonlyProps","onReplace","undefined","onDelete","handleErrorsClose","onConfirm","handleDelete","handleReplace","onSelected","handleSelected","onDownload","handleDownload","index","findIndex","fileDescriptor","uploadProgress","displayName","downloadLink","filter","path","downloadPath","window","open","files","Array","from","upload","newFile","defaultProps"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"number-input.d.ts","sourceRoot":"","sources":["../../src/number-input/number-input.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAS,UAAU,EAAqB,MAAM,6BAA6B,CAAC;AAInF,OAAO,EAAE,YAAY,EAAsB,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAS9D,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,UAAU,
|
|
1
|
+
{"version":3,"file":"number-input.d.ts","sourceRoot":"","sources":["../../src/number-input/number-input.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAS,UAAU,EAAqB,MAAM,6BAA6B,CAAC;AAInF,OAAO,EAAE,YAAY,EAAsB,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAS9D,MAAM,WAAW,gBAAgB,CAAC,MAAM,SAAS,UAAU,CAAE,SAAQ,IAAI,CACrE,UAAU,EACV,OAAO,GAAG,UAAU,CACvB;IACG,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CAC9C;AAED,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,UAAU,EAAE,sJAapD,gBAAgB,CAAC,MAAM,CAAC,4CAuL1B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/number-input/number-input.tsx"],"sourcesContent":["import {\n useCallback,\n useState,\n useEffect,\n useRef,\n SyntheticEvent,\n KeyboardEvent,\n FocusEvent,\n} from 'react';\n\nimport { useOptionalDependencies } from '@servicetitan/react-ioc';\n\nimport { Input, InputProps, InputOnChangeData } from '@servicetitan/design-system';\nimport { CULTURE_TOKEN } from '@servicetitan/culture';\n\nimport { processValue } from './process-value';\nimport { FormatNumber, getFormattedString } from './get-formatted-string';\nimport { EmptyValue, NumberValue } from './common-interfaces';\nimport { formatNumber as formatNumberDefault } from 'accounting';\n\nimport debounce from 'debounce';\n\nconst ARROW_UP_KEY = 38;\nconst ARROW_DOWN_KEY = 40;\nconst DEBOUNCE_WAIT = 300;\n\nexport interface NumberInputProps<TEmpty extends EmptyValue>\n extends Omit<InputProps, 'value' | 'onChange'> {\n value: NumberValue<TEmpty>;\n emptyValue: TEmpty;\n decimalPlaces?: number;\n useEmptyThousandsSeparator?: boolean;\n min?: number;\n max?: number;\n useKeyboardNavigation?: boolean;\n formatNumber?: FormatNumber;\n onChange(value: NumberValue<TEmpty>): void;\n}\n\nexport const NumberInput = <TEmpty extends EmptyValue>({\n value,\n onChange,\n onFocus,\n onBlur,\n emptyValue,\n decimalPlaces,\n useEmptyThousandsSeparator,\n min,\n max,\n useKeyboardNavigation,\n formatNumber = formatNumberDefault,\n ...props\n}: NumberInputProps<TEmpty>) => {\n const [\n {\n NumberFormat: {\n NumberGroupSeparator: thousandsSeparator = ',',\n NumberDecimalSeparator: decimalSeparator = '.',\n } = {},\n } = {},\n ] = useOptionalDependencies(CULTURE_TOKEN);\n\n const getFormattedValue = useCallback(\n () =>\n getFormattedString(\n value,\n {\n emptyValue,\n precision: decimalPlaces,\n separators: {\n thousand: useEmptyThousandsSeparator ? '' : thousandsSeparator,\n decimal: decimalSeparator,\n },\n },\n formatNumber\n ),\n [\n decimalPlaces,\n decimalSeparator,\n emptyValue,\n thousandsSeparator,\n useEmptyThousandsSeparator,\n value,\n formatNumber,\n ]\n );\n\n const [isFocused, setIsFocused] = useState(false);\n const [state, setState] = useState({\n numberValue: value,\n stringValue: getFormattedValue(),\n });\n\n useEffect(() => {\n if (isFocused) {\n return;\n }\n\n setState({\n numberValue: value,\n stringValue: getFormattedValue(),\n });\n }, [value, getFormattedValue, isFocused]);\n\n const handleChange = (_0: SyntheticEvent<HTMLInputElement>, { value }: InputOnChangeData) => {\n updateValue(value);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.keyCode === ARROW_UP_KEY || event.keyCode === ARROW_DOWN_KEY) {\n const newValue = (state.numberValue ?? 0) + (event.keyCode === ARROW_UP_KEY ? 1 : -1);\n\n updateValue(String(newValue));\n event.preventDefault();\n }\n };\n\n /*\n ** \"updateImmediateValue\" updates the value immediately without clamping min/max,\n ** then \"updateClampedValueDebounced\" updates applying the min/max after debounce delay\n **\n ** Example: User can type \"100\" if min is \"5\" without the \"1\" immediately being clamped\n */\n const updateImmediateValue = (value: string, silent = false) => {\n const newState = processValue(\n value,\n {\n emptyValue,\n precision: decimalPlaces,\n separators: {\n thousand: thousandsSeparator,\n decimal: decimalSeparator,\n },\n },\n formatNumber\n );\n\n setState(newState);\n\n if (!silent) {\n onChange(newState.numberValue);\n }\n };\n\n const updateClampedValueDebounced = useRef<(value: string, silent: boolean) => void>();\n\n useEffect(() => {\n let isCurrent = true;\n\n const updateClampedValue = (value: string, silent = false) => {\n if (isCurrent) {\n const newState = processValue(\n value,\n {\n emptyValue,\n precision: decimalPlaces,\n separators: {\n thousand: thousandsSeparator,\n decimal: decimalSeparator,\n },\n range: { min, max },\n },\n formatNumber\n );\n\n setState(newState);\n\n if (!silent) {\n onChange(newState.numberValue);\n }\n }\n };\n\n updateClampedValueDebounced.current = debounce(updateClampedValue, DEBOUNCE_WAIT);\n\n return () => {\n isCurrent = false;\n };\n }, [\n emptyValue,\n decimalPlaces,\n thousandsSeparator,\n decimalSeparator,\n min,\n max,\n formatNumber,\n onChange,\n ]);\n\n const updateValue = (value: string, silent = false) => {\n updateImmediateValue(value, silent);\n updateClampedValueDebounced.current?.(value, silent);\n };\n\n const handleFocus = (event: FocusEvent<HTMLInputElement>) => {\n if (state.stringValue.length) {\n updateValue(\n // prepare the value which user does see (rounded), but without trailing zeroes after decimal and separator\n decimalPlaces\n ? state.stringValue.replace(new RegExp(`[${decimalSeparator}]?0+$`), '')\n : state.stringValue,\n true\n );\n }\n\n setIsFocused(true);\n\n if (onFocus) {\n onFocus(event);\n }\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n setState({\n numberValue: value,\n stringValue: getFormattedValue(),\n });\n\n setIsFocused(false);\n\n if (onBlur) {\n onBlur(event);\n }\n };\n\n return (\n <Input\n {...props}\n value={state.stringValue}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={useKeyboardNavigation ? handleKeyDown : undefined}\n />\n );\n};\n"],"names":["useCallback","useState","useEffect","useRef","useOptionalDependencies","Input","CULTURE_TOKEN","processValue","getFormattedString","formatNumber","formatNumberDefault","debounce","ARROW_UP_KEY","ARROW_DOWN_KEY","DEBOUNCE_WAIT","NumberInput","value","onChange","onFocus","onBlur","emptyValue","decimalPlaces","useEmptyThousandsSeparator","min","max","useKeyboardNavigation","props","NumberFormat","NumberGroupSeparator","thousandsSeparator","NumberDecimalSeparator","decimalSeparator","getFormattedValue","precision","separators","thousand","decimal","isFocused","setIsFocused","state","setState","numberValue","stringValue","handleChange","_0","updateValue","handleKeyDown","event","keyCode","newValue","String","preventDefault","updateImmediateValue","silent","newState","updateClampedValueDebounced","isCurrent","updateClampedValue","range","current","handleFocus","length","replace","RegExp","handleBlur","onKeyDown","undefined"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/number-input/number-input.tsx"],"sourcesContent":["import {\n useCallback,\n useState,\n useEffect,\n useRef,\n SyntheticEvent,\n KeyboardEvent,\n FocusEvent,\n} from 'react';\n\nimport { useOptionalDependencies } from '@servicetitan/react-ioc';\n\nimport { Input, InputProps, InputOnChangeData } from '@servicetitan/design-system';\nimport { CULTURE_TOKEN } from '@servicetitan/culture';\n\nimport { processValue } from './process-value';\nimport { FormatNumber, getFormattedString } from './get-formatted-string';\nimport { EmptyValue, NumberValue } from './common-interfaces';\nimport { formatNumber as formatNumberDefault } from 'accounting';\n\nimport debounce from 'debounce';\n\nconst ARROW_UP_KEY = 38;\nconst ARROW_DOWN_KEY = 40;\nconst DEBOUNCE_WAIT = 300;\n\nexport interface NumberInputProps<TEmpty extends EmptyValue> extends Omit<\n InputProps,\n 'value' | 'onChange'\n> {\n value: NumberValue<TEmpty>;\n emptyValue: TEmpty;\n decimalPlaces?: number;\n useEmptyThousandsSeparator?: boolean;\n min?: number;\n max?: number;\n useKeyboardNavigation?: boolean;\n formatNumber?: FormatNumber;\n onChange(value: NumberValue<TEmpty>): void;\n}\n\nexport const NumberInput = <TEmpty extends EmptyValue>({\n value,\n onChange,\n onFocus,\n onBlur,\n emptyValue,\n decimalPlaces,\n useEmptyThousandsSeparator,\n min,\n max,\n useKeyboardNavigation,\n formatNumber = formatNumberDefault,\n ...props\n}: NumberInputProps<TEmpty>) => {\n const [\n {\n NumberFormat: {\n NumberGroupSeparator: thousandsSeparator = ',',\n NumberDecimalSeparator: decimalSeparator = '.',\n } = {},\n } = {},\n ] = useOptionalDependencies(CULTURE_TOKEN);\n\n const getFormattedValue = useCallback(\n () =>\n getFormattedString(\n value,\n {\n emptyValue,\n precision: decimalPlaces,\n separators: {\n thousand: useEmptyThousandsSeparator ? '' : thousandsSeparator,\n decimal: decimalSeparator,\n },\n },\n formatNumber\n ),\n [\n decimalPlaces,\n decimalSeparator,\n emptyValue,\n thousandsSeparator,\n useEmptyThousandsSeparator,\n value,\n formatNumber,\n ]\n );\n\n const [isFocused, setIsFocused] = useState(false);\n const [state, setState] = useState({\n numberValue: value,\n stringValue: getFormattedValue(),\n });\n\n useEffect(() => {\n if (isFocused) {\n return;\n }\n\n setState({\n numberValue: value,\n stringValue: getFormattedValue(),\n });\n }, [value, getFormattedValue, isFocused]);\n\n const handleChange = (_0: SyntheticEvent<HTMLInputElement>, { value }: InputOnChangeData) => {\n updateValue(value);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.keyCode === ARROW_UP_KEY || event.keyCode === ARROW_DOWN_KEY) {\n const newValue = (state.numberValue ?? 0) + (event.keyCode === ARROW_UP_KEY ? 1 : -1);\n\n updateValue(String(newValue));\n event.preventDefault();\n }\n };\n\n /*\n ** \"updateImmediateValue\" updates the value immediately without clamping min/max,\n ** then \"updateClampedValueDebounced\" updates applying the min/max after debounce delay\n **\n ** Example: User can type \"100\" if min is \"5\" without the \"1\" immediately being clamped\n */\n const updateImmediateValue = (value: string, silent = false) => {\n const newState = processValue(\n value,\n {\n emptyValue,\n precision: decimalPlaces,\n separators: {\n thousand: thousandsSeparator,\n decimal: decimalSeparator,\n },\n },\n formatNumber\n );\n\n setState(newState);\n\n if (!silent) {\n onChange(newState.numberValue);\n }\n };\n\n const updateClampedValueDebounced = useRef<(value: string, silent: boolean) => void>();\n\n useEffect(() => {\n let isCurrent = true;\n\n const updateClampedValue = (value: string, silent = false) => {\n if (isCurrent) {\n const newState = processValue(\n value,\n {\n emptyValue,\n precision: decimalPlaces,\n separators: {\n thousand: thousandsSeparator,\n decimal: decimalSeparator,\n },\n range: { min, max },\n },\n formatNumber\n );\n\n setState(newState);\n\n if (!silent) {\n onChange(newState.numberValue);\n }\n }\n };\n\n updateClampedValueDebounced.current = debounce(updateClampedValue, DEBOUNCE_WAIT);\n\n return () => {\n isCurrent = false;\n };\n }, [\n emptyValue,\n decimalPlaces,\n thousandsSeparator,\n decimalSeparator,\n min,\n max,\n formatNumber,\n onChange,\n ]);\n\n const updateValue = (value: string, silent = false) => {\n updateImmediateValue(value, silent);\n updateClampedValueDebounced.current?.(value, silent);\n };\n\n const handleFocus = (event: FocusEvent<HTMLInputElement>) => {\n if (state.stringValue.length) {\n updateValue(\n // prepare the value which user does see (rounded), but without trailing zeroes after decimal and separator\n decimalPlaces\n ? state.stringValue.replace(new RegExp(`[${decimalSeparator}]?0+$`), '')\n : state.stringValue,\n true\n );\n }\n\n setIsFocused(true);\n\n if (onFocus) {\n onFocus(event);\n }\n };\n\n const handleBlur = (event: FocusEvent<HTMLInputElement>) => {\n setState({\n numberValue: value,\n stringValue: getFormattedValue(),\n });\n\n setIsFocused(false);\n\n if (onBlur) {\n onBlur(event);\n }\n };\n\n return (\n <Input\n {...props}\n value={state.stringValue}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={useKeyboardNavigation ? handleKeyDown : undefined}\n />\n );\n};\n"],"names":["useCallback","useState","useEffect","useRef","useOptionalDependencies","Input","CULTURE_TOKEN","processValue","getFormattedString","formatNumber","formatNumberDefault","debounce","ARROW_UP_KEY","ARROW_DOWN_KEY","DEBOUNCE_WAIT","NumberInput","value","onChange","onFocus","onBlur","emptyValue","decimalPlaces","useEmptyThousandsSeparator","min","max","useKeyboardNavigation","props","NumberFormat","NumberGroupSeparator","thousandsSeparator","NumberDecimalSeparator","decimalSeparator","getFormattedValue","precision","separators","thousand","decimal","isFocused","setIsFocused","state","setState","numberValue","stringValue","handleChange","_0","updateValue","handleKeyDown","event","keyCode","newValue","String","preventDefault","updateImmediateValue","silent","newState","updateClampedValueDebounced","isCurrent","updateClampedValue","range","current","handleFocus","length","replace","RegExp","handleBlur","onKeyDown","undefined"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/form",
|
|
3
|
-
"version": "38.
|
|
3
|
+
"version": "38.2.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"homepage": "https://docs.st.dev/docs/frontend/form",
|
|
6
6
|
"repository": {
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
],
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@progress/kendo-react-dateinputs": "~5.5.0",
|
|
20
|
-
"@servicetitan/confirm": "^38.
|
|
21
|
-
"@servicetitan/culture": "^38.
|
|
20
|
+
"@servicetitan/confirm": "^38.2.0",
|
|
21
|
+
"@servicetitan/culture": "^38.2.0",
|
|
22
22
|
"@servicetitan/design-system": "~14.5.1",
|
|
23
|
-
"@servicetitan/form-state": "^38.
|
|
24
|
-
"@servicetitan/hash-browser-router": "^
|
|
25
|
-
"@servicetitan/react-ioc": "^
|
|
23
|
+
"@servicetitan/form-state": "^38.2.0",
|
|
24
|
+
"@servicetitan/hash-browser-router": "^34.0.1",
|
|
25
|
+
"@servicetitan/react-ioc": "^34.0.1",
|
|
26
26
|
"@servicetitan/tokens": ">=12.2.1",
|
|
27
|
-
"@servicetitan/web-components": "^
|
|
27
|
+
"@servicetitan/web-components": "^34.0.1",
|
|
28
28
|
"@types/js-cookie": "^3.0.3",
|
|
29
29
|
"@types/react": "~18.2.55",
|
|
30
30
|
"@types/react-input-mask": "~2.0.5",
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@progress/kendo-react-dateinputs": "~5.5.0",
|
|
42
|
-
"@servicetitan/confirm": "^38.
|
|
43
|
-
"@servicetitan/culture": "^38.
|
|
42
|
+
"@servicetitan/confirm": "^38.2.0",
|
|
43
|
+
"@servicetitan/culture": "^38.2.0",
|
|
44
44
|
"@servicetitan/design-system": ">=13.2.1",
|
|
45
|
-
"@servicetitan/form-state": "^38.
|
|
45
|
+
"@servicetitan/form-state": "^38.2.0",
|
|
46
46
|
"@servicetitan/react-ioc": ">21.0.0",
|
|
47
47
|
"@servicetitan/tokens": ">=12.2.1",
|
|
48
48
|
"accounting": "~0.4.1",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"less": true,
|
|
68
68
|
"webpack": false
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "b013c9f39c05c44f888a5bca5ff6aadb89cd7a6f"
|
|
71
71
|
}
|
|
@@ -24,8 +24,10 @@ const ARROW_UP_KEY = 38;
|
|
|
24
24
|
const ARROW_DOWN_KEY = 40;
|
|
25
25
|
const DEBOUNCE_WAIT = 300;
|
|
26
26
|
|
|
27
|
-
export interface NumberInputProps<TEmpty extends EmptyValue>
|
|
28
|
-
|
|
27
|
+
export interface NumberInputProps<TEmpty extends EmptyValue> extends Omit<
|
|
28
|
+
InputProps,
|
|
29
|
+
'value' | 'onChange'
|
|
30
|
+
> {
|
|
29
31
|
value: NumberValue<TEmpty>;
|
|
30
32
|
emptyValue: TEmpty;
|
|
31
33
|
decimalPlaces?: number;
|