@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
@@ -0,0 +1,124 @@
1
+ import type { FormField } from '../../types';
2
+ /**
3
+ * Defines a typed object entry
4
+ */
5
+ export type Entry<T> = {
6
+ [K in keyof T]: [K, T[K]];
7
+ }[keyof T];
8
+ /**
9
+ * Converts a `Map<K, V>` type to its equivalent when performing `[...map.entries()]`.
10
+ * @example ```typescript
11
+ * const map: MapType = new Map(['key', 'value']);
12
+ * const entries = [...map.entries()]; // Same type as MapEntries<MapType>
13
+ *
14
+ * typeof entries === MapEntries<MapType>
15
+ * ```
16
+ */
17
+ export type MapEntries<MapToConvert> = MapToConvert extends Map<infer Key, infer Value> ? [Key, Value][] : never;
18
+ /**
19
+ * Check if value is a string
20
+ */
21
+ export declare const isString: (value: unknown) => value is string;
22
+ /**
23
+ * Check if value is a number
24
+ */
25
+ export declare const isNumber: (value: unknown) => value is number;
26
+ /**
27
+ * Check if value is a boolean
28
+ */
29
+ export declare const isBoolean: (value: unknown) => value is boolean;
30
+ /**
31
+ * Check if value undefined
32
+ */
33
+ export declare const isUndefined: (value: unknown) => value is undefined;
34
+ /**
35
+ * Makes sure a value is not `null` or `undefined`.
36
+ * Useful for type safety when filtering empty elements from an array. Check out the example for more in-depth explanation.
37
+ * @param value The value to type-check.
38
+ * @example ```typescript
39
+ * const items = [1, null, 4, undefined, 8];
40
+ *
41
+ * const filteredItemsError: number[] = items.filter((item) => value !== undefined && value !== null); // Type '(number | null | undefined)[]' is not assignable to type 'number[]'.
42
+ *
43
+ * const filteredItemsSuccess: number[] = items.filter(isNotEmpty); // Success!
44
+ * ```
45
+ */
46
+ export declare const isNotEmpty: <T>(value: T | null | undefined) => value is T;
47
+ /**
48
+ * Check if a key is included in a readonly array
49
+ * @param key
50
+ * @param source readonly array of strings
51
+ * @returns True/false
52
+ */
53
+ export declare const isKeyOf: <T extends string>(key: string | null | undefined, source: readonly T[]) => key is (typeof source)[number];
54
+ /**
55
+ * Gets the keys of an object with inferred typing.
56
+ * @param object
57
+ * @returns
58
+ */
59
+ export declare const getObjectKeys: <T extends Record<string, unknown>>(object: T) => (keyof T)[];
60
+ /**
61
+ * Gets type safe `Object.entries()`.
62
+ * @param object
63
+ */
64
+ export declare const getObjectEntries: <T extends Readonly<Record<string, unknown>>>(object: T) => Entry<T>[];
65
+ /**
66
+ * @returns `true` if the target is an instance of Element type.
67
+ * @param target
68
+ */
69
+ export declare const isElement: (target: unknown) => target is Element;
70
+ /**
71
+ * @returns `true` if the target is an instance of HTMLElement type.
72
+ * @param target
73
+ */
74
+ export declare const isHTMLElement: (target: unknown) => target is HTMLElement;
75
+ /**
76
+ * @returns `true` if the target is an instance of HTMLVideoElement type.
77
+ * @param target
78
+ */
79
+ export declare const isHTMLVideoElement: (target: unknown) => target is HTMLVideoElement;
80
+ /**
81
+ * @returns `true` if the target is an instance of HTMLInputElement type.
82
+ * @param target
83
+ */
84
+ export declare const isHTMLInputElement: (target: unknown) => target is HTMLInputElement;
85
+ /**
86
+ * @returns `true` if the target is an instance of HTMLSelectElement type.
87
+ * @param target
88
+ */
89
+ export declare const isHTMLSelectElement: (target: unknown) => target is HTMLSelectElement;
90
+ /**
91
+ * @returns `true` if the target is an instance of HTMLTextAreaElement type.
92
+ * @param target
93
+ */
94
+ export declare const isHTMLTextAreaElement: (target: unknown) => target is HTMLTextAreaElement;
95
+ /**
96
+ * Checks if an element is a form field element
97
+ * @param element
98
+ */
99
+ export declare const isFormField: (element: Element | EventTarget | null) => element is FormField;
100
+ /**
101
+ * @returns `true` if the target is an instance of HTMLAnchorElement type.
102
+ * @param target
103
+ */
104
+ export declare const isHTMLAnchorElement: (target: unknown) => target is HTMLAnchorElement;
105
+ /**
106
+ * @returns `true` if the target is an instance of HTMLOptionElement type.
107
+ * @param target
108
+ */
109
+ export declare const isHTMLOptionElement: (target: unknown) => target is HTMLOptionElement;
110
+ /**
111
+ * @returns `true` if the target is an instance of HTMLImageElement type.
112
+ * @param target
113
+ */
114
+ export declare const isHTMLImageElement: (target: unknown) => target is HTMLImageElement;
115
+ /**
116
+ * @returns `true` if the target is an instance of HTMLButtonElement type.
117
+ * @param target
118
+ */
119
+ export declare const isHTMLButtonElement: (target: unknown) => target is HTMLButtonElement;
120
+ /**
121
+ * @returns `true` if the target is an instance of File type.
122
+ * @param target
123
+ */
124
+ export declare const isFile: (target: unknown) => target is File;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Check if value is a string
3
+ */
4
+ export const isString = (value) => typeof value === 'string';
5
+ /**
6
+ * Check if value is a number
7
+ */
8
+ export const isNumber = (value) => typeof value === 'number';
9
+ /**
10
+ * Check if value is a boolean
11
+ */
12
+ export const isBoolean = (value) => typeof value === 'boolean';
13
+ /**
14
+ * Check if value undefined
15
+ */
16
+ export const isUndefined = (value) => value === undefined;
17
+ /**
18
+ * Makes sure a value is not `null` or `undefined`.
19
+ * Useful for type safety when filtering empty elements from an array. Check out the example for more in-depth explanation.
20
+ * @param value The value to type-check.
21
+ * @example ```typescript
22
+ * const items = [1, null, 4, undefined, 8];
23
+ *
24
+ * const filteredItemsError: number[] = items.filter((item) => value !== undefined && value !== null); // Type '(number | null | undefined)[]' is not assignable to type 'number[]'.
25
+ *
26
+ * const filteredItemsSuccess: number[] = items.filter(isNotEmpty); // Success!
27
+ * ```
28
+ */
29
+ export const isNotEmpty = (value) => value !== undefined && value !== null;
30
+ /**
31
+ * Check if a key is included in a readonly array
32
+ * @param key
33
+ * @param source readonly array of strings
34
+ * @returns True/false
35
+ */
36
+ export const isKeyOf = (key, source) => !!key && source.includes(key);
37
+ /**
38
+ * Gets the keys of an object with inferred typing.
39
+ * @param object
40
+ * @returns
41
+ */
42
+ export const getObjectKeys = (object) => Object.keys(object);
43
+ /**
44
+ * Gets type safe `Object.entries()`.
45
+ * @param object
46
+ */
47
+ export const getObjectEntries = (object) => Object.entries(object);
48
+ /**
49
+ * @returns `true` if the target is an instance of Element type.
50
+ * @param target
51
+ */
52
+ export const isElement = (target) => target instanceof Element;
53
+ /**
54
+ * @returns `true` if the target is an instance of HTMLElement type.
55
+ * @param target
56
+ */
57
+ export const isHTMLElement = (target) => target instanceof HTMLElement;
58
+ /**
59
+ * @returns `true` if the target is an instance of HTMLVideoElement type.
60
+ * @param target
61
+ */
62
+ export const isHTMLVideoElement = (target) => target instanceof HTMLVideoElement;
63
+ /**
64
+ * @returns `true` if the target is an instance of HTMLInputElement type.
65
+ * @param target
66
+ */
67
+ export const isHTMLInputElement = (target) => target instanceof HTMLInputElement;
68
+ /**
69
+ * @returns `true` if the target is an instance of HTMLSelectElement type.
70
+ * @param target
71
+ */
72
+ export const isHTMLSelectElement = (target) => target instanceof HTMLSelectElement;
73
+ /**
74
+ * @returns `true` if the target is an instance of HTMLTextAreaElement type.
75
+ * @param target
76
+ */
77
+ export const isHTMLTextAreaElement = (target) => target instanceof HTMLTextAreaElement;
78
+ /**
79
+ * Checks if an element is a form field element
80
+ * @param element
81
+ */
82
+ export const isFormField = (element) => isHTMLInputElement(element) || isHTMLSelectElement(element) || isHTMLTextAreaElement(element);
83
+ /**
84
+ * @returns `true` if the target is an instance of HTMLAnchorElement type.
85
+ * @param target
86
+ */
87
+ export const isHTMLAnchorElement = (target) => target instanceof HTMLAnchorElement;
88
+ /**
89
+ * @returns `true` if the target is an instance of HTMLOptionElement type.
90
+ * @param target
91
+ */
92
+ export const isHTMLOptionElement = (target) => target instanceof HTMLOptionElement;
93
+ /**
94
+ * @returns `true` if the target is an instance of HTMLImageElement type.
95
+ * @param target
96
+ */
97
+ export const isHTMLImageElement = (target) => target instanceof HTMLImageElement;
98
+ /**
99
+ * @returns `true` if the target is an instance of HTMLButtonElement type.
100
+ * @param target
101
+ */
102
+ export const isHTMLButtonElement = (target) => target instanceof HTMLButtonElement;
103
+ /**
104
+ * @returns `true` if the target is an instance of File type.
105
+ * @param target
106
+ */
107
+ export const isFile = (target) => target instanceof File;
@@ -1,10 +1,17 @@
1
1
  export * from './capitalizeFirstLetter';
2
2
  export * from './cleanupTooltipMessage';
3
- export * from './goto';
3
+ export * from './encodeDecodeConfigs';
4
+ export * from './dom';
5
+ export * from './events';
6
+ export * from './forms';
4
7
  export * from './getTimeNow';
5
8
  export * from './minifyCode';
6
9
  export * from './noop';
10
+ export * from './guards';
7
11
  export * from './numbers';
12
+ export * from './parseCSV';
13
+ export * from './string';
8
14
  export * from './objectsToModuleExports';
9
15
  export * from './trimText';
10
16
  export * from './toHumanReadableList';
17
+ export * from './wait';
@@ -1,10 +1,17 @@
1
1
  export * from './capitalizeFirstLetter';
2
2
  export * from './cleanupTooltipMessage';
3
- export * from './goto';
3
+ export * from './encodeDecodeConfigs';
4
+ export * from './dom';
5
+ export * from './events';
6
+ export * from './forms';
4
7
  export * from './getTimeNow';
5
8
  export * from './minifyCode';
6
9
  export * from './noop';
10
+ export * from './guards';
7
11
  export * from './numbers';
12
+ export * from './parseCSV';
13
+ export * from './string';
8
14
  export * from './objectsToModuleExports';
9
15
  export * from './trimText';
10
16
  export * from './toHumanReadableList';
17
+ export * from './wait';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Parse CSV data
3
+ * @param csvText CSV data as string
4
+ * @returns Parsed CSV data as an array of objects
5
+ */
6
+ export declare const parseCSV: <Result extends Record<string, string>>(csvText: string) => Promise<Result[]>;
@@ -0,0 +1,29 @@
1
+ import { parse } from 'csv-parse/browser/esm';
2
+ /**
3
+ * Parse CSV data
4
+ * @param csvText CSV data as string
5
+ * @returns Parsed CSV data as an array of objects
6
+ */
7
+ export const parseCSV = async (csvText) => {
8
+ return new Promise((resolve, reject) => {
9
+ const results = [];
10
+ parse(csvText, {
11
+ columns: true,
12
+ skip_empty_lines: true,
13
+ trim: true
14
+ })
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ .on('readable', function () {
17
+ let record;
18
+ while ((record = this.read()) !== null) {
19
+ results.push(record);
20
+ }
21
+ })
22
+ .on('error', (error) => {
23
+ reject(error);
24
+ })
25
+ .on('end', () => {
26
+ resolve(results);
27
+ });
28
+ });
29
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Removes the trailing slash from a URL string.
3
+ *
4
+ * @example
5
+ * ```
6
+ * This:
7
+ * https://www.finsweet.com/attributes/attractions/capri-island/
8
+ *
9
+ * Becomes:
10
+ * https://www.finsweet.com/attributes/attractions/capri-island
11
+ * ```
12
+ *
13
+ * @param value The value to mutate.
14
+ * @returns A new string without a trailing slash.
15
+ */
16
+ export declare const removeTrailingSlash: (value: string) => string;
17
+ /**
18
+ * Convert a string of comma separated values to an array of values.
19
+ *
20
+ * @param string Comma separated string.
21
+ * @param filterEmpty Defines if empty values should be filtered out of the returned array. Defaults to `true`.
22
+ */
23
+ export declare const extractCommaSeparatedValues: (string: string | null | undefined, filterEmpty?: boolean) => string[];
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Removes the trailing slash from a URL string.
3
+ *
4
+ * @example
5
+ * ```
6
+ * This:
7
+ * https://www.finsweet.com/attributes/attractions/capri-island/
8
+ *
9
+ * Becomes:
10
+ * https://www.finsweet.com/attributes/attractions/capri-island
11
+ * ```
12
+ *
13
+ * @param value The value to mutate.
14
+ * @returns A new string without a trailing slash.
15
+ */
16
+ export const removeTrailingSlash = (value) => value.replace(/\/+$/, '');
17
+ /**
18
+ * Convert a string of comma separated values to an array of values.
19
+ *
20
+ * @param string Comma separated string.
21
+ * @param filterEmpty Defines if empty values should be filtered out of the returned array. Defaults to `true`.
22
+ */
23
+ export const extractCommaSeparatedValues = (string, filterEmpty = true) => {
24
+ if (!string)
25
+ return [];
26
+ const items = string.split(',').reduce((accumulatedValue, currentValue) => {
27
+ const value = currentValue.trim();
28
+ if (!filterEmpty || value)
29
+ accumulatedValue.push(value);
30
+ return accumulatedValue;
31
+ }, []);
32
+ return items;
33
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @returns Awaitable promise for waiting X time.
3
+ * @param time
4
+ */
5
+ export declare const wait: (time: number) => Promise<unknown>;
6
+ /**
7
+ * @returns A promise that resolves once Webflow has fully loaded.
8
+ */
9
+ export declare const waitWebflowReady: () => Promise<unknown>;
10
+ /**
11
+ * @returns A promise that resolves once the DOM is ready.
12
+ */
13
+ export declare const waitDOMReady: () => Promise<unknown>;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @returns Awaitable promise for waiting X time.
3
+ * @param time
4
+ */
5
+ export const wait = (time) => new Promise((resolve) => setTimeout(resolve, time));
6
+ /**
7
+ * @returns A promise that resolves once Webflow has fully loaded.
8
+ */
9
+ export const waitWebflowReady = async () => {
10
+ return new Promise((resolve) => {
11
+ window.Webflow ||= [];
12
+ window.Webflow.push(resolve);
13
+ });
14
+ };
15
+ /**
16
+ * @returns A promise that resolves once the DOM is ready.
17
+ */
18
+ export const waitDOMReady = async () => {
19
+ return new Promise((resolve) => {
20
+ if (document.readyState === 'loading') {
21
+ document.addEventListener('DOMContentLoaded', resolve);
22
+ }
23
+ else {
24
+ resolve(undefined);
25
+ }
26
+ });
27
+ };
@@ -1,10 +1,10 @@
1
1
  export * from './animations';
2
2
  export * from './api';
3
- export * from './auth';
4
3
  export * from './browser-storage';
5
- export * from './constants';
6
4
  export * from './custom-code';
7
- export * from './diff-mapper';
5
+ export * from './constants';
8
6
  export * from './helpers';
9
7
  export * from './logger';
8
+ export * from './webflow';
10
9
  export * from './webflow-canvas';
10
+ export type * from '../types';
@@ -1,10 +1,9 @@
1
1
  export * from './animations';
2
2
  export * from './api';
3
- export * from './auth';
4
3
  export * from './browser-storage';
5
- export * from './constants';
6
4
  export * from './custom-code';
7
- export * from './diff-mapper';
5
+ export * from './constants';
8
6
  export * from './helpers';
9
7
  export * from './logger';
8
+ export * from './webflow';
10
9
  export * from './webflow-canvas';
@@ -1,5 +1,4 @@
1
- export type PredefinedLoggerContext = 'finsweet-components' | 'webflow-apps-ui-utils' | 'fast-search' | 'fs-cmp';
2
- export type LoggerContext = PredefinedLoggerContext | (string & Record<never, never>);
1
+ export type LoggerContext = string & Record<never, never>;
3
2
  export interface LogData {
4
3
  [key: string]: any;
5
4
  }
@@ -0,0 +1,2 @@
1
+ export * from './isPreviewMode';
2
+ export * from './router';
@@ -0,0 +1,2 @@
1
+ export * from './isPreviewMode';
2
+ export * from './router';
@@ -0,0 +1 @@
1
+ export declare const isPreviewMode: import("svelte/store").Writable<boolean>;
@@ -0,0 +1,2 @@
1
+ import { writable } from 'svelte/store';
2
+ export const isPreviewMode = writable(false);
@@ -0,0 +1,54 @@
1
+ export declare class CopyJSONButton {
2
+ private readonly element;
3
+ private readonly hiddenTrigger;
4
+ private readonly successCSSClass?;
5
+ private readonly textNode;
6
+ private copyData;
7
+ private successText;
8
+ private errorText;
9
+ private notificationDuration;
10
+ private notificationActive;
11
+ private originalText;
12
+ constructor({ element, copyData, successText, errorText, notificationDuration, successCSSClass }: {
13
+ element: HTMLElement;
14
+ copyData: Record<string, unknown>;
15
+ successText?: string;
16
+ errorText?: string;
17
+ notificationDuration?: number;
18
+ successCSSClass?: string;
19
+ });
20
+ /**
21
+ * Inits the component.
22
+ */
23
+ private init;
24
+ /**
25
+ * Creates a hidden button that will serve as the copy trigger.
26
+ * @returns The new button element.
27
+ */
28
+ private createHiddenTrigger;
29
+ /**
30
+ * Handles click events: triggers a copy command on the element.
31
+ */
32
+ private handleClick;
33
+ /**
34
+ * Handles the copy event, transfers the JSON data to the user's clipboard.
35
+ * @param e
36
+ */
37
+ private handleCopy;
38
+ /**
39
+ * Triggers a `success`/`error` notification on the button.
40
+ * If the `successCSSClass` is specific, it adds/removes on the button.
41
+ * @param state `success` or `error`
42
+ */
43
+ private triggerNotification;
44
+ /**
45
+ * Updates the JSON data to be copied.
46
+ * @param newCopyData
47
+ */
48
+ updateCopyData(newCopyData: Record<string, unknown>): void;
49
+ /**
50
+ * Updates the button's text content.
51
+ * @param newText The new text to be displayed.
52
+ */
53
+ updateTextContent(newText: string): void;
54
+ }
@@ -0,0 +1,117 @@
1
+ import { findTextNode } from '../helpers';
2
+ export class CopyJSONButton {
3
+ element;
4
+ hiddenTrigger;
5
+ successCSSClass;
6
+ textNode;
7
+ copyData;
8
+ successText = 'Copied!';
9
+ errorText = 'Something went wrong';
10
+ notificationDuration = 500;
11
+ notificationActive = false;
12
+ originalText;
13
+ constructor({ element, copyData, successText, errorText, notificationDuration, successCSSClass }) {
14
+ this.element = element;
15
+ this.copyData = copyData;
16
+ if (successText)
17
+ this.successText = successText;
18
+ if (errorText)
19
+ this.errorText = errorText;
20
+ if (notificationDuration)
21
+ this.notificationDuration = notificationDuration;
22
+ if (successCSSClass)
23
+ this.successCSSClass = successCSSClass;
24
+ this.textNode = findTextNode(element) || element;
25
+ this.originalText = this.textNode.textContent || '';
26
+ this.hiddenTrigger = this.createHiddenTrigger();
27
+ this.init();
28
+ }
29
+ /**
30
+ * Inits the component.
31
+ */
32
+ init() {
33
+ const { element, hiddenTrigger } = this;
34
+ element.addEventListener('click', (e) => this.handleClick(e));
35
+ hiddenTrigger.addEventListener('copy', (e) => this.handleCopy(e));
36
+ }
37
+ /**
38
+ * Creates a hidden button that will serve as the copy trigger.
39
+ * @returns The new button element.
40
+ */
41
+ createHiddenTrigger() {
42
+ const { element } = this;
43
+ const button = document.createElement('button');
44
+ button.contentEditable = 'true';
45
+ Object.assign(button.style, {
46
+ position: 'absolute',
47
+ clip: 'rect(1px, 1px, 1px, 1px)',
48
+ clipPath: 'inset(0px 0px 99.9% 99.9%)',
49
+ overflow: 'hidden',
50
+ height: '1px',
51
+ width: '1px',
52
+ padding: '0',
53
+ border: '0'
54
+ });
55
+ (element.parentElement || document.body).appendChild(button);
56
+ return button;
57
+ }
58
+ /**
59
+ * Handles click events: triggers a copy command on the element.
60
+ */
61
+ handleClick(e) {
62
+ e.preventDefault();
63
+ this.hiddenTrigger.focus();
64
+ document.execCommand('copy');
65
+ }
66
+ /**
67
+ * Handles the copy event, transfers the JSON data to the user's clipboard.
68
+ * @param e
69
+ */
70
+ handleCopy(e) {
71
+ try {
72
+ // Copy starter form JSON to clipboard
73
+ e.clipboardData?.setData('application/json', JSON.stringify(this.copyData).trim());
74
+ e.preventDefault();
75
+ // Trigger notification
76
+ this.triggerNotification('success');
77
+ }
78
+ catch {
79
+ this.triggerNotification('error');
80
+ }
81
+ }
82
+ /**
83
+ * Triggers a `success`/`error` notification on the button.
84
+ * If the `successCSSClass` is specific, it adds/removes on the button.
85
+ * @param state `success` or `error`
86
+ */
87
+ triggerNotification(state) {
88
+ const { notificationActive, notificationDuration, originalText, element, successCSSClass, successText, errorText } = this;
89
+ if (notificationActive)
90
+ return;
91
+ this.notificationActive = true;
92
+ this.textNode.textContent = state === 'success' ? successText : errorText;
93
+ if (successCSSClass)
94
+ element.classList.add(successCSSClass);
95
+ window.setTimeout(() => {
96
+ this.textNode.textContent = originalText;
97
+ if (successCSSClass)
98
+ element.classList.remove(successCSSClass);
99
+ this.notificationActive = false;
100
+ }, notificationDuration);
101
+ }
102
+ /**
103
+ * Updates the JSON data to be copied.
104
+ * @param newCopyData
105
+ */
106
+ updateCopyData(newCopyData) {
107
+ this.copyData = newCopyData;
108
+ }
109
+ /**
110
+ * Updates the button's text content.
111
+ * @param newText The new text to be displayed.
112
+ */
113
+ updateTextContent(newText) {
114
+ this.textNode.textContent = newText;
115
+ this.originalText = newText;
116
+ }
117
+ }