@finsweet/webflow-apps-utils 1.0.6 → 1.0.8

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 (151) hide show
  1. package/dist/index.d.ts +0 -3
  2. package/dist/index.js +0 -3
  3. package/dist/types/dom.d.ts +1 -0
  4. package/dist/types/dom.js +1 -0
  5. package/dist/types/index.d.ts +1 -0
  6. package/dist/types/index.js +1 -0
  7. package/dist/types/webflow.d.ts +1 -1
  8. package/dist/ui/components/layout/Layout.svelte +4 -3
  9. package/dist/ui/components/layout/Layout.svelte.d.ts +2 -0
  10. package/dist/ui/components/layout/common/EditModeMessage.svelte +1 -1
  11. package/dist/ui/components/layout/examples/ExampleLayout.svelte +1 -1
  12. package/dist/ui/components/layout/examples/Wrapper.svelte +1 -1
  13. package/dist/ui/components/text/Text.svelte +4 -2
  14. package/dist/ui/components/text/types.d.ts +22 -0
  15. package/dist/ui/icons/ChevronIcon.svelte +1 -1
  16. package/dist/ui/index.d.ts +4 -0
  17. package/dist/ui/index.js +4 -0
  18. package/dist/{providers → ui/providers}/GlobalProvider.stories.js +7 -7
  19. package/dist/{providers → ui/providers}/GlobalProvider.svelte +1 -1
  20. package/dist/{router → ui/router}/providers/RouterProvider.svelte +1 -1
  21. package/dist/{router → ui/router}/router.svelte.d.ts +0 -1
  22. package/dist/{router → ui/router}/router.svelte.js +3 -2
  23. package/dist/{stores → ui/stores}/forms/Form.stories.js +5 -5
  24. package/dist/{stores → ui/stores}/forms/FormDemo.svelte +1 -1
  25. package/dist/{stores → ui/stores}/index.d.ts +1 -2
  26. package/dist/{stores → ui/stores}/index.js +1 -2
  27. package/dist/ui/utils/api/checkIfAppModeIsDesign.d.ts +4 -0
  28. package/dist/ui/utils/api/checkIfAppModeIsDesign.js +19 -0
  29. package/dist/ui/utils/api/clipboard/handlePaste.d.ts +15 -0
  30. package/dist/ui/utils/api/clipboard/handlePaste.js +49 -0
  31. package/dist/ui/utils/api/clipboard/index.d.ts +1 -0
  32. package/dist/ui/utils/api/clipboard/index.js +1 -0
  33. package/dist/ui/utils/api/getAllAssets.d.ts +11 -0
  34. package/dist/ui/utils/api/getAllAssets.js +20 -0
  35. package/dist/ui/utils/api/getFinsweetComponentsEnvironment.d.ts +8 -0
  36. package/dist/ui/utils/api/getFinsweetComponentsEnvironment.js +66 -0
  37. package/dist/ui/utils/api/index.d.ts +5 -0
  38. package/dist/ui/utils/api/index.js +5 -0
  39. package/dist/ui/utils/api/insertWithXSCP.d.ts +4 -0
  40. package/dist/ui/utils/api/insertWithXSCP.js +12 -0
  41. package/dist/{utils → ui/utils}/auth/crossWindowLogin.d.ts +1 -1
  42. package/dist/{utils → ui/utils}/auth/crossWindowLogin.js +1 -1
  43. package/dist/{utils → ui/utils}/auth/index.d.ts +1 -1
  44. package/dist/{utils → ui/utils}/auth/index.js +4 -6
  45. package/dist/{utils → ui/utils}/diff-mapper/DiffMapper.stories.js +2 -2
  46. package/dist/{utils → ui/utils}/diff-mapper/DiffMapperDemo.svelte +1 -1
  47. package/dist/{utils → ui/utils}/helpers/goto.js +2 -4
  48. package/dist/ui/utils/helpers/index.d.ts +1 -0
  49. package/dist/ui/utils/helpers/index.js +1 -0
  50. package/dist/ui/utils/index.d.ts +3 -0
  51. package/dist/ui/utils/index.js +3 -0
  52. package/dist/utils/constants.d.ts +5 -0
  53. package/dist/utils/constants.js +11 -0
  54. package/dist/utils/custom-code/api.d.ts +1 -1
  55. package/dist/utils/custom-code/api.js +4 -6
  56. package/dist/utils/custom-code/configs.d.ts +3 -2
  57. package/dist/utils/custom-code/configs.js +5 -8
  58. package/dist/utils/custom-code/index.d.ts +1 -1
  59. package/dist/utils/custom-code/index.js +1 -1
  60. package/dist/utils/helpers/dom.d.ts +37 -0
  61. package/dist/utils/helpers/dom.js +104 -0
  62. package/dist/utils/helpers/encodeDecodeConfigs.d.ts +13 -0
  63. package/dist/utils/helpers/encodeDecodeConfigs.js +20 -0
  64. package/dist/utils/helpers/events.d.ts +19 -0
  65. package/dist/utils/helpers/events.js +28 -0
  66. package/dist/utils/helpers/forms.d.ts +22 -0
  67. package/dist/utils/helpers/forms.js +82 -0
  68. package/dist/utils/helpers/guards.d.ts +124 -0
  69. package/dist/utils/helpers/guards.js +107 -0
  70. package/dist/utils/helpers/index.d.ts +8 -1
  71. package/dist/utils/helpers/index.js +8 -1
  72. package/dist/utils/helpers/parseCSV.d.ts +6 -0
  73. package/dist/utils/helpers/parseCSV.js +29 -0
  74. package/dist/utils/helpers/string.d.ts +23 -0
  75. package/dist/utils/helpers/string.js +33 -0
  76. package/dist/utils/helpers/wait.d.ts +13 -0
  77. package/dist/utils/helpers/wait.js +27 -0
  78. package/dist/utils/index.d.ts +3 -3
  79. package/dist/utils/index.js +2 -3
  80. package/dist/utils/logger/index.d.ts +1 -2
  81. package/dist/utils/stores/index.d.ts +2 -0
  82. package/dist/utils/stores/index.js +2 -0
  83. package/dist/utils/stores/isPreviewMode.d.ts +1 -0
  84. package/dist/utils/stores/isPreviewMode.js +2 -0
  85. package/dist/utils/webflow/CopyJSONButton.d.ts +54 -0
  86. package/dist/utils/webflow/CopyJSONButton.js +117 -0
  87. package/dist/utils/webflow/DisplayController.d.ts +55 -0
  88. package/dist/utils/webflow/DisplayController.js +91 -0
  89. package/dist/utils/webflow/Interaction.d.ts +47 -0
  90. package/dist/utils/webflow/Interaction.js +52 -0
  91. package/dist/utils/webflow/index.d.ts +4 -0
  92. package/dist/utils/webflow/index.js +4 -0
  93. package/dist/utils/webflow/webflow.d.ts +32 -0
  94. package/dist/utils/webflow/webflow.js +90 -0
  95. package/package.json +15 -7
  96. /package/dist/{providers → ui/providers}/GlobalProvider.stories.d.ts +0 -0
  97. /package/dist/{providers → ui/providers}/GlobalProvider.svelte.d.ts +0 -0
  98. /package/dist/{providers → ui/providers}/GlobalProviderDemo.svelte +0 -0
  99. /package/dist/{providers → ui/providers}/GlobalProviderDemo.svelte.d.ts +0 -0
  100. /package/dist/{providers → ui/providers}/configuratorUtils.d.ts +0 -0
  101. /package/dist/{providers → ui/providers}/configuratorUtils.js +0 -0
  102. /package/dist/{providers → ui/providers}/globalContext.svelte.d.ts +0 -0
  103. /package/dist/{providers → ui/providers}/globalContext.svelte.js +0 -0
  104. /package/dist/{providers → ui/providers}/index.d.ts +0 -0
  105. /package/dist/{providers → ui/providers}/index.js +0 -0
  106. /package/dist/{providers → ui/providers}/types.d.ts +0 -0
  107. /package/dist/{providers → ui/providers}/types.js +0 -0
  108. /package/dist/{router → ui/router}/Router.stories.d.ts +0 -0
  109. /package/dist/{router → ui/router}/Router.stories.js +0 -0
  110. /package/dist/{router → ui/router}/examples/RouterExample.svelte +0 -0
  111. /package/dist/{router → ui/router}/examples/RouterExample.svelte.d.ts +0 -0
  112. /package/dist/{router → ui/router}/examples/index.d.ts +0 -0
  113. /package/dist/{router → ui/router}/examples/index.js +0 -0
  114. /package/dist/{router → ui/router}/examples/pages/AboutPage.svelte +0 -0
  115. /package/dist/{router → ui/router}/examples/pages/AboutPage.svelte.d.ts +0 -0
  116. /package/dist/{router → ui/router}/examples/pages/HomePage.svelte +0 -0
  117. /package/dist/{router → ui/router}/examples/pages/HomePage.svelte.d.ts +0 -0
  118. /package/dist/{router → ui/router}/examples/pages/NotFoundPage.svelte +0 -0
  119. /package/dist/{router → ui/router}/examples/pages/NotFoundPage.svelte.d.ts +0 -0
  120. /package/dist/{router → ui/router}/hooks.svelte.d.ts +0 -0
  121. /package/dist/{router → ui/router}/hooks.svelte.js +0 -0
  122. /package/dist/{router → ui/router}/index.d.ts +0 -0
  123. /package/dist/{router → ui/router}/index.js +0 -0
  124. /package/dist/{router → ui/router}/providers/Link.svelte +0 -0
  125. /package/dist/{router → ui/router}/providers/Link.svelte.d.ts +0 -0
  126. /package/dist/{router → ui/router}/providers/Route.svelte +0 -0
  127. /package/dist/{router → ui/router}/providers/Route.svelte.d.ts +0 -0
  128. /package/dist/{router → ui/router}/providers/RouterProvider.svelte.d.ts +0 -0
  129. /package/dist/{router → ui/router}/providers/index.d.ts +0 -0
  130. /package/dist/{router → ui/router}/providers/index.js +0 -0
  131. /package/dist/{stores → ui/stores}/breakpoints.d.ts +0 -0
  132. /package/dist/{stores → ui/stores}/breakpoints.js +0 -0
  133. /package/dist/{stores → ui/stores}/componentInjectErrors.d.ts +0 -0
  134. /package/dist/{stores → ui/stores}/componentInjectErrors.js +0 -0
  135. /package/dist/{stores/forms.d.ts → ui/stores/form.d.ts} +0 -0
  136. /package/dist/{stores/forms.js → ui/stores/form.js} +0 -0
  137. /package/dist/{stores → ui/stores}/forms/Form.stories.d.ts +0 -0
  138. /package/dist/{stores → ui/stores}/forms/FormDemo.svelte.d.ts +0 -0
  139. /package/dist/{stores → ui/stores}/showConfirmActionModal.d.ts +0 -0
  140. /package/dist/{stores → ui/stores}/showConfirmActionModal.js +0 -0
  141. /package/dist/{stores → ui/stores}/siteInfo.d.ts +0 -0
  142. /package/dist/{stores → ui/stores}/siteInfo.js +0 -0
  143. /package/dist/{utils → ui/utils}/diff-mapper/DiffMapper.stories.d.ts +0 -0
  144. /package/dist/{utils → ui/utils}/diff-mapper/DiffMapperDemo.svelte.d.ts +0 -0
  145. /package/dist/{utils → ui/utils}/diff-mapper/deepDiffMapper.d.ts +0 -0
  146. /package/dist/{utils → ui/utils}/diff-mapper/deepDiffMapper.js +0 -0
  147. /package/dist/{utils → ui/utils}/diff-mapper/index.d.ts +0 -0
  148. /package/dist/{utils → ui/utils}/diff-mapper/index.js +0 -0
  149. /package/dist/{utils → ui/utils}/helpers/goto.d.ts +0 -0
  150. /package/dist/{stores → utils/stores}/router.d.ts +0 -0
  151. /package/dist/{stores → utils/stores}/router.js +0 -0
package/dist/index.d.ts CHANGED
@@ -1,6 +1,3 @@
1
1
  export * from './ui';
2
- export * from './router';
3
- export * from './stores';
4
- export * from './providers';
5
2
  export * from './utils';
6
3
  export * from './types';
package/dist/index.js CHANGED
@@ -1,6 +1,3 @@
1
1
  export * from './ui';
2
- export * from './router';
3
- export * from './stores';
4
- export * from './providers';
5
2
  export * from './utils';
6
3
  export * from './types';
@@ -0,0 +1 @@
1
+ export type FormField = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,5 @@
1
1
  export * from './auth';
2
+ export * from './dom';
2
3
  export * from './customCode';
3
4
  export * from './license';
4
5
  export * from './webflow';
@@ -1,4 +1,5 @@
1
1
  export * from './auth';
2
+ export * from './dom';
2
3
  export * from './customCode';
3
4
  export * from './license';
4
5
  export * from './webflow';
@@ -96,7 +96,7 @@ export type XSCPMetadata = {
96
96
  }[];
97
97
  };
98
98
  };
99
- type PastedNodes = {
99
+ export type PastedNodes = {
100
100
  children: string[];
101
101
  classes: string[];
102
102
  tag: string;
@@ -2,7 +2,6 @@
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLAttributes } from 'svelte/elements';
4
4
 
5
- import { useAppContext } from '../../../providers';
6
5
  import {
7
6
  CheckCircleOutlinedIcon,
8
7
  WarningCircleIcon,
@@ -41,6 +40,8 @@
41
40
  containerMode?: boolean;
42
41
  /** Size variant for the footer */
43
42
  footerSize?: 'normal' | 'large';
43
+ /** Padding for the main content container (CSS value) */
44
+ mainContentPadding?: string;
44
45
  /** Array of notification objects for tab status indicators */
45
46
  notifications?: Array<{
46
47
  /** Tab path this notification applies to */
@@ -76,6 +77,7 @@
76
77
  sidebarWidth = '274px',
77
78
  containerMode = false,
78
79
  footerSize = 'normal',
80
+ mainContentPadding = 'var(--Spacing-24, 24px)',
79
81
  notifications = [],
80
82
  sidebar,
81
83
  main,
@@ -240,7 +242,7 @@
240
242
  <!-- Main Content -->
241
243
  <div class="main-content" data-area="main">
242
244
  {#if main}
243
- <div class="main-content-container">
245
+ <div class="main-content-container" style="padding: {mainContentPadding}">
244
246
  {#if showEditModeMessage}
245
247
  <EditModeMessage />
246
248
  {/if}
@@ -462,7 +464,6 @@
462
464
  flex-direction: column;
463
465
  align-items: flex-start;
464
466
  align-self: stretch;
465
- padding: var(--Spacing-24, 24px);
466
467
  gap: var(--Spacing-16, 16px);
467
468
  }
468
469
 
@@ -28,6 +28,8 @@ interface LayoutProps extends HTMLAttributes<HTMLDivElement> {
28
28
  containerMode?: boolean;
29
29
  /** Size variant for the footer */
30
30
  footerSize?: 'normal' | 'large';
31
+ /** Padding for the main content container (CSS value) */
32
+ mainContentPadding?: string;
31
33
  /** Array of notification objects for tab status indicators */
32
34
  notifications?: Array<{
33
35
  /** Tab path this notification applies to */
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
- import { useAppContext } from '../../../../providers';
3
2
  import { Pencil, WarningTriangleOutlineIcon } from '../../../icons';
3
+ import { useAppContext } from '../../../providers';
4
4
  import { BRAND } from '../../../../utils';
5
5
 
6
6
  import { Notification } from '../../notification';
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { onMount } from 'svelte';
3
3
 
4
- import { useAppContext } from '../../../../providers';
4
+ import { useAppContext } from '../../../providers';
5
5
 
6
6
  import { CheckCircleIcon, CodeIcon, InfoIcon, SettingsIcon } from '../../../icons';
7
7
  import { Button } from '../../button';
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { GlobalProvider } from '../../../../providers';
2
+ import { GlobalProvider } from '../../../providers';
3
3
 
4
4
  import ExampleLayout from './ExampleLayout.svelte';
5
5
  </script>
@@ -43,6 +43,7 @@
43
43
 
44
44
  // Link behavior
45
45
  link = false,
46
+ linkHover = true,
46
47
 
47
48
  // Event handlers
48
49
  onclick,
@@ -211,6 +212,7 @@
211
212
  const classes = ['labels'];
212
213
  if (disabled) classes.push('disabled');
213
214
  if (link) classes.push('link');
215
+ if (link && linkHover) classes.push('link-hover');
214
216
  if (loading) classes.push('is-busy');
215
217
  if (hasPopup && popupConfig.active) classes.push('active');
216
218
  classes.push(className);
@@ -839,8 +841,8 @@
839
841
  border-radius: 4px;
840
842
  }
841
843
 
842
- .labels.link:hover:not(.disabled),
843
- .labels.link.is-busy {
844
+ .labels.link-hover:hover:not(.disabled),
845
+ .labels.link-hover.is-busy {
844
846
  background-color: var(--defaultLightHover);
845
847
  border-radius: 4px;
846
848
  }
@@ -25,26 +25,48 @@ export interface PopupConfig {
25
25
  onclick?: () => void;
26
26
  }
27
27
  export interface TextProps {
28
+ /** The text content to display */
28
29
  label?: string;
30
+ /** Additional CSS classes to apply to the component */
29
31
  class?: string;
32
+ /** Whether to render the label as HTML instead of plain text */
30
33
  raw?: boolean;
34
+ /** Whether to capitalize the first letter of the text */
31
35
  capitalize?: boolean;
36
+ /** Whether the component is disabled and non-interactive */
32
37
  disabled?: boolean;
38
+ /** HTML title attribute for accessibility and hover tooltip */
33
39
  title?: string;
40
+ /** Text wrapping behavior - 'nowrap' prevents wrapping, 'normal' allows wrapping */
34
41
  wrap?: 'nowrap' | 'normal';
42
+ /** Horizontal alignment of the text content */
35
43
  textAlign?: 'left' | 'center' | 'right';
44
+ /** Font size - use predefined sizes or custom CSS value */
36
45
  fontSize?: TEXT_SIZES | string;
46
+ /** Font weight - use predefined weights or custom CSS value */
37
47
  fontWeight?: TEXT_WEIGHTS | string;
48
+ /** Text color as any valid CSS color value */
38
49
  fontColor?: string;
50
+ /** Fixed height for the component container */
39
51
  height?: string;
52
+ /** Width at which text will be truncated with ellipsis */
40
53
  ellipsisOnWidth?: string;
54
+ /** Tooltip configuration object with all tooltip-related settings */
41
55
  tooltip?: Partial<TooltipProps>;
42
56
  /** Specifies whether to show tooltip on the text or icon. Requires icon prop when set to 'icon' */
43
57
  tooltipTarget?: 'text' | 'icon';
58
+ /** Configuration for action popup functionality (delete, reset, etc.) */
44
59
  popup?: PopupConfig;
60
+ /** Icon component to display alongside the text */
45
61
  icon?: Component | null;
62
+ /** Whether to show loading spinner instead of icon */
46
63
  loading?: boolean;
64
+ /** Whether to style the text as a clickable link with pointer cursor */
47
65
  link?: boolean;
66
+ /** Whether to show hover background effect when link is true (default: true) */
67
+ linkHover?: boolean;
68
+ /** Custom content snippet to render instead of the label text */
48
69
  children?: Snippet;
70
+ /** Additional pill/badge content snippet to display */
49
71
  pill?: Snippet;
50
72
  }
@@ -1,4 +1,4 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
2
2
  <path
3
3
  fill-rule="evenodd"
4
4
  clip-rule="evenodd"
@@ -1,2 +1,6 @@
1
1
  export * from './components';
2
2
  export * from './icons';
3
+ export * from './utils';
4
+ export * from './stores';
5
+ export * from './providers';
6
+ export * from './router';
package/dist/ui/index.js CHANGED
@@ -1,2 +1,6 @@
1
1
  export * from './components';
2
2
  export * from './icons';
3
+ export * from './utils';
4
+ export * from './stores';
5
+ export * from './providers';
6
+ export * from './router';
@@ -34,7 +34,7 @@ The \`GlobalProvider\` is a comprehensive context management system built on Sve
34
34
 
35
35
  \`\`\`svelte
36
36
  <script lang="ts">
37
- import { GlobalProvider } from './';
37
+ import { GlobalProvider } from '../../providers';
38
38
 
39
39
  const initialContexts = {
40
40
  app: {
@@ -66,7 +66,7 @@ The \`GlobalProvider\` automatically creates these default contexts:
66
66
 
67
67
  \`\`\`svelte
68
68
  <script lang="ts">
69
- import { useAppContext, useFormContext, useDataContext } from './';
69
+ import { useAppContext, useFormContext, useDataContext } from '../../providers';
70
70
 
71
71
  const appContext = useAppContext();
72
72
  const formContext = useFormContext();
@@ -141,7 +141,7 @@ The \`GlobalProvider\` includes sophisticated configurator state management with
141
141
 
142
142
  \`\`\`svelte
143
143
  <script lang="ts">
144
- import { useConfiguratorContext, useAppContext } from './';
144
+ import { useConfiguratorContext, useAppContext } from '../../providers';
145
145
 
146
146
  // Define your configurator type
147
147
  type MyConfiguratorType = {
@@ -230,7 +230,7 @@ const config6 = { user: { name: 'John', age: 31 }, settings: { theme: 'dark' } }
230
230
  ### Generic Context Usage
231
231
 
232
232
  \`\`\`typescript
233
- import type { ContextOperations, AppContextData, DataContextData } from './';
233
+ import type { ContextOperations, AppContextData, DataContextData } from '../../providers';
234
234
 
235
235
  // For custom contexts
236
236
  const userContext: ContextOperations<UserType> = useContext<UserType>('user');
@@ -266,7 +266,7 @@ The GlobalProvider system includes several powerful utility functions for advanc
266
266
  For detailed object comparison and change analysis:
267
267
 
268
268
  \`\`\`typescript
269
- import { hasChangesViaDiff, getDetailedDiff, compareKeys } from './';
269
+ import { hasChangesViaDiff, getDetailedDiff, compareKeys } from '../../providers';
270
270
 
271
271
  // Quick change detection
272
272
  const hasChanges = hasChangesViaDiff(oldConfig, newConfig);
@@ -291,7 +291,7 @@ import {
291
291
  validateWatchOptions,
292
292
  extractKeys,
293
293
  createDebouncedUpdate
294
- } from './';
294
+ } from '../../providers';
295
295
 
296
296
  // Create default configurator state
297
297
  const defaultState = createDefaultConfiguratorState<MyConfigType>();
@@ -313,7 +313,7 @@ const debouncedSave = createDebouncedUpdate(saveConfig, 300);
313
313
  ### Performance Optimization Helpers
314
314
 
315
315
  \`\`\`typescript
316
- import { createDebouncedUpdate } from './';
316
+ import { createDebouncedUpdate } from '../../providers';
317
317
 
318
318
  // Create debounced functions for expensive operations
319
319
  const debouncedValidation = createDebouncedUpdate((config) => {
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { getFinsweetComponentsEnvironment } from '../utils/index.js';
2
+ import { getFinsweetComponentsEnvironment } from '../../utils/index.js';
3
3
 
4
4
  import { createGlobalContext, setGlobalContext } from './globalContext.svelte';
5
5
  import type { GlobalProviderProps } from './types';
@@ -1,8 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { onDestroy, onMount, setContext, type Snippet } from 'svelte';
3
3
 
4
+ import { LoadingScreen } from '../..';
4
5
  import type { RouteConfig, Router } from '../router.svelte';
5
- import { LoadingScreen } from '../../ui';
6
6
 
7
7
  interface Props {
8
8
  /** Router instance to use for routing */
@@ -102,4 +102,3 @@ export declare function createRouter(config?: RouterConfig): Router;
102
102
  */
103
103
  export declare const router: Router;
104
104
  export * from './hooks.svelte.js';
105
- export * from './providers/index.js';
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { routerStore } from '../stores';
2
+ import { routerStore } from '../../utils/stores';
3
3
  /**
4
4
  * Custom Client-Side Router for Svelte 5
5
5
  */
@@ -394,4 +394,5 @@ export function createRouter(config) {
394
394
  export const router = createRouter();
395
395
  // Export hooks and utilities
396
396
  export * from './hooks.svelte.js';
397
- export * from './providers/index.js';
397
+ // Providers moved to main package - import from @finsweet/webflow-apps-utils directly
398
+ // export * from './providers/index.js';
@@ -35,7 +35,7 @@ The form validation system provides:
35
35
  The main class for creating and managing form validation state.
36
36
 
37
37
  \`\`\`typescript
38
- import { FormValidator } from './';
38
+ import { FormValidator } from '../../../stores/forms';
39
39
 
40
40
  // Define your form data structure
41
41
  interface MyFormData {
@@ -196,7 +196,7 @@ The system maintains a global registry of all forms for cross-component access.
196
196
  Retrieve a form instance by its identifier:
197
197
 
198
198
  \`\`\`typescript
199
- import { getFormById } from './';
199
+ import { getFormById } from '../../../stores/forms';
200
200
 
201
201
  const form = getFormById('my-form-id');
202
202
  if (form) {
@@ -209,7 +209,7 @@ if (form) {
209
209
  Check if a specific form is valid:
210
210
 
211
211
  \`\`\`typescript
212
- import { isFormValid } from './';
212
+ import { isFormValid } from '../../../stores/forms';
213
213
 
214
214
  if (isFormValid('my-form-id')) {
215
215
  console.log('Form is valid!');
@@ -221,7 +221,7 @@ if (isFormValid('my-form-id')) {
221
221
  Get error messages for a specific form:
222
222
 
223
223
  \`\`\`typescript
224
- import { getFormErrors } from './';
224
+ import { getFormErrors } from '../../../stores/forms';
225
225
 
226
226
  const errors = getFormErrors('my-form-id');
227
227
  console.log(errors);
@@ -232,7 +232,7 @@ console.log(errors);
232
232
  Reset a form by its identifier:
233
233
 
234
234
  \`\`\`typescript
235
- import { resetForm } from './';
235
+ import { resetForm } from '../../../stores/forms';
236
236
 
237
237
  resetForm('my-form-id');
238
238
  \`\`\`
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { FormValidator } from '../forms';
2
+ import { FormValidator } from '../form';
3
3
 
4
4
  interface DemoFormData {
5
5
  name: string;
@@ -1,6 +1,5 @@
1
1
  export * from './breakpoints';
2
- export * from './forms';
2
+ export * from './form';
3
3
  export * from './componentInjectErrors';
4
- export * from './router';
5
4
  export * from './showConfirmActionModal';
6
5
  export * from './siteInfo';
@@ -1,6 +1,5 @@
1
1
  export * from './breakpoints';
2
- export * from './forms';
2
+ export * from './form';
3
3
  export * from './componentInjectErrors';
4
- export * from './router';
5
4
  export * from './showConfirmActionModal';
6
5
  export * from './siteInfo';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Checks if the app mode is design and shows error notification if not.
3
+ */
4
+ export declare const checkIfAppModeIsDesign: () => Promise<boolean>;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Checks if the app mode is design and shows error notification if not.
3
+ */
4
+ export const checkIfAppModeIsDesign = async () => {
5
+ const capabilities = await webflow.canForAppMode([
6
+ webflow.appModes.canDesign,
7
+ webflow.appModes.canEdit
8
+ ]);
9
+ if (capabilities.canDesign) {
10
+ // Proceed with the action
11
+ return true;
12
+ }
13
+ // Provide feedback to the user
14
+ await webflow.notify({
15
+ type: 'Error',
16
+ message: 'This action cannot be performed right now. Ensure you are working in the Primary Locale, on the Main Branch, and in design mode.'
17
+ });
18
+ return false;
19
+ };
@@ -0,0 +1,15 @@
1
+ import type { XSCPMetadata } from '../../../../types';
2
+ /**
3
+ * Processes pasted component data to validate Finsweet components.
4
+ */
5
+ export declare const processPastedComponent: (pasteData: XSCPMetadata, component: string) => {
6
+ data: XSCPMetadata;
7
+ key: string;
8
+ } | undefined;
9
+ /**
10
+ * Handles pasting of Webflow components from clipboard.
11
+ */
12
+ export declare const handlePasteXSCP: (e: ClipboardEvent, component: string) => {
13
+ data: XSCPMetadata;
14
+ key: string;
15
+ } | undefined;
@@ -0,0 +1,49 @@
1
+ import { getLogger } from '../../../../utils/logger';
2
+ const logger = getLogger('webflow-apps-ui-utils');
3
+ /**
4
+ * Processes pasted component data to validate Finsweet components.
5
+ */
6
+ export const processPastedComponent = (pasteData, component) => {
7
+ const valid = pasteData?.payload?.nodes?.some((node) => node?.data?.xattr?.some((attr) => {
8
+ if (component === 'consent') {
9
+ // consent is kinda different
10
+ const bannerFound = attr.name.includes(`fs-consent-element`) && attr.value === 'banner';
11
+ const wrapperFound = attr.name.includes(`fs-consent-element`) && attr.value === 'wrapper';
12
+ return bannerFound || wrapperFound;
13
+ }
14
+ return attr.name.includes(`fs-${component}-instance`);
15
+ }));
16
+ if (valid) {
17
+ return { data: pasteData, key: component };
18
+ }
19
+ };
20
+ /**
21
+ * Handles pasting of Webflow components from clipboard.
22
+ */
23
+ export const handlePasteXSCP = (e, component) => {
24
+ if (!e.clipboardData?.types.includes('application/json'))
25
+ return;
26
+ const data = e.clipboardData?.getData('application/json');
27
+ const clipboard = JSON.parse(data);
28
+ if (clipboard?.type === '@webflow/XscpData') {
29
+ try {
30
+ const data = e.clipboardData.getData('application/json');
31
+ const clipboard = JSON.parse(data);
32
+ if (clipboard?.type === '@webflow/XscpData') {
33
+ return processPastedComponent(clipboard, component);
34
+ }
35
+ webflow.notify({
36
+ type: 'Error',
37
+ message: 'Invalid! You can only paste valid Finsweet Components.'
38
+ });
39
+ }
40
+ catch (error) {
41
+ logger.error({}, 'handlePasteXSCP', error);
42
+ webflow.notify({
43
+ type: 'Error',
44
+ message: 'Invalid! You can only paste valid Finsweet Components.'
45
+ });
46
+ return;
47
+ }
48
+ }
49
+ };
@@ -0,0 +1 @@
1
+ export * from './handlePaste';
@@ -0,0 +1 @@
1
+ export * from './handlePaste';
@@ -0,0 +1,11 @@
1
+ export interface AllAssets {
2
+ name: string;
3
+ url: string;
4
+ mimeType: string;
5
+ altText: string;
6
+ asset: Asset;
7
+ }
8
+ /**
9
+ * Gets all assets from the Webflow Canvas with their metadata.
10
+ */
11
+ export declare const getAllAssets: () => Promise<AllAssets[]>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Gets all assets from the Webflow Canvas with their metadata.
3
+ */
4
+ export const getAllAssets = async () => {
5
+ const assets = await webflow.getAllAssets();
6
+ const assetPromises = assets.map(async (asset) => {
7
+ const url = await asset.getUrl();
8
+ const name = await asset.getName();
9
+ const mimeType = await asset.getMimeType();
10
+ const altText = (await asset.getAltText()) ?? '';
11
+ return {
12
+ name,
13
+ url,
14
+ mimeType,
15
+ altText,
16
+ asset
17
+ };
18
+ });
19
+ return await Promise.all(assetPromises);
20
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Gets the Finsweet components environment configuration.
3
+ */
4
+ export declare const getFinsweetComponentsEnvironment: () => {
5
+ development: boolean;
6
+ coreScript: string;
7
+ api: string;
8
+ };
@@ -0,0 +1,66 @@
1
+ import { COMPONENTS_CORE_SCRIPT, COMPONENTS_CORE_SCRIPT_LOCAL, COMPONENTS_SERVER_DEV_ENDPOINT, COMPONENTS_SERVER_DEV_ENDPOINT_LOCAL, COMPONENTS_SERVER_PROD_ENDPOINT, getLocalStorage } from '../../../utils';
2
+ const DEV_MODE_KEY = 'fsComponentsDevMode';
3
+ const DEV_MODE_SCRIPT_KEY = 'fsComponentsDevModeScript';
4
+ const DEV_MODE_API_KEY = 'fsComponentsDevModeApi';
5
+ const URL_DEV_MODE_KEY = 'dev';
6
+ const URL_DEV_MODE_SCRIPT_KEY = 'script';
7
+ const URL_DEV_MODE_API_KEY = 'api';
8
+ let lastLogTime = 0;
9
+ const LOG_THROTTLE_MS = 3000;
10
+ /**
11
+ * Gets a parameter value from the URL search params.
12
+ */
13
+ const getUrlParam = (key) => {
14
+ if (typeof window === 'undefined')
15
+ return null;
16
+ try {
17
+ const urlParams = new URLSearchParams(window.location.search);
18
+ return urlParams.get(key);
19
+ }
20
+ catch (e) {
21
+ console.error('Error getting URL parameter:', e);
22
+ return null;
23
+ }
24
+ };
25
+ /**
26
+ * Throttled console log that only logs once within the throttle interval.
27
+ */
28
+ const throttledLog = (message, data) => {
29
+ const now = Date.now();
30
+ if (now - lastLogTime >= LOG_THROTTLE_MS) {
31
+ console.log(message, data || '');
32
+ lastLogTime = now;
33
+ }
34
+ };
35
+ /**
36
+ * Gets the Finsweet components environment configuration.
37
+ */
38
+ export const getFinsweetComponentsEnvironment = () => {
39
+ const devFromUrl = getUrlParam(URL_DEV_MODE_KEY);
40
+ const scriptFromUrl = getUrlParam(URL_DEV_MODE_SCRIPT_KEY);
41
+ const apiFromUrl = getUrlParam(URL_DEV_MODE_API_KEY);
42
+ const dev = devFromUrl !== null ? devFromUrl === 'true' : getLocalStorage(DEV_MODE_KEY) === 'true';
43
+ let script = scriptFromUrl || getLocalStorage(DEV_MODE_SCRIPT_KEY) || COMPONENTS_CORE_SCRIPT;
44
+ let api = dev
45
+ ? apiFromUrl || getLocalStorage(DEV_MODE_API_KEY) || COMPONENTS_SERVER_DEV_ENDPOINT
46
+ : COMPONENTS_SERVER_PROD_ENDPOINT;
47
+ const isBrowser = typeof window !== 'undefined';
48
+ const isLocalhost = isBrowser && window?.location?.hostname?.includes('localhost');
49
+ //if localhost then use local scripts
50
+ if (isLocalhost) {
51
+ script = COMPONENTS_CORE_SCRIPT_LOCAL;
52
+ api = COMPONENTS_SERVER_DEV_ENDPOINT_LOCAL;
53
+ }
54
+ const development = !!dev || isLocalhost;
55
+ if (development) {
56
+ throttledLog(`\n\nFinsweet Components Environment:
57
+ - API: ${api}
58
+ - Core script: ${script}
59
+ - Development mode: ${development ? 'Yes' : 'No'}\n\n`);
60
+ }
61
+ return {
62
+ development,
63
+ coreScript: script,
64
+ api
65
+ };
66
+ };
@@ -0,0 +1,5 @@
1
+ export * from './checkIfAppModeIsDesign';
2
+ export * from './clipboard';
3
+ export * from './getAllAssets';
4
+ export * from './getFinsweetComponentsEnvironment';
5
+ export * from './insertWithXSCP';
@@ -0,0 +1,5 @@
1
+ export * from './checkIfAppModeIsDesign';
2
+ export * from './clipboard';
3
+ export * from './getAllAssets';
4
+ export * from './getFinsweetComponentsEnvironment';
5
+ export * from './insertWithXSCP';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Inserts a template into the Designer Canvas using XSCP APIs.
3
+ */
4
+ export declare const insertWithXSCP: (template: string) => Promise<void>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Inserts a template into the Designer Canvas using XSCP APIs.
3
+ */
4
+ export const insertWithXSCP = async (template) => {
5
+ try {
6
+ // @ts-expect-error - typings not available for xscp
7
+ await webflow._internal.xscp(template);
8
+ }
9
+ catch (error) {
10
+ throw new Error(`Failed to insert template with XSCP: ${error}`);
11
+ }
12
+ };
@@ -1,4 +1,4 @@
1
- import type { FinsweetAuth } from '../../types';
1
+ import type { FinsweetAuth } from '../../../types';
2
2
  /**
3
3
  * Opens a popup window for cross-window authentication with Auth0.
4
4
  */