nihonput 0.1.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/LICENSE +21 -0
- package/README.ja.md +318 -0
- package/README.md +318 -0
- package/dist/index.d.mts +216 -0
- package/dist/index.d.ts +216 -0
- package/dist/index.js +948 -0
- package/dist/index.mjs +892 -0
- package/package.json +50 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,948 @@
|
|
|
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.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
PREFECTURES: () => PREFECTURES,
|
|
24
|
+
PREFECTURE_SHORT_NAMES: () => PREFECTURE_SHORT_NAMES,
|
|
25
|
+
addPhoneNumberHyphen: () => addPhoneNumberHyphen,
|
|
26
|
+
addPostalCodeHyphen: () => addPostalCodeHyphen,
|
|
27
|
+
containsFullWidthPhoneNumber: () => containsFullWidthPhoneNumber,
|
|
28
|
+
containsHiragana: () => containsHiragana,
|
|
29
|
+
containsKatakana: () => containsKatakana,
|
|
30
|
+
defaultErrorMessages: () => defaultErrorMessages,
|
|
31
|
+
isFullWidthPostalCode: () => isFullWidthPostalCode,
|
|
32
|
+
isHalfWidthPhoneNumber: () => isHalfWidthPhoneNumber,
|
|
33
|
+
isHalfWidthPostalCode: () => isHalfWidthPostalCode,
|
|
34
|
+
normalizePrefecture: () => normalizePrefecture,
|
|
35
|
+
toFullWidth: () => toFullWidth,
|
|
36
|
+
toFullWidthHyphen: () => toFullWidthHyphen,
|
|
37
|
+
toFullWidthNumbers: () => toFullWidthNumbers,
|
|
38
|
+
toHalfWidth: () => toHalfWidth,
|
|
39
|
+
toHalfWidthHyphen: () => toHalfWidthHyphen,
|
|
40
|
+
toHalfWidthNumbers: () => toHalfWidthNumbers,
|
|
41
|
+
toHiragana: () => toHiragana,
|
|
42
|
+
toKatakana: () => toKatakana,
|
|
43
|
+
useAddressField: () => useAddressField,
|
|
44
|
+
useNameField: () => useNameField,
|
|
45
|
+
usePhoneNumberField: () => usePhoneNumberField,
|
|
46
|
+
usePostalCodeField: () => usePostalCodeField,
|
|
47
|
+
usePrefectureField: () => usePrefectureField,
|
|
48
|
+
validateHiragana: () => validateHiragana,
|
|
49
|
+
validateKatakana: () => validateKatakana,
|
|
50
|
+
validatePhoneNumber: () => validatePhoneNumber,
|
|
51
|
+
validatePostalCode: () => validatePostalCode,
|
|
52
|
+
validatePrefecture: () => validatePrefecture
|
|
53
|
+
});
|
|
54
|
+
module.exports = __toCommonJS(index_exports);
|
|
55
|
+
|
|
56
|
+
// src/hooks/useNameField.ts
|
|
57
|
+
var import_react = require("react");
|
|
58
|
+
|
|
59
|
+
// src/types/index.ts
|
|
60
|
+
var defaultErrorMessages = {
|
|
61
|
+
katakanaOnly: "\u30AB\u30BF\u30AB\u30CA\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
62
|
+
hiraganaOnly: "\u3072\u3089\u304C\u306A\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
63
|
+
invalidPostalCode: "\u6B63\u3057\u3044\u90F5\u4FBF\u756A\u53F7\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: 123-4567\uFF09",
|
|
64
|
+
invalidPrefecture: "\u6B63\u3057\u3044\u90FD\u9053\u5E9C\u770C\u540D\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
65
|
+
invalidPhoneNumber: "\u6B63\u3057\u3044\u96FB\u8A71\u756A\u53F7\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
66
|
+
invalidWidth: "\u6B63\u3057\u3044\u6587\u5B57\u5E45\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
67
|
+
invalidFormat: "\u6B63\u3057\u3044\u5F62\u5F0F\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// src/validators/katakana.ts
|
|
71
|
+
function validateKatakana(value) {
|
|
72
|
+
if (!value) return true;
|
|
73
|
+
const katakanaRegex = /^[\u30A0-\u30FF\u3000\s]+$/;
|
|
74
|
+
return katakanaRegex.test(value);
|
|
75
|
+
}
|
|
76
|
+
function containsHiragana(value) {
|
|
77
|
+
if (!value) return false;
|
|
78
|
+
const hiraganaRegex = /[\u3040-\u309F]/;
|
|
79
|
+
return hiraganaRegex.test(value);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/normalizers/toKatakana.ts
|
|
83
|
+
function toKatakana(value) {
|
|
84
|
+
if (!value) return value;
|
|
85
|
+
return value.replace(/[\u3040-\u309F]/g, (char) => {
|
|
86
|
+
return String.fromCharCode(char.charCodeAt(0) + 96);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/hooks/useNameField.ts
|
|
91
|
+
function useNameField(options) {
|
|
92
|
+
const {
|
|
93
|
+
kanaMode,
|
|
94
|
+
normalizeOn = "blur",
|
|
95
|
+
validateOn = "blur",
|
|
96
|
+
errorMessages = {}
|
|
97
|
+
} = options;
|
|
98
|
+
const [value, setValue] = (0, import_react.useState)("");
|
|
99
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
100
|
+
const [isValidating, setIsValidating] = (0, import_react.useState)(false);
|
|
101
|
+
const isComposingRef = (0, import_react.useRef)(false);
|
|
102
|
+
const messages = {
|
|
103
|
+
katakanaOnly: errorMessages.katakanaOnly ?? defaultErrorMessages.katakanaOnly,
|
|
104
|
+
invalidFormat: errorMessages.invalidFormat ?? defaultErrorMessages.invalidFormat
|
|
105
|
+
};
|
|
106
|
+
const normalize = (0, import_react.useCallback)(
|
|
107
|
+
(val) => {
|
|
108
|
+
if (kanaMode === "auto-convert") {
|
|
109
|
+
return toKatakana(val);
|
|
110
|
+
}
|
|
111
|
+
return val;
|
|
112
|
+
},
|
|
113
|
+
[kanaMode]
|
|
114
|
+
);
|
|
115
|
+
const validate = (0, import_react.useCallback)(
|
|
116
|
+
(val) => {
|
|
117
|
+
if (!val) return null;
|
|
118
|
+
if (kanaMode === "error-on-hiragana") {
|
|
119
|
+
if (containsHiragana(val)) {
|
|
120
|
+
return messages.katakanaOnly;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (!validateKatakana(val)) {
|
|
124
|
+
return messages.katakanaOnly;
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
},
|
|
128
|
+
[kanaMode, messages.katakanaOnly]
|
|
129
|
+
);
|
|
130
|
+
const handleChange = (0, import_react.useCallback)(
|
|
131
|
+
(e) => {
|
|
132
|
+
const newValue = e.target.value;
|
|
133
|
+
setValue(newValue);
|
|
134
|
+
if (isComposingRef.current) return;
|
|
135
|
+
if (normalizeOn === "change") {
|
|
136
|
+
setValue(normalize(newValue));
|
|
137
|
+
}
|
|
138
|
+
if (validateOn === "change") {
|
|
139
|
+
setIsValidating(true);
|
|
140
|
+
const validationError = validate(
|
|
141
|
+
normalizeOn === "change" ? normalize(newValue) : newValue
|
|
142
|
+
);
|
|
143
|
+
setError(validationError);
|
|
144
|
+
setIsValidating(false);
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
148
|
+
);
|
|
149
|
+
const handleBlur = (0, import_react.useCallback)(
|
|
150
|
+
(e) => {
|
|
151
|
+
const currentValue = e.target.value;
|
|
152
|
+
if (normalizeOn === "blur") {
|
|
153
|
+
const normalized = normalize(currentValue);
|
|
154
|
+
setValue(normalized);
|
|
155
|
+
if (validateOn === "blur") {
|
|
156
|
+
setIsValidating(true);
|
|
157
|
+
setError(validate(normalized));
|
|
158
|
+
setIsValidating(false);
|
|
159
|
+
}
|
|
160
|
+
} else if (validateOn === "blur") {
|
|
161
|
+
setIsValidating(true);
|
|
162
|
+
setError(validate(currentValue));
|
|
163
|
+
setIsValidating(false);
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
167
|
+
);
|
|
168
|
+
const handleCompositionStart = (0, import_react.useCallback)(
|
|
169
|
+
(_e) => {
|
|
170
|
+
isComposingRef.current = true;
|
|
171
|
+
},
|
|
172
|
+
[]
|
|
173
|
+
);
|
|
174
|
+
const handleCompositionEnd = (0, import_react.useCallback)(
|
|
175
|
+
(e) => {
|
|
176
|
+
isComposingRef.current = false;
|
|
177
|
+
const currentValue = e.currentTarget.value;
|
|
178
|
+
if (normalizeOn === "compositionEnd") {
|
|
179
|
+
const normalized = normalize(currentValue);
|
|
180
|
+
setValue(normalized);
|
|
181
|
+
if (validateOn === "blur" || validateOn === "change") {
|
|
182
|
+
setIsValidating(true);
|
|
183
|
+
setError(validate(normalized));
|
|
184
|
+
setIsValidating(false);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
189
|
+
);
|
|
190
|
+
return {
|
|
191
|
+
value,
|
|
192
|
+
onChange: handleChange,
|
|
193
|
+
onBlur: handleBlur,
|
|
194
|
+
onCompositionStart: handleCompositionStart,
|
|
195
|
+
onCompositionEnd: handleCompositionEnd,
|
|
196
|
+
error,
|
|
197
|
+
isValidating,
|
|
198
|
+
isComposing: isComposingRef.current
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/hooks/usePostalCodeField.ts
|
|
203
|
+
var import_react2 = require("react");
|
|
204
|
+
|
|
205
|
+
// src/validators/postalCode.ts
|
|
206
|
+
function validatePostalCode(value) {
|
|
207
|
+
if (!value) return true;
|
|
208
|
+
const normalized = value.replace(/[0-9]/g, (s) => String.fromCharCode(s.charCodeAt(0) - 65248)).replace(/[ー-]/g, "-");
|
|
209
|
+
const postalCodeRegex = /^\d{3}-?\d{4}$/;
|
|
210
|
+
return postalCodeRegex.test(normalized);
|
|
211
|
+
}
|
|
212
|
+
function isHalfWidthPostalCode(value) {
|
|
213
|
+
if (!value) return true;
|
|
214
|
+
const halfWidthRegex = /^[\d-]+$/;
|
|
215
|
+
return halfWidthRegex.test(value);
|
|
216
|
+
}
|
|
217
|
+
function isFullWidthPostalCode(value) {
|
|
218
|
+
if (!value) return true;
|
|
219
|
+
const fullWidthRegex = /^[0-9ー-]+$/;
|
|
220
|
+
return fullWidthRegex.test(value);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// src/normalizers/toHalfWidth.ts
|
|
224
|
+
function toHalfWidth(value) {
|
|
225
|
+
if (!value) return value;
|
|
226
|
+
return value.replace(/[\uFF01-\uFF5E]/g, (char) => {
|
|
227
|
+
return String.fromCharCode(char.charCodeAt(0) - 65248);
|
|
228
|
+
}).replace(/\u3000/g, " ");
|
|
229
|
+
}
|
|
230
|
+
function toHalfWidthNumbers(value) {
|
|
231
|
+
if (!value) return value;
|
|
232
|
+
return value.replace(/[0-9]/g, (char) => {
|
|
233
|
+
return String.fromCharCode(char.charCodeAt(0) - 65248);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
function toHalfWidthHyphen(value) {
|
|
237
|
+
if (!value) return value;
|
|
238
|
+
return value.replace(/[ー-―]/g, "-");
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/normalizers/toFullWidth.ts
|
|
242
|
+
function toFullWidth(value) {
|
|
243
|
+
if (!value) return value;
|
|
244
|
+
return value.replace(/[\x21-\x7E]/g, (char) => {
|
|
245
|
+
return String.fromCharCode(char.charCodeAt(0) + 65248);
|
|
246
|
+
}).replace(/ /g, "\u3000");
|
|
247
|
+
}
|
|
248
|
+
function toFullWidthNumbers(value) {
|
|
249
|
+
if (!value) return value;
|
|
250
|
+
return value.replace(/[0-9]/g, (char) => {
|
|
251
|
+
return String.fromCharCode(char.charCodeAt(0) + 65248);
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function toFullWidthHyphen(value) {
|
|
255
|
+
if (!value) return value;
|
|
256
|
+
return value.replace(/-/g, "\u30FC");
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// src/normalizers/addHyphen.ts
|
|
260
|
+
function addPostalCodeHyphen(value) {
|
|
261
|
+
if (!value) return value;
|
|
262
|
+
let normalized = toHalfWidthNumbers(value);
|
|
263
|
+
normalized = toHalfWidthHyphen(normalized);
|
|
264
|
+
const digitsOnly = normalized.replace(/-/g, "");
|
|
265
|
+
if (digitsOnly.length >= 4) {
|
|
266
|
+
return digitsOnly.slice(0, 3) + "-" + digitsOnly.slice(3, 7);
|
|
267
|
+
}
|
|
268
|
+
return digitsOnly;
|
|
269
|
+
}
|
|
270
|
+
function addPhoneNumberHyphen(value) {
|
|
271
|
+
if (!value) return value;
|
|
272
|
+
let normalized = toHalfWidthNumbers(value);
|
|
273
|
+
normalized = toHalfWidthHyphen(normalized);
|
|
274
|
+
const digitsOnly = normalized.replace(/-/g, "");
|
|
275
|
+
if (digitsOnly.length === 11) {
|
|
276
|
+
if (digitsOnly.startsWith("0")) {
|
|
277
|
+
return digitsOnly.slice(0, 3) + "-" + digitsOnly.slice(3, 7) + "-" + digitsOnly.slice(7);
|
|
278
|
+
}
|
|
279
|
+
} else if (digitsOnly.length === 10) {
|
|
280
|
+
if (digitsOnly.startsWith("0")) {
|
|
281
|
+
if (digitsOnly.startsWith("03") || digitsOnly.startsWith("06")) {
|
|
282
|
+
return digitsOnly.slice(0, 2) + "-" + digitsOnly.slice(2, 6) + "-" + digitsOnly.slice(6);
|
|
283
|
+
}
|
|
284
|
+
return digitsOnly.slice(0, 4) + "-" + digitsOnly.slice(4, 6) + "-" + digitsOnly.slice(6);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return digitsOnly;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// src/hooks/usePostalCodeField.ts
|
|
291
|
+
function usePostalCodeField(options) {
|
|
292
|
+
const {
|
|
293
|
+
widthMode,
|
|
294
|
+
onInvalid,
|
|
295
|
+
autoHyphen = true,
|
|
296
|
+
normalizeOn = "blur",
|
|
297
|
+
validateOn = "blur",
|
|
298
|
+
errorMessages = {}
|
|
299
|
+
} = options;
|
|
300
|
+
const [value, setValue] = (0, import_react2.useState)("");
|
|
301
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
302
|
+
const [isValidating, setIsValidating] = (0, import_react2.useState)(false);
|
|
303
|
+
const isComposingRef = (0, import_react2.useRef)(false);
|
|
304
|
+
const messages = {
|
|
305
|
+
invalidWidth: errorMessages.invalidWidth ?? defaultErrorMessages.invalidWidth,
|
|
306
|
+
invalidFormat: errorMessages.invalidFormat ?? defaultErrorMessages.invalidPostalCode
|
|
307
|
+
};
|
|
308
|
+
const normalizeWidth = (0, import_react2.useCallback)(
|
|
309
|
+
(val) => {
|
|
310
|
+
if (widthMode === "half-width-only") {
|
|
311
|
+
let normalized = toHalfWidthNumbers(val);
|
|
312
|
+
normalized = toHalfWidthHyphen(normalized);
|
|
313
|
+
return normalized;
|
|
314
|
+
} else {
|
|
315
|
+
let normalized = toFullWidthNumbers(val);
|
|
316
|
+
normalized = toFullWidthHyphen(normalized);
|
|
317
|
+
return normalized;
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
[widthMode]
|
|
321
|
+
);
|
|
322
|
+
const normalize = (0, import_react2.useCallback)(
|
|
323
|
+
(val) => {
|
|
324
|
+
let normalized = val;
|
|
325
|
+
if (onInvalid === "auto-convert") {
|
|
326
|
+
normalized = normalizeWidth(normalized);
|
|
327
|
+
}
|
|
328
|
+
if (autoHyphen && widthMode === "half-width-only") {
|
|
329
|
+
normalized = addPostalCodeHyphen(normalized);
|
|
330
|
+
}
|
|
331
|
+
return normalized;
|
|
332
|
+
},
|
|
333
|
+
[onInvalid, autoHyphen, widthMode, normalizeWidth]
|
|
334
|
+
);
|
|
335
|
+
const validate = (0, import_react2.useCallback)(
|
|
336
|
+
(val) => {
|
|
337
|
+
if (!val) return null;
|
|
338
|
+
if (onInvalid === "error") {
|
|
339
|
+
if (widthMode === "half-width-only" && !isHalfWidthPostalCode(val)) {
|
|
340
|
+
return messages.invalidWidth;
|
|
341
|
+
}
|
|
342
|
+
if (widthMode === "full-width-only" && !isFullWidthPostalCode(val)) {
|
|
343
|
+
return messages.invalidWidth;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (!validatePostalCode(val)) {
|
|
347
|
+
return messages.invalidFormat;
|
|
348
|
+
}
|
|
349
|
+
return null;
|
|
350
|
+
},
|
|
351
|
+
[onInvalid, widthMode, messages.invalidWidth, messages.invalidFormat]
|
|
352
|
+
);
|
|
353
|
+
const handleChange = (0, import_react2.useCallback)(
|
|
354
|
+
(e) => {
|
|
355
|
+
const newValue = e.target.value;
|
|
356
|
+
setValue(newValue);
|
|
357
|
+
if (isComposingRef.current) return;
|
|
358
|
+
if (normalizeOn === "change") {
|
|
359
|
+
setValue(normalize(newValue));
|
|
360
|
+
}
|
|
361
|
+
if (validateOn === "change") {
|
|
362
|
+
setIsValidating(true);
|
|
363
|
+
const validationError = validate(
|
|
364
|
+
normalizeOn === "change" ? normalize(newValue) : newValue
|
|
365
|
+
);
|
|
366
|
+
setError(validationError);
|
|
367
|
+
setIsValidating(false);
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
371
|
+
);
|
|
372
|
+
const handleBlur = (0, import_react2.useCallback)(
|
|
373
|
+
(e) => {
|
|
374
|
+
const currentValue = e.target.value;
|
|
375
|
+
if (normalizeOn === "blur") {
|
|
376
|
+
const normalized = normalize(currentValue);
|
|
377
|
+
setValue(normalized);
|
|
378
|
+
if (validateOn === "blur") {
|
|
379
|
+
setIsValidating(true);
|
|
380
|
+
setError(validate(normalized));
|
|
381
|
+
setIsValidating(false);
|
|
382
|
+
}
|
|
383
|
+
} else if (validateOn === "blur") {
|
|
384
|
+
setIsValidating(true);
|
|
385
|
+
setError(validate(currentValue));
|
|
386
|
+
setIsValidating(false);
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
390
|
+
);
|
|
391
|
+
const handleCompositionStart = (0, import_react2.useCallback)(
|
|
392
|
+
(_e) => {
|
|
393
|
+
isComposingRef.current = true;
|
|
394
|
+
},
|
|
395
|
+
[]
|
|
396
|
+
);
|
|
397
|
+
const handleCompositionEnd = (0, import_react2.useCallback)(
|
|
398
|
+
(e) => {
|
|
399
|
+
isComposingRef.current = false;
|
|
400
|
+
const currentValue = e.currentTarget.value;
|
|
401
|
+
if (normalizeOn === "compositionEnd") {
|
|
402
|
+
const normalized = normalize(currentValue);
|
|
403
|
+
setValue(normalized);
|
|
404
|
+
if (validateOn === "blur" || validateOn === "change") {
|
|
405
|
+
setIsValidating(true);
|
|
406
|
+
setError(validate(normalized));
|
|
407
|
+
setIsValidating(false);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
412
|
+
);
|
|
413
|
+
return {
|
|
414
|
+
value,
|
|
415
|
+
onChange: handleChange,
|
|
416
|
+
onBlur: handleBlur,
|
|
417
|
+
onCompositionStart: handleCompositionStart,
|
|
418
|
+
onCompositionEnd: handleCompositionEnd,
|
|
419
|
+
error,
|
|
420
|
+
isValidating,
|
|
421
|
+
isComposing: isComposingRef.current
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// src/hooks/usePrefectureField.ts
|
|
426
|
+
var import_react3 = require("react");
|
|
427
|
+
|
|
428
|
+
// src/validators/prefecture.ts
|
|
429
|
+
var PREFECTURES = [
|
|
430
|
+
"\u5317\u6D77\u9053",
|
|
431
|
+
"\u9752\u68EE\u770C",
|
|
432
|
+
"\u5CA9\u624B\u770C",
|
|
433
|
+
"\u5BAE\u57CE\u770C",
|
|
434
|
+
"\u79CB\u7530\u770C",
|
|
435
|
+
"\u5C71\u5F62\u770C",
|
|
436
|
+
"\u798F\u5CF6\u770C",
|
|
437
|
+
"\u8328\u57CE\u770C",
|
|
438
|
+
"\u6803\u6728\u770C",
|
|
439
|
+
"\u7FA4\u99AC\u770C",
|
|
440
|
+
"\u57FC\u7389\u770C",
|
|
441
|
+
"\u5343\u8449\u770C",
|
|
442
|
+
"\u6771\u4EAC\u90FD",
|
|
443
|
+
"\u795E\u5948\u5DDD\u770C",
|
|
444
|
+
"\u65B0\u6F5F\u770C",
|
|
445
|
+
"\u5BCC\u5C71\u770C",
|
|
446
|
+
"\u77F3\u5DDD\u770C",
|
|
447
|
+
"\u798F\u4E95\u770C",
|
|
448
|
+
"\u5C71\u68A8\u770C",
|
|
449
|
+
"\u9577\u91CE\u770C",
|
|
450
|
+
"\u5C90\u961C\u770C",
|
|
451
|
+
"\u9759\u5CA1\u770C",
|
|
452
|
+
"\u611B\u77E5\u770C",
|
|
453
|
+
"\u4E09\u91CD\u770C",
|
|
454
|
+
"\u6ECB\u8CC0\u770C",
|
|
455
|
+
"\u4EAC\u90FD\u5E9C",
|
|
456
|
+
"\u5927\u962A\u5E9C",
|
|
457
|
+
"\u5175\u5EAB\u770C",
|
|
458
|
+
"\u5948\u826F\u770C",
|
|
459
|
+
"\u548C\u6B4C\u5C71\u770C",
|
|
460
|
+
"\u9CE5\u53D6\u770C",
|
|
461
|
+
"\u5CF6\u6839\u770C",
|
|
462
|
+
"\u5CA1\u5C71\u770C",
|
|
463
|
+
"\u5E83\u5CF6\u770C",
|
|
464
|
+
"\u5C71\u53E3\u770C",
|
|
465
|
+
"\u5FB3\u5CF6\u770C",
|
|
466
|
+
"\u9999\u5DDD\u770C",
|
|
467
|
+
"\u611B\u5A9B\u770C",
|
|
468
|
+
"\u9AD8\u77E5\u770C",
|
|
469
|
+
"\u798F\u5CA1\u770C",
|
|
470
|
+
"\u4F50\u8CC0\u770C",
|
|
471
|
+
"\u9577\u5D0E\u770C",
|
|
472
|
+
"\u718A\u672C\u770C",
|
|
473
|
+
"\u5927\u5206\u770C",
|
|
474
|
+
"\u5BAE\u5D0E\u770C",
|
|
475
|
+
"\u9E7F\u5150\u5CF6\u770C",
|
|
476
|
+
"\u6C96\u7E04\u770C"
|
|
477
|
+
];
|
|
478
|
+
var PREFECTURE_SHORT_NAMES = {
|
|
479
|
+
\u5317\u6D77: "\u5317\u6D77\u9053",
|
|
480
|
+
\u9752\u68EE: "\u9752\u68EE\u770C",
|
|
481
|
+
\u5CA9\u624B: "\u5CA9\u624B\u770C",
|
|
482
|
+
\u5BAE\u57CE: "\u5BAE\u57CE\u770C",
|
|
483
|
+
\u79CB\u7530: "\u79CB\u7530\u770C",
|
|
484
|
+
\u5C71\u5F62: "\u5C71\u5F62\u770C",
|
|
485
|
+
\u798F\u5CF6: "\u798F\u5CF6\u770C",
|
|
486
|
+
\u8328\u57CE: "\u8328\u57CE\u770C",
|
|
487
|
+
\u6803\u6728: "\u6803\u6728\u770C",
|
|
488
|
+
\u7FA4\u99AC: "\u7FA4\u99AC\u770C",
|
|
489
|
+
\u57FC\u7389: "\u57FC\u7389\u770C",
|
|
490
|
+
\u5343\u8449: "\u5343\u8449\u770C",
|
|
491
|
+
\u6771\u4EAC: "\u6771\u4EAC\u90FD",
|
|
492
|
+
\u795E\u5948\u5DDD: "\u795E\u5948\u5DDD\u770C",
|
|
493
|
+
\u65B0\u6F5F: "\u65B0\u6F5F\u770C",
|
|
494
|
+
\u5BCC\u5C71: "\u5BCC\u5C71\u770C",
|
|
495
|
+
\u77F3\u5DDD: "\u77F3\u5DDD\u770C",
|
|
496
|
+
\u798F\u4E95: "\u798F\u4E95\u770C",
|
|
497
|
+
\u5C71\u68A8: "\u5C71\u68A8\u770C",
|
|
498
|
+
\u9577\u91CE: "\u9577\u91CE\u770C",
|
|
499
|
+
\u5C90\u961C: "\u5C90\u961C\u770C",
|
|
500
|
+
\u9759\u5CA1: "\u9759\u5CA1\u770C",
|
|
501
|
+
\u611B\u77E5: "\u611B\u77E5\u770C",
|
|
502
|
+
\u4E09\u91CD: "\u4E09\u91CD\u770C",
|
|
503
|
+
\u6ECB\u8CC0: "\u6ECB\u8CC0\u770C",
|
|
504
|
+
\u4EAC\u90FD: "\u4EAC\u90FD\u5E9C",
|
|
505
|
+
\u5927\u962A: "\u5927\u962A\u5E9C",
|
|
506
|
+
\u5175\u5EAB: "\u5175\u5EAB\u770C",
|
|
507
|
+
\u5948\u826F: "\u5948\u826F\u770C",
|
|
508
|
+
\u548C\u6B4C\u5C71: "\u548C\u6B4C\u5C71\u770C",
|
|
509
|
+
\u9CE5\u53D6: "\u9CE5\u53D6\u770C",
|
|
510
|
+
\u5CF6\u6839: "\u5CF6\u6839\u770C",
|
|
511
|
+
\u5CA1\u5C71: "\u5CA1\u5C71\u770C",
|
|
512
|
+
\u5E83\u5CF6: "\u5E83\u5CF6\u770C",
|
|
513
|
+
\u5C71\u53E3: "\u5C71\u53E3\u770C",
|
|
514
|
+
\u5FB3\u5CF6: "\u5FB3\u5CF6\u770C",
|
|
515
|
+
\u9999\u5DDD: "\u9999\u5DDD\u770C",
|
|
516
|
+
\u611B\u5A9B: "\u611B\u5A9B\u770C",
|
|
517
|
+
\u9AD8\u77E5: "\u9AD8\u77E5\u770C",
|
|
518
|
+
\u798F\u5CA1: "\u798F\u5CA1\u770C",
|
|
519
|
+
\u4F50\u8CC0: "\u4F50\u8CC0\u770C",
|
|
520
|
+
\u9577\u5D0E: "\u9577\u5D0E\u770C",
|
|
521
|
+
\u718A\u672C: "\u718A\u672C\u770C",
|
|
522
|
+
\u5927\u5206: "\u5927\u5206\u770C",
|
|
523
|
+
\u5BAE\u5D0E: "\u5BAE\u5D0E\u770C",
|
|
524
|
+
\u9E7F\u5150\u5CF6: "\u9E7F\u5150\u5CF6\u770C",
|
|
525
|
+
\u6C96\u7E04: "\u6C96\u7E04\u770C"
|
|
526
|
+
};
|
|
527
|
+
function validatePrefecture(value) {
|
|
528
|
+
if (!value) return true;
|
|
529
|
+
return PREFECTURES.includes(value) || Object.keys(PREFECTURE_SHORT_NAMES).includes(value);
|
|
530
|
+
}
|
|
531
|
+
function normalizePrefecture(value) {
|
|
532
|
+
if (!value) return value;
|
|
533
|
+
if (PREFECTURES.includes(value)) {
|
|
534
|
+
return value;
|
|
535
|
+
}
|
|
536
|
+
return PREFECTURE_SHORT_NAMES[value] || value;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// src/hooks/usePrefectureField.ts
|
|
540
|
+
function usePrefectureField(options = {}) {
|
|
541
|
+
const {
|
|
542
|
+
autoComplete = true,
|
|
543
|
+
normalizeOn = "blur",
|
|
544
|
+
validateOn = "blur",
|
|
545
|
+
errorMessages = {}
|
|
546
|
+
} = options;
|
|
547
|
+
const [value, setValue] = (0, import_react3.useState)("");
|
|
548
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
549
|
+
const [isValidating, setIsValidating] = (0, import_react3.useState)(false);
|
|
550
|
+
const isComposingRef = (0, import_react3.useRef)(false);
|
|
551
|
+
const messages = {
|
|
552
|
+
invalidPrefecture: errorMessages.invalidPrefecture ?? defaultErrorMessages.invalidPrefecture
|
|
553
|
+
};
|
|
554
|
+
const normalize = (0, import_react3.useCallback)(
|
|
555
|
+
(val) => {
|
|
556
|
+
if (autoComplete) {
|
|
557
|
+
return normalizePrefecture(val);
|
|
558
|
+
}
|
|
559
|
+
return val;
|
|
560
|
+
},
|
|
561
|
+
[autoComplete]
|
|
562
|
+
);
|
|
563
|
+
const validate = (0, import_react3.useCallback)(
|
|
564
|
+
(val) => {
|
|
565
|
+
if (!val) return null;
|
|
566
|
+
if (!validatePrefecture(val)) {
|
|
567
|
+
return messages.invalidPrefecture;
|
|
568
|
+
}
|
|
569
|
+
return null;
|
|
570
|
+
},
|
|
571
|
+
[messages.invalidPrefecture]
|
|
572
|
+
);
|
|
573
|
+
const handleChange = (0, import_react3.useCallback)(
|
|
574
|
+
(e) => {
|
|
575
|
+
const newValue = e.target.value;
|
|
576
|
+
setValue(newValue);
|
|
577
|
+
if (isComposingRef.current) return;
|
|
578
|
+
if (normalizeOn === "change") {
|
|
579
|
+
setValue(normalize(newValue));
|
|
580
|
+
}
|
|
581
|
+
if (validateOn === "change") {
|
|
582
|
+
setIsValidating(true);
|
|
583
|
+
const validationError = validate(
|
|
584
|
+
normalizeOn === "change" ? normalize(newValue) : newValue
|
|
585
|
+
);
|
|
586
|
+
setError(validationError);
|
|
587
|
+
setIsValidating(false);
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
591
|
+
);
|
|
592
|
+
const handleBlur = (0, import_react3.useCallback)(
|
|
593
|
+
(e) => {
|
|
594
|
+
const currentValue = e.target.value;
|
|
595
|
+
if (normalizeOn === "blur") {
|
|
596
|
+
const normalized = normalize(currentValue);
|
|
597
|
+
setValue(normalized);
|
|
598
|
+
if (validateOn === "blur") {
|
|
599
|
+
setIsValidating(true);
|
|
600
|
+
setError(validate(normalized));
|
|
601
|
+
setIsValidating(false);
|
|
602
|
+
}
|
|
603
|
+
} else if (validateOn === "blur") {
|
|
604
|
+
setIsValidating(true);
|
|
605
|
+
setError(validate(currentValue));
|
|
606
|
+
setIsValidating(false);
|
|
607
|
+
}
|
|
608
|
+
},
|
|
609
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
610
|
+
);
|
|
611
|
+
const handleCompositionStart = (0, import_react3.useCallback)(
|
|
612
|
+
(_e) => {
|
|
613
|
+
isComposingRef.current = true;
|
|
614
|
+
},
|
|
615
|
+
[]
|
|
616
|
+
);
|
|
617
|
+
const handleCompositionEnd = (0, import_react3.useCallback)(
|
|
618
|
+
(e) => {
|
|
619
|
+
isComposingRef.current = false;
|
|
620
|
+
const currentValue = e.currentTarget.value;
|
|
621
|
+
if (normalizeOn === "compositionEnd") {
|
|
622
|
+
const normalized = normalize(currentValue);
|
|
623
|
+
setValue(normalized);
|
|
624
|
+
if (validateOn === "blur" || validateOn === "change") {
|
|
625
|
+
setIsValidating(true);
|
|
626
|
+
setError(validate(normalized));
|
|
627
|
+
setIsValidating(false);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
},
|
|
631
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
632
|
+
);
|
|
633
|
+
return {
|
|
634
|
+
value,
|
|
635
|
+
onChange: handleChange,
|
|
636
|
+
onBlur: handleBlur,
|
|
637
|
+
onCompositionStart: handleCompositionStart,
|
|
638
|
+
onCompositionEnd: handleCompositionEnd,
|
|
639
|
+
error,
|
|
640
|
+
isValidating,
|
|
641
|
+
isComposing: isComposingRef.current
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// src/hooks/useAddressField.ts
|
|
646
|
+
var import_react4 = require("react");
|
|
647
|
+
function containsHalfWidthAlphanumeric(value) {
|
|
648
|
+
return /[A-Za-z0-9]/.test(value);
|
|
649
|
+
}
|
|
650
|
+
function useAddressField(options) {
|
|
651
|
+
const {
|
|
652
|
+
alphanumericMode,
|
|
653
|
+
onInvalid,
|
|
654
|
+
normalizeOn = "blur",
|
|
655
|
+
validateOn = "blur",
|
|
656
|
+
errorMessages = {}
|
|
657
|
+
} = options;
|
|
658
|
+
const [value, setValue] = (0, import_react4.useState)("");
|
|
659
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
660
|
+
const [isValidating, setIsValidating] = (0, import_react4.useState)(false);
|
|
661
|
+
const isComposingRef = (0, import_react4.useRef)(false);
|
|
662
|
+
const messages = {
|
|
663
|
+
invalidWidth: errorMessages.invalidWidth ?? defaultErrorMessages.invalidWidth
|
|
664
|
+
};
|
|
665
|
+
const normalize = (0, import_react4.useCallback)(
|
|
666
|
+
(val) => {
|
|
667
|
+
if (alphanumericMode === "full-width-only" && onInvalid === "auto-convert") {
|
|
668
|
+
return toFullWidth(val);
|
|
669
|
+
}
|
|
670
|
+
return val;
|
|
671
|
+
},
|
|
672
|
+
[alphanumericMode, onInvalid]
|
|
673
|
+
);
|
|
674
|
+
const validate = (0, import_react4.useCallback)(
|
|
675
|
+
(val) => {
|
|
676
|
+
if (!val) return null;
|
|
677
|
+
if (alphanumericMode === "full-width-only" && onInvalid === "error" && containsHalfWidthAlphanumeric(val)) {
|
|
678
|
+
return messages.invalidWidth;
|
|
679
|
+
}
|
|
680
|
+
return null;
|
|
681
|
+
},
|
|
682
|
+
[alphanumericMode, onInvalid, messages.invalidWidth]
|
|
683
|
+
);
|
|
684
|
+
const handleChange = (0, import_react4.useCallback)(
|
|
685
|
+
(e) => {
|
|
686
|
+
const newValue = e.target.value;
|
|
687
|
+
setValue(newValue);
|
|
688
|
+
if (isComposingRef.current) return;
|
|
689
|
+
if (normalizeOn === "change") {
|
|
690
|
+
setValue(normalize(newValue));
|
|
691
|
+
}
|
|
692
|
+
if (validateOn === "change") {
|
|
693
|
+
setIsValidating(true);
|
|
694
|
+
const validationError = validate(
|
|
695
|
+
normalizeOn === "change" ? normalize(newValue) : newValue
|
|
696
|
+
);
|
|
697
|
+
setError(validationError);
|
|
698
|
+
setIsValidating(false);
|
|
699
|
+
}
|
|
700
|
+
},
|
|
701
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
702
|
+
);
|
|
703
|
+
const handleBlur = (0, import_react4.useCallback)(
|
|
704
|
+
(e) => {
|
|
705
|
+
const currentValue = e.target.value;
|
|
706
|
+
if (normalizeOn === "blur") {
|
|
707
|
+
const normalized = normalize(currentValue);
|
|
708
|
+
setValue(normalized);
|
|
709
|
+
if (validateOn === "blur") {
|
|
710
|
+
setIsValidating(true);
|
|
711
|
+
setError(validate(normalized));
|
|
712
|
+
setIsValidating(false);
|
|
713
|
+
}
|
|
714
|
+
} else if (validateOn === "blur") {
|
|
715
|
+
setIsValidating(true);
|
|
716
|
+
setError(validate(currentValue));
|
|
717
|
+
setIsValidating(false);
|
|
718
|
+
}
|
|
719
|
+
},
|
|
720
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
721
|
+
);
|
|
722
|
+
const handleCompositionStart = (0, import_react4.useCallback)(
|
|
723
|
+
(_e) => {
|
|
724
|
+
isComposingRef.current = true;
|
|
725
|
+
},
|
|
726
|
+
[]
|
|
727
|
+
);
|
|
728
|
+
const handleCompositionEnd = (0, import_react4.useCallback)(
|
|
729
|
+
(e) => {
|
|
730
|
+
isComposingRef.current = false;
|
|
731
|
+
const currentValue = e.currentTarget.value;
|
|
732
|
+
if (normalizeOn === "compositionEnd") {
|
|
733
|
+
const normalized = normalize(currentValue);
|
|
734
|
+
setValue(normalized);
|
|
735
|
+
if (validateOn === "blur" || validateOn === "change") {
|
|
736
|
+
setIsValidating(true);
|
|
737
|
+
setError(validate(normalized));
|
|
738
|
+
setIsValidating(false);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
},
|
|
742
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
743
|
+
);
|
|
744
|
+
return {
|
|
745
|
+
value,
|
|
746
|
+
onChange: handleChange,
|
|
747
|
+
onBlur: handleBlur,
|
|
748
|
+
onCompositionStart: handleCompositionStart,
|
|
749
|
+
onCompositionEnd: handleCompositionEnd,
|
|
750
|
+
error,
|
|
751
|
+
isValidating,
|
|
752
|
+
isComposing: isComposingRef.current
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// src/hooks/usePhoneNumberField.ts
|
|
757
|
+
var import_react5 = require("react");
|
|
758
|
+
|
|
759
|
+
// src/validators/phoneNumber.ts
|
|
760
|
+
function validatePhoneNumber(value) {
|
|
761
|
+
if (!value) return true;
|
|
762
|
+
const normalized = value.replace(/[0-9]/g, (s) => String.fromCharCode(s.charCodeAt(0) - 65248)).replace(/[ー-]/g, "-");
|
|
763
|
+
const digitsOnly = normalized.replace(/-/g, "");
|
|
764
|
+
if (digitsOnly.length < 10 || digitsOnly.length > 11) {
|
|
765
|
+
return false;
|
|
766
|
+
}
|
|
767
|
+
const phoneRegex = /^[\d-]+$/;
|
|
768
|
+
return phoneRegex.test(normalized);
|
|
769
|
+
}
|
|
770
|
+
function isHalfWidthPhoneNumber(value) {
|
|
771
|
+
if (!value) return true;
|
|
772
|
+
const halfWidthRegex = /^[\d-]+$/;
|
|
773
|
+
return halfWidthRegex.test(value);
|
|
774
|
+
}
|
|
775
|
+
function containsFullWidthPhoneNumber(value) {
|
|
776
|
+
if (!value) return false;
|
|
777
|
+
const fullWidthRegex = /[0-9ー-]/;
|
|
778
|
+
return fullWidthRegex.test(value);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// src/hooks/usePhoneNumberField.ts
|
|
782
|
+
function usePhoneNumberField(options) {
|
|
783
|
+
const {
|
|
784
|
+
onInvalid,
|
|
785
|
+
autoHyphen = true,
|
|
786
|
+
normalizeOn = "blur",
|
|
787
|
+
validateOn = "blur",
|
|
788
|
+
errorMessages = {}
|
|
789
|
+
} = options;
|
|
790
|
+
const [value, setValue] = (0, import_react5.useState)("");
|
|
791
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
|
792
|
+
const [isValidating, setIsValidating] = (0, import_react5.useState)(false);
|
|
793
|
+
const isComposingRef = (0, import_react5.useRef)(false);
|
|
794
|
+
const messages = {
|
|
795
|
+
invalidWidth: errorMessages.invalidWidth ?? defaultErrorMessages.invalidWidth,
|
|
796
|
+
invalidFormat: errorMessages.invalidFormat ?? defaultErrorMessages.invalidPhoneNumber
|
|
797
|
+
};
|
|
798
|
+
const normalize = (0, import_react5.useCallback)(
|
|
799
|
+
(val) => {
|
|
800
|
+
let normalized = val;
|
|
801
|
+
if (onInvalid === "auto-convert") {
|
|
802
|
+
normalized = toHalfWidthNumbers(normalized);
|
|
803
|
+
normalized = toHalfWidthHyphen(normalized);
|
|
804
|
+
}
|
|
805
|
+
if (autoHyphen) {
|
|
806
|
+
normalized = addPhoneNumberHyphen(normalized);
|
|
807
|
+
}
|
|
808
|
+
return normalized;
|
|
809
|
+
},
|
|
810
|
+
[onInvalid, autoHyphen]
|
|
811
|
+
);
|
|
812
|
+
const validate = (0, import_react5.useCallback)(
|
|
813
|
+
(val) => {
|
|
814
|
+
if (!val) return null;
|
|
815
|
+
if (onInvalid === "error" && containsFullWidthPhoneNumber(val)) {
|
|
816
|
+
return messages.invalidWidth;
|
|
817
|
+
}
|
|
818
|
+
if (!validatePhoneNumber(val)) {
|
|
819
|
+
return messages.invalidFormat;
|
|
820
|
+
}
|
|
821
|
+
return null;
|
|
822
|
+
},
|
|
823
|
+
[onInvalid, messages.invalidWidth, messages.invalidFormat]
|
|
824
|
+
);
|
|
825
|
+
const handleChange = (0, import_react5.useCallback)(
|
|
826
|
+
(e) => {
|
|
827
|
+
const newValue = e.target.value;
|
|
828
|
+
setValue(newValue);
|
|
829
|
+
if (isComposingRef.current) return;
|
|
830
|
+
if (normalizeOn === "change") {
|
|
831
|
+
setValue(normalize(newValue));
|
|
832
|
+
}
|
|
833
|
+
if (validateOn === "change") {
|
|
834
|
+
setIsValidating(true);
|
|
835
|
+
const validationError = validate(
|
|
836
|
+
normalizeOn === "change" ? normalize(newValue) : newValue
|
|
837
|
+
);
|
|
838
|
+
setError(validationError);
|
|
839
|
+
setIsValidating(false);
|
|
840
|
+
}
|
|
841
|
+
},
|
|
842
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
843
|
+
);
|
|
844
|
+
const handleBlur = (0, import_react5.useCallback)(
|
|
845
|
+
(e) => {
|
|
846
|
+
const currentValue = e.target.value;
|
|
847
|
+
if (normalizeOn === "blur") {
|
|
848
|
+
const normalized = normalize(currentValue);
|
|
849
|
+
setValue(normalized);
|
|
850
|
+
if (validateOn === "blur") {
|
|
851
|
+
setIsValidating(true);
|
|
852
|
+
setError(validate(normalized));
|
|
853
|
+
setIsValidating(false);
|
|
854
|
+
}
|
|
855
|
+
} else if (validateOn === "blur") {
|
|
856
|
+
setIsValidating(true);
|
|
857
|
+
setError(validate(currentValue));
|
|
858
|
+
setIsValidating(false);
|
|
859
|
+
}
|
|
860
|
+
},
|
|
861
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
862
|
+
);
|
|
863
|
+
const handleCompositionStart = (0, import_react5.useCallback)(
|
|
864
|
+
(_e) => {
|
|
865
|
+
isComposingRef.current = true;
|
|
866
|
+
},
|
|
867
|
+
[]
|
|
868
|
+
);
|
|
869
|
+
const handleCompositionEnd = (0, import_react5.useCallback)(
|
|
870
|
+
(e) => {
|
|
871
|
+
isComposingRef.current = false;
|
|
872
|
+
const currentValue = e.currentTarget.value;
|
|
873
|
+
if (normalizeOn === "compositionEnd") {
|
|
874
|
+
const normalized = normalize(currentValue);
|
|
875
|
+
setValue(normalized);
|
|
876
|
+
if (validateOn === "blur" || validateOn === "change") {
|
|
877
|
+
setIsValidating(true);
|
|
878
|
+
setError(validate(normalized));
|
|
879
|
+
setIsValidating(false);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
},
|
|
883
|
+
[normalize, validate, normalizeOn, validateOn]
|
|
884
|
+
);
|
|
885
|
+
return {
|
|
886
|
+
value,
|
|
887
|
+
onChange: handleChange,
|
|
888
|
+
onBlur: handleBlur,
|
|
889
|
+
onCompositionStart: handleCompositionStart,
|
|
890
|
+
onCompositionEnd: handleCompositionEnd,
|
|
891
|
+
error,
|
|
892
|
+
isValidating,
|
|
893
|
+
isComposing: isComposingRef.current
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// src/validators/hiragana.ts
|
|
898
|
+
function validateHiragana(value) {
|
|
899
|
+
if (!value) return true;
|
|
900
|
+
const hiraganaRegex = /^[\u3040-\u309F\u30FC\u3000\s]+$/;
|
|
901
|
+
return hiraganaRegex.test(value);
|
|
902
|
+
}
|
|
903
|
+
function containsKatakana(value) {
|
|
904
|
+
if (!value) return false;
|
|
905
|
+
const katakanaRegex = /[\u30A0-\u30FF]/;
|
|
906
|
+
return katakanaRegex.test(value);
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// src/normalizers/toHiragana.ts
|
|
910
|
+
function toHiragana(value) {
|
|
911
|
+
if (!value) return value;
|
|
912
|
+
return value.replace(/[\u30A1-\u30F6]/g, (char) => {
|
|
913
|
+
return String.fromCharCode(char.charCodeAt(0) - 96);
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
917
|
+
0 && (module.exports = {
|
|
918
|
+
PREFECTURES,
|
|
919
|
+
PREFECTURE_SHORT_NAMES,
|
|
920
|
+
addPhoneNumberHyphen,
|
|
921
|
+
addPostalCodeHyphen,
|
|
922
|
+
containsFullWidthPhoneNumber,
|
|
923
|
+
containsHiragana,
|
|
924
|
+
containsKatakana,
|
|
925
|
+
defaultErrorMessages,
|
|
926
|
+
isFullWidthPostalCode,
|
|
927
|
+
isHalfWidthPhoneNumber,
|
|
928
|
+
isHalfWidthPostalCode,
|
|
929
|
+
normalizePrefecture,
|
|
930
|
+
toFullWidth,
|
|
931
|
+
toFullWidthHyphen,
|
|
932
|
+
toFullWidthNumbers,
|
|
933
|
+
toHalfWidth,
|
|
934
|
+
toHalfWidthHyphen,
|
|
935
|
+
toHalfWidthNumbers,
|
|
936
|
+
toHiragana,
|
|
937
|
+
toKatakana,
|
|
938
|
+
useAddressField,
|
|
939
|
+
useNameField,
|
|
940
|
+
usePhoneNumberField,
|
|
941
|
+
usePostalCodeField,
|
|
942
|
+
usePrefectureField,
|
|
943
|
+
validateHiragana,
|
|
944
|
+
validateKatakana,
|
|
945
|
+
validatePhoneNumber,
|
|
946
|
+
validatePostalCode,
|
|
947
|
+
validatePrefecture
|
|
948
|
+
});
|