@famgia/omnify-ai-guides 2.0.15
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 +105 -0
- package/dist/chunk-RCTEXK7C.js +549 -0
- package/dist/chunk-RCTEXK7C.js.map +1 -0
- package/dist/config/rules.yaml +524 -0
- package/dist/index.cjs +587 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +55 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/agents/architect.md.stub +150 -0
- package/dist/knowledge/agents/developer.md.stub +190 -0
- package/dist/knowledge/agents/reviewer.md.stub +134 -0
- package/dist/knowledge/agents/tester.md.stub +196 -0
- package/dist/knowledge/checklists/backend.md.stub +112 -0
- package/dist/knowledge/checklists/react.md.stub +108 -0
- package/dist/knowledge/claude-rules/laravel-controllers.md.stub +57 -0
- package/dist/knowledge/claude-rules/laravel-migrations.md.stub +47 -0
- package/dist/knowledge/claude-rules/laravel-tests.md.stub +52 -0
- package/dist/knowledge/claude-rules/naming.md.stub +369 -0
- package/dist/knowledge/claude-rules/performance.md.stub +256 -0
- package/dist/knowledge/claude-rules/php-standards.md.stub +305 -0
- package/dist/knowledge/claude-rules/react-components.md.stub +67 -0
- package/dist/knowledge/claude-rules/schema-yaml.md.stub +83 -0
- package/dist/knowledge/claude-rules/security.md.stub +164 -0
- package/dist/knowledge/cursor-rules/antd-deprecations.mdc.stub +62 -0
- package/dist/knowledge/cursor-rules/basemodel-readonly.mdc.stub +66 -0
- package/dist/knowledge/cursor-rules/baserequest-readonly.mdc.stub +74 -0
- package/dist/knowledge/cursor-rules/baseresource-readonly.mdc.stub +78 -0
- package/dist/knowledge/cursor-rules/laravel-controller.mdc.stub +421 -0
- package/dist/knowledge/cursor-rules/laravel-request.mdc.stub +112 -0
- package/dist/knowledge/cursor-rules/laravel-resource.mdc.stub +73 -0
- package/dist/knowledge/cursor-rules/laravel-review.mdc.stub +69 -0
- package/dist/knowledge/cursor-rules/laravel-testing.mdc.stub +138 -0
- package/dist/knowledge/cursor-rules/laravel.mdc.stub +138 -0
- package/dist/knowledge/cursor-rules/migrations-workflow.mdc.stub +224 -0
- package/dist/knowledge/cursor-rules/model-editable.mdc.stub +120 -0
- package/dist/knowledge/cursor-rules/omnify-migrations.mdc.stub +109 -0
- package/dist/knowledge/cursor-rules/omnify-schema.mdc.stub +358 -0
- package/dist/knowledge/cursor-rules/omnify.mdc.stub +58 -0
- package/dist/knowledge/cursor-rules/react-design.mdc.stub +693 -0
- package/dist/knowledge/cursor-rules/react-form.mdc.stub +292 -0
- package/dist/knowledge/cursor-rules/react-services.mdc.stub +304 -0
- package/dist/knowledge/cursor-rules/react.mdc.stub +336 -0
- package/dist/knowledge/cursor-rules/request-editable.mdc.stub +111 -0
- package/dist/knowledge/cursor-rules/resource-editable.mdc.stub +125 -0
- package/dist/knowledge/cursor-rules/schema-create.mdc.stub +440 -0
- package/dist/knowledge/cursor-rules/validation-rules.mdc.stub +181 -0
- package/dist/knowledge/laravel/README.md.stub +59 -0
- package/dist/knowledge/laravel/architecture.md.stub +424 -0
- package/dist/knowledge/laravel/authentication.md.stub +588 -0
- package/dist/knowledge/laravel/controller.md.stub +484 -0
- package/dist/knowledge/laravel/datetime.md.stub +334 -0
- package/dist/knowledge/laravel/migrations-team.md.stub +376 -0
- package/dist/knowledge/laravel/openapi.md.stub +449 -0
- package/dist/knowledge/laravel/request.md.stub +450 -0
- package/dist/knowledge/laravel/resource.md.stub +516 -0
- package/dist/knowledge/laravel/service.md.stub +503 -0
- package/dist/knowledge/laravel/testing.md.stub +1504 -0
- package/dist/knowledge/omnify/antdesign-guide.md.stub +401 -0
- package/dist/knowledge/omnify/config-guide.md.stub +405 -0
- package/dist/knowledge/omnify/japan-guide.md.stub +186 -0
- package/dist/knowledge/omnify/laravel-guide.md.stub +61 -0
- package/dist/knowledge/omnify/partial-schema-guide.md.stub +353 -0
- package/dist/knowledge/omnify/react-form-guide.md.stub +225 -0
- package/dist/knowledge/omnify/schema-guide.md.stub +144 -0
- package/dist/knowledge/omnify/typescript-guide.md.stub +337 -0
- package/dist/knowledge/react/README.md.stub +221 -0
- package/dist/knowledge/react/antd-guide.md +528 -0
- package/dist/knowledge/react/antd-guide.md.stub +528 -0
- package/dist/knowledge/react/checklist.md.stub +108 -0
- package/dist/knowledge/react/datetime-guide.md.stub +137 -0
- package/dist/knowledge/react/design-philosophy.md.stub +363 -0
- package/dist/knowledge/react/i18n-guide.md.stub +211 -0
- package/dist/knowledge/react/laravel-integration.md.stub +181 -0
- package/dist/knowledge/react/service-pattern.md.stub +180 -0
- package/dist/knowledge/react/tanstack-query.md.stub +339 -0
- package/dist/knowledge/react/types-guide.md +669 -0
- package/dist/knowledge/react/types-guide.md.stub +669 -0
- package/dist/knowledge/workflows/bug-fix.md.stub +201 -0
- package/dist/knowledge/workflows/code-review.md.stub +164 -0
- package/dist/knowledge/workflows/new-feature.md.stub +327 -0
- package/dist/plugin-M95GyBll.d.cts +191 -0
- package/dist/plugin-M95GyBll.d.ts +191 -0
- package/dist/plugin.cjs +573 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +2 -0
- package/dist/plugin.d.ts +2 -0
- package/dist/plugin.js +15 -0
- package/dist/plugin.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
# Omnify + Ant Design Integration Guide
|
|
2
|
+
|
|
3
|
+
This guide shows how to use Omnify-generated validation rules with Ant Design Forms.
|
|
4
|
+
|
|
5
|
+
## Generated Files
|
|
6
|
+
|
|
7
|
+
Omnify generates validation rules in `rules/` directory:
|
|
8
|
+
- `rules/{Model}.rules.ts` - Validation rules for each model
|
|
9
|
+
|
|
10
|
+
## File Structure
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
// rules/User.rules.ts
|
|
14
|
+
|
|
15
|
+
// Display name for model (multi-locale)
|
|
16
|
+
export const UserDisplayName: LocaleMap = {
|
|
17
|
+
ja: 'ユーザー',
|
|
18
|
+
en: 'User',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Display names for properties (multi-locale)
|
|
22
|
+
export const UserPropertyDisplayNames: Record<string, LocaleMap> = {
|
|
23
|
+
name: { ja: '名前', en: 'Name' },
|
|
24
|
+
email: { ja: 'メールアドレス', en: 'Email' },
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Validation rules with multi-locale messages
|
|
28
|
+
export const UserRules: Record<string, ValidationRule[]> = {
|
|
29
|
+
name: [
|
|
30
|
+
{ required: true, message: { ja: '名前は必須です', en: 'Name is required' } },
|
|
31
|
+
{ max: 100, message: { ja: '名前は100文字以内で入力してください', en: 'Name must be at most 100 characters' } },
|
|
32
|
+
],
|
|
33
|
+
email: [
|
|
34
|
+
{ required: true, message: { ja: 'メールアドレスは必須です', en: 'Email is required' } },
|
|
35
|
+
{ type: 'email', message: { ja: 'メールアドレスの形式が正しくありません', en: 'Email is not a valid email address' } },
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Helper functions
|
|
40
|
+
export function userSchemas(locale: string): Record<string, Rule[]>;
|
|
41
|
+
export function getUserLabel(locale: string): string;
|
|
42
|
+
export function getUserFieldLabel(property: string, locale: string): string;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Basic Usage
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { Form, Input, Button } from 'antd';
|
|
49
|
+
import {
|
|
50
|
+
userSchemas,
|
|
51
|
+
getUserLabel,
|
|
52
|
+
getUserFieldLabel
|
|
53
|
+
} from '@omnify/schemas/User';
|
|
54
|
+
|
|
55
|
+
interface UserFormProps {
|
|
56
|
+
locale?: string;
|
|
57
|
+
onSubmit: (values: User) => void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function UserForm({ locale = 'ja', onSubmit }: UserFormProps) {
|
|
61
|
+
const [form] = Form.useForm();
|
|
62
|
+
const rules = userSchemas(locale);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Form
|
|
66
|
+
form={form}
|
|
67
|
+
layout="vertical"
|
|
68
|
+
onFinish={onSubmit}
|
|
69
|
+
>
|
|
70
|
+
<Form.Item
|
|
71
|
+
name="name"
|
|
72
|
+
label={getUserFieldLabel('name', locale)}
|
|
73
|
+
rules={rules.name}
|
|
74
|
+
>
|
|
75
|
+
<Input placeholder={getUserFieldLabel('name', locale)} />
|
|
76
|
+
</Form.Item>
|
|
77
|
+
|
|
78
|
+
<Form.Item
|
|
79
|
+
name="email"
|
|
80
|
+
label={getUserFieldLabel('email', locale)}
|
|
81
|
+
rules={rules.email}
|
|
82
|
+
>
|
|
83
|
+
<Input type="email" />
|
|
84
|
+
</Form.Item>
|
|
85
|
+
|
|
86
|
+
<Form.Item>
|
|
87
|
+
<Button type="primary" htmlType="submit">
|
|
88
|
+
{locale === 'ja' ? '送信' : 'Submit'}
|
|
89
|
+
</Button>
|
|
90
|
+
</Form.Item>
|
|
91
|
+
</Form>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## With Edit Mode (Initial Values)
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import { Form, Input, Button, Spin } from 'antd';
|
|
100
|
+
import { userSchemas, getUserFieldLabel } from '@omnify/schemas/User';
|
|
101
|
+
import { User } from '@omnify/schemas';
|
|
102
|
+
|
|
103
|
+
interface UserEditFormProps {
|
|
104
|
+
user: User;
|
|
105
|
+
locale?: string;
|
|
106
|
+
onSubmit: (values: Partial<User>) => void;
|
|
107
|
+
loading?: boolean;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function UserEditForm({ user, locale = 'ja', onSubmit, loading }: UserEditFormProps) {
|
|
111
|
+
const [form] = Form.useForm();
|
|
112
|
+
const rules = userSchemas(locale);
|
|
113
|
+
|
|
114
|
+
// Set initial values when user data changes
|
|
115
|
+
React.useEffect(() => {
|
|
116
|
+
form.setFieldsValue(user);
|
|
117
|
+
}, [user, form]);
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<Spin spinning={loading}>
|
|
121
|
+
<Form
|
|
122
|
+
form={form}
|
|
123
|
+
layout="vertical"
|
|
124
|
+
initialValues={user}
|
|
125
|
+
onFinish={onSubmit}
|
|
126
|
+
>
|
|
127
|
+
<Form.Item
|
|
128
|
+
name="name"
|
|
129
|
+
label={getUserFieldLabel('name', locale)}
|
|
130
|
+
rules={rules.name}
|
|
131
|
+
>
|
|
132
|
+
<Input />
|
|
133
|
+
</Form.Item>
|
|
134
|
+
|
|
135
|
+
<Form.Item
|
|
136
|
+
name="email"
|
|
137
|
+
label={getUserFieldLabel('email', locale)}
|
|
138
|
+
rules={rules.email}
|
|
139
|
+
>
|
|
140
|
+
<Input type="email" />
|
|
141
|
+
</Form.Item>
|
|
142
|
+
|
|
143
|
+
<Form.Item>
|
|
144
|
+
<Button type="primary" htmlType="submit" loading={loading}>
|
|
145
|
+
{locale === 'ja' ? '更新' : 'Update'}
|
|
146
|
+
</Button>
|
|
147
|
+
</Form.Item>
|
|
148
|
+
</Form>
|
|
149
|
+
</Spin>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Dynamic Locale Switching
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
import { Form, Input, Select } from 'antd';
|
|
158
|
+
import { useState, useMemo } from 'react';
|
|
159
|
+
import { userSchemas, getUserFieldLabel, getUserLabel } from '@omnify/schemas/User';
|
|
160
|
+
|
|
161
|
+
export function UserFormWithLocale() {
|
|
162
|
+
const [locale, setLocale] = useState('ja');
|
|
163
|
+
const [form] = Form.useForm();
|
|
164
|
+
|
|
165
|
+
// Memoize rules to avoid recalculation
|
|
166
|
+
const rules = useMemo(() => userSchemas(locale), [locale]);
|
|
167
|
+
|
|
168
|
+
return (
|
|
169
|
+
<>
|
|
170
|
+
<Select value={locale} onChange={setLocale} style={{ marginBottom: 16 }}>
|
|
171
|
+
<Select.Option value="ja">日本語</Select.Option>
|
|
172
|
+
<Select.Option value="en">English</Select.Option>
|
|
173
|
+
<Select.Option value="vi">Tiếng Việt</Select.Option>
|
|
174
|
+
</Select>
|
|
175
|
+
|
|
176
|
+
<h2>{getUserLabel(locale)}</h2>
|
|
177
|
+
|
|
178
|
+
<Form form={form} layout="vertical">
|
|
179
|
+
<Form.Item
|
|
180
|
+
name="name"
|
|
181
|
+
label={getUserFieldLabel('name', locale)}
|
|
182
|
+
rules={rules.name}
|
|
183
|
+
>
|
|
184
|
+
<Input />
|
|
185
|
+
</Form.Item>
|
|
186
|
+
|
|
187
|
+
<Form.Item
|
|
188
|
+
name="email"
|
|
189
|
+
label={getUserFieldLabel('email', locale)}
|
|
190
|
+
rules={rules.email}
|
|
191
|
+
>
|
|
192
|
+
<Input type="email" />
|
|
193
|
+
</Form.Item>
|
|
194
|
+
</Form>
|
|
195
|
+
</>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## With Table Columns
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
import { Table, TableColumnsType } from 'antd';
|
|
204
|
+
import { getUserFieldLabel } from '@omnify/schemas/User';
|
|
205
|
+
import { User } from '@omnify/schemas';
|
|
206
|
+
|
|
207
|
+
interface UserTableProps {
|
|
208
|
+
users: User[];
|
|
209
|
+
locale?: string;
|
|
210
|
+
loading?: boolean;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function UserTable({ users, locale = 'ja', loading }: UserTableProps) {
|
|
214
|
+
const columns: TableColumnsType<User> = [
|
|
215
|
+
{
|
|
216
|
+
title: getUserFieldLabel('name', locale),
|
|
217
|
+
dataIndex: 'name',
|
|
218
|
+
key: 'name',
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
title: getUserFieldLabel('email', locale),
|
|
222
|
+
dataIndex: 'email',
|
|
223
|
+
key: 'email',
|
|
224
|
+
},
|
|
225
|
+
];
|
|
226
|
+
|
|
227
|
+
return (
|
|
228
|
+
<Table
|
|
229
|
+
columns={columns}
|
|
230
|
+
dataSource={users}
|
|
231
|
+
rowKey="id"
|
|
232
|
+
loading={loading}
|
|
233
|
+
/>
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Custom Form Hook
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
import { Form, FormInstance } from 'antd';
|
|
242
|
+
import { useMemo } from 'react';
|
|
243
|
+
|
|
244
|
+
// Generic hook for any model's rules
|
|
245
|
+
export function useModelForm<T>(
|
|
246
|
+
getRules: (locale: string) => Record<string, any[]>,
|
|
247
|
+
locale: string = 'ja'
|
|
248
|
+
): {
|
|
249
|
+
form: FormInstance<T>;
|
|
250
|
+
rules: Record<string, any[]>;
|
|
251
|
+
} {
|
|
252
|
+
const [form] = Form.useForm<T>();
|
|
253
|
+
const rules = useMemo(() => getRules(locale), [getRules, locale]);
|
|
254
|
+
|
|
255
|
+
return { form, rules };
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Usage
|
|
259
|
+
import { userSchemas } from '@omnify/schemas/User';
|
|
260
|
+
|
|
261
|
+
function MyComponent() {
|
|
262
|
+
const { form, rules } = useModelForm(userSchemas, 'ja');
|
|
263
|
+
|
|
264
|
+
return (
|
|
265
|
+
<Form form={form}>
|
|
266
|
+
<Form.Item name="name" rules={rules.name}>
|
|
267
|
+
<Input />
|
|
268
|
+
</Form.Item>
|
|
269
|
+
</Form>
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Modal Form
|
|
275
|
+
|
|
276
|
+
```tsx
|
|
277
|
+
import { Modal, Form, Input, message } from 'antd';
|
|
278
|
+
import { userSchemas, getUserLabel, getUserFieldLabel } from '@omnify/schemas/User';
|
|
279
|
+
import { User } from '@omnify/schemas';
|
|
280
|
+
|
|
281
|
+
interface UserModalFormProps {
|
|
282
|
+
open: boolean;
|
|
283
|
+
onClose: () => void;
|
|
284
|
+
onSubmit: (values: Partial<User>) => Promise<void>;
|
|
285
|
+
initialValues?: Partial<User>;
|
|
286
|
+
locale?: string;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export function UserModalForm({
|
|
290
|
+
open,
|
|
291
|
+
onClose,
|
|
292
|
+
onSubmit,
|
|
293
|
+
initialValues,
|
|
294
|
+
locale = 'ja'
|
|
295
|
+
}: UserModalFormProps) {
|
|
296
|
+
const [form] = Form.useForm();
|
|
297
|
+
const [loading, setLoading] = useState(false);
|
|
298
|
+
const rules = userSchemas(locale);
|
|
299
|
+
|
|
300
|
+
const handleSubmit = async () => {
|
|
301
|
+
try {
|
|
302
|
+
const values = await form.validateFields();
|
|
303
|
+
setLoading(true);
|
|
304
|
+
await onSubmit(values);
|
|
305
|
+
message.success(locale === 'ja' ? '保存しました' : 'Saved successfully');
|
|
306
|
+
form.resetFields();
|
|
307
|
+
onClose();
|
|
308
|
+
} catch (error) {
|
|
309
|
+
if (error instanceof Error) {
|
|
310
|
+
message.error(error.message);
|
|
311
|
+
}
|
|
312
|
+
} finally {
|
|
313
|
+
setLoading(false);
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
return (
|
|
318
|
+
<Modal
|
|
319
|
+
title={getUserLabel(locale)}
|
|
320
|
+
open={open}
|
|
321
|
+
onCancel={onClose}
|
|
322
|
+
onOk={handleSubmit}
|
|
323
|
+
confirmLoading={loading}
|
|
324
|
+
okText={locale === 'ja' ? '保存' : 'Save'}
|
|
325
|
+
cancelText={locale === 'ja' ? 'キャンセル' : 'Cancel'}
|
|
326
|
+
>
|
|
327
|
+
<Form
|
|
328
|
+
form={form}
|
|
329
|
+
layout="vertical"
|
|
330
|
+
initialValues={initialValues}
|
|
331
|
+
>
|
|
332
|
+
<Form.Item
|
|
333
|
+
name="name"
|
|
334
|
+
label={getUserFieldLabel('name', locale)}
|
|
335
|
+
rules={rules.name}
|
|
336
|
+
>
|
|
337
|
+
<Input />
|
|
338
|
+
</Form.Item>
|
|
339
|
+
|
|
340
|
+
<Form.Item
|
|
341
|
+
name="email"
|
|
342
|
+
label={getUserFieldLabel('email', locale)}
|
|
343
|
+
rules={rules.email}
|
|
344
|
+
>
|
|
345
|
+
<Input type="email" />
|
|
346
|
+
</Form.Item>
|
|
347
|
+
</Form>
|
|
348
|
+
</Modal>
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Validation Rule Types
|
|
354
|
+
|
|
355
|
+
Omnify generates these rule types based on schema:
|
|
356
|
+
|
|
357
|
+
| Schema | Generated Rule |
|
|
358
|
+
|--------|---------------|
|
|
359
|
+
| `required: true` | `{ required: true, message: {...} }` |
|
|
360
|
+
| `type: Email` | `{ type: 'email', message: {...} }` |
|
|
361
|
+
| `maxLength: N` | `{ max: N, message: {...} }` |
|
|
362
|
+
| `minLength: N` | `{ min: N, message: {...} }` |
|
|
363
|
+
| `max: N` (numeric) | `{ max: N, type: 'number', message: {...} }` |
|
|
364
|
+
| `min: N` (numeric) | `{ min: N, type: 'number', message: {...} }` |
|
|
365
|
+
| `pattern: regex` | `{ pattern: /regex/, message: {...} }` |
|
|
366
|
+
|
|
367
|
+
## Built-in Validation Messages
|
|
368
|
+
|
|
369
|
+
Omnify includes templates for 5 languages:
|
|
370
|
+
- Japanese (ja)
|
|
371
|
+
- English (en)
|
|
372
|
+
- Vietnamese (vi)
|
|
373
|
+
- Korean (ko)
|
|
374
|
+
- Chinese (zh)
|
|
375
|
+
|
|
376
|
+
Custom templates can be configured in `omnify.config.ts`:
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
export default defineConfig({
|
|
380
|
+
output: {
|
|
381
|
+
typescript: {
|
|
382
|
+
validationTemplates: {
|
|
383
|
+
required: {
|
|
384
|
+
ja: '${displayName}を入力してください',
|
|
385
|
+
en: '${displayName} is required',
|
|
386
|
+
vi: '${displayName} là bắt buộc',
|
|
387
|
+
},
|
|
388
|
+
maxLength: {
|
|
389
|
+
ja: '${displayName}は${max}文字以内です',
|
|
390
|
+
en: '${displayName} must be at most ${max} characters',
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
});
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Available placeholders:
|
|
399
|
+
- `${displayName}` - Property display name
|
|
400
|
+
- `${min}` - Minimum value/length
|
|
401
|
+
- `${max}` - Maximum value/length
|