@formality-ui/core 0.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 ADDED
@@ -0,0 +1,254 @@
1
+ # @formality-ui/core
2
+
3
+ Framework-agnostic form utilities for the Formality framework. This package provides pure functions for expression evaluation, condition processing, validation, and configuration management that can be used with any JavaScript framework.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @formality-ui/core
9
+ # or
10
+ pnpm add @formality-ui/core
11
+ # or
12
+ yarn add @formality-ui/core
13
+ ```
14
+
15
+ ## Overview
16
+
17
+ `@formality-ui/core` is the foundation of the Formality framework. It provides:
18
+
19
+ - **Expression Engine**: Parse and evaluate dynamic expressions against form state
20
+ - **Condition Evaluation**: Process conditional visibility, disabled states, and value setting
21
+ - **Validation Pipeline**: Compose and run validators with error message resolution
22
+ - **Value Transformation**: Parse input values and format display values
23
+ - **Configuration Utilities**: Merge and resolve field configurations
24
+ - **Label Resolution**: Auto-generate and resolve field labels
25
+
26
+ ## Key Features
27
+
28
+ ### Zero Framework Dependencies
29
+
30
+ This package has no React, Vue, or Svelte dependencies. It exports pure functions that can be used in any JavaScript environment.
31
+
32
+ ### Expression Evaluation
33
+
34
+ Evaluate dynamic expressions against form state:
35
+
36
+ ```typescript
37
+ import { evaluate, buildEvaluationContext } from '@formality-ui/core';
38
+
39
+ const context = buildEvaluationContext({
40
+ fields: {
41
+ client: { value: { id: 5, name: 'Acme' } },
42
+ signed: { value: true },
43
+ },
44
+ record: { originalName: 'Old Name' },
45
+ });
46
+
47
+ // Simple field access
48
+ evaluate('client', context); // { id: 5, name: 'Acme' }
49
+ evaluate('client.id', context); // 5
50
+
51
+ // Expressions
52
+ evaluate('client && signed', context); // true
53
+ evaluate('client.id > 3', context); // true
54
+ ```
55
+
56
+ ### Condition Evaluation
57
+
58
+ Evaluate conditions for field visibility and disabled state:
59
+
60
+ ```typescript
61
+ import { evaluateConditions } from '@formality-ui/core';
62
+
63
+ const result = evaluateConditions({
64
+ conditions: [
65
+ { when: 'signed', is: false, disabled: true },
66
+ { when: 'archived', truthy: true, visible: false },
67
+ ],
68
+ fieldValues: { signed: false, archived: false },
69
+ });
70
+
71
+ result.disabled; // true
72
+ result.visible; // true
73
+ ```
74
+
75
+ ### Validation
76
+
77
+ Compose and run validators:
78
+
79
+ ```typescript
80
+ import { runValidator, composeValidators, required, minLength } from '@formality-ui/core';
81
+
82
+ const validator = composeValidators([required(), minLength(3)]);
83
+ const result = await runValidator(validator, 'ab', {});
84
+ // { type: 'minLength', message: 'Minimum 3 characters required' }
85
+ ```
86
+
87
+ ### Value Transformation
88
+
89
+ Parse and format values:
90
+
91
+ ```typescript
92
+ import { parse, format, createFloatParser, createFloatFormatter } from '@formality-ui/core';
93
+
94
+ const parser = createFloatParser();
95
+ const formatter = createFloatFormatter(2);
96
+
97
+ parse('42.567', parser); // 42.567 (number)
98
+ format(42.567, formatter); // '42.57' (string, 2 decimals)
99
+ ```
100
+
101
+ ### Label Resolution
102
+
103
+ Auto-generate human-readable labels from field names:
104
+
105
+ ```typescript
106
+ import { humanizeLabel, resolveLabel } from '@formality-ui/core';
107
+
108
+ humanizeLabel('clientContact'); // 'Client Contact'
109
+ humanizeLabel('minGrossMargin'); // 'Min Gross Margin'
110
+ humanizeLabel('userId'); // 'User Id'
111
+ ```
112
+
113
+ ## API Reference
114
+
115
+ ### Expression Engine
116
+
117
+ | Function | Description |
118
+ |----------|-------------|
119
+ | `evaluate(expr, context)` | Evaluate an expression string against context |
120
+ | `evaluateDescriptor(descriptor, context)` | Evaluate a SelectValue descriptor |
121
+ | `buildEvaluationContext(fields, record, props)` | Build evaluation context |
122
+ | `buildFormContext(fields, record)` | Build form-level context |
123
+ | `buildFieldContext(name, fields, record, props)` | Build field-level context |
124
+ | `inferFieldsFromExpression(expr)` | Extract field dependencies from expression |
125
+ | `inferFieldsFromDescriptor(descriptor)` | Extract field dependencies from descriptor |
126
+ | `clearExpressionCache()` | Clear the expression parser cache |
127
+
128
+ ### Condition Evaluation
129
+
130
+ | Function | Description |
131
+ |----------|-------------|
132
+ | `evaluateConditions(input)` | Evaluate conditions and return disabled/visible/setValue |
133
+ | `conditionMatches(condition, context)` | Check if a single condition matches |
134
+ | `mergeConditionResults(results)` | Merge multiple condition results |
135
+ | `inferFieldsFromConditions(conditions)` | Extract field dependencies from conditions |
136
+
137
+ ### Validation
138
+
139
+ | Function | Description |
140
+ |----------|-------------|
141
+ | `runValidator(spec, value, formValues, validators)` | Run validator(s) asynchronously |
142
+ | `runValidatorSync(spec, value, formValues, validators)` | Run validator(s) synchronously |
143
+ | `isValid(result)` | Check if validation result is valid |
144
+ | `composeValidators(validators)` | Compose multiple validators |
145
+ | `required()` | Built-in required validator |
146
+ | `minLength(min)` | Built-in minimum length validator |
147
+ | `maxLength(max)` | Built-in maximum length validator |
148
+ | `pattern(regex)` | Built-in pattern validator |
149
+ | `resolveErrorMessage(result, messages)` | Resolve error message from result |
150
+ | `formatTypeAsMessage(type)` | Format validation type as message |
151
+ | `createErrorMessages(config)` | Create error messages configuration |
152
+ | `getErrorType(result)` | Get the error type from result |
153
+ | `createValidationError(type, message)` | Create a validation error object |
154
+
155
+ ### Value Transformation
156
+
157
+ | Function | Description |
158
+ |----------|-------------|
159
+ | `parse(value, parser, parsers)` | Parse input value |
160
+ | `format(value, formatter, formatters)` | Format value for display |
161
+ | `extractValueField(value, field)` | Extract a field from a value object |
162
+ | `transformFieldName(name, config)` | Transform field name based on config |
163
+ | `createFloatParser()` | Create float parser |
164
+ | `createFloatFormatter(decimals)` | Create float formatter with precision |
165
+ | `createIntParser()` | Create integer parser |
166
+ | `createTrimParser()` | Create string trimming parser |
167
+ | `createDefaultParsers()` | Create default parsers configuration |
168
+ | `createDefaultFormatters()` | Create default formatters configuration |
169
+
170
+ ### Configuration
171
+
172
+ | Function | Description |
173
+ |----------|-------------|
174
+ | `deepMerge(target, source)` | Deep merge objects |
175
+ | `mergeInputConfigs(base, override)` | Merge input configurations |
176
+ | `resolveInputConfig(type, inputs, formInputs)` | Resolve input configuration |
177
+ | `resolveFieldType(name, config, inputs)` | Resolve field type from config |
178
+ | `mergeStaticProps(layers)` | Merge static props from multiple layers |
179
+ | `mergeFieldProps(layers)` | Merge props from multiple layers |
180
+ | `createConfigContext(config)` | Create configuration context |
181
+ | `resolveInitialValue(name, config, inputConfig, record)` | Resolve initial field value |
182
+ | `resolveAllInitialValues(config, inputs, record)` | Resolve all initial values |
183
+ | `isEmptyValue(value)` | Check if a value is empty |
184
+ | `getInputDefaultValue(inputConfig)` | Get default value from input config |
185
+ | `mergeRecordWithDefaults(config, inputs, record)` | Merge record with default values |
186
+
187
+ ### Labels & Ordering
188
+
189
+ | Function | Description |
190
+ |----------|-------------|
191
+ | `humanizeLabel(fieldName)` | Convert camelCase to human-readable |
192
+ | `resolveLabel(name, config, evaluated, props)` | Resolve field label |
193
+ | `resolveFormTitle(formConfig, record)` | Resolve form title |
194
+ | `isAutoGeneratedLabel(label, fieldName)` | Check if label was auto-generated |
195
+ | `createLabelWithUnit(label, unit)` | Create label with unit suffix |
196
+ | `parseLabelWithUnit(labelWithUnit)` | Parse label with unit |
197
+ | `sortFieldsByOrder(fields, config)` | Sort fields by order property |
198
+ | `getUnusedFields(allFields, usedFields)` | Get unused field names |
199
+ | `getOrderedUnusedFields(allFields, usedFields, config)` | Get ordered unused fields |
200
+
201
+ ## TypeScript Types
202
+
203
+ ```typescript
204
+ import type {
205
+ // Configuration
206
+ SelectValue,
207
+ SelectFunction,
208
+ InputConfig,
209
+ FieldConfig,
210
+ FormConfig,
211
+ FormFieldsConfig,
212
+ GroupConfig,
213
+ FormalityProviderConfig,
214
+
215
+ // State
216
+ FieldError,
217
+ FieldState,
218
+ FormState,
219
+
220
+ // Conditions
221
+ ConditionDescriptor,
222
+ ConditionResult,
223
+
224
+ // Validation
225
+ ValidatorSpec,
226
+ ValidatorFunction,
227
+ ValidationResult,
228
+ ValidatorFactory,
229
+ ValidatorsConfig,
230
+ ErrorMessagesConfig,
231
+
232
+ // Transform
233
+ ParserFunction,
234
+ FormatterFunction,
235
+ ParserSpec,
236
+ FormatterSpec,
237
+ ParsersConfig,
238
+ FormattersConfig,
239
+
240
+ // Expression
241
+ EvaluationContext,
242
+ } from '@formality-ui/core';
243
+ ```
244
+
245
+ ## Constants
246
+
247
+ | Constant | Description |
248
+ |----------|-------------|
249
+ | `QUALIFIED_PREFIXES` | Prefixes for qualified field references |
250
+ | `KEYWORDS` | Reserved keywords in expressions |
251
+
252
+ ## License
253
+
254
+ MIT