-
-
- {props.items.length > 1 && (
-
-
- {props.storyIndex + 1} / {props.items.length}
-
-
- )}
-
- {currentStory && (
-
- {currentStory.title && (
- {currentStory.title}
- )}
- {currentStory.content && (
-
- {currentStory.content}
-
- )}
- {!currentStory.content && currentStory.description && (
-
- {currentStory.description}
-
- )}
- {currentStory.url && (
-
-
- {i18n('label_more')}
-
-
- )}
-
- )}
-
-
- {IndexType.Single === props.indexType ? (
-
- ) : (
-
- {IndexType.Start !== props.indexType && (
-
- )}
- {IndexType.InProccess !== props.indexType && (
-
- )}
- {IndexType.End !== props.indexType && (
-
- )}
-
- )}
- {props.action && }
-
-
-
-
);
diff --git a/src/components/Stories/components/VideoView/VideoView.scss b/src/components/Stories/components/VideoView/VideoView.scss
index 93064a34..064dba36 100644
--- a/src/components/Stories/components/VideoView/VideoView.scss
+++ b/src/components/Stories/components/VideoView/VideoView.scss
@@ -2,9 +2,44 @@
$block: '.#{variables.$ns}stories-video-view';
+$borderRadius: 20px;
+
#{$block} {
- width: auto;
+ width: 100%;
+ height: 100%;
max-width: 100%;
max-height: 100%;
- margin: auto;
+
+ position: relative;
+ overflow: hidden;
+
+ &_style_half-size {
+ border-radius: $borderRadius;
+ }
+
+ &_style_half-size-with-margins {
+ width: calc(100% - 2 * var(--g-spacing-2));
+ height: calc(100% - 2 * var(--g-spacing-2));
+
+ border-radius: $borderRadius;
+ margin: var(--g-spacing-2);
+ }
+
+ &_style_full-size {
+ position: absolute;
+ inset-block-start: 0;
+ inset-inline-start: 0;
+ border-radius: $borderRadius;
+
+ z-index: 0;
+ }
+
+ &__video {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+
+ z-index: 0;
+ }
}
diff --git a/src/components/Stories/components/VideoView/VideoView.tsx b/src/components/Stories/components/VideoView/VideoView.tsx
index 4798a9af..39a7851c 100644
--- a/src/components/Stories/components/VideoView/VideoView.tsx
+++ b/src/components/Stories/components/VideoView/VideoView.tsx
@@ -1,27 +1,31 @@
import {block} from '../../../utils/cn';
-import type {StoriesItemMedia} from '../../types';
+import type {MediaRendererProps} from '../MediaRenderer/MediaRenderer';
import './VideoView.scss';
const b = block('stories-video-view');
-export interface VideoViewProps {
- media: StoriesItemMedia;
-}
+export interface VideoViewProps extends MediaRendererProps {}
+
+export function VideoView({media, style}: VideoViewProps) {
+ if (media.type === 'video') {
+ return (
+
+
+
+ );
+ }
-export function VideoView({media}: VideoViewProps) {
- return media.type === 'video' ? (
-
- ) : null;
+ return null;
}
diff --git a/src/components/Stories/types.ts b/src/components/Stories/types.ts
index df711b98..cbdf4581 100644
--- a/src/components/Stories/types.ts
+++ b/src/components/Stories/types.ts
@@ -1,9 +1,12 @@
import type * as React from 'react';
+import {ButtonProps} from '@gravity-ui/uikit';
+
export type StoriesItemMedia = {url: string} & (
| {
- /** default 'image' */
- type?: 'image';
+ type: 'image';
+ /** url for img srcSet props - apply on Retina display */
+ url2x?: string;
}
| {
type: 'video';
@@ -12,11 +15,31 @@ export type StoriesItemMedia = {url: string} & (
}
);
+export enum StoriesTextBlockStyle {
+ Card = 'card',
+ Transparent = 'transparent',
+}
+
+export enum StoriesMediaBlockStyle {
+ HalfSizeWithMargins = 'half-size-with-margins',
+ HalfSize = 'half-size',
+ FullSize = 'full-size',
+}
+
+export interface StoriesItemTextColorStyles {
+ titleColor?: string;
+ descriptionColor?: string;
+ counterColor?: string;
+}
+
export interface StoriesItem {
title?: string;
- /** @deprecated use `content` property instead */
- description?: string;
content?: React.ReactNode;
+ textColorStyles?: StoriesItemTextColorStyles;
+ textBlockStyle: StoriesTextBlockStyle;
+ mediaBlockStyle: StoriesMediaBlockStyle;
+ firstAction?: ButtonProps;
+ secondAction?: ButtonProps;
/** Url for link "more" */
url?: string;
media?: StoriesItemMedia;
diff --git a/src/components/StoriesGroup/README.md b/src/components/StoriesGroup/README.md
index e5dbea8c..17d8a01f 100644
--- a/src/components/StoriesGroup/README.md
+++ b/src/components/StoriesGroup/README.md
@@ -37,6 +37,7 @@ Component for displaying group of stories. It looks like a carousel in a modal w
'and organizations, settings, help center, search, notifications, favorites.',
url: 'https://yandex.eu',
media: {
+ type: 'image',
url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-2.png',
},
},
@@ -56,6 +57,7 @@ Component for displaying group of stories. It looks like a carousel in a modal w
title: 'New navigation (3)',
description: 'Switch to the new navigation right now',
media: {
+ type: 'image',
url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-4.png',
},
},
diff --git a/src/components/StoriesGroup/StoriesGroup.scss b/src/components/StoriesGroup/StoriesGroup.scss
index 7712f08c..6f2249cb 100644
--- a/src/components/StoriesGroup/StoriesGroup.scss
+++ b/src/components/StoriesGroup/StoriesGroup.scss
@@ -7,6 +7,10 @@ $borderRadius: 20px;
--g-modal-border-radius: #{$borderRadius};
--g-modal-margin: 20px;
+ & .g-modal__content-wrapper {
+ overflow-x: initial;
+ }
+
&__modal-content {
background-color: inherit;
border-radius: $borderRadius;
diff --git a/src/components/StoriesGroup/__stories__/StoriesGroup.stories.tsx b/src/components/StoriesGroup/__stories__/StoriesGroup.stories.tsx
index 216dc8b7..ae85db4e 100644
--- a/src/components/StoriesGroup/__stories__/StoriesGroup.stories.tsx
+++ b/src/components/StoriesGroup/__stories__/StoriesGroup.stories.tsx
@@ -3,8 +3,9 @@ import * as React from 'react';
import {Button} from '@gravity-ui/uikit';
import type {Meta, StoryFn} from '@storybook/react';
-import {StoriesGroup} from '../../StoriesGroup/StoriesGroup';
-import type {StoriesGroupProps} from '../../StoriesGroup/StoriesGroup';
+import {StoriesMediaBlockStyle, StoriesTextBlockStyle} from '../../Stories';
+import {StoriesGroup} from '../StoriesGroup';
+import type {StoriesGroupProps} from '../StoriesGroup';
import type {StoriesGroupItem} from '../types';
export default {
@@ -12,22 +13,27 @@ export default {
component: StoriesGroup,
} as Meta;
-const groups: StoriesGroupItem[] = [
- {
+const baseGroups: StoriesGroupItem[] = new Array(12).fill(0).map((_, index) => {
+ return {
items: [
{
title: 'New navigation',
+ textBlockStyle: StoriesTextBlockStyle.Card,
+ mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
description:
'At the top of the panel is the service navigation for each service. ' +
'Below are common navigation elements: a component for switching between accounts ' +
'and organizations, settings, help center, search, notifications, favorites.',
url: 'https://yandex.eu',
media: {
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-2.png',
+ type: 'image',
+ url: `https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-${(index % 3) + 5}.png`,
},
},
{
title: 'New navigation (2)',
+ textBlockStyle: StoriesTextBlockStyle.Transparent,
+ mediaBlockStyle: StoriesMediaBlockStyle.HalfSizeWithMargins,
description: 'A little more about the new navigation',
media: {
url: 'https://storage.yandexcloud.net/uikit-storybook-assets/sample_960x400_ocean_with_audio.mp4',
@@ -35,18 +41,69 @@ const groups: StoriesGroupItem[] = [
},
},
],
- },
+ };
+});
+
+const groups: StoriesGroupItem[] = [
{
items: [
{
- title: 'New navigation (3)',
- description: 'Switch to the new navigation right now',
+ title: 'New navigation',
+ textBlockStyle: StoriesTextBlockStyle.Card,
+ mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
+ firstAction: {
+ children: 'First button',
+ view: 'action',
+ },
+ secondAction: {
+ children: 'Second button',
+ view: 'normal',
+ },
+ content:
+ 'At the top of the panel is the service navigation for each service. ' +
+ 'Below are common navigation elements: a component for switching between accounts ' +
+ 'and organizations, settings, help center, search, notifications, favorites.',
+ url: 'https://yandex.eu',
media: {
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-4.png',
+ type: 'image',
+ url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-6.png',
+ },
+ },
+ {
+ title: 'New navigation',
+ textBlockStyle: StoriesTextBlockStyle.Transparent,
+ mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
+ content:
+ 'At the top of the panel is the service navigation for each service. ' +
+ 'Below are common navigation elements: a component for switching between accounts ' +
+ 'and organizations, settings, help center, search, notifications, favorites.',
+ url: 'https://yandex.eu',
+ media: {
+ type: 'image',
+ url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-6.png',
+ },
+ },
+ {
+ title: 'New navigation (2)',
+ textBlockStyle: StoriesTextBlockStyle.Transparent,
+ mediaBlockStyle: StoriesMediaBlockStyle.HalfSizeWithMargins,
+ firstAction: {
+ children: 'First button',
+ view: 'action',
+ },
+ secondAction: {
+ children: 'Second button',
+ view: 'normal',
+ },
+ content: 'A little more about the new navigation',
+ media: {
+ url: 'https://storage.yandexcloud.net/uikit-storybook-assets/sample_960x400_ocean_with_audio.mp4',
+ type: 'video',
},
},
],
},
+ ...baseGroups,
];
const DefaultTemplate: StoryFn
= (props: StoriesGroupProps) => {
@@ -81,6 +138,15 @@ export const Default = DefaultTemplate.bind({});
Default.args = {
initialStoryIndex: [0, 0],
open: false,
- groups,
+ groups: groups.slice(0, 2),
};
Default.argTypes = {};
+
+export const MoreGroups = DefaultTemplate.bind({});
+
+MoreGroups.args = {
+ initialStoryIndex: [0, 0],
+ open: false,
+ groups,
+};
+MoreGroups.argTypes = {};
diff --git a/src/components/unstable/Stories/README.md b/src/components/unstable/Stories/README.md
deleted file mode 100644
index db530550..00000000
--- a/src/components/unstable/Stories/README.md
+++ /dev/null
@@ -1,65 +0,0 @@
-## Stories
-
-Component for displaying stories. It looks like a carousel in a modal with given places to display text and media.
-
-### PropTypes
-
-| Property | Type | Required | Default | Description |
-| :------------------ | :-------------- | :------- | :------ | :----------------------------------------------- |
-| open | `Boolean` | ✓ | | Visibility flag |
-| items | `StoriesItem[]` | ✓ | | List of stories to display |
-| initialStoryIndex | `Number` | | 0 | Index of the first story to be displayed |
-| onClose | `Function` | | | Action on close |
-| onPreviousClick | `Function` | | | Action when switching to previous story |
-| onNextClick | `Function` | | | Action when switching to next story |
-| disableOutsideClick | `Boolean` | | true | If `true`, do not close stories on click outside |
-| className | `string` | | | Stories modal class |
-
-### StoriesItem object
-
-| Field | Type | Required | Default | Description |
-| --------------- | ------------------------ | -------- | ------- | ---------------------------------------- |
-| title | `String` | | | Title |
-| description | `String` | | | Main text |
-| url | `String` | | | Link to display more information |
-| media | `StoriesItemMedia` | | | Media content |
-| firstAction | `ButtonProps` | | | Custom action button props |
-| secondAction | `ButtonProps` | | | Custom action button props |
-| textBlockStyle | `StoriesTextBlockStyle` | ✓ | | Props for styling text content in Story |
-| mediaBlockStyle | `StoriesMediaBlockStyle` | ✓ | | Props for styling media content in Story |
-| textColorStyles | `StoriesItemTextStyles` | | | Props for styling text color in Story |
-
-### StoriesItemMedia object
-
-| Field | Type | Required | Default | Description |
-| --------- | -------- | -------- | ------- | -------------------------------------------------- |
-| type | `String` | ✓ | | Content type (`image` or `video`) |
-| url | `String` | ✓ | | File link |
-| url2x | `String` | | | File link for Retina display (only used for image) |
-| posterUrl | `String` | | | Poster URL (only used for video) |
-
-### StoriesItemTextStyles object
-
-| Field | Type | Required | Default | Description |
-| ---------------- | -------- | -------- | ------- | -------------------------------- |
-| titleColor | `String` | | | Apply color to Story title |
-| descriptionColor | `String` | | | Apply color to Story description |
-| counterColor | `String` | | | Apply color to Story counter |
-
-#### Usage example
-
-```jsx harmony
-
-```
diff --git a/src/components/unstable/Stories/Stories.scss b/src/components/unstable/Stories/Stories.scss
deleted file mode 100644
index bb5639a0..00000000
--- a/src/components/unstable/Stories/Stories.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-@use '../variables';
-
-$block: '.#{variables.$ns}stories';
-
-#{$block} {
- --g-modal-border-radius: var(--g-spacing-5);
- --g-modal-margin: var(--g-spacing-5);
-
- & .g-modal__content-wrapper {
- overflow-x: initial;
- }
-
- &__modal-content {
- border-radius: var(--g-spacing-5);
- }
-}
diff --git a/src/components/unstable/Stories/Stories.tsx b/src/components/unstable/Stories/Stories.tsx
deleted file mode 100644
index 3b1130f1..00000000
--- a/src/components/unstable/Stories/Stories.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-import * as React from 'react';
-
-import type {ModalCloseReason} from '@gravity-ui/uikit';
-import {Modal} from '@gravity-ui/uikit';
-
-import {block} from '../utils/cn';
-
-import {IndexType, StoriesLayout} from './components/StoriesLayout/StoriesLayout';
-import {useSyncWithLS} from './hooks';
-import type {StoriesItem} from './types';
-
-import './Stories.scss';
-
-const b = block('stories');
-
-export interface StoriesProps {
- open: boolean;
- items: StoriesItem[];
- onClose?: (
- event: MouseEvent | KeyboardEvent | React.MouseEvent,
- reason: ModalCloseReason | 'closeButtonClick',
- ) => void;
- initialStoryIndex?: number;
- onPreviousClick?: (storyIndex: number) => void;
- onNextClick?: (storyIndex: number) => void;
- disableOutsideClick?: boolean;
- className?: string;
- syncInTabsKey?: string;
-}
-
-export function Stories({
- open,
- onClose,
- items,
- onPreviousClick,
- onNextClick,
- initialStoryIndex = 0,
- disableOutsideClick = true,
- className,
- syncInTabsKey,
-}: StoriesProps) {
- const [storyIndex, setStoryIndex] = React.useState(initialStoryIndex);
-
- const handleClose = React.useCallback>(
- (event, reason) => {
- onClose?.(event, reason);
- },
- [onClose],
- );
-
- const {callback: closeWithLS} = useSyncWithLS>({
- callback: (event, reason) => {
- onClose?.(event, reason);
- },
- uniqueKey: `close-story-${syncInTabsKey}`,
- });
-
- const handleButtonClose = React.useCallback<
- (event: MouseEvent | KeyboardEvent | React.MouseEvent) => void
- >(
- (event) => {
- handleClose(event, 'closeButtonClick');
- if (syncInTabsKey) closeWithLS(event, 'closeButtonClick');
- },
- [handleClose, syncInTabsKey, closeWithLS],
- );
-
- const handleGotoPrevious = React.useCallback(() => {
- setStoryIndex((currentStoryIndex) => {
- if (currentStoryIndex <= 0) {
- return 0;
- }
-
- const newIndex = currentStoryIndex - 1;
- onPreviousClick?.(newIndex);
- return newIndex;
- });
- }, [onPreviousClick]);
-
- const handleGotoNext = React.useCallback(() => {
- setStoryIndex((currentStoryIndex) => {
- if (currentStoryIndex >= items.length - 1) {
- return items.length - 1;
- }
-
- const newIndex = currentStoryIndex + 1;
- onNextClick?.(newIndex);
- return newIndex;
- });
- }, [items, onNextClick]);
-
- if (items.length === 0) {
- return null;
- }
-
- // case when items has changed and index has ceased to be valid
- if (items[storyIndex] === undefined) {
- const correctIndex = items[initialStoryIndex] === undefined ? 0 : initialStoryIndex;
- setStoryIndex(correctIndex);
-
- return null;
- }
-
- const indexType =
- (items.length === 1 && IndexType.Single) ||
- (storyIndex === 0 && IndexType.Start) ||
- (storyIndex === items.length - 1 && IndexType.End) ||
- IndexType.InProccess;
-
- return (
-
-
-
- );
-}
diff --git a/src/components/unstable/Stories/__stories__/Stories.stories.tsx b/src/components/unstable/Stories/__stories__/Stories.stories.tsx
deleted file mode 100644
index b6700ddc..00000000
--- a/src/components/unstable/Stories/__stories__/Stories.stories.tsx
+++ /dev/null
@@ -1,327 +0,0 @@
-import * as React from 'react';
-
-import {Button, Flex, Text} from '@gravity-ui/uikit';
-import type {Meta, StoryFn} from '@storybook/react';
-
-import type {StoriesProps} from '../Stories';
-import {Stories} from '../Stories';
-import type {StoriesItem} from '../types';
-import {StoriesMediaBlockStyle, StoriesTextBlockStyle} from '../types';
-
-export default {
- title: 'Components/unstable/Stories',
- component: Stories,
-} as Meta;
-
-const items: StoriesItem[] = [
- {
- title: 'New navigation',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- firstAction: {
- children: 'First button',
- view: 'action',
- },
- secondAction: {
- children: 'Second button',
- view: 'normal',
- },
- description:
- 'At the top of the panel is the service navigation for each service. ' +
- 'Below are common navigation elements: a component for switching between accounts ' +
- 'and organizations, settings, help center, search, notifications, favorites.' +
- 'At the top of the panel is the service navigation for each service. ' +
- 'Below are common navigation elements: a component for switching between accounts ' +
- 'and organizations, settings, help center, search, notifications, favorites.' +
- 'At the top of the panel is the service navigation for each service. ' +
- 'Below are common navigation elements: a component for switching between accounts ' +
- 'and organizations, settings, help center, search, notifications, favorites.' +
- 'At the top of the panel is the service navigation for each service. ' +
- 'Below are common navigation elements: a component for switching between accounts ' +
- 'and organizations, settings, help center, search, notifications, favorites.' +
- 'At the top of the panel is the service navigation for each service. ' +
- 'Below are common navigation elements: a component for switching between accounts ' +
- 'and organizations, settings, help center, search, notifications, favorites.',
- url: 'https://yandex.eu',
- media: {
- type: 'image',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-6.png',
- },
- },
- {
- title: 'New navigation (2)',
- description: 'A little more about the new navigation',
- textBlockStyle: StoriesTextBlockStyle.Transparent,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- firstAction: {
- children: 'First button',
- view: 'action',
- },
- secondAction: {
- children: 'Second button',
- view: 'normal',
- },
- media: {
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-6.png',
- type: 'image',
- },
- },
- {
- title: 'New navigation (2)',
- description: 'A little more about the new navigation',
- textBlockStyle: StoriesTextBlockStyle.Transparent,
- mediaBlockStyle: StoriesMediaBlockStyle.HalfSize,
- media: {
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/sample_960x400_ocean_with_audio.mp4',
- type: 'video',
- },
- },
- {
- title: 'New navigation (2)',
- description: 'A little more about the new navigation',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- media: {
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/sample_960x400_ocean_with_audio.mp4',
- type: 'video',
- },
- },
- {
- title: 'New navigation (3)',
- description: 'Switch to the new navigation right now',
- textBlockStyle: StoriesTextBlockStyle.Transparent,
- mediaBlockStyle: StoriesMediaBlockStyle.HalfSizeWithMargins,
- media: {
- type: 'image',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-7.png',
- },
- },
-];
-
-const BaseStory = ({description, items}: {description: string; items: StoriesProps['items']}) => {
- const [visible, setVisible] = React.useState(false);
-
- return (
-
- {description}
- {
- setVisible(true);
- }}
- >
- Open
-
-
- {
- setVisible(false);
- }}
- />
-
- );
-};
-
-const DefaultTemplate: StoryFn = () => {
- const itemsFirst: StoriesProps['items'] = [
- {
- title: 'Default story with simple text',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.HalfSizeWithMargins,
- description:
- 'This story has default value for props textBlockStyle = "card" and mediaBlockStyle = "half-size-with-margins" ',
- media: {
- type: 'image',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-7.png',
- },
- },
- {
- title: 'Story without margins in media block',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.HalfSize,
- description:
- 'Props value: textBlockStyle = "card", mediaBlockStyle = "half-size-with-margins" and media type = "image"',
- media: {
- type: 'image',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-7.png',
- },
- },
- {
- title: 'Story with full-size media block',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- description:
- 'Props value: textBlockStyle = "card", mediaBlockStyle = "full-size" and media type = "image"',
- media: {
- type: 'image',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-6.png',
- },
- },
- {
- title: 'Story with full-size media block and transparent text-block',
- textBlockStyle: StoriesTextBlockStyle.Transparent,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- description:
- 'Props value: textBlockStyle = "transparent", mediaBlockStyle = "full-size" and media type = "image"',
- media: {
- type: 'image',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-6.png',
- },
- },
- ];
-
- const itemsSecond: StoriesProps['items'] = [
- {
- title: 'Story with video half-size',
- textBlockStyle: StoriesTextBlockStyle.Transparent,
- mediaBlockStyle: StoriesMediaBlockStyle.HalfSize,
- description:
- 'Props value: textBlockStyle = "transparent", mediaBlockStyle = "half-size" and media type = "video"',
- media: {
- type: 'video',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/sample_960x400_ocean_with_audio.mp4',
- },
- },
- {
- title: 'Story with video half-size with margins and extra actions',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.HalfSizeWithMargins,
- firstAction: {
- children: 'First button',
- view: 'action',
- },
- secondAction: {
- children: 'Second button',
- view: 'normal',
- },
- description:
- 'Props value: textBlockStyle = "card", mediaBlockStyle = "half-size-with-margins" and media type = "video"',
- media: {
- type: 'video',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/sample_960x400_ocean_with_audio.mp4',
- },
- },
- {
- title: 'Story with video full-size',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- description:
- 'Props value: textBlockStyle = "card", mediaBlockStyle = "full-size" and media type = "video"',
- media: {
- type: 'video',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/sample_960x400_ocean_with_audio.mp4',
- },
- },
- ];
-
- const itemsThird: StoriesProps['items'] = [
- {
- title: 'Story with full-size image, extra actions, long text and default text colors',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- firstAction: {
- children: 'First button',
- view: 'action',
- },
- secondAction: {
- children: 'Second button',
- view: 'normal',
- },
- description:
- 'Lorem ipsum odor amet, consectetuer adipiscing elit. Nunc at parturient tristique senectus class duis eget per taciti. Eu rutrum est euismod risus aliquet in. Vehicula habitant nostra enim quis blandit consequat. Blandit ex ut purus; vestibulum accumsan duis? Porttitor accumsan at molestie integer nulla habitant? Egestas urna suscipit eleifend tortor mauris montes vulputate primis?Tempor viverra vitae tempus consectetur egestas? Quam dolor dictumst pellentesque porta; pulvinar conubia placerat risus. Leo at elementum vivamus fermentum erat taciti. Turpis ipsum faucibus primis purus, montes curae eu vel. Lacus metus sagittis dictumst diam libero imperdiet rhoncus neque. Natoque nullam inceptos porttitor integer porttitor nascetur a interdum. Imperdiet scelerisque rutrum congue massa eleifend torquent nisi. Sociosqu libero volutpat nisl orci viverra. Tristique egestas auctor conubia; etiam lectus scelerisque ligula. Magnis ultrices venenatis vivamus hac taciti inceptos leo. Interdum magnis sollicitudin elementum placerat montes. Lacinia platea netus nascetur ornare sociosqu. Inceptos taciti iaculis interdum nisl sodales in eros fermentum. Justo maecenas elementum condimentum feugiat consectetur semper sollicitudin. Primis sodales posuere facilisis donec ipsum efficitur. Faucibus accumsan lectus bibendum rhoncus maecenas, eget aliquam netus. Lectus torquent ut sodales fringilla natoque.',
- media: {
- type: 'image',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-6.png',
- },
- },
- {
- title: 'Story with full-size image, transparent text-block and long content with extra actions and custom text colors',
- textBlockStyle: StoriesTextBlockStyle.Transparent,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- textColorStyles: {
- titleColor: 'var(--g-color-text-brand)',
- counterColor: 'var(--g-color-text-brand)',
- descriptionColor: 'var(--g-color-text-inverted-primary)',
- },
- firstAction: {
- children: 'First button',
- view: 'action',
- },
- secondAction: {
- children: 'Second button',
- view: 'normal-contrast',
- },
- description:
- 'Lorem ipsum odor amet, consectetuer adipiscing elit. Nunc at parturient tristique senectus class duis eget per taciti. Eu rutrum est euismod risus aliquet in. Vehicula habitant nostra enim quis blandit consequat. Blandit ex ut purus; vestibulum accumsan duis? Porttitor accumsan at molestie integer nulla habitant? Egestas urna suscipit eleifend tortor mauris montes vulputate primis?Tempor viverra vitae tempus consectetur egestas? Quam dolor dictumst pellentesque porta; pulvinar conubia placerat risus. Leo at elementum vivamus fermentum erat taciti. Turpis ipsum faucibus primis purus, montes curae eu vel. Lacus metus sagittis dictumst diam libero imperdiet rhoncus neque. Natoque nullam inceptos porttitor integer porttitor nascetur a interdum. Imperdiet scelerisque rutrum congue massa eleifend torquent nisi. Sociosqu libero volutpat nisl orci viverra. Tristique egestas auctor conubia; etiam lectus scelerisque ligula. Magnis ultrices venenatis vivamus hac taciti inceptos leo. Interdum magnis sollicitudin elementum placerat montes. Lacinia platea netus nascetur ornare sociosqu. Inceptos taciti iaculis interdum nisl sodales in eros fermentum. Justo maecenas elementum condimentum feugiat consectetur semper sollicitudin. Primis sodales posuere facilisis donec ipsum efficitur. Faucibus accumsan lectus bibendum rhoncus maecenas, eget aliquam netus. Lectus torquent ut sodales fringilla natoque.',
- media: {
- type: 'image',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-7.png',
- },
- },
- {
- title: 'Story with full-size video, extra actions, long text and default text colors',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- firstAction: {
- children: 'First button',
- view: 'action',
- },
- secondAction: {
- children: 'Second button',
- view: 'normal',
- },
- description:
- 'Lorem ipsum odor amet, consectetuer adipiscing elit. Nunc at parturient tristique senectus class duis eget per taciti. Eu rutrum est euismod risus aliquet in. Vehicula habitant nostra enim quis blandit consequat. Blandit ex ut purus; vestibulum accumsan duis? Porttitor accumsan at molestie integer nulla habitant? Egestas urna suscipit eleifend tortor mauris montes vulputate primis?Tempor viverra vitae tempus consectetur egestas? Quam dolor dictumst pellentesque porta; pulvinar conubia placerat risus. Leo at elementum vivamus fermentum erat taciti. Turpis ipsum faucibus primis purus, montes curae eu vel. Lacus metus sagittis dictumst diam libero imperdiet rhoncus neque. Natoque nullam inceptos porttitor integer porttitor nascetur a interdum. Imperdiet scelerisque rutrum congue massa eleifend torquent nisi. Sociosqu libero volutpat nisl orci viverra. Tristique egestas auctor conubia; etiam lectus scelerisque ligula. Magnis ultrices venenatis vivamus hac taciti inceptos leo. Interdum magnis sollicitudin elementum placerat montes. Lacinia platea netus nascetur ornare sociosqu. Inceptos taciti iaculis interdum nisl sodales in eros fermentum. Justo maecenas elementum condimentum feugiat consectetur semper sollicitudin. Primis sodales posuere facilisis donec ipsum efficitur. Faucibus accumsan lectus bibendum rhoncus maecenas, eget aliquam netus. Lectus torquent ut sodales fringilla natoque.',
- media: {
- type: 'video',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/sample_960x400_ocean_with_audio.mp4',
- },
- },
- ];
-
- const exampleDescription = [
- 'Stories with different text and media block styles',
- 'Stories with video content',
- 'Stories with all features',
- ];
-
- return (
-
- {[itemsFirst, itemsSecond, itemsThird].map((items, index) => {
- return (
-
- );
- })}
-
- );
-};
-export const Default = DefaultTemplate.bind({});
-Default.args = {
- open: false,
- items,
-};
-Default.argTypes = {
- onPreviousClick: {action: 'onPreviousClick'},
- onNextClick: {action: 'onNextClick'},
-};
-
-export const Single = DefaultTemplate.bind({});
-Single.args = {
- open: false,
- items: [items[0]],
-};
-
-export const WithCustomAction = DefaultTemplate.bind({});
-WithCustomAction.args = {
- open: false,
- items: [items[0]],
-};
-
-export const WithSyncInTabs = DefaultTemplate.bind({});
-WithSyncInTabs.args = {
- open: true,
- syncInTabsKey: 'test-story',
- items: [items[0]],
-};
diff --git a/src/components/unstable/Stories/components/ImageView/ImageView.scss b/src/components/unstable/Stories/components/ImageView/ImageView.scss
deleted file mode 100644
index 60c88bcf..00000000
--- a/src/components/unstable/Stories/components/ImageView/ImageView.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-@use '../../../variables';
-
-$block: '.#{variables.$ns}stories-image-view';
-
-$borderRadius: 20px;
-
-#{$block} {
- width: 100%;
- height: 100%;
- max-width: 100%;
- max-height: 100%;
-
- &_style_half-size {
- border-radius: $borderRadius;
- }
-
- &_style_half-size-with-margins {
- width: calc(100% - 2 * var(--g-spacing-2));
- height: calc(100% - 2 * var(--g-spacing-2));
- border-radius: $borderRadius;
-
- margin: var(--g-spacing-2);
- }
-
- &_style_full-size {
- position: absolute;
- border-radius: $borderRadius;
-
- inset-block-start: 0;
- inset-inline-start: 0;
- z-index: 0;
- }
-}
diff --git a/src/components/unstable/Stories/components/ImageView/ImageView.tsx b/src/components/unstable/Stories/components/ImageView/ImageView.tsx
deleted file mode 100644
index 21285095..00000000
--- a/src/components/unstable/Stories/components/ImageView/ImageView.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import {block} from '../../../utils/cn';
-import type {MediaRendererProps} from '../MediaRenderer/MediaRenderer';
-
-import './ImageView.scss';
-
-const b = block('stories-image-view');
-
-export interface ImageViewProps extends MediaRendererProps {}
-
-export function ImageView({media, style}: ImageViewProps) {
- if (media.type === 'image') {
- return (
-
- );
- }
-
- return null;
-}
diff --git a/src/components/unstable/Stories/components/MediaRenderer/MediaRenderer.tsx b/src/components/unstable/Stories/components/MediaRenderer/MediaRenderer.tsx
deleted file mode 100644
index ccccb58e..00000000
--- a/src/components/unstable/Stories/components/MediaRenderer/MediaRenderer.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import {ImageView, VideoView} from '../../components';
-import type {StoriesItemMedia} from '../../types';
-import {StoriesMediaBlockStyle} from '../../types';
-
-export interface MediaRendererProps {
- media: StoriesItemMedia;
- style?: StoriesMediaBlockStyle;
-}
-
-export function MediaRenderer({media, style}: MediaRendererProps) {
- return (media.type || 'image') === 'image' ? (
-
- ) : (
-
- );
-}
diff --git a/src/components/unstable/Stories/components/StoriesLayout/StoriesLayout.scss b/src/components/unstable/Stories/components/StoriesLayout/StoriesLayout.scss
deleted file mode 100644
index 75048a9b..00000000
--- a/src/components/unstable/Stories/components/StoriesLayout/StoriesLayout.scss
+++ /dev/null
@@ -1,128 +0,0 @@
-@use '@gravity-ui/uikit/styles/mixins';
-@use '../../../variables';
-
-$block: '.#{variables.$ns}stories-layout';
-
-$maxWidth: 1280px;
-$maxHeight: 640px;
-$minWidth: 800px;
-$minHeight: 480px;
-$fixedBtnSize: 44px;
-
-$actionBtnZIndex: 50;
-$textContentZIndex: 30;
-
-#{$block} {
- &__wrap-outer {
- height: calc(100vh - 2 * var(--g-modal-margin));
- width: calc(100vw - 2 * var(--g-modal-margin));
- background-color: var(--g-color-base-background);
- display: flex;
- border-radius: var(--g-spacing-5);
- max-width: $maxWidth;
- max-height: $maxHeight;
- min-width: $minWidth;
- min-height: $minHeight;
- }
-
- &__container {
- display: flex;
- box-shadow: 0 8px 20px var(--g-color-sfx-shadow);
- border-radius: var(--g-spacing-5);
- position: relative;
-
- width: 100%;
- height: 100%;
- }
-
- &__left-pane {
- flex-basis: calc(50% - var(--g-spacing-4));
- margin-inline: var(--g-spacing-2);
- margin-block: var(--g-spacing-2);
- padding: var(--g-spacing-8);
-
- display: flex;
- flex-direction: column;
- align-items: stretch;
- flex-shrink: 0;
- box-sizing: border-box;
- z-index: $textContentZIndex;
-
- &_blockStyle_card {
- background-color: var(--g-color-base-background);
- border-radius: var(--g-spacing-3);
- }
-
- &_blockStyle_transparent {
- background-color: transparent;
- }
- }
-
- &__right-pane {
- flex-basis: 50%;
-
- width: 100%;
- height: 100%;
-
- display: flex;
- }
-
- &__counter {
- color: var(--g-color-text-secondary);
- }
-
- &__text-block {
- display: flex;
- flex-grow: 1;
- align-items: flex-start;
- justify-content: flex-start;
- flex-direction: column;
- margin-block-start: var(--g-spacing-10);
- overflow-y: scroll;
- }
-
- &__action-block {
- margin-block-start: var(--g-spacing-8);
- }
-
- &__text-header {
- color: var(--g-color-text-primary);
- }
-
- &__text-content {
- color: var(--g-color-text-complementary);
-
- #{$block}__text-header + & {
- margin-block-start: var(--g-spacing-4);
- }
- }
-
- &__story-link-block {
- margin-block-start: var(--g-spacing-4);
- }
-
- &__navigation-btn {
- --g-border-radius-xl: 50%;
-
- position: absolute;
- inset-block-start: calc(50% - ($fixedBtnSize / 2));
- z-index: $actionBtnZIndex;
-
- &_back {
- inset-inline-start: calc(0px - ($fixedBtnSize / 2));
- }
-
- &_next {
- inset-inline-end: calc(0px - ($fixedBtnSize / 2));
- }
- }
-
- &__close-btn {
- --g-border-radius-xl: 50%;
-
- position: absolute;
- inset-block-start: var(--g-spacing-4);
- inset-inline-end: var(--g-spacing-4);
- z-index: $actionBtnZIndex;
- }
-}
diff --git a/src/components/unstable/Stories/components/StoriesLayout/StoriesLayout.tsx b/src/components/unstable/Stories/components/StoriesLayout/StoriesLayout.tsx
deleted file mode 100644
index 20ac7020..00000000
--- a/src/components/unstable/Stories/components/StoriesLayout/StoriesLayout.tsx
+++ /dev/null
@@ -1,167 +0,0 @@
-import * as React from 'react';
-
-import {ChevronLeft, ChevronRight, Xmark} from '@gravity-ui/icons';
-import {Button, Flex, Icon, Link, Text} from '@gravity-ui/uikit';
-
-import {MediaRenderer} from '..';
-import {block} from '../../../utils/cn';
-import {i18n} from '../../i18n';
-import type {StoriesItem} from '../../types';
-import {StoriesTextBlockStyle} from '../../types';
-
-import './StoriesLayout.scss';
-
-const b = block('stories-layout');
-
-export enum IndexType {
- Start = 1,
- End,
- InProccess,
- Single,
-}
-
-export type StoriesLayoutProps = {
- items: StoriesItem[];
- storyIndex: number;
- indexType: IndexType;
- handleButtonClose: (
- event: MouseEvent | KeyboardEvent | React.MouseEvent,
- ) => void;
- handleGotoPrevious: () => void;
- handleGotoNext: () => void;
-};
-
-// StoriesGroup component also use it
-export const StoriesLayout = ({
- items,
- indexType,
- storyIndex,
- handleButtonClose,
- handleGotoNext,
- handleGotoPrevious,
-}: StoriesLayoutProps) => {
- const currentStory = items[storyIndex];
-
- return (
-
-
-
- {items.length > 1 && (
-
- {storyIndex + 1} / {items.length}
-
- )}
-
- {currentStory && (
-
- {currentStory.title && (
-
- {currentStory.title}
-
- )}
- {currentStory.description && (
-
- {currentStory.description}
-
- )}
- {currentStory.url && (
-
-
- {i18n('label_more')}
-
-
- )}
- {Boolean(currentStory.firstAction || currentStory.secondAction) && (
-
- {currentStory.firstAction && (
-
- )}
- {currentStory.secondAction && (
-
- )}
-
- )}
-
- )}
-
-
-
- {currentStory?.media && (
-
- )}
-
-
-
-
- {indexType !== IndexType.Start && indexType !== IndexType.Single && (
-
-
-
- )}
- {indexType !== IndexType.End && indexType !== IndexType.Single && (
-
-
-
- )}
-
-
- );
-};
diff --git a/src/components/unstable/Stories/components/VideoView/VideoView.scss b/src/components/unstable/Stories/components/VideoView/VideoView.scss
deleted file mode 100644
index 4b3d5d15..00000000
--- a/src/components/unstable/Stories/components/VideoView/VideoView.scss
+++ /dev/null
@@ -1,43 +0,0 @@
-@use '../../../variables';
-
-$block: '.#{variables.$ns}stories-video-view';
-
-#{$block} {
- width: 100%;
- height: 100%;
- max-width: 100%;
- max-height: 100%;
-
- position: relative;
- overflow: hidden;
-
- &_style_half-size {
- border-radius: var(--g-spacing-5);
- }
-
- &_style_half-size-with-margins {
- width: calc(100% - 2 * var(--g-spacing-2));
- height: calc(100% - 2 * var(--g-spacing-2));
-
- border-radius: var(--g-spacing-5);
- margin: var(--g-spacing-2);
- }
-
- &_style_full-size {
- position: absolute;
- inset-block-start: 0;
- inset-inline-start: 0;
- border-radius: var(--g-spacing-5);
-
- z-index: 0;
- }
-
- &__video {
- position: absolute;
- width: 100%;
- height: 100%;
- object-fit: cover;
-
- z-index: 0;
- }
-}
diff --git a/src/components/unstable/Stories/components/VideoView/VideoView.tsx b/src/components/unstable/Stories/components/VideoView/VideoView.tsx
deleted file mode 100644
index 39a7851c..00000000
--- a/src/components/unstable/Stories/components/VideoView/VideoView.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import {block} from '../../../utils/cn';
-import type {MediaRendererProps} from '../MediaRenderer/MediaRenderer';
-
-import './VideoView.scss';
-
-const b = block('stories-video-view');
-
-export interface VideoViewProps extends MediaRendererProps {}
-
-export function VideoView({media, style}: VideoViewProps) {
- if (media.type === 'video') {
- return (
-
-
-
- );
- }
-
- return null;
-}
diff --git a/src/components/unstable/Stories/components/index.ts b/src/components/unstable/Stories/components/index.ts
deleted file mode 100644
index a5c6628f..00000000
--- a/src/components/unstable/Stories/components/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './ImageView/ImageView';
-export * from './VideoView/VideoView';
-export * from './MediaRenderer/MediaRenderer';
diff --git a/src/components/unstable/Stories/hooks/index.ts b/src/components/unstable/Stories/hooks/index.ts
deleted file mode 100644
index b4312444..00000000
--- a/src/components/unstable/Stories/hooks/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './useSyncWithLS';
diff --git a/src/components/unstable/Stories/hooks/useSyncWithLS/README.md b/src/components/unstable/Stories/hooks/useSyncWithLS/README.md
deleted file mode 100644
index a9ee3ce0..00000000
--- a/src/components/unstable/Stories/hooks/useSyncWithLS/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-# useSyncWithLS
-
-
-
-```tsx
-import {useSyncWithLS} from '@gravity-ui/components';
-```
-
-The `useSyncWithLS` hook executes callback when value changed in Local Storage
-
-## Properties
-
-| Name | Description | Type | Default |
-| :----------------------- | :----------------------------------------------------------- | :------------: | :---------: |
-| callback | Callback function called when key in local storage triggered | `VoidFunction` | |
-| dataSourceName | Name for data source of keys | `string` | 'sync-tabs' |
-| uniqueKey | Key in local storage for handle | `string` | |
-| disableActiveTabCallback | Disable callback in tab that triggers local storage | `boolean` | 'false' |
diff --git a/src/components/unstable/Stories/hooks/useSyncWithLS/index.ts b/src/components/unstable/Stories/hooks/useSyncWithLS/index.ts
deleted file mode 100644
index d8481236..00000000
--- a/src/components/unstable/Stories/hooks/useSyncWithLS/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export {useSyncWithLS} from './useSyncWithLS';
-export type {UseSyncWithLSInputProps, UseSyncWithLSOutputProps} from './useSyncWithLS';
diff --git a/src/components/unstable/Stories/hooks/useSyncWithLS/useSyncWithLS.ts b/src/components/unstable/Stories/hooks/useSyncWithLS/useSyncWithLS.ts
deleted file mode 100644
index 27de2850..00000000
--- a/src/components/unstable/Stories/hooks/useSyncWithLS/useSyncWithLS.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import * as React from 'react';
-
-export type UseSyncWithLSInputProps = {
- callback: T;
- uniqueKey: string;
- dataSourceName?: string;
- disableActiveTabCallback?: boolean;
-};
-export type UseSyncWithLSOutputProps = {callback: (...args: unknown[]) => void};
-
-export const useSyncWithLS = ({
- dataSourceName = 'sync-tabs',
- callback,
- uniqueKey,
- disableActiveTabCallback = false,
-}: UseSyncWithLSInputProps): UseSyncWithLSOutputProps => {
- const key = `${dataSourceName}.${uniqueKey}`;
-
- const handler = (event: StorageEvent) => {
- if (event.key === key && event.newValue) {
- return callback();
- }
- return undefined;
- };
-
- React.useEffect(() => {
- // Action in non-active tab
- window.addEventListener('storage', handler);
-
- return () => {
- window.removeEventListener('storage', handler);
- localStorage.removeItem(key);
- };
- });
-
- return {
- callback: React.useCallback(() => {
- localStorage.setItem(key, String(Number(localStorage.getItem(key) || '0') + 1));
-
- if (disableActiveTabCallback) {
- return undefined;
- }
- return callback();
- }, [key, disableActiveTabCallback, callback]),
- };
-};
diff --git a/src/components/unstable/Stories/i18n/en.json b/src/components/unstable/Stories/i18n/en.json
deleted file mode 100644
index c23bb920..00000000
--- a/src/components/unstable/Stories/i18n/en.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "label_back": "Back",
- "label_next": "Next",
- "label_close": "Close",
- "label_more": "More"
-}
diff --git a/src/components/unstable/Stories/i18n/index.ts b/src/components/unstable/Stories/i18n/index.ts
deleted file mode 100644
index a7574679..00000000
--- a/src/components/unstable/Stories/i18n/index.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import {addComponentKeysets} from '@gravity-ui/uikit/i18n';
-
-import {UNSTABLE_NAMESPACE} from '../../../utils/cn';
-
-import en from './en.json';
-import ru from './ru.json';
-
-export const i18n = addComponentKeysets({en, ru}, `${UNSTABLE_NAMESPACE}stories`);
diff --git a/src/components/unstable/Stories/i18n/ru.json b/src/components/unstable/Stories/i18n/ru.json
deleted file mode 100644
index 7c082d74..00000000
--- a/src/components/unstable/Stories/i18n/ru.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "label_back": "Назад",
- "label_next": "Дальше",
- "label_close": "Закрыть",
- "label_more": "Подробнее"
-}
diff --git a/src/components/unstable/Stories/index.ts b/src/components/unstable/Stories/index.ts
deleted file mode 100644
index 066d3171..00000000
--- a/src/components/unstable/Stories/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './Stories';
-export * from './hooks';
-export * from './types';
diff --git a/src/components/unstable/Stories/types.ts b/src/components/unstable/Stories/types.ts
deleted file mode 100644
index b9bc99ee..00000000
--- a/src/components/unstable/Stories/types.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import {ButtonProps} from '@gravity-ui/uikit';
-
-export type StoriesItemMedia = {url: string} & (
- | {
- type: 'image';
- /** url for img srcSet props - apply on Retina display */
- url2x?: string;
- }
- | {
- type: 'video';
- /** A URL for an image to be shown while the video is downloading */
- posterUrl?: string;
- }
-);
-
-export enum StoriesTextBlockStyle {
- Card = 'card',
- Transparent = 'transparent',
-}
-
-export enum StoriesMediaBlockStyle {
- HalfSizeWithMargins = 'half-size-with-margins',
- HalfSize = 'half-size',
- FullSize = 'full-size',
-}
-
-export interface StoriesItemTextColorStyles {
- titleColor?: string;
- descriptionColor?: string;
- counterColor?: string;
-}
-
-export interface StoriesItem {
- title?: string;
- description?: string;
- textColorStyles?: StoriesItemTextColorStyles;
- textBlockStyle: StoriesTextBlockStyle;
- mediaBlockStyle: StoriesMediaBlockStyle;
- firstAction?: ButtonProps;
- secondAction?: ButtonProps;
- /** Url for link "more" */
- url?: string;
- media?: StoriesItemMedia;
-}
diff --git a/src/components/unstable/StoriesGroup/README.md b/src/components/unstable/StoriesGroup/README.md
deleted file mode 100644
index 17d8a01f..00000000
--- a/src/components/unstable/StoriesGroup/README.md
+++ /dev/null
@@ -1,68 +0,0 @@
-## StoriesGroup
-
-Component for displaying group of stories. It looks like a carousel in a modal with given places to display text and media.
-
-### PropTypes
-
-| Property | Type | Required | Default | Description |
-| :------------------ | :---------------------------------------- | :------- | :------ | :--------------------------------------------------------- |
-| open | `Boolean` | ✓ | | Visibility flag |
-| groups | `StoriesGroupItem[]` | ✓ | | List of groups of stories to display |
-| initialStoryIndex | `[groupIndex: Number, itemIndex: Number]` | | [0, 0] | Index of the first story to be displayed |
-| onClose | `Function` | | | Action on close |
-| onItemSelect | `Function` | | | Action when switching to story |
-| disableOutsideClick | `Boolean` | | true | If `true`, do not close stories on click outside |
-| maxSliderItemsCount | `Number` | | 12 | Positive maximum number of slider thumbnails on the screen |
-
-### StoriesGroupItem object
-
-| Field | Type | Required | Default | Description |
-| -------------- | ------------------------------------------------------------------------------------------------------------------ | -------- | ------- | ------------------------------------------------------------------------------------------ |
-| items | `[StoriesItem](https://github.com/gravity-ui/uikit/tree/main/src/components/Stories#storiesitem-object)[]` | | | Array of items as in `Stories` component |
-| thumbnailMedia | `[StoriesItemMedia](https://github.com/gravity-ui/uikit/tree/main/src/components/Stories#storiesitemmedia-object)` | | | Media content for preview, otherwise first StoriesItem.media from StoriesItem will be used |
-
-#### Usage example
-
-```jsx harmony
-
-```
diff --git a/src/components/unstable/StoriesGroup/StoriesGroup.scss b/src/components/unstable/StoriesGroup/StoriesGroup.scss
deleted file mode 100644
index 6f2249cb..00000000
--- a/src/components/unstable/StoriesGroup/StoriesGroup.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-@use '../variables';
-
-$block: '.#{variables.$ns}stories-group';
-$borderRadius: 20px;
-
-#{$block} {
- --g-modal-border-radius: #{$borderRadius};
- --g-modal-margin: 20px;
-
- & .g-modal__content-wrapper {
- overflow-x: initial;
- }
-
- &__modal-content {
- background-color: inherit;
- border-radius: $borderRadius;
- }
-}
diff --git a/src/components/unstable/StoriesGroup/StoriesGroup.tsx b/src/components/unstable/StoriesGroup/StoriesGroup.tsx
deleted file mode 100644
index 5650f825..00000000
--- a/src/components/unstable/StoriesGroup/StoriesGroup.tsx
+++ /dev/null
@@ -1,178 +0,0 @@
-import * as React from 'react';
-
-import {Modal} from '@gravity-ui/uikit';
-import type {ModalCloseReason} from '@gravity-ui/uikit';
-
-import {IndexType, StoriesLayout} from '../Stories/components/StoriesLayout/StoriesLayout';
-import {block} from '../utils/cn';
-
-import {StoriesPreview} from './components';
-import type {StoriesGroupItem} from './types';
-
-import './StoriesGroup.scss';
-
-const DEFAULT_MAX_SLIDER_ITEMS_COUNT = 12;
-
-const b = block('stories-group');
-
-export interface StoriesGroupProps {
- open: boolean;
- groups: StoriesGroupItem[];
- initialStoryIndex?: [groupIndex: number, itemIndex: number];
- disableOutsideClick?: boolean;
- maxSliderItemsCount?: number;
- onClose?: (
- event: MouseEvent | KeyboardEvent | React.MouseEvent,
- reason: ModalCloseReason | 'closeButtonClick',
- ) => void;
- onItemSelect?: (
- itemIndexes: [groupIndex: number, itemIndex: number],
- selectedFromThumbnail: boolean,
- ) => void;
-}
-
-// eslint-disable-next-line complexity
-export const StoriesGroup = ({
- open,
- groups,
- onItemSelect,
- disableOutsideClick = true,
- initialStoryIndex = [0, 0],
- maxSliderItemsCount = DEFAULT_MAX_SLIDER_ITEMS_COUNT,
- onClose,
-}: StoriesGroupProps) => {
- const [[groupIndex, itemIndex], setStoryIndex] = React.useState(initialStoryIndex);
-
- const handleClose = React.useCallback>(
- (event, reason) => {
- onClose?.(event, reason);
- },
- [onClose],
- );
-
- const handleButtonClose = React.useCallback<
- (event: MouseEvent | KeyboardEvent | React.MouseEvent) => void
- >(
- (event) => {
- handleClose(event, 'closeButtonClick');
- },
- [handleClose],
- );
-
- const handleGotoPrevious = React.useCallback(() => {
- setStoryIndex((prevState) => {
- const [currentGroupIndex, currentItemIndex] = prevState;
-
- if (currentItemIndex > 0) {
- const newState: [number, number] = [currentGroupIndex, currentItemIndex - 1];
-
- onItemSelect?.(newState, false);
- return newState;
- }
-
- // try to find previous valid group
- for (let i = currentGroupIndex - 1; i >= 0; --i) {
- if (groups[i].items.length !== 0) {
- const newState: [number, number] = [i, groups[i].items.length - 1];
-
- onItemSelect?.(newState, false);
- return newState;
- }
- }
-
- return prevState;
- });
- }, [groups, onItemSelect]);
-
- const handleGotoNext = React.useCallback(() => {
- setStoryIndex((prevState) => {
- const [currentGroupIndex, currentItemIndex] = prevState;
-
- if (currentItemIndex < groups[currentGroupIndex]?.items.length - 1) {
- const newState: [number, number] = [currentGroupIndex, currentItemIndex + 1];
- onItemSelect?.(newState, false);
- return newState;
- }
-
- // try to find next valid group
- for (let i = currentGroupIndex + 1; i < groups.length; ++i) {
- if (groups[i].items.length !== 0) {
- const newState: [number, number] = [i, 0];
- onItemSelect?.(newState, false);
- return newState;
- }
- }
-
- return prevState;
- });
- }, [groups, onItemSelect]);
-
- const onGroupSelect = React.useCallback(
- (newGroupIndex: number) => {
- setStoryIndex([newGroupIndex, 0]);
- onItemSelect?.([newGroupIndex, 0], true);
- },
- [onItemSelect],
- );
-
- if (groups.length === 0) {
- return null;
- }
-
- const currentGroup = groups[groupIndex];
- const currentItems = currentGroup?.items || [];
-
- // case when groups has changed and indexs has ceased to be valid
- if (currentGroup === undefined || currentItems[itemIndex] === undefined) {
- if (
- groups[initialStoryIndex[0]] &&
- groups[initialStoryIndex[0]].items[initialStoryIndex[1]]
- ) {
- setStoryIndex(initialStoryIndex);
- } else {
- // try to find first valid index
- for (let i = 0; i < groups.length; ++i) {
- if (groups[i] && groups[i].items.length !== 0) {
- setStoryIndex([i, 0]);
- break;
- }
- }
- }
-
- return null;
- }
-
- const indexType =
- (groups.length === 1 && currentItems.length === 1 && IndexType.Single) ||
- (groupIndex === 0 && itemIndex === 0 && IndexType.Start) ||
- (groupIndex === groups.length - 1 &&
- itemIndex === currentItems.length - 1 &&
- IndexType.End) ||
- IndexType.InProccess;
-
- return (
-
- 0 ? maxSliderItemsCount : 1}
- groups={groups}
- groupIndex={groupIndex}
- onGroupSelect={onGroupSelect}
- onClose={disableOutsideClick ? undefined : handleClose}
- />
-
-
- );
-};
diff --git a/src/components/unstable/StoriesGroup/__stories__/StoriesGroup.stories.tsx b/src/components/unstable/StoriesGroup/__stories__/StoriesGroup.stories.tsx
deleted file mode 100644
index 240ca26a..00000000
--- a/src/components/unstable/StoriesGroup/__stories__/StoriesGroup.stories.tsx
+++ /dev/null
@@ -1,152 +0,0 @@
-import * as React from 'react';
-
-import {Button} from '@gravity-ui/uikit';
-import type {Meta, StoryFn} from '@storybook/react';
-
-import {StoriesMediaBlockStyle, StoriesTextBlockStyle} from '../../Stories';
-import {StoriesGroup} from '../StoriesGroup';
-import type {StoriesGroupProps} from '../StoriesGroup';
-import type {StoriesGroupItem} from '../types';
-
-export default {
- title: 'Components/unstable/StoriesGroup',
- component: StoriesGroup,
-} as Meta;
-
-const baseGroups: StoriesGroupItem[] = new Array(12).fill(0).map((_, index) => {
- return {
- items: [
- {
- title: 'New navigation',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- description:
- 'At the top of the panel is the service navigation for each service. ' +
- 'Below are common navigation elements: a component for switching between accounts ' +
- 'and organizations, settings, help center, search, notifications, favorites.',
- url: 'https://yandex.eu',
- media: {
- type: 'image',
- url: `https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-${(index % 3) + 5}.png`,
- },
- },
- {
- title: 'New navigation (2)',
- textBlockStyle: StoriesTextBlockStyle.Transparent,
- mediaBlockStyle: StoriesMediaBlockStyle.HalfSizeWithMargins,
- description: 'A little more about the new navigation',
- media: {
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/sample_960x400_ocean_with_audio.mp4',
- type: 'video',
- },
- },
- ],
- };
-});
-
-const groups: StoriesGroupItem[] = [
- {
- items: [
- {
- title: 'New navigation',
- textBlockStyle: StoriesTextBlockStyle.Card,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- firstAction: {
- children: 'First button',
- view: 'action',
- },
- secondAction: {
- children: 'Second button',
- view: 'normal',
- },
- description:
- 'At the top of the panel is the service navigation for each service. ' +
- 'Below are common navigation elements: a component for switching between accounts ' +
- 'and organizations, settings, help center, search, notifications, favorites.',
- url: 'https://yandex.eu',
- media: {
- type: 'image',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-6.png',
- },
- },
- {
- title: 'New navigation',
- textBlockStyle: StoriesTextBlockStyle.Transparent,
- mediaBlockStyle: StoriesMediaBlockStyle.FullSize,
- description:
- 'At the top of the panel is the service navigation for each service. ' +
- 'Below are common navigation elements: a component for switching between accounts ' +
- 'and organizations, settings, help center, search, notifications, favorites.',
- url: 'https://yandex.eu',
- media: {
- type: 'image',
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/story-picture-6.png',
- },
- },
- {
- title: 'New navigation (2)',
- textBlockStyle: StoriesTextBlockStyle.Transparent,
- mediaBlockStyle: StoriesMediaBlockStyle.HalfSizeWithMargins,
- firstAction: {
- children: 'First button',
- view: 'action',
- },
- secondAction: {
- children: 'Second button',
- view: 'normal',
- },
- description: 'A little more about the new navigation',
- media: {
- url: 'https://storage.yandexcloud.net/uikit-storybook-assets/sample_960x400_ocean_with_audio.mp4',
- type: 'video',
- },
- },
- ],
- },
- ...baseGroups,
-];
-
-const DefaultTemplate: StoryFn = (props: StoriesGroupProps) => {
- const [visible, setVisible] = React.useState(props.open);
-
- React.useEffect(() => {
- setVisible(props.open);
- }, [props.open]);
-
- return (
-
-
- {
- setVisible(true);
- }}
- >
- Open
-
-
- {
- setVisible(false);
- }}
- />
-
- );
-};
-export const Default = DefaultTemplate.bind({});
-Default.args = {
- initialStoryIndex: [0, 0],
- open: false,
- groups: groups.slice(0, 2),
-};
-Default.argTypes = {};
-
-export const MoreGroups = DefaultTemplate.bind({});
-
-MoreGroups.args = {
- initialStoryIndex: [0, 0],
- open: false,
- groups,
-};
-MoreGroups.argTypes = {};
diff --git a/src/components/unstable/StoriesGroup/components/StoriesPreview/StoriesPreview.scss b/src/components/unstable/StoriesGroup/components/StoriesPreview/StoriesPreview.scss
deleted file mode 100644
index cb9e00c7..00000000
--- a/src/components/unstable/StoriesGroup/components/StoriesPreview/StoriesPreview.scss
+++ /dev/null
@@ -1,65 +0,0 @@
-@use '../../../variables';
-
-$block: '.#{variables.$ns}stories-group-preview';
-
-#{$block} {
- user-select: none;
- padding-block-end: 16px;
-
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 8px;
-
- &__slider-preview-list-wrapper {
- display: flex;
- gap: 8px;
- }
-
- &__stories-preview-item {
- $disabled: #{&}_disabled;
-
- position: relative;
- box-sizing: border-box;
-
- display: flex;
- align-items: center;
- justify-content: center;
-
- cursor: pointer;
-
- overflow: hidden;
- width: 40px;
- height: 40px;
- border-radius: 8px;
-
- background-color: var(--g-color-base-background);
-
- &::after {
- content: '';
- position: absolute;
- inset-block-start: 0;
- inset-inline-start: 0;
-
- background-color: var(--g-color-sfx-shadow);
- width: 40px;
- height: 40px;
- }
-
- &_active,
- &:hover:not(#{$disabled}) {
- &::after {
- display: none;
- }
- }
-
- &_active {
- border: 2px solid var(--g-color-line-brand);
- }
- }
-
- &__slider-button-wrapper {
- width: 28px;
- height: 28px;
- }
-}
diff --git a/src/components/unstable/StoriesGroup/components/StoriesPreview/StoriesPreview.tsx b/src/components/unstable/StoriesGroup/components/StoriesPreview/StoriesPreview.tsx
deleted file mode 100644
index 6b110fbe..00000000
--- a/src/components/unstable/StoriesGroup/components/StoriesPreview/StoriesPreview.tsx
+++ /dev/null
@@ -1,220 +0,0 @@
-import * as React from 'react';
-
-import {ChevronLeft, ChevronRight} from '@gravity-ui/icons';
-import {Button, Icon} from '@gravity-ui/uikit';
-import type {ButtonButtonProps, ModalCloseReason} from '@gravity-ui/uikit';
-
-import {MediaRenderer} from '../../../Stories/components';
-import type {StoriesItemMedia} from '../../../Stories/types';
-import {block} from '../../../utils/cn';
-import type {StoriesGroupItem} from '../../types';
-
-import './StoriesPreview.scss';
-
-const PREVIEW_ITEM_SIZE = 40;
-const PREVIEW_LIST_GAP = 8;
-
-const b = block('stories-group-preview');
-
-type PreviewItemProps = {
- groupIndex: number;
-
- active: boolean;
- disabled: boolean;
-
- media?: StoriesItemMedia;
- onSelectGroup?: (groupIndex: number) => void;
-};
-const PreviewItem = ({active, disabled, groupIndex, media, onSelectGroup}: PreviewItemProps) => {
- const onClick = React.useCallback>(
- (event) => {
- event.preventDefault();
- event.stopPropagation();
-
- onSelectGroup?.(groupIndex);
- },
- [onSelectGroup, groupIndex],
- );
-
- return (
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
-
- {media && }
-
- );
-};
-
-type StoriesPreviewListProps = {
- groups: StoriesGroupItem[];
- groupIndex: number;
- onGroupSelect: (groupIndex: number) => void;
- offset?: number;
-};
-const StoriesPreviewList = ({
- groupIndex,
- groups,
- onGroupSelect,
- offset = 0,
-}: StoriesPreviewListProps) => {
- return (
-
- {groups.map(({thumbnailMedia, items}, i) => {
- const media = thumbnailMedia || items[0]?.media;
- const currentGroupIndex = offset + i;
-
- return (
-
- );
- })}
-
- );
-};
-
-type StoriesPreviewListWithSliderProps = {
- groups: StoriesGroupItem[];
- groupIndex: number;
- onGroupSelect: (groupIndex: number) => void;
- maxSliderItemsCount: number;
-};
-const StoriesPreviewListWithSlider = ({
- groupIndex,
- groups,
- onGroupSelect,
- maxSliderItemsCount,
-}: StoriesPreviewListWithSliderProps) => {
- const [offset, setOffset] = React.useState(0);
-
- React.useEffect(() => {
- const currentOffset = maxSliderItemsCount * Math.floor(groupIndex / maxSliderItemsCount);
- setOffset(currentOffset);
- }, [groupIndex, maxSliderItemsCount]);
-
- const setPreviewOffset = React.useCallback>(
- (event) => {
- event.preventDefault();
- event.stopPropagation();
-
- setOffset((currentOffset) => {
- return currentOffset - maxSliderItemsCount;
- });
- },
- [maxSliderItemsCount],
- );
-
- const setNextOffset = React.useCallback>(
- (event) => {
- event.preventDefault();
- event.stopPropagation();
-
- setOffset((currentOffset) => {
- return currentOffset + maxSliderItemsCount;
- });
- },
- [maxSliderItemsCount],
- );
-
- return (
-
- {groups.length > maxSliderItemsCount && (
-
- {offset !== 0 && (
-
-
-
- )}
-
- )}
-
-
-
- {groups.length > maxSliderItemsCount && (
-
- {offset < groups.length - maxSliderItemsCount && (
-
-
-
- )}
-
- )}
-
- );
-};
-
-export type StoriesPreviewProps = {
- groups: StoriesGroupItem[];
- groupIndex: number;
- onGroupSelect: (groupIndex: number) => void;
- maxSliderItemsCount: number;
- onClose?: (
- event: MouseEvent | KeyboardEvent | React.MouseEvent,
- reason: ModalCloseReason,
- ) => void;
-};
-
-// all onClick handlers of StoriesPreview childrens should have preventDefault() and stopPropagation() callings
-
-export const StoriesPreview = ({
- groups,
- groupIndex,
- onGroupSelect,
- maxSliderItemsCount,
- onClose,
-}: StoriesPreviewProps) => {
- const handleClose = React.useCallback>(
- (event) => {
- onClose?.(event, 'outsideClick');
- },
- [onClose],
- );
-
- if (groups.length < maxSliderItemsCount) {
- return (
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
-
-
-
- );
- }
-
- return (
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
-
-
-
- );
-};
diff --git a/src/components/unstable/StoriesGroup/components/index.ts b/src/components/unstable/StoriesGroup/components/index.ts
deleted file mode 100644
index ed721757..00000000
--- a/src/components/unstable/StoriesGroup/components/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './StoriesPreview/StoriesPreview';
diff --git a/src/components/unstable/StoriesGroup/index.ts b/src/components/unstable/StoriesGroup/index.ts
deleted file mode 100644
index 94e68de7..00000000
--- a/src/components/unstable/StoriesGroup/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './StoriesGroup';
-export * from './types';
diff --git a/src/components/unstable/StoriesGroup/types.ts b/src/components/unstable/StoriesGroup/types.ts
deleted file mode 100644
index 48a4f2ee..00000000
--- a/src/components/unstable/StoriesGroup/types.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import type {StoriesItem, StoriesItemMedia} from '../Stories/types';
-
-export interface StoriesGroupItem {
- items: StoriesItem[];
- /** Custom image for preview, otherwise first StoriesItem.media from StoriesItem will be used */
- thumbnailMedia?: StoriesItemMedia;
-}
diff --git a/src/components/unstable/index.ts b/src/components/unstable/index.ts
deleted file mode 100644
index bd36023a..00000000
--- a/src/components/unstable/index.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-/* eslint-disable camelcase */
-export {
- type StoriesItemMedia as unstable_StoriesItemMedia,
- type StoriesItem as unstable_StoriesItem,
- type StoriesProps as unstable_StoriesProps,
- Stories as unstable_Stories,
- useSyncWithLS as unstable_useSyncWithLS,
- StoriesMediaBlockStyle,
- StoriesTextBlockStyle,
- StoriesItemTextColorStyles,
-} from './Stories';
-
-export {
- type StoriesGroupItem,
- type StoriesGroupProps,
- StoriesGroup as unstable_StoriesGroup,
-} from './StoriesGroup';
diff --git a/src/components/unstable/utils/cn.ts b/src/components/unstable/utils/cn.ts
deleted file mode 100644
index ddad9f31..00000000
--- a/src/components/unstable/utils/cn.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import {withNaming} from '@bem-react/classname';
-
-export type CnMods = Record;
-
-export const NAMESPACE = 'gcu-';
-
-export const cn = withNaming({e: '__', m: '_', v: '_'});
-export const block = withNaming({n: NAMESPACE, e: '__', m: '_', v: '_'});
diff --git a/src/components/unstable/variables.scss b/src/components/unstable/variables.scss
deleted file mode 100644
index c3925b57..00000000
--- a/src/components/unstable/variables.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-$ns: 'gcu-';
-
-// Sizes
-$tinyOffset: 5px;
-$inlineOffset: 12px;
-$regularOffset: 16px;
-$normalOffset: 20px;
-$mediumOffset: 30px;
-$bigOffset: 40px;
-$doubleInlineOffset: $inlineOffset * 2;
-$doubleRegularOffset: $regularOffset * 2;
-$smallOffset: calc(#{$normalOffset} * 0.5);
-$microOffset: calc(#{$regularOffset} * 0.5);
-$nanoOffset: calc(#{$microOffset} * 0.5);
diff --git a/src/components/utils/cn.ts b/src/components/utils/cn.ts
index cc6a4af6..d6861921 100644
--- a/src/components/utils/cn.ts
+++ b/src/components/utils/cn.ts
@@ -3,7 +3,6 @@ import {withNaming} from '@bem-react/classname';
export type CnMods = Record;
export const NAMESPACE = 'gc-';
-export const UNSTABLE_NAMESPACE = 'gcu-';
export const cn = withNaming({e: '__', m: '_', v: '_'});
export const block = withNaming({n: NAMESPACE, e: '__', m: '_', v: '_'});