@mdxui/terminal 2.0.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/README.md +571 -0
- package/dist/ansi-css-Sk5mWtdK.d.ts +119 -0
- package/dist/ansi-css-V6JIHGsM.d.ts +119 -0
- package/dist/ansi-css-_3eSEU9d.d.ts +119 -0
- package/dist/chunk-3EFDH7PK.js +5235 -0
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/chunk-3X5IR6WE.js +884 -0
- package/dist/chunk-4FV5ZDCE.js +5236 -0
- package/dist/chunk-4OVMSF2J.js +243 -0
- package/dist/chunk-63FEETIS.js +4048 -0
- package/dist/chunk-B43KP7XJ.js +884 -0
- package/dist/chunk-BMTJXWUV.js +655 -0
- package/dist/chunk-C3SVH4N7.js +882 -0
- package/dist/chunk-EVWR7Y47.js +874 -0
- package/dist/chunk-F6A5VWUC.js +1285 -0
- package/dist/chunk-FD7KW7GE.js +882 -0
- package/dist/chunk-GBQ6UD6I.js +655 -0
- package/dist/chunk-GMDD3M6U.js +5227 -0
- package/dist/chunk-JBHRXOXM.js +1058 -0
- package/dist/chunk-JFOO3EYO.js +1182 -0
- package/dist/chunk-JQ5H3WXL.js +1291 -0
- package/dist/chunk-JQD5NASE.js +234 -0
- package/dist/chunk-KRHJP5R7.js +592 -0
- package/dist/chunk-KWF6WVJE.js +962 -0
- package/dist/chunk-LHYQVN3H.js +1038 -0
- package/dist/chunk-M3TLQLGC.js +1032 -0
- package/dist/chunk-MVW4Q5OP.js +240 -0
- package/dist/chunk-NXCZSWLU.js +1294 -0
- package/dist/chunk-O25TNRO6.js +607 -0
- package/dist/chunk-PNECDA2I.js +884 -0
- package/dist/chunk-QIHWRLJR.js +962 -0
- package/dist/chunk-QW5YMQ7K.js +882 -0
- package/dist/chunk-R5U7XKVJ.js +16 -0
- package/dist/chunk-RP2MVQLR.js +962 -0
- package/dist/chunk-TP6RXGXA.js +1087 -0
- package/dist/chunk-TQQSTITZ.js +655 -0
- package/dist/chunk-X24GWXQV.js +1281 -0
- package/dist/components/index.d.ts +802 -0
- package/dist/components/index.js +149 -0
- package/dist/data/index.d.ts +2554 -0
- package/dist/data/index.js +51 -0
- package/dist/forms/index.d.ts +1596 -0
- package/dist/forms/index.js +464 -0
- package/dist/index-CQRFZntR.d.ts +867 -0
- package/dist/index.d.ts +579 -0
- package/dist/index.js +786 -0
- package/dist/interactive-D0JkWosD.d.ts +217 -0
- package/dist/keyboard/index.d.ts +2 -0
- package/dist/keyboard/index.js +43 -0
- package/dist/renderers/index.d.ts +546 -0
- package/dist/renderers/index.js +2157 -0
- package/dist/storybook/index.d.ts +396 -0
- package/dist/storybook/index.js +641 -0
- package/dist/theme/index.d.ts +1339 -0
- package/dist/theme/index.js +123 -0
- package/dist/types-Bxu5PAgA.d.ts +710 -0
- package/dist/types-CIlop5Ji.d.ts +701 -0
- package/dist/types-Ca8p_p5X.d.ts +710 -0
- package/package.json +90 -0
- package/src/__tests__/components/data/card.test.ts +458 -0
- package/src/__tests__/components/data/list.test.ts +473 -0
- package/src/__tests__/components/data/metrics.test.ts +541 -0
- package/src/__tests__/components/data/table.test.ts +448 -0
- package/src/__tests__/components/input/field.test.ts +555 -0
- package/src/__tests__/components/input/form.test.ts +870 -0
- package/src/__tests__/components/input/search.test.ts +1238 -0
- package/src/__tests__/components/input/select.test.ts +658 -0
- package/src/__tests__/components/navigation/breadcrumb.test.ts +923 -0
- package/src/__tests__/components/navigation/command-palette.test.ts +1095 -0
- package/src/__tests__/components/navigation/sidebar.test.ts +1018 -0
- package/src/__tests__/components/navigation/tabs.test.ts +995 -0
- package/src/__tests__/components.test.tsx +1197 -0
- package/src/__tests__/core/compiler.test.ts +986 -0
- package/src/__tests__/core/parser.test.ts +785 -0
- package/src/__tests__/core/tier-switcher.test.ts +1103 -0
- package/src/__tests__/core/types.test.ts +1398 -0
- package/src/__tests__/data/collections.test.ts +1337 -0
- package/src/__tests__/data/db.test.ts +1265 -0
- package/src/__tests__/data/reactive.test.ts +1010 -0
- package/src/__tests__/data/sync.test.ts +1614 -0
- package/src/__tests__/errors.test.ts +660 -0
- package/src/__tests__/forms/integration.test.ts +444 -0
- package/src/__tests__/integration.test.ts +905 -0
- package/src/__tests__/keyboard.test.ts +1791 -0
- package/src/__tests__/renderer.test.ts +489 -0
- package/src/__tests__/renderers/ansi-css.test.ts +948 -0
- package/src/__tests__/renderers/ansi.test.ts +1366 -0
- package/src/__tests__/renderers/ascii.test.ts +1360 -0
- package/src/__tests__/renderers/interactive.test.ts +2353 -0
- package/src/__tests__/renderers/markdown.test.ts +1483 -0
- package/src/__tests__/renderers/text.test.ts +1369 -0
- package/src/__tests__/renderers/unicode.test.ts +1307 -0
- package/src/__tests__/theme.test.ts +639 -0
- package/src/__tests__/utils/assertions.ts +685 -0
- package/src/__tests__/utils/index.ts +115 -0
- package/src/__tests__/utils/test-renderer.ts +381 -0
- package/src/__tests__/utils/utils.test.ts +560 -0
- package/src/components/containers/card.ts +56 -0
- package/src/components/containers/dialog.ts +53 -0
- package/src/components/containers/index.ts +9 -0
- package/src/components/containers/panel.ts +59 -0
- package/src/components/feedback/badge.ts +40 -0
- package/src/components/feedback/index.ts +8 -0
- package/src/components/feedback/spinner.ts +23 -0
- package/src/components/helpers.ts +81 -0
- package/src/components/index.ts +153 -0
- package/src/components/layout/breadcrumb.ts +31 -0
- package/src/components/layout/index.ts +10 -0
- package/src/components/layout/list.ts +29 -0
- package/src/components/layout/sidebar.ts +79 -0
- package/src/components/layout/table.ts +62 -0
- package/src/components/primitives/box.ts +95 -0
- package/src/components/primitives/button.ts +54 -0
- package/src/components/primitives/index.ts +11 -0
- package/src/components/primitives/input.ts +88 -0
- package/src/components/primitives/select.ts +97 -0
- package/src/components/primitives/text.ts +60 -0
- package/src/components/render.ts +155 -0
- package/src/components/templates/app.ts +43 -0
- package/src/components/templates/index.ts +8 -0
- package/src/components/templates/site.ts +54 -0
- package/src/components/types.ts +777 -0
- package/src/core/compiler.ts +718 -0
- package/src/core/parser.ts +127 -0
- package/src/core/tier-switcher.ts +607 -0
- package/src/core/types.ts +672 -0
- package/src/data/collection.ts +316 -0
- package/src/data/collections.ts +50 -0
- package/src/data/context.tsx +174 -0
- package/src/data/db.ts +127 -0
- package/src/data/hooks.ts +532 -0
- package/src/data/index.ts +138 -0
- package/src/data/reactive.ts +1225 -0
- package/src/data/saas-collections.ts +375 -0
- package/src/data/sync.ts +1213 -0
- package/src/data/types.ts +660 -0
- package/src/forms/converters.ts +512 -0
- package/src/forms/index.ts +133 -0
- package/src/forms/schemas.ts +403 -0
- package/src/forms/types.ts +476 -0
- package/src/index.ts +542 -0
- package/src/keyboard/focus.ts +748 -0
- package/src/keyboard/index.ts +96 -0
- package/src/keyboard/integration.ts +371 -0
- package/src/keyboard/manager.ts +377 -0
- package/src/keyboard/presets.ts +90 -0
- package/src/renderers/ansi-css.ts +576 -0
- package/src/renderers/ansi.ts +802 -0
- package/src/renderers/ascii.ts +680 -0
- package/src/renderers/breadcrumb.ts +480 -0
- package/src/renderers/command-palette.ts +802 -0
- package/src/renderers/components/field.ts +210 -0
- package/src/renderers/components/form.ts +327 -0
- package/src/renderers/components/index.ts +21 -0
- package/src/renderers/components/search.ts +449 -0
- package/src/renderers/components/select.ts +222 -0
- package/src/renderers/index.ts +101 -0
- package/src/renderers/interactive/component-handlers.ts +622 -0
- package/src/renderers/interactive/cursor-manager.ts +147 -0
- package/src/renderers/interactive/focus-manager.ts +279 -0
- package/src/renderers/interactive/index.ts +661 -0
- package/src/renderers/interactive/input-handler.ts +164 -0
- package/src/renderers/interactive/keyboard-handler.ts +212 -0
- package/src/renderers/interactive/mouse-handler.ts +167 -0
- package/src/renderers/interactive/state-manager.ts +109 -0
- package/src/renderers/interactive/types.ts +338 -0
- package/src/renderers/interactive-string.ts +299 -0
- package/src/renderers/interactive.ts +59 -0
- package/src/renderers/markdown.ts +950 -0
- package/src/renderers/sidebar.ts +549 -0
- package/src/renderers/tabs.ts +682 -0
- package/src/renderers/text.ts +791 -0
- package/src/renderers/unicode.ts +917 -0
- package/src/renderers/utils.ts +942 -0
- package/src/router/adapters.ts +383 -0
- package/src/router/types.ts +140 -0
- package/src/router/utils.ts +452 -0
- package/src/schemas.ts +205 -0
- package/src/storybook/index.ts +91 -0
- package/src/storybook/interactive-decorator.tsx +659 -0
- package/src/storybook/keyboard-simulator.ts +501 -0
- package/src/theme/ansi-codes.ts +80 -0
- package/src/theme/box-drawing.ts +132 -0
- package/src/theme/color-convert.ts +254 -0
- package/src/theme/color-support.ts +321 -0
- package/src/theme/index.ts +134 -0
- package/src/theme/strip-ansi.ts +50 -0
- package/src/theme/tailwind-map.ts +469 -0
- package/src/theme/text-styles.ts +206 -0
- package/src/theme/theme-system.ts +568 -0
- package/src/types.ts +103 -0
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mdxui/terminal Form Zod Schemas
|
|
3
|
+
*
|
|
4
|
+
* Zod validation schemas for terminal form components.
|
|
5
|
+
* These schemas can be used with @hookform/resolvers/zod for
|
|
6
|
+
* React Hook Form integration.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { z } from 'zod'
|
|
12
|
+
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Field Value Schemas
|
|
15
|
+
// ============================================================================
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Schema for primitive field values.
|
|
19
|
+
*/
|
|
20
|
+
export const FieldValueSchema = z.union([
|
|
21
|
+
z.string(),
|
|
22
|
+
z.number(),
|
|
23
|
+
z.boolean(),
|
|
24
|
+
z.null(),
|
|
25
|
+
z.undefined(),
|
|
26
|
+
z.array(z.string()),
|
|
27
|
+
])
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Schema for select option configuration.
|
|
31
|
+
*/
|
|
32
|
+
export const SelectOptionSchema = z.object({
|
|
33
|
+
label: z.string(),
|
|
34
|
+
value: z.string(),
|
|
35
|
+
disabled: z.boolean().optional(),
|
|
36
|
+
description: z.string().optional(),
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Schema for search suggestion configuration.
|
|
41
|
+
*/
|
|
42
|
+
export const SearchSuggestionSchema = z.object({
|
|
43
|
+
label: z.string(),
|
|
44
|
+
value: z.string(),
|
|
45
|
+
description: z.string().optional(),
|
|
46
|
+
icon: z.string().optional(),
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Field Configuration Schemas
|
|
51
|
+
// ============================================================================
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Schema for field input types.
|
|
55
|
+
*/
|
|
56
|
+
export const FieldTypeSchema = z.enum([
|
|
57
|
+
'text',
|
|
58
|
+
'email',
|
|
59
|
+
'password',
|
|
60
|
+
'number',
|
|
61
|
+
'checkbox',
|
|
62
|
+
'textarea',
|
|
63
|
+
'select',
|
|
64
|
+
])
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Schema for field configuration.
|
|
68
|
+
*
|
|
69
|
+
* @remarks
|
|
70
|
+
* Validates the complete structure of a form field configuration.
|
|
71
|
+
* Use this to validate field configs passed to terminal renderers.
|
|
72
|
+
*/
|
|
73
|
+
export const FieldConfigSchema = z.object({
|
|
74
|
+
name: z.string().min(1, 'Field name is required'),
|
|
75
|
+
label: z.string().optional(),
|
|
76
|
+
type: FieldTypeSchema.optional(),
|
|
77
|
+
value: FieldValueSchema.optional(),
|
|
78
|
+
placeholder: z.string().optional(),
|
|
79
|
+
required: z.boolean().optional(),
|
|
80
|
+
error: z.string().optional(),
|
|
81
|
+
valid: z.boolean().optional(),
|
|
82
|
+
disabled: z.boolean().optional(),
|
|
83
|
+
readonly: z.boolean().optional(),
|
|
84
|
+
helperText: z.string().optional(),
|
|
85
|
+
focused: z.boolean().optional(),
|
|
86
|
+
cursorPosition: z.number().int().nonnegative().optional(),
|
|
87
|
+
selectionStart: z.number().int().nonnegative().optional(),
|
|
88
|
+
selectionEnd: z.number().int().nonnegative().optional(),
|
|
89
|
+
options: z.array(SelectOptionSchema).optional(),
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Schema for field group configuration.
|
|
94
|
+
*/
|
|
95
|
+
export const FieldGroupSchema = z.object({
|
|
96
|
+
title: z.string(),
|
|
97
|
+
fields: z.array(FieldConfigSchema),
|
|
98
|
+
collapsible: z.boolean().optional(),
|
|
99
|
+
collapsed: z.boolean().optional(),
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// Form State Schemas
|
|
104
|
+
// ============================================================================
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Schema for complete form state.
|
|
108
|
+
*
|
|
109
|
+
* @remarks
|
|
110
|
+
* Validates the full form configuration including all fields,
|
|
111
|
+
* groups, and UI state. Use this to validate form configs
|
|
112
|
+
* passed to the Form renderer.
|
|
113
|
+
*/
|
|
114
|
+
export const FormStateSchema = z.object({
|
|
115
|
+
title: z.string().optional(),
|
|
116
|
+
description: z.string().optional(),
|
|
117
|
+
fields: z.array(FieldConfigSchema).optional(),
|
|
118
|
+
groups: z.array(FieldGroupSchema).optional(),
|
|
119
|
+
error: z.string().optional(),
|
|
120
|
+
success: z.string().optional(),
|
|
121
|
+
loading: z.boolean().optional(),
|
|
122
|
+
submitLabel: z.string().optional(),
|
|
123
|
+
cancelLabel: z.string().optional(),
|
|
124
|
+
submitDisabled: z.boolean().optional(),
|
|
125
|
+
submitHotkey: z.string().optional(),
|
|
126
|
+
border: z.boolean().optional(),
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// Select State Schema
|
|
131
|
+
// ============================================================================
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Schema for select component state.
|
|
135
|
+
*/
|
|
136
|
+
export const SelectStateSchema = z.object({
|
|
137
|
+
options: z.array(SelectOptionSchema),
|
|
138
|
+
value: z.union([z.string(), z.array(z.string())]).optional(),
|
|
139
|
+
label: z.string().optional(),
|
|
140
|
+
placeholder: z.string().optional(),
|
|
141
|
+
required: z.boolean().optional(),
|
|
142
|
+
error: z.string().optional(),
|
|
143
|
+
valid: z.boolean().optional(),
|
|
144
|
+
disabled: z.boolean().optional(),
|
|
145
|
+
open: z.boolean().optional(),
|
|
146
|
+
multiple: z.boolean().optional(),
|
|
147
|
+
highlightedIndex: z.number().int().optional(),
|
|
148
|
+
searchable: z.boolean().optional(),
|
|
149
|
+
searchValue: z.string().optional(),
|
|
150
|
+
filteredOptions: z.array(SelectOptionSchema).optional(),
|
|
151
|
+
loading: z.boolean().optional(),
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// Search State Schema
|
|
156
|
+
// ============================================================================
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Schema for search component state.
|
|
160
|
+
*/
|
|
161
|
+
export const SearchStateSchema = z.object({
|
|
162
|
+
value: z.string(),
|
|
163
|
+
placeholder: z.string().optional(),
|
|
164
|
+
label: z.string().optional(),
|
|
165
|
+
disabled: z.boolean().optional(),
|
|
166
|
+
loading: z.boolean().optional(),
|
|
167
|
+
error: z.string().optional(),
|
|
168
|
+
focused: z.boolean().optional(),
|
|
169
|
+
cursorPosition: z.number().int().nonnegative().optional(),
|
|
170
|
+
suggestions: z.array(SearchSuggestionSchema).nullable().optional(),
|
|
171
|
+
showSuggestions: z.boolean().optional(),
|
|
172
|
+
highlightedIndex: z.number().int().optional(),
|
|
173
|
+
maxSuggestions: z.number().int().positive().optional(),
|
|
174
|
+
highlightMatches: z.boolean().optional(),
|
|
175
|
+
isTyping: z.boolean().optional(),
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
// ============================================================================
|
|
179
|
+
// Common Validation Schemas
|
|
180
|
+
// ============================================================================
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Schema for email validation.
|
|
184
|
+
*/
|
|
185
|
+
export const EmailSchema = z.string().email('Please enter a valid email address')
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Schema for password validation with common requirements.
|
|
189
|
+
*/
|
|
190
|
+
export const PasswordSchema = z
|
|
191
|
+
.string()
|
|
192
|
+
.min(8, 'Password must be at least 8 characters')
|
|
193
|
+
.regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
|
|
194
|
+
.regex(/[a-z]/, 'Password must contain at least one lowercase letter')
|
|
195
|
+
.regex(/[0-9]/, 'Password must contain at least one number')
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Schema for basic password validation (minimum length only).
|
|
199
|
+
*/
|
|
200
|
+
export const SimplePasswordSchema = z
|
|
201
|
+
.string()
|
|
202
|
+
.min(8, 'Password must be at least 8 characters')
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Schema for username validation.
|
|
206
|
+
*/
|
|
207
|
+
export const UsernameSchema = z
|
|
208
|
+
.string()
|
|
209
|
+
.min(3, 'Username must be at least 3 characters')
|
|
210
|
+
.max(20, 'Username must be at most 20 characters')
|
|
211
|
+
.regex(/^[a-zA-Z0-9_-]+$/, 'Username can only contain letters, numbers, underscores, and hyphens')
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Schema for URL validation.
|
|
215
|
+
*/
|
|
216
|
+
export const UrlSchema = z.string().url('Please enter a valid URL')
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Schema for phone number validation (basic).
|
|
220
|
+
*/
|
|
221
|
+
export const PhoneSchema = z
|
|
222
|
+
.string()
|
|
223
|
+
.regex(/^\+?[1-9]\d{1,14}$/, 'Please enter a valid phone number')
|
|
224
|
+
|
|
225
|
+
// ============================================================================
|
|
226
|
+
// Form Schema Builders
|
|
227
|
+
// ============================================================================
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Creates a login form schema.
|
|
231
|
+
*
|
|
232
|
+
* @param options - Optional customization options
|
|
233
|
+
* @returns Zod schema for login form validation
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```tsx
|
|
237
|
+
* const loginSchema = createLoginSchema()
|
|
238
|
+
* type LoginForm = z.infer<typeof loginSchema>
|
|
239
|
+
*
|
|
240
|
+
* // With remember me
|
|
241
|
+
* const loginSchemaWithRemember = createLoginSchema({ rememberMe: true })
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
export function createLoginSchema(options?: {
|
|
245
|
+
rememberMe?: boolean
|
|
246
|
+
strictPassword?: boolean
|
|
247
|
+
}) {
|
|
248
|
+
const base = z.object({
|
|
249
|
+
email: EmailSchema,
|
|
250
|
+
password: options?.strictPassword ? PasswordSchema : SimplePasswordSchema,
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
if (options?.rememberMe) {
|
|
254
|
+
return base.extend({
|
|
255
|
+
rememberMe: z.boolean().optional().default(false),
|
|
256
|
+
})
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return base
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Creates a registration form schema.
|
|
264
|
+
*
|
|
265
|
+
* @param options - Optional customization options
|
|
266
|
+
* @returns Zod schema for registration form validation
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```tsx
|
|
270
|
+
* const registerSchema = createRegistrationSchema({
|
|
271
|
+
* confirmPassword: true,
|
|
272
|
+
* termsRequired: true,
|
|
273
|
+
* })
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
export function createRegistrationSchema(options?: {
|
|
277
|
+
confirmPassword?: boolean
|
|
278
|
+
termsRequired?: boolean
|
|
279
|
+
usernameRequired?: boolean
|
|
280
|
+
}) {
|
|
281
|
+
let schema = z.object({
|
|
282
|
+
email: EmailSchema,
|
|
283
|
+
password: PasswordSchema,
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
if (options?.usernameRequired) {
|
|
287
|
+
schema = schema.extend({
|
|
288
|
+
username: UsernameSchema,
|
|
289
|
+
}) as typeof schema
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (options?.confirmPassword) {
|
|
293
|
+
schema = schema.extend({
|
|
294
|
+
confirmPassword: z.string(),
|
|
295
|
+
}) as typeof schema
|
|
296
|
+
|
|
297
|
+
// Add refinement for password match
|
|
298
|
+
return schema.refine(
|
|
299
|
+
(data) => {
|
|
300
|
+
const d = data as { password: string; confirmPassword?: string }
|
|
301
|
+
return d.password === d.confirmPassword
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
message: 'Passwords do not match',
|
|
305
|
+
path: ['confirmPassword'],
|
|
306
|
+
}
|
|
307
|
+
).and(
|
|
308
|
+
options?.termsRequired
|
|
309
|
+
? z.object({ acceptTerms: z.literal(true, { errorMap: () => ({ message: 'You must accept the terms' }) }) })
|
|
310
|
+
: z.object({})
|
|
311
|
+
)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (options?.termsRequired) {
|
|
315
|
+
return schema.extend({
|
|
316
|
+
acceptTerms: z.literal(true, {
|
|
317
|
+
errorMap: () => ({ message: 'You must accept the terms' }),
|
|
318
|
+
}),
|
|
319
|
+
})
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return schema
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Creates a contact form schema.
|
|
327
|
+
*
|
|
328
|
+
* @param options - Optional customization options
|
|
329
|
+
* @returns Zod schema for contact form validation
|
|
330
|
+
*/
|
|
331
|
+
export function createContactSchema(options?: {
|
|
332
|
+
phoneRequired?: boolean
|
|
333
|
+
subjectRequired?: boolean
|
|
334
|
+
}) {
|
|
335
|
+
let schema = z.object({
|
|
336
|
+
name: z.string().min(1, 'Name is required'),
|
|
337
|
+
email: EmailSchema,
|
|
338
|
+
message: z.string().min(10, 'Message must be at least 10 characters'),
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
if (options?.phoneRequired) {
|
|
342
|
+
schema = schema.extend({
|
|
343
|
+
phone: PhoneSchema,
|
|
344
|
+
}) as typeof schema
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (options?.subjectRequired) {
|
|
348
|
+
schema = schema.extend({
|
|
349
|
+
subject: z.string().min(1, 'Subject is required'),
|
|
350
|
+
}) as typeof schema
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return schema
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Creates a profile form schema.
|
|
358
|
+
*
|
|
359
|
+
* @returns Zod schema for profile form validation
|
|
360
|
+
*/
|
|
361
|
+
export function createProfileSchema() {
|
|
362
|
+
return z.object({
|
|
363
|
+
firstName: z.string().min(1, 'First name is required'),
|
|
364
|
+
lastName: z.string().min(1, 'Last name is required'),
|
|
365
|
+
email: EmailSchema,
|
|
366
|
+
bio: z.string().max(500, 'Bio must be at most 500 characters').optional(),
|
|
367
|
+
website: UrlSchema.optional().or(z.literal('')),
|
|
368
|
+
location: z.string().optional(),
|
|
369
|
+
timezone: z.string().optional(),
|
|
370
|
+
})
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Creates a settings form schema for common app settings.
|
|
375
|
+
*
|
|
376
|
+
* @returns Zod schema for settings form validation
|
|
377
|
+
*/
|
|
378
|
+
export function createSettingsSchema() {
|
|
379
|
+
return z.object({
|
|
380
|
+
emailNotifications: z.boolean().default(true),
|
|
381
|
+
pushNotifications: z.boolean().default(true),
|
|
382
|
+
marketingEmails: z.boolean().default(false),
|
|
383
|
+
theme: z.enum(['light', 'dark', 'system']).default('system'),
|
|
384
|
+
language: z.string().default('en'),
|
|
385
|
+
})
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// ============================================================================
|
|
389
|
+
// Type Exports
|
|
390
|
+
// ============================================================================
|
|
391
|
+
|
|
392
|
+
export type FieldConfig = z.infer<typeof FieldConfigSchema>
|
|
393
|
+
export type FieldGroup = z.infer<typeof FieldGroupSchema>
|
|
394
|
+
export type FormState = z.infer<typeof FormStateSchema>
|
|
395
|
+
export type SelectOption = z.infer<typeof SelectOptionSchema>
|
|
396
|
+
export type SelectState = z.infer<typeof SelectStateSchema>
|
|
397
|
+
export type SearchSuggestion = z.infer<typeof SearchSuggestionSchema>
|
|
398
|
+
export type SearchState = z.infer<typeof SearchStateSchema>
|
|
399
|
+
export type LoginFormValues = z.infer<ReturnType<typeof createLoginSchema>>
|
|
400
|
+
export type RegistrationFormValues = z.infer<ReturnType<typeof createRegistrationSchema>>
|
|
401
|
+
export type ContactFormValues = z.infer<ReturnType<typeof createContactSchema>>
|
|
402
|
+
export type ProfileFormValues = z.infer<ReturnType<typeof createProfileSchema>>
|
|
403
|
+
export type SettingsFormValues = z.infer<ReturnType<typeof createSettingsSchema>>
|