@xsolla/xui-input-color 0.184.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.
@@ -0,0 +1,916 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.tsx
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ InputColor: () => InputColor
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // src/InputColor.tsx
28
+ var import_react2 = require("react");
29
+
30
+ // ../../foundation/primitives-native/src/Box.tsx
31
+ var import_react_native = require("react-native");
32
+ var import_jsx_runtime = require("react/jsx-runtime");
33
+ var Box = ({
34
+ children,
35
+ onPress,
36
+ onLayout,
37
+ onMoveShouldSetResponder,
38
+ onResponderGrant,
39
+ onResponderMove,
40
+ onResponderRelease,
41
+ onResponderTerminate,
42
+ backgroundColor,
43
+ borderColor,
44
+ borderWidth,
45
+ borderBottomWidth,
46
+ borderBottomColor,
47
+ borderTopWidth,
48
+ borderTopColor,
49
+ borderLeftWidth,
50
+ borderLeftColor,
51
+ borderRightWidth,
52
+ borderRightColor,
53
+ borderRadius,
54
+ borderStyle,
55
+ height,
56
+ padding,
57
+ paddingHorizontal,
58
+ paddingVertical,
59
+ margin,
60
+ marginTop,
61
+ marginBottom,
62
+ marginLeft,
63
+ marginRight,
64
+ flexDirection,
65
+ alignItems,
66
+ justifyContent,
67
+ position,
68
+ top,
69
+ bottom,
70
+ left,
71
+ right,
72
+ width,
73
+ minWidth,
74
+ minHeight,
75
+ maxWidth,
76
+ maxHeight,
77
+ flex,
78
+ overflow,
79
+ zIndex,
80
+ hoverStyle,
81
+ pressStyle,
82
+ style,
83
+ "data-testid": dataTestId,
84
+ testID,
85
+ as,
86
+ src,
87
+ alt,
88
+ ...rest
89
+ }) => {
90
+ const getContainerStyle = (pressed) => ({
91
+ backgroundColor: pressed && pressStyle?.backgroundColor ? pressStyle.backgroundColor : backgroundColor,
92
+ borderColor,
93
+ borderWidth,
94
+ borderBottomWidth,
95
+ borderBottomColor,
96
+ borderTopWidth,
97
+ borderTopColor,
98
+ borderLeftWidth,
99
+ borderLeftColor,
100
+ borderRightWidth,
101
+ borderRightColor,
102
+ borderRadius,
103
+ borderStyle,
104
+ overflow,
105
+ zIndex,
106
+ height,
107
+ width,
108
+ minWidth,
109
+ minHeight,
110
+ maxWidth,
111
+ maxHeight,
112
+ padding,
113
+ paddingHorizontal,
114
+ paddingVertical,
115
+ margin,
116
+ marginTop,
117
+ marginBottom,
118
+ marginLeft,
119
+ marginRight,
120
+ flexDirection,
121
+ alignItems,
122
+ justifyContent,
123
+ position,
124
+ top,
125
+ bottom,
126
+ left,
127
+ right,
128
+ flex,
129
+ ...style
130
+ });
131
+ const finalTestID = dataTestId || testID;
132
+ const {
133
+ role,
134
+ tabIndex,
135
+ onKeyDown,
136
+ onKeyUp,
137
+ "aria-label": _ariaLabel,
138
+ "aria-labelledby": _ariaLabelledBy,
139
+ "aria-current": _ariaCurrent,
140
+ "aria-disabled": _ariaDisabled,
141
+ "aria-live": _ariaLive,
142
+ className,
143
+ "data-testid": _dataTestId,
144
+ ...nativeRest
145
+ } = rest;
146
+ if (as === "img" && src) {
147
+ const imageStyle = {
148
+ width,
149
+ height,
150
+ borderRadius,
151
+ position,
152
+ top,
153
+ bottom,
154
+ left,
155
+ right,
156
+ ...style
157
+ };
158
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
159
+ import_react_native.Image,
160
+ {
161
+ source: { uri: src },
162
+ style: imageStyle,
163
+ testID: finalTestID,
164
+ resizeMode: "cover",
165
+ ...nativeRest
166
+ }
167
+ );
168
+ }
169
+ if (onPress) {
170
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
171
+ import_react_native.Pressable,
172
+ {
173
+ onPress,
174
+ onLayout,
175
+ onMoveShouldSetResponder,
176
+ onResponderGrant,
177
+ onResponderMove,
178
+ onResponderRelease,
179
+ onResponderTerminate,
180
+ style: ({ pressed }) => getContainerStyle(pressed),
181
+ testID: finalTestID,
182
+ ...nativeRest,
183
+ children
184
+ }
185
+ );
186
+ }
187
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
188
+ import_react_native.View,
189
+ {
190
+ style: getContainerStyle(),
191
+ testID: finalTestID,
192
+ onLayout,
193
+ onMoveShouldSetResponder,
194
+ onResponderGrant,
195
+ onResponderMove,
196
+ onResponderRelease,
197
+ onResponderTerminate,
198
+ ...nativeRest,
199
+ children
200
+ }
201
+ );
202
+ };
203
+
204
+ // ../../foundation/primitives-native/src/Text.tsx
205
+ var import_react_native2 = require("react-native");
206
+ var import_jsx_runtime2 = require("react/jsx-runtime");
207
+ var roleMap = {
208
+ alert: "alert",
209
+ heading: "header",
210
+ button: "button",
211
+ link: "link",
212
+ text: "text"
213
+ };
214
+ var parseNumericValue = (value) => {
215
+ if (value === void 0) return void 0;
216
+ if (typeof value === "number") return value;
217
+ const parsed = parseFloat(value);
218
+ return isNaN(parsed) ? void 0 : parsed;
219
+ };
220
+ var Text = ({
221
+ children,
222
+ color,
223
+ fontSize,
224
+ fontWeight,
225
+ fontFamily,
226
+ textAlign,
227
+ lineHeight,
228
+ numberOfLines,
229
+ id,
230
+ role,
231
+ testID,
232
+ "data-testid": dataTestId,
233
+ style: styleProp,
234
+ ...props
235
+ }) => {
236
+ let resolvedFontFamily = fontFamily ? fontFamily.split(",")[0].replace(/['"]/g, "").trim() : void 0;
237
+ if (resolvedFontFamily === "Pilat Wide" || resolvedFontFamily === "Pilat Wide Bold" || resolvedFontFamily === "Aktiv Grotesk") {
238
+ resolvedFontFamily = void 0;
239
+ }
240
+ const incomingStyle = import_react_native2.StyleSheet.flatten(styleProp);
241
+ const baseStyle = {
242
+ color: color ?? incomingStyle?.color,
243
+ fontSize: typeof fontSize === "number" ? fontSize : void 0,
244
+ fontWeight,
245
+ fontFamily: resolvedFontFamily,
246
+ textDecorationLine: props.textDecoration,
247
+ textAlign: textAlign ?? incomingStyle?.textAlign,
248
+ lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),
249
+ marginTop: parseNumericValue(
250
+ incomingStyle?.marginTop
251
+ ),
252
+ marginBottom: parseNumericValue(
253
+ incomingStyle?.marginBottom
254
+ )
255
+ };
256
+ const accessibilityRole = role ? roleMap[role] : void 0;
257
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
258
+ import_react_native2.Text,
259
+ {
260
+ style: baseStyle,
261
+ numberOfLines,
262
+ testID: dataTestId || testID || id,
263
+ accessibilityRole,
264
+ children
265
+ }
266
+ );
267
+ };
268
+
269
+ // ../../foundation/primitives-native/src/Input.tsx
270
+ var import_react = require("react");
271
+ var import_react_native3 = require("react-native");
272
+ var import_jsx_runtime3 = require("react/jsx-runtime");
273
+ var keyboardTypeMap = {
274
+ text: "default",
275
+ number: "numeric",
276
+ email: "email-address",
277
+ tel: "phone-pad",
278
+ url: "url",
279
+ decimal: "decimal-pad"
280
+ };
281
+ var inputModeToKeyboardType = {
282
+ none: "default",
283
+ text: "default",
284
+ decimal: "decimal-pad",
285
+ numeric: "number-pad",
286
+ tel: "phone-pad",
287
+ search: "default",
288
+ email: "email-address",
289
+ url: "url"
290
+ };
291
+ var autoCompleteToTextContentType = {
292
+ "one-time-code": "oneTimeCode",
293
+ email: "emailAddress",
294
+ username: "username",
295
+ password: "password",
296
+ "new-password": "newPassword",
297
+ tel: "telephoneNumber",
298
+ "postal-code": "postalCode",
299
+ name: "name"
300
+ };
301
+ var InputPrimitive = (0, import_react.forwardRef)(
302
+ ({
303
+ value,
304
+ placeholder,
305
+ onChange,
306
+ onChangeText,
307
+ onFocus,
308
+ onBlur,
309
+ onKeyDown,
310
+ disabled,
311
+ secureTextEntry,
312
+ style,
313
+ color,
314
+ fontSize,
315
+ fontFamily,
316
+ placeholderTextColor,
317
+ maxLength,
318
+ type,
319
+ inputMode,
320
+ autoComplete,
321
+ id,
322
+ "aria-describedby": ariaDescribedBy,
323
+ "aria-label": ariaLabel,
324
+ "aria-disabled": ariaDisabled,
325
+ "data-testid": dataTestId,
326
+ testID
327
+ }, ref) => {
328
+ const handleChangeText = (text) => {
329
+ onChangeText?.(text);
330
+ if (onChange) {
331
+ const syntheticEvent = {
332
+ target: { value: text },
333
+ currentTarget: { value: text },
334
+ type: "change",
335
+ nativeEvent: { text },
336
+ preventDefault: () => {
337
+ },
338
+ stopPropagation: () => {
339
+ },
340
+ isTrusted: false
341
+ };
342
+ onChange(syntheticEvent);
343
+ }
344
+ };
345
+ const keyboardType = inputMode ? inputModeToKeyboardType[inputMode] || "default" : type ? keyboardTypeMap[type] || "default" : "default";
346
+ const textContentType = autoComplete ? autoCompleteToTextContentType[autoComplete] : void 0;
347
+ let resolvedFontFamily = fontFamily ? fontFamily.split(",")[0].replace(/['"]/g, "").trim() : void 0;
348
+ if (resolvedFontFamily === "Pilat Wide" || resolvedFontFamily === "Pilat Wide Bold" || resolvedFontFamily === "Aktiv Grotesk") {
349
+ resolvedFontFamily = void 0;
350
+ }
351
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
352
+ import_react_native3.TextInput,
353
+ {
354
+ ref,
355
+ value,
356
+ placeholder,
357
+ onChangeText: handleChangeText,
358
+ onFocus,
359
+ onBlur,
360
+ onKeyPress: (e) => {
361
+ if (onKeyDown) {
362
+ onKeyDown({
363
+ key: e.nativeEvent.key,
364
+ preventDefault: () => {
365
+ }
366
+ });
367
+ }
368
+ },
369
+ editable: !disabled,
370
+ secureTextEntry: secureTextEntry || type === "password",
371
+ keyboardType,
372
+ textContentType,
373
+ style: [
374
+ {
375
+ color,
376
+ fontSize: typeof fontSize === "number" ? fontSize : void 0,
377
+ fontFamily: resolvedFontFamily,
378
+ flex: 1,
379
+ padding: 0,
380
+ textAlign: style?.textAlign || "left"
381
+ },
382
+ style
383
+ ],
384
+ placeholderTextColor,
385
+ maxLength,
386
+ testID: dataTestId || testID || id,
387
+ accessibilityLabel: ariaLabel,
388
+ accessibilityHint: ariaDescribedBy,
389
+ accessibilityState: {
390
+ disabled: disabled || ariaDisabled
391
+ },
392
+ accessible: true
393
+ }
394
+ );
395
+ }
396
+ );
397
+ InputPrimitive.displayName = "InputPrimitive";
398
+
399
+ // ../../foundation/primitives-native/src/index.tsx
400
+ var isWeb = false;
401
+
402
+ // src/InputColor.tsx
403
+ var import_xui_core = require("@xsolla/xui-core");
404
+ var import_jsx_runtime4 = require("react/jsx-runtime");
405
+ var clamp = (n, min, max) => Math.min(Math.max(n, min), max);
406
+ var HEX_CHARS = /[^0-9a-fA-F]/g;
407
+ function hexToRgba(hex) {
408
+ let h = (hex || "").replace(/^#/, "");
409
+ if (h.length === 3 || h.length === 4) {
410
+ h = h.split("").map((c) => c + c).join("");
411
+ }
412
+ const r = parseInt(h.slice(0, 2), 16);
413
+ const g = parseInt(h.slice(2, 4), 16);
414
+ const b = parseInt(h.slice(4, 6), 16);
415
+ const a = h.length >= 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1;
416
+ return {
417
+ r: Number.isNaN(r) ? 0 : r,
418
+ g: Number.isNaN(g) ? 0 : g,
419
+ b: Number.isNaN(b) ? 0 : b,
420
+ a: Number.isNaN(a) ? 1 : parseFloat(a.toFixed(2))
421
+ };
422
+ }
423
+ function rgbaToHex({ r, g, b, a }, includeAlpha) {
424
+ const toHex = (n) => Math.round(clamp(n, 0, 255)).toString(16).padStart(2, "0");
425
+ const alpha = includeAlpha ? toHex(clamp(a, 0, 1) * 255) : "";
426
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}${alpha}`.toUpperCase();
427
+ }
428
+ var SWATCH_SIZE = {
429
+ xl: 36,
430
+ lg: 32,
431
+ md: 26,
432
+ sm: 20,
433
+ xs: 14
434
+ };
435
+ var ALPHA_WIDTH = {
436
+ xl: 96,
437
+ lg: 86,
438
+ md: 77,
439
+ sm: 67,
440
+ xs: 58
441
+ };
442
+ var FRAME_GAP = {
443
+ xl: 10,
444
+ lg: 10,
445
+ md: 8,
446
+ sm: 6,
447
+ xs: 4
448
+ };
449
+ var CHECKERBOARD = "conic-gradient(rgba(0,0,0,0.45) 25%, transparent 0 50%, rgba(0,0,0,0.45) 0 75%, transparent 0)";
450
+ function cornerRadii(corner, radius) {
451
+ const map = {
452
+ all: [radius, radius, radius, radius],
453
+ left: [radius, 0, 0, radius],
454
+ right: [0, radius, radius, 0],
455
+ middle: [0, 0, 0, 0]
456
+ };
457
+ const [tl, tr, br, bl] = map[corner];
458
+ return {
459
+ borderTopLeftRadius: tl,
460
+ borderTopRightRadius: tr,
461
+ borderBottomRightRadius: br,
462
+ borderBottomLeftRadius: bl
463
+ };
464
+ }
465
+ function ColorSwatch({
466
+ size,
467
+ rgba,
468
+ transparency,
469
+ borderColor
470
+ }) {
471
+ const solid = `rgb(${rgba.r}, ${rgba.g}, ${rgba.b})`;
472
+ const withAlpha = `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`;
473
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
474
+ Box,
475
+ {
476
+ width: size,
477
+ height: size,
478
+ position: "relative",
479
+ borderColor,
480
+ borderWidth: 1,
481
+ style: { borderRadius: 4, overflow: "hidden" },
482
+ "data-testid": "input-color__swatch-preview",
483
+ children: [
484
+ transparency && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
485
+ Box,
486
+ {
487
+ "aria-hidden": true,
488
+ style: {
489
+ position: "absolute",
490
+ inset: 0,
491
+ backgroundImage: CHECKERBOARD,
492
+ backgroundSize: "8px 8px",
493
+ opacity: 0.2
494
+ }
495
+ }
496
+ ),
497
+ transparency ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
498
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
499
+ Box,
500
+ {
501
+ style: {
502
+ position: "absolute",
503
+ top: 0,
504
+ bottom: 0,
505
+ left: 0,
506
+ right: "50%",
507
+ backgroundColor: solid
508
+ }
509
+ }
510
+ ),
511
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
512
+ Box,
513
+ {
514
+ style: {
515
+ position: "absolute",
516
+ top: 0,
517
+ bottom: 0,
518
+ left: "50%",
519
+ right: 0,
520
+ backgroundColor: withAlpha
521
+ }
522
+ }
523
+ )
524
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
525
+ Box,
526
+ {
527
+ style: { position: "absolute", inset: 0, backgroundColor: solid }
528
+ }
529
+ )
530
+ ]
531
+ }
532
+ );
533
+ }
534
+ function TextField({
535
+ value,
536
+ onCommit,
537
+ sanitize,
538
+ maxLength,
539
+ textAlign = "left",
540
+ color,
541
+ fontSize,
542
+ fontFamily,
543
+ ariaLabel,
544
+ inputMode = "text",
545
+ step,
546
+ testID,
547
+ onFocus,
548
+ onBlur
549
+ }) {
550
+ const [text, setText] = (0, import_react2.useState)(value);
551
+ const isFocusedRef = (0, import_react2.useRef)(false);
552
+ (0, import_react2.useEffect)(() => {
553
+ if (!isFocusedRef.current) setText(value);
554
+ }, [value]);
555
+ const handleChange = (e) => {
556
+ const next = sanitize(e.target.value);
557
+ setText(next);
558
+ onCommit(next);
559
+ };
560
+ const handleFocus = () => {
561
+ isFocusedRef.current = true;
562
+ onFocus();
563
+ };
564
+ const handleBlur = () => {
565
+ isFocusedRef.current = false;
566
+ setText(value);
567
+ onBlur();
568
+ };
569
+ const handleKeyDown = (e) => {
570
+ if (e.key === "Enter") {
571
+ e.currentTarget.blur();
572
+ return;
573
+ }
574
+ if (step && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
575
+ e.preventDefault();
576
+ const current = Number.parseInt(text, 10);
577
+ const base = Number.isNaN(current) ? 0 : current;
578
+ const next = String(
579
+ clamp(base + (e.key === "ArrowUp" ? 1 : -1), step.min, step.max)
580
+ );
581
+ setText(next);
582
+ onCommit(next);
583
+ }
584
+ };
585
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box, { flex: 1, height: "100%", justifyContent: "center", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
586
+ InputPrimitive,
587
+ {
588
+ value: text,
589
+ onChange: handleChange,
590
+ onFocus: handleFocus,
591
+ onBlur: handleBlur,
592
+ onKeyDown: handleKeyDown,
593
+ type: "text",
594
+ inputMode,
595
+ maxLength,
596
+ color,
597
+ fontSize,
598
+ fontFamily,
599
+ "aria-label": ariaLabel,
600
+ "data-testid": testID,
601
+ style: textAlign === "center" ? { textAlign: "center" } : void 0
602
+ }
603
+ ) });
604
+ }
605
+ var CHANNEL_LABEL = {
606
+ red: "Red channel",
607
+ green: "Green channel",
608
+ blue: "Blue channel",
609
+ alpha: "Opacity percentage"
610
+ };
611
+ var InputColor = (0, import_react2.forwardRef)(
612
+ ({
613
+ value,
614
+ defaultValue,
615
+ onChange,
616
+ onSwatchClick,
617
+ type = "color-hex",
618
+ transparency = false,
619
+ size = "md",
620
+ label,
621
+ id: providedId,
622
+ "aria-label": ariaLabel,
623
+ testID,
624
+ themeMode,
625
+ themeProductContext
626
+ }, ref) => {
627
+ const { theme } = (0, import_xui_core.useResolvedTheme)({ themeMode, themeProductContext });
628
+ const [internalValue, setInternalValue] = (0, import_react2.useState)(
629
+ value ?? defaultValue ?? "#000000"
630
+ );
631
+ (0, import_react2.useEffect)(() => {
632
+ if (value !== void 0) setInternalValue(value);
633
+ }, [value]);
634
+ const currentValue = internalValue;
635
+ const [focusedKey, setFocusedKey] = (0, import_react2.useState)(null);
636
+ const [liveMessage, setLiveMessage] = (0, import_react2.useState)("");
637
+ const rawId = (0, import_xui_core.useId)();
638
+ const safeId = rawId.replace(/:/g, "");
639
+ const inputId = providedId || `input-color-${safeId}`;
640
+ const labelId = `${inputId}-label`;
641
+ const rgba = (0, import_react2.useMemo)(() => hexToRgba(currentValue), [currentValue]);
642
+ const sizeStyles = theme.sizing.input(size);
643
+ const inputColors = theme.colors.control.input;
644
+ const borderRadius = theme.shape.input[size].borderRadius;
645
+ const swatchSize = SWATCH_SIZE[size];
646
+ const showSwatch = type === "color" || type === "color-hex" || type === "color-rgb";
647
+ const isHex = type === "hex" || type === "color-hex";
648
+ const isRgb = type === "rgb" || type === "color-rgb";
649
+ const isSwatchOnly = type === "color";
650
+ const textColor = inputColors.text;
651
+ const placeholderColor = inputColors.placeholder;
652
+ const fontFamily = theme.fonts.body;
653
+ const emit = (next) => {
654
+ setInternalValue(next);
655
+ setLiveMessage(`Color updated to ${next}`);
656
+ onChange?.(next);
657
+ };
658
+ const emitFromRgba = (next) => emit(rgbaToHex(next, transparency));
659
+ const segmentVisuals = (focused) => {
660
+ let backgroundColor = inputColors.bg;
661
+ let borderColor = inputColors.border;
662
+ let outlineColor;
663
+ if (focused) {
664
+ backgroundColor = theme.colors.control.focus.bg;
665
+ outlineColor = theme.colors.border.brand;
666
+ }
667
+ return { backgroundColor, borderColor, outlineColor };
668
+ };
669
+ const renderSegment = (key, corner, content, opts = {}) => {
670
+ const focused = focusedKey === key;
671
+ const { backgroundColor, borderColor, outlineColor } = segmentVisuals(focused);
672
+ const width = opts.square ? sizeStyles.height : opts.width;
673
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
674
+ Box,
675
+ {
676
+ backgroundColor,
677
+ borderColor,
678
+ borderWidth: 1,
679
+ height: sizeStyles.height,
680
+ width,
681
+ flex: opts.flex,
682
+ flexDirection: "row",
683
+ alignItems: "center",
684
+ justifyContent: opts.square ? "center" : "flex-start",
685
+ gap: FRAME_GAP[size],
686
+ paddingHorizontal: opts.square ? 0 : sizeStyles.paddingHorizontal,
687
+ position: "relative",
688
+ style: {
689
+ ...cornerRadii(corner, borderRadius),
690
+ minWidth: opts.square ? void 0 : 40,
691
+ ...outlineColor && isWeb ? { outline: `1px solid ${outlineColor}`, outlineOffset: "-1px" } : outlineColor && !isWeb ? { borderColor: outlineColor } : {}
692
+ },
693
+ hoverStyle: !focused ? {
694
+ backgroundColor: inputColors.bgHover,
695
+ borderColor: inputColors.borderHover
696
+ } : void 0,
697
+ children: content
698
+ },
699
+ key
700
+ );
701
+ };
702
+ const swatchVisual = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
703
+ ColorSwatch,
704
+ {
705
+ size: swatchSize,
706
+ rgba,
707
+ transparency,
708
+ borderColor: theme.colors.border.secondary
709
+ }
710
+ );
711
+ const swatchNode = isSwatchOnly ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
712
+ Box,
713
+ {
714
+ as: "button",
715
+ type: "button",
716
+ onPress: () => onSwatchClick?.(),
717
+ cursor: "pointer",
718
+ backgroundColor: "transparent",
719
+ borderWidth: 0,
720
+ padding: 0,
721
+ alignItems: "center",
722
+ justifyContent: "center",
723
+ "aria-label": "Open color picker",
724
+ "data-testid": "input-color__swatch",
725
+ onFocus: () => setFocusedKey("swatch"),
726
+ onBlur: () => setFocusedKey(null),
727
+ children: swatchVisual
728
+ }
729
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
730
+ Box,
731
+ {
732
+ "aria-hidden": true,
733
+ alignItems: "center",
734
+ justifyContent: "center",
735
+ "data-testid": "input-color__swatch-decorative",
736
+ children: swatchVisual
737
+ }
738
+ );
739
+ const hexContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
740
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
741
+ Text,
742
+ {
743
+ color: placeholderColor,
744
+ fontSize: sizeStyles.fontSize,
745
+ style: { lineHeight: `${sizeStyles.lineHeight}px` },
746
+ children: "#"
747
+ }
748
+ ),
749
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
750
+ TextField,
751
+ {
752
+ value: rgbaToHex(rgba, false).replace(/^#/, ""),
753
+ sanitize: (t) => t.replace(HEX_CHARS, "").toUpperCase(),
754
+ maxLength: 6,
755
+ onCommit: (digits) => {
756
+ if (digits.length === 3 || digits.length === 6) {
757
+ const next = hexToRgba(`#${digits}`);
758
+ emitFromRgba({ ...next, a: rgba.a });
759
+ }
760
+ },
761
+ color: textColor,
762
+ fontSize: sizeStyles.fontSize,
763
+ fontFamily,
764
+ ariaLabel: "Hex color value",
765
+ testID: "input-color__hex",
766
+ onFocus: () => setFocusedKey("hex"),
767
+ onBlur: () => setFocusedKey(null)
768
+ }
769
+ )
770
+ ] });
771
+ const channelContent = (channel) => {
772
+ const isAlpha = channel === "alpha";
773
+ const display = isAlpha ? Math.round(rgba.a * 100) : rgba[channel[0]];
774
+ const field = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
775
+ TextField,
776
+ {
777
+ value: String(display),
778
+ inputMode: "numeric",
779
+ sanitize: (t) => t.replace(/[^0-9]/g, ""),
780
+ maxLength: 3,
781
+ step: isAlpha ? { min: 0, max: 100 } : { min: 0, max: 255 },
782
+ onCommit: (t) => {
783
+ if (t === "") return;
784
+ const num = parseInt(t, 10);
785
+ if (Number.isNaN(num)) return;
786
+ if (isAlpha) {
787
+ emitFromRgba({ ...rgba, a: clamp(num, 0, 100) / 100 });
788
+ } else {
789
+ const k = channel[0];
790
+ emitFromRgba({ ...rgba, [k]: clamp(num, 0, 255) });
791
+ }
792
+ },
793
+ color: textColor,
794
+ fontSize: sizeStyles.fontSize,
795
+ fontFamily,
796
+ ariaLabel: CHANNEL_LABEL[channel],
797
+ testID: `input-color__channel-${channel}`,
798
+ onFocus: () => setFocusedKey(`channel-${channel}`),
799
+ onBlur: () => setFocusedKey(null)
800
+ }
801
+ );
802
+ if (!isAlpha) return field;
803
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
804
+ field,
805
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
806
+ Text,
807
+ {
808
+ color: placeholderColor,
809
+ fontSize: sizeStyles.fontSize,
810
+ style: { lineHeight: `${sizeStyles.lineHeight}px` },
811
+ children: "%"
812
+ }
813
+ )
814
+ ] });
815
+ };
816
+ const cells = [];
817
+ if (isSwatchOnly) {
818
+ cells.push({ key: "swatch", content: swatchNode, square: true });
819
+ } else if (isHex) {
820
+ cells.push({
821
+ key: "field",
822
+ flex: 1,
823
+ content: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
824
+ showSwatch && swatchNode,
825
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box, { flex: 1, flexDirection: "row", alignItems: "center", gap: 4, children: hexContent })
826
+ ] })
827
+ });
828
+ } else if (isRgb) {
829
+ if (showSwatch) {
830
+ cells.push({ key: "swatch", content: swatchNode, square: true });
831
+ }
832
+ ["red", "green", "blue"].forEach(
833
+ (channel) => cells.push({
834
+ key: `channel-${channel}`,
835
+ content: channelContent(channel),
836
+ flex: 1
837
+ })
838
+ );
839
+ }
840
+ if (transparency) {
841
+ cells.push({
842
+ key: "channel-alpha",
843
+ content: channelContent("alpha"),
844
+ width: ALPHA_WIDTH[size]
845
+ });
846
+ }
847
+ const control = cells.map((cell, i) => {
848
+ const corner = cells.length === 1 ? "all" : i === 0 ? "left" : i === cells.length - 1 ? "right" : "middle";
849
+ return renderSegment(cell.key, corner, cell.content, {
850
+ flex: cell.flex,
851
+ width: cell.width,
852
+ square: cell.square
853
+ });
854
+ });
855
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
856
+ Box,
857
+ {
858
+ ref,
859
+ flexDirection: "column",
860
+ gap: sizeStyles.fieldGap,
861
+ width: isSwatchOnly ? void 0 : "100%",
862
+ testID,
863
+ children: [
864
+ label && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box, { as: "label", id: labelId, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
865
+ Text,
866
+ {
867
+ color: theme.colors.content.secondary,
868
+ fontSize: sizeStyles.fontSize - 2,
869
+ fontWeight: "500",
870
+ children: label
871
+ }
872
+ ) }),
873
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
874
+ Box,
875
+ {
876
+ flexDirection: "row",
877
+ alignItems: "center",
878
+ gap: 2,
879
+ width: isSwatchOnly ? void 0 : "100%",
880
+ role: "group",
881
+ "aria-labelledby": label ? labelId : void 0,
882
+ "aria-label": !label ? ariaLabel : void 0,
883
+ children: control
884
+ }
885
+ ),
886
+ isWeb && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
887
+ Box,
888
+ {
889
+ role: "status",
890
+ "aria-live": "polite",
891
+ "data-testid": "input-color__live",
892
+ style: {
893
+ position: "absolute",
894
+ width: 1,
895
+ height: 1,
896
+ padding: 0,
897
+ margin: -1,
898
+ overflow: "hidden",
899
+ clip: "rect(0 0 0 0)",
900
+ whiteSpace: "nowrap",
901
+ border: 0
902
+ },
903
+ children: liveMessage
904
+ }
905
+ )
906
+ ]
907
+ }
908
+ );
909
+ }
910
+ );
911
+ InputColor.displayName = "InputColor";
912
+ // Annotate the CommonJS export names for ESM import in node:
913
+ 0 && (module.exports = {
914
+ InputColor
915
+ });
916
+ //# sourceMappingURL=index.js.map