@unlayer/react-elements 0.1.14 → 0.1.16
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/dist/index.cjs +62 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -5
- package/dist/index.d.ts +19 -5
- package/dist/index.js +62 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -160,7 +160,7 @@ declare const DEFAULT_CONFIG: UnlayerConfig;
|
|
|
160
160
|
* configurations that match exactly what the Unlayer editor supports.
|
|
161
161
|
*
|
|
162
162
|
* Usage:
|
|
163
|
-
* import { ColumnLayouts } from '@unlayer
|
|
163
|
+
* import { ColumnLayouts } from '@unlayer/react-elements';
|
|
164
164
|
* <Row layout={ColumnLayouts.TwoEqual}>
|
|
165
165
|
* <Column>...</Column>
|
|
166
166
|
* <Column>...</Column>
|
|
@@ -368,7 +368,8 @@ interface ButtonProps extends ItemComponentProps<ButtonSemanticProps> {
|
|
|
368
368
|
*
|
|
369
369
|
* @example Flat Props (Simple - most common)
|
|
370
370
|
* ```tsx
|
|
371
|
-
*
|
|
371
|
+
* // `href` accepts a plain URL string (the ergonomic form).
|
|
372
|
+
* <Button href="https://example.com" color="white" backgroundColor="#3b82f6" fontSize="16px">
|
|
372
373
|
* Click me
|
|
373
374
|
* </Button>
|
|
374
375
|
* ```
|
|
@@ -466,6 +467,13 @@ interface HtmlProps extends ItemComponentProps<SemanticProps<HtmlValues>> {
|
|
|
466
467
|
/**
|
|
467
468
|
* Html - Universal SSR/Client Component for custom HTML with Automatic Semantic Props
|
|
468
469
|
*
|
|
470
|
+
* ⚠️ Renders the HTML verbatim — it is NOT sanitized by default. Only pass HTML
|
|
471
|
+
* you trust, and make sure it is valid: notably, an inline SVG inside a `url(...)`
|
|
472
|
+
* must be URL-encoded, because a raw `"` inside a double-quoted `style="…"`
|
|
473
|
+
* closes the attribute and the rest leaks out as text. To sanitize (matching the
|
|
474
|
+
* editor's HTML block, which strips scripts/event handlers), pass a `toSafeHtml`
|
|
475
|
+
* function via the `UnlayerProvider` config.
|
|
476
|
+
*
|
|
469
477
|
* @example Flat Props
|
|
470
478
|
* ```tsx
|
|
471
479
|
* <Html html="<div>Custom HTML</div>" />
|
|
@@ -578,15 +586,21 @@ interface ParagraphProps extends ItemComponentProps<ParagraphSemanticProps> {
|
|
|
578
586
|
*/
|
|
579
587
|
declare const Paragraph: React$1.FC<ItemComponentProps<ParagraphSemanticProps>>;
|
|
580
588
|
|
|
581
|
-
type SocialSemanticProps = SemanticProps<SocialValues> & {
|
|
589
|
+
type SocialSemanticProps = Omit<SemanticProps<SocialValues>, "iconSize" | "spacing"> & {
|
|
582
590
|
/** Social icons shorthand (array of {name, url}) */
|
|
583
591
|
icons?: SocialIcon[];
|
|
584
592
|
/** Icon shape */
|
|
585
593
|
iconType?: "circle" | "rounded" | "squared";
|
|
594
|
+
/** Icon size in px — a number (34) or px string ("34px"). */
|
|
595
|
+
iconSize?: SizeInput;
|
|
596
|
+
/** Gap between icons in px — a number or px string. */
|
|
597
|
+
spacing?: SizeInput;
|
|
586
598
|
};
|
|
587
|
-
interface SocialProps extends Omit<ItemComponentProps<SemanticProps<SocialValues>>, "icons"> {
|
|
599
|
+
interface SocialProps extends Omit<ItemComponentProps<SemanticProps<SocialValues>>, "icons" | "iconSize" | "spacing"> {
|
|
588
600
|
icons?: SocialIcon[] | SocialValues["icons"];
|
|
589
601
|
iconType?: "circle" | "rounded" | "squared";
|
|
602
|
+
iconSize?: SizeInput;
|
|
603
|
+
spacing?: SizeInput;
|
|
590
604
|
}
|
|
591
605
|
/**
|
|
592
606
|
* Social - Renders social-media icon links.
|
|
@@ -958,4 +972,4 @@ declare function renderToHtmlParts(element: React__default.ReactElement, config?
|
|
|
958
972
|
declare function renderRowToJson(element: React__default.ReactElement): DesignRow;
|
|
959
973
|
declare function renderToJson(element: React__default.ReactElement): DesignJSON;
|
|
960
974
|
|
|
961
|
-
export { Body, Button, type ButtonProps, Column, type ColumnLayout, ColumnLayouts, DEFAULT_CONFIG, type DesignBody, type DesignColumn, type DesignContent, type DesignJSON, type DesignRow, Divider, type DividerProps, Document, type DocumentProps, Email, type EmailProps, Heading, type HeadingProps, type Href, Html, type HtmlParts, type HtmlProps, type Icons, Image, type ImageProps, type LinkStyle, Menu, type MenuItem, type MenuProps, Page, type PageProps, Paragraph, type ParagraphProps, Row, type RowProps, Social, type SocialIcon, type SocialProps, Table, type TableProps, type TextAlign, type UnlayerConfig, UnlayerProvider, type UnlayerProviderProps, type ValidColumnLayout, Video, type VideoProps, type VideoSource, htmlToTextJson, renderRowToJson, renderToHtml, renderToHtmlParts, renderToJson, renderToPlainText, useUnlayerConfig, validateColumnLayout };
|
|
975
|
+
export { Body, type BorderInput, Button, type ButtonProps, Column, type ColumnLayout, ColumnLayouts, DEFAULT_CONFIG, type DesignBody, type DesignColumn, type DesignContent, type DesignJSON, type DesignRow, Divider, type DividerProps, Document, type DocumentProps, Email, type EmailProps, type FontFamilyInput, type FontWeightInput, Heading, type HeadingLevel, type HeadingProps, type Href, Html, type HtmlParts, type HtmlProps, type Icons, Image, type ImageProps, type ImageSrcInput, type LinkStyle, Menu, type MenuItem, type MenuProps, Page, type PageProps, Paragraph, type ParagraphProps, Row, type RowProps, type SizeInput, Social, type SocialIcon, type SocialProps, Table, type TableProps, type TextAlign, type TextStyleProps, type UnlayerConfig, UnlayerProvider, type UnlayerProviderProps, type ValidColumnLayout, Video, type VideoProps, type VideoSource, htmlToTextJson, renderRowToJson, renderToHtml, renderToHtmlParts, renderToJson, renderToPlainText, useUnlayerConfig, validateColumnLayout };
|
package/dist/index.d.ts
CHANGED
|
@@ -160,7 +160,7 @@ declare const DEFAULT_CONFIG: UnlayerConfig;
|
|
|
160
160
|
* configurations that match exactly what the Unlayer editor supports.
|
|
161
161
|
*
|
|
162
162
|
* Usage:
|
|
163
|
-
* import { ColumnLayouts } from '@unlayer
|
|
163
|
+
* import { ColumnLayouts } from '@unlayer/react-elements';
|
|
164
164
|
* <Row layout={ColumnLayouts.TwoEqual}>
|
|
165
165
|
* <Column>...</Column>
|
|
166
166
|
* <Column>...</Column>
|
|
@@ -368,7 +368,8 @@ interface ButtonProps extends ItemComponentProps<ButtonSemanticProps> {
|
|
|
368
368
|
*
|
|
369
369
|
* @example Flat Props (Simple - most common)
|
|
370
370
|
* ```tsx
|
|
371
|
-
*
|
|
371
|
+
* // `href` accepts a plain URL string (the ergonomic form).
|
|
372
|
+
* <Button href="https://example.com" color="white" backgroundColor="#3b82f6" fontSize="16px">
|
|
372
373
|
* Click me
|
|
373
374
|
* </Button>
|
|
374
375
|
* ```
|
|
@@ -466,6 +467,13 @@ interface HtmlProps extends ItemComponentProps<SemanticProps<HtmlValues>> {
|
|
|
466
467
|
/**
|
|
467
468
|
* Html - Universal SSR/Client Component for custom HTML with Automatic Semantic Props
|
|
468
469
|
*
|
|
470
|
+
* ⚠️ Renders the HTML verbatim — it is NOT sanitized by default. Only pass HTML
|
|
471
|
+
* you trust, and make sure it is valid: notably, an inline SVG inside a `url(...)`
|
|
472
|
+
* must be URL-encoded, because a raw `"` inside a double-quoted `style="…"`
|
|
473
|
+
* closes the attribute and the rest leaks out as text. To sanitize (matching the
|
|
474
|
+
* editor's HTML block, which strips scripts/event handlers), pass a `toSafeHtml`
|
|
475
|
+
* function via the `UnlayerProvider` config.
|
|
476
|
+
*
|
|
469
477
|
* @example Flat Props
|
|
470
478
|
* ```tsx
|
|
471
479
|
* <Html html="<div>Custom HTML</div>" />
|
|
@@ -578,15 +586,21 @@ interface ParagraphProps extends ItemComponentProps<ParagraphSemanticProps> {
|
|
|
578
586
|
*/
|
|
579
587
|
declare const Paragraph: React$1.FC<ItemComponentProps<ParagraphSemanticProps>>;
|
|
580
588
|
|
|
581
|
-
type SocialSemanticProps = SemanticProps<SocialValues> & {
|
|
589
|
+
type SocialSemanticProps = Omit<SemanticProps<SocialValues>, "iconSize" | "spacing"> & {
|
|
582
590
|
/** Social icons shorthand (array of {name, url}) */
|
|
583
591
|
icons?: SocialIcon[];
|
|
584
592
|
/** Icon shape */
|
|
585
593
|
iconType?: "circle" | "rounded" | "squared";
|
|
594
|
+
/** Icon size in px — a number (34) or px string ("34px"). */
|
|
595
|
+
iconSize?: SizeInput;
|
|
596
|
+
/** Gap between icons in px — a number or px string. */
|
|
597
|
+
spacing?: SizeInput;
|
|
586
598
|
};
|
|
587
|
-
interface SocialProps extends Omit<ItemComponentProps<SemanticProps<SocialValues>>, "icons"> {
|
|
599
|
+
interface SocialProps extends Omit<ItemComponentProps<SemanticProps<SocialValues>>, "icons" | "iconSize" | "spacing"> {
|
|
588
600
|
icons?: SocialIcon[] | SocialValues["icons"];
|
|
589
601
|
iconType?: "circle" | "rounded" | "squared";
|
|
602
|
+
iconSize?: SizeInput;
|
|
603
|
+
spacing?: SizeInput;
|
|
590
604
|
}
|
|
591
605
|
/**
|
|
592
606
|
* Social - Renders social-media icon links.
|
|
@@ -958,4 +972,4 @@ declare function renderToHtmlParts(element: React__default.ReactElement, config?
|
|
|
958
972
|
declare function renderRowToJson(element: React__default.ReactElement): DesignRow;
|
|
959
973
|
declare function renderToJson(element: React__default.ReactElement): DesignJSON;
|
|
960
974
|
|
|
961
|
-
export { Body, Button, type ButtonProps, Column, type ColumnLayout, ColumnLayouts, DEFAULT_CONFIG, type DesignBody, type DesignColumn, type DesignContent, type DesignJSON, type DesignRow, Divider, type DividerProps, Document, type DocumentProps, Email, type EmailProps, Heading, type HeadingProps, type Href, Html, type HtmlParts, type HtmlProps, type Icons, Image, type ImageProps, type LinkStyle, Menu, type MenuItem, type MenuProps, Page, type PageProps, Paragraph, type ParagraphProps, Row, type RowProps, Social, type SocialIcon, type SocialProps, Table, type TableProps, type TextAlign, type UnlayerConfig, UnlayerProvider, type UnlayerProviderProps, type ValidColumnLayout, Video, type VideoProps, type VideoSource, htmlToTextJson, renderRowToJson, renderToHtml, renderToHtmlParts, renderToJson, renderToPlainText, useUnlayerConfig, validateColumnLayout };
|
|
975
|
+
export { Body, type BorderInput, Button, type ButtonProps, Column, type ColumnLayout, ColumnLayouts, DEFAULT_CONFIG, type DesignBody, type DesignColumn, type DesignContent, type DesignJSON, type DesignRow, Divider, type DividerProps, Document, type DocumentProps, Email, type EmailProps, type FontFamilyInput, type FontWeightInput, Heading, type HeadingLevel, type HeadingProps, type Href, Html, type HtmlParts, type HtmlProps, type Icons, Image, type ImageProps, type ImageSrcInput, type LinkStyle, Menu, type MenuItem, type MenuProps, Page, type PageProps, Paragraph, type ParagraphProps, Row, type RowProps, type SizeInput, Social, type SocialIcon, type SocialProps, Table, type TableProps, type TextAlign, type TextStyleProps, type UnlayerConfig, UnlayerProvider, type UnlayerProviderProps, type ValidColumnLayout, Video, type VideoProps, type VideoSource, htmlToTextJson, renderRowToJson, renderToHtml, renderToHtmlParts, renderToJson, renderToPlainText, useUnlayerConfig, validateColumnLayout };
|
package/dist/index.js
CHANGED
|
@@ -339,14 +339,27 @@ function mapSemanticProps(props, defaultValues, componentType) {
|
|
|
339
339
|
delete userProps.html;
|
|
340
340
|
delete result.html;
|
|
341
341
|
}
|
|
342
|
-
|
|
343
|
-
const v = userProps[key];
|
|
342
|
+
const canonicalizeLink = (v) => {
|
|
344
343
|
if (typeof v === "string") {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
};
|
|
344
|
+
return { name: "web", values: { href: v, target: "_blank" } };
|
|
345
|
+
}
|
|
346
|
+
if (v && typeof v === "object" && "name" in v && v.attrs && typeof v.attrs === "object") {
|
|
347
|
+
const { href: attrsHref, target: attrsTarget, ...customAttrs } = v.attrs;
|
|
348
|
+
if (attrsHref !== void 0 || attrsTarget !== void 0) {
|
|
349
|
+
const linkValues = { ...v.values };
|
|
350
|
+
if (!linkValues.href && attrsHref !== void 0) linkValues.href = attrsHref;
|
|
351
|
+
if (!linkValues.target && attrsTarget !== void 0) linkValues.target = attrsTarget;
|
|
352
|
+
const next = { ...v, values: linkValues };
|
|
353
|
+
if (Object.keys(customAttrs).length) next.attrs = customAttrs;
|
|
354
|
+
else delete next.attrs;
|
|
355
|
+
return next;
|
|
356
|
+
}
|
|
349
357
|
}
|
|
358
|
+
return v;
|
|
359
|
+
};
|
|
360
|
+
for (const key of ["href", "action"]) {
|
|
361
|
+
if (userProps[key] !== void 0) userProps[key] = canonicalizeLink(userProps[key]);
|
|
362
|
+
if (result[key] !== void 0) result[key] = canonicalizeLink(result[key]);
|
|
350
363
|
}
|
|
351
364
|
normalizeCssProps(userProps);
|
|
352
365
|
const nestedGroups = analyzeNestedStructure(defaultValues);
|
|
@@ -395,6 +408,16 @@ function mapSemanticProps(props, defaultValues, componentType) {
|
|
|
395
408
|
if (Object.keys(collected).length > 0) {
|
|
396
409
|
final.border = { ...final.border || {}, ...collected };
|
|
397
410
|
}
|
|
411
|
+
if (final.border && typeof final.border === "object") {
|
|
412
|
+
const b = { ...final.border };
|
|
413
|
+
for (const key of Object.keys(b)) {
|
|
414
|
+
if (!/Width$/.test(key)) continue;
|
|
415
|
+
const v = b[key];
|
|
416
|
+
if (typeof v === "number") b[key] = `${v}px`;
|
|
417
|
+
else if (typeof v === "string" && /^\d+(?:\.\d+)?$/.test(v.trim())) b[key] = `${v.trim()}px`;
|
|
418
|
+
}
|
|
419
|
+
final.border = b;
|
|
420
|
+
}
|
|
398
421
|
}
|
|
399
422
|
return final;
|
|
400
423
|
}
|
|
@@ -406,12 +429,14 @@ function normalizeLinkValue(value) {
|
|
|
406
429
|
if (typeof value !== "object") return void 0;
|
|
407
430
|
const v = value;
|
|
408
431
|
if ("url" in v) return v;
|
|
409
|
-
if ("name" in v && v.values && typeof v.values === "object") {
|
|
410
|
-
const inner = v.values;
|
|
432
|
+
if ("name" in v && (v.values && typeof v.values === "object" || v.attrs && typeof v.attrs === "object")) {
|
|
433
|
+
const inner = v.values && typeof v.values === "object" ? v.values : {};
|
|
434
|
+
const attrs = v.attrs && typeof v.attrs === "object" ? v.attrs : {};
|
|
435
|
+
const { href: attrsHref, target: attrsTarget, ...customAttrs } = attrs;
|
|
411
436
|
return {
|
|
412
|
-
url: inner.href
|
|
413
|
-
target: inner.target
|
|
414
|
-
...
|
|
437
|
+
url: inner.href || attrsHref || "",
|
|
438
|
+
target: inner.target || attrsTarget || "_blank",
|
|
439
|
+
...customAttrs
|
|
415
440
|
};
|
|
416
441
|
}
|
|
417
442
|
return void 0;
|
|
@@ -763,11 +788,11 @@ var Html = createItemComponent({
|
|
|
763
788
|
exporters: HtmlExporters
|
|
764
789
|
});
|
|
765
790
|
var Html_default = Html;
|
|
791
|
+
var { height: _placeholderHeight, ...defaultSrc } = ImageDefaults.src;
|
|
766
792
|
var DEFAULT_VALUES5 = {
|
|
767
793
|
...ImageDefaults,
|
|
768
|
-
// Override src with autoWidth/maxWidth for responsive rendering
|
|
769
794
|
src: {
|
|
770
|
-
...
|
|
795
|
+
...defaultSrc,
|
|
771
796
|
autoWidth: true,
|
|
772
797
|
maxWidth: "100%"
|
|
773
798
|
}
|
|
@@ -809,7 +834,7 @@ var Image = createItemComponent({
|
|
|
809
834
|
};
|
|
810
835
|
let displayPct;
|
|
811
836
|
let displayPx;
|
|
812
|
-
for (const candidate of [widthProp, maxWidthProp, userSrc.maxWidth]) {
|
|
837
|
+
for (const candidate of [widthProp, maxWidthProp, userSrc.maxWidth, userSrc.width]) {
|
|
813
838
|
if (candidate === void 0) continue;
|
|
814
839
|
const pct = asPercent(candidate);
|
|
815
840
|
if (pct) {
|
|
@@ -900,6 +925,17 @@ var Social = createItemComponent({
|
|
|
900
925
|
defaultValues: DEFAULT_VALUES8,
|
|
901
926
|
propMapper: (props) => {
|
|
902
927
|
const { icons, iconType, ...rest } = props;
|
|
928
|
+
const coerceSizes = (base) => {
|
|
929
|
+
for (const key of ["iconSize", "spacing"]) {
|
|
930
|
+
const v = base[key];
|
|
931
|
+
if (typeof v === "string") {
|
|
932
|
+
const m = /^(\d+(?:\.\d+)?)(?:px)?$/.exec(v.trim());
|
|
933
|
+
if (m) base[key] = parseFloat(m[1]);
|
|
934
|
+
else delete base[key];
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
return base;
|
|
938
|
+
};
|
|
903
939
|
if (Array.isArray(icons)) {
|
|
904
940
|
const mapped = icons.map((icon) => ({
|
|
905
941
|
name: icon.name,
|
|
@@ -914,7 +950,7 @@ var Social = createItemComponent({
|
|
|
914
950
|
iconType: iconType ?? base.icons?.iconType ?? "circle",
|
|
915
951
|
icons: mapped
|
|
916
952
|
};
|
|
917
|
-
return base;
|
|
953
|
+
return coerceSizes(base);
|
|
918
954
|
}
|
|
919
955
|
if (iconType !== void 0) {
|
|
920
956
|
const base = mapSemanticProps(
|
|
@@ -923,12 +959,10 @@ var Social = createItemComponent({
|
|
|
923
959
|
"Social"
|
|
924
960
|
);
|
|
925
961
|
base.icons = { ...DEFAULT_ICONS, ...base.icons, iconType };
|
|
926
|
-
return base;
|
|
962
|
+
return coerceSizes(base);
|
|
927
963
|
}
|
|
928
|
-
return
|
|
929
|
-
props,
|
|
930
|
-
DEFAULT_VALUES8,
|
|
931
|
-
"Social"
|
|
964
|
+
return coerceSizes(
|
|
965
|
+
mapSemanticProps(props, DEFAULT_VALUES8, "Social")
|
|
932
966
|
);
|
|
933
967
|
},
|
|
934
968
|
displayName: "Social",
|
|
@@ -1199,10 +1233,17 @@ var Row = (props) => {
|
|
|
1199
1233
|
...semanticProps
|
|
1200
1234
|
} = props;
|
|
1201
1235
|
const mode = modeProp ?? _config?.mode ?? "web";
|
|
1202
|
-
let cells
|
|
1236
|
+
let cells;
|
|
1203
1237
|
if (layout) {
|
|
1204
1238
|
validateColumnLayout(layout, React.Children.count(children));
|
|
1205
1239
|
cells = layout.cells;
|
|
1240
|
+
} else if (propsCells) {
|
|
1241
|
+
cells = propsCells;
|
|
1242
|
+
} else {
|
|
1243
|
+
const columnCount = React.Children.toArray(children).filter(
|
|
1244
|
+
(c) => React.isValidElement(c) && /^Column$/.test(c.type?.displayName || c.type?.name || "")
|
|
1245
|
+
).length;
|
|
1246
|
+
cells = Array(Math.max(1, columnCount)).fill(1);
|
|
1206
1247
|
}
|
|
1207
1248
|
const safeBodyValues = { ...DEFAULT_BODY_VALUES, ...bodyValues };
|
|
1208
1249
|
const values = mapSemanticProps(
|