@xsolla/xui-input-edit 0.198.0 → 0.200.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/native/index.js CHANGED
@@ -40,6 +40,38 @@ var import_react3 = __toESM(require("react"));
40
40
  // ../../foundation/primitives-native/src/Box.tsx
41
41
  var import_react_native = require("react-native");
42
42
  var import_jsx_runtime = require("react/jsx-runtime");
43
+ var roleToAccessibilityRole = {
44
+ button: "button",
45
+ link: "link",
46
+ img: "image",
47
+ image: "image",
48
+ summary: "summary",
49
+ switch: "switch",
50
+ checkbox: "checkbox",
51
+ radio: "radio",
52
+ heading: "header",
53
+ text: "text",
54
+ search: "search",
55
+ alert: "alert",
56
+ none: "none",
57
+ presentation: "none",
58
+ progressbar: "progressbar",
59
+ scrollbar: "scrollbar",
60
+ adjustable: "adjustable",
61
+ tab: "tab",
62
+ menu: "menu",
63
+ menuitem: "menuitem",
64
+ list: "list",
65
+ timer: "timer"
66
+ };
67
+ var toGapValue = (gap) => {
68
+ if (gap === void 0) return void 0;
69
+ if (typeof gap === "number") return gap;
70
+ const pxMatch = /^(\d+(?:\.\d+)?)px$/.exec(gap);
71
+ if (pxMatch) return Number(pxMatch[1]);
72
+ const asNumber = Number(gap);
73
+ return Number.isFinite(asNumber) ? asNumber : void 0;
74
+ };
43
75
  var Box = ({
44
76
  children,
45
77
  onPress,
@@ -72,8 +104,10 @@ var Box = ({
72
104
  marginLeft,
73
105
  marginRight,
74
106
  flexDirection,
107
+ flexWrap,
75
108
  alignItems,
76
109
  justifyContent,
110
+ alignSelf,
77
111
  position,
78
112
  top,
79
113
  bottom,
@@ -85,11 +119,14 @@ var Box = ({
85
119
  maxWidth,
86
120
  maxHeight,
87
121
  flex,
122
+ flexShrink,
123
+ gap,
88
124
  overflow,
89
125
  zIndex,
90
126
  hoverStyle,
91
127
  pressStyle,
92
128
  style,
129
+ disabled,
93
130
  "data-testid": dataTestId,
94
131
  testID,
95
132
  as,
@@ -128,14 +165,18 @@ var Box = ({
128
165
  marginLeft,
129
166
  marginRight,
130
167
  flexDirection,
168
+ flexWrap,
131
169
  alignItems,
132
170
  justifyContent,
171
+ alignSelf,
133
172
  position,
134
173
  top,
135
174
  bottom,
136
175
  left,
137
176
  right,
138
177
  flex,
178
+ flexShrink,
179
+ gap: toGapValue(gap),
139
180
  ...style
140
181
  });
141
182
  const finalTestID = dataTestId || testID;
@@ -144,15 +185,25 @@ var Box = ({
144
185
  tabIndex,
145
186
  onKeyDown,
146
187
  onKeyUp,
147
- "aria-label": _ariaLabel,
188
+ "aria-label": ariaLabel,
148
189
  "aria-labelledby": _ariaLabelledBy,
149
190
  "aria-current": _ariaCurrent,
150
- "aria-disabled": _ariaDisabled,
151
- "aria-live": _ariaLive,
191
+ "aria-disabled": ariaDisabled,
192
+ "aria-live": ariaLive,
193
+ "aria-busy": ariaBusy,
152
194
  className,
153
195
  "data-testid": _dataTestId,
196
+ cursor: _cursor,
197
+ type: _type,
154
198
  ...nativeRest
155
199
  } = rest;
200
+ const accessibilityRole = typeof role === "string" && roleToAccessibilityRole[role] || (as === "button" ? "button" : void 0);
201
+ const isDisabled = Boolean(disabled || ariaDisabled);
202
+ const accessibilityState = {
203
+ disabled: isDisabled || void 0,
204
+ busy: Boolean(ariaBusy) || void 0
205
+ };
206
+ const accessibilityLiveRegion = ariaLive === "polite" || ariaLive === "assertive" ? ariaLive : void 0;
156
207
  if (as === "img" && src) {
157
208
  const imageStyle = {
158
209
  width,
@@ -171,16 +222,18 @@ var Box = ({
171
222
  source: { uri: src },
172
223
  style: imageStyle,
173
224
  testID: finalTestID,
225
+ accessibilityLabel: typeof ariaLabel === "string" ? ariaLabel : alt,
174
226
  resizeMode: "cover",
175
227
  ...nativeRest
176
228
  }
177
229
  );
178
230
  }
179
- if (onPress) {
231
+ if (onPress || as === "button") {
180
232
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
181
233
  import_react_native.Pressable,
182
234
  {
183
- onPress,
235
+ onPress: !isDisabled && onPress ? onPress : void 0,
236
+ disabled: isDisabled,
184
237
  onLayout,
185
238
  onMoveShouldSetResponder,
186
239
  onResponderGrant,
@@ -189,6 +242,10 @@ var Box = ({
189
242
  onResponderTerminate,
190
243
  style: ({ pressed }) => getContainerStyle(pressed),
191
244
  testID: finalTestID,
245
+ accessibilityRole,
246
+ accessibilityLabel: typeof ariaLabel === "string" ? ariaLabel : void 0,
247
+ accessibilityState,
248
+ accessibilityLiveRegion,
192
249
  ...nativeRest,
193
250
  children
194
251
  }
@@ -205,6 +262,10 @@ var Box = ({
205
262
  onResponderMove,
206
263
  onResponderRelease,
207
264
  onResponderTerminate,
265
+ accessibilityRole,
266
+ accessibilityLabel: typeof ariaLabel === "string" ? ariaLabel : void 0,
267
+ accessibilityState,
268
+ accessibilityLiveRegion,
208
269
  ...nativeRest,
209
270
  children
210
271
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../src/InputEdit.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/TextArea.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["export * from \"./InputEdit\";\n","import React, {\n useState,\n useRef,\n useEffect,\n forwardRef,\n type TextareaHTMLAttributes,\n type ReactNode,\n} from \"react\";\n// prettier-ignore\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, TextAreaPrimitive, isWeb } from \"@xsolla/xui-primitives\";\nimport {\n useResolvedTheme,\n useId,\n type ThemeOverrideProps,\n} from \"@xsolla/xui-core\";\nimport { Edit, Check, Remove } from \"@xsolla/xui-icons-base\";\n\ntype InputEditMode = \"inline\" | \"form\";\n\n/**\n * Named typography styles, resolved from the theme's typography tokens. Drives the\n * field's font family / size / weight / line-height so the text can match surrounding\n * content (e.g. a heading) rather than only the fixed body sizes.\n */\ntype InputEditTextStyle =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"display\"\n | \"body-lg\"\n | \"body-md\"\n | \"body-sm\"\n | \"body-xs\"\n | \"body-xxs\";\n\nexport interface InputEditProps\n extends\n Omit<\n TextareaHTMLAttributes<HTMLTextAreaElement>,\n \"size\" | \"onChange\" | \"value\" | \"defaultValue\"\n >,\n ThemeOverrideProps {\n /**\n * Controlled value of the field.\n */\n value?: string;\n /**\n * Initial value for uncontrolled usage.\n */\n defaultValue?: string;\n /**\n * Placeholder shown when the field is empty.\n */\n placeholder?: string;\n /**\n * Change handler receiving the current text (HTML when `richText` is set).\n */\n onChangeText?: (text: string) => void;\n /**\n * Called when the edit is confirmed (check button or `Cmd`/`Ctrl` + `Enter`).\n */\n onConfirm?: (value: string) => void;\n /**\n * Called when the edit is cancelled (cross button or `Escape`). The value is reverted.\n */\n onCancel?: () => void;\n /**\n * Minimum number of visible text rows while editing.\n */\n rows?: number;\n /**\n * Show the floating confirm / cancel control while editing.\n */\n editControl?: boolean;\n /**\n * Show the edit affordance icon in display mode.\n */\n icon?: boolean;\n /**\n * Override the default edit (pencil) icon.\n */\n editIcon?: ReactNode;\n /**\n * Optional formatting toolbar shown in a floating bar below the field while editing\n * (e.g. text-align / bold / link `IconButton`s). Rendered to the left, mirroring the\n * confirm / cancel control on the right.\n */\n tools?: ReactNode;\n /**\n * Activation mode. `\"inline\"` (default) rests as plain text and reveals the editor on\n * click; `\"form\"` is always an open, editable field (like a standard form text area).\n */\n mode?: InputEditMode;\n /**\n * Named typography style applied to the text and editor (e.g. `\"h1\"`, `\"body-lg\"`).\n * Overrides the default font.\n */\n textStyle?: InputEditTextStyle;\n /**\n * Enable rich-text editing (web only). The field becomes a `contenteditable` surface\n * and `value` / `onChangeText` / `onConfirm` carry HTML. Wire a toolbar via `tools`\n * using `document.execCommand`. Falls back to a plain text field on React Native.\n * The HTML is not sanitized — sanitize before rendering untrusted values.\n */\n richText?: boolean;\n /**\n * Disable the control.\n */\n disabled?: boolean;\n /**\n * Highlight the control as invalid.\n */\n error?: boolean;\n /**\n * Error message displayed below the field (implies `error`).\n */\n errorMessage?: string;\n /**\n * Unique identifier for the input element. Used for accessibility linking.\n */\n id?: string;\n /**\n * Accessible label for screen readers (use when no visible label is present).\n */\n \"aria-label\"?: string;\n /**\n * ID of an external element that labels the field (e.g. a heading placed above it).\n */\n \"aria-labelledby\"?: string;\n testID?: string;\n /**\n * Optional class name applied to the root element (web).\n */\n className?: string;\n}\n\n// InputEdit has a single size (per the design). `textStyle` can still override the font.\nconst FIELD = {\n fontSize: 16,\n lineHeight: 18,\n framePadding: 11,\n iconSize: 16,\n};\n\n// Strip tags from an HTML value — used for empty detection and the native plain-text\n// fallback (React Native can't render contenteditable HTML inline).\nconst stripHtml = (html: string): string =>\n html.replace(/<[^>]*>/g, \"\").replace(/&nbsp;/gi, \" \");\n\nconst CONTROL_ICON_SIZE = 18;\nconst POPOVER_SHADOW =\n \"0px 6px 10px 4px rgba(7, 7, 8, 0.1), 0px 2px 3px 0px rgba(7, 7, 8, 0.2)\";\n// drop-shadow variant — follows the element's alpha shape so it wraps the bubble's\n// pointer (a plain box-shadow would clip at the rectangle edge).\nconst POPOVER_DROP_SHADOW =\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\";\n\n/**\n * A multi-line text field for editing freeform text. In `\"inline\"` mode it rests as\n * plain text and reveals a highlighted editor on click; in `\"form\"` mode it is always\n * an open, editable field. `Enter` inserts a new line; confirm via the floating control\n * or `Cmd`/`Ctrl` + `Enter`; clicking outside also commits. `Escape` cancels and\n * reverts.\n */\nexport const InputEdit = forwardRef<\n HTMLTextAreaElement | HTMLDivElement,\n InputEditProps\n>(\n (\n {\n value,\n defaultValue,\n placeholder = \"Placeholder\",\n onChangeText,\n onConfirm,\n onCancel,\n onKeyDown,\n editControl = true,\n icon = true,\n editIcon,\n tools,\n rows,\n mode = \"inline\",\n textStyle,\n richText = false,\n disabled = false,\n error = false,\n errorMessage,\n id: providedId,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n testID,\n className,\n themeMode,\n themeProductContext,\n ...rest\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(\n value ?? defaultValue ?? \"\"\n );\n const currentValue = isControlled ? (value as string) : internalValue;\n\n const isFormMode = mode === \"form\";\n // In form mode the editor is always rendered; in inline mode it appears on activation.\n const [isEditing, setIsEditing] = useState(false);\n const editing = isFormMode || isEditing;\n // Whether the editor currently holds focus — gates the floating controls so a form\n // with several fields doesn't show controls on every one at rest.\n const [focused, setFocused] = useState(false);\n // The \"active\" (focus-styled, controls-visible) state. Inline mode keys off the edit\n // session (controls appear the moment you click, before focus lands); form mode keys\n // off real focus (so resting fields stay quiet).\n const active = isFormMode ? focused : isEditing;\n // Rich text only applies on web (contenteditable is DOM-only); native falls back to\n // the plain textarea.\n const richEnabled = richText && isWeb;\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const editableRef = useRef<HTMLDivElement>(null);\n const focusField = () => {\n if (richEnabled) editableRef.current?.focus();\n else inputRef.current?.focus();\n };\n // Last value reported via onConfirm (or the initial value) — used to dedupe commits\n // and to revert on cancel.\n const committedValue = useRef(currentValue);\n // Measured height of the field box, so the floating controls follow it as the\n // multi-line field grows.\n const [fieldHeight, setFieldHeight] = useState<number | null>(null);\n\n // Generate a unique, ARIA-safe id (useId() yields colons that are invalid in id attrs).\n const rawId = useId();\n const safeId = rawId.replace(/:/g, \"\");\n const inputId = providedId || `input-edit-${safeId}`;\n const errorId = `${inputId}-error`;\n const triggerId = `${inputId}-trigger`;\n\n // Return focus to the display trigger so keyboard users are not dropped to the body.\n const focusTrigger = () => {\n if (isWeb) {\n setTimeout(() => document.getElementById(triggerId)?.focus(), 0);\n }\n };\n\n // In rich mode the underlying element is the contenteditable div, not a textarea —\n // exposed honestly so consumers don't read `.value` off a div.\n React.useImperativeHandle(\n ref,\n () =>\n (richEnabled ? editableRef.current : inputRef.current) as\n | HTMLTextAreaElement\n | HTMLDivElement,\n [richEnabled]\n );\n\n // Keep internal value in sync with the controlled value. An externally-set value is\n // treated as the committed baseline.\n useEffect(() => {\n if (value !== undefined) {\n setInternalValue(value);\n committedValue.current = value;\n }\n }, [value]);\n\n // Auto-grow the field to fit its content (multi-line), so the height tracks the text\n // without an inner scrollbar. The contenteditable div grows on its own; the textarea\n // needs its height reset and re-measured.\n const autoSize = () => {\n if (!isWeb) return;\n if (richEnabled) {\n // innerHTML is set imperatively just before this runs, so the div hasn't been\n // laid out yet — measure after the next paint or the height is stale on entry.\n requestAnimationFrame(() => {\n const el = editableRef.current;\n if (el) setFieldHeight(el.offsetHeight + FIELD.framePadding * 2);\n });\n return;\n }\n const el = inputRef.current;\n if (!el) return;\n el.style.height = \"auto\";\n el.style.height = `${el.scrollHeight}px`;\n setFieldHeight(el.scrollHeight + FIELD.framePadding * 2);\n };\n\n useEffect(() => {\n if (!editing) return;\n // Controlled contenteditable: write innerHTML only when the incoming value differs\n // from the DOM, so echoing our own input doesn't reset the caret.\n if (richEnabled) {\n const el = editableRef.current;\n if (el && el.innerHTML !== currentValue) el.innerHTML = currentValue;\n }\n autoSize();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editing, currentValue, richEnabled]);\n\n const isError = !!(error || errorMessage);\n // For rich values, \"empty\" means no visible text once tags are stripped.\n const isFilled = richText\n ? stripHtml(currentValue).trim().length > 0\n : currentValue.length > 0;\n // Plain-text projection of the value — used by the textarea and the native fallback.\n const plainText = richText ? stripHtml(currentValue) : currentValue;\n const inputColors = theme.colors.control.input;\n const borderRadius = theme.shape.input.md.borderRadius;\n\n // Resolve effective typography: a named textStyle (heading/body token) overrides the\n // size-derived font. Padding / icon size always come from `size`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const typo = theme.typographyTokens as any;\n const textStyleToken = textStyle\n ? (typo.heading[textStyle] ?? typo.basic[textStyle])\n : null;\n const fontSize = textStyleToken ? textStyleToken.fontSize : FIELD.fontSize;\n const lineHeight = textStyleToken\n ? parseInt(String(textStyleToken.lineHeight), 10)\n : FIELD.lineHeight;\n const fontWeight = textStyleToken ? textStyleToken.fontWeight : 400;\n const fontFamily =\n textStyleToken && textStyleToken.lineHeightCategory === \"display\"\n ? theme.fonts.heading\n : theme.fonts.body;\n\n // Vertical offset for the floating controls — just below the field's bottom edge.\n // Defaults to the single-line height before the field has been measured.\n const controlsTop =\n (fieldHeight ?? lineHeight + FIELD.framePadding * 2) -\n FIELD.framePadding +\n 4;\n\n const enterEdit = () => {\n if (disabled || isEditing) return;\n setIsEditing(true);\n // Focus the field once it has mounted.\n setTimeout(focusField, 0);\n };\n\n // Rich-text input: read the contenteditable's HTML on each edit.\n const handleRichInput = (e: React.FormEvent<HTMLDivElement>) => {\n handleChangeText(e.currentTarget.innerHTML);\n };\n\n // Paste as plain text to avoid importing foreign markup/styles (no sanitizer here).\n const handlePaste = (e: React.ClipboardEvent<HTMLDivElement>) => {\n e.preventDefault();\n const text = e.clipboardData.getData(\"text/plain\");\n document.execCommand(\"insertText\", false, text);\n };\n\n const handleChangeText = (next: string) => {\n onChangeText?.(next);\n if (!isControlled) {\n setInternalValue(next);\n }\n };\n\n // Explicit confirm (button / shortcut) always reports the value — it is a deliberate\n // save action.\n const commitExplicit = () => {\n onConfirm?.(currentValue);\n committedValue.current = currentValue;\n };\n\n // Commit on blur only when the value actually changed, so clicking in and out (or a\n // confirm immediately followed by the unmount blur) doesn't re-fire onConfirm.\n const commitOnBlur = () => {\n if (currentValue !== committedValue.current) {\n onConfirm?.(currentValue);\n committedValue.current = currentValue;\n }\n };\n\n // Inline mode collapses back to the plain-text display; form mode stays open.\n const exitEdit = () => {\n if (!isFormMode) {\n setIsEditing(false);\n setFocused(false);\n focusTrigger();\n }\n };\n\n const handleConfirm = () => {\n commitExplicit();\n exitEdit();\n };\n\n const handleCancel = () => {\n // Revert to the last committed value.\n if (!isControlled) {\n setInternalValue(committedValue.current);\n }\n onCancel?.();\n exitEdit();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {\n // Enter inserts a new line (multi-line). Confirm with Cmd/Ctrl + Enter.\n // These gestures are consumed by the component (use onConfirm / onCancel), so the\n // forwarded onKeyDown does not also fire for them.\n if (e.key === \"Enter\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n handleConfirm();\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n handleCancel();\n return;\n }\n onKeyDown?.(e as React.KeyboardEvent<HTMLTextAreaElement>);\n };\n\n const handleFocus = () => setFocused(true);\n\n // Clicking outside commits the current value. Control / tool buttons prevent blur\n // via onMouseDown, so they fire their own action instead of committing here.\n const handleBlur = () => {\n setFocused(false);\n commitOnBlur();\n if (!isFormMode) {\n setIsEditing(false);\n }\n };\n\n // Resolve background / border colors based on state. Error takes precedence over\n // the focus state — per Figma the error variant keeps the input bg, not the focus\n // bg. A resting form-mode field looks like a standard input; a resting inline field\n // is transparent so it blends with surrounding content.\n let fieldBg = \"transparent\";\n let fieldBorder = \"transparent\";\n if (disabled) {\n fieldBg = inputColors.bgDisable;\n fieldBorder = inputColors.borderDisable;\n } else if (isError) {\n fieldBg = inputColors.bg;\n fieldBorder = theme.colors.border.alert;\n } else if (active) {\n fieldBg = theme.colors.control.focus.bg;\n fieldBorder = theme.colors.border.brand;\n } else if (isFormMode) {\n fieldBg = inputColors.bg;\n fieldBorder = inputColors.border;\n }\n\n const textColor = disabled ? inputColors.textDisable : inputColors.text;\n const displayColor = isFilled ? textColor : inputColors.placeholder;\n\n const preventBlur = isWeb\n ? { onMouseDown: (e: React.MouseEvent) => e.preventDefault() }\n : {};\n\n // Edit control uses the high-contrast \"mono primary\" surface (inverts per theme).\n const controlBg = theme.colors.control.mono.primary.bg;\n const controlBgHover = theme.colors.control.mono.primary.bgHover;\n const controlIconColor = theme.colors.control.mono.text.primary;\n\n // In inline display mode the field is an interactive trigger: render it as a real\n // button so it is focusable and activatable with Enter / Space by keyboard users.\n // In form mode the editor is always present, so there is no trigger.\n const isTrigger = !editing && !disabled;\n const triggerProps = isTrigger\n ? {\n as: \"button\" as const,\n type: \"button\" as const,\n id: triggerId,\n onPress: enterEdit,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n }\n : {\n \"aria-disabled\": disabled || undefined,\n };\n\n return (\n <Box\n position=\"relative\"\n width=\"100%\"\n testID={testID}\n className={className}\n >\n {/* Inline anchor — sized to a single text line so the field aligns with surrounding content. */}\n <Box position=\"relative\" width=\"100%\" style={{ minHeight: lineHeight }}>\n {/* Field layer — expands outward (negative inset) so the hover/focus highlight\n does not shift the inline text. */}\n <Box\n {...triggerProps}\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems={\n editing || isError || disabled ? \"flex-start\" : \"center\"\n }\n gap={8}\n paddingVertical={FIELD.framePadding}\n paddingHorizontal={FIELD.framePadding}\n backgroundColor={fieldBg}\n borderColor={fieldBorder}\n borderWidth={1}\n cursor={disabled ? \"not-allowed\" : editing ? \"text\" : \"pointer\"}\n hoverStyle={\n !disabled && !editing && !isError\n ? {\n backgroundColor: inputColors.bgHover,\n borderColor: inputColors.borderHover,\n }\n : undefined\n }\n style={{\n // Pin top/left/right to the anchor (inflated outward); leave the bottom\n // free so the field grows downward with multi-line content.\n top: -FIELD.framePadding,\n left: -FIELD.framePadding,\n right: -FIELD.framePadding,\n minHeight: lineHeight + FIELD.framePadding * 2,\n borderRadius,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n width: \"auto\",\n }}\n >\n {editing && richEnabled ? (\n // Rich-text editor (web): a contenteditable surface holding HTML.\n <Box flex={1} position=\"relative\">\n {!isFilled && (\n <Text\n aria-hidden\n color={inputColors.placeholder}\n fontSize={fontSize}\n fontWeight={String(fontWeight)}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n fontFamily,\n lineHeight: `${lineHeight}px`,\n pointerEvents: \"none\",\n }}\n >\n {placeholder}\n </Text>\n )}\n <div\n ref={editableRef}\n id={inputId}\n contentEditable={!disabled}\n suppressContentEditableWarning\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-invalid={isError || undefined}\n aria-describedby={errorMessage ? errorId : undefined}\n data-testid=\"input-edit__field\"\n onInput={handleRichInput}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n style={{\n outline: \"none\",\n minHeight: `${lineHeight}px`,\n color: textColor,\n fontFamily,\n fontWeight,\n fontSize: `${fontSize}px`,\n lineHeight: `${lineHeight}px`,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n />\n </Box>\n ) : editing ? (\n <Box flex={1}>\n <TextAreaPrimitive\n ref={inputRef}\n id={inputId}\n value={plainText}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n rows={rows ?? 1}\n color={textColor}\n fontSize={fontSize}\n fontFamily={fontFamily}\n placeholderTextColor={inputColors.placeholder}\n aria-invalid={isError || undefined}\n aria-describedby={errorMessage ? errorId : undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n data-testid=\"input-edit__field\"\n style={{\n display: \"block\",\n overflow: \"hidden\",\n fontWeight,\n lineHeight: `${lineHeight}px`,\n }}\n {...rest}\n />\n </Box>\n ) : richText && isWeb && isFilled ? (\n // Rich display (read-only): render the stored HTML.\n <div\n data-testid=\"input-edit__text\"\n dangerouslySetInnerHTML={{ __html: currentValue }}\n style={{\n flex: 1,\n color: textColor,\n fontFamily,\n fontWeight,\n fontSize: `${fontSize}px`,\n lineHeight: `${lineHeight}px`,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n />\n ) : (\n <Text\n color={displayColor}\n fontSize={fontSize}\n fontWeight={String(fontWeight)}\n data-testid=\"input-edit__text\"\n style={{\n flex: 1,\n fontFamily,\n lineHeight: `${lineHeight}px`,\n wordBreak: \"break-word\",\n // Preserve author line breaks in multi-line values.\n whiteSpace: \"pre-wrap\",\n }}\n >\n {isFilled ? plainText : placeholder}\n </Text>\n )}\n\n {/* Edit affordance — shown only in the resting inline display states\n (Default / Hover), matching Figma (hidden while editing and in error /\n disabled states). Decorative: the trigger button already carries the\n accessible name, so hide the icon from assistive tech. */}\n {icon && !editing && !isError && !disabled && (\n <Box alignItems=\"center\" justifyContent=\"center\" aria-hidden>\n <Icon size={FIELD.iconSize} color={textColor}>\n {editIcon ?? <Edit />}\n </Icon>\n </Box>\n )}\n </Box>\n </Box>\n\n {/* Floating confirm / cancel control — shown while the editor is active. */}\n {active && editControl && (\n <Box\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems=\"center\"\n backgroundColor={controlBg}\n data-testid=\"input-edit__edit-control\"\n style={{\n top: controlsTop,\n right: -FIELD.framePadding,\n borderRadius: 4,\n overflow: \"hidden\",\n ...(isWeb\n ? {\n boxShadow: POPOVER_SHADOW,\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n >\n <Box\n as=\"button\"\n type=\"button\"\n alignItems=\"center\"\n justifyContent=\"center\"\n backgroundColor={controlBg}\n borderWidth={0}\n padding={4}\n cursor=\"pointer\"\n onPress={handleConfirm}\n aria-label=\"Confirm\"\n data-testid=\"input-edit__confirm\"\n hoverStyle={{ backgroundColor: controlBgHover }}\n {...preventBlur}\n >\n <Icon size={CONTROL_ICON_SIZE} color={controlIconColor}>\n <Check />\n </Icon>\n </Box>\n <Box\n backgroundColor={theme.colors.border.inverse}\n style={{ width: 1, alignSelf: \"stretch\" }}\n />\n <Box\n as=\"button\"\n type=\"button\"\n alignItems=\"center\"\n justifyContent=\"center\"\n backgroundColor={controlBg}\n borderWidth={0}\n padding={4}\n cursor=\"pointer\"\n onPress={handleCancel}\n aria-label=\"Cancel\"\n data-testid=\"input-edit__cancel\"\n hoverStyle={{ backgroundColor: controlBgHover }}\n {...preventBlur}\n >\n <Icon size={CONTROL_ICON_SIZE} color={controlIconColor}>\n <Remove />\n </Icon>\n </Box>\n </Box>\n )}\n\n {/* Formatting tools — floating bar below-left, mirroring the confirm / cancel\n control. preventBlur keeps the input focused when a tool is pressed. */}\n {active && tools && (\n <Box\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={4}\n padding={4}\n backgroundColor={theme.colors.background.primary}\n data-testid=\"input-edit__tools\"\n style={{\n top: controlsTop,\n left: -FIELD.framePadding,\n borderRadius: 4,\n ...(isWeb\n ? {\n boxShadow: POPOVER_SHADOW,\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n {...preventBlur}\n >\n {tools}\n </Box>\n )}\n\n {/* Error message — a frosted popover callout with a pointer aimed at the field,\n matching the Figma tooltip treatment. */}\n {isError && errorMessage && (\n <Box\n position=\"relative\"\n style={{\n marginTop: FIELD.framePadding + 4,\n width: \"max-content\",\n maxWidth: \"100%\",\n ...(isWeb\n ? {\n filter: POPOVER_DROP_SHADOW,\n WebkitFilter: POPOVER_DROP_SHADOW,\n }\n : {}),\n }}\n >\n {/* Pointer (rotated square) at the top-left, tucked behind the bubble. */}\n <Box\n position=\"absolute\"\n backgroundColor={theme.colors.background.primary}\n style={{\n width: 8,\n height: 8,\n top: -3,\n left: 16,\n transform: \"rotate(45deg)\",\n }}\n />\n <Box\n backgroundColor={theme.colors.background.primary}\n paddingVertical={8}\n paddingHorizontal={12}\n style={{\n borderRadius: 4,\n ...(isWeb\n ? {\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n >\n <Text\n id={errorId}\n role=\"status\"\n aria-live=\"polite\"\n color={theme.colors.content.alert.primary}\n fontSize={FIELD.fontSize - 2}\n style={{ lineHeight: `${FIELD.lineHeight}px` }}\n >\n {errorMessage}\n </Text>\n </Box>\n </Box>\n )}\n </Box>\n );\n }\n);\n\nInputEdit.displayName = \"InputEdit\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","import React, { forwardRef } from \"react\";\nimport { TextInput as RNTextInput } from \"react-native\";\nimport { TextAreaPrimitiveProps } from \"@xsolla/xui-primitives-core\";\n\nexport const TextAreaPrimitive = forwardRef<\n RNTextInput,\n TextAreaPrimitiveProps\n>(\n (\n {\n value,\n placeholder,\n onChange,\n onChangeText,\n onFocus,\n onBlur,\n onKeyDown,\n disabled,\n readOnly,\n style,\n color,\n fontSize,\n fontFamily,\n placeholderTextColor,\n maxLength,\n rows,\n id,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-label\": ariaLabel,\n \"aria-disabled\": ariaDisabled,\n \"aria-invalid\": ariaInvalid,\n \"data-testid\": dataTestId,\n testID,\n },\n ref\n ) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const handleChangeText = (text: string) => {\n onChangeText?.(text);\n\n if (onChange) {\n const syntheticEvent = {\n target: { value: text },\n currentTarget: { value: text },\n type: \"change\",\n nativeEvent: { text },\n preventDefault: () => {},\n stopPropagation: () => {},\n isTrusted: false,\n } as unknown as React.ChangeEvent<HTMLTextAreaElement>;\n onChange(syntheticEvent);\n }\n };\n\n return (\n <RNTextInput\n ref={ref}\n value={value}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyPress={(e) => {\n if (onKeyDown) {\n onKeyDown({\n key: e.nativeEvent.key,\n preventDefault: () => {},\n } as any);\n }\n }}\n editable={!disabled && !readOnly}\n multiline={true}\n numberOfLines={rows || 4}\n style={[\n {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontFamily: resolvedFontFamily,\n flex: 1,\n padding: 0,\n textAlignVertical: \"top\",\n textAlign: (style as any)?.textAlign || \"left\",\n },\n style as any,\n ]}\n placeholderTextColor={placeholderTextColor}\n maxLength={maxLength}\n testID={dataTestId || testID || id}\n accessibilityLabel={ariaLabel}\n // RN AccessibilityState has no `invalid` / `readOnly`; surface via hint.\n accessibilityHint={\n [\n ariaInvalid ? \"Invalid\" : null,\n readOnly ? \"Read only\" : null,\n ariaDescribedBy,\n ]\n .filter(Boolean)\n .join(\". \") || undefined\n }\n accessibilityState={{\n disabled: disabled || ariaDisabled,\n }}\n accessible={true}\n />\n );\n }\n);\n\nTextAreaPrimitive.displayName = \"TextAreaPrimitive\";\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_react","import_react_native","import_jsx_runtime","RNTextInput","import_jsx_runtime","React","el"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/InputEdit.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/TextArea.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["export * from \"./InputEdit\";\n","import React, {\n useState,\n useRef,\n useEffect,\n forwardRef,\n type TextareaHTMLAttributes,\n type ReactNode,\n} from \"react\";\n// prettier-ignore\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, TextAreaPrimitive, isWeb } from \"@xsolla/xui-primitives\";\nimport {\n useResolvedTheme,\n useId,\n type ThemeOverrideProps,\n} from \"@xsolla/xui-core\";\nimport { Edit, Check, Remove } from \"@xsolla/xui-icons-base\";\n\ntype InputEditMode = \"inline\" | \"form\";\n\n/**\n * Named typography styles, resolved from the theme's typography tokens. Drives the\n * field's font family / size / weight / line-height so the text can match surrounding\n * content (e.g. a heading) rather than only the fixed body sizes.\n */\ntype InputEditTextStyle =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"display\"\n | \"body-lg\"\n | \"body-md\"\n | \"body-sm\"\n | \"body-xs\"\n | \"body-xxs\";\n\nexport interface InputEditProps\n extends\n Omit<\n TextareaHTMLAttributes<HTMLTextAreaElement>,\n \"size\" | \"onChange\" | \"value\" | \"defaultValue\"\n >,\n ThemeOverrideProps {\n /**\n * Controlled value of the field.\n */\n value?: string;\n /**\n * Initial value for uncontrolled usage.\n */\n defaultValue?: string;\n /**\n * Placeholder shown when the field is empty.\n */\n placeholder?: string;\n /**\n * Change handler receiving the current text (HTML when `richText` is set).\n */\n onChangeText?: (text: string) => void;\n /**\n * Called when the edit is confirmed (check button or `Cmd`/`Ctrl` + `Enter`).\n */\n onConfirm?: (value: string) => void;\n /**\n * Called when the edit is cancelled (cross button or `Escape`). The value is reverted.\n */\n onCancel?: () => void;\n /**\n * Minimum number of visible text rows while editing.\n */\n rows?: number;\n /**\n * Show the floating confirm / cancel control while editing.\n */\n editControl?: boolean;\n /**\n * Show the edit affordance icon in display mode.\n */\n icon?: boolean;\n /**\n * Override the default edit (pencil) icon.\n */\n editIcon?: ReactNode;\n /**\n * Optional formatting toolbar shown in a floating bar below the field while editing\n * (e.g. text-align / bold / link `IconButton`s). Rendered to the left, mirroring the\n * confirm / cancel control on the right.\n */\n tools?: ReactNode;\n /**\n * Activation mode. `\"inline\"` (default) rests as plain text and reveals the editor on\n * click; `\"form\"` is always an open, editable field (like a standard form text area).\n */\n mode?: InputEditMode;\n /**\n * Named typography style applied to the text and editor (e.g. `\"h1\"`, `\"body-lg\"`).\n * Overrides the default font.\n */\n textStyle?: InputEditTextStyle;\n /**\n * Enable rich-text editing (web only). The field becomes a `contenteditable` surface\n * and `value` / `onChangeText` / `onConfirm` carry HTML. Wire a toolbar via `tools`\n * using `document.execCommand`. Falls back to a plain text field on React Native.\n * The HTML is not sanitized — sanitize before rendering untrusted values.\n */\n richText?: boolean;\n /**\n * Disable the control.\n */\n disabled?: boolean;\n /**\n * Highlight the control as invalid.\n */\n error?: boolean;\n /**\n * Error message displayed below the field (implies `error`).\n */\n errorMessage?: string;\n /**\n * Unique identifier for the input element. Used for accessibility linking.\n */\n id?: string;\n /**\n * Accessible label for screen readers (use when no visible label is present).\n */\n \"aria-label\"?: string;\n /**\n * ID of an external element that labels the field (e.g. a heading placed above it).\n */\n \"aria-labelledby\"?: string;\n testID?: string;\n /**\n * Optional class name applied to the root element (web).\n */\n className?: string;\n}\n\n// InputEdit has a single size (per the design). `textStyle` can still override the font.\nconst FIELD = {\n fontSize: 16,\n lineHeight: 18,\n framePadding: 11,\n iconSize: 16,\n};\n\n// Strip tags from an HTML value — used for empty detection and the native plain-text\n// fallback (React Native can't render contenteditable HTML inline).\nconst stripHtml = (html: string): string =>\n html.replace(/<[^>]*>/g, \"\").replace(/&nbsp;/gi, \" \");\n\nconst CONTROL_ICON_SIZE = 18;\nconst POPOVER_SHADOW =\n \"0px 6px 10px 4px rgba(7, 7, 8, 0.1), 0px 2px 3px 0px rgba(7, 7, 8, 0.2)\";\n// drop-shadow variant — follows the element's alpha shape so it wraps the bubble's\n// pointer (a plain box-shadow would clip at the rectangle edge).\nconst POPOVER_DROP_SHADOW =\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\";\n\n/**\n * A multi-line text field for editing freeform text. In `\"inline\"` mode it rests as\n * plain text and reveals a highlighted editor on click; in `\"form\"` mode it is always\n * an open, editable field. `Enter` inserts a new line; confirm via the floating control\n * or `Cmd`/`Ctrl` + `Enter`; clicking outside also commits. `Escape` cancels and\n * reverts.\n */\nexport const InputEdit = forwardRef<\n HTMLTextAreaElement | HTMLDivElement,\n InputEditProps\n>(\n (\n {\n value,\n defaultValue,\n placeholder = \"Placeholder\",\n onChangeText,\n onConfirm,\n onCancel,\n onKeyDown,\n editControl = true,\n icon = true,\n editIcon,\n tools,\n rows,\n mode = \"inline\",\n textStyle,\n richText = false,\n disabled = false,\n error = false,\n errorMessage,\n id: providedId,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n testID,\n className,\n themeMode,\n themeProductContext,\n ...rest\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(\n value ?? defaultValue ?? \"\"\n );\n const currentValue = isControlled ? (value as string) : internalValue;\n\n const isFormMode = mode === \"form\";\n // In form mode the editor is always rendered; in inline mode it appears on activation.\n const [isEditing, setIsEditing] = useState(false);\n const editing = isFormMode || isEditing;\n // Whether the editor currently holds focus — gates the floating controls so a form\n // with several fields doesn't show controls on every one at rest.\n const [focused, setFocused] = useState(false);\n // The \"active\" (focus-styled, controls-visible) state. Inline mode keys off the edit\n // session (controls appear the moment you click, before focus lands); form mode keys\n // off real focus (so resting fields stay quiet).\n const active = isFormMode ? focused : isEditing;\n // Rich text only applies on web (contenteditable is DOM-only); native falls back to\n // the plain textarea.\n const richEnabled = richText && isWeb;\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const editableRef = useRef<HTMLDivElement>(null);\n const focusField = () => {\n if (richEnabled) editableRef.current?.focus();\n else inputRef.current?.focus();\n };\n // Last value reported via onConfirm (or the initial value) — used to dedupe commits\n // and to revert on cancel.\n const committedValue = useRef(currentValue);\n // Measured height of the field box, so the floating controls follow it as the\n // multi-line field grows.\n const [fieldHeight, setFieldHeight] = useState<number | null>(null);\n\n // Generate a unique, ARIA-safe id (useId() yields colons that are invalid in id attrs).\n const rawId = useId();\n const safeId = rawId.replace(/:/g, \"\");\n const inputId = providedId || `input-edit-${safeId}`;\n const errorId = `${inputId}-error`;\n const triggerId = `${inputId}-trigger`;\n\n // Return focus to the display trigger so keyboard users are not dropped to the body.\n const focusTrigger = () => {\n if (isWeb) {\n setTimeout(() => document.getElementById(triggerId)?.focus(), 0);\n }\n };\n\n // In rich mode the underlying element is the contenteditable div, not a textarea —\n // exposed honestly so consumers don't read `.value` off a div.\n React.useImperativeHandle(\n ref,\n () =>\n (richEnabled ? editableRef.current : inputRef.current) as\n | HTMLTextAreaElement\n | HTMLDivElement,\n [richEnabled]\n );\n\n // Keep internal value in sync with the controlled value. An externally-set value is\n // treated as the committed baseline.\n useEffect(() => {\n if (value !== undefined) {\n setInternalValue(value);\n committedValue.current = value;\n }\n }, [value]);\n\n // Auto-grow the field to fit its content (multi-line), so the height tracks the text\n // without an inner scrollbar. The contenteditable div grows on its own; the textarea\n // needs its height reset and re-measured.\n const autoSize = () => {\n if (!isWeb) return;\n if (richEnabled) {\n // innerHTML is set imperatively just before this runs, so the div hasn't been\n // laid out yet — measure after the next paint or the height is stale on entry.\n requestAnimationFrame(() => {\n const el = editableRef.current;\n if (el) setFieldHeight(el.offsetHeight + FIELD.framePadding * 2);\n });\n return;\n }\n const el = inputRef.current;\n if (!el) return;\n el.style.height = \"auto\";\n el.style.height = `${el.scrollHeight}px`;\n setFieldHeight(el.scrollHeight + FIELD.framePadding * 2);\n };\n\n useEffect(() => {\n if (!editing) return;\n // Controlled contenteditable: write innerHTML only when the incoming value differs\n // from the DOM, so echoing our own input doesn't reset the caret.\n if (richEnabled) {\n const el = editableRef.current;\n if (el && el.innerHTML !== currentValue) el.innerHTML = currentValue;\n }\n autoSize();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editing, currentValue, richEnabled]);\n\n const isError = !!(error || errorMessage);\n // For rich values, \"empty\" means no visible text once tags are stripped.\n const isFilled = richText\n ? stripHtml(currentValue).trim().length > 0\n : currentValue.length > 0;\n // Plain-text projection of the value — used by the textarea and the native fallback.\n const plainText = richText ? stripHtml(currentValue) : currentValue;\n const inputColors = theme.colors.control.input;\n const borderRadius = theme.shape.input.md.borderRadius;\n\n // Resolve effective typography: a named textStyle (heading/body token) overrides the\n // size-derived font. Padding / icon size always come from `size`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const typo = theme.typographyTokens as any;\n const textStyleToken = textStyle\n ? (typo.heading[textStyle] ?? typo.basic[textStyle])\n : null;\n const fontSize = textStyleToken ? textStyleToken.fontSize : FIELD.fontSize;\n const lineHeight = textStyleToken\n ? parseInt(String(textStyleToken.lineHeight), 10)\n : FIELD.lineHeight;\n const fontWeight = textStyleToken ? textStyleToken.fontWeight : 400;\n const fontFamily =\n textStyleToken && textStyleToken.lineHeightCategory === \"display\"\n ? theme.fonts.heading\n : theme.fonts.body;\n\n // Vertical offset for the floating controls — just below the field's bottom edge.\n // Defaults to the single-line height before the field has been measured.\n const controlsTop =\n (fieldHeight ?? lineHeight + FIELD.framePadding * 2) -\n FIELD.framePadding +\n 4;\n\n const enterEdit = () => {\n if (disabled || isEditing) return;\n setIsEditing(true);\n // Focus the field once it has mounted.\n setTimeout(focusField, 0);\n };\n\n // Rich-text input: read the contenteditable's HTML on each edit.\n const handleRichInput = (e: React.FormEvent<HTMLDivElement>) => {\n handleChangeText(e.currentTarget.innerHTML);\n };\n\n // Paste as plain text to avoid importing foreign markup/styles (no sanitizer here).\n const handlePaste = (e: React.ClipboardEvent<HTMLDivElement>) => {\n e.preventDefault();\n const text = e.clipboardData.getData(\"text/plain\");\n document.execCommand(\"insertText\", false, text);\n };\n\n const handleChangeText = (next: string) => {\n onChangeText?.(next);\n if (!isControlled) {\n setInternalValue(next);\n }\n };\n\n // Explicit confirm (button / shortcut) always reports the value — it is a deliberate\n // save action.\n const commitExplicit = () => {\n onConfirm?.(currentValue);\n committedValue.current = currentValue;\n };\n\n // Commit on blur only when the value actually changed, so clicking in and out (or a\n // confirm immediately followed by the unmount blur) doesn't re-fire onConfirm.\n const commitOnBlur = () => {\n if (currentValue !== committedValue.current) {\n onConfirm?.(currentValue);\n committedValue.current = currentValue;\n }\n };\n\n // Inline mode collapses back to the plain-text display; form mode stays open.\n const exitEdit = () => {\n if (!isFormMode) {\n setIsEditing(false);\n setFocused(false);\n focusTrigger();\n }\n };\n\n const handleConfirm = () => {\n commitExplicit();\n exitEdit();\n };\n\n const handleCancel = () => {\n // Revert to the last committed value.\n if (!isControlled) {\n setInternalValue(committedValue.current);\n }\n onCancel?.();\n exitEdit();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {\n // Enter inserts a new line (multi-line). Confirm with Cmd/Ctrl + Enter.\n // These gestures are consumed by the component (use onConfirm / onCancel), so the\n // forwarded onKeyDown does not also fire for them.\n if (e.key === \"Enter\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n handleConfirm();\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n handleCancel();\n return;\n }\n onKeyDown?.(e as React.KeyboardEvent<HTMLTextAreaElement>);\n };\n\n const handleFocus = () => setFocused(true);\n\n // Clicking outside commits the current value. Control / tool buttons prevent blur\n // via onMouseDown, so they fire their own action instead of committing here.\n const handleBlur = () => {\n setFocused(false);\n commitOnBlur();\n if (!isFormMode) {\n setIsEditing(false);\n }\n };\n\n // Resolve background / border colors based on state. Error takes precedence over\n // the focus state — per Figma the error variant keeps the input bg, not the focus\n // bg. A resting form-mode field looks like a standard input; a resting inline field\n // is transparent so it blends with surrounding content.\n let fieldBg = \"transparent\";\n let fieldBorder = \"transparent\";\n if (disabled) {\n fieldBg = inputColors.bgDisable;\n fieldBorder = inputColors.borderDisable;\n } else if (isError) {\n fieldBg = inputColors.bg;\n fieldBorder = theme.colors.border.alert;\n } else if (active) {\n fieldBg = theme.colors.control.focus.bg;\n fieldBorder = theme.colors.border.brand;\n } else if (isFormMode) {\n fieldBg = inputColors.bg;\n fieldBorder = inputColors.border;\n }\n\n const textColor = disabled ? inputColors.textDisable : inputColors.text;\n const displayColor = isFilled ? textColor : inputColors.placeholder;\n\n const preventBlur = isWeb\n ? { onMouseDown: (e: React.MouseEvent) => e.preventDefault() }\n : {};\n\n // Edit control uses the high-contrast \"mono primary\" surface (inverts per theme).\n const controlBg = theme.colors.control.mono.primary.bg;\n const controlBgHover = theme.colors.control.mono.primary.bgHover;\n const controlIconColor = theme.colors.control.mono.text.primary;\n\n // In inline display mode the field is an interactive trigger: render it as a real\n // button so it is focusable and activatable with Enter / Space by keyboard users.\n // In form mode the editor is always present, so there is no trigger.\n const isTrigger = !editing && !disabled;\n const triggerProps = isTrigger\n ? {\n as: \"button\" as const,\n type: \"button\" as const,\n id: triggerId,\n onPress: enterEdit,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n }\n : {\n \"aria-disabled\": disabled || undefined,\n };\n\n return (\n <Box\n position=\"relative\"\n width=\"100%\"\n testID={testID}\n className={className}\n >\n {/* Inline anchor — sized to a single text line so the field aligns with surrounding content. */}\n <Box position=\"relative\" width=\"100%\" style={{ minHeight: lineHeight }}>\n {/* Field layer — expands outward (negative inset) so the hover/focus highlight\n does not shift the inline text. */}\n <Box\n {...triggerProps}\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems={\n editing || isError || disabled ? \"flex-start\" : \"center\"\n }\n gap={8}\n paddingVertical={FIELD.framePadding}\n paddingHorizontal={FIELD.framePadding}\n backgroundColor={fieldBg}\n borderColor={fieldBorder}\n borderWidth={1}\n cursor={disabled ? \"not-allowed\" : editing ? \"text\" : \"pointer\"}\n hoverStyle={\n !disabled && !editing && !isError\n ? {\n backgroundColor: inputColors.bgHover,\n borderColor: inputColors.borderHover,\n }\n : undefined\n }\n style={{\n // Pin top/left/right to the anchor (inflated outward); leave the bottom\n // free so the field grows downward with multi-line content.\n top: -FIELD.framePadding,\n left: -FIELD.framePadding,\n right: -FIELD.framePadding,\n minHeight: lineHeight + FIELD.framePadding * 2,\n borderRadius,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n width: \"auto\",\n }}\n >\n {editing && richEnabled ? (\n // Rich-text editor (web): a contenteditable surface holding HTML.\n <Box flex={1} position=\"relative\">\n {!isFilled && (\n <Text\n aria-hidden\n color={inputColors.placeholder}\n fontSize={fontSize}\n fontWeight={String(fontWeight)}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n fontFamily,\n lineHeight: `${lineHeight}px`,\n pointerEvents: \"none\",\n }}\n >\n {placeholder}\n </Text>\n )}\n <div\n ref={editableRef}\n id={inputId}\n contentEditable={!disabled}\n suppressContentEditableWarning\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-invalid={isError || undefined}\n aria-describedby={errorMessage ? errorId : undefined}\n data-testid=\"input-edit__field\"\n onInput={handleRichInput}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n style={{\n outline: \"none\",\n minHeight: `${lineHeight}px`,\n color: textColor,\n fontFamily,\n fontWeight,\n fontSize: `${fontSize}px`,\n lineHeight: `${lineHeight}px`,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n />\n </Box>\n ) : editing ? (\n <Box flex={1}>\n <TextAreaPrimitive\n ref={inputRef}\n id={inputId}\n value={plainText}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n rows={rows ?? 1}\n color={textColor}\n fontSize={fontSize}\n fontFamily={fontFamily}\n placeholderTextColor={inputColors.placeholder}\n aria-invalid={isError || undefined}\n aria-describedby={errorMessage ? errorId : undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n data-testid=\"input-edit__field\"\n style={{\n display: \"block\",\n overflow: \"hidden\",\n fontWeight,\n lineHeight: `${lineHeight}px`,\n }}\n {...rest}\n />\n </Box>\n ) : richText && isWeb && isFilled ? (\n // Rich display (read-only): render the stored HTML.\n <div\n data-testid=\"input-edit__text\"\n dangerouslySetInnerHTML={{ __html: currentValue }}\n style={{\n flex: 1,\n color: textColor,\n fontFamily,\n fontWeight,\n fontSize: `${fontSize}px`,\n lineHeight: `${lineHeight}px`,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n />\n ) : (\n <Text\n color={displayColor}\n fontSize={fontSize}\n fontWeight={String(fontWeight)}\n data-testid=\"input-edit__text\"\n style={{\n flex: 1,\n fontFamily,\n lineHeight: `${lineHeight}px`,\n wordBreak: \"break-word\",\n // Preserve author line breaks in multi-line values.\n whiteSpace: \"pre-wrap\",\n }}\n >\n {isFilled ? plainText : placeholder}\n </Text>\n )}\n\n {/* Edit affordance — shown only in the resting inline display states\n (Default / Hover), matching Figma (hidden while editing and in error /\n disabled states). Decorative: the trigger button already carries the\n accessible name, so hide the icon from assistive tech. */}\n {icon && !editing && !isError && !disabled && (\n <Box alignItems=\"center\" justifyContent=\"center\" aria-hidden>\n <Icon size={FIELD.iconSize} color={textColor}>\n {editIcon ?? <Edit />}\n </Icon>\n </Box>\n )}\n </Box>\n </Box>\n\n {/* Floating confirm / cancel control — shown while the editor is active. */}\n {active && editControl && (\n <Box\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems=\"center\"\n backgroundColor={controlBg}\n data-testid=\"input-edit__edit-control\"\n style={{\n top: controlsTop,\n right: -FIELD.framePadding,\n borderRadius: 4,\n overflow: \"hidden\",\n ...(isWeb\n ? {\n boxShadow: POPOVER_SHADOW,\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n >\n <Box\n as=\"button\"\n type=\"button\"\n alignItems=\"center\"\n justifyContent=\"center\"\n backgroundColor={controlBg}\n borderWidth={0}\n padding={4}\n cursor=\"pointer\"\n onPress={handleConfirm}\n aria-label=\"Confirm\"\n data-testid=\"input-edit__confirm\"\n hoverStyle={{ backgroundColor: controlBgHover }}\n {...preventBlur}\n >\n <Icon size={CONTROL_ICON_SIZE} color={controlIconColor}>\n <Check />\n </Icon>\n </Box>\n <Box\n backgroundColor={theme.colors.border.inverse}\n style={{ width: 1, alignSelf: \"stretch\" }}\n />\n <Box\n as=\"button\"\n type=\"button\"\n alignItems=\"center\"\n justifyContent=\"center\"\n backgroundColor={controlBg}\n borderWidth={0}\n padding={4}\n cursor=\"pointer\"\n onPress={handleCancel}\n aria-label=\"Cancel\"\n data-testid=\"input-edit__cancel\"\n hoverStyle={{ backgroundColor: controlBgHover }}\n {...preventBlur}\n >\n <Icon size={CONTROL_ICON_SIZE} color={controlIconColor}>\n <Remove />\n </Icon>\n </Box>\n </Box>\n )}\n\n {/* Formatting tools — floating bar below-left, mirroring the confirm / cancel\n control. preventBlur keeps the input focused when a tool is pressed. */}\n {active && tools && (\n <Box\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={4}\n padding={4}\n backgroundColor={theme.colors.background.primary}\n data-testid=\"input-edit__tools\"\n style={{\n top: controlsTop,\n left: -FIELD.framePadding,\n borderRadius: 4,\n ...(isWeb\n ? {\n boxShadow: POPOVER_SHADOW,\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n {...preventBlur}\n >\n {tools}\n </Box>\n )}\n\n {/* Error message — a frosted popover callout with a pointer aimed at the field,\n matching the Figma tooltip treatment. */}\n {isError && errorMessage && (\n <Box\n position=\"relative\"\n style={{\n marginTop: FIELD.framePadding + 4,\n width: \"max-content\",\n maxWidth: \"100%\",\n ...(isWeb\n ? {\n filter: POPOVER_DROP_SHADOW,\n WebkitFilter: POPOVER_DROP_SHADOW,\n }\n : {}),\n }}\n >\n {/* Pointer (rotated square) at the top-left, tucked behind the bubble. */}\n <Box\n position=\"absolute\"\n backgroundColor={theme.colors.background.primary}\n style={{\n width: 8,\n height: 8,\n top: -3,\n left: 16,\n transform: \"rotate(45deg)\",\n }}\n />\n <Box\n backgroundColor={theme.colors.background.primary}\n paddingVertical={8}\n paddingHorizontal={12}\n style={{\n borderRadius: 4,\n ...(isWeb\n ? {\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n >\n <Text\n id={errorId}\n role=\"status\"\n aria-live=\"polite\"\n color={theme.colors.content.alert.primary}\n fontSize={FIELD.fontSize - 2}\n style={{ lineHeight: `${FIELD.lineHeight}px` }}\n >\n {errorMessage}\n </Text>\n </Box>\n </Box>\n )}\n </Box>\n );\n }\n);\n\nInputEdit.displayName = \"InputEdit\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","import React, { forwardRef } from \"react\";\nimport { TextInput as RNTextInput } from \"react-native\";\nimport { TextAreaPrimitiveProps } from \"@xsolla/xui-primitives-core\";\n\nexport const TextAreaPrimitive = forwardRef<\n RNTextInput,\n TextAreaPrimitiveProps\n>(\n (\n {\n value,\n placeholder,\n onChange,\n onChangeText,\n onFocus,\n onBlur,\n onKeyDown,\n disabled,\n readOnly,\n style,\n color,\n fontSize,\n fontFamily,\n placeholderTextColor,\n maxLength,\n rows,\n id,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-label\": ariaLabel,\n \"aria-disabled\": ariaDisabled,\n \"aria-invalid\": ariaInvalid,\n \"data-testid\": dataTestId,\n testID,\n },\n ref\n ) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const handleChangeText = (text: string) => {\n onChangeText?.(text);\n\n if (onChange) {\n const syntheticEvent = {\n target: { value: text },\n currentTarget: { value: text },\n type: \"change\",\n nativeEvent: { text },\n preventDefault: () => {},\n stopPropagation: () => {},\n isTrusted: false,\n } as unknown as React.ChangeEvent<HTMLTextAreaElement>;\n onChange(syntheticEvent);\n }\n };\n\n return (\n <RNTextInput\n ref={ref}\n value={value}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyPress={(e) => {\n if (onKeyDown) {\n onKeyDown({\n key: e.nativeEvent.key,\n preventDefault: () => {},\n } as any);\n }\n }}\n editable={!disabled && !readOnly}\n multiline={true}\n numberOfLines={rows || 4}\n style={[\n {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontFamily: resolvedFontFamily,\n flex: 1,\n padding: 0,\n textAlignVertical: \"top\",\n textAlign: (style as any)?.textAlign || \"left\",\n },\n style as any,\n ]}\n placeholderTextColor={placeholderTextColor}\n maxLength={maxLength}\n testID={dataTestId || testID || id}\n accessibilityLabel={ariaLabel}\n // RN AccessibilityState has no `invalid` / `readOnly`; surface via hint.\n accessibilityHint={\n [\n ariaInvalid ? \"Invalid\" : null,\n readOnly ? \"Read only\" : null,\n ariaDescribedBy,\n ]\n .filter(Boolean)\n .join(\". \") || undefined\n }\n accessibilityState={{\n disabled: disabled || ariaDisabled,\n }}\n accessible={true}\n />\n );\n }\n);\n\nTextAreaPrimitive.displayName = \"TextAreaPrimitive\";\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_react","import_react_native","import_jsx_runtime","RNTextInput","import_jsx_runtime","React","el"]}
package/native/index.mjs CHANGED
@@ -13,6 +13,38 @@ import {
13
13
  Image
14
14
  } from "react-native";
15
15
  import { jsx } from "react/jsx-runtime";
16
+ var roleToAccessibilityRole = {
17
+ button: "button",
18
+ link: "link",
19
+ img: "image",
20
+ image: "image",
21
+ summary: "summary",
22
+ switch: "switch",
23
+ checkbox: "checkbox",
24
+ radio: "radio",
25
+ heading: "header",
26
+ text: "text",
27
+ search: "search",
28
+ alert: "alert",
29
+ none: "none",
30
+ presentation: "none",
31
+ progressbar: "progressbar",
32
+ scrollbar: "scrollbar",
33
+ adjustable: "adjustable",
34
+ tab: "tab",
35
+ menu: "menu",
36
+ menuitem: "menuitem",
37
+ list: "list",
38
+ timer: "timer"
39
+ };
40
+ var toGapValue = (gap) => {
41
+ if (gap === void 0) return void 0;
42
+ if (typeof gap === "number") return gap;
43
+ const pxMatch = /^(\d+(?:\.\d+)?)px$/.exec(gap);
44
+ if (pxMatch) return Number(pxMatch[1]);
45
+ const asNumber = Number(gap);
46
+ return Number.isFinite(asNumber) ? asNumber : void 0;
47
+ };
16
48
  var Box = ({
17
49
  children,
18
50
  onPress,
@@ -45,8 +77,10 @@ var Box = ({
45
77
  marginLeft,
46
78
  marginRight,
47
79
  flexDirection,
80
+ flexWrap,
48
81
  alignItems,
49
82
  justifyContent,
83
+ alignSelf,
50
84
  position,
51
85
  top,
52
86
  bottom,
@@ -58,11 +92,14 @@ var Box = ({
58
92
  maxWidth,
59
93
  maxHeight,
60
94
  flex,
95
+ flexShrink,
96
+ gap,
61
97
  overflow,
62
98
  zIndex,
63
99
  hoverStyle,
64
100
  pressStyle,
65
101
  style,
102
+ disabled,
66
103
  "data-testid": dataTestId,
67
104
  testID,
68
105
  as,
@@ -101,14 +138,18 @@ var Box = ({
101
138
  marginLeft,
102
139
  marginRight,
103
140
  flexDirection,
141
+ flexWrap,
104
142
  alignItems,
105
143
  justifyContent,
144
+ alignSelf,
106
145
  position,
107
146
  top,
108
147
  bottom,
109
148
  left,
110
149
  right,
111
150
  flex,
151
+ flexShrink,
152
+ gap: toGapValue(gap),
112
153
  ...style
113
154
  });
114
155
  const finalTestID = dataTestId || testID;
@@ -117,15 +158,25 @@ var Box = ({
117
158
  tabIndex,
118
159
  onKeyDown,
119
160
  onKeyUp,
120
- "aria-label": _ariaLabel,
161
+ "aria-label": ariaLabel,
121
162
  "aria-labelledby": _ariaLabelledBy,
122
163
  "aria-current": _ariaCurrent,
123
- "aria-disabled": _ariaDisabled,
124
- "aria-live": _ariaLive,
164
+ "aria-disabled": ariaDisabled,
165
+ "aria-live": ariaLive,
166
+ "aria-busy": ariaBusy,
125
167
  className,
126
168
  "data-testid": _dataTestId,
169
+ cursor: _cursor,
170
+ type: _type,
127
171
  ...nativeRest
128
172
  } = rest;
173
+ const accessibilityRole = typeof role === "string" && roleToAccessibilityRole[role] || (as === "button" ? "button" : void 0);
174
+ const isDisabled = Boolean(disabled || ariaDisabled);
175
+ const accessibilityState = {
176
+ disabled: isDisabled || void 0,
177
+ busy: Boolean(ariaBusy) || void 0
178
+ };
179
+ const accessibilityLiveRegion = ariaLive === "polite" || ariaLive === "assertive" ? ariaLive : void 0;
129
180
  if (as === "img" && src) {
130
181
  const imageStyle = {
131
182
  width,
@@ -144,16 +195,18 @@ var Box = ({
144
195
  source: { uri: src },
145
196
  style: imageStyle,
146
197
  testID: finalTestID,
198
+ accessibilityLabel: typeof ariaLabel === "string" ? ariaLabel : alt,
147
199
  resizeMode: "cover",
148
200
  ...nativeRest
149
201
  }
150
202
  );
151
203
  }
152
- if (onPress) {
204
+ if (onPress || as === "button") {
153
205
  return /* @__PURE__ */ jsx(
154
206
  Pressable,
155
207
  {
156
- onPress,
208
+ onPress: !isDisabled && onPress ? onPress : void 0,
209
+ disabled: isDisabled,
157
210
  onLayout,
158
211
  onMoveShouldSetResponder,
159
212
  onResponderGrant,
@@ -162,6 +215,10 @@ var Box = ({
162
215
  onResponderTerminate,
163
216
  style: ({ pressed }) => getContainerStyle(pressed),
164
217
  testID: finalTestID,
218
+ accessibilityRole,
219
+ accessibilityLabel: typeof ariaLabel === "string" ? ariaLabel : void 0,
220
+ accessibilityState,
221
+ accessibilityLiveRegion,
165
222
  ...nativeRest,
166
223
  children
167
224
  }
@@ -178,6 +235,10 @@ var Box = ({
178
235
  onResponderMove,
179
236
  onResponderRelease,
180
237
  onResponderTerminate,
238
+ accessibilityRole,
239
+ accessibilityLabel: typeof ariaLabel === "string" ? ariaLabel : void 0,
240
+ accessibilityState,
241
+ accessibilityLiveRegion,
181
242
  ...nativeRest,
182
243
  children
183
244
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/InputEdit.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/TextArea.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["import React, {\n useState,\n useRef,\n useEffect,\n forwardRef,\n type TextareaHTMLAttributes,\n type ReactNode,\n} from \"react\";\n// prettier-ignore\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, TextAreaPrimitive, isWeb } from \"@xsolla/xui-primitives\";\nimport {\n useResolvedTheme,\n useId,\n type ThemeOverrideProps,\n} from \"@xsolla/xui-core\";\nimport { Edit, Check, Remove } from \"@xsolla/xui-icons-base\";\n\ntype InputEditMode = \"inline\" | \"form\";\n\n/**\n * Named typography styles, resolved from the theme's typography tokens. Drives the\n * field's font family / size / weight / line-height so the text can match surrounding\n * content (e.g. a heading) rather than only the fixed body sizes.\n */\ntype InputEditTextStyle =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"display\"\n | \"body-lg\"\n | \"body-md\"\n | \"body-sm\"\n | \"body-xs\"\n | \"body-xxs\";\n\nexport interface InputEditProps\n extends\n Omit<\n TextareaHTMLAttributes<HTMLTextAreaElement>,\n \"size\" | \"onChange\" | \"value\" | \"defaultValue\"\n >,\n ThemeOverrideProps {\n /**\n * Controlled value of the field.\n */\n value?: string;\n /**\n * Initial value for uncontrolled usage.\n */\n defaultValue?: string;\n /**\n * Placeholder shown when the field is empty.\n */\n placeholder?: string;\n /**\n * Change handler receiving the current text (HTML when `richText` is set).\n */\n onChangeText?: (text: string) => void;\n /**\n * Called when the edit is confirmed (check button or `Cmd`/`Ctrl` + `Enter`).\n */\n onConfirm?: (value: string) => void;\n /**\n * Called when the edit is cancelled (cross button or `Escape`). The value is reverted.\n */\n onCancel?: () => void;\n /**\n * Minimum number of visible text rows while editing.\n */\n rows?: number;\n /**\n * Show the floating confirm / cancel control while editing.\n */\n editControl?: boolean;\n /**\n * Show the edit affordance icon in display mode.\n */\n icon?: boolean;\n /**\n * Override the default edit (pencil) icon.\n */\n editIcon?: ReactNode;\n /**\n * Optional formatting toolbar shown in a floating bar below the field while editing\n * (e.g. text-align / bold / link `IconButton`s). Rendered to the left, mirroring the\n * confirm / cancel control on the right.\n */\n tools?: ReactNode;\n /**\n * Activation mode. `\"inline\"` (default) rests as plain text and reveals the editor on\n * click; `\"form\"` is always an open, editable field (like a standard form text area).\n */\n mode?: InputEditMode;\n /**\n * Named typography style applied to the text and editor (e.g. `\"h1\"`, `\"body-lg\"`).\n * Overrides the default font.\n */\n textStyle?: InputEditTextStyle;\n /**\n * Enable rich-text editing (web only). The field becomes a `contenteditable` surface\n * and `value` / `onChangeText` / `onConfirm` carry HTML. Wire a toolbar via `tools`\n * using `document.execCommand`. Falls back to a plain text field on React Native.\n * The HTML is not sanitized — sanitize before rendering untrusted values.\n */\n richText?: boolean;\n /**\n * Disable the control.\n */\n disabled?: boolean;\n /**\n * Highlight the control as invalid.\n */\n error?: boolean;\n /**\n * Error message displayed below the field (implies `error`).\n */\n errorMessage?: string;\n /**\n * Unique identifier for the input element. Used for accessibility linking.\n */\n id?: string;\n /**\n * Accessible label for screen readers (use when no visible label is present).\n */\n \"aria-label\"?: string;\n /**\n * ID of an external element that labels the field (e.g. a heading placed above it).\n */\n \"aria-labelledby\"?: string;\n testID?: string;\n /**\n * Optional class name applied to the root element (web).\n */\n className?: string;\n}\n\n// InputEdit has a single size (per the design). `textStyle` can still override the font.\nconst FIELD = {\n fontSize: 16,\n lineHeight: 18,\n framePadding: 11,\n iconSize: 16,\n};\n\n// Strip tags from an HTML value — used for empty detection and the native plain-text\n// fallback (React Native can't render contenteditable HTML inline).\nconst stripHtml = (html: string): string =>\n html.replace(/<[^>]*>/g, \"\").replace(/&nbsp;/gi, \" \");\n\nconst CONTROL_ICON_SIZE = 18;\nconst POPOVER_SHADOW =\n \"0px 6px 10px 4px rgba(7, 7, 8, 0.1), 0px 2px 3px 0px rgba(7, 7, 8, 0.2)\";\n// drop-shadow variant — follows the element's alpha shape so it wraps the bubble's\n// pointer (a plain box-shadow would clip at the rectangle edge).\nconst POPOVER_DROP_SHADOW =\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\";\n\n/**\n * A multi-line text field for editing freeform text. In `\"inline\"` mode it rests as\n * plain text and reveals a highlighted editor on click; in `\"form\"` mode it is always\n * an open, editable field. `Enter` inserts a new line; confirm via the floating control\n * or `Cmd`/`Ctrl` + `Enter`; clicking outside also commits. `Escape` cancels and\n * reverts.\n */\nexport const InputEdit = forwardRef<\n HTMLTextAreaElement | HTMLDivElement,\n InputEditProps\n>(\n (\n {\n value,\n defaultValue,\n placeholder = \"Placeholder\",\n onChangeText,\n onConfirm,\n onCancel,\n onKeyDown,\n editControl = true,\n icon = true,\n editIcon,\n tools,\n rows,\n mode = \"inline\",\n textStyle,\n richText = false,\n disabled = false,\n error = false,\n errorMessage,\n id: providedId,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n testID,\n className,\n themeMode,\n themeProductContext,\n ...rest\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(\n value ?? defaultValue ?? \"\"\n );\n const currentValue = isControlled ? (value as string) : internalValue;\n\n const isFormMode = mode === \"form\";\n // In form mode the editor is always rendered; in inline mode it appears on activation.\n const [isEditing, setIsEditing] = useState(false);\n const editing = isFormMode || isEditing;\n // Whether the editor currently holds focus — gates the floating controls so a form\n // with several fields doesn't show controls on every one at rest.\n const [focused, setFocused] = useState(false);\n // The \"active\" (focus-styled, controls-visible) state. Inline mode keys off the edit\n // session (controls appear the moment you click, before focus lands); form mode keys\n // off real focus (so resting fields stay quiet).\n const active = isFormMode ? focused : isEditing;\n // Rich text only applies on web (contenteditable is DOM-only); native falls back to\n // the plain textarea.\n const richEnabled = richText && isWeb;\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const editableRef = useRef<HTMLDivElement>(null);\n const focusField = () => {\n if (richEnabled) editableRef.current?.focus();\n else inputRef.current?.focus();\n };\n // Last value reported via onConfirm (or the initial value) — used to dedupe commits\n // and to revert on cancel.\n const committedValue = useRef(currentValue);\n // Measured height of the field box, so the floating controls follow it as the\n // multi-line field grows.\n const [fieldHeight, setFieldHeight] = useState<number | null>(null);\n\n // Generate a unique, ARIA-safe id (useId() yields colons that are invalid in id attrs).\n const rawId = useId();\n const safeId = rawId.replace(/:/g, \"\");\n const inputId = providedId || `input-edit-${safeId}`;\n const errorId = `${inputId}-error`;\n const triggerId = `${inputId}-trigger`;\n\n // Return focus to the display trigger so keyboard users are not dropped to the body.\n const focusTrigger = () => {\n if (isWeb) {\n setTimeout(() => document.getElementById(triggerId)?.focus(), 0);\n }\n };\n\n // In rich mode the underlying element is the contenteditable div, not a textarea —\n // exposed honestly so consumers don't read `.value` off a div.\n React.useImperativeHandle(\n ref,\n () =>\n (richEnabled ? editableRef.current : inputRef.current) as\n | HTMLTextAreaElement\n | HTMLDivElement,\n [richEnabled]\n );\n\n // Keep internal value in sync with the controlled value. An externally-set value is\n // treated as the committed baseline.\n useEffect(() => {\n if (value !== undefined) {\n setInternalValue(value);\n committedValue.current = value;\n }\n }, [value]);\n\n // Auto-grow the field to fit its content (multi-line), so the height tracks the text\n // without an inner scrollbar. The contenteditable div grows on its own; the textarea\n // needs its height reset and re-measured.\n const autoSize = () => {\n if (!isWeb) return;\n if (richEnabled) {\n // innerHTML is set imperatively just before this runs, so the div hasn't been\n // laid out yet — measure after the next paint or the height is stale on entry.\n requestAnimationFrame(() => {\n const el = editableRef.current;\n if (el) setFieldHeight(el.offsetHeight + FIELD.framePadding * 2);\n });\n return;\n }\n const el = inputRef.current;\n if (!el) return;\n el.style.height = \"auto\";\n el.style.height = `${el.scrollHeight}px`;\n setFieldHeight(el.scrollHeight + FIELD.framePadding * 2);\n };\n\n useEffect(() => {\n if (!editing) return;\n // Controlled contenteditable: write innerHTML only when the incoming value differs\n // from the DOM, so echoing our own input doesn't reset the caret.\n if (richEnabled) {\n const el = editableRef.current;\n if (el && el.innerHTML !== currentValue) el.innerHTML = currentValue;\n }\n autoSize();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editing, currentValue, richEnabled]);\n\n const isError = !!(error || errorMessage);\n // For rich values, \"empty\" means no visible text once tags are stripped.\n const isFilled = richText\n ? stripHtml(currentValue).trim().length > 0\n : currentValue.length > 0;\n // Plain-text projection of the value — used by the textarea and the native fallback.\n const plainText = richText ? stripHtml(currentValue) : currentValue;\n const inputColors = theme.colors.control.input;\n const borderRadius = theme.shape.input.md.borderRadius;\n\n // Resolve effective typography: a named textStyle (heading/body token) overrides the\n // size-derived font. Padding / icon size always come from `size`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const typo = theme.typographyTokens as any;\n const textStyleToken = textStyle\n ? (typo.heading[textStyle] ?? typo.basic[textStyle])\n : null;\n const fontSize = textStyleToken ? textStyleToken.fontSize : FIELD.fontSize;\n const lineHeight = textStyleToken\n ? parseInt(String(textStyleToken.lineHeight), 10)\n : FIELD.lineHeight;\n const fontWeight = textStyleToken ? textStyleToken.fontWeight : 400;\n const fontFamily =\n textStyleToken && textStyleToken.lineHeightCategory === \"display\"\n ? theme.fonts.heading\n : theme.fonts.body;\n\n // Vertical offset for the floating controls — just below the field's bottom edge.\n // Defaults to the single-line height before the field has been measured.\n const controlsTop =\n (fieldHeight ?? lineHeight + FIELD.framePadding * 2) -\n FIELD.framePadding +\n 4;\n\n const enterEdit = () => {\n if (disabled || isEditing) return;\n setIsEditing(true);\n // Focus the field once it has mounted.\n setTimeout(focusField, 0);\n };\n\n // Rich-text input: read the contenteditable's HTML on each edit.\n const handleRichInput = (e: React.FormEvent<HTMLDivElement>) => {\n handleChangeText(e.currentTarget.innerHTML);\n };\n\n // Paste as plain text to avoid importing foreign markup/styles (no sanitizer here).\n const handlePaste = (e: React.ClipboardEvent<HTMLDivElement>) => {\n e.preventDefault();\n const text = e.clipboardData.getData(\"text/plain\");\n document.execCommand(\"insertText\", false, text);\n };\n\n const handleChangeText = (next: string) => {\n onChangeText?.(next);\n if (!isControlled) {\n setInternalValue(next);\n }\n };\n\n // Explicit confirm (button / shortcut) always reports the value — it is a deliberate\n // save action.\n const commitExplicit = () => {\n onConfirm?.(currentValue);\n committedValue.current = currentValue;\n };\n\n // Commit on blur only when the value actually changed, so clicking in and out (or a\n // confirm immediately followed by the unmount blur) doesn't re-fire onConfirm.\n const commitOnBlur = () => {\n if (currentValue !== committedValue.current) {\n onConfirm?.(currentValue);\n committedValue.current = currentValue;\n }\n };\n\n // Inline mode collapses back to the plain-text display; form mode stays open.\n const exitEdit = () => {\n if (!isFormMode) {\n setIsEditing(false);\n setFocused(false);\n focusTrigger();\n }\n };\n\n const handleConfirm = () => {\n commitExplicit();\n exitEdit();\n };\n\n const handleCancel = () => {\n // Revert to the last committed value.\n if (!isControlled) {\n setInternalValue(committedValue.current);\n }\n onCancel?.();\n exitEdit();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {\n // Enter inserts a new line (multi-line). Confirm with Cmd/Ctrl + Enter.\n // These gestures are consumed by the component (use onConfirm / onCancel), so the\n // forwarded onKeyDown does not also fire for them.\n if (e.key === \"Enter\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n handleConfirm();\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n handleCancel();\n return;\n }\n onKeyDown?.(e as React.KeyboardEvent<HTMLTextAreaElement>);\n };\n\n const handleFocus = () => setFocused(true);\n\n // Clicking outside commits the current value. Control / tool buttons prevent blur\n // via onMouseDown, so they fire their own action instead of committing here.\n const handleBlur = () => {\n setFocused(false);\n commitOnBlur();\n if (!isFormMode) {\n setIsEditing(false);\n }\n };\n\n // Resolve background / border colors based on state. Error takes precedence over\n // the focus state — per Figma the error variant keeps the input bg, not the focus\n // bg. A resting form-mode field looks like a standard input; a resting inline field\n // is transparent so it blends with surrounding content.\n let fieldBg = \"transparent\";\n let fieldBorder = \"transparent\";\n if (disabled) {\n fieldBg = inputColors.bgDisable;\n fieldBorder = inputColors.borderDisable;\n } else if (isError) {\n fieldBg = inputColors.bg;\n fieldBorder = theme.colors.border.alert;\n } else if (active) {\n fieldBg = theme.colors.control.focus.bg;\n fieldBorder = theme.colors.border.brand;\n } else if (isFormMode) {\n fieldBg = inputColors.bg;\n fieldBorder = inputColors.border;\n }\n\n const textColor = disabled ? inputColors.textDisable : inputColors.text;\n const displayColor = isFilled ? textColor : inputColors.placeholder;\n\n const preventBlur = isWeb\n ? { onMouseDown: (e: React.MouseEvent) => e.preventDefault() }\n : {};\n\n // Edit control uses the high-contrast \"mono primary\" surface (inverts per theme).\n const controlBg = theme.colors.control.mono.primary.bg;\n const controlBgHover = theme.colors.control.mono.primary.bgHover;\n const controlIconColor = theme.colors.control.mono.text.primary;\n\n // In inline display mode the field is an interactive trigger: render it as a real\n // button so it is focusable and activatable with Enter / Space by keyboard users.\n // In form mode the editor is always present, so there is no trigger.\n const isTrigger = !editing && !disabled;\n const triggerProps = isTrigger\n ? {\n as: \"button\" as const,\n type: \"button\" as const,\n id: triggerId,\n onPress: enterEdit,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n }\n : {\n \"aria-disabled\": disabled || undefined,\n };\n\n return (\n <Box\n position=\"relative\"\n width=\"100%\"\n testID={testID}\n className={className}\n >\n {/* Inline anchor — sized to a single text line so the field aligns with surrounding content. */}\n <Box position=\"relative\" width=\"100%\" style={{ minHeight: lineHeight }}>\n {/* Field layer — expands outward (negative inset) so the hover/focus highlight\n does not shift the inline text. */}\n <Box\n {...triggerProps}\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems={\n editing || isError || disabled ? \"flex-start\" : \"center\"\n }\n gap={8}\n paddingVertical={FIELD.framePadding}\n paddingHorizontal={FIELD.framePadding}\n backgroundColor={fieldBg}\n borderColor={fieldBorder}\n borderWidth={1}\n cursor={disabled ? \"not-allowed\" : editing ? \"text\" : \"pointer\"}\n hoverStyle={\n !disabled && !editing && !isError\n ? {\n backgroundColor: inputColors.bgHover,\n borderColor: inputColors.borderHover,\n }\n : undefined\n }\n style={{\n // Pin top/left/right to the anchor (inflated outward); leave the bottom\n // free so the field grows downward with multi-line content.\n top: -FIELD.framePadding,\n left: -FIELD.framePadding,\n right: -FIELD.framePadding,\n minHeight: lineHeight + FIELD.framePadding * 2,\n borderRadius,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n width: \"auto\",\n }}\n >\n {editing && richEnabled ? (\n // Rich-text editor (web): a contenteditable surface holding HTML.\n <Box flex={1} position=\"relative\">\n {!isFilled && (\n <Text\n aria-hidden\n color={inputColors.placeholder}\n fontSize={fontSize}\n fontWeight={String(fontWeight)}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n fontFamily,\n lineHeight: `${lineHeight}px`,\n pointerEvents: \"none\",\n }}\n >\n {placeholder}\n </Text>\n )}\n <div\n ref={editableRef}\n id={inputId}\n contentEditable={!disabled}\n suppressContentEditableWarning\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-invalid={isError || undefined}\n aria-describedby={errorMessage ? errorId : undefined}\n data-testid=\"input-edit__field\"\n onInput={handleRichInput}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n style={{\n outline: \"none\",\n minHeight: `${lineHeight}px`,\n color: textColor,\n fontFamily,\n fontWeight,\n fontSize: `${fontSize}px`,\n lineHeight: `${lineHeight}px`,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n />\n </Box>\n ) : editing ? (\n <Box flex={1}>\n <TextAreaPrimitive\n ref={inputRef}\n id={inputId}\n value={plainText}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n rows={rows ?? 1}\n color={textColor}\n fontSize={fontSize}\n fontFamily={fontFamily}\n placeholderTextColor={inputColors.placeholder}\n aria-invalid={isError || undefined}\n aria-describedby={errorMessage ? errorId : undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n data-testid=\"input-edit__field\"\n style={{\n display: \"block\",\n overflow: \"hidden\",\n fontWeight,\n lineHeight: `${lineHeight}px`,\n }}\n {...rest}\n />\n </Box>\n ) : richText && isWeb && isFilled ? (\n // Rich display (read-only): render the stored HTML.\n <div\n data-testid=\"input-edit__text\"\n dangerouslySetInnerHTML={{ __html: currentValue }}\n style={{\n flex: 1,\n color: textColor,\n fontFamily,\n fontWeight,\n fontSize: `${fontSize}px`,\n lineHeight: `${lineHeight}px`,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n />\n ) : (\n <Text\n color={displayColor}\n fontSize={fontSize}\n fontWeight={String(fontWeight)}\n data-testid=\"input-edit__text\"\n style={{\n flex: 1,\n fontFamily,\n lineHeight: `${lineHeight}px`,\n wordBreak: \"break-word\",\n // Preserve author line breaks in multi-line values.\n whiteSpace: \"pre-wrap\",\n }}\n >\n {isFilled ? plainText : placeholder}\n </Text>\n )}\n\n {/* Edit affordance — shown only in the resting inline display states\n (Default / Hover), matching Figma (hidden while editing and in error /\n disabled states). Decorative: the trigger button already carries the\n accessible name, so hide the icon from assistive tech. */}\n {icon && !editing && !isError && !disabled && (\n <Box alignItems=\"center\" justifyContent=\"center\" aria-hidden>\n <Icon size={FIELD.iconSize} color={textColor}>\n {editIcon ?? <Edit />}\n </Icon>\n </Box>\n )}\n </Box>\n </Box>\n\n {/* Floating confirm / cancel control — shown while the editor is active. */}\n {active && editControl && (\n <Box\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems=\"center\"\n backgroundColor={controlBg}\n data-testid=\"input-edit__edit-control\"\n style={{\n top: controlsTop,\n right: -FIELD.framePadding,\n borderRadius: 4,\n overflow: \"hidden\",\n ...(isWeb\n ? {\n boxShadow: POPOVER_SHADOW,\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n >\n <Box\n as=\"button\"\n type=\"button\"\n alignItems=\"center\"\n justifyContent=\"center\"\n backgroundColor={controlBg}\n borderWidth={0}\n padding={4}\n cursor=\"pointer\"\n onPress={handleConfirm}\n aria-label=\"Confirm\"\n data-testid=\"input-edit__confirm\"\n hoverStyle={{ backgroundColor: controlBgHover }}\n {...preventBlur}\n >\n <Icon size={CONTROL_ICON_SIZE} color={controlIconColor}>\n <Check />\n </Icon>\n </Box>\n <Box\n backgroundColor={theme.colors.border.inverse}\n style={{ width: 1, alignSelf: \"stretch\" }}\n />\n <Box\n as=\"button\"\n type=\"button\"\n alignItems=\"center\"\n justifyContent=\"center\"\n backgroundColor={controlBg}\n borderWidth={0}\n padding={4}\n cursor=\"pointer\"\n onPress={handleCancel}\n aria-label=\"Cancel\"\n data-testid=\"input-edit__cancel\"\n hoverStyle={{ backgroundColor: controlBgHover }}\n {...preventBlur}\n >\n <Icon size={CONTROL_ICON_SIZE} color={controlIconColor}>\n <Remove />\n </Icon>\n </Box>\n </Box>\n )}\n\n {/* Formatting tools — floating bar below-left, mirroring the confirm / cancel\n control. preventBlur keeps the input focused when a tool is pressed. */}\n {active && tools && (\n <Box\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={4}\n padding={4}\n backgroundColor={theme.colors.background.primary}\n data-testid=\"input-edit__tools\"\n style={{\n top: controlsTop,\n left: -FIELD.framePadding,\n borderRadius: 4,\n ...(isWeb\n ? {\n boxShadow: POPOVER_SHADOW,\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n {...preventBlur}\n >\n {tools}\n </Box>\n )}\n\n {/* Error message — a frosted popover callout with a pointer aimed at the field,\n matching the Figma tooltip treatment. */}\n {isError && errorMessage && (\n <Box\n position=\"relative\"\n style={{\n marginTop: FIELD.framePadding + 4,\n width: \"max-content\",\n maxWidth: \"100%\",\n ...(isWeb\n ? {\n filter: POPOVER_DROP_SHADOW,\n WebkitFilter: POPOVER_DROP_SHADOW,\n }\n : {}),\n }}\n >\n {/* Pointer (rotated square) at the top-left, tucked behind the bubble. */}\n <Box\n position=\"absolute\"\n backgroundColor={theme.colors.background.primary}\n style={{\n width: 8,\n height: 8,\n top: -3,\n left: 16,\n transform: \"rotate(45deg)\",\n }}\n />\n <Box\n backgroundColor={theme.colors.background.primary}\n paddingVertical={8}\n paddingHorizontal={12}\n style={{\n borderRadius: 4,\n ...(isWeb\n ? {\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n >\n <Text\n id={errorId}\n role=\"status\"\n aria-live=\"polite\"\n color={theme.colors.content.alert.primary}\n fontSize={FIELD.fontSize - 2}\n style={{ lineHeight: `${FIELD.lineHeight}px` }}\n >\n {errorMessage}\n </Text>\n </Box>\n </Box>\n )}\n </Box>\n );\n }\n);\n\nInputEdit.displayName = \"InputEdit\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","import React, { forwardRef } from \"react\";\nimport { TextInput as RNTextInput } from \"react-native\";\nimport { TextAreaPrimitiveProps } from \"@xsolla/xui-primitives-core\";\n\nexport const TextAreaPrimitive = forwardRef<\n RNTextInput,\n TextAreaPrimitiveProps\n>(\n (\n {\n value,\n placeholder,\n onChange,\n onChangeText,\n onFocus,\n onBlur,\n onKeyDown,\n disabled,\n readOnly,\n style,\n color,\n fontSize,\n fontFamily,\n placeholderTextColor,\n maxLength,\n rows,\n id,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-label\": ariaLabel,\n \"aria-disabled\": ariaDisabled,\n \"aria-invalid\": ariaInvalid,\n \"data-testid\": dataTestId,\n testID,\n },\n ref\n ) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const handleChangeText = (text: string) => {\n onChangeText?.(text);\n\n if (onChange) {\n const syntheticEvent = {\n target: { value: text },\n currentTarget: { value: text },\n type: \"change\",\n nativeEvent: { text },\n preventDefault: () => {},\n stopPropagation: () => {},\n isTrusted: false,\n } as unknown as React.ChangeEvent<HTMLTextAreaElement>;\n onChange(syntheticEvent);\n }\n };\n\n return (\n <RNTextInput\n ref={ref}\n value={value}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyPress={(e) => {\n if (onKeyDown) {\n onKeyDown({\n key: e.nativeEvent.key,\n preventDefault: () => {},\n } as any);\n }\n }}\n editable={!disabled && !readOnly}\n multiline={true}\n numberOfLines={rows || 4}\n style={[\n {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontFamily: resolvedFontFamily,\n flex: 1,\n padding: 0,\n textAlignVertical: \"top\",\n textAlign: (style as any)?.textAlign || \"left\",\n },\n style as any,\n ]}\n placeholderTextColor={placeholderTextColor}\n maxLength={maxLength}\n testID={dataTestId || testID || id}\n accessibilityLabel={ariaLabel}\n // RN AccessibilityState has no `invalid` / `readOnly`; surface via hint.\n accessibilityHint={\n [\n ariaInvalid ? \"Invalid\" : null,\n readOnly ? \"Read only\" : null,\n ariaDescribedBy,\n ]\n .filter(Boolean)\n .join(\". \") || undefined\n }\n accessibilityState={{\n disabled: disabled || ariaDisabled,\n }}\n accessible={true}\n />\n );\n }\n);\n\nTextAreaPrimitive.displayName = \"TextAreaPrimitive\";\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":"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","names":["React","forwardRef","jsx","View","jsx","jsx","jsx","forwardRef","React","el"]}
1
+ {"version":3,"sources":["../../src/InputEdit.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/TextArea.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["import React, {\n useState,\n useRef,\n useEffect,\n forwardRef,\n type TextareaHTMLAttributes,\n type ReactNode,\n} from \"react\";\n// prettier-ignore\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, TextAreaPrimitive, isWeb } from \"@xsolla/xui-primitives\";\nimport {\n useResolvedTheme,\n useId,\n type ThemeOverrideProps,\n} from \"@xsolla/xui-core\";\nimport { Edit, Check, Remove } from \"@xsolla/xui-icons-base\";\n\ntype InputEditMode = \"inline\" | \"form\";\n\n/**\n * Named typography styles, resolved from the theme's typography tokens. Drives the\n * field's font family / size / weight / line-height so the text can match surrounding\n * content (e.g. a heading) rather than only the fixed body sizes.\n */\ntype InputEditTextStyle =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"display\"\n | \"body-lg\"\n | \"body-md\"\n | \"body-sm\"\n | \"body-xs\"\n | \"body-xxs\";\n\nexport interface InputEditProps\n extends\n Omit<\n TextareaHTMLAttributes<HTMLTextAreaElement>,\n \"size\" | \"onChange\" | \"value\" | \"defaultValue\"\n >,\n ThemeOverrideProps {\n /**\n * Controlled value of the field.\n */\n value?: string;\n /**\n * Initial value for uncontrolled usage.\n */\n defaultValue?: string;\n /**\n * Placeholder shown when the field is empty.\n */\n placeholder?: string;\n /**\n * Change handler receiving the current text (HTML when `richText` is set).\n */\n onChangeText?: (text: string) => void;\n /**\n * Called when the edit is confirmed (check button or `Cmd`/`Ctrl` + `Enter`).\n */\n onConfirm?: (value: string) => void;\n /**\n * Called when the edit is cancelled (cross button or `Escape`). The value is reverted.\n */\n onCancel?: () => void;\n /**\n * Minimum number of visible text rows while editing.\n */\n rows?: number;\n /**\n * Show the floating confirm / cancel control while editing.\n */\n editControl?: boolean;\n /**\n * Show the edit affordance icon in display mode.\n */\n icon?: boolean;\n /**\n * Override the default edit (pencil) icon.\n */\n editIcon?: ReactNode;\n /**\n * Optional formatting toolbar shown in a floating bar below the field while editing\n * (e.g. text-align / bold / link `IconButton`s). Rendered to the left, mirroring the\n * confirm / cancel control on the right.\n */\n tools?: ReactNode;\n /**\n * Activation mode. `\"inline\"` (default) rests as plain text and reveals the editor on\n * click; `\"form\"` is always an open, editable field (like a standard form text area).\n */\n mode?: InputEditMode;\n /**\n * Named typography style applied to the text and editor (e.g. `\"h1\"`, `\"body-lg\"`).\n * Overrides the default font.\n */\n textStyle?: InputEditTextStyle;\n /**\n * Enable rich-text editing (web only). The field becomes a `contenteditable` surface\n * and `value` / `onChangeText` / `onConfirm` carry HTML. Wire a toolbar via `tools`\n * using `document.execCommand`. Falls back to a plain text field on React Native.\n * The HTML is not sanitized — sanitize before rendering untrusted values.\n */\n richText?: boolean;\n /**\n * Disable the control.\n */\n disabled?: boolean;\n /**\n * Highlight the control as invalid.\n */\n error?: boolean;\n /**\n * Error message displayed below the field (implies `error`).\n */\n errorMessage?: string;\n /**\n * Unique identifier for the input element. Used for accessibility linking.\n */\n id?: string;\n /**\n * Accessible label for screen readers (use when no visible label is present).\n */\n \"aria-label\"?: string;\n /**\n * ID of an external element that labels the field (e.g. a heading placed above it).\n */\n \"aria-labelledby\"?: string;\n testID?: string;\n /**\n * Optional class name applied to the root element (web).\n */\n className?: string;\n}\n\n// InputEdit has a single size (per the design). `textStyle` can still override the font.\nconst FIELD = {\n fontSize: 16,\n lineHeight: 18,\n framePadding: 11,\n iconSize: 16,\n};\n\n// Strip tags from an HTML value — used for empty detection and the native plain-text\n// fallback (React Native can't render contenteditable HTML inline).\nconst stripHtml = (html: string): string =>\n html.replace(/<[^>]*>/g, \"\").replace(/&nbsp;/gi, \" \");\n\nconst CONTROL_ICON_SIZE = 18;\nconst POPOVER_SHADOW =\n \"0px 6px 10px 4px rgba(7, 7, 8, 0.1), 0px 2px 3px 0px rgba(7, 7, 8, 0.2)\";\n// drop-shadow variant — follows the element's alpha shape so it wraps the bubble's\n// pointer (a plain box-shadow would clip at the rectangle edge).\nconst POPOVER_DROP_SHADOW =\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\";\n\n/**\n * A multi-line text field for editing freeform text. In `\"inline\"` mode it rests as\n * plain text and reveals a highlighted editor on click; in `\"form\"` mode it is always\n * an open, editable field. `Enter` inserts a new line; confirm via the floating control\n * or `Cmd`/`Ctrl` + `Enter`; clicking outside also commits. `Escape` cancels and\n * reverts.\n */\nexport const InputEdit = forwardRef<\n HTMLTextAreaElement | HTMLDivElement,\n InputEditProps\n>(\n (\n {\n value,\n defaultValue,\n placeholder = \"Placeholder\",\n onChangeText,\n onConfirm,\n onCancel,\n onKeyDown,\n editControl = true,\n icon = true,\n editIcon,\n tools,\n rows,\n mode = \"inline\",\n textStyle,\n richText = false,\n disabled = false,\n error = false,\n errorMessage,\n id: providedId,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n testID,\n className,\n themeMode,\n themeProductContext,\n ...rest\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState(\n value ?? defaultValue ?? \"\"\n );\n const currentValue = isControlled ? (value as string) : internalValue;\n\n const isFormMode = mode === \"form\";\n // In form mode the editor is always rendered; in inline mode it appears on activation.\n const [isEditing, setIsEditing] = useState(false);\n const editing = isFormMode || isEditing;\n // Whether the editor currently holds focus — gates the floating controls so a form\n // with several fields doesn't show controls on every one at rest.\n const [focused, setFocused] = useState(false);\n // The \"active\" (focus-styled, controls-visible) state. Inline mode keys off the edit\n // session (controls appear the moment you click, before focus lands); form mode keys\n // off real focus (so resting fields stay quiet).\n const active = isFormMode ? focused : isEditing;\n // Rich text only applies on web (contenteditable is DOM-only); native falls back to\n // the plain textarea.\n const richEnabled = richText && isWeb;\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const editableRef = useRef<HTMLDivElement>(null);\n const focusField = () => {\n if (richEnabled) editableRef.current?.focus();\n else inputRef.current?.focus();\n };\n // Last value reported via onConfirm (or the initial value) — used to dedupe commits\n // and to revert on cancel.\n const committedValue = useRef(currentValue);\n // Measured height of the field box, so the floating controls follow it as the\n // multi-line field grows.\n const [fieldHeight, setFieldHeight] = useState<number | null>(null);\n\n // Generate a unique, ARIA-safe id (useId() yields colons that are invalid in id attrs).\n const rawId = useId();\n const safeId = rawId.replace(/:/g, \"\");\n const inputId = providedId || `input-edit-${safeId}`;\n const errorId = `${inputId}-error`;\n const triggerId = `${inputId}-trigger`;\n\n // Return focus to the display trigger so keyboard users are not dropped to the body.\n const focusTrigger = () => {\n if (isWeb) {\n setTimeout(() => document.getElementById(triggerId)?.focus(), 0);\n }\n };\n\n // In rich mode the underlying element is the contenteditable div, not a textarea —\n // exposed honestly so consumers don't read `.value` off a div.\n React.useImperativeHandle(\n ref,\n () =>\n (richEnabled ? editableRef.current : inputRef.current) as\n | HTMLTextAreaElement\n | HTMLDivElement,\n [richEnabled]\n );\n\n // Keep internal value in sync with the controlled value. An externally-set value is\n // treated as the committed baseline.\n useEffect(() => {\n if (value !== undefined) {\n setInternalValue(value);\n committedValue.current = value;\n }\n }, [value]);\n\n // Auto-grow the field to fit its content (multi-line), so the height tracks the text\n // without an inner scrollbar. The contenteditable div grows on its own; the textarea\n // needs its height reset and re-measured.\n const autoSize = () => {\n if (!isWeb) return;\n if (richEnabled) {\n // innerHTML is set imperatively just before this runs, so the div hasn't been\n // laid out yet — measure after the next paint or the height is stale on entry.\n requestAnimationFrame(() => {\n const el = editableRef.current;\n if (el) setFieldHeight(el.offsetHeight + FIELD.framePadding * 2);\n });\n return;\n }\n const el = inputRef.current;\n if (!el) return;\n el.style.height = \"auto\";\n el.style.height = `${el.scrollHeight}px`;\n setFieldHeight(el.scrollHeight + FIELD.framePadding * 2);\n };\n\n useEffect(() => {\n if (!editing) return;\n // Controlled contenteditable: write innerHTML only when the incoming value differs\n // from the DOM, so echoing our own input doesn't reset the caret.\n if (richEnabled) {\n const el = editableRef.current;\n if (el && el.innerHTML !== currentValue) el.innerHTML = currentValue;\n }\n autoSize();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editing, currentValue, richEnabled]);\n\n const isError = !!(error || errorMessage);\n // For rich values, \"empty\" means no visible text once tags are stripped.\n const isFilled = richText\n ? stripHtml(currentValue).trim().length > 0\n : currentValue.length > 0;\n // Plain-text projection of the value — used by the textarea and the native fallback.\n const plainText = richText ? stripHtml(currentValue) : currentValue;\n const inputColors = theme.colors.control.input;\n const borderRadius = theme.shape.input.md.borderRadius;\n\n // Resolve effective typography: a named textStyle (heading/body token) overrides the\n // size-derived font. Padding / icon size always come from `size`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const typo = theme.typographyTokens as any;\n const textStyleToken = textStyle\n ? (typo.heading[textStyle] ?? typo.basic[textStyle])\n : null;\n const fontSize = textStyleToken ? textStyleToken.fontSize : FIELD.fontSize;\n const lineHeight = textStyleToken\n ? parseInt(String(textStyleToken.lineHeight), 10)\n : FIELD.lineHeight;\n const fontWeight = textStyleToken ? textStyleToken.fontWeight : 400;\n const fontFamily =\n textStyleToken && textStyleToken.lineHeightCategory === \"display\"\n ? theme.fonts.heading\n : theme.fonts.body;\n\n // Vertical offset for the floating controls — just below the field's bottom edge.\n // Defaults to the single-line height before the field has been measured.\n const controlsTop =\n (fieldHeight ?? lineHeight + FIELD.framePadding * 2) -\n FIELD.framePadding +\n 4;\n\n const enterEdit = () => {\n if (disabled || isEditing) return;\n setIsEditing(true);\n // Focus the field once it has mounted.\n setTimeout(focusField, 0);\n };\n\n // Rich-text input: read the contenteditable's HTML on each edit.\n const handleRichInput = (e: React.FormEvent<HTMLDivElement>) => {\n handleChangeText(e.currentTarget.innerHTML);\n };\n\n // Paste as plain text to avoid importing foreign markup/styles (no sanitizer here).\n const handlePaste = (e: React.ClipboardEvent<HTMLDivElement>) => {\n e.preventDefault();\n const text = e.clipboardData.getData(\"text/plain\");\n document.execCommand(\"insertText\", false, text);\n };\n\n const handleChangeText = (next: string) => {\n onChangeText?.(next);\n if (!isControlled) {\n setInternalValue(next);\n }\n };\n\n // Explicit confirm (button / shortcut) always reports the value — it is a deliberate\n // save action.\n const commitExplicit = () => {\n onConfirm?.(currentValue);\n committedValue.current = currentValue;\n };\n\n // Commit on blur only when the value actually changed, so clicking in and out (or a\n // confirm immediately followed by the unmount blur) doesn't re-fire onConfirm.\n const commitOnBlur = () => {\n if (currentValue !== committedValue.current) {\n onConfirm?.(currentValue);\n committedValue.current = currentValue;\n }\n };\n\n // Inline mode collapses back to the plain-text display; form mode stays open.\n const exitEdit = () => {\n if (!isFormMode) {\n setIsEditing(false);\n setFocused(false);\n focusTrigger();\n }\n };\n\n const handleConfirm = () => {\n commitExplicit();\n exitEdit();\n };\n\n const handleCancel = () => {\n // Revert to the last committed value.\n if (!isControlled) {\n setInternalValue(committedValue.current);\n }\n onCancel?.();\n exitEdit();\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {\n // Enter inserts a new line (multi-line). Confirm with Cmd/Ctrl + Enter.\n // These gestures are consumed by the component (use onConfirm / onCancel), so the\n // forwarded onKeyDown does not also fire for them.\n if (e.key === \"Enter\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n handleConfirm();\n return;\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n handleCancel();\n return;\n }\n onKeyDown?.(e as React.KeyboardEvent<HTMLTextAreaElement>);\n };\n\n const handleFocus = () => setFocused(true);\n\n // Clicking outside commits the current value. Control / tool buttons prevent blur\n // via onMouseDown, so they fire their own action instead of committing here.\n const handleBlur = () => {\n setFocused(false);\n commitOnBlur();\n if (!isFormMode) {\n setIsEditing(false);\n }\n };\n\n // Resolve background / border colors based on state. Error takes precedence over\n // the focus state — per Figma the error variant keeps the input bg, not the focus\n // bg. A resting form-mode field looks like a standard input; a resting inline field\n // is transparent so it blends with surrounding content.\n let fieldBg = \"transparent\";\n let fieldBorder = \"transparent\";\n if (disabled) {\n fieldBg = inputColors.bgDisable;\n fieldBorder = inputColors.borderDisable;\n } else if (isError) {\n fieldBg = inputColors.bg;\n fieldBorder = theme.colors.border.alert;\n } else if (active) {\n fieldBg = theme.colors.control.focus.bg;\n fieldBorder = theme.colors.border.brand;\n } else if (isFormMode) {\n fieldBg = inputColors.bg;\n fieldBorder = inputColors.border;\n }\n\n const textColor = disabled ? inputColors.textDisable : inputColors.text;\n const displayColor = isFilled ? textColor : inputColors.placeholder;\n\n const preventBlur = isWeb\n ? { onMouseDown: (e: React.MouseEvent) => e.preventDefault() }\n : {};\n\n // Edit control uses the high-contrast \"mono primary\" surface (inverts per theme).\n const controlBg = theme.colors.control.mono.primary.bg;\n const controlBgHover = theme.colors.control.mono.primary.bgHover;\n const controlIconColor = theme.colors.control.mono.text.primary;\n\n // In inline display mode the field is an interactive trigger: render it as a real\n // button so it is focusable and activatable with Enter / Space by keyboard users.\n // In form mode the editor is always present, so there is no trigger.\n const isTrigger = !editing && !disabled;\n const triggerProps = isTrigger\n ? {\n as: \"button\" as const,\n type: \"button\" as const,\n id: triggerId,\n onPress: enterEdit,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n }\n : {\n \"aria-disabled\": disabled || undefined,\n };\n\n return (\n <Box\n position=\"relative\"\n width=\"100%\"\n testID={testID}\n className={className}\n >\n {/* Inline anchor — sized to a single text line so the field aligns with surrounding content. */}\n <Box position=\"relative\" width=\"100%\" style={{ minHeight: lineHeight }}>\n {/* Field layer — expands outward (negative inset) so the hover/focus highlight\n does not shift the inline text. */}\n <Box\n {...triggerProps}\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems={\n editing || isError || disabled ? \"flex-start\" : \"center\"\n }\n gap={8}\n paddingVertical={FIELD.framePadding}\n paddingHorizontal={FIELD.framePadding}\n backgroundColor={fieldBg}\n borderColor={fieldBorder}\n borderWidth={1}\n cursor={disabled ? \"not-allowed\" : editing ? \"text\" : \"pointer\"}\n hoverStyle={\n !disabled && !editing && !isError\n ? {\n backgroundColor: inputColors.bgHover,\n borderColor: inputColors.borderHover,\n }\n : undefined\n }\n style={{\n // Pin top/left/right to the anchor (inflated outward); leave the bottom\n // free so the field grows downward with multi-line content.\n top: -FIELD.framePadding,\n left: -FIELD.framePadding,\n right: -FIELD.framePadding,\n minHeight: lineHeight + FIELD.framePadding * 2,\n borderRadius,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n width: \"auto\",\n }}\n >\n {editing && richEnabled ? (\n // Rich-text editor (web): a contenteditable surface holding HTML.\n <Box flex={1} position=\"relative\">\n {!isFilled && (\n <Text\n aria-hidden\n color={inputColors.placeholder}\n fontSize={fontSize}\n fontWeight={String(fontWeight)}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n fontFamily,\n lineHeight: `${lineHeight}px`,\n pointerEvents: \"none\",\n }}\n >\n {placeholder}\n </Text>\n )}\n <div\n ref={editableRef}\n id={inputId}\n contentEditable={!disabled}\n suppressContentEditableWarning\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-invalid={isError || undefined}\n aria-describedby={errorMessage ? errorId : undefined}\n data-testid=\"input-edit__field\"\n onInput={handleRichInput}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n style={{\n outline: \"none\",\n minHeight: `${lineHeight}px`,\n color: textColor,\n fontFamily,\n fontWeight,\n fontSize: `${fontSize}px`,\n lineHeight: `${lineHeight}px`,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n />\n </Box>\n ) : editing ? (\n <Box flex={1}>\n <TextAreaPrimitive\n ref={inputRef}\n id={inputId}\n value={plainText}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n rows={rows ?? 1}\n color={textColor}\n fontSize={fontSize}\n fontFamily={fontFamily}\n placeholderTextColor={inputColors.placeholder}\n aria-invalid={isError || undefined}\n aria-describedby={errorMessage ? errorId : undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n data-testid=\"input-edit__field\"\n style={{\n display: \"block\",\n overflow: \"hidden\",\n fontWeight,\n lineHeight: `${lineHeight}px`,\n }}\n {...rest}\n />\n </Box>\n ) : richText && isWeb && isFilled ? (\n // Rich display (read-only): render the stored HTML.\n <div\n data-testid=\"input-edit__text\"\n dangerouslySetInnerHTML={{ __html: currentValue }}\n style={{\n flex: 1,\n color: textColor,\n fontFamily,\n fontWeight,\n fontSize: `${fontSize}px`,\n lineHeight: `${lineHeight}px`,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n />\n ) : (\n <Text\n color={displayColor}\n fontSize={fontSize}\n fontWeight={String(fontWeight)}\n data-testid=\"input-edit__text\"\n style={{\n flex: 1,\n fontFamily,\n lineHeight: `${lineHeight}px`,\n wordBreak: \"break-word\",\n // Preserve author line breaks in multi-line values.\n whiteSpace: \"pre-wrap\",\n }}\n >\n {isFilled ? plainText : placeholder}\n </Text>\n )}\n\n {/* Edit affordance — shown only in the resting inline display states\n (Default / Hover), matching Figma (hidden while editing and in error /\n disabled states). Decorative: the trigger button already carries the\n accessible name, so hide the icon from assistive tech. */}\n {icon && !editing && !isError && !disabled && (\n <Box alignItems=\"center\" justifyContent=\"center\" aria-hidden>\n <Icon size={FIELD.iconSize} color={textColor}>\n {editIcon ?? <Edit />}\n </Icon>\n </Box>\n )}\n </Box>\n </Box>\n\n {/* Floating confirm / cancel control — shown while the editor is active. */}\n {active && editControl && (\n <Box\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems=\"center\"\n backgroundColor={controlBg}\n data-testid=\"input-edit__edit-control\"\n style={{\n top: controlsTop,\n right: -FIELD.framePadding,\n borderRadius: 4,\n overflow: \"hidden\",\n ...(isWeb\n ? {\n boxShadow: POPOVER_SHADOW,\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n >\n <Box\n as=\"button\"\n type=\"button\"\n alignItems=\"center\"\n justifyContent=\"center\"\n backgroundColor={controlBg}\n borderWidth={0}\n padding={4}\n cursor=\"pointer\"\n onPress={handleConfirm}\n aria-label=\"Confirm\"\n data-testid=\"input-edit__confirm\"\n hoverStyle={{ backgroundColor: controlBgHover }}\n {...preventBlur}\n >\n <Icon size={CONTROL_ICON_SIZE} color={controlIconColor}>\n <Check />\n </Icon>\n </Box>\n <Box\n backgroundColor={theme.colors.border.inverse}\n style={{ width: 1, alignSelf: \"stretch\" }}\n />\n <Box\n as=\"button\"\n type=\"button\"\n alignItems=\"center\"\n justifyContent=\"center\"\n backgroundColor={controlBg}\n borderWidth={0}\n padding={4}\n cursor=\"pointer\"\n onPress={handleCancel}\n aria-label=\"Cancel\"\n data-testid=\"input-edit__cancel\"\n hoverStyle={{ backgroundColor: controlBgHover }}\n {...preventBlur}\n >\n <Icon size={CONTROL_ICON_SIZE} color={controlIconColor}>\n <Remove />\n </Icon>\n </Box>\n </Box>\n )}\n\n {/* Formatting tools — floating bar below-left, mirroring the confirm / cancel\n control. preventBlur keeps the input focused when a tool is pressed. */}\n {active && tools && (\n <Box\n position=\"absolute\"\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={4}\n padding={4}\n backgroundColor={theme.colors.background.primary}\n data-testid=\"input-edit__tools\"\n style={{\n top: controlsTop,\n left: -FIELD.framePadding,\n borderRadius: 4,\n ...(isWeb\n ? {\n boxShadow: POPOVER_SHADOW,\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n {...preventBlur}\n >\n {tools}\n </Box>\n )}\n\n {/* Error message — a frosted popover callout with a pointer aimed at the field,\n matching the Figma tooltip treatment. */}\n {isError && errorMessage && (\n <Box\n position=\"relative\"\n style={{\n marginTop: FIELD.framePadding + 4,\n width: \"max-content\",\n maxWidth: \"100%\",\n ...(isWeb\n ? {\n filter: POPOVER_DROP_SHADOW,\n WebkitFilter: POPOVER_DROP_SHADOW,\n }\n : {}),\n }}\n >\n {/* Pointer (rotated square) at the top-left, tucked behind the bubble. */}\n <Box\n position=\"absolute\"\n backgroundColor={theme.colors.background.primary}\n style={{\n width: 8,\n height: 8,\n top: -3,\n left: 16,\n transform: \"rotate(45deg)\",\n }}\n />\n <Box\n backgroundColor={theme.colors.background.primary}\n paddingVertical={8}\n paddingHorizontal={12}\n style={{\n borderRadius: 4,\n ...(isWeb\n ? {\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n }\n : {}),\n }}\n >\n <Text\n id={errorId}\n role=\"status\"\n aria-live=\"polite\"\n color={theme.colors.content.alert.primary}\n fontSize={FIELD.fontSize - 2}\n style={{ lineHeight: `${FIELD.lineHeight}px` }}\n >\n {errorMessage}\n </Text>\n </Box>\n </Box>\n )}\n </Box>\n );\n }\n);\n\nInputEdit.displayName = \"InputEdit\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","import React, { forwardRef } from \"react\";\nimport { TextInput as RNTextInput } from \"react-native\";\nimport { TextAreaPrimitiveProps } from \"@xsolla/xui-primitives-core\";\n\nexport const TextAreaPrimitive = forwardRef<\n RNTextInput,\n TextAreaPrimitiveProps\n>(\n (\n {\n value,\n placeholder,\n onChange,\n onChangeText,\n onFocus,\n onBlur,\n onKeyDown,\n disabled,\n readOnly,\n style,\n color,\n fontSize,\n fontFamily,\n placeholderTextColor,\n maxLength,\n rows,\n id,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-label\": ariaLabel,\n \"aria-disabled\": ariaDisabled,\n \"aria-invalid\": ariaInvalid,\n \"data-testid\": dataTestId,\n testID,\n },\n ref\n ) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const handleChangeText = (text: string) => {\n onChangeText?.(text);\n\n if (onChange) {\n const syntheticEvent = {\n target: { value: text },\n currentTarget: { value: text },\n type: \"change\",\n nativeEvent: { text },\n preventDefault: () => {},\n stopPropagation: () => {},\n isTrusted: false,\n } as unknown as React.ChangeEvent<HTMLTextAreaElement>;\n onChange(syntheticEvent);\n }\n };\n\n return (\n <RNTextInput\n ref={ref}\n value={value}\n placeholder={placeholder}\n onChangeText={handleChangeText}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyPress={(e) => {\n if (onKeyDown) {\n onKeyDown({\n key: e.nativeEvent.key,\n preventDefault: () => {},\n } as any);\n }\n }}\n editable={!disabled && !readOnly}\n multiline={true}\n numberOfLines={rows || 4}\n style={[\n {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontFamily: resolvedFontFamily,\n flex: 1,\n padding: 0,\n textAlignVertical: \"top\",\n textAlign: (style as any)?.textAlign || \"left\",\n },\n style as any,\n ]}\n placeholderTextColor={placeholderTextColor}\n maxLength={maxLength}\n testID={dataTestId || testID || id}\n accessibilityLabel={ariaLabel}\n // RN AccessibilityState has no `invalid` / `readOnly`; surface via hint.\n accessibilityHint={\n [\n ariaInvalid ? \"Invalid\" : null,\n readOnly ? \"Read only\" : null,\n ariaDescribedBy,\n ]\n .filter(Boolean)\n .join(\". \") || undefined\n }\n accessibilityState={{\n disabled: disabled || ariaDisabled,\n }}\n accessible={true}\n />\n );\n }\n);\n\nTextAreaPrimitive.displayName = \"TextAreaPrimitive\";\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":"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","names":["React","forwardRef","jsx","View","jsx","jsx","jsx","forwardRef","React","el"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-input-edit",
3
- "version": "0.198.0",
3
+ "version": "0.200.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -13,9 +13,9 @@
13
13
  "test:coverage": "vitest run --coverage"
14
14
  },
15
15
  "dependencies": {
16
- "@xsolla/xui-core": "0.198.0",
17
- "@xsolla/xui-icons-base": "0.198.0",
18
- "@xsolla/xui-primitives-core": "0.198.0"
16
+ "@xsolla/xui-core": "0.200.0",
17
+ "@xsolla/xui-icons-base": "0.200.0",
18
+ "@xsolla/xui-primitives-core": "0.200.0"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": ">=16.8.0",