@@ -40,3 +40,107 @@ render(() => {
);
});
```
+
+## Скелетонизация текста
+
+Пакет `Skeleton` предоставляет хук `useSkeleton`, с помощью которого можно "скелетонизировать" текст, а также кастомизировать его отображение.
+*Обратите особое внимание на то, что у текста должны быть заданы `fontSize` и `lineHeight`*.
+
+```jsx live
+const rowsOptions = [
+ { key: 'computed', content: 'Computed' },
+ { key: '2', content: '2' },
+ { key: '4', content: '4' },
+ { key: '6', content: '6' },
+ { key: '8', content: '8' },
+ { key: '10', content: '10' },
+];
+
+const widthOptions = [
+ { key: 'computed', content: 'Computed' },
+ { key: '100', content: '100px' },
+ { key: '200', content: '200px' },
+ { key: '300', content: '300px' },
+ { key: '400', content: '400px' },
+ { key: 'array', content: '100-200-300-400' },
+];
+
+const alignOptions = [
+ { key: 'left', content: 'left' },
+ { key: 'center', content: 'center' },
+ { key: 'right', content: 'right' },
+];
+
+render(() => {
+ const [visible, setVisible] = React.useState(false);
+ const [rows, setRows] = React.useState('computed');
+ const [width, setWidth] = React.useState('computed');
+ const [align, setAlign] = React.useState('left');
+
+ const { renderSkeleton, textRef } = useSkeleton(visible, {
+ align,
+ ...(rows !== 'computed' && { rows: Number(rows) }),
+ ...(width !== 'computed' && width !== 'array' && { width: Number(width) }),
+ ...(width === 'array' && { width: [100, 200, 300, 400] }),
+ });
+
+ const skeleton = renderSkeleton({
+ wrapperClassName: 'wrapperClassName',
+ dataTestId: 'dataTestId',
+ });
+
+ return (
+ <>
+ {skeleton ? (
+ skeleton
+ ) : (
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
+ incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
+ nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
+ fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
+ culpa qui officia deserunt mollit anim id est laborum.
+
+ )}
+
+ setRows(selected.key)}
+ />
+
+ setWidth(selected.key)}
+ />
+
+ setAlign(selected.key)}
+ />
+
+
+ setVisible((prev) => !prev)}
+ />
+ >
+ );
+});
+```
diff --git a/packages/skeleton/src/hooks/use-skeleton/index.ts b/packages/skeleton/src/hooks/use-skeleton/index.ts
new file mode 100644
index 0000000000..bb1d014d11
--- /dev/null
+++ b/packages/skeleton/src/hooks/use-skeleton/index.ts
@@ -0,0 +1 @@
+export { useSkeleton } from './use-skeleton';
diff --git a/packages/typography/src/hooks/use-skeleton.module.css b/packages/skeleton/src/hooks/use-skeleton/use-skeleton.module.css
similarity index 83%
rename from packages/typography/src/hooks/use-skeleton.module.css
rename to packages/skeleton/src/hooks/use-skeleton/use-skeleton.module.css
index b81272b296..a6bb4ac6d9 100644
--- a/packages/typography/src/hooks/use-skeleton.module.css
+++ b/packages/skeleton/src/hooks/use-skeleton/use-skeleton.module.css
@@ -1,4 +1,4 @@
-@import '../../../vars/src/index.css';
+@import '../../../../vars/src/index.css';
.skeletonText.skeletonText {
border-radius: var(--border-radius-pill);
diff --git a/packages/typography/src/hooks/use-skeleton.test.tsx b/packages/skeleton/src/hooks/use-skeleton/use-skeleton.test.tsx
similarity index 74%
rename from packages/typography/src/hooks/use-skeleton.test.tsx
rename to packages/skeleton/src/hooks/use-skeleton/use-skeleton.test.tsx
index 4f4f0ed7f2..02f33a8a53 100644
--- a/packages/typography/src/hooks/use-skeleton.test.tsx
+++ b/packages/skeleton/src/hooks/use-skeleton/use-skeleton.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { useSkeleton } from './use-skeleton';
-import { TextSkeletonProps } from '../types';
+import { TextSkeletonProps } from '../../types/text-skeleton-props';
import { render } from '@testing-library/react';
const Skeleton = (props: TextSkeletonProps) => {
@@ -39,9 +39,14 @@ describe('useSkeleton tests', () => {
expect((rows[2] as HTMLDivElement).style.width).toBe('');
});
- for (const align of ['left', 'center', 'right'] as const) {
- it(`should set \`${align}\` className`, () => {
- const { container } = render();
- });
- }
+ it.each`
+ align | expectValue
+ ${'left'} | ${`left`}
+ ${'center'} | ${`center`}
+ ${'right'} | ${`right`}
+ `('should set align className $align', ({ align, expectValue }) => {
+ const { container } = render();
+
+ expect(container.firstElementChild).toHaveClass(expectValue);
+ });
});
diff --git a/packages/typography/src/hooks/use-skeleton.tsx b/packages/skeleton/src/hooks/use-skeleton/use-skeleton.tsx
similarity index 96%
rename from packages/typography/src/hooks/use-skeleton.tsx
rename to packages/skeleton/src/hooks/use-skeleton/use-skeleton.tsx
index 0c1cb096af..6c05ae1ada 100644
--- a/packages/typography/src/hooks/use-skeleton.tsx
+++ b/packages/skeleton/src/hooks/use-skeleton/use-skeleton.tsx
@@ -1,10 +1,10 @@
import React, { useRef, useState } from 'react';
import cn from 'classnames';
-import { Skeleton } from '@alfalab/core-components-skeleton';
import { useLayoutEffect_SAFE_FOR_SSR } from '@alfalab/hooks';
-import { TextSkeletonProps } from '../types';
+import { Skeleton } from '../../Component';
+import { TextSkeletonProps } from '../../types/text-skeleton-props';
import styles from './use-skeleton.module.css';
diff --git a/packages/skeleton/src/index.ts b/packages/skeleton/src/index.ts
index e51a5d2440..3d20139197 100644
--- a/packages/skeleton/src/index.ts
+++ b/packages/skeleton/src/index.ts
@@ -1 +1,4 @@
export * from './Component';
+
+export { useSkeleton } from './hooks/use-skeleton';
+export type { TextSkeletonProps } from './types/text-skeleton-props';
diff --git a/packages/skeleton/src/types/text-skeleton-props.ts b/packages/skeleton/src/types/text-skeleton-props.ts
new file mode 100644
index 0000000000..1413734594
--- /dev/null
+++ b/packages/skeleton/src/types/text-skeleton-props.ts
@@ -0,0 +1,23 @@
+type WidthUnit = number | string;
+
+export type TextSkeletonProps = {
+ /**
+ * Кол-во строк текста
+ */
+ rows?: number;
+
+ /**
+ * Ширина строки
+ */
+ width?: WidthUnit | WidthUnit[];
+
+ /**
+ * Выравнивание элементов по горизонтали
+ */
+ align?: 'left' | 'center' | 'right';
+
+ /**
+ * Класс для обертки скелетона
+ */
+ wrapperClassName?: string;
+};
diff --git a/packages/typography/src/hooks/index.ts b/packages/typography/src/hooks/index.ts
deleted file mode 100644
index 84b30c9fca..0000000000
--- a/packages/typography/src/hooks/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './use-skeleton';
diff --git a/packages/typography/src/text/component.tsx b/packages/typography/src/text/component.tsx
index e2a68e1e41..73d6d80db4 100644
--- a/packages/typography/src/text/component.tsx
+++ b/packages/typography/src/text/component.tsx
@@ -2,9 +2,10 @@ import React, { forwardRef, HTMLAttributes } from 'react';
import mergeRefs from 'react-merge-refs';
import cn from 'classnames';
+import { type TextSkeletonProps, useSkeleton } from '@alfalab/core-components-skeleton';
+
import { Color } from '../colors';
-import { useSkeleton } from '../hooks';
-import { TextElementType, TextSkeletonProps } from '../types';
+import { TextElementType } from '../types';
import colors from '../colors.module.css';
import styles from './index.module.css';
diff --git a/packages/typography/src/title/component.tsx b/packages/typography/src/title/component.tsx
index b304368260..b325d60c84 100644
--- a/packages/typography/src/title/component.tsx
+++ b/packages/typography/src/title/component.tsx
@@ -2,9 +2,9 @@ import React, { forwardRef, HTMLAttributes } from 'react';
import mergeRefs from 'react-merge-refs';
import cn from 'classnames';
+import { type TextSkeletonProps, useSkeleton } from '@alfalab/core-components-skeleton';
+
import { Color } from '../colors';
-import { useSkeleton } from '../hooks';
-import { TextSkeletonProps } from '../types';
import { getDefaultWeight } from './utils';
diff --git a/packages/typography/src/types.ts b/packages/typography/src/types.ts
index 3010a07bc2..67db0d2b1c 100644
--- a/packages/typography/src/types.ts
+++ b/packages/typography/src/types.ts
@@ -1,25 +1 @@
export type TextElementType = HTMLParagraphElement | HTMLSpanElement | HTMLDivElement;
-
-type WidthUnit = number | string;
-
-export type TextSkeletonProps = {
- /**
- * Кол-во строк текста
- */
- rows?: number;
-
- /**
- * Ширина строки
- */
- width?: WidthUnit | WidthUnit[];
-
- /**
- * Выравнивание элементов по горизонтали
- */
- align?: 'left' | 'center' | 'right';
-
- /**
- * Класс для обертки скелетона
- */
- wrapperClassName?: string;
-};