@cntrl-site/sdk-nextjs 0.15.5-2 → 0.15.5-4

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.
@@ -0,0 +1,5 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <state>
3
+ <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
4
+ </state>
5
+ </component>
@@ -35,6 +35,11 @@ const itemsMap = {
35
35
  [sdk_1.ArticleItemType.VimeoEmbed]: VimeoEmbed_1.VimeoEmbedItem,
36
36
  [sdk_1.ArticleItemType.Custom]: CustomItem_1.CustomItem
37
37
  };
38
+ const RichTextWrapper = ({ isRichText, children }) => {
39
+ if (!isRichText)
40
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
41
+ return ((0, jsx_runtime_1.jsx)("div", Object.assign({ style: { transformOrigin: 'top left', transform: 'scale(var(--layout-deviation))' } }, { children: children })));
42
+ };
38
43
  const noop = () => null;
39
44
  const Item = ({ item, sectionId }) => {
40
45
  var _a, _b;
@@ -43,6 +48,7 @@ const Item = ({ item, sectionId }) => {
43
48
  const layout = (0, useLayoutContext_1.useLayoutContext)();
44
49
  const exemplary = (_b = (_a = layouts.find(l => l.id === layout)) === null || _a === void 0 ? void 0 : _a.exemplary) !== null && _b !== void 0 ? _b : 1;
45
50
  const [wrapperHeight, setWrapperHeight] = (0, react_1.useState)(undefined);
51
+ const [itemHeight, setItemHeight] = (0, react_1.useState)(undefined);
46
52
  const { scale, scaleAnchor } = (0, useItemScale_1.useItemScale)(item, sectionId);
47
53
  const { top, left } = (0, useItemPosition_1.useItemPosition)(item, sectionId);
48
54
  const sectionHeight = (0, useSectionHeightMap_1.useSectionHeightData)(sectionId);
@@ -69,43 +75,45 @@ const Item = ({ item, sectionId }) => {
69
75
  return;
70
76
  }
71
77
  const wrapperHeight = getStickyItemWrapperHeight(sticky, height);
78
+ setItemHeight(height);
72
79
  setWrapperHeight(wrapperHeight);
73
80
  };
74
81
  (0, react_1.useEffect)(() => {
75
82
  isInitialRef.current = false;
76
83
  }, []);
77
84
  const isRichText = isItemType(item, sdk_1.ArticleItemType.RichText);
78
- const scaleIfRichText = isRichText
79
- ? { transformOrigin: 'top left', transform: 'scale(var(--layout-deviation))' }
80
- : {};
81
- const styles = Object.assign(Object.assign({}, scaleIfRichText), { top: stickyTop });
82
- return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: `item-wrapper-${item.id}`, style: isInitialRef.current ? {} : Object.assign({ top, left }, (wrapperHeight ? { height: `${wrapperHeight * 100}vw` } : {})) }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ suppressHydrationWarning: true, className: `item-${item.id}`, style: isInitialRef.current ? {} : styles }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: `item-${item.id}-inner`, style: {
83
- width: `${sizingAxis.x === sdk_1.ArticleItemSizingType.Manual
84
- ? isRichText
85
- ? `${width * exemplary}px`
86
- : `${width * 100}vw`
87
- : 'max-content'}`,
88
- height: `${sizingAxis.y === sdk_1.ArticleItemSizingType.Manual ? `${height * 100}vw` : 'unset'}`,
89
- transform: `scale(${scale})`,
90
- transformOrigin: ScaleAnchorMap_1.ScaleAnchorMap[scaleAnchor]
91
- } }, { children: (0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId, onResize: handleItemResize }) })) })), (0, jsx_runtime_1.jsx)(style_1.default, Object.assign({ id: id }, { children: `
85
+ const styles = {
86
+ top: stickyTop,
87
+ height: isRichText && itemHeight ? `${itemHeight * 100}vw` : 'unset'
88
+ };
89
+ return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: `item-wrapper-${item.id}`, style: isInitialRef.current ? {} : Object.assign({ top, left }, (wrapperHeight ? { height: `${wrapperHeight * 100}vw` } : {})) }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ suppressHydrationWarning: true, className: `item-${item.id}`, style: isInitialRef.current ? {} : styles }, { children: (0, jsx_runtime_1.jsx)(RichTextWrapper, Object.assign({ isRichText: isRichText }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: `item-${item.id}-inner`, style: {
90
+ width: `${sizingAxis.x === sdk_1.ArticleItemSizingType.Manual
91
+ ? isRichText
92
+ ? `${width * exemplary}px`
93
+ : `${width * 100}vw`
94
+ : 'max-content'}`,
95
+ height: `${sizingAxis.y === sdk_1.ArticleItemSizingType.Manual ? `${height * 100}vw` : 'unset'}`,
96
+ transform: `scale(${scale})`,
97
+ transformOrigin: ScaleAnchorMap_1.ScaleAnchorMap[scaleAnchor]
98
+ } }, { children: (0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId, onResize: handleItemResize }) })) })) })), (0, jsx_runtime_1.jsx)(style_1.default, Object.assign({ id: id }, { children: `
92
99
  ${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, hidden, hoverParams, sticky, sectionHeight, layoutParams]) => {
93
100
  const sizingAxis = parseSizing(layoutParams.sizing);
94
101
  return (`
95
102
  .item-${item.id} {
96
103
  position: ${sticky ? 'sticky' : 'absolute'};
97
- width: ${sizingAxis.x === sdk_1.ArticleItemSizingType.Manual ? `${area.width * 100}vw` : 'max-content'};
98
- height: ${sizingAxis.y === sdk_1.ArticleItemSizingType.Manual ? `${area.height * 100}vw` : 'unset'};
99
- transform: scale(${scale});
100
104
  top: ${sticky ? `${(0, getAnchoredItemTop_1.getAnchoredItemTop)(area.top - sticky.from, sectionHeight, area.anchorSide)}` : 0};
101
- transform-origin: ${ScaleAnchorMap_1.ScaleAnchorMap[scaleAnchor]};
102
105
  pointer-events: auto;
103
- --webkit-backface-visibility: hidden;
104
106
  cursor: ${hoverParams ? 'pointer' : 'default'};
105
107
  visibility: ${hidden ? 'hidden' : 'visible'};
108
+ height: fit-content;
106
109
  }
107
110
  .item-${item.id}-inner {
108
111
  transition: ${(0, HoverStyles_1.getTransitions)(['width', 'height', 'scale'], hoverParams)};
112
+ width: ${sizingAxis.x === sdk_1.ArticleItemSizingType.Manual ? `${area.width * 100}vw` : 'max-content'};
113
+ height: ${sizingAxis.y === sdk_1.ArticleItemSizingType.Manual ? `${area.height * 100}vw` : 'unset'};
114
+ transform: scale(${scale});
115
+ transform-origin: ${ScaleAnchorMap_1.ScaleAnchorMap[scaleAnchor]};
116
+ --webkit-backface-visibility: hidden;
109
117
  }
110
118
  .item-wrapper-${item.id} {
111
119
  position: absolute;
@@ -14,11 +14,10 @@ const HoverStyles_1 = require("../../utils/HoverStyles/HoverStyles");
14
14
  const useRichTextItemValues_1 = require("./useRichTextItemValues");
15
15
  const resize_observer_polyfill_1 = __importDefault(require("resize-observer-polyfill"));
16
16
  const RichTextItem = ({ item, sectionId, onResize }) => {
17
- const [content, styles, preset] = (0, useRichTextItem_1.useRichTextItem)(item);
17
+ const [content, styles] = (0, useRichTextItem_1.useRichTextItem)(item);
18
18
  const id = (0, react_1.useId)();
19
19
  const [ref, setRef] = (0, react_1.useState)(null);
20
20
  const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
21
- const className = preset ? `cntrl-preset-${preset.id}` : undefined;
22
21
  const { angle, blur } = (0, useRichTextItemValues_1.useRichTextItemValues)(item, sectionId);
23
22
  (0, react_1.useEffect)(() => {
24
23
  if (!ref || !onResize)
@@ -32,7 +31,7 @@ const RichTextItem = ({ item, sectionId, onResize }) => {
32
31
  observer.unobserve(ref);
33
32
  };
34
33
  }, [ref, onResize]);
35
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ ref: setRef, className: `${className} rich-text-wrapper-${item.id}`, style: {
34
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ ref: setRef, className: `rich-text-wrapper-${item.id}`, style: {
36
35
  transform: `rotate(${angle}deg)`,
37
36
  filter: `blur(${blur * 100}vw)`
38
37
  } }, { children: content })), (0, jsx_runtime_1.jsxs)(style_1.default, Object.assign({ id: id }, { children: [styles, `${(0, sdk_1.getLayoutStyles)(layouts, [item.state.hover], ([hoverParams]) => {
@@ -44,6 +43,28 @@ const RichTextItem = ({ item, sectionId, onResize }) => {
44
43
  ${(0, HoverStyles_1.getHoverStyles)(['angle', 'blur'], hoverParams)}
45
44
  }
46
45
  `);
46
+ })}`, `${(0, sdk_1.getLayoutStyles)(layouts, [item.layoutParams], ([layoutParams], exemplary) => {
47
+ const color = sdk_1.CntrlColor.parse(layoutParams.color);
48
+ return (`
49
+ .rich-text-wrapper-${item.id} {
50
+ font-size: ${Math.round(layoutParams.fontSize * exemplary)}px;
51
+ line-height: ${layoutParams.lineHeight * exemplary}px;
52
+ letter-spacing: ${layoutParams.letterSpacing * exemplary}px;
53
+ word-spacing: ${layoutParams.wordSpacing * exemplary}px;
54
+ font-family: ${layoutParams.typeFace};
55
+ font-weight: ${layoutParams.fontWeight};
56
+ font-style: ${layoutParams.fontStyle ? layoutParams.fontStyle : 'normal'};
57
+ text-decoration: ${layoutParams.textDecoration};
58
+ vertical-align: ${layoutParams.verticalAlign};
59
+ font-variant: ${layoutParams.fontVariant};
60
+ color: ${color.toCss()};
61
+ }
62
+ @supports not (color: oklch(42% 0.3 90 / 1)) {
63
+ .rich-text-wrapper-${item.id} {
64
+ color: ${color.fmt('rgba')};
65
+ }
66
+ }
67
+ `);
47
68
  })}`] }))] }));
48
69
  };
49
70
  exports.RichTextItem = RichTextItem;
@@ -4,7 +4,7 @@ exports.useRichTextItem = void 0;
4
4
  const RichTextConverter_1 = require("../../utils/RichTextConverter/RichTextConverter");
5
5
  const useCntrlContext_1 = require("../../provider/useCntrlContext");
6
6
  const useLayoutContext_1 = require("../useLayoutContext");
7
- const richTextConv = new RichTextConverter_1.RichTextConverter();
7
+ const richTextConverter = new RichTextConverter_1.RichTextConverter();
8
8
  const useRichTextItem = (item) => {
9
9
  var _a;
10
10
  const layoutId = (0, useLayoutContext_1.useLayoutContext)();
@@ -13,7 +13,7 @@ const useRichTextItem = (item) => {
13
13
  const preset = presetId
14
14
  ? (_a = typePresets === null || typePresets === void 0 ? void 0 : typePresets.presets.find(p => p.id === presetId)) !== null && _a !== void 0 ? _a : null
15
15
  : null;
16
- const [content, styles] = richTextConv.toHtml(item, layouts);
16
+ const [content, styles] = richTextConverter.toHtml(item, layouts);
17
17
  return [content, styles, preset];
18
18
  };
19
19
  exports.useRichTextItem = useRichTextItem;
@@ -5,7 +5,7 @@ const useKeyframeValue_1 = require("../../common/useKeyframeValue");
5
5
  const useLayoutContext_1 = require("../useLayoutContext");
6
6
  const useRichTextItemValues = (item, sectionId) => {
7
7
  const layoutId = (0, useLayoutContext_1.useLayoutContext)();
8
- const angle = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => ({ angle: layoutId ? item.area[layoutId].angle : 0 }), (animator, scroll, value) => animator.getRotation(value, scroll), sectionId);
8
+ const { angle } = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => ({ angle: layoutId ? item.area[layoutId].angle : 0 }), (animator, scroll, value) => animator.getRotation(value, scroll), sectionId);
9
9
  const blur = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => {
10
10
  if (!layoutId)
11
11
  return 0;
@@ -19,9 +19,9 @@ class RichTextConverter {
19
19
  return rec;
20
20
  }, {});
21
21
  let currentLineHeight = layouts.reduce((rec, layout) => {
22
- var _a, _b;
23
- const styles = richText.layoutParams[layout.id].styles;
24
- rec[layout.id] = (_b = (_a = styles === null || styles === void 0 ? void 0 : styles.find(s => s.style === 'LINEHEIGHT')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '0';
22
+ var _a;
23
+ const styles = richText.layoutParams[layout.id].rangeStyles;
24
+ rec[layout.id] = (_a = styles === null || styles === void 0 ? void 0 : styles.find(s => s.style === 'LINEHEIGHT')) === null || _a === void 0 ? void 0 : _a.value;
25
25
  return rec;
26
26
  }, {});
27
27
  for (let blockIndex = 0; blockIndex < blocks.length; blockIndex++) {
@@ -31,9 +31,12 @@ class RichTextConverter {
31
31
  if (content.length === 0) {
32
32
  root.push((0, jsx_runtime_1.jsx)("div", Object.assign({ className: `rt_${richText.id}_br_${blockIndex}` }, { children: (0, jsx_runtime_1.jsx)("br", {}) })));
33
33
  layouts.forEach(l => {
34
- const lh = RichTextConverter.fromDraftToInline({
34
+ const lhForLayout = currentLineHeight[l.id];
35
+ if (lhForLayout === undefined)
36
+ return;
37
+ const lh = RichTextConverter.fromRangeStylesToInline({
35
38
  name: 'LINEHEIGHT',
36
- value: currentLineHeight[l.id]
39
+ value: lhForLayout
37
40
  }, l.exemplary);
38
41
  styleRules[l.id].push(`.rt_${richText.id}_br_${blockIndex} {${lh}}`);
39
42
  });
@@ -41,7 +44,7 @@ class RichTextConverter {
41
44
  }
42
45
  const newStylesGroup = layouts.map(({ id: layoutId }) => {
43
46
  const params = richText.layoutParams[layoutId];
44
- const styles = params.styles
47
+ const styles = params.rangeStyles
45
48
  .filter(s => s.start >= block.start && s.end <= block.end)
46
49
  .map(s => (Object.assign(Object.assign({}, s), { start: s.start - block.start, end: s.end - block.start })));
47
50
  return ({
@@ -62,7 +65,6 @@ class RichTextConverter {
62
65
  text-align: ${ta};
63
66
  white-space: ${whiteSpace};
64
67
  overflow-wrap: break-word;
65
- line-height: 0;
66
68
  }
67
69
  `);
68
70
  });
@@ -109,7 +111,7 @@ class RichTextConverter {
109
111
  }
110
112
  styleRules[item.layout].push(`
111
113
  .${blockClass} .s-${styleGroup.start}-${styleGroup.end} {
112
- ${styleGroup.styles.map(s => RichTextConverter.fromDraftToInline(s, exemplary)).join('\n')}
114
+ ${styleGroup.styles.map(s => RichTextConverter.fromRangeStylesToInline(s, exemplary)).join('\n')}
113
115
  }
114
116
  `);
115
117
  if (color) {
@@ -193,7 +195,7 @@ class RichTextConverter {
193
195
  }
194
196
  return entitiesGroups;
195
197
  }
196
- static fromDraftToInline(draftStyle, exemplary) {
198
+ static fromRangeStylesToInline(draftStyle, exemplary) {
197
199
  const { value, name } = draftStyle;
198
200
  const map = {
199
201
  'COLOR': { 'color': getResolvedValue(value, name) },
@@ -206,7 +208,8 @@ class RichTextConverter {
206
208
  'WORDSPACING': { 'word-spacing': `${parseFloat(value) * exemplary}px` },
207
209
  'TEXTTRANSFORM': value ? { 'text-transform': value } : { 'text-transform': sdk_1.TextTransform.None },
208
210
  'VERTICALALIGN': value ? { 'vertical-align': value } : { 'vertical-align': sdk_1.VerticalAlign.Unset },
209
- 'TEXTDECORATION': { 'text-decoration': value }
211
+ 'TEXTDECORATION': { 'text-decoration': value },
212
+ 'FONTVARIANT': { 'font-variant': value }
210
213
  };
211
214
  const css = map[name];
212
215
  if (!css) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cntrl-site/sdk-nextjs",
3
- "version": "0.15.5-2",
3
+ "version": "0.15.5-4",
4
4
  "description": "SDK for Next.js",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/index.ts",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "homepage": "https://github.com/cntrl-site/sdk-nextjs#readme",
23
23
  "dependencies": {
24
- "@cntrl-site/sdk": "^1.1.10",
24
+ "@cntrl-site/sdk": "^1.1.11-1",
25
25
  "@types/vimeo__player": "^2.18.0",
26
26
  "@vimeo/player": "^2.20.1",
27
27
  "html-react-parser": "^3.0.1",
@@ -1,4 +1,4 @@
1
- import { ComponentType, FC, useEffect, useId, useRef, useState } from 'react';
1
+ import { ComponentType, FC, PropsWithChildren, useEffect, useId, useRef, useState } from 'react';
2
2
  import JSXStyle from 'styled-jsx/style';
3
3
  import {
4
4
  AnchorSide,
@@ -45,6 +45,19 @@ const itemsMap: Record<ArticleItemType, ComponentType<ItemProps<any>>> = {
45
45
  [ArticleItemType.Custom]: CustomItem
46
46
  };
47
47
 
48
+ interface RTWrapperProps {
49
+ isRichText: boolean;
50
+ }
51
+
52
+ const RichTextWrapper: FC<PropsWithChildren<RTWrapperProps>> = ({ isRichText, children }) => {
53
+ if (!isRichText) return <>{children}</>;
54
+ return (
55
+ <div style={{ transformOrigin: 'top left', transform: 'scale(var(--layout-deviation))' }}>
56
+ {children}
57
+ </div>
58
+ );
59
+ };
60
+
48
61
  const noop = () => null;
49
62
 
50
63
  export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
@@ -53,6 +66,7 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
53
66
  const layout = useLayoutContext();
54
67
  const exemplary = layouts.find(l => l.id === layout)?.exemplary ?? 1;
55
68
  const [wrapperHeight, setWrapperHeight] = useState<undefined | number>(undefined);
69
+ const [itemHeight, setItemHeight] = useState<undefined | number>(undefined);
56
70
  const { scale, scaleAnchor } = useItemScale(item, sectionId);
57
71
  const { top, left } = useItemPosition(item, sectionId);
58
72
  const sectionHeight = useSectionHeightData(sectionId);
@@ -79,7 +93,8 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
79
93
  setWrapperHeight(undefined);
80
94
  return;
81
95
  }
82
- const wrapperHeight = getStickyItemWrapperHeight(sticky, height)
96
+ const wrapperHeight = getStickyItemWrapperHeight(sticky, height);
97
+ setItemHeight(height);
83
98
  setWrapperHeight(wrapperHeight);
84
99
  };
85
100
 
@@ -88,13 +103,10 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
88
103
  }, []);
89
104
 
90
105
  const isRichText = isItemType(item, ArticleItemType.RichText);
91
- const scaleIfRichText = isRichText
92
- ? { transformOrigin: 'top left', transform: 'scale(var(--layout-deviation))' }
93
- : {};
94
106
 
95
107
  const styles = {
96
- ...scaleIfRichText,
97
- top: stickyTop
108
+ top: stickyTop,
109
+ height: isRichText && itemHeight ? `${itemHeight * 100}vw` : 'unset'
98
110
  };
99
111
 
100
112
  return (
@@ -107,21 +119,23 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
107
119
  className={`item-${item.id}`}
108
120
  style={isInitialRef.current ? {} : styles }
109
121
  >
110
- <div
111
- className={`item-${item.id}-inner`}
112
- style={{
113
- width: `${sizingAxis.x === SizingType.Manual
114
- ? isRichText
115
- ? `${width * exemplary}px`
116
- : `${width * 100}vw`
117
- : 'max-content'}`,
118
- height: `${sizingAxis.y === SizingType.Manual ? `${height * 100}vw` : 'unset'}`,
119
- transform: `scale(${scale})`,
120
- transformOrigin: ScaleAnchorMap[scaleAnchor]
121
- }}
122
- >
123
- <ItemComponent item={item} sectionId={sectionId} onResize={handleItemResize} />
124
- </div>
122
+ <RichTextWrapper isRichText={isRichText}>
123
+ <div
124
+ className={`item-${item.id}-inner`}
125
+ style={{
126
+ width: `${sizingAxis.x === SizingType.Manual
127
+ ? isRichText
128
+ ? `${width * exemplary}px`
129
+ : `${width * 100}vw`
130
+ : 'max-content'}`,
131
+ height: `${sizingAxis.y === SizingType.Manual ? `${height * 100}vw` : 'unset'}`,
132
+ transform: `scale(${scale})`,
133
+ transformOrigin: ScaleAnchorMap[scaleAnchor]
134
+ }}
135
+ >
136
+ <ItemComponent item={item} sectionId={sectionId} onResize={handleItemResize} />
137
+ </div>
138
+ </RichTextWrapper>
125
139
  </div>
126
140
  <JSXStyle id={id}>{`
127
141
  ${getLayoutStyles(layouts, layoutValues, ([area, hidden, hoverParams, sticky, sectionHeight, layoutParams]) => {
@@ -129,18 +143,19 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
129
143
  return (`
130
144
  .item-${item.id} {
131
145
  position: ${sticky ? 'sticky' : 'absolute'};
132
- width: ${sizingAxis.x === SizingType.Manual ? `${area.width * 100}vw` : 'max-content'};
133
- height: ${sizingAxis.y === SizingType.Manual ? `${area.height * 100}vw` : 'unset'};
134
- transform: scale(${scale});
135
146
  top: ${sticky ? `${getAnchoredItemTop(area.top - sticky.from, sectionHeight, area.anchorSide)}` : 0};
136
- transform-origin: ${ScaleAnchorMap[scaleAnchor]};
137
147
  pointer-events: auto;
138
- --webkit-backface-visibility: hidden;
139
148
  cursor: ${hoverParams ? 'pointer' : 'default'};
140
149
  visibility: ${hidden ? 'hidden' : 'visible'};
150
+ height: fit-content;
141
151
  }
142
152
  .item-${item.id}-inner {
143
153
  transition: ${getTransitions(['width', 'height', 'scale'], hoverParams)};
154
+ width: ${sizingAxis.x === SizingType.Manual ? `${area.width * 100}vw` : 'max-content'};
155
+ height: ${sizingAxis.y === SizingType.Manual ? `${area.height * 100}vw` : 'unset'};
156
+ transform: scale(${scale});
157
+ transform-origin: ${ScaleAnchorMap[scaleAnchor]};
158
+ --webkit-backface-visibility: hidden;
144
159
  }
145
160
  .item-wrapper-${item.id} {
146
161
  position: absolute;
@@ -1,5 +1,5 @@
1
1
  import { FC, useEffect, useId, useState } from 'react';
2
- import { ArticleItemType, getLayoutStyles, TRichTextItem } from '@cntrl-site/sdk';
2
+ import { ArticleItemType, CntrlColor, getLayoutStyles, TRichTextItem } from '@cntrl-site/sdk';
3
3
  import JSXStyle from 'styled-jsx/style';
4
4
  import { ItemProps } from '../Item';
5
5
  import { useRichTextItem } from './useRichTextItem';
@@ -9,11 +9,10 @@ import { useRichTextItemValues } from './useRichTextItemValues';
9
9
  import ResizeObserver from 'resize-observer-polyfill';
10
10
 
11
11
  export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, onResize }) => {
12
- const [content, styles, preset] = useRichTextItem(item);
12
+ const [content, styles] = useRichTextItem(item);
13
13
  const id = useId();
14
14
  const [ref, setRef] = useState<HTMLDivElement | null>(null);
15
15
  const { layouts } = useCntrlContext();
16
- const className = preset ? `cntrl-preset-${preset.id}` : undefined;
17
16
  const { angle, blur } = useRichTextItemValues(item, sectionId);
18
17
 
19
18
  useEffect(() => {
@@ -32,7 +31,7 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
32
31
  <>
33
32
  <div
34
33
  ref={setRef}
35
- className={`${className} rich-text-wrapper-${item.id}`}
34
+ className={`rich-text-wrapper-${item.id}`}
36
35
  style={{
37
36
  transform: `rotate(${angle}deg)`,
38
37
  filter: `blur(${blur * 100}vw)`
@@ -52,6 +51,29 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
52
51
  }
53
52
  `);
54
53
  })}`}
54
+ {`${getLayoutStyles(layouts, [item.layoutParams], ([layoutParams], exemplary) => {
55
+ const color = CntrlColor.parse(layoutParams.color);
56
+ return (`
57
+ .rich-text-wrapper-${item.id} {
58
+ font-size: ${Math.round(layoutParams.fontSize * exemplary)}px;
59
+ line-height: ${layoutParams.lineHeight * exemplary}px;
60
+ letter-spacing: ${layoutParams.letterSpacing * exemplary}px;
61
+ word-spacing: ${layoutParams.wordSpacing * exemplary}px;
62
+ font-family: ${layoutParams.typeFace};
63
+ font-weight: ${layoutParams.fontWeight};
64
+ font-style: ${layoutParams.fontStyle ? layoutParams.fontStyle : 'normal'};
65
+ text-decoration: ${layoutParams.textDecoration};
66
+ vertical-align: ${layoutParams.verticalAlign};
67
+ font-variant: ${layoutParams.fontVariant};
68
+ color: ${color.toCss()};
69
+ }
70
+ @supports not (color: oklch(42% 0.3 90 / 1)) {
71
+ .rich-text-wrapper-${item.id} {
72
+ color: ${color.fmt('rgba')};
73
+ }
74
+ }
75
+ `);
76
+ })}`}
55
77
  </JSXStyle>
56
78
  </>
57
79
  );
@@ -4,7 +4,7 @@ import { useCntrlContext } from '../../provider/useCntrlContext';
4
4
  import { ReactNode } from 'react';
5
5
  import { useLayoutContext } from '../useLayoutContext';
6
6
 
7
- const richTextConv = new RichTextConverter();
7
+ const richTextConverter = new RichTextConverter();
8
8
 
9
9
  export const useRichTextItem = (item: TRichTextItem): [ReactNode[], string, TTypePresetEntry | null] => {
10
10
  const layoutId = useLayoutContext();
@@ -13,6 +13,6 @@ export const useRichTextItem = (item: TRichTextItem): [ReactNode[], string, TTyp
13
13
  const preset = presetId
14
14
  ? typePresets?.presets.find(p => p.id === presetId) ?? null
15
15
  : null;
16
- const [content, styles] = richTextConv.toHtml(item, layouts);
16
+ const [content, styles] = richTextConverter.toHtml(item, layouts);
17
17
  return [content, styles, preset];
18
18
  };
@@ -4,7 +4,7 @@ import { useLayoutContext } from '../useLayoutContext';
4
4
 
5
5
  export const useRichTextItemValues = (item: TRichTextItem, sectionId: string) => {
6
6
  const layoutId = useLayoutContext();
7
- const angle = useKeyframeValue(
7
+ const { angle } = useKeyframeValue(
8
8
  item,
9
9
  (item, layoutId) => ({ angle: layoutId ? item.area[layoutId].angle : 0 }),
10
10
  (animator, scroll, value) => animator.getRotation(value, scroll),
@@ -46,9 +46,9 @@ export class RichTextConverter {
46
46
  rec[layout.id] = [];
47
47
  return rec;
48
48
  }, {});
49
- let currentLineHeight = layouts.reduce<Record<string, string>>((rec, layout) => {
50
- const styles = richText.layoutParams[layout.id].styles;
51
- rec[layout.id] = styles?.find(s => s.style === 'LINEHEIGHT')?.value ?? '0';
49
+ let currentLineHeight = layouts.reduce<Record<string, string | undefined>>((rec, layout) => {
50
+ const styles = richText.layoutParams[layout.id].rangeStyles;
51
+ rec[layout.id] = styles?.find(s => s.style === 'LINEHEIGHT')?.value;
52
52
  return rec;
53
53
  }, {});
54
54
 
@@ -59,9 +59,11 @@ export class RichTextConverter {
59
59
  if (content.length === 0) {
60
60
  root.push(<div className={`rt_${richText.id}_br_${blockIndex}`}><br /></div>);
61
61
  layouts.forEach(l => {
62
- const lh = RichTextConverter.fromDraftToInline({
62
+ const lhForLayout = currentLineHeight[l.id];
63
+ if (lhForLayout === undefined) return;
64
+ const lh = RichTextConverter.fromRangeStylesToInline({
63
65
  name: 'LINEHEIGHT',
64
- value: currentLineHeight[l.id]
66
+ value: lhForLayout
65
67
  }, l.exemplary);
66
68
  styleRules[l.id].push(`.rt_${richText.id}_br_${blockIndex} {${lh}}`);
67
69
  });
@@ -69,7 +71,7 @@ export class RichTextConverter {
69
71
  }
70
72
  const newStylesGroup = layouts.map(({ id: layoutId }) => {
71
73
  const params = richText.layoutParams[layoutId];
72
- const styles = params.styles!
74
+ const styles = params.rangeStyles!
73
75
  .filter(s => s.start >= block.start && s.end <= block.end)
74
76
  .map(s => ({ ...s, start: s.start - block.start, end: s.end - block.start }));
75
77
  return ({
@@ -90,7 +92,6 @@ export class RichTextConverter {
90
92
  text-align: ${ta};
91
93
  white-space: ${whiteSpace};
92
94
  overflow-wrap: break-word;
93
- line-height: 0;
94
95
  }
95
96
  `);
96
97
  });
@@ -140,7 +141,7 @@ export class RichTextConverter {
140
141
  }
141
142
  styleRules[item.layout].push(`
142
143
  .${blockClass} .s-${styleGroup.start}-${styleGroup.end} {
143
- ${styleGroup.styles.map(s => RichTextConverter.fromDraftToInline(s, exemplary)).join('\n')}
144
+ ${styleGroup.styles.map(s => RichTextConverter.fromRangeStylesToInline(s, exemplary)).join('\n')}
144
145
  }
145
146
  `);
146
147
  if (color) {
@@ -232,7 +233,7 @@ export class RichTextConverter {
232
233
  return entitiesGroups;
233
234
  }
234
235
 
235
- private static fromDraftToInline(draftStyle: Style, exemplary: number): string {
236
+ private static fromRangeStylesToInline(draftStyle: Style, exemplary: number): string {
236
237
  const { value, name } = draftStyle;
237
238
  const map: Record<string, Record<string, string | undefined>> = {
238
239
  'COLOR': { 'color': getResolvedValue(value, name) },
@@ -245,7 +246,8 @@ export class RichTextConverter {
245
246
  'WORDSPACING': { 'word-spacing': `${parseFloat(value!) * exemplary}px` },
246
247
  'TEXTTRANSFORM': value ? { 'text-transform': value as TextTransform } : { 'text-transform': TextTransform.None },
247
248
  'VERTICALALIGN': value ? { 'vertical-align': value as VerticalAlign } : { 'vertical-align': VerticalAlign.Unset },
248
- 'TEXTDECORATION': { 'text-decoration': value }
249
+ 'TEXTDECORATION': { 'text-decoration': value },
250
+ 'FONTVARIANT': { 'font-variant': value }
249
251
  };
250
252
  const css = map[name];
251
253
  if (!css) {
Binary file
Binary file