@deephaven/components 0.13.7 → 0.13.9-uuid-filter.2

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.
@@ -7,6 +7,7 @@ declare type DateTimeInputProps = {
7
7
  onBlur?(): void;
8
8
  'data-testid'?: string;
9
9
  };
10
+ export declare function fixIncompleteValue(value: string): string;
10
11
  export declare function addSeparators(value: string): string;
11
12
  declare const DateTimeInput: React.ForwardRefExoticComponent<DateTimeInputProps & React.RefAttributes<HTMLInputElement>>;
12
13
  export default DateTimeInput;
@@ -1 +1 @@
1
- {"version":3,"file":"DateTimeInput.d.ts","sourceRoot":"","sources":["../src/DateTimeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAkBrD,aAAK,kBAAkB,GAAG;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,IAAI,IAAI,CAAC;IACjB,MAAM,CAAC,IAAI,IAAI,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKnD;AAMD,QAAA,MAAM,aAAa,6FA4ClB,CAAC;AAaF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"DateTimeInput.d.ts","sourceRoot":"","sources":["../src/DateTimeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAmBrD,aAAK,kBAAkB,GAAG;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,IAAI,IAAI,CAAC;IACjB,MAAM,CAAC,IAAI,IAAI,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOxD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKnD;AAMD,QAAA,MAAM,aAAa,6FAuDlB,CAAC;AAaF,eAAe,aAAa,CAAC"}
@@ -10,8 +10,16 @@ var DATE_PATTERN = '[12][0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])'; //
10
10
 
11
11
  var TIME_PATTERN = '([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\\.[0-9]{3}\u200B[0-9]{3}\u200B[0-9]{3}';
12
12
  var FULL_DATE_PATTERN = "".concat(DATE_PATTERN, " ").concat(TIME_PATTERN);
13
- var DEFAULT_VALUE_STRING = '2022-01-01 00:00:00.000000000';
13
+ var DATE_VALUE_STRING = '2022-01-01';
14
+ var DEFAULT_VALUE_STRING = "".concat(DATE_VALUE_STRING, " 00:00:00.000000000");
14
15
  var FULL_DATE_FORMAT = 'YYYY-MM-DD HH:MM:SS.SSSSSSSSS';
16
+ export function fixIncompleteValue(value) {
17
+ if (value != null && value.length >= DATE_VALUE_STRING.length) {
18
+ return "".concat(value.substring(0, DATE_VALUE_STRING.length)).concat(value.substring(DATE_VALUE_STRING.length).replace(/\u2007/g, '0')).concat(DEFAULT_VALUE_STRING.substring(value.length));
19
+ }
20
+
21
+ return value;
22
+ }
15
23
  export function addSeparators(value) {
16
24
  var dateTimeMillis = value.substring(0, 23);
17
25
  var micros = value.substring(23, 26);
@@ -36,8 +44,19 @@ var DateTimeInput = /*#__PURE__*/React.forwardRef((props, ref) => {
36
44
  var handleChange = useCallback(newValue => {
37
45
  log.debug('handleChange', newValue);
38
46
  setValue(newValue);
39
- onChange(removeSeparators(newValue));
47
+ onChange(fixIncompleteValue(removeSeparators(newValue)));
40
48
  }, [onChange]);
49
+ var handleBlur = useCallback(() => {
50
+ var prevValue = removeSeparators(value);
51
+ var fixedValue = fixIncompleteValue(prevValue); // Update the value displayed in the input
52
+ // onChange with the fixed value already triggered in handleChange
53
+
54
+ if (fixedValue !== prevValue) {
55
+ setValue(addSeparators(fixedValue));
56
+ }
57
+
58
+ onBlur();
59
+ }, [value, onBlur]);
41
60
  return /*#__PURE__*/React.createElement("div", {
42
61
  className: "d-flex flex-row align-items-center"
43
62
  }, /*#__PURE__*/React.createElement(MaskedInput, {
@@ -52,7 +71,7 @@ var DateTimeInput = /*#__PURE__*/React.forwardRef((props, ref) => {
52
71
  selection: selection,
53
72
  value: value,
54
73
  onFocus: onFocus,
55
- onBlur: onBlur,
74
+ onBlur: handleBlur,
56
75
  "data-testid": dataTestId
57
76
  }));
58
77
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/DateTimeInput.tsx"],"names":["React","useCallback","useState","classNames","Log","MaskedInput","getNextSegmentValue","log","module","DATE_PATTERN","TIME_PATTERN","FULL_DATE_PATTERN","DEFAULT_VALUE_STRING","FULL_DATE_FORMAT","addSeparators","value","dateTimeMillis","substring","micros","nanos","filter","v","join","removeSeparators","replace","EXAMPLES","DateTimeInput","forwardRef","props","ref","className","onChange","undefined","defaultValue","onFocus","onBlur","dataTestId","setValue","length","selection","setSelection","handleChange","newValue","debug","displayName","defaultProps"],"mappings":"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","sourcesContent":["import React, { useCallback, useState } from 'react';\nimport classNames from 'classnames';\nimport Log from '@deephaven/log';\nimport MaskedInput, { SelectionSegment } from './MaskedInput';\nimport { getNextSegmentValue } from './DateInputUtils';\n\nconst log = Log.module('DateTimeInput');\n\n// This could be more restrictive and restrict days to the number of days in the month...\n// But then gotta take leap year into account and everything.\nconst DATE_PATTERN = '[12][0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])';\n// Put zero width spaces in the nanosecond part of the date to allow jumping between segments\nconst TIME_PATTERN =\n '([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\\\\.[0-9]{3}\\u200B[0-9]{3}\\u200B[0-9]{3}';\nconst FULL_DATE_PATTERN = `${DATE_PATTERN} ${TIME_PATTERN}`;\nconst DEFAULT_VALUE_STRING = '2022-01-01 00:00:00.000000000';\nconst FULL_DATE_FORMAT = 'YYYY-MM-DD HH:MM:SS.SSSSSSSSS';\n\ntype DateTimeInputProps = {\n className?: string;\n onChange?(value?: string): void;\n defaultValue?: string;\n onFocus?(): void;\n onBlur?(): void;\n 'data-testid'?: string;\n};\n\nexport function addSeparators(value: string): string {\n const dateTimeMillis = value.substring(0, 23);\n const micros = value.substring(23, 26);\n const nanos = value.substring(26);\n return [dateTimeMillis, micros, nanos].filter(v => v !== '').join('\\u200B');\n}\n\nconst removeSeparators = (value: string) => value.replace(/\\u200B/g, '');\n\nconst EXAMPLES = [addSeparators(DEFAULT_VALUE_STRING)];\n\nconst DateTimeInput = React.forwardRef<HTMLInputElement, DateTimeInputProps>(\n (props: DateTimeInputProps, ref) => {\n const {\n className = '',\n onChange = () => undefined,\n defaultValue = '',\n onFocus = () => undefined,\n onBlur = () => undefined,\n 'data-testid': dataTestId,\n } = props;\n const [value, setValue] = useState(\n defaultValue.length > 0 ? addSeparators(defaultValue) : ''\n );\n const [selection, setSelection] = useState<SelectionSegment>();\n\n const handleChange = useCallback(\n (newValue: string): void => {\n log.debug('handleChange', newValue);\n setValue(newValue);\n onChange(removeSeparators(newValue));\n },\n [onChange]\n );\n\n return (\n <div className=\"d-flex flex-row align-items-center\">\n <MaskedInput\n ref={ref}\n className={classNames(className)}\n example={EXAMPLES}\n getNextSegmentValue={getNextSegmentValue}\n onChange={handleChange}\n onSelect={setSelection}\n pattern={FULL_DATE_PATTERN}\n placeholder={FULL_DATE_FORMAT}\n selection={selection}\n value={value}\n onFocus={onFocus}\n onBlur={onBlur}\n data-testid={dataTestId}\n />\n </div>\n );\n }\n);\n\nDateTimeInput.displayName = 'DateTimeInput';\n\nDateTimeInput.defaultProps = {\n className: '',\n onChange: () => undefined,\n defaultValue: '',\n onFocus: () => undefined,\n onBlur: () => undefined,\n 'data-testid': undefined,\n};\n\nexport default DateTimeInput;\n"],"file":"DateTimeInput.js"}
1
+ {"version":3,"sources":["../src/DateTimeInput.tsx"],"names":["React","useCallback","useState","classNames","Log","MaskedInput","getNextSegmentValue","log","module","DATE_PATTERN","TIME_PATTERN","FULL_DATE_PATTERN","DATE_VALUE_STRING","DEFAULT_VALUE_STRING","FULL_DATE_FORMAT","fixIncompleteValue","value","length","substring","replace","addSeparators","dateTimeMillis","micros","nanos","filter","v","join","removeSeparators","EXAMPLES","DateTimeInput","forwardRef","props","ref","className","onChange","undefined","defaultValue","onFocus","onBlur","dataTestId","setValue","selection","setSelection","handleChange","newValue","debug","handleBlur","prevValue","fixedValue","displayName","defaultProps"],"mappings":"AAAA,OAAOA,KAAP,IAAgBC,WAAhB,EAA6BC,QAA7B,QAA6C,OAA7C;AACA,OAAOC,UAAP,MAAuB,YAAvB;AACA,OAAOC,GAAP,MAAgB,gBAAhB;OACOC,W;SACEC,mB;AAET,IAAMC,GAAG,GAAGH,GAAG,CAACI,MAAJ,CAAW,eAAX,CAAZ,C,CAEA;AACA;;AACA,IAAMC,YAAY,GAAG,yDAArB,C,CACA;;AACA,IAAMC,YAAY,GAChB,iFADF;AAEA,IAAMC,iBAAiB,aAAMF,YAAN,cAAsBC,YAAtB,CAAvB;AACA,IAAME,iBAAiB,GAAG,YAA1B;AACA,IAAMC,oBAAoB,aAAMD,iBAAN,wBAA1B;AACA,IAAME,gBAAgB,GAAG,+BAAzB;AAWA,OAAO,SAASC,kBAAT,CAA4BC,KAA5B,EAAmD;AACxD,MAAIA,KAAK,IAAI,IAAT,IAAiBA,KAAK,CAACC,MAAN,IAAgBL,iBAAiB,CAACK,MAAvD,EAA+D;AAC7D,qBAAUD,KAAK,CAACE,SAAN,CAAgB,CAAhB,EAAmBN,iBAAiB,CAACK,MAArC,CAAV,SAAyDD,KAAK,CAC3DE,SADsD,CAC5CN,iBAAiB,CAACK,MAD0B,EAEtDE,OAFsD,CAE9C,SAF8C,EAEnC,GAFmC,CAAzD,SAE6BN,oBAAoB,CAACK,SAArB,CAA+BF,KAAK,CAACC,MAArC,CAF7B;AAGD;;AACD,SAAOD,KAAP;AACD;AAED,OAAO,SAASI,aAAT,CAAuBJ,KAAvB,EAA8C;AACnD,MAAMK,cAAc,GAAGL,KAAK,CAACE,SAAN,CAAgB,CAAhB,EAAmB,EAAnB,CAAvB;AACA,MAAMI,MAAM,GAAGN,KAAK,CAACE,SAAN,CAAgB,EAAhB,EAAoB,EAApB,CAAf;AACA,MAAMK,KAAK,GAAGP,KAAK,CAACE,SAAN,CAAgB,EAAhB,CAAd;AACA,SAAO,CAACG,cAAD,EAAiBC,MAAjB,EAAyBC,KAAzB,EAAgCC,MAAhC,CAAuCC,CAAC,IAAIA,CAAC,KAAK,EAAlD,EAAsDC,IAAtD,CAA2D,QAA3D,CAAP;AACD;;AAED,IAAMC,gBAAgB,GAAIX,KAAD,IAAmBA,KAAK,CAACG,OAAN,CAAc,SAAd,EAAyB,EAAzB,CAA5C;;AAEA,IAAMS,QAAQ,GAAG,CAACR,aAAa,CAACP,oBAAD,CAAd,CAAjB;AAEA,IAAMgB,aAAa,gBAAG7B,KAAK,CAAC8B,UAAN,CACpB,CAACC,KAAD,EAA4BC,GAA5B,KAAoC;AAClC,MAAM;AACJC,IAAAA,SAAS,GAAG,EADR;AAEJC,IAAAA,QAAQ,GAAG,MAAMC,SAFb;AAGJC,IAAAA,YAAY,GAAG,EAHX;AAIJC,IAAAA,OAAO,GAAG,MAAMF,SAJZ;AAKJG,IAAAA,MAAM,GAAG,MAAMH,SALX;AAMJ,mBAAeI;AANX,MAOFR,KAPJ;AAQA,MAAM,CAACf,KAAD,EAAQwB,QAAR,IAAoBtC,QAAQ,CAChCkC,YAAY,CAACnB,MAAb,GAAsB,CAAtB,GAA0BG,aAAa,CAACgB,YAAD,CAAvC,GAAwD,EADxB,CAAlC;AAGA,MAAM,CAACK,SAAD,EAAYC,YAAZ,IAA4BxC,QAAQ,EAA1C;AAEA,MAAMyC,YAAY,GAAG1C,WAAW,CAC7B2C,QAAD,IAA4B;AAC1BrC,IAAAA,GAAG,CAACsC,KAAJ,CAAU,cAAV,EAA0BD,QAA1B;AACAJ,IAAAA,QAAQ,CAACI,QAAD,CAAR;AACAV,IAAAA,QAAQ,CAACnB,kBAAkB,CAACY,gBAAgB,CAACiB,QAAD,CAAjB,CAAnB,CAAR;AACD,GAL6B,EAM9B,CAACV,QAAD,CAN8B,CAAhC;AASA,MAAMY,UAAU,GAAG7C,WAAW,CAAC,MAAY;AACzC,QAAM8C,SAAS,GAAGpB,gBAAgB,CAACX,KAAD,CAAlC;AACA,QAAMgC,UAAU,GAAGjC,kBAAkB,CAACgC,SAAD,CAArC,CAFyC,CAGzC;AACA;;AACA,QAAIC,UAAU,KAAKD,SAAnB,EAA8B;AAC5BP,MAAAA,QAAQ,CAACpB,aAAa,CAAC4B,UAAD,CAAd,CAAR;AACD;;AACDV,IAAAA,MAAM;AACP,GAT6B,EAS3B,CAACtB,KAAD,EAAQsB,MAAR,CAT2B,CAA9B;AAWA,sBACE;AAAK,IAAA,SAAS,EAAC;AAAf,kBACE,oBAAC,WAAD;AACE,IAAA,GAAG,EAAEN,GADP;AAEE,IAAA,SAAS,EAAE7B,UAAU,CAAC8B,SAAD,CAFvB;AAGE,IAAA,OAAO,EAAEL,QAHX;AAIE,IAAA,mBAAmB,EAAEtB,mBAJvB;AAKE,IAAA,QAAQ,EAAEqC,YALZ;AAME,IAAA,QAAQ,EAAED,YANZ;AAOE,IAAA,OAAO,EAAE/B,iBAPX;AAQE,IAAA,WAAW,EAAEG,gBARf;AASE,IAAA,SAAS,EAAE2B,SATb;AAUE,IAAA,KAAK,EAAEzB,KAVT;AAWE,IAAA,OAAO,EAAEqB,OAXX;AAYE,IAAA,MAAM,EAAES,UAZV;AAaE,mBAAaP;AAbf,IADF,CADF;AAmBD,CAtDmB,CAAtB;AAyDAV,aAAa,CAACoB,WAAd,GAA4B,eAA5B;AAEApB,aAAa,CAACqB,YAAd,GAA6B;AAC3BjB,EAAAA,SAAS,EAAE,EADgB;AAE3BC,EAAAA,QAAQ,EAAE,MAAMC,SAFW;AAG3BC,EAAAA,YAAY,EAAE,EAHa;AAI3BC,EAAAA,OAAO,EAAE,MAAMF,SAJY;AAK3BG,EAAAA,MAAM,EAAE,MAAMH,SALa;AAM3B,iBAAeA;AANY,CAA7B;AASA,eAAeN,aAAf","sourcesContent":["import React, { useCallback, useState } from 'react';\nimport classNames from 'classnames';\nimport Log from '@deephaven/log';\nimport MaskedInput, { SelectionSegment } from './MaskedInput';\nimport { getNextSegmentValue } from './DateInputUtils';\n\nconst log = Log.module('DateTimeInput');\n\n// This could be more restrictive and restrict days to the number of days in the month...\n// But then gotta take leap year into account and everything.\nconst DATE_PATTERN = '[12][0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])';\n// Put zero width spaces in the nanosecond part of the date to allow jumping between segments\nconst TIME_PATTERN =\n '([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\\\\.[0-9]{3}\\u200B[0-9]{3}\\u200B[0-9]{3}';\nconst FULL_DATE_PATTERN = `${DATE_PATTERN} ${TIME_PATTERN}`;\nconst DATE_VALUE_STRING = '2022-01-01';\nconst DEFAULT_VALUE_STRING = `${DATE_VALUE_STRING} 00:00:00.000000000`;\nconst FULL_DATE_FORMAT = 'YYYY-MM-DD HH:MM:SS.SSSSSSSSS';\n\ntype DateTimeInputProps = {\n className?: string;\n onChange?(value?: string): void;\n defaultValue?: string;\n onFocus?(): void;\n onBlur?(): void;\n 'data-testid'?: string;\n};\n\nexport function fixIncompleteValue(value: string): string {\n if (value != null && value.length >= DATE_VALUE_STRING.length) {\n return `${value.substring(0, DATE_VALUE_STRING.length)}${value\n .substring(DATE_VALUE_STRING.length)\n .replace(/\\u2007/g, '0')}${DEFAULT_VALUE_STRING.substring(value.length)}`;\n }\n return value;\n}\n\nexport function addSeparators(value: string): string {\n const dateTimeMillis = value.substring(0, 23);\n const micros = value.substring(23, 26);\n const nanos = value.substring(26);\n return [dateTimeMillis, micros, nanos].filter(v => v !== '').join('\\u200B');\n}\n\nconst removeSeparators = (value: string) => value.replace(/\\u200B/g, '');\n\nconst EXAMPLES = [addSeparators(DEFAULT_VALUE_STRING)];\n\nconst DateTimeInput = React.forwardRef<HTMLInputElement, DateTimeInputProps>(\n (props: DateTimeInputProps, ref) => {\n const {\n className = '',\n onChange = () => undefined,\n defaultValue = '',\n onFocus = () => undefined,\n onBlur = () => undefined,\n 'data-testid': dataTestId,\n } = props;\n const [value, setValue] = useState(\n defaultValue.length > 0 ? addSeparators(defaultValue) : ''\n );\n const [selection, setSelection] = useState<SelectionSegment>();\n\n const handleChange = useCallback(\n (newValue: string): void => {\n log.debug('handleChange', newValue);\n setValue(newValue);\n onChange(fixIncompleteValue(removeSeparators(newValue)));\n },\n [onChange]\n );\n\n const handleBlur = useCallback((): void => {\n const prevValue = removeSeparators(value);\n const fixedValue = fixIncompleteValue(prevValue);\n // Update the value displayed in the input\n // onChange with the fixed value already triggered in handleChange\n if (fixedValue !== prevValue) {\n setValue(addSeparators(fixedValue));\n }\n onBlur();\n }, [value, onBlur]);\n\n return (\n <div className=\"d-flex flex-row align-items-center\">\n <MaskedInput\n ref={ref}\n className={classNames(className)}\n example={EXAMPLES}\n getNextSegmentValue={getNextSegmentValue}\n onChange={handleChange}\n onSelect={setSelection}\n pattern={FULL_DATE_PATTERN}\n placeholder={FULL_DATE_FORMAT}\n selection={selection}\n value={value}\n onFocus={onFocus}\n onBlur={handleBlur}\n data-testid={dataTestId}\n />\n </div>\n );\n }\n);\n\nDateTimeInput.displayName = 'DateTimeInput';\n\nDateTimeInput.defaultProps = {\n className: '',\n onChange: () => undefined,\n defaultValue: '',\n onFocus: () => undefined,\n onBlur: () => undefined,\n 'data-testid': undefined,\n};\n\nexport default DateTimeInput;\n"],"file":"DateTimeInput.js"}
@@ -1 +1 @@
1
- {"version":3,"file":"EditableItemList.d.ts","sourceRoot":"","sources":["../src/EditableItemList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAOf,UAAU,qBAAqB;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,GAAG,IAAI,CAAC;CAC3C;AAGD,QAAA,MAAM,gBAAgB,UAAW,qBAAqB,KAAG,MAAM,YA0H9D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"EditableItemList.d.ts","sourceRoot":"","sources":["../src/EditableItemList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAMN,MAAM,OAAO,CAAC;AAOf,UAAU,qBAAqB;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,GAAG,IAAI,CAAC;CAC3C;AAGD,QAAA,MAAM,gBAAgB,UAAW,qBAAqB,KAAG,MAAM,YA+H9D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -29,6 +29,10 @@ var EditableItemList = props => {
29
29
  setSelectedIndex(newIndex === -1 ? undefined : newIndex);
30
30
  }, [items, selectedIndex, onDelete]);
31
31
  var handleAdd = useCallback(() => {
32
+ if (value === '') {
33
+ return;
34
+ }
35
+
32
36
  var validationError = validate(value);
33
37
 
34
38
  if (validationError == null) {
@@ -43,7 +47,7 @@ var EditableItemList = props => {
43
47
  value: inputValue
44
48
  } = event.target;
45
49
  setValue(inputValue);
46
- setInputError(validate(inputValue));
50
+ setInputError(inputValue === '' ? null : validate(inputValue));
47
51
  }, [validate]);
48
52
  var handleInputFocus = useCallback(() => {
49
53
  setSelectedIndex(undefined);
@@ -91,15 +95,17 @@ var EditableItemList = props => {
91
95
  }, /*#__PURE__*/React.createElement(Button, {
92
96
  kind: "ghost",
93
97
  onClick: handleAdd,
94
- disabled: inputError != null || value == null || value === '',
98
+ disabled: inputError != null || value === '',
95
99
  icon: vsAdd,
96
- tooltip: "Add new item"
100
+ tooltip: "Add new item",
101
+ "data-testid": "add-item-button"
97
102
  }), /*#__PURE__*/React.createElement(Button, {
98
103
  kind: "ghost",
99
104
  onClick: handleDelete,
100
105
  disabled: selectedIndex === undefined,
101
106
  icon: vsTrash,
102
- tooltip: "Delete selected item"
107
+ tooltip: "Delete selected item",
108
+ "data-testid": "delete-item-button"
103
109
  }))));
104
110
  };
105
111
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/EditableItemList.tsx"],"names":["React","useCallback","useMemo","useState","classNames","clamp","vsAdd","vsTrash","Button","ItemList","EditableItemList","props","isInvalid","items","onAdd","undefined","onDelete","validate","inputError","setInputError","selectedIndex","setSelectedIndex","value","setValue","handleSelect","index","handleDelete","newIndex","length","handleAdd","validationError","handleInputChange","event","inputValue","target","handleInputFocus","handleInputKeyDown","key","selectedRanges","containerHeight","DEFAULT_ROW_HEIGHT","height","map","item","isSelected"],"mappings":"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","sourcesContent":["import React, {\n ChangeEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useState,\n} from 'react';\nimport classNames from 'classnames';\nimport clamp from 'lodash.clamp';\nimport { vsAdd, vsTrash } from '@deephaven/icons';\nimport { Range } from '@deephaven/utils';\nimport { Button, ItemList } from '.';\n\ninterface EditableItemListProps {\n isInvalid?: boolean;\n items: string[];\n onDelete: (item: string) => void;\n onAdd: (item: string) => void;\n validate?: (item: string) => Error | null;\n}\n\n// Display a list of items with an input for adding new items, and Add/Delete buttons\nconst EditableItemList = (props: EditableItemListProps): React.ReactElement => {\n const {\n isInvalid = false,\n items,\n onAdd = () => undefined,\n onDelete = () => undefined,\n validate = () => null,\n } = props;\n const [inputError, setInputError] = useState<Error | null>(null);\n const [selectedIndex, setSelectedIndex] = useState<number | undefined>();\n const [value, setValue] = useState('');\n\n const handleSelect = useCallback(index => {\n setSelectedIndex(index);\n }, []);\n\n const handleDelete = useCallback(() => {\n const newIndex =\n selectedIndex === items.length - 1 ? items.length - 2 : selectedIndex;\n if (\n selectedIndex !== undefined &&\n selectedIndex >= 0 &&\n selectedIndex < items.length\n ) {\n onDelete(items[selectedIndex]);\n }\n setSelectedIndex(newIndex === -1 ? undefined : newIndex);\n }, [items, selectedIndex, onDelete]);\n\n const handleAdd = useCallback(() => {\n const validationError = validate(value);\n if (validationError == null) {\n onAdd(value);\n setValue('');\n } else {\n setInputError(validationError);\n }\n }, [value, onAdd, validate]);\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n const { value: inputValue } = event.target;\n setValue(inputValue);\n setInputError(validate(inputValue));\n },\n [validate]\n );\n\n const handleInputFocus = useCallback(() => {\n setSelectedIndex(undefined);\n }, []);\n\n const handleInputKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (event.key === 'Enter') {\n handleAdd();\n }\n },\n [handleAdd]\n );\n\n const selectedRanges = useMemo(\n (): Range[] =>\n selectedIndex === undefined ? [] : [[selectedIndex, selectedIndex]],\n [selectedIndex]\n );\n const containerHeight = useMemo(\n (): number => 14 + clamp(items.length, 1, 6) * ItemList.DEFAULT_ROW_HEIGHT,\n [items.length]\n );\n\n return (\n <div\n className={classNames('editable-item-list-container', {\n 'is-invalid': isInvalid,\n })}\n >\n <div style={{ height: containerHeight }}>\n <ItemList\n itemCount={items.length}\n items={items.map((item, index) => ({\n value: item,\n isSelected: index === selectedIndex,\n }))}\n offset={0}\n onSelect={handleSelect}\n selectedRanges={selectedRanges}\n />\n </div>\n <div className=\"d-flex flex-row pt-2\">\n <div className=\"d-flex flex-grow-1\">\n <input\n className={classNames('form-control', {\n 'is-invalid': inputError != null,\n })}\n placeholder=\"Enter value\"\n type=\"text\"\n value={value}\n onChange={handleInputChange}\n onFocus={handleInputFocus}\n onKeyDown={handleInputKeyDown}\n />\n </div>\n <div className=\"d-flex align-items-start mt-1 ml-2\">\n <Button\n kind=\"ghost\"\n onClick={handleAdd}\n disabled={inputError != null || value == null || value === ''}\n icon={vsAdd}\n tooltip=\"Add new item\"\n />\n <Button\n kind=\"ghost\"\n onClick={handleDelete}\n disabled={selectedIndex === undefined}\n icon={vsTrash}\n tooltip=\"Delete selected item\"\n />\n </div>\n </div>\n </div>\n );\n};\n\nexport default EditableItemList;\n"],"file":"EditableItemList.js"}
1
+ {"version":3,"sources":["../src/EditableItemList.tsx"],"names":["React","useCallback","useMemo","useState","classNames","clamp","vsAdd","vsTrash","Button","ItemList","EditableItemList","props","isInvalid","items","onAdd","undefined","onDelete","validate","inputError","setInputError","selectedIndex","setSelectedIndex","value","setValue","handleSelect","index","handleDelete","newIndex","length","handleAdd","validationError","handleInputChange","event","inputValue","target","handleInputFocus","handleInputKeyDown","key","selectedRanges","containerHeight","DEFAULT_ROW_HEIGHT","height","map","item","isSelected"],"mappings":"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","sourcesContent":["import React, {\n ChangeEvent,\n KeyboardEvent,\n useCallback,\n useMemo,\n useState,\n} from 'react';\nimport classNames from 'classnames';\nimport clamp from 'lodash.clamp';\nimport { vsAdd, vsTrash } from '@deephaven/icons';\nimport { Range } from '@deephaven/utils';\nimport { Button, ItemList } from '.';\n\ninterface EditableItemListProps {\n isInvalid?: boolean;\n items: string[];\n onDelete: (item: string) => void;\n onAdd: (item: string) => void;\n validate?: (item: string) => Error | null;\n}\n\n// Display a list of items with an input for adding new items, and Add/Delete buttons\nconst EditableItemList = (props: EditableItemListProps): React.ReactElement => {\n const {\n isInvalid = false,\n items,\n onAdd = () => undefined,\n onDelete = () => undefined,\n validate = () => null,\n } = props;\n const [inputError, setInputError] = useState<Error | null>(null);\n const [selectedIndex, setSelectedIndex] = useState<number | undefined>();\n const [value, setValue] = useState('');\n\n const handleSelect = useCallback(index => {\n setSelectedIndex(index);\n }, []);\n\n const handleDelete = useCallback(() => {\n const newIndex =\n selectedIndex === items.length - 1 ? items.length - 2 : selectedIndex;\n if (\n selectedIndex !== undefined &&\n selectedIndex >= 0 &&\n selectedIndex < items.length\n ) {\n onDelete(items[selectedIndex]);\n }\n setSelectedIndex(newIndex === -1 ? undefined : newIndex);\n }, [items, selectedIndex, onDelete]);\n\n const handleAdd = useCallback(() => {\n if (value === '') {\n return;\n }\n const validationError = validate(value);\n if (validationError == null) {\n onAdd(value);\n setValue('');\n } else {\n setInputError(validationError);\n }\n }, [value, onAdd, validate]);\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n const { value: inputValue } = event.target;\n setValue(inputValue);\n setInputError(inputValue === '' ? null : validate(inputValue));\n },\n [validate]\n );\n\n const handleInputFocus = useCallback(() => {\n setSelectedIndex(undefined);\n }, []);\n\n const handleInputKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (event.key === 'Enter') {\n handleAdd();\n }\n },\n [handleAdd]\n );\n\n const selectedRanges = useMemo(\n (): Range[] =>\n selectedIndex === undefined ? [] : [[selectedIndex, selectedIndex]],\n [selectedIndex]\n );\n const containerHeight = useMemo(\n (): number => 14 + clamp(items.length, 1, 6) * ItemList.DEFAULT_ROW_HEIGHT,\n [items.length]\n );\n\n return (\n <div\n className={classNames('editable-item-list-container', {\n 'is-invalid': isInvalid,\n })}\n >\n <div style={{ height: containerHeight }}>\n <ItemList\n itemCount={items.length}\n items={items.map((item, index) => ({\n value: item,\n isSelected: index === selectedIndex,\n }))}\n offset={0}\n onSelect={handleSelect}\n selectedRanges={selectedRanges}\n />\n </div>\n <div className=\"d-flex flex-row pt-2\">\n <div className=\"d-flex flex-grow-1\">\n <input\n className={classNames('form-control', {\n 'is-invalid': inputError != null,\n })}\n placeholder=\"Enter value\"\n type=\"text\"\n value={value}\n onChange={handleInputChange}\n onFocus={handleInputFocus}\n onKeyDown={handleInputKeyDown}\n />\n </div>\n <div className=\"d-flex align-items-start mt-1 ml-2\">\n <Button\n kind=\"ghost\"\n onClick={handleAdd}\n disabled={inputError != null || value === ''}\n icon={vsAdd}\n tooltip=\"Add new item\"\n data-testid=\"add-item-button\"\n />\n <Button\n kind=\"ghost\"\n onClick={handleDelete}\n disabled={selectedIndex === undefined}\n icon={vsTrash}\n tooltip=\"Delete selected item\"\n data-testid=\"delete-item-button\"\n />\n </div>\n </div>\n </div>\n );\n};\n\nexport default EditableItemList;\n"],"file":"EditableItemList.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deephaven/components",
3
- "version": "0.13.7",
3
+ "version": "0.13.9-uuid-filter.2+26442b8",
4
4
  "description": "Deephaven React component library",
5
5
  "author": "Deephaven Data Labs LLC",
6
6
  "license": "Apache-2.0",
@@ -30,10 +30,10 @@
30
30
  "start": "cross-env NODE_ENV=development npm run watch"
31
31
  },
32
32
  "dependencies": {
33
- "@deephaven/icons": "^0.13.0",
34
- "@deephaven/log": "^0.13.0",
35
- "@deephaven/react-hooks": "^0.13.0",
36
- "@deephaven/utils": "^0.13.0",
33
+ "@deephaven/icons": "^0.13.9-uuid-filter.2+26442b8",
34
+ "@deephaven/log": "^0.13.9-uuid-filter.2+26442b8",
35
+ "@deephaven/react-hooks": "^0.13.9-uuid-filter.2+26442b8",
36
+ "@deephaven/utils": "^0.13.9-uuid-filter.2+26442b8",
37
37
  "@fortawesome/fontawesome-svg-core": "1.2.36",
38
38
  "@fortawesome/react-fontawesome": "^0.1.15",
39
39
  "bootstrap": "4.6.1",
@@ -58,8 +58,8 @@
58
58
  "react-dom": "^17.x"
59
59
  },
60
60
  "devDependencies": {
61
- "@deephaven/mocks": "^0.13.0",
62
- "@deephaven/tsconfig": "^0.13.0"
61
+ "@deephaven/mocks": "^0.13.9-uuid-filter.2+26442b8",
62
+ "@deephaven/tsconfig": "^0.13.9-uuid-filter.2+26442b8"
63
63
  },
64
64
  "files": [
65
65
  "dist",
@@ -71,5 +71,5 @@
71
71
  "publishConfig": {
72
72
  "access": "public"
73
73
  },
74
- "gitHead": "0f9ce526883e2d117359ccc232c10aaa09405554"
74
+ "gitHead": "26442b88756cfe4f515a98e51697a7f006e65e1f"
75
75
  }