@devtools-ui/input 0.2.0-next.0 → 0.2.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +55 -8
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.legacy-esm.js +57 -9
- package/dist/index.mjs +57 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/components/InputComponent.tsx +45 -4
- package/src/components/__tests__/input.test.tsx +57 -0
- package/src/dsl/__tests__/Input.test.tsx +36 -0
- package/src/{components/hooks.ts → hooks/index.ts} +41 -5
- package/src/types/index.ts +9 -0
- package/types/{components/hooks.d.ts → hooks/index.d.ts} +7 -1
- package/types/types/index.d.ts +6 -0
package/dist/cjs/index.cjs
CHANGED
|
@@ -41,8 +41,8 @@ var import_react2 = __toESM(require("react"));
|
|
|
41
41
|
var import_react3 = require("@chakra-ui/react");
|
|
42
42
|
var import_react4 = require("@player-ui/react");
|
|
43
43
|
|
|
44
|
-
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/
|
|
45
|
-
var import_react =
|
|
44
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/hooks/index.ts
|
|
45
|
+
var import_react = require("react");
|
|
46
46
|
var getConfig = (userConfig = {}) => {
|
|
47
47
|
return {
|
|
48
48
|
decimalSymbol: ".",
|
|
@@ -53,8 +53,8 @@ var getConfig = (userConfig = {}) => {
|
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
55
|
var useInputAssetProps = (props, config) => {
|
|
56
|
-
const [localValue, setLocalValue] = import_react.
|
|
57
|
-
const formatTimerRef = import_react.
|
|
56
|
+
const [localValue, setLocalValue] = (0, import_react.useState)(props.value ?? "");
|
|
57
|
+
const formatTimerRef = (0, import_react.useRef)(void 0);
|
|
58
58
|
const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);
|
|
59
59
|
function clearPending() {
|
|
60
60
|
if (formatTimerRef.current) {
|
|
@@ -144,10 +144,10 @@ var useInputAssetProps = (props, config) => {
|
|
|
144
144
|
}
|
|
145
145
|
};
|
|
146
146
|
const propsValue = props.value;
|
|
147
|
-
import_react.
|
|
147
|
+
(0, import_react.useEffect)(() => {
|
|
148
148
|
setLocalValue(formatValueWithAffix(propsValue));
|
|
149
149
|
}, [propsValue]);
|
|
150
|
-
import_react.
|
|
150
|
+
(0, import_react.useEffect)(() => clearPending, []);
|
|
151
151
|
return {
|
|
152
152
|
onBlur,
|
|
153
153
|
onChange,
|
|
@@ -156,12 +156,59 @@ var useInputAssetProps = (props, config) => {
|
|
|
156
156
|
value: localValue
|
|
157
157
|
};
|
|
158
158
|
};
|
|
159
|
+
var useFileInputAssetProps = (props) => {
|
|
160
|
+
const { accept } = props;
|
|
161
|
+
const acceptedExtensions = accept ? accept.concat(".json").join(", ") : ".json";
|
|
162
|
+
const onFileUpload = (e) => {
|
|
163
|
+
const fileList = e.target.files;
|
|
164
|
+
const file = fileList ? fileList[0] : "";
|
|
165
|
+
const reader = new FileReader();
|
|
166
|
+
reader.addEventListener(
|
|
167
|
+
"load",
|
|
168
|
+
() => {
|
|
169
|
+
props.set(reader.result);
|
|
170
|
+
},
|
|
171
|
+
false
|
|
172
|
+
);
|
|
173
|
+
if (file) {
|
|
174
|
+
reader.readAsText(file);
|
|
175
|
+
props.handleFile && props.handleFile(file.name);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
return {
|
|
179
|
+
type: "file",
|
|
180
|
+
onChange: onFileUpload,
|
|
181
|
+
accept: acceptedExtensions
|
|
182
|
+
};
|
|
183
|
+
};
|
|
159
184
|
|
|
160
185
|
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
186
|
+
var FileInputComponent = (props) => {
|
|
187
|
+
const hiddenFileInput = (0, import_react2.useRef)(null);
|
|
188
|
+
const [fileName, setFileName] = (0, import_react2.useState)("");
|
|
189
|
+
const handleClick = () => {
|
|
190
|
+
hiddenFileInput.current?.click();
|
|
191
|
+
};
|
|
192
|
+
const handleFile = (fileName2) => {
|
|
193
|
+
setFileName(fileName2);
|
|
194
|
+
};
|
|
195
|
+
const { id, label } = props;
|
|
196
|
+
const inputProps = useFileInputAssetProps({ ...props, handleFile });
|
|
197
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_react3.FormControl, null, /* @__PURE__ */ import_react2.default.createElement(import_react3.Button, { className: "button-file", onClick: handleClick }, /* @__PURE__ */ import_react2.default.createElement(import_react3.FormLabel, { style: { margin: 0 } }, label ? /* @__PURE__ */ import_react2.default.createElement(import_react4.ReactAsset, { ...label.asset }) : /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, "Select Content"))), /* @__PURE__ */ import_react2.default.createElement(
|
|
198
|
+
import_react3.Input,
|
|
199
|
+
{
|
|
200
|
+
id,
|
|
201
|
+
name: id,
|
|
202
|
+
...inputProps,
|
|
203
|
+
style: { display: "none" },
|
|
204
|
+
ref: hiddenFileInput
|
|
205
|
+
}
|
|
206
|
+
), fileName ? /* @__PURE__ */ import_react2.default.createElement("p", null, "Uploaded file: ", fileName) : null);
|
|
207
|
+
};
|
|
161
208
|
var InputComponent = (props) => {
|
|
162
|
-
const { validation, label, id, note, size, maxLength, placeholder } = props;
|
|
209
|
+
const { validation, label, id, note, size, maxLength, placeholder, file } = props;
|
|
163
210
|
const inputProps = useInputAssetProps(props);
|
|
164
|
-
return /* @__PURE__ */ import_react2.default.createElement(import_react3.FormControl, { isInvalid: Boolean(validation) }, label && /* @__PURE__ */ import_react2.default.createElement(import_react3.FormLabel, { htmlFor: id }, /* @__PURE__ */ import_react2.default.createElement(import_react4.ReactAsset, { ...label.asset })), /* @__PURE__ */ import_react2.default.createElement(
|
|
211
|
+
return file ? /* @__PURE__ */ import_react2.default.createElement(FileInputComponent, { ...props }) : /* @__PURE__ */ import_react2.default.createElement(import_react3.FormControl, { isInvalid: Boolean(validation) }, label && /* @__PURE__ */ import_react2.default.createElement(import_react3.FormLabel, { htmlFor: id }, /* @__PURE__ */ import_react2.default.createElement(import_react4.ReactAsset, { ...label.asset })), /* @__PURE__ */ import_react2.default.createElement(
|
|
165
212
|
import_react3.Input,
|
|
166
213
|
{
|
|
167
214
|
id,
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/index.ts","../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx","../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/hooks.ts","../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/dsl/Input.tsx","../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/transform/index.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./components\";\nexport * from \"./dsl\";\nexport * from \"./transform\";\n","import React from \"react\";\nimport {\n Input,\n FormControl,\n FormLabel,\n FormHelperText,\n FormErrorMessage,\n} from \"@chakra-ui/react\";\nimport { TransformedInput } from \"../types\";\nimport { ReactAsset } from \"@player-ui/react\";\nimport { useInputAssetProps } from \"./hooks\";\n\nexport const InputComponent = (props: TransformedInput) => {\n const { validation, label, id, note, size, maxLength, placeholder } = props;\n const inputProps = useInputAssetProps(props);\n\n return (\n <FormControl isInvalid={Boolean(validation)}>\n {label && (\n <FormLabel htmlFor={id}>\n <ReactAsset {...label.asset} />\n </FormLabel>\n )}\n <Input\n id={id}\n {...inputProps}\n size={size}\n maxLength={maxLength}\n placeholder={placeholder}\n />\n {validation && <FormErrorMessage>{validation.message}</FormErrorMessage>}\n {note && (\n <FormHelperText>\n <ReactAsset {...note.asset} />\n </FormHelperText>\n )}\n </FormControl>\n );\n};\n","import React from \"react\";\nimport type { TransformedInput } from \"../types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype KeyDownHandler = (currentValue: string, props?: TransformedInput) => any;\n\nexport interface InputHookConfig {\n /** Time in ms to wait before formatting the user input for normal keys */\n formatDelay?: number;\n\n /** Symbol to be used for decimal point */\n decimalSymbol?: string;\n\n /** Affix to append to value - does not save to model and is only for display on input */\n prefix?: string;\n\n /** Affix to prepend to value - does not save to model and is only for display on input */\n suffix?: string;\n}\n\n/** Create a valid config mixing in defaults and user overrides */\nexport const getConfig = (\n userConfig: InputHookConfig = {}\n): Required<InputHookConfig> => {\n return {\n decimalSymbol: \".\",\n formatDelay: 200,\n prefix: \"\",\n suffix: \"\",\n ...userConfig,\n };\n};\n\n/**\n * A hook to manage an input html element as an asset.\n * The hook returns an object containing props that are expected to reside on any html input.\n * It will handle formatting, setting values, beaconing, aria-labels, etc.\n *\n * @param props - The output of the input transform\n * @param config - Local config to manage user interaction overrides\n */\nexport const useInputAssetProps = (\n props: TransformedInput,\n config?: InputHookConfig\n) => {\n const [localValue, setLocalValue] = React.useState(props.value ?? \"\");\n const formatTimerRef = React.useRef<NodeJS.Timeout | undefined>(undefined);\n\n const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);\n\n /** Reset and pending format timers */\n function clearPending() {\n if (formatTimerRef.current) {\n clearTimeout(formatTimerRef.current);\n formatTimerRef.current = undefined;\n }\n }\n\n /** Affix handling logic on focus */\n function handleAffixOnFocus(target: HTMLInputElement) {\n let val = target.value;\n\n if (suffix) val = val.substring(0, val.indexOf(suffix));\n\n if (prefix && !val.includes(prefix)) {\n val = `${prefix}${val}`;\n }\n\n return val;\n }\n\n /** Edge cases handling for prefix */\n function handlePrefixEdgeCases(e: React.KeyboardEvent<HTMLInputElement>) {\n const target = e.target as HTMLInputElement;\n const start = target.selectionStart;\n const end = target.selectionEnd;\n const pl = prefix.length;\n const atStart = start === pl;\n const atEnd = end === pl;\n\n if (start && end && start < pl) {\n e.preventDefault();\n target.setSelectionRange(pl, end - start + pl);\n } else if (\n (e.key === \"ArrowLeft\" && atStart) ||\n (e.key === \"Backspace\" && atStart && atEnd) ||\n e.key === \"Home\"\n ) {\n e.preventDefault();\n target.setSelectionRange(prefix.length, prefix.length);\n }\n }\n\n /** Helper to add affixes to value where appropriate */\n function formatValueWithAffix(value: string | undefined) {\n if (!value) return \"\";\n\n return `${prefix}${value}${suffix}`;\n }\n\n /** Value handling logic on key down */\n const onKeyDownHandler: KeyDownHandler = (currentValue: string) => {\n const symbolPosition = currentValue.indexOf(decimalSymbol);\n const newValue = props.format(currentValue) ?? \"\";\n const newSymbolPosition = newValue.indexOf(decimalSymbol);\n\n if (\n (symbolPosition === -1 || symbolPosition === 0) &&\n newSymbolPosition > 0\n ) {\n // formatting added dot, so set cursor before dot\n return {\n newValue: newValue.includes(prefix)\n ? `${newValue}`\n : `${prefix}${newValue}`,\n newCursorPosition: newValue.includes(prefix)\n ? newSymbolPosition\n : newSymbolPosition + prefix.length,\n };\n }\n\n return {\n newValue: newValue.includes(prefix)\n ? `${newValue}`\n : `${prefix}${newValue}`,\n };\n };\n\n /** On blur, commit the value to the model */\n const onBlur: React.FocusEventHandler<HTMLInputElement> = (e) => {\n clearPending();\n\n const formatted =\n (prefix\n ? e.target.value.replace(prefix, \"\")\n : props.format(e.target.value)) ?? \"\";\n\n if (formatted) {\n props.set(formatted);\n setLocalValue(formatValueWithAffix(formatted));\n } else {\n props.set(\"\");\n setLocalValue(\"\");\n }\n };\n\n /** Keep track of any user changes */\n const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {\n setLocalValue(e.target.value);\n };\n\n /** Schedule a format of the current input in the future */\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (e) => {\n clearPending();\n\n if (prefix) handlePrefixEdgeCases(e);\n\n const target = e.target as HTMLInputElement;\n\n formatTimerRef.current = setTimeout(() => {\n const cursorPosition = target.selectionStart;\n const currentValue = target.value;\n\n /** Skip formatting if we're in the middle of the input */\n if (cursorPosition !== currentValue.length) {\n return;\n }\n\n const obj = onKeyDownHandler(currentValue);\n\n setLocalValue(obj.newValue);\n target.selectionStart = obj.newCursorPosition ?? target.selectionStart;\n target.selectionEnd = obj.newCursorPosition ?? target.selectionEnd;\n }, formatDelay);\n };\n\n /** Format value onFocus if affixes exist */\n const onFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {\n const target = e.target as HTMLInputElement;\n const inputEmpty = target.value === \"\";\n\n if ((!inputEmpty && suffix) || (inputEmpty && prefix)) {\n setLocalValue(handleAffixOnFocus(target));\n }\n };\n\n // Update the stored value if data changes\n const propsValue = props.value;\n React.useEffect(() => {\n setLocalValue(formatValueWithAffix(propsValue));\n }, [propsValue]);\n\n /** clear anything pending on unmount of input */\n React.useEffect(() => clearPending, []);\n\n return {\n onBlur,\n onChange,\n onKeyDown,\n onFocus,\n value: localValue,\n };\n};\n","import React from \"react\";\nimport {\n AssetPropsWithChildren,\n Asset,\n createSlot,\n BindingTemplateInstance,\n} from \"@player-tools/dsl\";\nimport { InputAsset } from \"../types\";\nimport { Text } from \"@devtools-ui/text\";\n\nexport const Input = (\n props: Omit<AssetPropsWithChildren<InputAsset>, \"binding\"> & {\n /** The binding */\n binding: BindingTemplateInstance;\n }\n) => {\n const { children, binding, ...rest } = props;\n return (\n <Asset type=\"input\" {...rest}>\n <property name=\"binding\">{binding.toValue()}</property>\n {children}\n </Asset>\n );\n};\n\nInput.Label = createSlot({\n name: \"label\",\n TextComp: Text,\n isArray: false,\n wrapInAsset: true,\n});\n\nInput.Note = createSlot({\n name: \"note\",\n TextComp: Text,\n isArray: false,\n wrapInAsset: true,\n});\n","import type { TransformFunction } from \"@player-ui/player\";\nimport { InputAsset, TransformedInput } from \"../types\";\n\nexport const inputTransform: TransformFunction<InputAsset, TransformedInput> = (\n asset,\n options\n) => {\n return {\n ...asset,\n format(val) {\n if (asset.binding === undefined) {\n return val;\n }\n\n return options.data.format(asset.binding, val);\n },\n set(val) {\n if (asset.binding === undefined) {\n return;\n }\n\n return options.data.model.set([[asset.binding, val]], {\n formatted: true,\n });\n },\n value:\n asset.binding === undefined\n ? \"\"\n : options.data.model.get(asset.binding, {\n includeInvalid: true,\n formatted: true,\n }),\n validation:\n asset.binding === undefined\n ? undefined\n : options.validation?.get(asset.binding, { track: true }),\n dataType:\n asset.binding === undefined\n ? undefined\n : options.validation?.type(asset.binding),\n };\n};\n"],"mappings":"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","names":["Input","import_react","React","React","import_react","Input","React"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/index.ts","../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx","../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/hooks/index.ts","../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/dsl/Input.tsx","../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/transform/index.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./components\";\nexport * from \"./dsl\";\nexport * from \"./transform\";\n","import React, { useState, useRef } from \"react\";\nimport {\n Input,\n Button,\n FormControl,\n FormLabel,\n FormHelperText,\n FormErrorMessage,\n} from \"@chakra-ui/react\";\nimport { TransformedInput } from \"../types\";\nimport { ReactAsset } from \"@player-ui/react\";\nimport { useInputAssetProps, useFileInputAssetProps } from \"../hooks\";\n\nconst FileInputComponent = (props: TransformedInput) => {\n const hiddenFileInput: React.Ref<any> = useRef(null);\n\n const [fileName, setFileName] = useState(\"\");\n\n const handleClick = () => {\n hiddenFileInput.current?.click();\n };\n\n const handleFile = (fileName: string) => {\n setFileName(fileName);\n };\n\n const { id, label } = props;\n\n const inputProps = useFileInputAssetProps({ ...props, handleFile });\n\n return (\n <FormControl>\n <Button className=\"button-file\" onClick={handleClick}>\n <FormLabel style={{ margin: 0 }}>\n {label ? <ReactAsset {...label.asset} /> : <>Select Content</>}\n </FormLabel>\n </Button>\n <Input\n id={id}\n name={id}\n {...inputProps}\n style={{ display: \"none\" }}\n ref={hiddenFileInput}\n />\n {fileName ? <p>Uploaded file: {fileName}</p> : null}\n </FormControl>\n );\n};\n\nexport const InputComponent = (props: TransformedInput) => {\n const { validation, label, id, note, size, maxLength, placeholder, file } =\n props;\n\n const inputProps = useInputAssetProps(props);\n\n return file ? (\n <FileInputComponent {...props} />\n ) : (\n <FormControl isInvalid={Boolean(validation)}>\n {label && (\n <FormLabel htmlFor={id}>\n <ReactAsset {...label.asset} />\n </FormLabel>\n )}\n <Input\n id={id}\n {...inputProps}\n size={size}\n maxLength={maxLength}\n placeholder={placeholder}\n />\n {validation && <FormErrorMessage>{validation.message}</FormErrorMessage>}\n {note && (\n <FormHelperText>\n <ReactAsset {...note.asset} />\n </FormHelperText>\n )}\n </FormControl>\n );\n};\n","import React, { useState, useEffect, useRef } from \"react\";\nimport type { TransformedInput } from \"../types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype KeyDownHandler = (currentValue: string, props?: TransformedInput) => any;\n\nexport interface InputHookConfig {\n /** Time in ms to wait before formatting the user input for normal keys */\n formatDelay?: number;\n\n /** Symbol to be used for decimal point */\n decimalSymbol?: string;\n\n /** Affix to append to value - does not save to model and is only for display on input */\n prefix?: string;\n\n /** Affix to prepend to value - does not save to model and is only for display on input */\n suffix?: string;\n}\n\n/** Create a valid config mixing in defaults and user overrides */\nexport const getConfig = (\n userConfig: InputHookConfig = {}\n): Required<InputHookConfig> => {\n return {\n decimalSymbol: \".\",\n formatDelay: 200,\n prefix: \"\",\n suffix: \"\",\n ...userConfig,\n };\n};\n\n/**\n * A hook to manage an input html element as an asset.\n * The hook returns an object containing props that are expected to reside on any html input.\n * It will handle formatting, setting values, beaconing, aria-labels, etc.\n *\n * @param props - The output of the input transform\n * @param config - Local config to manage user interaction overrides\n */\nexport const useInputAssetProps = (\n props: TransformedInput,\n config?: InputHookConfig\n) => {\n const [localValue, setLocalValue] = useState(props.value ?? \"\");\n const formatTimerRef = useRef<NodeJS.Timeout | undefined>(undefined);\n\n const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);\n\n /** Reset and pending format timers */\n function clearPending() {\n if (formatTimerRef.current) {\n clearTimeout(formatTimerRef.current);\n formatTimerRef.current = undefined;\n }\n }\n\n /** Affix handling logic on focus */\n function handleAffixOnFocus(target: HTMLInputElement) {\n let val = target.value;\n\n if (suffix) val = val.substring(0, val.indexOf(suffix));\n\n if (prefix && !val.includes(prefix)) {\n val = `${prefix}${val}`;\n }\n\n return val;\n }\n\n /** Edge cases handling for prefix */\n function handlePrefixEdgeCases(e: React.KeyboardEvent<HTMLInputElement>) {\n const target = e.target as HTMLInputElement;\n const start = target.selectionStart;\n const end = target.selectionEnd;\n const pl = prefix.length;\n const atStart = start === pl;\n const atEnd = end === pl;\n\n if (start && end && start < pl) {\n e.preventDefault();\n target.setSelectionRange(pl, end - start + pl);\n } else if (\n (e.key === \"ArrowLeft\" && atStart) ||\n (e.key === \"Backspace\" && atStart && atEnd) ||\n e.key === \"Home\"\n ) {\n e.preventDefault();\n target.setSelectionRange(prefix.length, prefix.length);\n }\n }\n\n /** Helper to add affixes to value where appropriate */\n function formatValueWithAffix(value: string | undefined) {\n if (!value) return \"\";\n\n return `${prefix}${value}${suffix}`;\n }\n\n /** Value handling logic on key down */\n const onKeyDownHandler: KeyDownHandler = (currentValue: string) => {\n const symbolPosition = currentValue.indexOf(decimalSymbol);\n const newValue = props.format(currentValue) ?? \"\";\n const newSymbolPosition = newValue.indexOf(decimalSymbol);\n\n if (\n (symbolPosition === -1 || symbolPosition === 0) &&\n newSymbolPosition > 0\n ) {\n // formatting added dot, so set cursor before dot\n return {\n newValue: newValue.includes(prefix)\n ? `${newValue}`\n : `${prefix}${newValue}`,\n newCursorPosition: newValue.includes(prefix)\n ? newSymbolPosition\n : newSymbolPosition + prefix.length,\n };\n }\n\n return {\n newValue: newValue.includes(prefix)\n ? `${newValue}`\n : `${prefix}${newValue}`,\n };\n };\n\n /** On blur, commit the value to the model */\n const onBlur: React.FocusEventHandler<HTMLInputElement> = (e) => {\n clearPending();\n\n const formatted =\n (prefix\n ? e.target.value.replace(prefix, \"\")\n : props.format(e.target.value)) ?? \"\";\n\n if (formatted) {\n props.set(formatted);\n setLocalValue(formatValueWithAffix(formatted));\n } else {\n props.set(\"\");\n setLocalValue(\"\");\n }\n };\n\n /** Keep track of any user changes */\n const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {\n setLocalValue(e.target.value);\n };\n\n /** Schedule a format of the current input in the future */\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (e) => {\n clearPending();\n\n if (prefix) handlePrefixEdgeCases(e);\n\n const target = e.target as HTMLInputElement;\n\n formatTimerRef.current = setTimeout(() => {\n const cursorPosition = target.selectionStart;\n const currentValue = target.value;\n\n /** Skip formatting if we're in the middle of the input */\n if (cursorPosition !== currentValue.length) {\n return;\n }\n\n const obj = onKeyDownHandler(currentValue);\n\n setLocalValue(obj.newValue);\n target.selectionStart = obj.newCursorPosition ?? target.selectionStart;\n target.selectionEnd = obj.newCursorPosition ?? target.selectionEnd;\n }, formatDelay);\n };\n\n /** Format value onFocus if affixes exist */\n const onFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {\n const target = e.target as HTMLInputElement;\n const inputEmpty = target.value === \"\";\n\n if ((!inputEmpty && suffix) || (inputEmpty && prefix)) {\n setLocalValue(handleAffixOnFocus(target));\n }\n };\n\n // Update the stored value if data changes\n const propsValue = props.value;\n useEffect(() => {\n setLocalValue(formatValueWithAffix(propsValue));\n }, [propsValue]);\n\n /** clear anything pending on unmount of input */\n useEffect(() => clearPending, []);\n\n return {\n onBlur,\n onChange,\n onKeyDown,\n onFocus,\n value: localValue,\n };\n};\n\n/** Props for file type Input */\nexport const useFileInputAssetProps = (props: TransformedInput) => {\n const { accept } = props;\n\n const acceptedExtensions = accept\n ? accept.concat(\".json\").join(\", \")\n : \".json\";\n\n /** Parses file content for upload into a string if file type Input */\n const onFileUpload: React.ChangeEventHandler = (e): void => {\n const fileList = (<HTMLInputElement>e.target).files;\n const file = fileList ? fileList[0] : \"\";\n const reader = new FileReader();\n\n reader.addEventListener(\n \"load\",\n () => {\n // this will set the file contents in the data model\n props.set(reader.result as string);\n },\n false\n );\n\n if (file) {\n reader.readAsText(file);\n props.handleFile && props.handleFile(file.name);\n }\n };\n\n return {\n type: \"file\",\n onChange: onFileUpload,\n accept: acceptedExtensions,\n };\n};\n","import React from \"react\";\nimport {\n AssetPropsWithChildren,\n Asset,\n createSlot,\n BindingTemplateInstance,\n} from \"@player-tools/dsl\";\nimport { InputAsset } from \"../types\";\nimport { Text } from \"@devtools-ui/text\";\n\nexport const Input = (\n props: Omit<AssetPropsWithChildren<InputAsset>, \"binding\"> & {\n /** The binding */\n binding: BindingTemplateInstance;\n }\n) => {\n const { children, binding, ...rest } = props;\n return (\n <Asset type=\"input\" {...rest}>\n <property name=\"binding\">{binding.toValue()}</property>\n {children}\n </Asset>\n );\n};\n\nInput.Label = createSlot({\n name: \"label\",\n TextComp: Text,\n isArray: false,\n wrapInAsset: true,\n});\n\nInput.Note = createSlot({\n name: \"note\",\n TextComp: Text,\n isArray: false,\n wrapInAsset: true,\n});\n","import type { TransformFunction } from \"@player-ui/player\";\nimport { InputAsset, TransformedInput } from \"../types\";\n\nexport const inputTransform: TransformFunction<InputAsset, TransformedInput> = (\n asset,\n options\n) => {\n return {\n ...asset,\n format(val) {\n if (asset.binding === undefined) {\n return val;\n }\n\n return options.data.format(asset.binding, val);\n },\n set(val) {\n if (asset.binding === undefined) {\n return;\n }\n\n return options.data.model.set([[asset.binding, val]], {\n formatted: true,\n });\n },\n value:\n asset.binding === undefined\n ? \"\"\n : options.data.model.get(asset.binding, {\n includeInvalid: true,\n formatted: true,\n }),\n validation:\n asset.binding === undefined\n ? undefined\n : options.validation?.get(asset.binding, { track: true }),\n dataType:\n asset.binding === undefined\n ? undefined\n : options.validation?.type(asset.binding),\n };\n};\n"],"mappings":"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","names":["Input","import_react","fileName","React","import_react","Input","React"]}
|
package/dist/index.legacy-esm.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
2
|
-
import React2 from "react";
|
|
2
|
+
import React2, { useState as useState2, useRef as useRef2 } from "react";
|
|
3
3
|
import {
|
|
4
4
|
Input,
|
|
5
|
+
Button,
|
|
5
6
|
FormControl,
|
|
6
7
|
FormLabel,
|
|
7
8
|
FormHelperText,
|
|
@@ -9,8 +10,8 @@ import {
|
|
|
9
10
|
} from "@chakra-ui/react";
|
|
10
11
|
import { ReactAsset } from "@player-ui/react";
|
|
11
12
|
|
|
12
|
-
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/
|
|
13
|
-
import
|
|
13
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/hooks/index.ts
|
|
14
|
+
import { useState, useEffect, useRef } from "react";
|
|
14
15
|
var getConfig = (userConfig = {}) => {
|
|
15
16
|
return {
|
|
16
17
|
decimalSymbol: ".",
|
|
@@ -21,8 +22,8 @@ var getConfig = (userConfig = {}) => {
|
|
|
21
22
|
};
|
|
22
23
|
};
|
|
23
24
|
var useInputAssetProps = (props, config) => {
|
|
24
|
-
const [localValue, setLocalValue] =
|
|
25
|
-
const formatTimerRef =
|
|
25
|
+
const [localValue, setLocalValue] = useState(props.value ?? "");
|
|
26
|
+
const formatTimerRef = useRef(void 0);
|
|
26
27
|
const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);
|
|
27
28
|
function clearPending() {
|
|
28
29
|
if (formatTimerRef.current) {
|
|
@@ -112,10 +113,10 @@ var useInputAssetProps = (props, config) => {
|
|
|
112
113
|
}
|
|
113
114
|
};
|
|
114
115
|
const propsValue = props.value;
|
|
115
|
-
|
|
116
|
+
useEffect(() => {
|
|
116
117
|
setLocalValue(formatValueWithAffix(propsValue));
|
|
117
118
|
}, [propsValue]);
|
|
118
|
-
|
|
119
|
+
useEffect(() => clearPending, []);
|
|
119
120
|
return {
|
|
120
121
|
onBlur,
|
|
121
122
|
onChange,
|
|
@@ -124,12 +125,59 @@ var useInputAssetProps = (props, config) => {
|
|
|
124
125
|
value: localValue
|
|
125
126
|
};
|
|
126
127
|
};
|
|
128
|
+
var useFileInputAssetProps = (props) => {
|
|
129
|
+
const { accept } = props;
|
|
130
|
+
const acceptedExtensions = accept ? accept.concat(".json").join(", ") : ".json";
|
|
131
|
+
const onFileUpload = (e) => {
|
|
132
|
+
const fileList = e.target.files;
|
|
133
|
+
const file = fileList ? fileList[0] : "";
|
|
134
|
+
const reader = new FileReader();
|
|
135
|
+
reader.addEventListener(
|
|
136
|
+
"load",
|
|
137
|
+
() => {
|
|
138
|
+
props.set(reader.result);
|
|
139
|
+
},
|
|
140
|
+
false
|
|
141
|
+
);
|
|
142
|
+
if (file) {
|
|
143
|
+
reader.readAsText(file);
|
|
144
|
+
props.handleFile && props.handleFile(file.name);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
return {
|
|
148
|
+
type: "file",
|
|
149
|
+
onChange: onFileUpload,
|
|
150
|
+
accept: acceptedExtensions
|
|
151
|
+
};
|
|
152
|
+
};
|
|
127
153
|
|
|
128
154
|
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
155
|
+
var FileInputComponent = (props) => {
|
|
156
|
+
const hiddenFileInput = useRef2(null);
|
|
157
|
+
const [fileName, setFileName] = useState2("");
|
|
158
|
+
const handleClick = () => {
|
|
159
|
+
hiddenFileInput.current?.click();
|
|
160
|
+
};
|
|
161
|
+
const handleFile = (fileName2) => {
|
|
162
|
+
setFileName(fileName2);
|
|
163
|
+
};
|
|
164
|
+
const { id, label } = props;
|
|
165
|
+
const inputProps = useFileInputAssetProps({ ...props, handleFile });
|
|
166
|
+
return /* @__PURE__ */ React2.createElement(FormControl, null, /* @__PURE__ */ React2.createElement(Button, { className: "button-file", onClick: handleClick }, /* @__PURE__ */ React2.createElement(FormLabel, { style: { margin: 0 } }, label ? /* @__PURE__ */ React2.createElement(ReactAsset, { ...label.asset }) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, "Select Content"))), /* @__PURE__ */ React2.createElement(
|
|
167
|
+
Input,
|
|
168
|
+
{
|
|
169
|
+
id,
|
|
170
|
+
name: id,
|
|
171
|
+
...inputProps,
|
|
172
|
+
style: { display: "none" },
|
|
173
|
+
ref: hiddenFileInput
|
|
174
|
+
}
|
|
175
|
+
), fileName ? /* @__PURE__ */ React2.createElement("p", null, "Uploaded file: ", fileName) : null);
|
|
176
|
+
};
|
|
129
177
|
var InputComponent = (props) => {
|
|
130
|
-
const { validation, label, id, note, size, maxLength, placeholder } = props;
|
|
178
|
+
const { validation, label, id, note, size, maxLength, placeholder, file } = props;
|
|
131
179
|
const inputProps = useInputAssetProps(props);
|
|
132
|
-
return /* @__PURE__ */ React2.createElement(FormControl, { isInvalid: Boolean(validation) }, label && /* @__PURE__ */ React2.createElement(FormLabel, { htmlFor: id }, /* @__PURE__ */ React2.createElement(ReactAsset, { ...label.asset })), /* @__PURE__ */ React2.createElement(
|
|
180
|
+
return file ? /* @__PURE__ */ React2.createElement(FileInputComponent, { ...props }) : /* @__PURE__ */ React2.createElement(FormControl, { isInvalid: Boolean(validation) }, label && /* @__PURE__ */ React2.createElement(FormLabel, { htmlFor: id }, /* @__PURE__ */ React2.createElement(ReactAsset, { ...label.asset })), /* @__PURE__ */ React2.createElement(
|
|
133
181
|
Input,
|
|
134
182
|
{
|
|
135
183
|
id,
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
2
|
-
import React2 from "react";
|
|
2
|
+
import React2, { useState as useState2, useRef as useRef2 } from "react";
|
|
3
3
|
import {
|
|
4
4
|
Input,
|
|
5
|
+
Button,
|
|
5
6
|
FormControl,
|
|
6
7
|
FormLabel,
|
|
7
8
|
FormHelperText,
|
|
@@ -9,8 +10,8 @@ import {
|
|
|
9
10
|
} from "@chakra-ui/react";
|
|
10
11
|
import { ReactAsset } from "@player-ui/react";
|
|
11
12
|
|
|
12
|
-
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/
|
|
13
|
-
import
|
|
13
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/hooks/index.ts
|
|
14
|
+
import { useState, useEffect, useRef } from "react";
|
|
14
15
|
var getConfig = (userConfig = {}) => {
|
|
15
16
|
return {
|
|
16
17
|
decimalSymbol: ".",
|
|
@@ -21,8 +22,8 @@ var getConfig = (userConfig = {}) => {
|
|
|
21
22
|
};
|
|
22
23
|
};
|
|
23
24
|
var useInputAssetProps = (props, config) => {
|
|
24
|
-
const [localValue, setLocalValue] =
|
|
25
|
-
const formatTimerRef =
|
|
25
|
+
const [localValue, setLocalValue] = useState(props.value ?? "");
|
|
26
|
+
const formatTimerRef = useRef(void 0);
|
|
26
27
|
const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);
|
|
27
28
|
function clearPending() {
|
|
28
29
|
if (formatTimerRef.current) {
|
|
@@ -112,10 +113,10 @@ var useInputAssetProps = (props, config) => {
|
|
|
112
113
|
}
|
|
113
114
|
};
|
|
114
115
|
const propsValue = props.value;
|
|
115
|
-
|
|
116
|
+
useEffect(() => {
|
|
116
117
|
setLocalValue(formatValueWithAffix(propsValue));
|
|
117
118
|
}, [propsValue]);
|
|
118
|
-
|
|
119
|
+
useEffect(() => clearPending, []);
|
|
119
120
|
return {
|
|
120
121
|
onBlur,
|
|
121
122
|
onChange,
|
|
@@ -124,12 +125,59 @@ var useInputAssetProps = (props, config) => {
|
|
|
124
125
|
value: localValue
|
|
125
126
|
};
|
|
126
127
|
};
|
|
128
|
+
var useFileInputAssetProps = (props) => {
|
|
129
|
+
const { accept } = props;
|
|
130
|
+
const acceptedExtensions = accept ? accept.concat(".json").join(", ") : ".json";
|
|
131
|
+
const onFileUpload = (e) => {
|
|
132
|
+
const fileList = e.target.files;
|
|
133
|
+
const file = fileList ? fileList[0] : "";
|
|
134
|
+
const reader = new FileReader();
|
|
135
|
+
reader.addEventListener(
|
|
136
|
+
"load",
|
|
137
|
+
() => {
|
|
138
|
+
props.set(reader.result);
|
|
139
|
+
},
|
|
140
|
+
false
|
|
141
|
+
);
|
|
142
|
+
if (file) {
|
|
143
|
+
reader.readAsText(file);
|
|
144
|
+
props.handleFile && props.handleFile(file.name);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
return {
|
|
148
|
+
type: "file",
|
|
149
|
+
onChange: onFileUpload,
|
|
150
|
+
accept: acceptedExtensions
|
|
151
|
+
};
|
|
152
|
+
};
|
|
127
153
|
|
|
128
154
|
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
155
|
+
var FileInputComponent = (props) => {
|
|
156
|
+
const hiddenFileInput = useRef2(null);
|
|
157
|
+
const [fileName, setFileName] = useState2("");
|
|
158
|
+
const handleClick = () => {
|
|
159
|
+
hiddenFileInput.current?.click();
|
|
160
|
+
};
|
|
161
|
+
const handleFile = (fileName2) => {
|
|
162
|
+
setFileName(fileName2);
|
|
163
|
+
};
|
|
164
|
+
const { id, label } = props;
|
|
165
|
+
const inputProps = useFileInputAssetProps({ ...props, handleFile });
|
|
166
|
+
return /* @__PURE__ */ React2.createElement(FormControl, null, /* @__PURE__ */ React2.createElement(Button, { className: "button-file", onClick: handleClick }, /* @__PURE__ */ React2.createElement(FormLabel, { style: { margin: 0 } }, label ? /* @__PURE__ */ React2.createElement(ReactAsset, { ...label.asset }) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, "Select Content"))), /* @__PURE__ */ React2.createElement(
|
|
167
|
+
Input,
|
|
168
|
+
{
|
|
169
|
+
id,
|
|
170
|
+
name: id,
|
|
171
|
+
...inputProps,
|
|
172
|
+
style: { display: "none" },
|
|
173
|
+
ref: hiddenFileInput
|
|
174
|
+
}
|
|
175
|
+
), fileName ? /* @__PURE__ */ React2.createElement("p", null, "Uploaded file: ", fileName) : null);
|
|
176
|
+
};
|
|
129
177
|
var InputComponent = (props) => {
|
|
130
|
-
const { validation, label, id, note, size, maxLength, placeholder } = props;
|
|
178
|
+
const { validation, label, id, note, size, maxLength, placeholder, file } = props;
|
|
131
179
|
const inputProps = useInputAssetProps(props);
|
|
132
|
-
return /* @__PURE__ */ React2.createElement(FormControl, { isInvalid: Boolean(validation) }, label && /* @__PURE__ */ React2.createElement(FormLabel, { htmlFor: id }, /* @__PURE__ */ React2.createElement(ReactAsset, { ...label.asset })), /* @__PURE__ */ React2.createElement(
|
|
180
|
+
return file ? /* @__PURE__ */ React2.createElement(FileInputComponent, { ...props }) : /* @__PURE__ */ React2.createElement(FormControl, { isInvalid: Boolean(validation) }, label && /* @__PURE__ */ React2.createElement(FormLabel, { htmlFor: id }, /* @__PURE__ */ React2.createElement(ReactAsset, { ...label.asset })), /* @__PURE__ */ React2.createElement(
|
|
133
181
|
Input,
|
|
134
182
|
{
|
|
135
183
|
id,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx","../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/hooks.ts","../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/dsl/Input.tsx","../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/transform/index.ts"],"sourcesContent":["import React from \"react\";\nimport {\n Input,\n FormControl,\n FormLabel,\n FormHelperText,\n FormErrorMessage,\n} from \"@chakra-ui/react\";\nimport { TransformedInput } from \"../types\";\nimport { ReactAsset } from \"@player-ui/react\";\nimport { useInputAssetProps } from \"./hooks\";\n\nexport const InputComponent = (props: TransformedInput) => {\n const { validation, label, id, note, size, maxLength, placeholder } = props;\n const inputProps = useInputAssetProps(props);\n\n return (\n <FormControl isInvalid={Boolean(validation)}>\n {label && (\n <FormLabel htmlFor={id}>\n <ReactAsset {...label.asset} />\n </FormLabel>\n )}\n <Input\n id={id}\n {...inputProps}\n size={size}\n maxLength={maxLength}\n placeholder={placeholder}\n />\n {validation && <FormErrorMessage>{validation.message}</FormErrorMessage>}\n {note && (\n <FormHelperText>\n <ReactAsset {...note.asset} />\n </FormHelperText>\n )}\n </FormControl>\n );\n};\n","import React from \"react\";\nimport type { TransformedInput } from \"../types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype KeyDownHandler = (currentValue: string, props?: TransformedInput) => any;\n\nexport interface InputHookConfig {\n /** Time in ms to wait before formatting the user input for normal keys */\n formatDelay?: number;\n\n /** Symbol to be used for decimal point */\n decimalSymbol?: string;\n\n /** Affix to append to value - does not save to model and is only for display on input */\n prefix?: string;\n\n /** Affix to prepend to value - does not save to model and is only for display on input */\n suffix?: string;\n}\n\n/** Create a valid config mixing in defaults and user overrides */\nexport const getConfig = (\n userConfig: InputHookConfig = {}\n): Required<InputHookConfig> => {\n return {\n decimalSymbol: \".\",\n formatDelay: 200,\n prefix: \"\",\n suffix: \"\",\n ...userConfig,\n };\n};\n\n/**\n * A hook to manage an input html element as an asset.\n * The hook returns an object containing props that are expected to reside on any html input.\n * It will handle formatting, setting values, beaconing, aria-labels, etc.\n *\n * @param props - The output of the input transform\n * @param config - Local config to manage user interaction overrides\n */\nexport const useInputAssetProps = (\n props: TransformedInput,\n config?: InputHookConfig\n) => {\n const [localValue, setLocalValue] = React.useState(props.value ?? \"\");\n const formatTimerRef = React.useRef<NodeJS.Timeout | undefined>(undefined);\n\n const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);\n\n /** Reset and pending format timers */\n function clearPending() {\n if (formatTimerRef.current) {\n clearTimeout(formatTimerRef.current);\n formatTimerRef.current = undefined;\n }\n }\n\n /** Affix handling logic on focus */\n function handleAffixOnFocus(target: HTMLInputElement) {\n let val = target.value;\n\n if (suffix) val = val.substring(0, val.indexOf(suffix));\n\n if (prefix && !val.includes(prefix)) {\n val = `${prefix}${val}`;\n }\n\n return val;\n }\n\n /** Edge cases handling for prefix */\n function handlePrefixEdgeCases(e: React.KeyboardEvent<HTMLInputElement>) {\n const target = e.target as HTMLInputElement;\n const start = target.selectionStart;\n const end = target.selectionEnd;\n const pl = prefix.length;\n const atStart = start === pl;\n const atEnd = end === pl;\n\n if (start && end && start < pl) {\n e.preventDefault();\n target.setSelectionRange(pl, end - start + pl);\n } else if (\n (e.key === \"ArrowLeft\" && atStart) ||\n (e.key === \"Backspace\" && atStart && atEnd) ||\n e.key === \"Home\"\n ) {\n e.preventDefault();\n target.setSelectionRange(prefix.length, prefix.length);\n }\n }\n\n /** Helper to add affixes to value where appropriate */\n function formatValueWithAffix(value: string | undefined) {\n if (!value) return \"\";\n\n return `${prefix}${value}${suffix}`;\n }\n\n /** Value handling logic on key down */\n const onKeyDownHandler: KeyDownHandler = (currentValue: string) => {\n const symbolPosition = currentValue.indexOf(decimalSymbol);\n const newValue = props.format(currentValue) ?? \"\";\n const newSymbolPosition = newValue.indexOf(decimalSymbol);\n\n if (\n (symbolPosition === -1 || symbolPosition === 0) &&\n newSymbolPosition > 0\n ) {\n // formatting added dot, so set cursor before dot\n return {\n newValue: newValue.includes(prefix)\n ? `${newValue}`\n : `${prefix}${newValue}`,\n newCursorPosition: newValue.includes(prefix)\n ? newSymbolPosition\n : newSymbolPosition + prefix.length,\n };\n }\n\n return {\n newValue: newValue.includes(prefix)\n ? `${newValue}`\n : `${prefix}${newValue}`,\n };\n };\n\n /** On blur, commit the value to the model */\n const onBlur: React.FocusEventHandler<HTMLInputElement> = (e) => {\n clearPending();\n\n const formatted =\n (prefix\n ? e.target.value.replace(prefix, \"\")\n : props.format(e.target.value)) ?? \"\";\n\n if (formatted) {\n props.set(formatted);\n setLocalValue(formatValueWithAffix(formatted));\n } else {\n props.set(\"\");\n setLocalValue(\"\");\n }\n };\n\n /** Keep track of any user changes */\n const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {\n setLocalValue(e.target.value);\n };\n\n /** Schedule a format of the current input in the future */\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (e) => {\n clearPending();\n\n if (prefix) handlePrefixEdgeCases(e);\n\n const target = e.target as HTMLInputElement;\n\n formatTimerRef.current = setTimeout(() => {\n const cursorPosition = target.selectionStart;\n const currentValue = target.value;\n\n /** Skip formatting if we're in the middle of the input */\n if (cursorPosition !== currentValue.length) {\n return;\n }\n\n const obj = onKeyDownHandler(currentValue);\n\n setLocalValue(obj.newValue);\n target.selectionStart = obj.newCursorPosition ?? target.selectionStart;\n target.selectionEnd = obj.newCursorPosition ?? target.selectionEnd;\n }, formatDelay);\n };\n\n /** Format value onFocus if affixes exist */\n const onFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {\n const target = e.target as HTMLInputElement;\n const inputEmpty = target.value === \"\";\n\n if ((!inputEmpty && suffix) || (inputEmpty && prefix)) {\n setLocalValue(handleAffixOnFocus(target));\n }\n };\n\n // Update the stored value if data changes\n const propsValue = props.value;\n React.useEffect(() => {\n setLocalValue(formatValueWithAffix(propsValue));\n }, [propsValue]);\n\n /** clear anything pending on unmount of input */\n React.useEffect(() => clearPending, []);\n\n return {\n onBlur,\n onChange,\n onKeyDown,\n onFocus,\n value: localValue,\n };\n};\n","import React from \"react\";\nimport {\n AssetPropsWithChildren,\n Asset,\n createSlot,\n BindingTemplateInstance,\n} from \"@player-tools/dsl\";\nimport { InputAsset } from \"../types\";\nimport { Text } from \"@devtools-ui/text\";\n\nexport const Input = (\n props: Omit<AssetPropsWithChildren<InputAsset>, \"binding\"> & {\n /** The binding */\n binding: BindingTemplateInstance;\n }\n) => {\n const { children, binding, ...rest } = props;\n return (\n <Asset type=\"input\" {...rest}>\n <property name=\"binding\">{binding.toValue()}</property>\n {children}\n </Asset>\n );\n};\n\nInput.Label = createSlot({\n name: \"label\",\n TextComp: Text,\n isArray: false,\n wrapInAsset: true,\n});\n\nInput.Note = createSlot({\n name: \"note\",\n TextComp: Text,\n isArray: false,\n wrapInAsset: true,\n});\n","import type { TransformFunction } from \"@player-ui/player\";\nimport { InputAsset, TransformedInput } from \"../types\";\n\nexport const inputTransform: TransformFunction<InputAsset, TransformedInput> = (\n asset,\n options\n) => {\n return {\n ...asset,\n format(val) {\n if (asset.binding === undefined) {\n return val;\n }\n\n return options.data.format(asset.binding, val);\n },\n set(val) {\n if (asset.binding === undefined) {\n return;\n }\n\n return options.data.model.set([[asset.binding, val]], {\n formatted: true,\n });\n },\n value:\n asset.binding === undefined\n ? \"\"\n : options.data.model.get(asset.binding, {\n includeInvalid: true,\n formatted: true,\n }),\n validation:\n asset.binding === undefined\n ? undefined\n : options.validation?.get(asset.binding, { track: true }),\n dataType:\n asset.binding === undefined\n ? undefined\n : options.validation?.type(asset.binding),\n };\n};\n"],"mappings":"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","names":["React","React","React","Input"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx","../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/hooks/index.ts","../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/dsl/Input.tsx","../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/transform/index.ts"],"sourcesContent":["import React, { useState, useRef } from \"react\";\nimport {\n Input,\n Button,\n FormControl,\n FormLabel,\n FormHelperText,\n FormErrorMessage,\n} from \"@chakra-ui/react\";\nimport { TransformedInput } from \"../types\";\nimport { ReactAsset } from \"@player-ui/react\";\nimport { useInputAssetProps, useFileInputAssetProps } from \"../hooks\";\n\nconst FileInputComponent = (props: TransformedInput) => {\n const hiddenFileInput: React.Ref<any> = useRef(null);\n\n const [fileName, setFileName] = useState(\"\");\n\n const handleClick = () => {\n hiddenFileInput.current?.click();\n };\n\n const handleFile = (fileName: string) => {\n setFileName(fileName);\n };\n\n const { id, label } = props;\n\n const inputProps = useFileInputAssetProps({ ...props, handleFile });\n\n return (\n <FormControl>\n <Button className=\"button-file\" onClick={handleClick}>\n <FormLabel style={{ margin: 0 }}>\n {label ? <ReactAsset {...label.asset} /> : <>Select Content</>}\n </FormLabel>\n </Button>\n <Input\n id={id}\n name={id}\n {...inputProps}\n style={{ display: \"none\" }}\n ref={hiddenFileInput}\n />\n {fileName ? <p>Uploaded file: {fileName}</p> : null}\n </FormControl>\n );\n};\n\nexport const InputComponent = (props: TransformedInput) => {\n const { validation, label, id, note, size, maxLength, placeholder, file } =\n props;\n\n const inputProps = useInputAssetProps(props);\n\n return file ? (\n <FileInputComponent {...props} />\n ) : (\n <FormControl isInvalid={Boolean(validation)}>\n {label && (\n <FormLabel htmlFor={id}>\n <ReactAsset {...label.asset} />\n </FormLabel>\n )}\n <Input\n id={id}\n {...inputProps}\n size={size}\n maxLength={maxLength}\n placeholder={placeholder}\n />\n {validation && <FormErrorMessage>{validation.message}</FormErrorMessage>}\n {note && (\n <FormHelperText>\n <ReactAsset {...note.asset} />\n </FormHelperText>\n )}\n </FormControl>\n );\n};\n","import React, { useState, useEffect, useRef } from \"react\";\nimport type { TransformedInput } from \"../types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype KeyDownHandler = (currentValue: string, props?: TransformedInput) => any;\n\nexport interface InputHookConfig {\n /** Time in ms to wait before formatting the user input for normal keys */\n formatDelay?: number;\n\n /** Symbol to be used for decimal point */\n decimalSymbol?: string;\n\n /** Affix to append to value - does not save to model and is only for display on input */\n prefix?: string;\n\n /** Affix to prepend to value - does not save to model and is only for display on input */\n suffix?: string;\n}\n\n/** Create a valid config mixing in defaults and user overrides */\nexport const getConfig = (\n userConfig: InputHookConfig = {}\n): Required<InputHookConfig> => {\n return {\n decimalSymbol: \".\",\n formatDelay: 200,\n prefix: \"\",\n suffix: \"\",\n ...userConfig,\n };\n};\n\n/**\n * A hook to manage an input html element as an asset.\n * The hook returns an object containing props that are expected to reside on any html input.\n * It will handle formatting, setting values, beaconing, aria-labels, etc.\n *\n * @param props - The output of the input transform\n * @param config - Local config to manage user interaction overrides\n */\nexport const useInputAssetProps = (\n props: TransformedInput,\n config?: InputHookConfig\n) => {\n const [localValue, setLocalValue] = useState(props.value ?? \"\");\n const formatTimerRef = useRef<NodeJS.Timeout | undefined>(undefined);\n\n const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);\n\n /** Reset and pending format timers */\n function clearPending() {\n if (formatTimerRef.current) {\n clearTimeout(formatTimerRef.current);\n formatTimerRef.current = undefined;\n }\n }\n\n /** Affix handling logic on focus */\n function handleAffixOnFocus(target: HTMLInputElement) {\n let val = target.value;\n\n if (suffix) val = val.substring(0, val.indexOf(suffix));\n\n if (prefix && !val.includes(prefix)) {\n val = `${prefix}${val}`;\n }\n\n return val;\n }\n\n /** Edge cases handling for prefix */\n function handlePrefixEdgeCases(e: React.KeyboardEvent<HTMLInputElement>) {\n const target = e.target as HTMLInputElement;\n const start = target.selectionStart;\n const end = target.selectionEnd;\n const pl = prefix.length;\n const atStart = start === pl;\n const atEnd = end === pl;\n\n if (start && end && start < pl) {\n e.preventDefault();\n target.setSelectionRange(pl, end - start + pl);\n } else if (\n (e.key === \"ArrowLeft\" && atStart) ||\n (e.key === \"Backspace\" && atStart && atEnd) ||\n e.key === \"Home\"\n ) {\n e.preventDefault();\n target.setSelectionRange(prefix.length, prefix.length);\n }\n }\n\n /** Helper to add affixes to value where appropriate */\n function formatValueWithAffix(value: string | undefined) {\n if (!value) return \"\";\n\n return `${prefix}${value}${suffix}`;\n }\n\n /** Value handling logic on key down */\n const onKeyDownHandler: KeyDownHandler = (currentValue: string) => {\n const symbolPosition = currentValue.indexOf(decimalSymbol);\n const newValue = props.format(currentValue) ?? \"\";\n const newSymbolPosition = newValue.indexOf(decimalSymbol);\n\n if (\n (symbolPosition === -1 || symbolPosition === 0) &&\n newSymbolPosition > 0\n ) {\n // formatting added dot, so set cursor before dot\n return {\n newValue: newValue.includes(prefix)\n ? `${newValue}`\n : `${prefix}${newValue}`,\n newCursorPosition: newValue.includes(prefix)\n ? newSymbolPosition\n : newSymbolPosition + prefix.length,\n };\n }\n\n return {\n newValue: newValue.includes(prefix)\n ? `${newValue}`\n : `${prefix}${newValue}`,\n };\n };\n\n /** On blur, commit the value to the model */\n const onBlur: React.FocusEventHandler<HTMLInputElement> = (e) => {\n clearPending();\n\n const formatted =\n (prefix\n ? e.target.value.replace(prefix, \"\")\n : props.format(e.target.value)) ?? \"\";\n\n if (formatted) {\n props.set(formatted);\n setLocalValue(formatValueWithAffix(formatted));\n } else {\n props.set(\"\");\n setLocalValue(\"\");\n }\n };\n\n /** Keep track of any user changes */\n const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {\n setLocalValue(e.target.value);\n };\n\n /** Schedule a format of the current input in the future */\n const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (e) => {\n clearPending();\n\n if (prefix) handlePrefixEdgeCases(e);\n\n const target = e.target as HTMLInputElement;\n\n formatTimerRef.current = setTimeout(() => {\n const cursorPosition = target.selectionStart;\n const currentValue = target.value;\n\n /** Skip formatting if we're in the middle of the input */\n if (cursorPosition !== currentValue.length) {\n return;\n }\n\n const obj = onKeyDownHandler(currentValue);\n\n setLocalValue(obj.newValue);\n target.selectionStart = obj.newCursorPosition ?? target.selectionStart;\n target.selectionEnd = obj.newCursorPosition ?? target.selectionEnd;\n }, formatDelay);\n };\n\n /** Format value onFocus if affixes exist */\n const onFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {\n const target = e.target as HTMLInputElement;\n const inputEmpty = target.value === \"\";\n\n if ((!inputEmpty && suffix) || (inputEmpty && prefix)) {\n setLocalValue(handleAffixOnFocus(target));\n }\n };\n\n // Update the stored value if data changes\n const propsValue = props.value;\n useEffect(() => {\n setLocalValue(formatValueWithAffix(propsValue));\n }, [propsValue]);\n\n /** clear anything pending on unmount of input */\n useEffect(() => clearPending, []);\n\n return {\n onBlur,\n onChange,\n onKeyDown,\n onFocus,\n value: localValue,\n };\n};\n\n/** Props for file type Input */\nexport const useFileInputAssetProps = (props: TransformedInput) => {\n const { accept } = props;\n\n const acceptedExtensions = accept\n ? accept.concat(\".json\").join(\", \")\n : \".json\";\n\n /** Parses file content for upload into a string if file type Input */\n const onFileUpload: React.ChangeEventHandler = (e): void => {\n const fileList = (<HTMLInputElement>e.target).files;\n const file = fileList ? fileList[0] : \"\";\n const reader = new FileReader();\n\n reader.addEventListener(\n \"load\",\n () => {\n // this will set the file contents in the data model\n props.set(reader.result as string);\n },\n false\n );\n\n if (file) {\n reader.readAsText(file);\n props.handleFile && props.handleFile(file.name);\n }\n };\n\n return {\n type: \"file\",\n onChange: onFileUpload,\n accept: acceptedExtensions,\n };\n};\n","import React from \"react\";\nimport {\n AssetPropsWithChildren,\n Asset,\n createSlot,\n BindingTemplateInstance,\n} from \"@player-tools/dsl\";\nimport { InputAsset } from \"../types\";\nimport { Text } from \"@devtools-ui/text\";\n\nexport const Input = (\n props: Omit<AssetPropsWithChildren<InputAsset>, \"binding\"> & {\n /** The binding */\n binding: BindingTemplateInstance;\n }\n) => {\n const { children, binding, ...rest } = props;\n return (\n <Asset type=\"input\" {...rest}>\n <property name=\"binding\">{binding.toValue()}</property>\n {children}\n </Asset>\n );\n};\n\nInput.Label = createSlot({\n name: \"label\",\n TextComp: Text,\n isArray: false,\n wrapInAsset: true,\n});\n\nInput.Note = createSlot({\n name: \"note\",\n TextComp: Text,\n isArray: false,\n wrapInAsset: true,\n});\n","import type { TransformFunction } from \"@player-ui/player\";\nimport { InputAsset, TransformedInput } from \"../types\";\n\nexport const inputTransform: TransformFunction<InputAsset, TransformedInput> = (\n asset,\n options\n) => {\n return {\n ...asset,\n format(val) {\n if (asset.binding === undefined) {\n return val;\n }\n\n return options.data.format(asset.binding, val);\n },\n set(val) {\n if (asset.binding === undefined) {\n return;\n }\n\n return options.data.model.set([[asset.binding, val]], {\n formatted: true,\n });\n },\n value:\n asset.binding === undefined\n ? \"\"\n : options.data.model.get(asset.binding, {\n includeInvalid: true,\n formatted: true,\n }),\n validation:\n asset.binding === undefined\n ? undefined\n : options.validation?.get(asset.binding, { track: true }),\n dataType:\n asset.binding === undefined\n ? undefined\n : options.validation?.type(asset.binding),\n };\n};\n"],"mappings":";AAAA,OAAOA,UAAS,YAAAC,WAAU,UAAAC,eAAc;AACxC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,kBAAkB;;;ACV3B,SAAgB,UAAU,WAAW,cAAc;AAqB5C,IAAM,YAAY,CACvB,aAA8B,CAAC,MACD;AAC9B,SAAO;AAAA,IACL,eAAe;AAAA,IACf,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,GAAG;AAAA,EACL;AACF;AAUO,IAAM,qBAAqB,CAChC,OACA,WACG;AACH,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,MAAM,SAAS,EAAE;AAC9D,QAAM,iBAAiB,OAAmC,MAAS;AAEnE,QAAM,EAAE,aAAa,eAAe,QAAQ,OAAO,IAAI,UAAU,MAAM;AAGvE,WAAS,eAAe;AACtB,QAAI,eAAe,SAAS;AAC1B,mBAAa,eAAe,OAAO;AACnC,qBAAe,UAAU;AAAA,IAC3B;AAAA,EACF;AAGA,WAAS,mBAAmB,QAA0B;AACpD,QAAI,MAAM,OAAO;AAEjB,QAAI;AAAQ,YAAM,IAAI,UAAU,GAAG,IAAI,QAAQ,MAAM,CAAC;AAEtD,QAAI,UAAU,CAAC,IAAI,SAAS,MAAM,GAAG;AACnC,YAAM,GAAG,MAAM,GAAG,GAAG;AAAA,IACvB;AAEA,WAAO;AAAA,EACT;AAGA,WAAS,sBAAsB,GAA0C;AACvE,UAAM,SAAS,EAAE;AACjB,UAAM,QAAQ,OAAO;AACrB,UAAM,MAAM,OAAO;AACnB,UAAM,KAAK,OAAO;AAClB,UAAM,UAAU,UAAU;AAC1B,UAAM,QAAQ,QAAQ;AAEtB,QAAI,SAAS,OAAO,QAAQ,IAAI;AAC9B,QAAE,eAAe;AACjB,aAAO,kBAAkB,IAAI,MAAM,QAAQ,EAAE;AAAA,IAC/C,WACG,EAAE,QAAQ,eAAe,WACzB,EAAE,QAAQ,eAAe,WAAW,SACrC,EAAE,QAAQ,QACV;AACA,QAAE,eAAe;AACjB,aAAO,kBAAkB,OAAO,QAAQ,OAAO,MAAM;AAAA,IACvD;AAAA,EACF;AAGA,WAAS,qBAAqB,OAA2B;AACvD,QAAI,CAAC;AAAO,aAAO;AAEnB,WAAO,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM;AAAA,EACnC;AAGA,QAAM,mBAAmC,CAAC,iBAAyB;AACjE,UAAM,iBAAiB,aAAa,QAAQ,aAAa;AACzD,UAAM,WAAW,MAAM,OAAO,YAAY,KAAK;AAC/C,UAAM,oBAAoB,SAAS,QAAQ,aAAa;AAExD,SACG,mBAAmB,MAAM,mBAAmB,MAC7C,oBAAoB,GACpB;AAEA,aAAO;AAAA,QACL,UAAU,SAAS,SAAS,MAAM,IAC9B,GAAG,QAAQ,KACX,GAAG,MAAM,GAAG,QAAQ;AAAA,QACxB,mBAAmB,SAAS,SAAS,MAAM,IACvC,oBACA,oBAAoB,OAAO;AAAA,MACjC;AAAA,IACF;AAEA,WAAO;AAAA,MACL,UAAU,SAAS,SAAS,MAAM,IAC9B,GAAG,QAAQ,KACX,GAAG,MAAM,GAAG,QAAQ;AAAA,IAC1B;AAAA,EACF;AAGA,QAAM,SAAoD,CAAC,MAAM;AAC/D,iBAAa;AAEb,UAAM,aACH,SACG,EAAE,OAAO,MAAM,QAAQ,QAAQ,EAAE,IACjC,MAAM,OAAO,EAAE,OAAO,KAAK,MAAM;AAEvC,QAAI,WAAW;AACb,YAAM,IAAI,SAAS;AACnB,oBAAc,qBAAqB,SAAS,CAAC;AAAA,IAC/C,OAAO;AACL,YAAM,IAAI,EAAE;AACZ,oBAAc,EAAE;AAAA,IAClB;AAAA,EACF;AAGA,QAAM,WAAuD,CAAC,MAAM;AAClE,kBAAc,EAAE,OAAO,KAAK;AAAA,EAC9B;AAGA,QAAM,YAA0D,CAAC,MAAM;AACrE,iBAAa;AAEb,QAAI;AAAQ,4BAAsB,CAAC;AAEnC,UAAM,SAAS,EAAE;AAEjB,mBAAe,UAAU,WAAW,MAAM;AACxC,YAAM,iBAAiB,OAAO;AAC9B,YAAM,eAAe,OAAO;AAG5B,UAAI,mBAAmB,aAAa,QAAQ;AAC1C;AAAA,MACF;AAEA,YAAM,MAAM,iBAAiB,YAAY;AAEzC,oBAAc,IAAI,QAAQ;AAC1B,aAAO,iBAAiB,IAAI,qBAAqB,OAAO;AACxD,aAAO,eAAe,IAAI,qBAAqB,OAAO;AAAA,IACxD,GAAG,WAAW;AAAA,EAChB;AAGA,QAAM,UAAqD,CAAC,MAAM;AAChE,UAAM,SAAS,EAAE;AACjB,UAAM,aAAa,OAAO,UAAU;AAEpC,QAAK,CAAC,cAAc,UAAY,cAAc,QAAS;AACrD,oBAAc,mBAAmB,MAAM,CAAC;AAAA,IAC1C;AAAA,EACF;AAGA,QAAM,aAAa,MAAM;AACzB,YAAU,MAAM;AACd,kBAAc,qBAAqB,UAAU,CAAC;AAAA,EAChD,GAAG,CAAC,UAAU,CAAC;AAGf,YAAU,MAAM,cAAc,CAAC,CAAC;AAEhC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,EACT;AACF;AAGO,IAAM,yBAAyB,CAAC,UAA4B;AACjE,QAAM,EAAE,OAAO,IAAI;AAEnB,QAAM,qBAAqB,SACvB,OAAO,OAAO,OAAO,EAAE,KAAK,IAAI,IAChC;AAGJ,QAAM,eAAyC,CAAC,MAAY;AAC1D,UAAM,WAA8B,EAAE,OAAQ;AAC9C,UAAM,OAAO,WAAW,SAAS,CAAC,IAAI;AACtC,UAAM,SAAS,IAAI,WAAW;AAE9B,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAEJ,cAAM,IAAI,OAAO,MAAgB;AAAA,MACnC;AAAA,MACA;AAAA,IACF;AAEA,QAAI,MAAM;AACR,aAAO,WAAW,IAAI;AACtB,YAAM,cAAc,MAAM,WAAW,KAAK,IAAI;AAAA,IAChD;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AACF;;;ADjOA,IAAM,qBAAqB,CAAC,UAA4B;AACtD,QAAM,kBAAkCC,QAAO,IAAI;AAEnD,QAAM,CAAC,UAAU,WAAW,IAAIC,UAAS,EAAE;AAE3C,QAAM,cAAc,MAAM;AACxB,oBAAgB,SAAS,MAAM;AAAA,EACjC;AAEA,QAAM,aAAa,CAACC,cAAqB;AACvC,gBAAYA,SAAQ;AAAA,EACtB;AAEA,QAAM,EAAE,IAAI,MAAM,IAAI;AAEtB,QAAM,aAAa,uBAAuB,EAAE,GAAG,OAAO,WAAW,CAAC;AAElE,SACE,gBAAAC,OAAA,cAAC,mBACC,gBAAAA,OAAA,cAAC,UAAO,WAAU,eAAc,SAAS,eACvC,gBAAAA,OAAA,cAAC,aAAU,OAAO,EAAE,QAAQ,EAAE,KAC3B,QAAQ,gBAAAA,OAAA,cAAC,cAAY,GAAG,MAAM,OAAO,IAAK,gBAAAA,OAAA,cAAAA,OAAA,gBAAE,gBAAc,CAC7D,CACF,GACA,gBAAAA,OAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAM;AAAA,MACL,GAAG;AAAA,MACJ,OAAO,EAAE,SAAS,OAAO;AAAA,MACzB,KAAK;AAAA;AAAA,EACP,GACC,WAAW,gBAAAA,OAAA,cAAC,WAAE,mBAAgB,QAAS,IAAO,IACjD;AAEJ;AAEO,IAAM,iBAAiB,CAAC,UAA4B;AACzD,QAAM,EAAE,YAAY,OAAO,IAAI,MAAM,MAAM,WAAW,aAAa,KAAK,IACtE;AAEF,QAAM,aAAa,mBAAmB,KAAK;AAE3C,SAAO,OACL,gBAAAA,OAAA,cAAC,sBAAoB,GAAG,OAAO,IAE/B,gBAAAA,OAAA,cAAC,eAAY,WAAW,QAAQ,UAAU,KACvC,SACC,gBAAAA,OAAA,cAAC,aAAU,SAAS,MAClB,gBAAAA,OAAA,cAAC,cAAY,GAAG,MAAM,OAAO,CAC/B,GAEF,gBAAAA,OAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACC,GAAG;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF,GACC,cAAc,gBAAAA,OAAA,cAAC,wBAAkB,WAAW,OAAQ,GACpD,QACC,gBAAAA,OAAA,cAAC,sBACC,gBAAAA,OAAA,cAAC,cAAY,GAAG,KAAK,OAAO,CAC9B,CAEJ;AAEJ;;;AE/EA,OAAOC,YAAW;AAClB;AAAA,EAEE;AAAA,EACA;AAAA,OAEK;AAEP,SAAS,YAAY;AAEd,IAAMC,SAAQ,CACnB,UAIG;AACH,QAAM,EAAE,UAAU,SAAS,GAAG,KAAK,IAAI;AACvC,SACE,gBAAAD,OAAA,cAAC,SAAM,MAAK,SAAS,GAAG,QACtB,gBAAAA,OAAA,cAAC,cAAS,MAAK,aAAW,QAAQ,QAAQ,CAAE,GAC3C,QACH;AAEJ;AAEAC,OAAM,QAAQ,WAAW;AAAA,EACvB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,aAAa;AACf,CAAC;AAEDA,OAAM,OAAO,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,aAAa;AACf,CAAC;;;AClCM,IAAM,iBAAkE,CAC7E,OACA,YACG;AACH,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO,KAAK;AACV,UAAI,MAAM,YAAY,QAAW;AAC/B,eAAO;AAAA,MACT;AAEA,aAAO,QAAQ,KAAK,OAAO,MAAM,SAAS,GAAG;AAAA,IAC/C;AAAA,IACA,IAAI,KAAK;AACP,UAAI,MAAM,YAAY,QAAW;AAC/B;AAAA,MACF;AAEA,aAAO,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,SAAS,GAAG,CAAC,GAAG;AAAA,QACpD,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,IACA,OACE,MAAM,YAAY,SACd,KACA,QAAQ,KAAK,MAAM,IAAI,MAAM,SAAS;AAAA,MACpC,gBAAgB;AAAA,MAChB,WAAW;AAAA,IACb,CAAC;AAAA,IACP,YACE,MAAM,YAAY,SACd,SACA,QAAQ,YAAY,IAAI,MAAM,SAAS,EAAE,OAAO,KAAK,CAAC;AAAA,IAC5D,UACE,MAAM,YAAY,SACd,SACA,QAAQ,YAAY,KAAK,MAAM,OAAO;AAAA,EAC9C;AACF;","names":["React","useState","useRef","useRef","useState","fileName","React","React","Input"]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devtools-ui/input",
|
|
3
|
-
"version": "0.2.0-next.
|
|
3
|
+
"version": "0.2.0-next.2",
|
|
4
4
|
"main": "dist/cjs/index.cjs",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@devtools-ui/text": "0.2.0-next.
|
|
6
|
+
"@devtools-ui/text": "0.2.0-next.2",
|
|
7
7
|
"@chakra-ui/react": "^2.8.2",
|
|
8
8
|
"@emotion/react": "^11.11.4",
|
|
9
9
|
"@emotion/styled": "^11.11.0",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useState, useRef } from "react";
|
|
2
2
|
import {
|
|
3
3
|
Input,
|
|
4
|
+
Button,
|
|
4
5
|
FormControl,
|
|
5
6
|
FormLabel,
|
|
6
7
|
FormHelperText,
|
|
@@ -8,13 +9,53 @@ import {
|
|
|
8
9
|
} from "@chakra-ui/react";
|
|
9
10
|
import { TransformedInput } from "../types";
|
|
10
11
|
import { ReactAsset } from "@player-ui/react";
|
|
11
|
-
import { useInputAssetProps } from "
|
|
12
|
+
import { useInputAssetProps, useFileInputAssetProps } from "../hooks";
|
|
13
|
+
|
|
14
|
+
const FileInputComponent = (props: TransformedInput) => {
|
|
15
|
+
const hiddenFileInput: React.Ref<any> = useRef(null);
|
|
16
|
+
|
|
17
|
+
const [fileName, setFileName] = useState("");
|
|
18
|
+
|
|
19
|
+
const handleClick = () => {
|
|
20
|
+
hiddenFileInput.current?.click();
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const handleFile = (fileName: string) => {
|
|
24
|
+
setFileName(fileName);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const { id, label } = props;
|
|
28
|
+
|
|
29
|
+
const inputProps = useFileInputAssetProps({ ...props, handleFile });
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<FormControl>
|
|
33
|
+
<Button className="button-file" onClick={handleClick}>
|
|
34
|
+
<FormLabel style={{ margin: 0 }}>
|
|
35
|
+
{label ? <ReactAsset {...label.asset} /> : <>Select Content</>}
|
|
36
|
+
</FormLabel>
|
|
37
|
+
</Button>
|
|
38
|
+
<Input
|
|
39
|
+
id={id}
|
|
40
|
+
name={id}
|
|
41
|
+
{...inputProps}
|
|
42
|
+
style={{ display: "none" }}
|
|
43
|
+
ref={hiddenFileInput}
|
|
44
|
+
/>
|
|
45
|
+
{fileName ? <p>Uploaded file: {fileName}</p> : null}
|
|
46
|
+
</FormControl>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
12
49
|
|
|
13
50
|
export const InputComponent = (props: TransformedInput) => {
|
|
14
|
-
const { validation, label, id, note, size, maxLength, placeholder } =
|
|
51
|
+
const { validation, label, id, note, size, maxLength, placeholder, file } =
|
|
52
|
+
props;
|
|
53
|
+
|
|
15
54
|
const inputProps = useInputAssetProps(props);
|
|
16
55
|
|
|
17
|
-
return (
|
|
56
|
+
return file ? (
|
|
57
|
+
<FileInputComponent {...props} />
|
|
58
|
+
) : (
|
|
18
59
|
<FormControl isInvalid={Boolean(validation)}>
|
|
19
60
|
{label && (
|
|
20
61
|
<FormLabel htmlFor={id}>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, fireEvent } from "@testing-library/react";
|
|
3
|
+
import { describe, expect, test } from "vitest";
|
|
4
|
+
import { InputComponent } from "../index";
|
|
5
|
+
import { TransformedInput } from "../../types";
|
|
6
|
+
|
|
7
|
+
describe("InputComponent test", () => {
|
|
8
|
+
const inputAssetPropsMock: TransformedInput = {
|
|
9
|
+
id: "default-input",
|
|
10
|
+
type: "input",
|
|
11
|
+
set: () => {},
|
|
12
|
+
format: (value) => value,
|
|
13
|
+
value: "test",
|
|
14
|
+
binding: "some.binding",
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const inputFileAssetPropsMock: TransformedInput = {
|
|
18
|
+
...inputAssetPropsMock,
|
|
19
|
+
id: "file-input",
|
|
20
|
+
file: true,
|
|
21
|
+
accept: [".txt"],
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
test("Renders default Input asset", () => {
|
|
25
|
+
const inputElement = render(<InputComponent {...inputAssetPropsMock} />);
|
|
26
|
+
|
|
27
|
+
const input = inputElement.container.querySelector(
|
|
28
|
+
"input"
|
|
29
|
+
) as HTMLInputElement;
|
|
30
|
+
|
|
31
|
+
fireEvent.change(input, { target: { value: "Test 2" } });
|
|
32
|
+
|
|
33
|
+
fireEvent.blur(input);
|
|
34
|
+
|
|
35
|
+
expect(input.value).toBe("Test 2");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("Renders file type Input asset", () => {
|
|
39
|
+
const inputElement = render(
|
|
40
|
+
<InputComponent {...inputFileAssetPropsMock} />
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const fileUploader = inputElement.container.querySelector(
|
|
44
|
+
"input"
|
|
45
|
+
) as HTMLInputElement;
|
|
46
|
+
|
|
47
|
+
const file = new File(['{"some":"content"}'], "content.json", {
|
|
48
|
+
type: "json",
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
fireEvent.change(fileUploader, { target: { files: [file] } });
|
|
52
|
+
|
|
53
|
+
expect(inputElement.container.querySelector("p")?.textContent).toBe(
|
|
54
|
+
"Uploaded file: content.json"
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -62,4 +62,40 @@ describe("DSL: Input", () => {
|
|
|
62
62
|
binding: "binding",
|
|
63
63
|
});
|
|
64
64
|
});
|
|
65
|
+
|
|
66
|
+
test("It should render a file uploader version of Input asset", async () => {
|
|
67
|
+
const rendered = await render(
|
|
68
|
+
<Input binding={b`binding`} file={true}>
|
|
69
|
+
<Input.Label>Label</Input.Label>
|
|
70
|
+
</Input>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
expect(rendered.jsonValue).toStrictEqual({
|
|
74
|
+
id: "root",
|
|
75
|
+
type: "input",
|
|
76
|
+
file: true,
|
|
77
|
+
label: {
|
|
78
|
+
asset: {
|
|
79
|
+
id: "label",
|
|
80
|
+
type: "text",
|
|
81
|
+
value: "Label",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
binding: "binding",
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("It should render a file uploader Input asset with accepted file extensions", async () => {
|
|
89
|
+
const rendered = await render(
|
|
90
|
+
<Input binding={b`binding`} file={true} accept={[".tsx", ".jsx"]} />
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
expect(rendered.jsonValue).toStrictEqual({
|
|
94
|
+
id: "root",
|
|
95
|
+
type: "input",
|
|
96
|
+
file: true,
|
|
97
|
+
accept: [".tsx", ".jsx"],
|
|
98
|
+
binding: "binding",
|
|
99
|
+
});
|
|
100
|
+
});
|
|
65
101
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useState, useEffect, useRef } from "react";
|
|
2
2
|
import type { TransformedInput } from "../types";
|
|
3
3
|
|
|
4
4
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -43,8 +43,8 @@ export const useInputAssetProps = (
|
|
|
43
43
|
props: TransformedInput,
|
|
44
44
|
config?: InputHookConfig
|
|
45
45
|
) => {
|
|
46
|
-
const [localValue, setLocalValue] =
|
|
47
|
-
const formatTimerRef =
|
|
46
|
+
const [localValue, setLocalValue] = useState(props.value ?? "");
|
|
47
|
+
const formatTimerRef = useRef<NodeJS.Timeout | undefined>(undefined);
|
|
48
48
|
|
|
49
49
|
const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);
|
|
50
50
|
|
|
@@ -186,12 +186,12 @@ export const useInputAssetProps = (
|
|
|
186
186
|
|
|
187
187
|
// Update the stored value if data changes
|
|
188
188
|
const propsValue = props.value;
|
|
189
|
-
|
|
189
|
+
useEffect(() => {
|
|
190
190
|
setLocalValue(formatValueWithAffix(propsValue));
|
|
191
191
|
}, [propsValue]);
|
|
192
192
|
|
|
193
193
|
/** clear anything pending on unmount of input */
|
|
194
|
-
|
|
194
|
+
useEffect(() => clearPending, []);
|
|
195
195
|
|
|
196
196
|
return {
|
|
197
197
|
onBlur,
|
|
@@ -201,3 +201,39 @@ export const useInputAssetProps = (
|
|
|
201
201
|
value: localValue,
|
|
202
202
|
};
|
|
203
203
|
};
|
|
204
|
+
|
|
205
|
+
/** Props for file type Input */
|
|
206
|
+
export const useFileInputAssetProps = (props: TransformedInput) => {
|
|
207
|
+
const { accept } = props;
|
|
208
|
+
|
|
209
|
+
const acceptedExtensions = accept
|
|
210
|
+
? accept.concat(".json").join(", ")
|
|
211
|
+
: ".json";
|
|
212
|
+
|
|
213
|
+
/** Parses file content for upload into a string if file type Input */
|
|
214
|
+
const onFileUpload: React.ChangeEventHandler = (e): void => {
|
|
215
|
+
const fileList = (<HTMLInputElement>e.target).files;
|
|
216
|
+
const file = fileList ? fileList[0] : "";
|
|
217
|
+
const reader = new FileReader();
|
|
218
|
+
|
|
219
|
+
reader.addEventListener(
|
|
220
|
+
"load",
|
|
221
|
+
() => {
|
|
222
|
+
// this will set the file contents in the data model
|
|
223
|
+
props.set(reader.result as string);
|
|
224
|
+
},
|
|
225
|
+
false
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
if (file) {
|
|
229
|
+
reader.readAsText(file);
|
|
230
|
+
props.handleFile && props.handleFile(file.name);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
type: "file",
|
|
236
|
+
onChange: onFileUpload,
|
|
237
|
+
accept: acceptedExtensions,
|
|
238
|
+
};
|
|
239
|
+
};
|
package/src/types/index.ts
CHANGED
|
@@ -24,6 +24,12 @@ export interface InputAsset extends Asset<"input"> {
|
|
|
24
24
|
|
|
25
25
|
/** Max character length in the Input */
|
|
26
26
|
maxLength?: number;
|
|
27
|
+
|
|
28
|
+
/** For file uploader Input */
|
|
29
|
+
file?: boolean;
|
|
30
|
+
|
|
31
|
+
/** File extensions to be accepted by the file uploader Input, .json supported by default */
|
|
32
|
+
accept?: string[];
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
export interface TransformedInput extends InputAsset {
|
|
@@ -41,4 +47,7 @@ export interface TransformedInput extends InputAsset {
|
|
|
41
47
|
|
|
42
48
|
/** The dataType defined from the schema */
|
|
43
49
|
dataType?: Schema.DataType;
|
|
50
|
+
|
|
51
|
+
/** Handler for persisting file name for file type input */
|
|
52
|
+
handleFile?: (name: string) => void;
|
|
44
53
|
}
|
|
@@ -27,4 +27,10 @@ export declare const useInputAssetProps: (props: TransformedInput, config?: Inpu
|
|
|
27
27
|
onFocus: React.FocusEventHandler<HTMLInputElement>;
|
|
28
28
|
value: string;
|
|
29
29
|
};
|
|
30
|
-
|
|
30
|
+
/** Props for file type Input */
|
|
31
|
+
export declare const useFileInputAssetProps: (props: TransformedInput) => {
|
|
32
|
+
type: string;
|
|
33
|
+
onChange: React.ChangeEventHandler<Element>;
|
|
34
|
+
accept: string;
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
package/types/types/index.d.ts
CHANGED
|
@@ -16,6 +16,10 @@ export interface InputAsset extends Asset<"input"> {
|
|
|
16
16
|
placeholder?: string;
|
|
17
17
|
/** Max character length in the Input */
|
|
18
18
|
maxLength?: number;
|
|
19
|
+
/** For file uploader Input */
|
|
20
|
+
file?: boolean;
|
|
21
|
+
/** File extensions to be accepted by the file uploader Input, .json supported by default */
|
|
22
|
+
accept?: string[];
|
|
19
23
|
}
|
|
20
24
|
export interface TransformedInput extends InputAsset {
|
|
21
25
|
/** A function to commit the new value to the data-model */
|
|
@@ -28,6 +32,8 @@ export interface TransformedInput extends InputAsset {
|
|
|
28
32
|
validation?: ValidationResponse;
|
|
29
33
|
/** The dataType defined from the schema */
|
|
30
34
|
dataType?: Schema.DataType;
|
|
35
|
+
/** Handler for persisting file name for file type input */
|
|
36
|
+
handleFile?: (name: string) => void;
|
|
31
37
|
}
|
|
32
38
|
export {};
|
|
33
39
|
//# sourceMappingURL=index.d.ts.map
|