@deephaven/components 1.14.0 → 1.16.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.
@@ -1 +1 @@
1
- {"version":3,"file":"DateTimeInput.d.ts","sourceRoot":"","sources":["../src/DateTimeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,aAAa,EAAyB,MAAM,OAAO,CAAC;AAoBzE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAiBF,eAAO,MAAM,aAAa,6FA0DxB,CAAC;AAIH,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"DateTimeInput.d.ts","sourceRoot":"","sources":["../src/DateTimeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,KAAK,aAAa,EAInB,MAAM,OAAO,CAAC;AAoBf,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAiBF,eAAO,MAAM,aAAa,6FAoGxB,CAAC;AAIH,eAAe,aAAa,CAAC"}
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useState } from 'react';
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
2
  import classNames from 'classnames';
3
3
  import Log from '@deephaven/log';
4
4
  import MaskedInput from "./MaskedInput.js";
@@ -38,6 +38,44 @@ export var DateTimeInput = /*#__PURE__*/React.forwardRef((props, ref) => {
38
38
  } = props;
39
39
  var [value, setValue] = useState(defaultValue.length > 0 ? addSeparators(defaultValue) : '');
40
40
  var [selection, setSelection] = useState();
41
+
42
+ /**
43
+ * Normalize text by:
44
+ * - Replacing 'T' with space to support ISO 8601 format
45
+ * - Removing timezone information (e.g., "EDT", "+05:00", "Z")
46
+ * - Adding zero-width space separators in the nanosecond part
47
+ * @param text The text
48
+ * @returns The normalized text
49
+ */
50
+ var normalizeText = useCallback(text => {
51
+ // Replace first 'T' separator with space for ISO 8601 format (without global flag to preserve 'T' in timezone like EDT)
52
+ var normalized = text.replace(/T/, ' ');
53
+
54
+ // Remove timezone information
55
+ // Match datetime up to optional fractional seconds, then strip everything else
56
+ // Pattern: YYYY-MM-DD HH:MM:SS[.SSSSSSSSS] followed by optional timezone
57
+ var dateTimeMatch = normalized.match(/^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}(?:\.\d+)?)/);
58
+ if (dateTimeMatch) {
59
+ [, normalized] = dateTimeMatch;
60
+ }
61
+
62
+ // Add zero-width space separators to match the expected pattern
63
+ return addSeparators(normalized);
64
+ }, []);
65
+
66
+ // Sync internal state with defaultValue prop when it changes
67
+ // Apply normalization to handle raw unformatted values (e.g., with timezone info)
68
+ useEffect(() => {
69
+ if (defaultValue.length > 0) {
70
+ var normalized = normalizeText(defaultValue);
71
+ setValue(normalized);
72
+ // Notify parent with the normalized value (without separators)
73
+ onChange(fixIncompleteValue(removeSeparators(normalized)));
74
+ } else {
75
+ setValue('');
76
+ onChange('');
77
+ }
78
+ }, [defaultValue, normalizeText, onChange]);
41
79
  var handleChange = useCallback(newValue => {
42
80
  log.debug('handleChange', newValue);
43
81
  setValue(newValue);
@@ -60,6 +98,7 @@ export var DateTimeInput = /*#__PURE__*/React.forwardRef((props, ref) => {
60
98
  className: classNames(className),
61
99
  example: EXAMPLES,
62
100
  getNextSegmentValue: getNextSegmentValue,
101
+ normalizePastedText: normalizeText,
63
102
  onChange: handleChange,
64
103
  onSelect: setSelection,
65
104
  onSubmit: onSubmit,
@@ -1 +1 @@
1
- {"version":3,"file":"DateTimeInput.js","names":["React","useCallback","useState","classNames","Log","MaskedInput","getNextSegmentValue","addSeparators","jsx","_jsx","log","module","DATE_PATTERN","TIME_PATTERN","FULL_DATE_PATTERN","concat","DATE_VALUE_STRING","DEFAULT_VALUE_STRING","FULL_DATE_FORMAT","fixIncompleteValue","value","length","substring","replace","removeSeparators","EXAMPLES","DateTimeInput","forwardRef","props","ref","className","onChange","undefined","defaultValue","onFocus","onBlur","onSubmit","dataTestId","setValue","selection","setSelection","handleChange","newValue","debug","handleBlur","prevValue","fixedValue","children","example","onSelect","pattern","placeholder","displayName"],"sources":["../src/DateTimeInput.tsx"],"sourcesContent":["import React, { type KeyboardEvent, useCallback, useState } from 'react';\nimport classNames from 'classnames';\nimport Log from '@deephaven/log';\nimport MaskedInput, { type SelectionSegment } from './MaskedInput';\nimport { getNextSegmentValue } from './DateInputUtils';\nimport { addSeparators } from './DateTimeInputUtils';\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\nexport type DateTimeInputProps = {\n className?: string;\n onChange?: (value: string) => void;\n defaultValue?: string;\n onFocus?: () => void;\n onBlur?: () => void;\n onSubmit?: (event: KeyboardEvent<HTMLInputElement>) => void;\n 'data-testid'?: string;\n};\n\nfunction 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\nfunction removeSeparators(value: string): string {\n return value.replace(/\\u200B/g, '');\n}\n\nconst EXAMPLES = [addSeparators(DEFAULT_VALUE_STRING)];\n\nexport const DateTimeInput = React.forwardRef<\n HTMLInputElement,\n DateTimeInputProps\n>((props, ref) => {\n const {\n className = '',\n onChange = () => undefined,\n defaultValue = '',\n onFocus = () => undefined,\n onBlur = () => undefined,\n onSubmit,\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 onSubmit={onSubmit}\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\nDateTimeInput.displayName = 'DateTimeInput';\n\nexport default DateTimeInput;\n"],"mappings":"AAAA,OAAOA,KAAK,IAAwBC,WAAW,EAAEC,QAAQ,QAAQ,OAAO;AACxE,OAAOC,UAAU,MAAM,YAAY;AACnC,OAAOC,GAAG,MAAM,gBAAgB;AAAC,OAC1BC,WAAW;AAAA,SACTC,mBAAmB;AAAA,SACnBC,aAAa;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAEtB,IAAMC,GAAG,GAAGN,GAAG,CAACO,MAAM,CAAC,eAAe,CAAC;;AAEvC;AACA;AACA,IAAMC,YAAY,GAAG,yDAAyD;AAC9E;AACA,IAAMC,YAAY,GAChB,iFAAiF;AACnF,IAAMC,iBAAiB,MAAAC,MAAA,CAAMH,YAAY,OAAAG,MAAA,CAAIF,YAAY,CAAE;AAC3D,IAAMG,iBAAiB,GAAG,YAAY;AACtC,IAAMC,oBAAoB,MAAAF,MAAA,CAAMC,iBAAiB,wBAAqB;AACtE,IAAME,gBAAgB,GAAG,+BAA+B;AAYxD,SAASC,kBAAkBA,CAACC,KAAa,EAAU;EACjD,IAAIA,KAAK,IAAI,IAAI,IAAIA,KAAK,CAACC,MAAM,IAAIL,iBAAiB,CAACK,MAAM,EAAE;IAC7D,UAAAN,MAAA,CAAUK,KAAK,CAACE,SAAS,CAAC,CAAC,EAAEN,iBAAiB,CAACK,MAAM,CAAC,EAAAN,MAAA,CAAGK,KAAK,CAC3DE,SAAS,CAACN,iBAAiB,CAACK,MAAM,CAAC,CACnCE,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,EAAAR,MAAA,CAAGE,oBAAoB,CAACK,SAAS,CAACF,KAAK,CAACC,MAAM,CAAC;EAC3E;EACA,OAAOD,KAAK;AACd;AAEA,SAASI,gBAAgBA,CAACJ,KAAa,EAAU;EAC/C,OAAOA,KAAK,CAACG,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;AACrC;AAEA,IAAME,QAAQ,GAAG,CAAClB,aAAa,CAACU,oBAAoB,CAAC,CAAC;AAEtD,OAAO,IAAMS,aAAa,gBAAG1B,KAAK,CAAC2B,UAAU,CAG3C,CAACC,KAAK,EAAEC,GAAG,KAAK;EAChB,IAAM;IACJC,SAAS,GAAG,EAAE;IACdC,QAAQ,GAAGA,CAAA,KAAMC,SAAS;IAC1BC,YAAY,GAAG,EAAE;IACjBC,OAAO,GAAGA,CAAA,KAAMF,SAAS;IACzBG,MAAM,GAAGA,CAAA,KAAMH,SAAS;IACxBI,QAAQ;IACR,aAAa,EAAEC;EACjB,CAAC,GAAGT,KAAK;EACT,IAAM,CAACR,KAAK,EAAEkB,QAAQ,CAAC,GAAGpC,QAAQ,CAChC+B,YAAY,CAACZ,MAAM,GAAG,CAAC,GAAGd,aAAa,CAAC0B,YAAY,CAAC,GAAG,EAC1D,CAAC;EACD,IAAM,CAACM,SAAS,EAAEC,YAAY,CAAC,GAAGtC,QAAQ,CAAmB,CAAC;EAE9D,IAAMuC,YAAY,GAAGxC,WAAW,CAC7ByC,QAAgB,IAAW;IAC1BhC,GAAG,CAACiC,KAAK,CAAC,cAAc,EAAED,QAAQ,CAAC;IACnCJ,QAAQ,CAACI,QAAQ,CAAC;IAClBX,QAAQ,CAACZ,kBAAkB,CAACK,gBAAgB,CAACkB,QAAQ,CAAC,CAAC,CAAC;EAC1D,CAAC,EACD,CAACX,QAAQ,CACX,CAAC;EAED,IAAMa,UAAU,GAAG3C,WAAW,CAAC,MAAY;IACzC,IAAM4C,SAAS,GAAGrB,gBAAgB,CAACJ,KAAK,CAAC;IACzC,IAAM0B,UAAU,GAAG3B,kBAAkB,CAAC0B,SAAS,CAAC;IAChD;IACA;IACA,IAAIC,UAAU,KAAKD,SAAS,EAAE;MAC5BP,QAAQ,CAAC/B,aAAa,CAACuC,UAAU,CAAC,CAAC;IACrC;IACAX,MAAM,CAAC,CAAC;EACV,CAAC,EAAE,CAACf,KAAK,EAAEe,MAAM,CAAC,CAAC;EAEnB,oBACE1B,IAAA;IAAKqB,SAAS,EAAC,oCAAoC;IAAAiB,QAAA,eACjDtC,IAAA,CAACJ,WAAW;MACVwB,GAAG,EAAEA,GAAI;MACTC,SAAS,EAAE3B,UAAU,CAAC2B,SAAS,CAAE;MACjCkB,OAAO,EAAEvB,QAAS;MAClBnB,mBAAmB,EAAEA,mBAAoB;MACzCyB,QAAQ,EAAEU,YAAa;MACvBQ,QAAQ,EAAET,YAAa;MACvBJ,QAAQ,EAAEA,QAAS;MACnBc,OAAO,EAAEpC,iBAAkB;MAC3BqC,WAAW,EAAEjC,gBAAiB;MAC9BqB,SAAS,EAAEA,SAAU;MACrBnB,KAAK,EAAEA,KAAM;MACbc,OAAO,EAAEA,OAAQ;MACjBC,MAAM,EAAES,UAAW;MACnB,eAAaP;IAAW,CACzB;EAAC,CACC,CAAC;AAEV,CAAC,CAAC;AAEFX,aAAa,CAAC0B,WAAW,GAAG,eAAe;AAE3C,eAAe1B,aAAa","ignoreList":[]}
1
+ {"version":3,"file":"DateTimeInput.js","names":["React","useCallback","useEffect","useState","classNames","Log","MaskedInput","getNextSegmentValue","addSeparators","jsx","_jsx","log","module","DATE_PATTERN","TIME_PATTERN","FULL_DATE_PATTERN","concat","DATE_VALUE_STRING","DEFAULT_VALUE_STRING","FULL_DATE_FORMAT","fixIncompleteValue","value","length","substring","replace","removeSeparators","EXAMPLES","DateTimeInput","forwardRef","props","ref","className","onChange","undefined","defaultValue","onFocus","onBlur","onSubmit","dataTestId","setValue","selection","setSelection","normalizeText","text","normalized","dateTimeMatch","match","handleChange","newValue","debug","handleBlur","prevValue","fixedValue","children","example","normalizePastedText","onSelect","pattern","placeholder","displayName"],"sources":["../src/DateTimeInput.tsx"],"sourcesContent":["import React, {\n type KeyboardEvent,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport classNames from 'classnames';\nimport Log from '@deephaven/log';\nimport MaskedInput, { type SelectionSegment } from './MaskedInput';\nimport { getNextSegmentValue } from './DateInputUtils';\nimport { addSeparators } from './DateTimeInputUtils';\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\nexport type DateTimeInputProps = {\n className?: string;\n onChange?: (value: string) => void;\n defaultValue?: string;\n onFocus?: () => void;\n onBlur?: () => void;\n onSubmit?: (event: KeyboardEvent<HTMLInputElement>) => void;\n 'data-testid'?: string;\n};\n\nfunction 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\nfunction removeSeparators(value: string): string {\n return value.replace(/\\u200B/g, '');\n}\n\nconst EXAMPLES = [addSeparators(DEFAULT_VALUE_STRING)];\n\nexport const DateTimeInput = React.forwardRef<\n HTMLInputElement,\n DateTimeInputProps\n>((props, ref) => {\n const {\n className = '',\n onChange = () => undefined,\n defaultValue = '',\n onFocus = () => undefined,\n onBlur = () => undefined,\n onSubmit,\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 /**\n * Normalize text by:\n * - Replacing 'T' with space to support ISO 8601 format\n * - Removing timezone information (e.g., \"EDT\", \"+05:00\", \"Z\")\n * - Adding zero-width space separators in the nanosecond part\n * @param text The text\n * @returns The normalized text\n */\n const normalizeText = useCallback((text: string): string => {\n // Replace first 'T' separator with space for ISO 8601 format (without global flag to preserve 'T' in timezone like EDT)\n let normalized = text.replace(/T/, ' ');\n\n // Remove timezone information\n // Match datetime up to optional fractional seconds, then strip everything else\n // Pattern: YYYY-MM-DD HH:MM:SS[.SSSSSSSSS] followed by optional timezone\n const dateTimeMatch = normalized.match(\n /^(\\d{4}-\\d{2}-\\d{2}\\s+\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?)/\n );\n\n if (dateTimeMatch) {\n [, normalized] = dateTimeMatch;\n }\n\n // Add zero-width space separators to match the expected pattern\n return addSeparators(normalized);\n }, []);\n\n // Sync internal state with defaultValue prop when it changes\n // Apply normalization to handle raw unformatted values (e.g., with timezone info)\n useEffect(() => {\n if (defaultValue.length > 0) {\n const normalized = normalizeText(defaultValue);\n setValue(normalized);\n // Notify parent with the normalized value (without separators)\n onChange(fixIncompleteValue(removeSeparators(normalized)));\n } else {\n setValue('');\n onChange('');\n }\n }, [defaultValue, normalizeText, onChange]);\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 normalizePastedText={normalizeText}\n onChange={handleChange}\n onSelect={setSelection}\n onSubmit={onSubmit}\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\nDateTimeInput.displayName = 'DateTimeInput';\n\nexport default DateTimeInput;\n"],"mappings":"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","ignoreList":[]}
@@ -32,6 +32,8 @@ type MaskedInputProps = {
32
32
  /** Retrieve the next value for a provided segment */
33
33
  getNextSegmentValue?: (segment: SelectionSegment, delta: number, segmentValue: string, value: string) => string;
34
34
  getPreferredReplacementString?: (value: string, replaceIndex: number, replaceChar: string, selectionStart: number, selectionEnd: number) => string;
35
+ /** Normalize pasted text before validation. Defaults to returning text unchanged. */
36
+ normalizePastedText?: (text: string) => string;
35
37
  onFocus?: React.FocusEventHandler;
36
38
  onBlur?: React.FocusEventHandler;
37
39
  'data-testid'?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"MaskedInput.d.ts","sourceRoot":"","sources":["../src/MaskedInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAIZ,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AASf,OAAO,oBAAoB,CAAC;AAI5B,QAAA,MAAM,mBAAmB;;;;CAIf,CAAC;AAQX,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAC;CACrF,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,2IAA2I;IAC3I,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,iDAAiD;IACjD,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,oCAAoC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,mCAAmC;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC5D,qDAAqD;IACrD,mBAAmB,CAAC,EAAE,CACpB,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,KACV,MAAM,CAAC;IACZ,6BAA6B,CAAC,EAAE,CAC9B,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,KACjB,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAClC,MAAM,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAEjC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;GAGG;AAIH,QAAA,MAAM,WAAW,2FA2dhB,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"MaskedInput.d.ts","sourceRoot":"","sources":["../src/MaskedInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAIZ,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AASf,OAAO,oBAAoB,CAAC;AAI5B,QAAA,MAAM,mBAAmB;;;;CAIf,CAAC;AAQX,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAC;CACrF,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,2IAA2I;IAC3I,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,iDAAiD;IACjD,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,oCAAoC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,mCAAmC;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC5D,qDAAqD;IACrD,mBAAmB,CAAC,EAAE,CACpB,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,KACV,MAAM,CAAC;IACZ,6BAA6B,CAAC,EAAE,CAC9B,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,KACjB,MAAM,CAAC;IACZ,qFAAqF;IACrF,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAClC,MAAM,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC;IAEjC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;GAGG;AAIH,QAAA,MAAM,WAAW,2FAkgBhB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -35,6 +35,7 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
35
35
  example,
36
36
  getNextSegmentValue = (range, delta, segmentValue) => segmentValue,
37
37
  getPreferredReplacementString = DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,
38
+ normalizePastedText = text => text,
38
39
  onChange = () => false,
39
40
  onSelect = () => false,
40
41
  onSubmit,
@@ -118,7 +119,7 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
118
119
  * @param checkValue The value to check validity of
119
120
  * @param cursorPosition The position of the cursor to check up to
120
121
  */
121
- function isValid(checkValue) {
122
+ var isValid = useCallback(function (checkValue) {
122
123
  var cursorPosition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : checkValue.length;
123
124
  var patternRegex = new RegExp("^".concat(pattern, "$"));
124
125
  if (patternRegex.test(checkValue)) {
@@ -131,7 +132,7 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
131
132
  }
132
133
  }
133
134
  return false;
134
- }
135
+ }, [pattern, examples]);
135
136
 
136
137
  /**
137
138
  * Returns the next segment after the given position
@@ -243,6 +244,33 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
243
244
  nextSegmentValue(selectionStart, 1);
244
245
  }
245
246
  }
247
+
248
+ /**
249
+ * Handles paste events into the input
250
+ * @param event The paste event
251
+ */
252
+ var handlePaste = useCallback(event => {
253
+ event.preventDefault();
254
+ event.stopPropagation();
255
+ if (!input.current) {
256
+ return;
257
+ }
258
+ var pastedText = event.clipboardData.getData('text/plain');
259
+ log.debug('handlePaste', pastedText);
260
+
261
+ // Normalize the pasted text
262
+ var normalizedText = normalizePastedText(pastedText);
263
+
264
+ // Check if the pasted value is valid
265
+ if (isValid(normalizedText, normalizedText.length)) {
266
+ onChange(normalizedText);
267
+ onSelect({
268
+ selectionStart: normalizedText.length,
269
+ selectionEnd: normalizedText.length,
270
+ selectionDirection: SELECTION_DIRECTION.NONE
271
+ });
272
+ }
273
+ }, [input, onChange, onSelect, isValid, normalizePastedText]);
246
274
  function handleKeyDown(event) {
247
275
  if (!input.current) {
248
276
  return;
@@ -364,6 +392,7 @@ var MaskedInput = /*#__PURE__*/React.forwardRef((props, ref) => {
364
392
  value: value,
365
393
  onChange: () => undefined,
366
394
  onKeyDown: handleKeyDown,
395
+ onPaste: handlePaste,
367
396
  onSelect: handleSelect,
368
397
  onSelectCapture: handleSelectCapture,
369
398
  onFocus: onFocus,
@@ -1 +1 @@
1
- {"version":3,"file":"MaskedInput.js","names":["React","useMemo","useEffect","useCallback","classNames","Log","useForwardedRef","DEFAULT_GET_PREFERRED_REPLACEMENT_STRING","fillToLength","trimTrailingMask","jsx","_jsx","log","module","SELECTION_DIRECTION","FORWARD","BACKWARD","NONE","FIXED_WIDTH_SPACE","MaskedInput","forwardRef","props","ref","className","example","getNextSegmentValue","range","delta","segmentValue","getPreferredReplacementString","onChange","onSelect","onSubmit","pattern","placeholder","selection","value","onFocus","onBlur","dataTestId","input","examples","Array","isArray","emptyMask","replace","setSelectedSegment","_input$current","debug","selectionStart","selectionEnd","selectionDirection","current","setSelectionRange","getSegment","cursorPosition","testValue","length","i","test","charAt","fillValue","checkValue","exampleValue","arguments","undefined","filledValue","concat","substring","isValid","patternRegex","RegExp","nextSegment","position","currentSegment","nextPosition","previousSegment","previousPosition","nextSegmentValue","segment","newSegmentValue","newValue","handleSelect","event","target","error","debug2","nativeEvent","type","_objectSpread","newSelection","handleSelectCapture","_input$current$select","preventDefault","stopPropagation","handleArrowKey","key","handleKeyDown","startsWith","trimmedValue","altKey","metaKey","ctrlKey","newChars","from","Set","toUpperCase","toLowerCase","newChar","maxReplaceIndex","replaceIndex","newSelectionStart","nextSegmentSelection","onKeyDown","onSelectCapture"],"sources":["../src/MaskedInput.tsx"],"sourcesContent":["import React, {\n useMemo,\n useEffect,\n useCallback,\n type KeyboardEvent,\n} from 'react';\nimport classNames from 'classnames';\nimport Log from '@deephaven/log';\nimport { useForwardedRef } from '@deephaven/react-hooks';\nimport {\n DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,\n fillToLength,\n trimTrailingMask,\n} from './MaskedInputUtils';\nimport './MaskedInput.scss';\n\nconst log = Log.module('MaskedInput');\n\nconst SELECTION_DIRECTION = {\n FORWARD: 'forward',\n BACKWARD: 'backward',\n NONE: 'none',\n} as const;\n\n/**\n * Special space character that's the same size as tabular numbers\n * https://www.fileformat.info/info/unicode/char/2007/index.htm\n */\nconst FIXED_WIDTH_SPACE = '\\u2007';\n\nexport type SelectionSegment = {\n selectionStart: number;\n selectionEnd: number;\n selectionDirection?: (typeof SELECTION_DIRECTION)[keyof typeof SELECTION_DIRECTION];\n};\n\ntype MaskedInputProps = {\n /** An extra class name to add to the component */\n className?: string;\n /** The regex pattern this masked input must match */\n pattern: string;\n /** Input placeholder */\n placeholder?: string;\n /** The current value to display */\n value: string;\n /** One or more examples of valid values. Used when deciding if next keystroke is valid (as rest of the current value may be incomplete) */\n example: string | string[];\n /** The current selection to use for the input */\n selection?: SelectionSegment;\n /** Called when the value changes. Note the value may still be incomplete. */\n onChange?: (value: string) => void;\n /** Called when selection changes */\n onSelect?: (segment: SelectionSegment) => void;\n /** Called when enter is pressed */\n onSubmit?: (event: KeyboardEvent<HTMLInputElement>) => void;\n /** Retrieve the next value for a provided segment */\n getNextSegmentValue?: (\n segment: SelectionSegment,\n delta: number,\n segmentValue: string,\n value: string\n ) => string;\n getPreferredReplacementString?: (\n value: string,\n replaceIndex: number,\n replaceChar: string,\n selectionStart: number,\n selectionEnd: number\n ) => string;\n onFocus?: React.FocusEventHandler;\n onBlur?: React.FocusEventHandler;\n\n 'data-testid'?: string;\n};\n\n/**\n * A masked input for entering data from a template.\n * Won't work by itself, must use within another component and handle updating the value/selection.\n */\n// Forward ref causes a false positive for display-name in eslint:\n// https://github.com/yannickcr/eslint-plugin-react/issues/2269\n// eslint-disable-next-line react/display-name\nconst MaskedInput = React.forwardRef<HTMLInputElement, MaskedInputProps>(\n (props: MaskedInputProps, ref) => {\n const {\n className,\n example,\n getNextSegmentValue = (range, delta, segmentValue) => segmentValue,\n getPreferredReplacementString = DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,\n onChange = () => false,\n onSelect = () => false,\n onSubmit,\n pattern,\n placeholder,\n selection,\n value,\n onFocus = () => false,\n onBlur = () => false,\n 'data-testid': dataTestId,\n } = props;\n const input = useForwardedRef(ref);\n const examples = useMemo(\n () => (Array.isArray(example) ? example : [example]),\n [example]\n );\n const emptyMask = useMemo(\n () => examples[0].replace(/[a-zA-Z0-9]/g, FIXED_WIDTH_SPACE),\n [examples]\n );\n\n useEffect(\n function setSelectedSegment() {\n if (selection != null) {\n log.debug('setting selection...', selection);\n const { selectionStart, selectionEnd, selectionDirection } =\n selection;\n input.current?.setSelectionRange(\n selectionStart,\n selectionEnd,\n selectionDirection\n );\n log.debug('selection set!');\n }\n },\n [selection, input]\n );\n\n /**\n * Returns the selection range for the segment at the given cursor position\n * @param cursorPosition The current position of the cursor\n */\n const getSegment = useCallback(\n (cursorPosition: number) => {\n let selectionStart = cursorPosition;\n let selectionEnd = cursorPosition;\n const testValue = examples.length > 0 ? examples[0] : value;\n\n for (let i = selectionStart - 1; i >= 0; i -= 1) {\n if (!/[a-zA-Z0-9]/g.test(testValue.charAt(i))) {\n break;\n }\n\n selectionStart = i;\n }\n\n for (let i = selectionEnd; i < testValue.length; i += 1) {\n if (!/[a-zA-Z0-9]/g.test(testValue.charAt(i))) {\n break;\n }\n\n selectionEnd = i + 1;\n }\n\n const selectionDirection =\n selectionStart === selectionEnd\n ? SELECTION_DIRECTION.NONE\n : SELECTION_DIRECTION.BACKWARD;\n\n return {\n selectionStart,\n selectionEnd,\n selectionDirection,\n };\n },\n [examples, value]\n );\n\n /**\n * Replaces all blank spaces and everything after the current cursor position with the example value\n * @param checkValue The value to check/fill in\n * @param exampleValue The example to fill in the value from\n * @param cursorPosition The cursor position\n * @returns The filled in value\n */\n function fillValue(\n checkValue: string,\n exampleValue: string,\n cursorPosition = checkValue.length\n ): string {\n let filledValue = '';\n for (let i = 0; i < cursorPosition; i += 1) {\n if (checkValue.charAt(i) !== FIXED_WIDTH_SPACE) {\n filledValue = filledValue.concat(checkValue[i]);\n } else {\n filledValue = filledValue.concat(exampleValue[i]);\n }\n }\n filledValue = filledValue.concat(exampleValue.substring(cursorPosition));\n\n return filledValue;\n }\n\n /**\n * Checks if a given `value` is valid up until the `cursorPosition`.\n * Uses the examples to build the rest of the string\n * @param checkValue The value to check validity of\n * @param cursorPosition The position of the cursor to check up to\n */\n function isValid(\n checkValue: string,\n cursorPosition = checkValue.length\n ): boolean {\n const patternRegex = new RegExp(`^${pattern}$`);\n if (patternRegex.test(checkValue)) {\n return true;\n }\n\n for (let i = 0; i < examples.length; i += 1) {\n const filledValue = fillValue(checkValue, examples[i], cursorPosition);\n if (patternRegex.test(filledValue)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Returns the next segment after the given position\n * @param position The cursor position to start at\n * @returns The new selection range\n */\n function nextSegment(position: number): SelectionSegment {\n const currentSegment = getSegment(position);\n const nextPosition = currentSegment.selectionEnd + 1;\n if (nextPosition >= value.length) {\n return currentSegment;\n }\n\n return getSegment(nextPosition);\n }\n\n /**\n * Returns the previous segment before the given position\n * @param position The cursor position to start at\n * @returns The new selection range\n */\n function previousSegment(position: number): SelectionSegment {\n const currentSegment = getSegment(position);\n const previousPosition = currentSegment.selectionStart - 1;\n if (previousPosition <= 0) {\n return currentSegment;\n }\n\n return getSegment(previousPosition);\n }\n\n function nextSegmentValue(position: number, delta: number): void {\n const segment = getSegment(position);\n const segmentValue = value.substring(\n segment.selectionStart,\n segment.selectionEnd\n );\n const newSegmentValue = getNextSegmentValue(\n segment,\n delta,\n segmentValue,\n value\n );\n const newValue =\n value.substring(0, segment.selectionStart) +\n newSegmentValue +\n value.substring(segment.selectionEnd);\n if (isValid(newValue, segment.selectionEnd)) {\n onChange(newValue);\n onSelect(segment);\n }\n }\n\n const handleSelect = useCallback(\n (event: React.UIEvent<HTMLInputElement>) => {\n const {\n selectionStart = 0,\n selectionEnd = 0,\n selectionDirection = 'none',\n } = event.target as HTMLInputElement;\n\n if (\n selectionStart === null ||\n selectionEnd === null ||\n selectionDirection === null\n ) {\n log.error(\n 'Selection attempted on non-text input element',\n event.target\n );\n return;\n }\n\n log.debug2(\n 'handleSelect',\n selectionStart,\n selectionEnd,\n selectionDirection\n );\n if (\n selection != null &&\n selectionStart === selection.selectionStart &&\n selectionEnd === selection.selectionEnd\n ) {\n return;\n }\n if (\n selection != null &&\n selectionStart === value.length &&\n selectionEnd === value.length &&\n event.nativeEvent.type !== 'mouseup'\n ) {\n // React triggers onSelect event with the cursor at the end of the input content\n // when the component is rendered at a different location in the DOM,\n // i.e. when start/end times switch places in the TimeSlider.\n // Ignore this event and reset the selection to its previous state.\n onSelect({ ...selection });\n return;\n }\n if (selectionStart === selectionEnd) {\n const newSelection = getSegment(selectionStart);\n log.debug(\n 'Selection segment from ',\n selectionStart,\n selectionEnd,\n '=>',\n newSelection\n );\n onSelect(newSelection);\n } else {\n onSelect({ selectionStart, selectionEnd, selectionDirection });\n }\n },\n [getSegment, onSelect, selection, value]\n );\n\n const handleSelectCapture = useCallback(\n (event: React.UIEvent<HTMLInputElement>) => {\n if (!input.current) {\n return;\n }\n log.debug('handleSelectCapture', event);\n const selectionStart = input.current.selectionStart ?? 0;\n if (\n selectionStart === value.length &&\n selection != null &&\n selectionStart !== selection.selectionStart\n ) {\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [input, selection, value]\n );\n\n function handleArrowKey(\n event: React.KeyboardEvent<HTMLInputElement>\n ): void {\n event.preventDefault();\n event.stopPropagation();\n\n if (!input.current) {\n return;\n }\n\n const { key } = event;\n const { selectionStart = 0, selectionEnd = 0 } = input.current;\n if (selectionStart === null || selectionEnd === null) {\n log.error(\n 'Selection arrow nvaigation attempted on non-text input element',\n event.target\n );\n return;\n }\n\n if (key === 'ArrowLeft') {\n onSelect(previousSegment(selectionStart));\n } else if (key === 'ArrowRight') {\n onSelect(nextSegment(selectionEnd));\n } else if (key === 'ArrowUp') {\n nextSegmentValue(selectionStart, -1);\n } else if (key === 'ArrowDown') {\n nextSegmentValue(selectionStart, 1);\n }\n }\n\n function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {\n if (!input.current) {\n return;\n }\n log.debug('handleKeyDown', event);\n const { key } = event;\n const { selectionStart = 0, selectionEnd = 0 } = input.current;\n if (selectionStart === null || selectionEnd === null) {\n log.error(\n 'Selection key event on non-text input element',\n event.target\n );\n return;\n }\n if (key === 'Enter') {\n onSubmit?.(event);\n return;\n }\n if (key.startsWith('Arrow')) {\n handleArrowKey(event);\n return;\n }\n\n if (key === 'Delete' || key === 'Backspace') {\n event.preventDefault();\n event.stopPropagation();\n\n // Deleting at the end of the value\n if (selectionEnd >= trimTrailingMask(value, emptyMask).length) {\n const newValue = value.substring(\n 0,\n // Delete whole selection or just the char before the cursor\n selectionStart === selectionEnd\n ? selectionStart - 1\n : selectionStart\n );\n const trimmedValue = trimTrailingMask(newValue, emptyMask);\n if (trimmedValue !== value) {\n onChange(trimmedValue);\n onSelect({\n selectionStart: trimmedValue.length,\n selectionEnd: trimmedValue.length,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n }\n return;\n }\n\n if (selectionStart !== selectionEnd) {\n // Replace all non-masked characters with blanks, set selection to start\n const newValue =\n value.substring(0, selectionStart) +\n value\n .substring(selectionStart, selectionEnd)\n .replace(/[a-zA-Z0-9]/g, FIXED_WIDTH_SPACE) +\n value.substring(selectionEnd);\n log.debug(\n 'Range ',\n selectionStart,\n selectionEnd,\n 'deleted, setting value',\n newValue\n );\n\n onChange(newValue);\n onSelect({\n selectionStart,\n selectionEnd: selectionStart,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n } else if (selectionStart > 0) {\n for (let i = selectionStart - 1; i >= 0; i -= 1) {\n // Only replace non placeholder text\n const newValue =\n value.substring(0, i) +\n value\n .substring(i, selectionStart)\n .replace(/[a-zA-Z0-9]/g, FIXED_WIDTH_SPACE) +\n value.substring(selectionStart);\n\n if (newValue !== value) {\n onChange(newValue);\n onSelect({\n selectionStart: i,\n selectionEnd: i,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n return;\n }\n }\n }\n\n return;\n }\n\n if (event.altKey || event.metaKey || event.ctrlKey || key.length > 1) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n // Get the different permutations of the character they entered, remove duplicates\n const newChars = Array.from(\n new Set([key, key.toUpperCase(), key.toLowerCase()])\n );\n for (let i = 0; i < newChars.length; i += 1) {\n const newChar = newChars[i];\n\n // If they're typing an alphanumeric character, be smart and allow it to jump ahead\n const maxReplaceIndex = /[a-zA-Z0-9]/g.test(newChar)\n ? examples[0].length - 1\n : selectionStart;\n for (\n let replaceIndex = selectionStart;\n replaceIndex <= maxReplaceIndex;\n replaceIndex += 1\n ) {\n // Fill with the example chars if necessary\n const filledValue = fillToLength(\n value,\n examples[0],\n replaceIndex + 1\n );\n const newValue = getPreferredReplacementString(\n filledValue,\n replaceIndex,\n newChar,\n selectionStart,\n selectionEnd\n );\n if (isValid(newValue, replaceIndex + 1)) {\n const currentSegment = getSegment(replaceIndex);\n const newSelectionStart = replaceIndex + 1;\n let newSelection: SelectionSegment = {\n selectionStart: newSelectionStart,\n selectionEnd: newSelectionStart,\n selectionDirection: SELECTION_DIRECTION.NONE,\n };\n if (newSelectionStart >= currentSegment.selectionEnd) {\n const nextSegmentSelection = nextSegment(replaceIndex);\n if (\n nextSegmentSelection.selectionStart !==\n currentSegment.selectionStart\n ) {\n newSelection = nextSegmentSelection;\n }\n }\n log.debug('handleKeyDown', key, '=>', newValue, newSelection);\n onChange(newValue);\n onSelect(newSelection);\n return;\n }\n }\n }\n }\n\n // Need to use \"text\" type so we can apply a pattern and make selection properly\n return (\n <input\n ref={input}\n className={classNames('form-control masked-input', className)}\n type=\"text\"\n pattern={pattern}\n placeholder={placeholder}\n value={value}\n onChange={() => undefined}\n onKeyDown={handleKeyDown}\n onSelect={handleSelect}\n onSelectCapture={handleSelectCapture}\n onFocus={onFocus}\n onBlur={onBlur}\n data-testid={dataTestId}\n />\n );\n }\n);\n\nexport default MaskedInput;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"MaskedInput.js","names":["React","useMemo","useEffect","useCallback","classNames","Log","useForwardedRef","DEFAULT_GET_PREFERRED_REPLACEMENT_STRING","fillToLength","trimTrailingMask","jsx","_jsx","log","module","SELECTION_DIRECTION","FORWARD","BACKWARD","NONE","FIXED_WIDTH_SPACE","MaskedInput","forwardRef","props","ref","className","example","getNextSegmentValue","range","delta","segmentValue","getPreferredReplacementString","normalizePastedText","text","onChange","onSelect","onSubmit","pattern","placeholder","selection","value","onFocus","onBlur","dataTestId","input","examples","Array","isArray","emptyMask","replace","setSelectedSegment","_input$current","debug","selectionStart","selectionEnd","selectionDirection","current","setSelectionRange","getSegment","cursorPosition","testValue","length","i","test","charAt","fillValue","checkValue","exampleValue","arguments","undefined","filledValue","concat","substring","isValid","patternRegex","RegExp","nextSegment","position","currentSegment","nextPosition","previousSegment","previousPosition","nextSegmentValue","segment","newSegmentValue","newValue","handleSelect","event","target","error","debug2","nativeEvent","type","_objectSpread","newSelection","handleSelectCapture","_input$current$select","preventDefault","stopPropagation","handleArrowKey","key","handlePaste","pastedText","clipboardData","getData","normalizedText","handleKeyDown","startsWith","trimmedValue","altKey","metaKey","ctrlKey","newChars","from","Set","toUpperCase","toLowerCase","newChar","maxReplaceIndex","replaceIndex","newSelectionStart","nextSegmentSelection","onKeyDown","onPaste","onSelectCapture"],"sources":["../src/MaskedInput.tsx"],"sourcesContent":["import React, {\n useMemo,\n useEffect,\n useCallback,\n type KeyboardEvent,\n} from 'react';\nimport classNames from 'classnames';\nimport Log from '@deephaven/log';\nimport { useForwardedRef } from '@deephaven/react-hooks';\nimport {\n DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,\n fillToLength,\n trimTrailingMask,\n} from './MaskedInputUtils';\nimport './MaskedInput.scss';\n\nconst log = Log.module('MaskedInput');\n\nconst SELECTION_DIRECTION = {\n FORWARD: 'forward',\n BACKWARD: 'backward',\n NONE: 'none',\n} as const;\n\n/**\n * Special space character that's the same size as tabular numbers\n * https://www.fileformat.info/info/unicode/char/2007/index.htm\n */\nconst FIXED_WIDTH_SPACE = '\\u2007';\n\nexport type SelectionSegment = {\n selectionStart: number;\n selectionEnd: number;\n selectionDirection?: (typeof SELECTION_DIRECTION)[keyof typeof SELECTION_DIRECTION];\n};\n\ntype MaskedInputProps = {\n /** An extra class name to add to the component */\n className?: string;\n /** The regex pattern this masked input must match */\n pattern: string;\n /** Input placeholder */\n placeholder?: string;\n /** The current value to display */\n value: string;\n /** One or more examples of valid values. Used when deciding if next keystroke is valid (as rest of the current value may be incomplete) */\n example: string | string[];\n /** The current selection to use for the input */\n selection?: SelectionSegment;\n /** Called when the value changes. Note the value may still be incomplete. */\n onChange?: (value: string) => void;\n /** Called when selection changes */\n onSelect?: (segment: SelectionSegment) => void;\n /** Called when enter is pressed */\n onSubmit?: (event: KeyboardEvent<HTMLInputElement>) => void;\n /** Retrieve the next value for a provided segment */\n getNextSegmentValue?: (\n segment: SelectionSegment,\n delta: number,\n segmentValue: string,\n value: string\n ) => string;\n getPreferredReplacementString?: (\n value: string,\n replaceIndex: number,\n replaceChar: string,\n selectionStart: number,\n selectionEnd: number\n ) => string;\n /** Normalize pasted text before validation. Defaults to returning text unchanged. */\n normalizePastedText?: (text: string) => string;\n onFocus?: React.FocusEventHandler;\n onBlur?: React.FocusEventHandler;\n\n 'data-testid'?: string;\n};\n\n/**\n * A masked input for entering data from a template.\n * Won't work by itself, must use within another component and handle updating the value/selection.\n */\n// Forward ref causes a false positive for display-name in eslint:\n// https://github.com/yannickcr/eslint-plugin-react/issues/2269\n// eslint-disable-next-line react/display-name\nconst MaskedInput = React.forwardRef<HTMLInputElement, MaskedInputProps>(\n (props: MaskedInputProps, ref) => {\n const {\n className,\n example,\n getNextSegmentValue = (range, delta, segmentValue) => segmentValue,\n getPreferredReplacementString = DEFAULT_GET_PREFERRED_REPLACEMENT_STRING,\n normalizePastedText = (text: string) => text,\n onChange = () => false,\n onSelect = () => false,\n onSubmit,\n pattern,\n placeholder,\n selection,\n value,\n onFocus = () => false,\n onBlur = () => false,\n 'data-testid': dataTestId,\n } = props;\n const input = useForwardedRef(ref);\n const examples = useMemo(\n () => (Array.isArray(example) ? example : [example]),\n [example]\n );\n const emptyMask = useMemo(\n () => examples[0].replace(/[a-zA-Z0-9]/g, FIXED_WIDTH_SPACE),\n [examples]\n );\n\n useEffect(\n function setSelectedSegment() {\n if (selection != null) {\n log.debug('setting selection...', selection);\n const { selectionStart, selectionEnd, selectionDirection } =\n selection;\n input.current?.setSelectionRange(\n selectionStart,\n selectionEnd,\n selectionDirection\n );\n log.debug('selection set!');\n }\n },\n [selection, input]\n );\n\n /**\n * Returns the selection range for the segment at the given cursor position\n * @param cursorPosition The current position of the cursor\n */\n const getSegment = useCallback(\n (cursorPosition: number) => {\n let selectionStart = cursorPosition;\n let selectionEnd = cursorPosition;\n const testValue = examples.length > 0 ? examples[0] : value;\n\n for (let i = selectionStart - 1; i >= 0; i -= 1) {\n if (!/[a-zA-Z0-9]/g.test(testValue.charAt(i))) {\n break;\n }\n\n selectionStart = i;\n }\n\n for (let i = selectionEnd; i < testValue.length; i += 1) {\n if (!/[a-zA-Z0-9]/g.test(testValue.charAt(i))) {\n break;\n }\n\n selectionEnd = i + 1;\n }\n\n const selectionDirection =\n selectionStart === selectionEnd\n ? SELECTION_DIRECTION.NONE\n : SELECTION_DIRECTION.BACKWARD;\n\n return {\n selectionStart,\n selectionEnd,\n selectionDirection,\n };\n },\n [examples, value]\n );\n\n /**\n * Replaces all blank spaces and everything after the current cursor position with the example value\n * @param checkValue The value to check/fill in\n * @param exampleValue The example to fill in the value from\n * @param cursorPosition The cursor position\n * @returns The filled in value\n */\n function fillValue(\n checkValue: string,\n exampleValue: string,\n cursorPosition = checkValue.length\n ): string {\n let filledValue = '';\n for (let i = 0; i < cursorPosition; i += 1) {\n if (checkValue.charAt(i) !== FIXED_WIDTH_SPACE) {\n filledValue = filledValue.concat(checkValue[i]);\n } else {\n filledValue = filledValue.concat(exampleValue[i]);\n }\n }\n filledValue = filledValue.concat(exampleValue.substring(cursorPosition));\n\n return filledValue;\n }\n\n /**\n * Checks if a given `value` is valid up until the `cursorPosition`.\n * Uses the examples to build the rest of the string\n * @param checkValue The value to check validity of\n * @param cursorPosition The position of the cursor to check up to\n */\n const isValid = useCallback(\n (checkValue: string, cursorPosition = checkValue.length): boolean => {\n const patternRegex = new RegExp(`^${pattern}$`);\n if (patternRegex.test(checkValue)) {\n return true;\n }\n\n for (let i = 0; i < examples.length; i += 1) {\n const filledValue = fillValue(\n checkValue,\n examples[i],\n cursorPosition\n );\n if (patternRegex.test(filledValue)) {\n return true;\n }\n }\n return false;\n },\n [pattern, examples]\n );\n\n /**\n * Returns the next segment after the given position\n * @param position The cursor position to start at\n * @returns The new selection range\n */\n function nextSegment(position: number): SelectionSegment {\n const currentSegment = getSegment(position);\n const nextPosition = currentSegment.selectionEnd + 1;\n if (nextPosition >= value.length) {\n return currentSegment;\n }\n\n return getSegment(nextPosition);\n }\n\n /**\n * Returns the previous segment before the given position\n * @param position The cursor position to start at\n * @returns The new selection range\n */\n function previousSegment(position: number): SelectionSegment {\n const currentSegment = getSegment(position);\n const previousPosition = currentSegment.selectionStart - 1;\n if (previousPosition <= 0) {\n return currentSegment;\n }\n\n return getSegment(previousPosition);\n }\n\n function nextSegmentValue(position: number, delta: number): void {\n const segment = getSegment(position);\n const segmentValue = value.substring(\n segment.selectionStart,\n segment.selectionEnd\n );\n const newSegmentValue = getNextSegmentValue(\n segment,\n delta,\n segmentValue,\n value\n );\n const newValue =\n value.substring(0, segment.selectionStart) +\n newSegmentValue +\n value.substring(segment.selectionEnd);\n if (isValid(newValue, segment.selectionEnd)) {\n onChange(newValue);\n onSelect(segment);\n }\n }\n\n const handleSelect = useCallback(\n (event: React.UIEvent<HTMLInputElement>) => {\n const {\n selectionStart = 0,\n selectionEnd = 0,\n selectionDirection = 'none',\n } = event.target as HTMLInputElement;\n\n if (\n selectionStart === null ||\n selectionEnd === null ||\n selectionDirection === null\n ) {\n log.error(\n 'Selection attempted on non-text input element',\n event.target\n );\n return;\n }\n\n log.debug2(\n 'handleSelect',\n selectionStart,\n selectionEnd,\n selectionDirection\n );\n if (\n selection != null &&\n selectionStart === selection.selectionStart &&\n selectionEnd === selection.selectionEnd\n ) {\n return;\n }\n if (\n selection != null &&\n selectionStart === value.length &&\n selectionEnd === value.length &&\n event.nativeEvent.type !== 'mouseup'\n ) {\n // React triggers onSelect event with the cursor at the end of the input content\n // when the component is rendered at a different location in the DOM,\n // i.e. when start/end times switch places in the TimeSlider.\n // Ignore this event and reset the selection to its previous state.\n onSelect({ ...selection });\n return;\n }\n if (selectionStart === selectionEnd) {\n const newSelection = getSegment(selectionStart);\n log.debug(\n 'Selection segment from ',\n selectionStart,\n selectionEnd,\n '=>',\n newSelection\n );\n onSelect(newSelection);\n } else {\n onSelect({ selectionStart, selectionEnd, selectionDirection });\n }\n },\n [getSegment, onSelect, selection, value]\n );\n\n const handleSelectCapture = useCallback(\n (event: React.UIEvent<HTMLInputElement>) => {\n if (!input.current) {\n return;\n }\n log.debug('handleSelectCapture', event);\n const selectionStart = input.current.selectionStart ?? 0;\n if (\n selectionStart === value.length &&\n selection != null &&\n selectionStart !== selection.selectionStart\n ) {\n event.preventDefault();\n event.stopPropagation();\n }\n },\n [input, selection, value]\n );\n\n function handleArrowKey(\n event: React.KeyboardEvent<HTMLInputElement>\n ): void {\n event.preventDefault();\n event.stopPropagation();\n\n if (!input.current) {\n return;\n }\n\n const { key } = event;\n const { selectionStart = 0, selectionEnd = 0 } = input.current;\n if (selectionStart === null || selectionEnd === null) {\n log.error(\n 'Selection arrow nvaigation attempted on non-text input element',\n event.target\n );\n return;\n }\n\n if (key === 'ArrowLeft') {\n onSelect(previousSegment(selectionStart));\n } else if (key === 'ArrowRight') {\n onSelect(nextSegment(selectionEnd));\n } else if (key === 'ArrowUp') {\n nextSegmentValue(selectionStart, -1);\n } else if (key === 'ArrowDown') {\n nextSegmentValue(selectionStart, 1);\n }\n }\n\n /**\n * Handles paste events into the input\n * @param event The paste event\n */\n const handlePaste = useCallback(\n (event: React.ClipboardEvent<HTMLInputElement>): void => {\n event.preventDefault();\n event.stopPropagation();\n\n if (!input.current) {\n return;\n }\n\n const pastedText = event.clipboardData.getData('text/plain');\n\n log.debug('handlePaste', pastedText);\n\n // Normalize the pasted text\n const normalizedText = normalizePastedText(pastedText);\n\n // Check if the pasted value is valid\n if (isValid(normalizedText, normalizedText.length)) {\n onChange(normalizedText);\n onSelect({\n selectionStart: normalizedText.length,\n selectionEnd: normalizedText.length,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n }\n },\n [input, onChange, onSelect, isValid, normalizePastedText]\n );\n\n function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {\n if (!input.current) {\n return;\n }\n log.debug('handleKeyDown', event);\n const { key } = event;\n const { selectionStart = 0, selectionEnd = 0 } = input.current;\n if (selectionStart === null || selectionEnd === null) {\n log.error(\n 'Selection key event on non-text input element',\n event.target\n );\n return;\n }\n if (key === 'Enter') {\n onSubmit?.(event);\n return;\n }\n if (key.startsWith('Arrow')) {\n handleArrowKey(event);\n return;\n }\n\n if (key === 'Delete' || key === 'Backspace') {\n event.preventDefault();\n event.stopPropagation();\n\n // Deleting at the end of the value\n if (selectionEnd >= trimTrailingMask(value, emptyMask).length) {\n const newValue = value.substring(\n 0,\n // Delete whole selection or just the char before the cursor\n selectionStart === selectionEnd\n ? selectionStart - 1\n : selectionStart\n );\n const trimmedValue = trimTrailingMask(newValue, emptyMask);\n if (trimmedValue !== value) {\n onChange(trimmedValue);\n onSelect({\n selectionStart: trimmedValue.length,\n selectionEnd: trimmedValue.length,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n }\n return;\n }\n\n if (selectionStart !== selectionEnd) {\n // Replace all non-masked characters with blanks, set selection to start\n const newValue =\n value.substring(0, selectionStart) +\n value\n .substring(selectionStart, selectionEnd)\n .replace(/[a-zA-Z0-9]/g, FIXED_WIDTH_SPACE) +\n value.substring(selectionEnd);\n log.debug(\n 'Range ',\n selectionStart,\n selectionEnd,\n 'deleted, setting value',\n newValue\n );\n\n onChange(newValue);\n onSelect({\n selectionStart,\n selectionEnd: selectionStart,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n } else if (selectionStart > 0) {\n for (let i = selectionStart - 1; i >= 0; i -= 1) {\n // Only replace non placeholder text\n const newValue =\n value.substring(0, i) +\n value\n .substring(i, selectionStart)\n .replace(/[a-zA-Z0-9]/g, FIXED_WIDTH_SPACE) +\n value.substring(selectionStart);\n\n if (newValue !== value) {\n onChange(newValue);\n onSelect({\n selectionStart: i,\n selectionEnd: i,\n selectionDirection: SELECTION_DIRECTION.NONE,\n });\n return;\n }\n }\n }\n\n return;\n }\n\n if (event.altKey || event.metaKey || event.ctrlKey || key.length > 1) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n // Get the different permutations of the character they entered, remove duplicates\n const newChars = Array.from(\n new Set([key, key.toUpperCase(), key.toLowerCase()])\n );\n for (let i = 0; i < newChars.length; i += 1) {\n const newChar = newChars[i];\n\n // If they're typing an alphanumeric character, be smart and allow it to jump ahead\n const maxReplaceIndex = /[a-zA-Z0-9]/g.test(newChar)\n ? examples[0].length - 1\n : selectionStart;\n for (\n let replaceIndex = selectionStart;\n replaceIndex <= maxReplaceIndex;\n replaceIndex += 1\n ) {\n // Fill with the example chars if necessary\n const filledValue = fillToLength(\n value,\n examples[0],\n replaceIndex + 1\n );\n const newValue = getPreferredReplacementString(\n filledValue,\n replaceIndex,\n newChar,\n selectionStart,\n selectionEnd\n );\n if (isValid(newValue, replaceIndex + 1)) {\n const currentSegment = getSegment(replaceIndex);\n const newSelectionStart = replaceIndex + 1;\n let newSelection: SelectionSegment = {\n selectionStart: newSelectionStart,\n selectionEnd: newSelectionStart,\n selectionDirection: SELECTION_DIRECTION.NONE,\n };\n if (newSelectionStart >= currentSegment.selectionEnd) {\n const nextSegmentSelection = nextSegment(replaceIndex);\n if (\n nextSegmentSelection.selectionStart !==\n currentSegment.selectionStart\n ) {\n newSelection = nextSegmentSelection;\n }\n }\n log.debug('handleKeyDown', key, '=>', newValue, newSelection);\n onChange(newValue);\n onSelect(newSelection);\n return;\n }\n }\n }\n }\n\n // Need to use \"text\" type so we can apply a pattern and make selection properly\n return (\n <input\n ref={input}\n className={classNames('form-control masked-input', className)}\n type=\"text\"\n pattern={pattern}\n placeholder={placeholder}\n value={value}\n onChange={() => undefined}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onSelect={handleSelect}\n onSelectCapture={handleSelectCapture}\n onFocus={onFocus}\n onBlur={onBlur}\n data-testid={dataTestId}\n />\n );\n }\n);\n\nexport default MaskedInput;\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deephaven/components",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "description": "Deephaven React component library",
5
5
  "author": "Deephaven Data Labs LLC",
6
6
  "license": "Apache-2.0",
@@ -78,5 +78,5 @@
78
78
  "publishConfig": {
79
79
  "access": "public"
80
80
  },
81
- "gitHead": "8acd6e2a7452e0430c4136506cad6408205ac9d1"
81
+ "gitHead": "33a489fbfa08dd8000983267ddae69217db90224"
82
82
  }