@devtools-ui/input 0.0.2--canary.11.588
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 +229 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/index.legacy-esm.js +199 -0
- package/dist/index.mjs +199 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +39 -0
- package/src/components/InputComponent.tsx +39 -0
- package/src/components/hooks.ts +203 -0
- package/src/components/index.ts +1 -0
- package/src/dsl/Input.tsx +38 -0
- package/src/dsl/__tests__/Input.test.tsx +65 -0
- package/src/dsl/index.ts +1 -0
- package/src/index.ts +4 -0
- package/src/transform/index.ts +42 -0
- package/src/types/index.ts +44 -0
- package/types/components/InputComponent.d.ts +4 -0
- package/types/components/hooks.d.ts +30 -0
- package/types/components/index.d.ts +2 -0
- package/types/dsl/Input.d.ts +16 -0
- package/types/dsl/index.d.ts +2 -0
- package/types/index.d.ts +5 -0
- package/types/transform/index.d.ts +4 -0
- package/types/types/index.d.ts +33 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
Input: () => Input2,
|
|
34
|
+
InputComponent: () => InputComponent,
|
|
35
|
+
inputTransform: () => inputTransform
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(src_exports);
|
|
38
|
+
|
|
39
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
40
|
+
var import_react2 = __toESM(require("react"));
|
|
41
|
+
var import_react3 = require("@chakra-ui/react");
|
|
42
|
+
var import_react4 = require("@player-ui/react");
|
|
43
|
+
|
|
44
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/hooks.ts
|
|
45
|
+
var import_react = __toESM(require("react"));
|
|
46
|
+
var getConfig = (userConfig = {}) => {
|
|
47
|
+
return {
|
|
48
|
+
decimalSymbol: ".",
|
|
49
|
+
formatDelay: 200,
|
|
50
|
+
prefix: "",
|
|
51
|
+
suffix: "",
|
|
52
|
+
...userConfig
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
var useInputAssetProps = (props, config) => {
|
|
56
|
+
const [localValue, setLocalValue] = import_react.default.useState(props.value ?? "");
|
|
57
|
+
const formatTimerRef = import_react.default.useRef(void 0);
|
|
58
|
+
const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);
|
|
59
|
+
function clearPending() {
|
|
60
|
+
if (formatTimerRef.current) {
|
|
61
|
+
clearTimeout(formatTimerRef.current);
|
|
62
|
+
formatTimerRef.current = void 0;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function handleAffixOnFocus(target) {
|
|
66
|
+
let val = target.value;
|
|
67
|
+
if (suffix)
|
|
68
|
+
val = val.substring(0, val.indexOf(suffix));
|
|
69
|
+
if (prefix && !val.includes(prefix)) {
|
|
70
|
+
val = `${prefix}${val}`;
|
|
71
|
+
}
|
|
72
|
+
return val;
|
|
73
|
+
}
|
|
74
|
+
function handlePrefixEdgeCases(e) {
|
|
75
|
+
const target = e.target;
|
|
76
|
+
const start = target.selectionStart;
|
|
77
|
+
const end = target.selectionEnd;
|
|
78
|
+
const pl = prefix.length;
|
|
79
|
+
const atStart = start === pl;
|
|
80
|
+
const atEnd = end === pl;
|
|
81
|
+
if (start && end && start < pl) {
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
target.setSelectionRange(pl, end - start + pl);
|
|
84
|
+
} else if (e.key === "ArrowLeft" && atStart || e.key === "Backspace" && atStart && atEnd || e.key === "Home") {
|
|
85
|
+
e.preventDefault();
|
|
86
|
+
target.setSelectionRange(prefix.length, prefix.length);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function formatValueWithAffix(value) {
|
|
90
|
+
if (!value)
|
|
91
|
+
return "";
|
|
92
|
+
return `${prefix}${value}${suffix}`;
|
|
93
|
+
}
|
|
94
|
+
const onKeyDownHandler = (currentValue) => {
|
|
95
|
+
const symbolPosition = currentValue.indexOf(decimalSymbol);
|
|
96
|
+
const newValue = props.format(currentValue) ?? "";
|
|
97
|
+
const newSymbolPosition = newValue.indexOf(decimalSymbol);
|
|
98
|
+
if ((symbolPosition === -1 || symbolPosition === 0) && newSymbolPosition > 0) {
|
|
99
|
+
return {
|
|
100
|
+
newValue: newValue.includes(prefix) ? `${newValue}` : `${prefix}${newValue}`,
|
|
101
|
+
newCursorPosition: newValue.includes(prefix) ? newSymbolPosition : newSymbolPosition + prefix.length
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
newValue: newValue.includes(prefix) ? `${newValue}` : `${prefix}${newValue}`
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
const onBlur = (e) => {
|
|
109
|
+
clearPending();
|
|
110
|
+
const formatted = (prefix ? e.target.value.replace(prefix, "") : props.format(e.target.value)) ?? "";
|
|
111
|
+
if (formatted) {
|
|
112
|
+
props.set(formatted);
|
|
113
|
+
setLocalValue(formatValueWithAffix(formatted));
|
|
114
|
+
} else {
|
|
115
|
+
props.set("");
|
|
116
|
+
setLocalValue("");
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const onChange = (e) => {
|
|
120
|
+
setLocalValue(e.target.value);
|
|
121
|
+
};
|
|
122
|
+
const onKeyDown = (e) => {
|
|
123
|
+
clearPending();
|
|
124
|
+
if (prefix)
|
|
125
|
+
handlePrefixEdgeCases(e);
|
|
126
|
+
const target = e.target;
|
|
127
|
+
formatTimerRef.current = setTimeout(() => {
|
|
128
|
+
const cursorPosition = target.selectionStart;
|
|
129
|
+
const currentValue = target.value;
|
|
130
|
+
if (cursorPosition !== currentValue.length) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const obj = onKeyDownHandler(currentValue);
|
|
134
|
+
setLocalValue(obj.newValue);
|
|
135
|
+
target.selectionStart = obj.newCursorPosition ?? target.selectionStart;
|
|
136
|
+
target.selectionEnd = obj.newCursorPosition ?? target.selectionEnd;
|
|
137
|
+
}, formatDelay);
|
|
138
|
+
};
|
|
139
|
+
const onFocus = (e) => {
|
|
140
|
+
const target = e.target;
|
|
141
|
+
const inputEmpty = target.value === "";
|
|
142
|
+
if (!inputEmpty && suffix || inputEmpty && prefix) {
|
|
143
|
+
setLocalValue(handleAffixOnFocus(target));
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const propsValue = props.value;
|
|
147
|
+
import_react.default.useEffect(() => {
|
|
148
|
+
setLocalValue(formatValueWithAffix(propsValue));
|
|
149
|
+
}, [propsValue]);
|
|
150
|
+
import_react.default.useEffect(() => clearPending, []);
|
|
151
|
+
return {
|
|
152
|
+
onBlur,
|
|
153
|
+
onChange,
|
|
154
|
+
onKeyDown,
|
|
155
|
+
onFocus,
|
|
156
|
+
value: localValue
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
161
|
+
var InputComponent = (props) => {
|
|
162
|
+
const { validation, label, id, note, size, maxLength, placeholder } = props;
|
|
163
|
+
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(
|
|
165
|
+
import_react3.Input,
|
|
166
|
+
{
|
|
167
|
+
id,
|
|
168
|
+
...inputProps,
|
|
169
|
+
size,
|
|
170
|
+
maxLength,
|
|
171
|
+
placeholder
|
|
172
|
+
}
|
|
173
|
+
), validation && /* @__PURE__ */ import_react2.default.createElement(import_react3.FormErrorMessage, null, validation.message), note && /* @__PURE__ */ import_react2.default.createElement(import_react3.FormHelperText, null, /* @__PURE__ */ import_react2.default.createElement(import_react4.ReactAsset, { ...note.asset })));
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/dsl/Input.tsx
|
|
177
|
+
var import_react5 = __toESM(require("react"));
|
|
178
|
+
var import_dsl = require("@player-tools/dsl");
|
|
179
|
+
var import_text = require("@devtools-ui/text");
|
|
180
|
+
var Input2 = (props) => {
|
|
181
|
+
const { children, binding, ...rest } = props;
|
|
182
|
+
return /* @__PURE__ */ import_react5.default.createElement(import_dsl.Asset, { type: "input", ...rest }, /* @__PURE__ */ import_react5.default.createElement("property", { name: "binding" }, binding.toValue()), children);
|
|
183
|
+
};
|
|
184
|
+
Input2.Label = (0, import_dsl.createSlot)({
|
|
185
|
+
name: "label",
|
|
186
|
+
TextComp: import_text.Text,
|
|
187
|
+
isArray: false,
|
|
188
|
+
wrapInAsset: true
|
|
189
|
+
});
|
|
190
|
+
Input2.Note = (0, import_dsl.createSlot)({
|
|
191
|
+
name: "note",
|
|
192
|
+
TextComp: import_text.Text,
|
|
193
|
+
isArray: false,
|
|
194
|
+
wrapInAsset: true
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/transform/index.ts
|
|
198
|
+
var inputTransform = (asset, options) => {
|
|
199
|
+
return {
|
|
200
|
+
...asset,
|
|
201
|
+
format(val) {
|
|
202
|
+
if (asset.binding === void 0) {
|
|
203
|
+
return val;
|
|
204
|
+
}
|
|
205
|
+
return options.data.format(asset.binding, val);
|
|
206
|
+
},
|
|
207
|
+
set(val) {
|
|
208
|
+
if (asset.binding === void 0) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
return options.data.model.set([[asset.binding, val]], {
|
|
212
|
+
formatted: true
|
|
213
|
+
});
|
|
214
|
+
},
|
|
215
|
+
value: asset.binding === void 0 ? "" : options.data.model.get(asset.binding, {
|
|
216
|
+
includeInvalid: true,
|
|
217
|
+
formatted: true
|
|
218
|
+
}),
|
|
219
|
+
validation: asset.binding === void 0 ? void 0 : options.validation?.get(asset.binding, { track: true }),
|
|
220
|
+
dataType: asset.binding === void 0 ? void 0 : options.validation?.type(asset.binding)
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
224
|
+
0 && (module.exports = {
|
|
225
|
+
Input,
|
|
226
|
+
InputComponent,
|
|
227
|
+
inputTransform
|
|
228
|
+
});
|
|
229
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA,eAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAC,gBAAkB;AAClB,IAAAA,gBAMO;AAEP,IAAAA,gBAA2B;;;ACT3B,mBAAkB;AAqBX,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,aAAAC,QAAM,SAAS,MAAM,SAAS,EAAE;AACpE,QAAM,iBAAiB,aAAAA,QAAM,OAAmC,MAAS;AAEzE,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,eAAAA,QAAM,UAAU,MAAM;AACpB,kBAAc,qBAAqB,UAAU,CAAC;AAAA,EAChD,GAAG,CAAC,UAAU,CAAC;AAGf,eAAAA,QAAM,UAAU,MAAM,cAAc,CAAC,CAAC;AAEtC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,EACT;AACF;;;AD9LO,IAAM,iBAAiB,CAAC,UAA4B;AACzD,QAAM,EAAE,YAAY,OAAO,IAAI,MAAM,MAAM,WAAW,YAAY,IAAI;AACtE,QAAM,aAAa,mBAAmB,KAAK;AAE3C,SACE,8BAAAC,QAAA,cAAC,6BAAY,WAAW,QAAQ,UAAU,KACvC,SACC,8BAAAA,QAAA,cAAC,2BAAU,SAAS,MAClB,8BAAAA,QAAA,cAAC,4BAAY,GAAG,MAAM,OAAO,CAC/B,GAEF,8BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACC,GAAG;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF,GACC,cAAc,8BAAAA,QAAA,cAAC,sCAAkB,WAAW,OAAQ,GACpD,QACC,8BAAAA,QAAA,cAAC,oCACC,8BAAAA,QAAA,cAAC,4BAAY,GAAG,KAAK,OAAO,CAC9B,CAEJ;AAEJ;;;AEtCA,IAAAC,gBAAkB;AAClB,iBAKO;AAEP,kBAAqB;AAEd,IAAMC,SAAQ,CACnB,UAIG;AACH,QAAM,EAAE,UAAU,SAAS,GAAG,KAAK,IAAI;AACvC,SACE,8BAAAC,QAAA,cAAC,oBAAM,MAAK,SAAS,GAAG,QACtB,8BAAAA,QAAA,cAAC,cAAS,MAAK,aAAW,QAAQ,QAAQ,CAAE,GAC3C,QACH;AAEJ;AAEAD,OAAM,YAAQ,uBAAW;AAAA,EACvB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,aAAa;AACf,CAAC;AAEDA,OAAM,WAAO,uBAAW;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":["Input","import_react","React","React","import_react","Input","React"]}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
2
|
+
import React2 from "react";
|
|
3
|
+
import {
|
|
4
|
+
Input,
|
|
5
|
+
FormControl,
|
|
6
|
+
FormLabel,
|
|
7
|
+
FormHelperText,
|
|
8
|
+
FormErrorMessage
|
|
9
|
+
} from "@chakra-ui/react";
|
|
10
|
+
import { ReactAsset } from "@player-ui/react";
|
|
11
|
+
|
|
12
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/hooks.ts
|
|
13
|
+
import React from "react";
|
|
14
|
+
var getConfig = (userConfig = {}) => {
|
|
15
|
+
return {
|
|
16
|
+
decimalSymbol: ".",
|
|
17
|
+
formatDelay: 200,
|
|
18
|
+
prefix: "",
|
|
19
|
+
suffix: "",
|
|
20
|
+
...userConfig
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
var useInputAssetProps = (props, config) => {
|
|
24
|
+
const [localValue, setLocalValue] = React.useState(props.value ?? "");
|
|
25
|
+
const formatTimerRef = React.useRef(void 0);
|
|
26
|
+
const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);
|
|
27
|
+
function clearPending() {
|
|
28
|
+
if (formatTimerRef.current) {
|
|
29
|
+
clearTimeout(formatTimerRef.current);
|
|
30
|
+
formatTimerRef.current = void 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function handleAffixOnFocus(target) {
|
|
34
|
+
let val = target.value;
|
|
35
|
+
if (suffix)
|
|
36
|
+
val = val.substring(0, val.indexOf(suffix));
|
|
37
|
+
if (prefix && !val.includes(prefix)) {
|
|
38
|
+
val = `${prefix}${val}`;
|
|
39
|
+
}
|
|
40
|
+
return val;
|
|
41
|
+
}
|
|
42
|
+
function handlePrefixEdgeCases(e) {
|
|
43
|
+
const target = e.target;
|
|
44
|
+
const start = target.selectionStart;
|
|
45
|
+
const end = target.selectionEnd;
|
|
46
|
+
const pl = prefix.length;
|
|
47
|
+
const atStart = start === pl;
|
|
48
|
+
const atEnd = end === pl;
|
|
49
|
+
if (start && end && start < pl) {
|
|
50
|
+
e.preventDefault();
|
|
51
|
+
target.setSelectionRange(pl, end - start + pl);
|
|
52
|
+
} else if (e.key === "ArrowLeft" && atStart || e.key === "Backspace" && atStart && atEnd || e.key === "Home") {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
target.setSelectionRange(prefix.length, prefix.length);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function formatValueWithAffix(value) {
|
|
58
|
+
if (!value)
|
|
59
|
+
return "";
|
|
60
|
+
return `${prefix}${value}${suffix}`;
|
|
61
|
+
}
|
|
62
|
+
const onKeyDownHandler = (currentValue) => {
|
|
63
|
+
const symbolPosition = currentValue.indexOf(decimalSymbol);
|
|
64
|
+
const newValue = props.format(currentValue) ?? "";
|
|
65
|
+
const newSymbolPosition = newValue.indexOf(decimalSymbol);
|
|
66
|
+
if ((symbolPosition === -1 || symbolPosition === 0) && newSymbolPosition > 0) {
|
|
67
|
+
return {
|
|
68
|
+
newValue: newValue.includes(prefix) ? `${newValue}` : `${prefix}${newValue}`,
|
|
69
|
+
newCursorPosition: newValue.includes(prefix) ? newSymbolPosition : newSymbolPosition + prefix.length
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
newValue: newValue.includes(prefix) ? `${newValue}` : `${prefix}${newValue}`
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
const onBlur = (e) => {
|
|
77
|
+
clearPending();
|
|
78
|
+
const formatted = (prefix ? e.target.value.replace(prefix, "") : props.format(e.target.value)) ?? "";
|
|
79
|
+
if (formatted) {
|
|
80
|
+
props.set(formatted);
|
|
81
|
+
setLocalValue(formatValueWithAffix(formatted));
|
|
82
|
+
} else {
|
|
83
|
+
props.set("");
|
|
84
|
+
setLocalValue("");
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const onChange = (e) => {
|
|
88
|
+
setLocalValue(e.target.value);
|
|
89
|
+
};
|
|
90
|
+
const onKeyDown = (e) => {
|
|
91
|
+
clearPending();
|
|
92
|
+
if (prefix)
|
|
93
|
+
handlePrefixEdgeCases(e);
|
|
94
|
+
const target = e.target;
|
|
95
|
+
formatTimerRef.current = setTimeout(() => {
|
|
96
|
+
const cursorPosition = target.selectionStart;
|
|
97
|
+
const currentValue = target.value;
|
|
98
|
+
if (cursorPosition !== currentValue.length) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const obj = onKeyDownHandler(currentValue);
|
|
102
|
+
setLocalValue(obj.newValue);
|
|
103
|
+
target.selectionStart = obj.newCursorPosition ?? target.selectionStart;
|
|
104
|
+
target.selectionEnd = obj.newCursorPosition ?? target.selectionEnd;
|
|
105
|
+
}, formatDelay);
|
|
106
|
+
};
|
|
107
|
+
const onFocus = (e) => {
|
|
108
|
+
const target = e.target;
|
|
109
|
+
const inputEmpty = target.value === "";
|
|
110
|
+
if (!inputEmpty && suffix || inputEmpty && prefix) {
|
|
111
|
+
setLocalValue(handleAffixOnFocus(target));
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const propsValue = props.value;
|
|
115
|
+
React.useEffect(() => {
|
|
116
|
+
setLocalValue(formatValueWithAffix(propsValue));
|
|
117
|
+
}, [propsValue]);
|
|
118
|
+
React.useEffect(() => clearPending, []);
|
|
119
|
+
return {
|
|
120
|
+
onBlur,
|
|
121
|
+
onChange,
|
|
122
|
+
onKeyDown,
|
|
123
|
+
onFocus,
|
|
124
|
+
value: localValue
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
129
|
+
var InputComponent = (props) => {
|
|
130
|
+
const { validation, label, id, note, size, maxLength, placeholder } = props;
|
|
131
|
+
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(
|
|
133
|
+
Input,
|
|
134
|
+
{
|
|
135
|
+
id,
|
|
136
|
+
...inputProps,
|
|
137
|
+
size,
|
|
138
|
+
maxLength,
|
|
139
|
+
placeholder
|
|
140
|
+
}
|
|
141
|
+
), validation && /* @__PURE__ */ React2.createElement(FormErrorMessage, null, validation.message), note && /* @__PURE__ */ React2.createElement(FormHelperText, null, /* @__PURE__ */ React2.createElement(ReactAsset, { ...note.asset })));
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/dsl/Input.tsx
|
|
145
|
+
import React3 from "react";
|
|
146
|
+
import {
|
|
147
|
+
Asset,
|
|
148
|
+
createSlot
|
|
149
|
+
} from "@player-tools/dsl";
|
|
150
|
+
import { Text } from "@devtools-ui/text";
|
|
151
|
+
var Input2 = (props) => {
|
|
152
|
+
const { children, binding, ...rest } = props;
|
|
153
|
+
return /* @__PURE__ */ React3.createElement(Asset, { type: "input", ...rest }, /* @__PURE__ */ React3.createElement("property", { name: "binding" }, binding.toValue()), children);
|
|
154
|
+
};
|
|
155
|
+
Input2.Label = createSlot({
|
|
156
|
+
name: "label",
|
|
157
|
+
TextComp: Text,
|
|
158
|
+
isArray: false,
|
|
159
|
+
wrapInAsset: true
|
|
160
|
+
});
|
|
161
|
+
Input2.Note = createSlot({
|
|
162
|
+
name: "note",
|
|
163
|
+
TextComp: Text,
|
|
164
|
+
isArray: false,
|
|
165
|
+
wrapInAsset: true
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/transform/index.ts
|
|
169
|
+
var inputTransform = (asset, options) => {
|
|
170
|
+
return {
|
|
171
|
+
...asset,
|
|
172
|
+
format(val) {
|
|
173
|
+
if (asset.binding === void 0) {
|
|
174
|
+
return val;
|
|
175
|
+
}
|
|
176
|
+
return options.data.format(asset.binding, val);
|
|
177
|
+
},
|
|
178
|
+
set(val) {
|
|
179
|
+
if (asset.binding === void 0) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
return options.data.model.set([[asset.binding, val]], {
|
|
183
|
+
formatted: true
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
value: asset.binding === void 0 ? "" : options.data.model.get(asset.binding, {
|
|
187
|
+
includeInvalid: true,
|
|
188
|
+
formatted: true
|
|
189
|
+
}),
|
|
190
|
+
validation: asset.binding === void 0 ? void 0 : options.validation?.get(asset.binding, { track: true }),
|
|
191
|
+
dataType: asset.binding === void 0 ? void 0 : options.validation?.type(asset.binding)
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
export {
|
|
195
|
+
Input2 as Input,
|
|
196
|
+
InputComponent,
|
|
197
|
+
inputTransform
|
|
198
|
+
};
|
|
199
|
+
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
2
|
+
import React2 from "react";
|
|
3
|
+
import {
|
|
4
|
+
Input,
|
|
5
|
+
FormControl,
|
|
6
|
+
FormLabel,
|
|
7
|
+
FormHelperText,
|
|
8
|
+
FormErrorMessage
|
|
9
|
+
} from "@chakra-ui/react";
|
|
10
|
+
import { ReactAsset } from "@player-ui/react";
|
|
11
|
+
|
|
12
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/hooks.ts
|
|
13
|
+
import React from "react";
|
|
14
|
+
var getConfig = (userConfig = {}) => {
|
|
15
|
+
return {
|
|
16
|
+
decimalSymbol: ".",
|
|
17
|
+
formatDelay: 200,
|
|
18
|
+
prefix: "",
|
|
19
|
+
suffix: "",
|
|
20
|
+
...userConfig
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
var useInputAssetProps = (props, config) => {
|
|
24
|
+
const [localValue, setLocalValue] = React.useState(props.value ?? "");
|
|
25
|
+
const formatTimerRef = React.useRef(void 0);
|
|
26
|
+
const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);
|
|
27
|
+
function clearPending() {
|
|
28
|
+
if (formatTimerRef.current) {
|
|
29
|
+
clearTimeout(formatTimerRef.current);
|
|
30
|
+
formatTimerRef.current = void 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function handleAffixOnFocus(target) {
|
|
34
|
+
let val = target.value;
|
|
35
|
+
if (suffix)
|
|
36
|
+
val = val.substring(0, val.indexOf(suffix));
|
|
37
|
+
if (prefix && !val.includes(prefix)) {
|
|
38
|
+
val = `${prefix}${val}`;
|
|
39
|
+
}
|
|
40
|
+
return val;
|
|
41
|
+
}
|
|
42
|
+
function handlePrefixEdgeCases(e) {
|
|
43
|
+
const target = e.target;
|
|
44
|
+
const start = target.selectionStart;
|
|
45
|
+
const end = target.selectionEnd;
|
|
46
|
+
const pl = prefix.length;
|
|
47
|
+
const atStart = start === pl;
|
|
48
|
+
const atEnd = end === pl;
|
|
49
|
+
if (start && end && start < pl) {
|
|
50
|
+
e.preventDefault();
|
|
51
|
+
target.setSelectionRange(pl, end - start + pl);
|
|
52
|
+
} else if (e.key === "ArrowLeft" && atStart || e.key === "Backspace" && atStart && atEnd || e.key === "Home") {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
target.setSelectionRange(prefix.length, prefix.length);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function formatValueWithAffix(value) {
|
|
58
|
+
if (!value)
|
|
59
|
+
return "";
|
|
60
|
+
return `${prefix}${value}${suffix}`;
|
|
61
|
+
}
|
|
62
|
+
const onKeyDownHandler = (currentValue) => {
|
|
63
|
+
const symbolPosition = currentValue.indexOf(decimalSymbol);
|
|
64
|
+
const newValue = props.format(currentValue) ?? "";
|
|
65
|
+
const newSymbolPosition = newValue.indexOf(decimalSymbol);
|
|
66
|
+
if ((symbolPosition === -1 || symbolPosition === 0) && newSymbolPosition > 0) {
|
|
67
|
+
return {
|
|
68
|
+
newValue: newValue.includes(prefix) ? `${newValue}` : `${prefix}${newValue}`,
|
|
69
|
+
newCursorPosition: newValue.includes(prefix) ? newSymbolPosition : newSymbolPosition + prefix.length
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
newValue: newValue.includes(prefix) ? `${newValue}` : `${prefix}${newValue}`
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
const onBlur = (e) => {
|
|
77
|
+
clearPending();
|
|
78
|
+
const formatted = (prefix ? e.target.value.replace(prefix, "") : props.format(e.target.value)) ?? "";
|
|
79
|
+
if (formatted) {
|
|
80
|
+
props.set(formatted);
|
|
81
|
+
setLocalValue(formatValueWithAffix(formatted));
|
|
82
|
+
} else {
|
|
83
|
+
props.set("");
|
|
84
|
+
setLocalValue("");
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const onChange = (e) => {
|
|
88
|
+
setLocalValue(e.target.value);
|
|
89
|
+
};
|
|
90
|
+
const onKeyDown = (e) => {
|
|
91
|
+
clearPending();
|
|
92
|
+
if (prefix)
|
|
93
|
+
handlePrefixEdgeCases(e);
|
|
94
|
+
const target = e.target;
|
|
95
|
+
formatTimerRef.current = setTimeout(() => {
|
|
96
|
+
const cursorPosition = target.selectionStart;
|
|
97
|
+
const currentValue = target.value;
|
|
98
|
+
if (cursorPosition !== currentValue.length) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const obj = onKeyDownHandler(currentValue);
|
|
102
|
+
setLocalValue(obj.newValue);
|
|
103
|
+
target.selectionStart = obj.newCursorPosition ?? target.selectionStart;
|
|
104
|
+
target.selectionEnd = obj.newCursorPosition ?? target.selectionEnd;
|
|
105
|
+
}, formatDelay);
|
|
106
|
+
};
|
|
107
|
+
const onFocus = (e) => {
|
|
108
|
+
const target = e.target;
|
|
109
|
+
const inputEmpty = target.value === "";
|
|
110
|
+
if (!inputEmpty && suffix || inputEmpty && prefix) {
|
|
111
|
+
setLocalValue(handleAffixOnFocus(target));
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const propsValue = props.value;
|
|
115
|
+
React.useEffect(() => {
|
|
116
|
+
setLocalValue(formatValueWithAffix(propsValue));
|
|
117
|
+
}, [propsValue]);
|
|
118
|
+
React.useEffect(() => clearPending, []);
|
|
119
|
+
return {
|
|
120
|
+
onBlur,
|
|
121
|
+
onChange,
|
|
122
|
+
onKeyDown,
|
|
123
|
+
onFocus,
|
|
124
|
+
value: localValue
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/components/InputComponent.tsx
|
|
129
|
+
var InputComponent = (props) => {
|
|
130
|
+
const { validation, label, id, note, size, maxLength, placeholder } = props;
|
|
131
|
+
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(
|
|
133
|
+
Input,
|
|
134
|
+
{
|
|
135
|
+
id,
|
|
136
|
+
...inputProps,
|
|
137
|
+
size,
|
|
138
|
+
maxLength,
|
|
139
|
+
placeholder
|
|
140
|
+
}
|
|
141
|
+
), validation && /* @__PURE__ */ React2.createElement(FormErrorMessage, null, validation.message), note && /* @__PURE__ */ React2.createElement(FormHelperText, null, /* @__PURE__ */ React2.createElement(ReactAsset, { ...note.asset })));
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/dsl/Input.tsx
|
|
145
|
+
import React3 from "react";
|
|
146
|
+
import {
|
|
147
|
+
Asset,
|
|
148
|
+
createSlot
|
|
149
|
+
} from "@player-tools/dsl";
|
|
150
|
+
import { Text } from "@devtools-ui/text";
|
|
151
|
+
var Input2 = (props) => {
|
|
152
|
+
const { children, binding, ...rest } = props;
|
|
153
|
+
return /* @__PURE__ */ React3.createElement(Asset, { type: "input", ...rest }, /* @__PURE__ */ React3.createElement("property", { name: "binding" }, binding.toValue()), children);
|
|
154
|
+
};
|
|
155
|
+
Input2.Label = createSlot({
|
|
156
|
+
name: "label",
|
|
157
|
+
TextComp: Text,
|
|
158
|
+
isArray: false,
|
|
159
|
+
wrapInAsset: true
|
|
160
|
+
});
|
|
161
|
+
Input2.Note = createSlot({
|
|
162
|
+
name: "note",
|
|
163
|
+
TextComp: Text,
|
|
164
|
+
isArray: false,
|
|
165
|
+
wrapInAsset: true
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// ../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/input/src/transform/index.ts
|
|
169
|
+
var inputTransform = (asset, options) => {
|
|
170
|
+
return {
|
|
171
|
+
...asset,
|
|
172
|
+
format(val) {
|
|
173
|
+
if (asset.binding === void 0) {
|
|
174
|
+
return val;
|
|
175
|
+
}
|
|
176
|
+
return options.data.format(asset.binding, val);
|
|
177
|
+
},
|
|
178
|
+
set(val) {
|
|
179
|
+
if (asset.binding === void 0) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
return options.data.model.set([[asset.binding, val]], {
|
|
183
|
+
formatted: true
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
value: asset.binding === void 0 ? "" : options.data.model.get(asset.binding, {
|
|
187
|
+
includeInvalid: true,
|
|
188
|
+
formatted: true
|
|
189
|
+
}),
|
|
190
|
+
validation: asset.binding === void 0 ? void 0 : options.validation?.get(asset.binding, { track: true }),
|
|
191
|
+
dataType: asset.binding === void 0 ? void 0 : options.validation?.type(asset.binding)
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
export {
|
|
195
|
+
Input2 as Input,
|
|
196
|
+
InputComponent,
|
|
197
|
+
inputTransform
|
|
198
|
+
};
|
|
199
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@devtools-ui/input",
|
|
3
|
+
"version": "0.0.2--canary.11.588",
|
|
4
|
+
"main": "dist/cjs/index.cjs",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@devtools-ui/text": "0.0.2--canary.11.588",
|
|
7
|
+
"@chakra-ui/react": "^2.8.2",
|
|
8
|
+
"@emotion/react": "^11.11.4",
|
|
9
|
+
"@emotion/styled": "^11.11.0",
|
|
10
|
+
"@player-tools/dsl": "0.5.2--canary.87.2261",
|
|
11
|
+
"@player-ui/types": "0.7.1",
|
|
12
|
+
"@player-ui/player": "0.7.1",
|
|
13
|
+
"@player-ui/react": "^0.7.1",
|
|
14
|
+
"@player-ui/asset-transform-plugin": "^0.7.1",
|
|
15
|
+
"@types/react": "^18.2.51",
|
|
16
|
+
"framer-motion": "^11.0.8",
|
|
17
|
+
"react": "^18.2.0",
|
|
18
|
+
"dlv": "^1.1.3",
|
|
19
|
+
"eslint-plugin-storybook": "^0.8.0",
|
|
20
|
+
"tslib": "^2.6.2"
|
|
21
|
+
},
|
|
22
|
+
"module": "dist/index.legacy-esm.js",
|
|
23
|
+
"types": "types/index.d.ts",
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"exports": {
|
|
26
|
+
"./package.json": "./package.json",
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./types/index.d.ts",
|
|
29
|
+
"import": "./dist/index.mjs",
|
|
30
|
+
"default": "./dist/cjs/index.cjs"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"src",
|
|
36
|
+
"types"
|
|
37
|
+
],
|
|
38
|
+
"peerDependencies": {}
|
|
39
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
Input,
|
|
4
|
+
FormControl,
|
|
5
|
+
FormLabel,
|
|
6
|
+
FormHelperText,
|
|
7
|
+
FormErrorMessage,
|
|
8
|
+
} from "@chakra-ui/react";
|
|
9
|
+
import { TransformedInput } from "../types";
|
|
10
|
+
import { ReactAsset } from "@player-ui/react";
|
|
11
|
+
import { useInputAssetProps } from "./hooks";
|
|
12
|
+
|
|
13
|
+
export const InputComponent = (props: TransformedInput) => {
|
|
14
|
+
const { validation, label, id, note, size, maxLength, placeholder } = props;
|
|
15
|
+
const inputProps = useInputAssetProps(props);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<FormControl isInvalid={Boolean(validation)}>
|
|
19
|
+
{label && (
|
|
20
|
+
<FormLabel htmlFor={id}>
|
|
21
|
+
<ReactAsset {...label.asset} />
|
|
22
|
+
</FormLabel>
|
|
23
|
+
)}
|
|
24
|
+
<Input
|
|
25
|
+
id={id}
|
|
26
|
+
{...inputProps}
|
|
27
|
+
size={size}
|
|
28
|
+
maxLength={maxLength}
|
|
29
|
+
placeholder={placeholder}
|
|
30
|
+
/>
|
|
31
|
+
{validation && <FormErrorMessage>{validation.message}</FormErrorMessage>}
|
|
32
|
+
{note && (
|
|
33
|
+
<FormHelperText>
|
|
34
|
+
<ReactAsset {...note.asset} />
|
|
35
|
+
</FormHelperText>
|
|
36
|
+
)}
|
|
37
|
+
</FormControl>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { TransformedInput } from "../types";
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
|
+
type KeyDownHandler = (currentValue: string, props?: TransformedInput) => any;
|
|
6
|
+
|
|
7
|
+
export interface InputHookConfig {
|
|
8
|
+
/** Time in ms to wait before formatting the user input for normal keys */
|
|
9
|
+
formatDelay?: number;
|
|
10
|
+
|
|
11
|
+
/** Symbol to be used for decimal point */
|
|
12
|
+
decimalSymbol?: string;
|
|
13
|
+
|
|
14
|
+
/** Affix to append to value - does not save to model and is only for display on input */
|
|
15
|
+
prefix?: string;
|
|
16
|
+
|
|
17
|
+
/** Affix to prepend to value - does not save to model and is only for display on input */
|
|
18
|
+
suffix?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Create a valid config mixing in defaults and user overrides */
|
|
22
|
+
export const getConfig = (
|
|
23
|
+
userConfig: InputHookConfig = {}
|
|
24
|
+
): Required<InputHookConfig> => {
|
|
25
|
+
return {
|
|
26
|
+
decimalSymbol: ".",
|
|
27
|
+
formatDelay: 200,
|
|
28
|
+
prefix: "",
|
|
29
|
+
suffix: "",
|
|
30
|
+
...userConfig,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A hook to manage an input html element as an asset.
|
|
36
|
+
* The hook returns an object containing props that are expected to reside on any html input.
|
|
37
|
+
* It will handle formatting, setting values, beaconing, aria-labels, etc.
|
|
38
|
+
*
|
|
39
|
+
* @param props - The output of the input transform
|
|
40
|
+
* @param config - Local config to manage user interaction overrides
|
|
41
|
+
*/
|
|
42
|
+
export const useInputAssetProps = (
|
|
43
|
+
props: TransformedInput,
|
|
44
|
+
config?: InputHookConfig
|
|
45
|
+
) => {
|
|
46
|
+
const [localValue, setLocalValue] = React.useState(props.value ?? "");
|
|
47
|
+
const formatTimerRef = React.useRef<NodeJS.Timeout | undefined>(undefined);
|
|
48
|
+
|
|
49
|
+
const { formatDelay, decimalSymbol, prefix, suffix } = getConfig(config);
|
|
50
|
+
|
|
51
|
+
/** Reset and pending format timers */
|
|
52
|
+
function clearPending() {
|
|
53
|
+
if (formatTimerRef.current) {
|
|
54
|
+
clearTimeout(formatTimerRef.current);
|
|
55
|
+
formatTimerRef.current = undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Affix handling logic on focus */
|
|
60
|
+
function handleAffixOnFocus(target: HTMLInputElement) {
|
|
61
|
+
let val = target.value;
|
|
62
|
+
|
|
63
|
+
if (suffix) val = val.substring(0, val.indexOf(suffix));
|
|
64
|
+
|
|
65
|
+
if (prefix && !val.includes(prefix)) {
|
|
66
|
+
val = `${prefix}${val}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return val;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Edge cases handling for prefix */
|
|
73
|
+
function handlePrefixEdgeCases(e: React.KeyboardEvent<HTMLInputElement>) {
|
|
74
|
+
const target = e.target as HTMLInputElement;
|
|
75
|
+
const start = target.selectionStart;
|
|
76
|
+
const end = target.selectionEnd;
|
|
77
|
+
const pl = prefix.length;
|
|
78
|
+
const atStart = start === pl;
|
|
79
|
+
const atEnd = end === pl;
|
|
80
|
+
|
|
81
|
+
if (start && end && start < pl) {
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
target.setSelectionRange(pl, end - start + pl);
|
|
84
|
+
} else if (
|
|
85
|
+
(e.key === "ArrowLeft" && atStart) ||
|
|
86
|
+
(e.key === "Backspace" && atStart && atEnd) ||
|
|
87
|
+
e.key === "Home"
|
|
88
|
+
) {
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
target.setSelectionRange(prefix.length, prefix.length);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Helper to add affixes to value where appropriate */
|
|
95
|
+
function formatValueWithAffix(value: string | undefined) {
|
|
96
|
+
if (!value) return "";
|
|
97
|
+
|
|
98
|
+
return `${prefix}${value}${suffix}`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Value handling logic on key down */
|
|
102
|
+
const onKeyDownHandler: KeyDownHandler = (currentValue: string) => {
|
|
103
|
+
const symbolPosition = currentValue.indexOf(decimalSymbol);
|
|
104
|
+
const newValue = props.format(currentValue) ?? "";
|
|
105
|
+
const newSymbolPosition = newValue.indexOf(decimalSymbol);
|
|
106
|
+
|
|
107
|
+
if (
|
|
108
|
+
(symbolPosition === -1 || symbolPosition === 0) &&
|
|
109
|
+
newSymbolPosition > 0
|
|
110
|
+
) {
|
|
111
|
+
// formatting added dot, so set cursor before dot
|
|
112
|
+
return {
|
|
113
|
+
newValue: newValue.includes(prefix)
|
|
114
|
+
? `${newValue}`
|
|
115
|
+
: `${prefix}${newValue}`,
|
|
116
|
+
newCursorPosition: newValue.includes(prefix)
|
|
117
|
+
? newSymbolPosition
|
|
118
|
+
: newSymbolPosition + prefix.length,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
newValue: newValue.includes(prefix)
|
|
124
|
+
? `${newValue}`
|
|
125
|
+
: `${prefix}${newValue}`,
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/** On blur, commit the value to the model */
|
|
130
|
+
const onBlur: React.FocusEventHandler<HTMLInputElement> = (e) => {
|
|
131
|
+
clearPending();
|
|
132
|
+
|
|
133
|
+
const formatted =
|
|
134
|
+
(prefix
|
|
135
|
+
? e.target.value.replace(prefix, "")
|
|
136
|
+
: props.format(e.target.value)) ?? "";
|
|
137
|
+
|
|
138
|
+
if (formatted) {
|
|
139
|
+
props.set(formatted);
|
|
140
|
+
setLocalValue(formatValueWithAffix(formatted));
|
|
141
|
+
} else {
|
|
142
|
+
props.set("");
|
|
143
|
+
setLocalValue("");
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/** Keep track of any user changes */
|
|
148
|
+
const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
|
|
149
|
+
setLocalValue(e.target.value);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/** Schedule a format of the current input in the future */
|
|
153
|
+
const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (e) => {
|
|
154
|
+
clearPending();
|
|
155
|
+
|
|
156
|
+
if (prefix) handlePrefixEdgeCases(e);
|
|
157
|
+
|
|
158
|
+
const target = e.target as HTMLInputElement;
|
|
159
|
+
|
|
160
|
+
formatTimerRef.current = setTimeout(() => {
|
|
161
|
+
const cursorPosition = target.selectionStart;
|
|
162
|
+
const currentValue = target.value;
|
|
163
|
+
|
|
164
|
+
/** Skip formatting if we're in the middle of the input */
|
|
165
|
+
if (cursorPosition !== currentValue.length) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const obj = onKeyDownHandler(currentValue);
|
|
170
|
+
|
|
171
|
+
setLocalValue(obj.newValue);
|
|
172
|
+
target.selectionStart = obj.newCursorPosition ?? target.selectionStart;
|
|
173
|
+
target.selectionEnd = obj.newCursorPosition ?? target.selectionEnd;
|
|
174
|
+
}, formatDelay);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/** Format value onFocus if affixes exist */
|
|
178
|
+
const onFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {
|
|
179
|
+
const target = e.target as HTMLInputElement;
|
|
180
|
+
const inputEmpty = target.value === "";
|
|
181
|
+
|
|
182
|
+
if ((!inputEmpty && suffix) || (inputEmpty && prefix)) {
|
|
183
|
+
setLocalValue(handleAffixOnFocus(target));
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// Update the stored value if data changes
|
|
188
|
+
const propsValue = props.value;
|
|
189
|
+
React.useEffect(() => {
|
|
190
|
+
setLocalValue(formatValueWithAffix(propsValue));
|
|
191
|
+
}, [propsValue]);
|
|
192
|
+
|
|
193
|
+
/** clear anything pending on unmount of input */
|
|
194
|
+
React.useEffect(() => clearPending, []);
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
onBlur,
|
|
198
|
+
onChange,
|
|
199
|
+
onKeyDown,
|
|
200
|
+
onFocus,
|
|
201
|
+
value: localValue,
|
|
202
|
+
};
|
|
203
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { InputComponent } from "./InputComponent";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
AssetPropsWithChildren,
|
|
4
|
+
Asset,
|
|
5
|
+
createSlot,
|
|
6
|
+
BindingTemplateInstance,
|
|
7
|
+
} from "@player-tools/dsl";
|
|
8
|
+
import { InputAsset } from "../types";
|
|
9
|
+
import { Text } from "@devtools-ui/text";
|
|
10
|
+
|
|
11
|
+
export const Input = (
|
|
12
|
+
props: Omit<AssetPropsWithChildren<InputAsset>, "binding"> & {
|
|
13
|
+
/** The binding */
|
|
14
|
+
binding: BindingTemplateInstance;
|
|
15
|
+
}
|
|
16
|
+
) => {
|
|
17
|
+
const { children, binding, ...rest } = props;
|
|
18
|
+
return (
|
|
19
|
+
<Asset type="input" {...rest}>
|
|
20
|
+
<property name="binding">{binding.toValue()}</property>
|
|
21
|
+
{children}
|
|
22
|
+
</Asset>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
Input.Label = createSlot({
|
|
27
|
+
name: "label",
|
|
28
|
+
TextComp: Text,
|
|
29
|
+
isArray: false,
|
|
30
|
+
wrapInAsset: true,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
Input.Note = createSlot({
|
|
34
|
+
name: "note",
|
|
35
|
+
TextComp: Text,
|
|
36
|
+
isArray: false,
|
|
37
|
+
wrapInAsset: true,
|
|
38
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import { render, binding as b } from "@player-tools/dsl";
|
|
4
|
+
import { Input } from "../Input";
|
|
5
|
+
|
|
6
|
+
describe("DSL: Input", () => {
|
|
7
|
+
test("Renders default input", async () => {
|
|
8
|
+
const rendered = await render(<Input binding={b`binding`} />);
|
|
9
|
+
|
|
10
|
+
expect(rendered.jsonValue).toStrictEqual({
|
|
11
|
+
id: "root",
|
|
12
|
+
type: "input",
|
|
13
|
+
binding: "binding",
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("Renders input with size, placeholder and maxLength", async () => {
|
|
18
|
+
const rendered = await render(
|
|
19
|
+
<Input
|
|
20
|
+
size={"md"}
|
|
21
|
+
placeholder={"User input"}
|
|
22
|
+
maxLength={10}
|
|
23
|
+
binding={b`binding`}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
expect(rendered.jsonValue).toStrictEqual({
|
|
28
|
+
id: "root",
|
|
29
|
+
type: "input",
|
|
30
|
+
placeholder: "User input",
|
|
31
|
+
size: "md",
|
|
32
|
+
maxLength: 10,
|
|
33
|
+
binding: "binding",
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("Renders input with label, binding and note", async () => {
|
|
38
|
+
const rendered = await render(
|
|
39
|
+
<Input binding={b`binding`}>
|
|
40
|
+
<Input.Label>Label</Input.Label>
|
|
41
|
+
<Input.Note>Some note</Input.Note>
|
|
42
|
+
</Input>
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
expect(rendered.jsonValue).toStrictEqual({
|
|
46
|
+
id: "root",
|
|
47
|
+
type: "input",
|
|
48
|
+
label: {
|
|
49
|
+
asset: {
|
|
50
|
+
id: "label",
|
|
51
|
+
type: "text",
|
|
52
|
+
value: "Label",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
note: {
|
|
56
|
+
asset: {
|
|
57
|
+
id: "note",
|
|
58
|
+
type: "text",
|
|
59
|
+
value: "Some note",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
binding: "binding",
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
package/src/dsl/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Input } from "./Input";
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { TransformFunction } from "@player-ui/player";
|
|
2
|
+
import { InputAsset, TransformedInput } from "../types";
|
|
3
|
+
|
|
4
|
+
export const inputTransform: TransformFunction<InputAsset, TransformedInput> = (
|
|
5
|
+
asset,
|
|
6
|
+
options
|
|
7
|
+
) => {
|
|
8
|
+
return {
|
|
9
|
+
...asset,
|
|
10
|
+
format(val) {
|
|
11
|
+
if (asset.binding === undefined) {
|
|
12
|
+
return val;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return options.data.format(asset.binding, val);
|
|
16
|
+
},
|
|
17
|
+
set(val) {
|
|
18
|
+
if (asset.binding === undefined) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return options.data.model.set([[asset.binding, val]], {
|
|
23
|
+
formatted: true,
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
value:
|
|
27
|
+
asset.binding === undefined
|
|
28
|
+
? ""
|
|
29
|
+
: options.data.model.get(asset.binding, {
|
|
30
|
+
includeInvalid: true,
|
|
31
|
+
formatted: true,
|
|
32
|
+
}),
|
|
33
|
+
validation:
|
|
34
|
+
asset.binding === undefined
|
|
35
|
+
? undefined
|
|
36
|
+
: options.validation?.get(asset.binding, { track: true }),
|
|
37
|
+
dataType:
|
|
38
|
+
asset.binding === undefined
|
|
39
|
+
? undefined
|
|
40
|
+
: options.validation?.type(asset.binding),
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { TextAsset } from "@devtools-ui/text";
|
|
2
|
+
import { Asset, Schema, AssetWrapper } from "@player-ui/types";
|
|
3
|
+
import { ValidationResponse } from "@player-ui/player";
|
|
4
|
+
|
|
5
|
+
export type InputSize = "xs" | "sm" | "md" | "lg";
|
|
6
|
+
|
|
7
|
+
type ValueType = string | undefined;
|
|
8
|
+
|
|
9
|
+
export interface InputAsset extends Asset<"input"> {
|
|
10
|
+
/** The location in the data-model to store the data */
|
|
11
|
+
binding: ValueType;
|
|
12
|
+
|
|
13
|
+
/** A text asset for the action's label */
|
|
14
|
+
label?: AssetWrapper<TextAsset>;
|
|
15
|
+
|
|
16
|
+
/** Asset container for a note. */
|
|
17
|
+
note?: AssetWrapper<TextAsset>;
|
|
18
|
+
|
|
19
|
+
/** Size of the Input height */
|
|
20
|
+
size?: InputSize;
|
|
21
|
+
|
|
22
|
+
/** Placeholder of the Input */
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
|
|
25
|
+
/** Max character length in the Input */
|
|
26
|
+
maxLength?: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface TransformedInput extends InputAsset {
|
|
30
|
+
/** A function to commit the new value to the data-model */
|
|
31
|
+
set: (newValue: ValueType) => void;
|
|
32
|
+
|
|
33
|
+
/** A function to format a value */
|
|
34
|
+
format: (newValue: ValueType) => ValueType;
|
|
35
|
+
|
|
36
|
+
/** The current value of the input from the data-model */
|
|
37
|
+
value: ValueType;
|
|
38
|
+
|
|
39
|
+
/** Any validation associated with the current input's value */
|
|
40
|
+
validation?: ValidationResponse;
|
|
41
|
+
|
|
42
|
+
/** The dataType defined from the schema */
|
|
43
|
+
dataType?: Schema.DataType;
|
|
44
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { TransformedInput } from "../types";
|
|
3
|
+
export interface InputHookConfig {
|
|
4
|
+
/** Time in ms to wait before formatting the user input for normal keys */
|
|
5
|
+
formatDelay?: number;
|
|
6
|
+
/** Symbol to be used for decimal point */
|
|
7
|
+
decimalSymbol?: string;
|
|
8
|
+
/** Affix to append to value - does not save to model and is only for display on input */
|
|
9
|
+
prefix?: string;
|
|
10
|
+
/** Affix to prepend to value - does not save to model and is only for display on input */
|
|
11
|
+
suffix?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Create a valid config mixing in defaults and user overrides */
|
|
14
|
+
export declare const getConfig: (userConfig?: InputHookConfig) => Required<InputHookConfig>;
|
|
15
|
+
/**
|
|
16
|
+
* A hook to manage an input html element as an asset.
|
|
17
|
+
* The hook returns an object containing props that are expected to reside on any html input.
|
|
18
|
+
* It will handle formatting, setting values, beaconing, aria-labels, etc.
|
|
19
|
+
*
|
|
20
|
+
* @param props - The output of the input transform
|
|
21
|
+
* @param config - Local config to manage user interaction overrides
|
|
22
|
+
*/
|
|
23
|
+
export declare const useInputAssetProps: (props: TransformedInput, config?: InputHookConfig) => {
|
|
24
|
+
onBlur: React.FocusEventHandler<HTMLInputElement>;
|
|
25
|
+
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
|
26
|
+
onKeyDown: React.KeyboardEventHandler<HTMLInputElement>;
|
|
27
|
+
onFocus: React.FocusEventHandler<HTMLInputElement>;
|
|
28
|
+
value: string;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { AssetPropsWithChildren, BindingTemplateInstance } from "@player-tools/dsl";
|
|
3
|
+
import { InputAsset } from "../types";
|
|
4
|
+
export declare const Input: {
|
|
5
|
+
(props: Omit<AssetPropsWithChildren<InputAsset>, "binding"> & {
|
|
6
|
+
/** The binding */
|
|
7
|
+
binding: BindingTemplateInstance;
|
|
8
|
+
}): React.JSX.Element;
|
|
9
|
+
Label: (props: {
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
}) => React.JSX.Element;
|
|
12
|
+
Note: (props: {
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
}) => React.JSX.Element;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=Input.d.ts.map
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { TextAsset } from "@devtools-ui/text";
|
|
2
|
+
import { Asset, Schema, AssetWrapper } from "@player-ui/types";
|
|
3
|
+
import { ValidationResponse } from "@player-ui/player";
|
|
4
|
+
export type InputSize = "xs" | "sm" | "md" | "lg";
|
|
5
|
+
type ValueType = string | undefined;
|
|
6
|
+
export interface InputAsset extends Asset<"input"> {
|
|
7
|
+
/** The location in the data-model to store the data */
|
|
8
|
+
binding: ValueType;
|
|
9
|
+
/** A text asset for the action's label */
|
|
10
|
+
label?: AssetWrapper<TextAsset>;
|
|
11
|
+
/** Asset container for a note. */
|
|
12
|
+
note?: AssetWrapper<TextAsset>;
|
|
13
|
+
/** Size of the Input height */
|
|
14
|
+
size?: InputSize;
|
|
15
|
+
/** Placeholder of the Input */
|
|
16
|
+
placeholder?: string;
|
|
17
|
+
/** Max character length in the Input */
|
|
18
|
+
maxLength?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface TransformedInput extends InputAsset {
|
|
21
|
+
/** A function to commit the new value to the data-model */
|
|
22
|
+
set: (newValue: ValueType) => void;
|
|
23
|
+
/** A function to format a value */
|
|
24
|
+
format: (newValue: ValueType) => ValueType;
|
|
25
|
+
/** The current value of the input from the data-model */
|
|
26
|
+
value: ValueType;
|
|
27
|
+
/** Any validation associated with the current input's value */
|
|
28
|
+
validation?: ValidationResponse;
|
|
29
|
+
/** The dataType defined from the schema */
|
|
30
|
+
dataType?: Schema.DataType;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|