@cntrl-site/sdk-nextjs 0.2.13 → 0.3.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.
Files changed (36) hide show
  1. package/.idea/inspectionProfiles/Project_Default.xml +15 -0
  2. package/lib/components/Article.js +2 -2
  3. package/lib/components/Item.js +4 -2
  4. package/lib/components/Page.js +4 -1
  5. package/lib/components/Section.js +3 -1
  6. package/lib/components/items/ImageItem.js +5 -1
  7. package/lib/components/items/RectangleItem.js +5 -1
  8. package/lib/components/items/RichTextItem.js +12 -4
  9. package/lib/components/items/VideoItem.js +26 -22
  10. package/lib/components/items/VimeoEmbed.js +3 -1
  11. package/lib/components/items/YoutubeEmbed.js +3 -1
  12. package/lib/index.js +4 -4
  13. package/lib/provider/CntrlSdkContext.js +7 -0
  14. package/lib/utils/{RichTextConverter.js → RichTextConverter/RichTextConverter.js} +3 -3
  15. package/lib/utils/generateTypePresetStyles/generateTypePresetStyles.js +27 -0
  16. package/package.json +5 -2
  17. package/src/components/Article.tsx +4 -5
  18. package/src/components/Item.tsx +4 -4
  19. package/src/components/Page.tsx +7 -1
  20. package/src/components/Section.tsx +4 -3
  21. package/src/components/items/ImageItem.tsx +15 -11
  22. package/src/components/items/RectangleItem.tsx +12 -8
  23. package/src/components/items/RichTextItem.tsx +22 -11
  24. package/src/components/items/VideoItem.tsx +31 -29
  25. package/src/components/items/VimeoEmbed.tsx +4 -2
  26. package/src/components/items/YoutubeEmbed.tsx +3 -1
  27. package/src/index.ts +2 -3
  28. package/src/provider/CntrlSdkContext.ts +13 -2
  29. package/src/utils/{RichTextConverter.tsx → RichTextConverter/RichTextConverter.tsx} +7 -6
  30. package/src/utils/generateTypePresetStyles/__mock__/layoutsMock.ts +37 -0
  31. package/src/utils/generateTypePresetStyles/__mock__/presetMock.ts +49 -0
  32. package/src/utils/generateTypePresetStyles/generateTypePresetStyles.test.ts +49 -0
  33. package/src/utils/generateTypePresetStyles/generateTypePresetStyles.ts +25 -0
  34. package/src/utils/getInvertedRanges.ts +43 -0
  35. package/.idea/workspace.xml +0 -293
  36. package/cntrl-site-sdk-nextjs-0.2.13.tgz +0 -0
@@ -0,0 +1,15 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
5
+ <option name="myValues">
6
+ <value>
7
+ <list size="1">
8
+ <item index="0" class="java.lang.String" itemvalue="jsx" />
9
+ </list>
10
+ </value>
11
+ </option>
12
+ <option name="myCustomValuesEnabled" value="true" />
13
+ </inspection_tool>
14
+ </profile>
15
+ </component>
@@ -4,8 +4,8 @@ exports.Article = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const Section_1 = require("./Section");
6
6
  const Item_1 = require("./Item");
7
- const Article = ({ article, layouts }) => {
8
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "article", children: article.sections.map((section, i) => ((0, jsx_runtime_1.jsx)(Section_1.Section, { section: section, layouts: layouts, children: article.sections[i].items.map(item => ((0, jsx_runtime_1.jsx)(Item_1.Item, { layouts: layouts, item: item }, item.id))) }, section.id))) }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
7
+ const Article = ({ article }) => {
8
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "article", children: article.sections.map((section, i) => ((0, jsx_runtime_1.jsx)(Section_1.Section, { section: section, children: article.sections[i].items.map(item => ((0, jsx_runtime_1.jsx)(Item_1.Item, { item: item }, item.id))) }, section.id))) }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
9
9
  .article {
10
10
  position: relative;
11
11
  overflow: hidden;
@@ -10,6 +10,7 @@ const RichTextItem_1 = require("./items/RichTextItem");
10
10
  const VimeoEmbed_1 = require("./items/VimeoEmbed");
11
11
  const YoutubeEmbed_1 = require("./items/YoutubeEmbed");
12
12
  const CustomItem_1 = require("./items/CustomItem");
13
+ const useCntrlContext_1 = require("../provider/useCntrlContext");
13
14
  const itemsMap = {
14
15
  [sdk_1.ArticleItemType.Rectangle]: RectangleItem_1.RectangleItem,
15
16
  [sdk_1.ArticleItemType.Image]: ImageItem_1.ImageItem,
@@ -20,14 +21,15 @@ const itemsMap = {
20
21
  [sdk_1.ArticleItemType.Custom]: CustomItem_1.CustomItem
21
22
  };
22
23
  const noop = () => null;
23
- const Item = ({ item, layouts }) => {
24
+ const Item = ({ item }) => {
25
+ const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
24
26
  const layoutValues = [item.area];
25
27
  if (item.layoutParams) {
26
28
  layoutValues.push(item.layoutParams);
27
29
  }
28
30
  const sizingAxis = parseSizing(item.commonParams.sizing);
29
31
  const ItemComponent = itemsMap[item.type] || noop;
30
- return ((0, jsx_runtime_1.jsxs)("div", { className: `item-${item.id}`, children: [(0, jsx_runtime_1.jsx)(ItemComponent, { item: item, layouts: layouts }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
32
+ return ((0, jsx_runtime_1.jsxs)("div", { className: `item-${item.id}`, children: [(0, jsx_runtime_1.jsx)(ItemComponent, { item: item }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
31
33
  ${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area]) => (`
32
34
  .item-${item.id} {
33
35
  position: absolute;
@@ -8,9 +8,12 @@ const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const html_react_parser_1 = __importDefault(require("html-react-parser"));
9
9
  const Article_1 = require("./Article");
10
10
  const Head_1 = require("./Head");
11
+ const useCntrlContext_1 = require("../provider/useCntrlContext");
12
+ const generateTypePresetStyles_1 = require("../utils/generateTypePresetStyles/generateTypePresetStyles");
11
13
  const Page = ({ article, project, meta }) => {
12
14
  const afterBodyOpen = (0, html_react_parser_1.default)(project.html.afterBodyOpen);
13
15
  const beforeBodyClose = (0, html_react_parser_1.default)(project.html.beforeBodyClose);
14
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Head_1.CNTRLHead, { project: project, meta: meta }), afterBodyOpen, (0, jsx_runtime_1.jsx)(Article_1.Article, { article: article, layouts: project.layouts }), beforeBodyClose] }));
16
+ const { typePresets, layouts } = (0, useCntrlContext_1.useCntrlContext)();
17
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Head_1.CNTRLHead, { project: project, meta: meta }), afterBodyOpen, (0, jsx_runtime_1.jsx)(Article_1.Article, { article: article }), beforeBodyClose, typePresets && typePresets.presets.length > 0 && ((0, jsx_runtime_1.jsx)("style", { children: (0, generateTypePresetStyles_1.generateTypePresetStyles)(typePresets, layouts) }))] }));
15
18
  };
16
19
  exports.Page = Page;
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Section = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const sdk_1 = require("@cntrl-site/sdk");
6
- const Section = ({ section, layouts, children }) => {
6
+ const useCntrlContext_1 = require("../provider/useCntrlContext");
7
+ const Section = ({ section, children }) => {
8
+ const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
7
9
  const getSectionVisibilityStyles = () => {
8
10
  return layouts
9
11
  .sort((a, b) => a.startsWith - b.startsWith)
@@ -4,7 +4,10 @@ exports.ImageItem = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const sdk_1 = require("@cntrl-site/sdk");
6
6
  const LinkWrapper_1 = require("../LinkWrapper");
7
- const ImageItem = ({ item, layouts }) => ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: item.link?.url, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `image-wrapper-${item.id}`, children: (0, jsx_runtime_1.jsx)("img", { className: "image", src: item.commonParams.url }) }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
7
+ const useCntrlContext_1 = require("../../provider/useCntrlContext");
8
+ const ImageItem = ({ item }) => {
9
+ const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
10
+ return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: item.link?.url, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `image-wrapper-${item.id}`, children: (0, jsx_runtime_1.jsx)("img", { className: "image", src: item.commonParams.url }) }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
8
11
  ${(0, sdk_1.getLayoutStyles)(layouts, [item.layoutParams], ([{ strokeColor, radius, strokeWidth, opacity }]) => (`
9
12
  .image-wrapper-${item.id} {
10
13
  position: absolute;
@@ -26,4 +29,5 @@ const ImageItem = ({ item, layouts }) => ((0, jsx_runtime_1.jsx)(LinkWrapper_1.L
26
29
  pointer-events: none;
27
30
  }
28
31
  ` })] }) }));
32
+ };
29
33
  exports.ImageItem = ImageItem;
@@ -4,7 +4,10 @@ exports.RectangleItem = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const sdk_1 = require("@cntrl-site/sdk");
6
6
  const LinkWrapper_1 = require("../LinkWrapper");
7
- const RectangleItem = ({ item, layouts }) => ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: item.link?.url, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `rectangle-${item.id}` }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
7
+ const useCntrlContext_1 = require("../../provider/useCntrlContext");
8
+ const RectangleItem = ({ item }) => {
9
+ const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
10
+ return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: item.link?.url, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `rectangle-${item.id}` }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
8
11
  ${(0, sdk_1.getLayoutStyles)(layouts, [item.layoutParams], ([{ strokeColor, fillColor, radius, strokeWidth }]) => (`
9
12
  .rectangle-${item.id} {
10
13
  position: absolute;
@@ -18,4 +21,5 @@ const RectangleItem = ({ item, layouts }) => ((0, jsx_runtime_1.jsx)(LinkWrapper
18
21
  border-width: ${strokeWidth * 100}vw;
19
22
  }`))}
20
23
  ` })] }) }));
24
+ };
21
25
  exports.RectangleItem = RectangleItem;
@@ -5,12 +5,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.RichTextItem = void 0;
7
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = require("react");
8
9
  //@ts-ignore
9
10
  const style_1 = __importDefault(require("styled-jsx/style"));
10
- const RichTextConverter_1 = require("../../utils/RichTextConverter");
11
+ const RichTextConverter_1 = require("../../utils/RichTextConverter/RichTextConverter");
12
+ const useCntrlContext_1 = require("../../provider/useCntrlContext");
11
13
  const richTextConv = new RichTextConverter_1.RichTextConverter();
12
- const RichTextItem = ({ item, layouts }) => {
13
- const [content, styles] = richTextConv.toHtml(item, layouts);
14
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "rich-text", children: content }), (0, jsx_runtime_1.jsx)(style_1.default, { id: item.id, children: styles })] }));
14
+ const RichTextItem = ({ item }) => {
15
+ const { layouts, typePresets } = (0, useCntrlContext_1.useCntrlContext)();
16
+ const preset = item.commonParams.preset
17
+ ? typePresets?.presets.find(p => p.id === item.commonParams.preset)
18
+ : null;
19
+ const [content, styles] = richTextConv.toHtml(item, layouts, !!preset);
20
+ return (0, react_1.createElement)(preset?.tag ?? 'div', {
21
+ className: preset ? `cntrl-preset-${preset.id}` : undefined
22
+ }, ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [content, (0, jsx_runtime_1.jsx)(style_1.default, { id: item.id, children: styles })] })));
15
23
  };
16
24
  exports.RichTextItem = RichTextItem;
@@ -4,26 +4,30 @@ exports.VideoItem = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const LinkWrapper_1 = require("../LinkWrapper");
6
6
  const sdk_1 = require("@cntrl-site/sdk");
7
- const VideoItem = ({ item, layouts }) => ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: item.link?.url, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `video-wrapper-${item.id}`, children: (0, jsx_runtime_1.jsx)("video", { autoPlay: true, muted: true, loop: true, playsInline: true, className: "video", children: (0, jsx_runtime_1.jsx)("source", { src: item.commonParams.url }) }) }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
8
- ${(0, sdk_1.getLayoutStyles)(layouts, [item.layoutParams], ([{ strokeColor, radius, strokeWidth, opacity }]) => (`
9
- .video-wrapper-${item.id} {
10
- position: absolute;
11
- overflow: hidden;
12
- width: 100%;
13
- height: 100%;
14
- border-style: solid;
15
- box-sizing: border-box;
16
- border-color: ${strokeColor};
17
- border-radius: ${radius * 100}vw;
18
- border-width: ${strokeWidth * 100}vw;
19
- opacity: ${opacity};
20
- }`))}
21
- .video {
22
- width: 100%;
23
- height: 100%;
24
- opacity: 1;
25
- object-fit: cover;
26
- pointer-events: none;
27
- }
28
- ` })] }) }));
7
+ const useCntrlContext_1 = require("../../provider/useCntrlContext");
8
+ const VideoItem = ({ item }) => {
9
+ const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
10
+ return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: item.link?.url, children: [(0, jsx_runtime_1.jsx)("div", { className: `video-wrapper-${item.id}`, children: (0, jsx_runtime_1.jsx)("video", { autoPlay: true, muted: true, loop: true, playsInline: true, className: "video", children: (0, jsx_runtime_1.jsx)("source", { src: item.commonParams.url }) }) }), (0, jsx_runtime_1.jsx)("style", { jsx: true, children: `
11
+ ${(0, sdk_1.getLayoutStyles)(layouts, [item.layoutParams], ([{ strokeColor, radius, strokeWidth, opacity }]) => (`
12
+ .video-wrapper-${item.id} {
13
+ position: absolute;
14
+ overflow: hidden;
15
+ width: 100%;
16
+ height: 100%;
17
+ border-style: solid;
18
+ box-sizing: border-box;
19
+ border-color: ${strokeColor};
20
+ border-radius: ${radius * 100}vw;
21
+ border-width: ${strokeWidth * 100}vw;
22
+ opacity: ${opacity};
23
+ }`))}
24
+ .video {
25
+ width: 100%;
26
+ height: 100%;
27
+ opacity: 1;
28
+ object-fit: cover;
29
+ pointer-events: none;
30
+ }
31
+ ` })] }));
32
+ };
29
33
  exports.VideoItem = VideoItem;
@@ -4,7 +4,9 @@ exports.VimeoEmbedItem = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const sdk_1 = require("@cntrl-site/sdk");
6
6
  const LinkWrapper_1 = require("../LinkWrapper");
7
- const VimeoEmbedItem = ({ item, layouts }) => {
7
+ const useCntrlContext_1 = require("../../provider/useCntrlContext");
8
+ const VimeoEmbedItem = ({ item }) => {
9
+ const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
8
10
  const { autoplay, controls, loop, muted, pictureInPicture, url } = item.commonParams;
9
11
  const getValidVimeoUrl = (url) => {
10
12
  const validURL = new URL(url);
@@ -5,7 +5,9 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const sdk_1 = require("@cntrl-site/sdk");
6
6
  const LinkWrapper_1 = require("../LinkWrapper");
7
7
  const getValidYoutubeUrl_1 = require("../../utils/getValidYoutubeUrl");
8
- const YoutubeEmbedItem = ({ item, layouts }) => {
8
+ const useCntrlContext_1 = require("../../provider/useCntrlContext");
9
+ const YoutubeEmbedItem = ({ item }) => {
10
+ const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
9
11
  const { autoplay, controls, url } = item.commonParams;
10
12
  const getValidYoutubeUrl = (url) => {
11
13
  const newUrl = new URL(url);
package/lib/index.js CHANGED
@@ -14,10 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.CustomItems = exports.CntrlProvider = exports.YoutubeEmbedItem = exports.VimeoEmbedItem = exports.LayoutStyle = exports.VideoItem = exports.RichTextItem = exports.RectangleItem = exports.ImageItem = exports.Item = exports.Section = exports.Article = exports.Head = exports.Page = exports.RichTextConverter = void 0;
18
- const defaultContext_1 = require("./provider/defaultContext");
17
+ exports.CntrlProvider = exports.YoutubeEmbedItem = exports.VimeoEmbedItem = exports.LayoutStyle = exports.VideoItem = exports.RichTextItem = exports.RectangleItem = exports.ImageItem = exports.Item = exports.Section = exports.Article = exports.Head = exports.Page = exports.RichTextConverter = exports.cntrlSdkContext = void 0;
18
+ var defaultContext_1 = require("./provider/defaultContext");
19
+ Object.defineProperty(exports, "cntrlSdkContext", { enumerable: true, get: function () { return defaultContext_1.cntrlSdkContext; } });
19
20
  __exportStar(require("@cntrl-site/sdk"), exports);
20
- var RichTextConverter_1 = require("./utils/RichTextConverter");
21
+ var RichTextConverter_1 = require("./utils/RichTextConverter/RichTextConverter");
21
22
  Object.defineProperty(exports, "RichTextConverter", { enumerable: true, get: function () { return RichTextConverter_1.RichTextConverter; } });
22
23
  var Page_1 = require("./components/Page");
23
24
  Object.defineProperty(exports, "Page", { enumerable: true, get: function () { return Page_1.Page; } });
@@ -46,4 +47,3 @@ Object.defineProperty(exports, "YoutubeEmbedItem", { enumerable: true, get: func
46
47
  // custom items
47
48
  var CntrlProvider_1 = require("./provider/CntrlProvider");
48
49
  Object.defineProperty(exports, "CntrlProvider", { enumerable: true, get: function () { return CntrlProvider_1.CntrlProvider; } });
49
- exports.CustomItems = defaultContext_1.cntrlSdkContext.customItems;
@@ -4,6 +4,13 @@ exports.CntrlSdkContext = void 0;
4
4
  class CntrlSdkContext {
5
5
  constructor(customItems) {
6
6
  this.customItems = customItems;
7
+ this.layouts = [];
8
+ }
9
+ setTypePresets(typePresets) {
10
+ this.typePresets = typePresets;
11
+ }
12
+ setLayouts(layouts) {
13
+ this.layouts = layouts;
7
14
  }
8
15
  }
9
16
  exports.CntrlSdkContext = CntrlSdkContext;
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RichTextConverter = exports.FontStyles = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const sdk_1 = require("@cntrl-site/sdk");
6
- const LinkWrapper_1 = require("../components/LinkWrapper");
6
+ const LinkWrapper_1 = require("../../components/LinkWrapper");
7
7
  exports.FontStyles = {
8
8
  'normal': {},
9
9
  'bold': { 'font-weight': 'bold' },
10
10
  'italic': { 'font-style': 'italic' }
11
11
  };
12
12
  class RichTextConverter {
13
- toHtml(richText, layouts) {
13
+ toHtml(richText, layouts, hasPreset) {
14
14
  const { text: rawText, blocks = [] } = richText.commonParams;
15
15
  const text = Array.from(rawText); // because of emoji
16
16
  const root = [];
@@ -58,7 +58,7 @@ class RichTextConverter {
58
58
  .${blockClass} {
59
59
  display: ${group.some(g => g.layout === l.id) ? 'block' : 'none'};
60
60
  text-align: ${ta};
61
- line-height: 0;
61
+ ${hasPreset ? '' : 'line-height: 0;'}
62
62
  white-space: normal;
63
63
  overflow-wrap: break-word;
64
64
  }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateTypePresetStyles = void 0;
4
+ const sdk_1 = require("@cntrl-site/sdk");
5
+ const reEmptyLines = /^\s*\n/gm;
6
+ function generateTypePresetStyles(preset, layouts) {
7
+ const sorted = layouts.slice().sort((a, b) => a.startsWith - b.startsWith);
8
+ const stylesStr = (`
9
+ ${preset.presets.map(p => (`
10
+ .cntrl-preset-${p.id} {
11
+ font-family: ${p.fontFamily};
12
+ ${p.fontStyle.length > 0 ? `font-style: ${p.fontStyle};` : ''}
13
+ font-weight: ${p.fontWeight};
14
+ }
15
+ ${sorted.map(l => (`
16
+ ${(0, sdk_1.getLayoutMediaQuery)(l.id, sorted)} {
17
+ .cntrl-preset-${p.id} {
18
+ font-size: ${p.layoutParams[l.id].fontSize * 100}vw;
19
+ line-height: ${p.layoutParams[l.id].lineHeight * 100}vw;
20
+ letter-spacing: ${p.layoutParams[l.id].letterSpacing * 100}vw;
21
+ word-spacing: ${p.layoutParams[l.id].wordSpacing * 100}vw;
22
+ color: ${p.layoutParams[l.id].color};
23
+ }
24
+ }`)).join('\n')}`)).join('\n')}`);
25
+ return stylesStr.replace(reEmptyLines, '');
26
+ }
27
+ exports.generateTypePresetStyles = generateTypePresetStyles;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cntrl-site/sdk-nextjs",
3
- "version": "0.2.13",
3
+ "version": "0.3.0",
4
4
  "description": "SDK for Next.js",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/index.js",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "homepage": "https://github.com/cntrl-site/sdk-nextjs#readme",
23
23
  "dependencies": {
24
- "@cntrl-site/sdk": "^0.2.13",
24
+ "@cntrl-site/sdk": "^0.3.0",
25
25
  "html-react-parser": "^3.0.1",
26
26
  "styled-jsx": "^5.0.2"
27
27
  },
@@ -33,8 +33,11 @@
33
33
  "devDependencies": {
34
34
  "@tsconfig/node16": "^1.0.3",
35
35
  "@tsconfig/recommended": "^1.0.1",
36
+ "@types/jest": "^29.2.5",
36
37
  "@types/node": "^18.11.7",
37
38
  "@types/react": "^18.0.15",
39
+ "jest": "^29.3.1",
40
+ "ts-jest": "^29.0.3",
38
41
  "typescript": "^4.7.4"
39
42
  },
40
43
  "directories": {
@@ -1,21 +1,20 @@
1
1
  import { FC } from 'react';
2
- import { TArticle, TLayout, getLayoutStyles } from '@cntrl-site/sdk';
2
+ import { TArticle } from '@cntrl-site/sdk';
3
3
  import { Section } from './Section';
4
4
  import { Item } from './Item';
5
5
 
6
6
  interface Props {
7
7
  article: TArticle;
8
- layouts: TLayout[];
9
8
  }
10
9
 
11
- export const Article: FC<Props> = ({ article, layouts }) => {
10
+ export const Article: FC<Props> = ({ article }) => {
12
11
  return (
13
12
  <>
14
13
  <div className="article">
15
14
  {article.sections.map((section, i) => (
16
- <Section section={section} key={section.id} layouts={layouts}>
15
+ <Section section={section} key={section.id}>
17
16
  {article.sections[i].items.map(item => (
18
- <Item layouts={layouts} item={item} key={item.id} />
17
+ <Item item={item} key={item.id} />
19
18
  ))}
20
19
  </Section>
21
20
  ))}
@@ -4,7 +4,6 @@ import {
4
4
  ArticleItemType,
5
5
  ArticleItemSizingType as SizingType,
6
6
  TArticleItemAny,
7
- TLayout,
8
7
  AnchorSide
9
8
  } from '@cntrl-site/sdk';
10
9
  import { RectangleItem } from './items/RectangleItem';
@@ -14,9 +13,9 @@ import { RichTextItem } from './items/RichTextItem';
14
13
  import { VimeoEmbedItem } from './items/VimeoEmbed';
15
14
  import { YoutubeEmbedItem } from './items/YoutubeEmbed';
16
15
  import { CustomItem } from './items/CustomItem';
16
+ import { useCntrlContext } from '../provider/useCntrlContext';
17
17
 
18
18
  export interface ItemProps<I extends TArticleItemAny> {
19
- layouts: TLayout[];
20
19
  item: I;
21
20
  }
22
21
 
@@ -32,7 +31,8 @@ const itemsMap: Record<ArticleItemType, ComponentType<ItemProps<any>>> = {
32
31
 
33
32
  const noop = () => null;
34
33
 
35
- export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, layouts }) => {
34
+ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item }) => {
35
+ const { layouts } = useCntrlContext();
36
36
  const layoutValues: Record<string, any>[] = [item.area];
37
37
  if (item.layoutParams) {
38
38
  layoutValues.push(item.layoutParams);
@@ -43,7 +43,7 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, layouts }) => {
43
43
 
44
44
  return (
45
45
  <div className={`item-${item.id}`}>
46
- <ItemComponent item={item} layouts={layouts} />
46
+ <ItemComponent item={item} />
47
47
  <style jsx>{`
48
48
  ${getLayoutStyles(layouts, layoutValues, ([area]) => (`
49
49
  .item-${item.id} {
@@ -3,6 +3,8 @@ import HTMLReactParser from 'html-react-parser';
3
3
  import { TArticle, TProject, TMeta } from '@cntrl-site/sdk';
4
4
  import { Article } from './Article';
5
5
  import { CNTRLHead } from './Head';
6
+ import { useCntrlContext } from '../provider/useCntrlContext';
7
+ import { generateTypePresetStyles } from '../utils/generateTypePresetStyles/generateTypePresetStyles';
6
8
 
7
9
  interface Props {
8
10
  article: TArticle;
@@ -13,12 +15,16 @@ interface Props {
13
15
  export const Page: FC<Props> = ({ article, project, meta }) => {
14
16
  const afterBodyOpen = HTMLReactParser(project.html.afterBodyOpen);
15
17
  const beforeBodyClose = HTMLReactParser(project.html.beforeBodyClose);
18
+ const { typePresets, layouts } = useCntrlContext();
16
19
  return (
17
20
  <>
18
21
  <CNTRLHead project={project} meta={meta} />
19
22
  {afterBodyOpen}
20
- <Article article={article} layouts={project.layouts} />
23
+ <Article article={article} />
21
24
  {beforeBodyClose}
25
+ {typePresets && typePresets.presets.length > 0 && (
26
+ <style>{generateTypePresetStyles(typePresets, layouts)}</style>
27
+ )}
22
28
  </>
23
29
  );
24
30
  };
@@ -1,15 +1,16 @@
1
1
  import { FC, ReactElement } from 'react';
2
- import { getLayoutMediaQuery, getLayoutStyles, TArticleSection, TLayout, TSectionHeight, SectionHeightMode } from '@cntrl-site/sdk';
2
+ import { getLayoutMediaQuery, getLayoutStyles, TArticleSection, TSectionHeight, SectionHeightMode } from '@cntrl-site/sdk';
3
+ import { useCntrlContext } from '../provider/useCntrlContext';
3
4
 
4
5
  type SectionChild = ReactElement<any, any>;
5
6
 
6
7
  interface Props {
7
8
  section: TArticleSection;
8
- layouts: TLayout[];
9
9
  children: SectionChild[];
10
10
  }
11
11
 
12
- export const Section: FC<Props> = ({ section, layouts, children }) => {
12
+ export const Section: FC<Props> = ({ section, children }) => {
13
+ const { layouts } = useCntrlContext();
13
14
  const getSectionVisibilityStyles = () => {
14
15
  return layouts
15
16
  .sort((a, b) => a.startsWith - b.startsWith)
@@ -2,14 +2,17 @@ import { FC } from 'react';
2
2
  import { getLayoutStyles, TImageItem } from '@cntrl-site/sdk';
3
3
  import { ItemProps } from '../Item';
4
4
  import { LinkWrapper } from '../LinkWrapper';
5
+ import { useCntrlContext } from '../../provider/useCntrlContext';
5
6
 
6
- export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, layouts }) => (
7
- <LinkWrapper url={item.link?.url}>
8
- <>
9
- <div className={`image-wrapper-${item.id}`}>
10
- <img className="image" src={item.commonParams.url} />
11
- </div>
12
- <style jsx>{`
7
+ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item }) => {
8
+ const { layouts } = useCntrlContext();
9
+ return (
10
+ <LinkWrapper url={item.link?.url}>
11
+ <>
12
+ <div className={`image-wrapper-${item.id}`}>
13
+ <img className="image" src={item.commonParams.url} />
14
+ </div>
15
+ <style jsx>{`
13
16
  ${getLayoutStyles(layouts, [item.layoutParams], ([{ strokeColor, radius, strokeWidth, opacity }]) => (`
14
17
  .image-wrapper-${item.id} {
15
18
  position: absolute;
@@ -23,7 +26,7 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, layouts }) => (
23
26
  opacity: ${opacity};
24
27
  border-width: ${strokeWidth * 100}vw;
25
28
  }`
26
- ))
29
+ ))
27
30
  }
28
31
  .image {
29
32
  width: 100%;
@@ -33,6 +36,7 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, layouts }) => (
33
36
  pointer-events: none;
34
37
  }
35
38
  `}</style>
36
- </>
37
- </LinkWrapper>
38
- );
39
+ </>
40
+ </LinkWrapper>
41
+ );
42
+ };
@@ -2,12 +2,15 @@ import { FC } from 'react';
2
2
  import { TRectangleItem, getLayoutStyles } from '@cntrl-site/sdk';
3
3
  import { ItemProps } from '../Item';
4
4
  import { LinkWrapper } from '../LinkWrapper';
5
+ import { useCntrlContext } from '../../provider/useCntrlContext';
5
6
 
6
- export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, layouts }) => (
7
- <LinkWrapper url={item.link?.url}>
8
- <>
9
- <div className={`rectangle-${item.id}`} />
10
- <style jsx>{`
7
+ export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item }) => {
8
+ const { layouts } = useCntrlContext();
9
+ return (
10
+ <LinkWrapper url={item.link?.url}>
11
+ <>
12
+ <div className={`rectangle-${item.id}`} />
13
+ <style jsx>{`
11
14
  ${getLayoutStyles(layouts, [item.layoutParams], ([{ strokeColor, fillColor, radius, strokeWidth }]) => (`
12
15
  .rectangle-${item.id} {
13
16
  position: absolute;
@@ -22,6 +25,7 @@ export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, layouts })
22
25
  }`
23
26
  ))}
24
27
  `}</style>
25
- </>
26
- </LinkWrapper>
27
- );
28
+ </>
29
+ </LinkWrapper>
30
+ );
31
+ };
@@ -1,20 +1,31 @@
1
- import { FC } from 'react';
1
+ import { FC, createElement } from 'react';
2
2
  import { TRichTextItem } from '@cntrl-site/sdk';
3
3
  //@ts-ignore
4
4
  import JSXStyle from 'styled-jsx/style';
5
5
  import { ItemProps } from '../Item';
6
- import { RichTextConverter } from '../../utils/RichTextConverter';
6
+ import { RichTextConverter } from '../../utils/RichTextConverter/RichTextConverter';
7
+ import { useCntrlContext } from '../../provider/useCntrlContext';
7
8
 
8
9
  const richTextConv = new RichTextConverter();
9
10
 
10
- export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, layouts }) => {
11
- const [content, styles] = richTextConv.toHtml(item, layouts);
12
- return (
13
- <>
14
- <div className="rich-text">{content}</div>
15
- <JSXStyle id={item.id}>
16
- {styles}
17
- </JSXStyle>
18
- </>
11
+ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item }) => {
12
+ const { layouts, typePresets } = useCntrlContext();
13
+ const preset = item.commonParams.preset
14
+ ? typePresets?.presets.find(p => p.id === item.commonParams.preset)
15
+ : null;
16
+ const [content, styles] = richTextConv.toHtml(item, layouts, !!preset);
17
+ return createElement(
18
+ preset?.tag ?? 'div',
19
+ {
20
+ className: preset ? `cntrl-preset-${preset.id}` : undefined
21
+ },
22
+ (
23
+ <>
24
+ {content}
25
+ <JSXStyle id={item.id}>
26
+ {styles}
27
+ </JSXStyle>
28
+ </>
29
+ )
19
30
  );
20
31
  };