@builder.io/sdk-svelte 1.0.26 → 1.0.28

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 (95) hide show
  1. package/lib/browser/blocks/accordion/accordion.svelte +160 -0
  2. package/lib/browser/blocks/accordion/accordion.svelte.d.ts +24 -0
  3. package/lib/browser/blocks/accordion/accordion.types.d.ts +12 -0
  4. package/lib/browser/blocks/accordion/accordion.types.js +1 -0
  5. package/lib/browser/blocks/accordion/component-info.d.ts +2 -0
  6. package/lib/browser/blocks/accordion/component-info.js +123 -0
  7. package/lib/browser/blocks/accordion/helpers.d.ts +1 -0
  8. package/lib/browser/blocks/accordion/helpers.js +3 -0
  9. package/lib/browser/blocks/accordion/index.d.ts +1 -0
  10. package/lib/browser/blocks/accordion/index.js +1 -0
  11. package/lib/browser/blocks/tabs/tabs.svelte +13 -10
  12. package/lib/browser/blocks/tabs/tabs.svelte.d.ts +2 -2
  13. package/lib/browser/components/block/animator.d.ts +0 -1
  14. package/lib/browser/components/block/animator.js +3 -3
  15. package/lib/browser/components/block/block.helpers.js +2 -2
  16. package/lib/browser/components/block/components/block-styles.svelte +2 -2
  17. package/lib/browser/components/content/components/enable-editor.svelte +1 -1
  18. package/lib/browser/components/content-variants/content-variants.types.d.ts +1 -1
  19. package/lib/browser/constants/builder-registered-components.js +5 -0
  20. package/lib/browser/constants/sdk-version.d.ts +1 -1
  21. package/lib/browser/constants/sdk-version.js +1 -1
  22. package/lib/browser/functions/camel-to-kebab-case.d.ts +1 -1
  23. package/lib/browser/functions/camel-to-kebab-case.js +1 -1
  24. package/lib/browser/functions/get-content/generate-content-url.js +2 -2
  25. package/lib/browser/helpers/flatten.d.ts +10 -0
  26. package/lib/browser/helpers/flatten.js +20 -0
  27. package/lib/edge/blocks/accordion/accordion.svelte +160 -0
  28. package/lib/edge/blocks/accordion/accordion.svelte.d.ts +24 -0
  29. package/lib/edge/blocks/accordion/accordion.types.d.ts +12 -0
  30. package/lib/edge/blocks/accordion/accordion.types.js +1 -0
  31. package/lib/edge/blocks/accordion/component-info.d.ts +2 -0
  32. package/lib/edge/blocks/accordion/component-info.js +123 -0
  33. package/lib/edge/blocks/accordion/helpers.d.ts +1 -0
  34. package/lib/edge/blocks/accordion/helpers.js +3 -0
  35. package/lib/edge/blocks/accordion/index.d.ts +1 -0
  36. package/lib/edge/blocks/accordion/index.js +1 -0
  37. package/lib/edge/blocks/tabs/tabs.svelte +13 -10
  38. package/lib/edge/blocks/tabs/tabs.svelte.d.ts +2 -2
  39. package/lib/edge/components/block/animator.d.ts +0 -1
  40. package/lib/edge/components/block/animator.js +3 -3
  41. package/lib/edge/components/block/block.helpers.js +2 -2
  42. package/lib/edge/components/block/components/block-styles.svelte +2 -2
  43. package/lib/edge/components/content/components/enable-editor.svelte +1 -1
  44. package/lib/edge/components/content-variants/content-variants.types.d.ts +1 -1
  45. package/lib/edge/constants/builder-registered-components.js +5 -0
  46. package/lib/edge/constants/sdk-version.d.ts +1 -1
  47. package/lib/edge/constants/sdk-version.js +1 -1
  48. package/lib/edge/functions/camel-to-kebab-case.d.ts +1 -1
  49. package/lib/edge/functions/camel-to-kebab-case.js +1 -1
  50. package/lib/edge/functions/get-content/generate-content-url.js +2 -2
  51. package/lib/edge/helpers/flatten.d.ts +10 -0
  52. package/lib/edge/helpers/flatten.js +20 -0
  53. package/lib/node/blocks/accordion/accordion.svelte +160 -0
  54. package/lib/node/blocks/accordion/accordion.svelte.d.ts +24 -0
  55. package/lib/node/blocks/accordion/accordion.types.d.ts +12 -0
  56. package/lib/node/blocks/accordion/accordion.types.js +1 -0
  57. package/lib/node/blocks/accordion/component-info.d.ts +2 -0
  58. package/lib/node/blocks/accordion/component-info.js +123 -0
  59. package/lib/node/blocks/accordion/helpers.d.ts +1 -0
  60. package/lib/node/blocks/accordion/helpers.js +3 -0
  61. package/lib/node/blocks/accordion/index.d.ts +1 -0
  62. package/lib/node/blocks/accordion/index.js +1 -0
  63. package/lib/node/blocks/tabs/tabs.svelte +13 -10
  64. package/lib/node/blocks/tabs/tabs.svelte.d.ts +2 -2
  65. package/lib/node/components/block/animator.d.ts +0 -1
  66. package/lib/node/components/block/animator.js +3 -3
  67. package/lib/node/components/block/block.helpers.js +2 -2
  68. package/lib/node/components/block/components/block-styles.svelte +2 -2
  69. package/lib/node/components/content/components/enable-editor.svelte +1 -1
  70. package/lib/node/components/content-variants/content-variants.types.d.ts +1 -1
  71. package/lib/node/constants/builder-registered-components.js +5 -0
  72. package/lib/node/constants/sdk-version.d.ts +1 -1
  73. package/lib/node/constants/sdk-version.js +1 -1
  74. package/lib/node/functions/camel-to-kebab-case.d.ts +1 -1
  75. package/lib/node/functions/camel-to-kebab-case.js +1 -1
  76. package/lib/node/functions/get-content/generate-content-url.js +2 -2
  77. package/lib/node/helpers/flatten.d.ts +10 -0
  78. package/lib/node/helpers/flatten.js +20 -0
  79. package/package.json +1 -1
  80. package/src/blocks/accordion/accordion.svelte +197 -0
  81. package/src/blocks/accordion/accordion.types.ts +12 -0
  82. package/src/blocks/accordion/component-info.ts +124 -0
  83. package/src/blocks/accordion/helpers.ts +3 -0
  84. package/src/blocks/accordion/index.ts +1 -0
  85. package/src/blocks/tabs/tabs.svelte +12 -10
  86. package/src/components/block/animator.ts +3 -3
  87. package/src/components/block/block.helpers.ts +2 -2
  88. package/src/components/block/components/block-styles.svelte +2 -2
  89. package/src/components/content/components/enable-editor.svelte +1 -1
  90. package/src/components/content-variants/content-variants.types.ts +1 -1
  91. package/src/constants/builder-registered-components.ts +5 -0
  92. package/src/constants/sdk-version.ts +1 -1
  93. package/src/functions/camel-to-kebab-case.ts +1 -1
  94. package/src/functions/get-content/generate-content-url.ts +3 -3
  95. package/src/helpers/flatten.ts +22 -0
@@ -0,0 +1,197 @@
1
+ <script lang="ts">
2
+ import Blocks from "../../components/blocks/index";
3
+ import type { AccordionProps } from "./accordion.types";
4
+ import type { Dictionary } from "../../types/typescript";
5
+ import { convertOrderNumberToString } from "./helpers";
6
+ import { camelToKebabCase } from "../../functions/camel-to-kebab-case";
7
+
8
+ export let grid: AccordionProps["grid"] = undefined;
9
+ export let oneAtATime: AccordionProps["oneAtATime"] = undefined;
10
+ export let items: AccordionProps["items"];
11
+ export let gridRowWidth: AccordionProps["gridRowWidth"] = undefined;
12
+ export let builderBlock: AccordionProps["builderBlock"];
13
+ export let builderContext: AccordionProps["builderContext"];
14
+ export let builderComponents: AccordionProps["builderComponents"];
15
+ export let builderLinkComponent: AccordionProps["builderLinkComponent"] =
16
+ undefined;
17
+ function stringifyStyles(stylesObj) {
18
+ let styles = "";
19
+ for (let key in stylesObj) {
20
+ const dashedKey = key.replace(/[A-Z]/g, function (match) {
21
+ return "-" + match.toLowerCase();
22
+ });
23
+ styles += dashedKey + ":" + stylesObj[key] + ";";
24
+ }
25
+ return styles;
26
+ }
27
+
28
+ function getAccordionTitleClassName(index: number) {
29
+ return `builder-accordion-title builder-accordion-title-${
30
+ open.includes(index) ? "open" : "closed"
31
+ }`;
32
+ }
33
+ function getAccordionDetailClassName(index: number) {
34
+ return `builder-accordion-detail builder-accordion-detail-${
35
+ open.includes(index) ? "open" : "closed"
36
+ }`;
37
+ }
38
+ function onClick(index: number) {
39
+ if (open.includes(index)) {
40
+ open = onlyOneAtATime() ? [] : open.filter((item) => item !== index);
41
+ } else {
42
+ open = onlyOneAtATime() ? [index] : open.concat(index);
43
+ }
44
+ }
45
+ $: onlyOneAtATime = () => {
46
+ return Boolean(grid || oneAtATime);
47
+ };
48
+ $: accordionStyles = () => {
49
+ const styles = {
50
+ display: "flex" as "flex" | "none",
51
+ alignItems: "stretch" as
52
+ | "stretch"
53
+ | "flex-start"
54
+ | "flex-end"
55
+ | "center"
56
+ | "baseline",
57
+ flexDirection: "column" as
58
+ | "column"
59
+ | "row"
60
+ | "column-reverse"
61
+ | "row-reverse",
62
+ ...(grid && {
63
+ flexDirection: "row" as
64
+ | "column"
65
+ | "row"
66
+ | "column-reverse"
67
+ | "row-reverse",
68
+ alignItems: "flex-start" as
69
+ | "stretch"
70
+ | "flex-start"
71
+ | "flex-end"
72
+ | "center"
73
+ | "baseline",
74
+ flexWrap: "wrap" as "nowrap" | "wrap",
75
+ }),
76
+ };
77
+ return styles;
78
+ };
79
+ $: accordionTitleStyles = () => {
80
+ const shared = {
81
+ display: "flex",
82
+ flexDirection: "column",
83
+ };
84
+ const styles = {
85
+ ...shared,
86
+ alignItems: "stretch",
87
+ cursor: "pointer",
88
+ };
89
+ return Object.fromEntries(
90
+ Object.entries(styles).filter(([_, value]) => value !== undefined)
91
+ ) as Dictionary<string>;
92
+ };
93
+ $: openGridItemOrder = () => {
94
+ let itemOrder: number | null = null;
95
+ const getOpenGridItemPosition = grid && open.length;
96
+ if (getOpenGridItemPosition && document) {
97
+ const openItemIndex = open[0];
98
+ const openItem = document.querySelector(
99
+ `.builder-accordion-title[data-index="${openItemIndex}"]`
100
+ );
101
+ let subjectItem = openItem;
102
+ itemOrder = openItemIndex;
103
+ if (subjectItem) {
104
+ let prevItemRect = subjectItem.getBoundingClientRect();
105
+ while ((subjectItem = subjectItem && subjectItem.nextElementSibling)) {
106
+ if (subjectItem) {
107
+ if (subjectItem.classList.contains("builder-accordion-detail")) {
108
+ continue;
109
+ }
110
+ const subjectItemRect = subjectItem.getBoundingClientRect();
111
+ if (subjectItemRect.left > prevItemRect.left) {
112
+ const index = parseInt(
113
+ subjectItem.getAttribute("data-index") || "",
114
+ 10
115
+ );
116
+ if (!isNaN(index)) {
117
+ prevItemRect = subjectItemRect;
118
+ itemOrder = index;
119
+ }
120
+ } else {
121
+ break;
122
+ }
123
+ }
124
+ }
125
+ }
126
+ }
127
+ if (typeof itemOrder === "number") {
128
+ itemOrder = itemOrder + 1;
129
+ }
130
+ return itemOrder;
131
+ };
132
+ $: accordionDetailStyles = () => {
133
+ const styles = {
134
+ ...{
135
+ order:
136
+ typeof openGridItemOrder() === "number"
137
+ ? (openGridItemOrder() as number)
138
+ : undefined,
139
+ },
140
+ ...(grid && {
141
+ width: "100%",
142
+ }),
143
+ };
144
+ return Object.fromEntries(
145
+ Object.entries(styles).filter(([_, value]) => value !== undefined)
146
+ ) as Dictionary<string>;
147
+ };
148
+
149
+ let open = [];
150
+ </script>
151
+
152
+ <div style={stringifyStyles(accordionStyles())} class="builder-accordion">
153
+ {#each items as item, index}
154
+ <div
155
+ style={stringifyStyles({
156
+ ...accordionTitleStyles(),
157
+ width: grid ? gridRowWidth : undefined,
158
+ ...{
159
+ order:
160
+ openGridItemOrder() !== null
161
+ ? convertOrderNumberToString(index)
162
+ : convertOrderNumberToString(index + 1),
163
+ },
164
+ })}
165
+ class={getAccordionTitleClassName(index)}
166
+ data-index={index}
167
+ on:click={(event) => {
168
+ onClick(index);
169
+ }}
170
+ >
171
+ <Blocks
172
+ blocks={item.title}
173
+ path={`items.${index}.title`}
174
+ parent={builderBlock.id}
175
+ context={builderContext}
176
+ registeredComponents={builderComponents}
177
+ linkComponent={builderLinkComponent}
178
+ />
179
+ </div>
180
+
181
+ {#if open.includes(index)}
182
+ <div
183
+ style={stringifyStyles(accordionDetailStyles())}
184
+ class={getAccordionDetailClassName(index)}
185
+ >
186
+ <Blocks
187
+ blocks={item.detail}
188
+ path={`items.${index}.detail`}
189
+ parent={builderBlock.id}
190
+ context={builderContext}
191
+ registeredComponents={builderComponents}
192
+ linkComponent={builderLinkComponent}
193
+ />
194
+ </div>
195
+ {/if}
196
+ {/each}
197
+ </div>
@@ -0,0 +1,12 @@
1
+ import type { BuilderBlock } from '../../types/builder-block';
2
+ import type { BuilderComponentsProp, BuilderDataProps, BuilderLinkComponentProp } from '../../types/builder-props';
3
+ export interface AccordionProps extends BuilderComponentsProp, BuilderLinkComponentProp, BuilderDataProps {
4
+ items: {
5
+ title: BuilderBlock[];
6
+ detail: BuilderBlock[];
7
+ }[];
8
+ oneAtATime?: boolean;
9
+ grid?: boolean;
10
+ gridRowWidth?: string;
11
+ useChildrenForItems?: boolean;
12
+ }
@@ -0,0 +1,124 @@
1
+ import type { ComponentInfo } from '../../types/components';
2
+ const defaultTitle = {
3
+ '@type': '@builder.io/sdk:Element',
4
+ layerName: 'Accordion item title',
5
+ responsiveStyles: {
6
+ large: {
7
+ marginTop: '10px',
8
+ position: 'relative',
9
+ display: 'flex',
10
+ alignItems: 'stretch',
11
+ flexDirection: 'column',
12
+ paddingBottom: '10px'
13
+ }
14
+ },
15
+ children: [{
16
+ '@type': '@builder.io/sdk:Element',
17
+ responsiveStyles: {
18
+ large: {
19
+ textAlign: 'left',
20
+ display: 'flex',
21
+ flexDirection: 'column'
22
+ }
23
+ },
24
+ component: {
25
+ name: 'Text',
26
+ options: {
27
+ text: 'I am an accordion title. Click me!'
28
+ }
29
+ }
30
+ }]
31
+ };
32
+ const defaultDetail = {
33
+ '@type': '@builder.io/sdk:Element',
34
+ layerName: 'Accordion item detail',
35
+ responsiveStyles: {
36
+ large: {
37
+ position: 'relative',
38
+ display: 'flex',
39
+ alignItems: 'stretch',
40
+ flexDirection: 'column',
41
+ marginTop: '10px',
42
+ paddingBottom: '10px'
43
+ }
44
+ },
45
+ children: [{
46
+ '@type': '@builder.io/sdk:Element',
47
+ responsiveStyles: {
48
+ large: {
49
+ paddingTop: '50px',
50
+ textAlign: 'left',
51
+ display: 'flex',
52
+ flexDirection: 'column',
53
+ paddingBottom: '50px'
54
+ }
55
+ },
56
+ component: {
57
+ name: 'Text',
58
+ options: {
59
+ text: 'I am an accordion detail, hello!'
60
+ }
61
+ }
62
+ }]
63
+ };
64
+ export const componentInfo: ComponentInfo = {
65
+ name: 'Builder:Accordion',
66
+ canHaveChildren: true,
67
+ image: 'https://cdn.builder.io/api/v1/image/assets%2FagZ9n5CUKRfbL9t6CaJOyVSK4Es2%2Ffab6c1fd3fe542408cbdec078bca7f35',
68
+ defaultStyles: {
69
+ display: 'flex',
70
+ flexDirection: 'column',
71
+ alignItems: 'stretch'
72
+ },
73
+ inputs: [{
74
+ name: 'items',
75
+ type: 'list',
76
+ broadcast: true,
77
+ subFields: [{
78
+ name: 'title',
79
+ type: 'uiBlocks',
80
+ hideFromUI: true,
81
+ defaultValue: [defaultTitle]
82
+ }, {
83
+ name: 'detail',
84
+ type: 'uiBlocks',
85
+ hideFromUI: true,
86
+ defaultValue: [defaultDetail]
87
+ }],
88
+ defaultValue: [{
89
+ title: [defaultTitle],
90
+ detail: [defaultDetail]
91
+ }, {
92
+ title: [defaultTitle],
93
+ detail: [defaultDetail]
94
+ }],
95
+ showIf: (options: Map<string, any>) => !options.get('useChildrenForItems')
96
+ }, {
97
+ name: 'oneAtATime',
98
+ helperText: 'Only allow opening one at a time (collapse all others when new item openned)',
99
+ type: 'boolean',
100
+ defaultValue: false
101
+ }, {
102
+ name: 'grid',
103
+ helperText: 'Display as a grid',
104
+ type: 'boolean',
105
+ defaultValue: false
106
+ }, {
107
+ name: 'gridRowWidth',
108
+ helperText: 'Display as a grid',
109
+ type: 'string',
110
+ showIf: (options: Map<string, any>) => options.get('grid'),
111
+ defaultValue: '25%'
112
+ }, {
113
+ name: 'useChildrenForItems',
114
+ type: 'boolean',
115
+ helperText: 'Use child elements for each slide, instead of the array. Useful for dynamically repeating items',
116
+ advanced: true,
117
+ defaultValue: false,
118
+ onChange: (options: Map<string, any>) => {
119
+ if (options.get('useChildrenForItems') === true) {
120
+ options.set('items', []);
121
+ }
122
+ }
123
+ }]
124
+ }
@@ -0,0 +1,3 @@
1
+ export const convertOrderNumberToString = (order: number) => {
2
+ return order.toString();
3
+ }
@@ -0,0 +1 @@
1
+ export { default } from './accordion.svelte'
@@ -5,9 +5,9 @@
5
5
 
6
6
  export let defaultActiveTab: TabsProps["defaultActiveTab"] = undefined;
7
7
  export let tabs: TabsProps["tabs"];
8
- export let activeTabStyle: TabsProps["activeTabStyle"] = undefined;
9
- export let tabHeaderLayout: TabsProps["tabHeaderLayout"] = undefined;
10
8
  export let collapsible: TabsProps["collapsible"] = undefined;
9
+ export let tabHeaderLayout: TabsProps["tabHeaderLayout"] = undefined;
10
+ export let activeTabStyle: TabsProps["activeTabStyle"] = undefined;
11
11
  export let builderBlock: TabsProps["builderBlock"];
12
12
  export let builderContext: TabsProps["builderContext"];
13
13
  export let builderComponents: TabsProps["builderComponents"];
@@ -27,8 +27,12 @@
27
27
  function activeTabContent(active: number) {
28
28
  return tabs && tabs[active].content;
29
29
  }
30
- function getActiveTabStyle(index: number) {
31
- return activeTab === index ? activeTabStyle : {};
30
+ function onClick(index: number) {
31
+ if (index === activeTab && collapsible) {
32
+ activeTab = -1;
33
+ } else {
34
+ activeTab = index;
35
+ }
32
36
  }
33
37
 
34
38
  let activeTab = defaultActiveTab ? defaultActiveTab - 1 : 0;
@@ -46,16 +50,14 @@
46
50
  >
47
51
  {#each tabs as tab, index (index)}
48
52
  <span
49
- style={stringifyStyles(getActiveTabStyle(index))}
53
+ style={stringifyStyles({
54
+ ...(activeTab === index ? activeTabStyle : {}),
55
+ })}
50
56
  class={`builder-tab-wrap ${
51
57
  activeTab === index ? "builder-tab-active" : ""
52
58
  }`}
53
59
  on:click={(event) => {
54
- if (index === activeTab && collapsible) {
55
- activeTab = -1;
56
- } else {
57
- activeTab = index;
58
- }
60
+ onClick(index);
59
61
  }}
60
62
  ><Blocks
61
63
  parent={builderBlock.id}
@@ -1,3 +1,4 @@
1
+ import { camelToKebabCase } from '../../functions/camel-to-kebab-case';
1
2
  import type { BuilderAnimation } from '../../types/builder-block';
2
3
 
3
4
  // eslint-disable-next-line @typescript-eslint/ban-types
@@ -52,7 +53,6 @@ function assign(target: object, ..._args: any[]) {
52
53
  }
53
54
  return to;
54
55
  }
55
- export const camelCaseToKebabCase = (str?: string) => str ? str.replace(/([A-Z])/g, g => `-${g[0].toLowerCase()}`) : '';
56
56
  export function bindAnimations(animations: BuilderAnimation[]) {
57
57
  for (const animation of animations) {
58
58
  switch (animation.trigger) {
@@ -121,7 +121,7 @@ export function triggerAnimation(animation: BuilderAnimation) {
121
121
  // TODO: only include properties explicitly set in the animation
122
122
  // using Object.keys(styles)
123
123
  setTimeout(() => {
124
- element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
124
+ element.style.transition = `all ${animation.duration}s ${camelToKebabCase(animation.easing)}`;
125
125
  if (animation.delay) {
126
126
  element.style.transitionDelay = animation.delay + 's';
127
127
  }
@@ -202,7 +202,7 @@ export function bindScrollInViewAnimation(animation: BuilderAnimation) {
202
202
 
203
203
  // TODO: queue/batch these timeouts!
204
204
  setTimeout(() => {
205
- element.style.transition = `all ${animation.duration}s ${camelCaseToKebabCase(animation.easing)}`;
205
+ element.style.transition = `all ${animation.duration}s ${camelToKebabCase(animation.easing)}`;
206
206
  if (animation.delay) {
207
207
  element.style.transitionDelay = animation.delay + 's';
208
208
  }
@@ -99,8 +99,8 @@ export const getInheritedStyles = ({
99
99
  return extractTextStyles(style);
100
100
  };
101
101
  export const shouldPassLinkComponent = (block: RegisteredComponent | null | undefined) => {
102
- return block && (block.isRSC || ['Core:Button', 'Symbol', 'Columns', 'Form:Form', 'Builder: Tabs'].includes(block.name));
102
+ return block && (block.isRSC || ['Core:Button', 'Symbol', 'Columns', 'Form:Form', 'Builder: Tabs', 'Builder:Accordion'].includes(block.name));
103
103
  };
104
104
  export const shouldPassRegisteredComponents = (block: RegisteredComponent | null | undefined) => {
105
- return block && (block.isRSC || ['Symbol', 'Columns', 'Form:Form', 'Builder: Tabs'].includes(block.name));
105
+ return block && (block.isRSC || ['Symbol', 'Columns', 'Form:Form', 'Builder: Tabs', 'Builder:Accordion'].includes(block.name));
106
106
  }
@@ -17,7 +17,7 @@
17
17
  import { checkIsDefined } from "../../../helpers/nullable";
18
18
  import type { BuilderBlock } from "../../../types/builder-block";
19
19
  import InlinedStyles from "../../inlined-styles.svelte";
20
- import { camelCaseToKebabCase } from "../animator";
20
+ import { camelToKebabCase } from "../../../functions/camel-to-kebab-case";
21
21
 
22
22
  export let block: BlockStylesProps["block"];
23
23
  export let context: BlockStylesProps["context"];
@@ -98,7 +98,7 @@
98
98
  className: `${className}:hover`,
99
99
  styles: {
100
100
  ...hoverStyles,
101
- transition: `all ${hoverAnimation.duration}s ${camelCaseToKebabCase(
101
+ transition: `all ${hoverAnimation.duration}s ${camelToKebabCase(
102
102
  hoverAnimation.easing
103
103
  )}`,
104
104
  transitionDelay: hoverAnimation.delay
@@ -330,7 +330,7 @@
330
330
  onMount(() => {
331
331
  if (!apiKey) {
332
332
  logger.error(
333
- "No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop."
333
+ "No API key provided to `Content` component. This can cause issues. Please provide an API key using the `apiKey` prop."
334
334
  );
335
335
  }
336
336
  evaluateJsCode();
@@ -26,7 +26,7 @@ export interface ContentVariantsPrps {
26
26
  context?: BuilderRenderContext;
27
27
 
28
28
  /**
29
- * Your API Key: needed to dynamically fetch symbols (required).
29
+ * Your API Key: needed to enable visual editing, and to dynamically fetch symbols (required).
30
30
  */
31
31
  apiKey: string;
32
32
  apiVersion?: ApiVersion;
@@ -16,6 +16,8 @@ import { componentInfo as tabsComponentInfo } from '../blocks/tabs/component-inf
16
16
  import { default as Tabs } from '../blocks/tabs/index';
17
17
  import { componentInfo as textComponentInfo } from '../blocks/text/component-info';
18
18
  import { default as Text } from '../blocks/text/index';
19
+ import { default as Accordion } from '../blocks/accordion/index';
20
+ import { componentInfo as accordionComponentInfo } from '../blocks/accordion/component-info';
19
21
  import type { RegisteredComponent } from '../context/types';
20
22
  import { getExtraComponents } from './extra-components';
21
23
  import { TARGET } from './target';
@@ -51,4 +53,7 @@ export const getDefaultRegisteredComponents: () => RegisteredComponent[] = () =>
51
53
  }, ...(TARGET === 'rsc' ? [] : [{
52
54
  component: Tabs,
53
55
  ...tabsComponentInfo
56
+ }, {
57
+ component: Accordion,
58
+ ...accordionComponentInfo
54
59
  }]), ...getExtraComponents()]
@@ -1 +1 @@
1
- export const SDK_VERSION = "1.0.26"
1
+ export const SDK_VERSION = "1.0.28"
@@ -1 +1 @@
1
- export const camelToKebabCase = (string: string) => string.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase()
1
+ export const camelToKebabCase = (str?: string) => str ? str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase() : ''
@@ -1,4 +1,4 @@
1
- import { flatten } from '../../helpers/flatten';
1
+ import { flatten, flattenMongoQuery } from '../../helpers/flatten';
2
2
  import { normalizeSearchParams } from '../../helpers/search/search';
3
3
  import { DEFAULT_API_VERSION } from '../../types/api-version';
4
4
  import { getBuilderSearchParamsFromWindow } from '../get-builder-search-params/index';
@@ -77,11 +77,11 @@ export const generateContentUrl = (options: GetContentOptions): URL => {
77
77
  url.searchParams.set('userAttributes', JSON.stringify(userAttributes));
78
78
  }
79
79
  if (query) {
80
- const flattened = flatten({
80
+ const flattened = flattenMongoQuery({
81
81
  query
82
82
  });
83
83
  for (const key in flattened) {
84
- url.searchParams.set(key, JSON.stringify((flattened as any)[key]));
84
+ url.searchParams.set(key, JSON.stringify(flattened[key]));
85
85
  }
86
86
  }
87
87
  return url;
@@ -16,4 +16,26 @@ export function flatten<T extends Record<string, any>>(object: T, path: string |
16
16
  [newPath]: value
17
17
  };
18
18
  }, ({} as T));
19
+ }
20
+
21
+ /**
22
+ * Flatten a nested MongoDB query object into a flat object with dot-separated keys.
23
+ * $ keys are not flattened and are left as is.
24
+ *
25
+ * { foo: { bar: { $gt: 5 }}} -> { 'foo.bar': { '$gt': 5 }}
26
+ * { foo: {'bar.id': { $elemMatch: { 'baz.id': { $in: ['abc', 'bcd'] }}}}} -> { 'foo.bar.id': { '$elemMatch': { 'baz.id': { '$in': ['abc', 'bcd'] }}}}
27
+ */
28
+ export function flattenMongoQuery(obj: any, _current?: any, _res: any = {}): {
29
+ [key: string]: string;
30
+ } {
31
+ for (const key in obj) {
32
+ const value = obj[key];
33
+ const newKey = _current ? _current + '.' + key : key;
34
+ if (value && typeof value === 'object' && !Array.isArray(value) && !Object.keys(value).find(item => item.startsWith('$'))) {
35
+ flattenMongoQuery(value, newKey, _res);
36
+ } else {
37
+ _res[newKey] = value;
38
+ }
39
+ }
40
+ return _res;
19
41
  }