@famgia/omnify-react 0.0.1
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 +178 -0
- package/dist/components/index.cjs +686 -0
- package/dist/components/index.cjs.map +1 -0
- package/dist/components/index.d.cts +95 -0
- package/dist/components/index.d.ts +95 -0
- package/dist/components/index.js +657 -0
- package/dist/components/index.js.map +1 -0
- package/dist/hooks/index.cjs +81 -0
- package/dist/hooks/index.cjs.map +1 -0
- package/dist/hooks/index.d.cts +20 -0
- package/dist/hooks/index.d.ts +20 -0
- package/dist/hooks/index.js +54 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.cjs +1005 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +947 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/index.cjs +479 -0
- package/dist/lib/index.cjs.map +1 -0
- package/dist/lib/index.d.cts +209 -0
- package/dist/lib/index.d.ts +209 -0
- package/dist/lib/index.js +425 -0
- package/dist/lib/index.js.map +1 -0
- package/package.json +110 -0
- package/scripts/postinstall.cjs +121 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,947 @@
|
|
|
1
|
+
// src/components/JapaneseNameField.tsx
|
|
2
|
+
import { Form, Input, Row, Col } from "antd";
|
|
3
|
+
|
|
4
|
+
// src/lib/zod-i18n.ts
|
|
5
|
+
var DEFAULT_MESSAGES = {
|
|
6
|
+
required: {
|
|
7
|
+
en: "${displayName} is required",
|
|
8
|
+
ja: "${displayName}\u306F\u5FC5\u9808\u3067\u3059",
|
|
9
|
+
vi: "${displayName} l\xE0 b\u1EAFt bu\u1ED9c",
|
|
10
|
+
ko: "${displayName}\uC740(\uB294) \uD544\uC218\uC785\uB2C8\uB2E4",
|
|
11
|
+
"zh-CN": "${displayName}\u662F\u5FC5\u586B\u9879",
|
|
12
|
+
"zh-TW": "${displayName}\u70BA\u5FC5\u586B\u6B04\u4F4D",
|
|
13
|
+
th: "${displayName} \u0E08\u0E33\u0E40\u0E1B\u0E47\u0E19\u0E15\u0E49\u0E2D\u0E07\u0E01\u0E23\u0E2D\u0E01",
|
|
14
|
+
es: "${displayName} es obligatorio"
|
|
15
|
+
},
|
|
16
|
+
minLength: {
|
|
17
|
+
en: "${displayName} must be at least ${min} characters",
|
|
18
|
+
ja: "${displayName}\u306F${min}\u6587\u5B57\u4EE5\u4E0A\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
19
|
+
vi: "${displayName} ph\u1EA3i c\xF3 \xEDt nh\u1EA5t ${min} k\xFD t\u1EF1",
|
|
20
|
+
ko: "${displayName}\uC740(\uB294) ${min}\uC790 \uC774\uC0C1\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4",
|
|
21
|
+
"zh-CN": "${displayName}\u81F3\u5C11\u9700\u8981${min}\u4E2A\u5B57\u7B26",
|
|
22
|
+
"zh-TW": "${displayName}\u81F3\u5C11\u9700\u8981${min}\u500B\u5B57\u5143",
|
|
23
|
+
th: "${displayName} \u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${min} \u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23",
|
|
24
|
+
es: "${displayName} debe tener al menos ${min} caracteres"
|
|
25
|
+
},
|
|
26
|
+
maxLength: {
|
|
27
|
+
en: "${displayName} must be at most ${max} characters",
|
|
28
|
+
ja: "${displayName}\u306F${max}\u6587\u5B57\u4EE5\u5185\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
29
|
+
vi: "${displayName} kh\xF4ng \u0111\u01B0\u1EE3c qu\xE1 ${max} k\xFD t\u1EF1",
|
|
30
|
+
ko: "${displayName}\uC740(\uB294) ${max}\uC790 \uC774\uD558\uC5EC\uC57C \uD569\uB2C8\uB2E4",
|
|
31
|
+
"zh-CN": "${displayName}\u6700\u591A${max}\u4E2A\u5B57\u7B26",
|
|
32
|
+
"zh-TW": "${displayName}\u6700\u591A${max}\u500B\u5B57\u5143",
|
|
33
|
+
th: "${displayName} \u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${max} \u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23",
|
|
34
|
+
es: "${displayName} debe tener como m\xE1ximo ${max} caracteres"
|
|
35
|
+
},
|
|
36
|
+
min: {
|
|
37
|
+
en: "${displayName} must be at least ${min}",
|
|
38
|
+
ja: "${displayName}\u306F${min}\u4EE5\u4E0A\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
39
|
+
vi: "${displayName} ph\u1EA3i l\u1EDBn h\u01A1n ho\u1EB7c b\u1EB1ng ${min}",
|
|
40
|
+
ko: "${displayName}\uC740(\uB294) ${min} \uC774\uC0C1\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4",
|
|
41
|
+
"zh-CN": "${displayName}\u5FC5\u987B\u5927\u4E8E\u7B49\u4E8E${min}",
|
|
42
|
+
"zh-TW": "${displayName}\u5FC5\u9808\u5927\u65BC\u7B49\u65BC${min}",
|
|
43
|
+
th: "${displayName} \u0E15\u0E49\u0E2D\u0E07\u0E21\u0E32\u0E01\u0E01\u0E27\u0E48\u0E32\u0E2B\u0E23\u0E37\u0E2D\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${min}",
|
|
44
|
+
es: "${displayName} debe ser al menos ${min}"
|
|
45
|
+
},
|
|
46
|
+
max: {
|
|
47
|
+
en: "${displayName} must be at most ${max}",
|
|
48
|
+
ja: "${displayName}\u306F${max}\u4EE5\u4E0B\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
49
|
+
vi: "${displayName} ph\u1EA3i nh\u1ECF h\u01A1n ho\u1EB7c b\u1EB1ng ${max}",
|
|
50
|
+
ko: "${displayName}\uC740(\uB294) ${max} \uC774\uD558\uC5EC\uC57C \uD569\uB2C8\uB2E4",
|
|
51
|
+
"zh-CN": "${displayName}\u5FC5\u987B\u5C0F\u4E8E\u7B49\u4E8E${max}",
|
|
52
|
+
"zh-TW": "${displayName}\u5FC5\u9808\u5C0F\u65BC\u7B49\u65BC${max}",
|
|
53
|
+
th: "${displayName} \u0E15\u0E49\u0E2D\u0E07\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32\u0E2B\u0E23\u0E37\u0E2D\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${max}",
|
|
54
|
+
es: "${displayName} debe ser como m\xE1ximo ${max}"
|
|
55
|
+
},
|
|
56
|
+
email: {
|
|
57
|
+
en: "Please enter a valid email address",
|
|
58
|
+
ja: "\u6709\u52B9\u306A\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
59
|
+
vi: "Vui l\xF2ng nh\u1EADp \u0111\u1ECBa ch\u1EC9 email h\u1EE3p l\u1EC7",
|
|
60
|
+
ko: "\uC720\uD6A8\uD55C \uC774\uBA54\uC77C \uC8FC\uC18C\uB97C \uC785\uB825\uD558\uC138\uC694",
|
|
61
|
+
"zh-CN": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u7535\u5B50\u90AE\u4EF6\u5730\u5740",
|
|
62
|
+
"zh-TW": "\u8ACB\u8F38\u5165\u6709\u6548\u7684\u96FB\u5B50\u90F5\u4EF6\u5730\u5740",
|
|
63
|
+
th: "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E2D\u0E35\u0E40\u0E21\u0E25\u0E17\u0E35\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
|
|
64
|
+
es: "Por favor, introduce una direcci\xF3n de correo electr\xF3nico v\xE1lida"
|
|
65
|
+
},
|
|
66
|
+
url: {
|
|
67
|
+
en: "Please enter a valid URL",
|
|
68
|
+
ja: "\u6709\u52B9\u306AURL\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
69
|
+
vi: "Vui l\xF2ng nh\u1EADp URL h\u1EE3p l\u1EC7",
|
|
70
|
+
ko: "\uC720\uD6A8\uD55C URL\uC744 \uC785\uB825\uD558\uC138\uC694",
|
|
71
|
+
"zh-CN": "\u8BF7\u8F93\u5165\u6709\u6548\u7684URL",
|
|
72
|
+
"zh-TW": "\u8ACB\u8F38\u5165\u6709\u6548\u7684\u7DB2\u5740",
|
|
73
|
+
th: "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01 URL \u0E17\u0E35\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
|
|
74
|
+
es: "Por favor, introduce una URL v\xE1lida"
|
|
75
|
+
},
|
|
76
|
+
pattern: {
|
|
77
|
+
en: "${displayName} format is invalid",
|
|
78
|
+
ja: "${displayName}\u306E\u5F62\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093",
|
|
79
|
+
vi: "${displayName} kh\xF4ng \u0111\xFAng \u0111\u1ECBnh d\u1EA1ng",
|
|
80
|
+
ko: "${displayName} \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4",
|
|
81
|
+
"zh-CN": "${displayName}\u683C\u5F0F\u4E0D\u6B63\u786E",
|
|
82
|
+
"zh-TW": "${displayName}\u683C\u5F0F\u4E0D\u6B63\u78BA",
|
|
83
|
+
th: "\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A${displayName}\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
|
|
84
|
+
es: "El formato de ${displayName} no es v\xE1lido"
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
var currentLocale = "ja";
|
|
88
|
+
var fallbackLocale = "en";
|
|
89
|
+
var customMessages = {};
|
|
90
|
+
function setZodLocale(locale) {
|
|
91
|
+
currentLocale = locale;
|
|
92
|
+
}
|
|
93
|
+
function getZodLocale() {
|
|
94
|
+
return currentLocale;
|
|
95
|
+
}
|
|
96
|
+
function setZodFallbackLocale(locale) {
|
|
97
|
+
fallbackLocale = locale;
|
|
98
|
+
}
|
|
99
|
+
function getZodFallbackLocale() {
|
|
100
|
+
return fallbackLocale;
|
|
101
|
+
}
|
|
102
|
+
function addZodMessages(messages) {
|
|
103
|
+
for (const [key, locales] of Object.entries(messages)) {
|
|
104
|
+
customMessages[key] = { ...customMessages[key], ...locales };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function getZodMessage(key, params = {}) {
|
|
108
|
+
const messages = customMessages[key] ?? DEFAULT_MESSAGES[key];
|
|
109
|
+
if (!messages) return key;
|
|
110
|
+
let message2 = messages[currentLocale] ?? messages[fallbackLocale] ?? messages["en"] ?? key;
|
|
111
|
+
for (const [param, value] of Object.entries(params)) {
|
|
112
|
+
message2 = message2.replace(new RegExp(`\\$\\{${param}\\}`, "g"), String(value));
|
|
113
|
+
}
|
|
114
|
+
return message2;
|
|
115
|
+
}
|
|
116
|
+
function getZodMessages(locale) {
|
|
117
|
+
const targetLocale = locale ?? currentLocale;
|
|
118
|
+
const result = {};
|
|
119
|
+
for (const [key, locales] of Object.entries(DEFAULT_MESSAGES)) {
|
|
120
|
+
result[key] = locales[targetLocale] ?? locales[fallbackLocale] ?? locales["en"] ?? key;
|
|
121
|
+
}
|
|
122
|
+
for (const [key, locales] of Object.entries(customMessages)) {
|
|
123
|
+
if (locales[targetLocale]) {
|
|
124
|
+
result[key] = locales[targetLocale];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/lib/form-validation.ts
|
|
131
|
+
function zodRule(schema, displayName) {
|
|
132
|
+
const field = displayName ?? "\u3053\u306E\u9805\u76EE";
|
|
133
|
+
return {
|
|
134
|
+
validator: async (_, value) => {
|
|
135
|
+
if (value === void 0 || value === null || value === "") {
|
|
136
|
+
if (schema.safeParse(void 0).success) return;
|
|
137
|
+
throw new Error(getZodMessage("required", { displayName: field }));
|
|
138
|
+
}
|
|
139
|
+
const result = schema.safeParse(value);
|
|
140
|
+
if (result.success) return;
|
|
141
|
+
const issue = result.error.issues[0];
|
|
142
|
+
if (!issue) {
|
|
143
|
+
throw new Error(getZodMessage("required", { displayName: field }));
|
|
144
|
+
}
|
|
145
|
+
const issueAny = issue;
|
|
146
|
+
switch (issue.code) {
|
|
147
|
+
case "too_small": {
|
|
148
|
+
const origin = issueAny.origin;
|
|
149
|
+
const minimum = issueAny.minimum;
|
|
150
|
+
if (origin === "string" && minimum === 1) {
|
|
151
|
+
throw new Error(getZodMessage("required", { displayName: field }));
|
|
152
|
+
}
|
|
153
|
+
if (origin === "string") {
|
|
154
|
+
throw new Error(getZodMessage("minLength", { displayName: field, min: minimum }));
|
|
155
|
+
}
|
|
156
|
+
throw new Error(getZodMessage("min", { displayName: field, min: minimum }));
|
|
157
|
+
}
|
|
158
|
+
case "too_big": {
|
|
159
|
+
const origin = issueAny.origin;
|
|
160
|
+
const maximum = issueAny.maximum;
|
|
161
|
+
if (origin === "string") {
|
|
162
|
+
throw new Error(getZodMessage("maxLength", { displayName: field, max: maximum }));
|
|
163
|
+
}
|
|
164
|
+
throw new Error(getZodMessage("max", { displayName: field, max: maximum }));
|
|
165
|
+
}
|
|
166
|
+
// Zod v4: 'invalid_string' → 'invalid_format'
|
|
167
|
+
case "invalid_format": {
|
|
168
|
+
const format = issueAny.format;
|
|
169
|
+
if (format === "email") {
|
|
170
|
+
throw new Error(getZodMessage("email", { displayName: field }));
|
|
171
|
+
}
|
|
172
|
+
if (format === "url") {
|
|
173
|
+
throw new Error(getZodMessage("url", { displayName: field }));
|
|
174
|
+
}
|
|
175
|
+
if (format === "regex") {
|
|
176
|
+
throw new Error(getZodMessage("pattern", { displayName: field }));
|
|
177
|
+
}
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
// Zod v3: 'invalid_string' (handled via default case for forward compatibility)
|
|
181
|
+
default: {
|
|
182
|
+
if (issue.code === "invalid_string") {
|
|
183
|
+
const validation = issueAny.validation;
|
|
184
|
+
if (validation === "email") {
|
|
185
|
+
throw new Error(getZodMessage("email", { displayName: field }));
|
|
186
|
+
}
|
|
187
|
+
if (validation === "url") {
|
|
188
|
+
throw new Error(getZodMessage("url", { displayName: field }));
|
|
189
|
+
}
|
|
190
|
+
if (validation === "regex") {
|
|
191
|
+
throw new Error(getZodMessage("pattern", { displayName: field }));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
case "invalid_type": {
|
|
197
|
+
const expected = issueAny.expected;
|
|
198
|
+
if (expected && value === void 0) {
|
|
199
|
+
throw new Error(getZodMessage("required", { displayName: field }));
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
throw new Error(issue.message);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function requiredRule(displayName) {
|
|
209
|
+
return {
|
|
210
|
+
required: true,
|
|
211
|
+
message: getZodMessage("required", { displayName })
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function isZodRequired(schema) {
|
|
215
|
+
const schemaDesc = schema?._def?.typeName;
|
|
216
|
+
const inner = schema?._def?.innerType;
|
|
217
|
+
if (schemaDesc === "ZodOptional" || schemaDesc === "ZodNullable") return false;
|
|
218
|
+
if (inner?._def?.typeName === "ZodOptional" || inner?._def?.typeName === "ZodNullable") return false;
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// src/components/JapaneseNameField.tsx
|
|
223
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
224
|
+
function getLabel(i18n, field, locale) {
|
|
225
|
+
return i18n.fields[field]?.label?.[locale] ?? i18n.fields[field]?.label?.["en"] ?? field;
|
|
226
|
+
}
|
|
227
|
+
function getCompoundLabel(i18n, prefix, locale) {
|
|
228
|
+
return i18n.fields[prefix]?.label?.[locale] ?? i18n.fields[prefix]?.label?.["en"];
|
|
229
|
+
}
|
|
230
|
+
function getPlaceholder(i18n, field, locale) {
|
|
231
|
+
return i18n.fields[field]?.placeholder?.[locale] ?? i18n.fields[field]?.placeholder?.["en"] ?? "";
|
|
232
|
+
}
|
|
233
|
+
function JapaneseNameField({
|
|
234
|
+
schemas,
|
|
235
|
+
i18n,
|
|
236
|
+
prefix = "name",
|
|
237
|
+
required = false,
|
|
238
|
+
showKana = true,
|
|
239
|
+
label,
|
|
240
|
+
kanaLabel
|
|
241
|
+
}) {
|
|
242
|
+
const locale = getZodLocale();
|
|
243
|
+
const lastnameField = `${prefix}_lastname`;
|
|
244
|
+
const firstnameField = `${prefix}_firstname`;
|
|
245
|
+
const kanaLastnameField = `${prefix}_kana_lastname`;
|
|
246
|
+
const kanaFirstnameField = `${prefix}_kana_firstname`;
|
|
247
|
+
const getRule = (field) => {
|
|
248
|
+
const schema = schemas[field];
|
|
249
|
+
if (!schema) return [];
|
|
250
|
+
return [zodRule(schema, getLabel(i18n, field, locale))];
|
|
251
|
+
};
|
|
252
|
+
const isFieldRequired = (field) => {
|
|
253
|
+
const schema = schemas[field];
|
|
254
|
+
if (!schema) return false;
|
|
255
|
+
return isZodRequired(schema);
|
|
256
|
+
};
|
|
257
|
+
const nameRequired = isFieldRequired(lastnameField) || isFieldRequired(firstnameField) || required;
|
|
258
|
+
const kanaRequired = isFieldRequired(kanaLastnameField) || isFieldRequired(kanaFirstnameField);
|
|
259
|
+
const nameLabel = label ?? getCompoundLabel(i18n, prefix, locale) ?? getLabel(i18n, lastnameField, locale);
|
|
260
|
+
const nameKanaLabel = kanaLabel ?? `${getCompoundLabel(i18n, prefix, locale) ?? getLabel(i18n, kanaLastnameField, locale)}\uFF08\u30AB\u30CA\uFF09`;
|
|
261
|
+
const lastnameShortLabel = locale === "ja" ? "\u59D3" : "Last";
|
|
262
|
+
const firstnameShortLabel = locale === "ja" ? "\u540D" : "First";
|
|
263
|
+
const prefixStyle = {
|
|
264
|
+
color: "rgba(0, 0, 0, 0.88)",
|
|
265
|
+
fontWeight: 500,
|
|
266
|
+
borderRight: "1px solid #d9d9d9",
|
|
267
|
+
paddingRight: 8,
|
|
268
|
+
marginRight: 4
|
|
269
|
+
};
|
|
270
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
271
|
+
/* @__PURE__ */ jsx(Form.Item, { label: nameLabel, required: nameRequired, style: { marginBottom: 0 }, children: /* @__PURE__ */ jsxs(Row, { gutter: 8, children: [
|
|
272
|
+
/* @__PURE__ */ jsx(Col, { span: 12, children: /* @__PURE__ */ jsx(Form.Item, { name: lastnameField, rules: getRule(lastnameField), style: { marginBottom: 16 }, children: /* @__PURE__ */ jsx(
|
|
273
|
+
Input,
|
|
274
|
+
{
|
|
275
|
+
prefix: /* @__PURE__ */ jsx("span", { style: prefixStyle, children: lastnameShortLabel }),
|
|
276
|
+
placeholder: getPlaceholder(i18n, lastnameField, locale)
|
|
277
|
+
}
|
|
278
|
+
) }) }),
|
|
279
|
+
/* @__PURE__ */ jsx(Col, { span: 12, children: /* @__PURE__ */ jsx(Form.Item, { name: firstnameField, rules: getRule(firstnameField), style: { marginBottom: 16 }, children: /* @__PURE__ */ jsx(
|
|
280
|
+
Input,
|
|
281
|
+
{
|
|
282
|
+
prefix: /* @__PURE__ */ jsx("span", { style: prefixStyle, children: firstnameShortLabel }),
|
|
283
|
+
placeholder: getPlaceholder(i18n, firstnameField, locale)
|
|
284
|
+
}
|
|
285
|
+
) }) })
|
|
286
|
+
] }) }),
|
|
287
|
+
showKana && /* @__PURE__ */ jsx(Form.Item, { label: nameKanaLabel, required: kanaRequired, style: { marginBottom: 0 }, children: /* @__PURE__ */ jsxs(Row, { gutter: 8, children: [
|
|
288
|
+
/* @__PURE__ */ jsx(Col, { span: 12, children: /* @__PURE__ */ jsx(
|
|
289
|
+
Form.Item,
|
|
290
|
+
{
|
|
291
|
+
name: kanaLastnameField,
|
|
292
|
+
rules: getRule(kanaLastnameField),
|
|
293
|
+
style: { marginBottom: 16 },
|
|
294
|
+
children: /* @__PURE__ */ jsx(
|
|
295
|
+
Input,
|
|
296
|
+
{
|
|
297
|
+
prefix: /* @__PURE__ */ jsx("span", { style: prefixStyle, children: lastnameShortLabel }),
|
|
298
|
+
placeholder: getPlaceholder(i18n, kanaLastnameField, locale)
|
|
299
|
+
}
|
|
300
|
+
)
|
|
301
|
+
}
|
|
302
|
+
) }),
|
|
303
|
+
/* @__PURE__ */ jsx(Col, { span: 12, children: /* @__PURE__ */ jsx(
|
|
304
|
+
Form.Item,
|
|
305
|
+
{
|
|
306
|
+
name: kanaFirstnameField,
|
|
307
|
+
rules: getRule(kanaFirstnameField),
|
|
308
|
+
style: { marginBottom: 16 },
|
|
309
|
+
children: /* @__PURE__ */ jsx(
|
|
310
|
+
Input,
|
|
311
|
+
{
|
|
312
|
+
prefix: /* @__PURE__ */ jsx("span", { style: prefixStyle, children: firstnameShortLabel }),
|
|
313
|
+
placeholder: getPlaceholder(i18n, kanaFirstnameField, locale)
|
|
314
|
+
}
|
|
315
|
+
)
|
|
316
|
+
}
|
|
317
|
+
) })
|
|
318
|
+
] }) })
|
|
319
|
+
] });
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// src/components/JapaneseAddressField.tsx
|
|
323
|
+
import { useState, useCallback } from "react";
|
|
324
|
+
import { Form as Form2, Input as Input2, Select, Button, message } from "antd";
|
|
325
|
+
import { SearchOutlined, LoadingOutlined } from "@ant-design/icons";
|
|
326
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
327
|
+
function getLabel2(i18n, field, locale) {
|
|
328
|
+
return i18n.fields[field]?.label?.[locale] ?? i18n.fields[field]?.label?.["en"] ?? field;
|
|
329
|
+
}
|
|
330
|
+
function getPlaceholder2(i18n, field, locale) {
|
|
331
|
+
return i18n.fields[field]?.placeholder?.[locale] ?? i18n.fields[field]?.placeholder?.["en"] ?? "";
|
|
332
|
+
}
|
|
333
|
+
async function lookupPostalCode(postalCode) {
|
|
334
|
+
try {
|
|
335
|
+
const response = await fetch(`https://zipcloud.ibsnet.co.jp/api/search?zipcode=${postalCode}`);
|
|
336
|
+
const data = await response.json();
|
|
337
|
+
if (data.results && data.results.length > 0) {
|
|
338
|
+
const result = data.results[0];
|
|
339
|
+
return {
|
|
340
|
+
prefectureCode: result.prefcode,
|
|
341
|
+
prefectureName: result.address1,
|
|
342
|
+
address1: result.address2,
|
|
343
|
+
address2: result.address3
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
return null;
|
|
347
|
+
} catch (error) {
|
|
348
|
+
console.error("Postal code lookup failed:", error);
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
var MESSAGES = {
|
|
353
|
+
ja: {
|
|
354
|
+
searchAddress: "\u4F4F\u6240\u691C\u7D22",
|
|
355
|
+
searching: "\u691C\u7D22\u4E2D...",
|
|
356
|
+
notFound: "\u90F5\u4FBF\u756A\u53F7\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F",
|
|
357
|
+
error: "\u4F4F\u6240\u691C\u7D22\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
|
|
358
|
+
invalidFormat: "\u90F5\u4FBF\u756A\u53F7\u306E\u5F62\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093\uFF08\u4F8B\uFF1A123-4567\uFF09"
|
|
359
|
+
},
|
|
360
|
+
en: {
|
|
361
|
+
searchAddress: "Search Address",
|
|
362
|
+
searching: "Searching...",
|
|
363
|
+
notFound: "Postal code not found",
|
|
364
|
+
error: "Address lookup failed",
|
|
365
|
+
invalidFormat: "Invalid postal code format (e.g., 123-4567)"
|
|
366
|
+
},
|
|
367
|
+
vi: {
|
|
368
|
+
searchAddress: "T\xECm \u0111\u1ECBa ch\u1EC9",
|
|
369
|
+
searching: "\u0110ang t\xECm...",
|
|
370
|
+
notFound: "Kh\xF4ng t\xECm th\u1EA5y m\xE3 b\u01B0u \u0111i\u1EC7n",
|
|
371
|
+
error: "T\xECm \u0111\u1ECBa ch\u1EC9 th\u1EA5t b\u1EA1i",
|
|
372
|
+
invalidFormat: "\u0110\u1ECBnh d\u1EA1ng m\xE3 b\u01B0u \u0111i\u1EC7n kh\xF4ng h\u1EE3p l\u1EC7 (VD: 123-4567)"
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
function getMessage(key, locale) {
|
|
376
|
+
return MESSAGES[locale]?.[key] ?? MESSAGES.ja[key];
|
|
377
|
+
}
|
|
378
|
+
function JapaneseAddressField({
|
|
379
|
+
form,
|
|
380
|
+
schemas,
|
|
381
|
+
i18n,
|
|
382
|
+
prefix = "address",
|
|
383
|
+
usePrefectureId = false,
|
|
384
|
+
prefectureOptions,
|
|
385
|
+
enablePostalLookup = true,
|
|
386
|
+
showSearchButton = true,
|
|
387
|
+
autoSearch = true,
|
|
388
|
+
onPostalLookup
|
|
389
|
+
}) {
|
|
390
|
+
const locale = getZodLocale();
|
|
391
|
+
const [isSearching, setIsSearching] = useState(false);
|
|
392
|
+
const postalCodeField = `${prefix}_postal_code`;
|
|
393
|
+
const prefectureField = usePrefectureId ? `${prefix}_prefecture_id` : `${prefix}_prefecture`;
|
|
394
|
+
const address1Field = `${prefix}_address1`;
|
|
395
|
+
const address2Field = `${prefix}_address2`;
|
|
396
|
+
const address3Field = `${prefix}_address3`;
|
|
397
|
+
const getRule = (field) => {
|
|
398
|
+
const schema = schemas[field];
|
|
399
|
+
if (!schema) return [];
|
|
400
|
+
return [zodRule(schema, getLabel2(i18n, field, locale))];
|
|
401
|
+
};
|
|
402
|
+
const isRequired = (field) => {
|
|
403
|
+
const schema = schemas[field];
|
|
404
|
+
if (!schema) return false;
|
|
405
|
+
return isZodRequired(schema);
|
|
406
|
+
};
|
|
407
|
+
const doLookup = useCallback(
|
|
408
|
+
async (postalCode) => {
|
|
409
|
+
const digits = postalCode.replace(/[^0-9]/g, "");
|
|
410
|
+
if (digits.length !== 7) {
|
|
411
|
+
message.warning(getMessage("invalidFormat", locale));
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
setIsSearching(true);
|
|
415
|
+
try {
|
|
416
|
+
const lookupFn = onPostalLookup ?? lookupPostalCode;
|
|
417
|
+
const result = await lookupFn(postalCode);
|
|
418
|
+
if (result) {
|
|
419
|
+
const prefectureValue = usePrefectureId ? result.prefectureCode : result.prefecture;
|
|
420
|
+
form.setFieldsValue({
|
|
421
|
+
[prefectureField]: prefectureValue,
|
|
422
|
+
[address1Field]: result.address1,
|
|
423
|
+
[address2Field]: result.address2
|
|
424
|
+
});
|
|
425
|
+
} else {
|
|
426
|
+
message.info(getMessage("notFound", locale));
|
|
427
|
+
}
|
|
428
|
+
} catch (error) {
|
|
429
|
+
message.error(getMessage("error", locale));
|
|
430
|
+
console.error("Postal code lookup failed:", error);
|
|
431
|
+
} finally {
|
|
432
|
+
setIsSearching(false);
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
[form, locale, onPostalLookup, prefectureField, address1Field, address2Field, usePrefectureId]
|
|
436
|
+
);
|
|
437
|
+
const handlePostalCodeChange = async (e) => {
|
|
438
|
+
const postalCode = e.target.value.replace(/[^0-9]/g, "");
|
|
439
|
+
if (autoSearch && enablePostalLookup && postalCode.length === 7) {
|
|
440
|
+
await doLookup(postalCode);
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
const handleSearchClick = async () => {
|
|
444
|
+
const postalCode = form.getFieldValue(postalCodeField);
|
|
445
|
+
if (postalCode) {
|
|
446
|
+
await doLookup(postalCode);
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
450
|
+
/* @__PURE__ */ jsx2(
|
|
451
|
+
Form2.Item,
|
|
452
|
+
{
|
|
453
|
+
name: postalCodeField,
|
|
454
|
+
label: getLabel2(i18n, postalCodeField, locale),
|
|
455
|
+
rules: getRule(postalCodeField),
|
|
456
|
+
required: isRequired(postalCodeField),
|
|
457
|
+
children: /* @__PURE__ */ jsx2(
|
|
458
|
+
Input2,
|
|
459
|
+
{
|
|
460
|
+
placeholder: getPlaceholder2(i18n, postalCodeField, locale),
|
|
461
|
+
style: { width: enablePostalLookup && showSearchButton ? "calc(100% - 110px)" : 150 },
|
|
462
|
+
onChange: handlePostalCodeChange,
|
|
463
|
+
addonAfter: enablePostalLookup && showSearchButton && /* @__PURE__ */ jsx2(
|
|
464
|
+
Button,
|
|
465
|
+
{
|
|
466
|
+
type: "text",
|
|
467
|
+
size: "small",
|
|
468
|
+
icon: isSearching ? /* @__PURE__ */ jsx2(LoadingOutlined, {}) : /* @__PURE__ */ jsx2(SearchOutlined, {}),
|
|
469
|
+
onClick: handleSearchClick,
|
|
470
|
+
disabled: isSearching,
|
|
471
|
+
children: getMessage("searchAddress", locale)
|
|
472
|
+
}
|
|
473
|
+
)
|
|
474
|
+
}
|
|
475
|
+
)
|
|
476
|
+
}
|
|
477
|
+
),
|
|
478
|
+
/* @__PURE__ */ jsx2(
|
|
479
|
+
Form2.Item,
|
|
480
|
+
{
|
|
481
|
+
name: prefectureField,
|
|
482
|
+
label: getLabel2(i18n, prefectureField, locale),
|
|
483
|
+
rules: getRule(prefectureField),
|
|
484
|
+
required: isRequired(prefectureField),
|
|
485
|
+
children: prefectureOptions ? /* @__PURE__ */ jsx2(
|
|
486
|
+
Select,
|
|
487
|
+
{
|
|
488
|
+
placeholder: getPlaceholder2(i18n, prefectureField, locale),
|
|
489
|
+
options: prefectureOptions,
|
|
490
|
+
style: { width: 200 },
|
|
491
|
+
showSearch: true,
|
|
492
|
+
optionFilterProp: "label"
|
|
493
|
+
}
|
|
494
|
+
) : /* @__PURE__ */ jsx2(
|
|
495
|
+
Input2,
|
|
496
|
+
{
|
|
497
|
+
placeholder: getPlaceholder2(i18n, prefectureField, locale),
|
|
498
|
+
style: { width: 200 }
|
|
499
|
+
}
|
|
500
|
+
)
|
|
501
|
+
}
|
|
502
|
+
),
|
|
503
|
+
/* @__PURE__ */ jsx2(
|
|
504
|
+
Form2.Item,
|
|
505
|
+
{
|
|
506
|
+
name: address1Field,
|
|
507
|
+
label: getLabel2(i18n, address1Field, locale),
|
|
508
|
+
rules: getRule(address1Field),
|
|
509
|
+
required: isRequired(address1Field),
|
|
510
|
+
children: /* @__PURE__ */ jsx2(Input2, { placeholder: getPlaceholder2(i18n, address1Field, locale) })
|
|
511
|
+
}
|
|
512
|
+
),
|
|
513
|
+
/* @__PURE__ */ jsx2(
|
|
514
|
+
Form2.Item,
|
|
515
|
+
{
|
|
516
|
+
name: address2Field,
|
|
517
|
+
label: getLabel2(i18n, address2Field, locale),
|
|
518
|
+
rules: getRule(address2Field),
|
|
519
|
+
required: isRequired(address2Field),
|
|
520
|
+
children: /* @__PURE__ */ jsx2(Input2, { placeholder: getPlaceholder2(i18n, address2Field, locale) })
|
|
521
|
+
}
|
|
522
|
+
),
|
|
523
|
+
/* @__PURE__ */ jsx2(
|
|
524
|
+
Form2.Item,
|
|
525
|
+
{
|
|
526
|
+
name: address3Field,
|
|
527
|
+
label: getLabel2(i18n, address3Field, locale),
|
|
528
|
+
rules: getRule(address3Field),
|
|
529
|
+
required: isRequired(address3Field),
|
|
530
|
+
children: /* @__PURE__ */ jsx2(Input2, { placeholder: getPlaceholder2(i18n, address3Field, locale) })
|
|
531
|
+
}
|
|
532
|
+
)
|
|
533
|
+
] });
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// src/components/JapaneseBankField.tsx
|
|
537
|
+
import { Form as Form3, Input as Input3, Select as Select2, Row as Row2, Col as Col2 } from "antd";
|
|
538
|
+
import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
539
|
+
function getLabel3(i18n, field, locale) {
|
|
540
|
+
return i18n.fields[field]?.label?.[locale] ?? i18n.fields[field]?.label?.["en"] ?? field;
|
|
541
|
+
}
|
|
542
|
+
function getPlaceholder3(i18n, field, locale) {
|
|
543
|
+
return i18n.fields[field]?.placeholder?.[locale] ?? i18n.fields[field]?.placeholder?.["en"] ?? "";
|
|
544
|
+
}
|
|
545
|
+
function JapaneseBankField({
|
|
546
|
+
schemas,
|
|
547
|
+
i18n,
|
|
548
|
+
prefix = "bank",
|
|
549
|
+
accountTypeOptions
|
|
550
|
+
}) {
|
|
551
|
+
const locale = getZodLocale();
|
|
552
|
+
const bankCodeField = `${prefix}_bank_code`;
|
|
553
|
+
const bankNameField = `${prefix}_bank_name`;
|
|
554
|
+
const branchCodeField = `${prefix}_branch_code`;
|
|
555
|
+
const branchNameField = `${prefix}_branch_name`;
|
|
556
|
+
const accountTypeField = `${prefix}_account_type`;
|
|
557
|
+
const accountNumberField = `${prefix}_account_number`;
|
|
558
|
+
const accountHolderField = `${prefix}_account_holder`;
|
|
559
|
+
const getRule = (field) => {
|
|
560
|
+
const schema = schemas[field];
|
|
561
|
+
if (!schema) return [];
|
|
562
|
+
return [zodRule(schema, getLabel3(i18n, field, locale))];
|
|
563
|
+
};
|
|
564
|
+
const isRequired = (field) => {
|
|
565
|
+
const schema = schemas[field];
|
|
566
|
+
if (!schema) return false;
|
|
567
|
+
return isZodRequired(schema);
|
|
568
|
+
};
|
|
569
|
+
const bankRequired = isRequired(bankCodeField) || isRequired(bankNameField);
|
|
570
|
+
const branchRequired = isRequired(branchCodeField) || isRequired(branchNameField);
|
|
571
|
+
const codeShortLabel = locale === "ja" ? "\u30B3\u30FC\u30C9" : "Code";
|
|
572
|
+
const nameShortLabel = locale === "ja" ? "\u540D\u79F0" : "Name";
|
|
573
|
+
const bankLabel = locale === "ja" ? "\u9280\u884C" : "Bank";
|
|
574
|
+
const branchLabel = locale === "ja" ? "\u652F\u5E97" : "Branch";
|
|
575
|
+
const prefixStyle = {
|
|
576
|
+
color: "rgba(0, 0, 0, 0.88)",
|
|
577
|
+
fontWeight: 500,
|
|
578
|
+
borderRight: "1px solid #d9d9d9",
|
|
579
|
+
paddingRight: 8,
|
|
580
|
+
marginRight: 4
|
|
581
|
+
};
|
|
582
|
+
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
583
|
+
/* @__PURE__ */ jsx3(Form3.Item, { label: bankLabel, required: bankRequired, style: { marginBottom: 0 }, children: /* @__PURE__ */ jsxs3(Row2, { gutter: 8, children: [
|
|
584
|
+
/* @__PURE__ */ jsx3(Col2, { span: 8, children: /* @__PURE__ */ jsx3(Form3.Item, { name: bankCodeField, rules: getRule(bankCodeField), style: { marginBottom: 16 }, children: /* @__PURE__ */ jsx3(
|
|
585
|
+
Input3,
|
|
586
|
+
{
|
|
587
|
+
prefix: /* @__PURE__ */ jsx3("span", { style: prefixStyle, children: codeShortLabel }),
|
|
588
|
+
placeholder: getPlaceholder3(i18n, bankCodeField, locale),
|
|
589
|
+
maxLength: 4
|
|
590
|
+
}
|
|
591
|
+
) }) }),
|
|
592
|
+
/* @__PURE__ */ jsx3(Col2, { span: 16, children: /* @__PURE__ */ jsx3(Form3.Item, { name: bankNameField, rules: getRule(bankNameField), style: { marginBottom: 16 }, children: /* @__PURE__ */ jsx3(
|
|
593
|
+
Input3,
|
|
594
|
+
{
|
|
595
|
+
prefix: /* @__PURE__ */ jsx3("span", { style: prefixStyle, children: nameShortLabel }),
|
|
596
|
+
placeholder: getPlaceholder3(i18n, bankNameField, locale)
|
|
597
|
+
}
|
|
598
|
+
) }) })
|
|
599
|
+
] }) }),
|
|
600
|
+
/* @__PURE__ */ jsx3(Form3.Item, { label: branchLabel, required: branchRequired, style: { marginBottom: 0 }, children: /* @__PURE__ */ jsxs3(Row2, { gutter: 8, children: [
|
|
601
|
+
/* @__PURE__ */ jsx3(Col2, { span: 8, children: /* @__PURE__ */ jsx3(
|
|
602
|
+
Form3.Item,
|
|
603
|
+
{
|
|
604
|
+
name: branchCodeField,
|
|
605
|
+
rules: getRule(branchCodeField),
|
|
606
|
+
style: { marginBottom: 16 },
|
|
607
|
+
children: /* @__PURE__ */ jsx3(
|
|
608
|
+
Input3,
|
|
609
|
+
{
|
|
610
|
+
prefix: /* @__PURE__ */ jsx3("span", { style: prefixStyle, children: codeShortLabel }),
|
|
611
|
+
placeholder: getPlaceholder3(i18n, branchCodeField, locale),
|
|
612
|
+
maxLength: 3
|
|
613
|
+
}
|
|
614
|
+
)
|
|
615
|
+
}
|
|
616
|
+
) }),
|
|
617
|
+
/* @__PURE__ */ jsx3(Col2, { span: 16, children: /* @__PURE__ */ jsx3(
|
|
618
|
+
Form3.Item,
|
|
619
|
+
{
|
|
620
|
+
name: branchNameField,
|
|
621
|
+
rules: getRule(branchNameField),
|
|
622
|
+
style: { marginBottom: 16 },
|
|
623
|
+
children: /* @__PURE__ */ jsx3(
|
|
624
|
+
Input3,
|
|
625
|
+
{
|
|
626
|
+
prefix: /* @__PURE__ */ jsx3("span", { style: prefixStyle, children: nameShortLabel }),
|
|
627
|
+
placeholder: getPlaceholder3(i18n, branchNameField, locale)
|
|
628
|
+
}
|
|
629
|
+
)
|
|
630
|
+
}
|
|
631
|
+
) })
|
|
632
|
+
] }) }),
|
|
633
|
+
/* @__PURE__ */ jsx3(
|
|
634
|
+
Form3.Item,
|
|
635
|
+
{
|
|
636
|
+
name: accountTypeField,
|
|
637
|
+
label: getLabel3(i18n, accountTypeField, locale),
|
|
638
|
+
rules: getRule(accountTypeField),
|
|
639
|
+
required: isRequired(accountTypeField),
|
|
640
|
+
children: accountTypeOptions ? /* @__PURE__ */ jsx3(
|
|
641
|
+
Select2,
|
|
642
|
+
{
|
|
643
|
+
placeholder: getPlaceholder3(i18n, accountTypeField, locale),
|
|
644
|
+
options: accountTypeOptions,
|
|
645
|
+
style: { width: 150 }
|
|
646
|
+
}
|
|
647
|
+
) : /* @__PURE__ */ jsx3(
|
|
648
|
+
Input3,
|
|
649
|
+
{
|
|
650
|
+
placeholder: getPlaceholder3(i18n, accountTypeField, locale),
|
|
651
|
+
style: { width: 150 }
|
|
652
|
+
}
|
|
653
|
+
)
|
|
654
|
+
}
|
|
655
|
+
),
|
|
656
|
+
/* @__PURE__ */ jsx3(
|
|
657
|
+
Form3.Item,
|
|
658
|
+
{
|
|
659
|
+
name: accountNumberField,
|
|
660
|
+
label: getLabel3(i18n, accountNumberField, locale),
|
|
661
|
+
rules: getRule(accountNumberField),
|
|
662
|
+
required: isRequired(accountNumberField),
|
|
663
|
+
children: /* @__PURE__ */ jsx3(
|
|
664
|
+
Input3,
|
|
665
|
+
{
|
|
666
|
+
placeholder: getPlaceholder3(i18n, accountNumberField, locale),
|
|
667
|
+
maxLength: 7,
|
|
668
|
+
style: { width: 150 }
|
|
669
|
+
}
|
|
670
|
+
)
|
|
671
|
+
}
|
|
672
|
+
),
|
|
673
|
+
/* @__PURE__ */ jsx3(
|
|
674
|
+
Form3.Item,
|
|
675
|
+
{
|
|
676
|
+
name: accountHolderField,
|
|
677
|
+
label: getLabel3(i18n, accountHolderField, locale),
|
|
678
|
+
rules: getRule(accountHolderField),
|
|
679
|
+
required: isRequired(accountHolderField),
|
|
680
|
+
children: /* @__PURE__ */ jsx3(Input3, { placeholder: getPlaceholder3(i18n, accountHolderField, locale) })
|
|
681
|
+
}
|
|
682
|
+
)
|
|
683
|
+
] });
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// src/hooks/use-form-mutation.ts
|
|
687
|
+
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
688
|
+
import { App } from "antd";
|
|
689
|
+
function getFormErrors(error) {
|
|
690
|
+
const data = error?.response?.data;
|
|
691
|
+
const errors = data?.errors;
|
|
692
|
+
if (!errors || typeof errors !== "object") return [];
|
|
693
|
+
return Object.entries(errors).map(([name, messages]) => ({
|
|
694
|
+
name,
|
|
695
|
+
errors: Array.isArray(messages) ? messages : [String(messages)]
|
|
696
|
+
}));
|
|
697
|
+
}
|
|
698
|
+
function getValidationMessage(error) {
|
|
699
|
+
const data = error?.response?.data;
|
|
700
|
+
return data?.message || null;
|
|
701
|
+
}
|
|
702
|
+
function useFormMutation({
|
|
703
|
+
form,
|
|
704
|
+
mutationFn,
|
|
705
|
+
invalidateKeys = [],
|
|
706
|
+
successMessage,
|
|
707
|
+
onSuccess,
|
|
708
|
+
onError
|
|
709
|
+
}) {
|
|
710
|
+
const queryClient = useQueryClient();
|
|
711
|
+
const { message: message2 } = App.useApp();
|
|
712
|
+
return useMutation({
|
|
713
|
+
mutationFn,
|
|
714
|
+
onSuccess: (data) => {
|
|
715
|
+
invalidateKeys.forEach((key) => {
|
|
716
|
+
queryClient.invalidateQueries({ queryKey: [...key] });
|
|
717
|
+
});
|
|
718
|
+
if (successMessage) {
|
|
719
|
+
message2.success(successMessage);
|
|
720
|
+
}
|
|
721
|
+
onSuccess?.(data);
|
|
722
|
+
},
|
|
723
|
+
onError: (error) => {
|
|
724
|
+
const formErrors = getFormErrors(error);
|
|
725
|
+
if (formErrors.length > 0) {
|
|
726
|
+
form.setFields(formErrors);
|
|
727
|
+
}
|
|
728
|
+
const validationMessage = getValidationMessage(error);
|
|
729
|
+
if (validationMessage) {
|
|
730
|
+
message2.error(validationMessage);
|
|
731
|
+
}
|
|
732
|
+
onError?.(error);
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// src/lib/rules/kana.ts
|
|
738
|
+
import { z } from "zod";
|
|
739
|
+
var CHAR_RANGES = {
|
|
740
|
+
// Full-width Katakana: ァ-ヶ (U+30A1-U+30F6) + ー (U+30FC)
|
|
741
|
+
fullWidthKatakana: "\u30A1-\u30F6\u30FC",
|
|
742
|
+
// Half-width Katakana: ヲ-゚ (U+FF66-U+FF9F)
|
|
743
|
+
halfWidthKatakana: "\uFF66-\uFF9F",
|
|
744
|
+
// Hiragana: ぁ-ゖ (U+3041-U+3096)
|
|
745
|
+
hiragana: "\u3041-\u3096",
|
|
746
|
+
// Full-width numbers: 0-9
|
|
747
|
+
fullWidthNumbers: "\uFF10-\uFF19",
|
|
748
|
+
// Half-width numbers: 0-9
|
|
749
|
+
halfWidthNumbers: "0-9",
|
|
750
|
+
// Full-width space: (U+3000)
|
|
751
|
+
fullWidthSpace: "\u3000",
|
|
752
|
+
// Half-width space
|
|
753
|
+
halfWidthSpace: " ",
|
|
754
|
+
// Common special chars for names
|
|
755
|
+
defaultSpecialChars: ["\u30FC", "\u30FB"]
|
|
756
|
+
};
|
|
757
|
+
var DEFAULT_OPTIONS = {
|
|
758
|
+
fullWidthKatakana: true,
|
|
759
|
+
halfWidthKatakana: false,
|
|
760
|
+
hiragana: false,
|
|
761
|
+
allowNumbers: false,
|
|
762
|
+
fullWidthNumbers: false,
|
|
763
|
+
halfWidthNumbers: false,
|
|
764
|
+
allowSpaces: true,
|
|
765
|
+
allowSpecialChars: ["\u30FC", "\u30FB"],
|
|
766
|
+
message: ""
|
|
767
|
+
};
|
|
768
|
+
function buildKanaPattern(options = {}) {
|
|
769
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
770
|
+
const parts = [];
|
|
771
|
+
if (opts.fullWidthKatakana) {
|
|
772
|
+
parts.push(CHAR_RANGES.fullWidthKatakana);
|
|
773
|
+
}
|
|
774
|
+
if (opts.halfWidthKatakana) {
|
|
775
|
+
parts.push(CHAR_RANGES.halfWidthKatakana);
|
|
776
|
+
}
|
|
777
|
+
if (opts.hiragana) {
|
|
778
|
+
parts.push(CHAR_RANGES.hiragana);
|
|
779
|
+
}
|
|
780
|
+
if (opts.allowNumbers || opts.fullWidthNumbers) {
|
|
781
|
+
parts.push(CHAR_RANGES.fullWidthNumbers);
|
|
782
|
+
}
|
|
783
|
+
if (opts.allowNumbers || opts.halfWidthNumbers) {
|
|
784
|
+
parts.push(CHAR_RANGES.halfWidthNumbers);
|
|
785
|
+
}
|
|
786
|
+
if (opts.allowSpaces) {
|
|
787
|
+
parts.push(CHAR_RANGES.fullWidthSpace);
|
|
788
|
+
parts.push(CHAR_RANGES.halfWidthSpace);
|
|
789
|
+
}
|
|
790
|
+
if (opts.allowSpecialChars && opts.allowSpecialChars.length > 0) {
|
|
791
|
+
const escaped = opts.allowSpecialChars.map((c) => c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
|
|
792
|
+
parts.push(escaped);
|
|
793
|
+
}
|
|
794
|
+
return `^[${parts.join("")}]*$`;
|
|
795
|
+
}
|
|
796
|
+
function getDefaultMessage(options = {}, locale = "ja") {
|
|
797
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
798
|
+
const messages = {
|
|
799
|
+
ja: {
|
|
800
|
+
fullWidthKatakana: "\u5168\u89D2\u30AB\u30BF\u30AB\u30CA",
|
|
801
|
+
halfWidthKatakana: "\u534A\u89D2\u30AB\u30BF\u30AB\u30CA",
|
|
802
|
+
hiragana: "\u3072\u3089\u304C\u306A",
|
|
803
|
+
mixed: "\u30AB\u30CA\u6587\u5B57"
|
|
804
|
+
},
|
|
805
|
+
en: {
|
|
806
|
+
fullWidthKatakana: "full-width katakana",
|
|
807
|
+
halfWidthKatakana: "half-width katakana",
|
|
808
|
+
hiragana: "hiragana",
|
|
809
|
+
mixed: "kana characters"
|
|
810
|
+
}
|
|
811
|
+
};
|
|
812
|
+
const msg = messages[locale] ?? messages["ja"];
|
|
813
|
+
let type = msg.mixed;
|
|
814
|
+
if (opts.fullWidthKatakana && !opts.halfWidthKatakana && !opts.hiragana) {
|
|
815
|
+
type = msg.fullWidthKatakana;
|
|
816
|
+
} else if (opts.halfWidthKatakana && !opts.fullWidthKatakana && !opts.hiragana) {
|
|
817
|
+
type = msg.halfWidthKatakana;
|
|
818
|
+
} else if (opts.hiragana && !opts.fullWidthKatakana && !opts.halfWidthKatakana) {
|
|
819
|
+
type = msg.hiragana;
|
|
820
|
+
}
|
|
821
|
+
if (locale === "ja") {
|
|
822
|
+
return `${type}\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044`;
|
|
823
|
+
}
|
|
824
|
+
return `Please enter in ${type}`;
|
|
825
|
+
}
|
|
826
|
+
function createKanaRegex(options = {}) {
|
|
827
|
+
return new RegExp(buildKanaPattern(options));
|
|
828
|
+
}
|
|
829
|
+
function validateKana(value, options = {}) {
|
|
830
|
+
if (!value) return true;
|
|
831
|
+
const regex = createKanaRegex(options);
|
|
832
|
+
return regex.test(value);
|
|
833
|
+
}
|
|
834
|
+
function getKanaPattern(options = {}) {
|
|
835
|
+
return buildKanaPattern(options);
|
|
836
|
+
}
|
|
837
|
+
function getKanaErrorMessage(options = {}, locale = "ja") {
|
|
838
|
+
return options.message ?? getDefaultMessage(options, locale);
|
|
839
|
+
}
|
|
840
|
+
var KATAKANA_FULL_WIDTH = {
|
|
841
|
+
fullWidthKatakana: true,
|
|
842
|
+
halfWidthKatakana: false,
|
|
843
|
+
hiragana: false,
|
|
844
|
+
allowSpaces: true,
|
|
845
|
+
allowSpecialChars: ["\u30FC", "\u30FB"]
|
|
846
|
+
};
|
|
847
|
+
var KATAKANA_HALF_WIDTH = {
|
|
848
|
+
fullWidthKatakana: false,
|
|
849
|
+
halfWidthKatakana: true,
|
|
850
|
+
hiragana: false,
|
|
851
|
+
allowSpaces: true,
|
|
852
|
+
allowSpecialChars: ["\uFF70"]
|
|
853
|
+
// Half-width prolonged sound mark
|
|
854
|
+
};
|
|
855
|
+
var HIRAGANA = {
|
|
856
|
+
fullWidthKatakana: false,
|
|
857
|
+
halfWidthKatakana: false,
|
|
858
|
+
hiragana: true,
|
|
859
|
+
allowSpaces: true,
|
|
860
|
+
allowSpecialChars: ["\u30FC"]
|
|
861
|
+
};
|
|
862
|
+
var KANA_ANY = {
|
|
863
|
+
fullWidthKatakana: true,
|
|
864
|
+
halfWidthKatakana: true,
|
|
865
|
+
hiragana: true,
|
|
866
|
+
allowSpaces: true,
|
|
867
|
+
allowSpecialChars: ["\u30FC", "\u30FB", "\uFF70"]
|
|
868
|
+
};
|
|
869
|
+
var KATAKANA_WITH_NUMBERS = {
|
|
870
|
+
fullWidthKatakana: true,
|
|
871
|
+
halfWidthKatakana: false,
|
|
872
|
+
hiragana: false,
|
|
873
|
+
allowNumbers: true,
|
|
874
|
+
allowSpaces: true,
|
|
875
|
+
allowSpecialChars: ["\u30FC", "\u30FB"]
|
|
876
|
+
};
|
|
877
|
+
var KATAKANA_PATTERN = /^[ァ-ヶー・ ]*$/;
|
|
878
|
+
var KATAKANA_HALF_PATTERN = /^[ヲ-゚ー ]*$/;
|
|
879
|
+
var HIRAGANA_PATTERN = /^[ぁ-ゖー ]*$/;
|
|
880
|
+
var KANA_ANY_PATTERN = /^[ァ-ヶぁ-ゖヲ-゚ー・ー ]*$/;
|
|
881
|
+
function kanaString(options = {}) {
|
|
882
|
+
const opts = { ...KATAKANA_FULL_WIDTH, ...options };
|
|
883
|
+
const regex = createKanaRegex(opts);
|
|
884
|
+
const message2 = getKanaErrorMessage(opts);
|
|
885
|
+
return z.string().regex(regex, { message: message2 });
|
|
886
|
+
}
|
|
887
|
+
function withKana(options = {}) {
|
|
888
|
+
return kanaString(options);
|
|
889
|
+
}
|
|
890
|
+
var kanaRules = {
|
|
891
|
+
createRegex: createKanaRegex,
|
|
892
|
+
validate: validateKana,
|
|
893
|
+
getPattern: getKanaPattern,
|
|
894
|
+
getMessage: getKanaErrorMessage,
|
|
895
|
+
// Zod helpers
|
|
896
|
+
string: kanaString,
|
|
897
|
+
// Presets
|
|
898
|
+
presets: {
|
|
899
|
+
fullWidthKatakana: KATAKANA_FULL_WIDTH,
|
|
900
|
+
halfWidthKatakana: KATAKANA_HALF_WIDTH,
|
|
901
|
+
hiragana: HIRAGANA,
|
|
902
|
+
any: KANA_ANY,
|
|
903
|
+
withNumbers: KATAKANA_WITH_NUMBERS
|
|
904
|
+
},
|
|
905
|
+
// Pattern constants for direct use
|
|
906
|
+
patterns: {
|
|
907
|
+
katakana: KATAKANA_PATTERN,
|
|
908
|
+
katakanaHalf: KATAKANA_HALF_PATTERN,
|
|
909
|
+
hiragana: HIRAGANA_PATTERN,
|
|
910
|
+
any: KANA_ANY_PATTERN
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
export {
|
|
914
|
+
HIRAGANA,
|
|
915
|
+
HIRAGANA_PATTERN,
|
|
916
|
+
JapaneseAddressField,
|
|
917
|
+
JapaneseBankField,
|
|
918
|
+
JapaneseNameField,
|
|
919
|
+
KANA_ANY,
|
|
920
|
+
KANA_ANY_PATTERN,
|
|
921
|
+
KATAKANA_FULL_WIDTH,
|
|
922
|
+
KATAKANA_HALF_PATTERN,
|
|
923
|
+
KATAKANA_HALF_WIDTH,
|
|
924
|
+
KATAKANA_PATTERN,
|
|
925
|
+
KATAKANA_WITH_NUMBERS,
|
|
926
|
+
addZodMessages,
|
|
927
|
+
createKanaRegex,
|
|
928
|
+
getKanaErrorMessage,
|
|
929
|
+
getKanaPattern,
|
|
930
|
+
getZodFallbackLocale,
|
|
931
|
+
getZodLocale,
|
|
932
|
+
getZodMessage,
|
|
933
|
+
getZodMessages,
|
|
934
|
+
isZodRequired,
|
|
935
|
+
getKanaPattern as kanaPattern,
|
|
936
|
+
createKanaRegex as kanaRegex,
|
|
937
|
+
kanaRules,
|
|
938
|
+
kanaString,
|
|
939
|
+
requiredRule,
|
|
940
|
+
setZodFallbackLocale,
|
|
941
|
+
setZodLocale,
|
|
942
|
+
useFormMutation,
|
|
943
|
+
validateKana,
|
|
944
|
+
withKana,
|
|
945
|
+
zodRule
|
|
946
|
+
};
|
|
947
|
+
//# sourceMappingURL=index.js.map
|