@cntrl-site/sdk-nextjs 0.16.14 → 0.17.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.
@@ -19,18 +19,22 @@ const RichTextItem = ({ item, sectionId, onResize }) => {
19
19
  const id = (0, react_1.useId)();
20
20
  const [ref, setRef] = (0, react_1.useState)(null);
21
21
  const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
22
- const { angle, blur } = (0, useRichTextItemValues_1.useRichTextItemValues)(item, sectionId);
22
+ const { angle, blur, wordSpacing, letterSpacing, color } = (0, useRichTextItemValues_1.useRichTextItemValues)(item, sectionId);
23
+ const textColor = (0, react_1.useMemo)(() => sdk_1.CntrlColor.parse(color), [color]);
23
24
  (0, useRegisterResize_1.useRegisterResize)(ref, onResize);
24
25
  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: {
25
26
  transform: `rotate(${angle}deg)`,
26
- filter: `blur(${blur * 100}vw)`
27
+ filter: `blur(${blur * 100}vw)`,
28
+ letterSpacing: `${letterSpacing * 100}vw`,
29
+ wordSpacing: `${wordSpacing * 100}vw`,
30
+ color: `${textColor.toCss()}`
27
31
  } }, { 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]) => {
28
32
  return (`
29
33
  .rich-text-wrapper-${item.id} {
30
- transition: ${(0, HoverStyles_1.getTransitions)(['angle', 'blur'], hoverParams)};
34
+ transition: ${(0, HoverStyles_1.getTransitions)(['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color'], hoverParams)};
31
35
  }
32
36
  .rich-text-wrapper-${item.id}:hover {
33
- ${(0, HoverStyles_1.getHoverStyles)(['angle', 'blur'], hoverParams)}
37
+ ${(0, HoverStyles_1.getHoverStyles)(['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color'], hoverParams)}
34
38
  }
35
39
  `);
36
40
  })}`, `${(0, sdk_1.getLayoutStyles)(layouts, [item.layoutParams], ([layoutParams], exemplary) => {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useRichTextItemValues = void 0;
4
4
  const useKeyframeValue_1 = require("../../common/useKeyframeValue");
5
5
  const useLayoutContext_1 = require("../useLayoutContext");
6
+ const DEFAULT_COLOR = 'rgba(0, 0, 0, 1)';
6
7
  const useRichTextItemValues = (item, sectionId) => {
7
8
  const layoutId = (0, useLayoutContext_1.useLayoutContext)();
8
9
  const { angle } = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => ({ angle: layoutId ? item.area[layoutId].angle : 0 }), (animator, scroll, value) => animator.getRotation(value, scroll), sectionId);
@@ -12,6 +13,24 @@ const useRichTextItemValues = (item, sectionId) => {
12
13
  const layoutParams = item.layoutParams[layoutId];
13
14
  return 'blur' in layoutParams ? layoutParams.blur : 0;
14
15
  }, (animator, scroll, value) => animator.getBlur({ blur: value }, scroll).blur, sectionId, [layoutId]);
15
- return { angle, blur };
16
+ const letterSpacing = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => {
17
+ if (!layoutId)
18
+ return 0;
19
+ const layoutParams = item.layoutParams[layoutId];
20
+ return 'letterSpacing' in layoutParams ? layoutParams.letterSpacing : 0;
21
+ }, (animator, scroll, value) => animator.getLetterSpacing({ letterSpacing: value }, scroll).letterSpacing, sectionId, [layoutId]);
22
+ const wordSpacing = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => {
23
+ if (!layoutId)
24
+ return 0;
25
+ const layoutParams = item.layoutParams[layoutId];
26
+ return 'wordSpacing' in layoutParams ? layoutParams.wordSpacing : 0;
27
+ }, (animator, scroll, value) => animator.getWordSpacing({ wordSpacing: value }, scroll).wordSpacing, sectionId, [layoutId]);
28
+ const color = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => {
29
+ if (!layoutId)
30
+ return DEFAULT_COLOR;
31
+ const layoutParams = item.layoutParams[layoutId];
32
+ return 'color' in layoutParams ? layoutParams.color : DEFAULT_COLOR;
33
+ }, (animator, scroll, value) => animator.getTextColor({ color: value }, scroll).color, sectionId, [layoutId]);
34
+ return { angle, blur, letterSpacing, wordSpacing, color };
16
35
  };
17
36
  exports.useRichTextItemValues = useRichTextItemValues;
@@ -183,6 +183,51 @@ class Animator {
183
183
  backdropBlur: rangeMap(pos, start.position, end.position, start.value.backdropBlur, end.value.backdropBlur, true)
184
184
  };
185
185
  }
186
+ getTextColor(values, pos) {
187
+ const keyframes = this.keyframesMap[sdk_1.KeyframeType.TextColor];
188
+ if (!keyframes || !keyframes.length)
189
+ return values;
190
+ if (keyframes.length === 1) {
191
+ const [keyframe] = keyframes;
192
+ return {
193
+ color: keyframe.value.color
194
+ };
195
+ }
196
+ const { start, end } = this.getStartEnd(pos, keyframes);
197
+ return {
198
+ color: this.getRangeColor(start, end, pos)
199
+ };
200
+ }
201
+ getLetterSpacing(values, pos) {
202
+ const keyframes = this.keyframesMap[sdk_1.KeyframeType.LetterSpacing];
203
+ if (!keyframes || !keyframes.length)
204
+ return values;
205
+ if (keyframes.length === 1) {
206
+ const [keyframe] = keyframes;
207
+ return {
208
+ letterSpacing: keyframe.value.letterSpacing
209
+ };
210
+ }
211
+ const { start, end } = this.getStartEnd(pos, keyframes);
212
+ return {
213
+ letterSpacing: rangeMap(pos, start.position, end.position, start.value.letterSpacing, end.value.letterSpacing, true)
214
+ };
215
+ }
216
+ getWordSpacing(values, pos) {
217
+ const keyframes = this.keyframesMap[sdk_1.KeyframeType.WordSpacing];
218
+ if (!keyframes || !keyframes.length)
219
+ return values;
220
+ if (keyframes.length === 1) {
221
+ const [keyframe] = keyframes;
222
+ return {
223
+ wordSpacing: keyframe.value.wordSpacing
224
+ };
225
+ }
226
+ const { start, end } = this.getStartEnd(pos, keyframes);
227
+ return {
228
+ wordSpacing: rangeMap(pos, start.position, end.position, start.value.wordSpacing, end.value.wordSpacing, true)
229
+ };
230
+ }
186
231
  getStartEnd(position, keyframes) {
187
232
  const index = (0, binSearchInsertAt_1.binSearchInsertAt)(keyframes, { position }, compare);
188
233
  const end = index === keyframes.length ? index - 1 : index;
@@ -216,7 +261,10 @@ function createKeyframesMap() {
216
261
  [sdk_1.KeyframeType.Opacity]: [],
217
262
  [sdk_1.KeyframeType.Scale]: [],
218
263
  [sdk_1.KeyframeType.Blur]: [],
219
- [sdk_1.KeyframeType.BackdropBlur]: []
264
+ [sdk_1.KeyframeType.BackdropBlur]: [],
265
+ [sdk_1.KeyframeType.LetterSpacing]: [],
266
+ [sdk_1.KeyframeType.WordSpacing]: [],
267
+ [sdk_1.KeyframeType.TextColor]: []
220
268
  };
221
269
  }
222
270
  function rangeMap(n, start1, stop1, start2, stop2, withinBounds = false) {
@@ -16,7 +16,10 @@ const hoverTransformationMap = {
16
16
  'strokeColor': (strokeColor) => `border-color: ${sdk_1.CntrlColor.parse(strokeColor).toCss()} !important;`,
17
17
  'fillColor': (fillColor) => `background-color: ${sdk_1.CntrlColor.parse(fillColor).toCss()} !important;`,
18
18
  'blur': (blur) => `filter: blur(${blur * 100}vw) !important;`,
19
- 'backdropBlur': (backdropBlur) => `backdrop-filter: blur(${backdropBlur * 100}vw) !important;`
19
+ 'backdropBlur': (backdropBlur) => `backdrop-filter: blur(${backdropBlur * 100}vw) !important;`,
20
+ 'color': (color) => `color: ${sdk_1.CntrlColor.parse(color).toCss()} !important;`,
21
+ 'letterSpacing': (letterSpacing) => `letter-spacing: ${letterSpacing * 100}vw !important;`,
22
+ 'wordSpacing': (wordSpacing) => `word-spacing: ${wordSpacing * 100}vw !important;`
20
23
  };
21
24
  const CSSPropertyNameMap = {
22
25
  'width': 'width',
@@ -31,7 +34,10 @@ const CSSPropertyNameMap = {
31
34
  'strokeColor': 'border-color',
32
35
  'fillColor': 'background-color',
33
36
  'blur': 'filter',
34
- 'backdropBlur': 'backdrop-filter'
37
+ 'backdropBlur': 'backdrop-filter',
38
+ 'letterSpacing': 'letter-spacing',
39
+ 'wordSpacing': 'word-spacing',
40
+ 'color': 'color'
35
41
  };
36
42
  function getTransitions(values, hover) {
37
43
  if (!hover)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cntrl-site/sdk-nextjs",
3
- "version": "0.16.14",
3
+ "version": "0.17.0",
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.2.2",
24
+ "@cntrl-site/sdk": "^1.2.3",
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 { FC, useId, useState } from 'react';
1
+ import { FC, useId, useMemo, useState } from 'react';
2
2
  import { ArticleItemType, CntrlColor, getLayoutStyles, TRichTextItem } from '@cntrl-site/sdk';
3
3
  import JSXStyle from 'styled-jsx/style';
4
4
  import { ItemProps } from '../Item';
@@ -14,7 +14,8 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
14
14
  const id = useId();
15
15
  const [ref, setRef] = useState<HTMLDivElement | null>(null);
16
16
  const { layouts } = useCntrlContext();
17
- const { angle, blur } = useRichTextItemValues(item, sectionId);
17
+ const { angle, blur, wordSpacing, letterSpacing, color } = useRichTextItemValues(item, sectionId);
18
+ const textColor = useMemo(() => CntrlColor.parse(color), [color]);
18
19
  useRegisterResize(ref, onResize);
19
20
 
20
21
  return (
@@ -24,7 +25,10 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
24
25
  className={`rich-text-wrapper-${item.id}`}
25
26
  style={{
26
27
  transform: `rotate(${angle}deg)`,
27
- filter: `blur(${blur * 100}vw)`
28
+ filter: `blur(${blur * 100}vw)`,
29
+ letterSpacing: `${letterSpacing * 100}vw`,
30
+ wordSpacing: `${wordSpacing * 100}vw`,
31
+ color: `${textColor.toCss()}`
28
32
  }}
29
33
  >
30
34
  {content}
@@ -34,10 +38,10 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
34
38
  {`${getLayoutStyles(layouts, [item.state.hover], ([hoverParams]) => {
35
39
  return (`
36
40
  .rich-text-wrapper-${item.id} {
37
- transition: ${getTransitions<ArticleItemType.RichText>(['angle', 'blur'], hoverParams)};
41
+ transition: ${getTransitions<ArticleItemType.RichText>(['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color'], hoverParams)};
38
42
  }
39
43
  .rich-text-wrapper-${item.id}:hover {
40
- ${getHoverStyles<ArticleItemType.RichText>(['angle', 'blur'], hoverParams)}
44
+ ${getHoverStyles<ArticleItemType.RichText>(['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color'], hoverParams)}
41
45
  }
42
46
  `);
43
47
  })}`}
@@ -2,6 +2,8 @@ import { useKeyframeValue } from '../../common/useKeyframeValue';
2
2
  import { TRichTextItem } from '@cntrl-site/sdk';
3
3
  import { useLayoutContext } from '../useLayoutContext';
4
4
 
5
+ const DEFAULT_COLOR = 'rgba(0, 0, 0, 1)';
6
+
5
7
  export const useRichTextItemValues = (item: TRichTextItem, sectionId: string) => {
6
8
  const layoutId = useLayoutContext();
7
9
  const { angle } = useKeyframeValue(
@@ -23,5 +25,41 @@ export const useRichTextItemValues = (item: TRichTextItem, sectionId: string) =>
23
25
  [layoutId]
24
26
  );
25
27
 
26
- return { angle, blur };
28
+ const letterSpacing = useKeyframeValue(
29
+ item,
30
+ (item, layoutId) => {
31
+ if (!layoutId) return 0;
32
+ const layoutParams = item.layoutParams[layoutId];
33
+ return 'letterSpacing' in layoutParams ? layoutParams.letterSpacing : 0;
34
+ },
35
+ (animator, scroll, value) => animator.getLetterSpacing({ letterSpacing: value }, scroll).letterSpacing,
36
+ sectionId,
37
+ [layoutId]
38
+ );
39
+
40
+ const wordSpacing = useKeyframeValue(
41
+ item,
42
+ (item, layoutId) => {
43
+ if (!layoutId) return 0;
44
+ const layoutParams = item.layoutParams[layoutId];
45
+ return 'wordSpacing' in layoutParams ? layoutParams.wordSpacing : 0;
46
+ },
47
+ (animator, scroll, value) => animator.getWordSpacing({ wordSpacing: value }, scroll).wordSpacing,
48
+ sectionId,
49
+ [layoutId]
50
+ );
51
+
52
+ const color = useKeyframeValue(
53
+ item,
54
+ (item, layoutId) => {
55
+ if (!layoutId) return DEFAULT_COLOR;
56
+ const layoutParams = item.layoutParams[layoutId];
57
+ return 'color' in layoutParams ? layoutParams.color : DEFAULT_COLOR;
58
+ },
59
+ (animator, scroll, value) => animator.getTextColor({ color: value }, scroll).color,
60
+ sectionId,
61
+ [layoutId]
62
+ );
63
+
64
+ return { angle, blur, letterSpacing, wordSpacing, color };
27
65
  };
@@ -232,6 +232,75 @@ export class Animator {
232
232
  };
233
233
  }
234
234
 
235
+ getTextColor(
236
+ values: TKeyframeValueMap[KeyframeType.TextColor],
237
+ pos: number
238
+ ): TKeyframeValueMap[KeyframeType.TextColor] {
239
+ const keyframes = this.keyframesMap[KeyframeType.TextColor];
240
+ if (!keyframes || !keyframes.length) return values;
241
+ if (keyframes.length === 1) {
242
+ const [keyframe] = keyframes;
243
+ return {
244
+ color: keyframe.value.color
245
+ };
246
+ }
247
+ const { start, end } = this.getStartEnd<KeyframeType.TextColor>(pos, keyframes);
248
+ return {
249
+ color: this.getRangeColor(start, end, pos)
250
+ };
251
+ }
252
+
253
+ getLetterSpacing(
254
+ values: TKeyframeValueMap[KeyframeType.LetterSpacing],
255
+ pos: number
256
+ ): TKeyframeValueMap[KeyframeType.LetterSpacing] {
257
+ const keyframes = this.keyframesMap[KeyframeType.LetterSpacing];
258
+ if (!keyframes || !keyframes.length) return values;
259
+ if (keyframes.length === 1) {
260
+ const [keyframe] = keyframes;
261
+ return {
262
+ letterSpacing: keyframe.value.letterSpacing
263
+ };
264
+ }
265
+ const { start, end } = this.getStartEnd<KeyframeType.LetterSpacing>(pos, keyframes);
266
+ return {
267
+ letterSpacing: rangeMap(
268
+ pos,
269
+ start.position,
270
+ end.position,
271
+ start.value.letterSpacing,
272
+ end.value.letterSpacing,
273
+ true
274
+ )
275
+ };
276
+ }
277
+
278
+ getWordSpacing(
279
+ values: TKeyframeValueMap[KeyframeType.WordSpacing],
280
+ pos: number
281
+ ): TKeyframeValueMap[KeyframeType.WordSpacing] {
282
+ const keyframes = this.keyframesMap[KeyframeType.WordSpacing];
283
+ if (!keyframes || !keyframes.length) return values;
284
+ if (keyframes.length === 1) {
285
+ const [keyframe] = keyframes;
286
+ return {
287
+ wordSpacing: keyframe.value.wordSpacing
288
+ };
289
+ }
290
+ const { start, end } = this.getStartEnd<KeyframeType.WordSpacing>(pos, keyframes);
291
+ return {
292
+ wordSpacing: rangeMap(
293
+ pos,
294
+ start.position,
295
+ end.position,
296
+ start.value.wordSpacing,
297
+ end.value.wordSpacing,
298
+ true
299
+ )
300
+ };
301
+ }
302
+
303
+
235
304
  getStartEnd<T extends KeyframeType>(position: number, keyframes: AnimationData<T>[]): PositionKeyframes<T> {
236
305
  const index = binSearchInsertAt(keyframes, { position }, compare);
237
306
  const end = index === keyframes.length ? index - 1 : index;
@@ -247,8 +316,8 @@ export class Animator {
247
316
  }
248
317
 
249
318
  private getRangeColor(
250
- start: AnimationData<KeyframeType.Color | KeyframeType.BorderColor>,
251
- end: AnimationData<KeyframeType.Color | KeyframeType.BorderColor>,
319
+ start: AnimationData<KeyframeType.Color | KeyframeType.BorderColor | KeyframeType.TextColor>,
320
+ end: AnimationData<KeyframeType.Color | KeyframeType.BorderColor | KeyframeType.TextColor>,
252
321
  position: number
253
322
  ): string {
254
323
  const rangeAmount = rangeMap(position, start.position, end.position, 0, 1, true);
@@ -272,7 +341,10 @@ function createKeyframesMap(): KeyframesMap {
272
341
  [KeyframeType.Opacity]: [],
273
342
  [KeyframeType.Scale]: [],
274
343
  [KeyframeType.Blur]: [],
275
- [KeyframeType.BackdropBlur]: []
344
+ [KeyframeType.BackdropBlur]: [],
345
+ [KeyframeType.LetterSpacing]: [],
346
+ [KeyframeType.WordSpacing]: [],
347
+ [KeyframeType.TextColor]: []
276
348
  };
277
349
  }
278
350
 
@@ -18,7 +18,10 @@ const hoverTransformationMap: Record<keyof ItemHoverParams, HoverParamsGetter> =
18
18
  'strokeColor': (strokeColor: string) => `border-color: ${CntrlColor.parse(strokeColor).toCss()} !important;`,
19
19
  'fillColor': (fillColor: string) => `background-color: ${CntrlColor.parse(fillColor).toCss()} !important;`,
20
20
  'blur': (blur: number) => `filter: blur(${blur * 100}vw) !important;`,
21
- 'backdropBlur': (backdropBlur: number) => `backdrop-filter: blur(${backdropBlur * 100}vw) !important;`
21
+ 'backdropBlur': (backdropBlur: number) => `backdrop-filter: blur(${backdropBlur * 100}vw) !important;`,
22
+ 'color': (color: string) => `color: ${CntrlColor.parse(color).toCss()} !important;`,
23
+ 'letterSpacing': (letterSpacing: number) => `letter-spacing: ${letterSpacing * 100}vw !important;`,
24
+ 'wordSpacing': (wordSpacing: number) => `word-spacing: ${wordSpacing * 100}vw !important;`
22
25
  };
23
26
 
24
27
  const CSSPropertyNameMap: Record<keyof ItemHoverParams, string> = {
@@ -34,7 +37,10 @@ const CSSPropertyNameMap: Record<keyof ItemHoverParams, string> = {
34
37
  'strokeColor': 'border-color',
35
38
  'fillColor': 'background-color',
36
39
  'blur': 'filter',
37
- 'backdropBlur': 'backdrop-filter'
40
+ 'backdropBlur': 'backdrop-filter',
41
+ 'letterSpacing': 'letter-spacing',
42
+ 'wordSpacing': 'word-spacing',
43
+ 'color': 'color'
38
44
  };
39
45
 
40
46
  export function getTransitions<T extends ArticleItemType>(
@@ -1,5 +0,0 @@
1
- <component name="ProjectCodeStyleConfiguration">
2
- <state>
3
- <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
4
- </state>
5
- </component>
@@ -1,15 +0,0 @@
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>