@builder.io/sdk-solid 1.0.28 → 1.0.29

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.
package/lib/node/dev.jsx CHANGED
@@ -2030,1010 +2030,1010 @@ var getDefaultCanTrack = (canTrack) => checkIsDefined(canTrack) ? canTrack : tru
2030
2030
  // src/components/content/content.tsx
2031
2031
  import { Show as Show13, createSignal as createSignal17 } from "solid-js";
2032
2032
 
2033
- // src/blocks/button/component-info.ts
2034
- var componentInfo = {
2035
- name: "Core:Button",
2036
- image: "https://cdn.builder.io/api/v1/image/assets%2FIsxPKMo2gPRRKeakUztj1D6uqed2%2F81a15681c3e74df09677dfc57a615b13",
2037
- defaultStyles: {
2038
- // TODO: make min width more intuitive and set one
2039
- appearance: "none",
2040
- paddingTop: "15px",
2041
- paddingBottom: "15px",
2042
- paddingLeft: "25px",
2043
- paddingRight: "25px",
2044
- backgroundColor: "#000000",
2045
- color: "white",
2046
- borderRadius: "4px",
2047
- textAlign: "center",
2048
- cursor: "pointer"
2033
+ // src/blocks/accordion/component-info.ts
2034
+ var defaultTitle = {
2035
+ "@type": "@builder.io/sdk:Element",
2036
+ layerName: "Accordion item title",
2037
+ responsiveStyles: {
2038
+ large: {
2039
+ marginTop: "10px",
2040
+ position: "relative",
2041
+ display: "flex",
2042
+ alignItems: "stretch",
2043
+ flexDirection: "column",
2044
+ paddingBottom: "10px"
2045
+ }
2049
2046
  },
2050
- inputs: [{
2051
- name: "text",
2052
- type: "text",
2053
- defaultValue: "Click me!",
2054
- bubble: true
2055
- }, {
2056
- name: "link",
2057
- type: "url",
2058
- bubble: true
2059
- }, {
2060
- name: "openLinkInNewTab",
2061
- type: "boolean",
2062
- defaultValue: false,
2063
- friendlyName: "Open link in new tab"
2064
- }],
2065
- static: true,
2066
- noWrap: true
2067
- };
2068
-
2069
- // src/blocks/columns/component-info.ts
2070
- var componentInfo2 = {
2071
- // TODO: ways to statically preprocess JSON for references, functions, etc
2072
- name: "Columns",
2073
- isRSC: true,
2074
- inputs: [{
2075
- name: "columns",
2076
- type: "array",
2077
- broadcast: true,
2078
- subFields: [{
2079
- name: "blocks",
2080
- type: "array",
2081
- hideFromUI: true,
2082
- defaultValue: [{
2083
- "@type": "@builder.io/sdk:Element",
2084
- responsiveStyles: {
2085
- large: {
2086
- display: "flex",
2087
- flexDirection: "column",
2088
- alignItems: "stretch",
2089
- flexShrink: "0",
2090
- position: "relative",
2091
- marginTop: "30px",
2092
- textAlign: "center",
2093
- lineHeight: "normal",
2094
- height: "auto",
2095
- minHeight: "20px",
2096
- minWidth: "20px",
2097
- overflow: "hidden"
2098
- }
2099
- },
2100
- component: {
2101
- name: "Image",
2102
- options: {
2103
- image: "https://builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d",
2104
- backgroundPosition: "center",
2105
- backgroundSize: "cover",
2106
- aspectRatio: 0.7004048582995948
2107
- }
2108
- }
2109
- }, {
2110
- "@type": "@builder.io/sdk:Element",
2111
- responsiveStyles: {
2112
- large: {
2113
- display: "flex",
2114
- flexDirection: "column",
2115
- alignItems: "stretch",
2116
- flexShrink: "0",
2117
- position: "relative",
2118
- marginTop: "30px",
2119
- textAlign: "center",
2120
- lineHeight: "normal",
2121
- height: "auto"
2122
- }
2123
- },
2124
- component: {
2125
- name: "Text",
2126
- options: {
2127
- text: "<p>Enter some text...</p>"
2128
- }
2129
- }
2130
- }]
2131
- }, {
2132
- name: "width",
2133
- type: "number",
2134
- hideFromUI: true,
2135
- helperText: "Width %, e.g. set to 50 to fill half of the space"
2136
- }, {
2137
- name: "link",
2138
- type: "url",
2139
- helperText: "Optionally set a url that clicking this column will link to"
2140
- }],
2141
- defaultValue: [{
2142
- blocks: [{
2143
- "@type": "@builder.io/sdk:Element",
2144
- responsiveStyles: {
2145
- large: {
2146
- display: "flex",
2147
- flexDirection: "column",
2148
- alignItems: "stretch",
2149
- flexShrink: "0",
2150
- position: "relative",
2151
- marginTop: "30px",
2152
- textAlign: "center",
2153
- lineHeight: "normal",
2154
- height: "auto",
2155
- minHeight: "20px",
2156
- minWidth: "20px",
2157
- overflow: "hidden"
2158
- }
2159
- },
2160
- component: {
2161
- name: "Image",
2162
- options: {
2163
- image: "https://builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d",
2164
- backgroundPosition: "center",
2165
- backgroundSize: "cover",
2166
- aspectRatio: 0.7004048582995948
2167
- }
2168
- }
2169
- }, {
2170
- "@type": "@builder.io/sdk:Element",
2171
- responsiveStyles: {
2172
- large: {
2173
- display: "flex",
2174
- flexDirection: "column",
2175
- alignItems: "stretch",
2176
- flexShrink: "0",
2177
- position: "relative",
2178
- marginTop: "30px",
2179
- textAlign: "center",
2180
- lineHeight: "normal",
2181
- height: "auto"
2182
- }
2183
- },
2184
- component: {
2185
- name: "Text",
2186
- options: {
2187
- text: "<p>Enter some text...</p>"
2188
- }
2189
- }
2190
- }]
2191
- }, {
2192
- blocks: [{
2193
- "@type": "@builder.io/sdk:Element",
2194
- responsiveStyles: {
2195
- large: {
2196
- display: "flex",
2197
- flexDirection: "column",
2198
- alignItems: "stretch",
2199
- flexShrink: "0",
2200
- position: "relative",
2201
- marginTop: "30px",
2202
- textAlign: "center",
2203
- lineHeight: "normal",
2204
- height: "auto",
2205
- minHeight: "20px",
2206
- minWidth: "20px",
2207
- overflow: "hidden"
2208
- }
2209
- },
2210
- component: {
2211
- name: "Image",
2212
- options: {
2213
- image: "https://builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d",
2214
- backgroundPosition: "center",
2215
- backgroundSize: "cover",
2216
- aspectRatio: 0.7004048582995948
2217
- }
2218
- }
2219
- }, {
2220
- "@type": "@builder.io/sdk:Element",
2221
- responsiveStyles: {
2222
- large: {
2223
- display: "flex",
2224
- flexDirection: "column",
2225
- alignItems: "stretch",
2226
- flexShrink: "0",
2227
- position: "relative",
2228
- marginTop: "30px",
2229
- textAlign: "center",
2230
- lineHeight: "normal",
2231
- height: "auto"
2232
- }
2233
- },
2234
- component: {
2235
- name: "Text",
2236
- options: {
2237
- text: "<p>Enter some text...</p>"
2238
- }
2239
- }
2240
- }]
2241
- }],
2242
- onChange: (options) => {
2243
- function clearWidths() {
2244
- columns.forEach((col) => {
2245
- col.delete("width");
2246
- });
2047
+ children: [{
2048
+ "@type": "@builder.io/sdk:Element",
2049
+ responsiveStyles: {
2050
+ large: {
2051
+ textAlign: "left",
2052
+ display: "flex",
2053
+ flexDirection: "column"
2247
2054
  }
2248
- const columns = options.get("columns");
2249
- if (Array.isArray(columns)) {
2250
- const containsColumnWithWidth = !!columns.find((col) => col.get("width"));
2251
- if (containsColumnWithWidth) {
2252
- const containsColumnWithoutWidth = !!columns.find((col) => !col.get("width"));
2253
- if (containsColumnWithoutWidth) {
2254
- clearWidths();
2255
- } else {
2256
- const sumWidths = columns.reduce((memo, col) => {
2257
- return memo + col.get("width");
2258
- }, 0);
2259
- const widthsDontAddUp = sumWidths !== 100;
2260
- if (widthsDontAddUp) {
2261
- clearWidths();
2262
- }
2263
- }
2264
- }
2055
+ },
2056
+ component: {
2057
+ name: "Text",
2058
+ options: {
2059
+ text: "I am an accordion title. Click me!"
2265
2060
  }
2266
2061
  }
2267
- }, {
2268
- name: "space",
2269
- type: "number",
2270
- defaultValue: 20,
2271
- helperText: "Size of gap between columns",
2272
- advanced: true
2273
- }, {
2274
- name: "stackColumnsAt",
2275
- type: "string",
2276
- defaultValue: "tablet",
2277
- helperText: "Convert horizontal columns to vertical at what device size",
2278
- enum: ["tablet", "mobile", "never"],
2279
- advanced: true
2280
- }, {
2281
- name: "reverseColumnsWhenStacked",
2282
- type: "boolean",
2283
- defaultValue: false,
2284
- helperText: "When stacking columns for mobile devices, reverse the ordering",
2285
- advanced: true
2286
2062
  }]
2287
2063
  };
2288
-
2289
- // src/blocks/fragment/component-info.ts
2290
- var componentInfo3 = {
2291
- name: "Fragment",
2292
- static: true,
2293
- hidden: true,
2294
- canHaveChildren: true,
2295
- noWrap: true
2296
- };
2297
-
2298
- // src/blocks/image/component-info.ts
2299
- var componentInfo4 = {
2300
- name: "Image",
2301
- static: true,
2302
- image: "https://firebasestorage.googleapis.com/v0/b/builder-3b0a2.appspot.com/o/images%2Fbaseline-insert_photo-24px.svg?alt=media&token=4e5d0ef4-f5e8-4e57-b3a9-38d63a9b9dc4",
2303
- defaultStyles: {
2304
- position: "relative",
2305
- minHeight: "20px",
2306
- minWidth: "20px",
2307
- overflow: "hidden"
2064
+ var defaultDetail = {
2065
+ "@type": "@builder.io/sdk:Element",
2066
+ layerName: "Accordion item detail",
2067
+ responsiveStyles: {
2068
+ large: {
2069
+ position: "relative",
2070
+ display: "flex",
2071
+ alignItems: "stretch",
2072
+ flexDirection: "column",
2073
+ marginTop: "10px",
2074
+ paddingBottom: "10px"
2075
+ }
2308
2076
  },
2309
- canHaveChildren: true,
2310
- inputs: [{
2311
- name: "image",
2312
- type: "file",
2313
- bubble: true,
2314
- allowedFileTypes: ["jpeg", "jpg", "png", "svg"],
2315
- required: true,
2316
- defaultValue: "https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F72c80f114dc149019051b6852a9e3b7a",
2317
- onChange: (options) => {
2318
- const DEFAULT_ASPECT_RATIO = 0.7041;
2319
- options.delete("srcset");
2320
- options.delete("noWebp");
2321
- function loadImage(url, timeout = 6e4) {
2322
- return new Promise((resolve, reject) => {
2323
- const img = document.createElement("img");
2324
- let loaded = false;
2325
- img.onload = () => {
2326
- loaded = true;
2327
- resolve(img);
2328
- };
2329
- img.addEventListener("error", (event) => {
2330
- console.warn("Image load failed", event.error);
2331
- reject(event.error);
2332
- });
2333
- img.src = url;
2334
- setTimeout(() => {
2335
- if (!loaded) {
2336
- reject(new Error("Image load timed out"));
2337
- }
2338
- }, timeout);
2339
- });
2340
- }
2341
- function round2(num) {
2342
- return Math.round(num * 1e3) / 1e3;
2077
+ children: [{
2078
+ "@type": "@builder.io/sdk:Element",
2079
+ responsiveStyles: {
2080
+ large: {
2081
+ paddingTop: "50px",
2082
+ textAlign: "left",
2083
+ display: "flex",
2084
+ flexDirection: "column",
2085
+ paddingBottom: "50px"
2343
2086
  }
2344
- const value = options.get("image");
2345
- const aspectRatio = options.get("aspectRatio");
2346
- fetch(value).then((res) => res.blob()).then((blob) => {
2347
- if (blob.type.includes("svg")) {
2348
- options.set("noWebp", true);
2349
- }
2350
- });
2351
- if (value && (!aspectRatio || aspectRatio === DEFAULT_ASPECT_RATIO)) {
2352
- return loadImage(value).then((img) => {
2353
- const possiblyUpdatedAspectRatio = options.get("aspectRatio");
2354
- if (options.get("image") === value && (!possiblyUpdatedAspectRatio || possiblyUpdatedAspectRatio === DEFAULT_ASPECT_RATIO)) {
2355
- if (img.width && img.height) {
2356
- options.set("aspectRatio", round2(img.height / img.width));
2357
- options.set("height", img.height);
2358
- options.set("width", img.width);
2359
- }
2360
- }
2361
- });
2087
+ },
2088
+ component: {
2089
+ name: "Text",
2090
+ options: {
2091
+ text: "I am an accordion detail, hello!"
2362
2092
  }
2363
2093
  }
2364
- }, {
2365
- name: "backgroundSize",
2366
- type: "text",
2367
- defaultValue: "cover",
2368
- enum: [{
2369
- label: "contain",
2370
- value: "contain",
2371
- helperText: "The image should never get cropped"
2372
- }, {
2373
- label: "cover",
2374
- value: "cover",
2375
- helperText: "The image should fill it's box, cropping when needed"
2376
- }]
2377
- }, {
2378
- name: "backgroundPosition",
2379
- type: "text",
2380
- defaultValue: "center",
2381
- enum: ["center", "top", "left", "right", "bottom", "top left", "top right", "bottom left", "bottom right"]
2382
- }, {
2383
- name: "altText",
2384
- type: "string",
2385
- helperText: "Text to display when the user has images off"
2386
- }, {
2387
- name: "height",
2388
- type: "number",
2389
- hideFromUI: true
2390
- }, {
2391
- name: "width",
2392
- type: "number",
2393
- hideFromUI: true
2394
- }, {
2395
- name: "sizes",
2396
- type: "string",
2397
- hideFromUI: true
2398
- }, {
2399
- name: "srcset",
2400
- type: "string",
2401
- hideFromUI: true
2402
- }, {
2403
- name: "lazy",
2404
- type: "boolean",
2405
- defaultValue: true,
2406
- hideFromUI: true
2407
- }, {
2408
- name: "fitContent",
2409
- type: "boolean",
2410
- helperText: "When child blocks are provided, fit to them instead of using the image's aspect ratio",
2411
- defaultValue: true
2412
- }, {
2413
- name: "aspectRatio",
2414
- type: "number",
2415
- helperText: "This is the ratio of height/width, e.g. set to 1.5 for a 300px wide and 200px tall photo. Set to 0 to not force the image to maintain it's aspect ratio",
2416
- advanced: true,
2417
- defaultValue: 0.7041
2418
2094
  }]
2419
2095
  };
2420
-
2421
- // src/blocks/section/component-info.ts
2422
- var componentInfo5 = {
2423
- name: "Core:Section",
2424
- static: true,
2425
- image: "https://cdn.builder.io/api/v1/image/assets%2FIsxPKMo2gPRRKeakUztj1D6uqed2%2F682efef23ace49afac61748dd305c70a",
2096
+ var componentInfo = {
2097
+ name: "Builder:Accordion",
2098
+ canHaveChildren: true,
2099
+ image: "https://cdn.builder.io/api/v1/image/assets%2FagZ9n5CUKRfbL9t6CaJOyVSK4Es2%2Ffab6c1fd3fe542408cbdec078bca7f35",
2100
+ defaultStyles: {
2101
+ display: "flex",
2102
+ flexDirection: "column",
2103
+ alignItems: "stretch"
2104
+ },
2426
2105
  inputs: [{
2427
- name: "maxWidth",
2428
- type: "number",
2429
- defaultValue: 1200
2106
+ name: "items",
2107
+ type: "list",
2108
+ broadcast: true,
2109
+ subFields: [{
2110
+ name: "title",
2111
+ type: "uiBlocks",
2112
+ hideFromUI: true,
2113
+ defaultValue: [defaultTitle]
2114
+ }, {
2115
+ name: "detail",
2116
+ type: "uiBlocks",
2117
+ hideFromUI: true,
2118
+ defaultValue: [defaultDetail]
2119
+ }],
2120
+ defaultValue: [{
2121
+ title: [defaultTitle],
2122
+ detail: [defaultDetail]
2123
+ }, {
2124
+ title: [defaultTitle],
2125
+ detail: [defaultDetail]
2126
+ }],
2127
+ showIf: (options) => !options.get("useChildrenForItems")
2430
2128
  }, {
2431
- name: "lazyLoad",
2129
+ name: "oneAtATime",
2130
+ helperText: "Only allow opening one at a time (collapse all others when new item openned)",
2432
2131
  type: "boolean",
2433
- defaultValue: false,
2132
+ defaultValue: false
2133
+ }, {
2134
+ name: "grid",
2135
+ helperText: "Display as a grid",
2136
+ type: "boolean",
2137
+ defaultValue: false
2138
+ }, {
2139
+ name: "gridRowWidth",
2140
+ helperText: "Display as a grid",
2141
+ type: "string",
2142
+ showIf: (options) => options.get("grid"),
2143
+ defaultValue: "25%"
2144
+ }, {
2145
+ name: "useChildrenForItems",
2146
+ type: "boolean",
2147
+ helperText: "Use child elements for each slide, instead of the array. Useful for dynamically repeating items",
2434
2148
  advanced: true,
2435
- description: "Only render this section when in view"
2436
- }],
2437
- defaultStyles: {
2438
- paddingLeft: "20px",
2439
- paddingRight: "20px",
2440
- paddingTop: "50px",
2441
- paddingBottom: "50px",
2442
- marginTop: "0px",
2443
- width: "100vw",
2444
- marginLeft: "calc(50% - 50vw)"
2445
- },
2446
- canHaveChildren: true,
2447
- defaultChildren: [{
2448
- "@type": "@builder.io/sdk:Element",
2449
- responsiveStyles: {
2450
- large: {
2451
- textAlign: "center"
2452
- }
2453
- },
2454
- component: {
2455
- name: "Text",
2456
- options: {
2457
- text: "<p><b>I am a section! My content keeps from getting too wide, so that it's easy to read even on big screens.</b></p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur</p>"
2149
+ defaultValue: false,
2150
+ onChange: (options) => {
2151
+ if (options.get("useChildrenForItems") === true) {
2152
+ options.set("items", []);
2458
2153
  }
2459
2154
  }
2460
2155
  }]
2461
2156
  };
2462
2157
 
2463
- // src/blocks/slot/component-info.ts
2464
- var componentInfo6 = {
2465
- name: "Slot",
2466
- isRSC: true,
2467
- description: "Allow child blocks to be inserted into this content when used as a Symbol",
2468
- docsLink: "https://www.builder.io/c/docs/symbols-with-blocks",
2469
- image: "https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F3aad6de36eae43b59b52c85190fdef56",
2470
- // Maybe wrap this for canHaveChildren so bind children to this hm
2471
- inputs: [{
2472
- name: "name",
2473
- type: "string",
2474
- required: true,
2475
- defaultValue: "children"
2476
- }]
2158
+ // src/blocks/accordion/accordion.tsx
2159
+ import { Show as Show8, For as For5, createSignal as createSignal9, createMemo as createMemo9 } from "solid-js";
2160
+
2161
+ // src/blocks/accordion/helpers.ts
2162
+ var convertOrderNumberToString = (order) => {
2163
+ return order.toString();
2477
2164
  };
2478
2165
 
2479
- // src/blocks/slot/slot.tsx
2480
- function Slot(props) {
2481
- return <div
2482
- style={{
2483
- "pointer-events": "auto"
2484
- }}
2485
- {...!props.builderContext.context?.symbolId && {
2486
- "builder-slot": props.name
2487
- }}
2488
- ><Blocks_default
2489
- parent={props.builderContext.context?.symbolId}
2490
- path={`symbol.data.${props.name}`}
2491
- context={props.builderContext}
2492
- blocks={props.builderContext.rootState?.[props.name]}
2493
- /></div>;
2166
+ // src/blocks/accordion/accordion.tsx
2167
+ function Accordion(props) {
2168
+ const [open, setOpen] = createSignal9([]);
2169
+ const onlyOneAtATime = createMemo9(() => {
2170
+ return Boolean(props.grid || props.oneAtATime);
2171
+ });
2172
+ const accordionStyles = createMemo9(() => {
2173
+ const styles = {
2174
+ display: "flex",
2175
+ alignItems: "stretch",
2176
+ flexDirection: "column",
2177
+ ...props.grid && {
2178
+ flexDirection: "row",
2179
+ alignItems: "flex-start",
2180
+ flexWrap: "wrap"
2181
+ }
2182
+ };
2183
+ return Object.fromEntries(
2184
+ Object.entries(styles).map(([key, value]) => [
2185
+ camelToKebabCase(key),
2186
+ value
2187
+ ])
2188
+ );
2189
+ });
2190
+ const accordionTitleStyles = createMemo9(() => {
2191
+ const shared = {
2192
+ display: "flex",
2193
+ flexDirection: "column"
2194
+ };
2195
+ const styles = Object.fromEntries(
2196
+ Object.entries({
2197
+ ...shared,
2198
+ alignItems: "stretch",
2199
+ cursor: "pointer"
2200
+ }).map(([key, value]) => [camelToKebabCase(key), value])
2201
+ );
2202
+ return Object.fromEntries(
2203
+ Object.entries(styles).filter(([_, value]) => value !== void 0)
2204
+ );
2205
+ });
2206
+ function getAccordionTitleClassName(index) {
2207
+ return `builder-accordion-title builder-accordion-title-${open().includes(index) ? "open" : "closed"}`;
2208
+ }
2209
+ function getAccordionDetailClassName(index) {
2210
+ return `builder-accordion-detail builder-accordion-detail-${open().includes(index) ? "open" : "closed"}`;
2211
+ }
2212
+ const openGridItemOrder = createMemo9(() => {
2213
+ let itemOrder = null;
2214
+ const getOpenGridItemPosition = props.grid && open().length;
2215
+ if (getOpenGridItemPosition && document) {
2216
+ const openItemIndex = open()[0];
2217
+ const openItem = document.querySelector(
2218
+ `.builder-accordion-title[data-index="${openItemIndex}"]`
2219
+ );
2220
+ let subjectItem = openItem;
2221
+ itemOrder = openItemIndex;
2222
+ if (subjectItem) {
2223
+ let prevItemRect = subjectItem.getBoundingClientRect();
2224
+ while (subjectItem = subjectItem && subjectItem.nextElementSibling) {
2225
+ if (subjectItem) {
2226
+ if (subjectItem.classList.contains("builder-accordion-detail")) {
2227
+ continue;
2228
+ }
2229
+ const subjectItemRect = subjectItem.getBoundingClientRect();
2230
+ if (subjectItemRect.left > prevItemRect.left) {
2231
+ const index = parseInt(
2232
+ subjectItem.getAttribute("data-index") || "",
2233
+ 10
2234
+ );
2235
+ if (!isNaN(index)) {
2236
+ prevItemRect = subjectItemRect;
2237
+ itemOrder = index;
2238
+ }
2239
+ } else {
2240
+ break;
2241
+ }
2242
+ }
2243
+ }
2244
+ }
2245
+ }
2246
+ if (typeof itemOrder === "number") {
2247
+ itemOrder = itemOrder + 1;
2248
+ }
2249
+ return itemOrder;
2250
+ });
2251
+ const accordionDetailStyles = createMemo9(() => {
2252
+ const styles = {
2253
+ ...{
2254
+ order: typeof openGridItemOrder() === "number" ? openGridItemOrder() : void 0
2255
+ },
2256
+ ...props.grid && {
2257
+ width: "100%"
2258
+ }
2259
+ };
2260
+ return Object.fromEntries(
2261
+ Object.entries(styles).filter(([_, value]) => value !== void 0)
2262
+ );
2263
+ });
2264
+ function onClick(index) {
2265
+ if (open().includes(index)) {
2266
+ setOpen(onlyOneAtATime() ? [] : open().filter((item) => item !== index));
2267
+ } else {
2268
+ setOpen(onlyOneAtATime() ? [index] : open().concat(index));
2269
+ }
2270
+ }
2271
+ return <div class="builder-accordion" style={accordionStyles()}><For5 each={props.items}>{(item, _index) => {
2272
+ const index = _index();
2273
+ return <>
2274
+ <div
2275
+ class={getAccordionTitleClassName(index)}
2276
+ style={{
2277
+ ...accordionTitleStyles(),
2278
+ width: props.grid ? props.gridRowWidth : void 0,
2279
+ ...{
2280
+ order: openGridItemOrder() !== null ? convertOrderNumberToString(index) : convertOrderNumberToString(index + 1)
2281
+ }
2282
+ }}
2283
+ data-index={index}
2284
+ onClick={(event) => onClick(index)}
2285
+ ><Blocks_default
2286
+ blocks={item.title}
2287
+ path={`items.${index}.title`}
2288
+ parent={props.builderBlock.id}
2289
+ context={props.builderContext}
2290
+ registeredComponents={props.builderComponents}
2291
+ linkComponent={props.builderLinkComponent}
2292
+ /></div>
2293
+ <Show8 when={open().includes(index)}><div
2294
+ class={getAccordionDetailClassName(index)}
2295
+ style={accordionDetailStyles()}
2296
+ ><Blocks_default
2297
+ blocks={item.detail}
2298
+ path={`items.${index}.detail`}
2299
+ parent={props.builderBlock.id}
2300
+ context={props.builderContext}
2301
+ registeredComponents={props.builderComponents}
2302
+ linkComponent={props.builderLinkComponent}
2303
+ /></div></Show8>
2304
+ </>;
2305
+ }}</For5></div>;
2494
2306
  }
2495
- var slot_default = Slot;
2307
+ var accordion_default = Accordion;
2496
2308
 
2497
- // src/blocks/symbol/component-info.ts
2498
- var componentInfo7 = {
2499
- name: "Symbol",
2500
- noWrap: true,
2501
- static: true,
2502
- isRSC: true,
2309
+ // src/blocks/button/component-info.ts
2310
+ var componentInfo2 = {
2311
+ name: "Core:Button",
2312
+ image: "https://cdn.builder.io/api/v1/image/assets%2FIsxPKMo2gPRRKeakUztj1D6uqed2%2F81a15681c3e74df09677dfc57a615b13",
2313
+ defaultStyles: {
2314
+ // TODO: make min width more intuitive and set one
2315
+ appearance: "none",
2316
+ paddingTop: "15px",
2317
+ paddingBottom: "15px",
2318
+ paddingLeft: "25px",
2319
+ paddingRight: "25px",
2320
+ backgroundColor: "#000000",
2321
+ color: "white",
2322
+ borderRadius: "4px",
2323
+ textAlign: "center",
2324
+ cursor: "pointer"
2325
+ },
2503
2326
  inputs: [{
2504
- name: "symbol",
2505
- type: "uiSymbol"
2506
- }, {
2507
- name: "dataOnly",
2508
- helperText: "Make this a data symbol that doesn't display any UI",
2509
- type: "boolean",
2510
- defaultValue: false,
2511
- advanced: true,
2512
- hideFromUI: true
2513
- }, {
2514
- name: "inheritState",
2515
- helperText: "Inherit the parent component state and data",
2516
- type: "boolean",
2517
- defaultValue: false,
2518
- advanced: true
2327
+ name: "text",
2328
+ type: "text",
2329
+ defaultValue: "Click me!",
2330
+ bubble: true
2519
2331
  }, {
2520
- name: "renderToLiquid",
2521
- helperText: "Render this symbols contents to liquid. Turn off to fetch with javascript and use custom targeting",
2332
+ name: "link",
2333
+ type: "url",
2334
+ bubble: true
2335
+ }, {
2336
+ name: "openLinkInNewTab",
2522
2337
  type: "boolean",
2523
2338
  defaultValue: false,
2524
- advanced: true,
2525
- hideFromUI: true
2526
- }, {
2527
- name: "useChildren",
2528
- hideFromUI: true,
2529
- type: "boolean"
2530
- }]
2339
+ friendlyName: "Open link in new tab"
2340
+ }],
2341
+ static: true,
2342
+ noWrap: true
2531
2343
  };
2532
2344
 
2533
- // src/blocks/tabs/component-info.ts
2534
- var defaultTab = {
2535
- "@type": "@builder.io/sdk:Element",
2536
- responsiveStyles: {
2537
- large: {
2538
- paddingLeft: "20px",
2539
- paddingRight: "20px",
2540
- paddingTop: "10px",
2541
- paddingBottom: "10px",
2542
- minWidth: "100px",
2543
- textAlign: "center",
2544
- display: "flex",
2545
- flexDirection: "column",
2546
- cursor: "pointer",
2547
- userSelect: "none"
2548
- }
2549
- },
2550
- component: {
2551
- name: "Text",
2552
- options: {
2553
- text: "New tab"
2554
- }
2555
- }
2556
- };
2557
- var defaultElement = {
2558
- "@type": "@builder.io/sdk:Element",
2559
- responsiveStyles: {
2560
- large: {
2561
- height: "200px",
2562
- display: "flex",
2563
- marginTop: "20px",
2564
- flexDirection: "column"
2565
- }
2566
- },
2567
- component: {
2568
- name: "Text",
2569
- options: {
2570
- text: "New tab content "
2571
- }
2572
- }
2573
- };
2574
- var componentInfo8 = {
2575
- name: "Builder: Tabs",
2345
+ // src/blocks/columns/component-info.ts
2346
+ var componentInfo3 = {
2347
+ // TODO: ways to statically preprocess JSON for references, functions, etc
2348
+ name: "Columns",
2349
+ isRSC: true,
2576
2350
  inputs: [{
2577
- name: "tabs",
2578
- type: "list",
2351
+ name: "columns",
2352
+ type: "array",
2579
2353
  broadcast: true,
2580
2354
  subFields: [{
2581
- name: "label",
2582
- type: "uiBlocks",
2355
+ name: "blocks",
2356
+ type: "array",
2583
2357
  hideFromUI: true,
2584
- defaultValue: [defaultTab]
2358
+ defaultValue: [{
2359
+ "@type": "@builder.io/sdk:Element",
2360
+ responsiveStyles: {
2361
+ large: {
2362
+ display: "flex",
2363
+ flexDirection: "column",
2364
+ alignItems: "stretch",
2365
+ flexShrink: "0",
2366
+ position: "relative",
2367
+ marginTop: "30px",
2368
+ textAlign: "center",
2369
+ lineHeight: "normal",
2370
+ height: "auto",
2371
+ minHeight: "20px",
2372
+ minWidth: "20px",
2373
+ overflow: "hidden"
2374
+ }
2375
+ },
2376
+ component: {
2377
+ name: "Image",
2378
+ options: {
2379
+ image: "https://builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d",
2380
+ backgroundPosition: "center",
2381
+ backgroundSize: "cover",
2382
+ aspectRatio: 0.7004048582995948
2383
+ }
2384
+ }
2385
+ }, {
2386
+ "@type": "@builder.io/sdk:Element",
2387
+ responsiveStyles: {
2388
+ large: {
2389
+ display: "flex",
2390
+ flexDirection: "column",
2391
+ alignItems: "stretch",
2392
+ flexShrink: "0",
2393
+ position: "relative",
2394
+ marginTop: "30px",
2395
+ textAlign: "center",
2396
+ lineHeight: "normal",
2397
+ height: "auto"
2398
+ }
2399
+ },
2400
+ component: {
2401
+ name: "Text",
2402
+ options: {
2403
+ text: "<p>Enter some text...</p>"
2404
+ }
2405
+ }
2406
+ }]
2585
2407
  }, {
2586
- name: "content",
2587
- type: "uiBlocks",
2408
+ name: "width",
2409
+ type: "number",
2588
2410
  hideFromUI: true,
2589
- defaultValue: [defaultElement]
2411
+ helperText: "Width %, e.g. set to 50 to fill half of the space"
2412
+ }, {
2413
+ name: "link",
2414
+ type: "url",
2415
+ helperText: "Optionally set a url that clicking this column will link to"
2590
2416
  }],
2591
2417
  defaultValue: [{
2592
- label: [{
2593
- ...defaultTab,
2418
+ blocks: [{
2419
+ "@type": "@builder.io/sdk:Element",
2420
+ responsiveStyles: {
2421
+ large: {
2422
+ display: "flex",
2423
+ flexDirection: "column",
2424
+ alignItems: "stretch",
2425
+ flexShrink: "0",
2426
+ position: "relative",
2427
+ marginTop: "30px",
2428
+ textAlign: "center",
2429
+ lineHeight: "normal",
2430
+ height: "auto",
2431
+ minHeight: "20px",
2432
+ minWidth: "20px",
2433
+ overflow: "hidden"
2434
+ }
2435
+ },
2594
2436
  component: {
2595
- name: "Text",
2437
+ name: "Image",
2596
2438
  options: {
2597
- text: "Tab 1"
2439
+ image: "https://builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d",
2440
+ backgroundPosition: "center",
2441
+ backgroundSize: "cover",
2442
+ aspectRatio: 0.7004048582995948
2598
2443
  }
2599
2444
  }
2600
- }],
2601
- content: [{
2602
- ...defaultElement,
2445
+ }, {
2446
+ "@type": "@builder.io/sdk:Element",
2447
+ responsiveStyles: {
2448
+ large: {
2449
+ display: "flex",
2450
+ flexDirection: "column",
2451
+ alignItems: "stretch",
2452
+ flexShrink: "0",
2453
+ position: "relative",
2454
+ marginTop: "30px",
2455
+ textAlign: "center",
2456
+ lineHeight: "normal",
2457
+ height: "auto"
2458
+ }
2459
+ },
2603
2460
  component: {
2604
2461
  name: "Text",
2605
2462
  options: {
2606
- text: "Tab 1 content"
2463
+ text: "<p>Enter some text...</p>"
2607
2464
  }
2608
2465
  }
2609
2466
  }]
2610
2467
  }, {
2611
- label: [{
2612
- ...defaultTab,
2468
+ blocks: [{
2469
+ "@type": "@builder.io/sdk:Element",
2470
+ responsiveStyles: {
2471
+ large: {
2472
+ display: "flex",
2473
+ flexDirection: "column",
2474
+ alignItems: "stretch",
2475
+ flexShrink: "0",
2476
+ position: "relative",
2477
+ marginTop: "30px",
2478
+ textAlign: "center",
2479
+ lineHeight: "normal",
2480
+ height: "auto",
2481
+ minHeight: "20px",
2482
+ minWidth: "20px",
2483
+ overflow: "hidden"
2484
+ }
2485
+ },
2613
2486
  component: {
2614
- name: "Text",
2487
+ name: "Image",
2615
2488
  options: {
2616
- text: "Tab 2"
2489
+ image: "https://builder.io/api/v1/image/assets%2Fpwgjf0RoYWbdnJSbpBAjXNRMe9F2%2Ffb27a7c790324294af8be1c35fe30f4d",
2490
+ backgroundPosition: "center",
2491
+ backgroundSize: "cover",
2492
+ aspectRatio: 0.7004048582995948
2617
2493
  }
2618
2494
  }
2619
- }],
2620
- content: [{
2621
- ...defaultElement,
2495
+ }, {
2496
+ "@type": "@builder.io/sdk:Element",
2497
+ responsiveStyles: {
2498
+ large: {
2499
+ display: "flex",
2500
+ flexDirection: "column",
2501
+ alignItems: "stretch",
2502
+ flexShrink: "0",
2503
+ position: "relative",
2504
+ marginTop: "30px",
2505
+ textAlign: "center",
2506
+ lineHeight: "normal",
2507
+ height: "auto"
2508
+ }
2509
+ },
2622
2510
  component: {
2623
2511
  name: "Text",
2624
2512
  options: {
2625
- text: "Tab 2 content"
2513
+ text: "<p>Enter some text...</p>"
2626
2514
  }
2627
2515
  }
2628
2516
  }]
2629
- }]
2630
- }, {
2631
- name: "activeTabStyle",
2632
- type: "uiStyle",
2633
- helperText: "CSS styles for the active tab",
2634
- defaultValue: {
2635
- backgroundColor: "rgba(0, 0, 0, 0.1)"
2517
+ }],
2518
+ onChange: (options) => {
2519
+ function clearWidths() {
2520
+ columns.forEach((col) => {
2521
+ col.delete("width");
2522
+ });
2523
+ }
2524
+ const columns = options.get("columns");
2525
+ if (Array.isArray(columns)) {
2526
+ const containsColumnWithWidth = !!columns.find((col) => col.get("width"));
2527
+ if (containsColumnWithWidth) {
2528
+ const containsColumnWithoutWidth = !!columns.find((col) => !col.get("width"));
2529
+ if (containsColumnWithoutWidth) {
2530
+ clearWidths();
2531
+ } else {
2532
+ const sumWidths = columns.reduce((memo, col) => {
2533
+ return memo + col.get("width");
2534
+ }, 0);
2535
+ const widthsDontAddUp = sumWidths !== 100;
2536
+ if (widthsDontAddUp) {
2537
+ clearWidths();
2538
+ }
2539
+ }
2540
+ }
2541
+ }
2636
2542
  }
2637
2543
  }, {
2638
- name: "defaultActiveTab",
2544
+ name: "space",
2639
2545
  type: "number",
2640
- helperText: 'Default tab to open to. Set to "1" for the first tab, "2" for the second, or choose "0" for none',
2641
- defaultValue: 1,
2546
+ defaultValue: 20,
2547
+ helperText: "Size of gap between columns",
2642
2548
  advanced: true
2643
2549
  }, {
2644
- name: "collapsible",
2550
+ name: "stackColumnsAt",
2551
+ type: "string",
2552
+ defaultValue: "tablet",
2553
+ helperText: "Convert horizontal columns to vertical at what device size",
2554
+ enum: ["tablet", "mobile", "never"],
2555
+ advanced: true
2556
+ }, {
2557
+ name: "reverseColumnsWhenStacked",
2645
2558
  type: "boolean",
2646
- helperText: "If on, clicking an open tab closes it so no tabs are active",
2647
2559
  defaultValue: false,
2560
+ helperText: "When stacking columns for mobile devices, reverse the ordering",
2648
2561
  advanced: true
2562
+ }]
2563
+ };
2564
+
2565
+ // src/blocks/fragment/component-info.ts
2566
+ var componentInfo4 = {
2567
+ name: "Fragment",
2568
+ static: true,
2569
+ hidden: true,
2570
+ canHaveChildren: true,
2571
+ noWrap: true
2572
+ };
2573
+
2574
+ // src/blocks/image/component-info.ts
2575
+ var componentInfo5 = {
2576
+ name: "Image",
2577
+ static: true,
2578
+ image: "https://firebasestorage.googleapis.com/v0/b/builder-3b0a2.appspot.com/o/images%2Fbaseline-insert_photo-24px.svg?alt=media&token=4e5d0ef4-f5e8-4e57-b3a9-38d63a9b9dc4",
2579
+ defaultStyles: {
2580
+ position: "relative",
2581
+ minHeight: "20px",
2582
+ minWidth: "20px",
2583
+ overflow: "hidden"
2584
+ },
2585
+ canHaveChildren: true,
2586
+ inputs: [{
2587
+ name: "image",
2588
+ type: "file",
2589
+ bubble: true,
2590
+ allowedFileTypes: ["jpeg", "jpg", "png", "svg"],
2591
+ required: true,
2592
+ defaultValue: "https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F72c80f114dc149019051b6852a9e3b7a",
2593
+ onChange: (options) => {
2594
+ const DEFAULT_ASPECT_RATIO = 0.7041;
2595
+ options.delete("srcset");
2596
+ options.delete("noWebp");
2597
+ function loadImage(url, timeout = 6e4) {
2598
+ return new Promise((resolve, reject) => {
2599
+ const img = document.createElement("img");
2600
+ let loaded = false;
2601
+ img.onload = () => {
2602
+ loaded = true;
2603
+ resolve(img);
2604
+ };
2605
+ img.addEventListener("error", (event) => {
2606
+ console.warn("Image load failed", event.error);
2607
+ reject(event.error);
2608
+ });
2609
+ img.src = url;
2610
+ setTimeout(() => {
2611
+ if (!loaded) {
2612
+ reject(new Error("Image load timed out"));
2613
+ }
2614
+ }, timeout);
2615
+ });
2616
+ }
2617
+ function round2(num) {
2618
+ return Math.round(num * 1e3) / 1e3;
2619
+ }
2620
+ const value = options.get("image");
2621
+ const aspectRatio = options.get("aspectRatio");
2622
+ fetch(value).then((res) => res.blob()).then((blob) => {
2623
+ if (blob.type.includes("svg")) {
2624
+ options.set("noWebp", true);
2625
+ }
2626
+ });
2627
+ if (value && (!aspectRatio || aspectRatio === DEFAULT_ASPECT_RATIO)) {
2628
+ return loadImage(value).then((img) => {
2629
+ const possiblyUpdatedAspectRatio = options.get("aspectRatio");
2630
+ if (options.get("image") === value && (!possiblyUpdatedAspectRatio || possiblyUpdatedAspectRatio === DEFAULT_ASPECT_RATIO)) {
2631
+ if (img.width && img.height) {
2632
+ options.set("aspectRatio", round2(img.height / img.width));
2633
+ options.set("height", img.height);
2634
+ options.set("width", img.width);
2635
+ }
2636
+ }
2637
+ });
2638
+ }
2639
+ }
2649
2640
  }, {
2650
- name: "tabHeaderLayout",
2651
- type: "enum",
2652
- helperText: "Change the layout of the tab headers (uses justify-content)",
2653
- defaultValue: "flex-start",
2641
+ name: "backgroundSize",
2642
+ type: "text",
2643
+ defaultValue: "cover",
2654
2644
  enum: [{
2655
- label: "Center",
2656
- value: "center"
2657
- }, {
2658
- label: "Space between",
2659
- value: "space-between"
2660
- }, {
2661
- label: "Space around",
2662
- value: "space-around"
2663
- }, {
2664
- label: "Left",
2665
- value: "flex-start"
2645
+ label: "contain",
2646
+ value: "contain",
2647
+ helperText: "The image should never get cropped"
2666
2648
  }, {
2667
- label: "Right",
2668
- value: "flex-end"
2649
+ label: "cover",
2650
+ value: "cover",
2651
+ helperText: "The image should fill it's box, cropping when needed"
2669
2652
  }]
2653
+ }, {
2654
+ name: "backgroundPosition",
2655
+ type: "text",
2656
+ defaultValue: "center",
2657
+ enum: ["center", "top", "left", "right", "bottom", "top left", "top right", "bottom left", "bottom right"]
2658
+ }, {
2659
+ name: "altText",
2660
+ type: "string",
2661
+ helperText: "Text to display when the user has images off"
2662
+ }, {
2663
+ name: "height",
2664
+ type: "number",
2665
+ hideFromUI: true
2666
+ }, {
2667
+ name: "width",
2668
+ type: "number",
2669
+ hideFromUI: true
2670
+ }, {
2671
+ name: "sizes",
2672
+ type: "string",
2673
+ hideFromUI: true
2674
+ }, {
2675
+ name: "srcset",
2676
+ type: "string",
2677
+ hideFromUI: true
2678
+ }, {
2679
+ name: "lazy",
2680
+ type: "boolean",
2681
+ defaultValue: true,
2682
+ hideFromUI: true
2683
+ }, {
2684
+ name: "fitContent",
2685
+ type: "boolean",
2686
+ helperText: "When child blocks are provided, fit to them instead of using the image's aspect ratio",
2687
+ defaultValue: true
2688
+ }, {
2689
+ name: "aspectRatio",
2690
+ type: "number",
2691
+ helperText: "This is the ratio of height/width, e.g. set to 1.5 for a 300px wide and 200px tall photo. Set to 0 to not force the image to maintain it's aspect ratio",
2692
+ advanced: true,
2693
+ defaultValue: 0.7041
2670
2694
  }]
2671
2695
  };
2672
2696
 
2673
- // src/blocks/tabs/tabs.tsx
2674
- import { Show as Show8, For as For5, createSignal as createSignal9 } from "solid-js";
2675
- function Tabs(props) {
2676
- const [activeTab, setActiveTab] = createSignal9(
2677
- props.defaultActiveTab ? props.defaultActiveTab - 1 : 0
2678
- );
2679
- function activeTabContent(active) {
2680
- return props.tabs && props.tabs[active].content;
2681
- }
2682
- function onClick(index) {
2683
- if (index === activeTab() && props.collapsible) {
2684
- setActiveTab(-1);
2685
- } else {
2686
- setActiveTab(index);
2687
- }
2688
- }
2689
- return <div>
2690
- <div
2691
- class="builder-tabs-wrap"
2692
- style={{
2693
- display: "flex",
2694
- "flex-direction": "row",
2695
- "justify-content": props.tabHeaderLayout || "flex-start",
2696
- overflow: "auto"
2697
- }}
2698
- ><For5 each={props.tabs}>{(tab, _index) => {
2699
- const index = _index();
2700
- return <span
2701
- class={`builder-tab-wrap ${activeTab() === index ? "builder-tab-active" : ""}`}
2702
- key={index}
2703
- style={{
2704
- ...activeTab() === index ? props.activeTabStyle : {}
2705
- }}
2706
- onClick={(event) => onClick(index)}
2707
- ><Blocks_default
2708
- parent={props.builderBlock.id}
2709
- path={`component.options.tabs.${index}.label`}
2710
- blocks={tab.label}
2711
- context={props.builderContext}
2712
- registeredComponents={props.builderComponents}
2713
- linkComponent={props.builderLinkComponent}
2714
- /></span>;
2715
- }}</For5></div>
2716
- <Show8 when={activeTabContent(activeTab())}><div><Blocks_default
2717
- parent={props.builderBlock.id}
2718
- path={`component.options.tabs.${activeTab()}.content`}
2719
- blocks={activeTabContent(activeTab())}
2720
- context={props.builderContext}
2721
- registeredComponents={props.builderComponents}
2722
- linkComponent={props.builderLinkComponent}
2723
- /></div></Show8>
2724
- </div>;
2725
- }
2726
- var tabs_default = Tabs;
2727
-
2728
- // src/blocks/text/component-info.ts
2729
- var componentInfo9 = {
2730
- name: "Text",
2697
+ // src/blocks/section/component-info.ts
2698
+ var componentInfo6 = {
2699
+ name: "Core:Section",
2731
2700
  static: true,
2701
+ image: "https://cdn.builder.io/api/v1/image/assets%2FIsxPKMo2gPRRKeakUztj1D6uqed2%2F682efef23ace49afac61748dd305c70a",
2702
+ inputs: [{
2703
+ name: "maxWidth",
2704
+ type: "number",
2705
+ defaultValue: 1200
2706
+ }, {
2707
+ name: "lazyLoad",
2708
+ type: "boolean",
2709
+ defaultValue: false,
2710
+ advanced: true,
2711
+ description: "Only render this section when in view"
2712
+ }],
2713
+ defaultStyles: {
2714
+ paddingLeft: "20px",
2715
+ paddingRight: "20px",
2716
+ paddingTop: "50px",
2717
+ paddingBottom: "50px",
2718
+ marginTop: "0px",
2719
+ width: "100vw",
2720
+ marginLeft: "calc(50% - 50vw)"
2721
+ },
2722
+ canHaveChildren: true,
2723
+ defaultChildren: [{
2724
+ "@type": "@builder.io/sdk:Element",
2725
+ responsiveStyles: {
2726
+ large: {
2727
+ textAlign: "center"
2728
+ }
2729
+ },
2730
+ component: {
2731
+ name: "Text",
2732
+ options: {
2733
+ text: "<p><b>I am a section! My content keeps from getting too wide, so that it's easy to read even on big screens.</b></p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur</p>"
2734
+ }
2735
+ }
2736
+ }]
2737
+ };
2738
+
2739
+ // src/blocks/slot/component-info.ts
2740
+ var componentInfo7 = {
2741
+ name: "Slot",
2732
2742
  isRSC: true,
2733
- image: "https://firebasestorage.googleapis.com/v0/b/builder-3b0a2.appspot.com/o/images%2Fbaseline-text_fields-24px%20(1).svg?alt=media&token=12177b73-0ee3-42ca-98c6-0dd003de1929",
2743
+ description: "Allow child blocks to be inserted into this content when used as a Symbol",
2744
+ docsLink: "https://www.builder.io/c/docs/symbols-with-blocks",
2745
+ image: "https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F3aad6de36eae43b59b52c85190fdef56",
2746
+ // Maybe wrap this for canHaveChildren so bind children to this hm
2734
2747
  inputs: [{
2735
- name: "text",
2736
- type: "html",
2748
+ name: "name",
2749
+ type: "string",
2737
2750
  required: true,
2738
- autoFocus: true,
2739
- bubble: true,
2740
- defaultValue: "Enter some text..."
2741
- }],
2742
- defaultStyles: {
2743
- lineHeight: "normal",
2744
- height: "auto",
2745
- textAlign: "center"
2746
- }
2751
+ defaultValue: "children"
2752
+ }]
2747
2753
  };
2748
2754
 
2749
- // src/blocks/text/text.tsx
2750
- function Text(props) {
2755
+ // src/blocks/slot/slot.tsx
2756
+ function Slot(props) {
2751
2757
  return <div
2752
- class="builder-text"
2753
- innerHTML={props.text?.toString() || ""}
2754
2758
  style={{
2755
- outline: "none"
2759
+ "pointer-events": "auto"
2756
2760
  }}
2757
- />;
2761
+ {...!props.builderContext.context?.symbolId && {
2762
+ "builder-slot": props.name
2763
+ }}
2764
+ ><Blocks_default
2765
+ parent={props.builderContext.context?.symbolId}
2766
+ path={`symbol.data.${props.name}`}
2767
+ context={props.builderContext}
2768
+ blocks={props.builderContext.rootState?.[props.name]}
2769
+ /></div>;
2758
2770
  }
2759
- var text_default = Text;
2760
-
2761
- // src/blocks/accordion/accordion.tsx
2762
- import { Show as Show9, For as For6, createSignal as createSignal10, createMemo as createMemo10 } from "solid-js";
2771
+ var slot_default = Slot;
2763
2772
 
2764
- // src/blocks/accordion/helpers.ts
2765
- var convertOrderNumberToString = (order) => {
2766
- return order.toString();
2773
+ // src/blocks/symbol/component-info.ts
2774
+ var componentInfo8 = {
2775
+ name: "Symbol",
2776
+ noWrap: true,
2777
+ static: true,
2778
+ isRSC: true,
2779
+ inputs: [{
2780
+ name: "symbol",
2781
+ type: "uiSymbol"
2782
+ }, {
2783
+ name: "dataOnly",
2784
+ helperText: "Make this a data symbol that doesn't display any UI",
2785
+ type: "boolean",
2786
+ defaultValue: false,
2787
+ advanced: true,
2788
+ hideFromUI: true
2789
+ }, {
2790
+ name: "inheritState",
2791
+ helperText: "Inherit the parent component state and data",
2792
+ type: "boolean",
2793
+ defaultValue: false,
2794
+ advanced: true
2795
+ }, {
2796
+ name: "renderToLiquid",
2797
+ helperText: "Render this symbols contents to liquid. Turn off to fetch with javascript and use custom targeting",
2798
+ type: "boolean",
2799
+ defaultValue: false,
2800
+ advanced: true,
2801
+ hideFromUI: true
2802
+ }, {
2803
+ name: "useChildren",
2804
+ hideFromUI: true,
2805
+ type: "boolean"
2806
+ }]
2767
2807
  };
2768
2808
 
2769
- // src/blocks/accordion/accordion.tsx
2770
- function Accordion(props) {
2771
- const [open, setOpen] = createSignal10([]);
2772
- const onlyOneAtATime = createMemo10(() => {
2773
- return Boolean(props.grid || props.oneAtATime);
2774
- });
2775
- const accordionStyles = createMemo10(() => {
2776
- const styles = {
2777
- display: "flex",
2778
- alignItems: "stretch",
2779
- flexDirection: "column",
2780
- ...props.grid && {
2781
- flexDirection: "row",
2782
- alignItems: "flex-start",
2783
- flexWrap: "wrap"
2784
- }
2785
- };
2786
- return Object.fromEntries(
2787
- Object.entries(styles).map(([key, value]) => [
2788
- camelToKebabCase(key),
2789
- value
2790
- ])
2791
- );
2792
- });
2793
- const accordionTitleStyles = createMemo10(() => {
2794
- const shared = {
2795
- display: "flex",
2796
- flexDirection: "column"
2797
- };
2798
- const styles = Object.fromEntries(
2799
- Object.entries({
2800
- ...shared,
2801
- alignItems: "stretch",
2802
- cursor: "pointer"
2803
- }).map(([key, value]) => [camelToKebabCase(key), value])
2804
- );
2805
- return Object.fromEntries(
2806
- Object.entries(styles).filter(([_, value]) => value !== void 0)
2807
- );
2808
- });
2809
- function getAccordionTitleClassName(index) {
2810
- return `builder-accordion-title builder-accordion-title-${open().includes(index) ? "open" : "closed"}`;
2811
- }
2812
- function getAccordionDetailClassName(index) {
2813
- return `builder-accordion-detail builder-accordion-detail-${open().includes(index) ? "open" : "closed"}`;
2814
- }
2815
- const openGridItemOrder = createMemo10(() => {
2816
- let itemOrder = null;
2817
- const getOpenGridItemPosition = props.grid && open().length;
2818
- if (getOpenGridItemPosition && document) {
2819
- const openItemIndex = open()[0];
2820
- const openItem = document.querySelector(
2821
- `.builder-accordion-title[data-index="${openItemIndex}"]`
2822
- );
2823
- let subjectItem = openItem;
2824
- itemOrder = openItemIndex;
2825
- if (subjectItem) {
2826
- let prevItemRect = subjectItem.getBoundingClientRect();
2827
- while (subjectItem = subjectItem && subjectItem.nextElementSibling) {
2828
- if (subjectItem) {
2829
- if (subjectItem.classList.contains("builder-accordion-detail")) {
2830
- continue;
2831
- }
2832
- const subjectItemRect = subjectItem.getBoundingClientRect();
2833
- if (subjectItemRect.left > prevItemRect.left) {
2834
- const index = parseInt(
2835
- subjectItem.getAttribute("data-index") || "",
2836
- 10
2837
- );
2838
- if (!isNaN(index)) {
2839
- prevItemRect = subjectItemRect;
2840
- itemOrder = index;
2841
- }
2842
- } else {
2843
- break;
2844
- }
2845
- }
2846
- }
2847
- }
2848
- }
2849
- if (typeof itemOrder === "number") {
2850
- itemOrder = itemOrder + 1;
2851
- }
2852
- return itemOrder;
2853
- });
2854
- const accordionDetailStyles = createMemo10(() => {
2855
- const styles = {
2856
- ...{
2857
- order: typeof openGridItemOrder() === "number" ? openGridItemOrder() : void 0
2858
- },
2859
- ...props.grid && {
2860
- width: "100%"
2861
- }
2862
- };
2863
- return Object.fromEntries(
2864
- Object.entries(styles).filter(([_, value]) => value !== void 0)
2865
- );
2866
- });
2867
- function onClick(index) {
2868
- if (open().includes(index)) {
2869
- setOpen(onlyOneAtATime() ? [] : open().filter((item) => item !== index));
2870
- } else {
2871
- setOpen(onlyOneAtATime() ? [index] : open().concat(index));
2872
- }
2873
- }
2874
- return <div class="builder-accordion" style={accordionStyles()}><For6 each={props.items}>{(item, _index) => {
2875
- const index = _index();
2876
- return <>
2877
- <div
2878
- class={getAccordionTitleClassName(index)}
2879
- style={{
2880
- ...accordionTitleStyles(),
2881
- width: props.grid ? props.gridRowWidth : void 0,
2882
- ...{
2883
- order: openGridItemOrder() !== null ? convertOrderNumberToString(index) : convertOrderNumberToString(index + 1)
2884
- }
2885
- }}
2886
- data-index={index}
2887
- onClick={(event) => onClick(index)}
2888
- ><Blocks_default
2889
- blocks={item.title}
2890
- path={`items.${index}.title`}
2891
- parent={props.builderBlock.id}
2892
- context={props.builderContext}
2893
- registeredComponents={props.builderComponents}
2894
- linkComponent={props.builderLinkComponent}
2895
- /></div>
2896
- <Show9 when={open().includes(index)}><div
2897
- class={getAccordionDetailClassName(index)}
2898
- style={accordionDetailStyles()}
2899
- ><Blocks_default
2900
- blocks={item.detail}
2901
- path={`items.${index}.detail`}
2902
- parent={props.builderBlock.id}
2903
- context={props.builderContext}
2904
- registeredComponents={props.builderComponents}
2905
- linkComponent={props.builderLinkComponent}
2906
- /></div></Show9>
2907
- </>;
2908
- }}</For6></div>;
2909
- }
2910
- var accordion_default = Accordion;
2911
-
2912
- // src/blocks/accordion/component-info.ts
2913
- var defaultTitle = {
2809
+ // src/blocks/tabs/component-info.ts
2810
+ var defaultTab = {
2914
2811
  "@type": "@builder.io/sdk:Element",
2915
- layerName: "Accordion item title",
2916
2812
  responsiveStyles: {
2917
2813
  large: {
2918
- marginTop: "10px",
2919
- position: "relative",
2814
+ paddingLeft: "20px",
2815
+ paddingRight: "20px",
2816
+ paddingTop: "10px",
2817
+ paddingBottom: "10px",
2818
+ minWidth: "100px",
2819
+ textAlign: "center",
2920
2820
  display: "flex",
2921
- alignItems: "stretch",
2922
2821
  flexDirection: "column",
2923
- paddingBottom: "10px"
2822
+ cursor: "pointer",
2823
+ userSelect: "none"
2924
2824
  }
2925
2825
  },
2926
- children: [{
2927
- "@type": "@builder.io/sdk:Element",
2928
- responsiveStyles: {
2929
- large: {
2930
- textAlign: "left",
2931
- display: "flex",
2932
- flexDirection: "column"
2933
- }
2934
- },
2935
- component: {
2936
- name: "Text",
2937
- options: {
2938
- text: "I am an accordion title. Click me!"
2939
- }
2826
+ component: {
2827
+ name: "Text",
2828
+ options: {
2829
+ text: "New tab"
2940
2830
  }
2941
- }]
2831
+ }
2942
2832
  };
2943
- var defaultDetail = {
2833
+ var defaultElement = {
2944
2834
  "@type": "@builder.io/sdk:Element",
2945
- layerName: "Accordion item detail",
2946
2835
  responsiveStyles: {
2947
2836
  large: {
2948
- position: "relative",
2837
+ height: "200px",
2949
2838
  display: "flex",
2950
- alignItems: "stretch",
2951
- flexDirection: "column",
2952
- marginTop: "10px",
2953
- paddingBottom: "10px"
2839
+ marginTop: "20px",
2840
+ flexDirection: "column"
2954
2841
  }
2955
2842
  },
2956
- children: [{
2957
- "@type": "@builder.io/sdk:Element",
2958
- responsiveStyles: {
2959
- large: {
2960
- paddingTop: "50px",
2961
- textAlign: "left",
2962
- display: "flex",
2963
- flexDirection: "column",
2964
- paddingBottom: "50px"
2965
- }
2966
- },
2967
- component: {
2968
- name: "Text",
2969
- options: {
2970
- text: "I am an accordion detail, hello!"
2971
- }
2843
+ component: {
2844
+ name: "Text",
2845
+ options: {
2846
+ text: "New tab content "
2972
2847
  }
2973
- }]
2848
+ }
2974
2849
  };
2975
- var componentInfo10 = {
2976
- name: "Builder:Accordion",
2977
- canHaveChildren: true,
2978
- image: "https://cdn.builder.io/api/v1/image/assets%2FagZ9n5CUKRfbL9t6CaJOyVSK4Es2%2Ffab6c1fd3fe542408cbdec078bca7f35",
2979
- defaultStyles: {
2980
- display: "flex",
2981
- flexDirection: "column",
2982
- alignItems: "stretch"
2983
- },
2850
+ var componentInfo9 = {
2851
+ name: "Builder: Tabs",
2984
2852
  inputs: [{
2985
- name: "items",
2853
+ name: "tabs",
2986
2854
  type: "list",
2987
2855
  broadcast: true,
2988
2856
  subFields: [{
2989
- name: "title",
2857
+ name: "label",
2990
2858
  type: "uiBlocks",
2991
2859
  hideFromUI: true,
2992
- defaultValue: [defaultTitle]
2860
+ defaultValue: [defaultTab]
2993
2861
  }, {
2994
- name: "detail",
2862
+ name: "content",
2995
2863
  type: "uiBlocks",
2996
2864
  hideFromUI: true,
2997
- defaultValue: [defaultDetail]
2865
+ defaultValue: [defaultElement]
2998
2866
  }],
2999
2867
  defaultValue: [{
3000
- title: [defaultTitle],
3001
- detail: [defaultDetail]
2868
+ label: [{
2869
+ ...defaultTab,
2870
+ component: {
2871
+ name: "Text",
2872
+ options: {
2873
+ text: "Tab 1"
2874
+ }
2875
+ }
2876
+ }],
2877
+ content: [{
2878
+ ...defaultElement,
2879
+ component: {
2880
+ name: "Text",
2881
+ options: {
2882
+ text: "Tab 1 content"
2883
+ }
2884
+ }
2885
+ }]
3002
2886
  }, {
3003
- title: [defaultTitle],
3004
- detail: [defaultDetail]
3005
- }],
3006
- showIf: (options) => !options.get("useChildrenForItems")
3007
- }, {
3008
- name: "oneAtATime",
3009
- helperText: "Only allow opening one at a time (collapse all others when new item openned)",
3010
- type: "boolean",
3011
- defaultValue: false
2887
+ label: [{
2888
+ ...defaultTab,
2889
+ component: {
2890
+ name: "Text",
2891
+ options: {
2892
+ text: "Tab 2"
2893
+ }
2894
+ }
2895
+ }],
2896
+ content: [{
2897
+ ...defaultElement,
2898
+ component: {
2899
+ name: "Text",
2900
+ options: {
2901
+ text: "Tab 2 content"
2902
+ }
2903
+ }
2904
+ }]
2905
+ }]
3012
2906
  }, {
3013
- name: "grid",
3014
- helperText: "Display as a grid",
3015
- type: "boolean",
3016
- defaultValue: false
2907
+ name: "activeTabStyle",
2908
+ type: "uiStyle",
2909
+ helperText: "CSS styles for the active tab",
2910
+ defaultValue: {
2911
+ backgroundColor: "rgba(0, 0, 0, 0.1)"
2912
+ }
3017
2913
  }, {
3018
- name: "gridRowWidth",
3019
- helperText: "Display as a grid",
3020
- type: "string",
3021
- showIf: (options) => options.get("grid"),
3022
- defaultValue: "25%"
2914
+ name: "defaultActiveTab",
2915
+ type: "number",
2916
+ helperText: 'Default tab to open to. Set to "1" for the first tab, "2" for the second, or choose "0" for none',
2917
+ defaultValue: 1,
2918
+ advanced: true
3023
2919
  }, {
3024
- name: "useChildrenForItems",
2920
+ name: "collapsible",
3025
2921
  type: "boolean",
3026
- helperText: "Use child elements for each slide, instead of the array. Useful for dynamically repeating items",
3027
- advanced: true,
2922
+ helperText: "If on, clicking an open tab closes it so no tabs are active",
3028
2923
  defaultValue: false,
3029
- onChange: (options) => {
3030
- if (options.get("useChildrenForItems") === true) {
3031
- options.set("items", []);
3032
- }
3033
- }
2924
+ advanced: true
2925
+ }, {
2926
+ name: "tabHeaderLayout",
2927
+ type: "enum",
2928
+ helperText: "Change the layout of the tab headers (uses justify-content)",
2929
+ defaultValue: "flex-start",
2930
+ enum: [{
2931
+ label: "Center",
2932
+ value: "center"
2933
+ }, {
2934
+ label: "Space between",
2935
+ value: "space-between"
2936
+ }, {
2937
+ label: "Space around",
2938
+ value: "space-around"
2939
+ }, {
2940
+ label: "Left",
2941
+ value: "flex-start"
2942
+ }, {
2943
+ label: "Right",
2944
+ value: "flex-end"
2945
+ }]
3034
2946
  }]
3035
2947
  };
3036
2948
 
2949
+ // src/blocks/tabs/tabs.tsx
2950
+ import { Show as Show9, For as For6, createSignal as createSignal10 } from "solid-js";
2951
+ function Tabs(props) {
2952
+ const [activeTab, setActiveTab] = createSignal10(
2953
+ props.defaultActiveTab ? props.defaultActiveTab - 1 : 0
2954
+ );
2955
+ function activeTabContent(active) {
2956
+ return props.tabs && props.tabs[active].content;
2957
+ }
2958
+ function onClick(index) {
2959
+ if (index === activeTab() && props.collapsible) {
2960
+ setActiveTab(-1);
2961
+ } else {
2962
+ setActiveTab(index);
2963
+ }
2964
+ }
2965
+ return <div>
2966
+ <div
2967
+ class="builder-tabs-wrap"
2968
+ style={{
2969
+ display: "flex",
2970
+ "flex-direction": "row",
2971
+ "justify-content": props.tabHeaderLayout || "flex-start",
2972
+ overflow: "auto"
2973
+ }}
2974
+ ><For6 each={props.tabs}>{(tab, _index) => {
2975
+ const index = _index();
2976
+ return <span
2977
+ class={`builder-tab-wrap ${activeTab() === index ? "builder-tab-active" : ""}`}
2978
+ key={index}
2979
+ style={{
2980
+ ...activeTab() === index ? props.activeTabStyle : {}
2981
+ }}
2982
+ onClick={(event) => onClick(index)}
2983
+ ><Blocks_default
2984
+ parent={props.builderBlock.id}
2985
+ path={`component.options.tabs.${index}.label`}
2986
+ blocks={tab.label}
2987
+ context={props.builderContext}
2988
+ registeredComponents={props.builderComponents}
2989
+ linkComponent={props.builderLinkComponent}
2990
+ /></span>;
2991
+ }}</For6></div>
2992
+ <Show9 when={activeTabContent(activeTab())}><div><Blocks_default
2993
+ parent={props.builderBlock.id}
2994
+ path={`component.options.tabs.${activeTab()}.content`}
2995
+ blocks={activeTabContent(activeTab())}
2996
+ context={props.builderContext}
2997
+ registeredComponents={props.builderComponents}
2998
+ linkComponent={props.builderLinkComponent}
2999
+ /></div></Show9>
3000
+ </div>;
3001
+ }
3002
+ var tabs_default = Tabs;
3003
+
3004
+ // src/blocks/text/component-info.ts
3005
+ var componentInfo10 = {
3006
+ name: "Text",
3007
+ static: true,
3008
+ isRSC: true,
3009
+ image: "https://firebasestorage.googleapis.com/v0/b/builder-3b0a2.appspot.com/o/images%2Fbaseline-text_fields-24px%20(1).svg?alt=media&token=12177b73-0ee3-42ca-98c6-0dd003de1929",
3010
+ inputs: [{
3011
+ name: "text",
3012
+ type: "html",
3013
+ required: true,
3014
+ autoFocus: true,
3015
+ bubble: true,
3016
+ defaultValue: "Enter some text..."
3017
+ }],
3018
+ defaultStyles: {
3019
+ lineHeight: "normal",
3020
+ height: "auto",
3021
+ textAlign: "center"
3022
+ }
3023
+ };
3024
+
3025
+ // src/blocks/text/text.tsx
3026
+ function Text(props) {
3027
+ return <div
3028
+ class="builder-text"
3029
+ innerHTML={props.text?.toString() || ""}
3030
+ style={{
3031
+ outline: "none"
3032
+ }}
3033
+ />;
3034
+ }
3035
+ var text_default = Text;
3036
+
3037
3037
  // src/blocks/custom-code/component-info.ts
3038
3038
  var componentInfo11 = {
3039
3039
  name: "Custom Code",
@@ -3474,13 +3474,11 @@ function FormComponent(props) {
3474
3474
  return;
3475
3475
  }
3476
3476
  event.preventDefault();
3477
- const el = event.currentTarget;
3477
+ const el = event.currentTarget || event.target;
3478
3478
  const headers = props.customHeaders || {};
3479
3479
  let body;
3480
3480
  const formData = new FormData(el);
3481
- const formPairs = Array.from(
3482
- event.currentTarget.querySelectorAll("input,select,textarea")
3483
- ).filter((el2) => !!el2.name).map((el2) => {
3481
+ const formPairs = Array.from(el.querySelectorAll("input,select,textarea")).filter((el2) => !!el2.name).map((el2) => {
3484
3482
  let value;
3485
3483
  const key = el2.name;
3486
3484
  if (el2 instanceof HTMLInputElement) {
@@ -3643,6 +3641,7 @@ function FormComponent(props) {
3643
3641
  name={props.name}
3644
3642
  onSubmit={(event) => onSubmit(event)}
3645
3643
  {...{}}
3644
+ {...{}}
3646
3645
  {...props.attributes}
3647
3646
  >
3648
3647
  <Show10 when={props.builderBlock && props.builderBlock.children}><For7 each={props.builderBlock?.children}>{(block, _index) => {
@@ -4081,34 +4080,34 @@ var getExtraComponents = () => [{
4081
4080
  // src/constants/builder-registered-components.ts
4082
4081
  var getDefaultRegisteredComponents = () => [{
4083
4082
  component: button_default,
4084
- ...componentInfo
4083
+ ...componentInfo2
4085
4084
  }, {
4086
4085
  component: columns_default,
4087
- ...componentInfo2
4086
+ ...componentInfo3
4088
4087
  }, {
4089
4088
  component: fragment_default,
4090
- ...componentInfo3
4089
+ ...componentInfo4
4091
4090
  }, {
4092
4091
  component: image_default,
4093
- ...componentInfo4
4092
+ ...componentInfo5
4094
4093
  }, {
4095
4094
  component: section_default,
4096
- ...componentInfo5
4095
+ ...componentInfo6
4097
4096
  }, {
4098
4097
  component: slot_default,
4099
- ...componentInfo6
4098
+ ...componentInfo7
4100
4099
  }, {
4101
4100
  component: symbol_default,
4102
- ...componentInfo7
4101
+ ...componentInfo8
4103
4102
  }, {
4104
4103
  component: text_default,
4105
- ...componentInfo9
4104
+ ...componentInfo10
4106
4105
  }, ...TARGET === "rsc" ? [] : [{
4107
4106
  component: tabs_default,
4108
- ...componentInfo8
4107
+ ...componentInfo9
4109
4108
  }, {
4110
4109
  component: accordion_default,
4111
- ...componentInfo10
4110
+ ...componentInfo
4112
4111
  }], ...getExtraComponents()];
4113
4112
 
4114
4113
  // src/functions/register-component.ts
@@ -4692,7 +4691,7 @@ function isFromTrustedHost(trustedHosts, e) {
4692
4691
  }
4693
4692
 
4694
4693
  // src/constants/sdk-version.ts
4695
- var SDK_VERSION = "1.0.28";
4694
+ var SDK_VERSION = "1.0.29";
4696
4695
 
4697
4696
  // src/functions/register.ts
4698
4697
  var registry = {};
@@ -5173,7 +5172,7 @@ function EnableEditor(props) {
5173
5172
  const searchParams = new URL(location.href).searchParams;
5174
5173
  const searchParamPreviewModel = searchParams.get("builder.preview");
5175
5174
  const searchParamPreviewId = searchParams.get(
5176
- `builder.preview.${searchParamPreviewModel}`
5175
+ `builder.overrides.${searchParamPreviewModel}`
5177
5176
  );
5178
5177
  const previewApiKey = searchParams.get("apiKey") || searchParams.get("builder.space");
5179
5178
  if (searchParamPreviewModel === props.model && previewApiKey === props.apiKey && (!props.content || searchParamPreviewId === props.content.id)) {