@vuu-ui/vuu-ui-controls 0.13.39 → 0.13.41
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/cjs/vuu-typeahead-input/VuuTypeaheadInput.css.js +1 -1
- package/cjs/vuu-typeahead-input/VuuTypeaheadInput.js +2 -0
- package/cjs/vuu-typeahead-input/VuuTypeaheadInput.js.map +1 -1
- package/cjs/vuu-typeahead-input/useVuuTypeaheadInput.js +20 -3
- package/cjs/vuu-typeahead-input/useVuuTypeaheadInput.js.map +1 -1
- package/esm/vuu-typeahead-input/VuuTypeaheadInput.css.js +1 -1
- package/esm/vuu-typeahead-input/VuuTypeaheadInput.js +2 -0
- package/esm/vuu-typeahead-input/VuuTypeaheadInput.js.map +1 -1
- package/esm/vuu-typeahead-input/useVuuTypeaheadInput.js +20 -3
- package/esm/vuu-typeahead-input/useVuuTypeaheadInput.js.map +1 -1
- package/package.json +12 -12
- package/types/vuu-typeahead-input/VuuTypeaheadInput.d.ts +3 -28
- package/types/vuu-typeahead-input/useVuuTypeaheadInput.d.ts +37 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var vuuTypeaheadInputCss = ".vuuTypeaheadInput {\n .saltPillInput-activationIndicator {\n display: none;\n }\n\n .saltButton {\n height:
|
|
3
|
+
var vuuTypeaheadInputCss = ".vuuTypeaheadInput {\n .saltPillInput-activationIndicator {\n display: none;\n }\n\n .saltPillInput-endAdornmentContainer {\n padding:0;\n }\n\n .saltButton {\n --vuuButton-borderColor: transparent;\n height: 24px;\n width: 24px;\n }\n\n .saltButton:before {\n content: \"\";\n background-color: var(--salt-separable-secondary-borderColor);\n height: 100%;\n left: calc(-1 * var(--salt-spacing-100));\n position: absolute;\n width: 1px;\n }\n\n .saltButton:after {\n --vuu-icon-color: var(--salt-content-primary-foreground);\n --vuu-icon-size: 10px;\n --vuu-icon-transform: rotate(45deg);\n\n content: \"\";\n background-color: var(--vuu-icon-color);\n height: var(--vuu-icon-size);\n mask: var(--vuu-svg-triangle-right) center center/var(--vuu-icon-size)\n var(--vuu-icon-size);\n mask-repeat: no-repeat;\n position: absolute;\n top: 3px;\n transform: var(--vuu-icon-transform, none);\n width: var(--vuu-icon-size);\n }\n}\n\n.vuuTypeaheadOption[aria-disabled=\"true\"] {\n color: var(--salt-content-secondary-foreground);\n}\n";
|
|
4
4
|
|
|
5
5
|
module.exports = vuuTypeaheadInputCss;
|
|
6
6
|
//# sourceMappingURL=VuuTypeaheadInput.css.js.map
|
|
@@ -18,6 +18,7 @@ const VuuTypeaheadInput = ({
|
|
|
18
18
|
freeTextWarning,
|
|
19
19
|
highlightFirstSuggestion,
|
|
20
20
|
inputProps: inputPropsProp,
|
|
21
|
+
minCharacterCountToTriggerSuggestions,
|
|
21
22
|
onCommit,
|
|
22
23
|
table
|
|
23
24
|
}) => {
|
|
@@ -44,6 +45,7 @@ const VuuTypeaheadInput = ({
|
|
|
44
45
|
freeTextWarning,
|
|
45
46
|
highlightFirstSuggestion,
|
|
46
47
|
inputProps: inputPropsProp,
|
|
48
|
+
minCharacterCountToTriggerSuggestions,
|
|
47
49
|
onCommit,
|
|
48
50
|
table
|
|
49
51
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VuuTypeaheadInput.js","sources":["../../../../packages/vuu-ui-controls/src/vuu-typeahead-input/VuuTypeaheadInput.tsx"],"sourcesContent":["import { ComboBox, Option } from \"@salt-ds/core\";\nimport {
|
|
1
|
+
{"version":3,"file":"VuuTypeaheadInput.js","sources":["../../../../packages/vuu-ui-controls/src/vuu-typeahead-input/VuuTypeaheadInput.tsx"],"sourcesContent":["import { ComboBox, Option } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { NO_DATA_MATCH } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport {\n useVuuTypeaheadInput,\n VuuTypeaheadInputHookProps,\n} from \"./useVuuTypeaheadInput\";\nimport vuuTypeaheadInputCss from \"./VuuTypeaheadInput.css\";\n\nconst classBase = \"vuuTypeaheadInput\";\nconst [noMatchingData] = NO_DATA_MATCH;\n\nexport interface VuuTypeaheadInputProps extends VuuTypeaheadInputHookProps {\n className?: string;\n}\n\nexport const VuuTypeaheadInput = ({\n allowFreeInput,\n className,\n column,\n freeTextWarning,\n highlightFirstSuggestion,\n inputProps: inputPropsProp,\n minCharacterCountToTriggerSuggestions,\n onCommit,\n table,\n}: VuuTypeaheadInputProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-typeahead-input\",\n css: vuuTypeaheadInputCss,\n window: targetWindow,\n });\n\n const {\n inputProps,\n noFreeText,\n onChange,\n onKeyDown,\n onOpenChange,\n onSelectionChange,\n open,\n ref,\n typeaheadValues,\n value,\n } = useVuuTypeaheadInput({\n allowFreeInput,\n column,\n freeTextWarning,\n highlightFirstSuggestion,\n inputProps: inputPropsProp,\n minCharacterCountToTriggerSuggestions,\n onCommit,\n table,\n });\n\n // need latest version of salt combobox\n // const defaultHighlightedIndex =\n // highlightFirstSuggestion === false ? -1 : undefined;\n\n return (\n <ComboBox\n className={cx(classBase, className)}\n // defaultHighlightedIndex={defaultHighlightedIndex}\n inputProps={inputProps}\n onChange={onChange}\n onKeyDown={onKeyDown}\n onOpenChange={onOpenChange}\n onSelectionChange={onSelectionChange}\n open={open}\n ref={ref}\n value={value}\n >\n {typeaheadValues.map((state) => (\n <Option\n className=\"vuuTypeaheadOption\"\n value={state}\n key={state}\n disabled={state === noMatchingData || state === noFreeText}\n />\n ))}\n </ComboBox>\n );\n};\n"],"names":["NO_DATA_MATCH","useWindow","useComponentCssInjection","vuuTypeaheadInputCss","useVuuTypeaheadInput","jsx","ComboBox","Option"],"mappings":";;;;;;;;;;;AAWA,MAAM,SAAY,GAAA,mBAAA;AAClB,MAAM,CAAC,cAAc,CAAI,GAAAA,sBAAA;AAMlB,MAAM,oBAAoB,CAAC;AAAA,EAChC,cAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACA,wBAAA;AAAA,EACA,UAAY,EAAA,cAAA;AAAA,EACZ,qCAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAA8B,KAAA;AAC5B,EAAA,MAAM,eAAeC,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,qBAAA;AAAA,IACR,GAAK,EAAAC,mBAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA;AAAA,IACJ,UAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAA;AAAA,IACA,iBAAA;AAAA,IACA,IAAA;AAAA,IACA,GAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,MACEC,yCAAqB,CAAA;AAAA,IACvB,cAAA;AAAA,IACA,MAAA;AAAA,IACA,eAAA;AAAA,IACA,wBAAA;AAAA,IACA,UAAY,EAAA,cAAA;AAAA,IACZ,qCAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACD,CAAA;AAMD,EACE,uBAAAC,cAAA;AAAA,IAACC,aAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAElC,UAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAA;AAAA,MACA,iBAAA;AAAA,MACA,IAAA;AAAA,MACA,GAAA;AAAA,MACA,KAAA;AAAA,MAEC,QAAA,EAAA,eAAA,CAAgB,GAAI,CAAA,CAAC,KACpB,qBAAAD,cAAA;AAAA,QAACE,WAAA;AAAA,QAAA;AAAA,UACC,SAAU,EAAA,oBAAA;AAAA,UACV,KAAO,EAAA,KAAA;AAAA,UAEP,QAAA,EAAU,KAAU,KAAA,cAAA,IAAkB,KAAU,KAAA;AAAA,SAAA;AAAA,QAD3C;AAAA,OAGR;AAAA;AAAA,GACH;AAEJ;;;;"}
|
|
@@ -4,6 +4,7 @@ var vuuDataReact = require('@vuu-ui/vuu-data-react');
|
|
|
4
4
|
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
5
5
|
var React = require('react');
|
|
6
6
|
|
|
7
|
+
const meetsMinTextLengthThreshold = (value, minLength) => value.length >= minLength;
|
|
7
8
|
const defaultFreeTextWarning = "Please select a value from the list of suggestions. If no suggestions match your text, then the value is not valid. If you believe this should be a valid value, please reach out to the support team";
|
|
8
9
|
const useVuuTypeaheadInput = ({
|
|
9
10
|
allowFreeInput = true,
|
|
@@ -11,6 +12,7 @@ const useVuuTypeaheadInput = ({
|
|
|
11
12
|
freeTextWarning,
|
|
12
13
|
highlightFirstSuggestion = true,
|
|
13
14
|
inputProps: inputPropsProp,
|
|
15
|
+
minCharacterCountToTriggerSuggestions = 1,
|
|
14
16
|
onCommit,
|
|
15
17
|
table
|
|
16
18
|
}) => {
|
|
@@ -40,6 +42,8 @@ const useVuuTypeaheadInput = ({
|
|
|
40
42
|
} else {
|
|
41
43
|
setTypeaheadValues(NO_FREE_TEXT);
|
|
42
44
|
}
|
|
45
|
+
} else if (evt.key === "Enter" && value2 === "") {
|
|
46
|
+
console.log("ENTER no value");
|
|
43
47
|
}
|
|
44
48
|
},
|
|
45
49
|
[NO_FREE_TEXT, allowFreeInput, onCommit, valueRef]
|
|
@@ -52,9 +56,13 @@ const useVuuTypeaheadInput = ({
|
|
|
52
56
|
React.useEffect(() => {
|
|
53
57
|
if (table) {
|
|
54
58
|
const vuuTable = vuuUtils.getVuuTable(table);
|
|
55
|
-
if (
|
|
59
|
+
if (meetsMinTextLengthThreshold(
|
|
60
|
+
value,
|
|
61
|
+
minCharacterCountToTriggerSuggestions
|
|
62
|
+
)) {
|
|
56
63
|
const params = value ? [vuuTable, column, value] : [vuuTable, column];
|
|
57
64
|
getSuggestions(params).then((suggestions) => {
|
|
65
|
+
console.log({ suggestions });
|
|
58
66
|
if (suggestions === false) {
|
|
59
67
|
setTypeaheadValues([]);
|
|
60
68
|
} else if (suggestions.length === 0 && value) {
|
|
@@ -78,7 +86,14 @@ const useVuuTypeaheadInput = ({
|
|
|
78
86
|
setTypeaheadValues([]);
|
|
79
87
|
}
|
|
80
88
|
}
|
|
81
|
-
}, [
|
|
89
|
+
}, [
|
|
90
|
+
table,
|
|
91
|
+
column,
|
|
92
|
+
getSuggestions,
|
|
93
|
+
value,
|
|
94
|
+
NO_FREE_TEXT,
|
|
95
|
+
minCharacterCountToTriggerSuggestions
|
|
96
|
+
]);
|
|
82
97
|
const handleChange = React.useCallback(
|
|
83
98
|
(evt) => {
|
|
84
99
|
const { value: newValue } = evt.target;
|
|
@@ -109,7 +124,9 @@ const useVuuTypeaheadInput = ({
|
|
|
109
124
|
);
|
|
110
125
|
};
|
|
111
126
|
const handleOpenChange = (newOpen) => {
|
|
112
|
-
if (newOpen && valueRef.current === "")
|
|
127
|
+
if (newOpen && valueRef.current === "") {
|
|
128
|
+
setOpen(newOpen);
|
|
129
|
+
} else {
|
|
113
130
|
setOpen(newOpen);
|
|
114
131
|
}
|
|
115
132
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVuuTypeaheadInput.js","sources":["../../../../packages/vuu-ui-controls/src/vuu-typeahead-input/useVuuTypeaheadInput.ts"],"sourcesContent":["import { useTypeaheadSuggestions } from \"@vuu-ui/vuu-data-react\";\nimport type { TypeaheadParams } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n dispatchKeyboardEvent,\n getVuuTable,\n useStateRef,\n NO_DATA_MATCH,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n ComponentPropsWithoutRef,\n KeyboardEventHandler,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ChangeEventHandler,\n type RefCallback,\n type SyntheticEvent,\n} from \"react\";\nimport type { VuuTypeaheadInputProps } from \"./VuuTypeaheadInput\";\n\nexport type VuuTypeaheadInputHookProps = Pick<\n VuuTypeaheadInputProps,\n | \"allowFreeInput\"\n | \"column\"\n | \"freeTextWarning\"\n | \"highlightFirstSuggestion\"\n | \"inputProps\"\n | \"onCommit\"\n | \"table\"\n>;\n\nconst defaultFreeTextWarning =\n \"Please select a value from the list of suggestions. If no suggestions match your text, then the value is not valid. If you believe this should be a valid value, please reach out to the support team\";\n\nexport const useVuuTypeaheadInput = ({\n allowFreeInput = true,\n column,\n freeTextWarning,\n highlightFirstSuggestion = true,\n inputProps: inputPropsProp,\n onCommit,\n table,\n}: VuuTypeaheadInputHookProps) => {\n const NO_FREE_TEXT = useMemo(\n () => [freeTextWarning ?? defaultFreeTextWarning],\n [freeTextWarning],\n );\n const [valueRef, setValue] = useStateRef(\"\");\n const [open, setOpen] = useState(false);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [typeaheadValues, setTypeaheadValues] = useState<string[]>([]);\n const getSuggestions = useTypeaheadSuggestions();\n const pendingListFocusRef = useRef(false);\n\n const { current: value } = valueRef;\n const commitTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (evt) => {\n const { current: value } = valueRef;\n if (evt.key === \"Enter\" && value !== \"\") {\n if (allowFreeInput) {\n commitTimeout.current = setTimeout(() => {\n onCommit?.(evt, value, \"text-input\");\n setOpen(false);\n commitTimeout.current = null;\n }, 200);\n } else {\n setTypeaheadValues(NO_FREE_TEXT);\n }\n }\n },\n [NO_FREE_TEXT, allowFreeInput, onCommit, valueRef],\n );\n\n const callbackRef = useCallback<RefCallback<HTMLDivElement>>((el) => {\n rootRef.current = el;\n const input = el?.querySelector(\"input\") ?? null;\n inputRef.current = input;\n }, []);\n\n useEffect(() => {\n if (table) {\n const vuuTable = getVuuTable(table);\n if (value) {\n const params: TypeaheadParams = value\n ? [vuuTable, column, value]\n : [vuuTable, column];\n getSuggestions(params)\n .then((suggestions) => {\n if (suggestions === false) {\n // TODO is this right\n setTypeaheadValues([]);\n } else if (suggestions.length === 0 && value) {\n setTypeaheadValues((values) =>\n // Do not update if we have already set suggestions to the no free text warning\n values === NO_FREE_TEXT ? NO_FREE_TEXT : NO_DATA_MATCH,\n );\n } else {\n setTypeaheadValues(suggestions);\n if (pendingListFocusRef.current && inputRef.current) {\n // This is a workaround for the fact that ComboBox does not automatically\n // highlight first list item when items have been populated dynamically.\n // This has been raised as a bug.\n //TODO this is failing to work correctly in new version of cypress\n dispatchKeyboardEvent(inputRef.current, \"keydown\", \"ArrowUp\");\n }\n }\n pendingListFocusRef.current = false;\n })\n .catch((err) => {\n console.error(\"Error getting suggestions\", err);\n });\n } else {\n setTypeaheadValues([]);\n }\n }\n }, [table, column, getSuggestions, value, NO_FREE_TEXT]);\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (evt) => {\n const { value: newValue } = evt.target;\n const { current: value } = valueRef;\n if (value === \"\" && newValue) {\n setOpen(true);\n const input = rootRef.current?.querySelector(\"input\");\n if (input && highlightFirstSuggestion) {\n pendingListFocusRef.current = true;\n }\n } else if (newValue === \"\" && value) {\n // treat clear value as a commit event\n onCommit(evt, \"\");\n }\n setValue(newValue);\n },\n [highlightFirstSuggestion, onCommit, setValue, valueRef],\n );\n\n const handleSelectionChange = (\n evt: SyntheticEvent,\n [newSelected]: string[],\n ) => {\n if (commitTimeout.current) {\n clearTimeout(commitTimeout.current);\n commitTimeout.current = null;\n }\n setValue(newSelected);\n onCommit(\n evt as SyntheticEvent<HTMLInputElement>,\n newSelected,\n \"typeahead-suggestion\",\n );\n };\n\n const handleOpenChange = (newOpen: boolean) => {\n if (newOpen && valueRef.current === \"\") {\n // ignore this, don't open dropdown unless user has typed at least one character\n } else {\n setOpen(newOpen);\n }\n };\n\n const inputProps: ComponentPropsWithoutRef<\"input\"> = {\n ...inputPropsProp,\n autoComplete: \"off\",\n };\n\n const [noFreeText] = NO_FREE_TEXT;\n return {\n inputProps,\n noFreeText,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n onOpenChange: handleOpenChange,\n onSelectionChange: handleSelectionChange,\n open,\n ref: callbackRef,\n typeaheadValues,\n value: valueRef.current,\n };\n};\n"],"names":["useMemo","useStateRef","useState","useRef","useTypeaheadSuggestions","useCallback","value","useEffect","getVuuTable","NO_DATA_MATCH","dispatchKeyboardEvent"],"mappings":";;;;;;AAiCA,MAAM,sBACJ,GAAA,uMAAA;AAEK,MAAM,uBAAuB,CAAC;AAAA,EACnC,cAAiB,GAAA,IAAA;AAAA,EACjB,MAAA;AAAA,EACA,eAAA;AAAA,EACA,wBAA2B,GAAA,IAAA;AAAA,EAC3B,UAAY,EAAA,cAAA;AAAA,EACZ,QAAA;AAAA,EACA;AACF,CAAkC,KAAA;AAChC,EAAA,MAAM,YAAe,GAAAA,aAAA;AAAA,IACnB,MAAM,CAAC,eAAA,IAAmB,sBAAsB,CAAA;AAAA,IAChD,CAAC,eAAe;AAAA,GAClB;AACA,EAAA,MAAM,CAAC,QAAA,EAAU,QAAQ,CAAA,GAAIC,qBAAY,EAAE,CAAA;AAC3C,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIC,eAAS,KAAK,CAAA;AACtC,EAAM,MAAA,QAAA,GAAWC,aAAgC,IAAI,CAAA;AACrD,EAAM,MAAA,OAAA,GAAUA,aAA8B,IAAI,CAAA;AAClD,EAAA,MAAM,CAAC,eAAiB,EAAA,kBAAkB,CAAI,GAAAD,cAAA,CAAmB,EAAE,CAAA;AACnE,EAAA,MAAM,iBAAiBE,oCAAwB,EAAA;AAC/C,EAAM,MAAA,mBAAA,GAAsBD,aAAO,KAAK,CAAA;AAExC,EAAM,MAAA,EAAE,OAAS,EAAA,KAAA,EAAU,GAAA,QAAA;AAC3B,EAAM,MAAA,aAAA,GAAgBA,aAA6C,IAAI,CAAA;AAEvE,EAAA,MAAM,aAAgB,GAAAE,iBAAA;AAAA,IACpB,CAAC,GAAQ,KAAA;AACP,MAAM,MAAA,EAAE,OAASC,EAAAA,MAAAA,EAAU,GAAA,QAAA;AAC3B,MAAA,IAAI,GAAI,CAAA,GAAA,KAAQ,OAAWA,IAAAA,MAAAA,KAAU,EAAI,EAAA;AACvC,QAAA,IAAI,cAAgB,EAAA;AAClB,UAAc,aAAA,CAAA,OAAA,GAAU,WAAW,MAAM;AACvC,YAAW,QAAA,GAAA,GAAA,EAAKA,QAAO,YAAY,CAAA;AACnC,YAAA,OAAA,CAAQ,KAAK,CAAA;AACb,YAAA,aAAA,CAAc,OAAU,GAAA,IAAA;AAAA,aACvB,GAAG,CAAA;AAAA,SACD,MAAA;AACL,UAAA,kBAAA,CAAmB,YAAY,CAAA;AAAA;AACjC;AACF,KACF;AAAA,IACA,CAAC,YAAA,EAAc,cAAgB,EAAA,QAAA,EAAU,QAAQ;AAAA,GACnD;AAEA,EAAM,MAAA,WAAA,GAAcD,iBAAyC,CAAA,CAAC,EAAO,KAAA;AACnE,IAAA,OAAA,CAAQ,OAAU,GAAA,EAAA;AAClB,IAAA,MAAM,KAAQ,GAAA,EAAA,EAAI,aAAc,CAAA,OAAO,CAAK,IAAA,IAAA;AAC5C,IAAA,QAAA,CAAS,OAAU,GAAA,KAAA;AAAA,GACrB,EAAG,EAAE,CAAA;AAEL,EAAAE,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAO,EAAA;AACT,MAAM,MAAA,QAAA,GAAWC,qBAAY,KAAK,CAAA;AAClC,MAAA,IAAI,KAAO,EAAA;AACT,QAAM,MAAA,MAAA,GAA0B,QAC5B,CAAC,QAAA,EAAU,QAAQ,KAAK,CAAA,GACxB,CAAC,QAAA,EAAU,MAAM,CAAA;AACrB,QAAA,cAAA,CAAe,MAAM,CAAA,CAClB,IAAK,CAAA,CAAC,WAAgB,KAAA;AACrB,UAAA,IAAI,gBAAgB,KAAO,EAAA;AAEzB,YAAA,kBAAA,CAAmB,EAAE,CAAA;AAAA,WACZ,MAAA,IAAA,WAAA,CAAY,MAAW,KAAA,CAAA,IAAK,KAAO,EAAA;AAC5C,YAAA,kBAAA;AAAA,cAAmB,CAAC,MAAA;AAAA;AAAA,gBAElB,MAAA,KAAW,eAAe,YAAe,GAAAC;AAAA;AAAA,aAC3C;AAAA,WACK,MAAA;AACL,YAAA,kBAAA,CAAmB,WAAW,CAAA;AAC9B,YAAI,IAAA,mBAAA,CAAoB,OAAW,IAAA,QAAA,CAAS,OAAS,EAAA;AAKnD,cAAsBC,8BAAA,CAAA,QAAA,CAAS,OAAS,EAAA,SAAA,EAAW,SAAS,CAAA;AAAA;AAC9D;AAEF,UAAA,mBAAA,CAAoB,OAAU,GAAA,KAAA;AAAA,SAC/B,CAAA,CACA,KAAM,CAAA,CAAC,GAAQ,KAAA;AACd,UAAQ,OAAA,CAAA,KAAA,CAAM,6BAA6B,GAAG,CAAA;AAAA,SAC/C,CAAA;AAAA,OACE,MAAA;AACL,QAAA,kBAAA,CAAmB,EAAE,CAAA;AAAA;AACvB;AACF,KACC,CAAC,KAAA,EAAO,QAAQ,cAAgB,EAAA,KAAA,EAAO,YAAY,CAAC,CAAA;AAEvD,EAAA,MAAM,YAAqD,GAAAL,iBAAA;AAAA,IACzD,CAAC,GAAQ,KAAA;AACP,MAAA,MAAM,EAAE,KAAA,EAAO,QAAS,EAAA,GAAI,GAAI,CAAA,MAAA;AAChC,MAAM,MAAA,EAAE,OAASC,EAAAA,MAAAA,EAAU,GAAA,QAAA;AAC3B,MAAIA,IAAAA,MAAAA,KAAU,MAAM,QAAU,EAAA;AAC5B,QAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,QAAA,MAAM,KAAQ,GAAA,OAAA,CAAQ,OAAS,EAAA,aAAA,CAAc,OAAO,CAAA;AACpD,QAAA,IAAI,SAAS,wBAA0B,EAAA;AACrC,UAAA,mBAAA,CAAoB,OAAU,GAAA,IAAA;AAAA;AAChC,OACF,MAAA,IAAW,QAAa,KAAA,EAAA,IAAMA,MAAO,EAAA;AAEnC,QAAA,QAAA,CAAS,KAAK,EAAE,CAAA;AAAA;AAElB,MAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,KACnB;AAAA,IACA,CAAC,wBAAA,EAA0B,QAAU,EAAA,QAAA,EAAU,QAAQ;AAAA,GACzD;AAEA,EAAA,MAAM,qBAAwB,GAAA,CAC5B,GACA,EAAA,CAAC,WAAW,CACT,KAAA;AACH,IAAA,IAAI,cAAc,OAAS,EAAA;AACzB,MAAA,YAAA,CAAa,cAAc,OAAO,CAAA;AAClC,MAAA,aAAA,CAAc,OAAU,GAAA,IAAA;AAAA;AAE1B,IAAA,QAAA,CAAS,WAAW,CAAA;AACpB,IAAA,QAAA;AAAA,MACE,GAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA,KACF;AAAA,GACF;AAEA,EAAM,MAAA,gBAAA,GAAmB,CAAC,OAAqB,KAAA;AAC7C,IAAI,IAAA,OAAA,IAAW,QAAS,CAAA,OAAA,KAAY,EAAI,EAAA,CAEjC,MAAA;AACL,MAAA,OAAA,CAAQ,OAAO,CAAA;AAAA;AACjB,GACF;AAEA,EAAA,MAAM,UAAgD,GAAA;AAAA,IACpD,GAAG,cAAA;AAAA,IACH,YAAc,EAAA;AAAA,GAChB;AAEA,EAAM,MAAA,CAAC,UAAU,CAAI,GAAA,YAAA;AACrB,EAAO,OAAA;AAAA,IACL,UAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAU,EAAA,YAAA;AAAA,IACV,SAAW,EAAA,aAAA;AAAA,IACX,YAAc,EAAA,gBAAA;AAAA,IACd,iBAAmB,EAAA,qBAAA;AAAA,IACnB,IAAA;AAAA,IACA,GAAK,EAAA,WAAA;AAAA,IACL,eAAA;AAAA,IACA,OAAO,QAAS,CAAA;AAAA,GAClB;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"useVuuTypeaheadInput.js","sources":["../../../../packages/vuu-ui-controls/src/vuu-typeahead-input/useVuuTypeaheadInput.ts"],"sourcesContent":["import { PillInputProps } from \"@salt-ds/core/dist-types/pill-input\";\nimport { useTypeaheadSuggestions } from \"@vuu-ui/vuu-data-react\";\nimport { TableSchemaTable } from \"@vuu-ui/vuu-data-types\";\nimport type { TypeaheadParams } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n dispatchKeyboardEvent,\n getVuuTable,\n useStateRef,\n NO_DATA_MATCH,\n type CommitHandler,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n ComponentPropsWithoutRef,\n KeyboardEventHandler,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ChangeEventHandler,\n type RefCallback,\n type SyntheticEvent,\n} from \"react\";\n\nconst meetsMinTextLengthThreshold = (value: string, minLength: number) =>\n value.length >= minLength;\n\nexport interface VuuTypeaheadInputHookProps {\n /**\n * Allows a text string to be submitted that does not match any suggestion\n * Defaults to true\n */\n allowFreeInput?: boolean;\n column: string;\n /**\n * A warning to display to the user if allowFreeText is false and they attempt\n * to commit text which does not match any suggestions. A default message will\n * be shown if not provided\n */\n freeTextWarning?: string;\n /**\n * When suggestions are displayed, should first option be highlighted ?\n * Highlighted option will be selected if Enter pressed. If this option\n * is not applied and no suggestion is highlighted, Enter will commit\n * current text. This will be desirable if filter operator will be\n * 'contains', not if filter operator will be '='.\n */\n highlightFirstSuggestion?: boolean;\n inputProps?: PillInputProps[\"inputProps\"];\n /**\n * If zero, suggestions will be shown even without any text input.\n * Suggestions will be displayed on click, or, if focused via keynoard,\n * on ArrowDown.\n * If n, where n > 0, then n characters must be typed before suggestion\n * list will be fetched.\n */\n minCharacterCountToTriggerSuggestions?: 0 | 1 | 2 | 3;\n onCommit: CommitHandler<HTMLInputElement>;\n table: TableSchemaTable;\n}\n\nconst defaultFreeTextWarning =\n \"Please select a value from the list of suggestions. If no suggestions match your text, then the value is not valid. If you believe this should be a valid value, please reach out to the support team\";\n\nexport const useVuuTypeaheadInput = ({\n allowFreeInput = true,\n column,\n freeTextWarning,\n highlightFirstSuggestion = true,\n inputProps: inputPropsProp,\n minCharacterCountToTriggerSuggestions = 1,\n onCommit,\n table,\n}: VuuTypeaheadInputHookProps) => {\n const NO_FREE_TEXT = useMemo(\n () => [freeTextWarning ?? defaultFreeTextWarning],\n [freeTextWarning],\n );\n const [valueRef, setValue] = useStateRef(\"\");\n const [open, setOpen] = useState(false);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [typeaheadValues, setTypeaheadValues] = useState<string[]>([]);\n const getSuggestions = useTypeaheadSuggestions();\n const pendingListFocusRef = useRef(false);\n\n const { current: value } = valueRef;\n const commitTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (evt) => {\n const { current: value } = valueRef;\n if (evt.key === \"Enter\" && value !== \"\") {\n if (allowFreeInput) {\n commitTimeout.current = setTimeout(() => {\n onCommit?.(evt, value, \"text-input\");\n setOpen(false);\n commitTimeout.current = null;\n }, 200);\n } else {\n setTypeaheadValues(NO_FREE_TEXT);\n }\n } else if (evt.key === \"Enter\" && value === \"\") {\n console.log(\"ENTER no value\");\n }\n },\n [NO_FREE_TEXT, allowFreeInput, onCommit, valueRef],\n );\n\n const callbackRef = useCallback<RefCallback<HTMLDivElement>>((el) => {\n rootRef.current = el;\n const input = el?.querySelector(\"input\") ?? null;\n inputRef.current = input;\n }, []);\n\n useEffect(() => {\n if (table) {\n const vuuTable = getVuuTable(table);\n if (\n meetsMinTextLengthThreshold(\n value,\n minCharacterCountToTriggerSuggestions,\n )\n ) {\n const params: TypeaheadParams = value\n ? [vuuTable, column, value]\n : [vuuTable, column];\n getSuggestions(params)\n .then((suggestions) => {\n console.log({ suggestions });\n if (suggestions === false) {\n // TODO is this right\n setTypeaheadValues([]);\n } else if (suggestions.length === 0 && value) {\n setTypeaheadValues((values) =>\n // Do not update if we have already set suggestions to the no free text warning\n values === NO_FREE_TEXT ? NO_FREE_TEXT : NO_DATA_MATCH,\n );\n } else {\n setTypeaheadValues(suggestions);\n if (pendingListFocusRef.current && inputRef.current) {\n // This is a workaround for the fact that ComboBox does not automatically\n // highlight first list item when items have been populated dynamically.\n // This has been raised as a bug.\n //TODO this is failing to work correctly in new version of cypress\n dispatchKeyboardEvent(inputRef.current, \"keydown\", \"ArrowUp\");\n }\n }\n pendingListFocusRef.current = false;\n })\n .catch((err) => {\n console.error(\"Error getting suggestions\", err);\n });\n } else {\n setTypeaheadValues([]);\n }\n }\n }, [\n table,\n column,\n getSuggestions,\n value,\n NO_FREE_TEXT,\n minCharacterCountToTriggerSuggestions,\n ]);\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (evt) => {\n const { value: newValue } = evt.target;\n const { current: value } = valueRef;\n if (value === \"\" && newValue) {\n setOpen(true);\n const input = rootRef.current?.querySelector(\"input\");\n if (input && highlightFirstSuggestion) {\n pendingListFocusRef.current = true;\n }\n } else if (newValue === \"\" && value) {\n // treat clear value as a commit event\n onCommit(evt, \"\");\n }\n setValue(newValue);\n },\n [highlightFirstSuggestion, onCommit, setValue, valueRef],\n );\n\n const handleSelectionChange = (\n evt: SyntheticEvent,\n [newSelected]: string[],\n ) => {\n if (commitTimeout.current) {\n clearTimeout(commitTimeout.current);\n commitTimeout.current = null;\n }\n setValue(newSelected);\n onCommit(\n evt as SyntheticEvent<HTMLInputElement>,\n newSelected,\n \"typeahead-suggestion\",\n );\n };\n\n const handleOpenChange = (newOpen: boolean) => {\n if (newOpen && valueRef.current === \"\") {\n // ignore this, don't open dropdown unless user has typed at least one character\n setOpen(newOpen);\n } else {\n setOpen(newOpen);\n }\n };\n\n const inputProps: ComponentPropsWithoutRef<\"input\"> = {\n ...inputPropsProp,\n autoComplete: \"off\",\n };\n\n const [noFreeText] = NO_FREE_TEXT;\n return {\n inputProps,\n noFreeText,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n onOpenChange: handleOpenChange,\n onSelectionChange: handleSelectionChange,\n open,\n ref: callbackRef,\n typeaheadValues,\n value: valueRef.current,\n };\n};\n"],"names":["useMemo","useStateRef","useState","useRef","useTypeaheadSuggestions","useCallback","value","useEffect","getVuuTable","NO_DATA_MATCH","dispatchKeyboardEvent"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var vuuTypeaheadInputCss = ".vuuTypeaheadInput {\n .saltPillInput-activationIndicator {\n display: none;\n }\n\n .saltButton {\n height:
|
|
1
|
+
var vuuTypeaheadInputCss = ".vuuTypeaheadInput {\n .saltPillInput-activationIndicator {\n display: none;\n }\n\n .saltPillInput-endAdornmentContainer {\n padding:0;\n }\n\n .saltButton {\n --vuuButton-borderColor: transparent;\n height: 24px;\n width: 24px;\n }\n\n .saltButton:before {\n content: \"\";\n background-color: var(--salt-separable-secondary-borderColor);\n height: 100%;\n left: calc(-1 * var(--salt-spacing-100));\n position: absolute;\n width: 1px;\n }\n\n .saltButton:after {\n --vuu-icon-color: var(--salt-content-primary-foreground);\n --vuu-icon-size: 10px;\n --vuu-icon-transform: rotate(45deg);\n\n content: \"\";\n background-color: var(--vuu-icon-color);\n height: var(--vuu-icon-size);\n mask: var(--vuu-svg-triangle-right) center center/var(--vuu-icon-size)\n var(--vuu-icon-size);\n mask-repeat: no-repeat;\n position: absolute;\n top: 3px;\n transform: var(--vuu-icon-transform, none);\n width: var(--vuu-icon-size);\n }\n}\n\n.vuuTypeaheadOption[aria-disabled=\"true\"] {\n color: var(--salt-content-secondary-foreground);\n}\n";
|
|
2
2
|
|
|
3
3
|
export { vuuTypeaheadInputCss as default };
|
|
4
4
|
//# sourceMappingURL=VuuTypeaheadInput.css.js.map
|
|
@@ -16,6 +16,7 @@ const VuuTypeaheadInput = ({
|
|
|
16
16
|
freeTextWarning,
|
|
17
17
|
highlightFirstSuggestion,
|
|
18
18
|
inputProps: inputPropsProp,
|
|
19
|
+
minCharacterCountToTriggerSuggestions,
|
|
19
20
|
onCommit,
|
|
20
21
|
table
|
|
21
22
|
}) => {
|
|
@@ -42,6 +43,7 @@ const VuuTypeaheadInput = ({
|
|
|
42
43
|
freeTextWarning,
|
|
43
44
|
highlightFirstSuggestion,
|
|
44
45
|
inputProps: inputPropsProp,
|
|
46
|
+
minCharacterCountToTriggerSuggestions,
|
|
45
47
|
onCommit,
|
|
46
48
|
table
|
|
47
49
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VuuTypeaheadInput.js","sources":["../../../../packages/vuu-ui-controls/src/vuu-typeahead-input/VuuTypeaheadInput.tsx"],"sourcesContent":["import { ComboBox, Option } from \"@salt-ds/core\";\nimport {
|
|
1
|
+
{"version":3,"file":"VuuTypeaheadInput.js","sources":["../../../../packages/vuu-ui-controls/src/vuu-typeahead-input/VuuTypeaheadInput.tsx"],"sourcesContent":["import { ComboBox, Option } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { NO_DATA_MATCH } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport {\n useVuuTypeaheadInput,\n VuuTypeaheadInputHookProps,\n} from \"./useVuuTypeaheadInput\";\nimport vuuTypeaheadInputCss from \"./VuuTypeaheadInput.css\";\n\nconst classBase = \"vuuTypeaheadInput\";\nconst [noMatchingData] = NO_DATA_MATCH;\n\nexport interface VuuTypeaheadInputProps extends VuuTypeaheadInputHookProps {\n className?: string;\n}\n\nexport const VuuTypeaheadInput = ({\n allowFreeInput,\n className,\n column,\n freeTextWarning,\n highlightFirstSuggestion,\n inputProps: inputPropsProp,\n minCharacterCountToTriggerSuggestions,\n onCommit,\n table,\n}: VuuTypeaheadInputProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-typeahead-input\",\n css: vuuTypeaheadInputCss,\n window: targetWindow,\n });\n\n const {\n inputProps,\n noFreeText,\n onChange,\n onKeyDown,\n onOpenChange,\n onSelectionChange,\n open,\n ref,\n typeaheadValues,\n value,\n } = useVuuTypeaheadInput({\n allowFreeInput,\n column,\n freeTextWarning,\n highlightFirstSuggestion,\n inputProps: inputPropsProp,\n minCharacterCountToTriggerSuggestions,\n onCommit,\n table,\n });\n\n // need latest version of salt combobox\n // const defaultHighlightedIndex =\n // highlightFirstSuggestion === false ? -1 : undefined;\n\n return (\n <ComboBox\n className={cx(classBase, className)}\n // defaultHighlightedIndex={defaultHighlightedIndex}\n inputProps={inputProps}\n onChange={onChange}\n onKeyDown={onKeyDown}\n onOpenChange={onOpenChange}\n onSelectionChange={onSelectionChange}\n open={open}\n ref={ref}\n value={value}\n >\n {typeaheadValues.map((state) => (\n <Option\n className=\"vuuTypeaheadOption\"\n value={state}\n key={state}\n disabled={state === noMatchingData || state === noFreeText}\n />\n ))}\n </ComboBox>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAWA,MAAM,SAAY,GAAA,mBAAA;AAClB,MAAM,CAAC,cAAc,CAAI,GAAA,aAAA;AAMlB,MAAM,oBAAoB,CAAC;AAAA,EAChC,cAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,eAAA;AAAA,EACA,wBAAA;AAAA,EACA,UAAY,EAAA,cAAA;AAAA,EACZ,qCAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAA8B,KAAA;AAC5B,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,qBAAA;AAAA,IACR,GAAK,EAAA,oBAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA;AAAA,IACJ,UAAA;AAAA,IACA,UAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAA;AAAA,IACA,iBAAA;AAAA,IACA,IAAA;AAAA,IACA,GAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,MACE,oBAAqB,CAAA;AAAA,IACvB,cAAA;AAAA,IACA,MAAA;AAAA,IACA,eAAA;AAAA,IACA,wBAAA;AAAA,IACA,UAAY,EAAA,cAAA;AAAA,IACZ,qCAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACD,CAAA;AAMD,EACE,uBAAA,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAElC,UAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,YAAA;AAAA,MACA,iBAAA;AAAA,MACA,IAAA;AAAA,MACA,GAAA;AAAA,MACA,KAAA;AAAA,MAEC,QAAA,EAAA,eAAA,CAAgB,GAAI,CAAA,CAAC,KACpB,qBAAA,GAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,SAAU,EAAA,oBAAA;AAAA,UACV,KAAO,EAAA,KAAA;AAAA,UAEP,QAAA,EAAU,KAAU,KAAA,cAAA,IAAkB,KAAU,KAAA;AAAA,SAAA;AAAA,QAD3C;AAAA,OAGR;AAAA;AAAA,GACH;AAEJ;;;;"}
|
|
@@ -2,6 +2,7 @@ import { useTypeaheadSuggestions } from '@vuu-ui/vuu-data-react';
|
|
|
2
2
|
import { useStateRef, getVuuTable, NO_DATA_MATCH, dispatchKeyboardEvent } from '@vuu-ui/vuu-utils';
|
|
3
3
|
import { useMemo, useState, useRef, useCallback, useEffect } from 'react';
|
|
4
4
|
|
|
5
|
+
const meetsMinTextLengthThreshold = (value, minLength) => value.length >= minLength;
|
|
5
6
|
const defaultFreeTextWarning = "Please select a value from the list of suggestions. If no suggestions match your text, then the value is not valid. If you believe this should be a valid value, please reach out to the support team";
|
|
6
7
|
const useVuuTypeaheadInput = ({
|
|
7
8
|
allowFreeInput = true,
|
|
@@ -9,6 +10,7 @@ const useVuuTypeaheadInput = ({
|
|
|
9
10
|
freeTextWarning,
|
|
10
11
|
highlightFirstSuggestion = true,
|
|
11
12
|
inputProps: inputPropsProp,
|
|
13
|
+
minCharacterCountToTriggerSuggestions = 1,
|
|
12
14
|
onCommit,
|
|
13
15
|
table
|
|
14
16
|
}) => {
|
|
@@ -38,6 +40,8 @@ const useVuuTypeaheadInput = ({
|
|
|
38
40
|
} else {
|
|
39
41
|
setTypeaheadValues(NO_FREE_TEXT);
|
|
40
42
|
}
|
|
43
|
+
} else if (evt.key === "Enter" && value2 === "") {
|
|
44
|
+
console.log("ENTER no value");
|
|
41
45
|
}
|
|
42
46
|
},
|
|
43
47
|
[NO_FREE_TEXT, allowFreeInput, onCommit, valueRef]
|
|
@@ -50,9 +54,13 @@ const useVuuTypeaheadInput = ({
|
|
|
50
54
|
useEffect(() => {
|
|
51
55
|
if (table) {
|
|
52
56
|
const vuuTable = getVuuTable(table);
|
|
53
|
-
if (
|
|
57
|
+
if (meetsMinTextLengthThreshold(
|
|
58
|
+
value,
|
|
59
|
+
minCharacterCountToTriggerSuggestions
|
|
60
|
+
)) {
|
|
54
61
|
const params = value ? [vuuTable, column, value] : [vuuTable, column];
|
|
55
62
|
getSuggestions(params).then((suggestions) => {
|
|
63
|
+
console.log({ suggestions });
|
|
56
64
|
if (suggestions === false) {
|
|
57
65
|
setTypeaheadValues([]);
|
|
58
66
|
} else if (suggestions.length === 0 && value) {
|
|
@@ -76,7 +84,14 @@ const useVuuTypeaheadInput = ({
|
|
|
76
84
|
setTypeaheadValues([]);
|
|
77
85
|
}
|
|
78
86
|
}
|
|
79
|
-
}, [
|
|
87
|
+
}, [
|
|
88
|
+
table,
|
|
89
|
+
column,
|
|
90
|
+
getSuggestions,
|
|
91
|
+
value,
|
|
92
|
+
NO_FREE_TEXT,
|
|
93
|
+
minCharacterCountToTriggerSuggestions
|
|
94
|
+
]);
|
|
80
95
|
const handleChange = useCallback(
|
|
81
96
|
(evt) => {
|
|
82
97
|
const { value: newValue } = evt.target;
|
|
@@ -107,7 +122,9 @@ const useVuuTypeaheadInput = ({
|
|
|
107
122
|
);
|
|
108
123
|
};
|
|
109
124
|
const handleOpenChange = (newOpen) => {
|
|
110
|
-
if (newOpen && valueRef.current === "")
|
|
125
|
+
if (newOpen && valueRef.current === "") {
|
|
126
|
+
setOpen(newOpen);
|
|
127
|
+
} else {
|
|
111
128
|
setOpen(newOpen);
|
|
112
129
|
}
|
|
113
130
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVuuTypeaheadInput.js","sources":["../../../../packages/vuu-ui-controls/src/vuu-typeahead-input/useVuuTypeaheadInput.ts"],"sourcesContent":["import { useTypeaheadSuggestions } from \"@vuu-ui/vuu-data-react\";\nimport type { TypeaheadParams } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n dispatchKeyboardEvent,\n getVuuTable,\n useStateRef,\n NO_DATA_MATCH,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n ComponentPropsWithoutRef,\n KeyboardEventHandler,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ChangeEventHandler,\n type RefCallback,\n type SyntheticEvent,\n} from \"react\";\nimport type { VuuTypeaheadInputProps } from \"./VuuTypeaheadInput\";\n\nexport type VuuTypeaheadInputHookProps = Pick<\n VuuTypeaheadInputProps,\n | \"allowFreeInput\"\n | \"column\"\n | \"freeTextWarning\"\n | \"highlightFirstSuggestion\"\n | \"inputProps\"\n | \"onCommit\"\n | \"table\"\n>;\n\nconst defaultFreeTextWarning =\n \"Please select a value from the list of suggestions. If no suggestions match your text, then the value is not valid. If you believe this should be a valid value, please reach out to the support team\";\n\nexport const useVuuTypeaheadInput = ({\n allowFreeInput = true,\n column,\n freeTextWarning,\n highlightFirstSuggestion = true,\n inputProps: inputPropsProp,\n onCommit,\n table,\n}: VuuTypeaheadInputHookProps) => {\n const NO_FREE_TEXT = useMemo(\n () => [freeTextWarning ?? defaultFreeTextWarning],\n [freeTextWarning],\n );\n const [valueRef, setValue] = useStateRef(\"\");\n const [open, setOpen] = useState(false);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [typeaheadValues, setTypeaheadValues] = useState<string[]>([]);\n const getSuggestions = useTypeaheadSuggestions();\n const pendingListFocusRef = useRef(false);\n\n const { current: value } = valueRef;\n const commitTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (evt) => {\n const { current: value } = valueRef;\n if (evt.key === \"Enter\" && value !== \"\") {\n if (allowFreeInput) {\n commitTimeout.current = setTimeout(() => {\n onCommit?.(evt, value, \"text-input\");\n setOpen(false);\n commitTimeout.current = null;\n }, 200);\n } else {\n setTypeaheadValues(NO_FREE_TEXT);\n }\n }\n },\n [NO_FREE_TEXT, allowFreeInput, onCommit, valueRef],\n );\n\n const callbackRef = useCallback<RefCallback<HTMLDivElement>>((el) => {\n rootRef.current = el;\n const input = el?.querySelector(\"input\") ?? null;\n inputRef.current = input;\n }, []);\n\n useEffect(() => {\n if (table) {\n const vuuTable = getVuuTable(table);\n if (value) {\n const params: TypeaheadParams = value\n ? [vuuTable, column, value]\n : [vuuTable, column];\n getSuggestions(params)\n .then((suggestions) => {\n if (suggestions === false) {\n // TODO is this right\n setTypeaheadValues([]);\n } else if (suggestions.length === 0 && value) {\n setTypeaheadValues((values) =>\n // Do not update if we have already set suggestions to the no free text warning\n values === NO_FREE_TEXT ? NO_FREE_TEXT : NO_DATA_MATCH,\n );\n } else {\n setTypeaheadValues(suggestions);\n if (pendingListFocusRef.current && inputRef.current) {\n // This is a workaround for the fact that ComboBox does not automatically\n // highlight first list item when items have been populated dynamically.\n // This has been raised as a bug.\n //TODO this is failing to work correctly in new version of cypress\n dispatchKeyboardEvent(inputRef.current, \"keydown\", \"ArrowUp\");\n }\n }\n pendingListFocusRef.current = false;\n })\n .catch((err) => {\n console.error(\"Error getting suggestions\", err);\n });\n } else {\n setTypeaheadValues([]);\n }\n }\n }, [table, column, getSuggestions, value, NO_FREE_TEXT]);\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (evt) => {\n const { value: newValue } = evt.target;\n const { current: value } = valueRef;\n if (value === \"\" && newValue) {\n setOpen(true);\n const input = rootRef.current?.querySelector(\"input\");\n if (input && highlightFirstSuggestion) {\n pendingListFocusRef.current = true;\n }\n } else if (newValue === \"\" && value) {\n // treat clear value as a commit event\n onCommit(evt, \"\");\n }\n setValue(newValue);\n },\n [highlightFirstSuggestion, onCommit, setValue, valueRef],\n );\n\n const handleSelectionChange = (\n evt: SyntheticEvent,\n [newSelected]: string[],\n ) => {\n if (commitTimeout.current) {\n clearTimeout(commitTimeout.current);\n commitTimeout.current = null;\n }\n setValue(newSelected);\n onCommit(\n evt as SyntheticEvent<HTMLInputElement>,\n newSelected,\n \"typeahead-suggestion\",\n );\n };\n\n const handleOpenChange = (newOpen: boolean) => {\n if (newOpen && valueRef.current === \"\") {\n // ignore this, don't open dropdown unless user has typed at least one character\n } else {\n setOpen(newOpen);\n }\n };\n\n const inputProps: ComponentPropsWithoutRef<\"input\"> = {\n ...inputPropsProp,\n autoComplete: \"off\",\n };\n\n const [noFreeText] = NO_FREE_TEXT;\n return {\n inputProps,\n noFreeText,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n onOpenChange: handleOpenChange,\n onSelectionChange: handleSelectionChange,\n open,\n ref: callbackRef,\n typeaheadValues,\n value: valueRef.current,\n };\n};\n"],"names":["value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useVuuTypeaheadInput.js","sources":["../../../../packages/vuu-ui-controls/src/vuu-typeahead-input/useVuuTypeaheadInput.ts"],"sourcesContent":["import { PillInputProps } from \"@salt-ds/core/dist-types/pill-input\";\nimport { useTypeaheadSuggestions } from \"@vuu-ui/vuu-data-react\";\nimport { TableSchemaTable } from \"@vuu-ui/vuu-data-types\";\nimport type { TypeaheadParams } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n dispatchKeyboardEvent,\n getVuuTable,\n useStateRef,\n NO_DATA_MATCH,\n type CommitHandler,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n ComponentPropsWithoutRef,\n KeyboardEventHandler,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ChangeEventHandler,\n type RefCallback,\n type SyntheticEvent,\n} from \"react\";\n\nconst meetsMinTextLengthThreshold = (value: string, minLength: number) =>\n value.length >= minLength;\n\nexport interface VuuTypeaheadInputHookProps {\n /**\n * Allows a text string to be submitted that does not match any suggestion\n * Defaults to true\n */\n allowFreeInput?: boolean;\n column: string;\n /**\n * A warning to display to the user if allowFreeText is false and they attempt\n * to commit text which does not match any suggestions. A default message will\n * be shown if not provided\n */\n freeTextWarning?: string;\n /**\n * When suggestions are displayed, should first option be highlighted ?\n * Highlighted option will be selected if Enter pressed. If this option\n * is not applied and no suggestion is highlighted, Enter will commit\n * current text. This will be desirable if filter operator will be\n * 'contains', not if filter operator will be '='.\n */\n highlightFirstSuggestion?: boolean;\n inputProps?: PillInputProps[\"inputProps\"];\n /**\n * If zero, suggestions will be shown even without any text input.\n * Suggestions will be displayed on click, or, if focused via keynoard,\n * on ArrowDown.\n * If n, where n > 0, then n characters must be typed before suggestion\n * list will be fetched.\n */\n minCharacterCountToTriggerSuggestions?: 0 | 1 | 2 | 3;\n onCommit: CommitHandler<HTMLInputElement>;\n table: TableSchemaTable;\n}\n\nconst defaultFreeTextWarning =\n \"Please select a value from the list of suggestions. If no suggestions match your text, then the value is not valid. If you believe this should be a valid value, please reach out to the support team\";\n\nexport const useVuuTypeaheadInput = ({\n allowFreeInput = true,\n column,\n freeTextWarning,\n highlightFirstSuggestion = true,\n inputProps: inputPropsProp,\n minCharacterCountToTriggerSuggestions = 1,\n onCommit,\n table,\n}: VuuTypeaheadInputHookProps) => {\n const NO_FREE_TEXT = useMemo(\n () => [freeTextWarning ?? defaultFreeTextWarning],\n [freeTextWarning],\n );\n const [valueRef, setValue] = useStateRef(\"\");\n const [open, setOpen] = useState(false);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [typeaheadValues, setTypeaheadValues] = useState<string[]>([]);\n const getSuggestions = useTypeaheadSuggestions();\n const pendingListFocusRef = useRef(false);\n\n const { current: value } = valueRef;\n const commitTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLInputElement>>(\n (evt) => {\n const { current: value } = valueRef;\n if (evt.key === \"Enter\" && value !== \"\") {\n if (allowFreeInput) {\n commitTimeout.current = setTimeout(() => {\n onCommit?.(evt, value, \"text-input\");\n setOpen(false);\n commitTimeout.current = null;\n }, 200);\n } else {\n setTypeaheadValues(NO_FREE_TEXT);\n }\n } else if (evt.key === \"Enter\" && value === \"\") {\n console.log(\"ENTER no value\");\n }\n },\n [NO_FREE_TEXT, allowFreeInput, onCommit, valueRef],\n );\n\n const callbackRef = useCallback<RefCallback<HTMLDivElement>>((el) => {\n rootRef.current = el;\n const input = el?.querySelector(\"input\") ?? null;\n inputRef.current = input;\n }, []);\n\n useEffect(() => {\n if (table) {\n const vuuTable = getVuuTable(table);\n if (\n meetsMinTextLengthThreshold(\n value,\n minCharacterCountToTriggerSuggestions,\n )\n ) {\n const params: TypeaheadParams = value\n ? [vuuTable, column, value]\n : [vuuTable, column];\n getSuggestions(params)\n .then((suggestions) => {\n console.log({ suggestions });\n if (suggestions === false) {\n // TODO is this right\n setTypeaheadValues([]);\n } else if (suggestions.length === 0 && value) {\n setTypeaheadValues((values) =>\n // Do not update if we have already set suggestions to the no free text warning\n values === NO_FREE_TEXT ? NO_FREE_TEXT : NO_DATA_MATCH,\n );\n } else {\n setTypeaheadValues(suggestions);\n if (pendingListFocusRef.current && inputRef.current) {\n // This is a workaround for the fact that ComboBox does not automatically\n // highlight first list item when items have been populated dynamically.\n // This has been raised as a bug.\n //TODO this is failing to work correctly in new version of cypress\n dispatchKeyboardEvent(inputRef.current, \"keydown\", \"ArrowUp\");\n }\n }\n pendingListFocusRef.current = false;\n })\n .catch((err) => {\n console.error(\"Error getting suggestions\", err);\n });\n } else {\n setTypeaheadValues([]);\n }\n }\n }, [\n table,\n column,\n getSuggestions,\n value,\n NO_FREE_TEXT,\n minCharacterCountToTriggerSuggestions,\n ]);\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (evt) => {\n const { value: newValue } = evt.target;\n const { current: value } = valueRef;\n if (value === \"\" && newValue) {\n setOpen(true);\n const input = rootRef.current?.querySelector(\"input\");\n if (input && highlightFirstSuggestion) {\n pendingListFocusRef.current = true;\n }\n } else if (newValue === \"\" && value) {\n // treat clear value as a commit event\n onCommit(evt, \"\");\n }\n setValue(newValue);\n },\n [highlightFirstSuggestion, onCommit, setValue, valueRef],\n );\n\n const handleSelectionChange = (\n evt: SyntheticEvent,\n [newSelected]: string[],\n ) => {\n if (commitTimeout.current) {\n clearTimeout(commitTimeout.current);\n commitTimeout.current = null;\n }\n setValue(newSelected);\n onCommit(\n evt as SyntheticEvent<HTMLInputElement>,\n newSelected,\n \"typeahead-suggestion\",\n );\n };\n\n const handleOpenChange = (newOpen: boolean) => {\n if (newOpen && valueRef.current === \"\") {\n // ignore this, don't open dropdown unless user has typed at least one character\n setOpen(newOpen);\n } else {\n setOpen(newOpen);\n }\n };\n\n const inputProps: ComponentPropsWithoutRef<\"input\"> = {\n ...inputPropsProp,\n autoComplete: \"off\",\n };\n\n const [noFreeText] = NO_FREE_TEXT;\n return {\n inputProps,\n noFreeText,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n onOpenChange: handleOpenChange,\n onSelectionChange: handleSelectionChange,\n open,\n ref: callbackRef,\n typeaheadValues,\n value: valueRef.current,\n };\n};\n"],"names":["value"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.13.
|
|
2
|
+
"version": "0.13.41",
|
|
3
3
|
"description": "VUU UI Controls",
|
|
4
4
|
"author": "heswell",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"devDependencies": {
|
|
7
|
-
"@vuu-ui/vuu-data-types": "0.13.
|
|
8
|
-
"@vuu-ui/vuu-protocol-types": "0.13.
|
|
9
|
-
"@vuu-ui/vuu-table-types": "0.13.
|
|
7
|
+
"@vuu-ui/vuu-data-types": "0.13.41",
|
|
8
|
+
"@vuu-ui/vuu-protocol-types": "0.13.41",
|
|
9
|
+
"@vuu-ui/vuu-table-types": "0.13.41"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@vuu-ui/vuu-context-menu": "0.13.
|
|
13
|
-
"@vuu-ui/vuu-data-react": "0.13.
|
|
14
|
-
"@vuu-ui/vuu-layout": "0.13.
|
|
15
|
-
"@vuu-ui/vuu-popups": "0.13.
|
|
16
|
-
"@vuu-ui/vuu-table": "0.13.
|
|
17
|
-
"@vuu-ui/vuu-utils": "0.13.
|
|
18
|
-
"@salt-ds/core": "1.
|
|
19
|
-
"@salt-ds/icons": "1.
|
|
12
|
+
"@vuu-ui/vuu-context-menu": "0.13.41",
|
|
13
|
+
"@vuu-ui/vuu-data-react": "0.13.41",
|
|
14
|
+
"@vuu-ui/vuu-layout": "0.13.41",
|
|
15
|
+
"@vuu-ui/vuu-popups": "0.13.41",
|
|
16
|
+
"@vuu-ui/vuu-table": "0.13.41",
|
|
17
|
+
"@vuu-ui/vuu-utils": "0.13.41",
|
|
18
|
+
"@salt-ds/core": "1.48.0",
|
|
19
|
+
"@salt-ds/icons": "1.14.0",
|
|
20
20
|
"@salt-ds/styles": "0.2.1",
|
|
21
21
|
"@salt-ds/window": "0.1.1",
|
|
22
22
|
"tabbable": "^6.0.0"
|
|
@@ -1,30 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { type CommitHandler } from "@vuu-ui/vuu-utils";
|
|
4
|
-
export interface VuuTypeaheadInputProps {
|
|
5
|
-
/**
|
|
6
|
-
* Allows a text string to be submitted that does not match any suggestion
|
|
7
|
-
* Defaults to true
|
|
8
|
-
*/
|
|
9
|
-
allowFreeInput?: boolean;
|
|
1
|
+
import { VuuTypeaheadInputHookProps } from "./useVuuTypeaheadInput";
|
|
2
|
+
export interface VuuTypeaheadInputProps extends VuuTypeaheadInputHookProps {
|
|
10
3
|
className?: string;
|
|
11
|
-
column: string;
|
|
12
|
-
/**
|
|
13
|
-
* A warning to display to the user if allowFreeText is false and they attempt
|
|
14
|
-
* to commit text which does not match any suggestions. A default message will
|
|
15
|
-
* be shown if not provided
|
|
16
|
-
*/
|
|
17
|
-
freeTextWarning?: string;
|
|
18
|
-
/**
|
|
19
|
-
* When suggestions are displayed, should first option be highlighted ?
|
|
20
|
-
* Highlighted option will be selected if Enter pressed. If this option
|
|
21
|
-
* is not applied and no suggestion is highlighted, Enter will commit
|
|
22
|
-
* current text. This will be desirable if filter operator will be
|
|
23
|
-
* 'contains', not if filter operator will be '='.
|
|
24
|
-
*/
|
|
25
|
-
highlightFirstSuggestion?: boolean;
|
|
26
|
-
inputProps?: PillInputProps["inputProps"];
|
|
27
|
-
onCommit: CommitHandler<HTMLInputElement>;
|
|
28
|
-
table: TableSchemaTable;
|
|
29
4
|
}
|
|
30
|
-
export declare const VuuTypeaheadInput: ({ allowFreeInput, className, column, freeTextWarning, highlightFirstSuggestion, inputProps: inputPropsProp, onCommit, table, }: VuuTypeaheadInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare const VuuTypeaheadInput: ({ allowFreeInput, className, column, freeTextWarning, highlightFirstSuggestion, inputProps: inputPropsProp, minCharacterCountToTriggerSuggestions, onCommit, table, }: VuuTypeaheadInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,7 +1,41 @@
|
|
|
1
|
+
import { PillInputProps } from "@salt-ds/core/dist-types/pill-input";
|
|
2
|
+
import { TableSchemaTable } from "@vuu-ui/vuu-data-types";
|
|
3
|
+
import { type CommitHandler } from "@vuu-ui/vuu-utils";
|
|
1
4
|
import { KeyboardEventHandler, type ChangeEventHandler, type RefCallback, type SyntheticEvent } from "react";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
export interface VuuTypeaheadInputHookProps {
|
|
6
|
+
/**
|
|
7
|
+
* Allows a text string to be submitted that does not match any suggestion
|
|
8
|
+
* Defaults to true
|
|
9
|
+
*/
|
|
10
|
+
allowFreeInput?: boolean;
|
|
11
|
+
column: string;
|
|
12
|
+
/**
|
|
13
|
+
* A warning to display to the user if allowFreeText is false and they attempt
|
|
14
|
+
* to commit text which does not match any suggestions. A default message will
|
|
15
|
+
* be shown if not provided
|
|
16
|
+
*/
|
|
17
|
+
freeTextWarning?: string;
|
|
18
|
+
/**
|
|
19
|
+
* When suggestions are displayed, should first option be highlighted ?
|
|
20
|
+
* Highlighted option will be selected if Enter pressed. If this option
|
|
21
|
+
* is not applied and no suggestion is highlighted, Enter will commit
|
|
22
|
+
* current text. This will be desirable if filter operator will be
|
|
23
|
+
* 'contains', not if filter operator will be '='.
|
|
24
|
+
*/
|
|
25
|
+
highlightFirstSuggestion?: boolean;
|
|
26
|
+
inputProps?: PillInputProps["inputProps"];
|
|
27
|
+
/**
|
|
28
|
+
* If zero, suggestions will be shown even without any text input.
|
|
29
|
+
* Suggestions will be displayed on click, or, if focused via keynoard,
|
|
30
|
+
* on ArrowDown.
|
|
31
|
+
* If n, where n > 0, then n characters must be typed before suggestion
|
|
32
|
+
* list will be fetched.
|
|
33
|
+
*/
|
|
34
|
+
minCharacterCountToTriggerSuggestions?: 0 | 1 | 2 | 3;
|
|
35
|
+
onCommit: CommitHandler<HTMLInputElement>;
|
|
36
|
+
table: TableSchemaTable;
|
|
37
|
+
}
|
|
38
|
+
export declare const useVuuTypeaheadInput: ({ allowFreeInput, column, freeTextWarning, highlightFirstSuggestion, inputProps: inputPropsProp, minCharacterCountToTriggerSuggestions, onCommit, table, }: VuuTypeaheadInputHookProps) => {
|
|
5
39
|
inputProps: Omit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">;
|
|
6
40
|
noFreeText: string;
|
|
7
41
|
onChange: ChangeEventHandler<HTMLInputElement>;
|