@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 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-native-web", "@scripso-homepad/ui"],
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: 14,
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: 12,
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 hasIcon = showIcon || icon != null;
369
- const iconNode = icon ?? /* @__PURE__ */ jsxRuntime.jsx(ArrowUpRightIcon, { size: metrics.iconSize, color: preset.iconColor });
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 getInputFieldStyles(state) {
470
- const outlineBase = {
523
+ function createOutlineStyle(ringColor) {
524
+ return {
471
525
  borderRadius: radii.lg + INPUT_OUTLINE_WIDTH,
472
- padding: INPUT_OUTLINE_WIDTH,
473
- backgroundColor: colors.transparent
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: outlineBase,
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: outlineBase,
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
- rightIcon ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles3.iconSlot, children: renderInputIcon(rightIcon, iconColor) }) : null
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: 12,
788
+ lineHeight: 16,
692
789
  color: colors.inputError
693
790
  },
694
791
  hint: {
695
792
  fontSize: 12,
696
- lineHeight: 12,
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: 12,
1290
+ lineHeight: 16,
1194
1291
  color: colors.inputError
1195
1292
  },
1196
1293
  hint: {
1197
1294
  fontSize: 12,
1198
- lineHeight: 12,
1295
+ lineHeight: 16,
1199
1296
  color: colors.stormGray300
1200
1297
  }
1201
1298
  });