@athoscommerce/snap-preact 1.2.3-beta.4 → 1.2.3-beta.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 (214) hide show
  1. package/README.md +16 -0
  2. package/dist/cjs/components/src/components/Atoms/TemplateSelect/TemplateSelect.d.ts +3 -3
  3. package/dist/cjs/components/src/components/Atoms/TemplateSelect/TemplateSelect.d.ts.map +1 -1
  4. package/dist/cjs/components/src/components/Atoms/TemplateSelect/TemplateSelect.js +7 -8
  5. package/dist/cjs/components/src/components/Molecules/ChatInspirationResultMessage/ChatInspirationResultMessage.d.ts +1 -1
  6. package/dist/cjs/components/src/components/Molecules/ChatInspirationResultMessage/ChatInspirationResultMessage.d.ts.map +1 -1
  7. package/dist/cjs/components/src/components/Molecules/ChatInspirationResultMessage/ChatInspirationResultMessage.js +3 -3
  8. package/dist/cjs/components/src/components/Molecules/ChatProductQueryMessage/ChatProductQueryMessage.d.ts +2 -0
  9. package/dist/cjs/components/src/components/Molecules/ChatProductQueryMessage/ChatProductQueryMessage.d.ts.map +1 -1
  10. package/dist/cjs/components/src/components/Molecules/ChatProductQueryMessage/ChatProductQueryMessage.js +24 -25
  11. package/dist/cjs/components/src/components/Molecules/Filter/Filter.d.ts +1 -1
  12. package/dist/cjs/components/src/components/Molecules/Filter/Filter.d.ts.map +1 -1
  13. package/dist/cjs/components/src/components/Molecules/Result/Result.d.ts.map +1 -1
  14. package/dist/cjs/components/src/components/Molecules/Result/Result.js +11 -6
  15. package/dist/cjs/components/src/components/Molecules/SearchInput/SearchInput.d.ts +4 -1
  16. package/dist/cjs/components/src/components/Molecules/SearchInput/SearchInput.d.ts.map +1 -1
  17. package/dist/cjs/components/src/components/Molecules/SearchInput/SearchInput.js +3 -3
  18. package/dist/cjs/components/src/components/Molecules/TemplatesEditor/Components/AbstractedControls.js +5 -5
  19. package/dist/cjs/components/src/components/Molecules/TemplatesEditor/Components/Control.d.ts.map +1 -1
  20. package/dist/cjs/components/src/components/Molecules/TemplatesEditor/Components/Control.js +31 -31
  21. package/dist/cjs/components/src/components/Molecules/TemplatesEditor/TemplatesEditor.d.ts.map +1 -1
  22. package/dist/cjs/components/src/components/Molecules/TemplatesEditor/TemplatesEditor.js +22 -36
  23. package/dist/cjs/components/src/components/Organisms/Chat/Chat.d.ts +7 -0
  24. package/dist/cjs/components/src/components/Organisms/Chat/Chat.d.ts.map +1 -1
  25. package/dist/cjs/components/src/components/Organisms/Chat/Chat.js +638 -431
  26. package/dist/cjs/components/src/components/Organisms/Chat/ChatResult.d.ts.map +1 -1
  27. package/dist/cjs/components/src/components/Organisms/Chat/ChatResult.js +4 -3
  28. package/dist/cjs/components/src/components/Organisms/Chat/MessageText.d.ts +3 -1
  29. package/dist/cjs/components/src/components/Organisms/Chat/MessageText.d.ts.map +1 -1
  30. package/dist/cjs/components/src/components/Organisms/Chat/MessageText.js +22 -19
  31. package/dist/cjs/components/src/components/Organisms/Chat/MessageUser.d.ts +3 -1
  32. package/dist/cjs/components/src/components/Organisms/Chat/MessageUser.d.ts.map +1 -1
  33. package/dist/cjs/components/src/components/Organisms/Chat/MessageUser.js +39 -21
  34. package/dist/cjs/components/src/components/Organisms/Chat/ResultsDisplay.d.ts +1 -1
  35. package/dist/cjs/components/src/components/Organisms/Chat/ResultsDisplay.d.ts.map +1 -1
  36. package/dist/cjs/components/src/components/Organisms/Chat/ResultsDisplay.js +7 -11
  37. package/dist/cjs/components/src/components/Organisms/FilterSummary/FilterSummary.d.ts +2 -2
  38. package/dist/cjs/components/src/components/Organisms/FilterSummary/FilterSummary.d.ts.map +1 -1
  39. package/dist/cjs/components/src/components/Organisms/ProductQuickView/ProductQuickView.d.ts +11 -0
  40. package/dist/cjs/components/src/components/Organisms/ProductQuickView/ProductQuickView.d.ts.map +1 -0
  41. package/dist/cjs/components/src/components/Organisms/ProductQuickView/ProductQuickView.js +461 -0
  42. package/dist/cjs/components/src/components/Organisms/ProductQuickView/index.d.ts +2 -0
  43. package/dist/cjs/components/src/components/Organisms/ProductQuickView/index.d.ts.map +1 -0
  44. package/dist/cjs/components/src/components/Organisms/ProductQuickView/index.js +17 -0
  45. package/dist/cjs/components/src/components/Templates/AutocompleteModal/AutocompleteModal.d.ts.map +1 -1
  46. package/dist/cjs/components/src/components/Templates/AutocompleteModal/AutocompleteModal.js +0 -2
  47. package/dist/cjs/components/src/hooks/useAcRenderedInput.d.ts.map +1 -1
  48. package/dist/cjs/components/src/hooks/useAcRenderedInput.js +65 -15
  49. package/dist/cjs/components/src/hooks/useMediaQuery.d.ts.map +1 -1
  50. package/dist/cjs/components/src/hooks/useMediaQuery.js +3 -1
  51. package/dist/cjs/components/src/index.d.ts +1 -0
  52. package/dist/cjs/components/src/index.d.ts.map +1 -1
  53. package/dist/cjs/components/src/index.js +1 -0
  54. package/dist/cjs/components/src/providers/theme.d.ts +1 -1
  55. package/dist/cjs/components/src/providers/theme.d.ts.map +1 -1
  56. package/dist/cjs/components/src/themes/base/base.js +3 -3
  57. package/dist/cjs/components/src/utilities/Colour/Colour.d.ts +11 -0
  58. package/dist/cjs/components/src/utilities/Colour/Colour.d.ts.map +1 -1
  59. package/dist/cjs/components/src/utilities/Colour/Colour.js +32 -0
  60. package/dist/cjs/src/Instantiators/RecommendationInstantiator.d.ts +1 -0
  61. package/dist/cjs/src/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
  62. package/dist/cjs/src/Instantiators/RecommendationInstantiator.js +161 -123
  63. package/dist/cjs/src/Snap.d.ts +1 -1
  64. package/dist/cjs/src/Snap.d.ts.map +1 -1
  65. package/dist/cjs/src/Snap.js +18 -6
  66. package/dist/cjs/src/SnapHybrid.d.ts.map +1 -1
  67. package/dist/cjs/src/Templates/SnapTemplates.d.ts +13 -72
  68. package/dist/cjs/src/Templates/SnapTemplates.d.ts.map +1 -1
  69. package/dist/cjs/src/Templates/SnapTemplates.js +123 -72
  70. package/dist/cjs/src/Templates/Stores/TargetStore.d.ts +7 -6
  71. package/dist/cjs/src/Templates/Stores/TargetStore.d.ts.map +1 -1
  72. package/dist/cjs/src/Templates/Stores/TargetStore.js +14 -8
  73. package/dist/cjs/src/Templates/Stores/TemplateEditor/TemplateEditorStore.d.ts +58 -8
  74. package/dist/cjs/src/Templates/Stores/TemplateEditor/TemplateEditorStore.d.ts.map +1 -1
  75. package/dist/cjs/src/Templates/Stores/TemplateEditor/TemplateEditorStore.js +467 -96
  76. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/autocompleteControllerUI.d.ts +1 -0
  77. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/autocompleteControllerUI.d.ts.map +1 -1
  78. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/autocompleteControllerUI.js +123 -70
  79. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/configUI.d.ts.map +1 -1
  80. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/configUI.js +9 -3
  81. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/searchControllerUI.d.ts +1 -0
  82. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/searchControllerUI.d.ts.map +1 -1
  83. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/searchControllerUI.js +86 -1
  84. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/themeUI.d.ts.map +1 -1
  85. package/dist/cjs/src/Templates/Stores/TemplateEditor/uiAbstractions/themeUI.js +33 -14
  86. package/dist/cjs/src/Templates/Stores/TemplateStore.d.ts +93 -30
  87. package/dist/cjs/src/Templates/Stores/TemplateStore.d.ts.map +1 -1
  88. package/dist/cjs/src/Templates/Stores/TemplateStore.js +33 -41
  89. package/dist/cjs/src/Templates/Stores/ThemeStore.d.ts +2 -8
  90. package/dist/cjs/src/Templates/Stores/ThemeStore.d.ts.map +1 -1
  91. package/dist/cjs/src/Templates/Stores/ThemeStore.js +3 -28
  92. package/dist/cjs/src/Templates/index.d.ts +1 -1
  93. package/dist/cjs/src/Templates/index.d.ts.map +1 -1
  94. package/dist/cjs/src/create/createChatController.js +1 -1
  95. package/dist/cjs/src/index.d.ts +1 -0
  96. package/dist/cjs/src/index.d.ts.map +1 -1
  97. package/dist/cjs/src/setupEvents.d.ts +13 -0
  98. package/dist/cjs/src/setupEvents.d.ts.map +1 -1
  99. package/dist/cjs/src/setupEvents.js +56 -8
  100. package/dist/cjs/src/types.d.ts +3 -1
  101. package/dist/cjs/src/types.d.ts.map +1 -1
  102. package/dist/cjs/src/utils/combineMerge.d.ts +2 -0
  103. package/dist/cjs/src/utils/combineMerge.d.ts.map +1 -0
  104. package/dist/cjs/src/utils/combineMerge.js +22 -0
  105. package/dist/cjs/src/utils/index.d.ts +1 -0
  106. package/dist/cjs/src/utils/index.d.ts.map +1 -1
  107. package/dist/cjs/src/utils/index.js +3 -1
  108. package/dist/esm/components/src/components/Atoms/TemplateSelect/TemplateSelect.d.ts +3 -3
  109. package/dist/esm/components/src/components/Atoms/TemplateSelect/TemplateSelect.d.ts.map +1 -1
  110. package/dist/esm/components/src/components/Atoms/TemplateSelect/TemplateSelect.js +7 -8
  111. package/dist/esm/components/src/components/Molecules/ChatInspirationResultMessage/ChatInspirationResultMessage.d.ts +1 -1
  112. package/dist/esm/components/src/components/Molecules/ChatInspirationResultMessage/ChatInspirationResultMessage.d.ts.map +1 -1
  113. package/dist/esm/components/src/components/Molecules/ChatInspirationResultMessage/ChatInspirationResultMessage.js +3 -3
  114. package/dist/esm/components/src/components/Molecules/ChatProductQueryMessage/ChatProductQueryMessage.d.ts +2 -0
  115. package/dist/esm/components/src/components/Molecules/ChatProductQueryMessage/ChatProductQueryMessage.d.ts.map +1 -1
  116. package/dist/esm/components/src/components/Molecules/ChatProductQueryMessage/ChatProductQueryMessage.js +24 -26
  117. package/dist/esm/components/src/components/Molecules/Filter/Filter.d.ts +1 -1
  118. package/dist/esm/components/src/components/Molecules/Filter/Filter.d.ts.map +1 -1
  119. package/dist/esm/components/src/components/Molecules/Result/Result.d.ts.map +1 -1
  120. package/dist/esm/components/src/components/Molecules/Result/Result.js +9 -4
  121. package/dist/esm/components/src/components/Molecules/SearchInput/SearchInput.d.ts +4 -1
  122. package/dist/esm/components/src/components/Molecules/SearchInput/SearchInput.d.ts.map +1 -1
  123. package/dist/esm/components/src/components/Molecules/SearchInput/SearchInput.js +3 -3
  124. package/dist/esm/components/src/components/Molecules/TemplatesEditor/Components/AbstractedControls.js +5 -5
  125. package/dist/esm/components/src/components/Molecules/TemplatesEditor/Components/Control.d.ts.map +1 -1
  126. package/dist/esm/components/src/components/Molecules/TemplatesEditor/Components/Control.js +29 -29
  127. package/dist/esm/components/src/components/Molecules/TemplatesEditor/TemplatesEditor.d.ts.map +1 -1
  128. package/dist/esm/components/src/components/Molecules/TemplatesEditor/TemplatesEditor.js +22 -35
  129. package/dist/esm/components/src/components/Organisms/Chat/Chat.d.ts +7 -0
  130. package/dist/esm/components/src/components/Organisms/Chat/Chat.d.ts.map +1 -1
  131. package/dist/esm/components/src/components/Organisms/Chat/Chat.js +557 -359
  132. package/dist/esm/components/src/components/Organisms/Chat/ChatResult.d.ts.map +1 -1
  133. package/dist/esm/components/src/components/Organisms/Chat/ChatResult.js +4 -3
  134. package/dist/esm/components/src/components/Organisms/Chat/MessageText.d.ts +3 -1
  135. package/dist/esm/components/src/components/Organisms/Chat/MessageText.d.ts.map +1 -1
  136. package/dist/esm/components/src/components/Organisms/Chat/MessageText.js +21 -19
  137. package/dist/esm/components/src/components/Organisms/Chat/MessageUser.d.ts +3 -1
  138. package/dist/esm/components/src/components/Organisms/Chat/MessageUser.d.ts.map +1 -1
  139. package/dist/esm/components/src/components/Organisms/Chat/MessageUser.js +36 -21
  140. package/dist/esm/components/src/components/Organisms/Chat/ResultsDisplay.d.ts +1 -1
  141. package/dist/esm/components/src/components/Organisms/Chat/ResultsDisplay.d.ts.map +1 -1
  142. package/dist/esm/components/src/components/Organisms/Chat/ResultsDisplay.js +7 -11
  143. package/dist/esm/components/src/components/Organisms/FilterSummary/FilterSummary.d.ts +2 -2
  144. package/dist/esm/components/src/components/Organisms/FilterSummary/FilterSummary.d.ts.map +1 -1
  145. package/dist/esm/components/src/components/Organisms/ProductQuickView/ProductQuickView.d.ts +11 -0
  146. package/dist/esm/components/src/components/Organisms/ProductQuickView/ProductQuickView.d.ts.map +1 -0
  147. package/dist/esm/components/src/components/Organisms/ProductQuickView/ProductQuickView.js +436 -0
  148. package/dist/esm/components/src/components/Organisms/ProductQuickView/index.d.ts +2 -0
  149. package/dist/esm/components/src/components/Organisms/ProductQuickView/index.d.ts.map +1 -0
  150. package/dist/esm/components/src/components/Organisms/ProductQuickView/index.js +1 -0
  151. package/dist/esm/components/src/components/Templates/AutocompleteModal/AutocompleteModal.d.ts.map +1 -1
  152. package/dist/esm/components/src/components/Templates/AutocompleteModal/AutocompleteModal.js +0 -2
  153. package/dist/esm/components/src/hooks/useAcRenderedInput.d.ts.map +1 -1
  154. package/dist/esm/components/src/hooks/useAcRenderedInput.js +61 -11
  155. package/dist/esm/components/src/hooks/useMediaQuery.d.ts.map +1 -1
  156. package/dist/esm/components/src/hooks/useMediaQuery.js +3 -1
  157. package/dist/esm/components/src/index.d.ts +1 -0
  158. package/dist/esm/components/src/index.d.ts.map +1 -1
  159. package/dist/esm/components/src/index.js +1 -0
  160. package/dist/esm/components/src/providers/theme.d.ts +1 -1
  161. package/dist/esm/components/src/providers/theme.d.ts.map +1 -1
  162. package/dist/esm/components/src/themes/base/base.js +3 -3
  163. package/dist/esm/components/src/utilities/Colour/Colour.d.ts +11 -0
  164. package/dist/esm/components/src/utilities/Colour/Colour.d.ts.map +1 -1
  165. package/dist/esm/components/src/utilities/Colour/Colour.js +30 -0
  166. package/dist/esm/src/Instantiators/RecommendationInstantiator.d.ts +1 -0
  167. package/dist/esm/src/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
  168. package/dist/esm/src/Instantiators/RecommendationInstantiator.js +130 -84
  169. package/dist/esm/src/Snap.d.ts +1 -1
  170. package/dist/esm/src/Snap.d.ts.map +1 -1
  171. package/dist/esm/src/Snap.js +21 -6
  172. package/dist/esm/src/SnapHybrid.d.ts.map +1 -1
  173. package/dist/esm/src/Templates/SnapTemplates.d.ts +13 -72
  174. package/dist/esm/src/Templates/SnapTemplates.d.ts.map +1 -1
  175. package/dist/esm/src/Templates/SnapTemplates.js +137 -78
  176. package/dist/esm/src/Templates/Stores/TargetStore.d.ts +7 -6
  177. package/dist/esm/src/Templates/Stores/TargetStore.d.ts.map +1 -1
  178. package/dist/esm/src/Templates/Stores/TargetStore.js +14 -8
  179. package/dist/esm/src/Templates/Stores/TemplateEditor/TemplateEditorStore.d.ts +58 -8
  180. package/dist/esm/src/Templates/Stores/TemplateEditor/TemplateEditorStore.d.ts.map +1 -1
  181. package/dist/esm/src/Templates/Stores/TemplateEditor/TemplateEditorStore.js +447 -89
  182. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/autocompleteControllerUI.d.ts +1 -0
  183. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/autocompleteControllerUI.d.ts.map +1 -1
  184. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/autocompleteControllerUI.js +118 -66
  185. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/configUI.d.ts.map +1 -1
  186. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/configUI.js +9 -3
  187. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/searchControllerUI.d.ts +1 -0
  188. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/searchControllerUI.d.ts.map +1 -1
  189. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/searchControllerUI.js +82 -1
  190. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/themeUI.d.ts.map +1 -1
  191. package/dist/esm/src/Templates/Stores/TemplateEditor/uiAbstractions/themeUI.js +27 -8
  192. package/dist/esm/src/Templates/Stores/TemplateStore.d.ts +93 -30
  193. package/dist/esm/src/Templates/Stores/TemplateStore.d.ts.map +1 -1
  194. package/dist/esm/src/Templates/Stores/TemplateStore.js +29 -38
  195. package/dist/esm/src/Templates/Stores/ThemeStore.d.ts +2 -8
  196. package/dist/esm/src/Templates/Stores/ThemeStore.d.ts.map +1 -1
  197. package/dist/esm/src/Templates/Stores/ThemeStore.js +3 -26
  198. package/dist/esm/src/Templates/index.d.ts +1 -1
  199. package/dist/esm/src/Templates/index.d.ts.map +1 -1
  200. package/dist/esm/src/create/createChatController.js +1 -1
  201. package/dist/esm/src/index.d.ts +1 -0
  202. package/dist/esm/src/index.d.ts.map +1 -1
  203. package/dist/esm/src/setupEvents.d.ts +13 -0
  204. package/dist/esm/src/setupEvents.d.ts.map +1 -1
  205. package/dist/esm/src/setupEvents.js +25 -8
  206. package/dist/esm/src/types.d.ts +3 -1
  207. package/dist/esm/src/types.d.ts.map +1 -1
  208. package/dist/esm/src/utils/combineMerge.d.ts +2 -0
  209. package/dist/esm/src/utils/combineMerge.d.ts.map +1 -0
  210. package/dist/esm/src/utils/combineMerge.js +16 -0
  211. package/dist/esm/src/utils/index.d.ts +1 -0
  212. package/dist/esm/src/utils/index.d.ts.map +1 -1
  213. package/dist/esm/src/utils/index.js +1 -0
  214. package/package.json +20 -14
@@ -1,9 +1,14 @@
1
- import { StorageStore, StorageType } from '@athoscommerce/snap-store-mobx';
2
- import { observable, makeObservable } from 'mobx';
1
+ import { StorageStore, StorageType } from '@athoscommerce/snap-toolbox';
2
+ import { observable, makeObservable, toJS } from 'mobx';
3
3
  import Color from 'color';
4
4
  import deepmerge from 'deepmerge';
5
5
  import { TEMPLATE_STORE_KEY } from '../TemplateStore';
6
- import { configUI, themeUI, searchControllerUI, autocompleteControllerUI, updateAutocompleteControllerState } from './uiAbstractions';
6
+ import { configUI, themeUI, searchControllerUI,
7
+ // searchTargetUI,
8
+ autocompleteControllerUI,
9
+ // autocompleteTargetUI,
10
+ updateAutocompleteControllerState, searchTargetUI, autocompleteTargetUI, } from './uiAbstractions';
11
+ import { combineMerge } from '../../../utils';
7
12
  const THEME_VARIABLE_DEFAULTS = {
8
13
  breakpoints: {
9
14
  mobile: 600,
@@ -19,20 +24,31 @@ const THEME_VARIABLE_DEFAULTS = {
19
24
  };
20
25
  export class TemplateEditorStore {
21
26
  constructor({ templatesStore }) {
22
- this.state = {
27
+ this.storedState = {
23
28
  hidden: false,
24
29
  activeTab: 'configuration',
25
30
  };
31
+ this.state = {
32
+ activeDomSelector: '',
33
+ };
26
34
  this.overrides = {
27
35
  config: {},
28
36
  controller: {},
29
37
  theme: {},
38
+ targets: {
39
+ search: [],
40
+ autocomplete: [],
41
+ },
30
42
  };
31
43
  this.initial = {
32
44
  config: {
33
45
  language: 'en',
34
46
  currency: 'usd',
35
47
  },
48
+ targets: {
49
+ search: [],
50
+ autocomplete: [],
51
+ },
36
52
  controller: {},
37
53
  theme: {
38
54
  extends: 'base',
@@ -49,6 +65,10 @@ export class TemplateEditorStore {
49
65
  search: searchControllerUI(this),
50
66
  autocomplete: autocompleteControllerUI(this),
51
67
  },
68
+ targets: {
69
+ search: searchTargetUI(this),
70
+ autocomplete: autocompleteTargetUI(this),
71
+ },
52
72
  };
53
73
  this.setThemeOverride = (obj) => {
54
74
  const { path, value } = obj;
@@ -57,40 +77,157 @@ export class TemplateEditorStore {
57
77
  return acc && acc[key];
58
78
  }, this.initial.theme);
59
79
  const themeConfigOverrides = generateObject(path, value == initialValue ? undefined : value);
60
- this.overrides.theme = removeEmptyObjects(deepmerge(this.overrides.theme || {}, themeConfigOverrides));
80
+ this.overrides.theme = removeEmptyObjects(deepmerge(this.overrides.theme || {}, themeConfigOverrides || {}));
61
81
  this.storage.set('overrides.theme', this.overrides.theme);
62
82
  const mergedOverrides = deepmerge(this.initial.theme || {}, this.overrides.theme || {});
83
+ const transformedMergedOverrides = transformThemeComponentOverrides(mergedOverrides);
63
84
  // update all themes with the new overrides
64
85
  Object.keys(this.templatesStore.themes.library).forEach((themeName) => {
65
86
  const themeStore = this.templatesStore.themes.library[themeName];
66
- themeStore.setEditorOverrides({ variables: mergedOverrides.variables || {} });
87
+ themeStore.setEditorOverrides(transformedMergedOverrides);
67
88
  });
68
89
  };
90
+ // ['variables', 'colors', 'primary']
91
+ // store.setThemeOverride({ path: ['variables', 'breakpoints', 'mobile'], value });
92
+ // ['search', '[0]', 'selector']
93
+ // store.setTargetOverride({ path: ['search', '[0]'], value });
94
+ // store.setTargetOverride({ path: ['search', '[0]', 'selector'], value });
95
+ // store.setTargetOverride({ path: ['search', '[0]'], value }); --- value = {...}
96
+ this.setTargetOverride = (obj) => {
97
+ const path = obj.path;
98
+ let value = obj.value;
99
+ /*
100
+ this.initial.targets = {
101
+ search: [
102
+ {...},
103
+ {...},
104
+ ]
105
+ }
106
+ */
107
+ const targetFeature = path[0];
108
+ // const lastPath = path[path.length - 1];
109
+ let targetIndex = -1;
110
+ // grab the initial config value using the path provided
111
+ const initialValue = path.reduce((acc, key) => {
112
+ // handle array index access
113
+ // e.g., [0], [1], etc.
114
+ // if the key is in the format of [index], convert it to a number and access the array
115
+ // otherwise, access the object property as usual
116
+ try {
117
+ const keyIndex = Number(key.replace(/^\[(\d+)\]$/, '$1'));
118
+ if (Number.isNaN(keyIndex)) {
119
+ // not an index position
120
+ return acc && acc[key];
121
+ }
122
+ else {
123
+ // we have a string key - use it to set the accumulator
124
+ targetIndex = keyIndex;
125
+ return acc && acc[keyIndex];
126
+ }
127
+ }
128
+ catch (error) {
129
+ // handle error
130
+ console.error('Error accessing path in initial targets:', error);
131
+ return undefined;
132
+ }
133
+ }, this.initial.targets);
134
+ const targetOverrides = generateObject(path, value == initialValue ? undefined : value);
135
+ const merged = deepmerge(toJS(this.overrides.targets) || {}, toJS(targetOverrides) || {}, { arrayMerge: combineMerge });
136
+ this.overrides.targets = removeEmptyObjects(merged);
137
+ this.storage.set('overrides.targets', this.overrides.targets);
138
+ // const plainInitial = convertObservableToPlain(this.initial.targets);
139
+ // const plainOverrides = convertObservableToPlain(this.overrides.targets);
140
+ const mergedOverrides = deepmerge(toJS(this.initial.targets) || {}, toJS(this.overrides.targets) || {}, {
141
+ arrayMerge: combineMerge,
142
+ });
143
+ const finalPath = path[path.length - 1];
144
+ if (finalPath == 'selector' && targetIndex > -1) {
145
+ // if reset button was clicked value will be undefined
146
+ if (typeof value == 'undefined') {
147
+ value = initialValue;
148
+ }
149
+ // needs to have a value and some actual elem to find
150
+ if (typeof value == 'string' && value.length > 1 && document.querySelector(value)) {
151
+ const activeTargeterKey = Object.keys(window.athos.controller[targetFeature].targeters)[targetIndex];
152
+ if (activeTargeterKey) {
153
+ const oldSelector = window.athos.controller[targetFeature].targeters[activeTargeterKey].targets[0].selector;
154
+ const elem = document.querySelector(oldSelector || '');
155
+ if (targetFeature == 'search' && elem) {
156
+ //create clone of elem with all attributes
157
+ const clonedElement = elem.cloneNode(true);
158
+ clonedElement.innerHTML = '';
159
+ //inject clone right after elem
160
+ elem.insertAdjacentElement('afterend', clonedElement);
161
+ //delete elem so targeter can retarget an element thats already been targeted
162
+ elem.remove();
163
+ }
164
+ window.athos.controller[targetFeature].targeters[activeTargeterKey].targets[0].selector = value;
165
+ /*
166
+ selector
167
+ inputSelector
168
+
169
+ targetSelector -> selector
170
+ inputSelector (optional) -> inputSelector
171
+ DomTargeter
172
+ * selector = selector
173
+ * props.input = inputSelector (optional)
174
+ */
175
+ window.athos.controller[targetFeature].retarget();
176
+ }
177
+ }
178
+ }
179
+ else if (finalPath == 'inputSelector' && targetIndex > -1) {
180
+ const activeTargeterKey = Object.keys(window.athos.controller[targetFeature].targeters)[targetIndex];
181
+ window.athos.controller[targetFeature].targeters[activeTargeterKey].targets[0].props.input = value;
182
+ window.athos.controller[targetFeature].retarget();
183
+ }
184
+ // if the component changed we need to tell the targetStore about it via:
185
+ const targetFeatureSet = this.templatesStore.targets[targetFeature];
186
+ if (targetFeatureSet && targetIndex != -1) {
187
+ const target = targetFeatureSet[targetIndex];
188
+ // if (target && lastPath) {
189
+ // const finalValue = mergedOverrides[targetFeature][targetIndex]?.selector;
190
+ // finalValue && target.setValue(lastPath, finalValue);
191
+ // }
192
+ // update values in target
193
+ const mergedTarget = mergedOverrides[targetFeature][targetIndex];
194
+ Object.keys(mergedTarget).forEach((key) => {
195
+ const value = mergedTarget[key];
196
+ target.setValue(key, value);
197
+ });
198
+ }
199
+ // target.setComponent
200
+ };
69
201
  this.templatesStore = templatesStore;
70
202
  this.storage = new StorageStore({ type: StorageType.local, key: TEMPLATE_STORE_KEY });
71
- this.state = this.storage.get('editor') || this.state;
72
- this.overrides = this.storage.get('overrides') || this.overrides;
73
- // prevent empty objects in overrides
74
- this.overrides.config = this.overrides.config || {};
75
- this.overrides.controller = this.overrides.controller || {};
76
- this.overrides.theme = this.overrides.theme || {};
203
+ this.storedState = this.storage.get('editor') || this.storedState;
77
204
  this.initial.config = deepmerge(this.initial.config, templatesStore.config.config);
78
205
  this.initial.controller = {}; // set when registering controllers
206
+ // set initial targets
207
+ if (templatesStore.config.search?.targets)
208
+ this.initial.targets.search = templatesStore.config.search?.targets;
209
+ if (templatesStore.config.autocomplete?.targets)
210
+ this.initial.targets.autocomplete = templatesStore.config.autocomplete?.targets;
79
211
  const themeConfig = JSON.parse(JSON.stringify(templatesStore.config.theme || {}));
80
212
  delete themeConfig.style;
81
- delete themeConfig.overrides;
82
213
  this.initial.theme = deepmerge(this.initial.theme, themeConfig);
83
- // normalize all colors to hexadecimal format using the Color library
84
- Object.keys(this.initial.theme.variables.colors).forEach((key) => {
85
- const color = this.initial.theme.variables.colors[key];
86
- this.initial.theme.variables.colors[key] = Color(color).hex();
214
+ // apply stored overrides (normalizes, persists, and triggers theme changes)
215
+ const storedOverrides = this.storage.get('overrides') || {};
216
+ this.setOverrides({
217
+ config: storedOverrides.config,
218
+ theme: storedOverrides.theme,
219
+ search: {
220
+ targets: storedOverrides.targets?.search,
221
+ settings: storedOverrides.controller?.search,
222
+ },
223
+ autocomplete: {
224
+ targets: storedOverrides.targets?.autocomplete,
225
+ settings: storedOverrides.controller?.autocomplete,
226
+ },
87
227
  });
88
- // switch to the theme set in the initial config if no override is set
89
- this.setTheme(this.overrides.theme.extends ?? this.initial.theme.extends);
90
- // initialize themes with overrides
91
- this.setThemeOverride({ path: [], value: undefined });
92
228
  this.storage.set('initial', this.initial);
93
229
  makeObservable(this, {
230
+ storedState: observable,
94
231
  state: observable,
95
232
  overrides: observable,
96
233
  initial: observable,
@@ -102,12 +239,77 @@ export class TemplateEditorStore {
102
239
  // });
103
240
  }
104
241
  switchTabs(tab) {
105
- this.state.activeTab = tab;
106
- this.storage.set('editor', this.state);
242
+ this.storedState.activeTab = tab;
243
+ this.storage.set('editor', this.storedState);
107
244
  }
108
245
  toggleHide(hide) {
109
- this.state.hidden = hide;
110
- this.storage.set('editor', this.state);
246
+ this.storedState.hidden = hide;
247
+ this.storage.set('editor', this.storedState);
248
+ }
249
+ setOverrides(overrides) {
250
+ // normalize and set overrides, preventing empty objects
251
+ this.overrides.config = overrides.config || {};
252
+ this.overrides.controller = {
253
+ search: overrides.search?.settings,
254
+ autocomplete: overrides.autocomplete?.settings,
255
+ };
256
+ this.overrides.theme = overrides.theme || {};
257
+ this.overrides.targets = {
258
+ search: overrides.search?.targets || [],
259
+ autocomplete: overrides.autocomplete?.targets || [],
260
+ };
261
+ // persist each section to storage
262
+ this.storage.set('overrides.config', this.overrides.config);
263
+ this.storage.set('overrides.controller', this.overrides.controller);
264
+ this.storage.set('overrides.targets', this.overrides.targets);
265
+ // apply language/currency overrides to the templates store
266
+ const language = (this.overrides.config.language || this.initial.config.language);
267
+ const currency = (this.overrides.config.currency || this.initial.config.currency);
268
+ this.templatesStore.setLanguage(language);
269
+ this.templatesStore.setCurrency(currency);
270
+ // re-apply controller configs with merged overrides
271
+ // (skip if initial.controller hasn't been populated yet — registerController handles that case)
272
+ ['search', 'autocomplete'].forEach((type) => {
273
+ const controller = window.athos?.controller?.[type];
274
+ if (controller && this.initial.controller[type]) {
275
+ // reset settings to initial values first, then merge overrides on top
276
+ // (controller.config.settings already has old overrides baked in, so we can't use it as a base)
277
+ const cleanConfig = { ...controller.config, settings: JSON.parse(JSON.stringify(this.initial.controller[type])) };
278
+ const mergedConfig = deepmerge(cleanConfig, {
279
+ settings: this.overrides.controller[type] || {},
280
+ });
281
+ controller.setConfig(mergedConfig);
282
+ }
283
+ });
284
+ // re-apply target overrides (component, selector, etc.)
285
+ ['search', 'autocomplete'].forEach((feature) => {
286
+ const targetFeatureSet = this.templatesStore.targets[feature];
287
+ const mergedTargets = deepmerge(toJS(this.initial.targets[feature]) || [], toJS(this.overrides.targets[feature]) || [], { arrayMerge: combineMerge });
288
+ targetFeatureSet.forEach((target, index) => {
289
+ const mergedTarget = mergedTargets[index];
290
+ if (mergedTarget) {
291
+ Object.keys(mergedTarget).forEach((key) => {
292
+ target.setValue(key, mergedTarget[key]);
293
+ });
294
+ }
295
+ });
296
+ });
297
+ // apply theme changes (also persists overrides.theme)
298
+ this.setTheme(this.overrides.theme.extends ?? this.initial.theme.extends);
299
+ }
300
+ resetOverrides() {
301
+ this.storage.set('overrides', undefined);
302
+ this.setOverrides({});
303
+ }
304
+ setActiveDomSelector(selectorId) {
305
+ if (selectorId?.length) {
306
+ this.state.activeDomSelector = selectorId;
307
+ this.toggleHide(true);
308
+ }
309
+ else {
310
+ this.state.activeDomSelector = '';
311
+ this.toggleHide(false);
312
+ }
111
313
  }
112
314
  setConfigOverride(obj) {
113
315
  const { path, value } = obj;
@@ -119,7 +321,6 @@ export class TemplateEditorStore {
119
321
  const updatedOverrides = removeEmptyObjects(deepmerge(this.overrides.config || {}, configOverrides));
120
322
  this.overrides.config = updatedOverrides;
121
323
  this.storage.set('overrides.config', updatedOverrides);
122
- // TODO: handle setting language and currency separately
123
324
  if (path[0] === 'language') {
124
325
  this.templatesStore.setLanguage((value || initialValue)).then(() => {
125
326
  this.storage.set('overrides.config', updatedOverrides);
@@ -138,24 +339,42 @@ export class TemplateEditorStore {
138
339
  }
139
340
  this.overrides.theme = deepmerge(this.overrides.theme, updatedConfig);
140
341
  this.storage.set('overrides.theme', this.overrides.theme);
342
+ // update initial variables from the newly selected theme's raw definition
343
+ const themeDefinition = this.templatesStore.library.themes[themeName];
344
+ if (themeDefinition) {
345
+ const themeConfig = JSON.parse(JSON.stringify(this.templatesStore.config.theme || {}));
346
+ delete themeConfig.style;
347
+ this.initial.theme.variables = deepmerge(themeDefinition.variables || {}, themeConfig.variables || {});
348
+ // normalize colors to hexadecimal format
349
+ Object.keys(this.initial.theme.variables.colors).forEach((key) => {
350
+ const color = this.initial.theme.variables.colors[key];
351
+ this.initial.theme.variables.colors[key] = Color(color).hex();
352
+ });
353
+ this.storage.set('initial', this.initial);
354
+ }
355
+ // update all library themes with recomputed editor overrides based on the new theme's variables
356
+ const mergedOverrides = deepmerge(this.initial.theme || {}, this.overrides.theme || {});
357
+ const transformedMergedOverrides = transformThemeComponentOverrides(mergedOverrides);
358
+ Object.keys(this.templatesStore.themes.library).forEach((libThemeName) => {
359
+ const themeStore = this.templatesStore.themes.library[libThemeName];
360
+ themeStore.setEditorOverrides(transformedMergedOverrides);
361
+ });
141
362
  // loop through all targets in templateStore and call setTheme on them all
142
363
  Object.keys(this.templatesStore.targets).forEach((feature) => {
143
364
  // loop through all the features (search, autocomplete, recommendations)
144
365
  if (feature == 'recommendation') {
145
- const recommendationObj = this.templatesStore.targets[feature];
146
- Object.keys(recommendationObj).forEach((recType) => {
147
- const targetMap = recommendationObj[recType];
148
- Object.keys(targetMap).forEach((target) => {
149
- const targetStore = targetMap[target];
150
- targetStore.setTheme(themeName, 'library');
366
+ const recommendationTargetObject = this.templatesStore.targets.recommendation;
367
+ Object.keys(recommendationTargetObject).forEach((recType) => {
368
+ const featureTargets = recommendationTargetObject[recType];
369
+ featureTargets.forEach((target) => {
370
+ target.setTheme(themeName, 'library');
151
371
  });
152
372
  });
153
373
  }
154
374
  else {
155
- const targetMap = this.templatesStore.targets[feature];
156
- Object.keys(targetMap).forEach((target) => {
157
- const targetStore = targetMap[target];
158
- targetStore.setTheme(themeName, 'library');
375
+ const featureTargets = this.templatesStore.targets[feature];
376
+ featureTargets.forEach((target) => {
377
+ target.setTheme(themeName, 'library');
159
378
  });
160
379
  }
161
380
  });
@@ -201,35 +420,35 @@ export class TemplateEditorStore {
201
420
  }
202
421
  getTargets() {
203
422
  const storeTargets = this.templatesStore.targets;
204
- const searchTargets = Object.keys(storeTargets.search || {}).map((target) => ({
423
+ const searchTargets = storeTargets.search.map((target) => ({
205
424
  type: 'search',
206
425
  target,
207
- template: storeTargets.search[target],
208
- selector: storeTargets.search[target].selector,
426
+ template: target.component,
427
+ selector: target.selector,
209
428
  }));
210
- const autocompleteTargets = Object.keys(storeTargets.autocomplete || {}).map((target) => ({
429
+ const autocompleteTargets = storeTargets.autocomplete.map((target) => ({
211
430
  type: 'autocomplete',
212
431
  target,
213
- template: storeTargets.autocomplete[target],
214
- selector: storeTargets.autocomplete[target].selector,
432
+ template: target.component,
433
+ selector: target.selector,
215
434
  }));
216
- const recommendationBundleTargets = Object.keys(storeTargets.recommendation.bundle || {}).map((target) => ({
435
+ const recommendationBundleTargets = storeTargets.recommendation.bundle.map((target) => ({
217
436
  type: 'recommendation/bundle',
218
437
  target,
219
- template: storeTargets.recommendation.bundle[target],
220
- selector: storeTargets.recommendation.bundle[target].selector,
438
+ template: target.component,
439
+ selector: target.selector,
221
440
  }));
222
- const recommendationDefaultTargets = Object.keys(storeTargets.recommendation.default || {}).map((target) => ({
441
+ const recommendationDefaultTargets = storeTargets.recommendation.default.map((target) => ({
223
442
  type: 'recommendation/default',
224
443
  target,
225
- template: storeTargets.recommendation.default[target],
226
- selector: storeTargets.recommendation.default[target].selector,
444
+ template: target.component,
445
+ selector: target.selector,
227
446
  }));
228
- const recommendationEmailTargets = Object.keys(storeTargets.recommendation.email || {}).map((target) => ({
447
+ const recommendationEmailTargets = storeTargets.recommendation.email.map((target) => ({
229
448
  type: 'recommendation/email',
230
449
  target,
231
- template: storeTargets.recommendation.email[target],
232
- selector: storeTargets.recommendation.email[target].selector,
450
+ template: target.component,
451
+ selector: target.selector,
233
452
  }));
234
453
  const targets = [
235
454
  ...searchTargets,
@@ -240,44 +459,125 @@ export class TemplateEditorStore {
240
459
  ];
241
460
  return targets;
242
461
  }
243
- generateTemplatesConfig() {
462
+ generateTemplatesConfig(options) {
463
+ const resolveSource = (opt) => {
464
+ if (opt === undefined || opt === true)
465
+ return { initial: true, overrides: true };
466
+ if (opt === false)
467
+ return { initial: false, overrides: false };
468
+ return { initial: opt.initial ?? true, overrides: opt.overrides ?? true };
469
+ };
470
+ const configOpt = resolveSource(options?.config);
471
+ let themeExtendsOpt;
472
+ let themeVariablesOpt;
473
+ let themeOverridesOpt;
474
+ if (options?.theme === undefined || options?.theme === true) {
475
+ themeExtendsOpt = { initial: true, overrides: true };
476
+ themeVariablesOpt = { initial: true, overrides: true };
477
+ themeOverridesOpt = { initial: true, overrides: true };
478
+ }
479
+ else if (options?.theme === false) {
480
+ themeExtendsOpt = { initial: false, overrides: false };
481
+ themeVariablesOpt = { initial: false, overrides: false };
482
+ themeOverridesOpt = { initial: false, overrides: false };
483
+ }
484
+ else {
485
+ themeExtendsOpt = resolveSource(options.theme.extends);
486
+ themeVariablesOpt = resolveSource(options.theme.variables);
487
+ themeOverridesOpt = resolveSource(options.theme.overrides);
488
+ }
489
+ const includeTheme = themeExtendsOpt.initial ||
490
+ themeExtendsOpt.overrides ||
491
+ themeVariablesOpt.initial ||
492
+ themeVariablesOpt.overrides ||
493
+ themeOverridesOpt.initial ||
494
+ themeOverridesOpt.overrides;
244
495
  const originalConfig = JSON.parse(JSON.stringify(this.templatesStore.config));
245
496
  delete originalConfig.search;
246
497
  delete originalConfig.autocomplete;
247
498
  delete originalConfig.recommendation;
248
499
  delete originalConfig.components;
249
- const storageConfigData = (this.storage.get('overrides.config') || {});
250
- const themeConfigData = (this.storage.get('overrides.theme') || {});
251
- const overrideConfig = { config: storageConfigData, theme: themeConfigData };
500
+ // selectively strip initial config
501
+ if (!configOpt.initial) {
502
+ delete originalConfig.config;
503
+ }
504
+ // selectively strip initial theme fields
505
+ if (!includeTheme) {
506
+ delete originalConfig.theme;
507
+ }
508
+ else if (originalConfig.theme) {
509
+ if (!themeExtendsOpt.initial)
510
+ delete originalConfig.theme.extends;
511
+ if (!themeVariablesOpt.initial)
512
+ delete originalConfig.theme.variables;
513
+ if (!themeOverridesOpt.initial)
514
+ delete originalConfig.theme.overrides;
515
+ }
516
+ const overrideConfig = {};
517
+ if (configOpt.overrides) {
518
+ overrideConfig.config = (this.storage.get('overrides.config') || {});
519
+ }
520
+ if (includeTheme) {
521
+ const themeOverrideData = (this.storage.get('overrides.theme') || {});
522
+ const filteredTheme = {};
523
+ if (themeExtendsOpt.overrides && themeOverrideData.extends !== undefined)
524
+ filteredTheme.extends = themeOverrideData.extends;
525
+ if (themeVariablesOpt.overrides && themeOverrideData.variables !== undefined)
526
+ filteredTheme.variables = themeOverrideData.variables;
527
+ if (themeOverridesOpt.overrides && themeOverrideData.overrides !== undefined)
528
+ filteredTheme.overrides = themeOverrideData.overrides;
529
+ if (Object.keys(filteredTheme).length) {
530
+ overrideConfig.theme = filteredTheme;
531
+ }
532
+ }
252
533
  const targets = this.getTargets();
253
- const searchTargets = targets
254
- .filter((target) => target.type === 'search')
255
- .map((target) => ({
256
- selector: target.selector,
257
- component: target.template.component,
258
- }));
259
- const autocompleteTargets = targets
260
- .filter((target) => target.type === 'autocomplete')
261
- .map((target) => ({
262
- selector: target.selector,
263
- component: target.template.component,
264
- }));
265
- // add search controller settings
266
- if (searchTargets.length) {
267
- overrideConfig.search = {
268
- targets: searchTargets,
269
- settings: this.overrides.controller.search || {},
270
- };
534
+ if (options?.search !== false) {
535
+ const searchTargets = targets
536
+ .filter((target) => target.type === 'search')
537
+ .map((target) => ({
538
+ selector: target.selector,
539
+ component: target.target.component,
540
+ }));
541
+ if (searchTargets.length) {
542
+ overrideConfig.search = {
543
+ targets: searchTargets,
544
+ settings: this.overrides.controller.search || {},
545
+ };
546
+ }
271
547
  }
272
- // add autocomplete controller settings
273
- if (autocompleteTargets.length) {
274
- overrideConfig.autocomplete = {
275
- targets: autocompleteTargets,
276
- settings: this.overrides.controller.autocomplete || {},
277
- };
548
+ if (options?.autocomplete !== false) {
549
+ const autocompleteTargets = targets
550
+ .filter((target) => target.type === 'autocomplete')
551
+ .map((target) => ({
552
+ selector: target.selector,
553
+ component: target.target.component,
554
+ }));
555
+ if (autocompleteTargets.length) {
556
+ overrideConfig.autocomplete = {
557
+ targets: autocompleteTargets,
558
+ settings: this.overrides.controller.autocomplete || {},
559
+ };
560
+ }
278
561
  }
279
562
  const config = deepmerge(originalConfig, overrideConfig);
280
- return config;
563
+ const cleaned = removeEmptyObjects(config);
564
+ if (!options?.unlocked) {
565
+ delete cleaned.unlocked;
566
+ }
567
+ // reorder keys: unlocked, config, theme, search, autocomplete, then everything else
568
+ const orderedKeys = ['unlocked', 'config', 'theme', 'search', 'autocomplete'];
569
+ const ordered = {};
570
+ for (const key of orderedKeys) {
571
+ if (key in cleaned) {
572
+ ordered[key] = cleaned[key];
573
+ }
574
+ }
575
+ for (const key of Object.keys(cleaned)) {
576
+ if (!(key in ordered)) {
577
+ ordered[key] = cleaned[key];
578
+ }
579
+ }
580
+ return ordered;
281
581
  }
282
582
  }
283
583
  function removeEmptyObjects(object) {
@@ -286,16 +586,33 @@ function removeEmptyObjects(object) {
286
586
  if (obj === null || typeof obj !== 'object') {
287
587
  return obj;
288
588
  }
589
+ // Handle arrays differently from objects
590
+ if (Array.isArray(obj)) {
591
+ return obj
592
+ .map((item) => cleanObj(item))
593
+ .filter((item) => {
594
+ // Keep non-null/undefined items
595
+ if (item === null || item === undefined)
596
+ return false;
597
+ // Keep non-empty objects/arrays
598
+ if (typeof item === 'object') {
599
+ return Array.isArray(item) ? item.length > 0 : Object.keys(item).length > 0;
600
+ }
601
+ // Keep primitive values
602
+ return true;
603
+ });
604
+ }
605
+ // Handle regular objects
289
606
  const result = {};
290
607
  Object.entries(obj).forEach(([key, value]) => {
291
608
  // Skip undefined values
292
609
  if (value === undefined)
293
610
  return;
294
611
  if (value !== null && typeof value === 'object') {
295
- // Recursively clean nested objects
612
+ // Recursively clean nested objects/arrays
296
613
  const cleanedValue = cleanObj(value);
297
- // Only add non-empty objects
298
- if (Object.keys(cleanedValue).length > 0) {
614
+ // Only add non-empty objects/arrays
615
+ if (Array.isArray(cleanedValue) ? cleanedValue.length > 0 : Object.keys(cleanedValue).length > 0) {
299
616
  result[key] = cleanedValue;
300
617
  }
301
618
  }
@@ -310,17 +627,58 @@ function removeEmptyObjects(object) {
310
627
  return cleanObj(object);
311
628
  }
312
629
  function generateObject(path, value) {
630
+ // modify this function to handle array index access
631
+ // e.g., [0], [1], etc.
632
+ // if the key is in the format of [index], convert it to a number and create an array
633
+ // otherwise, create an object property as usual
634
+ // Example:
635
+ // path = ['search', '[0]', 'selector'], value = '#new-selector'
636
+ // returns { search: [ { selector: '#new-selector' } ] }
637
+ // Example:
638
+ // path = ['search', '[0]'], value = { selector: '#new-selector', component: 'Search' }
639
+ // returns { search: [ { selector: '#new-selector', component: 'Search' } ] }
640
+ // Example:
641
+ // path = ['search', 'stuff', 'thing'], value = 'whatever'
642
+ // returns { search: { stuff: { thing: 'whatever' } } }
643
+ // Example:
644
+ // path = ['[0]'], value = { selector: '#new-selector', component: 'Search' }
645
+ // returns [ { selector: '#new-selector', component: 'Search' } ]
646
+ // if (typeof value == 'undefined') return {} as T;
313
647
  return path
314
648
  .slice()
315
649
  .reverse()
316
- .reduce((res, key, index) => {
317
- if (index === 0) {
318
- return {
319
- [key]: value,
320
- };
650
+ .reduce((res, key) => {
651
+ // Check if key is array index notation like [0], [1], etc.
652
+ const arrayIndexMatch = key.match(/^\[(\d+)\]$/);
653
+ if (arrayIndexMatch) {
654
+ // Extract the index number
655
+ const index = parseInt(arrayIndexMatch[1], 10);
656
+ // Create an array with the element at the specified index
657
+ const arr = [];
658
+ arr[index] = res;
659
+ return arr;
321
660
  }
661
+ // Regular object property
322
662
  return {
323
663
  [key]: res,
324
664
  };
325
- }, {});
665
+ }, value);
666
+ }
667
+ function transformThemeComponentOverrides(theme) {
668
+ const { overrides, variables } = theme;
669
+ const result = {};
670
+ if (variables) {
671
+ result.variables = variables;
672
+ }
673
+ if (overrides?.default) {
674
+ result.components = overrides.default;
675
+ }
676
+ if (overrides?.mobile || overrides?.tablet || overrides?.desktop) {
677
+ result.responsive = {
678
+ mobile: overrides?.mobile,
679
+ tablet: overrides?.tablet,
680
+ desktop: overrides?.desktop,
681
+ };
682
+ }
683
+ return result;
326
684
  }