@scripso-homepad/ui 0.3.7 → 0.3.8
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/README.md +7 -2
- package/dist/index.cjs +121 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +122 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Button.tsx +11 -2
- package/src/components/Input.stories.tsx +9 -0
- package/src/components/Input.tsx +48 -4
- package/src/components/PhoneInput.tsx +2 -2
- package/src/icons/EyeIcon.tsx +25 -37
- package/src/icons/EyeIcon.web.tsx +42 -0
- package/src/icons/EyeOffIcon.tsx +29 -0
- package/src/icons/EyeOffIcon.web.tsx +35 -0
- package/src/icons/eyeIconPaths.ts +8 -0
- package/src/theme/input.ts +29 -14
- package/src/theme/tokens.ts +3 -3
package/README.md
CHANGED
|
@@ -55,8 +55,13 @@ export default defineConfig({
|
|
|
55
55
|
}),
|
|
56
56
|
],
|
|
57
57
|
resolve: {
|
|
58
|
+
dedupe: ["react", "react-dom", "react-native", "react-native-web"],
|
|
58
59
|
alias: {
|
|
59
60
|
"react-native": "react-native-web",
|
|
61
|
+
react: path.resolve(__dirname, "node_modules/react"),
|
|
62
|
+
"react-dom": path.resolve(__dirname, "node_modules/react-dom"),
|
|
63
|
+
"react/jsx-runtime": path.resolve(__dirname, "node_modules/react/jsx-runtime"),
|
|
64
|
+
"react/jsx-dev-runtime": path.resolve(__dirname, "node_modules/react/jsx-dev-runtime"),
|
|
60
65
|
"@scripso-homepad/ui": resolveUiPackageEntry(),
|
|
61
66
|
},
|
|
62
67
|
extensions: [
|
|
@@ -71,8 +76,8 @@ export default defineConfig({
|
|
|
71
76
|
],
|
|
72
77
|
},
|
|
73
78
|
optimizeDeps: {
|
|
74
|
-
include: ["react-
|
|
75
|
-
exclude: ["react-native-svg"],
|
|
79
|
+
include: ["react", "react-dom", "react/jsx-runtime", "react-native-web"],
|
|
80
|
+
exclude: ["react-native-svg", "@scripso-homepad/ui"],
|
|
76
81
|
esbuildOptions: {
|
|
77
82
|
resolveExtensions: [
|
|
78
83
|
".web.js",
|
package/dist/index.cjs
CHANGED
|
@@ -233,14 +233,14 @@ var buttonTypography = {
|
|
|
233
233
|
fontFamily: fonts.sans,
|
|
234
234
|
fontSize: 14,
|
|
235
235
|
fontWeight: fontWeight.semibold,
|
|
236
|
-
lineHeight:
|
|
236
|
+
lineHeight: 18,
|
|
237
237
|
letterSpacing: 0
|
|
238
238
|
},
|
|
239
239
|
sm: {
|
|
240
240
|
fontFamily: fonts.sans,
|
|
241
241
|
fontSize: 12,
|
|
242
242
|
fontWeight: fontWeight.semibold,
|
|
243
|
-
lineHeight:
|
|
243
|
+
lineHeight: 16,
|
|
244
244
|
letterSpacing: 0
|
|
245
245
|
}
|
|
246
246
|
};
|
|
@@ -365,8 +365,9 @@ function Button({
|
|
|
365
365
|
useApplyWebClassName(textRef, textClassName);
|
|
366
366
|
const label = typeof children !== "undefined" ? children : title;
|
|
367
367
|
const hasCustomChildren = typeof children !== "undefined";
|
|
368
|
-
const
|
|
369
|
-
const
|
|
368
|
+
const customIcon = icon != null && typeof icon !== "boolean" ? icon : void 0;
|
|
369
|
+
const hasIcon = showIcon || icon === true || customIcon != null;
|
|
370
|
+
const iconNode = customIcon ?? /* @__PURE__ */ jsxRuntime.jsx(ArrowUpRightIcon, { size: metrics.iconSize, color: preset.iconColor });
|
|
370
371
|
const containerStyle = [
|
|
371
372
|
styles.base,
|
|
372
373
|
{
|
|
@@ -386,6 +387,7 @@ function Button({
|
|
|
386
387
|
styles.label,
|
|
387
388
|
metrics.text,
|
|
388
389
|
{ color: preset.textColor },
|
|
390
|
+
reactNative.Platform.OS === "android" ? styles.labelAndroid : null,
|
|
389
391
|
!hasIcon && styles.labelCentered,
|
|
390
392
|
hasIcon && styles.labelWithIcon,
|
|
391
393
|
textStyle
|
|
@@ -438,6 +440,9 @@ var styles = reactNative.StyleSheet.create({
|
|
|
438
440
|
opacity: 0.6
|
|
439
441
|
},
|
|
440
442
|
label: {},
|
|
443
|
+
labelAndroid: {
|
|
444
|
+
includeFontPadding: false
|
|
445
|
+
},
|
|
441
446
|
labelCentered: {
|
|
442
447
|
textAlign: "center"
|
|
443
448
|
},
|
|
@@ -452,6 +457,55 @@ var styles = reactNative.StyleSheet.create({
|
|
|
452
457
|
flexShrink: 0
|
|
453
458
|
}
|
|
454
459
|
});
|
|
460
|
+
|
|
461
|
+
// src/icons/eyeIconPaths.ts
|
|
462
|
+
var EYE_OPEN_OUTLINE_PATH = "M1.71835 10.2898C1.6489 10.1027 1.6489 9.89691 1.71835 9.70981C2.39476 8.06969 3.54294 6.66735 5.01732 5.68056C6.4917 4.69378 8.22588 4.16699 10 4.16699C11.7741 4.16699 13.5083 4.69378 14.9827 5.68056C16.4571 6.66735 17.6053 8.06969 18.2817 9.70981C18.3511 9.89691 18.3511 10.1027 18.2817 10.2898C17.6053 11.9299 16.4571 13.3323 14.9827 14.3191C13.5083 15.3058 11.7741 15.8326 10 15.8326C8.22588 15.8326 6.4917 15.3058 5.01732 14.3191C3.54294 13.3323 2.39476 11.9299 1.71835 10.2898Z";
|
|
463
|
+
var EYE_OPEN_PUPIL_PATH = "M10 12.4998C11.3807 12.4998 12.5 11.3805 12.5 9.99981C12.5 8.6191 11.3807 7.49981 10 7.49981C8.6193 7.49981 7.50001 8.6191 7.50001 9.99981C7.50001 11.3805 8.6193 12.4998 10 12.4998Z";
|
|
464
|
+
var EYE_OFF_PATH = "M10.733 5.076C13.0624 4.7984 15.4186 5.29082 17.4419 6.47805C19.4651 7.66528 21.0442 9.48208 21.938 11.651C22.0213 11.8755 22.0213 12.1225 21.938 12.347C21.5705 13.238 21.0848 14.0755 20.494 14.837M14.084 14.158C13.5182 14.7045 12.7604 15.0069 11.9738 15C11.1872 14.9932 10.4348 14.6777 9.87854 14.1215C9.32232 13.5652 9.00681 12.8128 8.99998 12.0262C8.99314 11.2396 9.29553 10.4818 9.842 9.916M17.479 17.499C16.1525 18.2848 14.6725 18.776 13.1394 18.9394C11.6063 19.1028 10.056 18.9345 8.59363 18.4459C7.13131 17.9573 5.79119 17.1599 4.66421 16.1077C3.53723 15.0556 2.64975 13.7734 2.062 12.348C1.97866 12.1235 1.97866 11.8765 2.062 11.652C2.94863 9.50186 4.50867 7.69725 6.508 6.509M2 2L22 22";
|
|
465
|
+
function EyeIcon({
|
|
466
|
+
size = 20,
|
|
467
|
+
color = "#c7cdd1",
|
|
468
|
+
strokeWidth = 2
|
|
469
|
+
}) {
|
|
470
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Svg__default.default, { width: size, height: size, viewBox: "0 0 20 20", fill: "none", children: [
|
|
471
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
472
|
+
Svg.Path,
|
|
473
|
+
{
|
|
474
|
+
d: EYE_OPEN_OUTLINE_PATH,
|
|
475
|
+
stroke: color,
|
|
476
|
+
strokeWidth,
|
|
477
|
+
strokeLinecap: "round",
|
|
478
|
+
strokeLinejoin: "round"
|
|
479
|
+
}
|
|
480
|
+
),
|
|
481
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
482
|
+
Svg.Path,
|
|
483
|
+
{
|
|
484
|
+
d: EYE_OPEN_PUPIL_PATH,
|
|
485
|
+
stroke: color,
|
|
486
|
+
strokeWidth,
|
|
487
|
+
strokeLinecap: "round",
|
|
488
|
+
strokeLinejoin: "round"
|
|
489
|
+
}
|
|
490
|
+
)
|
|
491
|
+
] });
|
|
492
|
+
}
|
|
493
|
+
function EyeOffIcon({
|
|
494
|
+
size = 20,
|
|
495
|
+
color = "#c7cdd1",
|
|
496
|
+
strokeWidth = 2
|
|
497
|
+
}) {
|
|
498
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Svg__default.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
499
|
+
Svg.Path,
|
|
500
|
+
{
|
|
501
|
+
d: EYE_OFF_PATH,
|
|
502
|
+
stroke: color,
|
|
503
|
+
strokeWidth,
|
|
504
|
+
strokeLinecap: "round",
|
|
505
|
+
strokeLinejoin: "round"
|
|
506
|
+
}
|
|
507
|
+
) });
|
|
508
|
+
}
|
|
455
509
|
var INPUT_HEIGHT = 52;
|
|
456
510
|
var INPUT_ICON_SIZE = 20;
|
|
457
511
|
var INPUT_ICON_GAP = 10;
|
|
@@ -466,17 +520,30 @@ function resolveInputVisualState({
|
|
|
466
520
|
if (focused) return "focused";
|
|
467
521
|
return "default";
|
|
468
522
|
}
|
|
469
|
-
function
|
|
470
|
-
|
|
523
|
+
function createOutlineStyle(ringColor) {
|
|
524
|
+
return {
|
|
471
525
|
borderRadius: radii.lg + INPUT_OUTLINE_WIDTH,
|
|
472
|
-
|
|
473
|
-
|
|
526
|
+
borderWidth: INPUT_OUTLINE_WIDTH,
|
|
527
|
+
borderColor: ringColor,
|
|
528
|
+
padding: 0,
|
|
529
|
+
backgroundColor: colors.transparent,
|
|
530
|
+
width: "100%",
|
|
531
|
+
alignSelf: "stretch",
|
|
532
|
+
...reactNative.Platform.OS !== "web" ? { overflow: "hidden" } : null
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
var defaultOutline = createOutlineStyle(colors.transparent);
|
|
536
|
+
function getInputFieldStyles(state) {
|
|
537
|
+
const containerBase = {
|
|
538
|
+
borderRadius: radii.lg,
|
|
539
|
+
...reactNative.Platform.OS !== "web" ? { overflow: "hidden" } : null
|
|
474
540
|
};
|
|
475
541
|
switch (state) {
|
|
476
542
|
case "disabled":
|
|
477
543
|
return {
|
|
478
|
-
outline:
|
|
544
|
+
outline: defaultOutline,
|
|
479
545
|
container: {
|
|
546
|
+
...containerBase,
|
|
480
547
|
borderWidth: 1,
|
|
481
548
|
borderColor: colors.stormGray50,
|
|
482
549
|
backgroundColor: colors.stormGray50
|
|
@@ -487,11 +554,9 @@ function getInputFieldStyles(state) {
|
|
|
487
554
|
};
|
|
488
555
|
case "error":
|
|
489
556
|
return {
|
|
490
|
-
outline:
|
|
491
|
-
...outlineBase,
|
|
492
|
-
backgroundColor: colors.inputOutlineError
|
|
493
|
-
},
|
|
557
|
+
outline: createOutlineStyle(colors.inputOutlineError),
|
|
494
558
|
container: {
|
|
559
|
+
...containerBase,
|
|
495
560
|
borderWidth: 1,
|
|
496
561
|
borderColor: colors.inputError,
|
|
497
562
|
backgroundColor: colors.white
|
|
@@ -502,11 +567,9 @@ function getInputFieldStyles(state) {
|
|
|
502
567
|
};
|
|
503
568
|
case "focused":
|
|
504
569
|
return {
|
|
505
|
-
outline:
|
|
506
|
-
...outlineBase,
|
|
507
|
-
backgroundColor: colors.inputOutlineFocus
|
|
508
|
-
},
|
|
570
|
+
outline: createOutlineStyle(colors.inputOutlineFocus),
|
|
509
571
|
container: {
|
|
572
|
+
...containerBase,
|
|
510
573
|
borderWidth: 1,
|
|
511
574
|
borderColor: colors.navy,
|
|
512
575
|
backgroundColor: colors.white
|
|
@@ -517,8 +580,9 @@ function getInputFieldStyles(state) {
|
|
|
517
580
|
};
|
|
518
581
|
default:
|
|
519
582
|
return {
|
|
520
|
-
outline:
|
|
583
|
+
outline: defaultOutline,
|
|
521
584
|
container: {
|
|
585
|
+
...containerBase,
|
|
522
586
|
borderWidth: 1,
|
|
523
587
|
borderColor: colors.stormGray50,
|
|
524
588
|
backgroundColor: colors.white
|
|
@@ -547,12 +611,13 @@ var inputFieldMetrics = reactNative.StyleSheet.create({
|
|
|
547
611
|
fontFamily: fonts.sans,
|
|
548
612
|
fontSize: fontSize.md,
|
|
549
613
|
fontWeight: fontWeight.medium,
|
|
550
|
-
lineHeight: fontSize.md,
|
|
614
|
+
lineHeight: reactNative.Platform.OS === "web" ? fontSize.md : 20,
|
|
551
615
|
paddingVertical: 0,
|
|
552
616
|
paddingHorizontal: 0,
|
|
553
617
|
margin: 0,
|
|
554
618
|
borderWidth: 0,
|
|
555
619
|
backgroundColor: colors.transparent,
|
|
620
|
+
...reactNative.Platform.OS === "android" ? { includeFontPadding: false } : null,
|
|
556
621
|
...reactNative.Platform.OS === "web" ? {
|
|
557
622
|
height: "100%",
|
|
558
623
|
minHeight: 0,
|
|
@@ -620,6 +685,8 @@ function Input({
|
|
|
620
685
|
errorClassName,
|
|
621
686
|
hintClassName,
|
|
622
687
|
editable = true,
|
|
688
|
+
secureTextEntry,
|
|
689
|
+
showPasswordToggle,
|
|
623
690
|
onFocus,
|
|
624
691
|
onBlur,
|
|
625
692
|
...props
|
|
@@ -628,10 +695,13 @@ function Input({
|
|
|
628
695
|
const inputRef = react.useRef(null);
|
|
629
696
|
const helperRef = react.useRef(null);
|
|
630
697
|
const [focused, setFocused] = react.useState(false);
|
|
698
|
+
const [passwordVisible, setPasswordVisible] = react.useState(false);
|
|
631
699
|
useApplyWebClassName(wrapperRef, className);
|
|
632
700
|
useApplyWebClassName(inputRef, inputClassName);
|
|
633
701
|
useApplyWebClassName(helperRef, error ? errorClassName : hintClassName);
|
|
634
702
|
const isDisabled = editable === false;
|
|
703
|
+
const passwordToggleEnabled = secureTextEntry === true && showPasswordToggle !== false && rightIcon == null;
|
|
704
|
+
const effectiveSecureTextEntry = passwordToggleEnabled ? !passwordVisible : secureTextEntry;
|
|
635
705
|
const visualState = resolveInputVisualState({
|
|
636
706
|
focused,
|
|
637
707
|
error: Boolean(error),
|
|
@@ -648,6 +718,26 @@ function Input({
|
|
|
648
718
|
onBlur?.(event);
|
|
649
719
|
}
|
|
650
720
|
const helperMessage = error ?? hint;
|
|
721
|
+
function togglePasswordVisibility() {
|
|
722
|
+
if (!isDisabled) {
|
|
723
|
+
setPasswordVisible((visible) => !visible);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
const trailingIcon = passwordToggleEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
727
|
+
reactNative.Pressable,
|
|
728
|
+
{
|
|
729
|
+
onPress: togglePasswordVisibility,
|
|
730
|
+
disabled: isDisabled,
|
|
731
|
+
accessibilityRole: "button",
|
|
732
|
+
accessibilityLabel: passwordVisible ? "Hide password" : "Show password",
|
|
733
|
+
hitSlop: 8,
|
|
734
|
+
style: styles3.iconPressable,
|
|
735
|
+
children: renderInputIcon(
|
|
736
|
+
passwordVisible ? /* @__PURE__ */ jsxRuntime.jsx(EyeOffIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(EyeIcon, {}),
|
|
737
|
+
iconColor
|
|
738
|
+
)
|
|
739
|
+
}
|
|
740
|
+
) : rightIcon ? renderInputIcon(rightIcon, iconColor) : null;
|
|
651
741
|
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { ref: wrapperRef, style: [styles3.wrapper, containerStyle], children: [
|
|
652
742
|
label ? /* @__PURE__ */ jsxRuntime.jsx(Label, { disabled: isDisabled, className: labelClassName, children: label }) : null,
|
|
653
743
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: fieldStyles.outline, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [inputFieldMetrics.container, fieldStyles.container], children: [
|
|
@@ -663,13 +753,14 @@ function Input({
|
|
|
663
753
|
],
|
|
664
754
|
placeholderTextColor: fieldStyles.placeholder,
|
|
665
755
|
editable,
|
|
756
|
+
secureTextEntry: effectiveSecureTextEntry,
|
|
666
757
|
onFocus: handleFocus,
|
|
667
758
|
onBlur: handleBlur,
|
|
668
759
|
accessibilityState: { disabled: isDisabled },
|
|
669
760
|
...props
|
|
670
761
|
}
|
|
671
762
|
),
|
|
672
|
-
|
|
763
|
+
trailingIcon ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles3.iconSlot, children: trailingIcon }) : null
|
|
673
764
|
] }) }),
|
|
674
765
|
helperMessage ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { ref: helperRef, style: error ? styles3.error : styles3.hint, children: helperMessage }) : null
|
|
675
766
|
] });
|
|
@@ -686,14 +777,20 @@ var styles3 = reactNative.StyleSheet.create({
|
|
|
686
777
|
justifyContent: "center",
|
|
687
778
|
flexShrink: 0
|
|
688
779
|
},
|
|
780
|
+
iconPressable: {
|
|
781
|
+
width: INPUT_ICON_SIZE,
|
|
782
|
+
height: INPUT_ICON_SIZE,
|
|
783
|
+
alignItems: "center",
|
|
784
|
+
justifyContent: "center"
|
|
785
|
+
},
|
|
689
786
|
error: {
|
|
690
787
|
fontSize: 12,
|
|
691
|
-
lineHeight:
|
|
788
|
+
lineHeight: 16,
|
|
692
789
|
color: colors.inputError
|
|
693
790
|
},
|
|
694
791
|
hint: {
|
|
695
792
|
fontSize: 12,
|
|
696
|
-
lineHeight:
|
|
793
|
+
lineHeight: 16,
|
|
697
794
|
color: colors.stormGray300
|
|
698
795
|
}
|
|
699
796
|
});
|
|
@@ -1190,12 +1287,12 @@ var styles5 = reactNative.StyleSheet.create({
|
|
|
1190
1287
|
},
|
|
1191
1288
|
error: {
|
|
1192
1289
|
fontSize: 12,
|
|
1193
|
-
lineHeight:
|
|
1290
|
+
lineHeight: 16,
|
|
1194
1291
|
color: colors.inputError
|
|
1195
1292
|
},
|
|
1196
1293
|
hint: {
|
|
1197
1294
|
fontSize: 12,
|
|
1198
|
-
lineHeight:
|
|
1295
|
+
lineHeight: 16,
|
|
1199
1296
|
color: colors.stormGray300
|
|
1200
1297
|
}
|
|
1201
1298
|
});
|