@finsweet/webflow-apps-utils 1.0.4 → 1.0.5

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 (35) hide show
  1. package/dist/providers/GlobalProvider.stories.d.ts +5 -0
  2. package/dist/providers/GlobalProvider.stories.js +419 -0
  3. package/dist/providers/GlobalProviderDemo.svelte +266 -0
  4. package/dist/providers/GlobalProviderDemo.svelte.d.ts +3 -0
  5. package/dist/providers/configuratorUtils.d.ts +11 -14
  6. package/dist/providers/configuratorUtils.js +68 -115
  7. package/dist/providers/index.d.ts +1 -1
  8. package/dist/providers/index.js +1 -1
  9. package/dist/router/Router.stories.js +519 -2
  10. package/dist/stores/forms/Form.stories.d.ts +5 -0
  11. package/dist/stores/forms/Form.stories.js +342 -0
  12. package/dist/stores/forms/FormDemo.svelte +545 -0
  13. package/dist/stores/forms/FormDemo.svelte.d.ts +18 -0
  14. package/dist/ui/components/button/Button.svelte +1 -1
  15. package/dist/ui/components/copy-text/CopyText.stories.js +1 -1
  16. package/dist/ui/components/copy-text/CopyText.svelte +17 -19
  17. package/dist/ui/components/layout/Layout.svelte +38 -5
  18. package/dist/ui/components/layout/Layout.svelte.d.ts +24 -1
  19. package/dist/ui/components/layout/examples/ExampleLayout.svelte +12 -12
  20. package/dist/ui/components/section/Section.svelte +4 -2
  21. package/dist/ui/index.css +6 -2
  22. package/dist/utils/diff-mapper/DiffMapper.stories.d.ts +5 -0
  23. package/dist/utils/diff-mapper/DiffMapper.stories.js +185 -0
  24. package/dist/utils/diff-mapper/DiffMapperDemo.svelte +351 -0
  25. package/dist/utils/diff-mapper/DiffMapperDemo.svelte.d.ts +18 -0
  26. package/dist/utils/diff-mapper/deepDiffMapper.d.ts +31 -0
  27. package/dist/utils/diff-mapper/deepDiffMapper.js +264 -0
  28. package/dist/utils/diff-mapper/index.d.ts +1 -0
  29. package/dist/utils/diff-mapper/index.js +1 -0
  30. package/dist/utils/index.d.ts +1 -0
  31. package/dist/utils/index.js +1 -0
  32. package/package.json +1 -1
  33. package/dist/providers/GlobalProvider.mdx +0 -322
  34. package/dist/router/Router.mdx +0 -958
  35. package/dist/stores/docs/Form.mdx +0 -542
@@ -0,0 +1,342 @@
1
+ import FormDemo from './FormDemo.svelte';
2
+ const meta = {
3
+ title: 'Utils/Form Validation System',
4
+ component: FormDemo,
5
+ parameters: {
6
+ layout: 'centered',
7
+ backgrounds: {
8
+ default: 'dark',
9
+ values: [
10
+ { name: 'dark', value: '#292929' },
11
+ { name: 'light', value: '#ffffff' }
12
+ ]
13
+ },
14
+ docs: {
15
+ description: {
16
+ component: `
17
+ # Form Validation System
18
+
19
+ A comprehensive form validation system built with Svelte stores and Zod for type-safe form handling in Webflow apps.
20
+
21
+ ## Overview
22
+
23
+ The form validation system provides:
24
+
25
+ - Type-safe form state management with Zod validation
26
+ - Unique instance name generation for Webflow components
27
+ - Real-time validation with error handling
28
+ - Form registry for managing multiple forms
29
+ - Class name sanitization for HTML compliance
30
+
31
+ ## Core Classes and Functions
32
+
33
+ ### FormValidator Class
34
+
35
+ The main class for creating and managing form validation state.
36
+
37
+ \`\`\`typescript
38
+ import { FormValidator } from './';
39
+
40
+ // Define your form data structure
41
+ interface MyFormData {
42
+ name: string;
43
+ instance: string;
44
+ class: string;
45
+ }
46
+
47
+ // Create a form validator
48
+ const formValidator = new FormValidator<MyFormData>(
49
+ 'my-form-id',
50
+ {
51
+ name: 'My Component',
52
+ instance: 'fs-component',
53
+ class: 'fs-component'
54
+ },
55
+ {
56
+ existingInstances: ['fs-existing-1', 'fs-existing-2']
57
+ }
58
+ );
59
+ \`\`\`
60
+
61
+ #### Constructor Parameters
62
+
63
+ - \`identifier: string\` - Unique identifier for the form (used in global registry)
64
+ - \`initialValues: T\` - Initial form values
65
+ - \`options.existingInstances?: string[]\` - Array of existing instance names for uniqueness validation
66
+
67
+ **Note:** Class validation is enabled by default. Use \`enableClassValidation(false)\` to disable it if your component doesn't require CSS classes.
68
+
69
+ ### Static Methods
70
+
71
+ #### generateNames()
72
+
73
+ Generates unique names, instances, and class names based on existing instances:
74
+
75
+ \`\`\`typescript
76
+ const generated = FormValidator.generateNames(
77
+ ['fs-slider-1', 'fs-slider-2'], // existing instances
78
+ 'slider', // solution name
79
+ 'Slider Component' // display name
80
+ );
81
+
82
+ // Returns:
83
+ // {
84
+ // name: 'Slider Component 3',
85
+ // instance: 'fs-slider-3',
86
+ // class: 'fs-slider-3'
87
+ // }
88
+ \`\`\`
89
+
90
+ #### sanitizeClassName()
91
+
92
+ Cleans up class names to ensure HTML compliance:
93
+
94
+ \`\`\`typescript
95
+ const cleaned = FormValidator.sanitizeClassName('my/invalid class-name!');
96
+ // Returns: 'my-invalid-class-name'
97
+ \`\`\`
98
+
99
+ ### Instance Methods
100
+
101
+ #### setField()
102
+
103
+ Updates a single form field:
104
+
105
+ \`\`\`typescript
106
+ formValidator.setField('name', 'New Component Name');
107
+ \`\`\`
108
+
109
+ #### setFields()
110
+
111
+ Updates multiple form fields at once:
112
+
113
+ \`\`\`typescript
114
+ formValidator.setFields({
115
+ name: 'New Name',
116
+ instance: 'fs-new-instance'
117
+ });
118
+ \`\`\`
119
+
120
+ #### validateWithInstances()
121
+
122
+ Updates the list of existing instances and re-validates:
123
+
124
+ \`\`\`typescript
125
+ formValidator.validateWithInstances(['fs-new-1', 'fs-new-2']);
126
+ \`\`\`
127
+
128
+ #### ignoreInstanceValidation()
129
+
130
+ Temporarily ignores a specific instance during validation (useful for edit mode):
131
+
132
+ \`\`\`typescript
133
+ formValidator.ignoreInstanceValidation('fs-current-instance', existingInstances);
134
+ \`\`\`
135
+
136
+ #### reset()
137
+
138
+ Resets the form to its initial state:
139
+
140
+ \`\`\`typescript
141
+ formValidator.reset();
142
+ \`\`\`
143
+
144
+ #### enableClassValidation()
145
+
146
+ Enables or disables class name validation dynamically:
147
+
148
+ \`\`\`typescript
149
+ // Disable class validation (useful for certain component types)
150
+ formValidator.enableClassValidation(false);
151
+
152
+ // Re-enable class validation
153
+ formValidator.enableClassValidation(true);
154
+ \`\`\`
155
+
156
+ #### getState()
157
+
158
+ Gets the current form state:
159
+
160
+ \`\`\`typescript
161
+ const state = formValidator.getState();
162
+ console.log(state.isValid, state.errors, state.values);
163
+ \`\`\`
164
+
165
+ #### setSubmitting()
166
+
167
+ Sets the form submission state:
168
+
169
+ \`\`\`typescript
170
+ formValidator.setSubmitting(true);
171
+ // ... perform submission
172
+ formValidator.setSubmitting(false);
173
+ \`\`\`
174
+
175
+ ## Form State Structure
176
+
177
+ The form state contains:
178
+
179
+ \`\`\`typescript
180
+ interface FormState<T> {
181
+ values: T; // Current form values
182
+ errors: Record<keyof T, string[]>; // Validation errors by field
183
+ touched: Record<keyof T, boolean>; // Fields that have been interacted with
184
+ isValid: boolean; // Overall form validity
185
+ isDirty: boolean; // Whether form has been modified
186
+ isSubmitting: boolean; // Submission state
187
+ }
188
+ \`\`\`
189
+
190
+ ## Global Form Registry
191
+
192
+ The system maintains a global registry of all forms for cross-component access.
193
+
194
+ ### getFormById()
195
+
196
+ Retrieve a form instance by its identifier:
197
+
198
+ \`\`\`typescript
199
+ import { getFormById } from './';
200
+
201
+ const form = getFormById('my-form-id');
202
+ if (form) {
203
+ console.log(form.getState());
204
+ }
205
+ \`\`\`
206
+
207
+ ### isFormValid()
208
+
209
+ Check if a specific form is valid:
210
+
211
+ \`\`\`typescript
212
+ import { isFormValid } from './';
213
+
214
+ if (isFormValid('my-form-id')) {
215
+ console.log('Form is valid!');
216
+ }
217
+ \`\`\`
218
+
219
+ ### getFormErrors()
220
+
221
+ Get error messages for a specific form:
222
+
223
+ \`\`\`typescript
224
+ import { getFormErrors } from './';
225
+
226
+ const errors = getFormErrors('my-form-id');
227
+ console.log(errors);
228
+ \`\`\`
229
+
230
+ ### resetForm()
231
+
232
+ Reset a form by its identifier:
233
+
234
+ \`\`\`typescript
235
+ import { resetForm } from './';
236
+
237
+ resetForm('my-form-id');
238
+ \`\`\`
239
+
240
+ ## Validation Rules
241
+
242
+ The system includes built-in validation for Webflow component forms:
243
+
244
+ ### Name Field
245
+
246
+ - Required (minimum 1 character)
247
+
248
+ ### Instance Field
249
+
250
+ - Required (minimum 1 character)
251
+ - Must be unique across existing instances
252
+ - Case-insensitive uniqueness check
253
+
254
+ ### Class Field
255
+
256
+ - Required by default (minimum 1 character when validation is enabled)
257
+ - Must contain only letters, numbers, underscores, and hyphens
258
+ - Automatically sanitized with \`sanitizeClassName()\`
259
+ - Can be disabled using \`enableClassValidation(false)\` for components that don't require CSS classes
260
+
261
+ ## Dynamic Class Validation
262
+
263
+ The form validator supports enabling or disabling class name validation based on your component's requirements. This is useful for components that don't require CSS classes or when you want to allow more flexible class naming.
264
+
265
+ ### When to Disable Class Validation
266
+
267
+ - Components that only use inline styles
268
+ - Third-party integrations that don't require CSS classes
269
+ - Temporary or test components
270
+ - Components where class names are generated programmatically
271
+
272
+ ### Usage Examples
273
+
274
+ \`\`\`typescript
275
+ // Create form with class validation enabled (default)
276
+ const formValidator = new FormValidator('component-form', initialValues);
277
+
278
+ // Disable class validation for a component that doesn't need CSS
279
+ formValidator.enableClassValidation(false);
280
+
281
+ // Re-enable class validation if needed later
282
+ formValidator.enableClassValidation(true);
283
+ \`\`\`
284
+
285
+ ## Best Practices
286
+
287
+ ### 1. Unique Form Identifiers
288
+
289
+ Always use unique identifiers for each form to prevent conflicts:
290
+
291
+ \`\`\`typescript
292
+ const formValidator = new FormValidator(\`\${componentType}-\${componentId}-form\`, initialValues);
293
+ \`\`\`
294
+
295
+ ### 2. Handle Existing Instances
296
+
297
+ Always provide existing instances for proper uniqueness validation:
298
+
299
+ \`\`\`typescript
300
+ const formValidator = new FormValidator('form-id', initialValues, {
301
+ existingInstances: getAllExistingInstances()
302
+ });
303
+ \`\`\`
304
+
305
+ ### 3. Edit Mode Handling
306
+
307
+ Use \`ignoreInstanceValidation()\` when editing existing components:
308
+
309
+ \`\`\`typescript
310
+ if (isEditMode) {
311
+ formValidator.ignoreInstanceValidation(currentInstance, existingInstances);
312
+ }
313
+ \`\`\`
314
+
315
+ ### 4. Cleanup
316
+
317
+ Always clean up form subscriptions to prevent memory leaks:
318
+
319
+ \`\`\`typescript
320
+ onDestroy(() => {
321
+ formSubscription.destroy();
322
+ });
323
+ \`\`\`
324
+
325
+ Click the interactive demo below to see the form validation system in action!
326
+ `
327
+ }
328
+ }
329
+ },
330
+ tags: ['autodocs']
331
+ };
332
+ export default meta;
333
+ export const Interactive = {
334
+ name: 'Interactive Demo',
335
+ parameters: {
336
+ docs: {
337
+ description: {
338
+ story: 'Explore the form validation system with a live interactive demo showing all features including validation, name generation, and error handling.'
339
+ }
340
+ }
341
+ }
342
+ };