@webstudio-is/react-sdk 0.198.0 → 0.199.0
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/index.js +21 -449
- package/lib/runtime.js +122 -0
- package/lib/types/index.d.ts +0 -1
- package/lib/types/page-settings-meta.d.ts +10 -0
- package/lib/types/page-settings-title.d.ts +17 -0
- package/lib/types/runtime.d.ts +2 -0
- package/package.json +10 -10
- package/placeholder.d.ts +0 -1
- package/lib/types/core-components.d.ts +0 -748
package/lib/index.js
CHANGED
|
@@ -77,438 +77,10 @@ import {
|
|
|
77
77
|
import {
|
|
78
78
|
ROOT_INSTANCE_ID,
|
|
79
79
|
createScope,
|
|
80
|
-
parseComponentName
|
|
80
|
+
parseComponentName,
|
|
81
|
+
descendantComponent,
|
|
82
|
+
rootComponent
|
|
81
83
|
} from "@webstudio-is/sdk";
|
|
82
|
-
|
|
83
|
-
// src/core-components.ts
|
|
84
|
-
import {
|
|
85
|
-
ContentBlockIcon,
|
|
86
|
-
ListViewIcon,
|
|
87
|
-
PaintBrushIcon,
|
|
88
|
-
SettingsIcon,
|
|
89
|
-
AddTemplateInstanceIcon
|
|
90
|
-
} from "@webstudio-is/icons/svg";
|
|
91
|
-
import { html } from "@webstudio-is/sdk/normalize.css";
|
|
92
|
-
var rootComponent = "ws:root";
|
|
93
|
-
var rootMeta = {
|
|
94
|
-
category: "hidden",
|
|
95
|
-
type: "container",
|
|
96
|
-
label: "Global Root",
|
|
97
|
-
icon: SettingsIcon,
|
|
98
|
-
presetStyle: {
|
|
99
|
-
html
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
var rootPropsMeta = {
|
|
103
|
-
props: {}
|
|
104
|
-
};
|
|
105
|
-
var portalComponent = "Slot";
|
|
106
|
-
var collectionComponent = "ws:collection";
|
|
107
|
-
var collectionMeta = {
|
|
108
|
-
category: "data",
|
|
109
|
-
order: 2,
|
|
110
|
-
type: "container",
|
|
111
|
-
label: "Collection",
|
|
112
|
-
icon: ListViewIcon,
|
|
113
|
-
stylable: false,
|
|
114
|
-
template: [
|
|
115
|
-
{
|
|
116
|
-
type: "instance",
|
|
117
|
-
component: collectionComponent,
|
|
118
|
-
props: [
|
|
119
|
-
{
|
|
120
|
-
name: "data",
|
|
121
|
-
type: "json",
|
|
122
|
-
value: [
|
|
123
|
-
"Collection Item 1",
|
|
124
|
-
"Collection Item 2",
|
|
125
|
-
"Collection Item 3"
|
|
126
|
-
]
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
name: "item",
|
|
130
|
-
type: "parameter",
|
|
131
|
-
variableName: "collectionItem",
|
|
132
|
-
variableAlias: "Collection Item"
|
|
133
|
-
}
|
|
134
|
-
],
|
|
135
|
-
children: [
|
|
136
|
-
{
|
|
137
|
-
type: "instance",
|
|
138
|
-
component: "Box",
|
|
139
|
-
children: [
|
|
140
|
-
{
|
|
141
|
-
type: "instance",
|
|
142
|
-
component: "Text",
|
|
143
|
-
children: [{ type: "expression", value: "collectionItem" }]
|
|
144
|
-
}
|
|
145
|
-
]
|
|
146
|
-
}
|
|
147
|
-
]
|
|
148
|
-
}
|
|
149
|
-
]
|
|
150
|
-
};
|
|
151
|
-
var collectionPropsMeta = {
|
|
152
|
-
props: {
|
|
153
|
-
data: {
|
|
154
|
-
required: true,
|
|
155
|
-
control: "json",
|
|
156
|
-
type: "json"
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
initialProps: ["data"]
|
|
160
|
-
};
|
|
161
|
-
var descendantComponent = "ws:descendant";
|
|
162
|
-
var descendantMeta = {
|
|
163
|
-
category: "internal",
|
|
164
|
-
type: "control",
|
|
165
|
-
label: "Descendant",
|
|
166
|
-
icon: PaintBrushIcon,
|
|
167
|
-
constraints: {
|
|
168
|
-
relation: "parent",
|
|
169
|
-
component: { $in: ["HtmlEmbed", "MarkdownEmbed"] }
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
var descendantPropsMeta = {
|
|
173
|
-
props: {
|
|
174
|
-
selector: {
|
|
175
|
-
required: true,
|
|
176
|
-
type: "string",
|
|
177
|
-
control: "select",
|
|
178
|
-
options: [
|
|
179
|
-
" p",
|
|
180
|
-
" h1",
|
|
181
|
-
" h2",
|
|
182
|
-
" h3",
|
|
183
|
-
" h4",
|
|
184
|
-
" h5",
|
|
185
|
-
" h6",
|
|
186
|
-
" :where(strong, b)",
|
|
187
|
-
" :where(em, i)",
|
|
188
|
-
" a",
|
|
189
|
-
" img",
|
|
190
|
-
" blockquote",
|
|
191
|
-
" code",
|
|
192
|
-
" :where(ul, ol)",
|
|
193
|
-
" li",
|
|
194
|
-
" hr"
|
|
195
|
-
]
|
|
196
|
-
}
|
|
197
|
-
},
|
|
198
|
-
initialProps: ["selector"]
|
|
199
|
-
};
|
|
200
|
-
var blockComponent = "ws:block";
|
|
201
|
-
var blockTemplateComponent = "ws:block-template";
|
|
202
|
-
var blockTemplateMeta = {
|
|
203
|
-
category: "hidden",
|
|
204
|
-
type: "container",
|
|
205
|
-
icon: AddTemplateInstanceIcon,
|
|
206
|
-
stylable: false,
|
|
207
|
-
constraints: {
|
|
208
|
-
relation: "parent",
|
|
209
|
-
component: { $eq: blockComponent }
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
var blockTemplatePropsMeta = {
|
|
213
|
-
props: {},
|
|
214
|
-
initialProps: []
|
|
215
|
-
};
|
|
216
|
-
var blockMeta = {
|
|
217
|
-
category: "typography",
|
|
218
|
-
type: "container",
|
|
219
|
-
label: "Content Block",
|
|
220
|
-
icon: ContentBlockIcon,
|
|
221
|
-
constraints: [
|
|
222
|
-
{
|
|
223
|
-
relation: "ancestor",
|
|
224
|
-
component: { $nin: [collectionComponent, blockComponent] }
|
|
225
|
-
},
|
|
226
|
-
{
|
|
227
|
-
relation: "child",
|
|
228
|
-
component: { $eq: blockTemplateComponent }
|
|
229
|
-
}
|
|
230
|
-
],
|
|
231
|
-
stylable: false,
|
|
232
|
-
template: [
|
|
233
|
-
{
|
|
234
|
-
type: "instance",
|
|
235
|
-
component: blockComponent,
|
|
236
|
-
props: [],
|
|
237
|
-
children: [
|
|
238
|
-
{
|
|
239
|
-
component: blockTemplateComponent,
|
|
240
|
-
type: "instance",
|
|
241
|
-
label: "Templates",
|
|
242
|
-
children: [
|
|
243
|
-
{
|
|
244
|
-
component: "Paragraph",
|
|
245
|
-
type: "instance",
|
|
246
|
-
children: []
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
component: "Heading",
|
|
250
|
-
type: "instance",
|
|
251
|
-
label: "Heading 1",
|
|
252
|
-
props: [
|
|
253
|
-
{
|
|
254
|
-
name: "tag",
|
|
255
|
-
type: "string",
|
|
256
|
-
value: "h1"
|
|
257
|
-
}
|
|
258
|
-
],
|
|
259
|
-
children: []
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
component: "Heading",
|
|
263
|
-
type: "instance",
|
|
264
|
-
label: "Heading 2",
|
|
265
|
-
props: [
|
|
266
|
-
{
|
|
267
|
-
name: "tag",
|
|
268
|
-
type: "string",
|
|
269
|
-
value: "h2"
|
|
270
|
-
}
|
|
271
|
-
],
|
|
272
|
-
children: []
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
component: "Heading",
|
|
276
|
-
type: "instance",
|
|
277
|
-
label: "Heading 3",
|
|
278
|
-
props: [
|
|
279
|
-
{
|
|
280
|
-
name: "tag",
|
|
281
|
-
type: "string",
|
|
282
|
-
value: "h3"
|
|
283
|
-
}
|
|
284
|
-
],
|
|
285
|
-
children: []
|
|
286
|
-
},
|
|
287
|
-
{
|
|
288
|
-
component: "Heading",
|
|
289
|
-
type: "instance",
|
|
290
|
-
label: "Heading 4",
|
|
291
|
-
props: [
|
|
292
|
-
{
|
|
293
|
-
name: "tag",
|
|
294
|
-
type: "string",
|
|
295
|
-
value: "h4"
|
|
296
|
-
}
|
|
297
|
-
],
|
|
298
|
-
children: []
|
|
299
|
-
},
|
|
300
|
-
{
|
|
301
|
-
component: "Heading",
|
|
302
|
-
type: "instance",
|
|
303
|
-
label: "Heading 5",
|
|
304
|
-
props: [
|
|
305
|
-
{
|
|
306
|
-
name: "tag",
|
|
307
|
-
type: "string",
|
|
308
|
-
value: "h5"
|
|
309
|
-
}
|
|
310
|
-
],
|
|
311
|
-
children: []
|
|
312
|
-
},
|
|
313
|
-
{
|
|
314
|
-
component: "Heading",
|
|
315
|
-
type: "instance",
|
|
316
|
-
label: "Heading 6",
|
|
317
|
-
props: [
|
|
318
|
-
{
|
|
319
|
-
name: "tag",
|
|
320
|
-
type: "string",
|
|
321
|
-
value: "h6"
|
|
322
|
-
}
|
|
323
|
-
],
|
|
324
|
-
children: []
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
component: "List",
|
|
328
|
-
type: "instance",
|
|
329
|
-
label: "List (Unordered)",
|
|
330
|
-
children: [
|
|
331
|
-
{
|
|
332
|
-
component: "ListItem",
|
|
333
|
-
type: "instance",
|
|
334
|
-
children: []
|
|
335
|
-
}
|
|
336
|
-
]
|
|
337
|
-
},
|
|
338
|
-
{
|
|
339
|
-
component: "List",
|
|
340
|
-
type: "instance",
|
|
341
|
-
label: "List (Ordered)",
|
|
342
|
-
props: [
|
|
343
|
-
{
|
|
344
|
-
name: "ordered",
|
|
345
|
-
type: "boolean",
|
|
346
|
-
value: true
|
|
347
|
-
}
|
|
348
|
-
],
|
|
349
|
-
children: [
|
|
350
|
-
{
|
|
351
|
-
component: "ListItem",
|
|
352
|
-
type: "instance",
|
|
353
|
-
children: []
|
|
354
|
-
}
|
|
355
|
-
]
|
|
356
|
-
},
|
|
357
|
-
{
|
|
358
|
-
component: "Link",
|
|
359
|
-
type: "instance",
|
|
360
|
-
children: []
|
|
361
|
-
},
|
|
362
|
-
{
|
|
363
|
-
component: "Image",
|
|
364
|
-
type: "instance",
|
|
365
|
-
styles: [
|
|
366
|
-
{
|
|
367
|
-
property: "marginRight",
|
|
368
|
-
value: {
|
|
369
|
-
type: "keyword",
|
|
370
|
-
value: "auto"
|
|
371
|
-
}
|
|
372
|
-
},
|
|
373
|
-
{
|
|
374
|
-
property: "marginLeft",
|
|
375
|
-
value: {
|
|
376
|
-
type: "keyword",
|
|
377
|
-
value: "auto"
|
|
378
|
-
}
|
|
379
|
-
},
|
|
380
|
-
{
|
|
381
|
-
property: "width",
|
|
382
|
-
value: {
|
|
383
|
-
type: "unit",
|
|
384
|
-
unit: "%",
|
|
385
|
-
value: 100
|
|
386
|
-
}
|
|
387
|
-
},
|
|
388
|
-
{
|
|
389
|
-
property: "height",
|
|
390
|
-
value: {
|
|
391
|
-
type: "keyword",
|
|
392
|
-
value: "auto"
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
],
|
|
396
|
-
children: []
|
|
397
|
-
},
|
|
398
|
-
{
|
|
399
|
-
component: "Separator",
|
|
400
|
-
type: "instance",
|
|
401
|
-
children: []
|
|
402
|
-
},
|
|
403
|
-
{
|
|
404
|
-
component: "Blockquote",
|
|
405
|
-
type: "instance",
|
|
406
|
-
children: []
|
|
407
|
-
},
|
|
408
|
-
{
|
|
409
|
-
component: "HtmlEmbed",
|
|
410
|
-
type: "instance",
|
|
411
|
-
children: []
|
|
412
|
-
},
|
|
413
|
-
{
|
|
414
|
-
component: "CodeText",
|
|
415
|
-
type: "instance",
|
|
416
|
-
children: []
|
|
417
|
-
}
|
|
418
|
-
]
|
|
419
|
-
},
|
|
420
|
-
{
|
|
421
|
-
type: "instance",
|
|
422
|
-
component: "Paragraph",
|
|
423
|
-
children: [
|
|
424
|
-
{
|
|
425
|
-
type: "text",
|
|
426
|
-
value: "The Content Block component designates regions on the page where pre-styled instances can be inserted in "
|
|
427
|
-
},
|
|
428
|
-
{
|
|
429
|
-
type: "instance",
|
|
430
|
-
component: "RichTextLink",
|
|
431
|
-
children: [
|
|
432
|
-
{
|
|
433
|
-
type: "text",
|
|
434
|
-
value: "Content mode"
|
|
435
|
-
}
|
|
436
|
-
],
|
|
437
|
-
props: [
|
|
438
|
-
{
|
|
439
|
-
type: "string",
|
|
440
|
-
name: "href",
|
|
441
|
-
value: "https://wstd.us/content-block"
|
|
442
|
-
}
|
|
443
|
-
]
|
|
444
|
-
},
|
|
445
|
-
{
|
|
446
|
-
type: "text",
|
|
447
|
-
value: "."
|
|
448
|
-
}
|
|
449
|
-
]
|
|
450
|
-
},
|
|
451
|
-
{
|
|
452
|
-
type: "instance",
|
|
453
|
-
component: "List",
|
|
454
|
-
children: [
|
|
455
|
-
{
|
|
456
|
-
type: "instance",
|
|
457
|
-
component: "ListItem",
|
|
458
|
-
children: [
|
|
459
|
-
{
|
|
460
|
-
type: "text",
|
|
461
|
-
value: "In Content mode, you can edit any direct child instances that were pre-added to the Content Block, as well as add new instances predefined in Templates."
|
|
462
|
-
}
|
|
463
|
-
]
|
|
464
|
-
},
|
|
465
|
-
{
|
|
466
|
-
type: "instance",
|
|
467
|
-
component: "ListItem",
|
|
468
|
-
children: [
|
|
469
|
-
{
|
|
470
|
-
type: "text",
|
|
471
|
-
value: "To predefine instances for insertion in Content mode, switch to Design mode and add them to the Templates container."
|
|
472
|
-
}
|
|
473
|
-
]
|
|
474
|
-
},
|
|
475
|
-
{
|
|
476
|
-
type: "instance",
|
|
477
|
-
component: "ListItem",
|
|
478
|
-
children: [
|
|
479
|
-
{
|
|
480
|
-
type: "text",
|
|
481
|
-
value: "To insert predefined instances in Content mode, click the + button while hovering over the Content Block on the canvas and choose an instance from the list."
|
|
482
|
-
}
|
|
483
|
-
]
|
|
484
|
-
}
|
|
485
|
-
]
|
|
486
|
-
}
|
|
487
|
-
]
|
|
488
|
-
}
|
|
489
|
-
]
|
|
490
|
-
};
|
|
491
|
-
var blockPropsMeta = {
|
|
492
|
-
props: {},
|
|
493
|
-
initialProps: []
|
|
494
|
-
};
|
|
495
|
-
var coreMetas = {
|
|
496
|
-
[rootComponent]: rootMeta,
|
|
497
|
-
[collectionComponent]: collectionMeta,
|
|
498
|
-
[descendantComponent]: descendantMeta,
|
|
499
|
-
[blockComponent]: blockMeta,
|
|
500
|
-
[blockTemplateComponent]: blockTemplateMeta
|
|
501
|
-
};
|
|
502
|
-
var corePropsMetas = {
|
|
503
|
-
[rootComponent]: rootPropsMeta,
|
|
504
|
-
[collectionComponent]: collectionPropsMeta,
|
|
505
|
-
[descendantComponent]: descendantPropsMeta,
|
|
506
|
-
[blockComponent]: blockPropsMeta,
|
|
507
|
-
[blockTemplateComponent]: blockTemplatePropsMeta
|
|
508
|
-
};
|
|
509
|
-
var isCoreComponent = (component) => component === rootComponent || component === collectionComponent || component === descendantComponent || component === blockComponent || component === blockTemplateComponent;
|
|
510
|
-
|
|
511
|
-
// src/css/css.ts
|
|
512
84
|
import { kebabCase } from "change-case";
|
|
513
85
|
var createImageValueTransformer = (assets, { assetBaseUrl }) => (styleValue) => {
|
|
514
86
|
if (styleValue.type === "image" && styleValue.value.type === "asset") {
|
|
@@ -1118,7 +690,11 @@ import {
|
|
|
1118
690
|
parseComponentName as parseComponentName2,
|
|
1119
691
|
generateExpression,
|
|
1120
692
|
decodeDataSourceVariable,
|
|
1121
|
-
transpileExpression as transpileExpression2
|
|
693
|
+
transpileExpression as transpileExpression2,
|
|
694
|
+
blockComponent,
|
|
695
|
+
blockTemplateComponent,
|
|
696
|
+
collectionComponent,
|
|
697
|
+
descendantComponent as descendantComponent2
|
|
1122
698
|
} from "@webstudio-is/sdk";
|
|
1123
699
|
var generateAction = ({
|
|
1124
700
|
scope,
|
|
@@ -1220,7 +796,7 @@ var generateJsxElement = ({
|
|
|
1220
796
|
children,
|
|
1221
797
|
classesMap
|
|
1222
798
|
}) => {
|
|
1223
|
-
if (instance.component ===
|
|
799
|
+
if (instance.component === descendantComponent2) {
|
|
1224
800
|
return "";
|
|
1225
801
|
}
|
|
1226
802
|
let generatedProps = "";
|
|
@@ -1232,8 +808,7 @@ ${indexAttribute}="${index}"`;
|
|
|
1232
808
|
let conditionValue;
|
|
1233
809
|
let collectionDataValue;
|
|
1234
810
|
let collectionItemValue;
|
|
1235
|
-
|
|
1236
|
-
const classes = classMapArray !== void 0 ? [JSON.stringify(classMapArray.join(" "))] : [];
|
|
811
|
+
let classNameValue;
|
|
1237
812
|
for (const prop of props.values()) {
|
|
1238
813
|
if (prop.instanceId !== instance.id) {
|
|
1239
814
|
continue;
|
|
@@ -1267,7 +842,7 @@ ${indexAttribute}="${index}"`;
|
|
|
1267
842
|
continue;
|
|
1268
843
|
}
|
|
1269
844
|
if (prop.name === "className" && propValue !== void 0) {
|
|
1270
|
-
|
|
845
|
+
classNameValue = propValue;
|
|
1271
846
|
continue;
|
|
1272
847
|
}
|
|
1273
848
|
if (propValue !== void 0) {
|
|
@@ -1275,9 +850,16 @@ ${indexAttribute}="${index}"`;
|
|
|
1275
850
|
${prop.name}={${propValue}}`;
|
|
1276
851
|
}
|
|
1277
852
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
853
|
+
const classMapArray = classesMap?.get(instance.id);
|
|
854
|
+
if (classMapArray || classNameValue) {
|
|
855
|
+
let classNameTemplate = classMapArray ? classMapArray.join(" ") : "";
|
|
856
|
+
if (classNameValue) {
|
|
857
|
+
if (classNameTemplate) {
|
|
858
|
+
classNameTemplate += " ";
|
|
859
|
+
}
|
|
860
|
+
classNameTemplate += "${" + classNameValue + "}";
|
|
861
|
+
}
|
|
862
|
+
generatedProps += "\nclassName={`" + classNameTemplate + "`}";
|
|
1281
863
|
}
|
|
1282
864
|
let generatedElement = "";
|
|
1283
865
|
if (instance.component === blockTemplateComponent) {
|
|
@@ -1489,16 +1071,9 @@ var generateWebstudioComponent = ({
|
|
|
1489
1071
|
};
|
|
1490
1072
|
export {
|
|
1491
1073
|
addGlobalRules,
|
|
1492
|
-
blockComponent,
|
|
1493
|
-
blockTemplateComponent,
|
|
1494
|
-
blockTemplateMeta,
|
|
1495
1074
|
collapsedAttribute,
|
|
1496
|
-
collectionComponent,
|
|
1497
1075
|
componentAttribute,
|
|
1498
|
-
coreMetas,
|
|
1499
|
-
corePropsMetas,
|
|
1500
1076
|
createImageValueTransformer,
|
|
1501
|
-
descendantComponent,
|
|
1502
1077
|
editablePlaceholderVariable,
|
|
1503
1078
|
editingPlaceholderVariable,
|
|
1504
1079
|
generateCss,
|
|
@@ -1512,11 +1087,8 @@ export {
|
|
|
1512
1087
|
idAttribute,
|
|
1513
1088
|
indexAttribute,
|
|
1514
1089
|
isAttributeNameSafe,
|
|
1515
|
-
isCoreComponent,
|
|
1516
1090
|
namespaceMeta,
|
|
1517
1091
|
normalizeProps,
|
|
1518
|
-
portalComponent,
|
|
1519
|
-
rootComponent,
|
|
1520
1092
|
selectorIdAttribute,
|
|
1521
1093
|
showAttribute,
|
|
1522
1094
|
textContentAttribute
|
package/lib/runtime.js
CHANGED
|
@@ -47,12 +47,134 @@ var useVariableState = (initialState) => {
|
|
|
47
47
|
return [value, setState];
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
+
// src/page-settings-meta.tsx
|
|
51
|
+
import { useEffect, useState as useState2 } from "react";
|
|
52
|
+
import { jsx } from "react/jsx-runtime";
|
|
53
|
+
var isElementRenderedWithReact = (element) => {
|
|
54
|
+
return Object.keys(element).some((key) => key.startsWith("__react"));
|
|
55
|
+
};
|
|
56
|
+
var isServer = typeof window === "undefined";
|
|
57
|
+
var Meta = (props) => {
|
|
58
|
+
const [localProps, setLocalProps] = useState2();
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
const selector = `meta[${props.name ? `name="${props.name}"` : `property="${props.property}"`}]`;
|
|
61
|
+
let allMetas = document.querySelectorAll(selector);
|
|
62
|
+
for (const meta of allMetas) {
|
|
63
|
+
if (!isElementRenderedWithReact(meta)) {
|
|
64
|
+
meta.remove();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
allMetas = document.querySelectorAll(selector);
|
|
68
|
+
if (allMetas.length === 0) {
|
|
69
|
+
setLocalProps(props);
|
|
70
|
+
}
|
|
71
|
+
}, [props]);
|
|
72
|
+
if (isServer) {
|
|
73
|
+
return /* @__PURE__ */ jsx("meta", { ...props });
|
|
74
|
+
}
|
|
75
|
+
if (localProps === void 0) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
return /* @__PURE__ */ jsx("meta", { ...localProps });
|
|
79
|
+
};
|
|
80
|
+
var PageSettingsMeta = ({
|
|
81
|
+
url,
|
|
82
|
+
host,
|
|
83
|
+
siteName,
|
|
84
|
+
pageMeta,
|
|
85
|
+
imageLoader
|
|
86
|
+
}) => {
|
|
87
|
+
const metas = [];
|
|
88
|
+
if (url !== void 0) {
|
|
89
|
+
metas.push({
|
|
90
|
+
property: "og:url",
|
|
91
|
+
content: url
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (pageMeta.title) {
|
|
95
|
+
metas.push({
|
|
96
|
+
property: "og:title",
|
|
97
|
+
content: pageMeta.title
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
metas.push({ property: "og:type", content: "website" });
|
|
101
|
+
if (siteName) {
|
|
102
|
+
metas.push({
|
|
103
|
+
property: "og:site_name",
|
|
104
|
+
content: siteName
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (pageMeta.excludePageFromSearch) {
|
|
108
|
+
metas.push({
|
|
109
|
+
name: "robots",
|
|
110
|
+
content: "noindex, nofollow"
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (pageMeta.description) {
|
|
114
|
+
metas.push({
|
|
115
|
+
name: "description",
|
|
116
|
+
content: pageMeta.description
|
|
117
|
+
});
|
|
118
|
+
metas.push({
|
|
119
|
+
property: "og:description",
|
|
120
|
+
content: pageMeta.description
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (pageMeta.socialImageAssetName) {
|
|
124
|
+
metas.push({
|
|
125
|
+
property: "og:image",
|
|
126
|
+
content: `https://${host}${imageLoader({
|
|
127
|
+
src: pageMeta.socialImageAssetName,
|
|
128
|
+
// Do not transform social image (not enough information do we need to do this)
|
|
129
|
+
format: "raw"
|
|
130
|
+
})}`
|
|
131
|
+
});
|
|
132
|
+
} else if (pageMeta.socialImageUrl) {
|
|
133
|
+
metas.push({
|
|
134
|
+
property: "og:image",
|
|
135
|
+
content: pageMeta.socialImageUrl
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
metas.push(...pageMeta.custom);
|
|
139
|
+
return metas.map((meta, index) => /* @__PURE__ */ jsx(Meta, { ...meta }, index));
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// src/page-settings-title.tsx
|
|
143
|
+
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
144
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
145
|
+
var isServer2 = typeof window === "undefined";
|
|
146
|
+
var PageSettingsTitle = (props) => {
|
|
147
|
+
const [localProps, setLocalProps] = useState3();
|
|
148
|
+
useEffect2(() => {
|
|
149
|
+
const selector = `head > title`;
|
|
150
|
+
let allTitles = document.querySelectorAll(selector);
|
|
151
|
+
for (const meta of allTitles) {
|
|
152
|
+
if (!isElementRenderedWithReact(meta)) {
|
|
153
|
+
meta.remove();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
allTitles = document.querySelectorAll(selector);
|
|
157
|
+
if (allTitles.length === 0) {
|
|
158
|
+
setLocalProps(props);
|
|
159
|
+
}
|
|
160
|
+
}, [props]);
|
|
161
|
+
if (isServer2) {
|
|
162
|
+
return /* @__PURE__ */ jsx2("title", { ...props });
|
|
163
|
+
}
|
|
164
|
+
if (localProps === void 0) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
return /* @__PURE__ */ jsx2("title", { ...localProps });
|
|
168
|
+
};
|
|
169
|
+
|
|
50
170
|
// src/runtime.ts
|
|
51
171
|
var xmlNodeTagSuffix = "-ws-xml-node-fb77f896-8e96-40b9-b8f8-90a4e70d724a";
|
|
52
172
|
var getIndexWithinAncestorFromComponentProps = (props) => {
|
|
53
173
|
return props["data-ws-index"];
|
|
54
174
|
};
|
|
55
175
|
export {
|
|
176
|
+
PageSettingsMeta,
|
|
177
|
+
PageSettingsTitle,
|
|
56
178
|
ReactSdkContext,
|
|
57
179
|
getClosestInstance,
|
|
58
180
|
getIndexWithinAncestorFromComponentProps,
|
package/lib/types/index.d.ts
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ImageLoader } from "@webstudio-is/image";
|
|
2
|
+
import type { PageMeta } from "@webstudio-is/sdk";
|
|
3
|
+
export declare const isElementRenderedWithReact: (element: Element) => boolean;
|
|
4
|
+
export declare const PageSettingsMeta: ({ url, host, siteName, pageMeta, imageLoader, }: {
|
|
5
|
+
url?: string;
|
|
6
|
+
host: string;
|
|
7
|
+
siteName: string;
|
|
8
|
+
pageMeta: PageMeta;
|
|
9
|
+
imageLoader: ImageLoader;
|
|
10
|
+
}) => import("react/jsx-runtime").JSX.Element[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type PageSettingsTitleProps = {
|
|
2
|
+
children: string;
|
|
3
|
+
};
|
|
4
|
+
/**
|
|
5
|
+
* Title tags are deduplicated on the server using the HTMLRewriter interface.
|
|
6
|
+
* This is not full deduplication. We simply skip rendering Page Setting title
|
|
7
|
+
* if it has already been rendered using HeadSlot/HeadTitle.
|
|
8
|
+
* To prevent React on the client from re-adding the removed title tag, we skip rendering them client-side.
|
|
9
|
+
* This approach works because React retains server-rendered title tag as long as they are not re-rendered by the client.
|
|
10
|
+
*
|
|
11
|
+
* The following component behavior ensures this:
|
|
12
|
+
* 1. On the server: Render title tag as usual.
|
|
13
|
+
* 2. On the client: Before rendering, remove any title tag with the same `name` or `property` that were not rendered by Client React,
|
|
14
|
+
* and then proceed with rendering as usual.
|
|
15
|
+
*/
|
|
16
|
+
export declare const PageSettingsTitle: (props: PageSettingsTitleProps) => import("react/jsx-runtime").JSX.Element | undefined;
|
|
17
|
+
export {};
|
package/lib/types/runtime.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export * from "./context";
|
|
2
2
|
export * from "./hook";
|
|
3
3
|
export * from "./variable-state";
|
|
4
|
+
export { PageSettingsMeta } from "./page-settings-meta";
|
|
5
|
+
export { PageSettingsTitle } from "./page-settings-title";
|
|
4
6
|
/**
|
|
5
7
|
* React has issues rendering certain elements, such as errors when a <link> element has children.
|
|
6
8
|
* To render XML, we wrap it with an <svg> tag and add a suffix to avoid React's default behavior on these elements.
|