diff --git a/memory-bank/usage/map.md b/memory-bank/usage/map.md index 5d4cfa39a..90c037c1e 100644 --- a/memory-bank/usage/map.md +++ b/memory-bank/usage/map.md @@ -95,6 +95,58 @@ graph TD - **Properties**: - `type`: MapType enum value (Yandex or Google) +## MapBlockProps Interface + +Map blocks use the same enhanced title support as Media blocks through MediaContentProps: + +- **Description**: Map blocks extend MediaBaseBlockProps, which includes MediaContentProps with enhanced title support. +- **File**: `src/models/constructor-items/blocks.ts` +- **Key Properties**: + - `title`: TitleItemBaseProps | string - Enhanced title support with object or string format + - `description`: string - Optional description text with YFM support + - `map`: MapProps - Map configuration (required) + - Inherits all MediaContentProps properties: `additionalInfo`, `links`, `buttons`, `size`, `list`, `controlPosition` + +### Enhanced Title Support for Maps + +Map blocks support the same enhanced title functionality as Media blocks: + +**Usage Examples**: + +```typescript +// Map with custom title size +{ + type: 'map-block', + title: { + text: 'Our Location', + textSize: 'l' + }, + map: { /* map config */ } +} + +// Map with clickable title +{ + type: 'map-block', + title: { + text: 'View on Google Maps', + url: 'https://maps.google.com/...', + urlTitle: 'Open in Google Maps' + }, + map: { /* map config */ } +} + +// Map with custom content +{ + type: 'map-block', + title: { + text: 'Office Location', + custom: 'πŸ“', + textSize: 'm' + }, + map: { /* map config */ } +} +``` + ## Usage Patterns > **Note**: In the code examples below, `b()` is a utility function used throughout the page-constructor project for BEM (Block Element Modifier) class naming. It generates CSS class names following the BEM methodology, making the code more maintainable and consistent. @@ -249,6 +301,7 @@ The Map component includes Storybook stories demonstrating: - Yandex Maps integration with coordinate-based markers - Different zoom levels and configurations - API key input for development/testing +- Enhanced title support Stories are located in `src/components/Map/__stories__/Map.stories.tsx` with example data in `data.json`. diff --git a/memory-bank/usage/media.md b/memory-bank/usage/media.md index 0d2361082..874af2ece 100644 --- a/memory-bank/usage/media.md +++ b/memory-bank/usage/media.md @@ -96,6 +96,69 @@ graph TD - Supports `color` for background color - Includes `videoMicrodata` for SEO structured data +### MediaContentProps Interface + +- **Description**: Defines the content properties for Media and Map blocks, extending ContentBlockProps with media-specific properties. +- **File**: `src/models/constructor-items/blocks.ts` +- **Key Properties**: + - `title`: TitleItemBaseProps | string - Enhanced title support with object or string format + - `description`: string - Optional description text with YFM support + - `button`: ButtonProps - Deprecated, use buttons array from ContentBlockProps instead + - Inherits from ContentBlockProps: `additionalInfo`, `links`, `buttons`, `size`, `list`, `controlPosition` + +#### Enhanced Title Support + +The `title` property in MediaContentProps now supports both simple strings and rich title objects: + +**String Format (Legacy)**: + +```typescript +title: 'Simple Title Text'; +``` + +**Object Format (Enhanced)**: + +```typescript +title: { + text: "Title Text", // Required: The title text + textSize?: TextSize, // Optional: 'xs' | 's' | 'sm' | 'm' | 'l' + url?: string, // Optional: Makes title clickable + urlTitle?: string, // Optional: Link title attribute + custom?: string | ReactNode, // Optional: Custom content (e.g., emoji) + onClick?: () => void, // Optional: Click handler +} +``` + +**Usage Examples**: + +```typescript +// Title with custom size +title: { + text: 'Large Title', + textSize: 'l' +} + +// Clickable title +title: { + text: 'Visit Our Site', + url: 'https://example.com', + urlTitle: 'Open example.com' +} + +// Interactive title +title: { + text: 'Click Me', + onClick: () => alert('Title clicked!') +} + +// Title with custom content +title: { + text: 'Featured Content', + custom: '⭐', + textSize: 'm' +} +``` + ### Media Sub-components The Media component internally uses specialized sub-components: @@ -569,6 +632,7 @@ The Media component includes comprehensive Storybook stories demonstrating: - Theme variations - Analytics integration - Responsive behavior +- Enhanced title support Stories are located in `src/components/Media/__stories__/Media.stories.tsx` with example data in `data.json`. diff --git a/src/blocks/Map/__stories__/Map.mdx b/src/blocks/Map/__stories__/Map.mdx index 20fa3d04a..68f31c99d 100644 --- a/src/blocks/Map/__stories__/Map.mdx +++ b/src/blocks/Map/__stories__/Map.mdx @@ -10,7 +10,7 @@ import * as MapStories from './Map.stories.tsx'; `type: map-block` -`title: string` β€” Title. +`title: string | TitleItemBaseProps` β€” Title. Can be a simple string or an object with additional properties like `textSize`, `url`, `urlTitle`, `custom`, and `onClick`. `description: string` β€” Description. diff --git a/src/blocks/Map/__stories__/Map.stories.tsx b/src/blocks/Map/__stories__/Map.stories.tsx index ccb220fda..64941bd0f 100644 --- a/src/blocks/Map/__stories__/Map.stories.tsx +++ b/src/blocks/Map/__stories__/Map.stories.tsx @@ -183,10 +183,43 @@ const MapsTypesTemplate: StoryFn = (args) => ( ); +const EnhancedTitleTemplate: StoryFn = (args) => ( + + alert('Map title clicked!'), + }, + map: { + ...data.ymap, + id: 'interactive-title-map', + }, + }, + ], + }} + /> + +); + export const Default = DefaultTemplate.bind({}); export const Size = SizeTemplate.bind({}); export const Direction = DirectionTemplate.bind({}); export const MapsTypes = MapsTypesTemplate.bind({}); +export const EnhancedTitle = EnhancedTitleTemplate.bind({}); const DefaultArgs = { ...data.default.content, @@ -201,3 +234,8 @@ Size.args = DefaultArgs as MapBlockProps; Direction.args = DefaultArgs as MapBlockProps; MapsTypes.args = DefaultArgs as MapBlockProps; + +EnhancedTitle.args = { + ...DefaultArgs, + ...data.enhancedTitle.largeClickable, +} as MapBlockProps; diff --git a/src/blocks/Map/__stories__/data.json b/src/blocks/Map/__stories__/data.json index 4055065d4..a57b104a9 100644 --- a/src/blocks/Map/__stories__/data.json +++ b/src/blocks/Map/__stories__/data.json @@ -61,5 +61,24 @@ "direction": { "defaultDirectionTitle": "Default Direction", "ReverseDirectionTitle": "Reverse Direction" + }, + "enhancedTitle": { + "largeClickable": { + "title": { + "text": "Large Clickable Media Title", + "textSize": "l", + "url": "https://example.com", + "urlTitle": "Open media example" + }, + "description": "Example with title object using custom size and clickable link" + }, + "interactiveWithIcon": { + "title": { + "text": "Interactive Media Title", + "textSize": "m", + "custom": "πŸ—ΊοΈ" + }, + "description": "Example with title object using onClick handler and custom content (emoji)" + } } } diff --git a/src/blocks/Media/Media.tsx b/src/blocks/Media/Media.tsx index 9ca9e007a..90e2463e0 100644 --- a/src/blocks/Media/Media.tsx +++ b/src/blocks/Media/Media.tsx @@ -23,7 +23,7 @@ export const MediaBlock = (props: MediaBlockProps) => { const theme = useTheme(); const mediaThemed = getThemedValue(media, theme); const mediaWithMicrodata = mergeVideoMicrodata(mediaThemed, { - name: title, + name: typeof title === 'object' ? title.text : title, description, }); diff --git a/src/blocks/Media/__stories__/Media.mdx b/src/blocks/Media/__stories__/Media.mdx index 9bf5cfd18..0b1dff22a 100644 --- a/src/blocks/Media/__stories__/Media.mdx +++ b/src/blocks/Media/__stories__/Media.mdx @@ -9,7 +9,7 @@ import * as MediaStories from './Media.stories.tsx'; `type: media-block` -`title: string` β€” Title. +`title: string | TitleItemBaseProps` β€” Title. Can be a simple string or an object with additional properties like `textSize`, `url`, `urlTitle`, `custom`, and `onClick`. `description: string` β€” Description. diff --git a/src/blocks/Media/__stories__/Media.stories.tsx b/src/blocks/Media/__stories__/Media.stories.tsx index 0e82744c0..94136a9ec 100644 --- a/src/blocks/Media/__stories__/Media.stories.tsx +++ b/src/blocks/Media/__stories__/Media.stories.tsx @@ -198,6 +198,27 @@ const IframeTemplate: StoryFn = (args) => ( /> ); +const EnhancedTitleTemplate: StoryFn = (args) => ( + alert('Media title clicked!'), + }, + }, + ], + }} + /> +); + export const Default = DefaultTemplate.bind({}); export const ImageSlider = ImageSliderTemplate.bind({}); export const Video = VideoTemplate.bind({}); @@ -208,6 +229,7 @@ export const WithoutShadowDeprecated = ImageSliderTemplate.bind({}); export const WithoutShadow = ImageSliderTemplate.bind({}); export const WithBorder = ImageSliderTemplate.bind({}); export const Iframe = IframeTemplate.bind({}); +export const EnhancedTitle = EnhancedTitleTemplate.bind({}); const DefaultArgs = { ...data.default.content, @@ -245,3 +267,7 @@ WithBorder.args = { Iframe.args = { ...DefaultArgs, } as MediaBlockProps; +EnhancedTitle.args = { + ...DefaultArgs, + ...data.enhancedTitle.largeClickable, +} as MediaBlockProps; diff --git a/src/blocks/Media/__stories__/data.json b/src/blocks/Media/__stories__/data.json index 4189c54fb..89db01b63 100644 --- a/src/blocks/Media/__stories__/data.json +++ b/src/blocks/Media/__stories__/data.json @@ -330,6 +330,25 @@ "defaultDirectionTitle": "Default Direction", "ReverseDirectionTitle": "Reverse Direction" }, + "enhancedTitle": { + "largeClickable": { + "title": { + "text": "Large Clickable Media Title", + "textSize": "l", + "url": "https://example.com", + "urlTitle": "Open media example" + }, + "description": "Example with title object using custom size and clickable link" + }, + "interactiveWithIcon": { + "title": { + "text": "Interactive Media Title", + "textSize": "m", + "custom": "🎬" + }, + "description": "Example with title object using onClick handler and custom content (emoji)" + } + }, "withoutShadow": { "content": { "type": "media-block", diff --git a/src/models/constructor-items/blocks.ts b/src/models/constructor-items/blocks.ts index adef6534d..a87b6a295 100644 --- a/src/models/constructor-items/blocks.ts +++ b/src/models/constructor-items/blocks.ts @@ -273,8 +273,7 @@ export interface MediaBaseBlockProps extends Animatable, MediaContentProps { } export interface MediaContentProps - extends Omit { - title: string; + extends Omit { description?: string; /** @deprecated Use array of buttons from ContentBlockProps instead**/ button?: ButtonProps;