diff --git a/memory-bank/activeContext.md b/memory-bank/activeContext.md index 95fa5144e..97ceee3c5 100644 --- a/memory-bank/activeContext.md +++ b/memory-bank/activeContext.md @@ -73,6 +73,17 @@ Recent development has focused on: - **Flexible Styling**: Allows any valid CSS color value (hex, rgb, rgba, named colors, etc.) - **Backward Compatibility**: Optional property that doesn't affect existing implementations +11. **CardLayout Title Centering Enhancement**: Added title centering support for CardLayout block: + + - **New Prop**: Added `centered?: boolean` prop to `CardLayoutBlockProps` for centering title and subtitle + - **Default Behavior**: Default value is `false`, maintaining backward compatibility (left-aligned by default) + - **Title Component Enhancement**: Extended `Title` component with `colJustifyContent?: GridJustifyContent` prop for controlling title and subtitle alignment + - **Responsive Behavior**: Dynamic `colSizes` based on `centered` prop: + - When `centered === false`: `sm: 8` (allows left-aligned title with narrower column) + - When `centered === true`: `sm: 12` (full width for centered title) + - **Implementation Logic**: Uses conditional check `centered ? GridJustifyContent.Center : GridJustifyContent.Start` for alignment and `centered ? 12 : 8` for column size + - **No Breaking Changes**: All changes are backward compatible with default `centered: false` value + ## Active Decisions and Considerations ### Architecture diff --git a/memory-bank/progress.md b/memory-bank/progress.md index b5f74dbdd..e14f4fa4b 100644 --- a/memory-bank/progress.md +++ b/memory-bank/progress.md @@ -49,6 +49,17 @@ Recently updated sub-block components with enhanced consistency: - **ContentList**: Enhanced with Gravity icons support for list items - **IconWrapper**: Updated to support both traditional image icons and Gravity UI icons +### Layout Blocks Enhancement + +- **CardLayout Block**: Enhanced with title centering support: + - **Title Centering Control**: New `centered?: boolean` prop allows centering title and subtitle + - **Title Component**: Extended with `colJustifyContent` prop for alignment control + - **Responsive Layout**: Dynamic column sizes adapt based on `centered` prop: + - When `centered === false`: uses `sm: 8` for narrower left-aligned title column + - When `centered === true`: uses `sm: 12` for full-width centered title + - **Implementation**: Conditional logic `centered ? GridJustifyContent.Center : GridJustifyContent.Start` for alignment and `centered ? 12 : 8` for column size + - **Backward Compatible**: Default `centered: false` maintains existing left-aligned behavior + ### Icon System Enhanced icon capabilities with Gravity UI integration: diff --git a/src/blocks/CardLayout/CardLayout.scss b/src/blocks/CardLayout/CardLayout.scss index c4a484533..404d6d22b 100644 --- a/src/blocks/CardLayout/CardLayout.scss +++ b/src/blocks/CardLayout/CardLayout.scss @@ -19,6 +19,15 @@ $largeBorderRadius: 32px; } } + &__title { + &_centered { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + } + } + &__image { position: absolute; top: 0; diff --git a/src/blocks/CardLayout/CardLayout.tsx b/src/blocks/CardLayout/CardLayout.tsx index 2e6fb102f..ad6294dfc 100644 --- a/src/blocks/CardLayout/CardLayout.tsx +++ b/src/blocks/CardLayout/CardLayout.tsx @@ -4,7 +4,7 @@ import isEmpty from 'lodash/isEmpty'; import {AnimateBlock, BackgroundImage, Title} from '../../components'; import {useTheme} from '../../context/theme'; -import {Col, GridColumnSizesType, Row} from '../../grid'; +import {Col, GridColumnSizesType, GridJustifyContent, Row} from '../../grid'; import {CardLayoutBlockProps as CardLayoutBlockParams, ClassNameProps} from '../../models'; import {block, getThemedValue} from '../../utils'; @@ -15,6 +15,7 @@ const DEFAULT_SIZES: GridColumnSizesType = { sm: 6, md: 4, }; + export type CardLayoutBlockProps = React.PropsWithChildren< Omit > & @@ -31,13 +32,21 @@ const CardLayout = ({ className, titleClassName, background, + centered = false, }: CardLayoutBlockProps) => { const theme = useTheme(); const {border, ...backgroundImageProps} = getThemedValue(background || {}, theme); return ( {(title || description) && ( - + <Title + title={title} + subtitle={description} + className={b('title', {centered}, titleClassName)} + colJustifyContent={ + centered ? GridJustifyContent.Center : GridJustifyContent.Start + } + /> )} <div className={b('content', { diff --git a/src/blocks/CardLayout/__stories__/data.json b/src/blocks/CardLayout/__stories__/data.json index 57783d42f..d9acf5e04 100644 --- a/src/blocks/CardLayout/__stories__/data.json +++ b/src/blocks/CardLayout/__stories__/data.json @@ -110,7 +110,8 @@ "content": { "type": "card-layout-block", "title": "Card layout with basic cards", - "description": "Three cards in a row on the desktop, two cards in a row on a tablet, one card in a row on a mobile phone." + "description": "Three cards in a row on the desktop, two cards in a row on a tablet, one card in a row on a mobile phone.", + "centered": false } }, "colSizes": { @@ -172,6 +173,7 @@ "type": "card-layout-block", "title": "Card layout with background image (basic cards)", "description": "Four cards in a row on the desktop, three cards in a row on the mini-desktop, two cards in a row on a tablet, one card in a row on a mobile phone.", + "centered": false, "colSizes": { "all": 12, "sm": 6, diff --git a/src/components/Title/Title.tsx b/src/components/Title/Title.tsx index 67d912ff1..a2520a8a2 100644 --- a/src/components/Title/Title.tsx +++ b/src/components/Title/Title.tsx @@ -1,4 +1,4 @@ -import {Col, GridColumnSizesType} from '../../grid'; +import {Col, GridColumnSizesType, GridJustifyContent} from '../../grid'; import {ClassNameProps, TitleItemProps, TitleProps as TitleParams} from '../../models'; import {block} from '../../utils'; import YFMWrapper from '../YFMWrapper/YFMWrapper'; @@ -11,6 +11,7 @@ const b = block('title'); export interface TitleProps extends TitleParams { colSizes?: GridColumnSizesType; + colJustifyContent?: GridJustifyContent; id?: string; } @@ -19,6 +20,7 @@ const Title = ({ subtitle, className, colSizes = {all: 12, sm: 8}, + colJustifyContent, id, }: TitleProps & ClassNameProps) => { if (!title && !subtitle) { @@ -31,12 +33,20 @@ const Title = ({ return ( <div className={b(null, className)} id={id}> {text && ( - <Col reset sizes={colSizes}> + <Col + reset + sizes={colSizes} + {...(colJustifyContent && {justifyContent: colJustifyContent})} + > <TitleItem text={text} {...titleProps} /> </Col> )} {subtitle && ( - <Col reset sizes={colSizes}> + <Col + reset + sizes={colSizes} + {...(colJustifyContent && {justifyContent: colJustifyContent})} + > <div className={b('description', {titleSize: titleProps?.textSize})}> <YFMWrapper content={subtitle} modifiers={{constructor: true}} /> </div> diff --git a/src/models/constructor-items/blocks.ts b/src/models/constructor-items/blocks.ts index ca402df2f..add481863 100644 --- a/src/models/constructor-items/blocks.ts +++ b/src/models/constructor-items/blocks.ts @@ -357,6 +357,7 @@ export interface TabsBlockProps extends Animatable { export interface CardLayoutBlockProps extends Childable, Animatable, LoadableChildren { title?: TitleItemProps | string; titleClassName?: string; + centered?: boolean; description?: string; colSizes?: GridColumnSizesType; background?: ThemeSupporting<