@elliemae/loan-field-renderers 26.2.2
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/dist/cjs/ARCHITECTURE.md +434 -0
- package/dist/cjs/OVERVIEW.md +229 -0
- package/dist/cjs/bll/constants.js +86 -0
- package/dist/cjs/bll/formatters/booleanFormatter.js +51 -0
- package/dist/cjs/bll/formatters/dateFormatter.js +78 -0
- package/dist/cjs/bll/formatters/dropdownFormatter.js +34 -0
- package/dist/cjs/bll/formatters/factory/index.js +115 -0
- package/dist/cjs/bll/formatters/index.js +24 -0
- package/dist/cjs/bll/formatters/numberFormatter.js +70 -0
- package/dist/cjs/bll/formatters/phoneFormatter.js +57 -0
- package/dist/cjs/bll/formatters/regexFormatter.js +52 -0
- package/dist/cjs/bll/formatters/ssnFormatter.js +50 -0
- package/dist/cjs/bll/formatters/textFormatter.js +43 -0
- package/dist/cjs/bll/formatters/zipFormatter.js +48 -0
- package/dist/cjs/bll/index.js +62 -0
- package/dist/cjs/bll/ssf/index.js +48 -0
- package/dist/cjs/bll/ssf/loan.js +81 -0
- package/dist/cjs/bll/ssf/loconnect.js +70 -0
- package/dist/cjs/bll/ssf/ssfBase.js +97 -0
- package/dist/cjs/bll/ssf/types.js +16 -0
- package/dist/cjs/bll/types.js +16 -0
- package/dist/cjs/bll/validators/dateValidator.js +60 -0
- package/dist/cjs/bll/validators/emailValidator.js +47 -0
- package/dist/cjs/bll/validators/factory/index.js +81 -0
- package/dist/cjs/bll/validators/index.js +24 -0
- package/dist/cjs/bll/validators/maxCharValidator.js +49 -0
- package/dist/cjs/bll/validators/requiredValidator.js +44 -0
- package/dist/cjs/bll/validators/zipValidator.js +53 -0
- package/dist/cjs/core/index.js +52 -0
- package/dist/cjs/demo/config.js +391 -0
- package/dist/cjs/demo/index.js +31 -0
- package/dist/cjs/package.json +7 -0
- package/dist/cjs/renderer/FieldRenderer.js +45 -0
- package/dist/cjs/renderer/base/hooks/fieldDescription.js +39 -0
- package/dist/cjs/renderer/base/hooks/fieldDisabled.js +53 -0
- package/dist/cjs/renderer/base/hooks/fieldGoTo.js +50 -0
- package/dist/cjs/renderer/base/hooks/fieldLocked.js +42 -0
- package/dist/cjs/renderer/base/hooks/fieldMeta.js +150 -0
- package/dist/cjs/renderer/base/hooks/fieldSubscribers.js +66 -0
- package/dist/cjs/renderer/base/hooks/fieldValidation.js +45 -0
- package/dist/cjs/renderer/base/hooks/fieldValue.js +215 -0
- package/dist/cjs/renderer/base/hooks/hookBase.js +29 -0
- package/dist/cjs/renderer/base/hooks/index.js +139 -0
- package/dist/cjs/renderer/base/renderer.js +198 -0
- package/dist/cjs/renderer/base/rendererValidator.js +97 -0
- package/dist/cjs/renderer/factory/index.js +58 -0
- package/dist/cjs/renderer/field-renderers/AddonRenderer.js +75 -0
- package/dist/cjs/renderer/field-renderers/CheckboxRenderer.js +123 -0
- package/dist/cjs/renderer/field-renderers/DateRenderer.js +206 -0
- package/dist/cjs/renderer/field-renderers/DropdownRenderer/hook.js +99 -0
- package/dist/cjs/renderer/field-renderers/DropdownRenderer/index.js +216 -0
- package/dist/cjs/renderer/field-renderers/LargeTextRenderer.js +209 -0
- package/dist/cjs/renderer/field-renderers/NumberRenderer.js +216 -0
- package/dist/cjs/renderer/field-renderers/RadioGroupRenderer.js +128 -0
- package/dist/cjs/renderer/field-renderers/RadioRenderer.js +121 -0
- package/dist/cjs/renderer/field-renderers/TextRenderer.js +223 -0
- package/dist/cjs/renderer/field-renderers/ToggleRenderer.js +121 -0
- package/dist/cjs/renderer/field-renderers/ZipCodeRenderer/helper.js +132 -0
- package/dist/cjs/renderer/field-renderers/ZipCodeRenderer/hook.js +128 -0
- package/dist/cjs/renderer/field-renderers/ZipCodeRenderer/index.js +273 -0
- package/dist/cjs/renderer/index.js +24 -0
- package/dist/cjs/renderer/styles.js +51 -0
- package/dist/cjs/renderer/types.js +16 -0
- package/dist/cjs/tests/base/flowBase.js +125 -0
- package/dist/cjs/tests/base/index.js +52 -0
- package/dist/cjs/tests/flows/checkboxRendererFlows.js +85 -0
- package/dist/cjs/tests/flows/dateRendererFlows.js +870 -0
- package/dist/cjs/tests/flows/dropdownRendererFlows.js +591 -0
- package/dist/cjs/tests/flows/largeTextRendererFlows.js +99 -0
- package/dist/cjs/tests/flows/numberRendererFlows.js +175 -0
- package/dist/cjs/tests/flows/radioRendererFlows.js +115 -0
- package/dist/cjs/tests/flows/textRendererFlows.js +349 -0
- package/dist/cjs/tests/flows/toggleRendererFlows.js +106 -0
- package/dist/cjs/tests/flows/zipCodeRendererFlows.js +1163 -0
- package/dist/cjs/utils/dateHelper.js +65 -0
- package/dist/esm/ARCHITECTURE.md +434 -0
- package/dist/esm/OVERVIEW.md +229 -0
- package/dist/esm/bll/constants.js +66 -0
- package/dist/esm/bll/formatters/booleanFormatter.js +33 -0
- package/dist/esm/bll/formatters/dateFormatter.js +48 -0
- package/dist/esm/bll/formatters/dropdownFormatter.js +14 -0
- package/dist/esm/bll/formatters/factory/index.js +97 -0
- package/dist/esm/bll/formatters/index.js +4 -0
- package/dist/esm/bll/formatters/numberFormatter.js +54 -0
- package/dist/esm/bll/formatters/phoneFormatter.js +41 -0
- package/dist/esm/bll/formatters/regexFormatter.js +34 -0
- package/dist/esm/bll/formatters/ssnFormatter.js +32 -0
- package/dist/esm/bll/formatters/textFormatter.js +25 -0
- package/dist/esm/bll/formatters/zipFormatter.js +30 -0
- package/dist/esm/bll/index.js +44 -0
- package/dist/esm/bll/ssf/index.js +30 -0
- package/dist/esm/bll/ssf/loan.js +63 -0
- package/dist/esm/bll/ssf/loconnect.js +52 -0
- package/dist/esm/bll/ssf/ssfBase.js +67 -0
- package/dist/esm/bll/ssf/types.js +0 -0
- package/dist/esm/bll/types.js +0 -0
- package/dist/esm/bll/validators/dateValidator.js +30 -0
- package/dist/esm/bll/validators/emailValidator.js +29 -0
- package/dist/esm/bll/validators/factory/index.js +63 -0
- package/dist/esm/bll/validators/index.js +4 -0
- package/dist/esm/bll/validators/maxCharValidator.js +31 -0
- package/dist/esm/bll/validators/requiredValidator.js +26 -0
- package/dist/esm/bll/validators/zipValidator.js +35 -0
- package/dist/esm/core/index.js +34 -0
- package/dist/esm/demo/config.js +371 -0
- package/dist/esm/demo/index.js +11 -0
- package/dist/esm/package.json +7 -0
- package/dist/esm/renderer/FieldRenderer.js +15 -0
- package/dist/esm/renderer/base/hooks/fieldDescription.js +19 -0
- package/dist/esm/renderer/base/hooks/fieldDisabled.js +33 -0
- package/dist/esm/renderer/base/hooks/fieldGoTo.js +30 -0
- package/dist/esm/renderer/base/hooks/fieldLocked.js +22 -0
- package/dist/esm/renderer/base/hooks/fieldMeta.js +132 -0
- package/dist/esm/renderer/base/hooks/fieldSubscribers.js +36 -0
- package/dist/esm/renderer/base/hooks/fieldValidation.js +25 -0
- package/dist/esm/renderer/base/hooks/fieldValue.js +195 -0
- package/dist/esm/renderer/base/hooks/hookBase.js +9 -0
- package/dist/esm/renderer/base/hooks/index.js +121 -0
- package/dist/esm/renderer/base/renderer.js +178 -0
- package/dist/esm/renderer/base/rendererValidator.js +77 -0
- package/dist/esm/renderer/factory/index.js +38 -0
- package/dist/esm/renderer/field-renderers/AddonRenderer.js +55 -0
- package/dist/esm/renderer/field-renderers/CheckboxRenderer.js +93 -0
- package/dist/esm/renderer/field-renderers/DateRenderer.js +176 -0
- package/dist/esm/renderer/field-renderers/DropdownRenderer/hook.js +79 -0
- package/dist/esm/renderer/field-renderers/DropdownRenderer/index.js +186 -0
- package/dist/esm/renderer/field-renderers/LargeTextRenderer.js +179 -0
- package/dist/esm/renderer/field-renderers/NumberRenderer.js +188 -0
- package/dist/esm/renderer/field-renderers/RadioGroupRenderer.js +108 -0
- package/dist/esm/renderer/field-renderers/RadioRenderer.js +91 -0
- package/dist/esm/renderer/field-renderers/TextRenderer.js +197 -0
- package/dist/esm/renderer/field-renderers/ToggleRenderer.js +91 -0
- package/dist/esm/renderer/field-renderers/ZipCodeRenderer/helper.js +112 -0
- package/dist/esm/renderer/field-renderers/ZipCodeRenderer/hook.js +108 -0
- package/dist/esm/renderer/field-renderers/ZipCodeRenderer/index.js +247 -0
- package/dist/esm/renderer/index.js +4 -0
- package/dist/esm/renderer/styles.js +21 -0
- package/dist/esm/renderer/types.js +0 -0
- package/dist/esm/tests/base/flowBase.js +105 -0
- package/dist/esm/tests/base/index.js +22 -0
- package/dist/esm/tests/flows/checkboxRendererFlows.js +65 -0
- package/dist/esm/tests/flows/dateRendererFlows.js +850 -0
- package/dist/esm/tests/flows/dropdownRendererFlows.js +571 -0
- package/dist/esm/tests/flows/largeTextRendererFlows.js +79 -0
- package/dist/esm/tests/flows/numberRendererFlows.js +155 -0
- package/dist/esm/tests/flows/radioRendererFlows.js +95 -0
- package/dist/esm/tests/flows/textRendererFlows.js +329 -0
- package/dist/esm/tests/flows/toggleRendererFlows.js +86 -0
- package/dist/esm/tests/flows/zipCodeRendererFlows.js +1143 -0
- package/dist/esm/utils/dateHelper.js +35 -0
- package/dist/types/lib/bll/constants.d.ts +9 -0
- package/dist/types/lib/bll/formatters/booleanFormatter.d.ts +5 -0
- package/dist/types/lib/bll/formatters/dateFormatter.d.ts +28 -0
- package/dist/types/lib/bll/formatters/dropdownFormatter.d.ts +6 -0
- package/dist/types/lib/bll/formatters/factory/index.d.ts +71 -0
- package/dist/types/lib/bll/formatters/index.d.ts +2 -0
- package/dist/types/lib/bll/formatters/numberFormatter.d.ts +6 -0
- package/dist/types/lib/bll/formatters/phoneFormatter.d.ts +7 -0
- package/dist/types/lib/bll/formatters/regexFormatter.d.ts +5 -0
- package/dist/types/lib/bll/formatters/ssnFormatter.d.ts +5 -0
- package/dist/types/lib/bll/formatters/textFormatter.d.ts +6 -0
- package/dist/types/lib/bll/formatters/zipFormatter.d.ts +5 -0
- package/dist/types/lib/bll/index.d.ts +20 -0
- package/dist/types/lib/bll/ssf/index.d.ts +25 -0
- package/dist/types/lib/bll/ssf/loan.d.ts +16 -0
- package/dist/types/lib/bll/ssf/loconnect.d.ts +15 -0
- package/dist/types/lib/bll/ssf/ssfBase.d.ts +23 -0
- package/dist/types/lib/bll/ssf/types.d.ts +99 -0
- package/dist/types/lib/bll/types.d.ts +47 -0
- package/dist/types/lib/bll/validators/dateValidator.d.ts +16 -0
- package/dist/types/lib/bll/validators/emailValidator.d.ts +4 -0
- package/dist/types/lib/bll/validators/factory/index.d.ts +15 -0
- package/dist/types/lib/bll/validators/index.d.ts +2 -0
- package/dist/types/lib/bll/validators/maxCharValidator.d.ts +4 -0
- package/dist/types/lib/bll/validators/requiredValidator.d.ts +4 -0
- package/dist/types/lib/bll/validators/zipValidator.d.ts +5 -0
- package/dist/types/lib/core/index.d.ts +29 -0
- package/dist/types/lib/demo/config.d.ts +11 -0
- package/dist/types/lib/demo/index.d.ts +1 -0
- package/dist/types/lib/renderer/FieldRenderer.d.ts +5 -0
- package/dist/types/lib/renderer/base/hooks/fieldDescription.d.ts +5 -0
- package/dist/types/lib/renderer/base/hooks/fieldDisabled.d.ts +10 -0
- package/dist/types/lib/renderer/base/hooks/fieldGoTo.d.ts +4 -0
- package/dist/types/lib/renderer/base/hooks/fieldLocked.d.ts +4 -0
- package/dist/types/lib/renderer/base/hooks/fieldMeta.d.ts +10 -0
- package/dist/types/lib/renderer/base/hooks/fieldSubscribers.d.ts +6 -0
- package/dist/types/lib/renderer/base/hooks/fieldValidation.d.ts +9 -0
- package/dist/types/lib/renderer/base/hooks/fieldValue.d.ts +31 -0
- package/dist/types/lib/renderer/base/hooks/hookBase.d.ts +9 -0
- package/dist/types/lib/renderer/base/hooks/index.d.ts +19 -0
- package/dist/types/lib/renderer/base/renderer.d.ts +43 -0
- package/dist/types/lib/renderer/base/rendererValidator.d.ts +15 -0
- package/dist/types/lib/renderer/factory/index.d.ts +5 -0
- package/dist/types/lib/renderer/field-renderers/AddonRenderer.d.ts +12 -0
- package/dist/types/lib/renderer/field-renderers/CheckboxRenderer.d.ts +7 -0
- package/dist/types/lib/renderer/field-renderers/DateRenderer.d.ts +13 -0
- package/dist/types/lib/renderer/field-renderers/DropdownRenderer/hook.d.ts +23 -0
- package/dist/types/lib/renderer/field-renderers/DropdownRenderer/index.d.ts +12 -0
- package/dist/types/lib/renderer/field-renderers/LargeTextRenderer.d.ts +17 -0
- package/dist/types/lib/renderer/field-renderers/NumberRenderer.d.ts +12 -0
- package/dist/types/lib/renderer/field-renderers/RadioGroupRenderer.d.ts +8 -0
- package/dist/types/lib/renderer/field-renderers/RadioRenderer.d.ts +8 -0
- package/dist/types/lib/renderer/field-renderers/TextRenderer.d.ts +8 -0
- package/dist/types/lib/renderer/field-renderers/ToggleRenderer.d.ts +24 -0
- package/dist/types/lib/renderer/field-renderers/ZipCodeRenderer/helper.d.ts +48 -0
- package/dist/types/lib/renderer/field-renderers/ZipCodeRenderer/hook.d.ts +17 -0
- package/dist/types/lib/renderer/field-renderers/ZipCodeRenderer/index.d.ts +9 -0
- package/dist/types/lib/renderer/index.d.ts +2 -0
- package/dist/types/lib/renderer/styles.d.ts +7 -0
- package/dist/types/lib/renderer/types.d.ts +325 -0
- package/dist/types/lib/tests/base/flowBase.d.ts +13 -0
- package/dist/types/lib/tests/base/index.d.ts +6 -0
- package/dist/types/lib/tests/flows/checkboxRendererFlows.d.ts +9 -0
- package/dist/types/lib/tests/flows/dateRendererFlows.d.ts +120 -0
- package/dist/types/lib/tests/flows/dropdownRendererFlows.d.ts +92 -0
- package/dist/types/lib/tests/flows/largeTextRendererFlows.d.ts +9 -0
- package/dist/types/lib/tests/flows/numberRendererFlows.d.ts +11 -0
- package/dist/types/lib/tests/flows/radioRendererFlows.d.ts +10 -0
- package/dist/types/lib/tests/flows/textRendererFlows.d.ts +16 -0
- package/dist/types/lib/tests/flows/toggleRendererFlows.d.ts +10 -0
- package/dist/types/lib/tests/flows/zipCodeRendererFlows.d.ts +169 -0
- package/dist/types/lib/tests/loan-field-renderer-flows.test.d.ts +1 -0
- package/dist/types/lib/utils/dateHelper.d.ts +8 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +103 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Loan Field Renderers — Overview
|
|
2
|
+
|
|
3
|
+
## What Is It?
|
|
4
|
+
|
|
5
|
+
A **metadata-driven smart control system** that renders loan form fields. Instead of each page manually handling data fetching, formatting, validation, locking, and persistence — a single component does it all.
|
|
6
|
+
|
|
7
|
+
**Before (without smart controls):**
|
|
8
|
+
Each page manually wires up SSF calls, formatting logic, validation, lock handling, accessibility, and event subscriptions for every field.
|
|
9
|
+
|
|
10
|
+
**After (with smart controls):**
|
|
11
|
+
|
|
12
|
+
```jsx
|
|
13
|
+
<FieldRenderer fieldId="FR0104" rendererType="number" />
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
One line. The system handles everything else automatically.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## What Does It Do Automatically?
|
|
21
|
+
|
|
22
|
+
| Capability | Description |
|
|
23
|
+
| ----------------- | -------------------------------------------------------------------------------- |
|
|
24
|
+
| **Data Fetch** | Fetches field metadata + current value from SSF on mount |
|
|
25
|
+
| **Formatting** | Applies the correct display format (currency, phone, SSN, date, zip) |
|
|
26
|
+
| **Input Masking** | Enforces input patterns (phone mask, SSN mask, number mask) |
|
|
27
|
+
| **Validation** | Runs configurable validation rules on blur (required, email, date, zip, maxChar) |
|
|
28
|
+
| **Persistence** | Parses display value back to raw data and saves to loan on blur |
|
|
29
|
+
| **Lock/Unlock** | Shows lock button, manages lock state, disables field when locked |
|
|
30
|
+
| **Read-Only** | Respects both field-level and loan-level read-only states |
|
|
31
|
+
| **Live Sync** | Subscribes to loan events — auto-refreshes when data changes externally |
|
|
32
|
+
| **Accessibility** | Builds ARIA attributes from field description metadata |
|
|
33
|
+
| **Go-To-Field** | Highlights the field when navigated to via Go-To-Field |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Supported Renderer Types
|
|
38
|
+
|
|
39
|
+
| Type | UI Component | Use Case |
|
|
40
|
+
| ------------ | ------------------- | --------------------------------------------------------- |
|
|
41
|
+
| `text` | Text input | Names, addresses, general text (supports Phone/SSN masks) |
|
|
42
|
+
| `number` | Masked number input | Amounts, rates, percentages |
|
|
43
|
+
| `date` | Date picker | Dates with configurable format |
|
|
44
|
+
| `dropdown` | Combobox | Picklists, state selection |
|
|
45
|
+
| `zipcode` | Autocomplete input | Zip codes with geo-lookup |
|
|
46
|
+
| `checkbox` | Checkbox | Yes/No boolean fields |
|
|
47
|
+
| `toggle` | Toggle switch | On/Off boolean fields |
|
|
48
|
+
| `radio` | Single radio button | One option in a group |
|
|
49
|
+
| `radiogroup` | Radio button group | Multiple exclusive options |
|
|
50
|
+
| `largetext` | Textarea | Comments, large text with char counter |
|
|
51
|
+
| `button` | Button | Action triggers |
|
|
52
|
+
| `email` | Text input | Email with built-in email validation |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## How It Works — 3 Phases
|
|
57
|
+
|
|
58
|
+
### Phase 1: Mount — "Set Up the Field"
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
Consumer passes fieldId + rendererType
|
|
62
|
+
│
|
|
63
|
+
▼
|
|
64
|
+
RendererFactory picks the right renderer
|
|
65
|
+
│
|
|
66
|
+
▼
|
|
67
|
+
Parallel SSF calls (all at once):
|
|
68
|
+
┌─────────────────────────────────┐
|
|
69
|
+
│ • Field metadata (format, │
|
|
70
|
+
│ options, readonly, lock, │
|
|
71
|
+
│ maxLength, description) │
|
|
72
|
+
│ • Current field value │
|
|
73
|
+
│ • Lock status │
|
|
74
|
+
│ • Loan readonly status │
|
|
75
|
+
│ • Go-To-Field status │
|
|
76
|
+
└─────────────────────────────────┘
|
|
77
|
+
│
|
|
78
|
+
▼
|
|
79
|
+
Build ViewModel → Render UI
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Phase 2: User Interaction — "Handle Input"
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
User types → onChange
|
|
86
|
+
┌────────────────────────────┐
|
|
87
|
+
│ Update local display value │
|
|
88
|
+
│ Fire optional callback │
|
|
89
|
+
└────────────────────────────┘
|
|
90
|
+
|
|
91
|
+
User leaves field → onBlur
|
|
92
|
+
┌────────────────────────────┐
|
|
93
|
+
│ 1. Format the value │
|
|
94
|
+
│ 2. Validate │
|
|
95
|
+
│ └─ Invalid? Show error, │
|
|
96
|
+
│ stop here │
|
|
97
|
+
│ 3. Parse to raw value │
|
|
98
|
+
│ 4. Save to loan via SSF │
|
|
99
|
+
│ 5. Fire optional callback │
|
|
100
|
+
└────────────────────────────┘
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Phase 3: External Changes — "Stay in Sync"
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
Business rule or another field changes loan data
|
|
107
|
+
│
|
|
108
|
+
▼
|
|
109
|
+
SSF fires "change" or "loanUpdated" event
|
|
110
|
+
│
|
|
111
|
+
▼
|
|
112
|
+
Field re-fetches its value from SSF
|
|
113
|
+
│
|
|
114
|
+
▼
|
|
115
|
+
Re-formats and updates display automatically
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Architecture — 3 Layers
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
┌───────────────────────────────────────────┐
|
|
124
|
+
│ RENDERER LAYER │
|
|
125
|
+
│ UI components, event handling, ViewModel │
|
|
126
|
+
│ 12 specific renderers + shared base class │
|
|
127
|
+
├───────────────────────────────────────────┤
|
|
128
|
+
│ BUSINESS LOGIC LAYER │
|
|
129
|
+
│ Formatters (10 types) — format ↔ parse │
|
|
130
|
+
│ Validators (5 types) — validate on blur │
|
|
131
|
+
│ SSF Service — loan data access & events │
|
|
132
|
+
├───────────────────────────────────────────┤
|
|
133
|
+
│ DATA ACCESS LAYER (SSF) │
|
|
134
|
+
│ Field metadata, values, lock status │
|
|
135
|
+
│ Loan readonly, Go-To-Field, state list │
|
|
136
|
+
│ Event subscriptions (change, loanUpdated) │
|
|
137
|
+
└───────────────────────────────────────────┘
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Key design decisions:**
|
|
141
|
+
|
|
142
|
+
- **Factory Pattern** — Renderers, formatters, and validators are created dynamically by type
|
|
143
|
+
- **Mixin Composition** — Hooks and SSF combine focused classes instead of deep inheritance
|
|
144
|
+
- **ViewModel Pattern** — All reactive state lives in one object, decoupled from UI
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## How Metadata Drives Everything
|
|
149
|
+
|
|
150
|
+
When a field is loaded, its metadata from SSF determines behavior automatically:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
fieldFormat: "D2" → NumberFormatter with 2 decimal places
|
|
154
|
+
fieldFormat: "SS" → SSN mask (***-**-1234)
|
|
155
|
+
fieldFormat: "ST" → Auto-fetch state dropdown list
|
|
156
|
+
fieldFormat: "P" → Phone mask ((123) 456-7890)
|
|
157
|
+
|
|
158
|
+
isLockField: true → Show lock button, disable when locked
|
|
159
|
+
isReadOnly: true → Disable the field
|
|
160
|
+
isReadonlyLoan → Loan-level check — if loan is disabled, all fields disable
|
|
161
|
+
maxLength: 50 → Enforce character limit
|
|
162
|
+
description: "..." → Set ARIA label/description
|
|
163
|
+
fieldOptions: [...] → Populate dropdown choices
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
No conditional logic needed in consuming pages — the metadata configures the control.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Consumer API — Quick Reference
|
|
171
|
+
|
|
172
|
+
### Basic Usage
|
|
173
|
+
|
|
174
|
+
```jsx
|
|
175
|
+
// Simple text field
|
|
176
|
+
<FieldRenderer fieldId="FR0001" rendererType="text" label="First Name" />
|
|
177
|
+
|
|
178
|
+
// Number with label
|
|
179
|
+
<FieldRenderer fieldId="FR0104" rendererType="number" label="Loan Amount" />
|
|
180
|
+
|
|
181
|
+
// Dropdown
|
|
182
|
+
<FieldRenderer fieldId="FR0200" rendererType="dropdown" label="State" />
|
|
183
|
+
|
|
184
|
+
// Date
|
|
185
|
+
<FieldRenderer fieldId="FR0300" rendererType="date" label="Closing Date" />
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### With Optional Props
|
|
189
|
+
|
|
190
|
+
```jsx
|
|
191
|
+
<FieldRenderer
|
|
192
|
+
fieldId="FR0104"
|
|
193
|
+
rendererType="number"
|
|
194
|
+
label="Loan Amount"
|
|
195
|
+
onBlur={(fieldId, value) => console.log('saved', value)}
|
|
196
|
+
onChange={(fieldId, value) => console.log('changed', value)}
|
|
197
|
+
validationRules={[{ type: 'required', message: 'Amount is required' }]}
|
|
198
|
+
autoFieldSet={true} // auto-persist on blur (default: true)
|
|
199
|
+
isDisable={false} // consumer-controlled disable
|
|
200
|
+
forceRefresh={refreshFlag} // trigger re-fetch from SSF
|
|
201
|
+
/>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Common Props
|
|
205
|
+
|
|
206
|
+
| Prop | Type | Purpose |
|
|
207
|
+
| ----------------- | ----------- | ------------------------------------------------- |
|
|
208
|
+
| `fieldId` | `string` | **(Required)** SSF field identifier |
|
|
209
|
+
| `rendererType` | `string` | **(Required)** Which UI control to render |
|
|
210
|
+
| `label` | `string` | Field label text |
|
|
211
|
+
| `onBlur` | `function` | Callback after value is validated and parsed |
|
|
212
|
+
| `onChange` | `function` | Callback on every value change |
|
|
213
|
+
| `validationRules` | `array` | Custom validation rules |
|
|
214
|
+
| `autoFieldSet` | `boolean` | Auto-save to SSF on blur (default: `true`) |
|
|
215
|
+
| `isDisable` | `boolean` | Consumer-controlled disable override |
|
|
216
|
+
| `forceRefresh` | `boolean` | Toggle to force re-fetch from SSF |
|
|
217
|
+
| `extra` | `object` | Pass-through props to the underlying DS component |
|
|
218
|
+
| `rightAddon` | `ReactNode` | Custom content to the right of the input |
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Adding a New Renderer (Extensibility)
|
|
223
|
+
|
|
224
|
+
1. Create `NewRenderer.tsx` extending `Renderer<T>`
|
|
225
|
+
2. Define props type in `renderer/types.ts`
|
|
226
|
+
3. Register in `renderer/factory/index.ts`
|
|
227
|
+
4. Add controlled props to `bll/constants.ts` (if applicable)
|
|
228
|
+
|
|
229
|
+
The factory pattern means zero changes to existing renderers or the `FieldRenderer` entry point.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const ACRONYM_FORMAT_MAP = {
|
|
2
|
+
SS: "SSN",
|
|
3
|
+
T: "DATE",
|
|
4
|
+
TD: "DATETIME",
|
|
5
|
+
I: "INTEGER",
|
|
6
|
+
S: "STRING",
|
|
7
|
+
Y: "YN",
|
|
8
|
+
P: "PHONE",
|
|
9
|
+
Z: "ZIPCODE",
|
|
10
|
+
ST: "STATE",
|
|
11
|
+
D2: "DECIMAL_2",
|
|
12
|
+
D3: "DECIMAL_3",
|
|
13
|
+
D4: "DECIMAL_4",
|
|
14
|
+
D5: "DECIMAL_5",
|
|
15
|
+
D6: "DECIMAL_6",
|
|
16
|
+
RS: "RA_STRING",
|
|
17
|
+
RI: "RA_INTEGER",
|
|
18
|
+
RD2: "RA_DECIMAL_2",
|
|
19
|
+
RD3: "RA_DECIMAL_3",
|
|
20
|
+
RD4: "RA_DECIMAL_4",
|
|
21
|
+
RD5: "RA_DECIMAL_5",
|
|
22
|
+
RD6: "RA_DECIMAL_6"
|
|
23
|
+
};
|
|
24
|
+
const FORMATTER_ACRONYMS = Object.keys(ACRONYM_FORMAT_MAP);
|
|
25
|
+
const FORMATTER_TYPE_MAP = {
|
|
26
|
+
ssn: "SSN",
|
|
27
|
+
date: "DATE",
|
|
28
|
+
datetime: "DATETIME",
|
|
29
|
+
integer: "INTEGER",
|
|
30
|
+
text: "STRING",
|
|
31
|
+
boolean: "YN",
|
|
32
|
+
phone: "PHONE",
|
|
33
|
+
zip: "ZIPCODE",
|
|
34
|
+
state: "STATE"
|
|
35
|
+
};
|
|
36
|
+
const DECIMAL_POINTS_MAP = {
|
|
37
|
+
D2: 2,
|
|
38
|
+
D3: 3,
|
|
39
|
+
D4: 4,
|
|
40
|
+
D5: 5,
|
|
41
|
+
D6: 6,
|
|
42
|
+
I: 0,
|
|
43
|
+
RI: 0,
|
|
44
|
+
RD2: 2,
|
|
45
|
+
RD3: 3,
|
|
46
|
+
RD4: 4,
|
|
47
|
+
RD5: 5,
|
|
48
|
+
RD6: 6
|
|
49
|
+
};
|
|
50
|
+
const RENDERER_CONTROLLED_PROPS = {
|
|
51
|
+
text: ["onChange", "onBlur", "value"],
|
|
52
|
+
number: ["onChange", "onBlur", "value"],
|
|
53
|
+
checkbox: ["value", "checked", "onChange"],
|
|
54
|
+
toggle: ["checked", "onChange"],
|
|
55
|
+
radio: ["onChange", "value", "checked"],
|
|
56
|
+
dropdown: ["selectedValues", "allOptions", "onChange", "onBlur", "onCreate"],
|
|
57
|
+
date: ["onDateChange", "onBlur", "date", "type"],
|
|
58
|
+
zipcode: ["onChange", "onBlur", "value", "onValueChange"]
|
|
59
|
+
};
|
|
60
|
+
export {
|
|
61
|
+
ACRONYM_FORMAT_MAP,
|
|
62
|
+
DECIMAL_POINTS_MAP,
|
|
63
|
+
FORMATTER_ACRONYMS,
|
|
64
|
+
FORMATTER_TYPE_MAP,
|
|
65
|
+
RENDERER_CONTROLLED_PROPS
|
|
66
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators2, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators2.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators2[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import { decorators } from "@elliemae/pui-app-sdk";
|
|
12
|
+
let BooleanFormatter = class {
|
|
13
|
+
format(input) {
|
|
14
|
+
if (input === null || input === void 0) return false;
|
|
15
|
+
if (typeof input === "boolean") return input;
|
|
16
|
+
if (input === "") return false;
|
|
17
|
+
if (typeof input === "string") {
|
|
18
|
+
const lower = input.toLowerCase();
|
|
19
|
+
return lower === "true" || lower === "yes" || lower === "y";
|
|
20
|
+
}
|
|
21
|
+
return Boolean(input);
|
|
22
|
+
}
|
|
23
|
+
parse(input) {
|
|
24
|
+
if (input === null || input === void 0) return void 0;
|
|
25
|
+
return input;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
BooleanFormatter = __decorateClass([
|
|
29
|
+
decorators.class.Singleton
|
|
30
|
+
], BooleanFormatter);
|
|
31
|
+
export {
|
|
32
|
+
BooleanFormatter
|
|
33
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import moment from "moment";
|
|
2
|
+
class DateFormatter {
|
|
3
|
+
/**
|
|
4
|
+
* Format date from storage format to display format
|
|
5
|
+
* @param {unknown} input - Date value from loan (typically YYYY-MM-DD or ISO format)
|
|
6
|
+
* @param {object} [options] - Formatting options
|
|
7
|
+
* @param {string} [options.dateFormat] - Target display format (default: MM/DD/YYYY)
|
|
8
|
+
* @returns {string} Formatted date string for UI display
|
|
9
|
+
*/
|
|
10
|
+
format(input, options) {
|
|
11
|
+
if (!input || input === "") return "";
|
|
12
|
+
const dateStr = String(input).trim();
|
|
13
|
+
if (!dateStr) return "";
|
|
14
|
+
if (dateStr.includes("_")) return dateStr;
|
|
15
|
+
const displayFormat = options?.dateFormat || "MM/DD/YYYY";
|
|
16
|
+
if (moment(dateStr, displayFormat, true).isValid()) {
|
|
17
|
+
return dateStr;
|
|
18
|
+
}
|
|
19
|
+
const parsed = moment(dateStr);
|
|
20
|
+
if (parsed.isValid()) {
|
|
21
|
+
return parsed.format(displayFormat);
|
|
22
|
+
}
|
|
23
|
+
return "";
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse date from display format to storage format
|
|
27
|
+
* @param {string} input - Date string from UI (in display format)
|
|
28
|
+
* @param {object} [options] - Parsing options
|
|
29
|
+
* @param {string} [options.dateFormat] - Source display format (default: MM/DD/YYYY)
|
|
30
|
+
* @returns {unknown} Date in storage format (YYYY-MM-DD)
|
|
31
|
+
*/
|
|
32
|
+
parse(input, options) {
|
|
33
|
+
if (!input || input === "") return "";
|
|
34
|
+
const displayFormat = options?.dateFormat || "MM/DD/YYYY";
|
|
35
|
+
let parsed = moment(input, displayFormat, true);
|
|
36
|
+
if (parsed.isValid()) {
|
|
37
|
+
return parsed.format("YYYY-MM-DD");
|
|
38
|
+
}
|
|
39
|
+
parsed = moment(input);
|
|
40
|
+
if (parsed.isValid()) {
|
|
41
|
+
return parsed.format("YYYY-MM-DD");
|
|
42
|
+
}
|
|
43
|
+
return input;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
DateFormatter
|
|
48
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators2, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators2.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators2[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import { decorators } from "@elliemae/pui-app-sdk";
|
|
12
|
+
import { PhoneFormatter } from "../phoneFormatter";
|
|
13
|
+
import { RegexFormatter } from "../regexFormatter";
|
|
14
|
+
import { SSNFormatter } from "../ssnFormatter";
|
|
15
|
+
import { ZipFormatter } from "../zipFormatter";
|
|
16
|
+
import { BooleanFormatter } from "../booleanFormatter";
|
|
17
|
+
import { TextFormatter } from "../textFormatter";
|
|
18
|
+
import { NumberFormatter } from "../numberFormatter";
|
|
19
|
+
import { DateFormatter } from "../dateFormatter";
|
|
20
|
+
import { DropdownFormatter } from "../dropdownFormatter";
|
|
21
|
+
let FormatterFactory = class {
|
|
22
|
+
/**
|
|
23
|
+
* Cache for formatter instances by acronym
|
|
24
|
+
* Since formatters are stateless, we can safely reuse instances
|
|
25
|
+
*/
|
|
26
|
+
formatterCache = /* @__PURE__ */ new Map();
|
|
27
|
+
/**
|
|
28
|
+
* Helper to check if acronym is for number formatter
|
|
29
|
+
* @param {string} acronym - Acronym to check
|
|
30
|
+
* @returns {boolean} True if number formatter
|
|
31
|
+
*/
|
|
32
|
+
isNumberAcronym(acronym) {
|
|
33
|
+
if (acronym === "DT" || acronym === "DD") return false;
|
|
34
|
+
return acronym === "I" || acronym === "RI" || acronym.startsWith("D") || acronym.startsWith("RD");
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Helper to check if acronym is for text formatter
|
|
38
|
+
* @param {string} acronym - Acronym to check
|
|
39
|
+
* @returns {boolean} True if text formatter
|
|
40
|
+
*/
|
|
41
|
+
isTextAcronym(acronym) {
|
|
42
|
+
return acronym === "S" || acronym === "ST";
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create specific formatter based on acronym
|
|
46
|
+
* @param {string} upperAcronym - Uppercase acronym
|
|
47
|
+
* @returns Specific formatter instance
|
|
48
|
+
*/
|
|
49
|
+
createSpecificFormatter(upperAcronym) {
|
|
50
|
+
switch (upperAcronym) {
|
|
51
|
+
case "SS":
|
|
52
|
+
return new SSNFormatter();
|
|
53
|
+
case "Y":
|
|
54
|
+
return new BooleanFormatter();
|
|
55
|
+
case "P":
|
|
56
|
+
return new PhoneFormatter();
|
|
57
|
+
case "Z":
|
|
58
|
+
return new ZipFormatter();
|
|
59
|
+
case "RS":
|
|
60
|
+
return new RegexFormatter();
|
|
61
|
+
case "DD":
|
|
62
|
+
return new DropdownFormatter();
|
|
63
|
+
case "DT":
|
|
64
|
+
case "TD":
|
|
65
|
+
case "T":
|
|
66
|
+
return new DateFormatter();
|
|
67
|
+
default:
|
|
68
|
+
throw new Error(
|
|
69
|
+
`Unknown acronym "${upperAcronym}". Cannot create formatter.`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
createFormatter(acronym) {
|
|
74
|
+
const upperAcronym = acronym.toUpperCase();
|
|
75
|
+
const cached = this.formatterCache.get(upperAcronym);
|
|
76
|
+
if (cached) {
|
|
77
|
+
return cached;
|
|
78
|
+
}
|
|
79
|
+
let formatter;
|
|
80
|
+
if (this.isNumberAcronym(upperAcronym)) {
|
|
81
|
+
formatter = new NumberFormatter();
|
|
82
|
+
} else if (this.isTextAcronym(upperAcronym)) {
|
|
83
|
+
formatter = new TextFormatter();
|
|
84
|
+
} else {
|
|
85
|
+
formatter = this.createSpecificFormatter(upperAcronym);
|
|
86
|
+
}
|
|
87
|
+
this.formatterCache.set(upperAcronym, formatter);
|
|
88
|
+
return formatter;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
FormatterFactory = __decorateClass([
|
|
92
|
+
decorators.class.Singleton
|
|
93
|
+
], FormatterFactory);
|
|
94
|
+
const factoryInstance = new FormatterFactory();
|
|
95
|
+
export {
|
|
96
|
+
factoryInstance
|
|
97
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators2, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators2.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators2[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import { decorators } from "@elliemae/pui-app-sdk";
|
|
12
|
+
import {
|
|
13
|
+
getNumberMaskedValue
|
|
14
|
+
} from "@elliemae/ds-form-helpers-mask-hooks";
|
|
15
|
+
let NumberFormatter = class {
|
|
16
|
+
getMaskOptions(fieldFormat, decimalPlaces) {
|
|
17
|
+
return {
|
|
18
|
+
decimalPlaces: decimalPlaces || 0,
|
|
19
|
+
allowNegative: true,
|
|
20
|
+
decimalRequired: !(fieldFormat === "I" || fieldFormat === "RI"),
|
|
21
|
+
includeThousandsSeparator: true,
|
|
22
|
+
prefix: "",
|
|
23
|
+
suffix: ""
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
format(input, { fieldFormat, numberOptions = {} }) {
|
|
27
|
+
if (input === null || input === void 0) return "";
|
|
28
|
+
if (input === "") return "";
|
|
29
|
+
if (!fieldFormat) return String(input);
|
|
30
|
+
const decimalPlaces = parseInt(fieldFormat.match(/\d+$/)?.[0] || "0", 10) || 0;
|
|
31
|
+
const maskOptions = this.getMaskOptions(fieldFormat, decimalPlaces);
|
|
32
|
+
const decimalValue = fieldFormat === "I" || fieldFormat === "RI" ? input : parseFloat(String(input).replace(/[^\d.-]/g, "")).toFixed(
|
|
33
|
+
maskOptions.decimalPlaces || 2
|
|
34
|
+
);
|
|
35
|
+
const maskedValue = getNumberMaskedValue(String(decimalValue), {
|
|
36
|
+
...maskOptions,
|
|
37
|
+
...numberOptions
|
|
38
|
+
});
|
|
39
|
+
return maskedValue;
|
|
40
|
+
}
|
|
41
|
+
parse(input, { fieldFormat, unmaskPattern = /[^\d.-]/g }) {
|
|
42
|
+
if (input === void 0 || input === null || input === "") return void 0;
|
|
43
|
+
if (!fieldFormat) return Number(input);
|
|
44
|
+
const decimalPlaces = parseInt(fieldFormat.match(/\d+$/)?.[0] || "0", 10) || 0;
|
|
45
|
+
const unmaskedValue = input.replace(unmaskPattern, "");
|
|
46
|
+
return decimalPlaces > 0 ? Number(parseFloat(unmaskedValue).toFixed(decimalPlaces)) : Number(unmaskedValue);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
NumberFormatter = __decorateClass([
|
|
50
|
+
decorators.class.Singleton
|
|
51
|
+
], NumberFormatter);
|
|
52
|
+
export {
|
|
53
|
+
NumberFormatter
|
|
54
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators2, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators2.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators2[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import { decorators } from "@elliemae/pui-app-sdk";
|
|
12
|
+
import {
|
|
13
|
+
getPhoneMaskedValue
|
|
14
|
+
} from "@elliemae/ds-form-helpers-mask-hooks";
|
|
15
|
+
let PhoneFormatter = class {
|
|
16
|
+
format(input, { isInternational }) {
|
|
17
|
+
if (input === null || input === void 0) {
|
|
18
|
+
return "";
|
|
19
|
+
}
|
|
20
|
+
const maskedValue = getPhoneMaskedValue(String(input), { isInternational });
|
|
21
|
+
return maskedValue;
|
|
22
|
+
}
|
|
23
|
+
parse(input, { unmaskPattern = /[()-\s]/g } = {}) {
|
|
24
|
+
if (!input) return void 0;
|
|
25
|
+
const unmaskedValue = input.replace(unmaskPattern, "");
|
|
26
|
+
return unmaskedValue;
|
|
27
|
+
}
|
|
28
|
+
static getPhoneFormatOptions({
|
|
29
|
+
isInternational = false
|
|
30
|
+
}) {
|
|
31
|
+
return {
|
|
32
|
+
isInternational
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
PhoneFormatter = __decorateClass([
|
|
37
|
+
decorators.class.Singleton
|
|
38
|
+
], PhoneFormatter);
|
|
39
|
+
export {
|
|
40
|
+
PhoneFormatter
|
|
41
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators2, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators2.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators2[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import { decorators } from "@elliemae/pui-app-sdk";
|
|
12
|
+
import { getRegExpMaskedValue } from "@elliemae/ds-form-helpers-mask-hooks";
|
|
13
|
+
let RegexFormatter = class {
|
|
14
|
+
format(input, patterns) {
|
|
15
|
+
if (!patterns || patterns.length === 0) {
|
|
16
|
+
return input;
|
|
17
|
+
}
|
|
18
|
+
const maskedValue = getRegExpMaskedValue(input, patterns);
|
|
19
|
+
return maskedValue;
|
|
20
|
+
}
|
|
21
|
+
parse(input, patterns) {
|
|
22
|
+
if (!patterns || patterns.length === 0) {
|
|
23
|
+
return input;
|
|
24
|
+
}
|
|
25
|
+
const unmaskedValue = getRegExpMaskedValue(input, patterns);
|
|
26
|
+
return unmaskedValue;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
RegexFormatter = __decorateClass([
|
|
30
|
+
decorators.class.Singleton
|
|
31
|
+
], RegexFormatter);
|
|
32
|
+
export {
|
|
33
|
+
RegexFormatter
|
|
34
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators2, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators2.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators2[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import { decorators } from "@elliemae/pui-app-sdk";
|
|
12
|
+
import { getSSNMaskedValue } from "@elliemae/ds-form-helpers-mask-hooks";
|
|
13
|
+
let SSNFormatter = class {
|
|
14
|
+
format(input) {
|
|
15
|
+
if (input === null || input === void 0 || input === "") {
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
const maskedValue = getSSNMaskedValue(String(input));
|
|
19
|
+
return maskedValue;
|
|
20
|
+
}
|
|
21
|
+
parse(input) {
|
|
22
|
+
if (!input) return void 0;
|
|
23
|
+
const unmaskedValue = input.replace(/-/g, "");
|
|
24
|
+
return unmaskedValue;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
SSNFormatter = __decorateClass([
|
|
28
|
+
decorators.class.Singleton
|
|
29
|
+
], SSNFormatter);
|
|
30
|
+
export {
|
|
31
|
+
SSNFormatter
|
|
32
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators2, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators2.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators2[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import { decorators } from "@elliemae/pui-app-sdk";
|
|
12
|
+
let TextFormatter = class {
|
|
13
|
+
format(input) {
|
|
14
|
+
return input ? String(input) : "";
|
|
15
|
+
}
|
|
16
|
+
parse(input) {
|
|
17
|
+
return input;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
TextFormatter = __decorateClass([
|
|
21
|
+
decorators.class.Singleton
|
|
22
|
+
], TextFormatter);
|
|
23
|
+
export {
|
|
24
|
+
TextFormatter
|
|
25
|
+
};
|