@dynamic-field-kit/core 1.0.6 โ†’ 1.0.9

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 CHANGED
@@ -1,8 +1,13 @@
1
- # Dynamic Field Kit
1
+ # @dynamic-field-kit/core
2
2
 
3
- A lightweight, extensible **dynamic form engine** for React, built for scalable applications and design systems.
3
+ **Core types and field registry for dynamic-field-kit** (v1.0.7)
4
4
 
5
- `dynamic-field-kit` lets you define forms using **configuration objects** instead of hard-coded UI, and allows applications to **freely extend field types** (`text`, `number`, `checkbox`, `select`, `date`, `custom`, โ€ฆ) without modifying the library.
5
+ A lightweight, extensible **dynamic form engine** framework-agnostic. Define forms using **configuration objects** instead of hard-coded UI, and allow applications to **freely extend field types** without modifying the library.
6
+
7
+ `dynamic-field-kit` provides:
8
+ - A shared `fieldRegistry` singleton that stores renderer implementations across frameworks.
9
+ - Exchange types (`FieldDescription`, `FieldRendererProps`) that let you register renderers in any UI framework (React, Angular, Vue, etc.).
10
+ - An extensible `FieldTypeMap` interface so consumers add custom field types with full TypeScript support.
6
11
 
7
12
  ---
8
13
 
@@ -13,30 +18,29 @@ A lightweight, extensible **dynamic form engine** for React, built for scalable
13
18
  - Pluggable field renderers via registry
14
19
  - Runtime conditional fields (`appearCondition`)
15
20
  - Clean TypeScript declarations (DTS-safe)
16
- - Core logic separated from React rendering
21
+ - Framework-agnostic (works with React, Angular, Vue, or vanilla JS)
17
22
  - Ideal for form builders & design systems
18
23
 
19
24
  ---
20
25
 
21
- ## ๐Ÿ“ฆ Packages
26
+ ## ๐Ÿ“ฆ Packages in the Monorepo
22
27
 
23
28
  | Package | Description |
24
29
  |------|------------|
25
- | `@dynamic-field-kit/core` | Core types and field registry |
30
+ | `@dynamic-field-kit/core` | Core types and field registry (you are here) |
26
31
  | `@dynamic-field-kit/react` | React components (FieldInput, MultiFieldInput, DynamicInput) |
32
+ | `@dynamic-field-kit/angular` | Angular components and module (standalone + NgModule exports) |
27
33
 
28
34
  ---
29
35
 
30
36
  ## ๐Ÿ“ฅ Installation
31
37
 
38
+ The core package is a peer dependency for UI framework adapters. Install together:
39
+
32
40
  ```bash
33
41
  npm install @dynamic-field-kit/core @dynamic-field-kit/react
34
- ```
35
-
36
- **Peer dependency**
37
-
38
- ```txt
39
- react >= 17
42
+ # or for Angular
43
+ npm install @dynamic-field-kit/core @dynamic-field-kit/angular
40
44
  ```
41
45
 
42
46
  ---
@@ -125,105 +129,38 @@ const fields: FieldDescription[] = [
125
129
  | appearCondition | Runtime visibility condition |
126
130
 
127
131
  **Field Registry (Render Layer)**
128
- The library does **not** ship UI components.
129
132
 
130
- Instead, applications register their own renderers.
133
+ The library does **not** ship UI components. Instead, applications register their own renderers using the `fieldRegistry` from the framework adapter (`@dynamic-field-kit/react`, `@dynamic-field-kit/angular`, etc.).
131
134
 
135
+ Example (framework adapter determines how to invoke the renderer):
132
136
  ```ts
133
- import { fieldRegistry } from "@dynamic-field-kit/react"
134
-
135
- fieldRegistry.register("text", ({ value, onValueChange, label }) => (
136
- <div>
137
- <label>{label}</label>
138
- <input
139
- value={value ?? ""}
140
- onChange={(e) => onValueChange?.(e.target.value)}
141
- />
142
- </div>
143
- ))
144
-
145
- fieldRegistry.register("checkbox", ({ value, onValueChange, label }) => (
146
- <label>
147
- <input
148
- type="checkbox"
149
- checked={!!value}
150
- onChange={(e) => onValueChange?.(e.target.checked)}
151
- />
152
- {label}
153
- </label>
154
- ))
155
-
156
- ```
157
-
158
- ---
137
+ import { fieldRegistry } from "@dynamic-field-kit/react" // or /angular
159
138
 
160
- ## โš›๏ธ React Usage
161
-
162
- **MultiFieldInput (Main Form Engine)**
163
-
164
- ```tsx
165
- import { MultiFieldInput } from "@dynamic-field-kit/react"
166
- import { FieldDescription } from "@dynamic-field-kit/core"
167
-
168
- const fields: FieldDescription[] = [
169
- { name: "email", type: "text", label: "Email" },
170
- { name: "age", type: "number", label: "Age" }
171
- ]
172
-
173
- const Example = () => {
174
- return (
175
- <MultiFieldInput
176
- fieldDescriptions={fields}
177
- onChange={(data) => {
178
- console.log("Form data:", data)
179
- }}
180
- />
181
- )
182
- }
139
+ fieldRegistry.register("text", myTextRenderer)
140
+ fieldRegistry.register("checkbox", myCheckboxRenderer)
183
141
  ```
184
142
 
185
- **Controlled Form**
186
- ```tsx
187
- const [formData, setFormData] = useState({})
188
-
189
- <MultiFieldInput
190
- fieldDescriptions={fields}
191
- properties={formData}
192
- onChange={setFormData}
193
- />
194
- ```
195
143
 
196
- ---
197
144
 
198
145
  ## โž• Adding a New Field Type
199
146
 
200
- You **do not** need to modify the library.
201
-
202
- Just extend `FieldTypeMap`:
147
+ You **do not** need to modify the library. Just extend `FieldTypeMap` in your application:
203
148
 
204
149
  ```ts
205
150
  declare module "@dynamic-field-kit/core" {
206
151
  interface FieldTypeMap {
207
152
  date: Date
153
+ myCustom: any
208
154
  }
209
155
  }
210
156
  ```
211
157
 
212
- Then register a renderer:
158
+ Then register renderers using the framework-specific adapter:
213
159
 
214
- ```ts
215
- fieldRegistry.register("date", ({ value, onValueChange }) => (
216
- <input
217
- type="date"
218
- value={value ? value.toISOString().slice(0, 10) : ""}
219
- onChange={(e) =>
220
- onValueChange?.(new Date(e.target.value))
221
- }
222
- />
223
- ))
224
- ```
160
+ - React: `import { fieldRegistry } from "@dynamic-field-kit/react"`
161
+ - Angular: `import { fieldRegistry } from "@dynamic-field-kit/angular"`
225
162
 
226
- Now `"date"` is fully type-safe everywhere.
163
+ Now your custom types are fully type-safe throughout the codebase.
227
164
 
228
165
  ---
229
166
  ## ๐Ÿง  Domain Typing (Optional)
@@ -246,45 +183,28 @@ const fields: FieldDescription[] = [
246
183
  ```
247
184
  This keeps the library generic while allowing strict typing in the app.
248
185
 
249
- ---
250
-
251
- ## ๐Ÿงฉ Components API
252
-
253
- **<DynamicInput />**
254
-
255
- Resolves and renders a field based on its type.
186
+ ## ๐Ÿ“š Next Steps
256
187
 
257
- ```tsx
258
- <DynamicInput type="text" value="hello" />
259
- ```
260
- ---
261
-
262
- **<FieldInput />**
263
-
264
- Renders a single field with value binding.
265
-
266
- ```tsx
267
- <FieldInput
268
- fieldDescription={field}
269
- renderInfos={formData}
270
- onChange={(value, key) => {}}
271
- />
272
- ```
273
-
274
- ## Demo
275
- - [Examples](https://github.com/vannt-dev/dynamic-field-kit-demo)
188
+ - **React integration**: See `@dynamic-field-kit/react` for component usage and examples.
189
+ - **Angular integration**: See `@dynamic-field-kit/angular` for component usage and examples.
190
+ - **Framework-agnostic**: Use `fieldRegistry` from any adapter to register custom renderers.
276
191
 
277
192
  ---
278
193
 
279
194
  ## ๐Ÿ— Architecture
280
195
 
196
+ The monorepo contains framework-agnostic core and framework-specific adapters:
197
+
281
198
  ```
282
- dynamic-field-kit
199
+ dynamic-field-kit (monorepo)
283
200
  โ”œโ”€ packages/
284
- โ”‚ โ”œโ”€ core # framework-agnostic types
285
- โ”‚ โ””โ”€ react # React renderer + registry
201
+ โ”‚ โ”œโ”€ core # Framework-agnostic types and registry
202
+ โ”‚ โ”œโ”€ react # React renderer & DynamicInput component
203
+ โ”‚ โ””โ”€ angular # Angular components & DynamicFieldKitModule
286
204
  ```
287
205
 
206
+ All packages share the same `fieldRegistry` instance so registrations are visible across frameworks (in the same process).
207
+
288
208
  ---
289
209
 
290
210
  ## ๐Ÿšซ Non-Goals
package/dist/index.js CHANGED
@@ -25,13 +25,13 @@ __export(index_exports, {
25
25
  });
26
26
  module.exports = __toCommonJS(index_exports);
27
27
 
28
- // src/fieldRegistry.ts
28
+ // src/FieldRegistry.ts
29
29
  var FieldRegistry = class {
30
30
  constructor() {
31
- // โ— INTERNAL = string, KHร”NG constrain
31
+ // โ— INTERNAL = string, not constrain
32
32
  this.registry = {};
33
33
  }
34
- // โœ… Type safety แปŸ API
34
+ // โœ… Type safety API
35
35
  register(type, renderer) {
36
36
  this.registry[type] = renderer;
37
37
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/fieldRegistry.ts"],"sourcesContent":["export * from \"./types\"\r\nexport * from \"./fieldRegistry\"\r\n","import { JSX } from \"react\"\r\nimport type { FieldRendererProps, FieldTypeMap } from \"./types\"\r\n\r\nexport type FieldRenderer<T = any> = (props: FieldRendererProps<T>) => JSX.Element\r\n\r\nexport class FieldRegistry {\r\n // โ— INTERNAL = string, KHร”NG constrain\r\n private registry: Record<string, FieldRenderer<any>> = {}\r\n\r\n // โœ… Type safety แปŸ API\r\n register<K extends keyof FieldTypeMap>(\r\n type: K,\r\n renderer: FieldRenderer<FieldTypeMap[K]>\r\n ) {\r\n this.registry[type as string] = renderer\r\n }\r\n\r\n get<K extends keyof FieldTypeMap>(\r\n type: K\r\n ): FieldRenderer<FieldTypeMap[K]> | undefined {\r\n return this.registry[type as string]\r\n }\r\n}\r\n\r\nexport const fieldRegistry = new FieldRegistry()\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKO,IAAM,gBAAN,MAAoB;AAAA,EAApB;AAEH;AAAA,SAAQ,WAA+C,CAAC;AAAA;AAAA;AAAA,EAGxD,SACI,MACA,UACF;AACE,SAAK,SAAS,IAAc,IAAI;AAAA,EACpC;AAAA,EAEA,IACI,MAC0C;AAC1C,WAAO,KAAK,SAAS,IAAc;AAAA,EACvC;AACJ;AAEO,IAAM,gBAAgB,IAAI,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/FieldRegistry.ts"],"sourcesContent":["export * from \"./types\"\r\nexport * from \"./FieldRegistry\"\r\n","import { JSX } from \"react\"\r\nimport type { FieldRendererProps, FieldTypeMap } from \"./types\"\r\n\r\nexport type FieldRenderer<T = any> = (props: FieldRendererProps<T>) => JSX.Element\r\n\r\nexport class FieldRegistry {\r\n // โ— INTERNAL = string, not constrain\r\n private registry: Record<string, FieldRenderer<any>> = {}\r\n\r\n // โœ… Type safety API\r\n register<K extends keyof FieldTypeMap>(\r\n type: K,\r\n renderer: FieldRenderer<FieldTypeMap[K]>\r\n ) {\r\n this.registry[type as string] = renderer\r\n }\r\n\r\n get<K extends keyof FieldTypeMap>(\r\n type: K\r\n ): FieldRenderer<FieldTypeMap[K]> | undefined {\r\n return this.registry[type as string]\r\n }\r\n}\r\n\r\nexport const fieldRegistry = new FieldRegistry()\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKO,IAAM,gBAAN,MAAoB;AAAA,EAApB;AAEH;AAAA,SAAQ,WAA+C,CAAC;AAAA;AAAA;AAAA,EAGxD,SACI,MACA,UACF;AACE,SAAK,SAAS,IAAc,IAAI;AAAA,EACpC;AAAA,EAEA,IACI,MAC0C;AAC1C,WAAO,KAAK,SAAS,IAAc;AAAA,EACvC;AACJ;AAEO,IAAM,gBAAgB,IAAI,cAAc;","names":[]}
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- // src/fieldRegistry.ts
1
+ // src/FieldRegistry.ts
2
2
  var FieldRegistry = class {
3
3
  constructor() {
4
- // โ— INTERNAL = string, KHร”NG constrain
4
+ // โ— INTERNAL = string, not constrain
5
5
  this.registry = {};
6
6
  }
7
- // โœ… Type safety แปŸ API
7
+ // โœ… Type safety API
8
8
  register(type, renderer) {
9
9
  this.registry[type] = renderer;
10
10
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/fieldRegistry.ts"],"sourcesContent":["import { JSX } from \"react\"\r\nimport type { FieldRendererProps, FieldTypeMap } from \"./types\"\r\n\r\nexport type FieldRenderer<T = any> = (props: FieldRendererProps<T>) => JSX.Element\r\n\r\nexport class FieldRegistry {\r\n // โ— INTERNAL = string, KHร”NG constrain\r\n private registry: Record<string, FieldRenderer<any>> = {}\r\n\r\n // โœ… Type safety แปŸ API\r\n register<K extends keyof FieldTypeMap>(\r\n type: K,\r\n renderer: FieldRenderer<FieldTypeMap[K]>\r\n ) {\r\n this.registry[type as string] = renderer\r\n }\r\n\r\n get<K extends keyof FieldTypeMap>(\r\n type: K\r\n ): FieldRenderer<FieldTypeMap[K]> | undefined {\r\n return this.registry[type as string]\r\n }\r\n}\r\n\r\nexport const fieldRegistry = new FieldRegistry()\r\n"],"mappings":";AAKO,IAAM,gBAAN,MAAoB;AAAA,EAApB;AAEH;AAAA,SAAQ,WAA+C,CAAC;AAAA;AAAA;AAAA,EAGxD,SACI,MACA,UACF;AACE,SAAK,SAAS,IAAc,IAAI;AAAA,EACpC;AAAA,EAEA,IACI,MAC0C;AAC1C,WAAO,KAAK,SAAS,IAAc;AAAA,EACvC;AACJ;AAEO,IAAM,gBAAgB,IAAI,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/FieldRegistry.ts"],"sourcesContent":["import { JSX } from \"react\"\r\nimport type { FieldRendererProps, FieldTypeMap } from \"./types\"\r\n\r\nexport type FieldRenderer<T = any> = (props: FieldRendererProps<T>) => JSX.Element\r\n\r\nexport class FieldRegistry {\r\n // โ— INTERNAL = string, not constrain\r\n private registry: Record<string, FieldRenderer<any>> = {}\r\n\r\n // โœ… Type safety API\r\n register<K extends keyof FieldTypeMap>(\r\n type: K,\r\n renderer: FieldRenderer<FieldTypeMap[K]>\r\n ) {\r\n this.registry[type as string] = renderer\r\n }\r\n\r\n get<K extends keyof FieldTypeMap>(\r\n type: K\r\n ): FieldRenderer<FieldTypeMap[K]> | undefined {\r\n return this.registry[type as string]\r\n }\r\n}\r\n\r\nexport const fieldRegistry = new FieldRegistry()\r\n"],"mappings":";AAKO,IAAM,gBAAN,MAAoB;AAAA,EAApB;AAEH;AAAA,SAAQ,WAA+C,CAAC;AAAA;AAAA;AAAA,EAGxD,SACI,MACA,UACF;AACE,SAAK,SAAS,IAAc,IAAI;AAAA,EACpC;AAAA,EAEA,IACI,MAC0C;AAC1C,WAAO,KAAK,SAAS,IAAc;AAAA,EACvC;AACJ;AAEO,IAAM,gBAAgB,IAAI,cAAc;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-field-kit/core",
3
- "version": "1.0.6",
3
+ "version": "1.0.9",
4
4
  "description": "Core types and field registry for dynamic-field-kit",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.cjs",
@@ -19,6 +19,22 @@
19
19
  },
20
20
  "scripts": {
21
21
  "build": "tsup",
22
- "clean": "rm -rf dist"
22
+ "clean": "rimraf dist",
23
+ "prepublishOnly": "npm run clean && npm run build",
24
+ "release:patch": "npm version patch && npm publish",
25
+ "release:minor": "npm version minor && npm publish",
26
+ "release:major": "npm version major && npm publish"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/vannt-dev/dynamic-field-kit.git"
31
+ },
32
+ "keywords": [
33
+ "dynamic-field",
34
+ "dynamic-field-kit",
35
+ "dynamic-field-kit/core"
36
+ ],
37
+ "devDependencies": {
38
+ "rimraf": "^6.1.3"
23
39
  }
24
40
  }