sprint-asia-custom-component 0.1.167 → 0.1.169

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/dist/index.js CHANGED
@@ -29145,6 +29145,14 @@
29145
29145
  }, props.subtitle))))))));
29146
29146
  };
29147
29147
 
29148
+ const formatNumber = val => {
29149
+ if (!val) return "";
29150
+ return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
29151
+ };
29152
+ const parseNumber = val => {
29153
+ if (!val) return "";
29154
+ return val.replace(/\./g, ""); // hapus titik biar jadi angka murni
29155
+ };
29148
29156
  const TextInput = ({
29149
29157
  title = "",
29150
29158
  rightComponent = null,
@@ -29165,15 +29173,27 @@
29165
29173
  }) => {
29166
29174
  const [isFocused, setIsFocused] = React.useState(false);
29167
29175
  const [showPassword, setShowPassword] = React.useState(false);
29168
- const handleFocus = () => {
29169
- setIsFocused(true);
29170
- };
29171
- const handleBlur = () => {
29172
- setIsFocused(false);
29173
- };
29174
- const handleTogglePasswordVisibility = () => {
29175
- setShowPassword(!showPassword);
29176
+ const handleFocus = () => setIsFocused(true);
29177
+ const handleBlur = () => setIsFocused(false);
29178
+ const handleTogglePasswordVisibility = () => setShowPassword(!showPassword);
29179
+ const handleChange = e => {
29180
+ let val = e.target.value;
29181
+ if (type === "number") {
29182
+ // hapus semua karakter non digit
29183
+ const raw = parseNumber(val.replace(/\D/g, ""));
29184
+ // kirim angka murni ke parent
29185
+ onChangeInput({
29186
+ ...e,
29187
+ target: {
29188
+ ...e.target,
29189
+ value: raw
29190
+ }
29191
+ });
29192
+ return;
29193
+ }
29194
+ onChangeInput(e);
29176
29195
  };
29196
+ const displayValue = type === "number" ? value ? formatNumber(value) : "" : value;
29177
29197
  return /*#__PURE__*/React__default["default"].createElement("div", {
29178
29198
  className: `w-full ${className}`
29179
29199
  }, /*#__PURE__*/React__default["default"].createElement("div", {
@@ -29194,27 +29214,27 @@
29194
29214
  ${mode === "primary" && "text-black"}
29195
29215
  ${mode === "disable" && "text-neutral50"}
29196
29216
  ${mode === "danger" && "text-danger500"}
29197
- `
29217
+ `
29198
29218
  })), /*#__PURE__*/React__default["default"].createElement("input", {
29199
29219
  min: minimum !== null && minimum !== undefined && type === "number" ? minimum : undefined,
29200
29220
  max: maximum !== null && maximum !== undefined && type === "number" ? maximum : undefined,
29201
- type: type === "password" ? showPassword ? "text" : "password" : type,
29221
+ type: type === "password" ? showPassword ? "text" : "password" : "text" // number tetap text
29222
+ ,
29202
29223
  className: `py-2.5 px-4 w-full font-normal text-sm text-black rounded-md border
29203
- ${!value && mode === "default" && "bg-neutral20 border-neutral50 focus:outline-2 outline-primary500"}
29204
- ${value && mode === "default" && "bg-neutral20 border-black focus:outline-2 outline-primary500"}
29205
- ${isFocused && mode === "default" && "bg-neutral20 border-primary500"}
29206
- ${mode === "disable" && "bg-neutral30 border-neutral50"}
29207
- ${mode === "white" && "bg-white border-neutral50"}
29208
- ${mode === "danger" && "bg-danger50 border-danger500 focus:outline-2 outline-danger500"}
29209
- ${leftIcon || leftAdornment ? "pl-8" : "pl-3"}
29210
- ${leftIcon && leftAdornment ? "pl-16" : "pl-3"}
29211
- ${rightIcon || rightAdornment ? "pr-8" : "pr-3"}
29212
- ${rightIcon && rightAdornment ? "pr-16" : "pr-3"}`,
29224
+ ${!value && mode === "default" && "bg-neutral20 border-neutral50 focus:outline-2 outline-primary500"}
29225
+ ${value && mode === "default" && "bg-neutral20 border-black focus:outline-2 outline-primary500"}
29226
+ ${isFocused && mode === "default" && "bg-neutral20 border-primary500"}
29227
+ ${mode === "disable" && "bg-neutral30 border-neutral50"}
29228
+ ${mode === "white" && "bg-white border-neutral50"}
29229
+ ${mode === "danger" && "bg-danger50 border-danger500 focus:outline-2 outline-danger500"}
29230
+ ${leftIcon || leftAdornment ? "pl-8" : "pl-3"}
29231
+ ${leftIcon && leftAdornment ? "pl-16" : "pl-3"}
29232
+ ${rightIcon || rightAdornment ? "pr-8" : "pr-3"}
29233
+ ${rightIcon && rightAdornment ? "pr-16" : "pr-3"}`,
29213
29234
  placeholder: placeholder,
29214
- "data-mask": "000.000.000-00",
29215
29235
  disabled: mode === "disable",
29216
- value: value,
29217
- onChange: onChangeInput,
29236
+ value: displayValue,
29237
+ onChange: handleChange,
29218
29238
  onFocus: handleFocus,
29219
29239
  onBlur: handleBlur
29220
29240
  }), type === "password" && /*#__PURE__*/React__default["default"].createElement("span", {
@@ -29234,7 +29254,7 @@
29234
29254
  ${mode === "primary" && "text-neutral50"}
29235
29255
  ${mode === "disable" && "text-neutral50"}
29236
29256
  ${mode === "danger" && "text-danger500"}
29237
- `
29257
+ `
29238
29258
  }))), footer && /*#__PURE__*/React__default["default"].createElement("div", {
29239
29259
  className: "mt-1"
29240
29260
  }, mode === "danger" ? /*#__PURE__*/React__default["default"].createElement("div", {
@@ -51870,7 +51890,8 @@
51870
51890
  footer = null,
51871
51891
  mode = "default",
51872
51892
  placeholder = "",
51873
- redeemType = ""
51893
+ redeemType = "",
51894
+ isEdited = true // ✅ tambahkan prop isEdited
51874
51895
  }) => {
51875
51896
  const [isOpen, setIsOpen] = React.useState(false);
51876
51897
  const wrapperRef = React.useRef(null);
@@ -51919,12 +51940,14 @@
51919
51940
  }, /*#__PURE__*/React__default["default"].createElement("div", {
51920
51941
  className: `
51921
51942
  flex items-center rounded-md overflow-hidden w-full pr-3
51943
+ ${!isEdited ? "bg-neutral30 cursor-not-allowed" : ""}
51922
51944
  ${mode === "danger" ? "border border-danger500 bg-danger50" : "border border-neutral50 bg-neutral20"}
51923
51945
  `
51924
51946
  }, /*#__PURE__*/React__default["default"].createElement("div", {
51925
- className: "flex items-center px-3 py-2 cursor-pointer border-r border-neutral50 mr-3",
51947
+ className: `flex items-center px-3 py-2 border-r border-neutral50 mr-3
51948
+ ${isEdited && redeemType !== "ppob" ? "cursor-pointer" : "cursor-not-allowed"}`,
51926
51949
  onClick: () => {
51927
- if (redeemType !== "ppob") {
51950
+ if (isEdited && redeemType !== "ppob") {
51928
51951
  setIsOpen(!isOpen);
51929
51952
  }
51930
51953
  }
@@ -51934,17 +51957,22 @@
51934
51957
  className: "w-4 h-4 object-cover rounded-full"
51935
51958
  }), /*#__PURE__*/React__default["default"].createElement("p", {
51936
51959
  className: "text-sm font-bold text-neutral300 ml-3 mr-2"
51937
- }, dropdownCountry.option), redeemType !== "ppob" && (isOpen ? /*#__PURE__*/React__default["default"].createElement(PiCaretUp, null) : /*#__PURE__*/React__default["default"].createElement(PiCaretDown, null))), /*#__PURE__*/React__default["default"].createElement("input", {
51960
+ }, dropdownCountry.option), isEdited && redeemType !== "ppob" && (isOpen ? /*#__PURE__*/React__default["default"].createElement(PiCaretUp, null) : /*#__PURE__*/React__default["default"].createElement(PiCaretDown, null))), /*#__PURE__*/React__default["default"].createElement("input", {
51938
51961
  type: "number",
51939
51962
  value: value,
51940
51963
  onChange: onChangeInput,
51941
51964
  className: `
51942
51965
  flex-1 w-full py-2.5 text-sm text-black focus:outline-none
51943
51966
  placeholder:text-neutral300
51967
+ ${!isEdited ? "bg-neutral30 cursor-not-allowed" : ""}
51944
51968
  ${mode === "danger" ? "bg-danger50 text-danger500" : "bg-neutral20"}
51945
51969
  `,
51946
- placeholder: placeholder
51947
- })), isOpen && redeemType !== "ppob" && /*#__PURE__*/React__default["default"].createElement("div", {
51970
+ placeholder: placeholder,
51971
+ disabled: !isEdited // disable input kalau isEdited false
51972
+ })), isOpen && redeemType !== "ppob" && isEdited &&
51973
+ /*#__PURE__*/
51974
+ // ✅ hanya tampil kalau isEdited true
51975
+ React__default["default"].createElement("div", {
51948
51976
  className: "absolute top-full mt-1 z-10 rounded-md shadow-md bg-neutral20 ring-1 ring-black ring-opacity-5 overflow-y-auto max-h-64 no-scrollbar",
51949
51977
  style: {
51950
51978
  width: wrapperWidth
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sprint-asia-custom-component",
3
3
  "main": "dist/index.js",
4
- "version": "0.1.167",
4
+ "version": "0.1.169",
5
5
  "private": false,
6
6
  "dependencies": {
7
7
  "@headlessui/react": "^1.7.18",
@@ -13,6 +13,7 @@ const DropdownPhone = ({
13
13
  mode = "default",
14
14
  placeholder = "",
15
15
  redeemType = "",
16
+ isEdited = true, // ✅ tambahkan prop isEdited
16
17
  }) => {
17
18
  const [isOpen, setIsOpen] = useState(false);
18
19
  const wrapperRef = useRef(null);
@@ -71,15 +72,17 @@ const DropdownPhone = ({
71
72
  <div
72
73
  className={`
73
74
  flex items-center rounded-md overflow-hidden w-full pr-3
75
+ ${!isEdited ? "bg-neutral30 cursor-not-allowed" : ""}
74
76
  ${mode === "danger"
75
77
  ? "border border-danger500 bg-danger50"
76
78
  : "border border-neutral50 bg-neutral20"}
77
79
  `}
78
80
  >
79
81
  <div
80
- className="flex items-center px-3 py-2 cursor-pointer border-r border-neutral50 mr-3"
82
+ className={`flex items-center px-3 py-2 border-r border-neutral50 mr-3
83
+ ${isEdited && redeemType !== "ppob" ? "cursor-pointer" : "cursor-not-allowed"}`}
81
84
  onClick={() => {
82
- if (redeemType !== "ppob") {
85
+ if (isEdited && redeemType !== "ppob") {
83
86
  setIsOpen(!isOpen);
84
87
  }
85
88
  }}
@@ -92,7 +95,7 @@ const DropdownPhone = ({
92
95
  <p className="text-sm font-bold text-neutral300 ml-3 mr-2">
93
96
  {dropdownCountry.option}
94
97
  </p>
95
- {redeemType !== "ppob" && (isOpen ? <PiCaretUp /> : <PiCaretDown />)}
98
+ {isEdited && redeemType !== "ppob" && (isOpen ? <PiCaretUp /> : <PiCaretDown />)}
96
99
  </div>
97
100
 
98
101
  <input
@@ -102,13 +105,15 @@ const DropdownPhone = ({
102
105
  className={`
103
106
  flex-1 w-full py-2.5 text-sm text-black focus:outline-none
104
107
  placeholder:text-neutral300
108
+ ${!isEdited ? "bg-neutral30 cursor-not-allowed" : ""}
105
109
  ${mode === "danger" ? "bg-danger50 text-danger500" : "bg-neutral20"}
106
110
  `}
107
111
  placeholder={placeholder}
112
+ disabled={!isEdited} // ✅ disable input kalau isEdited false
108
113
  />
109
114
  </div>
110
115
 
111
- {isOpen && redeemType !== "ppob" && (
116
+ {isOpen && redeemType !== "ppob" && isEdited && ( // ✅ hanya tampil kalau isEdited true
112
117
  <div
113
118
  className="absolute top-full mt-1 z-10 rounded-md shadow-md bg-neutral20 ring-1 ring-black ring-opacity-5 overflow-y-auto max-h-64 no-scrollbar"
114
119
  style={{ width: wrapperWidth }}
@@ -175,4 +180,4 @@ const DropdownPhone = ({
175
180
  );
176
181
  };
177
182
 
178
- export default DropdownPhone;
183
+ export default DropdownPhone;
@@ -1,6 +1,16 @@
1
1
  import React, { useState } from "react";
2
2
  import { PiEyeClosedLight, PiEye, PiInfo } from "react-icons/pi";
3
3
 
4
+ const formatNumber = (val) => {
5
+ if (!val) return "";
6
+ return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
7
+ };
8
+
9
+ const parseNumber = (val) => {
10
+ if (!val) return "";
11
+ return val.replace(/\./g, ""); // hapus titik biar jadi angka murni
12
+ };
13
+
4
14
  const TextInput = ({
5
15
  title = "",
6
16
  rightComponent = null,
@@ -22,25 +32,39 @@ const TextInput = ({
22
32
  const [isFocused, setIsFocused] = useState(false);
23
33
  const [showPassword, setShowPassword] = useState(false);
24
34
 
25
- const handleFocus = () => {
26
- setIsFocused(true);
27
- };
35
+ const handleFocus = () => setIsFocused(true);
36
+ const handleBlur = () => setIsFocused(false);
37
+ const handleTogglePasswordVisibility = () => setShowPassword(!showPassword);
28
38
 
29
- const handleBlur = () => {
30
- setIsFocused(false);
31
- };
39
+ const handleChange = (e) => {
40
+ let val = e.target.value;
32
41
 
33
- const handleTogglePasswordVisibility = () => {
34
- setShowPassword(!showPassword);
42
+ if (type === "number") {
43
+ // hapus semua karakter non digit
44
+ const raw = parseNumber(val.replace(/\D/g, ""));
45
+ // kirim angka murni ke parent
46
+ onChangeInput({
47
+ ...e,
48
+ target: { ...e.target, value: raw },
49
+ });
50
+ return;
51
+ }
52
+
53
+ onChangeInput(e);
35
54
  };
36
55
 
56
+ const displayValue =
57
+ type === "number" ? (value ? formatNumber(value) : "") : value;
58
+
37
59
  return (
38
60
  <div className={`w-full ${className}`}>
39
61
  <div className="flex w-full items-center">
40
62
  {title && (
41
63
  <div className="flex">
42
64
  <p className="text-sm font-normal text-black mb-1">{title}</p>
43
- {isRequired && <p className="text-sm font-normal text-danger500 ml-1">*</p>}
65
+ {isRequired && (
66
+ <p className="text-sm font-normal text-danger500 ml-1">*</p>
67
+ )}
44
68
  </div>
45
69
  )}
46
70
  {rightComponent}
@@ -56,34 +80,51 @@ const TextInput = ({
56
80
  ${mode === "primary" && "text-black"}
57
81
  ${mode === "disable" && "text-neutral50"}
58
82
  ${mode === "danger" && "text-danger500"}
59
- `}
83
+ `}
60
84
  />
61
85
  )}
62
86
  </section>
63
87
 
64
88
  <input
65
- min={minimum !== null && minimum !== undefined && type === "number" ? minimum : undefined}
66
- max={maximum !== null && maximum !== undefined && type === "number" ? maximum : undefined}
67
- type={type === "password" ? (showPassword ? "text" : "password") : type}
89
+ min={
90
+ minimum !== null && minimum !== undefined && type === "number"
91
+ ? minimum
92
+ : undefined
93
+ }
94
+ max={
95
+ maximum !== null && maximum !== undefined && type === "number"
96
+ ? maximum
97
+ : undefined
98
+ }
99
+ type={
100
+ type === "password" ? (showPassword ? "text" : "password") : "text"
101
+ } // number tetap text
68
102
  className={`py-2.5 px-4 w-full font-normal text-sm text-black rounded-md border
69
- ${!value &&
70
- mode === "default" &&
71
- "bg-neutral20 border-neutral50 focus:outline-2 outline-primary500"
103
+ ${
104
+ !value &&
105
+ mode === "default" &&
106
+ "bg-neutral20 border-neutral50 focus:outline-2 outline-primary500"
107
+ }
108
+ ${
109
+ value &&
110
+ mode === "default" &&
111
+ "bg-neutral20 border-black focus:outline-2 outline-primary500"
112
+ }
113
+ ${isFocused && mode === "default" && "bg-neutral20 border-primary500"}
114
+ ${mode === "disable" && "bg-neutral30 border-neutral50"}
115
+ ${mode === "white" && "bg-white border-neutral50"}
116
+ ${
117
+ mode === "danger" &&
118
+ "bg-danger50 border-danger500 focus:outline-2 outline-danger500"
72
119
  }
73
- ${value && mode === "default" && "bg-neutral20 border-black focus:outline-2 outline-primary500"}
74
- ${isFocused && mode === "default" && "bg-neutral20 border-primary500"}
75
- ${mode === "disable" && "bg-neutral30 border-neutral50"}
76
- ${mode === "white" && "bg-white border-neutral50"}
77
- ${mode === "danger" && "bg-danger50 border-danger500 focus:outline-2 outline-danger500"}
78
- ${leftIcon || leftAdornment ? "pl-8" : "pl-3"}
79
- ${leftIcon && leftAdornment ? "pl-16" : "pl-3"}
80
- ${rightIcon || rightAdornment ? "pr-8" : "pr-3"}
81
- ${rightIcon && rightAdornment ? "pr-16" : "pr-3"}`}
120
+ ${leftIcon || leftAdornment ? "pl-8" : "pl-3"}
121
+ ${leftIcon && leftAdornment ? "pl-16" : "pl-3"}
122
+ ${rightIcon || rightAdornment ? "pr-8" : "pr-3"}
123
+ ${rightIcon && rightAdornment ? "pr-16" : "pr-3"}`}
82
124
  placeholder={placeholder}
83
- data-mask="000.000.000-00"
84
125
  disabled={mode === "disable"}
85
- value={value}
86
- onChange={onChangeInput}
126
+ value={displayValue}
127
+ onChange={handleChange}
87
128
  onFocus={handleFocus}
88
129
  onBlur={handleBlur}
89
130
  />
@@ -94,9 +135,19 @@ const TextInput = ({
94
135
  onClick={handleTogglePasswordVisibility}
95
136
  >
96
137
  {showPassword ? (
97
- <PiEye size={16} className={`text-black ${mode === "danger" && "text-danger500"}`} />
138
+ <PiEye
139
+ size={16}
140
+ className={`text-black ${
141
+ mode === "danger" && "text-danger500"
142
+ }`}
143
+ />
98
144
  ) : (
99
- <PiEyeClosedLight size={16} className={`text-black ${mode === "danger" && "text-danger500"}`} />
145
+ <PiEyeClosedLight
146
+ size={16}
147
+ className={`text-black ${
148
+ mode === "danger" && "text-danger500"
149
+ }`}
150
+ />
100
151
  )}
101
152
  </span>
102
153
  )}
@@ -110,7 +161,7 @@ const TextInput = ({
110
161
  ${mode === "primary" && "text-neutral50"}
111
162
  ${mode === "disable" && "text-neutral50"}
112
163
  ${mode === "danger" && "text-danger500"}
113
- `}
164
+ `}
114
165
  />
115
166
  )}
116
167
  </section>
@@ -134,4 +185,4 @@ const TextInput = ({
134
185
  );
135
186
  };
136
187
 
137
- export default TextInput;
188
+ export default TextInput;