@xsolla/xui-input-edit 0.176.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/web/index.mjs ADDED
@@ -0,0 +1,944 @@
1
+ // src/InputEdit.tsx
2
+ import React3, {
3
+ useState,
4
+ useRef,
5
+ useEffect,
6
+ forwardRef as forwardRef2
7
+ } from "react";
8
+
9
+ // ../../foundation/primitives-web/src/Box.tsx
10
+ import React2 from "react";
11
+ import styled from "styled-components";
12
+
13
+ // ../../foundation/primitives-web/src/filterDOMProps.ts
14
+ import React from "react";
15
+
16
+ // ../../../node_modules/@emotion/memoize/dist/memoize.esm.js
17
+ function memoize(fn) {
18
+ var cache = {};
19
+ return function(arg) {
20
+ if (cache[arg] === void 0) cache[arg] = fn(arg);
21
+ return cache[arg];
22
+ };
23
+ }
24
+ var memoize_esm_default = memoize;
25
+
26
+ // ../../../node_modules/@emotion/is-prop-valid/dist/is-prop-valid.esm.js
27
+ var reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|inert|itemProp|itemScope|itemType|itemID|itemRef|on|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/;
28
+ var index = memoize_esm_default(
29
+ function(prop) {
30
+ return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111 && prop.charCodeAt(1) === 110 && prop.charCodeAt(2) < 91;
31
+ }
32
+ /* Z+1 */
33
+ );
34
+ var is_prop_valid_esm_default = index;
35
+
36
+ // ../../foundation/primitives-web/src/filterDOMProps.ts
37
+ var ADDITIONAL_BLOCKED_PROPS = /* @__PURE__ */ new Set([
38
+ // RN-only event handlers (pass isPropValid's on* pattern)
39
+ "onPress",
40
+ "onChangeText",
41
+ "onLayout",
42
+ "onMoveShouldSetResponder",
43
+ "onResponderGrant",
44
+ "onResponderMove",
45
+ "onResponderRelease",
46
+ "onResponderTerminate",
47
+ // SVG attributes that pass isPropValid
48
+ "strokeWidth",
49
+ // CSS properties that pass isPropValid but are used as component props
50
+ "overflow",
51
+ "cursor",
52
+ "fontSize",
53
+ "fontWeight",
54
+ "fontFamily",
55
+ "textDecoration"
56
+ ]);
57
+ function shouldForwardProp(key) {
58
+ if (ADDITIONAL_BLOCKED_PROPS.has(key)) return false;
59
+ return is_prop_valid_esm_default(key);
60
+ }
61
+ function createFilteredElement(defaultTag) {
62
+ const Component = React.forwardRef(
63
+ ({ children, elementType, ...props }, ref) => {
64
+ const Tag = elementType || defaultTag;
65
+ const htmlProps = {};
66
+ for (const key of Object.keys(props)) {
67
+ if (shouldForwardProp(key)) {
68
+ htmlProps[key] = props[key];
69
+ }
70
+ }
71
+ return React.createElement(
72
+ Tag,
73
+ { ref, ...htmlProps },
74
+ children
75
+ );
76
+ }
77
+ );
78
+ Component.displayName = `Filtered(${defaultTag})`;
79
+ return Component;
80
+ }
81
+
82
+ // ../../foundation/primitives-web/src/Box.tsx
83
+ import { jsx } from "react/jsx-runtime";
84
+ var FilteredDiv = createFilteredElement("div");
85
+ var StyledBox = styled(FilteredDiv)`
86
+ display: flex;
87
+ box-sizing: border-box;
88
+ background-color: ${(props) => props.backgroundColor || "transparent"};
89
+ border-color: ${(props) => props.borderColor || "transparent"};
90
+ border-width: ${(props) => typeof props.borderWidth === "number" ? `${props.borderWidth}px` : props.borderWidth || 0};
91
+
92
+ ${(props) => props.borderBottomWidth !== void 0 && `
93
+ border-bottom-width: ${typeof props.borderBottomWidth === "number" ? `${props.borderBottomWidth}px` : props.borderBottomWidth};
94
+ border-bottom-color: ${props.borderBottomColor || props.borderColor || "transparent"};
95
+ border-bottom-style: solid;
96
+ `}
97
+ ${(props) => props.borderTopWidth !== void 0 && `
98
+ border-top-width: ${typeof props.borderTopWidth === "number" ? `${props.borderTopWidth}px` : props.borderTopWidth};
99
+ border-top-color: ${props.borderTopColor || props.borderColor || "transparent"};
100
+ border-top-style: solid;
101
+ `}
102
+ ${(props) => props.borderLeftWidth !== void 0 && `
103
+ border-left-width: ${typeof props.borderLeftWidth === "number" ? `${props.borderLeftWidth}px` : props.borderLeftWidth};
104
+ border-left-color: ${props.borderLeftColor || props.borderColor || "transparent"};
105
+ border-left-style: solid;
106
+ `}
107
+ ${(props) => props.borderRightWidth !== void 0 && `
108
+ border-right-width: ${typeof props.borderRightWidth === "number" ? `${props.borderRightWidth}px` : props.borderRightWidth};
109
+ border-right-color: ${props.borderRightColor || props.borderColor || "transparent"};
110
+ border-right-style: solid;
111
+ `}
112
+
113
+ border-style: ${(props) => props.borderStyle || (props.borderWidth || props.borderBottomWidth || props.borderTopWidth || props.borderLeftWidth || props.borderRightWidth ? "solid" : "none")};
114
+ border-radius: ${(props) => typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius || 0};
115
+ height: ${(props) => typeof props.height === "number" ? `${props.height}px` : props.height || "auto"};
116
+ width: ${(props) => typeof props.width === "number" ? `${props.width}px` : props.width || "auto"};
117
+ min-width: ${(props) => typeof props.minWidth === "number" ? `${props.minWidth}px` : props.minWidth || "auto"};
118
+ min-height: ${(props) => typeof props.minHeight === "number" ? `${props.minHeight}px` : props.minHeight || "auto"};
119
+ max-width: ${(props) => typeof props.maxWidth === "number" ? `${props.maxWidth}px` : props.maxWidth || "none"};
120
+ max-height: ${(props) => typeof props.maxHeight === "number" ? `${props.maxHeight}px` : props.maxHeight || "none"};
121
+
122
+ padding: ${(props) => typeof props.padding === "number" ? `${props.padding}px` : props.padding || 0};
123
+ ${(props) => props.paddingHorizontal && `
124
+ padding-left: ${typeof props.paddingHorizontal === "number" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};
125
+ padding-right: ${typeof props.paddingHorizontal === "number" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};
126
+ `}
127
+ ${(props) => props.paddingVertical && `
128
+ padding-top: ${typeof props.paddingVertical === "number" ? `${props.paddingVertical}px` : props.paddingVertical};
129
+ padding-bottom: ${typeof props.paddingVertical === "number" ? `${props.paddingVertical}px` : props.paddingVertical};
130
+ `}
131
+ ${(props) => props.paddingTop !== void 0 && `padding-top: ${typeof props.paddingTop === "number" ? `${props.paddingTop}px` : props.paddingTop};`}
132
+ ${(props) => props.paddingBottom !== void 0 && `padding-bottom: ${typeof props.paddingBottom === "number" ? `${props.paddingBottom}px` : props.paddingBottom};`}
133
+ ${(props) => props.paddingLeft !== void 0 && `padding-left: ${typeof props.paddingLeft === "number" ? `${props.paddingLeft}px` : props.paddingLeft};`}
134
+ ${(props) => props.paddingRight !== void 0 && `padding-right: ${typeof props.paddingRight === "number" ? `${props.paddingRight}px` : props.paddingRight};`}
135
+
136
+ margin: ${(props) => typeof props.margin === "number" ? `${props.margin}px` : props.margin || 0};
137
+ ${(props) => props.marginTop !== void 0 && `margin-top: ${typeof props.marginTop === "number" ? `${props.marginTop}px` : props.marginTop};`}
138
+ ${(props) => props.marginBottom !== void 0 && `margin-bottom: ${typeof props.marginBottom === "number" ? `${props.marginBottom}px` : props.marginBottom};`}
139
+ ${(props) => props.marginLeft !== void 0 && `margin-left: ${typeof props.marginLeft === "number" ? `${props.marginLeft}px` : props.marginLeft};`}
140
+ ${(props) => props.marginRight !== void 0 && `margin-right: ${typeof props.marginRight === "number" ? `${props.marginRight}px` : props.marginRight};`}
141
+
142
+ flex-direction: ${(props) => props.flexDirection || "column"};
143
+ flex-wrap: ${(props) => props.flexWrap || "nowrap"};
144
+ align-items: ${(props) => props.alignItems || "stretch"};
145
+ justify-content: ${(props) => props.justifyContent || "flex-start"};
146
+ cursor: ${(props) => props.cursor ? props.cursor : props.onClick || props.onPress ? "pointer" : "inherit"};
147
+ position: ${(props) => props.position || "static"};
148
+ top: ${(props) => typeof props.top === "number" ? `${props.top}px` : props.top};
149
+ bottom: ${(props) => typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom};
150
+ left: ${(props) => typeof props.left === "number" ? `${props.left}px` : props.left};
151
+ right: ${(props) => typeof props.right === "number" ? `${props.right}px` : props.right};
152
+ flex: ${(props) => props.flex};
153
+ flex-shrink: ${(props) => props.flexShrink ?? 1};
154
+ gap: ${(props) => typeof props.gap === "number" ? `${props.gap}px` : props.gap || 0};
155
+ align-self: ${(props) => props.alignSelf || "auto"};
156
+ overflow: ${(props) => props.overflow || "visible"};
157
+ overflow-x: ${(props) => props.overflowX || "visible"};
158
+ overflow-y: ${(props) => props.overflowY || "visible"};
159
+ z-index: ${(props) => props.zIndex};
160
+ opacity: ${(props) => props.disabled ? 0.5 : 1};
161
+ pointer-events: ${(props) => props.disabled ? "none" : "auto"};
162
+
163
+ &:hover {
164
+ ${(props) => props.hoverStyle?.backgroundColor && `background-color: ${props.hoverStyle.backgroundColor};`}
165
+ ${(props) => props.hoverStyle?.borderColor && `border-color: ${props.hoverStyle.borderColor};`}
166
+ }
167
+
168
+ &:active {
169
+ ${(props) => props.pressStyle?.backgroundColor && `background-color: ${props.pressStyle.backgroundColor};`}
170
+ }
171
+ `;
172
+ var Box = React2.forwardRef(
173
+ ({
174
+ children,
175
+ onPress,
176
+ onKeyDown,
177
+ onKeyUp,
178
+ role,
179
+ "aria-label": ariaLabel,
180
+ "aria-labelledby": ariaLabelledBy,
181
+ "aria-current": ariaCurrent,
182
+ "aria-disabled": ariaDisabled,
183
+ "aria-live": ariaLive,
184
+ "aria-busy": ariaBusy,
185
+ "aria-describedby": ariaDescribedBy,
186
+ "aria-expanded": ariaExpanded,
187
+ "aria-haspopup": ariaHasPopup,
188
+ "aria-pressed": ariaPressed,
189
+ "aria-controls": ariaControls,
190
+ tabIndex,
191
+ as,
192
+ src,
193
+ alt,
194
+ onError,
195
+ onLoad,
196
+ type,
197
+ disabled,
198
+ id,
199
+ testID,
200
+ "data-testid": dataTestId,
201
+ ...props
202
+ }, ref) => {
203
+ if (as === "img" && src) {
204
+ return /* @__PURE__ */ jsx(
205
+ "img",
206
+ {
207
+ src,
208
+ alt: alt || "",
209
+ onError,
210
+ onLoad,
211
+ style: {
212
+ display: "block",
213
+ objectFit: "cover",
214
+ width: typeof props.width === "number" ? `${props.width}px` : props.width,
215
+ height: typeof props.height === "number" ? `${props.height}px` : props.height,
216
+ borderRadius: typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius,
217
+ position: props.position,
218
+ top: typeof props.top === "number" ? `${props.top}px` : props.top,
219
+ left: typeof props.left === "number" ? `${props.left}px` : props.left,
220
+ right: typeof props.right === "number" ? `${props.right}px` : props.right,
221
+ bottom: typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom,
222
+ ...props.style
223
+ }
224
+ }
225
+ );
226
+ }
227
+ return /* @__PURE__ */ jsx(
228
+ StyledBox,
229
+ {
230
+ ref,
231
+ elementType: as,
232
+ id,
233
+ type: as === "button" ? type || "button" : void 0,
234
+ disabled: as === "button" ? disabled : void 0,
235
+ onClick: onPress,
236
+ onKeyDown,
237
+ onKeyUp,
238
+ role,
239
+ "aria-label": ariaLabel,
240
+ "aria-labelledby": ariaLabelledBy,
241
+ "aria-current": ariaCurrent,
242
+ "aria-disabled": ariaDisabled,
243
+ "aria-busy": ariaBusy,
244
+ "aria-describedby": ariaDescribedBy,
245
+ "aria-expanded": ariaExpanded,
246
+ "aria-haspopup": ariaHasPopup,
247
+ "aria-pressed": ariaPressed,
248
+ "aria-controls": ariaControls,
249
+ "aria-live": ariaLive,
250
+ tabIndex: tabIndex !== void 0 ? tabIndex : void 0,
251
+ "data-testid": dataTestId || testID,
252
+ ...props,
253
+ children
254
+ }
255
+ );
256
+ }
257
+ );
258
+ Box.displayName = "Box";
259
+
260
+ // ../../foundation/primitives-web/src/Text.tsx
261
+ import styled2 from "styled-components";
262
+ import { jsx as jsx2 } from "react/jsx-runtime";
263
+ var FilteredSpan = createFilteredElement("span");
264
+ var StyledText = styled2(FilteredSpan)`
265
+ color: ${(props) => props.color || "inherit"};
266
+ font-size: ${(props) => typeof props.fontSize === "number" ? `${props.fontSize}px` : props.fontSize || "inherit"};
267
+ font-weight: ${(props) => props.fontWeight || "normal"};
268
+ font-family: ${(props) => props.fontFamily || '"Aktiv Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'};
269
+ line-height: ${(props) => typeof props.lineHeight === "number" ? `${props.lineHeight}px` : props.lineHeight || "inherit"};
270
+ white-space: ${(props) => props.whiteSpace || "normal"};
271
+ text-align: ${(props) => props.textAlign || "inherit"};
272
+ text-decoration: ${(props) => props.textDecoration || "none"};
273
+ `;
274
+ var Text = ({
275
+ style,
276
+ className,
277
+ id,
278
+ role,
279
+ testID,
280
+ "data-testid": dataTestId,
281
+ numberOfLines: _numberOfLines,
282
+ ...props
283
+ }) => {
284
+ return /* @__PURE__ */ jsx2(
285
+ StyledText,
286
+ {
287
+ ...props,
288
+ style,
289
+ className,
290
+ id,
291
+ role,
292
+ "data-testid": dataTestId || testID
293
+ }
294
+ );
295
+ };
296
+
297
+ // ../../foundation/primitives-web/src/Icon.tsx
298
+ import styled3 from "styled-components";
299
+ import { jsx as jsx3 } from "react/jsx-runtime";
300
+ var FilteredDiv2 = createFilteredElement("div");
301
+ var StyledIcon = styled3(FilteredDiv2)`
302
+ display: flex;
303
+ align-items: center;
304
+ justify-content: center;
305
+ width: ${(props) => typeof props.size === "number" ? `${props.size}px` : props.size || "24px"};
306
+ height: ${(props) => typeof props.size === "number" ? `${props.size}px` : props.size || "24px"};
307
+ color: ${(props) => props.color || "currentColor"};
308
+
309
+ svg {
310
+ width: 100%;
311
+ height: 100%;
312
+ fill: none;
313
+ stroke: currentColor;
314
+ }
315
+ `;
316
+ var Icon = ({
317
+ children,
318
+ testID,
319
+ "data-testid": dataTestId,
320
+ ...props
321
+ }) => {
322
+ return /* @__PURE__ */ jsx3(StyledIcon, { "data-testid": dataTestId || testID, ...props, children });
323
+ };
324
+
325
+ // ../../foundation/primitives-web/src/TextArea.tsx
326
+ import { forwardRef } from "react";
327
+ import styled4 from "styled-components";
328
+ import { jsx as jsx4 } from "react/jsx-runtime";
329
+ var FilteredTextArea = createFilteredElement("textarea");
330
+ var StyledTextArea = styled4(FilteredTextArea)`
331
+ background: transparent;
332
+ border: none;
333
+ outline: none;
334
+ width: 100%;
335
+ height: 100%;
336
+ padding: 0;
337
+ margin: 0;
338
+ color: ${(props) => props.color || "inherit"};
339
+ font-size: ${(props) => typeof props.fontSize === "number" ? `${props.fontSize}px` : props.fontSize || "inherit"};
340
+ font-family: ${(props) => props.fontFamily || '"Aktiv Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'};
341
+ text-align: inherit;
342
+ resize: none;
343
+
344
+ &::placeholder {
345
+ color: ${(props) => props.placeholderTextColor || "rgba(255, 255, 255, 0.5)"};
346
+ }
347
+
348
+ &:disabled {
349
+ cursor: not-allowed;
350
+ }
351
+ `;
352
+ var TextAreaPrimitive = forwardRef(
353
+ ({
354
+ value,
355
+ placeholder,
356
+ onChangeText,
357
+ onFocus,
358
+ onBlur,
359
+ onKeyDown,
360
+ disabled,
361
+ style,
362
+ color,
363
+ fontSize,
364
+ fontFamily,
365
+ placeholderTextColor,
366
+ maxLength,
367
+ rows,
368
+ testID,
369
+ "data-testid": dataTestId
370
+ }, ref) => {
371
+ return /* @__PURE__ */ jsx4(
372
+ StyledTextArea,
373
+ {
374
+ ref,
375
+ value,
376
+ placeholder,
377
+ onChange: (e) => onChangeText?.(e.target.value),
378
+ onFocus,
379
+ onBlur,
380
+ onKeyDown,
381
+ disabled,
382
+ style,
383
+ color,
384
+ fontSize,
385
+ fontFamily,
386
+ placeholderTextColor,
387
+ maxLength,
388
+ rows,
389
+ "data-testid": dataTestId || testID
390
+ }
391
+ );
392
+ }
393
+ );
394
+ TextAreaPrimitive.displayName = "TextAreaPrimitive";
395
+
396
+ // ../../foundation/primitives-web/src/index.tsx
397
+ var isWeb = true;
398
+
399
+ // src/InputEdit.tsx
400
+ import {
401
+ useResolvedTheme,
402
+ useId
403
+ } from "@xsolla/xui-core";
404
+ import { Edit, Check, Remove } from "@xsolla/xui-icons-base";
405
+ import { jsx as jsx5, jsxs } from "react/jsx-runtime";
406
+ var FIELD = {
407
+ fontSize: 16,
408
+ lineHeight: 18,
409
+ framePadding: 11,
410
+ iconSize: 16
411
+ };
412
+ var stripHtml = (html) => html.replace(/<[^>]*>/g, "").replace(/&nbsp;/gi, " ");
413
+ var CONTROL_ICON_SIZE = 18;
414
+ var POPOVER_SHADOW = "0px 6px 10px 4px rgba(7, 7, 8, 0.1), 0px 2px 3px 0px rgba(7, 7, 8, 0.2)";
415
+ var POPOVER_DROP_SHADOW = "drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))";
416
+ var InputEdit = forwardRef2(
417
+ ({
418
+ value,
419
+ defaultValue,
420
+ placeholder = "Placeholder",
421
+ onChangeText,
422
+ onConfirm,
423
+ onCancel,
424
+ onKeyDown,
425
+ editControl = true,
426
+ icon = true,
427
+ editIcon,
428
+ tools,
429
+ rows,
430
+ mode = "inline",
431
+ textStyle,
432
+ richText = false,
433
+ disabled = false,
434
+ error = false,
435
+ errorMessage,
436
+ id: providedId,
437
+ "aria-label": ariaLabel,
438
+ "aria-labelledby": ariaLabelledBy,
439
+ testID,
440
+ className,
441
+ themeMode,
442
+ themeProductContext,
443
+ ...rest
444
+ }, ref) => {
445
+ const { theme } = useResolvedTheme({ themeMode, themeProductContext });
446
+ const isControlled = value !== void 0;
447
+ const [internalValue, setInternalValue] = useState(
448
+ value ?? defaultValue ?? ""
449
+ );
450
+ const currentValue = isControlled ? value : internalValue;
451
+ const isFormMode = mode === "form";
452
+ const [isEditing, setIsEditing] = useState(false);
453
+ const editing = isFormMode || isEditing;
454
+ const [focused, setFocused] = useState(false);
455
+ const active = isFormMode ? focused : isEditing;
456
+ const richEnabled = richText && isWeb;
457
+ const inputRef = useRef(null);
458
+ const editableRef = useRef(null);
459
+ const focusField = () => {
460
+ if (richEnabled) editableRef.current?.focus();
461
+ else inputRef.current?.focus();
462
+ };
463
+ const committedValue = useRef(currentValue);
464
+ const [fieldHeight, setFieldHeight] = useState(null);
465
+ const rawId = useId();
466
+ const safeId = rawId.replace(/:/g, "");
467
+ const inputId = providedId || `input-edit-${safeId}`;
468
+ const errorId = `${inputId}-error`;
469
+ const triggerId = `${inputId}-trigger`;
470
+ const focusTrigger = () => {
471
+ if (isWeb) {
472
+ setTimeout(() => document.getElementById(triggerId)?.focus(), 0);
473
+ }
474
+ };
475
+ React3.useImperativeHandle(
476
+ ref,
477
+ () => richEnabled ? editableRef.current : inputRef.current,
478
+ [richEnabled]
479
+ );
480
+ useEffect(() => {
481
+ if (value !== void 0) {
482
+ setInternalValue(value);
483
+ committedValue.current = value;
484
+ }
485
+ }, [value]);
486
+ const autoSize = () => {
487
+ if (!isWeb) return;
488
+ if (richEnabled) {
489
+ requestAnimationFrame(() => {
490
+ const el2 = editableRef.current;
491
+ if (el2) setFieldHeight(el2.offsetHeight + FIELD.framePadding * 2);
492
+ });
493
+ return;
494
+ }
495
+ const el = inputRef.current;
496
+ if (!el) return;
497
+ el.style.height = "auto";
498
+ el.style.height = `${el.scrollHeight}px`;
499
+ setFieldHeight(el.scrollHeight + FIELD.framePadding * 2);
500
+ };
501
+ useEffect(() => {
502
+ if (!editing) return;
503
+ if (richEnabled) {
504
+ const el = editableRef.current;
505
+ if (el && el.innerHTML !== currentValue) el.innerHTML = currentValue;
506
+ }
507
+ autoSize();
508
+ }, [editing, currentValue, richEnabled]);
509
+ const isError = !!(error || errorMessage);
510
+ const isFilled = richText ? stripHtml(currentValue).trim().length > 0 : currentValue.length > 0;
511
+ const plainText = richText ? stripHtml(currentValue) : currentValue;
512
+ const inputColors = theme.colors.control.input;
513
+ const borderRadius = theme.shape.input.md.borderRadius;
514
+ const typo = theme.typographyTokens;
515
+ const textStyleToken = textStyle ? typo.heading[textStyle] ?? typo.basic[textStyle] : null;
516
+ const fontSize = textStyleToken ? textStyleToken.fontSize : FIELD.fontSize;
517
+ const lineHeight = textStyleToken ? parseInt(String(textStyleToken.lineHeight), 10) : FIELD.lineHeight;
518
+ const fontWeight = textStyleToken ? textStyleToken.fontWeight : 400;
519
+ const fontFamily = textStyleToken && textStyleToken.lineHeightCategory === "display" ? theme.fonts.heading : theme.fonts.body;
520
+ const controlsTop = (fieldHeight ?? lineHeight + FIELD.framePadding * 2) - FIELD.framePadding + 4;
521
+ const enterEdit = () => {
522
+ if (disabled || isEditing) return;
523
+ setIsEditing(true);
524
+ setTimeout(focusField, 0);
525
+ };
526
+ const handleRichInput = (e) => {
527
+ handleChangeText(e.currentTarget.innerHTML);
528
+ };
529
+ const handlePaste = (e) => {
530
+ e.preventDefault();
531
+ const text = e.clipboardData.getData("text/plain");
532
+ document.execCommand("insertText", false, text);
533
+ };
534
+ const handleChangeText = (next) => {
535
+ onChangeText?.(next);
536
+ if (!isControlled) {
537
+ setInternalValue(next);
538
+ }
539
+ };
540
+ const commitExplicit = () => {
541
+ onConfirm?.(currentValue);
542
+ committedValue.current = currentValue;
543
+ };
544
+ const commitOnBlur = () => {
545
+ if (currentValue !== committedValue.current) {
546
+ onConfirm?.(currentValue);
547
+ committedValue.current = currentValue;
548
+ }
549
+ };
550
+ const exitEdit = () => {
551
+ if (!isFormMode) {
552
+ setIsEditing(false);
553
+ setFocused(false);
554
+ focusTrigger();
555
+ }
556
+ };
557
+ const handleConfirm = () => {
558
+ commitExplicit();
559
+ exitEdit();
560
+ };
561
+ const handleCancel = () => {
562
+ if (!isControlled) {
563
+ setInternalValue(committedValue.current);
564
+ }
565
+ onCancel?.();
566
+ exitEdit();
567
+ };
568
+ const handleKeyDown = (e) => {
569
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
570
+ e.preventDefault();
571
+ handleConfirm();
572
+ return;
573
+ }
574
+ if (e.key === "Escape") {
575
+ e.preventDefault();
576
+ handleCancel();
577
+ return;
578
+ }
579
+ onKeyDown?.(e);
580
+ };
581
+ const handleFocus = () => setFocused(true);
582
+ const handleBlur = () => {
583
+ setFocused(false);
584
+ commitOnBlur();
585
+ if (!isFormMode) {
586
+ setIsEditing(false);
587
+ }
588
+ };
589
+ let fieldBg = "transparent";
590
+ let fieldBorder = "transparent";
591
+ if (disabled) {
592
+ fieldBg = inputColors.bgDisable;
593
+ fieldBorder = inputColors.borderDisable;
594
+ } else if (isError) {
595
+ fieldBg = inputColors.bg;
596
+ fieldBorder = theme.colors.border.alert;
597
+ } else if (active) {
598
+ fieldBg = theme.colors.control.focus.bg;
599
+ fieldBorder = theme.colors.border.brand;
600
+ } else if (isFormMode) {
601
+ fieldBg = inputColors.bg;
602
+ fieldBorder = inputColors.border;
603
+ }
604
+ const textColor = disabled ? inputColors.textDisable : inputColors.text;
605
+ const displayColor = isFilled ? textColor : inputColors.placeholder;
606
+ const preventBlur = isWeb ? { onMouseDown: (e) => e.preventDefault() } : {};
607
+ const controlBg = theme.colors.control.mono.primary.bg;
608
+ const controlBgHover = theme.colors.control.mono.primary.bgHover;
609
+ const controlIconColor = theme.colors.control.mono.text.primary;
610
+ const isTrigger = !editing && !disabled;
611
+ const triggerProps = isTrigger ? {
612
+ as: "button",
613
+ type: "button",
614
+ id: triggerId,
615
+ onPress: enterEdit,
616
+ "aria-label": ariaLabel,
617
+ "aria-labelledby": ariaLabelledBy
618
+ } : {
619
+ "aria-disabled": disabled || void 0
620
+ };
621
+ return /* @__PURE__ */ jsxs(
622
+ Box,
623
+ {
624
+ position: "relative",
625
+ width: "100%",
626
+ testID,
627
+ className,
628
+ children: [
629
+ /* @__PURE__ */ jsx5(Box, { position: "relative", width: "100%", style: { minHeight: lineHeight }, children: /* @__PURE__ */ jsxs(
630
+ Box,
631
+ {
632
+ ...triggerProps,
633
+ position: "absolute",
634
+ flexDirection: "row",
635
+ alignItems: editing || isError || disabled ? "flex-start" : "center",
636
+ gap: 8,
637
+ paddingVertical: FIELD.framePadding,
638
+ paddingHorizontal: FIELD.framePadding,
639
+ backgroundColor: fieldBg,
640
+ borderColor: fieldBorder,
641
+ borderWidth: 1,
642
+ cursor: disabled ? "not-allowed" : editing ? "text" : "pointer",
643
+ hoverStyle: !disabled && !editing && !isError ? {
644
+ backgroundColor: inputColors.bgHover,
645
+ borderColor: inputColors.borderHover
646
+ } : void 0,
647
+ style: {
648
+ // Pin top/left/right to the anchor (inflated outward); leave the bottom
649
+ // free so the field grows downward with multi-line content.
650
+ top: -FIELD.framePadding,
651
+ left: -FIELD.framePadding,
652
+ right: -FIELD.framePadding,
653
+ minHeight: lineHeight + FIELD.framePadding * 2,
654
+ borderRadius,
655
+ boxSizing: "border-box",
656
+ textAlign: "left",
657
+ width: "auto"
658
+ },
659
+ children: [
660
+ editing && richEnabled ? (
661
+ // Rich-text editor (web): a contenteditable surface holding HTML.
662
+ /* @__PURE__ */ jsxs(Box, { flex: 1, position: "relative", children: [
663
+ !isFilled && /* @__PURE__ */ jsx5(
664
+ Text,
665
+ {
666
+ "aria-hidden": true,
667
+ color: inputColors.placeholder,
668
+ fontSize,
669
+ fontWeight: String(fontWeight),
670
+ style: {
671
+ position: "absolute",
672
+ top: 0,
673
+ left: 0,
674
+ fontFamily,
675
+ lineHeight: `${lineHeight}px`,
676
+ pointerEvents: "none"
677
+ },
678
+ children: placeholder
679
+ }
680
+ ),
681
+ /* @__PURE__ */ jsx5(
682
+ "div",
683
+ {
684
+ ref: editableRef,
685
+ id: inputId,
686
+ contentEditable: !disabled,
687
+ suppressContentEditableWarning: true,
688
+ role: "textbox",
689
+ "aria-multiline": "true",
690
+ "aria-label": ariaLabel,
691
+ "aria-labelledby": ariaLabelledBy,
692
+ "aria-invalid": isError || void 0,
693
+ "aria-describedby": errorMessage ? errorId : void 0,
694
+ "data-testid": "input-edit__field",
695
+ onInput: handleRichInput,
696
+ onFocus: handleFocus,
697
+ onBlur: handleBlur,
698
+ onKeyDown: handleKeyDown,
699
+ onPaste: handlePaste,
700
+ style: {
701
+ outline: "none",
702
+ minHeight: `${lineHeight}px`,
703
+ color: textColor,
704
+ fontFamily,
705
+ fontWeight,
706
+ fontSize: `${fontSize}px`,
707
+ lineHeight: `${lineHeight}px`,
708
+ whiteSpace: "pre-wrap",
709
+ wordBreak: "break-word"
710
+ }
711
+ }
712
+ )
713
+ ] })
714
+ ) : editing ? /* @__PURE__ */ jsx5(Box, { flex: 1, children: /* @__PURE__ */ jsx5(
715
+ TextAreaPrimitive,
716
+ {
717
+ ref: inputRef,
718
+ id: inputId,
719
+ value: plainText,
720
+ placeholder,
721
+ onChangeText: handleChangeText,
722
+ onFocus: handleFocus,
723
+ onBlur: handleBlur,
724
+ onKeyDown: handleKeyDown,
725
+ disabled,
726
+ rows: rows ?? 1,
727
+ color: textColor,
728
+ fontSize,
729
+ fontFamily,
730
+ placeholderTextColor: inputColors.placeholder,
731
+ "aria-invalid": isError || void 0,
732
+ "aria-describedby": errorMessage ? errorId : void 0,
733
+ "aria-label": ariaLabel,
734
+ "aria-labelledby": ariaLabelledBy,
735
+ "data-testid": "input-edit__field",
736
+ style: {
737
+ display: "block",
738
+ overflow: "hidden",
739
+ fontWeight,
740
+ lineHeight: `${lineHeight}px`
741
+ },
742
+ ...rest
743
+ }
744
+ ) }) : richText && isWeb && isFilled ? (
745
+ // Rich display (read-only): render the stored HTML.
746
+ /* @__PURE__ */ jsx5(
747
+ "div",
748
+ {
749
+ "data-testid": "input-edit__text",
750
+ dangerouslySetInnerHTML: { __html: currentValue },
751
+ style: {
752
+ flex: 1,
753
+ color: textColor,
754
+ fontFamily,
755
+ fontWeight,
756
+ fontSize: `${fontSize}px`,
757
+ lineHeight: `${lineHeight}px`,
758
+ whiteSpace: "pre-wrap",
759
+ wordBreak: "break-word"
760
+ }
761
+ }
762
+ )
763
+ ) : /* @__PURE__ */ jsx5(
764
+ Text,
765
+ {
766
+ color: displayColor,
767
+ fontSize,
768
+ fontWeight: String(fontWeight),
769
+ "data-testid": "input-edit__text",
770
+ style: {
771
+ flex: 1,
772
+ fontFamily,
773
+ lineHeight: `${lineHeight}px`,
774
+ wordBreak: "break-word",
775
+ // Preserve author line breaks in multi-line values.
776
+ whiteSpace: "pre-wrap"
777
+ },
778
+ children: isFilled ? plainText : placeholder
779
+ }
780
+ ),
781
+ icon && !editing && !isError && !disabled && /* @__PURE__ */ jsx5(Box, { alignItems: "center", justifyContent: "center", "aria-hidden": true, children: /* @__PURE__ */ jsx5(Icon, { size: FIELD.iconSize, color: textColor, children: editIcon ?? /* @__PURE__ */ jsx5(Edit, {}) }) })
782
+ ]
783
+ }
784
+ ) }),
785
+ active && editControl && /* @__PURE__ */ jsxs(
786
+ Box,
787
+ {
788
+ position: "absolute",
789
+ flexDirection: "row",
790
+ alignItems: "center",
791
+ backgroundColor: controlBg,
792
+ "data-testid": "input-edit__edit-control",
793
+ style: {
794
+ top: controlsTop,
795
+ right: -FIELD.framePadding,
796
+ borderRadius: 4,
797
+ overflow: "hidden",
798
+ ...isWeb ? {
799
+ boxShadow: POPOVER_SHADOW,
800
+ backdropFilter: "blur(12px)",
801
+ WebkitBackdropFilter: "blur(12px)"
802
+ } : {}
803
+ },
804
+ children: [
805
+ /* @__PURE__ */ jsx5(
806
+ Box,
807
+ {
808
+ as: "button",
809
+ type: "button",
810
+ alignItems: "center",
811
+ justifyContent: "center",
812
+ backgroundColor: controlBg,
813
+ borderWidth: 0,
814
+ padding: 4,
815
+ cursor: "pointer",
816
+ onPress: handleConfirm,
817
+ "aria-label": "Confirm",
818
+ "data-testid": "input-edit__confirm",
819
+ hoverStyle: { backgroundColor: controlBgHover },
820
+ ...preventBlur,
821
+ children: /* @__PURE__ */ jsx5(Icon, { size: CONTROL_ICON_SIZE, color: controlIconColor, children: /* @__PURE__ */ jsx5(Check, {}) })
822
+ }
823
+ ),
824
+ /* @__PURE__ */ jsx5(
825
+ Box,
826
+ {
827
+ backgroundColor: theme.colors.border.inverse,
828
+ style: { width: 1, alignSelf: "stretch" }
829
+ }
830
+ ),
831
+ /* @__PURE__ */ jsx5(
832
+ Box,
833
+ {
834
+ as: "button",
835
+ type: "button",
836
+ alignItems: "center",
837
+ justifyContent: "center",
838
+ backgroundColor: controlBg,
839
+ borderWidth: 0,
840
+ padding: 4,
841
+ cursor: "pointer",
842
+ onPress: handleCancel,
843
+ "aria-label": "Cancel",
844
+ "data-testid": "input-edit__cancel",
845
+ hoverStyle: { backgroundColor: controlBgHover },
846
+ ...preventBlur,
847
+ children: /* @__PURE__ */ jsx5(Icon, { size: CONTROL_ICON_SIZE, color: controlIconColor, children: /* @__PURE__ */ jsx5(Remove, {}) })
848
+ }
849
+ )
850
+ ]
851
+ }
852
+ ),
853
+ active && tools && /* @__PURE__ */ jsx5(
854
+ Box,
855
+ {
856
+ position: "absolute",
857
+ flexDirection: "row",
858
+ alignItems: "center",
859
+ gap: 4,
860
+ padding: 4,
861
+ backgroundColor: theme.colors.background.primary,
862
+ "data-testid": "input-edit__tools",
863
+ style: {
864
+ top: controlsTop,
865
+ left: -FIELD.framePadding,
866
+ borderRadius: 4,
867
+ ...isWeb ? {
868
+ boxShadow: POPOVER_SHADOW,
869
+ backdropFilter: "blur(12px)",
870
+ WebkitBackdropFilter: "blur(12px)"
871
+ } : {}
872
+ },
873
+ ...preventBlur,
874
+ children: tools
875
+ }
876
+ ),
877
+ isError && errorMessage && /* @__PURE__ */ jsxs(
878
+ Box,
879
+ {
880
+ position: "relative",
881
+ style: {
882
+ marginTop: FIELD.framePadding + 4,
883
+ width: "max-content",
884
+ maxWidth: "100%",
885
+ ...isWeb ? {
886
+ filter: POPOVER_DROP_SHADOW,
887
+ WebkitFilter: POPOVER_DROP_SHADOW
888
+ } : {}
889
+ },
890
+ children: [
891
+ /* @__PURE__ */ jsx5(
892
+ Box,
893
+ {
894
+ position: "absolute",
895
+ backgroundColor: theme.colors.background.primary,
896
+ style: {
897
+ width: 8,
898
+ height: 8,
899
+ top: -3,
900
+ left: 16,
901
+ transform: "rotate(45deg)"
902
+ }
903
+ }
904
+ ),
905
+ /* @__PURE__ */ jsx5(
906
+ Box,
907
+ {
908
+ backgroundColor: theme.colors.background.primary,
909
+ paddingVertical: 8,
910
+ paddingHorizontal: 12,
911
+ style: {
912
+ borderRadius: 4,
913
+ ...isWeb ? {
914
+ backdropFilter: "blur(12px)",
915
+ WebkitBackdropFilter: "blur(12px)"
916
+ } : {}
917
+ },
918
+ children: /* @__PURE__ */ jsx5(
919
+ Text,
920
+ {
921
+ id: errorId,
922
+ role: "status",
923
+ "aria-live": "polite",
924
+ color: theme.colors.content.alert.primary,
925
+ fontSize: FIELD.fontSize - 2,
926
+ style: { lineHeight: `${FIELD.lineHeight}px` },
927
+ children: errorMessage
928
+ }
929
+ )
930
+ }
931
+ )
932
+ ]
933
+ }
934
+ )
935
+ ]
936
+ }
937
+ );
938
+ }
939
+ );
940
+ InputEdit.displayName = "InputEdit";
941
+ export {
942
+ InputEdit
943
+ };
944
+ //# sourceMappingURL=index.mjs.map