@redneckz/wildless-cms-uni-blocks 0.4.4 → 0.4.5

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 (123) hide show
  1. package/bundle/blocks.schema.json +1 -1
  2. package/bundle/bundle.umd.js +38 -11
  3. package/bundle/bundle.umd.min.js +1 -1
  4. package/dist/components/BenefitsBlock/BenefitsBlock.js +32 -9
  5. package/dist/components/BenefitsBlock/BenefitsBlock.js.map +1 -1
  6. package/dist/components/BenefitsBlock/BenefitsBlockContent.d.ts +9 -2
  7. package/dist/content-page-repository/transformContentPage.js +9 -3
  8. package/dist/content-page-repository/transformContentPage.js.map +1 -1
  9. package/dist/content-page-repository/transformImg.d.ts +11 -0
  10. package/dist/content-page-repository/transformImg.js +100 -0
  11. package/dist/content-page-repository/transformImg.js.map +1 -0
  12. package/dist/content-page-repository/transformPicture.js +15 -40
  13. package/dist/content-page-repository/transformPicture.js.map +1 -1
  14. package/dist/content-page-repository/transformSrc.d.ts +3 -0
  15. package/dist/content-page-repository/transformSrc.js +20 -0
  16. package/dist/content-page-repository/transformSrc.js.map +1 -0
  17. package/dist/model/ImageSize.d.ts +6 -0
  18. package/dist/model/ImageSize.js +2 -0
  19. package/dist/model/ImageSize.js.map +1 -0
  20. package/dist/model/Picture.d.ts +19 -6
  21. package/dist/ui-kit/Img/ImgAsPicture.js +6 -2
  22. package/dist/ui-kit/Img/ImgAsPicture.js.map +1 -1
  23. package/dist/utils/isPictureSizeEmpty.d.ts +2 -0
  24. package/dist/utils/isPictureSizeEmpty.js +7 -0
  25. package/dist/utils/isPictureSizeEmpty.js.map +1 -0
  26. package/lib/common.css +1 -1
  27. package/lib/components/BenefitsBlock/BenefitsBlock.fixture.d.ts +2 -0
  28. package/lib/components/BenefitsBlock/BenefitsBlock.js +32 -9
  29. package/lib/components/BenefitsBlock/BenefitsBlock.js.map +1 -1
  30. package/lib/components/BenefitsBlock/BenefitsBlockContent.d.ts +9 -2
  31. package/lib/content-page-repository/transformContentPage.js +9 -3
  32. package/lib/content-page-repository/transformContentPage.js.map +1 -1
  33. package/lib/content-page-repository/transformImg.d.ts +11 -0
  34. package/lib/content-page-repository/transformImg.js +94 -0
  35. package/lib/content-page-repository/transformImg.js.map +1 -0
  36. package/lib/content-page-repository/transformPicture.js +15 -40
  37. package/lib/content-page-repository/transformPicture.js.map +1 -1
  38. package/lib/content-page-repository/transformSrc.d.ts +3 -0
  39. package/lib/content-page-repository/transformSrc.js +14 -0
  40. package/lib/content-page-repository/transformSrc.js.map +1 -0
  41. package/lib/model/ImageSize.d.ts +6 -0
  42. package/lib/model/ImageSize.js +2 -0
  43. package/lib/model/ImageSize.js.map +1 -0
  44. package/lib/model/Picture.d.ts +19 -6
  45. package/lib/ui-kit/Img/ImgAsPicture.js +6 -2
  46. package/lib/ui-kit/Img/ImgAsPicture.js.map +1 -1
  47. package/lib/utils/isPictureSizeEmpty.d.ts +2 -0
  48. package/lib/utils/isPictureSizeEmpty.js +4 -0
  49. package/lib/utils/isPictureSizeEmpty.js.map +1 -0
  50. package/mobile/bundle/bundle.umd.js +6 -2
  51. package/mobile/bundle/bundle.umd.min.js +1 -1
  52. package/mobile/dist/components/BenefitsBlock/BenefitsBlock.js +32 -9
  53. package/mobile/dist/components/BenefitsBlock/BenefitsBlock.js.map +1 -1
  54. package/mobile/dist/components/BenefitsBlock/BenefitsBlockContent.d.ts +9 -2
  55. package/mobile/dist/content-page-repository/transformContentPage.js +9 -3
  56. package/mobile/dist/content-page-repository/transformContentPage.js.map +1 -1
  57. package/mobile/dist/content-page-repository/transformImg.d.ts +11 -0
  58. package/mobile/dist/content-page-repository/transformImg.js +100 -0
  59. package/mobile/dist/content-page-repository/transformImg.js.map +1 -0
  60. package/mobile/dist/content-page-repository/transformPicture.js +15 -40
  61. package/mobile/dist/content-page-repository/transformPicture.js.map +1 -1
  62. package/mobile/dist/content-page-repository/transformSrc.d.ts +3 -0
  63. package/mobile/dist/content-page-repository/transformSrc.js +20 -0
  64. package/mobile/dist/content-page-repository/transformSrc.js.map +1 -0
  65. package/mobile/dist/model/ImageSize.d.ts +6 -0
  66. package/mobile/dist/model/ImageSize.js +2 -0
  67. package/mobile/dist/model/ImageSize.js.map +1 -0
  68. package/mobile/dist/model/Picture.d.ts +19 -6
  69. package/mobile/dist/ui-kit/Img/ImgAsPicture.js +6 -2
  70. package/mobile/dist/ui-kit/Img/ImgAsPicture.js.map +1 -1
  71. package/mobile/dist/utils/isPictureSizeEmpty.d.ts +2 -0
  72. package/mobile/dist/utils/isPictureSizeEmpty.js +7 -0
  73. package/mobile/dist/utils/isPictureSizeEmpty.js.map +1 -0
  74. package/mobile/lib/components/BenefitsBlock/BenefitsBlock.js +32 -9
  75. package/mobile/lib/components/BenefitsBlock/BenefitsBlock.js.map +1 -1
  76. package/mobile/lib/components/BenefitsBlock/BenefitsBlockContent.d.ts +9 -2
  77. package/mobile/lib/content-page-repository/transformContentPage.js +9 -3
  78. package/mobile/lib/content-page-repository/transformContentPage.js.map +1 -1
  79. package/mobile/lib/content-page-repository/transformImg.d.ts +11 -0
  80. package/mobile/lib/content-page-repository/transformImg.js +94 -0
  81. package/mobile/lib/content-page-repository/transformImg.js.map +1 -0
  82. package/mobile/lib/content-page-repository/transformPicture.js +15 -40
  83. package/mobile/lib/content-page-repository/transformPicture.js.map +1 -1
  84. package/mobile/lib/content-page-repository/transformSrc.d.ts +3 -0
  85. package/mobile/lib/content-page-repository/transformSrc.js +14 -0
  86. package/mobile/lib/content-page-repository/transformSrc.js.map +1 -0
  87. package/mobile/lib/model/ImageSize.d.ts +6 -0
  88. package/mobile/lib/model/ImageSize.js +2 -0
  89. package/mobile/lib/model/ImageSize.js.map +1 -0
  90. package/mobile/lib/model/Picture.d.ts +19 -6
  91. package/mobile/lib/ui-kit/Img/ImgAsPicture.js +6 -2
  92. package/mobile/lib/ui-kit/Img/ImgAsPicture.js.map +1 -1
  93. package/mobile/lib/utils/isPictureSizeEmpty.d.ts +2 -0
  94. package/mobile/lib/utils/isPictureSizeEmpty.js +4 -0
  95. package/mobile/lib/utils/isPictureSizeEmpty.js.map +1 -0
  96. package/mobile/src/components/BenefitsBlock/BenefitsBlock.example.json +1 -0
  97. package/mobile/src/components/BenefitsBlock/BenefitsBlock.tsx +78 -28
  98. package/mobile/src/components/BenefitsBlock/BenefitsBlockContent.ts +10 -2
  99. package/mobile/src/components/ContentPage/ContentPage.page.json +1 -2
  100. package/mobile/src/components/__snapshots__/Blocks.spec.tsx.snap +1 -1
  101. package/mobile/src/content-page-repository/transformContentPage.ts +10 -3
  102. package/mobile/src/content-page-repository/transformImg.ts +157 -0
  103. package/mobile/src/content-page-repository/transformPicture.ts +24 -58
  104. package/mobile/src/content-page-repository/transformSrc.ts +21 -0
  105. package/mobile/src/model/ImageSize.ts +6 -0
  106. package/mobile/src/model/Picture.ts +29 -6
  107. package/mobile/src/ui-kit/Img/ImgAsPicture.tsx +8 -2
  108. package/mobile/src/utils/isPictureSizeEmpty.ts +5 -0
  109. package/package.json +2 -1
  110. package/src/components/BenefitsBlock/BenefitsBlock.example.json +1 -0
  111. package/src/components/BenefitsBlock/BenefitsBlock.fixture.tsx +94 -1
  112. package/src/components/BenefitsBlock/BenefitsBlock.tsx +78 -28
  113. package/src/components/BenefitsBlock/BenefitsBlockContent.ts +10 -2
  114. package/src/components/ContentPage/ContentPage.page.json +1 -2
  115. package/src/components/__snapshots__/Blocks.spec.tsx.snap +1 -1
  116. package/src/content-page-repository/transformContentPage.ts +10 -3
  117. package/src/content-page-repository/transformImg.ts +157 -0
  118. package/src/content-page-repository/transformPicture.ts +24 -58
  119. package/src/content-page-repository/transformSrc.ts +21 -0
  120. package/src/model/ImageSize.ts +6 -0
  121. package/src/model/Picture.ts +29 -6
  122. package/src/ui-kit/Img/ImgAsPicture.tsx +8 -2
  123. package/src/utils/isPictureSizeEmpty.ts +5 -0
@@ -1,55 +1,30 @@
1
- import fs from 'fs';
2
1
  import path from 'path';
3
2
  import sharp from 'sharp';
4
- import util from 'util';
5
- const mkdir = util.promisify(fs.mkdir);
3
+ import { transformImg } from './transformImg.js';
6
4
  export async function transformPicture(pagePath, picture, options) {
7
5
  const sources = picture.sources || [];
8
6
  const src = picture?.src || '';
9
- const [transformedPicture, ...transformedSources] = await Promise.all([picture].concat(sources).map((_) => transformImg(pagePath, src, { ...options, ..._ })));
7
+ const transformedPicture = await transformImg({
8
+ pagePath,
9
+ src,
10
+ transformationOptions: { ...options, ...picture },
11
+ });
12
+ const { width, height } = await sharp(path.resolve(options.publicDir, transformedPicture)).metadata();
13
+ const containerSize = width && height ? { width, height } : undefined;
14
+ const transformedSources = await Promise.all(sources.map((_) => transformImg({
15
+ pagePath,
16
+ src,
17
+ containerSize,
18
+ transformationOptions: { ...options, ..._ },
19
+ })));
10
20
  return {
11
21
  ...picture,
12
22
  src: transformedPicture,
13
23
  sources: transformedSources.map((_, i) => ({
14
24
  ...sources[i],
15
25
  src: _,
26
+ size: { width, height },
16
27
  })),
17
28
  };
18
29
  }
19
- async function transformImg(pagePath, src, transformationOptions) {
20
- const { contentDir, publicDir, format, options, size } = transformationOptions;
21
- const pageDir = path.dirname(pagePath);
22
- const imgPath = `${pageDir}/${src}`;
23
- let chain = sharp(imgPath);
24
- if (size) {
25
- chain = chain.resize(size?.width, size?.height, {
26
- fit: sharp.fit.contain,
27
- background: [0, 0, 0, 0],
28
- });
29
- }
30
- if (format) {
31
- chain = chain.toFormat(format, options);
32
- }
33
- const transformedSrc = transformSrc(src, transformationOptions);
34
- const transformedImgPath = `${publicDir}/${path.relative(contentDir, `${path.dirname(pagePath)}/${transformedSrc}`)}`;
35
- await mkdir(path.dirname(transformedImgPath), { recursive: true });
36
- try {
37
- await chain.toFile(transformedImgPath);
38
- }
39
- catch (e) {
40
- console.error(e);
41
- }
42
- return transformedSrc;
43
- }
44
- function transformSrc(src, { format, size }) {
45
- const noTransform = !format && !size;
46
- if (noTransform) {
47
- return src;
48
- }
49
- const fileName = path.basename(src, path.extname(src));
50
- const fileSizes = [size?.width, size?.height].filter(Boolean);
51
- const suffix = fileSizes.length ? `-${fileSizes.join('-')}` : '';
52
- const ext = String(format) || path.extname(src);
53
- return `${fileName}${suffix}.${ext}`;
54
- }
55
30
  //# sourceMappingURL=transformPicture.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transformPicture.js","sourceRoot":"","sources":["../../src/content-page-repository/transformPicture.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transformPicture.js","sourceRoot":"","sources":["../../src/content-page-repository/transformPicture.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,OAAgB,EAChB,OAA8B;IAE9B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;IACtC,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;IAE/B,MAAM,kBAAkB,GAAG,MAAM,YAAY,CAAC;QAC5C,QAAQ;QACR,GAAG;QACH,qBAAqB,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE;KAClD,CAAC,CAAC;IAEH,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CACnC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,CACpD,CAAC,QAAQ,EAAE,CAAC;IACb,MAAM,aAAa,GAAG,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAEtE,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,GAAG,CAC1C,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAChB,YAAY,CAAC;QACX,QAAQ;QACR,GAAG;QACH,aAAa;QACb,qBAAqB,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,CAAC,EAAE;KAC5C,CAAC,CACH,CACF,CAAC;IAEF,OAAO;QACL,GAAG,OAAO;QACV,GAAG,EAAE,kBAAkB;QACvB,OAAO,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACzC,GAAG,OAAO,CAAC,CAAC,CAAC;YACb,GAAG,EAAE,CAAC;YACN,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;SACxB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ImgSource } from '../model/Picture';
2
+ import type { TransformationOptions } from './TransformationOptions';
3
+ export declare function transformSrc(src: string, { format, size }: TransformationOptions & ImgSource): string;
@@ -0,0 +1,14 @@
1
+ import path from 'path';
2
+ import { isPictureSizeEmpty } from '../utils/isPictureSizeEmpty.js';
3
+ export function transformSrc(src, { format, size }) {
4
+ const noTransform = isPictureSizeEmpty(size) && !format;
5
+ if (noTransform) {
6
+ return src;
7
+ }
8
+ const fileName = path.basename(src, path.extname(src));
9
+ const fileSizes = [size?.width, size?.height].filter(Boolean);
10
+ const suffix = fileSizes.length ? `-${fileSizes.join('-')}` : '';
11
+ const ext = format ? String(format) : 'webp';
12
+ return `${fileName}${suffix}.${ext}`;
13
+ }
14
+ //# sourceMappingURL=transformSrc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformSrc.js","sourceRoot":"","sources":["../../src/content-page-repository/transformSrc.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,UAAU,YAAY,CAC1B,GAAW,EACX,EAAE,MAAM,EAAE,IAAI,EAAqC;IAEnD,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IACxD,IAAI,WAAW,EAAE;QACf,OAAO,GAAG,CAAC;KACZ;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAE7C,OAAO,GAAG,QAAQ,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare type ImageSize = {
2
+ /** @title Ширина */
3
+ width: number;
4
+ /** @title Высота */
5
+ height: number;
6
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ImageSize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageSize.js","sourceRoot":"","sources":["../../src/model/ImageSize.ts"],"names":[],"mappings":""}
@@ -1,6 +1,23 @@
1
1
  import type { IconName } from '../icons/IconName';
2
2
  import type { IconVersion } from './IconVersion';
3
+ import { ImageSize } from './ImageSize';
3
4
  export declare type ImgFormats = 'jpeg' | 'jpg' | 'png' | 'gif' | 'webp' | 'heif' | 'avif';
5
+ /**
6
+ * @title Позиционирование
7
+ * @enumNames [
8
+ * "Сверху слева",
9
+ * "Сверху по центру",
10
+ * "Сверху справа",
11
+ * "Посередине слева",
12
+ * "Посередине по центру",
13
+ * "Посередине справа",
14
+ * "Снизу слева",
15
+ * "Снизу по центру",
16
+ * "Снизу справа"
17
+ * ]
18
+ * @default "center"
19
+ */
20
+ export declare type ImgAlignment = 'northwest' | 'north' | 'northeast' | 'west' | 'center' | 'east' | 'southwest' | 'south' | 'southeast';
4
21
  export interface Img {
5
22
  /** @title Картинка */
6
23
  src?: string;
@@ -15,6 +32,7 @@ export interface Img {
15
32
  */
16
33
  export declare type MediaQuery = 1919 | 1439 | 1279;
17
34
  export interface ImgSource {
35
+ alignment?: ImgAlignment;
18
36
  /** @title Иконка */
19
37
  icon?: IconName;
20
38
  iconVersion?: IconVersion;
@@ -26,12 +44,7 @@ export interface ImgSource {
26
44
  options?: Record<string, any>;
27
45
  media?: MediaQuery;
28
46
  /** @title Размер изображения */
29
- size?: {
30
- /** @title Ширина */
31
- width?: number;
32
- /** @title Высота */
33
- height?: number;
34
- };
47
+ size?: Partial<ImageSize>;
35
48
  }
36
49
  /** @title Изображение */
37
50
  export interface Picture extends Img, ImgSource {
@@ -14,14 +14,18 @@ export const ImgAsPicture = JSX(({ className = '', image, imageClassName = '', i
14
14
  return (_jsxs("picture", { className: `${pictureStyles} ${className}`, children: [image?.sources?.length
15
15
  ? image.sources
16
16
  .sort(sourcesComparator)
17
- .map(({ src, format, media, size }, index) => (_jsx("source", { srcSet: src, type: formatToMimeType(format), media: media ? `(max-width: ${media}px)` : '', ...size }, `${index}_${src}`)))
17
+ .map(({ src, format, media }, index) => (_jsx("source", { srcSet: src, type: formatToMimeType(format), media: media ? `(max-width: ${media}px)` : '', ...image.size }, `${index}_${src}`)))
18
18
  : null, renderImg(image, imageClassName, isMobile)] }));
19
19
  });
20
20
  const renderImg = (image, imageClassName = '', isMobile = false) => {
21
+ const style = {
22
+ width: image.size?.width ? `${image.size?.width}px` : '100%',
23
+ height: image.size?.height ? `${image.size?.height}px` : '100%',
24
+ };
21
25
  const title = image.title || '';
22
26
  const alt = image.alt || image.title;
23
27
  const imgStyle = isMobile ? 'm-auto' : 'm-0';
24
- return (_jsx("img", { src: image.src, className: `${imgStyle} ${imageClassName}`, alt: alt, title: title, ...image.size }));
28
+ return (_jsx("img", { src: image.src, className: `${imgStyle} ${imageClassName}`, alt: alt, title: title, style: style, ...image.size }));
25
29
  };
26
30
  export function formatToMimeType(format) {
27
31
  return format ? `image/${String(format)}` : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"ImgAsPicture.js","sourceRoot":"","sources":["../../../src/ui-kit/Img/ImgAsPicture.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAIxC,MAAM,iBAAiB,GAAG,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE;IACnD,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE;QACtB,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;KAC1B;IAED,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAC7B,CAAC,EAAE,SAAS,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,GAAG,EAAE,EAAE,QAAQ,GAAG,KAAK,EAAE,EAAE,EAAE;IACnE,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;QAC9C,OAAO,IAAI,CAAC;KACb;IAED,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;IAEtD,OAAO,CACL,mBAAS,SAAS,EAAE,GAAG,aAAa,IAAI,SAAS,EAAE,aAChD,KAAK,EAAE,OAAO,EAAE,MAAM;gBACrB,CAAC,CAAC,KAAK,CAAC,OAAO;qBACV,IAAI,CAAC,iBAAiB,CAAC;qBACvB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAC5C,iBAEE,MAAM,EAAE,GAAG,EACX,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAC9B,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,eAAe,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,KACzC,IAAI,IAJH,GAAG,KAAK,IAAI,GAAG,EAAE,CAKtB,CACH,CAAC;gBACN,CAAC,CAAC,IAAI,EACP,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,CAAC,IACnC,CACX,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,KAAc,EAAE,cAAc,GAAG,EAAE,EAAE,QAAQ,GAAG,KAAK,EAAE,EAAE;IAC1E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC;IACrC,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IAE7C,OAAO,CACL,cACE,GAAG,EAAE,KAAK,CAAC,GAAG,EACd,SAAS,EAAE,GAAG,QAAQ,IAAI,cAAc,EAAE,EAC1C,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,KACR,KAAK,CAAC,IAAI,GACd,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,MAA2B;IAC1D,OAAO,MAAM,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC"}
1
+ {"version":3,"file":"ImgAsPicture.js","sourceRoot":"","sources":["../../../src/ui-kit/Img/ImgAsPicture.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAIxC,MAAM,iBAAiB,GAAG,CAAC,CAAU,EAAE,CAAU,EAAE,EAAE;IACnD,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE;QACtB,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;KAC1B;IAED,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAC7B,CAAC,EAAE,SAAS,GAAG,EAAE,EAAE,KAAK,EAAE,cAAc,GAAG,EAAE,EAAE,QAAQ,GAAG,KAAK,EAAE,EAAE,EAAE;IACnE,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;QAC9C,OAAO,IAAI,CAAC;KACb;IAED,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC;IAEtD,OAAO,CACL,mBAAS,SAAS,EAAE,GAAG,aAAa,IAAI,SAAS,EAAE,aAChD,KAAK,EAAE,OAAO,EAAE,MAAM;gBACrB,CAAC,CAAC,KAAK,CAAC,OAAO;qBACV,IAAI,CAAC,iBAAiB,CAAC;qBACvB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CACtC,iBAEE,MAAM,EAAE,GAAG,EACX,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAC9B,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,eAAe,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,KACzC,KAAK,CAAC,IAAI,IAJT,GAAG,KAAK,IAAI,GAAG,EAAE,CAKtB,CACH,CAAC;gBACN,CAAC,CAAC,IAAI,EACP,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,CAAC,IACnC,CACX,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,KAAc,EAAE,cAAc,GAAG,EAAE,EAAE,QAAQ,GAAG,KAAK,EAAE,EAAE;IAC1E,MAAM,KAAK,GAAG;QACZ,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM;QAC5D,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC,MAAM;KAChE,CAAC;IAEF,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC;IACrC,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IAE7C,OAAO,CACL,cACE,GAAG,EAAE,KAAK,CAAC,GAAG,EACd,SAAS,EAAE,GAAG,QAAQ,IAAI,cAAc,EAAE,EAC1C,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,KACR,KAAK,CAAC,IAAI,GACd,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,MAA2B;IAC1D,OAAO,MAAM,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Picture } from '../model/Picture';
2
+ export declare function isPictureSizeEmpty(size: Picture['size']): boolean;
@@ -0,0 +1,4 @@
1
+ export function isPictureSizeEmpty(size) {
2
+ return !(size?.width || size?.height);
3
+ }
4
+ //# sourceMappingURL=isPictureSizeEmpty.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isPictureSizeEmpty.js","sourceRoot":"","sources":["../../src/utils/isPictureSizeEmpty.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,kBAAkB,CAAC,IAAqB;IACtD,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "title": "Преимущества",
3
+ "benefitsBlockVersion": "primary",
3
4
  "benefitList": [
4
5
  {
5
6
  "label": "Преимущество №1",
@@ -3,64 +3,114 @@ import { BlockWrapper } from '../../ui-kit/BlockWrapper';
3
3
  import type { UniBlockProps } from '../../types';
4
4
  import { Heading } from '../../ui-kit/Heading/Heading';
5
5
  import { Img } from '../../ui-kit/Img/Img';
6
- import type { BenefitItemProps, BenefitsBlockContent } from './BenefitsBlockContent';
7
- import { DescriptionDef, ListBenefitDef, TextBenefitDef } from './BenefitsBlockContent';
6
+ import type { BenefitsBlockContent, ListBenefitDef, TextBenefitDef } from './BenefitsBlockContent';
7
+ import {
8
+ BenefitBlockItemProps,
9
+ BenefitsBlockVersion,
10
+ DescriptionDef,
11
+ } from './BenefitsBlockContent';
12
+ import { Picture } from '../../model/Picture';
8
13
 
9
14
  export interface BenefitsBlockProps extends BenefitsBlockContent, UniBlockProps {}
10
15
 
16
+ const benefitsBlockStyleMap = {
17
+ primary: 'bg-white',
18
+ secondary: 'bg-primary-main',
19
+ };
20
+
21
+ const benefitsTextStyleMap = {
22
+ primary: '',
23
+ secondary: 'text-white',
24
+ };
25
+
26
+ const benefitsDescriptionStyleMap = {
27
+ primary: 'text-secondary-text',
28
+ secondary: 'text-white opacity-80',
29
+ };
30
+
31
+ const benefitsIconStyleMap = {
32
+ primary: 'bg-main-divider text-primary-main',
33
+ secondary: 'bg-white/30 text-black',
34
+ };
35
+
11
36
  export const BenefitsBlock = JSX<BenefitsBlockProps>(
12
- ({ className = '', title, benefitList, ...rest }) => {
37
+ ({ className = '', title, benefitList, benefitsBlockVersion = 'primary', ...rest }) => {
13
38
  return (
14
39
  <BlockWrapper
15
- className={`font-sans text-primary-text bg-white p-12 flex flex-col items-center ${className}`}
40
+ className={`font-sans text-primary-text p-12 flex flex-col items-center ${className} ${benefitsBlockStyleMap[benefitsBlockVersion]}`}
16
41
  {...rest}
17
42
  >
18
43
  {title ? (
19
- <Heading headingType="h3" as="h2" className="max-w-[47rem] text-center" title={title} />
44
+ <Heading
45
+ headingType="h3"
46
+ as="h2"
47
+ className={`max-w-[47rem] text-center ${benefitsTextStyleMap[benefitsBlockVersion]}`}
48
+ title={title}
49
+ />
20
50
  ) : null}
21
- {benefitList?.length ? renderBenefits(benefitList) : null}
51
+ {benefitList?.length ? renderBenefits(benefitList, benefitsBlockVersion) : null}
22
52
  </BlockWrapper>
23
53
  );
24
54
  },
25
55
  );
26
56
 
27
- const renderBenefits = (benefits: BenefitItemProps[]) => {
57
+ const renderBenefits = (
58
+ benefitList: BenefitBlockItemProps[],
59
+ benefitsBlockVersion: BenefitsBlockVersion,
60
+ ) => {
28
61
  return (
29
62
  <div className="flex flex-wrap w-full justify-center gap-x-20 mt-8">
30
- {benefits.map(renderStep)}
63
+ {benefitList.map(renderStep(benefitsBlockVersion))}
31
64
  </div>
32
65
  );
33
66
  };
34
67
 
35
- const renderStep = (benefit: BenefitItemProps, i: number) => {
36
- const description = benefit?.description || undefined;
68
+ const setIconVersion = (benefitIcon: Picture, benefitsBlockVersion: BenefitsBlockVersion) => {
69
+ if (!benefitIcon.icon) {
70
+ return benefitIcon;
71
+ }
72
+ benefitIcon.iconVersion = benefitsBlockVersion === 'secondary' ? 'white' : 'normal';
37
73
 
38
- return (
39
- <div key={String(i)} className="flex items-center basis-1/2 max-w-[500px] mb-14">
40
- {benefit?.icon?.icon ? (
41
- <Img
42
- className="w-[50px] h-[50px] min-w-[50px] p-3 rounded-full bg-main-divider"
43
- image={benefit.icon}
44
- asSVG
45
- />
46
- ) : null}
47
- {benefit?.icon?.src ? <Img image={benefit.icon} /> : null}
48
- <div className="ml-5">
49
- {benefit?.label ? <h3 className="text-h6 m-0">{benefit.label}</h3> : null}
50
- {renderDescription(description)}
51
- </div>
52
- </div>
53
- );
74
+ return benefitIcon;
54
75
  };
55
76
 
56
- const renderDescription = (description?: DescriptionDef) => {
77
+ const renderStep =
78
+ (benefitsBlockVersion: BenefitsBlockVersion) => (benefit: BenefitBlockItemProps, i: number) => {
79
+ const description = (benefit?.description || undefined) as DescriptionDef;
80
+
81
+ return (
82
+ <div key={String(i)} className="flex items-center basis-1/2 max-w-[500px] mb-14">
83
+ {benefit?.icon?.icon ? (
84
+ <Img
85
+ className={`w-[50px] h-[50px] min-w-[50px] p-3 rounded-full ${benefitsIconStyleMap[benefitsBlockVersion]}`}
86
+ image={setIconVersion(benefit.icon, benefitsBlockVersion)}
87
+ asSVG
88
+ />
89
+ ) : null}
90
+ {benefit?.icon?.src ? <Img image={benefit.icon} /> : null}
91
+ <div className="ml-5">
92
+ {benefit?.label ? (
93
+ <h3 className={`text-h6 m-0 ${benefitsTextStyleMap[benefitsBlockVersion]}`}>
94
+ {benefit.label}
95
+ </h3>
96
+ ) : null}
97
+ {renderDescription(description, benefitsBlockVersion)}
98
+ </div>
99
+ </div>
100
+ );
101
+ };
102
+
103
+ const renderDescription = (
104
+ description: DescriptionDef,
105
+ benefitsBlockVersion: BenefitsBlockVersion,
106
+ ) => {
57
107
  const benefitType = description ? description?.benefitType : null;
58
108
  if (!benefitType) {
59
109
  return null;
60
110
  }
61
111
 
62
112
  return description ? (
63
- <div className="text-l-light text-secondary-text mt-2">
113
+ <div className={`text-l-light mt-2 ${benefitsDescriptionStyleMap[benefitsBlockVersion]}`}>
64
114
  {benefitType === 'list'
65
115
  ? renderListBenefit(description as ListBenefitDef)
66
116
  : renderTextBenefit(description as TextBenefitDef)}
@@ -37,7 +37,7 @@ export type DescriptionDef = EmptyOption | TextBenefitDef | ListBenefitDef;
37
37
  /**
38
38
  * @title Преимущество
39
39
  */
40
- export interface BenefitItemProps {
40
+ export interface BenefitBlockItemProps {
41
41
  /** @title Название */
42
42
  label?: string;
43
43
  /** @title Описание */
@@ -45,6 +45,12 @@ export interface BenefitItemProps {
45
45
  icon?: Picture;
46
46
  }
47
47
 
48
+ /**
49
+ * @title Цвет блока
50
+ * @enumNames ["Основная", "Второстепенная"]
51
+ */
52
+ export type BenefitsBlockVersion = 'primary' | 'secondary';
53
+
48
54
  /**
49
55
  * @title Блок преимущества
50
56
  */
@@ -53,5 +59,7 @@ export type BenefitsBlockContent = TitleProps & {
53
59
  * @title Список преимуществ
54
60
  * @maxItems 6
55
61
  */
56
- benefitList?: BenefitItemProps[];
62
+ benefitList?: BenefitBlockItemProps[];
63
+ /** @default primary */
64
+ benefitsBlockVersion?: BenefitsBlockVersion;
57
65
  };
@@ -1914,8 +1914,7 @@
1914
1914
  "alt": "Варианты потребительского кредита",
1915
1915
  "format": "webp",
1916
1916
  "size": {
1917
- "width": 400,
1918
- "height": 300
1917
+ "width": 300
1919
1918
  }
1920
1919
  }
1921
1920
  }
@@ -8,7 +8,7 @@ exports[`Blocks Accordion should render block "Accordion" without content 1`] =
8
8
 
9
9
  exports[`Blocks BenefitsBlock should render block "BenefitsBlock" without content 1`] = `
10
10
  <section
11
- class="font-sans text-primary-text bg-white p-12 flex flex-col items-center "
11
+ class="font-sans text-primary-text p-12 flex flex-col items-center bg-white"
12
12
  />
13
13
  `;
14
14
 
@@ -18,11 +18,16 @@ export async function transformContentPage(
18
18
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
19
19
  return mapJSON<ContentPageDef>(JSON.parse(content), async (value: any, [key]) => {
20
20
  const isMarkdown = typeof value === 'string' && key?.endsWith('__md');
21
- const isPicture = value && isLocalPath(value?.src);
21
+
22
22
  if (isMarkdown) {
23
23
  return await transformMarkdown(value);
24
- } else if (isPicture) {
25
- return await transformPicture(pagePath, value as Picture, options);
24
+ } else if (isPicture(value)) {
25
+ try {
26
+ return await transformPicture(pagePath, value, options);
27
+ } catch (ex) {
28
+ console.warn('Error while transforming picture on page: %s', pagePath);
29
+ console.error(ex);
30
+ }
26
31
  }
27
32
 
28
33
  return value;
@@ -34,3 +39,5 @@ const isLocalPath = (_: any): boolean => isString(_) && _.length < 512 && !isURL
34
39
  const isString = (_: any): _ is string => Boolean(_ && typeof _ === 'string');
35
40
 
36
41
  const isURL = (src: string) => ['data:', 'https:', 'http:'].some((proto) => src.startsWith(proto));
42
+
43
+ const isPicture = (_: any): _ is Picture => Boolean(_ && isLocalPath(_?.src));
@@ -0,0 +1,157 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import util from 'util';
4
+ import sharp from 'sharp';
5
+ import type { ResizeOptions, Sharp } from 'sharp';
6
+ import type { ImageSize } from '../model/ImageSize';
7
+ import type { TransformationOptions } from './TransformationOptions';
8
+ import type { ImgAlignment, ImgSource, Picture } from '../model/Picture';
9
+ import { transformSrc } from './transformSrc';
10
+ import { isPictureSizeEmpty } from '../utils/isPictureSizeEmpty';
11
+
12
+ const mkdir = util.promisify(fs.mkdir);
13
+
14
+ type TransformImgParams = {
15
+ pagePath: string;
16
+ src: string;
17
+ containerSize?: ImageSize;
18
+ transformationOptions: TransformationOptions & ImgSource;
19
+ };
20
+
21
+ export async function transformImg({
22
+ pagePath,
23
+ src,
24
+ containerSize,
25
+ transformationOptions,
26
+ }: TransformImgParams): Promise<string> {
27
+ if (!src) {
28
+ return '';
29
+ }
30
+
31
+ const { contentDir, publicDir, format, options, size, alignment } = transformationOptions;
32
+
33
+ const pageDir = path.dirname(pagePath);
34
+ const imgPath = `${pageDir}/${src}`;
35
+ let chain = sharp(imgPath);
36
+
37
+ const targetSize = getPictureSize(size, containerSize);
38
+
39
+ if (targetSize) {
40
+ chain = resizeImg(chain, targetSize, getResizeFit(targetSize));
41
+ }
42
+
43
+ if (containerSize) {
44
+ chain = resizeImg(chain, containerSize);
45
+
46
+ // Save intermediate transform result to modify further
47
+ const { data } = await chain.toBuffer({ resolveWithObject: true });
48
+
49
+ chain = resizeImg(
50
+ sharp(data),
51
+ getCompositionResizeSize(containerSize, targetSize),
52
+ getResizeFit(targetSize),
53
+ );
54
+
55
+ chain = await compositeImg({ chain, containerSize, alignment });
56
+ }
57
+
58
+ if (format) {
59
+ chain = chain.toFormat(format, options);
60
+ }
61
+
62
+ const transformedSrc = transformSrc(src, transformationOptions);
63
+ const transformedImgPath = `${publicDir}/${path.relative(
64
+ contentDir,
65
+ `${path.dirname(pagePath)}/${transformedSrc}`,
66
+ )}`;
67
+
68
+ await mkdir(path.dirname(transformedImgPath), { recursive: true });
69
+
70
+ try {
71
+ await chain.toFile(transformedImgPath);
72
+ } catch (e) {
73
+ console.error(e);
74
+ }
75
+
76
+ return transformedSrc;
77
+ }
78
+
79
+ function createBackgroundImageChain({ width, height }: ImageSize) {
80
+ const channels = 4;
81
+ const rgbaColor = 0x00000000;
82
+
83
+ const canvas = Buffer.alloc(width * height * channels, rgbaColor);
84
+
85
+ return sharp(canvas, { raw: { width, height, channels } });
86
+ }
87
+
88
+ function resizeImg(chain: Sharp, size: Picture['size'], options?: ResizeOptions) {
89
+ return chain.resize(size?.width, size?.height, {
90
+ fit: sharp.fit.fill,
91
+ background: { r: 0, g: 0, b: 0, alpha: 0 },
92
+ ...options,
93
+ });
94
+ }
95
+
96
+ type CompositeImgParams = {
97
+ chain: Sharp;
98
+ containerSize: ImageSize;
99
+ alignment?: ImgAlignment;
100
+ };
101
+
102
+ async function compositeImg({
103
+ chain,
104
+ containerSize,
105
+ alignment,
106
+ }: CompositeImgParams): Promise<Sharp> {
107
+ const { data } = await chain.toBuffer({ resolveWithObject: true });
108
+
109
+ return createBackgroundImageChain(containerSize).composite([
110
+ {
111
+ input: data,
112
+ gravity: alignment,
113
+ },
114
+ ]);
115
+ }
116
+
117
+ function getPictureSize(size: Picture['size'], containerSize?: ImageSize) {
118
+ // If containerSize is undefined intrinsic dimensions of image will be used then.
119
+ return isPictureSizeEmpty(size) ? containerSize : size;
120
+ }
121
+
122
+ function getCompositionResizeSize(
123
+ containerSize: ImageSize,
124
+ size: Picture['size'] = {},
125
+ ): Picture['size'] {
126
+ const { width, height } = size;
127
+ const { width: containerWidth, height: containerHeight } = containerSize;
128
+
129
+ let widthRatio = 0;
130
+ let heightRatio = 0;
131
+
132
+ if (!(width || height)) {
133
+ return undefined;
134
+ }
135
+
136
+ if (width) {
137
+ widthRatio = containerWidth / width;
138
+ }
139
+
140
+ if (height) {
141
+ heightRatio = containerHeight / height;
142
+ }
143
+
144
+ return widthRatio > heightRatio
145
+ ? { width: Math.min(Number(width), containerWidth) }
146
+ : { height: Math.min(Number(height), containerHeight) };
147
+ }
148
+
149
+ function getResizeFit(size: Picture['size']): ResizeOptions {
150
+ /*
151
+ Editor behaviour with one dimension present: resize by given dimension maintaining aspect ratio. (fit: contain)
152
+ With two dimensions present: resize trying to fill given dimensions (fit: fill)
153
+ */
154
+ return {
155
+ fit: size?.width && size?.height ? sharp.fit.fill : sharp.fit.contain,
156
+ };
157
+ }