pdyform 1.2.0 → 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.
Files changed (118) hide show
  1. package/README.md +28 -1
  2. package/example/README.md +36 -0
  3. package/example/react-demo/dist/assets/index-BBU9cJqy.css +1 -0
  4. package/example/react-demo/dist/assets/index-DeJS8UcQ.js +105 -0
  5. package/example/react-demo/dist/index.html +13 -0
  6. package/example/react-demo/index.html +12 -0
  7. package/example/react-demo/node_modules/.bin/browserslist +17 -0
  8. package/example/react-demo/node_modules/.bin/tsc +17 -0
  9. package/example/react-demo/node_modules/.bin/tsserver +17 -0
  10. package/example/react-demo/node_modules/.bin/vite +17 -0
  11. package/example/react-demo/node_modules/.vite/deps/@radix-ui_react-checkbox.js +300 -0
  12. package/example/react-demo/node_modules/.vite/deps/@radix-ui_react-checkbox.js.map +7 -0
  13. package/example/react-demo/node_modules/.vite/deps/@radix-ui_react-label.js +194 -0
  14. package/example/react-demo/node_modules/.vite/deps/@radix-ui_react-label.js.map +7 -0
  15. package/example/react-demo/node_modules/.vite/deps/@radix-ui_react-radio-group.js +530 -0
  16. package/example/react-demo/node_modules/.vite/deps/@radix-ui_react-radio-group.js.map +7 -0
  17. package/example/react-demo/node_modules/.vite/deps/@radix-ui_react-select.js +4808 -0
  18. package/example/react-demo/node_modules/.vite/deps/@radix-ui_react-select.js.map +7 -0
  19. package/example/react-demo/node_modules/.vite/deps/_metadata.json +115 -0
  20. package/example/react-demo/node_modules/.vite/deps/chunk-3D5PZ6F6.js +49 -0
  21. package/example/react-demo/node_modules/.vite/deps/chunk-3D5PZ6F6.js.map +7 -0
  22. package/example/react-demo/node_modules/.vite/deps/chunk-5Q2RBQLA.js +127 -0
  23. package/example/react-demo/node_modules/.vite/deps/chunk-5Q2RBQLA.js.map +7 -0
  24. package/example/react-demo/node_modules/.vite/deps/chunk-G3PMV62Z.js +36 -0
  25. package/example/react-demo/node_modules/.vite/deps/chunk-G3PMV62Z.js.map +7 -0
  26. package/example/react-demo/node_modules/.vite/deps/chunk-GX7YZ5KV.js +370 -0
  27. package/example/react-demo/node_modules/.vite/deps/chunk-GX7YZ5KV.js.map +7 -0
  28. package/example/react-demo/node_modules/.vite/deps/chunk-PUFJGYAC.js +928 -0
  29. package/example/react-demo/node_modules/.vite/deps/chunk-PUFJGYAC.js.map +7 -0
  30. package/example/react-demo/node_modules/.vite/deps/chunk-SIU35MPB.js +21 -0
  31. package/example/react-demo/node_modules/.vite/deps/chunk-SIU35MPB.js.map +7 -0
  32. package/example/react-demo/node_modules/.vite/deps/chunk-TOMGVNQP.js +1906 -0
  33. package/example/react-demo/node_modules/.vite/deps/chunk-TOMGVNQP.js.map +7 -0
  34. package/example/react-demo/node_modules/.vite/deps/chunk-YYN6DZAU.js +21628 -0
  35. package/example/react-demo/node_modules/.vite/deps/chunk-YYN6DZAU.js.map +7 -0
  36. package/example/react-demo/node_modules/.vite/deps/chunk-ZE5VSJFE.js +144 -0
  37. package/example/react-demo/node_modules/.vite/deps/chunk-ZE5VSJFE.js.map +7 -0
  38. package/example/react-demo/node_modules/.vite/deps/class-variance-authority.js +51 -0
  39. package/example/react-demo/node_modules/.vite/deps/class-variance-authority.js.map +7 -0
  40. package/example/react-demo/node_modules/.vite/deps/clsx.js +10 -0
  41. package/example/react-demo/node_modules/.vite/deps/clsx.js.map +7 -0
  42. package/example/react-demo/node_modules/.vite/deps/lucide-react.js +29725 -0
  43. package/example/react-demo/node_modules/.vite/deps/lucide-react.js.map +7 -0
  44. package/example/react-demo/node_modules/.vite/deps/package.json +3 -0
  45. package/example/react-demo/node_modules/.vite/deps/react-dom.js +7 -0
  46. package/example/react-demo/node_modules/.vite/deps/react-dom.js.map +7 -0
  47. package/example/react-demo/node_modules/.vite/deps/react-dom_client.js +39 -0
  48. package/example/react-demo/node_modules/.vite/deps/react-dom_client.js.map +7 -0
  49. package/example/react-demo/node_modules/.vite/deps/react.js +6 -0
  50. package/example/react-demo/node_modules/.vite/deps/react.js.map +7 -0
  51. package/example/react-demo/node_modules/.vite/deps/react_jsx-dev-runtime.js +913 -0
  52. package/example/react-demo/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +7 -0
  53. package/example/react-demo/node_modules/.vite/deps/react_jsx-runtime.js +7 -0
  54. package/example/react-demo/node_modules/.vite/deps/react_jsx-runtime.js.map +7 -0
  55. package/example/react-demo/node_modules/.vite/deps/tailwind-merge.js +2534 -0
  56. package/example/react-demo/node_modules/.vite/deps/tailwind-merge.js.map +7 -0
  57. package/example/react-demo/package.json +23 -0
  58. package/example/react-demo/postcss.config.mjs +6 -0
  59. package/example/react-demo/src/App.tsx +64 -0
  60. package/example/react-demo/src/main.tsx +10 -0
  61. package/example/react-demo/src/styles.css +102 -0
  62. package/example/react-demo/tailwind.config.mjs +50 -0
  63. package/example/react-demo/tsconfig.json +16 -0
  64. package/example/react-demo/vite.config.ts +14 -0
  65. package/example/shared/defaultSchema.ts +68 -0
  66. package/example/vue-demo/dist/assets/index-BhWj3D5x.css +1 -0
  67. package/example/vue-demo/dist/assets/index-Bw3THsrD.js +44 -0
  68. package/example/vue-demo/dist/index.html +13 -0
  69. package/example/vue-demo/index.html +12 -0
  70. package/example/vue-demo/node_modules/.bin/tsc +17 -0
  71. package/example/vue-demo/node_modules/.bin/tsserver +17 -0
  72. package/example/vue-demo/node_modules/.bin/vite +17 -0
  73. package/example/vue-demo/node_modules/.vite/deps/_metadata.json +46 -0
  74. package/example/vue-demo/node_modules/.vite/deps/chunk-PZ5AY32C.js +10 -0
  75. package/example/vue-demo/node_modules/.vite/deps/chunk-PZ5AY32C.js.map +7 -0
  76. package/example/vue-demo/node_modules/.vite/deps/chunk-TCXBSQ4M.js +12877 -0
  77. package/example/vue-demo/node_modules/.vite/deps/chunk-TCXBSQ4M.js.map +7 -0
  78. package/example/vue-demo/node_modules/.vite/deps/clsx.js +22 -0
  79. package/example/vue-demo/node_modules/.vite/deps/clsx.js.map +7 -0
  80. package/example/vue-demo/node_modules/.vite/deps/lucide-vue-next.js +29720 -0
  81. package/example/vue-demo/node_modules/.vite/deps/lucide-vue-next.js.map +7 -0
  82. package/example/vue-demo/node_modules/.vite/deps/package.json +3 -0
  83. package/example/vue-demo/node_modules/.vite/deps/radix-vue.js +24321 -0
  84. package/example/vue-demo/node_modules/.vite/deps/radix-vue.js.map +7 -0
  85. package/example/vue-demo/node_modules/.vite/deps/tailwind-merge.js +2534 -0
  86. package/example/vue-demo/node_modules/.vite/deps/tailwind-merge.js.map +7 -0
  87. package/example/vue-demo/node_modules/.vite/deps/vue.js +348 -0
  88. package/example/vue-demo/node_modules/.vite/deps/vue.js.map +7 -0
  89. package/example/vue-demo/package.json +20 -0
  90. package/example/vue-demo/postcss.config.mjs +6 -0
  91. package/example/vue-demo/src/App.vue +61 -0
  92. package/example/vue-demo/src/env.d.ts +1 -0
  93. package/example/vue-demo/src/main.ts +5 -0
  94. package/example/vue-demo/src/style.css +102 -0
  95. package/example/vue-demo/tailwind.config.mjs +50 -0
  96. package/example/vue-demo/tsconfig.json +15 -0
  97. package/example/vue-demo/vite.config.ts +14 -0
  98. package/package.json +7 -2
  99. package/packages/core/dist/{chunk-KQR3LFND.js → chunk-GQASS6PM.js} +20 -0
  100. package/packages/core/dist/index.cjs +20 -0
  101. package/packages/core/dist/index.js +1 -1
  102. package/packages/core/dist/utils.cjs +20 -0
  103. package/packages/core/dist/utils.js +1 -1
  104. package/packages/core/node_modules/.vite/vitest/results.json +1 -1
  105. package/packages/core/src/utils.ts +21 -0
  106. package/packages/core/test/utils.test.ts +6 -0
  107. package/packages/react/dist/index.cjs +22 -13
  108. package/packages/react/dist/index.js +22 -13
  109. package/packages/react/node_modules/.bin/vite +4 -4
  110. package/packages/react/node_modules/.vite/vitest/results.json +1 -1
  111. package/packages/react/src/components/InputRenderer.tsx +23 -12
  112. package/packages/react/test/FormFieldRenderer.test.tsx +10 -0
  113. package/packages/vue/dist/index.js +1 -1
  114. package/packages/vue/dist/index.mjs +9 -3
  115. package/packages/vue/node_modules/.vite/vitest/results.json +1 -1
  116. package/packages/vue/src/components/InputRenderer.vue +10 -1
  117. package/packages/vue/test/FormFieldRenderer.test.ts +11 -0
  118. package/pnpm-workspace.yaml +1 -1
@@ -0,0 +1,348 @@
1
+ import {
2
+ BaseTransition,
3
+ BaseTransitionPropsValidators,
4
+ Comment,
5
+ DeprecationTypes,
6
+ EffectScope,
7
+ ErrorCodes,
8
+ ErrorTypeStrings,
9
+ Fragment,
10
+ KeepAlive,
11
+ ReactiveEffect,
12
+ Static,
13
+ Suspense,
14
+ Teleport,
15
+ Text,
16
+ TrackOpTypes,
17
+ Transition,
18
+ TransitionGroup,
19
+ TriggerOpTypes,
20
+ VueElement,
21
+ assertNumber,
22
+ callWithAsyncErrorHandling,
23
+ callWithErrorHandling,
24
+ camelize,
25
+ capitalize,
26
+ cloneVNode,
27
+ compatUtils,
28
+ compile,
29
+ computed,
30
+ createApp,
31
+ createBaseVNode,
32
+ createBlock,
33
+ createCommentVNode,
34
+ createElementBlock,
35
+ createHydrationRenderer,
36
+ createPropsRestProxy,
37
+ createRenderer,
38
+ createSSRApp,
39
+ createSlots,
40
+ createStaticVNode,
41
+ createTextVNode,
42
+ createVNode,
43
+ customRef,
44
+ defineAsyncComponent,
45
+ defineComponent,
46
+ defineCustomElement,
47
+ defineEmits,
48
+ defineExpose,
49
+ defineModel,
50
+ defineOptions,
51
+ defineProps,
52
+ defineSSRCustomElement,
53
+ defineSlots,
54
+ devtools,
55
+ effect,
56
+ effectScope,
57
+ getCurrentInstance,
58
+ getCurrentScope,
59
+ getCurrentWatcher,
60
+ getTransitionRawChildren,
61
+ guardReactiveProps,
62
+ h,
63
+ handleError,
64
+ hasInjectionContext,
65
+ hydrate,
66
+ hydrateOnIdle,
67
+ hydrateOnInteraction,
68
+ hydrateOnMediaQuery,
69
+ hydrateOnVisible,
70
+ initCustomFormatter,
71
+ initDirectivesForSSR,
72
+ inject,
73
+ isMemoSame,
74
+ isProxy,
75
+ isReactive,
76
+ isReadonly,
77
+ isRef,
78
+ isRuntimeOnly,
79
+ isShallow,
80
+ isVNode,
81
+ markRaw,
82
+ mergeDefaults,
83
+ mergeModels,
84
+ mergeProps,
85
+ nextTick,
86
+ nodeOps,
87
+ normalizeClass,
88
+ normalizeProps,
89
+ normalizeStyle,
90
+ onActivated,
91
+ onBeforeMount,
92
+ onBeforeUnmount,
93
+ onBeforeUpdate,
94
+ onDeactivated,
95
+ onErrorCaptured,
96
+ onMounted,
97
+ onRenderTracked,
98
+ onRenderTriggered,
99
+ onScopeDispose,
100
+ onServerPrefetch,
101
+ onUnmounted,
102
+ onUpdated,
103
+ onWatcherCleanup,
104
+ openBlock,
105
+ patchProp,
106
+ popScopeId,
107
+ provide,
108
+ proxyRefs,
109
+ pushScopeId,
110
+ queuePostFlushCb,
111
+ reactive,
112
+ readonly,
113
+ ref,
114
+ registerRuntimeCompiler,
115
+ render,
116
+ renderList,
117
+ renderSlot,
118
+ resolveComponent,
119
+ resolveDirective,
120
+ resolveDynamicComponent,
121
+ resolveFilter,
122
+ resolveTransitionHooks,
123
+ setBlockTracking,
124
+ setDevtoolsHook,
125
+ setTransitionHooks,
126
+ shallowReactive,
127
+ shallowReadonly,
128
+ shallowRef,
129
+ ssrContextKey,
130
+ ssrUtils,
131
+ stop,
132
+ toDisplayString,
133
+ toHandlerKey,
134
+ toHandlers,
135
+ toRaw,
136
+ toRef,
137
+ toRefs,
138
+ toValue,
139
+ transformVNodeArgs,
140
+ triggerRef,
141
+ unref,
142
+ useAttrs,
143
+ useCssModule,
144
+ useCssVars,
145
+ useHost,
146
+ useId,
147
+ useModel,
148
+ useSSRContext,
149
+ useShadowRoot,
150
+ useSlots,
151
+ useTemplateRef,
152
+ useTransitionState,
153
+ vModelCheckbox,
154
+ vModelDynamic,
155
+ vModelRadio,
156
+ vModelSelect,
157
+ vModelText,
158
+ vShow,
159
+ version,
160
+ warn,
161
+ watch,
162
+ watchEffect,
163
+ watchPostEffect,
164
+ watchSyncEffect,
165
+ withAsyncContext,
166
+ withCtx,
167
+ withDefaults,
168
+ withDirectives,
169
+ withKeys,
170
+ withMemo,
171
+ withModifiers,
172
+ withScopeId
173
+ } from "./chunk-TCXBSQ4M.js";
174
+ import "./chunk-PZ5AY32C.js";
175
+ export {
176
+ BaseTransition,
177
+ BaseTransitionPropsValidators,
178
+ Comment,
179
+ DeprecationTypes,
180
+ EffectScope,
181
+ ErrorCodes,
182
+ ErrorTypeStrings,
183
+ Fragment,
184
+ KeepAlive,
185
+ ReactiveEffect,
186
+ Static,
187
+ Suspense,
188
+ Teleport,
189
+ Text,
190
+ TrackOpTypes,
191
+ Transition,
192
+ TransitionGroup,
193
+ TriggerOpTypes,
194
+ VueElement,
195
+ assertNumber,
196
+ callWithAsyncErrorHandling,
197
+ callWithErrorHandling,
198
+ camelize,
199
+ capitalize,
200
+ cloneVNode,
201
+ compatUtils,
202
+ compile,
203
+ computed,
204
+ createApp,
205
+ createBlock,
206
+ createCommentVNode,
207
+ createElementBlock,
208
+ createBaseVNode as createElementVNode,
209
+ createHydrationRenderer,
210
+ createPropsRestProxy,
211
+ createRenderer,
212
+ createSSRApp,
213
+ createSlots,
214
+ createStaticVNode,
215
+ createTextVNode,
216
+ createVNode,
217
+ customRef,
218
+ defineAsyncComponent,
219
+ defineComponent,
220
+ defineCustomElement,
221
+ defineEmits,
222
+ defineExpose,
223
+ defineModel,
224
+ defineOptions,
225
+ defineProps,
226
+ defineSSRCustomElement,
227
+ defineSlots,
228
+ devtools,
229
+ effect,
230
+ effectScope,
231
+ getCurrentInstance,
232
+ getCurrentScope,
233
+ getCurrentWatcher,
234
+ getTransitionRawChildren,
235
+ guardReactiveProps,
236
+ h,
237
+ handleError,
238
+ hasInjectionContext,
239
+ hydrate,
240
+ hydrateOnIdle,
241
+ hydrateOnInteraction,
242
+ hydrateOnMediaQuery,
243
+ hydrateOnVisible,
244
+ initCustomFormatter,
245
+ initDirectivesForSSR,
246
+ inject,
247
+ isMemoSame,
248
+ isProxy,
249
+ isReactive,
250
+ isReadonly,
251
+ isRef,
252
+ isRuntimeOnly,
253
+ isShallow,
254
+ isVNode,
255
+ markRaw,
256
+ mergeDefaults,
257
+ mergeModels,
258
+ mergeProps,
259
+ nextTick,
260
+ nodeOps,
261
+ normalizeClass,
262
+ normalizeProps,
263
+ normalizeStyle,
264
+ onActivated,
265
+ onBeforeMount,
266
+ onBeforeUnmount,
267
+ onBeforeUpdate,
268
+ onDeactivated,
269
+ onErrorCaptured,
270
+ onMounted,
271
+ onRenderTracked,
272
+ onRenderTriggered,
273
+ onScopeDispose,
274
+ onServerPrefetch,
275
+ onUnmounted,
276
+ onUpdated,
277
+ onWatcherCleanup,
278
+ openBlock,
279
+ patchProp,
280
+ popScopeId,
281
+ provide,
282
+ proxyRefs,
283
+ pushScopeId,
284
+ queuePostFlushCb,
285
+ reactive,
286
+ readonly,
287
+ ref,
288
+ registerRuntimeCompiler,
289
+ render,
290
+ renderList,
291
+ renderSlot,
292
+ resolveComponent,
293
+ resolveDirective,
294
+ resolveDynamicComponent,
295
+ resolveFilter,
296
+ resolveTransitionHooks,
297
+ setBlockTracking,
298
+ setDevtoolsHook,
299
+ setTransitionHooks,
300
+ shallowReactive,
301
+ shallowReadonly,
302
+ shallowRef,
303
+ ssrContextKey,
304
+ ssrUtils,
305
+ stop,
306
+ toDisplayString,
307
+ toHandlerKey,
308
+ toHandlers,
309
+ toRaw,
310
+ toRef,
311
+ toRefs,
312
+ toValue,
313
+ transformVNodeArgs,
314
+ triggerRef,
315
+ unref,
316
+ useAttrs,
317
+ useCssModule,
318
+ useCssVars,
319
+ useHost,
320
+ useId,
321
+ useModel,
322
+ useSSRContext,
323
+ useShadowRoot,
324
+ useSlots,
325
+ useTemplateRef,
326
+ useTransitionState,
327
+ vModelCheckbox,
328
+ vModelDynamic,
329
+ vModelRadio,
330
+ vModelSelect,
331
+ vModelText,
332
+ vShow,
333
+ version,
334
+ warn,
335
+ watch,
336
+ watchEffect,
337
+ watchPostEffect,
338
+ watchSyncEffect,
339
+ withAsyncContext,
340
+ withCtx,
341
+ withDefaults,
342
+ withDirectives,
343
+ withKeys,
344
+ withMemo,
345
+ withModifiers,
346
+ withScopeId
347
+ };
348
+ //# sourceMappingURL=vue.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@example/vue-demo",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "vue": "^3.5.29",
13
+ "pdyform": "workspace:*"
14
+ },
15
+ "devDependencies": {
16
+ "@vitejs/plugin-vue": "^5.2.4",
17
+ "typescript": "^5.9.3",
18
+ "vite": "^5.4.21"
19
+ }
20
+ }
@@ -0,0 +1,6 @@
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ };
@@ -0,0 +1,61 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue';
3
+ import { DynamicForm } from 'pdyform/vue';
4
+ import type { FormSchema } from 'pdyform/core';
5
+ import { defaultSchema } from '../../shared/defaultSchema';
6
+
7
+ const schemaText = ref(JSON.stringify(defaultSchema, null, 2));
8
+ const schema = ref<FormSchema>(defaultSchema);
9
+ const parseError = ref('');
10
+ const submitResult = ref('');
11
+
12
+ const handleSchemaChange = (nextText: string) => {
13
+ schemaText.value = nextText;
14
+
15
+ try {
16
+ const parsed = JSON.parse(nextText) as FormSchema;
17
+ if (!parsed || !Array.isArray(parsed.fields)) {
18
+ parseError.value = 'Schema must contain a fields array.';
19
+ return;
20
+ }
21
+ schema.value = parsed;
22
+ parseError.value = '';
23
+ } catch (error) {
24
+ parseError.value = error instanceof Error ? error.message : 'Unknown parsing error';
25
+ }
26
+ };
27
+
28
+ const handleSubmit = (values: Record<string, unknown>) => {
29
+ submitResult.value = JSON.stringify(values, null, 2);
30
+ };
31
+ </script>
32
+
33
+ <template>
34
+ <main class="page">
35
+ <header>
36
+ <h1>pdyform Vue Demo</h1>
37
+ <p>Edit schema JSON on the left and validate render/submit behavior on the right.</p>
38
+ </header>
39
+
40
+ <section class="grid">
41
+ <div class="panel">
42
+ <h2>Schema Editor</h2>
43
+ <textarea
44
+ :value="schemaText"
45
+ spellcheck="false"
46
+ @input="(event) => handleSchemaChange((event.target as HTMLTextAreaElement).value)"
47
+ />
48
+ <p v-if="parseError" class="error">JSON Parse Error: {{ parseError }}</p>
49
+ <p v-else class="ok">Schema is valid.</p>
50
+ </div>
51
+
52
+ <div class="panel">
53
+ <h2>Rendered Form</h2>
54
+ <DynamicForm :schema="schema" @submit="handleSubmit" />
55
+
56
+ <h3>Submit Payload</h3>
57
+ <pre>{{ submitResult || 'Submit the form to inspect values.' }}</pre>
58
+ </div>
59
+ </section>
60
+ </main>
61
+ </template>
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,5 @@
1
+ import { createApp } from 'vue';
2
+ import App from './App.vue';
3
+ import './style.css';
4
+
5
+ createApp(App).mount('#app');
@@ -0,0 +1,102 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ --background: 0 0% 100%;
7
+ --foreground: 222.2 84% 4.9%;
8
+ --card: 0 0% 100%;
9
+ --card-foreground: 222.2 84% 4.9%;
10
+ --popover: 0 0% 100%;
11
+ --popover-foreground: 222.2 84% 4.9%;
12
+ --primary: 222.2 47.4% 11.2%;
13
+ --primary-foreground: 210 40% 98%;
14
+ --secondary: 210 40% 96.1%;
15
+ --secondary-foreground: 222.2 47.4% 11.2%;
16
+ --muted: 210 40% 96.1%;
17
+ --muted-foreground: 215.4 16.3% 46.9%;
18
+ --accent: 210 40% 96.1%;
19
+ --accent-foreground: 222.2 47.4% 11.2%;
20
+ --destructive: 0 84.2% 60.2%;
21
+ --destructive-foreground: 210 40% 98%;
22
+ --border: 214.3 31.8% 91.4%;
23
+ --input: 214.3 31.8% 91.4%;
24
+ --ring: 222.2 84% 4.9%;
25
+ --radius: 0.5rem;
26
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
27
+ color: #101828;
28
+ background: #f5f7fb;
29
+ }
30
+
31
+ @layer base {
32
+ * {
33
+ @apply border-border;
34
+ }
35
+
36
+ body {
37
+ @apply bg-background text-foreground;
38
+ }
39
+ }
40
+
41
+ * {
42
+ box-sizing: border-box;
43
+ }
44
+
45
+ body {
46
+ margin: 0;
47
+ }
48
+
49
+ .page {
50
+ max-width: 1280px;
51
+ margin: 0 auto;
52
+ padding: 24px;
53
+ }
54
+
55
+ .grid {
56
+ display: grid;
57
+ grid-template-columns: repeat(2, minmax(0, 1fr));
58
+ gap: 16px;
59
+ }
60
+
61
+ .panel {
62
+ background: #fff;
63
+ border: 1px solid #d0d5dd;
64
+ border-radius: 12px;
65
+ padding: 16px;
66
+ }
67
+
68
+ textarea {
69
+ width: 100%;
70
+ min-height: 520px;
71
+ resize: vertical;
72
+ border: 1px solid #d0d5dd;
73
+ border-radius: 8px;
74
+ padding: 12px;
75
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
76
+ font-size: 12px;
77
+ line-height: 1.5;
78
+ }
79
+
80
+ pre {
81
+ min-height: 120px;
82
+ white-space: pre-wrap;
83
+ background: #0f172a;
84
+ color: #f8fafc;
85
+ border-radius: 8px;
86
+ padding: 12px;
87
+ font-size: 12px;
88
+ }
89
+
90
+ .error {
91
+ color: #b42318;
92
+ }
93
+
94
+ .ok {
95
+ color: #027a48;
96
+ }
97
+
98
+ @media (max-width: 1000px) {
99
+ .grid {
100
+ grid-template-columns: 1fr;
101
+ }
102
+ }
@@ -0,0 +1,50 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ darkMode: ['class'],
4
+ content: [
5
+ './index.html',
6
+ './src/**/*.{js,ts,vue}',
7
+ '../../packages/vue/src/**/*.{js,ts,vue}',
8
+ ],
9
+ theme: {
10
+ extend: {
11
+ colors: {
12
+ border: 'hsl(var(--border))',
13
+ input: 'hsl(var(--input))',
14
+ ring: 'hsl(var(--ring))',
15
+ background: 'hsl(var(--background))',
16
+ foreground: 'hsl(var(--foreground))',
17
+ primary: {
18
+ DEFAULT: 'hsl(var(--primary))',
19
+ foreground: 'hsl(var(--primary-foreground))',
20
+ },
21
+ secondary: {
22
+ DEFAULT: 'hsl(var(--secondary))',
23
+ foreground: 'hsl(var(--secondary-foreground))',
24
+ },
25
+ destructive: {
26
+ DEFAULT: 'hsl(var(--destructive))',
27
+ foreground: 'hsl(var(--destructive-foreground))',
28
+ },
29
+ muted: {
30
+ DEFAULT: 'hsl(var(--muted))',
31
+ foreground: 'hsl(var(--muted-foreground))',
32
+ },
33
+ accent: {
34
+ DEFAULT: 'hsl(var(--accent))',
35
+ foreground: 'hsl(var(--accent-foreground))',
36
+ },
37
+ popover: {
38
+ DEFAULT: 'hsl(var(--popover))',
39
+ foreground: 'hsl(var(--popover-foreground))',
40
+ },
41
+ },
42
+ borderRadius: {
43
+ lg: 'var(--radius)',
44
+ md: 'calc(var(--radius) - 2px)',
45
+ sm: 'calc(var(--radius) - 4px)',
46
+ },
47
+ },
48
+ },
49
+ plugins: [],
50
+ };
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "strict": true,
8
+ "resolveJsonModule": true,
9
+ "isolatedModules": true,
10
+ "esModuleInterop": true,
11
+ "noEmit": true,
12
+ "types": ["vite/client"]
13
+ },
14
+ "include": ["src", "../shared"]
15
+ }
@@ -0,0 +1,14 @@
1
+ import { fileURLToPath, URL } from 'node:url';
2
+ import { defineConfig } from 'vite';
3
+ import vue from '@vitejs/plugin-vue';
4
+
5
+ export default defineConfig({
6
+ plugins: [vue()],
7
+ resolve: {
8
+ alias: {
9
+ 'pdyform/vue': fileURLToPath(new URL('../../packages/vue/src/index.ts', import.meta.url)),
10
+ 'pdyform/core': fileURLToPath(new URL('../../packages/core/src/index.ts', import.meta.url)),
11
+ },
12
+ dedupe: ['vue'],
13
+ },
14
+ });
package/package.json CHANGED
@@ -50,11 +50,16 @@
50
50
  "typescript-eslint": "^8.56.1",
51
51
  "vitest": "^1.0.0"
52
52
  },
53
- "version": "1.2.0",
53
+ "version": "2.0.0",
54
54
  "scripts": {
55
55
  "build:all": "turbo run build",
56
56
  "dev:all": "turbo run dev",
57
+ "dev:example": "turbo run dev --filter=@example/*",
57
58
  "test:all": "turbo run test",
58
- "lint:all": "turbo run lint"
59
+ "lint:all": "turbo run lint",
60
+ "dev:example:react": "pnpm --filter @example/react-demo dev",
61
+ "dev:example:vue": "pnpm --filter @example/vue-demo dev",
62
+ "build:example:react": "pnpm --filter @example/react-demo build",
63
+ "build:example:vue": "pnpm --filter @example/vue-demo build"
59
64
  }
60
65
  }
@@ -1,4 +1,10 @@
1
1
  // src/utils.ts
2
+ function parseNumberish(value) {
3
+ if (typeof value === "number") return Number.isNaN(value) ? null : value;
4
+ if (typeof value !== "string" || value.trim() === "") return null;
5
+ const parsed = Number(value);
6
+ return Number.isNaN(parsed) ? null : parsed;
7
+ }
2
8
  function validateField(value, field) {
3
9
  if (!field.validations) return null;
4
10
  for (const rule of field.validations) {
@@ -9,6 +15,13 @@ function validateField(value, field) {
9
15
  }
10
16
  break;
11
17
  case "min":
18
+ if (field.type === "number") {
19
+ const numericValue = parseNumberish(value);
20
+ if (numericValue !== null && numericValue < rule.value) {
21
+ return rule.message || `${field.label} must be at least ${rule.value}`;
22
+ }
23
+ break;
24
+ }
12
25
  if (typeof value === "number" && value < rule.value) {
13
26
  return rule.message || `${field.label} must be at least ${rule.value}`;
14
27
  }
@@ -17,6 +30,13 @@ function validateField(value, field) {
17
30
  }
18
31
  break;
19
32
  case "max":
33
+ if (field.type === "number") {
34
+ const numericValue = parseNumberish(value);
35
+ if (numericValue !== null && numericValue > rule.value) {
36
+ return rule.message || `${field.label} must be at most ${rule.value}`;
37
+ }
38
+ break;
39
+ }
20
40
  if (typeof value === "number" && value > rule.value) {
21
41
  return rule.message || `${field.label} must be at most ${rule.value}`;
22
42
  }